diff --git a/Android.bp b/Android.bp index d585c6c9ca8ca57197d8b9b4ebd8f333271eb60b..2066ba6d4b81efd72bd132dcd3cec6b1983bf942 100644 --- a/Android.bp +++ b/Android.bp @@ -70,5 +70,5 @@ cc_defaults { "-Werror=reorder-init-list", ], c_std: "c99", - cpp_std: "c++17", + cpp_std: "c++20", } diff --git a/OWNERS_leaudio b/OWNERS_leaudio index 30db38d7995a5464633021e6f1f61d743d5e8eb1..0ba606bbf0a93823fbc6d975e4764668385a7116 100644 --- a/OWNERS_leaudio +++ b/OWNERS_leaudio @@ -1,3 +1,4 @@ siyuanh@google.com jpawlowski@google.com rongxuan@google.com +yuyangh@google.com diff --git a/README.md b/README.md index 60daa85761dbb04c4e2e158d9a6da1e9ee4621b9..3df5e04b6d58623edbcdb0aa0b245db879a580f6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ sudo apt-get install repo git-core gnupg flex bison gperf build-essential \ libgl1-mesa-dev libxml2-utils xsltproc unzip liblz4-tool libssl-dev \ libc++-dev libevent-dev \ flatbuffers-compiler libflatbuffers1 openssl \ - libflatbuffers-dev libtinyxml2-dev \ + libflatbuffers-dev libfmt-dev libtinyxml2-dev \ libglib2.0-dev libevent-dev libnss3-dev libdbus-1-dev \ libprotobuf-dev ninja-build generate-ninja protobuf-compiler \ libre2-9 debmake \ diff --git a/TEST_MAPPING b/TEST_MAPPING index 4e568c8a98c06c3a7713d86f40c1649b3667f671..8f167cf47bef32ce0d6bcc4102b31c0ae4d4f06f 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -323,9 +323,15 @@ { "name": "bluetooth_le_audio_codec_manager_test" }, + { + "name": "bluetooth-test-audio-hal-a2dp-provider-info" + }, { "name": "bluetooth_test_gdx_unit" }, + { + "name": "CtsStrictJavaPackagesTestCases" + }, { "name": "asrc_resampler_test" } diff --git a/android/app/Android.bp b/android/app/Android.bp index 1d43cfefa3445f04077b9f95e0a66543e8dbac17..835fb9f9317ac8d5beb46f9eec0ce7dc765d920f 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -37,6 +37,9 @@ java_library { ], min_sdk_version: "Tiramisu", sdk_version: "module_current", + lint: { + baseline_filename: "lint-baseline.xml", + }, } java_library { @@ -49,6 +52,9 @@ java_library { ], min_sdk_version: "Tiramisu", sdk_version: "module_current", + lint: { + baseline_filename: "lint-baseline.xml", + }, } // Bluetooth JNI @@ -99,17 +105,21 @@ cc_library_shared { "libbase", "libbluetooth", "libbluetooth-dumpsys", + "libbluetooth-gdx", "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_core_rs_bridge", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", + "libbt-audio-asrc", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", "libbt-btu-main-thread", "libbt-common", "libbt-hci", + "libbt-jni-thread", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", @@ -228,6 +238,7 @@ android_app { jni_uses_platform_apis: true, libs: [ "app-compat-annotations", + "bluetooth_flags_java_lib", "error_prone_annotations", "framework-annotations-lib", "framework-bluetooth-pre-jarjar", @@ -255,7 +266,6 @@ android_app { "bluetooth-protos-lite", "bluetooth.change-ids", "bluetooth.mapsapi", - "bluetooth_flags_java_lib", "com.android.obex", "com.android.vcard", "guava", @@ -290,7 +300,7 @@ android_app { "UseSparseArrays", "UseValueOf", ], - strict_updatability_linting: true, + baseline_filename: "lint-baseline.xml", }, optimize: { diff --git a/android/app/AndroidManifest.xml b/android/app/AndroidManifest.xml index 3e07cc5b0f58da57d85960c1436b8b34b8b55d36..c0548dd8325cb423f03cd38aa6cad185f19ca7f4 100644 --- a/android/app/AndroidManifest.xml +++ b/android/app/AndroidManifest.xml @@ -104,64 +104,16 @@ - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/app/aidl/Android.bp b/android/app/aidl/Android.bp index 8a5e2612d55d38a65b7aac28324155e5cad3a8c8..6d9c8871c3bf04539497b5d1edfdc2d7ff6f3759 100644 --- a/android/app/aidl/Android.bp +++ b/android/app/aidl/Android.bp @@ -57,7 +57,6 @@ filegroup { "android/bluetooth/IBluetoothQualityReportReadyCallback.aidl", "android/bluetooth/IBluetoothSap.aidl", "android/bluetooth/IBluetoothSocketManager.aidl", - "android/bluetooth/IBluetoothStateChangeCallback.aidl", "android/bluetooth/IBluetoothVolumeControl.aidl", "android/bluetooth/IBluetoothVolumeControlCallback.aidl", "android/bluetooth/IncomingRfcommSocketInfo.aidl", diff --git a/android/app/aidl/android/bluetooth/IBluetooth.aidl b/android/app/aidl/android/bluetooth/IBluetooth.aidl index 80c6fe426f1c5c16098d82529dbbc21e52fa02bd..b937d99d97ecd8f2d19b2a21a395c2bc28d68a42 100644 --- a/android/app/aidl/android/bluetooth/IBluetooth.aidl +++ b/android/app/aidl/android/bluetooth/IBluetooth.aidl @@ -26,7 +26,6 @@ import android.bluetooth.IBluetoothConnectionCallback; import android.bluetooth.IBluetoothMetadataListener; import android.bluetooth.IBluetoothOobDataCallback; import android.bluetooth.IBluetoothSocketManager; -import android.bluetooth.IBluetoothStateChangeCallback; import android.bluetooth.BluetoothActivityEnergyInfo; import android.bluetooth.BluetoothSinkAudioPolicy; import android.bluetooth.BluetoothClass; @@ -176,7 +175,9 @@ interface IBluetooth IBluetoothSocketManager getSocketManager(); @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") - oneway void logL2capcocClientConnection(in BluetoothDevice device, int port, boolean isSecured, int result, long socketCreationTimeMillis, long socketCreationLatencyMillis, long socketConnectionTimeMillis, in SynchronousResultReceiver receiver); + oneway void logL2capcocClientConnection(in BluetoothDevice device, int port, boolean isSecured, int result, long socketCreationTimeNanos, long socketCreationLatencyNanos, long socketConnectionTimeNanos, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") + oneway void logRfcommConnectionAttempt(in BluetoothDevice device, boolean isSecured, int resultCode, long socketCreationTimeNanos, boolean isSerialPort, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") oneway void factoryReset(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @@ -309,4 +310,13 @@ interface IBluetooth @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") oneway void unregAllGattClient(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + + @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") + oneway void getProfile(int profile, in SynchronousResultReceiver receiver); + + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + oneway void setActiveAudioDevicePolicy(in BluetoothDevice device, int activeAudioDevicePolicy, in AttributionSource source, in SynchronousResultReceiver receiver); + + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + oneway void getActiveAudioDevicePolicy(in BluetoothDevice device, in AttributionSource source, in SynchronousResultReceiver receiver); } diff --git a/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl b/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl index 8c5305e02aa6f2687d42c84854fd987f4dc25dd6..ab05c5156c216bd79f35bb6b9ddd3f3ef255d018 100644 --- a/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl +++ b/android/app/aidl/android/bluetooth/IBluetoothGatt.aidl @@ -190,4 +190,10 @@ oneway interface IBluetoothGatt { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") void stopDistanceMeasurement(in ParcelUuid uuid, in BluetoothDevice device, in int method, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + void getChannelSoundingMaxSupportedSecurityLevel(in BluetoothDevice remoteDevice, in AttributionSource attributionSource, + in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + void getLocalChannelSoundingMaxSupportedSecurityLevel(in AttributionSource attributionSource, + in SynchronousResultReceiver receiver); } diff --git a/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl b/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl index 421e1ada88844a986c65fcf01dd1b23bb3008f28..1753700b6b88cd2a7bd6838fe62950bf3695b037 100644 --- a/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl +++ b/android/app/aidl/android/bluetooth/IBluetoothHidHost.aidl @@ -42,6 +42,10 @@ oneway interface IBluetoothHidHost { 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(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + void setPreferredTransport(in BluetoothDevice device, int transport, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + void getPreferredTransport(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void getProtocolMode(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") diff --git a/android/app/aidl/android/bluetooth/IBluetoothLeAudio.aidl b/android/app/aidl/android/bluetooth/IBluetoothLeAudio.aidl index d2dd14563ca3dd8933e0c96e04115f3e1e275bc1..9c6f87e7c5257ecf2171bdb15ddb4890fe72a870 100644 --- a/android/app/aidl/android/bluetooth/IBluetoothLeAudio.aidl +++ b/android/app/aidl/android/bluetooth/IBluetoothLeAudio.aidl @@ -81,6 +81,9 @@ oneway interface IBluetoothLeAudio { const int GROUP_NODE_ADDED = 1; const int GROUP_NODE_REMOVED = 2; + const int GROUP_STREAM_STATUS_IDLE = 0; + const int GROUP_STREAM_STATUS_STREAMING = 1; + /** * Get device group id. Devices with same group id belong to same group (i.e left and right * earbud) @@ -119,4 +122,6 @@ oneway interface IBluetoothLeAudio { void getMaximumStreamsPerBroadcast(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT})") void getMaximumSubgroupsPerBroadcast(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + void isBroadcastActive(in AttributionSource attributionSource, in SynchronousResultReceiver receiver); } diff --git a/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl index 547b3cb0c6ebb9302721c7e7194b79cd030fe6f1..92ecfe814d4218aec4c5847bbe82131041f54d1d 100644 --- a/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl +++ b/android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl @@ -31,4 +31,5 @@ oneway interface IBluetoothLeAudioCallback { void onGroupNodeAdded(in BluetoothDevice device, int groupId); void onGroupNodeRemoved(in BluetoothDevice device, int groupId); void onGroupStatusChanged(int groupId, int groupStatus); + void onGroupStreamStatusChanged(int groupId, int groupStreamStatus); } diff --git a/android/app/aidl/android/bluetooth/IBluetoothVolumeControl.aidl b/android/app/aidl/android/bluetooth/IBluetoothVolumeControl.aidl index 179cb8ac7e302763dd0ee66bbaa07f4eabef1efa..b269181545732ad6d924e7f665ca4d319d8822b5 100644 --- a/android/app/aidl/android/bluetooth/IBluetoothVolumeControl.aidl +++ b/android/app/aidl/android/bluetooth/IBluetoothVolumeControl.aidl @@ -37,28 +37,30 @@ oneway interface IBluetoothVolumeControl { 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)") + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") void getConnectedDevices(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 getDevicesMatchingConnectionStates(in int[] states, 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 getConnectionState(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 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 isVolumeOffsetAvailable(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); - @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") - void setVolumeOffset(in BluetoothDevice device, int volumeOffset, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + void getNumberOfVolumeOffsetInstances(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 setVolumeOffset(in BluetoothDevice device, int instanceId, int volumeOffset, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void setGroupVolume(int group_id, int volume, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void getGroupVolume(int group_id, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") void setGroupActive(int group_id, boolean active, 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 setDeviceVolume(in BluetoothDevice device, int volume, boolean isGroupOp, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") @@ -75,4 +77,6 @@ oneway interface IBluetoothVolumeControl { void registerCallback(in IBluetoothVolumeControlCallback 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 IBluetoothVolumeControlCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") + void notifyNewRegisteredCallback(in IBluetoothVolumeControlCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver); } diff --git a/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl b/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl index 4467be1e9b67fdd4aa1c434598d6aa8a40da1861..e0679897395270a67f1d2fce3afbe08ea7fa84a0 100644 --- a/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl +++ b/android/app/aidl/android/bluetooth/IBluetoothVolumeControlCallback.aidl @@ -26,6 +26,8 @@ import java.util.List; * @hide */ oneway interface IBluetoothVolumeControlCallback { - void onVolumeOffsetChanged(in BluetoothDevice device, in int volumeOffset); + void onVolumeOffsetChanged(in BluetoothDevice device, in int instanceId, in int volumeOffset); + void onVolumeOffsetAudioLocationChanged(in BluetoothDevice device, in int instanceId, in int audioLocation); + void onVolumeOffsetAudioDescriptionChanged(in BluetoothDevice device, in int instanceId, in String audioDescription); void onDeviceVolumeChanged(in BluetoothDevice device, in int volume); } diff --git a/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl b/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl index 2e3241c360f17b8f581053d61e87f53e40b81b95..35e88a4a6848c886b753b3d82f58729541220212 100644 --- a/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl +++ b/android/app/aidl/android/bluetooth/le/IAdvertisingSetCallback.aidl @@ -20,7 +20,7 @@ package android.bluetooth.le; * @hide */ oneway interface IAdvertisingSetCallback { - void onAdvertisingSetStarted(in int advertiserId, in int tx_power, in int status); + void onAdvertisingSetStarted(in IBinder gattBinder, in int advertiserId, in int tx_power, in int status); void onOwnAddressRead(in int advertiserId, in int addressType, in String address); void onAdvertisingSetStopped(in int advertiserId); void onAdvertisingEnabled(in int advertiserId, in boolean enable, in int status); diff --git a/android/app/jni/OWNERS b/android/app/jni/OWNERS index 3baddf6903d5b9bc00ce5ef86c6cf8c50e2f029e..826f56b4e06f6c1d60c4ec0d20f37e565071869f 100644 --- a/android/app/jni/OWNERS +++ b/android/app/jni/OWNERS @@ -1 +1,4 @@ per-file com_android_bluetooth_hearing_aid.cpp=file:/OWNERS_hearingaid +per-file com_android_bluetooth_csip_set_coordinator.cpp=file:/OWNERS_leaudio +per-file com_android_bluetooth_le_audio.cpp=file:/OWNERS_leaudio +per-file com_android_bluetooth_vc.cpp=file:/OWNERS_leaudio diff --git a/android/app/jni/com_android_bluetooth.h b/android/app/jni/com_android_bluetooth.h index 502e695621090456862c7ca6f8dc885ad77d4f4a..45b4e74d1314799e5e2a932f714b24e0176ce54e 100644 --- a/android/app/jni/com_android_bluetooth.h +++ b/android/app/jni/com_android_bluetooth.h @@ -15,15 +15,16 @@ * limitations under the License. */ -#ifndef COM_ANDROID_BLUETOOTH_H -#define COM_ANDROID_BLUETOOTH_H +#pragma once + +#include #include "hardware/bluetooth.h" #include "hardware/hardware.h" #include "jni.h" -#include "jni_logging.h" #include "nativehelper/ScopedLocalRef.h" -#include "utils/Log.h" + +namespace log = bluetooth::log; namespace android { @@ -38,15 +39,15 @@ public: ~CallbackEnv() { if (mCallbackEnv && mCallbackEnv->ExceptionCheck()) { - ALOGE("An exception was thrown by callback '%s'.", mName); - LOGE_EX(mCallbackEnv); - mCallbackEnv->ExceptionClear(); + log::error("An exception was thrown by callback '{}'.", mName); + jniLogException(mCallbackEnv, ANDROID_LOG_ERROR, LOG_TAG); + mCallbackEnv->ExceptionClear(); } } bool valid() const { if (!mCallbackEnv || !isCallbackThread()) { - ALOGE("%s: Callback env fail", mName); + log::error("{}: Callback env fail", mName); return false; } return true; @@ -184,5 +185,3 @@ void jniGetMethodsOrDie(JNIEnv* env, const char* className, jniGetMethodsOrDie(env, classname, methodsArray, NELEM(methodsArray)) } // namespace android - -#endif /* COM_ANDROID_BLUETOOTH_H */ diff --git a/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp b/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp index 6472ef2397c57fb3f907b2a5b373535a812110af..747e25fbde43af4f1e32bcb97c138408dd81ce44 100644 --- a/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp +++ b/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp @@ -22,7 +22,7 @@ #include "base/logging.h" #include "com_android_bluetooth.h" -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "hardware/bt_bqr.h" using bluetooth::bqr::BluetoothQualityReportCallbacks; @@ -46,7 +46,7 @@ class BluetoothQualityReportCallbacksImpl void bqr_delivery_callback(const RawAddress bd_addr, uint8_t lmp_ver, uint16_t lmp_subver, uint16_t manufacturer_id, std::vector bqr_raw_data) override { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -57,7 +57,7 @@ class BluetoothQualityReportCallbacksImpl ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Error while allocation byte array for addr in %s", __func__); + log::error("Error while allocation byte array for addr"); return; } @@ -67,8 +67,7 @@ class BluetoothQualityReportCallbacksImpl ScopedLocalRef raw_data( sCallbackEnv.get(), sCallbackEnv->NewByteArray(bqr_raw_data.size())); if (!raw_data.get()) { - ALOGE("Error while allocation byte array for bqr raw data in %s", - __func__); + log::error("Error while allocation byte array for bqr raw data"); return; } sCallbackEnv->SetByteArrayRegion(raw_data.get(), 0, bqr_raw_data.size(), @@ -93,32 +92,32 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothQualityReportInterface != nullptr) { - LOG(INFO) << "Cleaning up BluetoothQualityReport Interface before " - "initializing..."; + log::info( + "Cleaning up BluetoothQualityReport Interface before initializing..."); sBluetoothQualityReportInterface = nullptr; } if (mCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up BluetoothQualityReport callback object"; + log::info("Cleaning up BluetoothQualityReport callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) - << "Failed to allocate Global Ref for BluetoothQualityReport Callbacks"; + log::error( + "Failed to allocate Global Ref for BluetoothQualityReport Callbacks"); return; } sBluetoothQualityReportInterface = (BluetoothQualityReportInterface*)btInf->get_profile_interface(BT_BQR_ID); if (sBluetoothQualityReportInterface == nullptr) { - LOG(ERROR) << "Failed to get BluetoothQualityReport Interface"; + log::error("Failed to get BluetoothQualityReport Interface"); return; } @@ -131,7 +130,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } diff --git a/android/app/jni/com_android_bluetooth_a2dp.cpp b/android/app/jni/com_android_bluetooth_a2dp.cpp index c2427e10bf04ae2dc0ce21f64aae627c65bfc063..7486ccbb58920cd39a1ada3d4a27a105f600a373 100644 --- a/android/app/jni/com_android_bluetooth_a2dp.cpp +++ b/android/app/jni/com_android_bluetooth_a2dp.cpp @@ -44,6 +44,7 @@ static struct { } android_bluetooth_BluetoothCodecConfig; static const btav_source_interface_t* sBluetoothA2dpInterface = nullptr; +static std::vector supported_codecs; static std::shared_timed_mutex interface_mutex; static jobject mCallbacksObj = nullptr; @@ -52,7 +53,7 @@ static std::shared_timed_mutex callbacks_mutex; static void bta2dp_connection_state_callback(const RawAddress& bd_addr, btav_connection_state_t state, const btav_error_t& /* error */) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -61,7 +62,7 @@ static void bta2dp_connection_state_callback(const RawAddress& bd_addr, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Fail to new jbyteArray bd addr", __func__); + log::error("Fail to new jbyteArray bd addr"); return; } @@ -74,7 +75,7 @@ static void bta2dp_connection_state_callback(const RawAddress& bd_addr, static void bta2dp_audio_state_callback(const RawAddress& bd_addr, btav_audio_state_t state) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -83,7 +84,7 @@ static void bta2dp_audio_state_callback(const RawAddress& bd_addr, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Fail to new jbyteArray bd addr", __func__); + log::error("Fail to new jbyteArray bd addr"); return; } @@ -98,7 +99,7 @@ static void bta2dp_audio_config_callback( const RawAddress& bd_addr, btav_a2dp_codec_config_t codec_config, std::vector codecs_local_capabilities, std::vector codecs_selectable_capabilities) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -150,7 +151,7 @@ static void bta2dp_audio_config_callback( ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(RawAddress::kLength)); if (!addr.get()) { - ALOGE("%s: Fail to new jbyteArray bd addr", __func__); + log::error("Fail to new jbyteArray bd addr"); return; } sCallbackEnv->SetByteArrayRegion( @@ -164,7 +165,7 @@ static void bta2dp_audio_config_callback( static bool bta2dp_mandatory_codec_preferred_callback( const RawAddress& bd_addr) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -173,7 +174,7 @@ static bool bta2dp_mandatory_codec_preferred_callback( ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(RawAddress::kLength)); if (!addr.get()) { - ALOGE("%s: Fail to new jbyteArray bd addr", __func__); + log::error("Fail to new jbyteArray bd addr"); return false; } sCallbackEnv->SetByteArrayRegion( @@ -201,7 +202,7 @@ static std::vector prepareCodecPreferences( if (jcodecConfig == nullptr) continue; if (!env->IsInstanceOf(jcodecConfig, android_bluetooth_BluetoothCodecConfig.clazz)) { - ALOGE("%s: Invalid BluetoothCodecConfig instance", __func__); + log::error("Invalid BluetoothCodecConfig instance"); continue; } jint codecType = env->CallIntMethod( @@ -251,32 +252,31 @@ static void initNative(JNIEnv* env, jobject object, const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - ALOGE("%s: Bluetooth module is not loaded", __func__); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothA2dpInterface != nullptr) { - ALOGW("%s: Cleaning up A2DP Interface before initializing...", __func__); + log::warn("Cleaning up A2DP Interface before initializing..."); sBluetoothA2dpInterface->cleanup(); sBluetoothA2dpInterface = nullptr; } if (mCallbacksObj != nullptr) { - ALOGW("%s: Cleaning up A2DP callback object", __func__); + log::warn("Cleaning up A2DP callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - ALOGE("%s: Failed to allocate Global Ref for A2DP Callbacks", __func__); + log::error("Failed to allocate Global Ref for A2DP Callbacks"); return; } android_bluetooth_BluetoothCodecConfig.clazz = (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothCodecConfig")); if (android_bluetooth_BluetoothCodecConfig.clazz == nullptr) { - ALOGE("%s: Failed to allocate Global Ref for BluetoothCodecConfig class", - __func__); + log::error("Failed to allocate Global Ref for BluetoothCodecConfig class"); return; } @@ -284,7 +284,7 @@ static void initNative(JNIEnv* env, jobject object, (btav_source_interface_t*)btInf->get_profile_interface( BT_PROFILE_ADVANCED_AUDIO_ID); if (sBluetoothA2dpInterface == nullptr) { - ALOGE("%s: Failed to get Bluetooth A2DP Interface", __func__); + log::error("Failed to get Bluetooth A2DP Interface"); return; } @@ -296,10 +296,10 @@ static void initNative(JNIEnv* env, jobject object, bt_status_t status = sBluetoothA2dpInterface->init( &sBluetoothA2dpCallbacks, maxConnectedAudioDevices, codec_priorities, - codec_offloading); + codec_offloading, &supported_codecs); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed to initialize Bluetooth A2DP, status: %d", __func__, - status); + log::error("Failed to initialize Bluetooth A2DP, status: {}", + bt_status_text(status)); sBluetoothA2dpInterface = nullptr; return; } @@ -311,7 +311,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - ALOGE("%s: Bluetooth module is not loaded", __func__); + log::error("Bluetooth module is not loaded"); return; } @@ -330,44 +330,38 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { } static jobjectArray getSupportedCodecTypesNative(JNIEnv* env) { - ALOGI("%s: %p", __func__, sBluetoothA2dpInterface); + log::info("{}", fmt::ptr(sBluetoothA2dpInterface)); jclass android_bluetooth_BluetoothCodecType_clazz = (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothCodecType")); if (android_bluetooth_BluetoothCodecType_clazz == nullptr) { - ALOGE("%s: Failed to allocate Global Ref for BluetoothCodecType class", - __func__); + log::error("Failed to allocate Global Ref for BluetoothCodecType class"); return nullptr; } - jmethodID createFromType = env->GetStaticMethodID( - android_bluetooth_BluetoothCodecType_clazz, "createFromType", - "(I)Landroid/bluetooth/BluetoothCodecType;"); - if (createFromType == nullptr) { - ALOGE( - "%s: Failed to find method createFromType of BluetoothCodecType class", - __func__); + jmethodID init = env->GetMethodID(android_bluetooth_BluetoothCodecType_clazz, + "", "(IJLjava/lang/String;)V"); + + if (init == nullptr) { + log::error("Failed to find method of BluetoothCodecType class"); return nullptr; } - std::array default_supported_codecs = { - BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, BTAV_A2DP_CODEC_INDEX_SOURCE_AAC, - BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD, - BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC, BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS, - }; jobjectArray result = - env->NewObjectArray(default_supported_codecs.size(), + env->NewObjectArray(supported_codecs.size(), android_bluetooth_BluetoothCodecType_clazz, nullptr); + if (result == nullptr) { - ALOGE("%s: Failed to allocate result array of BluetoothCodecType", - __func__); + log::error("Failed to allocate result array of BluetoothCodecType"); return nullptr; } - for (size_t index = 0; index < default_supported_codecs.size(); index++) { - jobject codec_type = env->CallStaticObjectMethod( - android_bluetooth_BluetoothCodecType_clazz, createFromType, - (jint)default_supported_codecs[index]); + for (size_t index = 0; index < supported_codecs.size(); index++) { + jobject codec_type = env->NewObject( + android_bluetooth_BluetoothCodecType_clazz, init, + (jint)supported_codecs[index].codec_type, + (jlong)supported_codecs[index].codec_id, + env->NewStringUTF(supported_codecs[index].codec_name.c_str())); env->SetObjectArrayElement(result, index, codec_type); } @@ -376,10 +370,10 @@ static jobjectArray getSupportedCodecTypesNative(JNIEnv* env) { static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); + log::info("sBluetoothA2dpInterface: {}", fmt::ptr(sBluetoothA2dpInterface)); std::shared_lock lock(interface_mutex); if (!sBluetoothA2dpInterface) { - ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); + log::error("Failed to get the Bluetooth A2DP Interface"); return JNI_FALSE; } @@ -393,7 +387,7 @@ static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, bd_addr.FromOctets(reinterpret_cast(addr)); bt_status_t status = sBluetoothA2dpInterface->connect(bd_addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed A2DP connection, status: %d", __func__, status); + log::error("Failed A2DP connection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -401,10 +395,10 @@ static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, static jboolean disconnectA2dpNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); + log::info("sBluetoothA2dpInterface: {}", fmt::ptr(sBluetoothA2dpInterface)); std::shared_lock lock(interface_mutex); if (!sBluetoothA2dpInterface) { - ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); + log::error("Failed to get the Bluetooth A2DP Interface"); return JNI_FALSE; } @@ -418,7 +412,7 @@ static jboolean disconnectA2dpNative(JNIEnv* env, jobject /* object */, bd_addr.FromOctets(reinterpret_cast(addr)); bt_status_t status = sBluetoothA2dpInterface->disconnect(bd_addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed A2DP disconnection, status: %d", __func__, status); + log::error("Failed A2DP disconnection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -426,10 +420,10 @@ static jboolean disconnectA2dpNative(JNIEnv* env, jobject /* object */, static jboolean setSilenceDeviceNative(JNIEnv* env, jobject /* object */, jbyteArray address, jboolean silence) { - ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); + log::info("sBluetoothA2dpInterface: {}", fmt::ptr(sBluetoothA2dpInterface)); std::shared_lock lock(interface_mutex); if (!sBluetoothA2dpInterface) { - ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); + log::error("Failed to get the Bluetooth A2DP Interface"); return JNI_FALSE; } @@ -445,7 +439,8 @@ static jboolean setSilenceDeviceNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothA2dpInterface->set_silence_device(bd_addr, silence); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed A2DP set_silence_device, status: %d", __func__, status); + log::error("Failed A2DP set_silence_device, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -453,10 +448,10 @@ static jboolean setSilenceDeviceNative(JNIEnv* env, jobject /* object */, static jboolean setActiveDeviceNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); + log::info("sBluetoothA2dpInterface: {}", fmt::ptr(sBluetoothA2dpInterface)); std::shared_lock lock(interface_mutex); if (!sBluetoothA2dpInterface) { - ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); + log::error("Failed to get the Bluetooth A2DP Interface"); return JNI_FALSE; } @@ -468,7 +463,8 @@ static jboolean setActiveDeviceNative(JNIEnv* env, jobject /* object */, } bt_status_t status = sBluetoothA2dpInterface->set_active_device(bd_addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed A2DP set_active_device, status: %d", __func__, status); + log::error("Failed A2DP set_active_device, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -477,10 +473,10 @@ static jboolean setActiveDeviceNative(JNIEnv* env, jobject /* object */, static jboolean setCodecConfigPreferenceNative(JNIEnv* env, jobject object, jbyteArray address, jobjectArray codecConfigArray) { - ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); + log::info("sBluetoothA2dpInterface: {}", fmt::ptr(sBluetoothA2dpInterface)); std::shared_lock lock(interface_mutex); if (!sBluetoothA2dpInterface) { - ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); + log::error("Failed to get the Bluetooth A2DP Interface"); return JNI_FALSE; } @@ -498,7 +494,8 @@ static jboolean setCodecConfigPreferenceNative(JNIEnv* env, jobject object, bt_status_t status = sBluetoothA2dpInterface->config_codec(bd_addr, codec_preferences); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed codec configuration, status: %d", __func__, status); + log::error("Failed codec configuration, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; diff --git a/android/app/jni/com_android_bluetooth_a2dp_sink.cpp b/android/app/jni/com_android_bluetooth_a2dp_sink.cpp index d2abfb6055a0c09fa3e7b6869698c2a525b43358..c4ffb2e2a437dc16b604e1661743693f1a787a29 100644 --- a/android/app/jni/com_android_bluetooth_a2dp_sink.cpp +++ b/android/app/jni/com_android_bluetooth_a2dp_sink.cpp @@ -37,7 +37,7 @@ static std::shared_timed_mutex callbacks_mutex; static void a2dp_sink_connection_state_callback( const RawAddress& bd_addr, btav_connection_state_t state, const btav_error_t& /* error */) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); if (!mCallbacksObj) return; @@ -47,7 +47,7 @@ static void a2dp_sink_connection_state_callback( ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for connection state"); + log::error("Fail to new jbyteArray bd addr for connection state"); return; } @@ -59,7 +59,7 @@ static void a2dp_sink_connection_state_callback( static void a2dp_sink_audio_state_callback(const RawAddress& bd_addr, btav_audio_state_t state) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); if (!mCallbacksObj) return; @@ -69,7 +69,7 @@ static void a2dp_sink_audio_state_callback(const RawAddress& bd_addr, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for connection state"); + log::error("Fail to new jbyteArray bd addr for connection state"); return; } @@ -82,7 +82,7 @@ static void a2dp_sink_audio_state_callback(const RawAddress& bd_addr, static void a2dp_sink_audio_config_callback(const RawAddress& bd_addr, uint32_t sample_rate, uint8_t channel_count) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(callbacks_mutex); if (!mCallbacksObj) return; @@ -92,7 +92,7 @@ static void a2dp_sink_audio_config_callback(const RawAddress& bd_addr, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for connection state"); + log::error("Fail to new jbyteArray bd addr for connection state"); return; } @@ -116,18 +116,18 @@ static void initNative(JNIEnv* env, jobject object, const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothA2dpInterface != NULL) { - ALOGW("Cleaning up A2DP Interface before initializing..."); + log::warn("Cleaning up A2DP Interface before initializing..."); sBluetoothA2dpInterface->cleanup(); sBluetoothA2dpInterface = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up A2DP callback object"); + log::warn("Cleaning up A2DP callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -136,14 +136,15 @@ static void initNative(JNIEnv* env, jobject object, (btav_sink_interface_t*)btInf->get_profile_interface( BT_PROFILE_ADVANCED_AUDIO_SINK_ID); if (sBluetoothA2dpInterface == NULL) { - ALOGE("Failed to get Bluetooth A2DP Sink Interface"); + log::error("Failed to get Bluetooth A2DP Sink Interface"); return; } bt_status_t status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks, maxConnectedAudioDevices); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to initialize Bluetooth A2DP Sink, status: %d", status); + log::error("Failed to initialize Bluetooth A2DP Sink, status: {}", + bt_status_text(status)); sBluetoothA2dpInterface = NULL; return; } @@ -156,7 +157,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } @@ -173,7 +174,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); + log::info("sBluetoothA2dpInterface: {}", fmt::ptr(sBluetoothA2dpInterface)); if (!sBluetoothA2dpInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); @@ -186,7 +187,7 @@ static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, bd_addr.FromOctets(reinterpret_cast(addr)); bt_status_t status = sBluetoothA2dpInterface->connect(bd_addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed HF connection, status: %d", status); + log::error("Failed HF connection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -206,7 +207,7 @@ static jboolean disconnectA2dpNative(JNIEnv* env, jobject /* object */, bd_addr.FromOctets(reinterpret_cast(addr)); bt_status_t status = sBluetoothA2dpInterface->disconnect(bd_addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed HF disconnection, status: %d", status); + log::error("Failed HF disconnection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -228,7 +229,7 @@ static jboolean setActiveDeviceNative(JNIEnv* env, jobject /* object */, jbyteArray address) { if (!sBluetoothA2dpInterface) return JNI_FALSE; - ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); + log::info("sBluetoothA2dpInterface: {}", fmt::ptr(sBluetoothA2dpInterface)); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { @@ -240,7 +241,8 @@ static jboolean setActiveDeviceNative(JNIEnv* env, jobject /* object */, rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothA2dpInterface->set_active_device(rawAddress); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending passthru command, status: %d", status); + log::error("Failed sending passthru command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); diff --git a/android/app/jni/com_android_bluetooth_avrcp_controller.cpp b/android/app/jni/com_android_bluetooth_avrcp_controller.cpp index 6382f460937bfc2b9a6cbcd8699cfe2c2f805d02..13c26c15ce91d9aaf7a08ab981ac7b89fa1e6b07 100644 --- a/android/app/jni/com_android_bluetooth_avrcp_controller.cpp +++ b/android/app/jni/com_android_bluetooth_avrcp_controller.cpp @@ -55,28 +55,28 @@ static std::shared_timed_mutex sCallbacks_mutex; static void btavrcp_passthrough_response_callback( const RawAddress& /* bd_addr */, int id, int pressed) { - ALOGV("%s: id: %d, pressed: %d --- Not implemented", __func__, id, pressed); + log::verbose("id: {}, pressed: {} --- Not implemented", id, pressed); } static void btavrcp_groupnavigation_response_callback(int id, int pressed) { - ALOGV("%s: id: %d, pressed: %d --- Not implemented", __func__, id, pressed); + log::verbose("id: {}, pressed: {} --- Not implemented", id, pressed); } static void btavrcp_connection_state_callback(bool rc_connect, bool br_connect, const RawAddress& bd_addr) { - ALOGI("%s: conn state: rc: %d br: %d", __func__, rc_connect, br_connect); + log::info("conn state: rc: {} br: {}", rc_connect, br_connect); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -89,30 +89,30 @@ static void btavrcp_connection_state_callback(bool rc_connect, bool br_connect, static void btavrcp_get_rcfeatures_callback(const RawAddress& /* bd_addr */, int /* features */) { - ALOGV("%s --- Not implemented", __func__); + log::verbose("--- Not implemented"); } static void btavrcp_setplayerapplicationsetting_rsp_callback( const RawAddress& /* bd_addr */, uint8_t /* accepted */) { - ALOGV("%s --- Not implemented", __func__); + log::verbose("--- Not implemented"); } static void btavrcp_playerapplicationsetting_callback( const RawAddress& bd_addr, uint8_t num_attr, btrc_player_app_attr_t* app_attrs, uint8_t /* num_ext_attr */, btrc_player_app_ext_attr_t* /* ext_attrs */) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -125,12 +125,12 @@ static void btavrcp_playerapplicationsetting_callback( /*2 bytes for id and num */ arraylen += 2 + app_attrs[i].num_val; } - ALOGV(" arraylen %d", arraylen); + log::verbose(" arraylen {}", arraylen); ScopedLocalRef playerattribs( sCallbackEnv.get(), sCallbackEnv->NewByteArray(arraylen)); if (!playerattribs.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -152,19 +152,19 @@ static void btavrcp_playerapplicationsetting_callback( static void btavrcp_playerapplicationsetting_changed_callback( const RawAddress& bd_addr, const btrc_player_settings_t& vals) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -174,7 +174,7 @@ static void btavrcp_playerapplicationsetting_changed_callback( ScopedLocalRef playerattribs( sCallbackEnv.get(), sCallbackEnv->NewByteArray(arraylen)); if (!playerattribs.get()) { - ALOGE("Fail to new jbyteArray playerattribs "); + log::error("Fail to new jbyteArray playerattribs "); return; } /* @@ -195,19 +195,19 @@ static void btavrcp_playerapplicationsetting_changed_callback( static void btavrcp_set_abs_vol_cmd_callback(const RawAddress& bd_addr, uint8_t abs_vol, uint8_t label) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -219,19 +219,19 @@ static void btavrcp_set_abs_vol_cmd_callback(const RawAddress& bd_addr, static void btavrcp_register_notification_absvol_callback( const RawAddress& bd_addr, uint8_t label) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -249,26 +249,26 @@ static void btavrcp_track_changed_callback(const RawAddress& bd_addr, * byteArray will be formatted like this: id,len,string * Assuming text feild to be null terminated. */ - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } ScopedLocalRef attribIds(sCallbackEnv.get(), sCallbackEnv->NewIntArray(num_attr)); if (!attribIds.get()) { - ALOGE(" failed to set new array for attribIds"); + log::error(" failed to set new array for attribIds"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -279,7 +279,7 @@ static void btavrcp_track_changed_callback(const RawAddress& bd_addr, sCallbackEnv.get(), sCallbackEnv->NewObjectArray((jint)num_attr, strclazz, 0)); if (!stringArray.get()) { - ALOGE(" failed to get String array"); + log::error(" failed to get String array"); return; } @@ -288,7 +288,7 @@ static void btavrcp_track_changed_callback(const RawAddress& bd_addr, sCallbackEnv.get(), sCallbackEnv->NewStringUTF((char*)(p_attrs[i].text))); if (!str.get()) { - ALOGE("Unable to get str"); + log::error("Unable to get str"); return; } sCallbackEnv->SetIntArrayRegion(attribIds.get(), i, 1, @@ -304,19 +304,19 @@ static void btavrcp_track_changed_callback(const RawAddress& bd_addr, static void btavrcp_play_position_changed_callback(const RawAddress& bd_addr, uint32_t song_len, uint32_t song_pos) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -327,19 +327,19 @@ static void btavrcp_play_position_changed_callback(const RawAddress& bd_addr, static void btavrcp_play_status_changed_callback( const RawAddress& bd_addr, btrc_play_status_t play_status) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -355,19 +355,19 @@ static void btavrcp_get_folder_items_callback( * BTRC_ITEM_MEDIA, BTRC_ITEM_FOLDER. Here we translate them to their java * counterparts by calling the java constructor for each of the items. */ - ALOGV("%s count %d", __func__, count); + log::verbose("count {}", count); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -389,12 +389,12 @@ static void btavrcp_get_folder_items_callback( (jint)count, class_AvrcpItem, 0)); } if (!itemArray.get()) { - ALOGE("%s itemArray allocation failed.", __func__); + log::error("itemArray allocation failed."); return; } for (int i = 0; i < count; i++) { const btrc_folder_items_t* item = &(folder_items[i]); - ALOGV("%s item type %d", __func__, item->item_type); + log::verbose("item type {}", item->item_type); switch (item->item_type) { case BTRC_ITEM_MEDIA: { // Parse name @@ -402,7 +402,7 @@ static void btavrcp_get_folder_items_callback( sCallbackEnv.get(), sCallbackEnv->NewStringUTF((const char*)item->media.name)); if (!mediaName.get()) { - ALOGE("%s can't allocate media name string!", __func__); + log::error("can't allocate media name string!"); return; } // Parse UID @@ -412,7 +412,7 @@ static void btavrcp_get_folder_items_callback( sCallbackEnv.get(), sCallbackEnv->NewIntArray(item->media.num_attrs)); if (!attrIdArray.get()) { - ALOGE("%s can't allocate attr id array!", __func__); + log::error("can't allocate attr id array!"); return; } ScopedLocalRef attrValArray( @@ -421,7 +421,7 @@ static void btavrcp_get_folder_items_callback( item->media.num_attrs, sCallbackEnv->FindClass("java/lang/String"), 0)); if (!attrValArray.get()) { - ALOGE("%s can't allocate attr val array!", __func__); + log::error("can't allocate attr val array!"); return; } @@ -444,7 +444,7 @@ static void btavrcp_get_folder_items_callback( (jint)item->media.type, mediaName.get(), attrIdArray.get(), attrValArray.get())); if (!mediaObj.get()) { - ALOGE("%s failed to create AvrcpItem for type ITEM_MEDIA", __func__); + log::error("failed to create AvrcpItem for type ITEM_MEDIA"); return; } sCallbackEnv->SetObjectArrayElement(itemArray.get(), i, mediaObj.get()); @@ -457,7 +457,7 @@ static void btavrcp_get_folder_items_callback( sCallbackEnv.get(), sCallbackEnv->NewStringUTF((const char*)item->folder.name)); if (!folderName.get()) { - ALOGE("%s can't allocate folder name string!", __func__); + log::error("can't allocate folder name string!"); return; } // Parse UID @@ -470,7 +470,7 @@ static void btavrcp_get_folder_items_callback( (jint)item->folder.type, folderName.get(), (jint)item->folder.playable)); if (!folderObj.get()) { - ALOGE("%s failed to create AvrcpItem for type ITEM_FOLDER", __func__); + log::error("failed to create AvrcpItem for type ITEM_FOLDER"); return; } sCallbackEnv->SetObjectArrayElement(itemArray.get(), i, @@ -489,7 +489,7 @@ static void btavrcp_get_folder_items_callback( sCallbackEnv->NewByteArray(BTRC_FEATURE_BIT_MASK_SIZE * sizeof(uint8_t))); if (!featureBitArray.get()) { - ALOGE("%s failed to allocate featureBitArray", __func__); + log::error("failed to allocate featureBitArray"); return; } sCallbackEnv->SetByteArrayRegion( @@ -500,7 +500,7 @@ static void btavrcp_get_folder_items_callback( sCallbackEnv.get(), sCallbackEnv->NewStringUTF((const char*)item->player.name)); if (!playerName.get()) { - ALOGE("%s can't allocate player name string!", __func__); + log::error("can't allocate player name string!"); return; } ScopedLocalRef playerObj( @@ -511,7 +511,7 @@ static void btavrcp_get_folder_items_callback( playerName.get(), featureBitArray.get(), playStatus, playerType)); if (!playerObj.get()) { - ALOGE("%s failed to create AvrcpPlayer from ITEM_PLAYER", __func__); + log::error("failed to create AvrcpPlayer from ITEM_PLAYER"); return; } sCallbackEnv->SetObjectArrayElement(itemArray.get(), i, @@ -520,7 +520,7 @@ static void btavrcp_get_folder_items_callback( } default: - ALOGE("%s cannot understand type %d", __func__, item->item_type); + log::error("cannot understand type {}", item->item_type); } } @@ -535,18 +535,18 @@ static void btavrcp_get_folder_items_callback( static void btavrcp_change_path_callback(const RawAddress& bd_addr, uint32_t count) { - ALOGI("%s count %d", __func__, count); + log::info("count {}", count); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -560,18 +560,18 @@ static void btavrcp_change_path_callback(const RawAddress& bd_addr, static void btavrcp_set_browsed_player_callback(const RawAddress& bd_addr, uint8_t num_items, uint8_t depth) { - ALOGI("%s items %d depth %d", __func__, num_items, depth); + log::info("items {} depth {}", num_items, depth); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -584,18 +584,18 @@ static void btavrcp_set_browsed_player_callback(const RawAddress& bd_addr, static void btavrcp_set_addressed_player_callback(const RawAddress& bd_addr, uint8_t status) { - ALOGI("%s status %d", __func__, status); + log::info("status {}", status); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -609,18 +609,18 @@ static void btavrcp_set_addressed_player_callback(const RawAddress& bd_addr, static void btavrcp_addressed_player_changed_callback(const RawAddress& bd_addr, uint16_t id) { - ALOGI("%s status %d", __func__, id); + log::info("status {}", id); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -633,14 +633,14 @@ static void btavrcp_addressed_player_changed_callback(const RawAddress& bd_addr, static void btavrcp_now_playing_content_changed_callback( const RawAddress& bd_addr) { - ALOGI("%s", __func__); + log::info(""); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -653,19 +653,19 @@ static void btavrcp_now_playing_content_changed_callback( static void btavrcp_available_player_changed_callback ( const RawAddress& bd_addr) { - ALOGI("%s", __func__); + log::info(""); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); - return; + log::error("sCallbacksObj is null"); + return; } if (!sCallbackEnv.valid()) return; ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -677,11 +677,11 @@ static void btavrcp_available_player_changed_callback ( static void btavrcp_get_rcpsm_callback(const RawAddress& bd_addr, uint16_t psm) { - ALOGE("%s -> psm received of %d", __func__, psm); + log::error("-> psm received of {}", psm); std::shared_lock lock(sCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbacksObj) { - ALOGE("%s: sCallbacksObj is null", __func__); + log::error("sCallbacksObj is null"); return; } if (!sCallbackEnv.valid()) return; @@ -689,7 +689,7 @@ static void btavrcp_get_rcpsm_callback(const RawAddress& bd_addr, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("%s: Failed to allocate a new byte array", __func__); + log::error("Failed to allocate a new byte array"); return; } @@ -741,18 +741,18 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothAvrcpInterface != NULL) { - ALOGW("Cleaning up Avrcp Interface before initializing..."); + log::warn("Cleaning up Avrcp Interface before initializing..."); sBluetoothAvrcpInterface->cleanup(); sBluetoothAvrcpInterface = NULL; } if (sCallbacksObj != NULL) { - ALOGW("Cleaning up Avrcp callback object"); + log::warn("Cleaning up Avrcp callback object"); env->DeleteGlobalRef(sCallbacksObj); sCallbacksObj = NULL; } @@ -761,15 +761,15 @@ static void initNative(JNIEnv* env, jobject object) { (btrc_ctrl_interface_t*)btInf->get_profile_interface( BT_PROFILE_AV_RC_CTRL_ID); if (sBluetoothAvrcpInterface == NULL) { - ALOGE("Failed to get Bluetooth Avrcp Controller Interface"); + log::error("Failed to get Bluetooth Avrcp Controller Interface"); return; } bt_status_t status = sBluetoothAvrcpInterface->init(&sBluetoothAvrcpCallbacks); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to initialize Bluetooth Avrcp Controller, status: %d", - status); + log::error("Failed to initialize Bluetooth Avrcp Controller, status: {}", + bt_status_text(status)); sBluetoothAvrcpInterface = NULL; return; } @@ -782,7 +782,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } @@ -802,9 +802,9 @@ static jboolean sendPassThroughCommandNative(JNIEnv* env, jobject /* object */, jint key_state) { if (!sBluetoothAvrcpInterface) return JNI_FALSE; - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); - ALOGI("key_code: %d, key_state: %d", key_code, key_state); + log::info("key_code: {}, key_state: {}", key_code, key_state); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { @@ -817,7 +817,8 @@ static jboolean sendPassThroughCommandNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothAvrcpInterface->send_pass_through_cmd( rawAddress, (uint8_t)key_code, (uint8_t)key_state); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending passthru command, status: %d", status); + log::error("Failed sending passthru command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -831,9 +832,9 @@ static jboolean sendGroupNavigationCommandNative(JNIEnv* env, jint key_state) { if (!sBluetoothAvrcpInterface) return JNI_FALSE; - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); - ALOGI("key_code: %d, key_state: %d", key_code, key_state); + log::info("key_code: {}, key_state: {}", key_code, key_state); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { @@ -846,7 +847,8 @@ static jboolean sendGroupNavigationCommandNative(JNIEnv* env, bt_status_t status = sBluetoothAvrcpInterface->send_group_navigation_cmd( rawAddress, (uint8_t)key_code, (uint8_t)key_state); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending Grp Navigation command, status: %d", status); + log::error("Failed sending Grp Navigation command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -856,7 +858,7 @@ static jboolean sendGroupNavigationCommandNative(JNIEnv* env, static void setPlayerApplicationSettingValuesNative( JNIEnv* env, jobject /* object */, jbyteArray address, jbyte num_attrib, jbyteArray attrib_ids, jbyteArray attrib_val) { - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); if (!sBluetoothAvrcpInterface) return; jbyte* addr = env->GetByteArrayElements(address, NULL); @@ -869,7 +871,8 @@ static void setPlayerApplicationSettingValuesNative( uint8_t* pAttrsVal = new uint8_t[num_attrib]; if ((!pAttrs) || (!pAttrsVal)) { delete[] pAttrs; - ALOGE("setPlayerApplicationSettingValuesNative: not have enough memeory"); + log::error( + "setPlayerApplicationSettingValuesNative: not have enough memory"); return; } @@ -893,7 +896,8 @@ static void setPlayerApplicationSettingValuesNative( bt_status_t status = sBluetoothAvrcpInterface->set_player_app_setting_cmd( rawAddress, (uint8_t)num_attrib, pAttrs, pAttrsVal); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending setPlAppSettValNative command, status: %d", status); + log::error("Failed sending setPlAppSettValNative command, status: {}", + bt_status_text(status)); } delete[] pAttrs; delete[] pAttrsVal; @@ -912,14 +916,15 @@ static void sendAbsVolRspNative(JNIEnv* env, jobject /* object */, return; } - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothAvrcpInterface->set_volume_rsp( rawAddress, (uint8_t)abs_vol, (uint8_t)label); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending sendAbsVolRspNative command, status: %d", status); + log::error("Failed sending sendAbsVolRspNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -934,7 +939,7 @@ static void sendRegisterAbsVolRspNative(JNIEnv* env, jobject /* object */, jniThrowIOException(env, EINVAL); return; } - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); @@ -942,8 +947,8 @@ static void sendRegisterAbsVolRspNative(JNIEnv* env, jobject /* object */, rawAddress, (btrc_notification_type_t)rsp_type, (uint8_t)abs_vol, (uint8_t)label); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending sendRegisterAbsVolRspNative command, status: %d", - status); + log::error("Failed sending sendRegisterAbsVolRspNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -957,14 +962,16 @@ static void getCurrentMetadataNative(JNIEnv* env, jobject /* object */, jniThrowIOException(env, EINVAL); return; } - ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::verbose("sBluetoothAvrcpInterface: {}", + fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothAvrcpInterface->get_current_metadata_cmd(rawAddress); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending getCurrentMetadataNative command, status: %d", status); + log::error("Failed sending getCurrentMetadataNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -978,14 +985,16 @@ static void getPlaybackStateNative(JNIEnv* env, jobject /* object */, jniThrowIOException(env, EINVAL); return; } - ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::verbose("sBluetoothAvrcpInterface: {}", + fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothAvrcpInterface->get_playback_state_cmd(rawAddress); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending getPlaybackStateNative command, status: %d", status); + log::error("Failed sending getPlaybackStateNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -998,14 +1007,16 @@ static void getNowPlayingListNative(JNIEnv* env, jobject /* object */, jniThrowIOException(env, EINVAL); return; } - ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::verbose("sBluetoothAvrcpInterface: {}", + fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothAvrcpInterface->get_now_playing_list_cmd( rawAddress, start, end); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending getNowPlayingListNative command, status: %d", status); + log::error("Failed sending getNowPlayingListNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -1018,14 +1029,16 @@ static void getFolderListNative(JNIEnv* env, jobject /* object */, jniThrowIOException(env, EINVAL); return; } - ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::verbose("sBluetoothAvrcpInterface: {}", + fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothAvrcpInterface->get_folder_list_cmd(rawAddress, start, end); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending getFolderListNative command, status: %d", status); + log::error("Failed sending getFolderListNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -1038,14 +1051,15 @@ static void getPlayerListNative(JNIEnv* env, jobject /* object */, jniThrowIOException(env, EINVAL); return; } - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothAvrcpInterface->get_player_list_cmd(rawAddress, start, end); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending getPlayerListNative command, status: %d", status); + log::error("Failed sending getPlayerListNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -1066,14 +1080,15 @@ static void changeFolderPathNative(JNIEnv* env, jobject /* object */, // return; //} - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); bt_status_t status = sBluetoothAvrcpInterface->change_folder_path_cmd( rawAddress, (uint8_t)direction, (uint8_t*)&uid); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending changeFolderPathNative command, status: %d", status); + log::error("Failed sending changeFolderPathNative command, status: {}", + bt_status_text(status)); } // env->ReleaseByteArrayElements(address, addr, 0); } @@ -1089,11 +1104,12 @@ static void setBrowsedPlayerNative(JNIEnv* env, jobject /* object */, RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); bt_status_t status = sBluetoothAvrcpInterface->set_browsed_player_cmd( rawAddress, (uint16_t)id); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending setBrowsedPlayerNative command, status: %d", status); + log::error("Failed sending setBrowsedPlayerNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -1109,12 +1125,12 @@ static void setAddressedPlayerNative(JNIEnv* env, jobject /* object */, RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); bt_status_t status = sBluetoothAvrcpInterface->set_addressed_player_cmd( rawAddress, (uint16_t)id); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending setAddressedPlayerNative command, status: %d", - status); + log::error("Failed sending setAddressedPlayerNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } @@ -1137,11 +1153,12 @@ static void playItemNative(JNIEnv* env, jobject /* object */, RawAddress rawAddress; rawAddress.FromOctets((uint8_t*)addr); - ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface); + log::info("sBluetoothAvrcpInterface: {}", fmt::ptr(sBluetoothAvrcpInterface)); bt_status_t status = sBluetoothAvrcpInterface->play_item_cmd( rawAddress, (uint8_t)scope, (uint8_t*)&uid, (uint16_t)uidCounter); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending playItemNative command, status: %d", status); + log::error("Failed sending playItemNative command, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); } diff --git a/android/app/jni/com_android_bluetooth_avrcp_target.cpp b/android/app/jni/com_android_bluetooth_avrcp_target.cpp index a5e4949de33a5aaaa1750307fa01833c0d0f1ae3..1e9678cdffe8e53c59699d9e02f739be8c2b10fe 100644 --- a/android/app/jni/com_android_bluetooth_avrcp_target.cpp +++ b/android/app/jni/com_android_bluetooth_avrcp_target.cpp @@ -233,7 +233,7 @@ static jmethodID method_getPlayerSettings; static jmethodID method_setPlayerSettings; static void initNative(JNIEnv* env, jobject object) { - ALOGD("%s", __func__); + log::debug(""); std::unique_lock interface_lock(interface_mutex); std::unique_lock callbacks_lock(callbacks_mutex); mJavaInterface = env->NewGlobalRef(object); @@ -245,20 +245,20 @@ static void initNative(JNIEnv* env, jobject object) { static void registerBipServerNative(JNIEnv* /* env */, jobject /* object */, jint l2cap_psm) { - ALOGD("%s: l2cap_psm=%d", __func__, (int)l2cap_psm); + log::debug("l2cap_psm={}", (int)l2cap_psm); std::unique_lock interface_lock(interface_mutex); if (sServiceInterface == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return; } sServiceInterface->RegisterBipServer((int)l2cap_psm); } static void unregisterBipServerNative(JNIEnv* /* env */, jobject /* object */) { - ALOGD("%s", __func__); + log::debug(""); std::unique_lock interface_lock(interface_mutex); if (sServiceInterface == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return; } sServiceInterface->UnregisterBipServer(); @@ -267,10 +267,10 @@ static void unregisterBipServerNative(JNIEnv* /* env */, jobject /* object */) { static void sendMediaUpdateNative(JNIEnv* /* env */, jobject /* object */, jboolean metadata, jboolean state, jboolean queue) { - ALOGD("%s", __func__); + log::debug(""); std::unique_lock interface_lock(interface_mutex); if (mServiceCallbacks == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return; } @@ -281,10 +281,10 @@ static void sendMediaUpdateNative(JNIEnv* /* env */, jobject /* object */, static void sendFolderUpdateNative(JNIEnv* /* env */, jobject /* object */, jboolean available_players, jboolean addressed_player, jboolean uids) { - ALOGD("%s", __func__); + log::debug(""); std::unique_lock interface_lock(interface_mutex); if (mServiceCallbacks == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return; } @@ -309,10 +309,10 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { jboolean connectDeviceNative(JNIEnv* env, jobject /* object */, jstring address) { - ALOGD("%s", __func__); + log::debug(""); std::unique_lock interface_lock(interface_mutex); if (mServiceCallbacks == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return JNI_FALSE; } @@ -329,10 +329,10 @@ jboolean connectDeviceNative(JNIEnv* env, jobject /* object */, jboolean disconnectDeviceNative(JNIEnv* env, jobject /* object */, jstring address) { - ALOGD("%s", __func__); + log::debug(""); std::unique_lock interface_lock(interface_mutex); if (mServiceCallbacks == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return JNI_FALSE; } @@ -348,7 +348,7 @@ jboolean disconnectDeviceNative(JNIEnv* env, jobject /* object */, } static void sendMediaKeyEvent(int key, KeyState state) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -519,7 +519,7 @@ static FolderInfo getFolderInfoFromJavaObj(JNIEnv* env, jobject folder) { } static SongInfo getSongInfo() { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return SongInfo(); @@ -532,7 +532,7 @@ static SongInfo getSongInfo() { } static PlayStatus getCurrentPlayStatus() { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return PlayStatus(); @@ -542,7 +542,7 @@ static PlayStatus getCurrentPlayStatus() { sCallbackEnv->CallObjectMethod(mJavaInterface, method_getPlaybackStatus); if (playStatus == nullptr) { - ALOGE("%s: Got a null play status", __func__); + log::error("Got a null play status"); return status; } @@ -564,7 +564,7 @@ static PlayStatus getCurrentPlayStatus() { } static std::string getCurrentMediaId() { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return ""; @@ -572,7 +572,7 @@ static std::string getCurrentMediaId() { jstring media_id = (jstring)sCallbackEnv->CallObjectMethod( mJavaInterface, method_getCurrentMediaId); if (media_id == nullptr) { - ALOGE("%s: Got a null media ID", __func__); + log::error("Got a null media ID"); return ""; } @@ -584,7 +584,7 @@ static std::string getCurrentMediaId() { } static std::vector getNowPlayingList() { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return std::vector(); @@ -592,7 +592,7 @@ static std::vector getNowPlayingList() { jobject song_list = sCallbackEnv->CallObjectMethod(mJavaInterface, method_getNowPlayingList); if (song_list == nullptr) { - ALOGE("%s: Got a null now playing list", __func__); + log::error("Got a null now playing list"); return std::vector(); } @@ -619,7 +619,7 @@ static std::vector getNowPlayingList() { } static uint16_t getCurrentPlayerId() { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return 0u; @@ -631,7 +631,7 @@ static uint16_t getCurrentPlayerId() { } static std::vector getMediaPlayerList() { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) @@ -641,7 +641,7 @@ static std::vector getMediaPlayerList() { mJavaInterface, method_getMediaPlayerList); if (player_list == nullptr) { - ALOGE("%s: Got a null media player list", __func__); + log::error("Got a null media player list"); return std::vector(); } @@ -697,7 +697,7 @@ static std::vector getMediaPlayerList() { } static void setBrowsedPlayer(uint16_t player_id, SetBrowsedPlayerCb cb) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -711,7 +711,7 @@ static void setBrowsedPlayerResponseNative(JNIEnv* env, jobject /* object */, jint /* player_id */, jboolean success, jstring root_id, jint num_items) { - ALOGD("%s", __func__); + log::debug(""); std::string root; if (root_id != nullptr) { @@ -725,7 +725,7 @@ static void setBrowsedPlayerResponseNative(JNIEnv* env, jobject /* object */, static void getFolderItemsResponseNative(JNIEnv* env, jobject /* object */, jstring parent_id, jobject list) { - ALOGD("%s", __func__); + log::debug(""); std::string id; if (parent_id != nullptr) { @@ -739,8 +739,8 @@ static void getFolderItemsResponseNative(JNIEnv* env, jobject /* object */, // that both callbacks can be handled with one lookup if a request comes // for a folder that is already trying to be looked at. if (get_folder_items_cb_map.find(id) == get_folder_items_cb_map.end()) { - ALOGE("Could not find response callback for the request of \"%s\"", - id.c_str()); + log::error("Could not find response callback for the request of \"{}\"", + id); return; } @@ -748,7 +748,7 @@ static void getFolderItemsResponseNative(JNIEnv* env, jobject /* object */, get_folder_items_cb_map.erase(id); if (list == nullptr) { - ALOGE("%s: Got a null get folder items response list", __func__); + log::error("Got a null get folder items response list"); callback.Run(std::vector()); return; } @@ -802,7 +802,7 @@ static void getFolderItemsResponseNative(JNIEnv* env, jobject /* object */, static void getFolderItems(uint16_t player_id, std::string media_id, GetFolderItemsCb cb) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -818,7 +818,7 @@ static void getFolderItems(uint16_t player_id, std::string media_id, static void playItem(uint16_t player_id, bool now_playing, std::string media_id) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -829,7 +829,7 @@ static void playItem(uint16_t player_id, bool now_playing, } static void setActiveDevice(const RawAddress& address) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -840,7 +840,7 @@ static void setActiveDevice(const RawAddress& address) { } static void volumeDeviceConnected(const RawAddress& address) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -853,7 +853,7 @@ static void volumeDeviceConnected(const RawAddress& address) { static void volumeDeviceConnected( const RawAddress& address, ::bluetooth::avrcp::VolumeInterface::VolumeChangedCb cb) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -866,7 +866,7 @@ static void volumeDeviceConnected( } static void volumeDeviceDisconnected(const RawAddress& address) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -887,14 +887,14 @@ static void sendVolumeChangedNative(JNIEnv* env, jobject /* object */, if (!success) return; - ALOGD("%s", __func__); + log::debug(""); if (volumeCallbackMap.find(bdaddr) != volumeCallbackMap.end()) { volumeCallbackMap.find(bdaddr)->second.Run(volume & 0x7F); } } static void setVolume(int8_t volume) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -906,7 +906,7 @@ static void setBipClientStatusNative(JNIEnv* env, jobject /* object */, jstring address, jboolean connected) { std::unique_lock interface_lock(interface_mutex); if (mServiceCallbacks == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return; } @@ -923,7 +923,7 @@ static void setBipClientStatusNative(JNIEnv* env, jobject /* object */, // Called from native to list available player settings static void listPlayerSettings(ListPlayerSettingsCb cb) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -934,7 +934,7 @@ static void listPlayerSettings(ListPlayerSettingsCb cb) { static void listPlayerSettingsResponseNative(JNIEnv* env, jobject /* object */, jbyteArray attributes) { - ALOGD("%s", __func__); + log::debug(""); std::vector attributes_vector; copyJavaArraytoCppVector(env, attributes, attributes_vector); @@ -945,7 +945,7 @@ static void listPlayerSettingsResponseNative(JNIEnv* env, jobject /* object */, // Called from native to list available values for player setting static void listPlayerSettingValues(PlayerAttribute attribute, ListPlayerSettingValuesCb cb) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -959,7 +959,7 @@ static void listPlayerSettingValuesResponseNative(JNIEnv* env, jobject /* object */, jbyte attribute, jbyteArray values) { - ALOGD("%s", __func__); + log::debug(""); PlayerAttribute player_attribute = static_cast(attribute); std::vector values_vector; copyJavaArraytoCppVector(env, values, values_vector); @@ -969,7 +969,7 @@ static void listPlayerSettingValuesResponseNative(JNIEnv* env, // Called from native to get current player settings static void getPlayerSettings(std::vector attributes, GetCurrentPlayerSettingValueCb cb) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -987,7 +987,7 @@ static void getPlayerSettings(std::vector attributes, static void getPlayerSettingsResponseNative(JNIEnv* env, jobject /* object */, jbyteArray attributes, jbyteArray values) { - ALOGD("%s", __func__); + log::debug(""); std::vector attributes_vector; std::vector values_vector; copyJavaArraytoCppVector(env, attributes, attributes_vector); @@ -1000,7 +1000,7 @@ static void getPlayerSettingsResponseNative(JNIEnv* env, jobject /* object */, static void setPlayerSettings(std::vector attributes, std::vector values, SetPlayerSettingValueCb cb) { - ALOGD("%s", __func__); + log::debug(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || !mJavaInterface) return; @@ -1024,16 +1024,16 @@ static void setPlayerSettings(std::vector attributes, static void setPlayerSettingsResponseNative(JNIEnv* /* env */, jobject /* object */, jboolean success) { - ALOGD("%s", __func__); + log::debug(""); set_player_setting_value_cb.Run(success); } static void sendPlayerSettingsNative(JNIEnv* env, jobject /* object */, jbyteArray attributes, jbyteArray values) { - ALOGD("%s", __func__); + log::debug(""); std::unique_lock interface_lock(interface_mutex); if (mServiceCallbacks == nullptr) { - ALOGW("%s: Service not loaded.", __func__); + log::warn("Service not loaded."); return; } std::vector attributes_vector; diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp index e3b197afc2bb2552b4ab348da5fc9959290a86de..6b10df82a7e0dcd74b8aa37a92510bacad1ca6cc 100644 --- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp @@ -16,6 +16,7 @@ */ #define LOG_TAG "BluetoothServiceJni" + #include #include #include @@ -30,7 +31,7 @@ #include "com_android_bluetooth.h" #include "hardware/bt_sock.h" -#include "os/logging/log_redaction.h" +#include "os/logging/log_adapter.h" #include "utils/Log.h" #include "utils/misc.h" @@ -39,6 +40,14 @@ using bluetooth::Uuid; extern bt_interface_t bluetoothInterface; #endif +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter { +}; +} // namespace fmt + namespace android { // Both @@ -69,6 +78,7 @@ static jmethodID method_switchCodecCallback; static jmethodID method_acquireWakeLock; static jmethodID method_releaseWakeLock; static jmethodID method_energyInfo; +static jmethodID method_keyMissingCallback; static struct { jclass clazz; @@ -98,13 +108,13 @@ bool isCallbackThread() { static void adapter_state_change_callback(bt_state_t status) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; - ALOGV("%s: Status is: %d", __func__, status); + log::verbose("Status is: {}", status); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status); @@ -116,7 +126,7 @@ static int get_properties(int num_properties, bt_property_t* properties, ScopedLocalRef propVal( callbackEnv, callbackEnv->NewByteArray(properties[i].len)); if (!propVal.get()) { - ALOGE("Error while allocation of array in %s", __func__); + log::error("Error while allocation of array"); return -1; } @@ -132,17 +142,18 @@ static void adapter_properties_callback(bt_status_t status, int num_properties, bt_property_t* properties) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; - ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); + log::verbose("Status is: {}, Properties: {}", bt_status_text(status), + num_properties); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Status %d is incorrect", __func__, status); + log::error("Status {} is incorrect", bt_status_text(status)); return; } @@ -150,7 +161,7 @@ static void adapter_properties_callback(bt_status_t status, int num_properties, sCallbackEnv.get(), (jbyteArray)sCallbackEnv->NewByteArray(num_properties)); if (!val.get()) { - ALOGE("%s: Error allocating byteArray", __func__); + log::error("Error allocating byteArray"); return; } @@ -164,14 +175,14 @@ static void adapter_properties_callback(bt_status_t status, int num_properties, sCallbackEnv.get(), sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL)); if (!props.get()) { - ALOGE("%s: Error allocating object Array for properties", __func__); + log::error("Error allocating object Array for properties"); return; } ScopedLocalRef types( sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties)); if (!types.get()) { - ALOGE("%s: Error allocating int Array for values", __func__); + log::error("Error allocating int Array for values"); return; } @@ -192,17 +203,18 @@ static void remote_device_properties_callback(bt_status_t status, bt_property_t* properties) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; - ALOGV("%s: Status is: %d, Properties: %d", __func__, status, num_properties); + log::verbose("Status is: {}, Properties: {}", bt_status_text(status), + num_properties); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Status %d is incorrect", __func__, status); + log::error("Status {} is incorrect", bt_status_text(status)); return; } @@ -210,7 +222,7 @@ static void remote_device_properties_callback(bt_status_t status, sCallbackEnv.get(), (jbyteArray)sCallbackEnv->NewByteArray(num_properties)); if (!val.get()) { - ALOGE("%s: Error allocating byteArray", __func__); + log::error("Error allocating byteArray"); return; } @@ -224,21 +236,21 @@ static void remote_device_properties_callback(bt_status_t status, sCallbackEnv.get(), sCallbackEnv->NewObjectArray(num_properties, mclass.get(), NULL)); if (!props.get()) { - ALOGE("%s: Error allocating object Array for properties", __func__); + log::error("Error allocating object Array for properties"); return; } ScopedLocalRef types( sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_properties)); if (!types.get()) { - ALOGE("%s: Error allocating int Array for values", __func__); + log::error("Error allocating int Array for values"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Error while allocation byte array in %s", __func__); + log::error("Error while allocation byte array"); return; } @@ -260,7 +272,7 @@ static void device_found_callback(int num_properties, bt_property_t* properties) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -273,7 +285,7 @@ static void device_found_callback(int num_properties, if (properties[i].type == BT_PROPERTY_BDADDR) { addr.reset(sCallbackEnv->NewByteArray(properties[i].len)); if (!addr.get()) { - ALOGE("Address is NULL (unable to allocate) in %s", __func__); + log::error("Address is NULL (unable to allocate)"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, properties[i].len, @@ -282,12 +294,13 @@ static void device_found_callback(int num_properties, } } if (!addr.get()) { - ALOGE("Address is NULL in %s", __func__); + log::error("Address is NULL"); return; } - ALOGV("%s: Properties: %d, Address: %s", __func__, num_properties, - (const char*)properties[addr_index].val); + log::verbose( + "Properties: {}, Address: {}", num_properties, + ADDRESS_TO_LOGGABLE_STR(*(RawAddress*)properties[addr_index].val)); remote_device_properties_callback(BT_STATUS_SUCCESS, (RawAddress*)properties[addr_index].val, @@ -302,7 +315,7 @@ static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr, int fail_reason) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -310,14 +323,14 @@ static void bond_state_changed_callback(bt_status_t status, RawAddress* bd_addr, if (!sCallbackEnv.valid()) return; if (!bd_addr) { - ALOGE("Address is null in %s", __func__); + log::error("Address is null"); return; } ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Address allocation failed in %s", __func__); + log::error("Address allocation failed"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -332,7 +345,7 @@ static void address_consolidate_callback(RawAddress* main_bd_addr, RawAddress* secondary_bd_addr) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -341,7 +354,7 @@ static void address_consolidate_callback(RawAddress* main_bd_addr, ScopedLocalRef main_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!main_addr.get()) { - ALOGE("Address allocation failed in %s", __func__); + log::error("Address allocation failed"); return; } sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress), @@ -350,7 +363,7 @@ static void address_consolidate_callback(RawAddress* main_bd_addr, ScopedLocalRef secondary_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!secondary_addr.get()) { - ALOGE("Address allocation failed in %s", __func__); + log::error("Address allocation failed"); return; } @@ -366,7 +379,7 @@ static void le_address_associate_callback(RawAddress* main_bd_addr, RawAddress* secondary_bd_addr) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -375,7 +388,7 @@ static void le_address_associate_callback(RawAddress* main_bd_addr, ScopedLocalRef main_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!main_addr.get()) { - ALOGE("Address allocation failed in %s", __func__); + log::error("Address allocation failed"); return; } sCallbackEnv->SetByteArrayRegion(main_addr.get(), 0, sizeof(RawAddress), @@ -384,7 +397,7 @@ static void le_address_associate_callback(RawAddress* main_bd_addr, ScopedLocalRef secondary_addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!secondary_addr.get()) { - ALOGE("Address allocation failed in %s", __func__); + log::error("Address allocation failed"); return; } @@ -403,13 +416,13 @@ static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, bt_conn_direction_t /* direction */, uint16_t acl_handle) { if (!bd_addr) { - ALOGE("Address is null in %s", __func__); + log::error("Address is null"); return; } std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -419,7 +432,7 @@ static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Address allocation failed in %s", __func__); + log::error("Address allocation failed"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -434,14 +447,14 @@ static void acl_state_changed_callback(bt_status_t status, RawAddress* bd_addr, static void discovery_state_changed_callback(bt_discovery_state_t state) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; - ALOGV("%s: DiscoveryState:%d ", __func__, state); + log::verbose("DiscoveryState:{} ", state); sCallbackEnv->CallVoidMethod( sJniCallbacksObj, method_discoveryStateChangeCallback, (jint)state); @@ -450,13 +463,13 @@ static void discovery_state_changed_callback(bt_discovery_state_t state) { static void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, uint32_t cod, bool min_16_digits) { if (!bd_addr) { - ALOGE("Address is null in %s", __func__); + log::error("Address is null"); return; } std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -466,7 +479,7 @@ static void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Error while allocating in: %s", __func__); + log::error("Error while allocating"); return; } @@ -476,7 +489,7 @@ static void pin_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, ScopedLocalRef devname( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t))); if (!devname.get()) { - ALOGE("Error while allocating in: %s", __func__); + log::error("Error while allocating"); return; } @@ -491,13 +504,13 @@ static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, uint32_t cod, bt_ssp_variant_t pairing_variant, uint32_t pass_key) { if (!bd_addr) { - ALOGE("Address is null in %s", __func__); + log::error("Address is null"); return; } std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -507,7 +520,7 @@ static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Error while allocating in: %s", __func__); + log::error("Error while allocating"); return; } @@ -517,7 +530,7 @@ static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, ScopedLocalRef devname( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdname_t))); if (!devname.get()) { - ALOGE("Error while allocating in: %s", __func__); + log::error("Error while allocating"); return; } @@ -530,7 +543,7 @@ static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname, } static jobject createClassicOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) { - ALOGV("%s", __func__); + log::verbose(""); jmethodID classicBuilderConstructor; jmethodID setRMethod; jmethodID setNameMethod; @@ -594,7 +607,7 @@ static jobject createClassicOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) { } static jobject createLeOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) { - ALOGV("%s", __func__); + log::verbose(""); jmethodID leBuilderConstructor; jmethodID setRMethod; @@ -655,11 +668,11 @@ static jobject createLeOobDataObject(JNIEnv* env, bt_oob_data_t oob_data) { static void generate_local_oob_data_callback(tBT_TRANSPORT transport, bt_oob_data_t oob_data) { - ALOGV("%s", __func__); + log::verbose(""); std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -682,7 +695,7 @@ static void generate_local_oob_data_callback(tBT_TRANSPORT transport, // TRANSPORT_AUTO is a concept, however, the host stack doesn't fully // implement it So passing it from the java layer is currently useless until // the implementation and concept of TRANSPORT_AUTO is fleshed out. - ALOGE("TRANSPORT: %d not implemented", transport); + log::error("TRANSPORT: {} not implemented", transport); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_oobDataReceivedCallback, (jint)transport, nullptr); @@ -695,16 +708,16 @@ static void link_quality_report_callback( int negative_acknowledgement_count) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; - ALOGV("%s: LinkQualityReportCallback: %d %d %d %d %d %d", __func__, - report_id, rssi, snr, retransmission_count, packets_not_receive_count, - negative_acknowledgement_count); + log::verbose("LinkQualityReportCallback: {} {} {} {} {} {}", report_id, rssi, + snr, retransmission_count, packets_not_receive_count, + negative_acknowledgement_count); sCallbackEnv->CallVoidMethod( sJniCallbacksObj, method_linkQualityReportCallback, @@ -716,15 +729,15 @@ static void link_quality_report_callback( static void switch_buffer_size_callback(bool is_low_latency_buffer_size) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; - ALOGV("%s: SwitchBufferSizeCallback: %s", __func__, - is_low_latency_buffer_size ? "true" : "false"); + log::verbose("SwitchBufferSizeCallback: {}", + is_low_latency_buffer_size ? "true" : "false"); sCallbackEnv->CallVoidMethod( sJniCallbacksObj, method_switchBufferSizeCallback, @@ -734,15 +747,15 @@ static void switch_buffer_size_callback(bool is_low_latency_buffer_size) { static void switch_codec_callback(bool is_low_latency_buffer_size) { std::shared_lock lock(jniObjMutex); if (!sJniCallbacksObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; - ALOGV("%s: SwitchCodecCallback: %s", __func__, - is_low_latency_buffer_size ? "true" : "false"); + log::verbose("SwitchCodecCallback: {}", + is_low_latency_buffer_size ? "true" : "false"); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_switchCodecCallback, (jboolean)is_low_latency_buffer_size); @@ -752,6 +765,29 @@ static void le_rand_callback(uint64_t /* random */) { // Android doesn't support the LeRand API. } +static void key_missing_callback(const RawAddress bd_addr) { + std::shared_lock lock(jniObjMutex); + if (!sJniCallbacksObj) { + log::error("JNI obj is null. Failed to call JNI callback"); + return; + } + + CallbackEnv sCallbackEnv(__func__); + if (!sCallbackEnv.valid()) return; + + ScopedLocalRef addr( + sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); + if (!addr.get()) { + log::error("Address allocation failed"); + return; + } + sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), + (jbyte*)&bd_addr); + + sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_keyMissingCallback, + addr.get()); +} + static void callback_thread_event(bt_cb_thread_evt event) { if (event == ASSOCIATE_JVM) { JavaVMAttachArgs args; @@ -762,10 +798,10 @@ static void callback_thread_event(bt_cb_thread_evt event) { vm->AttachCurrentThread(&callbackEnv, &args); sHaveCallbackThread = true; sCallbackThread = pthread_self(); - ALOGV("Callback thread attached: %p", callbackEnv); + log::verbose("Callback thread attached: {}", fmt::ptr(callbackEnv)); } else if (event == DISASSOCIATE_JVM) { if (!isCallbackThread()) { - ALOGE("Callback: '%s' is not called on the correct thread", __func__); + log::error("Callback: '' is not called on the correct thread"); return; } vm->DetachCurrentThread(); @@ -779,14 +815,15 @@ static void dut_mode_recv_callback(uint16_t /* opcode */, uint8_t* /* buf */, static void le_test_mode_recv_callback(bt_status_t status, uint16_t packet_count) { - ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count); + log::verbose("status:{} packet_count:{} ", bt_status_text(status), + packet_count); } static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info, bt_uid_traffic_t* uid_data) { std::shared_lock lock(jniObjMutex); if (!sJniAdapterServiceObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return; } @@ -838,7 +875,8 @@ static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks), generate_local_oob_data_callback, switch_buffer_size_callback, switch_codec_callback, - le_rand_callback}; + le_rand_callback, + key_missing_callback}; class JNIThreadAttacher { public: @@ -846,9 +884,9 @@ class JNIThreadAttacher { status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6); if (status_ != JNI_OK && status_ != JNI_EDETACHED) { - ALOGE( - "JNIThreadAttacher: unable to get environment for JNI CALL, " - "status: %d", + log::error( + "JNIThreadAttacher: unable to get environment for JNI CALL, status: " + "{}", status_); env_ = nullptr; return; @@ -857,8 +895,8 @@ class JNIThreadAttacher { if (status_ == JNI_EDETACHED) { char name[17] = {0}; if (prctl(PR_GET_NAME, (unsigned long)name) != 0) { - ALOGE( - "JNIThreadAttacher: unable to grab previous thread name, error: %s", + log::error( + "JNIThreadAttacher: unable to grab previous thread name, error: {}", strerror(errno)); env_ = nullptr; return; @@ -867,7 +905,7 @@ class JNIThreadAttacher { JavaVMAttachArgs args = { .version = JNI_VERSION_1_6, .name = name, .group = nullptr}; if (vm_->AttachCurrentThread(&env_, &args) != 0) { - ALOGE("JNIThreadAttacher: unable to attach thread to VM"); + log::error("JNIThreadAttacher: unable to attach thread to VM"); env_ = nullptr; return; } @@ -889,7 +927,7 @@ class JNIThreadAttacher { static int acquire_wake_lock_callout(const char* lock_name) { std::shared_lock lock(jniObjMutex); if (!sJniAdapterServiceObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return BT_STATUS_NOT_READY; } @@ -897,7 +935,7 @@ static int acquire_wake_lock_callout(const char* lock_name) { JNIEnv* env = attacher.getEnv(); if (env == nullptr) { - ALOGE("%s: Unable to get JNI Env", __func__); + log::error("Unable to get JNI Env"); return BT_STATUS_JNI_THREAD_ATTACH_ERROR; } @@ -909,7 +947,7 @@ static int acquire_wake_lock_callout(const char* lock_name) { sJniCallbacksObj, method_acquireWakeLock, lock_name_jni.get()); if (!acquired) ret = BT_STATUS_WAKELOCK_ERROR; } else { - ALOGE("%s unable to allocate string: %s", __func__, lock_name); + log::error("unable to allocate string: {}", lock_name); ret = BT_STATUS_NOMEM; } } @@ -920,7 +958,7 @@ static int acquire_wake_lock_callout(const char* lock_name) { static int release_wake_lock_callout(const char* lock_name) { std::shared_lock lock(jniObjMutex); if (!sJniAdapterServiceObj) { - ALOGE("%s, JNI obj is null. Failed to call JNI callback", __func__); + log::error("JNI obj is null. Failed to call JNI callback"); return BT_STATUS_NOT_READY; } @@ -928,7 +966,7 @@ static int release_wake_lock_callout(const char* lock_name) { JNIEnv* env = attacher.getEnv(); if (env == nullptr) { - ALOGE("%s: Unable to get JNI Env", __func__); + log::error("Unable to get JNI Env"); return BT_STATUS_JNI_THREAD_ATTACH_ERROR; } @@ -940,7 +978,7 @@ static int release_wake_lock_callout(const char* lock_name) { sJniCallbacksObj, method_releaseWakeLock, lock_name_jni.get()); if (!released) ret = BT_STATUS_WAKELOCK_ERROR; } else { - ALOGE("%s unable to allocate string: %s", __func__, lock_name); + log::error("unable to allocate string: {}", lock_name); ret = BT_STATUS_NOMEM; } } @@ -966,20 +1004,20 @@ int hal_util_load_bt_library(const bt_interface_t** interface) { void* handle = dlopen("libbluetooth.so", RTLD_NOW); if (!handle) { const char* err_str = dlerror(); - ALOGE("%s: failed to load Bluetooth library, error=%s", __func__, - err_str ? err_str : "error unknown"); + log::error("failed to load Bluetooth library, error={}", + err_str ? err_str : "error unknown"); goto error; } // Get the address of the bt_interface_t. itf = (bt_interface_t*)dlsym(handle, sym); if (!itf) { - ALOGE("%s: failed to load symbol from Bluetooth library %s", __func__, sym); + log::error("failed to load symbol from Bluetooth library {}", sym); goto error; } // Success. - ALOGI("%s: loaded Bluetooth library successfully", __func__); + log::info("loaded Bluetooth library successfully"); *interface = itf; return 0; @@ -997,7 +1035,7 @@ static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest, jstring userDataDirectory) { std::unique_lock lock(jniObjMutex); - ALOGV("%s", __func__); + log::verbose(""); android_bluetooth_UidTraffic.clazz = (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic")); @@ -1041,13 +1079,13 @@ static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest, delete[] flagObjs; if (ret != BT_STATUS_SUCCESS) { - ALOGE("Error while setting the callbacks: %d\n", ret); + log::error("Error while setting the callbacks: {}", ret); sBluetoothInterface = NULL; return JNI_FALSE; } ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts); if (ret != BT_STATUS_SUCCESS) { - ALOGE("Error while setting Bluetooth callouts: %d\n", ret); + log::error("Error while setting Bluetooth callouts: {}", ret); sBluetoothInterface->cleanup(); sBluetoothInterface = NULL; return JNI_FALSE; @@ -1057,7 +1095,7 @@ static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest, (btsock_interface_t*)sBluetoothInterface->get_profile_interface( BT_PROFILE_SOCKETS_ID); if (sBluetoothSocketInterface == NULL) { - ALOGE("Error getting socket interface"); + log::error("Error getting socket interface"); } return JNI_TRUE; @@ -1066,12 +1104,12 @@ static bool initNative(JNIEnv* env, jobject obj, jboolean isGuest, static bool cleanupNative(JNIEnv* env, jobject /* obj */) { std::unique_lock lock(jniObjMutex); - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; sBluetoothInterface->cleanup(); - ALOGI("%s: return from cleanup", __func__); + log::info("return from cleanup"); if (sJniCallbacksObj) { env->DeleteGlobalRef(sJniCallbacksObj); @@ -1091,7 +1129,7 @@ static bool cleanupNative(JNIEnv* env, jobject /* obj */) { } static jboolean enableNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; int ret = sBluetoothInterface->enable(); @@ -1100,7 +1138,7 @@ static jboolean enableNative(JNIEnv* /* env */, jobject /* obj */) { } static jboolean disableNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1113,7 +1151,7 @@ static jboolean disableNative(JNIEnv* /* env */, jobject /* obj */) { } static jboolean startDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1122,7 +1160,7 @@ static jboolean startDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) { } static jboolean cancelDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1133,7 +1171,7 @@ static jboolean cancelDiscoveryNative(JNIEnv* /* env */, jobject /* obj */) { static jboolean createBondNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jint addrType, jint transport) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1152,7 +1190,7 @@ static jboolean createBondNative(JNIEnv* env, jobject /* obj */, } if (ret != BT_STATUS_SUCCESS) { - ALOGW("%s: Failed to initiate bonding. Status = %d", __func__, ret); + log::warn("Failed to initiate bonding. Status = {}", ret); } env->ReleaseByteArrayElements(address, addr, 0); @@ -1180,7 +1218,7 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, jint transport) { // Need both arguments to be non NULL if (oobData == NULL) { - ALOGE("%s: oobData is null! Nothing to do.", __func__); + log::error("oobData is null! Nothing to do."); return JNI_FALSE; } @@ -1192,8 +1230,8 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, // Check the data int len = env->GetArrayLength(address); if (len != OOB_ADDRESS_SIZE) { - ALOGE("%s: addressBytes must be 7 bytes in length (address plus type) 6+1!", - __func__); + log::error( + "addressBytes must be 7 bytes in length (address plus type) 6+1!"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -1201,7 +1239,7 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, // Convert the address from byte[] jbyte* addressBytes = env->GetByteArrayElements(address, NULL); if (addressBytes == NULL) { - ALOGE("%s: addressBytes cannot be null!", __func__); + log::error("addressBytes cannot be null!"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -1218,10 +1256,10 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, deviceNameBytes = env->GetByteArrayElements(deviceName, NULL); int len = env->GetArrayLength(deviceName); if (len > OOB_NAME_MAX_SIZE) { - ALOGI( - "%s: wrong length of deviceName, should be empty or less than or " - "equal to %d bytes.", - __func__, OOB_NAME_MAX_SIZE); + log::info( + "wrong length of deviceName, should be empty or less than or equal " + "to {} bytes.", + OOB_NAME_MAX_SIZE); jniThrowIOException(env, EINVAL); env->ReleaseByteArrayElements(deviceName, deviceNameBytes, 0); return JNI_FALSE; @@ -1233,7 +1271,7 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, jbyteArray confirmation = callByteArrayGetter( env, oobData, "android/bluetooth/OobData", "getConfirmationHash"); if (confirmation == NULL) { - ALOGE("%s: confirmation cannot be null!", __func__); + log::error("confirmation cannot be null!"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -1243,10 +1281,8 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, confirmationBytes = env->GetByteArrayElements(confirmation, NULL); len = env->GetArrayLength(confirmation); if (confirmationBytes == NULL || len != OOB_C_SIZE) { - ALOGI( - "%s: wrong length of Confirmation, should be empty or %d " - "bytes.", - __func__, OOB_C_SIZE); + log::info("wrong length of Confirmation, should be empty or {} bytes.", + OOB_C_SIZE); jniThrowIOException(env, EINVAL); env->ReleaseByteArrayElements(confirmation, confirmationBytes, 0); return JNI_FALSE; @@ -1262,8 +1298,8 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, randomizerBytes = env->GetByteArrayElements(randomizer, NULL); int len = env->GetArrayLength(randomizer); if (randomizerBytes == NULL || len != OOB_R_SIZE) { - ALOGI("%s: wrong length of Random, should be empty or %d bytes.", - __func__, OOB_R_SIZE); + log::info("wrong length of Random, should be empty or {} bytes.", + OOB_R_SIZE); jniThrowIOException(env, EINVAL); env->ReleaseByteArrayElements(randomizer, randomizerBytes, 0); return JNI_FALSE; @@ -1281,8 +1317,8 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, jbyte* oobDataLengthBytes = NULL; if (oobDataLength == NULL || env->GetArrayLength(oobDataLength) != OOB_DATA_LEN_SIZE) { - ALOGI("%s: wrong length of oobDataLength, should be empty or %d bytes.", - __func__, OOB_DATA_LEN_SIZE); + log::info("wrong length of oobDataLength, should be empty or {} bytes.", + OOB_DATA_LEN_SIZE); jniThrowIOException(env, EINVAL); env->ReleaseByteArrayElements(oobDataLength, oobDataLengthBytes, 0); return JNI_FALSE; @@ -1300,8 +1336,8 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, classOfDeviceBytes = env->GetByteArrayElements(classOfDevice, NULL); int len = env->GetArrayLength(classOfDevice); if (len != OOB_COD_SIZE) { - ALOGI("%s: wrong length of classOfDevice, should be empty or %d bytes.", - __func__, OOB_COD_SIZE); + log::info("wrong length of classOfDevice, should be empty or {} bytes.", + OOB_COD_SIZE); jniThrowIOException(env, EINVAL); env->ReleaseByteArrayElements(classOfDevice, classOfDeviceBytes, 0); return JNI_FALSE; @@ -1318,8 +1354,8 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, temporaryKeyBytes = env->GetByteArrayElements(temporaryKey, NULL); int len = env->GetArrayLength(temporaryKey); if (len != OOB_TK_SIZE) { - ALOGI("%s: wrong length of temporaryKey, should be empty or %d bytes.", - __func__, OOB_TK_SIZE); + log::info("wrong length of temporaryKey, should be empty or {} bytes.", + OOB_TK_SIZE); jniThrowIOException(env, EINVAL); env->ReleaseByteArrayElements(temporaryKey, temporaryKeyBytes, 0); return JNI_FALSE; @@ -1335,8 +1371,8 @@ static jboolean set_data(JNIEnv* env, bt_oob_data_t& oob_data, jobject oobData, leAppearanceBytes = env->GetByteArrayElements(leAppearance, NULL); int len = env->GetArrayLength(leAppearance); if (len != OOB_LE_APPEARANCE_SIZE) { - ALOGI("%s: wrong length of leAppearance, should be empty or %d bytes.", - __func__, OOB_LE_APPEARANCE_SIZE); + log::info("wrong length of leAppearance, should be empty or {} bytes.", + OOB_LE_APPEARANCE_SIZE); jniThrowIOException(env, EINVAL); env->ReleaseByteArrayElements(leAppearance, leAppearanceBytes, 0); return JNI_FALSE; @@ -1363,7 +1399,7 @@ static void generateLocalOobDataNative(JNIEnv* /* env */, jobject /* obj */, if (sBluetoothInterface->generate_local_oob_data(transport) != BT_STATUS_SUCCESS) { - ALOGE("%s: Call to generate_local_oob_data failed!", __func__); + log::error("Call to generate_local_oob_data failed!"); bt_oob_data_t oob_data; oob_data.is_valid = false; generate_local_oob_data_callback(transport, oob_data); @@ -1378,7 +1414,7 @@ static jboolean createBondOutOfBandNative(JNIEnv* env, jobject /* obj */, // No data? Can't do anything if (p192Data == NULL && p256Data == NULL) { - ALOGE("%s: All OOB Data are null! Nothing to do.", __func__); + log::error("All OOB Data are null! Nothing to do."); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -1387,7 +1423,7 @@ static jboolean createBondOutOfBandNative(JNIEnv* env, jobject /* obj */, // In the future we want to remove this and just reverse the address // for the oobdata in the host stack. if (address == NULL) { - ALOGE("%s: Address cannot be null! Nothing to do.", __func__); + log::error("Address cannot be null! Nothing to do."); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -1395,8 +1431,8 @@ static jboolean createBondOutOfBandNative(JNIEnv* env, jobject /* obj */, // Check the data int len = env->GetArrayLength(address); if (len != 6) { - ALOGE("%s: addressBytes must be 6 bytes in length (address plus type) 6+1!", - __func__); + log::error( + "addressBytes must be 6 bytes in length (address plus type) 6+1!"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -1434,7 +1470,7 @@ static jboolean createBondOutOfBandNative(JNIEnv* env, jobject /* obj */, static jboolean removeBondNative(JNIEnv* env, jobject /* obj */, jbyteArray address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1452,7 +1488,7 @@ static jboolean removeBondNative(JNIEnv* env, jobject /* obj */, static jboolean cancelBondNative(JNIEnv* env, jobject /* obj */, jbyteArray address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1467,9 +1503,17 @@ static jboolean cancelBondNative(JNIEnv* env, jobject /* obj */, return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } +static jboolean pairingIsBusyNative(JNIEnv* /*env*/, jobject /* obj */) { + log::verbose(""); + + if (!sBluetoothInterface) return JNI_FALSE; + + return sBluetoothInterface->pairing_is_busy(); +} + static int getConnectionStateNative(JNIEnv* env, jobject /* obj */, jbyteArray address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); @@ -1487,7 +1531,7 @@ static int getConnectionStateNative(JNIEnv* env, jobject /* obj */, static jboolean pinReplyNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jboolean accept, jint len, jbyteArray pinArray) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1518,7 +1562,7 @@ static jboolean pinReplyNative(JNIEnv* env, jobject /* obj */, static jboolean sspReplyNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jint type, jboolean accept, jint passkey) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1537,7 +1581,7 @@ static jboolean sspReplyNative(JNIEnv* env, jobject /* obj */, static jboolean setAdapterPropertyNative(JNIEnv* env, jobject /* obj */, jint type, jbyteArray value) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1555,7 +1599,7 @@ static jboolean setAdapterPropertyNative(JNIEnv* env, jobject /* obj */, static jboolean getAdapterPropertiesNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1565,7 +1609,7 @@ static jboolean getAdapterPropertiesNative(JNIEnv* /* env */, static jboolean getAdapterPropertyNative(JNIEnv* /* env */, jobject /* obj */, jint type) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1575,7 +1619,7 @@ static jboolean getAdapterPropertyNative(JNIEnv* /* env */, jobject /* obj */, static jboolean getDevicePropertyNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jint type) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1594,7 +1638,7 @@ static jboolean getDevicePropertyNative(JNIEnv* env, jobject /* obj */, static jboolean setDevicePropertyNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jint type, jbyteArray value) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1626,7 +1670,7 @@ static jboolean setDevicePropertyNative(JNIEnv* env, jobject /* obj */, static jboolean getRemoteServicesNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jint transport) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1643,7 +1687,7 @@ static jboolean getRemoteServicesNative(JNIEnv* env, jobject /* obj */, } static int readEnergyInfoNative() { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; int ret = sBluetoothInterface->read_energy_info(); @@ -1652,7 +1696,7 @@ static int readEnergyInfoNative() { static void dumpNative(JNIEnv* env, jobject /* obj */, jobject fdObj, jobjectArray argArray) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return; int fd = jniGetFDFromFileDescriptor(env, fdObj); @@ -1683,7 +1727,7 @@ static void dumpNative(JNIEnv* env, jobject /* obj */, jobject fdObj, } static jbyteArray dumpMetricsNative(JNIEnv* env, jobject /* obj */) { - ALOGI("%s", __func__); + log::info(""); if (!sBluetoothInterface) return env->NewByteArray(0); std::string output; @@ -1696,7 +1740,7 @@ static jbyteArray dumpMetricsNative(JNIEnv* env, jobject /* obj */) { } static jboolean factoryResetNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; int ret = sBluetoothInterface->config_clear(); return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -1704,7 +1748,7 @@ static jboolean factoryResetNative(JNIEnv* /* env */, jobject /* obj */) { static jbyteArray obfuscateAddressNative(JNIEnv* env, jobject /* obj */, jbyteArray address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return env->NewByteArray(0); jbyte* addr = env->GetByteArrayElements(address, nullptr); if (addr == nullptr) { @@ -1724,7 +1768,7 @@ static jbyteArray obfuscateAddressNative(JNIEnv* env, jobject /* obj */, static jboolean setBufferLengthMillisNative(JNIEnv* /* env */, jobject /* obj */, jint codec, jint size) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -1815,7 +1859,7 @@ static void requestMaximumTxDataLengthNative(JNIEnv* env, jobject /* obj */, static int getMetricIdNative(JNIEnv* env, jobject /* obj */, jbyteArray address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return 0; // 0 is invalid id jbyte* addr = env->GetByteArrayElements(address, nullptr); if (addr == nullptr) { @@ -1830,7 +1874,7 @@ static int getMetricIdNative(JNIEnv* env, jobject /* obj */, static jboolean allowLowLatencyAudioNative(JNIEnv* env, jobject /* obj */, jboolean allowed, jbyteArray address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return false; jbyte* addr = env->GetByteArrayElements(address, nullptr); if (addr == nullptr) { @@ -1847,7 +1891,7 @@ static jboolean allowLowLatencyAudioNative(JNIEnv* env, jobject /* obj */, static void metadataChangedNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jint key, jbyteArray value) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return; jbyte* addr = env->GetByteArrayElements(address, nullptr); if (addr == nullptr) { @@ -1858,7 +1902,7 @@ static void metadataChangedNative(JNIEnv* env, jobject /* obj */, addr_obj.FromOctets((uint8_t*)addr); if (value == NULL) { - ALOGE("metadataChangedNative() ignoring NULL array"); + log::error("metadataChangedNative() ignoring NULL array"); return; } @@ -1876,22 +1920,22 @@ static void metadataChangedNative(JNIEnv* env, jobject /* obj */, static jboolean isLogRedactionEnabledNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); return bluetooth::os::should_log_be_redacted(); } static jboolean interopMatchAddrNative(JNIEnv* env, jclass /* clazz */, jstring feature_name, jstring address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) { - ALOGW("%s: sBluetoothInterface is null.", __func__); + log::warn("sBluetoothInterface is null."); return JNI_FALSE; } const char* tmp_addr = env->GetStringUTFChars(address, NULL); if (!tmp_addr) { - ALOGW("%s: address is null.", __func__); + log::warn("address is null."); return JNI_FALSE; } RawAddress bdaddr; @@ -1900,13 +1944,13 @@ static jboolean interopMatchAddrNative(JNIEnv* env, jclass /* clazz */, env->ReleaseStringUTFChars(address, tmp_addr); if (!success) { - ALOGW("%s: address is invalid.", __func__); + log::warn("address is invalid."); return JNI_FALSE; } const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL); if (!feature_name_str) { - ALOGW("%s: feature name is null.", __func__); + log::warn("feature name is null."); return JNI_FALSE; } @@ -1919,22 +1963,22 @@ static jboolean interopMatchAddrNative(JNIEnv* env, jclass /* clazz */, static jboolean interopMatchNameNative(JNIEnv* env, jclass /* clazz */, jstring feature_name, jstring name) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) { - ALOGW("%s: sBluetoothInterface is null.", __func__); + log::warn("sBluetoothInterface is null."); return JNI_FALSE; } const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL); if (!feature_name_str) { - ALOGW("%s: feature name is null.", __func__); + log::warn("feature name is null."); return JNI_FALSE; } const char* name_str = env->GetStringUTFChars(name, NULL); if (!name_str) { - ALOGW("%s: name is null.", __func__); + log::warn("name is null."); env->ReleaseStringUTFChars(feature_name, feature_name_str); return JNI_FALSE; } @@ -1950,16 +1994,16 @@ static jboolean interopMatchNameNative(JNIEnv* env, jclass /* clazz */, static jboolean interopMatchAddrOrNameNative(JNIEnv* env, jclass /* clazz */, jstring feature_name, jstring address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) { - ALOGW("%s: sBluetoothInterface is null.", __func__); + log::warn("sBluetoothInterface is null."); return JNI_FALSE; } const char* tmp_addr = env->GetStringUTFChars(address, NULL); if (!tmp_addr) { - ALOGW("%s: address is null.", __func__); + log::warn("address is null."); return JNI_FALSE; } RawAddress bdaddr; @@ -1968,13 +2012,13 @@ static jboolean interopMatchAddrOrNameNative(JNIEnv* env, jclass /* clazz */, env->ReleaseStringUTFChars(address, tmp_addr); if (!success) { - ALOGW("%s: address is invalid.", __func__); + log::warn("address is invalid."); return JNI_FALSE; } const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL); if (!feature_name_str) { - ALOGW("%s: feature name is null.", __func__); + log::warn("feature name is null."); return JNI_FALSE; } @@ -1989,22 +2033,21 @@ static void interopDatabaseAddRemoveAddrNative(JNIEnv* env, jclass /* clazz */, jboolean do_add, jstring feature_name, jstring address, jint length) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) { - ALOGW("%s: sBluetoothInterface is null.", __func__); + log::warn("sBluetoothInterface is null."); return; } if ((do_add == JNI_TRUE) && (length <= 0 || length > 6)) { - ALOGE("%s: address length %d is invalid, valid length is [1,6]", __func__, - length); + log::error("address length {} is invalid, valid length is [1,6]", length); return; } const char* tmp_addr = env->GetStringUTFChars(address, NULL); if (!tmp_addr) { - ALOGW("%s: address is null.", __func__); + log::warn("address is null."); return; } RawAddress bdaddr; @@ -2013,13 +2056,13 @@ static void interopDatabaseAddRemoveAddrNative(JNIEnv* env, jclass /* clazz */, env->ReleaseStringUTFChars(address, tmp_addr); if (!success) { - ALOGW("%s: address is invalid.", __func__); + log::warn("address is invalid."); return; } const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL); if (!feature_name_str) { - ALOGW("%s: feature name is null.", __func__); + log::warn("feature name is null."); return; } @@ -2033,22 +2076,22 @@ static void interopDatabaseAddRemoveNameNative(JNIEnv* env, jclass /* clazz */, jboolean do_add, jstring feature_name, jstring name) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) { - ALOGW("%s: sBluetoothInterface is null.", __func__); + log::warn("sBluetoothInterface is null."); return; } const char* feature_name_str = env->GetStringUTFChars(feature_name, NULL); if (!feature_name_str) { - ALOGW("%s: feature name is null.", __func__); + log::warn("feature name is null."); return; } const char* name_str = env->GetStringUTFChars(name, NULL); if (!name_str) { - ALOGW("%s: name is null.", __func__); + log::warn("name is null."); env->ReleaseStringUTFChars(feature_name, feature_name_str); return; } @@ -2062,13 +2105,13 @@ static void interopDatabaseAddRemoveNameNative(JNIEnv* env, jclass /* clazz */, static int getRemotePbapPceVersionNative(JNIEnv* env, jobject /* obj */, jstring address) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; const char* tmp_addr = env->GetStringUTFChars(address, NULL); if (!tmp_addr) { - ALOGW("%s: address is null.", __func__); + log::warn("address is null."); return JNI_FALSE; } @@ -2078,7 +2121,7 @@ static int getRemotePbapPceVersionNative(JNIEnv* env, jobject /* obj */, env->ReleaseStringUTFChars(address, tmp_addr); if (!success) { - ALOGW("%s: address is invalid.", __func__); + log::warn("address is invalid."); return JNI_FALSE; } @@ -2087,7 +2130,7 @@ static int getRemotePbapPceVersionNative(JNIEnv* env, jobject /* obj */, static jboolean pbapPseDynamicVersionUpgradeIsEnabledNative(JNIEnv* /* env */, jobject /* obj */) { - ALOGV("%s", __func__); + log::verbose(""); if (!sBluetoothInterface) return JNI_FALSE; @@ -2116,6 +2159,7 @@ int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) { (void*)createBondOutOfBandNative}, {"removeBondNative", "([B)Z", (void*)removeBondNative}, {"cancelBondNative", "([B)Z", (void*)cancelBondNative}, + {"pairingIsBusyNative", "()Z", (void*)pairingIsBusyNative}, {"generateLocalOobDataNative", "(I)V", (void*)generateLocalOobDataNative}, {"getConnectionStateNative", "([B)I", (void*)getConnectionStateNative}, {"pinReplyNative", "([BZI[B)Z", (void*)pinReplyNative}, @@ -2198,6 +2242,7 @@ int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) { {"releaseWakeLock", "(Ljava/lang/String;)Z", &method_releaseWakeLock}, {"energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V", &method_energyInfo}, + {"keyMissingCallback", "([B)V", &method_keyMissingCallback}, }; GET_JAVA_METHODS(env, "com/android/bluetooth/btservice/JniCallbacks", javaMethods); @@ -2208,11 +2253,11 @@ int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) { GET_JAVA_METHODS(env, "android/bluetooth/UidTraffic", javaUuidTrafficMethods); if (env->GetJavaVM(&vm) != JNI_OK) { - ALOGE("Could not get JavaVM"); + log::error("Could not get JavaVM"); } if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) { - ALOGE("No Bluetooth Library found"); + log::error("No Bluetooth Library found"); } return 0; @@ -2224,123 +2269,151 @@ int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) { * JNI Initialization */ jint JNI_OnLoad(JavaVM* jvm, void* /* reserved */) { + /* Set the default logging level for the process using the tag + * "log.tag.bluetooth" and/or "persist.log.tag.bluetooth" via the android + * logging framework. + */ + const char* stack_default_log_tag = "bluetooth"; + int default_prio = ANDROID_LOG_INFO; + if (__android_log_is_loggable(ANDROID_LOG_VERBOSE, stack_default_log_tag, + default_prio)) { + __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE); + log::info("Set stack default log level to 'VERBOSE'"); + } else if (__android_log_is_loggable(ANDROID_LOG_DEBUG, stack_default_log_tag, + default_prio)) { + __android_log_set_minimum_priority(ANDROID_LOG_DEBUG); + log::info("Set stack default log level to 'DEBUG'"); + } else if (__android_log_is_loggable(ANDROID_LOG_INFO, stack_default_log_tag, + default_prio)) { + __android_log_set_minimum_priority(ANDROID_LOG_INFO); + log::info("Set stack default log level to 'INFO'"); + } else if (__android_log_is_loggable(ANDROID_LOG_WARN, stack_default_log_tag, + default_prio)) { + __android_log_set_minimum_priority(ANDROID_LOG_WARN); + log::info("Set stack default log level to 'WARN'"); + } else if (__android_log_is_loggable(ANDROID_LOG_ERROR, stack_default_log_tag, + default_prio)) { + __android_log_set_minimum_priority(ANDROID_LOG_ERROR); + log::info("Set stack default log level to 'ERROR'"); + } + JNIEnv* e; int status; - ALOGV("Bluetooth Adapter Service : loading JNI\n"); + log::verbose("Bluetooth Adapter Service : loading JNI\n"); // Check JNI version if (jvm->GetEnv((void**)&e, JNI_VERSION_1_6)) { - ALOGE("JNI version mismatch error"); + log::error("JNI version mismatch error"); return JNI_ERR; } status = android::register_com_android_bluetooth_btservice_AdapterService(e); if (status < 0) { - ALOGE("jni adapter service registration failure, status: %d", status); + log::error("jni adapter service registration failure, status: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_btservice_BluetoothKeystore(e); if (status < 0) { - ALOGE("jni BluetoothKeyStore registration failure: %d", status); + log::error("jni BluetoothKeyStore registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_hfp(e); if (status < 0) { - ALOGE("jni hfp registration failure, status: %d", status); + log::error("jni hfp registration failure, status: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_hfpclient(e); if (status < 0) { - ALOGE("jni hfp client registration failure, status: %d", status); + log::error("jni hfp client registration failure, status: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_a2dp(e); if (status < 0) { - ALOGE("jni a2dp source registration failure: %d", status); + log::error("jni a2dp source registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_a2dp_sink(e); if (status < 0) { - ALOGE("jni a2dp sink registration failure: %d", status); + log::error("jni a2dp sink registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_avrcp_target(e); if (status < 0) { - ALOGE("jni new avrcp target registration failure: %d", status); + log::error("jni new avrcp target registration failure: {}", status); } status = android::register_com_android_bluetooth_avrcp_controller(e); if (status < 0) { - ALOGE("jni avrcp controller registration failure: %d", status); + log::error("jni avrcp controller registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_hid_host(e); if (status < 0) { - ALOGE("jni hid registration failure: %d", status); + log::error("jni hid registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_hid_device(e); if (status < 0) { - ALOGE("jni hidd registration failure: %d", status); + log::error("jni hidd registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_pan(e); if (status < 0) { - ALOGE("jni pan registration failure: %d", status); + log::error("jni pan registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_gatt(e); if (status < 0) { - ALOGE("jni gatt registration failure: %d", status); + log::error("jni gatt registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_sdp(e); if (status < 0) { - ALOGE("jni sdp registration failure: %d", status); + log::error("jni sdp registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_hearing_aid(e); if (status < 0) { - ALOGE("jni hearing aid registration failure: %d", status); + log::error("jni hearing aid registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_hap_client(e); if (status < 0) { - ALOGE("jni le audio hearing access client registration failure: %d", - status); + log::error("jni le audio hearing access client registration failure: {}", + status); return JNI_ERR; } status = android::register_com_android_bluetooth_le_audio(e); if (status < 0) { - ALOGE("jni le_audio registration failure: %d", status); + log::error("jni le_audio registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_vc(e); if (status < 0) { - ALOGE("jni vc registration failure: %d", status); + log::error("jni vc registration failure: {}", status); return JNI_ERR; } status = android::register_com_android_bluetooth_csip_set_coordinator(e); if (status < 0) { - ALOGE("jni csis client registration failure: %d", status); + log::error("jni csis client registration failure: {}", status); return JNI_ERR; } @@ -2348,7 +2421,7 @@ jint JNI_OnLoad(JavaVM* jvm, void* /* reserved */) { android::register_com_android_bluetooth_btservice_BluetoothQualityReport( e); if (status < 0) { - ALOGE("jni bluetooth quality report registration failure: %d", status); + log::error("jni bluetooth quality report registration failure: {}", status); return JNI_ERR; } @@ -2362,8 +2435,8 @@ void jniGetMethodsOrDie(JNIEnv* env, const char* className, const JNIJavaMethod* methods, int nMethods) { jclass clazz = env->FindClass(className); if (clazz == nullptr) { - LOG(FATAL) << "Native registration unable to find class '" << className - << "'; aborting..."; + log::fatal("Native registration unable to find class '{}' aborting...", + className); } for (int i = 0; i < nMethods; i++) { @@ -2374,9 +2447,9 @@ void jniGetMethodsOrDie(JNIEnv* env, const char* className, *method.id = env->GetMethodID(clazz, method.name, method.signature); } if (method.id == nullptr) { - LOG(FATAL) << "In class " << className << ": Unable to find '" - << method.name << "' with signature=" << method.signature - << " is_static=" << method.is_static; + log::fatal( + "In class {}: Unable to find '{}' with signature={} is_static={}", + className, method.name, method.signature, method.is_static); } } diff --git a/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp b/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp index 1c5e382c52b07c6f3ad0fb13778ea2f021261861..7d083cc68573ecdd4405d1d66bf332f91f6312cc 100644 --- a/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp +++ b/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp @@ -44,7 +44,7 @@ class BluetoothKeystoreCallbacksImpl void set_encrypt_key_or_remove_key( const std::string prefixString, const std::string decryptedString) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -60,7 +60,7 @@ class BluetoothKeystoreCallbacksImpl } std::string get_key(const std::string prefixString) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -72,7 +72,7 @@ class BluetoothKeystoreCallbacksImpl mCallbacksObj, method_getKeyCallback, j_prefixString); if (j_decrypt_str == nullptr) { - ALOGE("%s: Got a null decrypt_str", __func__); + log::error("Got a null decrypt_str"); return ""; } @@ -92,32 +92,30 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothKeystoreInterface != nullptr) { - LOG(INFO) - << "Cleaning up BluetoothKeystore Interface before initializing..."; + log::info("Cleaning up BluetoothKeystore Interface before initializing..."); sBluetoothKeystoreInterface = nullptr; } if (mCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up BluetoothKeystore callback object"; + log::info("Cleaning up BluetoothKeystore callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) - << "Failed to allocate Global Ref for BluetoothKeystore Callbacks"; + log::error("Failed to allocate Global Ref for BluetoothKeystore Callbacks"); return; } sBluetoothKeystoreInterface = (BluetoothKeystoreInterface*)btInf->get_profile_interface(BT_KEYSTORE_ID); if (sBluetoothKeystoreInterface == nullptr) { - LOG(ERROR) << "Failed to get BluetoothKeystore Interface"; + log::error("Failed to get BluetoothKeystore Interface"); return; } @@ -130,7 +128,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } diff --git a/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp b/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp index bd24892a76443e2a2dc21a7eeebc9242f0c3dd41..58f8c7fc5dcb6c19d0f4827194252962a331700f 100644 --- a/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp +++ b/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp @@ -75,8 +75,8 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { void OnConnectionState(const RawAddress& bd_addr, ConnectionState state) override { - LOG(INFO) << __func__ << ", state:" << int(state) - << ", addr: " << bd_addr.ToRedactedStringForLogging(); + log::info("state:{}, addr: {}", int(state), + bd_addr.ToRedactedStringForLogging()); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -85,7 +85,7 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new bd addr jbyteArray for connection state"; + log::error("Failed to new bd addr jbyteArray for connection state"); return; } @@ -105,7 +105,7 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new bd addr jbyteArray for device available"; + log::error("Failed to new bd addr jbyteArray for device available"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -117,7 +117,7 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { } void OnSetMemberAvailable(const RawAddress& bd_addr, int group_id) override { - LOG(INFO) << __func__ << ", group id:" << group_id; + log::info("group id:{}", group_id); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -126,7 +126,7 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for connection state"; + log::error("Failed to new jbyteArray bd addr for connection state"); return; } @@ -138,8 +138,8 @@ class CsisClientCallbacksImpl : public CsisClientCallbacks { void OnGroupLockChanged(int group_id, bool locked, CsisGroupLockStatus status) override { - LOG(INFO) << __func__ << ", group_id: " << int(group_id) - << ", locked: " << locked << ", status: " << (int)status; + log::info("group_id: {}, locked: {}, status: {}", group_id, locked, + (int)status); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -159,31 +159,31 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } if (sCsisClientInterface != nullptr) { - LOG(INFO) << "Cleaning up Csis Interface before initializing..."; + log::info("Cleaning up Csis Interface before initializing..."); sCsisClientInterface->Cleanup(); sCsisClientInterface = nullptr; } if (mCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up Csis callback object"; + log::info("Cleaning up Csis callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for Csis Client Callbacks"; + log::error("Failed to allocate Global Ref for Csis Client Callbacks"); return; } sCsisClientInterface = (CsisClientInterface*)btInf->get_profile_interface( BT_PROFILE_CSIS_CLIENT_ID); if (sCsisClientInterface == nullptr) { - LOG(ERROR) << "Failed to get Csis Client Interface"; + log::error("Failed to get Csis Client Interface"); return; } @@ -196,7 +196,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } @@ -215,8 +215,7 @@ static jboolean connectNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sCsisClientInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Csis Client Interface Interface"; + log::error("Failed to get the Csis Client Interface Interface"); return JNI_FALSE; } @@ -236,7 +235,7 @@ static jboolean disconnectNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sCsisClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Csis Client Interface"; + log::error("Failed to get the Csis Client Interface"); return JNI_FALSE; } @@ -254,11 +253,10 @@ static jboolean disconnectNative(JNIEnv* env, jobject /* object */, static void groupLockSetNative(JNIEnv* /* env */, jobject /* object */, jint group_id, jboolean lock) { - LOG(INFO) << __func__; + log::info(""); if (!sCsisClientInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Csis Client Interface"; + log::error("Failed to get the Bluetooth Csis Client Interface"); return; } diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp index 0e1836937369d713072fee24fffc594548e9bce8..aaf908a7984478db2396396a06c2f27ad8087bae 100644 --- a/android/app/jni/com_android_bluetooth_gatt.cpp +++ b/android/app/jni/com_android_bluetooth_gatt.cpp @@ -26,22 +26,13 @@ #include #include "com_android_bluetooth.h" -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "hardware/bt_gatt.h" #include "hardware/bt_gatt_types.h" #include "rust/cxx.h" #include "rust/src/gatt/ffi/gatt_shim.h" #include "src/gatt/ffi.rs.h" #include "utils/Log.h" -#define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) -#define debug(fmt, ...) \ - ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) -#define warn(fmt, ...) \ - ALOGW("WARNING: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__) -#define error(fmt, ...) \ - ALOGE("ERROR: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__) -#define asrt(s) \ - if (!(s)) ALOGE("%s(L%d): ASSERT %s failed! ##", __func__, __LINE__, #s) using bluetooth::Uuid; @@ -1111,7 +1102,7 @@ class JniScanningCallbacks : ScanningCallbacks { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!mPeriodicScanCallbacksObj) { - ALOGE("mPeriodicScanCallbacksObj is NULL. Return."); + log::error("mPeriodicScanCallbacksObj is NULL. Return."); return; } ScopedLocalRef addr(sCallbackEnv.get(), @@ -1154,7 +1145,7 @@ class JniScanningCallbacks : ScanningCallbacks { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!mPeriodicScanCallbacksObj) { - ALOGE("mPeriodicScanCallbacksObj is NULL. Return."); + log::error("mPeriodicScanCallbacksObj is NULL. Return."); return; } ScopedLocalRef addr(sCallbackEnv.get(), @@ -1171,7 +1162,7 @@ class JniScanningCallbacks : ScanningCallbacks { if (!sCallbackEnv.valid()) return; if (!mPeriodicScanCallbacksObj) { - ALOGE("mPeriodicScanCallbacksObj is NULL. Return."); + log::error("mPeriodicScanCallbacksObj is NULL. Return."); return; } sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, @@ -1247,18 +1238,18 @@ static void initializeNative(JNIEnv* env, jobject object) { btIf = getBluetoothInterface(); if (btIf == NULL) { - error("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sGattIf != NULL) { - ALOGW("Cleaning up Bluetooth GATT Interface before initializing..."); + log::warn("Cleaning up Bluetooth GATT Interface before initializing..."); sGattIf->cleanup(); sGattIf = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth GATT callback object"); + log::warn("Cleaning up Bluetooth GATT callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -1266,13 +1257,14 @@ static void initializeNative(JNIEnv* env, jobject object) { sGattIf = (btgatt_interface_t*)btIf->get_profile_interface(BT_PROFILE_GATT_ID); if (sGattIf == NULL) { - error("Failed to get Bluetooth GATT Interface"); + log::error("Failed to get Bluetooth GATT Interface"); return; } bt_status_t status = sGattIf->init(&sGattCallbacks); if (status != BT_STATUS_SUCCESS) { - error("Failed to initialize Bluetooth GATT, status: %d", status); + log::error("Failed to initialize Bluetooth GATT, status: {}", + bt_status_text(status)); sGattIf = NULL; return; } @@ -1477,7 +1469,7 @@ static void gattClientWriteCharacteristicNative(JNIEnv* env, if (!sGattIf) return; if (value == NULL) { - warn("gattClientWriteCharacteristicNative() ignoring NULL array"); + log::warn("gattClientWriteCharacteristicNative() ignoring NULL array"); return; } @@ -1505,7 +1497,7 @@ static void gattClientWriteDescriptorNative(JNIEnv* env, jobject /* object */, if (!sGattIf) return; if (value == NULL) { - warn("gattClientWriteDescriptorNative() ignoring NULL array"); + log::warn("gattClientWriteDescriptorNative() ignoring NULL array"); return; } @@ -1551,8 +1543,8 @@ static void gattSetScanParametersNative(JNIEnv* /* env */, jobject /* object */, jint scan_window_unit) { if (!sGattIf) return; sGattIf->scanner->SetScanParameters( - client_if, scan_interval_unit, scan_window_unit, - base::Bind(&set_scan_params_cmpl_cb, client_if)); + client_if, /* use active scan */ 0x01, scan_interval_unit, + scan_window_unit, base::Bind(&set_scan_params_cmpl_cb, client_if)); } void scan_filter_param_cb(uint8_t client_if, uint8_t avbl_space, uint8_t action, @@ -1716,7 +1708,7 @@ static void gattClientScanFilterAddNative(JNIEnv* env, jobject /* object */, int len = env->GetArrayLength(irkByteArray.get()); // IRK is 128 bits or 16 octets, set the bytes or zero it out if (len != 16) { - ALOGE("%s: Invalid IRK length '%d'; expected 16", __func__, len); + log::error("Invalid IRK length '{}'; expected 16", len); jniThrowIOException(env, EINVAL); return; } @@ -2139,7 +2131,7 @@ static void gattServerSendResponseNative(JNIEnv* env, jobject /* object */, static void advertiseInitializeNative(JNIEnv* env, jobject object) { std::unique_lock lock(callbacks_mutex); if (mAdvertiseCallbacksObj != NULL) { - ALOGW("Cleaning up Advertise callback object"); + log::warn("Cleaning up Advertise callback object"); env->DeleteGlobalRef(mAdvertiseCallbacksObj); mAdvertiseCallbacksObj = NULL; } @@ -2230,8 +2222,7 @@ static PeriodicAdvertisingParameters parsePeriodicParams(JNIEnv* env, uint16_t interval = env->CallIntMethod(i, methodId); p.enable = true; - p.include_adi = - bluetooth::common::init_flags::periodic_advertising_adi_is_enabled(); + p.include_adi = true; p.min_interval = interval; p.max_interval = interval + 16; /* 20ms difference betwen min and max */ uint16_t props = 0; @@ -2439,17 +2430,15 @@ static void setPeriodicAdvertisingEnableNative(JNIEnv* /* env */, jboolean enable) { if (!sGattIf) return; - bool include_adi = - bluetooth::common::init_flags::periodic_advertising_adi_is_enabled(); sGattIf->advertiser->SetPeriodicAdvertisingEnable( - advertiser_id, enable, include_adi, + advertiser_id, enable, true /*include_adi*/, base::Bind(&enablePeriodicSetCb, advertiser_id, enable)); } static void periodicScanInitializeNative(JNIEnv* env, jobject object) { std::unique_lock lock(callbacks_mutex); if (mPeriodicScanCallbacksObj != NULL) { - ALOGW("Cleaning up periodic scan callback object"); + log::warn("Cleaning up periodic scan callback object"); env->DeleteGlobalRef(mPeriodicScanCallbacksObj); mPeriodicScanCallbacksObj = NULL; } @@ -2524,7 +2513,7 @@ static void gattTestNative(JNIEnv* env, jobject /* object */, jint command, static void distanceMeasurementInitializeNative(JNIEnv* env, jobject object) { std::unique_lock lock(callbacks_mutex); if (mDistanceMeasurementCallbacksObj != NULL) { - ALOGW("Cleaning up Advertise callback object"); + log::warn("Cleaning up Advertise callback object"); env->DeleteGlobalRef(mDistanceMeasurementCallbacksObj); mDistanceMeasurementCallbacksObj = NULL; } @@ -2542,11 +2531,11 @@ static void distanceMeasurementCleanupNative(JNIEnv* env, } static void startDistanceMeasurementNative(JNIEnv* env, jobject /* object */, - jstring address, jint frequency, + jstring address, jint interval, jint method) { if (!sGattIf) return; sGattIf->distance_measurement_manager->StartDistanceMeasurement( - str2addr(env, address), frequency, method); + str2addr(env, address), interval, method); } static void stopDistanceMeasurementNative(JNIEnv* env, jobject /* object */, @@ -2589,7 +2578,7 @@ static int register_com_android_bluetooth_gatt_scan(JNIEnv* env) { {"gattClientScanFilterParamClearAllNative", "(I)V", (void*)gattClientScanFilterParamClearAllNative}, {"gattClientScanFilterAddNative", - "(I[Lcom/android/bluetooth/gatt/ScanFilterQueue$Entry;I)V", + "(I[Lcom/android/bluetooth/le_scan/ScanFilterQueue$Entry;I)V", (void*)gattClientScanFilterAddNative}, {"gattClientScanFilterClearNative", "(II)V", (void*)gattClientScanFilterClearNative}, @@ -2599,7 +2588,7 @@ static int register_com_android_bluetooth_gatt_scan(JNIEnv* env) { (void*)gattSetScanParametersNative}, }; return REGISTER_NATIVE_METHODS( - env, "com/android/bluetooth/gatt/ScanNativeInterface", methods); + env, "com/android/bluetooth/le_scan/ScanNativeInterface", methods); } static int register_com_android_bluetooth_gatt_advertise_manager(JNIEnv* env) { @@ -2669,7 +2658,7 @@ static int register_com_android_bluetooth_gatt_periodic_scan(JNIEnv* env) { (void*)transferSetInfoNative}, }; const int result = REGISTER_NATIVE_METHODS( - env, "com/android/bluetooth/gatt/PeriodicScanNativeInterface", methods); + env, "com/android/bluetooth/le_scan/PeriodicScanNativeInterface", methods); if (result != 0) { return result; } @@ -2683,7 +2672,7 @@ static int register_com_android_bluetooth_gatt_periodic_scan(JNIEnv* env) { {"onBigInfoReport", "(IZ)V", &method_onBigInfoReport}, }; GET_JAVA_METHODS(env, - "com/android/bluetooth/gatt/PeriodicScanNativeInterface", + "com/android/bluetooth/le_scan/PeriodicScanNativeInterface", javaMethods); return 0; diff --git a/android/app/jni/com_android_bluetooth_hap_client.cpp b/android/app/jni/com_android_bluetooth_hap_client.cpp index 067af34197bc08cf735b2ba8cd668da87a20c561..148a6e29e2d00136def7d851d3dae65ad5982355 100644 --- a/android/app/jni/com_android_bluetooth_hap_client.cpp +++ b/android/app/jni/com_android_bluetooth_hap_client.cpp @@ -73,7 +73,7 @@ class HasClientCallbacksImpl : public HasClientCallbacks { void OnConnectionState(ConnectionState state, const RawAddress& bd_addr) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -82,7 +82,7 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new bd addr jbyteArray for connection state"; + log::error("Failed to new bd addr jbyteArray for connection state"); return; } @@ -100,7 +100,7 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new bd addr jbyteArray for device available"; + log::error("Failed to new bd addr jbyteArray for device available"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -118,7 +118,7 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new bd addr jbyteArray for device available"; + log::error("Failed to new bd addr jbyteArray for device available"); return; } sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress), @@ -138,7 +138,7 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new bd addr jbyteArray for preset selected"; + log::error("Failed to new bd addr jbyteArray for preset selected"); return; } sCallbackEnv->SetByteArrayRegion( @@ -164,8 +164,7 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) - << "Failed to new bd addr jbyteArray for preset select error"; + log::error("Failed to new bd addr jbyteArray for preset select error"); return; } sCallbackEnv->SetByteArrayRegion( @@ -198,14 +197,14 @@ class HasClientCallbacksImpl : public HasClientCallbacks { for (auto const& info : detail_records) { const char* name = info.preset_name.c_str(); if (!sCallbackEnv.isValidUtf(name)) { - ALOGE("%s: name is not a valid UTF string.", __func__); + log::error("name is not a valid UTF string."); name = null_str; } ScopedLocalRef name_str(sCallbackEnv.get(), sCallbackEnv->NewStringUTF(name)); if (!name_str.get()) { - LOG(ERROR) << "Failed to new preset name String for preset name"; + log::error("Failed to new preset name String for preset name"); return; } @@ -222,7 +221,7 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new bd addr jbyteArray for preset name"; + log::error("Failed to new bd addr jbyteArray for preset name"); return; } sCallbackEnv->SetByteArrayRegion( @@ -250,8 +249,8 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) - << "Failed to new bd addr jbyteArray for preset name get error"; + log::error( + "Failed to new bd addr jbyteArray for preset name get error"); return; } sCallbackEnv->SetByteArrayRegion( @@ -279,8 +278,8 @@ class HasClientCallbacksImpl : public HasClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) - << "Failed to new bd addr jbyteArray for preset name set error"; + log::error( + "Failed to new bd addr jbyteArray for preset name set error"); return; } sCallbackEnv->SetByteArrayRegion( @@ -307,40 +306,40 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } if (sHasClientInterface != nullptr) { - LOG(INFO) << "Cleaning up HearingAid Interface before initializing..."; + log::info("Cleaning up HearingAid Interface before initializing..."); sHasClientInterface->Cleanup(); sHasClientInterface = nullptr; } if (mCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up HearingAid callback object"; + log::info("Cleaning up HearingAid callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for Hearing Access Callbacks"; + log::error("Failed to allocate Global Ref for Hearing Access Callbacks"); return; } android_bluetooth_BluetoothHapPresetInfo.clazz = (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothHapPresetInfo")); if (android_bluetooth_BluetoothHapPresetInfo.clazz == nullptr) { - ALOGE("%s: Failed to allocate Global Ref for BluetoothHapPresetInfo class", - __func__); + log::error( + "Failed to allocate Global Ref for BluetoothHapPresetInfo class"); return; } sHasClientInterface = (HasClientInterface*)btInf->get_profile_interface( BT_PROFILE_HAP_CLIENT_ID); if (sHasClientInterface == nullptr) { - LOG(ERROR) - << "Failed to get Bluetooth Hearing Access Service Client Interface"; + log::error( + "Failed to get Bluetooth Hearing Access Service Client Interface"); return; } @@ -353,7 +352,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } @@ -372,7 +371,7 @@ static jboolean connectHapClientNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return JNI_FALSE; } @@ -392,7 +391,7 @@ static jboolean disconnectHapClientNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return JNI_FALSE; } @@ -412,7 +411,7 @@ static void selectActivePresetNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint preset_index) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -432,7 +431,7 @@ static void groupSelectActivePresetNative(JNIEnv* /* env */, jint preset_index) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -443,7 +442,7 @@ static void nextActivePresetNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -462,7 +461,7 @@ static void groupNextActivePresetNative(JNIEnv* /* env */, jobject /* object */, jint group_id) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -473,7 +472,7 @@ static void previousActivePresetNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -493,7 +492,7 @@ static void groupPreviousActivePresetNative(JNIEnv* /* env */, jint group_id) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -504,7 +503,7 @@ static void getPresetInfoNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint preset_index) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -524,7 +523,7 @@ static void setPresetNameNative(JNIEnv* env, jobject /* object */, jstring name) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } @@ -552,7 +551,7 @@ static void groupSetPresetNameNative(JNIEnv* env, jobject /* object */, jstring name) { std::shared_lock lock(interface_mutex); if (!sHasClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth HAP Interface"; + log::error("Failed to get the Bluetooth HAP Interface"); return; } diff --git a/android/app/jni/com_android_bluetooth_hearing_aid.cpp b/android/app/jni/com_android_bluetooth_hearing_aid.cpp index 648ff8d1d1d87ca56795a71ae49f22f0b92b8ac0..6ccee327ea75365c9ec53287c8305907d84ff99c 100644 --- a/android/app/jni/com_android_bluetooth_hearing_aid.cpp +++ b/android/app/jni/com_android_bluetooth_hearing_aid.cpp @@ -42,7 +42,7 @@ class HearingAidCallbacksImpl : public HearingAidCallbacks { ~HearingAidCallbacksImpl() = default; void OnConnectionState(ConnectionState state, const RawAddress& bd_addr) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -51,7 +51,7 @@ class HearingAidCallbacksImpl : public HearingAidCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for connection state"; + log::error("Failed to new jbyteArray bd addr for connection state"); return; } @@ -63,8 +63,7 @@ class HearingAidCallbacksImpl : public HearingAidCallbacks { void OnDeviceAvailable(uint8_t capabilities, uint64_t hi_sync_id, const RawAddress& bd_addr) override { - LOG(INFO) << __func__ << ": capabilities=" << +capabilities - << " hi_sync_id=" << hi_sync_id; + log::info("capabilities={} hi_sync_id={}", +capabilities, hi_sync_id); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -73,7 +72,7 @@ class HearingAidCallbacksImpl : public HearingAidCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for connection state"; + log::error("Failed to new jbyteArray bd addr for connection state"); return; } @@ -93,31 +92,31 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } if (sHearingAidInterface != nullptr) { - LOG(INFO) << "Cleaning up HearingAid Interface before initializing..."; + log::info("Cleaning up HearingAid Interface before initializing..."); sHearingAidInterface->Cleanup(); sHearingAidInterface = nullptr; } if (mCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up HearingAid callback object"; + log::info("Cleaning up HearingAid callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for Hearing Aid Callbacks"; + log::error("Failed to allocate Global Ref for Hearing Aid Callbacks"); return; } sHearingAidInterface = (HearingAidInterface*)btInf->get_profile_interface( BT_PROFILE_HEARING_AID_ID); if (sHearingAidInterface == nullptr) { - LOG(ERROR) << "Failed to get Bluetooth Hearing Aid Interface"; + log::error("Failed to get Bluetooth Hearing Aid Interface"); return; } @@ -130,7 +129,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } @@ -147,7 +146,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { static jboolean connectHearingAidNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sHearingAidInterface) return JNI_FALSE; @@ -165,7 +164,7 @@ static jboolean connectHearingAidNative(JNIEnv* env, jobject /* object */, static jboolean disconnectHearingAidNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sHearingAidInterface) return JNI_FALSE; @@ -200,8 +199,7 @@ static jboolean addToAcceptlistNative(JNIEnv* env, jobject /* object */, static void setVolumeNative(JNIEnv* /* env */, jclass /* clazz */, jint volume) { if (!sHearingAidInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Hearing Aid Interface"; + log::error("Failed to get the Bluetooth Hearing Aid Interface"); return; } sHearingAidInterface->SetVolume(volume); diff --git a/android/app/jni/com_android_bluetooth_hfp.cpp b/android/app/jni/com_android_bluetooth_hfp.cpp index d33669f49150ef7743d6e2e85c023cf08b4eafb7..beea022c679be57a8bd97e387af8e05a6cd4ee65 100644 --- a/android/app/jni/com_android_bluetooth_hfp.cpp +++ b/android/app/jni/com_android_bluetooth_hfp.cpp @@ -61,7 +61,7 @@ static jbyteArray marshall_bda(RawAddress* bd_addr) { jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); if (!addr) { - ALOGE("Fail to new jbyteArray bd addr"); + log::error("Fail to new jbyteArray bd addr"); return nullptr; } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), @@ -79,7 +79,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { void ConnectionStateCallback( bluetooth::headset::bthf_connection_state_t state, RawAddress* bd_addr) override { - ALOGI("%s %d for %s", __func__, state, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::info("{} for {}", state, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -94,7 +94,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { void AudioStateCallback(bluetooth::headset::bthf_audio_state_t state, RawAddress* bd_addr) override { - ALOGI("%s, %d for %s", __func__, state, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::info("{} for {}", state, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -115,7 +115,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -130,7 +130,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -145,7 +145,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -161,7 +161,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -176,13 +176,13 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } char null_str[] = ""; if (!sCallbackEnv.isValidUtf(number)) { - ALOGE("%s: number is not a valid UTF string.", __func__); + log::error("number is not a valid UTF string."); number = null_str; } @@ -199,7 +199,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -216,7 +216,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiseReductionEnable, @@ -260,7 +260,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -277,7 +277,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -291,7 +291,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -305,7 +305,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -319,7 +319,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -333,13 +333,13 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } char null_str[] = ""; if (!sCallbackEnv.isValidUtf(at_string)) { - ALOGE("%s: at_string is not a valid UTF string.", __func__); + log::error("at_string is not a valid UTF string."); at_string = null_str; } @@ -356,7 +356,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for audio state"); + log::error("Fail to new jbyteArray bd addr for audio state"); return; } @@ -374,7 +374,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { char null_str[] = ""; if (!sCallbackEnv.isValidUtf(at_string)) { - ALOGE("%s: at_string is not a valid UTF string.", __func__); + log::error("at_string is not a valid UTF string."); at_string = null_str; } @@ -417,7 +417,7 @@ class JniHeadsetCallbacks : bluetooth::headset::Callbacks { uint64_t /* end_ts */, const char* /* pkt_status_in_hex */, const char* /* pkt_status_in_binary */) override { - ALOGE("Not implemented and shouldn't be called"); + log::error("Not implemented and shouldn't be called"); } }; @@ -428,20 +428,19 @@ static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, const bt_interface_t* btInf = getBluetoothInterface(); if (!btInf) { - ALOGE("%s: Bluetooth module is not loaded", __func__); + log::error("Bluetooth module is not loaded"); jniThrowIOException(env, EINVAL); return; } if (sBluetoothHfpInterface) { - ALOGI("%s: Cleaning up Bluetooth Handsfree Interface before initializing", - __func__); + log::info("Cleaning up Bluetooth Handsfree Interface before initializing"); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface = nullptr; } if (mCallbacksObj) { - ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); + log::info("Cleaning up Bluetooth Handsfree callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } @@ -450,7 +449,7 @@ static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, (bluetooth::headset::Interface*)btInf->get_profile_interface( BT_PROFILE_HANDSFREE_ID); if (!sBluetoothHfpInterface) { - ALOGW("%s: Failed to get Bluetooth Handsfree Interface", __func__); + log::warn("Failed to get Bluetooth Handsfree Interface"); jniThrowIOException(env, EINVAL); return; } @@ -458,8 +457,8 @@ static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients, sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(), max_hf_clients, inband_ringing_enabled); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed to initialize Bluetooth Handsfree Interface, status: %d", - __func__, status); + log::error("Failed to initialize Bluetooth Handsfree Interface, status: {}", + bt_status_text(status)); sBluetoothHfpInterface = nullptr; return; } @@ -473,18 +472,18 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (!btInf) { - ALOGW("%s: Bluetooth module is not loaded", __func__); + log::warn("Bluetooth module is not loaded"); return; } if (sBluetoothHfpInterface) { - ALOGI("%s: Cleaning up Bluetooth Handsfree Interface", __func__); + log::info("Cleaning up Bluetooth Handsfree Interface"); sBluetoothHfpInterface->Cleanup(); sBluetoothHfpInterface = nullptr; } if (mCallbacksObj) { - ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__); + log::info("Cleaning up Bluetooth Handsfree callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } @@ -494,20 +493,19 @@ static jboolean connectHfpNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } - ALOGI("%s: device %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); + log::info("device {}", ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed HF connection, status: %d", status); + log::error("Failed HF connection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -517,20 +515,19 @@ static jboolean disconnectHfpNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } - ALOGI("%s: device %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); + log::info("device {}", ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed HF disconnection, status: %d", status); + log::error("Failed HF disconnection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -540,21 +537,21 @@ static jboolean connectAudioNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } - ALOGI("%s: device %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); + log::info("device {}", ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr, 0); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed HF audio connection, status: %d", status); + log::error("Failed HF audio connection, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -564,21 +561,21 @@ static jboolean disconnectAudioNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } - ALOGI("%s: device %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); + log::info("device {}", ADDRESS_TO_LOGGABLE_CSTR(*((RawAddress*)addr))); bt_status_t status = sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed HF audio disconnection, status: %d", status); + log::error("Failed HF audio disconnection, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -589,12 +586,12 @@ static jboolean isNoiseReductionSupportedNative(JNIEnv* env, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -609,12 +606,12 @@ static jboolean isVoiceRecognitionSupportedNative(JNIEnv* env, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -628,19 +625,20 @@ static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to start voice recognition, status: %d", status); + log::error("Failed to start voice recognition, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -650,19 +648,20 @@ static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to stop voice recognition, status: %d", status); + log::error("Failed to stop voice recognition, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -673,12 +672,12 @@ static jboolean setVolumeNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -686,7 +685,7 @@ static jboolean setVolumeNative(JNIEnv* env, jobject /* object */, (bluetooth::headset::bthf_volume_type_t)volume_type, volume, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("FAILED to control volume, status: %d", status); + log::error("FAILED to control volume, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -698,12 +697,12 @@ static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -713,7 +712,8 @@ static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject /* object */, battery_charge, (RawAddress*)addr); env->ReleaseByteArrayElements(address, addr, 0); if (status != BT_STATUS_SUCCESS) { - ALOGE("FAILED to notify device status, status: %d", status); + log::error("FAILED to notify device status, status: {}", + bt_status_text(status)); } return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } @@ -722,12 +722,12 @@ static jboolean copsResponseNative(JNIEnv* env, jobject /* object */, jstring operator_str, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -735,7 +735,8 @@ static jboolean copsResponseNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending cops response, status: %d", status); + log::error("Failed sending cops response, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); env->ReleaseStringUTFChars(operator_str, operator_name); @@ -748,12 +749,12 @@ static jboolean cindResponseNative(JNIEnv* env, jobject /* object */, jint battery_charge, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -762,7 +763,7 @@ static jboolean cindResponseNative(JNIEnv* env, jobject /* object */, (bluetooth::headset::bthf_call_state_t)call_state, signal, roam, battery_charge, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: failed, status: %d", __func__, status); + log::error("failed, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -773,12 +774,12 @@ static jboolean atResponseStringNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -786,7 +787,8 @@ static jboolean atResponseStringNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed formatted AT response, status: %d", status); + log::error("Failed formatted AT response, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); env->ReleaseStringUTFChars(response_str, response); @@ -798,12 +800,12 @@ static jboolean atResponseCodeNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -811,7 +813,7 @@ static jboolean atResponseCodeNative(JNIEnv* env, jobject /* object */, (bluetooth::headset::bthf_at_response_t)response_code, cmee_code, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed AT response, status: %d", status); + log::error("Failed AT response, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -823,12 +825,12 @@ static jboolean clccResponseNative(JNIEnv* env, jobject /* object */, jint type, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -845,7 +847,8 @@ static jboolean clccResponseNative(JNIEnv* env, jobject /* object */, number, (bluetooth::headset::bthf_call_addrtype_t)type, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending CLCC response, status: %d", status); + log::error("Failed sending CLCC response, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); if (number) { @@ -861,12 +864,12 @@ static jboolean phoneStateChangeNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } @@ -880,7 +883,8 @@ static jboolean phoneStateChangeNative(JNIEnv* env, jobject /* object */, number, (bluetooth::headset::bthf_call_addrtype_t)type, name, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed report phone state change, status: %d", status); + log::error("Failed report phone state change, status: {}", + bt_status_text(status)); } env->ReleaseStringUTFChars(number_str, number); if (name != nullptr) { @@ -894,12 +898,12 @@ static jboolean setScoAllowedNative(JNIEnv* /* env */, jobject /* object */, jboolean value) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed HF set sco allowed, status: %d", status); + log::error("Failed HF set sco allowed, status: {}", bt_status_text(status)); } return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } @@ -908,19 +912,20 @@ static jboolean sendBsirNative(JNIEnv* env, jobject /* object */, jboolean value, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed sending BSIR, value=%d, status=%d", value, status); + log::error("Failed sending BSIR, value={}, status={}", value, + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -930,19 +935,20 @@ static jboolean setActiveDeviceNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sBluetoothHfpInterface) { - ALOGW("%s: sBluetoothHfpInterface is null", __func__); + log::warn("sBluetoothHfpInterface is null"); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("%s: failed to get device address", __func__); + log::error("failed to get device address"); jniThrowIOException(env, EINVAL); return JNI_FALSE; } bt_status_t status = sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to set active device, status: %d", status); + log::error("Failed to set active device, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; diff --git a/android/app/jni/com_android_bluetooth_hfpclient.cpp b/android/app/jni/com_android_bluetooth_hfpclient.cpp index b5d5910372fc1e2bc30c483d4148d6d1ee48b3c2..f51255bf6e97c680b63b360b472ca077a424d53c 100644 --- a/android/app/jni/com_android_bluetooth_hfpclient.cpp +++ b/android/app/jni/com_android_bluetooth_hfpclient.cpp @@ -17,11 +17,11 @@ #define LOG_TAG "BluetoothHeadsetClientServiceJni" +#include + #include "com_android_bluetooth.h" #include "hardware/bt_hf_client.h" -#include "utils/Log.h" - -#include +#include "os/logging/log_adapter.h" namespace android { @@ -60,7 +60,7 @@ static jbyteArray marshall_bda(const RawAddress* bd_addr) { jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); if (!addr) { - ALOGE("Fail to new jbyteArray bd addr"); + log::error("Fail to new jbyteArray bd addr"); return NULL; } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), @@ -79,7 +79,7 @@ static void connection_state_cb(const RawAddress* bd_addr, ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) return; - ALOGD("%s: state %d peer_feat %d chld_feat %d", __func__, state, peer_feat, chld_feat); + log::debug("state {} peer_feat {} chld_feat {}", state, peer_feat, chld_feat); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jint)state, (jint)peer_feat, (jint)chld_feat, addr.get()); @@ -170,7 +170,7 @@ static void current_operator_cb(const RawAddress* bd_addr, const char* name) { const char null_str[] = ""; if (!sCallbackEnv.isValidUtf(name)) { - ALOGE("%s: name is not a valid UTF string.", __func__); + log::error("name is not a valid UTF string."); name = null_str; } @@ -201,9 +201,7 @@ static void callsetup_cb(const RawAddress* bd_addr, ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) return; - ALOGD("callsetup_cb bdaddr %02x:%02x:%02x:%02x:%02x:%02x", - bd_addr->address[0], bd_addr->address[1], bd_addr->address[2], - bd_addr->address[3], bd_addr->address[4], bd_addr->address[5]); + log::debug("callsetup_cb bdaddr {}", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCallSetup, (jint)callsetup, addr.get()); @@ -245,7 +243,7 @@ static void clip_cb(const RawAddress* bd_addr, const char* number) { const char null_str[] = ""; if (!sCallbackEnv.isValidUtf(number)) { - ALOGE("%s: number is not a valid UTF string.", __func__); + log::error("number is not a valid UTF string."); number = null_str; } @@ -265,7 +263,7 @@ static void call_waiting_cb(const RawAddress* bd_addr, const char* number) { const char null_str[] = ""; if (!sCallbackEnv.isValidUtf(number)) { - ALOGE("%s: number is not a valid UTF string.", __func__); + log::error("number is not a valid UTF string."); number = null_str; } @@ -289,7 +287,7 @@ static void current_calls_cb(const RawAddress* bd_addr, int index, const char null_str[] = ""; if (!sCallbackEnv.isValidUtf(number)) { - ALOGE("%s: number is not a valid UTF string.", __func__); + log::error("number is not a valid UTF string."); number = null_str; } @@ -334,7 +332,7 @@ static void subscriber_info_cb(const RawAddress* bd_addr, const char* name, const char null_str[] = ""; if (!sCallbackEnv.isValidUtf(name)) { - ALOGE("%s: name is not a valid UTF string.", __func__); + log::error("name is not a valid UTF string."); name = null_str; } @@ -367,7 +365,7 @@ static void last_voice_tag_number_cb(const RawAddress* bd_addr, const char null_str[] = ""; if (!sCallbackEnv.isValidUtf(number)) { - ALOGE("%s: number is not a valid UTF string.", __func__); + log::error("number is not a valid UTF string."); number = null_str; } @@ -430,24 +428,24 @@ static bthf_client_callbacks_t sBluetoothHfpClientCallbacks = { }; static void initializeNative(JNIEnv* env, jobject object) { - ALOGD("%s: HfpClient", __func__); + log::debug("HfpClient"); std::unique_lock interface_lock(interface_mutex); std::unique_lock callbacks_lock(callbacks_mutex); const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothHfpClientInterface != NULL) { - ALOGW("Cleaning up Bluetooth HFP Client Interface before initializing"); + log::warn("Cleaning up Bluetooth HFP Client Interface before initializing"); sBluetoothHfpClientInterface->cleanup(); sBluetoothHfpClientInterface = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth HFP Client callback object"); + log::warn("Cleaning up Bluetooth HFP Client callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -456,14 +454,15 @@ static void initializeNative(JNIEnv* env, jobject object) { (bthf_client_interface_t*)btInf->get_profile_interface( BT_PROFILE_HANDSFREE_CLIENT_ID); if (sBluetoothHfpClientInterface == NULL) { - ALOGE("Failed to get Bluetooth HFP Client Interface"); + log::error("Failed to get Bluetooth HFP Client Interface"); return; } bt_status_t status = sBluetoothHfpClientInterface->init(&sBluetoothHfpClientCallbacks); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to initialize Bluetooth HFP Client, status: %d", status); + log::error("Failed to initialize Bluetooth HFP Client, status: {}", + bt_status_text(status)); sBluetoothHfpClientInterface = NULL; return; } @@ -477,18 +476,18 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothHfpClientInterface != NULL) { - ALOGW("Cleaning up Bluetooth HFP Client Interface..."); + log::warn("Cleaning up Bluetooth HFP Client Interface..."); sBluetoothHfpClientInterface->cleanup(); sBluetoothHfpClientInterface = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth HFP Client callback object"); + log::warn("Cleaning up Bluetooth HFP Client callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -508,7 +507,7 @@ static jboolean connectNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->connect((const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed AG connection, status: %d", status); + log::error("Failed AG connection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -528,7 +527,7 @@ static jboolean disconnectNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->disconnect((const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed AG disconnection, status: %d", status); + log::error("Failed AG disconnection, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -548,7 +547,8 @@ static jboolean connectAudioNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->connect_audio((const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed AG audio connection, status: %d", status); + log::error("Failed AG audio connection, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -568,7 +568,8 @@ static jboolean disconnectAudioNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->disconnect_audio((const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed AG audio disconnection, status: %d", status); + log::error("Failed AG audio disconnection, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -588,7 +589,8 @@ static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->start_voice_recognition( (const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to start voice recognition, status: %d", status); + log::error("Failed to start voice recognition, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -608,7 +610,8 @@ static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->stop_voice_recognition( (const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to stop voice recognition, status: %d", status); + log::error("Failed to stop voice recognition, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -629,7 +632,7 @@ static jboolean setVolumeNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->volume_control( (const RawAddress*)addr, (bthf_client_volume_type_t)volume_type, volume); if (status != BT_STATUS_SUCCESS) { - ALOGE("FAILED to control volume, status: %d", status); + log::error("FAILED to control volume, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -655,7 +658,7 @@ static jboolean dialNative(JNIEnv* env, jobject /* object */, number == nullptr ? "" : number); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to dial, status: %d", status); + log::error("Failed to dial, status: {}", bt_status_text(status)); } if (number != nullptr) { env->ReleaseStringUTFChars(number_str, number); @@ -678,7 +681,8 @@ static jboolean dialMemoryNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->dial_memory( (const RawAddress*)addr, (int)location); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to dial from memory, status: %d", status); + log::error("Failed to dial from memory, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -701,7 +705,8 @@ static jboolean handleCallActionNative(JNIEnv* env, jobject /* object */, (const RawAddress*)addr, (bthf_client_call_action_t)action, (int)index); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to enter private mode, status: %d", status); + log::error("Failed to enter private mode, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -722,7 +727,8 @@ static jboolean queryCurrentCallsNative(JNIEnv* env, jobject /* object */, (const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to query current calls, status: %d", status); + log::error("Failed to query current calls, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; @@ -744,7 +750,8 @@ static jboolean queryCurrentOperatorNameNative(JNIEnv* env, sBluetoothHfpClientInterface->query_current_operator_name( (const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to query current operator name, status: %d", status); + log::error("Failed to query current operator name, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -765,7 +772,8 @@ static jboolean retrieveSubscriberInfoNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->retrieve_subscriber_info( (const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to retrieve subscriber info, status: %d", status); + log::error("Failed to retrieve subscriber info, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -786,7 +794,7 @@ static jboolean sendDtmfNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHfpClientInterface->send_dtmf( (const RawAddress*)addr, (char)code); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to send DTMF, status: %d", status); + log::error("Failed to send DTMF, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -810,7 +818,8 @@ static jboolean requestLastVoiceTagNumberNative(JNIEnv* env, (const RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to request last Voice Tag number, status: %d", status); + log::error("Failed to request last Voice Tag number, status: {}", + bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -837,7 +846,7 @@ static jboolean sendATCmdNative(JNIEnv* env, jobject /* object */, (const RawAddress*)addr, cmd, val1, val2, arg); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to send cmd, status: %d", status); + log::error("Failed to send cmd, status: {}", bt_status_text(status)); } if (arg != NULL) { @@ -868,7 +877,7 @@ static jboolean sendAndroidAtNative(JNIEnv* env, jobject /* object */, (const RawAddress*)addr, arg); if (status != BT_STATUS_SUCCESS) { - ALOGE("FAILED to control volume, status: %d", status); + log::error("FAILED to control volume, status: {}", bt_status_text(status)); } if (arg != NULL) { diff --git a/android/app/jni/com_android_bluetooth_hid_device.cpp b/android/app/jni/com_android_bluetooth_hid_device.cpp index 4a7c1553e1f45799ad12ac5b4f1e332909222302..e4cff153af6d3cff9c76a2fdf6a466ee46eede01 100644 --- a/android/app/jni/com_android_bluetooth_hid_device.cpp +++ b/android/app/jni/com_android_bluetooth_hid_device.cpp @@ -41,7 +41,7 @@ static jbyteArray marshall_bda(RawAddress* bd_addr) { jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); if (!addr) { - ALOGE("Fail to new jbyteArray bd addr"); + log::error("Fail to new jbyteArray bd addr"); return NULL; } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), @@ -64,7 +64,7 @@ static void application_state_callback(RawAddress* bd_addr, if (bd_addr) { addr.reset(marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("%s: failed to allocate storage for bt_addr", __FUNCTION__); + log::error("failed to allocate storage for bt_addr"); return; } } @@ -79,7 +79,7 @@ static void connection_state_callback(RawAddress* bd_addr, ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("%s: failed to allocate storage for bt_addr", __FUNCTION__); + log::error("failed to allocate storage for bt_addr"); return; } @@ -102,7 +102,7 @@ static void set_report_callback(uint8_t type, uint8_t id, uint16_t len, ScopedLocalRef data(sCallbackEnv.get(), sCallbackEnv->NewByteArray(len)); if (!data.get()) { - ALOGE("%s: failed to allocate storage for report data", __FUNCTION__); + log::error("failed to allocate storage for report data"); return; } sCallbackEnv->SetByteArrayRegion(data.get(), 0, len, (jbyte*)p_data); @@ -124,7 +124,7 @@ static void intr_data_callback(uint8_t report_id, uint16_t len, ScopedLocalRef data(sCallbackEnv.get(), sCallbackEnv->NewByteArray(len)); if (!data.get()) { - ALOGE("%s: failed to allocate storage for report data", __FUNCTION__); + log::error("failed to allocate storage for report data"); return; } sCallbackEnv->SetByteArrayRegion(data.get(), 0, len, (jbyte*)p_data); @@ -154,58 +154,58 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btif; bt_status_t status; - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if ((btif = getBluetoothInterface()) == NULL) { - ALOGE("Cannot obtain BT interface"); + log::error("Cannot obtain BT interface"); return; } if (sHiddIf != NULL) { - ALOGW("Cleaning up interface"); + log::warn("Cleaning up interface"); sHiddIf->cleanup(); sHiddIf = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up callback object"); + log::warn("Cleaning up callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } if ((sHiddIf = (bthd_interface_t*)btif->get_profile_interface( BT_PROFILE_HIDDEV_ID)) == NULL) { - ALOGE("Cannot obtain interface"); + log::error("Cannot obtain interface"); return; } if ((status = sHiddIf->init(&sHiddCb)) != BT_STATUS_SUCCESS) { - ALOGE("Failed to initialize interface (%d)", status); + log::error("Failed to initialize interface ({})", bt_status_text(status)); sHiddIf = NULL; return; } mCallbacksObj = env->NewGlobalRef(object); - ALOGV("%s done", __FUNCTION__); + log::verbose("done"); } static void cleanupNative(JNIEnv* env, jobject /* object */) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if (sHiddIf != NULL) { - ALOGI("Cleaning up interface"); + log::info("Cleaning up interface"); sHiddIf->cleanup(); sHiddIf = NULL; } if (mCallbacksObj != NULL) { - ALOGI("Cleaning up callback object"); + log::info("Cleaning up callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } - ALOGV("%s done", __FUNCTION__); + log::verbose("done"); } static void fill_qos(JNIEnv* env, jintArray in, bthd_qos_param_t* out) { @@ -241,10 +241,10 @@ static jboolean registerAppNative(JNIEnv* env, jobject /* thiz */, jstring name, jstring description, jstring provider, jbyte subclass, jbyteArray descriptors, jintArray p_in_qos, jintArray p_out_qos) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } @@ -273,7 +273,7 @@ static jboolean registerAppNative(JNIEnv* env, jobject /* thiz */, jstring name, bt_status_t ret = sHiddIf->register_app(&app_param, &in_qos, &out_qos); - ALOGV("%s: register_app() returned %d", __FUNCTION__, ret); + log::verbose("register_app() returned {}", bt_status_text(ret)); if (ret == BT_STATUS_SUCCESS) { result = JNI_TRUE; @@ -286,30 +286,30 @@ static jboolean registerAppNative(JNIEnv* env, jobject /* thiz */, jstring name, free(data); } - ALOGV("%s done (%d)", __FUNCTION__, result); + log::verbose("done ({})", result); return result; } static jboolean unregisterAppNative(JNIEnv* /* env */, jobject /* thiz */) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); jboolean result = JNI_FALSE; if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } bt_status_t ret = sHiddIf->unregister_app(); - ALOGV("%s: unregister_app() returned %d", __FUNCTION__, ret); + log::verbose("unregister_app() returned {}", bt_status_text(ret)); if (ret == BT_STATUS_SUCCESS) { result = JNI_TRUE; } - ALOGV("%s done (%d)", __FUNCTION__, result); + log::verbose("done ({})", result); return result; } @@ -319,7 +319,7 @@ static jboolean sendReportNative(JNIEnv* env, jobject /* thiz */, jint id, jboolean result = JNI_FALSE; if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } @@ -347,10 +347,10 @@ static jboolean sendReportNative(JNIEnv* env, jobject /* thiz */, jint id, static jboolean replyReportNative(JNIEnv* env, jobject /* thiz */, jbyte type, jbyte id, jbyteArray data) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } @@ -368,7 +368,7 @@ static jboolean replyReportNative(JNIEnv* env, jobject /* thiz */, jbyte type, bt_status_t ret = sHiddIf->send_report((bthd_report_type_t)report_type, id, size, buf); - ALOGV("%s: send_report() returned %d", __FUNCTION__, ret); + log::verbose("send_report() returned {}", bt_status_text(ret)); if (ret == BT_STATUS_SUCCESS) { result = JNI_TRUE; @@ -377,17 +377,17 @@ static jboolean replyReportNative(JNIEnv* env, jobject /* thiz */, jbyte type, free(buf); } - ALOGV("%s done (%d)", __FUNCTION__, result); + log::verbose("done ({})", result); return result; } static jboolean reportErrorNative(JNIEnv* /* env */, jobject /* thiz */, jbyte error) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } @@ -395,22 +395,22 @@ static jboolean reportErrorNative(JNIEnv* /* env */, jobject /* thiz */, bt_status_t ret = sHiddIf->report_error(error); - ALOGV("%s: report_error() returned %d", __FUNCTION__, ret); + log::verbose("report_error() returned {}", bt_status_text(ret)); if (ret == BT_STATUS_SUCCESS) { result = JNI_TRUE; } - ALOGV("%s done (%d)", __FUNCTION__, result); + log::verbose("done ({})", result); return result; } static jboolean unplugNative(JNIEnv* /* env */, jobject /* thiz */) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } @@ -418,23 +418,23 @@ static jboolean unplugNative(JNIEnv* /* env */, jobject /* thiz */) { bt_status_t ret = sHiddIf->virtual_cable_unplug(); - ALOGV("%s: virtual_cable_unplug() returned %d", __FUNCTION__, ret); + log::verbose("virtual_cable_unplug() returned {}", bt_status_text(ret)); if (ret == BT_STATUS_SUCCESS) { result = JNI_TRUE; } - ALOGV("%s done (%d)", __FUNCTION__, result); + log::verbose("done ({})", result); return result; } static jboolean connectNative(JNIEnv* env, jobject /* thiz */, jbyteArray address) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } @@ -442,28 +442,28 @@ static jboolean connectNative(JNIEnv* env, jobject /* thiz */, jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } bt_status_t ret = sHiddIf->connect((RawAddress*)addr); - ALOGV("%s: connect() returned %d", __FUNCTION__, ret); + log::verbose("connect() returned {}", bt_status_text(ret)); if (ret == BT_STATUS_SUCCESS) { result = JNI_TRUE; } - ALOGV("%s done (%d)", __FUNCTION__, result); + log::verbose("done ({})", result); return result; } static jboolean disconnectNative(JNIEnv* /* env */, jobject /* thiz */) { - ALOGV("%s enter", __FUNCTION__); + log::verbose("enter"); if (!sHiddIf) { - ALOGE("%s: Failed to get the Bluetooth HIDD Interface", __func__); + log::error("Failed to get the Bluetooth HIDD Interface"); return JNI_FALSE; } @@ -471,13 +471,13 @@ static jboolean disconnectNative(JNIEnv* /* env */, jobject /* thiz */) { bt_status_t ret = sHiddIf->disconnect(); - ALOGV("%s: disconnect() returned %d", __FUNCTION__, ret); + log::verbose("disconnect() returned {}", bt_status_text(ret)); if (ret == BT_STATUS_SUCCESS) { result = JNI_TRUE; } - ALOGV("%s done (%d)", __FUNCTION__, result); + log::verbose("done ({})", result); return result; } diff --git a/android/app/jni/com_android_bluetooth_hid_host.cpp b/android/app/jni/com_android_bluetooth_hid_host.cpp index e89ce844c29a069b47dcb90dfb7c7ebdbde3661a..b21fc9c5b5b35f894173c20e7040e064c316e28f 100644 --- a/android/app/jni/com_android_bluetooth_hid_host.cpp +++ b/android/app/jni/com_android_bluetooth_hid_host.cpp @@ -41,7 +41,7 @@ static jbyteArray marshall_bda(RawAddress* bd_addr) { jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); if (!addr) { - ALOGE("Fail to new jbyteArray bd addr"); + log::error("Fail to new jbyteArray bd addr"); return NULL; } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), @@ -55,12 +55,12 @@ static void connection_state_callback(RawAddress* bd_addr, CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!mCallbacksObj) { - ALOGE("%s: mCallbacksObj is null", __func__); + log::error("mCallbacksObj is null"); return; } ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for HID channel state"); + log::error("Fail to new jbyteArray bd addr for HID channel state"); return; } @@ -75,17 +75,17 @@ static void get_protocol_mode_callback(RawAddress* bd_addr, CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!mCallbacksObj) { - ALOGE("%s: mCallbacksObj is null", __func__); + log::error("mCallbacksObj is null"); return; } if (hh_status != BTHH_OK) { - ALOGE("BTHH Status is not OK!"); + log::error("BTHH Status is not OK!"); return; } ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for get protocal mode callback"); + log::error("Fail to new jbyteArray bd addr for get protocol mode callback"); return; } @@ -99,23 +99,23 @@ static void get_report_callback(RawAddress* bd_addr, bthh_status_t hh_status, CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!mCallbacksObj) { - ALOGE("%s: mCallbacksObj is null", __func__); + log::error("mCallbacksObj is null"); return; } if (hh_status != BTHH_OK) { - ALOGE("BTHH Status is not OK!"); + log::error("BTHH Status is not OK!"); return; } ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for get report callback"); + log::error("Fail to new jbyteArray bd addr for get report callback"); return; } ScopedLocalRef data(sCallbackEnv.get(), sCallbackEnv->NewByteArray(rpt_size)); if (!data.get()) { - ALOGE("Fail to new jbyteArray data for get report callback"); + log::error("Fail to new jbyteArray data for get report callback"); return; } @@ -126,17 +126,17 @@ static void get_report_callback(RawAddress* bd_addr, bthh_status_t hh_status, static void virtual_unplug_callback(RawAddress* bd_addr, bthh_status_t hh_status) { - ALOGV("call to virtual_unplug_callback"); + log::verbose("call to virtual_unplug_callback"); std::shared_lock lock(mCallbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!mCallbacksObj) { - ALOGE("%s: mCallbacksObj is null", __func__); + log::error("mCallbacksObj is null"); return; } ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for HID channel state"); + log::error("Fail to new jbyteArray bd addr for HID channel state"); return; } sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVirtualUnplug, @@ -148,13 +148,13 @@ static void handshake_callback(RawAddress* bd_addr, bthh_status_t hh_status) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; if (!mCallbacksObj) { - ALOGE("%s: mCallbacksObj is null", __func__); + log::error("mCallbacksObj is null"); return; } ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("Fail to new jbyteArray bd addr for handshake callback"); + log::error("Fail to new jbyteArray bd addr for handshake callback"); return; } sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHandshake, addr.get(), @@ -170,7 +170,7 @@ static void get_idle_time_callback(RawAddress* bd_addr, ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - ALOGE("%s: Fail to new jbyteArray bd addr", __func__); + log::error("Fail to new jbyteArray bd addr"); return; } sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIdleTime, addr.get(), @@ -192,18 +192,18 @@ static void initializeNative(JNIEnv* env, jobject object) { std::unique_lock lock(mCallbacks_mutex); const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothHidInterface != NULL) { - ALOGW("Cleaning up Bluetooth HID Interface before initializing..."); + log::warn("Cleaning up Bluetooth HID Interface before initializing..."); sBluetoothHidInterface->cleanup(); sBluetoothHidInterface = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth GID callback object"); + log::warn("Cleaning up Bluetooth GID callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -211,13 +211,14 @@ static void initializeNative(JNIEnv* env, jobject object) { sBluetoothHidInterface = (bthh_interface_t*)btInf->get_profile_interface(BT_PROFILE_HIDHOST_ID); if (sBluetoothHidInterface == NULL) { - ALOGE("Failed to get Bluetooth HID Interface"); + log::error("Failed to get Bluetooth HID Interface"); return; } bt_status_t status = sBluetoothHidInterface->init(&sBluetoothHidCallbacks); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed to initialize Bluetooth HID, status: %d", status); + log::error("Failed to initialize Bluetooth HID, status: {}", + bt_status_text(status)); sBluetoothHidInterface = NULL; return; } @@ -230,18 +231,18 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothHidInterface != NULL) { - ALOGW("Cleaning up Bluetooth HID Interface..."); + log::warn("Cleaning up Bluetooth HID Interface..."); sBluetoothHidInterface->cleanup(); sBluetoothHidInterface = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth GID callback object"); + log::warn("Cleaning up Bluetooth GID callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -253,14 +254,15 @@ static jboolean connectHidNative(JNIEnv* env, jobject /* object */, jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } jboolean ret = JNI_TRUE; bt_status_t status = sBluetoothHidInterface->connect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS && status != BT_STATUS_BUSY) { - ALOGE("Failed HID channel connection, status: %d", status); + log::error("Failed HID channel connection, status: {}", + bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); @@ -276,13 +278,14 @@ static jboolean disconnectHidNative(JNIEnv* env, jobject /* object */, addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } bt_status_t status = sBluetoothHidInterface->disconnect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed disconnect hid channel, status: %d", status); + log::error("Failed disconnect hid channel, status: {}", + bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); @@ -296,7 +299,7 @@ static jboolean getProtocolModeNative(JNIEnv* env, jobject /* object */, jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } @@ -306,7 +309,7 @@ static jboolean getProtocolModeNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHidInterface->get_protocol( (RawAddress*)addr, (bthh_protocol_mode_t)protocolMode); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed get protocol mode, status: %d", status); + log::error("Failed get protocol mode, status: {}", bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); @@ -320,7 +323,7 @@ static jboolean virtualUnPlugNative(JNIEnv* env, jobject /* object */, jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } @@ -328,7 +331,7 @@ static jboolean virtualUnPlugNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHidInterface->virtual_unplug((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed virual unplug, status: %d", status); + log::error("Failed virual unplug, status: {}", bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); @@ -339,11 +342,11 @@ static jboolean setProtocolModeNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint protocolMode) { if (!sBluetoothHidInterface) return JNI_FALSE; - ALOGD("%s: protocolMode = %d", __func__, protocolMode); + log::debug("protocolMode = {}", protocolMode); jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } @@ -356,7 +359,7 @@ static jboolean setProtocolModeNative(JNIEnv* env, jobject /* object */, mode = BTHH_BOOT_MODE; break; default: - ALOGE("Unknown HID protocol mode"); + log::error("Unknown HID protocol mode"); return JNI_FALSE; } @@ -364,7 +367,7 @@ static jboolean setProtocolModeNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHidInterface->set_protocol((RawAddress*)addr, mode); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed set protocol mode, status: %d", status); + log::error("Failed set protocol mode, status: {}", bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); @@ -375,13 +378,13 @@ static jboolean setProtocolModeNative(JNIEnv* env, jobject /* object */, static jboolean getReportNative(JNIEnv* env, jobject /* object */, jbyteArray address, jbyte reportType, jbyte reportId, jint bufferSize) { - ALOGV("%s: reportType = %d, reportId = %d, bufferSize = %d", __func__, - reportType, reportId, bufferSize); + log::verbose("reportType = {}, reportId = {}, bufferSize = {}", reportType, + reportId, bufferSize); if (!sBluetoothHidInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } @@ -392,7 +395,7 @@ static jboolean getReportNative(JNIEnv* env, jobject /* object */, (RawAddress*)addr, (bthh_report_type_t)rType, (uint8_t)rId, bufferSize); jboolean ret = JNI_TRUE; if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed get report, status: %d", status); + log::error("Failed get report, status: {}", bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); @@ -403,12 +406,12 @@ static jboolean getReportNative(JNIEnv* env, jobject /* object */, static jboolean setReportNative(JNIEnv* env, jobject /* object */, jbyteArray address, jbyte reportType, jstring report) { - ALOGV("%s: reportType = %d", __func__, reportType); + log::verbose("reportType = {}", reportType); if (!sBluetoothHidInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } jint rType = reportType; @@ -418,7 +421,7 @@ static jboolean setReportNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHidInterface->set_report( (RawAddress*)addr, (bthh_report_type_t)rType, (char*)c_report); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed set report, status: %d", status); + log::error("Failed set report, status: {}", bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseStringUTFChars(report, c_report); @@ -429,13 +432,13 @@ static jboolean setReportNative(JNIEnv* env, jobject /* object */, static jboolean sendDataNative(JNIEnv* env, jobject /* object */, jbyteArray address, jstring report) { - ALOGV("%s", __func__); + log::verbose(""); jboolean ret = JNI_TRUE; if (!sBluetoothHidInterface) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } @@ -444,7 +447,7 @@ static jboolean sendDataNative(JNIEnv* env, jobject /* object */, bt_status_t status = sBluetoothHidInterface->send_data((RawAddress*)addr, (char*)c_report); if (status != BT_STATUS_SUCCESS) { - ALOGE("Failed set data, status: %d", status); + log::error("Failed set data, status: {}", bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseStringUTFChars(report, c_report); @@ -459,13 +462,13 @@ static jboolean getIdleTimeNative(JNIEnv* env, jobject /* object */, jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("%s: Bluetooth device address null", __func__); + log::error("Bluetooth device address null"); return JNI_FALSE; } bt_status_t status = sBluetoothHidInterface->get_idle_time((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed get idle time, status: %d", __func__, status); + log::error("Failed get idle time, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); @@ -478,14 +481,14 @@ static jboolean setIdleTimeNative(JNIEnv* env, jobject /* object */, jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - ALOGE("%s: Bluetooth device address null", __func__); + log::error("Bluetooth device address null"); return JNI_FALSE; } bt_status_t status = sBluetoothHidInterface->set_idle_time((RawAddress*)addr, idle_time); if (status != BT_STATUS_SUCCESS) { - ALOGE("%s: Failed set idle time, status: %d", __func__, status); + log::error("Failed set idle time, status: {}", bt_status_text(status)); } env->ReleaseByteArrayElements(address, addr, 0); diff --git a/android/app/jni/com_android_bluetooth_le_audio.cpp b/android/app/jni/com_android_bluetooth_le_audio.cpp index e6f07c48f5b6b720e1e722419bf243f2c2c94b89..21996efcdf4243fc01d8cd2e87270d5d01d04b4b 100644 --- a/android/app/jni/com_android_bluetooth_le_audio.cpp +++ b/android/app/jni/com_android_bluetooth_le_audio.cpp @@ -36,6 +36,7 @@ using bluetooth::le_audio::btle_audio_sample_rate_index_t; using bluetooth::le_audio::ConnectionState; using bluetooth::le_audio::GroupNodeStatus; using bluetooth::le_audio::GroupStatus; +using bluetooth::le_audio::GroupStreamStatus; using bluetooth::le_audio::LeAudioBroadcasterCallbacks; using bluetooth::le_audio::LeAudioBroadcasterInterface; using bluetooth::le_audio::LeAudioClientCallbacks; @@ -55,6 +56,7 @@ static jmethodID method_onAudioGroupSelectableCodecConf; static jmethodID method_onHealthBasedRecommendationAction; static jmethodID method_onHealthBasedGroupRecommendationAction; static jmethodID method_onUnicastMonitorModeStatus; +static jmethodID method_onGroupStreamStatus; static struct { jclass clazz; @@ -112,13 +114,13 @@ static std::shared_timed_mutex callbacks_mutex; jobject prepareCodecConfigObj(JNIEnv* env, btle_audio_codec_config_t codecConfig) { - LOG(INFO) << __func__ << "ct: " << codecConfig.codec_type - << ", codec_priority: " << codecConfig.codec_priority - << ", sample_rate: " << codecConfig.sample_rate - << ", bits_per_sample: " << codecConfig.bits_per_sample - << ", channel_count: " << codecConfig.channel_count - << ", frame_duration: " << codecConfig.frame_duration - << ", octets_per_frame: " << codecConfig.octets_per_frame; + log::info( + "ct: {}, codec_priority: {}, sample_rate: {}, bits_per_sample: {}, " + "channel_count: {}, frame_duration: {}, octets_per_frame: {}", + codecConfig.codec_type, codecConfig.codec_priority, + codecConfig.sample_rate, codecConfig.bits_per_sample, + codecConfig.channel_count, codecConfig.frame_duration, + codecConfig.octets_per_frame); jobject codecConfigObj = env->NewObject( android_bluetooth_BluetoothLeAudioCodecConfig.clazz, @@ -152,7 +154,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { ~LeAudioClientCallbacksImpl() = default; void OnInitialized(void) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; @@ -161,8 +163,8 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnConnectionState(ConnectionState state, const RawAddress& bd_addr) override { - LOG(INFO) << __func__ << ", state:" << int(state) - << ", addr: " << bd_addr.ToRedactedStringForLogging(); + log::info("state:{}, addr: {}", int(state), + bd_addr.ToRedactedStringForLogging()); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -171,7 +173,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for connection state"; + log::error("Failed to new jbyteArray bd addr for connection state"); return; } @@ -182,7 +184,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { } void OnGroupStatus(int group_id, GroupStatus group_status) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -194,7 +196,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnGroupNodeStatus(const RawAddress& bd_addr, int group_id, GroupNodeStatus node_status) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -203,7 +205,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for group status"; + log::error("Failed to new jbyteArray bd addr for group status"); return; } @@ -216,7 +218,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnAudioConf(uint8_t direction, int group_id, uint32_t sink_audio_location, uint32_t source_audio_location, uint16_t avail_cont) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -230,7 +232,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnSinkAudioLocationAvailable(const RawAddress& bd_addr, uint32_t sink_audio_location) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -239,7 +241,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for group status"; + log::error("Failed to new jbyteArray bd addr for group status"); return; } @@ -254,7 +256,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { std::vector local_input_capa_codec_conf, std::vector local_output_capa_codec_conf) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -274,7 +276,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnAudioGroupCurrentCodecConf( int group_id, btle_audio_codec_config_t input_codec_conf, btle_audio_codec_config_t output_codec_conf) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -295,7 +297,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { std::vector input_selectable_codec_conf, std::vector output_selectable_codec_conf) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -314,7 +316,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnHealthBasedRecommendationAction( const RawAddress& bd_addr, bluetooth::le_audio::LeAudioHealthBasedAction action) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -323,7 +325,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for group status"; + log::error("Failed to new jbyteArray bd addr for group status"); return; } @@ -337,7 +339,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnHealthBasedGroupRecommendationAction( int group_id, bluetooth::le_audio::LeAudioHealthBasedAction action) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -350,7 +352,7 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { void OnUnicastMonitorModeStatus(uint8_t direction, UnicastMonitorModeStatus status) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -360,6 +362,18 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { method_onUnicastMonitorModeStatus, (jint)direction, (jint)status); } + + void OnGroupStreamStatus(int group_id, + GroupStreamStatus group_stream_status) override { + LOG(INFO) << __func__; + + std::shared_lock lock(callbacks_mutex); + CallbackEnv sCallbackEnv(__func__); + if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; + + sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGroupStreamStatus, + (jint)group_id, (jint)group_stream_status); + } }; static LeAudioClientCallbacksImpl sLeAudioClientCallbacks; @@ -375,7 +389,7 @@ std::vector prepareCodecPreferences( if (!env->IsInstanceOf( jcodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.clazz)) { - ALOGE("%s: Invalid BluetoothLeAudioCodecConfig instance", __func__); + log::error("Invalid BluetoothLeAudioCodecConfig instance"); continue; } jint codecType = env->CallIntMethod( @@ -397,18 +411,18 @@ static void initNative(JNIEnv* env, jobject object, const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } if (mCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up LeAudio callback object"; + log::info("Cleaning up LeAudio callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for LeAudio Callbacks"; + log::error("Failed to allocate Global Ref for LeAudio Callbacks"); return; } @@ -416,8 +430,8 @@ static void initNative(JNIEnv* env, jobject object, (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothLeAudioCodecConfig")); if (android_bluetooth_BluetoothLeAudioCodecConfig.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for " - "BluetoothLeAudioCodecConfig class"; + log::error( + "Failed to allocate Global Ref for BluetoothLeAudioCodecConfig class"); return; } @@ -425,7 +439,7 @@ static void initNative(JNIEnv* env, jobject object, (LeAudioClientInterface*)btInf->get_profile_interface( BT_PROFILE_LE_AUDIO_ID); if (sLeAudioClientInterface == nullptr) { - LOG(ERROR) << "Failed to get Bluetooth LeAudio Interface"; + log::error("Failed to get Bluetooth LeAudio Interface"); return; } @@ -442,7 +456,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } @@ -462,7 +476,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { static jboolean connectLeAudioNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) return JNI_FALSE; @@ -480,7 +494,7 @@ static jboolean connectLeAudioNative(JNIEnv* env, jobject /* object */, static jboolean disconnectLeAudioNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) return JNI_FALSE; @@ -502,7 +516,7 @@ static jboolean setEnableStateNative(JNIEnv* env, jobject /* object */, jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return JNI_FALSE; } @@ -523,7 +537,7 @@ static jboolean groupAddNodeNative(JNIEnv* env, jobject /* object */, jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return JNI_FALSE; } @@ -543,7 +557,7 @@ static jboolean groupRemoveNodeNative(JNIEnv* env, jobject /* object */, jint group_id, jbyteArray address) { std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return JNI_FALSE; } @@ -561,11 +575,11 @@ static jboolean groupRemoveNodeNative(JNIEnv* env, jobject /* object */, static void groupSetActiveNative(JNIEnv* /* env */, jobject /* object */, jint group_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return; } @@ -582,7 +596,7 @@ static void setCodecConfigPreferenceNative(JNIEnv* env, jobject /* object */, android_bluetooth_BluetoothLeAudioCodecConfig.clazz) || !env->IsInstanceOf(outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.clazz)) { - ALOGE("%s: Invalid BluetoothLeAudioCodecConfig instance", __func__); + log::error("Invalid BluetoothLeAudioCodecConfig instance"); return; } @@ -678,7 +692,7 @@ static void setCcidInformationNative(JNIEnv* /* env */, jobject /* object */, jint ccid, jint contextType) { std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return; } @@ -689,7 +703,7 @@ static void setInCallNative(JNIEnv* /* env */, jobject /* object */, jboolean inCall) { std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return; } @@ -700,7 +714,7 @@ static void setUnicastMonitorModeNative(JNIEnv* /* env */, jobject /* object */, jint direction, jboolean enable) { std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return; } @@ -712,7 +726,7 @@ static void sendAudioProfilePreferencesNative( jboolean isDuplexPreferenceLeAudio) { std::shared_lock lock(interface_mutex); if (!sLeAudioClientInterface) { - LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface"; + log::error("Failed to get the Bluetooth LeAudio Interface"); return; } @@ -752,7 +766,7 @@ jbyteArray prepareRawLtvArray( jbyteArray raw_metadata = env->NewByteArray(raw_meta_size); if (!raw_metadata) { - LOG(ERROR) << "Failed to create new jbyteArray for raw LTV"; + log::error("Failed to create new jbyteArray for raw LTV"); return nullptr; } @@ -828,7 +842,7 @@ jobject prepareLeAudioCodecConfigMetadataObject( ScopedLocalRef raw_metadata(env, prepareRawLtvArray(env, metadata)); if (!raw_metadata.get()) { - LOG(ERROR) << "Failed to create raw metadata jbyteArray"; + log::error("Failed to create raw metadata jbyteArray"); return nullptr; } @@ -848,7 +862,7 @@ jobject prepareLeBroadcastChannelObject( env, prepareLeAudioCodecConfigMetadataObject( env, bis_config.codec_specific_params)); if (!meta_object.get()) { - LOG(ERROR) << "Failed to create new metadata object for bis config"; + log::error("Failed to create new metadata object for bis config"); return nullptr; } @@ -874,7 +888,7 @@ jobject prepareLeAudioContentMetadataObject( program_info_str = env->NewStringUTF(p_str.c_str()); if (!program_info_str) { - LOG(ERROR) << "Failed to create new preset name String for preset name"; + log::error("Failed to create new preset name String for preset name"); return nullptr; } } @@ -890,7 +904,7 @@ jobject prepareLeAudioContentMetadataObject( language_str = env->NewStringUTF(l_str.c_str()); if (!language_str) { - LOG(ERROR) << "Failed to create new preset name String for language"; + log::error("Failed to create new preset name String for language"); return nullptr; } } @@ -899,7 +913,7 @@ jobject prepareLeAudioContentMetadataObject( ScopedLocalRef raw_metadata(env, prepareRawLtvArray(env, metadata)); if (!raw_metadata.get()) { - LOG(ERROR) << "Failed to create raw_metadata jbyteArray"; + log::error("Failed to create raw_metadata jbyteArray"); return nullptr; } @@ -926,7 +940,7 @@ jobject prepareLeBroadcastChannelListObject( jobject array = env->NewObject(java_util_ArrayList.clazz, java_util_ArrayList.constructor); if (!array) { - LOG(ERROR) << "Failed to create array for subgroups"; + log::error("Failed to create array for subgroups"); return nullptr; } @@ -934,7 +948,7 @@ jobject prepareLeBroadcastChannelListObject( ScopedLocalRef channel_obj( env, prepareLeBroadcastChannelObject(env, el)); if (!channel_obj.get()) { - LOG(ERROR) << "Failed to create new channel object"; + log::error("Failed to create new channel object"); return nullptr; } @@ -956,21 +970,21 @@ jobject prepareLeBroadcastSubgroupObject( env, prepareLeAudioCodecConfigMetadataObject( env, subgroup.codec_config.codec_specific_params)); if (!codec_config_meta_obj.get()) { - LOG(ERROR) << "Failed to create new codec config metadata"; + log::error("Failed to create new codec config metadata"); return nullptr; } ScopedLocalRef content_meta_obj( env, prepareLeAudioContentMetadataObject(env, subgroup.metadata)); if (!content_meta_obj.get()) { - LOG(ERROR) << "Failed to create new codec config metadata"; + log::error("Failed to create new codec config metadata"); return nullptr; } ScopedLocalRef channel_list_obj( env, prepareLeBroadcastChannelListObject(env, subgroup.bis_configs)); if (!channel_list_obj.get()) { - LOG(ERROR) << "Failed to create new codec config metadata"; + log::error("Failed to create new codec config metadata"); return nullptr; } @@ -989,7 +1003,7 @@ jobject prepareLeBroadcastSubgroupListObject( jobject array = env->NewObject(java_util_ArrayList.clazz, java_util_ArrayList.constructor); if (!array) { - LOG(ERROR) << "Failed to create array for subgroups"; + log::error("Failed to create array for subgroups"); return nullptr; } @@ -997,7 +1011,7 @@ jobject prepareLeBroadcastSubgroupListObject( ScopedLocalRef subgroup_obj( env, prepareLeBroadcastSubgroupObject(env, el)); if (!subgroup_obj.get()) { - LOG(ERROR) << "Failed to create new subgroup object"; + log::error("Failed to create new subgroup object"); return nullptr; } @@ -1016,7 +1030,7 @@ jobject prepareBluetoothDeviceObject(JNIEnv* env, const RawAddress& addr, ScopedLocalRef addr_jstr(env, env->NewStringUTF(addr_str.c_str())); if (!addr_jstr.get()) { - LOG(ERROR) << "Failed to create new preset name String for preset name"; + log::error("Failed to create new preset name String for preset name"); return nullptr; } @@ -1032,7 +1046,7 @@ jobject prepareBluetoothLeBroadcastMetadataObject( env, prepareBluetoothDeviceObject(env, broadcast_metadata.addr, broadcast_metadata.addr_type)); if (!device_obj.get()) { - LOG(ERROR) << "Failed to create new BluetoothDevice"; + log::error("Failed to create new BluetoothDevice"); return nullptr; } @@ -1041,7 +1055,7 @@ jobject prepareBluetoothLeBroadcastMetadataObject( prepareLeBroadcastSubgroupListObject( env, broadcast_metadata.basic_audio_announcement.subgroup_configs)); if (!subgroup_list_obj.get()) { - LOG(ERROR) << "Failed to create new Subgroup array"; + log::error("Failed to create new Subgroup array"); return nullptr; } @@ -1057,7 +1071,7 @@ jobject prepareBluetoothLeBroadcastMetadataObject( ScopedLocalRef code(env, env->NewByteArray(nativeCodeSize)); if (!code.get()) { - LOG(ERROR) << "Failed to create new jbyteArray for the broadcast code"; + log::error("Failed to create new jbyteArray for the broadcast code"); return nullptr; } @@ -1071,7 +1085,7 @@ jobject prepareBluetoothLeBroadcastMetadataObject( ScopedLocalRef broadcast_name( env, env->NewStringUTF(broadcast_metadata.broadcast_name.c_str())); if (!broadcast_name.get()) { - LOG(ERROR) << "Failed to create new broadcast name String"; + log::error("Failed to create new broadcast name String"); return nullptr; } @@ -1091,7 +1105,7 @@ jobject prepareBluetoothLeBroadcastMetadataObject( env, prepareLeAudioContentMetadataObject( env, broadcast_metadata.public_announcement.metadata)); if (!public_meta_obj.get()) { - LOG(ERROR) << "Failed to create new public metadata obj"; + log::error("Failed to create new public metadata obj"); return nullptr; } @@ -1114,7 +1128,7 @@ class LeAudioBroadcasterCallbacksImpl : public LeAudioBroadcasterCallbacks { ~LeAudioBroadcasterCallbacksImpl() = default; void OnBroadcastCreated(uint32_t broadcast_id, bool success) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterCallbacksMutex); CallbackEnv sCallbackEnv(__func__); @@ -1126,7 +1140,7 @@ class LeAudioBroadcasterCallbacksImpl : public LeAudioBroadcasterCallbacks { } void OnBroadcastDestroyed(uint32_t broadcast_id) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterCallbacksMutex); CallbackEnv sCallbackEnv(__func__); @@ -1139,7 +1153,7 @@ class LeAudioBroadcasterCallbacksImpl : public LeAudioBroadcasterCallbacks { void OnBroadcastStateChanged(uint32_t broadcast_id, BroadcastState state) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterCallbacksMutex); CallbackEnv sCallbackEnv(__func__); @@ -1154,7 +1168,7 @@ class LeAudioBroadcasterCallbacksImpl : public LeAudioBroadcasterCallbacks { void OnBroadcastMetadataChanged(uint32_t broadcast_id, const bluetooth::le_audio::BroadcastMetadata& broadcast_metadata) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterCallbacksMutex); CallbackEnv sCallbackEnv(__func__); @@ -1180,21 +1194,21 @@ static void BroadcasterInitNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } android_bluetooth_BluetoothDevice.clazz = (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothDevice")); if (android_bluetooth_BluetoothDevice.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for BluetoothDevice class"; + log::error("Failed to allocate Global Ref for BluetoothDevice class"); return; } java_util_ArrayList.clazz = (jclass)env->NewGlobalRef(env->FindClass("java/util/ArrayList")); if (java_util_ArrayList.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for ArrayList class"; + log::error("Failed to allocate Global Ref for ArrayList class"); return; } @@ -1202,8 +1216,9 @@ static void BroadcasterInitNative(JNIEnv* env, jobject object) { (jclass)env->NewGlobalRef(env->FindClass( "android/bluetooth/BluetoothLeAudioCodecConfigMetadata")); if (android_bluetooth_BluetoothLeAudioCodecConfigMetadata.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for " - "BluetoothLeAudioCodecConfigMetadata class"; + log::error( + "Failed to allocate Global Ref for BluetoothLeAudioCodecConfigMetadata " + "class"); return; } @@ -1211,8 +1226,9 @@ static void BroadcasterInitNative(JNIEnv* env, jobject object) { (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothLeAudioContentMetadata")); if (android_bluetooth_BluetoothLeAudioContentMetadata.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for " - "BluetoothLeAudioContentMetadata class"; + log::error( + "Failed to allocate Global Ref for BluetoothLeAudioContentMetadata " + "class"); return; } @@ -1220,8 +1236,8 @@ static void BroadcasterInitNative(JNIEnv* env, jobject object) { (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothLeBroadcastSubgroup")); if (android_bluetooth_BluetoothLeBroadcastSubgroup.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for " - "BluetoothLeBroadcastSubgroup class"; + log::error( + "Failed to allocate Global Ref for BluetoothLeBroadcastSubgroup class"); return; } @@ -1229,8 +1245,8 @@ static void BroadcasterInitNative(JNIEnv* env, jobject object) { (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothLeBroadcastChannel")); if (android_bluetooth_BluetoothLeBroadcastChannel.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for " - "BluetoothLeBroadcastChannel class"; + log::error( + "Failed to allocate Global Ref for BluetoothLeBroadcastChannel class"); return; } @@ -1238,20 +1254,20 @@ static void BroadcasterInitNative(JNIEnv* env, jobject object) { (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothLeBroadcastMetadata")); if (android_bluetooth_BluetoothLeBroadcastMetadata.clazz == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for " - "BluetoothLeBroadcastMetadata class"; + log::error( + "Failed to allocate Global Ref for BluetoothLeBroadcastMetadata class"); return; } if (sBroadcasterCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up LeAudio Broadcaster callback object"; + log::info("Cleaning up LeAudio Broadcaster callback object"); env->DeleteGlobalRef(sBroadcasterCallbacksObj); sBroadcasterCallbacksObj = nullptr; } if ((sBroadcasterCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) - << "Failed to allocate Global Ref for LeAudio Broadcaster Callbacks"; + log::error( + "Failed to allocate Global Ref for LeAudio Broadcaster Callbacks"); return; } @@ -1259,7 +1275,7 @@ static void BroadcasterInitNative(JNIEnv* env, jobject object) { (LeAudioBroadcasterInterface*)btInf->get_profile_interface( BT_PROFILE_LE_AUDIO_BROADCASTER_ID); if (sLeAudioBroadcasterInterface == nullptr) { - LOG(ERROR) << "Failed to get Bluetooth LeAudio Broadcaster Interface"; + log::error("Failed to get Bluetooth LeAudio Broadcaster Interface"); return; } @@ -1272,7 +1288,7 @@ static void BroadcasterStopNative(JNIEnv* /* env */, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } @@ -1288,7 +1304,7 @@ static void BroadcasterCleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } @@ -1348,7 +1364,7 @@ static void CreateBroadcastNative(JNIEnv* env, jobject /* object */, jbyteArray publicMetadata, jintArray qualityArray, jobjectArray metadataArray) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; @@ -1356,7 +1372,7 @@ static void CreateBroadcastNative(JNIEnv* env, jobject /* object */, if (broadcast_code) { jsize size = env->GetArrayLength(broadcast_code); if (size > 16) { - ALOGE("%s: broadcast code to long", __func__); + log::error("broadcast code to long"); return; } @@ -1424,7 +1440,7 @@ static void UpdateMetadataNative(JNIEnv* env, jobject /* object */, static void StartBroadcastNative(JNIEnv* /* env */, jobject /* object */, jint broadcast_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; sLeAudioBroadcasterInterface->StartBroadcast(broadcast_id); @@ -1432,7 +1448,7 @@ static void StartBroadcastNative(JNIEnv* /* env */, jobject /* object */, static void StopBroadcastNative(JNIEnv* /* env */, jobject /* object */, jint broadcast_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; sLeAudioBroadcasterInterface->StopBroadcast(broadcast_id); @@ -1440,7 +1456,7 @@ static void StopBroadcastNative(JNIEnv* /* env */, jobject /* object */, static void PauseBroadcastNative(JNIEnv* /* env */, jobject /* object */, jint broadcast_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; sLeAudioBroadcasterInterface->PauseBroadcast(broadcast_id); @@ -1448,7 +1464,7 @@ static void PauseBroadcastNative(JNIEnv* /* env */, jobject /* object */, static void DestroyBroadcastNative(JNIEnv* /* env */, jobject /* object */, jint broadcast_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; sLeAudioBroadcasterInterface->DestroyBroadcast(broadcast_id); @@ -1456,7 +1472,7 @@ static void DestroyBroadcastNative(JNIEnv* /* env */, jobject /* object */, static void getBroadcastMetadataNative(JNIEnv* /* env */, jobject /* object */, jint broadcast_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(sBroadcasterInterfaceMutex); if (!sLeAudioBroadcasterInterface) return; sLeAudioBroadcasterInterface->GetBroadcastMetadata(broadcast_id); @@ -1609,6 +1625,7 @@ int register_com_android_bluetooth_le_audio(JNIEnv* env) { &method_onHealthBasedGroupRecommendationAction}, {"onUnicastMonitorModeStatus", "(II)V", &method_onUnicastMonitorModeStatus}, + {"onGroupStreamStatus", "(II)V", &method_onGroupStreamStatus}, }; GET_JAVA_METHODS(env, "com/android/bluetooth/le_audio/LeAudioNativeInterface", javaMethods); diff --git a/android/app/jni/com_android_bluetooth_pan.cpp b/android/app/jni/com_android_bluetooth_pan.cpp index a216ebb103458e8959497bbca100339a1aaa22db..975f18ad38138fbf278dfc83ba68c120907bdbeb 100644 --- a/android/app/jni/com_android_bluetooth_pan.cpp +++ b/android/app/jni/com_android_bluetooth_pan.cpp @@ -16,23 +16,13 @@ #define LOG_TAG "BluetoothPanServiceJni" +#include +#include + #include "com_android_bluetooth.h" #include "hardware/bt_pan.h" #include "utils/Log.h" -#include - -#include -#define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) -#define debug(fmt, ...) \ - ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__) -#define warn(fmt, ...) \ - ALOGW("## WARNING : %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__) -#define error(fmt, ...) \ - ALOGE("## ERROR : %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__) -#define asrt(s) \ - if (!(s)) ALOGE("## %s(L%d): ASSERT %s failed! ##", __func__, __LINE__, #s) - namespace android { static jmethodID method_onConnectStateChanged; @@ -47,7 +37,7 @@ static jbyteArray marshall_bda(const RawAddress* bd_addr) { jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress)); if (!addr) { - ALOGE("Fail to new jbyteArray bd addr"); + log::error("Fail to new jbyteArray bd addr"); return NULL; } sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress), @@ -57,9 +47,9 @@ static jbyteArray marshall_bda(const RawAddress* bd_addr) { static void control_state_callback(btpan_control_state_t state, int local_role, bt_status_t error, const char* ifname) { - debug("state:%d, local_role:%d, ifname:%s", state, local_role, ifname); + log::debug("state:{}, local_role:{}, ifname:{}", state, local_role, ifname); if (mCallbacksObj == NULL) { - error("Callbacks Obj is NULL: '%s", __func__); + log::error("Callbacks Obj is NULL"); return; } CallbackEnv sCallbackEnv(__func__); @@ -75,17 +65,17 @@ static void connection_state_callback(btpan_connection_state_t state, bt_status_t error, const RawAddress* bd_addr, int local_role, int remote_role) { - debug("state:%d, local_role:%d, remote_role:%d", state, local_role, - remote_role); + log::debug("state:{}, local_role:{}, remote_role:{}", state, local_role, + remote_role); if (mCallbacksObj == NULL) { - error("Callbacks Obj is NULL: '%s", __func__); + log::error("Callbacks Obj is NULL"); return; } CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ScopedLocalRef addr(sCallbackEnv.get(), marshall_bda(bd_addr)); if (!addr.get()) { - error("Fail to new jbyteArray bd addr for PAN channel state"); + log::error("Fail to new jbyteArray bd addr for PAN channel state"); return; } sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, @@ -101,30 +91,30 @@ static btpan_callbacks_t sBluetoothPanCallbacks = { static const bt_interface_t* btIf; static void initializeNative(JNIEnv* env, jobject object) { - debug("Initialize pan"); + log::debug("Initialize pan"); if (btIf) return; btIf = getBluetoothInterface(); if (btIf == NULL) { - error("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sPanIf != NULL) { - ALOGW("Cleaning up Bluetooth PAN Interface before initializing..."); + log::warn("Cleaning up Bluetooth PAN Interface before initializing..."); sPanIf->cleanup(); sPanIf = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth PAN callback object"); + log::warn("Cleaning up Bluetooth PAN callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } sPanIf = (btpan_interface_t*)btIf->get_profile_interface(BT_PROFILE_PAN_ID); if (sPanIf == NULL) { - error("Failed to get Bluetooth PAN Interface"); + log::error("Failed to get Bluetooth PAN Interface"); return; } @@ -132,10 +122,12 @@ static void initializeNative(JNIEnv* env, jobject object) { bt_status_t status = sPanIf->init(&sBluetoothPanCallbacks); if (status != BT_STATUS_SUCCESS) { - error("Failed to initialize Bluetooth PAN, status: %d", status); + log::error("Failed to initialize Bluetooth PAN, status: {}", + bt_status_text(status)); sPanIf = NULL; if (mCallbacksObj != NULL) { - ALOGW("initialization failed: Cleaning up Bluetooth PAN callback object"); + log::warn( + "initialization failed: Cleaning up Bluetooth PAN callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -144,17 +136,17 @@ static void initializeNative(JNIEnv* env, jobject object) { } static void cleanupNative(JNIEnv* env, jobject /* object */) { - debug("Cleanup pan"); + log::debug("Cleanup pan"); if (!btIf) return; if (sPanIf != NULL) { - ALOGW("Cleaning up Bluetooth PAN Interface..."); + log::warn("Cleaning up Bluetooth PAN Interface..."); sPanIf->cleanup(); sPanIf = NULL; } if (mCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth PAN callback object"); + log::warn("Cleaning up Bluetooth PAN callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = NULL; } @@ -164,19 +156,20 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { static jboolean connectPanNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint src_role, jint dest_role) { - debug("Connect pan"); + log::debug("Connect pan"); if (!sPanIf) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - error("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } jboolean ret = JNI_TRUE; bt_status_t status = sPanIf->connect((RawAddress*)addr, src_role, dest_role); if (status != BT_STATUS_SUCCESS) { - error("Failed PAN channel connection, status: %d", status); + log::error("Failed PAN channel connection, status: {}", + bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); @@ -186,19 +179,20 @@ static jboolean connectPanNative(JNIEnv* env, jobject /* object */, static jboolean disconnectPanNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - debug("Disconnects pan"); + log::debug("Disconnects pan"); if (!sPanIf) return JNI_FALSE; jbyte* addr = env->GetByteArrayElements(address, NULL); if (!addr) { - error("Bluetooth device address null"); + log::error("Bluetooth device address null"); return JNI_FALSE; } jboolean ret = JNI_TRUE; bt_status_t status = sPanIf->disconnect((RawAddress*)addr); if (status != BT_STATUS_SUCCESS) { - error("Failed disconnect pan channel, status: %d", status); + log::error("Failed disconnect pan channel, status: {}", + bt_status_text(status)); ret = JNI_FALSE; } env->ReleaseByteArrayElements(address, addr, 0); diff --git a/android/app/jni/com_android_bluetooth_sdp.cpp b/android/app/jni/com_android_bluetooth_sdp.cpp index 62ee16ae3fb19a8bf7d95d491df118c91f28c723..206cb441780952aaf7f137f1072c9f4a056abcc0 100644 --- a/android/app/jni/com_android_bluetooth_sdp.cpp +++ b/android/app/jni/com_android_bluetooth_sdp.cpp @@ -55,11 +55,11 @@ static void initializeNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothSdpInterface != NULL) { - ALOGW("Cleaning up Bluetooth SDP Interface before initializing..."); + log::warn("Cleaning up Bluetooth SDP Interface before initializing..."); sBluetoothSdpInterface->deinit(); sBluetoothSdpInterface = NULL; } @@ -67,7 +67,7 @@ static void initializeNative(JNIEnv* env, jobject object) { sBluetoothSdpInterface = (btsdp_interface_t*)btInf->get_profile_interface( BT_PROFILE_SDP_CLIENT_ID); if (sBluetoothSdpInterface == NULL) { - ALOGE("Error getting SDP client interface"); + log::error("Error getting SDP client interface"); } else { sBluetoothSdpInterface->init(&sBluetoothSdpCallbacks); } @@ -77,7 +77,7 @@ static void initializeNative(JNIEnv* env, jobject object) { static jboolean sdpSearchNative(JNIEnv* env, jobject /* obj */, jbyteArray address, jbyteArray uuidObj) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return JNI_FALSE; @@ -87,22 +87,22 @@ static jboolean sdpSearchNative(JNIEnv* env, jobject /* obj */, return JNI_FALSE; } - jbyte* uuid = env->GetByteArrayElements(uuidObj, NULL); - if (!uuid) { - ALOGE("failed to get uuid"); + jbyte* raw_uuid = env->GetByteArrayElements(uuidObj, NULL); + if (!raw_uuid) { + log::error("failed to get uuid"); env->ReleaseByteArrayElements(address, addr, 0); return JNI_FALSE; } - ALOGD("%s UUID %.*s", __func__, 16, (uint8_t*)uuid); + Uuid uuid = Uuid::From128BitBE((uint8_t*)raw_uuid); + log::debug("UUID {}", uuid); - int ret = sBluetoothSdpInterface->sdp_search( - (RawAddress*)addr, Uuid::From128BitBE((uint8_t*)uuid)); + int ret = sBluetoothSdpInterface->sdp_search((RawAddress*)addr, uuid); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Search initialization failed: %d", ret); + log::error("SDP Search initialization failed: {}", ret); } if (addr) env->ReleaseByteArrayElements(address, addr, 0); - if (uuid) env->ReleaseByteArrayElements(uuidObj, uuid, 0); + if (raw_uuid) env->ReleaseByteArrayElements(uuidObj, raw_uuid, 0); return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } @@ -125,7 +125,7 @@ static void sdp_search_callback(bt_status_t status, const RawAddress& bd_addr, sCallbackEnv->SetByteArrayRegion(uuid.get(), 0, sizeof(Uuid), (const jbyte*)uuid_in.To128BitBE().data()); - ALOGD("%s: Status is: %d, Record count: %d", __func__, status, count); + log::debug("Status is: {}, Record count: {}", bt_status_text(status), count); // Ensure we run the loop at least once, to also signal errors if they occur for (int i = 0; i < count || i == 0; i++) { @@ -133,7 +133,7 @@ static void sdp_search_callback(bt_status_t status, const RawAddress& bd_addr, bluetooth_sdp_record* record = &records[i]; ScopedLocalRef service_name(sCallbackEnv.get(), NULL); if (record->hdr.service_name_length > 0) { - ALOGD("%s, ServiceName: %s", __func__, record->mas.hdr.service_name); + log::debug("ServiceName: {}", record->mas.hdr.service_name); service_name.reset( (jstring)sCallbackEnv->NewStringUTF(record->mas.hdr.service_name)); } @@ -192,7 +192,7 @@ static void sdp_search_callback(bt_status_t status, const RawAddress& bd_addr, (jint)record->mas.hdr.profile_version, service_name.get(), more_results); } else if (uuid_in == UUID_DIP) { - ALOGD("%s, Get UUID_DIP", __func__); + log::debug("Get UUID_DIP"); sCallbackEnv->CallVoidMethod( sCallbacksObj, method_sdpDipRecordFoundCallback, (jint)status, addr.get(), uuid.get(), (jint)record->dip.spec_id, @@ -222,7 +222,7 @@ static jint sdpCreateMapMasRecordNative(JNIEnv* env, jobject /* obj */, jstring name_str, jint mas_id, jint scn, jint l2cap_psm, jint version, jint msg_types, jint features) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized @@ -248,9 +248,9 @@ static jint sdpCreateMapMasRecordNative(JNIEnv* env, jobject /* obj */, int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Create record failed: %d", ret); + log::error("SDP Create record failed: {}", ret); } else { - ALOGD("SDP Create record success - handle: %d", handle); + log::debug("SDP Create record success - handle: {}", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); @@ -261,7 +261,7 @@ static jint sdpCreateMapMnsRecordNative(JNIEnv* env, jobject /* obj */, jstring name_str, jint scn, jint l2cap_psm, jint version, jint features) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized @@ -285,9 +285,9 @@ static jint sdpCreateMapMnsRecordNative(JNIEnv* env, jobject /* obj */, int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Create record failed: %d", ret); + log::error("SDP Create record failed: {}", ret); } else { - ALOGD("SDP Create record success - handle: %d", handle); + log::debug("SDP Create record success - handle: {}", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); @@ -296,7 +296,7 @@ static jint sdpCreateMapMnsRecordNative(JNIEnv* env, jobject /* obj */, static jint sdpCreatePbapPceRecordNative(JNIEnv* env, jobject /* obj */, jstring name_str, jint version) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized @@ -316,9 +316,9 @@ static jint sdpCreatePbapPceRecordNative(JNIEnv* env, jobject /* obj */, int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Create record failed: %d", ret); + log::error("SDP Create record failed: {}", ret); } else { - ALOGD("SDP Create record success - handle: %d", handle); + log::debug("SDP Create record success - handle: {}", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); @@ -330,7 +330,7 @@ static jint sdpCreatePbapPseRecordNative(JNIEnv* env, jobject /* obj */, jint l2cap_psm, jint version, jint supported_repositories, jint features) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized @@ -355,9 +355,9 @@ static jint sdpCreatePbapPseRecordNative(JNIEnv* env, jobject /* obj */, int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Create record failed: %d", ret); + log::error("SDP Create record failed: {}", ret); } else { - ALOGD("SDP Create record success - handle: %d", handle); + log::debug("SDP Create record success - handle: {}", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); @@ -368,7 +368,7 @@ static jint sdpCreateOppOpsRecordNative(JNIEnv* env, jobject /* obj */, jstring name_str, jint scn, jint l2cap_psm, jint version, jbyteArray supported_formats_list) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized @@ -402,9 +402,9 @@ static jint sdpCreateOppOpsRecordNative(JNIEnv* env, jobject /* obj */, int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Create record failed: %d", ret); + log::error("SDP Create record failed: {}", ret); } else { - ALOGD("SDP Create record success - handle: %d", handle); + log::debug("SDP Create record success - handle: {}", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); @@ -416,7 +416,7 @@ static jint sdpCreateOppOpsRecordNative(JNIEnv* env, jobject /* obj */, static jint sdpCreateSapsRecordNative(JNIEnv* env, jobject /* obj */, jstring name_str, jint scn, jint version) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return -1; bluetooth_sdp_record record = {}; // Must be zero initialized @@ -437,9 +437,9 @@ static jint sdpCreateSapsRecordNative(JNIEnv* env, jobject /* obj */, int handle = -1; int ret = sBluetoothSdpInterface->create_sdp_record(&record, &handle); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Create record failed: %d", ret); + log::error("SDP Create record failed: {}", ret); } else { - ALOGD("SDP Create record success - handle: %d", handle); + log::debug("SDP Create record success - handle: {}", handle); } if (service_name) env->ReleaseStringUTFChars(name_str, service_name); @@ -448,16 +448,16 @@ static jint sdpCreateSapsRecordNative(JNIEnv* env, jobject /* obj */, static jboolean sdpRemoveSdpRecordNative(JNIEnv* /* env */, jobject /* obj */, jint record_id) { - ALOGD("%s", __func__); + log::debug(""); if (!sBluetoothSdpInterface) return false; int ret = sBluetoothSdpInterface->remove_sdp_record(record_id); if (ret != BT_STATUS_SUCCESS) { - ALOGE("SDP Remove record failed: %d", ret); + log::error("SDP Remove record failed: {}", ret); return false; } - ALOGD("SDP Remove record success - handle: %d", record_id); + log::debug("SDP Remove record success - handle: {}", record_id); return true; } @@ -465,18 +465,18 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == NULL) { - ALOGE("Bluetooth module is not loaded"); + log::error("Bluetooth module is not loaded"); return; } if (sBluetoothSdpInterface != NULL) { - ALOGW("Cleaning up Bluetooth SDP Interface..."); + log::warn("Cleaning up Bluetooth SDP Interface..."); sBluetoothSdpInterface->deinit(); sBluetoothSdpInterface = NULL; } if (sCallbacksObj != NULL) { - ALOGW("Cleaning up Bluetooth SDP object"); + log::warn("Cleaning up Bluetooth SDP object"); env->DeleteGlobalRef(sCallbacksObj); sCallbacksObj = NULL; } diff --git a/android/app/jni/com_android_bluetooth_vc.cpp b/android/app/jni/com_android_bluetooth_vc.cpp index 60cd30e49b2bb2cee7c88f3a0118f894c19949cf..26dee38cc2ac5e1803701b310e6cfb2bd7314423 100644 --- a/android/app/jni/com_android_bluetooth_vc.cpp +++ b/android/app/jni/com_android_bluetooth_vc.cpp @@ -48,8 +48,8 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { ~VolumeControlCallbacksImpl() = default; void OnConnectionState(ConnectionState state, const RawAddress& bd_addr) override { - LOG(INFO) << __func__ << ", state:" << int(state) - << ", addr: " << bd_addr.ToRedactedStringForLogging(); + log::info("state:{}, addr: {}", int(state), + bd_addr.ToRedactedStringForLogging()); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -58,7 +58,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for connection state"; + log::error("Failed to new jbyteArray bd addr for connection state"); return; } @@ -70,7 +70,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { void OnVolumeStateChanged(const RawAddress& bd_addr, uint8_t volume, bool mute, bool isAutonomous) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -79,7 +79,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for connection state"; + log::error("Failed to new jbyteArray bd addr for connection state"); return; } @@ -91,7 +91,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { void OnGroupVolumeStateChanged(int group_id, uint8_t volume, bool mute, bool isAutonomous) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -104,7 +104,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { void OnDeviceAvailable(const RawAddress& bd_addr, uint8_t num_offsets) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -113,7 +113,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for onDeviceAvailable"; + log::error("Failed to new jbyteArray bd addr for onDeviceAvailable"); return; } @@ -126,7 +126,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { void OnExtAudioOutVolumeOffsetChanged(const RawAddress& bd_addr, uint8_t ext_output_id, int16_t offset) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -135,8 +135,9 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for " - "OnExtAudioOutVolumeOffsetChanged"; + log::error( + "Failed to new jbyteArray bd addr for " + "OnExtAudioOutVolumeOffsetChanged"); return; } @@ -150,7 +151,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { void OnExtAudioOutLocationChanged(const RawAddress& bd_addr, uint8_t ext_output_id, uint32_t location) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -159,8 +160,8 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for " - "OnExtAudioOutLocationChanged"; + log::error( + "Failed to new jbyteArray bd addr for OnExtAudioOutLocationChanged"); return; } @@ -174,7 +175,7 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { void OnExtAudioOutDescriptionChanged(const RawAddress& bd_addr, uint8_t ext_output_id, std::string descr) override { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); @@ -183,8 +184,9 @@ class VolumeControlCallbacksImpl : public VolumeControlCallbacks { ScopedLocalRef addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { - LOG(ERROR) << "Failed to new jbyteArray bd addr for " - "OnExtAudioOutDescriptionChanged"; + log::error( + "Failed to new jbyteArray bd addr for " + "OnExtAudioOutDescriptionChanged"); return; } @@ -205,31 +207,31 @@ static void initNative(JNIEnv* env, jobject object) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } if (sVolumeControlInterface != nullptr) { - LOG(INFO) << "Cleaning up VolumeControl Interface before initializing..."; + log::info("Cleaning up VolumeControl Interface before initializing..."); sVolumeControlInterface->Cleanup(); sVolumeControlInterface = nullptr; } if (mCallbacksObj != nullptr) { - LOG(INFO) << "Cleaning up VolumeControl callback object"; + log::info("Cleaning up VolumeControl callback object"); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { - LOG(ERROR) << "Failed to allocate Global Ref for Volume control Callbacks"; + log::error("Failed to allocate Global Ref for Volume control Callbacks"); return; } sVolumeControlInterface = (VolumeControlInterface*)btInf->get_profile_interface(BT_PROFILE_VC_ID); if (sVolumeControlInterface == nullptr) { - LOG(ERROR) << "Failed to get Bluetooth Volume Control Interface"; + log::error("Failed to get Bluetooth Volume Control Interface"); return; } @@ -242,7 +244,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { - LOG(ERROR) << "Bluetooth module is not loaded"; + log::error("Bluetooth module is not loaded"); return; } @@ -259,12 +261,11 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { static jboolean connectVolumeControlNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return JNI_FALSE; } @@ -282,12 +283,11 @@ static jboolean connectVolumeControlNative(JNIEnv* env, jobject /* object */, static jboolean disconnectVolumeControlNative(JNIEnv* env, jobject /* object */, jbyteArray address) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return JNI_FALSE; } @@ -306,8 +306,7 @@ static jboolean disconnectVolumeControlNative(JNIEnv* env, jobject /* object */, static void setVolumeNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint volume) { if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return; } @@ -325,8 +324,7 @@ static void setVolumeNative(JNIEnv* env, jobject /* object */, static void setGroupVolumeNative(JNIEnv* /* env */, jobject /* object */, jint group_id, jint volume) { if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return; } @@ -335,8 +333,7 @@ static void setGroupVolumeNative(JNIEnv* /* env */, jobject /* object */, static void muteNative(JNIEnv* env, jobject /* object */, jbyteArray address) { if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return; } @@ -354,8 +351,7 @@ static void muteNative(JNIEnv* env, jobject /* object */, jbyteArray address) { static void muteGroupNative(JNIEnv* /* env */, jobject /* object */, jint group_id) { if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return; } sVolumeControlInterface->Mute(group_id); @@ -364,8 +360,7 @@ static void muteGroupNative(JNIEnv* /* env */, jobject /* object */, static void unmuteNative(JNIEnv* env, jobject /* object */, jbyteArray address) { if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return; } @@ -383,8 +378,7 @@ static void unmuteNative(JNIEnv* env, jobject /* object */, static void unmuteGroupNative(JNIEnv* /* env */, jobject /* object */, jint group_id) { if (!sVolumeControlInterface) { - LOG(ERROR) << __func__ - << ": Failed to get the Bluetooth Volume Control Interface"; + log::error("Failed to get the Bluetooth Volume Control Interface"); return; } sVolumeControlInterface->Unmute(group_id); @@ -395,7 +389,7 @@ static jboolean getExtAudioOutVolumeOffsetNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint ext_output_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) return JNI_FALSE; @@ -416,7 +410,7 @@ static jboolean setExtAudioOutVolumeOffsetNative(JNIEnv* env, jbyteArray address, jint ext_output_id, jint offset) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) return JNI_FALSE; @@ -436,7 +430,7 @@ static jboolean setExtAudioOutVolumeOffsetNative(JNIEnv* env, static jboolean getExtAudioOutLocationNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint ext_output_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) return JNI_FALSE; @@ -456,7 +450,7 @@ static jboolean setExtAudioOutLocationNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint ext_output_id, jint location) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) return JNI_FALSE; @@ -477,7 +471,7 @@ static jboolean getExtAudioOutDescriptionNative(JNIEnv* env, jobject /* object */, jbyteArray address, jint ext_output_id) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) return JNI_FALSE; @@ -498,7 +492,7 @@ static jboolean setExtAudioOutDescriptionNative(JNIEnv* env, jbyteArray address, jint ext_output_id, jstring descr) { - LOG(INFO) << __func__; + log::info(""); std::shared_lock lock(interface_mutex); if (!sVolumeControlInterface) return JNI_FALSE; diff --git a/android/app/lint-baseline.xml b/android/app/lint-baseline.xml index 3c6ab974d702da194f8827155e8f57c4a132e7a5..7e3bde0fc7a6cc710c66149cf7472ab7d544a260 100644 --- a/android/app/lint-baseline.xml +++ b/android/app/lint-baseline.xml @@ -1,5 +1,5 @@ - + + message='This LinearLayout should use `android:layout_height="wrap_content"`'> @@ -27,7 +27,7 @@ + message='This LinearLayout should use `android:layout_height="wrap_content"`'> @@ -35,7 +35,7 @@ + message='This LinearLayout should use `android:layout_height="wrap_content"`'> @@ -381,7 +381,7 @@ id="SimpleDateFormat" message="To get local formatting use `getDateInstance()`, `getDateTimeInstance()`, or `getTimeInstance()`, or use `new SimpleDateFormat(String template, Locale locale)` with for example `Locale.US` for ASCII dates."> @@ -571,7 +571,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -579,7 +579,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -587,7 +587,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -595,7 +595,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -603,7 +603,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -611,7 +611,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -619,7 +619,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -627,7 +627,7 @@ + message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout's root element)"> @@ -5043,7 +5043,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% a`'?"> @@ -5051,7 +5051,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% b`'?"> @@ -5059,7 +5059,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5067,7 +5067,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5075,7 +5075,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5083,7 +5083,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5091,7 +5091,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5099,7 +5099,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5107,7 +5107,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5115,7 +5115,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5123,7 +5123,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5131,7 +5131,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5139,7 +5139,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5147,7 +5147,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% e`'?"> @@ -5155,7 +5155,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% e`'?"> @@ -5163,7 +5163,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% f`'?"> @@ -5171,7 +5171,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% f`'?"> @@ -5179,7 +5179,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% f`'?"> @@ -5187,7 +5187,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% h`'?"> @@ -5195,7 +5195,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% s`'?"> @@ -5203,7 +5203,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% s`'?"> @@ -5211,7 +5211,7 @@ + message="Incorrect formatting string `notification_sent_complete`; missing conversion character in '`% c`'?"> @@ -5219,7 +5219,7 @@ + message="Inconsistent formatting types for argument #1 in format string `notification_sent_complete` ('% d'): Found both '`d`' here and '`e`' in values-eu/strings.xml"> @@ -5449,7 +5449,7 @@ + message="`mBluetoothConnectionReceiver` \ is missing `RECEIVER_EXPORTED` or `RECEIVER_NOT_EXPORTED` flag for unprotected \ broadcasts registered for an IntentFilter that cannot be inspected by lint"> @@ -5457,7 +5457,7 @@ + message="A `<queries>` declaration should generally be used instead of QUERY_ALL_PACKAGES; \ see https://g.co/dev/packagevisibility for details"> @@ -5465,7 +5465,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5473,7 +5473,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5481,7 +5481,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5489,7 +5489,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5497,7 +5497,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5505,7 +5505,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5513,7 +5513,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5521,7 +5521,7 @@ + message="Provide a timeout when requesting a wakelock with `PowerManager.Wakelock.acquire(long timeout)`. This will ensure the OS will cleanup any wakelocks that last longer than you intend, and will save your user's battery."> @@ -5673,7 +5673,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5681,7 +5681,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5689,7 +5689,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5697,7 +5697,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5705,7 +5705,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5713,7 +5713,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5721,7 +5721,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5729,7 +5729,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5737,7 +5737,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5745,7 +5745,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5753,7 +5753,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5761,7 +5761,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5769,7 +5769,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5777,7 +5777,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5785,7 +5785,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5793,7 +5793,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5801,7 +5801,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5809,7 +5809,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5817,7 +5817,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5825,7 +5825,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5833,7 +5833,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5841,7 +5841,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5849,7 +5849,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5857,7 +5857,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5865,7 +5865,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5873,7 +5873,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5881,7 +5881,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5889,7 +5889,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5897,7 +5897,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5905,7 +5905,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5913,7 +5913,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5921,7 +5921,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5929,7 +5929,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5937,7 +5937,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5945,7 +5945,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5953,7 +5953,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5961,7 +5961,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5969,7 +5969,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5977,7 +5977,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5985,7 +5985,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -5993,7 +5993,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6001,7 +6001,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6009,7 +6009,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6017,7 +6017,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6025,7 +6025,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6033,7 +6033,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6041,7 +6041,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6049,7 +6049,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6057,7 +6057,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6065,7 +6065,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6073,7 +6073,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6081,7 +6081,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6089,7 +6089,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6097,7 +6097,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6105,7 +6105,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6113,7 +6113,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6121,7 +6121,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6129,7 +6129,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6137,7 +6137,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6145,7 +6145,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6153,7 +6153,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6161,7 +6161,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6169,7 +6169,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6177,7 +6177,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6185,7 +6185,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6193,7 +6193,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6201,7 +6201,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6209,7 +6209,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6217,7 +6217,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6225,7 +6225,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6233,7 +6233,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6241,7 +6241,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6249,7 +6249,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6257,7 +6257,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6265,7 +6265,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6273,7 +6273,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6281,7 +6281,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6289,7 +6289,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6297,7 +6297,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6305,7 +6305,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6313,7 +6313,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6321,7 +6321,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6329,7 +6329,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6337,7 +6337,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6345,7 +6345,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6353,7 +6353,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6361,7 +6361,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6369,7 +6369,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6377,7 +6377,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6385,7 +6385,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6393,7 +6393,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6401,7 +6401,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6409,7 +6409,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6417,7 +6417,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6425,7 +6425,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6433,7 +6433,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6441,7 +6441,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6449,7 +6449,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6457,7 +6457,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6465,7 +6465,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6473,7 +6473,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6481,7 +6481,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6489,7 +6489,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6497,7 +6497,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6505,7 +6505,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6513,7 +6513,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6521,7 +6521,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6529,7 +6529,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6537,7 +6537,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6545,7 +6545,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6553,7 +6553,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6561,7 +6561,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6569,7 +6569,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6577,7 +6577,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6585,7 +6585,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6593,7 +6593,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6601,7 +6601,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6609,7 +6609,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6617,7 +6617,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6625,7 +6625,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6633,7 +6633,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6641,7 +6641,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6649,7 +6649,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6657,7 +6657,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6665,7 +6665,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6673,7 +6673,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6681,7 +6681,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6689,7 +6689,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6697,7 +6697,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6705,7 +6705,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6713,7 +6713,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6721,7 +6721,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6729,7 +6729,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6737,7 +6737,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6745,7 +6745,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6753,7 +6753,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6761,7 +6761,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6769,7 +6769,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6777,7 +6777,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6785,7 +6785,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6793,7 +6793,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6801,7 +6801,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6809,7 +6809,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6817,7 +6817,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6825,7 +6825,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6833,7 +6833,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6841,7 +6841,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6849,7 +6849,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6857,7 +6857,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6865,7 +6865,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6873,7 +6873,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6881,7 +6881,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6889,7 +6889,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6897,7 +6897,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6905,7 +6905,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6913,7 +6913,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6921,7 +6921,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> @@ -6929,7 +6929,7 @@ + message='Replace "..." with ellipsis character (…, &#8230;) ?'> diff --git a/android/app/res/drawable/bt_incomming_file_notification.xml b/android/app/res/drawable/ic_bluetooth_file_transfer_notification.xml similarity index 100% rename from android/app/res/drawable/bt_incomming_file_notification.xml rename to android/app/res/drawable/ic_bluetooth_file_transfer_notification.xml diff --git a/android/app/res/drawable/ic_bluetooth_settings.xml b/android/app/res/drawable/ic_bluetooth_settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..00678fb0f7f79d3bf4848e474a0018206b8ecf79 --- /dev/null +++ b/android/app/res/drawable/ic_bluetooth_settings.xml @@ -0,0 +1,10 @@ + + + + diff --git a/android/app/res/menu/receivedfilescontextfinished.xml b/android/app/res/menu/receivedfilescontextfinished.xml deleted file mode 100644 index 79bfa3ff7616833bfd2b2068f534cccc61f795c3..0000000000000000000000000000000000000000 --- a/android/app/res/menu/receivedfilescontextfinished.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - diff --git a/android/app/res/values-af/strings.xml b/android/app/res/values-af/strings.xml index 425476f69160e4ae0016ca6b22d0e84d12dda3d7..6c7a0dea70fc4de1fce1bd2f716e677828db1e3c 100644 --- a/android/app/res/values-af/strings.xml +++ b/android/app/res/values-af/strings.xml @@ -101,7 +101,6 @@ "Verbinding onsuksesvol." "Versoek kan nie korrek hanteer word nie." "Onbekende fout" - "Ontvang deur Bluetooth" "Bluetooth-deling" "%1$s volledig ontvang." "%1$s klaar gestuur." @@ -136,4 +135,8 @@ "Jou toestel onthou om Bluetooth aan te hou in vliegtuigmodus. Skakel Bluetooth af as jy nie wil hê dit moet aan bly nie." "Wi-fi en Bluetooth bly aan" "Jou toestel onthou om wi‑fi en Bluetooth aan te hou in vliegtuigmodus. Skakel wi-fi en Bluetooth af as jy nie wil hê dit moet aan bly nie." + "Bluetooth is outomaties geaktiveer" + "Outomatiese herbegin kan in Bluetooth-instellings aan- en afgeskakel word." + "Skakel af" + "Outomatiese verandering in Bluetooth-status" diff --git a/android/app/res/values-am/strings.xml b/android/app/res/values-am/strings.xml index 4b23792a97ca097baa25ec4e75c99d5aa62dd5f0..9dd788ed09b864de763f42a2b86c1ccbe4250df7 100644 --- a/android/app/res/values-am/strings.xml +++ b/android/app/res/values-am/strings.xml @@ -101,7 +101,6 @@ "ተያያዥ አልተሳካም።" "ጥየቃውን በትክክል መያዝ አይቻልም።" "ያልታወቀ ስህተት" - "ብሉቱዝ ተቀብሏል" "የብሉቱዝ ማጋሪያ" "%1$s ተቀብሎ ተጠናቋል።" "%1$s ልኮ ተጠናቋል።" @@ -136,4 +135,8 @@ "መሣሪያዎ ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርቶ እንዲቆይ ካልፈለጉ ብሉቱዝን ያጥፉት።" "Wi-Fi እና ብሉቱዝ በርተው ይቆያሉ" "መሣሪያዎ Wi-Fiን እና ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርተው እንዲቆዩ ካልፈለጉ Wi-Fi እና ብሉቱዝን ያጥፏቸው።" + "ብሉቱዝ በራስ-ሰር ነቅቷል" + "በራስ-ሰር ዳግም ማስጀመር በብሉቱዝ ቅንብሮች ውስጥ ሊቀያየር ይችላል።" + "አጥፋ" + "ብሉቱዝ የራስ-ሰር ሁኔታ ለውጥ" diff --git a/android/app/res/values-ar/strings.xml b/android/app/res/values-ar/strings.xml index 7106e0638d0bd85c984bffe82df247ea12979881..1a9243391c045029c375f3f7fa809dc21425f5de 100644 --- a/android/app/res/values-ar/strings.xml +++ b/android/app/res/values-ar/strings.xml @@ -101,7 +101,6 @@ "لم يتم الاتصال بنجاح." "لا يمكن معالجة الطلب بشكل صحيح." "خطأ غير معروف." - "ملفات بلوتوث المستلَمة" "مشاركة البلوتوث" "اكتمل استلام %1$s." "اكتمل إرسال %1$s." @@ -136,4 +135,8 @@ "يتذكر جهازك الاحتفاظ بتقنية البلوتوث مفعَّلة في \"وضع الطيران\". يمكنك إيقاف تقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلها." "‏تظل شبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين." "‏يتذكر جهازك الاحتفاظ بشبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين في \"وضع الطيران\". يمكنك إيقاف شبكة Wi‑Fi وتقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلهما." + "تم تفعيل البلوتوث تلقائيًا" + "يمكن إيقاف ميزة إعادة التشغيل التلقائية أو تفعيلها من خلال إعدادات البلوتوث." + "إيقاف" + "تغيير حالة تفعيل أو إيقاف البلوتوث تلقائيًا" diff --git a/android/app/res/values-as/strings.xml b/android/app/res/values-as/strings.xml index 020d1b73a3e4a84f7c5e94b4fee7fc194475f4ae..7256f24fe66788d8e9282f195b62c18a985a9713 100644 --- a/android/app/res/values-as/strings.xml +++ b/android/app/res/values-as/strings.xml @@ -101,7 +101,6 @@ "সংযোগ কৰিব পৰা নগ\'ল।" "অনুৰোধ সঠিকভাৱে পৰিচালনা কৰিব নোৱাৰি।" "অজ্ঞাত আসোঁৱাহ।" - "ব্লুটুথ লাভ কৰা হ’ল" "ব্লুটুথ শ্বেয়াৰ" "%1$s লাভ কৰা কাৰ্য সম্পূৰ্ণ হ’ল।" "%1$s প্ৰেৰণ কৰা কাম সম্পূৰ্ণ হ’ল" @@ -136,4 +135,8 @@ "আপোনাৰ ডিভাইচটোৱে এয়াৰপ্লেন ম’ডত ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি যদি ব্লুটুথ অন হৈ থকাটো নিবিচাৰে, তেন্তে ইয়াক অফ কৰক।" "ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থাকে" "আপোনাৰ ডিভাইচটোৱে এয়াৰপ্লেন ম’ডত ৱাই-ফাই আৰু ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থকাটো নিবিচাৰিলে সেইবোৰ অফ কৰক।" + "ব্লুটুথ স্বয়ংক্ৰিয়ভাৱে সক্ষম কৰা হৈছে" + "ব্লুটুথৰ ছেটিঙত স্বয়ংক্ৰিয় ৰিষ্টাৰ্ট ট’গল কৰা হ’ব পাৰে।" + "অফ কৰক" + "ব্লুটুথৰ স্বয়ংক্ৰিয় স্থিতি সলনি হোৱা" diff --git a/android/app/res/values-az/strings.xml b/android/app/res/values-az/strings.xml index 5d1599f998663243bbd48efb2e93d048d032784c..147bb2365fd2528b23686ddc9dfde56508c58942 100644 --- a/android/app/res/values-az/strings.xml +++ b/android/app/res/values-az/strings.xml @@ -101,7 +101,6 @@ "Uğursuz bağlantı." "Sorğu düzgün idarə edilə bilməz." "Naməlum xəta." - "Bluetooth ilə qəbul edilənlər" "Bluetooth Paylaşım" "%1$s tam qəbul olundu." "%1$s tam göndərildi." @@ -136,4 +135,8 @@ "Cihaz təyyarə rejimində Bluetooth-u aktiv saxlayır. İstəmirsinizsə, Bluetooth-u deaktiv edin." "Wi-Fi və Bluetooth aktiv qalır" "Cihaz təyyarə rejimində Wi‑Fi və Bluetooth-u aktiv saxlayır. İstəmirsinizsə, Wi-Fi və Bluetooth-u deaktiv edin." + "Bluetooth avtomatik aktivləşdirildi" + "Avtomatik yenidən başlatma Bluetooth Ayarlarında dəyişdirilə bilər." + "Deaktiv edin" + "Bluetooth-un avtomatik vəziyyət dəyişikliyi" diff --git a/android/app/res/values-b+sr+Latn/strings.xml b/android/app/res/values-b+sr+Latn/strings.xml index 6dce4428775b22f23316b6b71c468a3b5e11eb8a..35e0148a1ab4bd9f7de11c436339269bbdeaeacd 100644 --- a/android/app/res/values-b+sr+Latn/strings.xml +++ b/android/app/res/values-b+sr+Latn/strings.xml @@ -101,7 +101,6 @@ "Povezivanje nije uspelo." "Nije moguće ispravno obraditi zahtev." "Nepoznata greška." - "Primljeno preko Bluetooth-a" "Deljenje preko Bluetooth-a" "%1$s Primljeno u celosti." "%1$s Slanje je dovršeno." @@ -136,4 +135,8 @@ "Uređaj pamti da ne treba da isključuje Bluetooth u režimu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." "WiFi i Bluetooth ostaju uključeni" "Uređaj pamti da ne treba da isključuje WiFi i Bluetooth u režimu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." + "Bluetooth je automatski omogućen" + "Automatski restart može da se uključi ili isključi u podešavanjima Bluetooth-a." + "Isključi" + "Automatski status Bluetooth-a je promenjen" diff --git a/android/app/res/values-be/strings.xml b/android/app/res/values-be/strings.xml index 9a2a1f9f12a803383e2db01ad156cec57d2620fe..529ad0f36f62830fccc7b233d8fb121f79e0365b 100644 --- a/android/app/res/values-be/strings.xml +++ b/android/app/res/values-be/strings.xml @@ -101,7 +101,6 @@ "Няўдалая спроба падключэння." "Запыт не можа быць правільна апрацаваны" "Невядомая памылка." - "Атрыманае праз Bluetooth" "Абагульванне праз Bluetooth" "Атрыманне завершанае: %1$s." "Адпраўленне завершана: %1$s." @@ -136,4 +135,8 @@ "На прыладзе ў рэжыме палёту Bluetooth застанецца ўключаным, але вы можаце выключыць яго." "Wi-Fi і Bluetooth застаюцца ўключанымі" "На прыладзе ў рэжыме палёту Wi‑Fi і Bluetooth будуць заставацца ўключанымі, але вы можаце выключыць іх." + "Bluetooth быў уключаны аўтаматычна" + "У наладах Bluetooth можна ўключыць аўтаматычны перазапуск." + "Выключыць" + "Аўтаматычнае змяненне стану Bluetooth" diff --git a/android/app/res/values-bg/strings.xml b/android/app/res/values-bg/strings.xml index 5ec8326d74035f819af87840e047068b32f0117f..e6475cd3637c2c4c8b88ca72fd5d39820a1c841f 100644 --- a/android/app/res/values-bg/strings.xml +++ b/android/app/res/values-bg/strings.xml @@ -101,7 +101,6 @@ "Връзката не е успешна." "Заявката не може да бъде обработена правилно." "Неизвестна грешка." - "Получено с Bluetooth" "Споделяне през Bluetooth" "%1$s – Получаването завърши." "%1$s – Изпращането завърши." @@ -136,4 +135,8 @@ "Функцията за Bluetooth ще бъде включена, докато устройството ви е в самолетен режим. Ако не искате това, изключете я." "Функциите за Wi-Fi и Bluetooth няма да бъдат изключени" "Функциите за Wi‑Fi и Bluetooth ще бъдат включени, докато устройството ви е в самолетен режим. Ако не искате това, изключете ги." + "Функцията за Bluetooth е активирана автоматично" + "Автоматичното рестартиране може да се превключва от настройките за Bluetooth." + "Изключване" + "Автоматична промяна в състоянието на Bluetooth" diff --git a/android/app/res/values-bn/strings.xml b/android/app/res/values-bn/strings.xml index e4c139f13e66c50466f7667f4a33db8237d0e783..b2b418fe11028891198c6eb432ac58ee2c13b0f5 100644 --- a/android/app/res/values-bn/strings.xml +++ b/android/app/res/values-bn/strings.xml @@ -101,7 +101,6 @@ "সংযোগ অসফল।" "অনুরোধ সঠিকভাবে পরিচালনা করা যাবে না।" "অজানা ত্রুটি৷" - "ব্লুটুথ প্রাপ্তি" "ব্লুটুথ শেয়ার" "%1$s প্রাপ্ত করা সম্পূর্ণ।" "%1$s পাঠানো সম্পূর্ণ।" @@ -136,4 +135,8 @@ "\'বিমান মোড\'-এ থাকাকালীন আপনার ডিভাইস ব্লুটুথ চালু রাখে। আপনি ব্লুটুথ চালু না রাখতে চাইলে এটি বন্ধ করুন।" "ওয়াই-ফাই ও ব্লুটুথ চালু থাকে" "\'বিমান মোড\'-এ থাকাকালীন আপনার ডিভাইস, ওয়াই-ফাই ও ব্লুটুথ চালু রাখে। আপনি যদি ওয়াই-ফাই এবং ব্লুটুথ চালু রাখতে না চান, সেগুলি বন্ধ করে দিন।" + "ব্লুটুথ অটোমেটিক চালু হয়ে গেছে" + "ব্লুটুথ সেটিংসে অটোমেটিক রিস্টার্ট করার সুবিধা টগল করা যাবে।" + "বন্ধ করুন" + "ব্লুটুথ অটোমেটিক চালু হওয়ার সেটিং পরিবর্তন করেছে" diff --git a/android/app/res/values-bs/strings.xml b/android/app/res/values-bs/strings.xml index 69cbb3c0b3b219da03a40ffa444e0673d9116ec5..11e7d08b119c21d82c2edfdb4d8cef5900835c1b 100644 --- a/android/app/res/values-bs/strings.xml +++ b/android/app/res/values-bs/strings.xml @@ -101,7 +101,6 @@ "Povezivanje nije uspjelo." "Nije moguće pravilno obraditi zahtjev." "Nepoznata greška." - "Primljeno putem Bluetootha" "Dijeljenje putem Bluetootha" "%1$s Primanje završeno." "%1$s Slanje dovršeno." @@ -136,4 +135,8 @@ "Uređaj pamti da Bluetooth treba biti uključen u načinu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." "WiFi i Bluetooth ostaju uključeni" "Uređaj pamti da WiFi i Bluetooth trebaju biti uključeni u načinu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." + "Bluetooth je automatski omogućen" + "Automatsko ponovno pokretanje se može uključiti/isključiti u Postavkama Bluetootha." + "Isključi" + "Automatska promjena stanja Bluetootha" diff --git a/android/app/res/values-ca/strings.xml b/android/app/res/values-ca/strings.xml index 3ee27e5eedd907a307492915942139fb3efaab03..e3e23681e993ad17822b18f95928be71c24b1cd1 100644 --- a/android/app/res/values-ca/strings.xml +++ b/android/app/res/values-ca/strings.xml @@ -101,7 +101,6 @@ "Connexió incorrecta." "La sol·licitud no es pot processar correctament." "Error desconegut." - "Rebut per Bluetooth" "Compartir amb Bluetooth" "Recepció completada (%1$s)" "%1$s: enviament complet." @@ -136,4 +135,8 @@ "El dispositiu recorda mantenir el Bluetooth activat en mode d\'avió. Desactiva el Bluetooth si no vols que es quedi activat." "La Wi‑Fi i el Bluetooth es mantenen activats" "El dispositiu recorda mantenir la Wi‑Fi i el Bluetooth activats en mode d\'avió. Desactiva la Wi‑Fi i el Bluetooth si no vols que es quedin activats." + "El Bluetooth s\'ha activat automàticament" + "El reinici automàtic es pot commutar a la configuració del Bluetooth." + "Desactiva" + "Canvi d\'estat automàtic del Bluetooth" diff --git a/android/app/res/values-cs/strings.xml b/android/app/res/values-cs/strings.xml index 656778a08b7c0421d2857d762c58b99078b180c6..23f94a84309627ed5f51a4acfda889bf7d56bded 100644 --- a/android/app/res/values-cs/strings.xml +++ b/android/app/res/values-cs/strings.xml @@ -101,7 +101,6 @@ "Připojení se nezdařilo." "Požadavek není možné správně zpracovat." "Neznámá chyba." - "Bluetooth – přijaté soubory" "Sdílení Bluetooth" "%1$s Přijetí dokončeno." "%1$s Odeslání dokončeno." @@ -136,4 +135,8 @@ "Zařízení si pamatuje, že má v režimu Letadlo ponechat zapnutý Bluetooth. Pokud nechcete, aby Bluetooth zůstal zapnutý, vypněte ho." "Wi-Fi a Bluetooth zůstávají zapnuté" "Zařízení si pamatuje, že má v režimu Letadlo ponechat zapnutou Wi-Fi a Bluetooth. Pokud nechcete, aby Wi-Fi a Bluetooth zůstaly zapnuté, vypněte je." + "Rozhraní Bluetooth bylo automaticky zapnuto" + "Automatický restart lze přepnout v Nastavení Bluetooth." + "Vypnout" + "Automatická změna stavu rozhraní Bluetooth" diff --git a/android/app/res/values-da/strings.xml b/android/app/res/values-da/strings.xml index 5142cdaebde1bdfef35ade9755ffbecb81a638d8..2bb6d00ecce2512c844925205ab208e3e36b7a65 100644 --- a/android/app/res/values-da/strings.xml +++ b/android/app/res/values-da/strings.xml @@ -101,7 +101,6 @@ "Forbindelsen mislykkedes." "Anmodningen kan ikke håndteres korrekt." "Ukendt fejl." - "Modtaget via Bluetooth" "Bluetooth-deling" "%1$s Modtaget." "%1$s Afsendelse fuldført." @@ -136,4 +135,8 @@ "Din enhed beholder Bluetooth aktiveret i flytilstand. Deaktiver Bluetooth, hvis du ikke vil have, at det forbliver aktiveret." "Wi-Fi og Bluetooth forbliver aktiveret" "Din enhed beholder Wi-Fi og Bluetooth aktiveret i flytilstand. Deaktiver Wi-Fi og Bluetooth, hvis du ikke vil have, at de forbliver aktiveret." + "Bluetooth er automatisk blevet aktiveret" + "Automatisk genstart kan slås til/fra i Bluetooth-indstillingerne." + "Deaktiver" + "Automatisk ændring af Bluetooth-tilstand" diff --git a/android/app/res/values-de/strings.xml b/android/app/res/values-de/strings.xml index 7f23b5186ca339a3ccb9df29dc4e24ec50125a39..b6cd552271551e4d8f14356bb74380f05df74bb5 100644 --- a/android/app/res/values-de/strings.xml +++ b/android/app/res/values-de/strings.xml @@ -101,7 +101,6 @@ "Verbindung fehlgeschlagen" "Die Anfrage kann nicht richtig verarbeitet werden." "Unbekannter Fehler" - "Per Bluetooth empfangen" "Bluetooth-Freigabe" "%1$s vollständig empfangen." "%1$s vollständig gesendet." @@ -136,4 +135,8 @@ "Auf deinem Gerät bleibt Bluetooth im Flugmodus eingeschaltet. Schalte Bluetooth aus, wenn du das nicht möchtest." "WLAN und Bluetooth bleiben eingeschaltet" "Auf deinem Gerät bleiben WLAN und Bluetooth im Flugmodus eingeschaltet. Schalte sie aus, wenn du das nicht möchtest." + "Bluetooth wurde automatisch aktiviert" + "Der automatische Neustart kann in den Bluetooth-Einstellungen aktiviert oder deaktiviert werden." + "Deaktivieren" + "Automatische Änderung des Bluetooth-Status" diff --git a/android/app/res/values-el/strings.xml b/android/app/res/values-el/strings.xml index ada53d395cb75a62e12f7ce83ba283981d4c28af..ba1cde9a4b4eb8ebe14b595bab669bc45b886095 100644 --- a/android/app/res/values-el/strings.xml +++ b/android/app/res/values-el/strings.xml @@ -101,7 +101,6 @@ "Η σύνδεση δεν ήταν επιτυχής." "Δεν μπορεί να γίνει σωστός χειρισμός του αιτήματος." "Άγνωστο σφάλμα." - "Ελήφθη μέσω Bluetooth" "Μοιραστείτε μέσω Bluetooth" "Ελήφθησαν πλήρως %1$s." "Ολοκληρώθηκε η αποστολή %1$s." @@ -136,4 +135,8 @@ "Η συσκευή σας θυμάται να διατηρεί ενεργοποιημένο το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Bluetooth αν δεν θέλετε να παραμένει ενεργοποιημένο." "Το Wi-Fi και το Bluetooth παραμένουν ενεργοποιημένα" "Η συσκευή θυμάται να διατηρεί ενεργοποιημένο το Wi‑Fi και το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Wi-Fi και το Bluetooth αν δεν θέλετε να παραμένουν ενεργοποιημένα." + "Το Bluetooth ενεργοποιήθηκε αυτόματα" + "Η εναλλαγή της λειτουργίας αυτόματης επανεκκίνησης μπορεί να γίνει από τις Ρυθμίσεις Bluetooth." + "Απενεργοποίηση" + "Αυτόματη αλλαγή κατάστασης Bluetooth" diff --git a/android/app/res/values-en-rAU/strings.xml b/android/app/res/values-en-rAU/strings.xml index 73ffd04a0ca0d0dab4bd49d920e82b449a847396..d249d7f0ebf16b8d137c6b862ffad34dce70d57b 100644 --- a/android/app/res/values-en-rAU/strings.xml +++ b/android/app/res/values-en-rAU/strings.xml @@ -101,7 +101,6 @@ "Connection unsuccessful." "Request can\'t be handled correctly." "Unknown error." - "Bluetooth received" "Bluetooth Share" "%1$s Received complete." "%1$s Sent complete." @@ -136,4 +135,8 @@ "Your device remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." "Wi-Fi and Bluetooth stay on" "Your device remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + "Bluetooth has been automatically enabled" + "Automatic restart can be toggled in Bluetooth settings." + "Turn off" + "Bluetooth automatic state change" diff --git a/android/app/res/values-en-rCA/strings.xml b/android/app/res/values-en-rCA/strings.xml index bbba4a440a88122b51adaaf06ada23c25e45beb9..f875ac79265adc40237435595644bcb7ef1efb3f 100644 --- a/android/app/res/values-en-rCA/strings.xml +++ b/android/app/res/values-en-rCA/strings.xml @@ -101,7 +101,6 @@ "Connection unsuccessful." "Request can\'t be handled correctly." "Unknown error." - "Bluetooth received" "Bluetooth Share" "%1$s Received complete." "%1$s Sent complete." @@ -136,4 +135,8 @@ "Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on." "Wi-Fi and Bluetooth stay on" "Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + "Bluetooth has been automatically enabled" + "Automatic restart can be toggled in Bluetooth Settings." + "Turn off" + "Bluetooth automatic state change" diff --git a/android/app/res/values-en-rGB/strings.xml b/android/app/res/values-en-rGB/strings.xml index 73ffd04a0ca0d0dab4bd49d920e82b449a847396..d249d7f0ebf16b8d137c6b862ffad34dce70d57b 100644 --- a/android/app/res/values-en-rGB/strings.xml +++ b/android/app/res/values-en-rGB/strings.xml @@ -101,7 +101,6 @@ "Connection unsuccessful." "Request can\'t be handled correctly." "Unknown error." - "Bluetooth received" "Bluetooth Share" "%1$s Received complete." "%1$s Sent complete." @@ -136,4 +135,8 @@ "Your device remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." "Wi-Fi and Bluetooth stay on" "Your device remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + "Bluetooth has been automatically enabled" + "Automatic restart can be toggled in Bluetooth settings." + "Turn off" + "Bluetooth automatic state change" diff --git a/android/app/res/values-en-rIN/strings.xml b/android/app/res/values-en-rIN/strings.xml index 73ffd04a0ca0d0dab4bd49d920e82b449a847396..d249d7f0ebf16b8d137c6b862ffad34dce70d57b 100644 --- a/android/app/res/values-en-rIN/strings.xml +++ b/android/app/res/values-en-rIN/strings.xml @@ -101,7 +101,6 @@ "Connection unsuccessful." "Request can\'t be handled correctly." "Unknown error." - "Bluetooth received" "Bluetooth Share" "%1$s Received complete." "%1$s Sent complete." @@ -136,4 +135,8 @@ "Your device remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." "Wi-Fi and Bluetooth stay on" "Your device remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + "Bluetooth has been automatically enabled" + "Automatic restart can be toggled in Bluetooth settings." + "Turn off" + "Bluetooth automatic state change" diff --git a/android/app/res/values-en-rXC/strings.xml b/android/app/res/values-en-rXC/strings.xml index c81c28b3ac518569d6c837884c353c251607419a..80df24c1fddd982aa0f0789ade5d82a6e4867f9c 100644 --- a/android/app/res/values-en-rXC/strings.xml +++ b/android/app/res/values-en-rXC/strings.xml @@ -101,7 +101,6 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎Connection unsuccessful.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‏‎‎Request can\'t be handled correctly.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎Unknown error.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎Bluetooth received‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎Bluetooth Share‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ Received complete.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ Sent complete.‎‏‎‎‏‎" @@ -136,4 +135,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎Wi-Fi and Bluetooth stay on‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‎‎Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎Bluetooth has been automatically enabled‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎Automatic restart can be toggled in Bluetooth Settings.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎Turn off‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎Bluetooth automatic state change‎‏‎‎‏‎" diff --git a/android/app/res/values-es-rUS/strings.xml b/android/app/res/values-es-rUS/strings.xml index 8a10bd5c3ba62deffa351f78b33f8f6fe08b2bcf..f58355cea3eb983b3abe10a6d82c62837f418c36 100644 --- a/android/app/res/values-es-rUS/strings.xml +++ b/android/app/res/values-es-rUS/strings.xml @@ -101,7 +101,6 @@ "Conexión incorrecta" "No se puede procesar la solicitud correctamente." "Error desconocido" - "Recibido por Bluetooth" "Compartir por Bluetooth" "Se recibieron %1$s completos." "%1$s enviados por completo." @@ -136,4 +135,8 @@ "El dispositivo dejará activado el Bluetooth en el modo de avión. Desactiva el Bluetooth si no quieres que permanezca activado." "El Wi-Fi y el Bluetooth permanecen activados" "El dispositivo dejará activado el Wi-Fi y el Bluetooth en el modo de avión. Desactívalos si no quieres que permanezcan activados." + "El Bluetooth se habilitó automáticamente" + "El reinicio automático se puede activar o desactivar en la configuración de Bluetooth." + "Desactivar" + "Cambio automático del estado de Bluetooth" diff --git a/android/app/res/values-es/strings.xml b/android/app/res/values-es/strings.xml index 48cf103ec4ae9ad3501cd8e78343a1827fe3f8c0..a1e10965602a88959229434ea467a818e2a79c45 100644 --- a/android/app/res/values-es/strings.xml +++ b/android/app/res/values-es/strings.xml @@ -101,7 +101,6 @@ "Conexión incorrecta" "No se puede procesar la solicitud correctamente." "Error desconocido" - "Recibido por Bluetooth" "Bluetooth Share" "Recepción de %1$s completada" "Envío de %1$s completado" @@ -136,4 +135,8 @@ "Tu dispositivo se acordará de mantener activado el Bluetooth en modo Avión. Desactiva el Bluetooth si no quieres que permanezca activado." "El Wi-Fi y el Bluetooth permanecen activados" "Tu dispositivo se acordará de mantener activados el Wi-Fi y el Bluetooth en modo Avión. Desactívalos si no quieres que permanezcan activados." + "El Bluetooth se ha habilitado automáticamente" + "El reinicio automático se puede activar o desactivar en los ajustes del Bluetooth." + "Desactivar" + "Cambio de estado automático del Bluetooth" diff --git a/android/app/res/values-et/strings.xml b/android/app/res/values-et/strings.xml index 52a5fdf10a9ed1187c4dd62f3877321b399fcb85..d11907f9010d4953eab409b9f95c83e248472fed 100644 --- a/android/app/res/values-et/strings.xml +++ b/android/app/res/values-et/strings.xml @@ -101,7 +101,6 @@ "Ühendus ebaõnnestus." "Taotlust ei saa õigesti käsitleda." "Tundmatu viga." - "Bluetoothiga vastu võetud" "Jagamine Bluetoothiga" "%1$s vastuvõtmine lõpetatud." "%1$s saatmine lõpetatud." @@ -136,4 +135,8 @@ "Teie seade hoiab Bluetoothi lennukirežiimis sisselülitatuna. Lülitage Bluetooth välja, kui te ei soovi, et see oleks sisse lülitatud." "WiFi ja Bluetoothi jäävad sisselülitatuks" "Teie seade hoiab WiFi ja Bluetoothi lennukirežiimis sisselülitatuna. Lülitage WiFi ja Bluetooth välja, kui te ei soovi, et need oleksid sisse lülitatud." + "Bluetooth on automaatselt lubatud" + "Automaatse taaskäivitamise saab sisse lülitada Bluetoothi seadetes." + "Lülita välja" + "Bluetoothi oleku automaatne muutmine" diff --git a/android/app/res/values-eu/strings.xml b/android/app/res/values-eu/strings.xml index 64e721afa756265aece7caee621b631acbd8405d..ff0b32d38e103e33289e6bc9c1a8ce73fd716599 100644 --- a/android/app/res/values-eu/strings.xml +++ b/android/app/res/values-eu/strings.xml @@ -18,9 +18,9 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Bluetootha" "Atzitu deskargen kudeatzailea." - "Bluetooth bidezko partekatzeen kudeatzailea atzitzea eta fitxategiak transferitzeko erabiltzeko baimena ematen die aplikazioei." + "Bluetooth bidezko partekatzeen kudeatzailea atzitzea eta fitxategiak transferitzeko erabiltzeko baimena ematen dio aplikazioari." "Ezarri Bluetooth bidezko gailuak onartutakoen zerrendan." - "Bluetooth bidezko gailu bat aldi baterako onartutakoen zerrendan ezartzeko baimena ematen die aplikazioei, gailu honetara fitxategiak bidaltzeko baimena izan dezan, baina gailu honen erabiltzaileari berrespena eskatu beharrik gabe." + "Bluetooth bidezko gailu bat aldi baterako onartutakoen zerrendan ezartzeko baimena ematen dio aplikazioari, gailu honetara fitxategiak bidaltzeko baimena izan dezan, baina gailu honen erabiltzaileari berrespena eskatu beharrik gabe." "Bluetootha" "Identifikatu ezin den gailua" "Ezezaguna" @@ -101,7 +101,6 @@ "Ezin izan da konektatu." "Ezin da eskaera behar bezala kudeatu." "Errore ezezaguna." - "Bluetooth bidez jasotakoak" "Bluetooth bidez partekatzea" "%1$s jaso dira osorik." "%1$s osorik bidali da." @@ -136,4 +135,8 @@ "Hegaldi moduan, Bluetootha aktibatuta mantentzeaz gogoratzen da gailua. Halakorik nahi ez baduzu, desaktiba ezazu zuk zeuk." "Wifia eta Bluetootha aktibatuta mantentzen dira" "Hegaldi moduan, wifia eta Bluetootha aktibatuta mantentzeaz gogoratzen da gailua. Halakorik nahi ez baduzu, desaktiba itzazu zuk zeuk." + "Bluetootha automatikoki gaitu da" + "Bluetootharen ezarpenetan alda daiteke automatikoki berrabiarazteko aukera." + "Desaktibatu" + "Bluetootharen egoera automatikoki aldatu da" diff --git a/android/app/res/values-fa/strings.xml b/android/app/res/values-fa/strings.xml index e72edd954df88f3a2dd08fa298a7ea634007a9a1..87bfa9627b07854b359fa1023f85d29fd70b7249 100644 --- a/android/app/res/values-fa/strings.xml +++ b/android/app/res/values-fa/strings.xml @@ -101,7 +101,6 @@ "اتصال ناموفق بود." "درخواست به درستی انجام نمی‌شود." "خطای ناشناس." - "بلوتوث دریافت شد" "اشتراکگذاری بلوتوث" "%1$s دریافت کامل شد." "%1$s ارسال کامل شد." @@ -136,4 +135,8 @@ "دستگاهتان به‌یاد می‌آورد که بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید بلوتوث روشن بماند، آن را خاموش کنید." "‏‫Wi-Fi و بلوتوث روشن بماند" "‏دستگاهتان به‌یاد می‌آورد که Wi-Fi و بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید Wi-Fi و بلوتوث روشن بمانند، آن‌ها را خاموش کنید." + "بلوتوث به‌طور خودکار فعال شد" + "بازراه‌اندازی خودکار را می‌توان در تنظیمات بلوتوث روشن/خاموش کرد." + "خاموش کردن" + "تغییر خودکار وضعیت بلوتوث" diff --git a/android/app/res/values-fi/strings.xml b/android/app/res/values-fi/strings.xml index 8f33c50ce94ff4841ddddee0ac91eb052d1f8a4d..2ce26a0d2ab221d9f29ae819c33cfb3aed3057e2 100644 --- a/android/app/res/values-fi/strings.xml +++ b/android/app/res/values-fi/strings.xml @@ -31,7 +31,7 @@ "Jos haluat käyttää Bluetooth-palveluita, ota Bluetooth käyttöön." "Otetaanko Bluetooth käyttöön nyt?" "Peru" - "Ota käyttöön" + "Laita päälle" "Tiedostonsiirto" "Hyväksytäänkö saapuva tiedosto?" "Hylkää" @@ -101,7 +101,6 @@ "Yhteys epäonnistui." "Pyyntö ei ole käsiteltävissä." "Tuntematon virhe." - "Bluetooth, vastaanotettu" "Bluetooth-jako" "%1$s vastaanotto valmis." "%1$s lähetys valmis." @@ -136,4 +135,8 @@ "Laitteen Bluetooth pysyy päällä lentokonetilassa. Voit halutessasi laittaa Bluetooth-yhteyden pois päältä." "Wi-Fi ja Bluetooth pysyvät päällä" "Laitteen Wi-Fi-yhteys ja Bluetooth pysyvät päällä lentokonetilassa. Voit halutessasi laittaa ne pois päältä." + "Bluetooth on otettu automaattisesti käyttöön" + "Automaattisen uudelleenkäynnistyksen voi laittaa päälle/pois Bluetoothin asetuksista." + "Laita pois päältä" + "Bluetoothin automaattiasetuksen muutos" diff --git a/android/app/res/values-fr-rCA/strings.xml b/android/app/res/values-fr-rCA/strings.xml index 1884953ea5cf211668d2d4ecda3b319cc07921a0..8ddbe92685c8b79850b9a2cbd0e26f62aeea133d 100644 --- a/android/app/res/values-fr-rCA/strings.xml +++ b/android/app/res/values-fr-rCA/strings.xml @@ -101,7 +101,6 @@ "Échec de la connexion." "Impossible de traiter la demande correctement." "Erreur inconnue." - "Reçu par Bluetooth" "Partage Bluetooth" "Réception de %1$s terminée" "Envoi de %1$s terminé" @@ -136,4 +135,8 @@ "Votre appareil se souvient de garder le Bluetooth activé en mode Avion. Désactivez le Bluetooth si vous ne souhaitez pas qu\'il reste activé." "Le Wi-Fi et le Bluetooth restent activés" "Votre appareil se souvient de garder le Wi-Fi et le Bluetooth activés en mode Avion. Désactivez le Wi-Fi et le Bluetooth si vous ne souhaitez pas qu\'ils restent activés." + "Le Bluetooth a été automatiquement activé" + "Le redémarrage automatique peut être activé/désactivé dans les paramètres Bluetooth." + "Désactiver" + "Changement d\'état automatique du Bluetooth" diff --git a/android/app/res/values-fr/strings.xml b/android/app/res/values-fr/strings.xml index 321d505f742deca45cc9a477049242c77fcab204..53e2802ee8270d84d4996695607210b9f3eabeb5 100644 --- a/android/app/res/values-fr/strings.xml +++ b/android/app/res/values-fr/strings.xml @@ -101,7 +101,6 @@ "Échec de la connexion." "Impossible de traiter la demande correctement." "Erreur inconnue." - "Reçus via Bluetooth" "Partage Bluetooth" "Réception de %1$s terminée" "Envoi de %1$s terminé" @@ -136,4 +135,8 @@ "Le Bluetooth de votre appareil restera activé en mode Avion, mais vous pouvez le désactiver." "Le Wi-Fi et le Bluetooth restent activés" "Le Wi‑Fi et le Bluetooth de votre appareil resteront activés en mode Avion, mais vous pouvez les désactivez." + "Le Bluetooth a été activé automatiquement" + "Le redémarrage automatique peut être activé ou désactivé depuis les paramètres Bluetooth." + "Désactiver" + "Changement de statut automatique du Bluetooth" diff --git a/android/app/res/values-gl/strings.xml b/android/app/res/values-gl/strings.xml index 5f43ed314877527e726c29319c65a59a21f00b87..a0ffe6be27e65e69b2e1a71204eef999ed6b19b5 100644 --- a/android/app/res/values-gl/strings.xml +++ b/android/app/res/values-gl/strings.xml @@ -101,7 +101,6 @@ "Conexión incorrecta" "A solicitude non se pode atender correctamente." "Erro descoñecido" - "Recibido por Bluetooth" "Uso compartido por Bluetooth" "%1$s: recepción completa." "Envío de %1$s completado." @@ -136,4 +135,8 @@ "O teu dispositivo lembrará manter o Bluetooth activado no modo avión. Se non queres que permaneza nese estado, desactívao." "A wifi e o Bluetooth permanecen activados" "O teu dispositivo lembrará manter a wifi e o Bluetooth activados no modo avión. Se non queres que permanezan nese estado, desactívaos." + "Activouse automaticamente o Bluetooth" + "O reinicio automático pode activarse e desactivarse na configuración do Bluetooth." + "Desactivar" + "Cambio automático do estado do Bluetooth" diff --git a/android/app/res/values-gu/strings.xml b/android/app/res/values-gu/strings.xml index 1f2a403c2b851322b57508aacb71ad14bc13b20d..2a3412095260ca30079483f8fa9c77d50cb13315 100644 --- a/android/app/res/values-gu/strings.xml +++ b/android/app/res/values-gu/strings.xml @@ -101,7 +101,6 @@ "કનેક્શન અસફળ." "વિનંતી યોગ્ય રીતે હેન્ડલ કરી શકાતી નથી." "અજાણી ભૂલ." - "બ્લૂટૂથથી મળેલી ફાઇલો" "બ્લૂટૂથ શેર" "%1$s પ્રાપ્તિ પૂર્ણ" "%1$s મોકલવું પૂર્ણ." @@ -136,4 +135,8 @@ "તમારું ડિવાઇસ બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." "વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રહે છે" "તમારું ડિવાઇસ વાઇ-ફાઇ અને બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." + "બ્લૂટૂથ ઑટોમૅટિક રીતે ચાલુ થઈ ગયું છે" + "બ્લૂટૂથ સેટિંગમાં જઈને ઑટોમૅટિક રીતે ફરી શરૂ કરવાની સુવિધા ટૉગલ કરી શકાય છે." + "બંધ કરો" + "બ્લૂટૂથ ઑટોમૅટિક રીતે ચાલુ થવાનું સેટિંગ બદલવામાં આવ્યું છે" diff --git a/android/app/res/values-hi/strings.xml b/android/app/res/values-hi/strings.xml index 03c8c3ccfd6871cefabb4307209c923e7b0b2e55..6622a3e4105ad3b2fce96fe1ebbe9c047263f757 100644 --- a/android/app/res/values-hi/strings.xml +++ b/android/app/res/values-hi/strings.xml @@ -77,7 +77,7 @@ "इस प्रकार की फ़ाइल प्रबंधित करने के लिए कोई ऐप्लिकेशन नहीं है. \n" "कोई फ़ाइल नहीं" "फ़ाइल मौजूद नहीं है. \n" - "कृपया प्रतीक्षा करें..." + "कृपया इंतज़ार करें..." "ब्लूटूथ चालू कर रहा है…" "फ़ाइल मिलेगी. सूचना पैनल में प्रगति देखें." "फ़ाइल पाई नहीं जा सकती." @@ -101,7 +101,6 @@ "कनेक्‍शन विफल." "अनुरोध को सही तरह से प्रबंधित नहीं किया जा सकता." "अज्ञात गड़बड़ी‍." - "ब्लूटूथ से मिली फ़ाइलें" "ब्लूटूथ के ज़रिए शेयर" "%1$s मिलना पूरा हुआ." "%1$s भेजना पूरा हुआ." @@ -136,4 +135,8 @@ "फ़्लाइट मोड में भी, आपके डिवाइस का ब्लूटूथ चालू रहता है. अगर ब्लूटूथ चालू नहीं रखना है, तो उसे बंद कर दें." "वाई-फ़ाई और ब्लूटूथ चालू रहते हैं" "फ़्लाइट मोड में भी, आपके डिवाइस का वाई-फ़ाई और ब्लूटूथ चालू रहता है. अगर वाई-फ़ाई और ब्लूटूथ को चालू नहीं रखना है, तो उन्हें बंद कर दें." + "ब्लूटूथ अपने-आप चालू हो गया है" + "ब्लूटूथ की सेटिंग में अपने-आप रीस्टार्ट होने की सुविधा को टॉगल किया जा सकता है." + "बंद करें" + "ब्लूटूथ अपने-आप चालू होने की सेटिंग को बदल दिया गया है" diff --git a/android/app/res/values-hr/strings.xml b/android/app/res/values-hr/strings.xml index a0782a3f49cc25019394cd4d9bbc06fd6512075d..c6005390d2a868775850376644a7ac499385a7fe 100644 --- a/android/app/res/values-hr/strings.xml +++ b/android/app/res/values-hr/strings.xml @@ -101,7 +101,6 @@ "Neuspješno povezivanje." "Zahtjev nije moguće ispravno obraditi." "Nepoznata pogreška." - "Primljeno Bluetoothom" "Dijeljenje Bluetoothom" "%1$s primljeno u cijelosti." "%1$s Poslano u potpunosti." @@ -136,4 +135,8 @@ "Uređaj će zapamtiti da Bluetooth treba ostati uključen u načinu rada u zrakoplovu. Isključite Bluetooth ako ne želite da ostane uključen." "Wi-Fi i Bluetooth ostat će uključeni" "Uređaj će zapamtiti da Wi‑Fi i Bluetooth trebaju ostati uključeni u načinu rada u zrakoplovu. Isključite Wi-Fi i Bluetooth ako ne želite da ostanu uključeni." + "Bluetooth je automatski omogućen" + "Automatsko ponovno pokretanje može se uključiti u postavkama Bluetootha." + "Isključi" + "Automatska promjena stanja Bluetootha" diff --git a/android/app/res/values-hu/strings.xml b/android/app/res/values-hu/strings.xml index f6dd025e8612067b3fa34618e2f7d1fea4d2e1b3..3372a85737d3ac22da905d864c05d6cba836b223 100644 --- a/android/app/res/values-hu/strings.xml +++ b/android/app/res/values-hu/strings.xml @@ -101,7 +101,6 @@ "A kapcsolódás sikertelen." "A kérést nem lehet megfelelően kezelni." "Ismeretlen hiba." - "Fogadás Bluetooth-on keresztül" "Bluetooth-megosztás" "%1$s A fogadás kész." "%1$s A küldés kész.." @@ -136,4 +135,8 @@ "Az eszköz bekapcsolva tartja a Bluetootht Repülős üzemmódban. Kapcsolja ki a Bluetootht, ha nem szeretné, hogy bekapcsolva maradjon." "A Wi-Fi és a Bluetooth bekapcsolva marad" "Az eszköz bekapcsolva tartja a Wi‑Fi-t és a Bluetootht Repülős üzemmódban. Ha nem szeretné, hogy bekapcsolva maradjon a Wi-Fi és a Bluetooth, kapcsolja ki őket." + "A Bluetooth automatikusan engedélyezve" + "Az automatikus újraindítás a Bluetooth beállításai között kapcsolható be és ki." + "Igen" + "Bluetooth állapotának automatikus módosítása" diff --git a/android/app/res/values-hy/strings.xml b/android/app/res/values-hy/strings.xml index 980211304699107aaa2478b46c0d274aded9c6ef..381f3e833a9217f76dfb0a5884d24ad4486acb94 100644 --- a/android/app/res/values-hy/strings.xml +++ b/android/app/res/values-hy/strings.xml @@ -101,7 +101,6 @@ "Միացումը անհաջող էր:" "Հարցումը հնարավոր չէ ճշգրտորեն մշակել:" "Անհայտ սխալ:" - "Bluetooth-ով ստացված" "Bluetooth-ով փոխանցում" "%1$s ստացումն ավարտված է:" "%1$s ուղարկումն ավարտված է:" @@ -136,4 +135,8 @@ "Ավիառեժիմում Bluetooth-ը միացված կմնա։ Ցանկության դեպքում կարող եք անջատել Bluetooth-ը։" "Wi-Fi-ը և Bluetooth-ը մնում են միացված" "Ավիառեժիմում Wi-Fi-ը և Bluetooth-ը միացված կմնան։ Ցանկության դեպքում կարող եք անջատել Wi-Fi-ը և Bluetooth-ը։" + "Bluetooth-ն ավտոմատ միացել է" + "Ավտոմատ վերագործարկումը կարող եք միացնել/անջատել Bluetooth-ի կարգավորումներում։" + "Անջատել" + "Bluetooth-ի ավտոմատ կարգավիճակի փոփոխություն" diff --git a/android/app/res/values-in/strings.xml b/android/app/res/values-in/strings.xml index e6c31b9f38a68c12e3cb7ecccf1a9c7fa35a4607..ab72716ce21adc20ebb4068f5a298383936b9b93 100644 --- a/android/app/res/values-in/strings.xml +++ b/android/app/res/values-in/strings.xml @@ -101,7 +101,6 @@ "Sambungan tidak berhasil." "Permintaan tidak dapat ditangani dengan semestinya." "Kesalahan tidak dikenal." - "Bluetooth diterima" "Berbagi via Bluetooth" "%1$s Telah selesai diterima." "%1$s Telah selesai dikirim." @@ -136,4 +135,8 @@ "Perangkat akan mengingat untuk tetap mengaktifkan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Bluetooth terus aktif." "Wi-Fi dan Bluetooth tetap aktif" "Perangkat akan mengingat untuk tetap mengaktifkan Wi-Fi dan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Wi-Fi dan Bluetooth terus aktif." + "Bluetooth telah otomatis diaktifkan" + "Mulai ulang otomatis dapat diaktifkan/dinonaktifkan di Setelan Bluetooth." + "Nonaktifkan" + "Status otomatis Bluetooth diubah" diff --git a/android/app/res/values-is/strings.xml b/android/app/res/values-is/strings.xml index 667a6cb752a7d30a1fe30748d76f0f37bbb324a9..107f0ae5e989f3850f20eab8802cf0ad9c07bea6 100644 --- a/android/app/res/values-is/strings.xml +++ b/android/app/res/values-is/strings.xml @@ -101,7 +101,6 @@ "Tenging mistókst." "Ekki er hægt að afgreiða beiðnina á réttan hátt." "Óþekkt villa." - "Móttekið um Bluetooth" "Bluetooth-deiling" "Móttöku %1$s lokið." "Sendingu %1$s lokið." @@ -136,4 +135,8 @@ "Tækið man að hafa kveikt á Bluetooth í flugstillingu. Slökktu á Bluetooth ef þú vilt ekki hafa kveikt á því." "Áfram verður kveikt á Wi-Fi og Bluetooth" "Tæki man að hafa kveikt á Wi-Fi og Bluetooth í flugstillingu. Slökktu á Wi-Fi og Bluetooth ef þú vilt ekki hafa kveikt á þessu." + "Kveikt var á Bluetooth sjálfkrafa" + "Hægt er að kveikja/slökkva á sjálfvirkri endurræsingu í stillingum Bluetooth." + "Slökkva" + "Staða Bluetooth breyttist sjálfkrafa" diff --git a/android/app/res/values-it/strings.xml b/android/app/res/values-it/strings.xml index 73c7df59438276a852e2fea70da0ea893548778a..991e8a491382d513bcdb053238554902613967f0 100644 --- a/android/app/res/values-it/strings.xml +++ b/android/app/res/values-it/strings.xml @@ -101,7 +101,6 @@ "Connessione non riuscita." "Impossibile gestire correttamente la richiesta." "Errore sconosciuto." - "Ricevuti tramite Bluetooth" "Condivisione Bluetooth" "Ricezione completata (%1$s)" "Invio completato (%1$s)" @@ -136,4 +135,8 @@ "Il dispositivo memorizza che deve tenere attivo il Bluetooth in modalità aereo. Disattiva il Bluetooth se non vuoi tenerlo attivo." "Wi-Fi e Bluetooth rimangono attivi" "Il dispositivo memorizza che deve tenere attivi il Wi‑Fi e il Bluetooth in modalità aereo. Disattiva il Wi-Fi e il Bluetooth se non vuoi tenerli attivi." + "Il Bluetooth è stato attivato automaticamente" + "È possibile attivare/disattivare il riavvio automatico nelle impostazioni del Bluetooth." + "Disattiva" + "Modifica dello stato automatico del Bluetooth" diff --git a/android/app/res/values-iw/strings.xml b/android/app/res/values-iw/strings.xml index 288935f50d03cd58af0e6022885e89c280b10b90..8073217cab1464bb35678bfdfc2a5b2bb8f8ed50 100644 --- a/android/app/res/values-iw/strings.xml +++ b/android/app/res/values-iw/strings.xml @@ -101,7 +101,6 @@ "החיבור נכשל." "לא ניתן לטפל בבקשה כהלכה." "שגיאה לא ידועה." - "‏קבצים שהתקבלו דרך Bluetooth" "‏שיתוף Bluetooth" "%1$s שהתקבלו הושלמו." "%1$s שנשלחו הושלמו." @@ -136,4 +135,8 @@ "‏חיבור ה-Bluetooth במכשיר יישאר מופעל במצב טיסה. אפשר להשבית את ה-Bluetooth אם לא רוצים שהוא יפעל." "‏חיבורי ה-Wi‑Fi וה-Bluetooth יישארו מופעלים" "‏חיבורי ה-Wi‑Fi וה-Bluetooth במכשיר יישארו מופעלים במצב טיסה. אפשר להשבית את ה-Wi-Fi וה-Bluetooth אם לא רוצים שהם יפעלו." + "‏‫Bluetooth מופעל באופן אוטומטי" + "‏אפשר להחליף את המצב להפעלה אוטומטית מחדש בהגדרות של Bluetooth." + "השבתה" + "‏החלפת מצב אוטומטית של Bluetooth" diff --git a/android/app/res/values-ja/strings.xml b/android/app/res/values-ja/strings.xml index 39782962a8eb0d16ef4091223b4e8ea239954992..076e002e880eb01540577b78c13892a00812ad28 100644 --- a/android/app/res/values-ja/strings.xml +++ b/android/app/res/values-ja/strings.xml @@ -101,7 +101,6 @@ "接続できませんでした。" "リクエストを正しく処理できません。" "不明なエラーです。" - "Bluetooth で受信したファイル" "Bluetooth 共有" "%1$sの受信が完了しました。" "%1$sの送信が完了しました。" @@ -136,4 +135,8 @@ "機内モードでも、デバイスの Bluetooth は ON のままになります。Bluetooth を ON にしたくない場合は OFF にしてください。" "Wi-Fi と Bluetooth を ON のままにする" "機内モードでも、デバイスの Wi-Fi と Bluetooth は ON のままになります。Wi-Fi と Bluetooth を ON にしたくない場合は OFF にしてください。" + "Bluetooth は自動で有効になりました" + "自動再起動は [Bluetooth の設定] で切り替えられます。" + "OFF にする" + "Bluetooth の自動状態変更" diff --git a/android/app/res/values-ka/strings.xml b/android/app/res/values-ka/strings.xml index a46b7283b0925bc656c87250e3b31cdd22eacdc6..2f25322d231bec03fbf0f4fad1cffa3bf4c88a85 100644 --- a/android/app/res/values-ka/strings.xml +++ b/android/app/res/values-ka/strings.xml @@ -101,7 +101,6 @@ "კავშირი ვერ განხორციელდა." "მოთხოვნის სწორად დამუშავება ვერ ხერხდება." "უცნობი შეცდომა." - "Bluetooth-ით მიღებული" "Bluetooth გაზიარება" "%1$s მიღება დასრულდა." "%1$s გაგზავნა დასრულდა." @@ -136,4 +135,8 @@ "თქვენს მოწყობილობას ახსოვს, რომ Bluetooth ჩართული დატოვოს თვითმფრინავის რეჟიმში. გამორთეთ Bluetooth, თუ არ გსურთ, რომ ის ჩართული იყოს." "Wi-Fi და Bluetooth ჩართული დარჩება" "თქვენს მოწყობილობას ახსოვს, რომ Wi‑Fi და Bluetooth ჩართული დატოვოს თვითმფრინავის რეჟიმში. გამორთეთ Wi-Fi და Bluetooth, თუ არ გსურთ, რომ ისინი ჩართული იყოს." + "Bluetooth ჩართულია ავტომატურად" + "ავტომატური გადატვირთვის გადართვა შესაძლებელია Bluetooth-ის პარამეტრებიდან." + "გამორთვა" + "Bluetooth-ის მდგომარეობის ავტომატური შეცვლა" diff --git a/android/app/res/values-kk/strings.xml b/android/app/res/values-kk/strings.xml index 4a977f371711cc696ff4f0f2ed44ccc3dd29f018..72e30ca5cf018d8dc957c8858b2a209834ab43be 100644 --- a/android/app/res/values-kk/strings.xml +++ b/android/app/res/values-kk/strings.xml @@ -101,7 +101,6 @@ "Байланыс сәтсіз болды." "Өтінішті дұрыс орындау мүмкін емес." "Белгісіз қателік." - "Bluetooth арқылы алынғандар" "Bluetooth бөлісу" "%1$s Толығымен қабылданды." "%1$s Жіберіліп болды." @@ -136,4 +135,8 @@ "Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оны өшіріп қоюыңызға болады." "Wi-Fi мен Bluetooth қосулы тұрады" "Wi‑Fi мен Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оларды өшіріп қоюыңызға болады." + "Bluetooth автоматты түрде іске қосылды" + "Автоматты түрде өшіріп қосуды Bluetooth параметрлерін ауыстыруға болады." + "Өшіру" + "Bluetooth-тің күйін автоматты түрде өзгерту" diff --git a/android/app/res/values-km/strings.xml b/android/app/res/values-km/strings.xml index c785fd29f32aa1812e8a233e24eeda1f3df6aca3..556a3d6b4b64c27669a09a88aac0d1a34b86bf8b 100644 --- a/android/app/res/values-km/strings.xml +++ b/android/app/res/values-km/strings.xml @@ -101,7 +101,6 @@ "ការ​តភ្ជាប់​​មិន​ជោគជ័យ​។" "មិន​អាច​ដោះស្រាយ​សំណើ​​​​ដោយ​ត្រឹមត្រូវ​ទេ។" "មិន​ស្គាល់​កំហុស។" - "​បាន​ទទួលតាម​​ប៊្លូ​ធូ​ស" "ការ​ចែករំលែក​ប៊្លូ​ធូ​ស" "បាន​ទទួល​ពេញ​លេញ %1$s ។" "បាន​ផ្ញើ​ពេញ​លេញ %1$s ។" @@ -136,4 +135,8 @@ "ឧបករណ៍របស់អ្នក​ចាំថាត្រូវបន្តបើកប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់ឱ្យបន្តបើកទេ។" "Wi-Fi និងប៊្លូធូស​បន្តបើក" "ឧបករណ៍របស់អ្នក​ចាំថាត្រូវបន្តបើក Wi-Fi និងប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទ Wi-Fi និង​ប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់ឱ្យបន្តបើកទេ។" + "ប៊្លូធូសត្រូវបានបើកដោយស្វ័យប្រវត្តិ" + "អាចបិទ/បើកការចាប់ផ្ដើម​ឡើងវិញស្វ័យប្រវត្តិនៅក្នុងការកំណត់ប៊្លូធូស។" + "បិទ" + "ការផ្លាស់ប្ដូរស្ថានភាពស្វ័យប្រវត្តិរបស់ប៊្លូធូស" diff --git a/android/app/res/values-kn/strings.xml b/android/app/res/values-kn/strings.xml index 0e0ecd2ff09802fa53e89b47a6d4123d3927a87e..3378aeac6052c000acdc27f2f103b974625de4e2 100644 --- a/android/app/res/values-kn/strings.xml +++ b/android/app/res/values-kn/strings.xml @@ -101,7 +101,6 @@ "ಸಂಪರ್ಕವು ವಿಫಲವಾಗಿದೆ." "ವಿನಂತಿಯನ್ನು ಸರಿಯಾಗಿ ನಿರ್ವಹಿಸಲಾಗುವುದಿಲ್ಲ." "ಅಪರಿಚಿತ ದೋಷ." - "ಬ್ಲೂಟೂತ್‌ ಸ್ವೀಕರಿಸಲಾಗಿದೆ" "ಬ್ಲೂಟೂತ್‌ ಹಂಚಿಕೆ" "%1$s ಸ್ವೀಕರಿಸುವುದು ಪೂರ್ಣಗೊಂಡಿದೆ." "%1$s ಕಳುಹಿಸುವುದು ಪೂರ್ಣಗೊಂಡಿದೆ." @@ -136,4 +135,8 @@ "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಸಾಧನ ನೆನಪಿನಲ್ಲಿರಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅದನ್ನು ಆಫ್ ಮಾಡಿ." "ವೈ-ಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರುತ್ತದೆ" "ವೈ-ಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಅನ್ನು ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಇರಿಸಿಕೊಳ್ಳಲು ನಿಮ್ಮ ಸಾಧನ ನೆನಪಿನಲ್ಲಿರಿಸಿಕೊಳ್ಳುತ್ತದೆ. ವೈಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅವುಗಳನ್ನು ಆಫ್ ಮಾಡಿ." + "ಬ್ಲೂಟೂತ್ ಅನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ" + "ಸ್ವಯಂಚಾಲಿತ ಮರುಪ್ರಾರಂಭವನ್ನು ಬ್ಲೂಟೂತ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಟಾಗಲ್ ಮಾಡಬಹುದು." + "ಆಫ್ ಮಾಡಿ" + "ಬ್ಲೂಟೂತ್ ಸ್ವಯಂಚಾಲಿತ ಸ್ಥಿತಿಯ ಬದಲಾವಣೆ" diff --git a/android/app/res/values-ko/strings.xml b/android/app/res/values-ko/strings.xml index 2995916a079cb6bb2ce3e90d6d9d84969556a335..91204090cb5366ff0bab1b99e8e2b10004a23afc 100644 --- a/android/app/res/values-ko/strings.xml +++ b/android/app/res/values-ko/strings.xml @@ -101,7 +101,6 @@ "연결하지 못했습니다." "요청을 제대로 처리할 수 없습니다." "알 수 없는 오류입니다." - "블루투스로 받은 파일" "블루투스 공유" "%1$s 수신을 완료했습니다." "%1$s 전송을 완료했습니다." @@ -136,4 +135,8 @@ "비행기 모드에서 기기의 블루투스가 켜진 상태로 유지됩니다. 유지하지 않으려면 블루투스를 사용 중지하세요." "Wi-Fi 및 블루투스 계속 사용" "비행기 모드에서 기기의 Wi-Fi 및 블루투스가 켜진 상태로 유지됩니다. 유지하지 않으려면 Wi-Fi와 블루투스를 사용 중지하세요." + "블루투스가 자동으로 사용 설정되었습니다" + "자동 재시작 기능은 블루투스 설정에서 전환할 수 있습니다." + "사용 중지" + "블루투스 자동 상태 변경" diff --git a/android/app/res/values-ky/strings.xml b/android/app/res/values-ky/strings.xml index f5bcd7526c45f8966a5f9caec7d862b5a047c995..397cae1bb2c70f3f792db33ca464125a6277d158 100644 --- a/android/app/res/values-ky/strings.xml +++ b/android/app/res/values-ky/strings.xml @@ -101,7 +101,6 @@ "Байланышкан жок." "Сурамды туура иштетүү мүмкүн эмес." "Белгисиз ката." - "Bluetooth аркылуу алынгандар" "Bluetooth аркылуу бөлүшүү" "Бардыгы кабыл алынды: %1$s." "Бардыгы жөнөтүлдү: %1$s." @@ -136,4 +135,8 @@ "Түзмөгүңүз учак режиминде Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Bluetooth\'ду өчүрүп койсоңуз болот." "Wi-Fi менен Bluetooth күйүк бойдон калат" "Түзмөгүңүз учак режиминде Wi‑Fi\'га жана Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Wi-Fi менен Bluetooth\'ду өчүрүп койсоңуз болот." + "Bluetooth автоматтык түрдө иштетилди" + "Автоматтык түрдө өчүрүп күйгүзүүнү Bluetooth жөндөөлөрүнөн өчүрүп/күйгүзүгө болот." + "Өчүрүү" + "Bluetooth\'тун абалын автоматтык түрдө өзгөртүү" diff --git a/android/app/res/values-lo/strings.xml b/android/app/res/values-lo/strings.xml index 7068a289af9ecabb0ff144b6a297449e5c037179..a9bdba6b654cb965a5e63c2eed5d2e3425779788 100644 --- a/android/app/res/values-lo/strings.xml +++ b/android/app/res/values-lo/strings.xml @@ -101,7 +101,6 @@ "ການເຊື່ອມຕໍ່ບໍ່ສຳເລັດຜົນ" "ການຮ້ອງຂໍບໍ່ສາມາດຖືກຈັດການໄດ້ຢ່າງຖືກຕ້ອງ." "ຄວາມຜິດພາດທີ່ບໍ່ຮູ້ຈັກ." - "ໄຟລ໌ທີ່ໄດ້ຮັບແລ້ວຈາກ Bluetooth" "ແບ່ງປັນໃນ Bluetooth" "%1$s ໄດ້ຮັບຮຽບຮ້ອຍແລ້ວ." "%1$s ຖືກສົ່ງສຳເລັດແລ້ວ." @@ -136,4 +135,8 @@ "ອຸປະກອນຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." "Wi-Fi ແລະ Bluetooth ຈະເປີດປະໄວ້" "ອຸປະກອນຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Wi-Fi ແລະ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Wi-Fi ແລະ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." + "Bluetooth ຖືກເປີດການນຳໃຊ້ໂດຍອັດຕະໂນມັດ" + "ສາມາດເປີດ/ປິດການຣີສະຕາດອັດຕະໂນມັດໄດ້ໃນການຕັ້ງຄ່າ Bluetooth." + "ປິດ" + "ການປ່ຽນສະຖານະ Bluetooth ອັດຕະໂນມັດ" diff --git a/android/app/res/values-lt/strings.xml b/android/app/res/values-lt/strings.xml index 1851fef1cb12a522b9cd06f630ab30a8f00eeb06..ab601bb139e578af1d7a5b38bea988087686127b 100644 --- a/android/app/res/values-lt/strings.xml +++ b/android/app/res/values-lt/strings.xml @@ -101,7 +101,6 @@ "Nepavyko užmegzti ryšio." "Nepavyksta tinkamai apdoroti užklausos." "Nežinoma klaida." - "„Bluetooth“ gauta" "„Bluetooth“ bendrinimas" "%1$s gauta." "%1$s išsiųsta." @@ -136,4 +135,8 @@ "Įrenginys prisimena, kad lėktuvo režimu reikia palikti įjungtą „Bluetooth“ ryšį. Išjunkite „Bluetooth“, jei nenorite, kad jis liktų įjungtas." "„Wi‑Fi“ ir „Bluetooth“ ryšys lieka įjungtas" "Įrenginys prisimena, kad lėktuvo režimu reikia palikti įjungtą „Wi‑Fi“ ir „Bluetooth“ ryšį. Išjunkite „Wi-Fi“ ir „Bluetooth“, jei nenorite, kad jie liktų įjungti." + "„Bluetooth“ įgalinta automatiškai" + "Automatinį paleidimą iš naujo galima perjungti „Bluetooth“ nustatymuose." + "Išjungti" + "„Bluetooth“ automatinis būsenos pakeitimas" diff --git a/android/app/res/values-lv/strings.xml b/android/app/res/values-lv/strings.xml index 431013fa6689cf47f29b227bf1bad50b20eca004..cdd2af8f54ef6dc81068a82ea77cee3edfc3f145 100644 --- a/android/app/res/values-lv/strings.xml +++ b/android/app/res/values-lv/strings.xml @@ -101,7 +101,6 @@ "Neizdevās izveidot savienojumu." "Pieprasījumu nevar pareizi apstrādāt." "Nezināma kļūda." - "Bluetooth saņemtie faili" "Bluetooth kopīgošana" "Faila %1$s saņemšana pabeigta." "Faila %1$s sūtīšana ir pabeigta." @@ -136,4 +135,8 @@ "Lidojuma režīmā ierīcē joprojām būs ieslēgts Bluetooth savienojums. Izslēdziet Bluetooth savienojumu, ja nevēlaties, lai tas paliktu ieslēgts." "Wi-Fi savienojums un tehnoloģija Bluetooth paliek ieslēgta" "Lidojuma režīmā ierīcē joprojām būs ieslēgti Wi-Fi un Bluetooth savienojumi. Izslēdziet Wi-Fi un Bluetooth savienojumus, ja nevēlaties, lai tie paliktu ieslēgti." + "Bluetooth savienojums ir iespējots automātiski" + "Automātisko restartēšanu var pārslēgt Bluetooth iestatījumos" + "Izslēgt" + "Automātiska Bluetooth stāvokļa maiņa" diff --git a/android/app/res/values-mk/strings.xml b/android/app/res/values-mk/strings.xml index 383808d3a0c87eb8f09c076f704e2c6298e42301..72a03256e08091fbf32465ce4804448d5da6d83f 100644 --- a/android/app/res/values-mk/strings.xml +++ b/android/app/res/values-mk/strings.xml @@ -101,7 +101,6 @@ "Врската е неуспешна." "Барањето не може да се обработи правилно." "Непозната грешка." - "Прием од Bluetooth" "Споделено преку Bluetooth" "%1$s Примањето е завршено." "%1$s Праќањето е завршено." @@ -136,4 +135,8 @@ "Уредот помни да го задржи Bluetooth вклучен во авионски режим. Исклучете го Bluetooth ако не сакате да остане вклучен." "Wi-Fi и Bluetooth остануваат вклучени" "Уредот помни да ги задржи Wi‑Fi и Bluetooth вклучени во авионски режим. Исклучете ги Wi-Fi и Bluetooth ако не сакате да бидат вклучени." + "Bluetooth е овозможен автоматски" + "Автоматското рестартирање може да се вклучи/исклучи во поставките за Bluetooth." + "Исклучи" + "Автоматска промена на состојбата на Bluetooth" diff --git a/android/app/res/values-ml/strings.xml b/android/app/res/values-ml/strings.xml index bd3d6660f0fc96be100bd788a98632c8a73cbb43..a6b819274850723fc43079e688166c81ee27abdd 100644 --- a/android/app/res/values-ml/strings.xml +++ b/android/app/res/values-ml/strings.xml @@ -101,7 +101,6 @@ "കണക്ഷൻ പരാജയപ്പെട്ടു." "അഭ്യർത്ഥന ശരിയായി കൈകാര്യം ചെയ്യാനാകില്ല." "അജ്ഞാത പിശക്." - "Bluetooth-ലൂടെ ലഭിച്ചവ" "Bluetooth പങ്കിടൽ" "%1$s നേടൽ പൂർത്തിയായി." "%1$s അയച്ചത് പൂർത്തിയായി." @@ -136,4 +135,8 @@ "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ Bluetooth ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഉപകരണം ഓർമ്മിക്കുന്നു. Bluetooth ഓണാക്കി വയ്ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അത് ഓഫാക്കുക." "വൈഫൈ, Bluetooth എന്നിവ ഓണായ നിലയിൽ തുടരും" "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഉപകരണം ഓർമ്മിക്കുന്നു. വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്‌ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അവ ഓഫാക്കുക." + "Bluetooth സ്വയമേവ പ്രവർത്തനക്ഷമമാക്കി" + "Bluetooth ക്രമീകരണത്തിൽ സ്വയമേവയുള്ള റീസ്റ്റാർട്ട് ടോഗിൾ ചെയ്യാനാകും." + "ഓഫാക്കുക" + "Bluetooth നിലയുടെ സ്വയമേവയുള്ള മാറ്റം" diff --git a/android/app/res/values-mn/strings.xml b/android/app/res/values-mn/strings.xml index 5f76295016ac62a0bc1426124314057c3cc462b8..86e5c8110e9016820d9c90a17ca0e3ece92d2c6a 100644 --- a/android/app/res/values-mn/strings.xml +++ b/android/app/res/values-mn/strings.xml @@ -101,7 +101,6 @@ "Холболт амжилтгүй." "Хүсэлтийг зөв гүйцэтгэх боломжгүй." "Тодорхойгүй алдаа." - "Bluetooth хүлээж авсан" "Bluetooth хуваалцах" "%1$s Бүрэн хүлээж авсан." "%1$s Илгээж дууссан." @@ -136,4 +135,8 @@ "Таны төхөөрөмж Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та асаалттай байлгахыг хүсэхгүй байвал Bluetooth-г унтраана уу." "Wi-Fi болон Bluetooth асаалттай хэвээр байна" "Таны төхөөрөмж Wi-Fi болон Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та Wi-Fi болон Bluetooth-г асаалттай байлгахыг хүсэхгүй байвал тэдгээрийг унтраана уу." + "Bluetooth-г автоматаар идэвхжүүлсэн" + "Автоматаар дахин эхлүүлэхийг Bluetooth-н Тохиргоонд асаах/унтраах боломжтой." + "Унтраах" + "Bluetooth-н автомат төлөвийн өөрчлөлт" diff --git a/android/app/res/values-mr/strings.xml b/android/app/res/values-mr/strings.xml index 0162bfae10aa5c4ef68a592d68efb8177779cabb..1b0a81e78f25f7e1dc2cf193a5185f5e8e430468 100644 --- a/android/app/res/values-mr/strings.xml +++ b/android/app/res/values-mr/strings.xml @@ -101,7 +101,6 @@ "कनेक्‍शन अयशस्‍वी." "विनंती योग्य रीतीने हाताळली जाऊ शकत नाही." "अज्ञात एरर" - "ब्लूटूथ मिळवले" "ब्लूटूथ शेअर" "%1$s प्राप्त करणे पूर्ण." "%1$s पाठविणे पूर्ण." @@ -136,4 +135,8 @@ "तुमचे डिव्हाइस विमान मोडमध्ये ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवते. तुम्हाला ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." "वाय-फाय आणि ब्लूटूथ सुरू राहते" "तुमचे डिव्हाइस विमान मोडमध्ये वाय-फाय आणि ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवते. तुम्हाला वाय-फाय आणि ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." + "ब्लूटूथ आपोआप सुरू करण्यात आले आहे" + "ब्लूटूथ सेटिंग्ज मध्ये ऑटोमॅटिक रीस्टार्ट टॉगल केले जाऊ शकते." + "बंद करा" + "ब्लूटूथची स्थिती आपोआप बदलणे" diff --git a/android/app/res/values-ms/strings.xml b/android/app/res/values-ms/strings.xml index 195866c6aa1d48ae7d4c88b2b893413f68aad164..613532cab0a6d7c2bda8ec1214e30ff02fa3abe5 100644 --- a/android/app/res/values-ms/strings.xml +++ b/android/app/res/values-ms/strings.xml @@ -101,7 +101,6 @@ "Sambungan tidak berjaya." "Permintaan tidak dapat dikendalikan dengan betul." "Ralat tidak diketahui." - "Bluetooth diterima" "Perkongsian Bluetooth" "%1$s Penerimaan selesai." "%1$s Penghantaran selesai." @@ -136,4 +135,8 @@ "Peranti anda diingatkan untuk terus menghidupkan Bluetooth dalam mod pesawat. Matikan Bluetooth jika anda tidak mahu Bluetooth sentiasa hidup." "Wi-Fi dan Bluetooth kekal dihidupkan" "Peranti anda diingatkan untuk terus menghidupkan Wi-Fi dan Bluetooth dalam mod pesawat. Matikan Wi-Fi dan Bluetooth jika anda tidak mahu Wi-Fi dan Bluetooth sentiasa hidup." + "Bluetooth telah didayakan secara automatik" + "Mulakan semula automatik boleh ditogol dalam Tetapan Bluetooth." + "Matikan" + "Perubahan keadaan automatik Bluetooth" diff --git a/android/app/res/values-my/strings.xml b/android/app/res/values-my/strings.xml index 295afd15aeb2d797c3be2c06217c9a6f9087abb6..b60ecaf69b2e1be8514d7ae7e892f342b544d4eb 100644 --- a/android/app/res/values-my/strings.xml +++ b/android/app/res/values-my/strings.xml @@ -101,7 +101,6 @@ "ချိတ်ဆက်ခြင်း မအောင်မြင်ပါ" "တောင်းခံခြင်းကို မှန်ကန်စွာကိုင်တွယ်မရပါ" "အမည်မသိသော မှားယွင်းမှု" - "ဘလူးတုသ် လက်ခံရပြီး" "ဘလူးတုသ် မျှဝေမှု" "%1$s လက်ခံရရှိပြီး" "%1$s ပို့ခြင်း ပြီးဆုံးပြီး" @@ -136,4 +135,8 @@ "လေယာဉ်ပျံမုဒ်သုံးစဉ် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်စက်က မှတ်မိသည်။ ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" "Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားသည်" "လေယာဉ်ပျံမုဒ်သုံးစဉ် Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်စက်က မှတ်မိသည်။ Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" + "ဘလူးတုသ်ကို အလိုအလျောက်ဖွင့်ထားသည်" + "အလိုအလျောက်ပြန်စခြင်းကို ဘလူးတုသ်ဆက်တင်များတွင် ပြောင်းနိုင်သည်။" + "ပိတ်ရန်" + "အလိုအလျောက် ဘလူးတုသ်အခြေအနေ ပြောင်းလဲမှု" diff --git a/android/app/res/values-nb/strings.xml b/android/app/res/values-nb/strings.xml index f1586840857e8e5fca1e3c49a41a77feccd4bd00..f12753c03d7bf6b3c64423fcc074016d4f9eec23 100644 --- a/android/app/res/values-nb/strings.xml +++ b/android/app/res/values-nb/strings.xml @@ -101,7 +101,6 @@ "Tilkobling mislyktes." "Kan ikke behandle forespørsel på riktig måte." "Ukjent feil." - "Bluetooth mottatt" "Bluetooth-deling" "%1$s mottatt – ferdig." "%1$s sendt." @@ -136,4 +135,8 @@ "Enheten husker at Bluetooth skal være på i flymodus. Slå av Bluetooth hvis du ikke vil at det skal være på." "Wifi og Bluetooth holdes påslått" "Enheten husker at wifi og Bluetooth skal være på i flymodus. Slå av wifi og Bluetooth hvis du ikke vil at de skal være på." + "Bluetooth er slått på automatisk" + "Du kan slå automatisk omstart av/på i Bluetooth-innstillingene." + "Slå av" + "Bluetooth endret tilstand automatisk" diff --git a/android/app/res/values-ne/strings.xml b/android/app/res/values-ne/strings.xml index 87729300f0e94e33fe53be3a1f99268c29af6a43..ab17805530787f85ef6bd42440df6cbeb2f8a6f8 100644 --- a/android/app/res/values-ne/strings.xml +++ b/android/app/res/values-ne/strings.xml @@ -101,7 +101,6 @@ "जडान असफल।" "अनुरोधलाई सही रूपमा सम्हाल्न सकिँदैन।" "अज्ञात त्रुटि।" - "ब्लुटुथबाट प्राप्त भएको" "ब्लुटुथमार्फत गरिने आदान प्रदान" "%1$s प्राप्त गर्ने कार्य सम्पन्न भयो।" "%1$s पठाउने कार्य पुरा भयो।" @@ -136,4 +135,8 @@ "तपाईंको डिभाइस अर्को पटक हवाइजहाज मोडमा लैजाँदा तपाईंको फोनले ब्लुटुथ अन राख्नु पर्ने कुरा याद गर्छ। तपाईं ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने ब्लुटुथ अफ गर्नुहोस्।" "Wi-Fi र ब्लुटुथ अन रहिरहने छन्" "हवाइजहाज मोडमा पनि तपाईंको डिभाइसको Wi-Fi र ब्लुटुथ अन नै रहिरहने छन्। तपाईं Wi-Fi र ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने तिनलाई अफ गर्नुहोस्।" + "ब्लुटुथ स्वतः अन गरिएको छ" + "स्वतः रिस्टार्ट गर्ने सुविधा ब्लुटुथसम्बन्धी सेटिङमा गई अन/अफ गर्न सकिन्छ।" + "अफ गर्नुहोस्" + "ब्लुटुथको स्थिति स्वतः परिवर्तन गरियो" diff --git a/android/app/res/values-nl/strings.xml b/android/app/res/values-nl/strings.xml index cbda859d0667e229ab0a7c9b2934e68985520feb..e5f90da12ecec4aaabb35e34782f1d7a5884b0f6 100644 --- a/android/app/res/values-nl/strings.xml +++ b/android/app/res/values-nl/strings.xml @@ -101,7 +101,6 @@ "Verbinding mislukt." "Het verzoek kan niet correct worden verwerkt." "Onbekende fout." - "Ontvangen via bluetooth" "Delen via bluetooth" "%1$s ontvangen voltooid." "%1$s verzonden voltooid." @@ -136,4 +135,8 @@ "Bluetooth op je apparaat blijft aan in de vliegtuigmodus. Zet bluetooth uit als je niet wilt dat dit aan blijft." "Wifi en bluetooth blijven aan" "Wifi en bluetooth op je apparaat blijven aan in de vliegtuigmodus. Zet wifi en bluetooth uit als je niet wilt dat ze aan blijven." + "Bluetooth is automatisch aangezet" + "Je kunt Automatisch opnieuw opstarten aan- of uitzetten in de bluetooth-instellingen." + "Uitzetten" + "Automatische wijziging in status van bluetooth" diff --git a/android/app/res/values-or/strings.xml b/android/app/res/values-or/strings.xml index 920ca675d6ed543ba8bd2a47b8e7cbf782167a94..cee3fad4ed7c12cbbbd46a28a8cdf65c14e68315 100644 --- a/android/app/res/values-or/strings.xml +++ b/android/app/res/values-or/strings.xml @@ -101,7 +101,6 @@ "ସଂଯୋଗ ବିଫଳ ହେଲା।" "ଅନୁରୋଧକୁ ଠିକ୍‌ ଭାବେ ସମ୍ଭାଳି ହେବନାହିଁ।" "ଅଜଣା ତୃଟି।" - "ବ୍ଲୁଟୁଥ ପ୍ରାପ୍ତ ହୋଇଛି" "ବ୍ଲୁଟୂଥ୍‍‌ ସେୟାର୍‌" "%1$s ପ୍ରାପ୍ତ କରିବା ସମ୍ପୂର୍ଣ୍ଣ ହେଲା।" "%1$s ପଠାଇବା ସମ୍ପୂର୍ଣ୍ଣ ହେଲା।" @@ -136,4 +135,8 @@ "ଆପଣଙ୍କ ଡିଭାଇସ ଏୟାରପ୍ଲେନ ମୋଡରେ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ବ୍ଲୁଟୁଥ ଚାଲୁ ରହୁ ବୋଲି ଚାହୁଁନାହାଁନ୍ତି ତେବେ ଏହାକୁ ବନ୍ଦ କରନ୍ତୁ।" "ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରହେ" "ଆପଣଙ୍କ ଡିଭାଇସ ଏୟାରପ୍ଲେନ ମୋଡରେ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରହୁ ବୋଲି ଚାହୁଁନାହାଁନ୍ତି ତେବେ ସେଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ।" + "ବ୍ଲୁଟୁଥକୁ ସ୍ୱତଃ ସକ୍ଷମ କରାଯାଇଛି" + "ବ୍ଲୁଟୁଥ ସେଟିଂସରେ ସ୍ଵତଃ ରିଷ୍ଟାର୍ଟ ଟୋଗଲ କରାଯାଇପାରିବ।" + "ବନ୍ଦ କରନ୍ତୁ" + "ବ୍ଲୁଟୁଥର ସ୍ୱତଃ ସ୍ଥିତି ପରିବର୍ତ୍ତନ" diff --git a/android/app/res/values-pa/strings.xml b/android/app/res/values-pa/strings.xml index c4258cc308ed9008a252909b7a48ebfddf442f53..5d98280dc54a3364a7fda9fb45589225ab30bad9 100644 --- a/android/app/res/values-pa/strings.xml +++ b/android/app/res/values-pa/strings.xml @@ -101,7 +101,6 @@ "ਕਨੈਕਸ਼ਨ ਅਸਫਲ।" "ਬੇਨਤੀ ਨੂੰ ਸਹੀ ਢੰਗ ਨਾਲ ਸੰਭਾਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।" "ਅਗਿਆਤ ਅਸ਼ੁੱਧੀ।" - "ਬਲੂਟੁੱਥ ਰਾਹੀਂ ਪ੍ਰਾਪਤ" "ਬਲੂਟੁੱਥ ਸਾਂਝਾਕਰਨ" "%1$s ਪੂਰਾ ਪ੍ਰਾਪਤ ਕੀਤਾ।" "%1$s ਪੂਰਾ ਭੇਜਿਆ ਗਿਆ।" @@ -136,4 +135,8 @@ "ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਸਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" "ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਚਾਲੂ ਰਹਿੰਦੇ ਹਨ" "ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਨ੍ਹਾਂ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" + "ਬਲੂਟੁੱਥ ਨੂੰ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚਾਲੂ ਕੀਤਾ ਗਿਆ ਹੈ" + "ਸਵੈਚਲਿਤ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਦੀ ਸੁਵਿਧਾ ਨੂੰ ਬਲੂਟੁੱਥ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਟੌਗਲ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।" + "ਬੰਦ ਕਰੋ" + "ਬਲੂਟੁੱਥ ਨੂੰ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚਾਲੂ ਕਰਨ ਦੀ ਸੁਵਿਧਾ ਨੂੰ ਬਦਲ ਦਿੱਤਾ ਗਿਆ ਹੈ" diff --git a/android/app/res/values-pl/strings.xml b/android/app/res/values-pl/strings.xml index d8ef0a41f8ffe1681910bd6a9faf387891434b2b..521210df9d653d5ba701c963a501189355a6b82e 100644 --- a/android/app/res/values-pl/strings.xml +++ b/android/app/res/values-pl/strings.xml @@ -101,7 +101,6 @@ "Nie można połączyć." "Nie można poprawnie obsłużyć żądania." "Nieznany błąd." - "Odebrane przez Bluetooth" "Udostępnianie Bluetooth" "Odbieranie %1$s zakończono." "Wysyłanie %1$s zakończono." @@ -136,4 +135,8 @@ "Bluetooth na urządzeniu pozostaje włączony w trybie samolotowym. Wyłącz Bluetooth, jeśli nie chcesz, żeby pozostawał włączony." "Wi-Fi i Bluetooth pozostają włączone" "Wi-Fi i Bluetooth na urządzeniu pozostają włączone w trybie samolotowym. Wyłącz Wi-Fi i Bluetooth, jeśli nie chcesz, żeby funkcje te pozostawały włączone." + "Bluetooth został automatycznie włączony" + "Automatyczne ponowne uruchamianie można włączyć w Ustawieniach Bluetootha." + "Wyłącz" + "Automatyczna zmiana stanu Bluetooth" diff --git a/android/app/res/values-pt-rPT/strings.xml b/android/app/res/values-pt-rPT/strings.xml index db13dd6009b48c7ef9743dc28078f9dd42686dad..a7d9d696d18a1b3ee46daac0cb7d4154f084beb7 100644 --- a/android/app/res/values-pt-rPT/strings.xml +++ b/android/app/res/values-pt-rPT/strings.xml @@ -101,7 +101,6 @@ "A ligação falhou." "Não é possível processar o pedido corretamente." "Erro desconhecido." - "Bluetooth recebido" "Partilha por Bluetooth" "Recepção completa de %1$s." "Envio de %1$s concluído" @@ -136,4 +135,8 @@ "O seu dispositivo lembra-se de manter o Bluetooth ativado no modo de avião. Desative o Bluetooth se não quiser que fique ativado." "O Wi-Fi e o Bluetooth mantêm-se ativados" "O seu dispositivo lembra-se de manter o Wi-Fi e o Bluetooth ativados no modo de avião. Desative o Wi-Fi e o Bluetooth se não quiser que fiquem ativados." + "O Bluetooth foi ativado automaticamente" + "O reinício automático pode ser ativado/desativado nas definições de Bluetooth." + "Desativar" + "Alteração de estado automática do Bluetooth" diff --git a/android/app/res/values-pt/strings.xml b/android/app/res/values-pt/strings.xml index 68260daa6ac7393b7f6ae1e495b9b29ba5b1a128..040d10321be16287975cfd849ddbc7b65de37db0 100644 --- a/android/app/res/values-pt/strings.xml +++ b/android/app/res/values-pt/strings.xml @@ -101,7 +101,6 @@ "Falha na conexão." "Não é possível tratar a solicitação corretamente." "Erro desconhecido." - "Recebido por Bluetooth" "Envio por Bluetooth" "%1$s Recebimento concluído." "%1$s Envio concluído." @@ -136,4 +135,8 @@ "O dispositivo vai manter o Bluetooth ativado no modo avião. Ele poderá ser desativado manualmente se você preferir." "O Wi-Fi e o Bluetooth ficam ativados" "O dispositivo vai manter o Wi-Fi e o Bluetooth ativados no modo avião. Eles podem ser desativados manualmente se você preferir." + "O Bluetooth foi ativado automaticamente" + "A reinicialização automática pode ser ativada nas configurações do Bluetooth." + "Desativar" + "Mudança automática de estado do Bluetooth" diff --git a/android/app/res/values-ro/strings.xml b/android/app/res/values-ro/strings.xml index e54f39f37d3b81f8bbc005b01443500ac34435da..e1408360ab670810d890527ae354da8afed7d9bf 100644 --- a/android/app/res/values-ro/strings.xml +++ b/android/app/res/values-ro/strings.xml @@ -101,7 +101,6 @@ "Conectare eșuată." "Solicitarea nu poate fi gestionată corect." "Eroare necunoscută." - "Bluetooth recepționat" "Distribuire prin Bluetooth" "Primire finalizată: %1$s." "Trimitere finalizată: %1$s." @@ -136,4 +135,8 @@ "Dispozitivul reține să păstreze Bluetooth activat în modul Avion. Dezactivează Bluetooth dacă nu vrei să rămână activat." "Wi-Fi și Bluetooth rămân activate" "Dispozitivul reține să păstreze funcțiile Wi-Fi și Bluetooth activate în modul Avion. Dezactivează Wi-Fi și Bluetooth dacă nu vrei să rămână activate." + "Bluetooth s-a activat automat" + "Repornirea automată poate fi comutată în Setările Bluetooth." + "Dezactivează" + "Schimbare automată de stare Bluetooth" diff --git a/android/app/res/values-ru/strings.xml b/android/app/res/values-ru/strings.xml index 37047a0da35397d79b45ee29bd504c85534c3810..0107dba39da6c28df41e69c5ddfaea3275e6225c 100644 --- a/android/app/res/values-ru/strings.xml +++ b/android/app/res/values-ru/strings.xml @@ -101,7 +101,6 @@ "Не удалось установить соединение." "Невозможно правильно обработать запрос." "Неизвестная ошибка" - "Получено по Bluetooth" "Передача по Bluetooth" "Получено: %1$s." "Отправлено: %1$s." @@ -136,4 +135,8 @@ "Функция Bluetooth останется включенной в режиме полета. Вы можете отключить ее, если хотите." "Функции Wi‑Fi и Bluetooth остаются включенными" "Wi‑Fi и Bluetooth останутся включенными в режиме полета. Вы можете отключить их, если хотите." + "Bluetooth включен автоматически" + "В настройках Bluetooth можно включить автоматический перезапуск." + "Отключить" + "Автоматическое изменение состояния Bluetooth" diff --git a/android/app/res/values-si/strings.xml b/android/app/res/values-si/strings.xml index 26a964f9e7cd84106c378bd3c86cbb4154e56694..9f260426441ffdd6a6e2e794b1d37febab590f3e 100644 --- a/android/app/res/values-si/strings.xml +++ b/android/app/res/values-si/strings.xml @@ -101,7 +101,6 @@ "සම්බන්ධය අසාර්ථකයි." "ඉල්ලීම නිවැරදිව හැසිරවීමට නොහැකිය." "නොදන්නා දෝෂයකි." - "බ්ලූටූත් ලැබිණි" "බ්ලූටූත් බෙදා ගැනීම" "%1$s ලැබීම සම්පූර්ණයි." "%1$s යැවීම සම්පූර්ණයි." @@ -136,4 +135,8 @@ "ඔබේ උපාංගයට අහස්යානා ආකාරයේ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. ඔබට බ්ලූටූත් ක්‍රියාත්මක වීමට අවශ්‍ය නොවේ නම් එය ක්‍රියාවිරහිත කරන්න." "Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව පවතී" "ඔබේ උපාංගයට අහස්යානා ආකාරයේ Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. Wi-Fi සහ බ්ලූටූත් ඒවා ක්‍රියාත්මක වීමට ඔබට අවශ්‍ය නැතිනම් ක්‍රියා විරහිත කරන්න." + "බ්ලූටූත් ස්වයංක්‍රීයව සබල කර ඇත" + "බ්ලූටූත් සැකසීම් තුළ ස්වයංක්‍රීය නැවත ආරම්භ කිරීම ටොගල් කළ හැක." + "අක්‍රිය කරන්න" + "බ්ලූටූත් ස්වයංක්‍රීය තත්ත්‍වය වෙනස් කිරීම" diff --git a/android/app/res/values-sk/strings.xml b/android/app/res/values-sk/strings.xml index d67347b4de3e792c277b51e05eb736e1ad2edc84..05797b14d806496c6ee3bedcbe4fa5eeb1f95f8f 100644 --- a/android/app/res/values-sk/strings.xml +++ b/android/app/res/values-sk/strings.xml @@ -101,7 +101,6 @@ "Neúspešný pokus o pripojenie." "Žiadosť nie je možné správne spracovať." "Neznáma chyba." - "Prijaté cez Bluetooth" "Zdieľanie Bluetooth" "%1$s, príjem dokončený" "%1$s Odosielanie dokončené." @@ -136,4 +135,8 @@ "Zariadenie si pamätá, aby v režime v lietadle nevypínalo rozhranie Bluetooth. Ak ho nechcete ponechať zapnuté, vypnite ho." "Wi‑Fi a Bluetooth zostanú zapnuté" "Zariadenie si pamätá, aby v režime v lietadle nevypínalo Wi‑Fi ani Bluetooth. Ak ich nechcete ponechať zapnuté, vypnite ich." + "Rozhranie Bluetooth bolo automaticky zapnuté" + "Automatický reštart sa dá prepnúť v nastaveniach rozhrania Bluetooth." + "Vypnúť" + "Automatická zmena stavu rozhrania Bluetooth" diff --git a/android/app/res/values-sl/strings.xml b/android/app/res/values-sl/strings.xml index 3946c0cabee19cf0d28d6d2d8228f6ccb77b6d48..c67abc5acbbad7b7b89d3e11fc1fbcc9327d83d1 100644 --- a/android/app/res/values-sl/strings.xml +++ b/android/app/res/values-sl/strings.xml @@ -101,7 +101,6 @@ "Povezava neuspešna." "Zahteve ni mogoče pravilno obravnavati." "Neznana napaka." - "Bluetooth – prejeto" "Deljenje prek Bluetootha" "%1$s Prejemanje je končano." "%1$s Pošiljanje je dokončano." @@ -136,4 +135,8 @@ "Naprava v načinu za letalo pusti Bluetooth vklopljen. Če ne želite, da Bluetooth ostane vklopljen, ga izklopite." "Wi-Fi in Bluetooth ostaneta vklopljena" "Naprava v načinu za letalo pusti Wi-Fi in Bluetooth vklopljena. Če ne želite, da Wi-Fi in Bluetooth ostaneta vklopljena, ju izklopite." + "Bluetooth je bil samodejno omogočen" + "Samodejni zagon lahko preklopite v nastavitvah za Bluetooth." + "Izklopi" + "Samodejna sprememba stanja Bluetootha" diff --git a/android/app/res/values-sq/strings.xml b/android/app/res/values-sq/strings.xml index f3ed014bfed4206c42261da4eedb2f75ebed2c17..f1f46ec6611833e0d7195cafbd0dcb820064929e 100644 --- a/android/app/res/values-sq/strings.xml +++ b/android/app/res/values-sq/strings.xml @@ -101,7 +101,6 @@ "Lidhja ishte e pasuksesshme." "Kërkesa nuk mund të trajtohet si duhet." "Gabim i panjohur." - "Marrjet përmes Bluetooth-it" "Ndarja përmes \"Bluetooth-it\"" "%1$s - Marrja përfundoi." "%1$s Dërgimi përfundoi." @@ -136,4 +135,8 @@ "Pajisja jote kujtohet që ta mbajë Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Bluetooth-in nëse nuk dëshiron që të qëndrojë i aktivizuar." "Wi-Fi dhe Bluetooth-i qëndrojnë aktivë" "Pajisja jote kujtohet që ta mbajë Wi-Fi dhe Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Wi-Fi dhe Bluetooth-in nëse nuk dëshiron që të qëndrojnë aktivë." + "Bluetooth-i është aktivizuar automatikisht" + "Rinisja automatike mund të aktivizohet/çaktivizohet te \"Cilësimet\" e Bluetooth-it." + "Çaktivizo" + "Ndryshimi automatik i gjendjes së Bluetooth-it" diff --git a/android/app/res/values-sr/strings.xml b/android/app/res/values-sr/strings.xml index b851eb159504e5384c9d43a1081391cce04531ce..8ac47dd9ad2e5e1dd5894c1c3828b23faab9675b 100644 --- a/android/app/res/values-sr/strings.xml +++ b/android/app/res/values-sr/strings.xml @@ -101,7 +101,6 @@ "Повезивање није успело." "Није могуће исправно обрадити захтев." "Непозната грешка." - "Примљено преко Bluetooth-а" "Дељење преко Bluetooth-а" "%1$s Примљено у целости." "%1$s Слање је довршено." @@ -136,4 +135,8 @@ "Уређај памти да не треба да искључује Bluetooth у режиму рада у авиону. Искључите Bluetooth ако не желите да остане укључен." "WiFi и Bluetooth остају укључени" "Уређај памти да не треба да искључује WiFi и Bluetooth у режиму рада у авиону. Искључите WiFi и Bluetooth ако не желите да остану укључени." + "Bluetooth је аутоматски омогућен" + "Аутоматски рестарт може да се укључи или искључи у подешавањима Bluetooth-а." + "Искључи" + "Аутоматски статус Bluetooth-а је промењен" diff --git a/android/app/res/values-sv/strings.xml b/android/app/res/values-sv/strings.xml index a197bdaba32a25797c6111677aa6171f6bc1959f..829ee819a35393b69219fbe45d78f53f227662c6 100644 --- a/android/app/res/values-sv/strings.xml +++ b/android/app/res/values-sv/strings.xml @@ -101,7 +101,6 @@ "Anslutningen misslyckades." "Begäran kan inte hanteras korrekt." "Okänt fel." - "Mottaget via Bluetooth" "Bluetooth-delning" "%1$s har tagits emot fullständigt." "%1$s har skickats fullständigt." @@ -136,4 +135,8 @@ "Enheten kommer ihåg att hålla Bluetooth aktiverat i flygplansläge. Inaktivera Bluetooth om du inte vill att det ska hållas aktiverat." "Wifi och Bluetooth ska vara aktiverade" "Enheten kommer ihåg att hålla wifi och Bluetooth aktiverade i flygplansläge. Du kan inaktivera wifi och Bluetooth om du inte vill hålla dem aktiverade." + "Bluetooth har aktiverats automatiskt" + "Automatisk omstart kan aktiveras och inaktiveras i Bluetooth-inställningarna." + "Inaktivera" + "Ändring av automatiskt Bluetooth-läge" diff --git a/android/app/res/values-sw/strings.xml b/android/app/res/values-sw/strings.xml index 29768f66afd0b61b94bd4d1c97e39d6534307cc0..6311017679ee7759fc731ad524beca6b6ba24443 100644 --- a/android/app/res/values-sw/strings.xml +++ b/android/app/res/values-sw/strings.xml @@ -101,7 +101,6 @@ "Muunganisho haujafanikiwa." "Ombi haliwezi kushughulikiwa kwa usahihi." "Hitilafu isiyojulikana." - "Zilizopokewa kupitia Bluetooth" "Shiriki Bluetooth" "%1$s Imepokelewa kikamilifu" "Kutuma kwa %1$s kumekamilika." @@ -136,4 +135,8 @@ "Kifaa chako kitaendelea kuwasha Bluetooth katika hali ya ndegeni. Zima Bluetooth iwapo hutaki iendelee kuwaka." "Wi-Fi na Bluetooth zitaendelea kuwaka" "Kifaa chako kitaendelea kuwasha Wi-Fi na Bluetooth ukiwa katika hali ya ndegeni. Zima Wi-Fi na Bluetooth ikiwa hutaki ziendelee kuwaka." + "Bluetooth imewashwa kiotomatiki" + "Unaweza kuwasha au kuzima kipengele cha zima kisha uwashe kiotomatiki katika Mipangilio ya Bluetooth." + "Zima" + "Mabadiliko ya kiotomatiki kwenye hali ya Bluetooth" diff --git a/android/app/res/values-ta/strings.xml b/android/app/res/values-ta/strings.xml index 6e040191dd4b22761895399d6d2099cefe6e5e42..149e81e69b0a6d064fea32930ea2fadda183db6d 100644 --- a/android/app/res/values-ta/strings.xml +++ b/android/app/res/values-ta/strings.xml @@ -101,7 +101,6 @@ "இணைப்பு தோல்வி." "கோரிக்கை சரியாக கையாளப்படவில்லை." "தெரியாத பிழை." - "புளூடூத் - பெற்றவை" "புளூடூத் பகிர்வு" "%1$s பெறப்பட்டது." "%1$s அனுப்புவது முடிந்தது." @@ -136,4 +135,8 @@ "உங்கள் சாதனம் விமானப் பயன்முறையில் புளூடூத்தை இயக்கத்திலேயே வைத்திருக்கும். புளூடூத்தை இயக்கத்தில் வைத்திருக்க விரும்பவில்லை எனில் நீங்கள் அதை முடக்கலாம்." "வைஃபையும் புளூடூத்தும் இயக்கத்திலேயே இருத்தல்" "உங்கள் சாதனம் விமானப் பயன்முறையில் வைஃபையையும் புளூடூத்தையும் இயக்கத்திலேயே வைத்திருக்கும். வைஃபையையும் புளூடூத்தையும் இயக்கத்தில் வைத்திருக்க விரும்பவில்லை எனில் நீங்கள் அவற்றை முடக்கலாம்." + "புளூடூத் தானாகவே இயக்கப்பட்டுள்ளது" + "புளூடூத் அமைப்புகளில் தானாகவே மீண்டும் தொடங்கப்படுவதை நிலைமாற்றலாம்." + "முடக்கு" + "புளூடூத் தானியங்கு நிலை மாற்றம்" diff --git a/android/app/res/values-te/strings.xml b/android/app/res/values-te/strings.xml index 788a1869271a6b7c05ba7526d3e505428bffe7ca..1be831cc420803ed29ec041943c7a9a67e472cd2 100644 --- a/android/app/res/values-te/strings.xml +++ b/android/app/res/values-te/strings.xml @@ -101,7 +101,6 @@ "కనెక్షన్ విఫలమైంది." "రిక్వెస్ట్‌ సరిగ్గా నిర్వహించబడదు." "తెలియని ఎర్రర్." - "బ్లూటూత్‌తో స్వీకరించినవి" "బ్లూటూత్ షేర్" "%1$s స్వీకరించడం పూర్తయింది." "%1$s పంపడం పూర్తయింది." @@ -136,4 +135,8 @@ "విమానం మోడ్‌లో బ్లూటూత్ ఆన్‌లో ఉంచాలని మీ పరికరం గుర్తుంచుకుంటుంది. బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే దాన్ని ఆఫ్ చేయండి." "Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉంటాయి" "మీ పరికరం విమానం మోడ్‌లో Wi‑Fiని, బ్లూటూత్‌ను ఆన్‌లో ఉంచాలని గుర్తుంచుకుంటుంది. Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే వాటిని ఆఫ్ చేయండి." + "బ్లూటూత్ ఆటోమేటిక్‌గా ఎనేబుల్ చేయబడింది" + "బ్లూటూత్ సెట్టింగ్‌లలో ఆటోమేటిక్ రీస్టార్ట్ బటన్‌ను టోగుల్ చేయవచ్చు." + "ఆఫ్ చేయండి" + "బ్లూటూత్ ఆటోమేటిక్ స్థితి మార్పు" diff --git a/android/app/res/values-th/strings.xml b/android/app/res/values-th/strings.xml index c23e367888d219ad59d94e89860611a33b3b84d1..cbc8dd0aa781946459e26d0a144535bc2344bb2b 100644 --- a/android/app/res/values-th/strings.xml +++ b/android/app/res/values-th/strings.xml @@ -101,7 +101,6 @@ "การเชื่อมต่อไม่สำเร็จ" "ไม่สามารถจัดการคำขอได้อย่างถูกต้อง" "ข้อผิดพลาดที่ไม่ทราบสาเหตุ" - "ไฟล์ที่ได้รับแล้วผ่านบลูทูธ" "การแชร์ทางบลูทูธ" "ได้รับแล้ว %1$s" "ส่ง %1$s เรียบร้อยแล้ว" @@ -136,4 +135,8 @@ "อุปกรณ์จำว่าจะต้องเปิดบลูทูธไว้ในโหมดบนเครื่องบิน ปิดบลูทูธหากคุณไม่ต้องการให้เปิดไว้" "Wi-Fi และบลูทูธยังเปิดอยู่" "อุปกรณ์จำว่าจะต้องเปิด Wi-Fi และบลูทูธไว้ในโหมดบนเครื่องบิน ปิด Wi-Fi และบลูทูธหากคุณไม่ต้องการให้เปิดไว้" + "เปิดใช้บลูทูธโดยอัตโนมัติแล้ว" + "เปิด/ปิดการรีสตาร์ทอัตโนมัติได้ในการตั้งค่าบลูทูธ" + "ปิด" + "การเปลี่ยนสถานะ \"อัตโนมัติ\" ของบลูทูธ" diff --git a/android/app/res/values-tl/strings.xml b/android/app/res/values-tl/strings.xml index aeffc11a9da57436a242b120b602307b5b2eda43..18d81ffda448c86b2a35354d34a7f427eca4ab49 100644 --- a/android/app/res/values-tl/strings.xml +++ b/android/app/res/values-tl/strings.xml @@ -101,7 +101,6 @@ "Hindi matagumpay ang koneksyon." "Hindi mapangasiwaan nang tama ang kahilingan." "Hindi kilalang error." - "Natanggap sa bluetooth" "Pagbabahagi sa Bluetooth" "%1$s Kumpleto na ang pagtanggap." "%1$s Kumpleto na ang pagpapadala." @@ -136,4 +135,8 @@ "Tinatandaan ng iyong device na panatilihing naka-on ang Bluetooth habang nasa airplane mode. I-off ang Bluetooth kung ayaw mo itong manatiling naka-on." "Mananatiling naka-on ang Wi-Fi at Bluetooth" "Tinatandaan ng iyong device na panatilihing naka-on ang Wi-Fi at Bluetooth habang nasa airplane mode. I-off ang Wi-Fi at Bluetooth kung ayaw mong manatiling naka-on ang mga ito." + "Awtomatikong na-enable ang Bluetooth" + "Puwedeng i-toggle ang awtomatikong pag-restart sa Mga Setting ng Bluetooth." + "I-off" + "Awtomatikong pagbago sa status ng Bluetooth" diff --git a/android/app/res/values-tr/strings.xml b/android/app/res/values-tr/strings.xml index 020bb4f494f0a15403dd5604376aa1c850400c47..f8e54e8b598819e0663f0b5ceb12cf43818f747d 100644 --- a/android/app/res/values-tr/strings.xml +++ b/android/app/res/values-tr/strings.xml @@ -101,7 +101,6 @@ "Bağlantı başarısız." "İstek düzgün bir şekilde işlenemiyor." "Bilinmeyen hata." - "Bluetooth ile alınanlar" "Bluetooth Paylaşımı" "%1$s Alma tamamlandı." "%1$s Gönderme tamamlandı." @@ -136,4 +135,8 @@ "Cihazınız, uçak modundayken Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız Bluetooth\'u kapatın." "Kablosuz bağlantı ve Bluetooth açık kalır" "Cihazınız, uçak modundayken kablosuz bağlantıyı ve Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız kablosuz bağlantıyı ve Bluetooth\'u kapatın." + "Bluetooth otomatik olarak etkinleştirildi" + "Otomatik yeniden başlatma düğmesi, Bluetooth ayarlarından açılıp kapatılabilir." + "Kapat" + "Bluetooth otomatik durum değişikliği" diff --git a/android/app/res/values-uk/strings.xml b/android/app/res/values-uk/strings.xml index 244246df51df66ac605211931f894e45304e2c54..f3478016e813841c7ab7ec25cb7fbe546e5b536f 100644 --- a/android/app/res/values-uk/strings.xml +++ b/android/app/res/values-uk/strings.xml @@ -101,7 +101,6 @@ "Помилка з’єднання." "Запит неможливо обробити належним чином." "Невідома помилка." - "Отримані через Bluetooth" "Обмін даними через Bluetooth" "Завершено отримання %1$s." "Заверш. надсил. %1$s." @@ -136,4 +135,8 @@ "У режимі польоту функція Bluetooth на пристрої залишатиметься ввімкненою. За бажання її можна вимкнути." "Wi-Fi і Bluetooth залишаються ввімкненими" "У режимі польоту функції Wi-Fi і Bluetooth на пристрої залишатимуться ввімкненими. За бажання їх можна вимкнути." + "Bluetooth увімкнено автоматично" + "Автоматичний перезапуск можна вмикати й вимикати в налаштуваннях Bluetooth." + "Вимкнути" + "Автоматичне змінення стану Bluetooth" diff --git a/android/app/res/values-ur/strings.xml b/android/app/res/values-ur/strings.xml index 36ce6b90b139e4bcc1adcc5ce2eb4b691e727ce0..d0ad0a58ec9a35ceb9198a960d60ab26839799d4 100644 --- a/android/app/res/values-ur/strings.xml +++ b/android/app/res/values-ur/strings.xml @@ -101,7 +101,6 @@ "کنکشن ناکام ہو گیا۔" "درخواست کو ٹھیک سے ہینڈل نہیں کیا جا سکتا۔" "نامعلوم خرابی۔" - "بلوٹوتھ کے ذریعے موصول کردہ" "بلوٹوتھ اشتراک" "%1$s وصولی مکمل۔" "%1$s بھیجنا مکمل ہو گیا۔" @@ -136,4 +135,8 @@ "آپ کا آلہ ہوائی جہاز وضع میں بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ بلوٹوتھ آن رہے تو اسے آف کریں۔" "‏Wi-Fi اور بلوٹوتھ آن رہنے دیں" "‏آپ کا آلہ ہوائی جہاز وضع میں Wi-Fi اور بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ Wi-Fi اور بلوٹوتھ آن رہیں تو انہیں آف کریں۔" + "بلوٹوتھ خودکار طور پر فعال ہو گیا ہے" + "خودکار ری اسٹارٹ کو بلوٹوتھ ترتیبات میں ٹوگل کیا جا سکتا ہے۔" + "آف کریں" + "بلوٹوتھ خودکار حالت میں تبدیلی" diff --git a/android/app/res/values-uz/strings.xml b/android/app/res/values-uz/strings.xml index d456f10b118a22abc0877af59fc7e635cfed5617..7cbf0bc3ffdeb7f51124a504f25e4c59ec3c64a7 100644 --- a/android/app/res/values-uz/strings.xml +++ b/android/app/res/values-uz/strings.xml @@ -101,7 +101,6 @@ "Ulanish muvaffaqiyatsiz yakunlandi." "So‘rovni to‘g‘ri bajarib bo‘lmaydi." "Noma’lum xato." - "Bluetooth orqali olingan" "Bluetooth uzatmalari" "To‘liq qabul qilindi: %1$s" "To‘liq yuborildi: %1$s" @@ -136,4 +135,8 @@ "Qurilmangiz parvoz rejimida Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Bluetooth aloqasini oʻchiring." "Wi-Fi va Bluetooth yoniq qoladi" "Qurilmangiz parvoz rejimida Wi‑Fi va Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Wi-Fi va Bluetooth aloqasini oʻchiring." + "Bluetooth avtomatik yoqilgan" + "Avtomatik qayta yoqishni Bluetooth sozlamalarida belgilash mumkin." + "Faolsizlantirish" + "Bluetooth holatini avtomatik oʻzgartirish" diff --git a/android/app/res/values-vi/strings.xml b/android/app/res/values-vi/strings.xml index 61ae148f2d4a7c5378bd5d8be6187db0360e1705..e842d6d6f9fe18fe47bca77891bf3db34b0aaf01 100644 --- a/android/app/res/values-vi/strings.xml +++ b/android/app/res/values-vi/strings.xml @@ -101,7 +101,6 @@ "Kết nối không thành công." "Không thể xử lý yêu cầu đúng cách." "Lỗi không xác định." - "Đã nhận qua bluetooth" "Chia sẻ qua Bluetooth" "Hoàn tất nhận %1$s." "Hoàn tất gửi %1$s." @@ -136,4 +135,8 @@ "Thiết bị của bạn sẽ luôn bật Bluetooth ở chế độ trên máy bay. Nếu không muốn như vậy thì bạn có thể tắt Bluetooth." "Wi-Fi và Bluetooth vẫn đang bật" "Thiết bị của bạn sẽ luôn bật Wi-Fi và Bluetooth ở chế độ trên máy bay. Nếu không muốn như vậy thì bạn có thể tắt Wi-Fi và Bluetooth." + "Bluetooth đã được tự động bật" + "Bạn có thể bật/tắt tính năng Tự động khởi động lại trong phần Cài đặt Bluetooth." + "Tắt" + "Tự động thay đổi trạng thái Bluetooth" diff --git a/android/app/res/values-zh-rCN/strings.xml b/android/app/res/values-zh-rCN/strings.xml index e04dede015342b392cd9ed41ede629ccb0537a91..a387723b0a3a2350cc98fbad6ec2a00e98435eeb 100644 --- a/android/app/res/values-zh-rCN/strings.xml +++ b/android/app/res/values-zh-rCN/strings.xml @@ -101,7 +101,6 @@ "连接失败。" "无法正确处理请求。" "未知错误。" - "通过蓝牙接收的文件" "蓝牙共享" "%1$s接收完成。" "%1$s发送完成。" @@ -136,4 +135,8 @@ "在飞行模式下设备将记住保持开启蓝牙。如果您不想保持开启和蓝牙,请关闭蓝牙。" "WLAN 和蓝牙保持开启状态" "在飞行模式下设备将记住保持开启 WLAN 和蓝牙。如果您不想保持开启 WLAN 和蓝牙,请关闭 WLAN 和蓝牙。" + "已自动启用蓝牙" + "可在蓝牙设置中开启/关闭自动重启功能。" + "关闭" + "蓝牙自动状态变更" diff --git a/android/app/res/values-zh-rHK/strings.xml b/android/app/res/values-zh-rHK/strings.xml index d3f427c15a091ab8f07027bbd76c20a57fbe7f0d..d3ccdf2020fdab532f6c6548f60716d002707879 100644 --- a/android/app/res/values-zh-rHK/strings.xml +++ b/android/app/res/values-zh-rHK/strings.xml @@ -101,7 +101,6 @@ "連線失敗。" "無法正確處理要求。" "未知錯誤。" - "透過藍牙接收的檔案" "藍牙分享" "已完成 %1$s 的接收作業。" "已完成 %1$s 的傳送作業。" @@ -136,4 +135,8 @@ "裝置會記得在飛行模式下保持藍牙開啟。如果你不希望保持開啟,請關閉藍牙。" "Wi-Fi 和藍牙保持開啟" "裝置會記得在飛行模式下保持 Wi-Fi 及藍牙開啟。如果你不希望保持開啟,請關閉 Wi-Fi 及藍牙。" + "已自動啟用藍牙" + "可在藍牙設定中開啟或關閉自動重新啟動功能。" + "關閉" + "藍牙自動狀態變更" diff --git a/android/app/res/values-zh-rTW/strings.xml b/android/app/res/values-zh-rTW/strings.xml index 0884f6e68e7d0a45623a3b4cc8fc32f46016a65a..db74c3706a66e9b71597bed9d1cd15e96a5fa300 100644 --- a/android/app/res/values-zh-rTW/strings.xml +++ b/android/app/res/values-zh-rTW/strings.xml @@ -101,7 +101,6 @@ "連線失敗。" "無法正確處理要求。" "未知的錯誤。" - "透過藍牙接收的檔案" "藍牙分享" "已完成 %1$s 的接收作業。" "已完成 %1$s 的傳送作業。" @@ -136,4 +135,8 @@ "裝置會記得在飛航模式下讓藍牙保持開啟狀態。如果不要保持開啟狀態,請關閉藍牙。" "Wi-Fi 和藍牙會保持開啟狀態" "裝置會記得在飛航模式下讓 Wi-Fi 和藍牙保持開啟狀態。如果不要保持開啟狀態,請關閉 Wi-Fi 和藍牙。" + "藍牙已自動啟用" + "可在藍牙設定中開啟或關閉自動重新啟動功能。" + "關閉" + "藍牙自動狀態變更" diff --git a/android/app/res/values-zu/strings.xml b/android/app/res/values-zu/strings.xml index d36cbaf1d1ed9559fa1a05ee3d66c8054ad4cef2..0a5d456c5e6070bd0626c6f19c87bfda5df79b69 100644 --- a/android/app/res/values-zu/strings.xml +++ b/android/app/res/values-zu/strings.xml @@ -101,7 +101,6 @@ "Ukuxhumeka akuphumelelanga." "Isicelo asikwazi ukuphathwa ngokulungile" "Iphutha elingaziwa" - "I-Bluetooth etholiwe" "Ukwabelana kwe-bluetooth" "%1$s Ukuthola kuqedile." "%1$s Ukuthumela kuqedile." @@ -136,4 +135,8 @@ "Idivayisi yakho ikhumbula ukugcina i-Bluetooth ivuliwe kumodi yendiza. Vala i-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." "I-Wi-Fi ne-Bluetooth kuhlala kuvuliwe" "Ifoni yakho ikhumbula ukugcina i-Wi-Fi ne-Bluetooth kuvuliwe kumodi yendiza. Vala i-Wi-Fi ne-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." + "I-Bluetooth inikwe amandla ngokuzenzekelayo" + "Ukuqalisa kabusha okuzenzekelayo kungashintshwa Kumasethingi e-Bluetooth." + "Vala" + "Ukushintsha kwesimo se-Bluetooth okuzenzekelayo" diff --git a/android/app/res/values/strings.xml b/android/app/res/values/strings.xml index 4018d3cab302f72c27f7a253976e7110cfe3422e..fe34075875f377c53b0f62bde9b59af0a2be4fb2 100644 --- a/android/app/res/values/strings.xml +++ b/android/app/res/values/strings.xml @@ -203,9 +203,6 @@ Request can\'t be handled correctly. Unknown error. - - Bluetooth received - Bluetooth Share %1$s Received complete. @@ -259,4 +256,8 @@ Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on. Wi-Fi and Bluetooth stay on Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on. + Bluetooth has been automatically enabled + Automatic restart can be toggled in Bluetooth Settings. + Turn off + Bluetooth automatic state change diff --git a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java index ed682a38eb13767d960174b65b069c3806e79e7b..22604dde37a42d71bddf1873ab0868af2fe67c8c 100644 --- a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java +++ b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java @@ -60,15 +60,8 @@ public class BluetoothEventLogger { /** Add the event record and log debug message */ public synchronized void logd(String tag, String msg) { - logd(true, tag, msg); - } - - /** Add the event record and log debug message */ - public synchronized void logd(boolean debug, String tag, String msg) { add(msg); - if (debug) { - Log.d(tag, msg); - } + Log.d(tag, msg); } /** Add the event record and log warning message */ diff --git a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java index 74f223bcb4662c98edafb92727f63d65638e8bb7..9873eedd20449967cbf155c13259925118eead83 100644 --- a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java +++ b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java @@ -30,6 +30,8 @@ import android.content.Context; import android.content.Intent; import android.content.res.AssetFileDescriptor; import android.database.Cursor; +import android.media.session.MediaController; +import android.media.session.MediaSessionManager; import android.net.Uri; import android.os.Bundle; import android.os.CancellationSignal; @@ -51,6 +53,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.List; import java.util.Set; /** @@ -236,6 +239,11 @@ public class BluetoothMethodProxy { manager.registerSync(scanResult, skip, timeout, callback, handler); } + /** Proxies {@link PeriodicAdvertisingManager#unregisterSync(PeriodicAdvertisingCallback)}. */ + public void periodicAdvertisingManagerUnregisterSync( + PeriodicAdvertisingManager manager, PeriodicAdvertisingCallback callback) { + manager.unregisterSync(callback); + } /** * Proxies {@link PeriodicAdvertisingManager#transferSync}. */ @@ -270,4 +278,10 @@ public class BluetoothMethodProxy { public Looper handlerThreadGetLooper(HandlerThread handlerThread) { return handlerThread.getLooper(); } + + /** Peoziws {@link MediaSessionManager#getActiveSessions} */ + public @NonNull List mediaSessionManagerGetActiveSessions( + MediaSessionManager manager) { + return manager.getActiveSessions(null); + } } diff --git a/android/app/src/com/android/bluetooth/ObexServerSockets.java b/android/app/src/com/android/bluetooth/ObexServerSockets.java index 1b6864bdf74719ada6d6517ca7b8a8d54605cb80..2b1c9d6d9ff8a8cc3d23114f1083af226a56ea3f 100644 --- a/android/app/src/com/android/bluetooth/ObexServerSockets.java +++ b/android/app/src/com/android/bluetooth/ObexServerSockets.java @@ -47,9 +47,8 @@ import java.util.concurrent.atomic.AtomicInteger; * In both cases the {@link ObexServerSockets} object have terminated, and a new must be created. */ public class ObexServerSockets { - private final String mTag; - private static final String STAG = "ObexServerSockets"; - private static final boolean D = true; // TODO: set to false! + private static final String TAG = "ObexServerSockets"; + private static final boolean D = true; // TODO: set this to false! private final IObexConnectionHandler mConHandler; /* The wrapped sockets */ @@ -66,7 +65,6 @@ public class ObexServerSockets { mConHandler = conHandler; mRfcommSocket = rfcommSocket; mL2capSocket = l2capSocket; - mTag = "ObexServerSockets" + sInstanceCounter.getAndIncrement(); } /** @@ -113,7 +111,7 @@ public class ObexServerSockets { private static ObexServerSockets create(IObexConnectionHandler validator, int rfcommChannel, int l2capPsm, boolean isSecure) { if (D) { - Log.d(STAG, "create(rfcomm = " + rfcommChannel + ", l2capPsm = " + l2capPsm + ")"); + Log.d(TAG, "create(rfcomm = " + rfcommChannel + ", l2capPsm = " + l2capPsm + ")"); } BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter(); if (bt == null) { @@ -142,10 +140,10 @@ public class ObexServerSockets { } } } catch (IOException e) { - Log.e(STAG, "Error create ServerSockets ", e); + Log.e(TAG, "Error create ServerSockets ", e); initSocketOK = false; } catch (SecurityException e) { - Log.e(STAG, "Error create ServerSockets ", e); + Log.e(TAG, "Error create ServerSockets ", e); initSocketOK = false; break; } @@ -154,16 +152,16 @@ public class ObexServerSockets { int state = bt.getState(); if ((state != BluetoothAdapter.STATE_TURNING_ON) && (state != BluetoothAdapter.STATE_ON)) { - Log.w(STAG, "initServerSockets failed as BT is (being) turned off"); + Log.w(TAG, "initServerSockets failed as BT is (being) turned off"); break; } try { if (D) { - Log.v(STAG, "waiting 300 ms..."); + Log.v(TAG, "waiting 300 ms..."); } Thread.sleep(300); } catch (InterruptedException e) { - Log.e(STAG, "create() was interrupted"); + Log.e(TAG, "create() was interrupted"); } } else { break; @@ -172,13 +170,13 @@ public class ObexServerSockets { if (initSocketOK) { if (D) { - Log.d(STAG, "Succeed to create listening sockets "); + Log.d(TAG, "Succeed to create listening sockets "); } ObexServerSockets sockets = new ObexServerSockets(validator, rfcommSocket, l2capSocket); sockets.startAccept(); return sockets; } else { - Log.e(STAG, "Error to create listening socket after " + CREATE_RETRY_TIME + " try"); + Log.e(TAG, "Error to create listening socket after " + CREATE_RETRY_TIME + " try"); return null; } } @@ -207,9 +205,7 @@ public class ObexServerSockets { * the {@link IObexConnectionValidator#onConnect()}, at which point both threads will exit. */ private void startAccept() { - if (D) { - Log.d(mTag, "startAccept()"); - } + Log.d(TAG, "startAccept()"); mRfcommThread = new SocketAcceptThread(mRfcommSocket); mRfcommThread.start(); @@ -225,9 +221,7 @@ public class ObexServerSockets { * @return true if the connection is accepted, false otherwise. */ private synchronized boolean onConnect(BluetoothDevice device, BluetoothSocket conSocket) { - if (D) { - Log.d(mTag, "onConnect() socket: " + conSocket); - } + Log.d(TAG, "onConnect() socket: " + conSocket); return mConHandler.onConnect(device, conSocket); } @@ -238,7 +232,7 @@ public class ObexServerSockets { shutdown(false); BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); if ((mAdapter != null) && (mAdapter.getState() == BluetoothAdapter.STATE_ON)) { - Log.d(mTag, "onAcceptFailed() calling shutdown..."); + Log.d(TAG, "onAcceptFailed() calling shutdown..."); mConHandler.onAcceptFailed(); } } @@ -249,9 +243,7 @@ public class ObexServerSockets { * has ended execution */ public synchronized void shutdown(boolean block) { - if (D) { - Log.d(mTag, "shutdown(block = " + block + ")"); - } + Log.d(TAG, "shutdown(block = " + block + ")"); if (mRfcommThread != null) { mRfcommThread.shutdown(); } @@ -270,7 +262,7 @@ public class ObexServerSockets { mL2capThread = null; } } catch (InterruptedException e) { - Log.i(mTag, "shutdown() interrupted, continue waiting...", e); + Log.i(TAG, "shutdown() interrupted, continue waiting...", e); } } } else { @@ -314,28 +306,24 @@ public class ObexServerSockets { BluetoothDevice device; try { - if (D) { - Log.d(mTag, "Accepting socket connection..."); - } + Log.d(TAG, "Accepting socket connection..."); connSocket = mServerSocket.accept(); - if (D) { - Log.d(mTag, "Accepted socket connection from: " + mServerSocket); - } + Log.d(TAG, "Accepted socket connection from: " + mServerSocket); if (connSocket == null) { // TODO: Do we need a max error count, to avoid spinning? - Log.w(mTag, "connSocket is null - reattempt accept"); + Log.w(TAG, "connSocket is null - reattempt accept"); continue; } device = connSocket.getRemoteDevice(); if (device == null) { - Log.i(mTag, "getRemoteDevice() = null - reattempt accept"); + Log.i(TAG, "getRemoteDevice() = null - reattempt accept"); try { connSocket.close(); } catch (IOException e) { - Log.w(mTag, "Error closing the socket. ignoring...", e); + Log.w(TAG, "Error closing the socket. ignoring...", e); } continue; } @@ -348,7 +336,7 @@ public class ObexServerSockets { /* Close connection if we already have a connection with another device * by responding to the OBEX connect request. */ - Log.i(mTag, "RemoteDevice is invalid - creating ObexRejectServer."); + Log.i(TAG, "RemoteDevice is invalid - creating ObexRejectServer."); BluetoothObexTransport obexTrans = new BluetoothObexTransport(connSocket); // Create and detach a selfdestructing ServerSession to respond to any @@ -364,16 +352,14 @@ public class ObexServerSockets { if (mStopped) { // Expected exception because of shutdown. } else { - Log.w(mTag, "Accept exception for " + mServerSocket, ex); + Log.w(TAG, "Accept exception for " + mServerSocket, ex); ObexServerSockets.this.onAcceptFailed(); } mStopped = true; } } // End while() } finally { - if (D) { - Log.d(mTag, "AcceptThread ended for: " + mServerSocket); - } + Log.d(TAG, "AcceptThread ended for: " + mServerSocket); } } @@ -391,18 +377,14 @@ public class ObexServerSockets { try { mServerSocket.close(); } catch (IOException e) { - if (D) { - Log.d(mTag, "Exception while thread shutdown:", e); - } + Log.w(TAG, "Exception while thread shutdown:", e); } } // If called from another thread, interrupt the thread if (!Thread.currentThread().equals(this)) { // TODO: Will this interrupt the thread if it is blocked in synchronized? // Else: change to use InterruptableLock - if (D) { - Log.d(mTag, "shutdown called from another thread - interrupt()."); - } + Log.d(TAG, "shutdown called from another thread - interrupt()."); interrupt(); } } diff --git a/android/app/src/com/android/bluetooth/Utils.java b/android/app/src/com/android/bluetooth/Utils.java index 3e686bb023d9bbad63b15bb24c8eed5c5b4eab9f..8ce32f5d06f368c7a889ea681b652535fc32d083 100644 --- a/android/app/src/com/android/bluetooth/Utils.java +++ b/android/app/src/com/android/bluetooth/Utils.java @@ -189,6 +189,23 @@ public final class Utils { return String.format("XX:XX:XX:XX:%02X:%02X", address[4], address[5]); } + /** + * Returns the correct device address to be used for connections over BR/EDR transport. + * + * @param device the device for which to obtain the connection address + * @return either identity address or device address as a byte array + */ + public static byte[] getByteBrEdrAddress(BluetoothDevice device) { + final AdapterService service = AdapterService.getAdapterService(); + // If dual mode device bonded over BLE first, BR/EDR address will be identity address + // Otherwise, BR/EDR address will be same address as in BluetoothDevice#getAddress + byte[] address = service.getByteIdentityAddress(device); + if (address == null) { + address = getByteAddress(device); + } + return address; + } + public static byte[] getByteAddress(BluetoothDevice device) { return getBytesFromAddress(device.getAddress()); } diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java index 000229bc479d67c73168b7d775e402b716a0c6bf..6c52b2b1498cbcfba60a69d0feba050b384ffb70 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java @@ -31,6 +31,7 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -173,7 +174,11 @@ public class A2dpNativeInterface { if (device == null) { return Utils.getBytesFromAddress("00:00:00:00:00:00"); } - return mAdapterService.getByteIdentityAddress(device); + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getByteBrEdrAddress(device); + } else { + return mAdapterService.getByteIdentityAddress(device); + } } private void sendMessageToService(A2dpStackEvent event) { diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java index e42cb0c1eff057cdc648442a311a5c18ab686a1c..f22be4abae32643c5260220b99b7407bfca9d3cf 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java @@ -41,7 +41,6 @@ import android.bluetooth.BufferConstraints; import android.bluetooth.IBluetoothA2dp; import android.companion.CompanionDeviceManager; import android.content.AttributionSource; -import android.content.Context; import android.content.Intent; import android.media.AudioDeviceCallback; import android.media.AudioDeviceInfo; @@ -59,13 +58,14 @@ import android.util.Log; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; +import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.AudioRoutingManager; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.flags.FeatureFlags; -import com.android.bluetooth.flags.FeatureFlagsImpl; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetService; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -89,19 +89,18 @@ public class A2dpService extends ProfileService { private static A2dpService sA2dpService; - private final FeatureFlags mFeatureFlags; - private AdapterService mAdapterService; - private DatabaseManager mDatabaseManager; + private final A2dpNativeInterface mNativeInterface; + private final AdapterService mAdapterService; + private final AudioManager mAudioManager; + private final DatabaseManager mDatabaseManager; + private final CompanionDeviceManager mCompanionDeviceManager; + private HandlerThread mStateMachinesThread; private Handler mHandler = null; - private final A2dpNativeInterface mNativeInterface; @VisibleForTesting ServiceFactory mFactory = new ServiceFactory(); - @VisibleForTesting - AudioManager mAudioManager; private A2dpCodecConfig mA2dpCodecConfig; - private CompanionDeviceManager mCompanionDeviceManager; @GuardedBy("mStateMachines") private BluetoothDevice mActiveDevice; @@ -126,48 +125,42 @@ public class A2dpService extends ProfileService { private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback(); - A2dpService() { - mNativeInterface = requireNonNull(A2dpNativeInterface.getInstance()); - mFeatureFlags = new FeatureFlagsImpl(); + public A2dpService(AdapterService adapterService) { + this(adapterService, A2dpNativeInterface.getInstance()); } @VisibleForTesting - A2dpService(Context ctx, A2dpNativeInterface nativeInterface, FeatureFlags featureFlags) { - super(ctx); + A2dpService(AdapterService adapterService, A2dpNativeInterface nativeInterface) { + super(requireNonNull(adapterService)); + mAdapterService = adapterService; mNativeInterface = requireNonNull(nativeInterface); - mFeatureFlags = featureFlags; + mDatabaseManager = requireNonNull(mAdapterService.getDatabase()); + mAudioManager = requireNonNull(getSystemService(AudioManager.class)); + + // Some platform may not have the FEATURE_COMPANION_DEVICE_SETUP + mCompanionDeviceManager = getSystemService(CompanionDeviceManager.class); } public static boolean isEnabled() { return BluetoothProperties.isProfileA2dpSourceEnabled().orElse(false); } + ActiveDeviceManager getActiveDeviceManager() { + return mAdapterService.getActiveDeviceManager(); + } + @Override protected IProfileServiceBinder initBinder() { return new BluetoothA2dpBinder(this); } @Override - protected boolean start() { + public void start() { Log.i(TAG, "start()"); if (sA2dpService != null) { throw new IllegalStateException("start() called twice"); } - // Step 1: Get AdapterService, DatabaseManager, AudioManager. - // None of them can be null. - mAdapterService = - requireNonNull( - AdapterService.getAdapterService(), - "AdapterService cannot be null when A2dpService starts"); - mDatabaseManager = - requireNonNull( - mAdapterService.getDatabase(), - "DatabaseManager cannot be null when A2dpService starts"); - mAudioManager = getSystemService(AudioManager.class); - mCompanionDeviceManager = getSystemService(CompanionDeviceManager.class); - requireNonNull(mAudioManager, "AudioManager cannot be null when A2dpService starts"); - // Step 2: Get maximum number of connected audio devices mMaxConnectedAudioDevices = mAdapterService.getMaxConnectedAudioDevices(); Log.i(TAG, "Max connected audio devices set to " + mMaxConnectedAudioDevices); @@ -202,16 +195,14 @@ public class A2dpService extends ProfileService { // Step 9: Clear active device removeActiveDevice(false); - - return true; } @Override - protected boolean stop() { + public void stop() { Log.i(TAG, "stop()"); if (sA2dpService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } // Step 9: Clear active device and stop playing audio @@ -254,16 +245,10 @@ public class A2dpService extends ProfileService { // Step 2: Reset maximum number of connected audio devices mMaxConnectedAudioDevices = 1; - - // Step 1: Clear AdapterService, AudioManager - mAudioManager = null; - mAdapterService = null; - - return true; } @Override - protected void cleanup() { + public void cleanup() { Log.i(TAG, "cleanup()"); } @@ -1325,7 +1310,7 @@ public class A2dpService extends ProfileService { if (toState == BluetoothProfile.STATE_CONNECTED) { MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.A2DP); } - if (!mFeatureFlags.audioRoutingCentralization()) { + if (!Flags.audioRoutingCentralization()) { // Set the active device if only one connected device is supported and it was connected if (toState == BluetoothProfile.STATE_CONNECTED && (mMaxConnectedAudioDevices == 1)) { setActiveDevice(device); @@ -1479,15 +1464,22 @@ public class A2dpService extends ProfileService { SynchronousResultReceiver receiver) { try { A2dpService service = getService(source); - boolean result = false; if (service != null) { - if (device == null) { - result = service.removeActiveDevice(false); + if (Flags.audioRoutingCentralization()) { + ((AudioRoutingManager) service.getActiveDeviceManager()) + .activateDeviceProfile(device, BluetoothProfile.A2DP, receiver); } else { - result = service.setActiveDevice(device); + boolean result; + if (device == null) { + result = service.removeActiveDevice(false); + } else { + result = service.setActiveDevice(device); + } + receiver.send(result); } + } else { + receiver.send(false); } - receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); } @@ -1602,6 +1594,12 @@ public class A2dpService extends ProfileService { return; } if (!hasBluetoothPrivilegedPermission(service)) { + if (service.mCompanionDeviceManager == null) { + throw new SecurityException( + "Caller should have BLUETOOTH_PRIVILEGED in order to call" + + " setCodecConfigPreference without a CompanionDeviceManager" + + " service"); + } enforceCdmAssociation(service.mCompanionDeviceManager, service, source.getPackageName(), Binder.getCallingUid(), device); } diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java index 1a58e200c62b614db1350326e1cfd412eacae7cf..f4ba3785a8feaf6e21163682eeb1b0dfba751c43 100644 --- a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java +++ b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java @@ -105,7 +105,11 @@ final class A2dpStateMachine extends StateMachine { A2dpStateMachine(BluetoothDevice device, A2dpService a2dpService, A2dpNativeInterface a2dpNativeInterface, Looper looper) { super(TAG, looper); - setDbg(DBG); + + // Let the logging framework enforce the log level. TAG is set above in the parent + // constructor. + setDbg(true); + mDevice = device; mA2dpService = a2dpService; mA2dpNativeInterface = a2dpNativeInterface; diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java index e61d8da306ccd19d7617eb5a18144150c5a80fc2..08c1247b1c1df98bfc4ee1bb3a4d7d7cbfbd2385 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java @@ -21,6 +21,7 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -85,7 +86,11 @@ public class A2dpSinkNativeInterface { } private byte[] getByteAddress(BluetoothDevice device) { - return mAdapterService.getByteIdentityAddress(device); + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getByteBrEdrAddress(device); + } else { + return mAdapterService.getByteIdentityAddress(device); + } } /** diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java index b347447bc106b271c2b08536a04ee78bd33be6d0..c823b7676f3d9f7ee3a8765a280d245b2b3e1ee1 100644 --- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java +++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java @@ -74,7 +74,8 @@ public class A2dpSinkService extends ProfileService { private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; - A2dpSinkService() { + public A2dpSinkService(Context ctx) { + super(ctx); mNativeInterface = requireNonNull(A2dpSinkNativeInterface.getInstance()); mLooper = Looper.getMainLooper(); } @@ -91,7 +92,7 @@ public class A2dpSinkService extends ProfileService { } @Override - protected boolean start() { + public void start() { mAdapterService = requireNonNull( AdapterService.getAdapterService(), @@ -109,11 +110,10 @@ public class A2dpSinkService extends ProfileService { } setA2dpSinkService(this); - return true; } @Override - protected boolean stop() { + public void stop() { setA2dpSinkService(null); mNativeInterface.cleanup(); for (A2dpSinkStateMachine stateMachine : mDeviceStateMap.values()) { @@ -126,7 +126,6 @@ public class A2dpSinkService extends ProfileService { mA2dpSinkStreamHandler = null; } } - return true; } public static synchronized A2dpSinkService getA2dpSinkService() { @@ -637,6 +636,13 @@ public class A2dpSinkService extends ProfileService { return; } A2dpSinkStateMachine stateMachine = getStateMachineForDevice(device); + if (stateMachine == null) { + Log.w( + TAG, + "Received audio config changed event for an unconnected device, device=" + + device); + return; + } stateMachine.onStackEvent(event); } diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java index 67bf06f55ebef636370e004839bd15f255e1592f..4c2ab41fa23d918a246d4e2dd8c781f3d6054fe4 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java @@ -37,8 +37,7 @@ import android.util.Log; import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.Utils; -import com.android.bluetooth.flags.FeatureFlags; -import com.android.bluetooth.flags.FeatureFlagsImpl; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; @@ -92,7 +91,6 @@ public class MediaPlayerList { private MediaSessionManager mMediaSessionManager; private MediaData mCurrMediaData = null; private final AudioManager mAudioManager; - private final FeatureFlags mFeatureFlags = new FeatureFlagsImpl(); private final BluetoothEventLogger mActivePlayerLogger = new BluetoothEventLogger(ACTIVE_PLAYER_LOGGER_SIZE, ACTIVE_PLAYER_LOGGER_TITLE); @@ -211,7 +209,7 @@ public class MediaPlayerList { // Build the list of browsable players and afterwards, build the list of media players Intent intent = new Intent(android.service.media.MediaBrowserService.SERVICE_INTERFACE); - if (mFeatureFlags.keepStoppedMediaBrowserService()) { + if (Flags.keepStoppedMediaBrowserService()) { // Don't query stopped apps, that would end up unstopping them intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); } @@ -844,11 +842,11 @@ public class MediaPlayerList { } } if (isActive != mAudioPlaybackIsActive) { - mAudioPlaybackStateLogger.logd(DEBUG, TAG, "onPlaybackConfigChanged: " + mAudioPlaybackStateLogger.logd(TAG, "onPlaybackConfigChanged: " + (mAudioPlaybackIsActive ? "Active" : "Non-active") + " -> " + (isActive ? "Active" : "Non-active")); if (isActive) { - mAudioPlaybackStateLogger.logd(DEBUG, TAG, "onPlaybackConfigChanged: " + mAudioPlaybackStateLogger.logd(TAG, "onPlaybackConfigChanged: " + "active config: " + activeConfig); } mAudioPlaybackIsActive = isActive; diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java index 4506ead53a8753b57a98a907d477ce0d36f8b23e..443e5f91350be5d77b48eb208f88380a0b857b38 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java @@ -104,10 +104,7 @@ public class AvrcpTargetService extends ProfileService { private static AvrcpTargetService sInstance = null; - AvrcpTargetService() {} - - @VisibleForTesting - AvrcpTargetService(Context ctx) { + public AvrcpTargetService(Context ctx) { super(ctx); } @@ -191,10 +188,9 @@ public class AvrcpTargetService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (sInstance != null) { - Log.wtf(TAG, "The service has already been initialized"); - return false; + throw new IllegalStateException("start() called twice"); } IntentFilter userFilter = new IntentFilter(); @@ -245,16 +241,15 @@ public class AvrcpTargetService extends ProfileService { // Only allow the service to be used once it is initialized sInstance = this; - return true; } @Override - protected boolean stop() { + public void stop() { Log.i(TAG, "Stopping the AVRCP Target Service"); if (sInstance == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } if (mAvrcpCoverArtService != null) { @@ -276,7 +271,6 @@ public class AvrcpTargetService extends ProfileService { mNativeInterface = null; mAudioManager = null; mReceiver = null; - return true; } private void init() { @@ -463,7 +457,6 @@ public class AvrcpTargetService extends ProfileService { BluetoothDevice activeDevice = getA2dpActiveDevice(); MediaPlayerWrapper player = mMediaPlayerList.getActivePlayer(); mMediaKeyEventLogger.logd( - DEBUG, TAG, "sendMediaKeyEvent:" + " device=" diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java index 780b00db13c0667c0eb8f5058aff713fe6681a13..9599c866658975eae08428f42dc9358582fab521 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java @@ -179,7 +179,7 @@ class AvrcpVolumeManager extends AudioDeviceCallback { void setVolume(@NonNull BluetoothDevice device, int avrcpVolume) { int deviceVolume = avrcpToSystemVolume(avrcpVolume); - mVolumeEventLogger.logd(DEBUG, TAG, "setVolume:" + mVolumeEventLogger.logd(TAG, "setVolume:" + " device=" + device + " avrcpVolume=" + avrcpVolume + " deviceVolume=" + deviceVolume @@ -196,7 +196,7 @@ class AvrcpVolumeManager extends AudioDeviceCallback { return; } int avrcpVolume = systemToAvrcpVolume(deviceVolume); - mVolumeEventLogger.logd(DEBUG, TAG, "sendVolumeChanged:" + mVolumeEventLogger.logd(TAG, "sendVolumeChanged:" + " device=" + device + " avrcpVolume=" + avrcpVolume + " deviceVolume=" + deviceVolume diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java index 38ccee8d97b4d12ec7de981f9b507a6888f049b0..fc9248cb6fd267a5ce603932087c24134c6109ef 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java @@ -134,8 +134,9 @@ public class AvrcpControllerService extends ProfileService { } } - AvrcpControllerService() { - mNativeInterface = AvrcpControllerNativeInterface.getInstance(); + public AvrcpControllerService(Context ctx) { + super(ctx); + mNativeInterface = requireNonNull(AvrcpControllerNativeInterface.getInstance()); } @VisibleForTesting @@ -149,7 +150,7 @@ public class AvrcpControllerService extends ProfileService { } @Override - protected synchronized boolean start() { + public synchronized void start() { mNativeInterface.init(this); setComponentAvailable(ON_ERROR_SETTINGS_ACTIVITY, true); mAdapterService = AdapterService.getAdapterService(); @@ -165,11 +166,10 @@ public class AvrcpControllerService extends ProfileService { Intent startIntent = new Intent(this, BluetoothMediaBrowserService.class); startService(startIntent); setActiveDevice(null); - return true; } @Override - protected synchronized boolean stop() { + public synchronized void stop() { setActiveDevice(null); Intent stopIntent = new Intent(this, BluetoothMediaBrowserService.class); stopService(stopIntent); @@ -187,7 +187,6 @@ public class AvrcpControllerService extends ProfileService { } setComponentAvailable(ON_ERROR_SETTINGS_ACTIVITY, false); mNativeInterface.cleanup(); - return true; } public static AvrcpControllerService getAvrcpControllerService() { diff --git a/android/app/src/com/android/bluetooth/bas/BatteryService.java b/android/app/src/com/android/bluetooth/bas/BatteryService.java index 4691be7fea2230d26856b900ae258db385c19a56..e52220dd9d21e73548b9ffd60030002eeb8c5853 100644 --- a/android/app/src/com/android/bluetooth/bas/BatteryService.java +++ b/android/app/src/com/android/bluetooth/bas/BatteryService.java @@ -66,10 +66,7 @@ public class BatteryService extends ProfileService { private Handler mHandler; private final Map mStateMachines = new HashMap<>(); - BatteryService() {} - - @VisibleForTesting - BatteryService(Context ctx) { + public BatteryService(Context ctx) { super(ctx); } @@ -83,7 +80,7 @@ public class BatteryService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -102,18 +99,16 @@ public class BatteryService extends ProfileService { mStateMachinesThread.start(); setBatteryService(this); - - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sBatteryService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } setBatteryService(null); @@ -145,12 +140,10 @@ public class BatteryService extends ProfileService { } mAdapterService = null; - - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java b/android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java new file mode 100644 index 0000000000000000000000000000000000000000..0e8890cdada4da8e24dd181348ceb0f862e32cf4 --- /dev/null +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientPeriodicAdvertisingManager.java @@ -0,0 +1,84 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bluetooth.bass_client; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.le.PeriodicAdvertisingManager; +import android.util.Log; + +/** Bass Client Periodic Advertising object handler */ +class BassClientPeriodicAdvertisingManager { + private static final String TAG = "BassClientPeriodicAdvertisingManager"; + + private static PeriodicAdvertisingManager sPeriodicAdvertisingManager; + + private BassClientPeriodicAdvertisingManager() {} + + /** + * Return true if initialization of Periodic Advertising Manager instance on Default Bluetooth + * Adapter is successful. + */ + public static boolean initializePeriodicAdvertisingManagerOnDefaultAdapter() { + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + + if (sPeriodicAdvertisingManager != null) { + Log.w(TAG, "Periodic Advertising Manager already initialized - re-initializing"); + } + + if (adapter == null) { + Log.e(TAG, "Failed to get Default Bluetooth Adapter"); + return false; + } + + sPeriodicAdvertisingManager = adapter.getPeriodicAdvertisingManager(); + + if (sPeriodicAdvertisingManager == null) { + Log.e(TAG, "Failed to get Default Periodic Advertising Manager"); + return false; + } + + Log.d(TAG, "BassClientPeriodicAdvertisingManager initialized"); + + return true; + } + + public static synchronized PeriodicAdvertisingManager getPeriodicAdvertisingManager() { + if (sPeriodicAdvertisingManager == null) { + Log.e( + TAG, + "getPeriodicAdvertisingManager: Periodic Advertising Manager is not " + + "initialized"); + return null; + } + + return sPeriodicAdvertisingManager; + } + + public static void clearPeriodicAdvertisingManager() { + if (sPeriodicAdvertisingManager == null) { + Log.e( + TAG, + "clearPeriodicAdvertisingManager: Periodic Advertising Manager is not " + + "initialized"); + return; + } + + Log.d(TAG, "BassClientPeriodicAdvertisingManager cleared"); + + sPeriodicAdvertisingManager = null; + } +} diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java index cb3558e9990679e20dbdfe6bebec452d231c449d..5f726c294acbf609d2373e53f8a2a0806671441b 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java @@ -18,6 +18,7 @@ package com.android.bluetooth.bass_client; import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static com.android.bluetooth.flags.Flags.leaudioBroadcastFeatureSupport; import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission; import android.bluetooth.BluetoothAdapter; @@ -35,7 +36,6 @@ import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.content.Context; -import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -59,10 +59,13 @@ import com.android.bluetooth.flags.FeatureFlagsImpl; import com.android.bluetooth.le_audio.LeAudioService; import com.android.internal.annotations.VisibleForTesting; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Deque; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -79,6 +82,21 @@ public class BassClientService extends ProfileService { private static final int MAX_BASS_CLIENT_STATE_MACHINES = 10; private static final int MAX_ACTIVE_SYNCED_SOURCES_NUM = 4; + private static final int STATUS_LOCAL_STREAM_REQUESTED = 0; + private static final int STATUS_LOCAL_STREAM_STREAMING = 1; + private static final int STATUS_LOCAL_STREAM_SUSPENDED = 2; + + // Do not modify without updating the HAL bt_le_audio.h files. + // Match up with BroadcastState enum of bt_le_audio.h + private static final int BROADCAST_STATE_STOPPED = 0; + private static final int BROADCAST_STATE_CONFIGURING = 1; + private static final int BROADCAST_STATE_PAUSED = 2; + private static final int BROADCAST_STATE_STOPPING = 3; + private static final int BROADCAST_STATE_STREAMING = 4; + + /* 1 minute timeout for primary device reconnection in Private Broadcast case */ + private static final int DIALING_OUT_TIMEOUT_MS = 60000; + private static BassClientService sService; private final Map mStateMachines = new HashMap<>(); @@ -94,6 +112,9 @@ public class BassClientService extends ProfileService { private final Map mBroadcastMetadataMap = new ConcurrentHashMap<>(); private final LinkedList mPausedBroadcastSinks = new LinkedList<>(); + private final Deque mPendingAddSources = new ArrayDeque<>(); + private final Map> mLocalBroadcastReceivers = + new ConcurrentHashMap<>(); private HandlerThread mStateMachinesThread; private HandlerThread mCallbackHandlerThread; @@ -101,6 +122,7 @@ public class BassClientService extends ProfileService { private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private BluetoothAdapter mBluetoothAdapter = null; + private DialingOutTimeoutEvent mDialingOutTimeoutEvent = null; /* Caching the PeriodicAdvertisementResult from Broadcast source */ /* This is stored at service so that each device state machine can access @@ -117,6 +139,8 @@ public class BassClientService extends ProfileService { mPeriodicAdvertisementResultMap; private ScanCallback mSearchScanCallback; private Callbacks mCallbacks; + private boolean mIsAssistantActive = false; + Optional mUnicastSourceStreamStatus = Optional.empty(); private static final int LOG_NB_EVENTS = 100; private static final BluetoothEventLogger sEventLogger = @@ -126,19 +150,35 @@ public class BassClientService extends ProfileService { @VisibleForTesting ServiceFactory mServiceFactory = new ServiceFactory(); - BassClientService() { + public BassClientService(Context ctx) { + super(ctx); mFeatureFlags = new FeatureFlagsImpl(); } @VisibleForTesting BassClientService(Context ctx, FeatureFlags featureFlags) { - attachBaseContext(ctx); + super(ctx); mFeatureFlags = featureFlags; - onCreate(); } public static boolean isEnabled() { - return BluetoothProperties.isProfileBapBroadcastAssistEnabled().orElse(false); + return leaudioBroadcastFeatureSupport() + && BluetoothProperties.isProfileBapBroadcastAssistEnabled().orElse(false); + } + + private static class AddSourceData { + BluetoothDevice mSink; + BluetoothLeBroadcastMetadata mSourceMetadata; + boolean mIsGroupOp; + + AddSourceData( + BluetoothDevice sink, + BluetoothLeBroadcastMetadata sourceMetadata, + boolean isGroupOp) { + mSink = sink; + mSourceMetadata = sourceMetadata; + mIsGroupOp = isGroupOp; + } } void updatePeriodicAdvertisementResultMap( @@ -199,10 +239,10 @@ public class BassClientService extends ProfileService { } if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) { paRes.updateSyncHandle(syncHandle); - if (mSyncHandleToBroadcastIdMap != null - && paRes.getBroadcastId() != BassConstants.INVALID_BROADCAST_ID) { - // broadcast successfully synced, update the map - mSyncHandleToBroadcastIdMap.put(syncHandle, paRes.getBroadcastId()); + if (paRes.getBroadcastId() != BassConstants.INVALID_BROADCAST_ID) { + // broadcast successfully synced + // update the sync handle for the broadcast source + updateSyncHandleForBroadcastId(syncHandle, paRes.getBroadcastId()); } } if (addressType != BassConstants.INVALID_ADV_ADDRESS_TYPE) { @@ -296,7 +336,7 @@ public class BassClientService extends ProfileService { } } } - sEventLogger.logd(DBG, TAG, "Broadcast Source Unsynced: scanDelegator= " + scanDelegator + sEventLogger.logd(TAG, "Broadcast Source Unsynced: scanDelegator= " + scanDelegator + ", syncHandle= " + syncHandle); } @@ -314,7 +354,7 @@ public class BassClientService extends ProfileService { mActiveSourceMap.get(scanDelegator).add(syncHandle); } } - sEventLogger.logd(DBG, TAG, "Broadcast Source Synced: scanDelegator= " + scanDelegator + sEventLogger.logd(TAG, "Broadcast Source Synced: scanDelegator= " + scanDelegator + ", syncHandle= " + syncHandle); } @@ -349,7 +389,7 @@ public class BassClientService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -380,15 +420,28 @@ public class BassClientService extends ProfileService { mSyncHandleToBaseDataMap = new HashMap(); mSyncHandleToBroadcastIdMap = new HashMap(); mSearchScanCallback = null; - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } + mUnicastSourceStreamStatus = Optional.empty(); + + if (mDialingOutTimeoutEvent != null) { + mHandler.removeCallbacks(mDialingOutTimeoutEvent); + mDialingOutTimeoutEvent = null; + } + + if (mIsAssistantActive) { + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + if (leAudioService != null) { + leAudioService.activeBroadcastAssistantNotification(false); + } + } + synchronized (mStateMachines) { for (BassClientStateMachine sm : mStateMachines.values()) { BassObjectsFactory.getInstance().destroyStateMachine(sm); @@ -422,6 +475,9 @@ public class BassClientService extends ProfileService { if (mActiveSourceMap != null) { mActiveSourceMap.clear(); } + if (mLocalBroadcastReceivers != null) { + mLocalBroadcastReceivers.clear(); + } if (mPendingGroupOp != null) { mPendingGroupOp.clear(); } @@ -435,13 +491,6 @@ public class BassClientService extends ProfileService { mSyncHandleToBroadcastIdMap.clear(); mSyncHandleToBroadcastIdMap = null; } - return true; - } - - @Override - public boolean onUnbind(Intent intent) { - Log.d(TAG, "Need to unregister app"); - return super.onUnbind(intent); } BluetoothDevice getDeviceForSyncHandle(int syncHandle) { @@ -478,6 +527,17 @@ public class BassClientService extends ProfileService { return BassConstants.INVALID_BROADCAST_ID; } + void updateSyncHandleForBroadcastId(int syncHandle, int broadcastId) { + if (mSyncHandleToBroadcastIdMap == null) { + Log.e(TAG, "mSyncHandleToBroadcastIdMap is null"); + return; + } + + mSyncHandleToBroadcastIdMap.entrySet().removeIf(entry -> entry.getValue() == broadcastId); + mSyncHandleToBroadcastIdMap.put(syncHandle, broadcastId); + log("Updated mSyncHandleToBroadcastIdMap: " + mSyncHandleToBroadcastIdMap); + } + private static synchronized void setBassClientService(BassClientService instance) { if (DBG) { Log.d(TAG, "setBassClientService(): set to: " + instance); @@ -509,6 +569,24 @@ public class BassClientService extends ProfileService { return ret; } + private boolean isAnyPendingAddSourceOperation() { + for (BluetoothDevice device : getConnectedDevices()) { + List> operations = mPendingGroupOp.get(device); + if (operations == null) { + continue; + } + + boolean isAnyPendingAddSourceOperationForDevice = operations.stream() + .anyMatch(e -> e.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE)); + + if (isAnyPendingAddSourceOperationForDevice) { + return true; + } + } + + return false; + } + private void checkForPendingGroupOpRequest(BluetoothDevice sink, int reason, int reqMsg, Object obj) { log("checkForPendingGroupOpRequest device: " + sink + ", reason: " + reason @@ -542,6 +620,17 @@ public class BassClientService extends ProfileService { (m.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE)) && (metadata.getBroadcastId() == ((BluetoothLeBroadcastMetadata) m.second).getBroadcastId())); + + if (!isAnyPendingAddSourceOperation() && mIsAssistantActive + && mPausedBroadcastSinks.isEmpty()) { + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + mIsAssistantActive = false; + mUnicastSourceStreamStatus = Optional.empty(); + + if (leAudioService != null) { + leAudioService.activeBroadcastAssistantNotification(false); + } + } } break; case BassClientStateMachine.REMOVE_BCAST_SOURCE: @@ -557,6 +646,54 @@ public class BassClientService extends ProfileService { } } + private void localNotifyReceiveStateChanged() { + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + if (leAudioService == null) { + return; + } + + boolean isAssistantActive = isAnyReceiverReceivingBroadcast(); + + if (isAssistantActive) { + /* Assistant become active */ + if (!mIsAssistantActive) { + mIsAssistantActive = true; + leAudioService.activeBroadcastAssistantNotification(true); + return; + } + } else { + /* Assistant become inactive */ + if (mIsAssistantActive && mPausedBroadcastSinks.isEmpty()) { + mIsAssistantActive = false; + mUnicastSourceStreamStatus = Optional.empty(); + leAudioService.activeBroadcastAssistantNotification(false); + + return; + } + } + } + + private void localNotifySourceAdded( + BluetoothDevice sink, BluetoothLeBroadcastReceiveState receiveState) { + if (!isLocalBroadcast(receiveState)) { + return; + } + + int broadcastId = receiveState.getBroadcastId(); + + /* Track devices bonded to local broadcast for further broadcast status handling when sink + * device is: + * - disconnecting (if no more receivers, broadcast can be stopped) + * - connecting (resynchronize if connection lost) + */ + if (mLocalBroadcastReceivers.containsKey(broadcastId)) { + mLocalBroadcastReceivers.get(broadcastId).add(sink); + } else { + mLocalBroadcastReceivers.put( + broadcastId, new HashSet(Arrays.asList(sink))); + } + } + private void setSourceGroupManaged(BluetoothDevice sink, int sourceId, boolean isGroupOp) { log("setSourceGroupManaged device: " + sink); if (isGroupOp) { @@ -580,6 +717,12 @@ public class BassClientService extends ProfileService { if (mGroupManagedSources.containsKey(sink) && mGroupManagedSources.get(sink).contains(sourceId)) { BassClientStateMachine stateMachine = getOrCreateStateMachine(sink); + if (stateMachine == null) { + Log.e(TAG, "Can't get state machine for device: " + sink); + return new Pair>( + null, null); + } + BluetoothLeBroadcastMetadata metadata = stateMachine.getCurrentBroadcastMetadata(sourceId); if (metadata != null) { @@ -675,6 +818,41 @@ public class BassClientService extends ProfileService { return isRoomAvailable; } + private Integer getSourceIdToRemove(BluetoothDevice device) { + BassClientStateMachine stateMachine = null; + + synchronized (mStateMachines) { + stateMachine = getOrCreateStateMachine(device); + } + if (stateMachine == null) { + log("stateMachine is null"); + return BassConstants.INVALID_SOURCE_ID; + } + List sources = stateMachine.getAllSources(); + if (sources.isEmpty()) { + log("sources is empty"); + return BassConstants.INVALID_SOURCE_ID; + } + + Integer sourceId = BassConstants.INVALID_SOURCE_ID; + // Select the source by checking if there is one with PA not synced + Optional receiver = + sources.stream() + .filter( + e -> + (e.getPaSyncState() + != BluetoothLeBroadcastReceiveState + .PA_SYNC_STATE_SYNCHRONIZED)) + .findAny(); + if (receiver.isPresent()) { + sourceId = receiver.get().getSourceId(); + } else { + // If all sources are synced, continue to pick the 1st source + sourceId = sources.get(0).getSourceId(); + } + return sourceId; + } + private BassClientStateMachine getOrCreateStateMachine(BluetoothDevice device) { if (device == null) { Log.e(TAG, "getOrCreateStateMachine failed: device cannot be null"); @@ -695,12 +873,51 @@ public class BassClientService extends ProfileService { stateMachine = BassObjectsFactory.getInstance() .makeStateMachine( - device, this, mStateMachinesThread.getLooper(), mFeatureFlags); - mStateMachines.put(device, stateMachine); + device, + this, + mAdapterService, + mStateMachinesThread.getLooper(), + mFeatureFlags); + if (stateMachine != null) { + mStateMachines.put(device, stateMachine); + } + return stateMachine; } } + class DialingOutTimeoutEvent implements Runnable { + Integer mBroadcastId; + + DialingOutTimeoutEvent(Integer broadcastId) { + mBroadcastId = broadcastId; + } + + @Override + public void run() { + mDialingOutTimeoutEvent = null; + + if (getBassClientService() == null) { + Log.e(TAG, "DialingOutTimeoutEvent: No Bass service"); + return; + } + + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + if (leAudioService == null) { + Log.d(TAG, "DialingOutTimeoutEvent: No available LeAudioService"); + return; + } + + sEventLogger.logd(TAG, "Broadcast timeout: " + mBroadcastId); + mLocalBroadcastReceivers.remove(mBroadcastId); + leAudioService.stopBroadcast(mBroadcastId); + } + + public boolean isScheduledForBroadcast(Integer broadcastId) { + return mBroadcastId.equals(broadcastId); + } + } + /** * Get the BassClientService instance * @@ -738,6 +955,43 @@ public class BassClientService extends ProfileService { mActiveSourceMap.remove(device); } + private void handleReconnectingAudioSharingModeDevice(BluetoothDevice device) { + /* In case of reconnecting Audio Sharing mode device */ + if (mDialingOutTimeoutEvent != null) { + for (Map.Entry> entry : + mLocalBroadcastReceivers.entrySet()) { + Integer broadcastId = entry.getKey(); + HashSet devices = entry.getValue(); + + /* If associated with any broadcast, try to remove pending timeout callback */ + if ((mDialingOutTimeoutEvent.isScheduledForBroadcast(broadcastId)) + && (devices.contains(device))) { + Log.i( + TAG, + "connectionStateChanged: reconnected previousely synced device: " + + device); + mHandler.removeCallbacks(mDialingOutTimeoutEvent); + mDialingOutTimeoutEvent = null; + break; + } + } + } + } + + private void informConnectedDeviceAboutScanOffloadStop() { + for (BluetoothDevice device : getConnectedDevices()) { + synchronized (mStateMachines) { + BassClientStateMachine stateMachine = getOrCreateStateMachine(device); + if (stateMachine == null) { + Log.w(TAG, "informConnectedDeviceAboutScanOffloadStop: Can't get state " + + "machine for device: " + device); + continue; + } + stateMachine.sendMessage(BassClientStateMachine.STOP_SCAN_OFFLOAD); + } + } + } + void handleConnectionStateChanged(BluetoothDevice device, int fromState, int toState) { mHandler.post(() -> connectionStateChanged(device, fromState, toState)); } @@ -756,7 +1010,6 @@ public class BassClientService extends ProfileService { } sEventLogger.logd( - DBG, TAG, "connectionStateChanged: fromState= " + BluetoothProfile.getConnectionStateName(fromState) @@ -772,6 +1025,8 @@ public class BassClientService extends ProfileService { log("Unbonded " + device + ". Removing state machine"); removeStateMachine(device); } + } else if (toState == BluetoothProfile.STATE_CONNECTED) { + handleReconnectingAudioSharingModeDevice(device); } } @@ -822,6 +1077,11 @@ public class BassClientService extends ProfileService { } synchronized (mStateMachines) { BassClientStateMachine stateMachine = getOrCreateStateMachine(device); + if (stateMachine == null) { + Log.e(TAG, "Can't get state machine for device: " + device); + return false; + } + stateMachine.sendMessage(BassClientStateMachine.CONNECT); } return true; @@ -843,6 +1103,11 @@ public class BassClientService extends ProfileService { } synchronized (mStateMachines) { BassClientStateMachine stateMachine = getOrCreateStateMachine(device); + if (stateMachine == null) { + Log.e(TAG, "Can't get state machine for device: " + device); + return false; + } + stateMachine.sendMessage(BassClientStateMachine.DISCONNECT); } return true; @@ -1069,7 +1334,7 @@ public class BassClientService extends ProfileService { | ((broadcastIdArray[1] & 0xff) << 8) | (broadcastIdArray[0] & 0xff)); - sEventLogger.logd(DBG, TAG, "Broadcast Source Found: Broadcast ID: " + sEventLogger.logd(TAG, "Broadcast Source Found: Broadcast ID: " + broadcastId); if (broadcastId != BassConstants.INVALID_BROADCAST_ID @@ -1088,6 +1353,7 @@ public class BassClientService extends ProfileService { public void onScanFailed(int errorCode) { Log.e(TAG, "Scan Failure:" + errorCode); + informConnectedDeviceAboutScanOffloadStop(); } }; // when starting scan, clear the previously cached broadcast scan results @@ -1113,8 +1379,21 @@ public class BassClientService extends ProfileService { .setServiceData(BassConstants.BAAS_UUID, serviceData, serviceDataMask).build()); } + + for (BluetoothDevice device : getConnectedDevices()) { + synchronized (mStateMachines) { + BassClientStateMachine stateMachine = getOrCreateStateMachine(device); + if (stateMachine == null) { + Log.w(TAG, "startSearchingForSources: Can't get state machine for " + + "device: " + device); + continue; + } + stateMachine.sendMessage(BassClientStateMachine.START_SCAN_OFFLOAD); + } + } + scanner.startScan(filters, settings, mSearchScanCallback); - sEventLogger.logd(DBG, TAG, "startSearchingForSources"); + sEventLogger.logd(TAG, "startSearchingForSources"); mCallbacks.notifySearchStarted(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); } } @@ -1140,9 +1419,10 @@ public class BassClientService extends ProfileService { mCallbacks.notifySearchStopFailed(BluetoothStatusCodes.ERROR_UNKNOWN); return; } + informConnectedDeviceAboutScanOffloadStop(); scanner.stopScan(mSearchScanCallback); mSearchScanCallback = null; - sEventLogger.logd(DBG, TAG, "stopSearchingForSources"); + sEventLogger.logd(TAG, "stopSearchingForSources"); mCallbacks.notifySearchStopped(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); } } @@ -1158,11 +1438,6 @@ public class BassClientService extends ProfileService { } void selectSource(BluetoothDevice sink, ScanResult result, boolean autoTrigger) { - if (!hasRoomForBroadcastSourceAddition(sink)) { - log("selectSource: No more slot"); - return; - } - List activeSyncedSrc = getActiveSyncedSources(sink); if (activeSyncedSrc != null && activeSyncedSrc.size() >= MAX_ACTIVE_SYNCED_SOURCES_NUM) { log("selectSource : reached max allowed active source"); @@ -1170,6 +1445,10 @@ public class BassClientService extends ProfileService { // removing the 1st synced source before proceeding to add new synchronized (mStateMachines) { BassClientStateMachine stateMachine = getOrCreateStateMachine(sink); + if (stateMachine == null) { + Log.e(TAG, "Can't get state machine for device: " + sink); + return; + } Message message = stateMachine.obtainMessage(BassClientStateMachine.REACHED_MAX_SOURCE_LIMIT); message.arg1 = syncHandle; @@ -1178,9 +1457,13 @@ public class BassClientService extends ProfileService { } synchronized (mStateMachines) { - sEventLogger.logd(DBG, TAG, "Select Broadcast Source"); + sEventLogger.logd(TAG, "Select Broadcast Source"); BassClientStateMachine stateMachine = getOrCreateStateMachine(sink); + if (stateMachine == null) { + Log.e(TAG, "Can't get state machine for device: " + sink); + return; + } Message message = stateMachine.obtainMessage( BassClientStateMachine.SELECT_BCAST_SOURCE); message.obj = result; @@ -1195,12 +1478,19 @@ public class BassClientService extends ProfileService { * @param sink Broadcast Sink to which the Broadcast Source should be added * @param sourceMetadata Broadcast Source metadata to be added to the Broadcast Sink * @param isGroupOp set to true If Application wants to perform this operation for all - * coordinated set members, False otherwise + * coordinated set members, False otherwise */ - public void addSource(BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata, + public void addSource( + BluetoothDevice sink, + BluetoothLeBroadcastMetadata sourceMetadata, boolean isGroupOp) { - log("addSource: device: " + sink + " sourceMetadata" + sourceMetadata - + " isGroupOp: " + isGroupOp); + log( + "addSource: device: " + + sink + + " sourceMetadata" + + sourceMetadata + + " isGroupOp: " + + isGroupOp); List devices = getTargetDeviceList(sink, isGroupOp); // Don't coordinate it as a group if there's no group or there is one device only @@ -1210,15 +1500,15 @@ public class BassClientService extends ProfileService { if (sourceMetadata == null) { log("addSource: Error bad parameter: sourceMetadata cannot be null"); - for (BluetoothDevice device : devices) { - mCallbacks.notifySourceAddFailed(device, sourceMetadata, - BluetoothStatusCodes.ERROR_BAD_PARAMETERS); - } return; } - /* Store metadata for sink device */ - mBroadcastMetadataMap.put(sink, sourceMetadata); + if (!isAllowedToAddSource()) { + Log.d(TAG, "Add source to pending list"); + mPendingAddSources.push(new AddSourceData(sink, sourceMetadata, isGroupOp)); + + return; + } byte[] code = sourceMetadata.getBroadcastCode(); for (BluetoothDevice device : devices) { @@ -1240,8 +1530,41 @@ public class BassClientService extends ProfileService { } if (!hasRoomForBroadcastSourceAddition(device)) { log("addSource: device has no room"); - mCallbacks.notifySourceAddFailed(device, sourceMetadata, - BluetoothStatusCodes.ERROR_REMOTE_NOT_ENOUGH_RESOURCES); + Integer sourceId = getSourceIdToRemove(device); + if (sourceId != BassConstants.INVALID_SOURCE_ID) { + sEventLogger.logd( + TAG, + "Switch Broadcast Source: device: " + + device + + ", old SourceId: " + + sourceId + + ", new SourceMetadata: " + + sourceMetadata); + + // new source will be added once the existing source got removed + if (isGroupOp) { + // mark group op for both remove and add source + // so setSourceGroupManaged will be updated accordingly in callbacks + enqueueSourceGroupOp( + device, BassClientStateMachine.REMOVE_BCAST_SOURCE, sourceId); + enqueueSourceGroupOp( + device, BassClientStateMachine.ADD_BCAST_SOURCE, sourceMetadata); + } + + /* Store metadata for sink device */ + mBroadcastMetadataMap.put(device, sourceMetadata); + + Message message = + stateMachine.obtainMessage(BassClientStateMachine.SWITCH_BCAST_SOURCE); + message.obj = sourceMetadata; + message.arg1 = sourceId; + stateMachine.sendMessage(message); + } else { + mCallbacks.notifySourceAddFailed( + device, + sourceMetadata, + BluetoothStatusCodes.ERROR_REMOTE_NOT_ENOUGH_RESOURCES); + } continue; } if (!isValidBroadcastSourceAddition(device, sourceMetadata)) { @@ -1260,16 +1583,18 @@ public class BassClientService extends ProfileService { } } + /* Store metadata for sink device */ + mBroadcastMetadataMap.put(device, sourceMetadata); + if (isGroupOp) { enqueueSourceGroupOp(device, BassClientStateMachine.ADD_BCAST_SOURCE, sourceMetadata); } sEventLogger.logd( - DBG, TAG, "Add Broadcast Source: device: " - + sink + + device + ", sourceMetadata: " + sourceMetadata + ", isGroupOp: " @@ -1279,7 +1604,7 @@ public class BassClientService extends ProfileService { message.obj = sourceMetadata; stateMachine.sendMessage(message); if (code != null && code.length != 0) { - sEventLogger.logd(DBG, TAG, "Set Broadcast Code (Add Source context)"); + sEventLogger.logd(TAG, "Set Broadcast Code (Add Source context)"); message = stateMachine.obtainMessage(BassClientStateMachine.SET_BCAST_CODE); message.obj = sourceMetadata; @@ -1292,13 +1617,12 @@ public class BassClientService extends ProfileService { /** * Modify the Broadcast Source information on a Broadcast Sink * - * @param sink representing the Broadcast Sink to which the Broadcast - * Source should be updated + * @param sink representing the Broadcast Sink to which the Broadcast Source should be updated * @param sourceId source ID as delivered in onSourceAdded * @param updatedMetadata updated Broadcast Source metadata to be updated on the Broadcast Sink */ - public void modifySource(BluetoothDevice sink, int sourceId, - BluetoothLeBroadcastMetadata updatedMetadata) { + public void modifySource( + BluetoothDevice sink, int sourceId, BluetoothLeBroadcastMetadata updatedMetadata) { log("modifySource: device: " + sink + " sourceId " + sourceId); Map devices = getGroupManagedDeviceSources(sink, sourceId).second; @@ -1352,10 +1676,9 @@ public class BassClientService extends ProfileService { } sEventLogger.logd( - DBG, TAG, "Modify Broadcast Source: device: " - + sink + + device + ", sourceId: " + sourceId + ", updatedMetadata: " @@ -1368,7 +1691,7 @@ public class BassClientService extends ProfileService { message.obj = updatedMetadata; stateMachine.sendMessage(message); if (code != null && code.length != 0) { - sEventLogger.logd(DBG, TAG, "Set Broadcast Code (Modify Source context)"); + sEventLogger.logd(TAG, "Set Broadcast Code (Modify Source context)"); message = stateMachine.obtainMessage(BassClientStateMachine.SET_BCAST_CODE); message.obj = updatedMetadata; message.arg1 = BassClientStateMachine.ARGTYPE_METADATA; @@ -1417,17 +1740,13 @@ public class BassClientService extends ProfileService { continue; } - BluetoothLeBroadcastReceiveState recvState = - stateMachine.getBroadcastReceiveStateForSourceId(sourceId); BluetoothLeBroadcastMetadata metaData = stateMachine.getCurrentBroadcastMetadata(sourceId); - if (metaData != null && recvState != null && recvState.getPaSyncState() - == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) { + if (metaData != null && stateMachine.isSyncedToTheSource(sourceId)) { sEventLogger.logd( - DBG, TAG, "Remove Broadcast Source(Force lost PA sync): device: " - + sink + + device + ", sourceId: " + sourceId); @@ -1444,9 +1763,8 @@ public class BassClientService extends ProfileService { } sEventLogger.logd( - DBG, TAG, - "Remove Broadcast Source: device: " + sink + ", sourceId: " + sourceId); + "Remove Broadcast Source: device: " + device + ", sourceId: " + sourceId); Message message = stateMachine.obtainMessage(BassClientStateMachine.REMOVE_BCAST_SOURCE); @@ -1504,23 +1822,36 @@ public class BassClientService extends ProfileService { return stateMachine.getMaximumSourceCapacity(); } + private boolean isLocalBroadcast(int sourceAdvertisingSid) { + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + if (leAudioService == null) { + return false; + } + + boolean wasFound = + leAudioService.getAllBroadcastMetadata().stream() + .anyMatch( + meta -> { + return meta.getSourceAdvertisingSid() == sourceAdvertisingSid; + }); + log("isLocalBroadcast=" + wasFound); + return wasFound; + } + boolean isLocalBroadcast(BluetoothLeBroadcastMetadata metaData) { if (metaData == null) { return false; } - LeAudioService leAudioService = mServiceFactory.getLeAudioService(); - if (leAudioService == null) { + return isLocalBroadcast(metaData.getSourceAdvertisingSid()); + } + + boolean isLocalBroadcast(BluetoothLeBroadcastReceiveState receiveState) { + if (receiveState == null) { return false; } - boolean wasFound = leAudioService.getAllBroadcastMetadata() - .stream() - .anyMatch(meta -> { - return meta.getSourceAdvertisingSid() == metaData.getSourceAdvertisingSid(); - }); - log("isLocalBroadcast=" + wasFound); - return wasFound; + return isLocalBroadcast(receiveState.getSourceAdvertisingSid()); } static void log(String msg) { @@ -1529,51 +1860,271 @@ public class BassClientService extends ProfileService { } } - private void stopLocalSourceReceivers(int broadcastId, boolean store) { + private void stopSourceReceivers(int broadcastId, boolean store) { if (DBG) { - Log.d(TAG, "stopLocalSourceReceivers()"); + Log.d(TAG, "stopSourceReceivers(), broadcastId: " + broadcastId + ", store: " + store); } if (store && !mPausedBroadcastSinks.isEmpty()) { - Log.w(TAG, "stopLocalSourceReceivers(), paused broadcast sinks are replaced"); + Log.w(TAG, "stopSourceReceivers(), paused broadcast sinks are replaced"); + sEventLogger.logd(TAG, "Clear broadcast sinks paused cache"); mPausedBroadcastSinks.clear(); } + Map sourcesToRemove = new HashMap<>(); + for (BluetoothDevice device : getConnectedDevices()) { for (BluetoothLeBroadcastReceiveState receiveState : getAllSources(device)) { - /* Check if local/last broadcast is the synced one */ - if (receiveState.getBroadcastId() != broadcastId) continue; - - removeSource(device, receiveState.getSourceId()); + /* Check if local/last broadcast is the synced one. Invalid broadcast ID means + * that all receivers should be considered. + */ + if ((broadcastId != BassConstants.INVALID_BROADCAST_ID) + && (receiveState.getBroadcastId() != broadcastId)) { + continue; + } if (store && !mPausedBroadcastSinks.contains(device)) { + sEventLogger.logd(TAG, "Add broadcast sink to paused cache: " + device); mPausedBroadcastSinks.add(device); } + + sourcesToRemove.put(device, receiveState.getSourceId()); + } + } + + for (Map.Entry entry : sourcesToRemove.entrySet()) { + removeSource(entry.getKey(), entry.getValue()); + } + } + + private boolean isAllowedToAddSource() { + if (mFeatureFlags.leaudioBroadcastAudioHandoverPolicies()) { + /* Check if should wait for status update */ + if (mUnicastSourceStreamStatus.isEmpty()) { + /* Assistant was not active, inform about activation */ + if (!mIsAssistantActive) { + mIsAssistantActive = true; + + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + if (leAudioService != null) { + leAudioService.activeBroadcastAssistantNotification(true); + } + + } + + return false; + } + + return mUnicastSourceStreamStatus.get() == STATUS_LOCAL_STREAM_SUSPENDED; + } + + /* Don't block if this is not a handover case */ + return true; + } + + private boolean isAnyReceiverReceivingBroadcast() { + for (BluetoothDevice device : getConnectedDevices()) { + for (BluetoothLeBroadcastReceiveState receiveState : getAllSources(device)) { + for (int i = 0; i < receiveState.getNumSubgroups(); i++) { + Long syncState = receiveState.getBisSyncState().get(i); + + /* Not synced to BIS of failed to sync to BIG */ + if (syncState == 0x00000000 || syncState == 0xFFFFFFFF) { + continue; + } + + return true; + } + } + } + + return false; + } + + /** Return true if there is any non primary device receiving broadcast */ + private boolean isAudioSharingModeOn(Integer broadcastId) { + if (mLocalBroadcastReceivers == null) { + Log.w(TAG, "isAudioSharingModeOn: Local Broadcaster Receivers is not initialized"); + return false; + } + + HashSet devices = mLocalBroadcastReceivers.get(broadcastId); + if (devices == null) { + Log.w(TAG, "isAudioSharingModeOn: No receivers receiving broadcast: " + broadcastId); + return false; + } + + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + if (leAudioService == null) { + Log.d(TAG, "isAudioSharingModeOn: No available LeAudioService"); + return false; + } + + return devices.stream().anyMatch(d -> !leAudioService.isPrimaryDevice(d)); + } + + /** Handle disconnection of potential broadcast sinks */ + public void handleDeviceDisconnection(BluetoothDevice sink, boolean isIntentional) { + LeAudioService leAudioService = mServiceFactory.getLeAudioService(); + if (leAudioService == null) { + Log.d(TAG, "BluetoothLeBroadcastReceiveState: No available LeAudioService"); + return; + } + + for (Map.Entry> entry : + mLocalBroadcastReceivers.entrySet()) { + Integer broadcastId = entry.getKey(); + HashSet devices = entry.getValue(); + + /* If somehow there is a non playing broadcast, let's remove it */ + if (!leAudioService.isPlaying(broadcastId)) { + Log.w(TAG, "Non playing broadcast remove from receivers list"); + mLocalBroadcastReceivers.remove(broadcastId); + continue; + } + + if (isIntentional) { + /* Check if disconnecting device participated in this broadcast reception */ + if (!devices.remove(sink)) { + continue; + } + + mBroadcastMetadataMap.remove(sink); + + /* Check if there is any other primary device receiving this broadcast */ + if (devices.stream() + .anyMatch( + d -> + ((getConnectionState(d) == BluetoothProfile.STATE_CONNECTED) + && leAudioService.isPrimaryDevice(d)))) { + continue; + } + + Log.d( + TAG, + "handleIntendedDeviceDisconnection: No more potential broadcast " + + "(broadcast ID: " + + broadcastId + + ") receivers - stopping broadcast"); + mLocalBroadcastReceivers.remove(broadcastId); + leAudioService.stopBroadcast(broadcastId); + } else { + /* Unintentional disconnection of primary device in private broadcast mode */ + if (!isAudioSharingModeOn(broadcastId) + && !devices.stream() + .anyMatch( + d -> + !d.equals(sink) + && (getConnectionState(d) + == BluetoothProfile + .STATE_CONNECTED))) { + mLocalBroadcastReceivers.remove(broadcastId); + leAudioService.stopBroadcast(broadcastId); + continue; + } + + /* Unintentional disconnection of primary/secondary in broadcast sharing mode */ + if (devices.stream() + .anyMatch( + d -> + !d.equals(sink) + && (getConnectionState(d) + == BluetoothProfile.STATE_CONNECTED))) { + continue; + } else { + Log.d( + TAG, + "handleUnintendedDeviceDisconnection: No more potential broadcast " + + "(broadcast ID: " + + broadcastId + + ") receivers - stopping broadcast"); + mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(broadcastId); + mHandler.postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS); + } } } } /** Request receivers to suspend broadcast sources synchronization */ public void suspendReceiversSourceSynchronization(int broadcastId) { - sEventLogger.logd(DBG, TAG, "Suspend receivers source synchronization: " + broadcastId); - stopLocalSourceReceivers(broadcastId, true); + sEventLogger.logd(TAG, "Suspend receivers source synchronization: " + broadcastId); + stopSourceReceivers(broadcastId, true); + } + + /** Request all receivers to suspend broadcast sources synchronization */ + public void suspendAllReceiversSourceSynchronization() { + sEventLogger.logd(TAG, "Suspend all receivers source synchronization"); + stopSourceReceivers(BassConstants.INVALID_BROADCAST_ID, true); } /** Request receivers to stop broadcast sources synchronization and remove them */ public void stopReceiversSourceSynchronization(int broadcastId) { - sEventLogger.logd(DBG, TAG, "Stop receivers source synchronization: " + broadcastId); - stopLocalSourceReceivers(broadcastId, false); + sEventLogger.logd(TAG, "Stop receivers source synchronization: " + broadcastId); + stopSourceReceivers(broadcastId, false); } /** Request receivers to resume broadcast source synchronization */ - public void resumeReceiversSourceSynchronization(int broadcastId) { - sEventLogger.logd(DBG, TAG, "Resume receivers source synchronization: " + broadcastId); + public void resumeReceiversSourceSynchronization() { + sEventLogger.logd(TAG, "Resume receivers source synchronization"); while (!mPausedBroadcastSinks.isEmpty()) { BluetoothDevice sink = mPausedBroadcastSinks.remove(); + sEventLogger.logd(TAG, "Remove broadcast sink from paused cache: " + sink); BluetoothLeBroadcastMetadata metadata = mBroadcastMetadataMap.get(sink); - addSource(sink, metadata, true); + if (metadata != null) { + addSource(sink, metadata, false); + } + } + } + + /** Handle Unicast source stream status change */ + public void handleUnicastSourceStreamStatusChange(int status) { + mUnicastSourceStreamStatus = Optional.of(status); + + if (status == STATUS_LOCAL_STREAM_REQUESTED) { + if (isAnyReceiverReceivingBroadcast()) { + suspendAllReceiversSourceSynchronization(); + } + } else if (status == STATUS_LOCAL_STREAM_SUSPENDED) { + /* Resume paused receivers if there are some */ + if (!mPausedBroadcastSinks.isEmpty()) { + resumeReceiversSourceSynchronization(); + } + + /* Add pending sources if there are some */ + while (!mPendingAddSources.isEmpty()) { + AddSourceData addSourceData = mPendingAddSources.pop(); + + addSource( + addSourceData.mSink, + addSourceData.mSourceMetadata, + addSourceData.mIsGroupOp); + } + } else if (status == STATUS_LOCAL_STREAM_STREAMING) { + Log.d(TAG, "Ignore STREAMING source status"); + } + } + + /** Handle broadcast state changed */ + public void notifyBroadcastStateChanged(int state, int broadcastId) { + switch (state) { + case BROADCAST_STATE_STOPPED: + if (mLocalBroadcastReceivers == null) { + Log.e(TAG, "notifyBroadcastStateChanged: mLocalBroadcastReceivers is invalid"); + break; + } + + if (mLocalBroadcastReceivers.remove(broadcastId) != null) { + sEventLogger.logd(TAG, "Broadcast ID: " + broadcastId + ", stopped"); + } + break; + case BROADCAST_STATE_CONFIGURING: + case BROADCAST_STATE_PAUSED: + case BROADCAST_STATE_STOPPING: + case BROADCAST_STATE_STREAMING: + default: + break; } } @@ -1729,28 +2280,27 @@ public class BassClientService extends ProfileService { } void notifySearchStarted(int reason) { - sEventLogger.logd(DBG, TAG, "notifySearchStarted: " + ", reason: " + reason); + sEventLogger.logd(TAG, "notifySearchStarted: reason: " + reason); obtainMessage(MSG_SEARCH_STARTED, reason, 0).sendToTarget(); } void notifySearchStartFailed(int reason) { - sEventLogger.loge(TAG, "notifySearchStartFailed: " + ", reason: " + reason); + sEventLogger.loge(TAG, "notifySearchStartFailed: reason: " + reason); obtainMessage(MSG_SEARCH_STARTED_FAILED, reason, 0).sendToTarget(); } void notifySearchStopped(int reason) { - sEventLogger.logd(DBG, TAG, "notifySearchStopped: " + ", reason: " + reason); + sEventLogger.logd(TAG, "notifySearchStopped: reason: " + reason); obtainMessage(MSG_SEARCH_STOPPED, reason, 0).sendToTarget(); } void notifySearchStopFailed(int reason) { - sEventLogger.loge(TAG, "notifySearchStopFailed: " + ", reason: " + reason); + sEventLogger.loge(TAG, "notifySearchStopFailed: reason: " + reason); obtainMessage(MSG_SEARCH_STOPPED_FAILED, reason, 0).sendToTarget(); } void notifySourceFound(BluetoothLeBroadcastMetadata source) { sEventLogger.logd( - DBG, TAG, "invokeCallback: MSG_SOURCE_FOUND" + ", source: " @@ -1768,11 +2318,12 @@ public class BassClientService extends ProfileService { void notifySourceAdded(BluetoothDevice sink, BluetoothLeBroadcastReceiveState recvState, int reason) { + sService.localNotifySourceAdded(sink, recvState); + sEventLogger.logd( - DBG, TAG, "notifySourceAdded: " - + ", source: " + + "source: " + sink + ", sourceId: " + recvState.getSourceId() @@ -1793,10 +2344,9 @@ public class BassClientService extends ProfileService { void notifySourceModified(BluetoothDevice sink, int sourceId, int reason) { sEventLogger.logd( - DBG, TAG, "notifySourceModified: " - + ", source: " + + "source: " + sink + ", sourceId: " + sourceId @@ -1814,10 +2364,9 @@ public class BassClientService extends ProfileService { void notifySourceRemoved(BluetoothDevice sink, int sourceId, int reason) { sEventLogger.logd( - DBG, TAG, "notifySourceRemoved: " - + ", source: " + + "source: " + sink + ", sourceId: " + sourceId @@ -1842,6 +2391,9 @@ public class BassClientService extends ProfileService { void notifyReceiveStateChanged(BluetoothDevice sink, int sourceId, BluetoothLeBroadcastReceiveState state) { ObjParams param = new ObjParams(sink, state); + + sService.localNotifyReceiveStateChanged(); + String subgroupState = " / SUB GROUPS: "; for (int i = 0; i < state.getNumSubgroups(); i++) { subgroupState += "IDX: " + i + ", SYNC: " + state.getBisSyncState().get(i); @@ -1850,7 +2402,7 @@ public class BassClientService extends ProfileService { sEventLogger.logd( TAG, "notifyReceiveStateChanged: " - + ", source: " + + "source: " + sink + ", state: SRC ID: " + state.getSourceId() @@ -1873,7 +2425,7 @@ public class BassClientService extends ProfileService { } void notifySourceLost(int broadcastId) { - sEventLogger.logd(TAG, "notifySourceLost: " + ", broadcastId: " + broadcastId); + sEventLogger.logd(TAG, "notifySourceLost: broadcastId: " + broadcastId); obtainMessage(MSG_SOURCE_LOST, 0, broadcastId).sendToTarget(); } } diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java index 0930a99a8e4b5e673197128bc7b020f2f8fcf23b..890f72d061f8cb8446d959d5d6f02ce3352fd0e8 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java @@ -19,7 +19,6 @@ package com.android.bluetooth.bass_client; import static android.Manifest.permission.BLUETOOTH_CONNECT; import android.annotation.Nullable; -import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCallback; @@ -38,7 +37,6 @@ import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUtils; import android.bluetooth.BluetoothUtils.TypeValueEntry; import android.bluetooth.le.PeriodicAdvertisingCallback; -import android.bluetooth.le.PeriodicAdvertisingManager; import android.bluetooth.le.PeriodicAdvertisingReport; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; @@ -49,11 +47,12 @@ import android.os.Message; import android.os.ParcelUuid; import android.provider.DeviceConfig; import android.util.Log; +import android.util.Pair; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.Utils; +import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; -import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.flags.FeatureFlags; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.State; @@ -106,6 +105,7 @@ public class BassClientStateMachine extends StateMachine { static final int PSYNC_ACTIVE_TIMEOUT = 14; static final int CONNECT_TIMEOUT = 15; static final int REACHED_MAX_SOURCE_LIMIT = 16; + static final int SWITCH_BCAST_SOURCE = 17; // NOTE: the value is not "final" - it is modified in the unit tests @VisibleForTesting @@ -129,6 +129,8 @@ public class BassClientStateMachine extends StateMachine { private final Connecting mConnecting = new Connecting(); private final ConnectedProcessing mConnectedProcessing = new ConnectedProcessing(); private final FeatureFlags mFeatureFlags; + private final List> mSourceSyncRequestsQueue = + new ArrayList>(); @VisibleForTesting final List mBroadcastCharacteristics = @@ -144,6 +146,7 @@ public class BassClientStateMachine extends StateMachine { boolean mDiscoveryInitiated = false; @VisibleForTesting BassClientService mService; + AdapterService mAdapterService; @VisibleForTesting BluetoothGattCharacteristic mBroadcastScanControlPoint; private final Map mFirstTimeBisDiscoveryMap; @@ -151,9 +154,6 @@ public class BassClientStateMachine extends StateMachine { private ScanResult mScanRes = null; @VisibleForTesting int mNumOfBroadcastReceiverStates = 0; - private BluetoothAdapter mBluetoothAdapter = - BluetoothAdapter.getDefaultAdapter(); - private ServiceFactory mFactory = new ServiceFactory(); @VisibleForTesting int mPendingOperation = -1; @VisibleForTesting @@ -164,8 +164,6 @@ public class BassClientStateMachine extends StateMachine { @VisibleForTesting boolean mSetBroadcastCodePending = false; private final Map mPendingRemove = new HashMap(); - // Psync and PAST interfaces - private PeriodicAdvertisingManager mPeriodicAdvManager; @VisibleForTesting boolean mAutoTriggered = false; private boolean mDefNoPAS = false; @@ -181,16 +179,19 @@ public class BassClientStateMachine extends StateMachine { BluetoothGattCallback mGattCallback = null; @VisibleForTesting PeriodicAdvertisingCallback mLocalPeriodicAdvCallback = new PACallback(); int mMaxSingleAttributeWriteValueLen = 0; + @VisibleForTesting BluetoothLeBroadcastMetadata mPendingSourceToSwitch = null; BassClientStateMachine( BluetoothDevice device, BassClientService svc, + AdapterService adapterService, Looper looper, int connectTimeoutMs, FeatureFlags featureFlags) { super(TAG + "(" + device.toString() + ")", looper); mDevice = device; mService = svc; + mAdapterService = adapterService; mConnectTimeoutMs = connectTimeoutMs; mFeatureFlags = Objects.requireNonNull(featureFlags, "Feature Flags cannot be null"); addState(mDisconnected); @@ -198,11 +199,6 @@ public class BassClientStateMachine extends StateMachine { addState(mConnecting); addState(mConnectedProcessing); setInitialState(mDisconnected); - // PSYNC and PAST instances - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - if (mBluetoothAdapter != null) { - mPeriodicAdvManager = mBluetoothAdapter.getPeriodicAdvertisingManager(); - } mFirstTimeBisDiscoveryMap = new HashMap(); long token = Binder.clearCallingIdentity(); mIsAllowedList = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, @@ -217,12 +213,25 @@ public class BassClientStateMachine extends StateMachine { static BassClientStateMachine make( BluetoothDevice device, BassClientService svc, + AdapterService adapterService, Looper looper, FeatureFlags featureFlags) { Log.d(TAG, "make for device " + device); + + if (!BassClientPeriodicAdvertisingManager + .initializePeriodicAdvertisingManagerOnDefaultAdapter()) { + Log.e(TAG, "Failed to initialize Periodic Advertising Manager on Default Adapter"); + return null; + } + BassClientStateMachine BassclientSm = new BassClientStateMachine( - device, svc, looper, BassConstants.CONNECT_TIMEOUT_MS, featureFlags); + device, + svc, + adapterService, + looper, + BassConstants.CONNECT_TIMEOUT_MS, + featureFlags); BassclientSm.start(); return BassclientSm; } @@ -257,9 +266,11 @@ public class BassClientStateMachine extends StateMachine { mPendingSourceId = -1; mPendingMetadata = null; mPendingSourceToAdd = null; + mPendingSourceToSwitch = null; mCurrentMetadata.clear(); mPendingRemove.clear(); mPeriodicAdvCallbacksMap.clear(); + mSourceSyncRequestsQueue.clear(); } Boolean hasPendingSourceOperation() { @@ -318,6 +329,19 @@ public class BassClientStateMachine extends StateMachine { return null; } + boolean isSyncedToTheSource(int sourceId) { + BluetoothLeBroadcastReceiveState recvState = getBroadcastReceiveStateForSourceId(sourceId); + + return recvState != null + && (recvState.getPaSyncState() + == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED + || recvState.getBisSyncState().stream() + .anyMatch( + bitmap -> { + return bitmap != 0; + })); + } + void parseBaseData(BluetoothDevice device, int syncHandle, byte[] serviceData) { log("parseBaseData" + Arrays.toString(serviceData)); BaseData base = BaseData.parseBaseData(serviceData); @@ -424,8 +448,8 @@ public class BassClientStateMachine extends StateMachine { // null if no name present String broadcastName = checkAndParseBroadcastName(scanRecord); - // Avoid duplicated sync requests for the same broadcast BIG - if (isDuplicatedSyncRequest(broadcastId)) { + // Avoid duplicated sync request if the same broadcast BIG is synced + if (isSourceSynced(broadcastId)) { log("Skip duplicated sync request to broadcast id: " + broadcastId); return false; } @@ -435,13 +459,17 @@ public class BassClientStateMachine extends StateMachine { int tempHandle = BassConstants.INVALID_SYNC_HANDLE; mPeriodicAdvCallbacksMap.put(tempHandle, paCb); try { - BluetoothMethodProxy.getInstance().periodicAdvertisingManagerRegisterSync( - mPeriodicAdvManager, scanRes, 0, BassConstants.PSYNC_TIMEOUT, - paCb, null); + BluetoothMethodProxy.getInstance() + .periodicAdvertisingManagerRegisterSync( + BassClientPeriodicAdvertisingManager + .getPeriodicAdvertisingManager(), + scanRes, + 0, + BassConstants.PSYNC_TIMEOUT, + paCb, + null); } catch (IllegalArgumentException ex) { Log.w(TAG, "registerSync:IllegalArgumentException"); - Message message = obtainMessage(STOP_SCAN_OFFLOAD); - sendMessage(message); mPeriodicAdvCallbacksMap.remove(tempHandle); return false; } @@ -459,22 +487,18 @@ public class BassClientStateMachine extends StateMachine { return true; } - private boolean isDuplicatedSyncRequest(int broadcastId) { - // Either there is active sync to the same broadcast id or pending operation - // This is required because selectSource can be triggered from both scanning(user) - // and adding inactive source(auto) + private boolean isSourceSynced(int broadcastId) { List activeSyncedSrc = mService.getActiveSyncedSources(mDevice); - if ((mPendingSourceToAdd != null && broadcastId == mPendingSourceToAdd.getBroadcastId()) - || (activeSyncedSrc != null - && activeSyncedSrc.contains( - mService.getSyncHandleForBroadcastId(broadcastId)))) { - return true; - } - return false; + return (activeSyncedSrc != null + && activeSyncedSrc.contains(mService.getSyncHandleForBroadcastId(broadcastId))); } private void cancelActiveSync(Integer syncHandle) { log("cancelActiveSync: syncHandle = " + syncHandle); + if (syncHandle == null) { + // clean up the pending sync request if syncHandle is null + mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); + } List activeSyncedSrc = mService.getActiveSyncedSources(mDevice); /* Stop sync if there is some running */ @@ -495,9 +519,6 @@ public class BassClientStateMachine extends StateMachine { // all sources are removed, clean up removeMessages(PSYNC_ACTIVE_TIMEOUT); mService.clearNotifiedFlags(); - // trigger scan stop here - Message message = obtainMessage(STOP_SCAN_OFFLOAD); - sendMessage(message); } } } @@ -506,11 +527,16 @@ public class BassClientStateMachine extends StateMachine { if (syncHandle != BassConstants.INVALID_SYNC_HANDLE && mPeriodicAdvCallbacksMap.containsKey(syncHandle)) { try { - mPeriodicAdvManager.unregisterSync(mPeriodicAdvCallbacksMap.get(syncHandle)); + BluetoothMethodProxy.getInstance() + .periodicAdvertisingManagerUnregisterSync( + BassClientPeriodicAdvertisingManager + .getPeriodicAdvertisingManager(), + mPeriodicAdvCallbacksMap.get(syncHandle)); } catch (IllegalArgumentException ex) { Log.w(TAG, "unregisterSync:IllegalArgumentException"); return false; } + mPeriodicAdvCallbacksMap.remove(syncHandle); } else { log("calling unregisterSync, not found syncHandle: " + syncHandle); } @@ -586,9 +612,11 @@ public class BassClientStateMachine extends StateMachine { } metaData.setSourceDevice(device, device.getAddressType()); byte[] arrayPresentationDelay = baseData.getLevelOne().presentationDelay; - int presentationDelay = (int) ((arrayPresentationDelay[2] & 0xff) << 16 - | (arrayPresentationDelay[1] & 0xff) - | (arrayPresentationDelay[0] & 0xff)); + int presentationDelay = + (int) + ((arrayPresentationDelay[2] & 0xff) << 16 + | (arrayPresentationDelay[1] & 0xff) << 8 + | (arrayPresentationDelay[0] & 0xff)); metaData.setPresentationDelayMicros(presentationDelay); PeriodicAdvertisementResult result = mService.getPeriodicAdvertisementResult( @@ -665,12 +693,19 @@ public class BassClientStateMachine extends StateMachine { & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS); log("Initiate PAST for: " + mDevice + ", syncHandle: " + syncHandle + "serviceData" + serviceData); - BluetoothMethodProxy.getInstance().periodicAdvertisingManagerTransferSync( - mPeriodicAdvManager, mDevice, serviceData, syncHandle); + BluetoothMethodProxy.getInstance() + .periodicAdvertisingManagerTransferSync( + BassClientPeriodicAdvertisingManager + .getPeriodicAdvertisingManager(), + mDevice, + serviceData, + syncHandle); } } else { - if (mService.isLocalBroadcast(mPendingMetadata)) { - int advHandle = mPendingMetadata.getSourceAdvertisingSid(); + BluetoothLeBroadcastMetadata currentMetadata = + getCurrentBroadcastMetadata(recvState.getSourceId()); + if (mService.isLocalBroadcast(currentMetadata)) { + int advHandle = currentMetadata.getSourceAdvertisingSid(); serviceData = 0x000000FF & recvState.getSourceId(); serviceData = serviceData << 8; // Address we set in the Source Address can differ from the address in the air @@ -679,17 +714,18 @@ public class BassClientStateMachine extends StateMachine { log("Initiate local broadcast PAST for: " + mDevice + ", advSID/Handle: " + advHandle + ", serviceData: " + serviceData); - BluetoothMethodProxy.getInstance().periodicAdvertisingManagerTransferSetInfo( - mPeriodicAdvManager, mDevice, serviceData, advHandle, - mLocalPeriodicAdvCallback); + BluetoothMethodProxy.getInstance() + .periodicAdvertisingManagerTransferSetInfo( + BassClientPeriodicAdvertisingManager + .getPeriodicAdvertisingManager(), + mDevice, + serviceData, + advHandle, + mLocalPeriodicAdvCallback); } else { Log.e(TAG, "There is no valid sync handle for this Source"); } } - } else if (state == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED - || state == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_NO_PAST) { - Message message = obtainMessage(STOP_SCAN_OFFLOAD); - sendMessage(message); } } @@ -722,25 +758,28 @@ public class BassClientStateMachine extends StateMachine { } log("processBroadcastReceiverState: receiverState length: " + receiverState.length); - BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothLeBroadcastReceiveState recvState = null; if (receiverState.length == 0 || isEmpty(Arrays.copyOfRange(receiverState, 1, receiverState.length - 1))) { - String emptyBluetoothDevice = "00:00:00:00:00:00"; + byte[] emptyBluetoothDeviceAddress = Utils.getBytesFromAddress("00:00:00:00:00:00"); if (mPendingOperation == REMOVE_BCAST_SOURCE) { - recvState = new BluetoothLeBroadcastReceiveState(mPendingSourceId, - BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType - btAdapter.getRemoteDevice(emptyBluetoothDevice), // sourceDevice - 0, // sourceAdvertisingSid - 0, // broadcastId - BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState - // bigEncryptionState - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null, // badCode - 0, // numSubgroups - Arrays.asList(new Long[0]), // bisSyncState - Arrays.asList(new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata - ); + recvState = + new BluetoothLeBroadcastReceiveState( + mPendingSourceId, + BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType + mAdapterService.getDeviceFromByte( + emptyBluetoothDeviceAddress), // sourceDev + 0, // sourceAdvertisingSid + 0, // broadcastId + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState + // bigEncryptionState + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, // badCode + 0, // numSubgroups + Arrays.asList(new Long[0]), // bisSyncState + Arrays.asList( + new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata + ); } else if (receiverState.length == 0) { if (mBluetoothLeBroadcastReceiveStates != null) { mNextSourceId = (byte) mBluetoothLeBroadcastReceiveStates.size(); @@ -750,19 +789,23 @@ public class BassClientStateMachine extends StateMachine { return null; } mNextSourceId++; - recvState = new BluetoothLeBroadcastReceiveState(mNextSourceId, - BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType - btAdapter.getRemoteDevice(emptyBluetoothDevice), // sourceDevice - 0, // sourceAdvertisingSid - 0, // broadcastId - BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState - // bigEncryptionState - BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, - null, // badCode - 0, // numSubgroups - Arrays.asList(new Long[0]), // bisSyncState - Arrays.asList(new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata - ); + recvState = + new BluetoothLeBroadcastReceiveState( + mNextSourceId, + BluetoothDevice.ADDRESS_TYPE_PUBLIC, // sourceAddressType + mAdapterService.getDeviceFromByte( + emptyBluetoothDeviceAddress), // sourceDev + 0, // sourceAdvertisingSid + 0, // broadcastId + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, // paSyncState + // bigEncryptionState + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, // badCode + 0, // numSubgroups + Arrays.asList(new Long[0]), // bisSyncState + Arrays.asList( + new BluetoothLeAudioContentMetadata[0]) // subgroupMetadata + ); } } else { byte paSyncState = receiverState[BassConstants.BCAST_RCVR_STATE_PA_SYNC_IDX]; @@ -823,9 +866,7 @@ public class BassClientStateMachine extends StateMachine { byte sourceAddressType = receiverState[BassConstants .BCAST_RCVR_STATE_SRC_ADDR_TYPE_IDX]; BassUtils.reverse(sourceAddress); - String address = Utils.getAddressStringFromByte(sourceAddress); - BluetoothDevice device = btAdapter.getRemoteLeDevice( - address, sourceAddressType); + BluetoothDevice device = mAdapterService.getDeviceFromByte(sourceAddress); byte sourceAdvSid = receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ADV_SID_IDX]; recvState = new BluetoothLeBroadcastReceiveState( sourceId, @@ -873,10 +914,12 @@ public class BassClientStateMachine extends StateMachine { if (oldRecvState.getSourceDevice() == null || oldRecvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) { log("New Source Addition"); - mService.getCallbacks().notifySourceAdded(mDevice, recvState, - BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + mService.getCallbacks() + .notifySourceAdded( + mDevice, recvState, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); if (mPendingMetadata != null) { setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata); + mPendingMetadata = null; } checkAndUpdateBroadcastCode(recvState); processPASyncState(recvState); @@ -888,12 +931,31 @@ public class BassClientStateMachine extends StateMachine { cancelActiveSync( mService.getSyncHandleForBroadcastId(recvState.getBroadcastId())); setCurrentBroadcastMetadata(oldRecvState.getSourceId(), null); - mService.getCallbacks().notifySourceRemoved(mDevice, - oldRecvState.getSourceId(), - BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + if (mPendingSourceToSwitch != null) { + // Source remove is triggered by switch source request + mService.getCallbacks() + .notifySourceRemoved( + mDevice, + oldRecvState.getSourceId(), + BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST); + log("Switching to new source"); + Message message = obtainMessage(ADD_BCAST_SOURCE); + message.obj = mPendingSourceToSwitch; + sendMessage(message); + mPendingSourceToSwitch = null; + } else { + mService.getCallbacks() + .notifySourceRemoved( + mDevice, + oldRecvState.getSourceId(), + BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); + } } else { log("update to an existing recvState"); - setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata); + if (mPendingMetadata != null) { + setCurrentBroadcastMetadata(recvState.getSourceId(), mPendingMetadata); + mPendingMetadata = null; + } mService.getCallbacks().notifySourceModified(mDevice, recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); checkAndUpdateBroadcastCode(recvState); @@ -1094,15 +1156,19 @@ public class BassClientStateMachine extends StateMachine { } } else { log("failed to sync to PA: " + mPASyncRetryCounter); - if (!mAutoTriggered) { - Message message = obtainMessage(STOP_SCAN_OFFLOAD); - sendMessage(message); - } mAutoTriggered = false; // remove failed sync handle mPeriodicAdvCallbacksMap.remove(BassConstants.INVALID_SYNC_HANDLE); } mPendingSourceToAdd = null; + if (!mSourceSyncRequestsQueue.isEmpty()) { + log("Processing the next source to sync"); + Pair queuedSourceToSync = mSourceSyncRequestsQueue.remove(0); + Message msg = obtainMessage(SELECT_BCAST_SOURCE); + msg.obj = queuedSourceToSync.first; + msg.arg1 = queuedSourceToSync.second; + sendMessage(msg); + } } @Override @@ -1131,8 +1197,11 @@ public class BassClientStateMachine extends StateMachine { @Override public void onBigInfoAdvertisingReport(int syncHandle, boolean encrypted) { - log("onBIGInfoAdvertisingReport: syncHandle=" + syncHandle + - " ,encrypted =" + encrypted); + log( + "onBIGInfoAdvertisingReport: syncHandle=" + + syncHandle + + " ,encrypted =" + + encrypted); BluetoothDevice srcDevice = mService.getDeviceForSyncHandle(syncHandle); if (srcDevice == null) { log("No device found."); @@ -1159,6 +1228,12 @@ public class BassClientStateMachine extends StateMachine { mService.getCallbacks().notifySourceFound(metaData); } } + + @Override + public void onSyncTransferred(BluetoothDevice device, int status) { + log("onSyncTransferred: device=" + device + + " ,status =" + status); + } } /** @@ -1439,10 +1514,12 @@ public class BassClientStateMachine extends StateMachine { stream.write((metaData.getBroadcastId() & 0x0000000000FF0000) >>> 16); // PA_Sync - if (!mDefNoPAS) { - stream.write(0x01); + if (mDefNoPAS) { + // Synchronize to PA – PAST not available + stream.write(0x02); } else { - stream.write(0x00); + // Synchronize to PA – PAST available + stream.write(0x01); } // PA_Interval @@ -1639,6 +1716,7 @@ public class BassClientStateMachine extends StateMachine { log("Disconnecting from " + mDevice); mAllowReconnect = false; if (mBluetoothGatt != null) { + mService.handleDeviceDisconnection(mDevice, true); mBluetoothGatt.disconnect(); mBluetoothGatt.close(); mBluetoothGatt = null; @@ -1655,6 +1733,7 @@ public class BassClientStateMachine extends StateMachine { Log.w(TAG, "device is already connected to Bass" + mDevice); } else { Log.w(TAG, "unexpected disconnected from " + mDevice); + mService.handleDeviceDisconnection(mDevice, false); resetBluetoothGatt(); cancelActiveSync(null); transitionTo(mDisconnected); @@ -1691,12 +1770,43 @@ public class BassClientStateMachine extends StateMachine { case SELECT_BCAST_SOURCE: ScanResult scanRes = (ScanResult) message.obj; boolean auto = ((int) message.arg1) == BassConstants.AUTO; - selectSource(scanRes, auto); + // check if invalid sync handle exists indicating a pending sync request + if (mPeriodicAdvCallbacksMap.containsKey(BassConstants.INVALID_SYNC_HANDLE)) { + log( + "SELECT_BCAST_SOURCE queued due to waiting for a previous sync" + + " response"); + mSourceSyncRequestsQueue.add( + new Pair(scanRes, message.arg1)); + } else { + selectSource(scanRes, auto); + } break; case REACHED_MAX_SOURCE_LIMIT: int handle = message.arg1; cancelActiveSync(handle); break; + case SWITCH_BCAST_SOURCE: + metaData = (BluetoothLeBroadcastMetadata) message.obj; + int sourceIdToRemove = message.arg1; + // Save pending source to be added once existing source got removed + mPendingSourceToSwitch = metaData; + // Remove the source first + BluetoothLeBroadcastMetadata metaDataToUpdate = + getCurrentBroadcastMetadata(sourceIdToRemove); + if (metaDataToUpdate != null && isSyncedToTheSource(sourceIdToRemove)) { + log("SWITCH_BCAST_SOURCE force source to lost PA sync"); + Message msg = obtainMessage(UPDATE_BCAST_SOURCE); + msg.arg1 = sourceIdToRemove; + msg.arg2 = BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE; + msg.obj = metaDataToUpdate; + /* Pending remove set. Remove source once not synchronized to PA */ + sendMessage(msg); + } else { + Message msg = obtainMessage(REMOVE_BCAST_SOURCE); + msg.arg1 = sourceIdToRemove; + sendMessage(msg); + } + break; case ADD_BCAST_SOURCE: metaData = (BluetoothLeBroadcastMetadata) message.obj; @@ -1713,7 +1823,10 @@ public class BassClientStateMachine extends StateMachine { && mService.getCachedBroadcast(broadcastId) != null) { // If the source has been synced before, try to re-sync(auto/true) // with the source by previously cached scan result - selectSource(mService.getCachedBroadcast(broadcastId), true); + Message msg = obtainMessage(SELECT_BCAST_SOURCE); + msg.obj = mService.getCachedBroadcast(broadcastId); + msg.arg1 = BassConstants.AUTO; + sendMessage(msg); mPendingSourceToAdd = metaData; } else { mService.getCallbacks().notifySourceAddFailed(mDevice, metaData, @@ -1825,6 +1938,16 @@ public class BassClientStateMachine extends StateMachine { Log.e(TAG, "REMOVE_BCAST_SOURCE: no Bluetooth Gatt handle, Fatal"); mService.getCallbacks().notifySourceRemoveFailed(mDevice, sid, BluetoothStatusCodes.ERROR_UNKNOWN); + if (mPendingSourceToSwitch != null) { + // Switching source failed + // Need to notify add source failure for service to cleanup + mService.getCallbacks() + .notifySourceAddFailed( + mDevice, + mPendingSourceToSwitch, + BluetoothStatusCodes.ERROR_UNKNOWN); + mPendingSourceToSwitch = null; + } } break; case PSYNC_ACTIVE_TIMEOUT: @@ -1867,11 +1990,11 @@ public class BassClientStateMachine extends StateMachine { case ADD_BCAST_SOURCE: if (!isSuccess(status)) { cancelActiveSync(null); - Message message = obtainMessage(STOP_SCAN_OFFLOAD); - sendMessage(message); - mService.getCallbacks().notifySourceAddFailed(mDevice, - mPendingMetadata, status); - mPendingMetadata = null; + if (mPendingMetadata != null) { + mService.getCallbacks() + .notifySourceAddFailed(mDevice, mPendingMetadata, status); + mPendingMetadata = null; + } } break; case UPDATE_BCAST_SOURCE: @@ -1889,6 +2012,13 @@ public class BassClientStateMachine extends StateMachine { if (!isSuccess(status)) { mService.getCallbacks().notifySourceRemoveFailed(mDevice, mPendingSourceId, status); + if (mPendingSourceToSwitch != null) { + // Switching source failed + // Need to notify add source failure for service to cleanup + mService.getCallbacks() + .notifySourceAddFailed(mDevice, mPendingSourceToSwitch, status); + mPendingSourceToSwitch = null; + } } break; case SET_BCAST_CODE: @@ -1937,6 +2067,7 @@ public class BassClientStateMachine extends StateMachine { Log.w(TAG, "DISCONNECT requested!: " + mDevice); mAllowReconnect = false; if (mBluetoothGatt != null) { + mService.handleDeviceDisconnection(mDevice, true); mBluetoothGatt.disconnect(); mBluetoothGatt.close(); mBluetoothGatt = null; @@ -1957,6 +2088,7 @@ public class BassClientStateMachine extends StateMachine { Log.w(TAG, "should never happen from this state"); } else { Log.w(TAG, "Unexpected disconnection " + mDevice); + mService.handleDeviceDisconnection(mDevice, false); resetBluetoothGatt(); cancelActiveSync(null); transitionTo(mDisconnected); @@ -1993,6 +2125,7 @@ public class BassClientStateMachine extends StateMachine { case SET_BCAST_CODE: case REMOVE_BCAST_SOURCE: case REACHED_MAX_SOURCE_LIMIT: + case SWITCH_BCAST_SOURCE: case PSYNC_ACTIVE_TIMEOUT: log("defer the message: " + messageWhatToString(message.what) @@ -2054,7 +2187,7 @@ public class BassClientStateMachine extends StateMachine { } synchronized boolean isConnected() { - return getCurrentState() == mConnected; + return (getCurrentState() == mConnected) || (getCurrentState() == mConnectedProcessing); } public static String messageWhatToString(int what) { @@ -2085,6 +2218,8 @@ public class BassClientStateMachine extends StateMachine { return "REMOVE_BCAST_SOURCE"; case REACHED_MAX_SOURCE_LIMIT: return "REACHED_MAX_SOURCE_LIMIT"; + case SWITCH_BCAST_SOURCE: + return "SWITCH_BCAST_SOURCE"; case PSYNC_ACTIVE_TIMEOUT: return "PSYNC_ACTIVE_TIMEOUT"; case CONNECT_TIMEOUT: diff --git a/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java b/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java index ee09cb9a3adee97122f821c534624672fc8b3f97..16f1d9918ba453fd3868b97ac2752a0a1af7f232 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java @@ -22,6 +22,7 @@ import android.os.Looper; import android.util.Log; import com.android.bluetooth.Utils; +import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.flags.FeatureFlags; import com.android.internal.annotations.VisibleForTesting; @@ -75,9 +76,10 @@ public class BassObjectsFactory { public BassClientStateMachine makeStateMachine( BluetoothDevice device, BassClientService svc, + AdapterService adapterService, Looper looper, FeatureFlags featureFlags) { - return BassClientStateMachine.make(device, svc, looper, featureFlags); + return BassClientStateMachine.make(device, svc, adapterService, looper, featureFlags); } /** diff --git a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java index eb729ec71a8907b8108407bd405d8fb6bec6fefc..71f7ee73a6db2c9aadbc1069695c2289cce3750f 100644 --- a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +++ b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java @@ -39,7 +39,7 @@ import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.flags.FeatureFlags; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; @@ -100,7 +100,7 @@ import java.util.Set; * active Bluetooth device. */ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallback { - private static final String TAG = "ActiveDeviceManager"; + private static final String TAG = ActiveDeviceManager.class.getSimpleName(); private static final boolean DBG = true; @VisibleForTesting static final int A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS = 5_000; @@ -112,7 +112,6 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac private Handler mHandler = null; private final AudioManager mAudioManager; private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback; - private final FeatureFlags mFeatureFlags; private final Object mLock = new Object(); @GuardedBy("mLock") @@ -811,10 +810,9 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac } } - ActiveDeviceManager(AdapterService service, ServiceFactory factory, FeatureFlags featureFlags) { + ActiveDeviceManager(AdapterService service, ServiceFactory factory) { mAdapterService = service; mDbManager = mAdapterService.getDatabase(); - mFeatureFlags = Objects.requireNonNull(featureFlags, "Feature Flags cannot be null"); mFactory = factory; mAudioManager = service.getSystemService(AudioManager.class); mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback(); @@ -987,6 +985,16 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac if (device == null) { success = leAudioService.removeActiveDevice(hasFallbackDevice); } else { + if (Flags.leaudioActiveDeviceManagerGroupHandlingFix()) { + if ((mLeAudioActiveDevice != null) + && (Objects.equals( + mLeAudioActiveDevice, leAudioService.getLeadDevice(device)))) { + if (DBG) { + Log.d(TAG, "New LeAudioDevice is a part of an active group"); + } + return true; + } + } success = leAudioService.setActiveDevice(device); } @@ -994,7 +1002,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac return false; } - mLeAudioActiveDevice = device; + if (Flags.leaudioActiveDeviceManagerGroupHandlingFix()) { + mLeAudioActiveDevice = leAudioService.getLeadDevice(device); + } else { + mLeAudioActiveDevice = device; + } + if (device == null) { mLeHearingAidActiveDevice = null; mPendingLeHearingAidActiveDevice.remove(device); @@ -1245,7 +1258,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac * @return {@code true} if is broadcasting audio, {@code false} otherwise */ private boolean isBroadcastingAudio() { - if (!mFeatureFlags.leaudioBroadcastAudioHandoverPolicies()) { + if (!Flags.leaudioBroadcastAudioHandoverPolicies()) { // disable this if feature flag is false return false; } diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java index 18218d5e72b78d4ebec2c96482861fc9f8e6ce7e..9f63bc13611d918ac52e816fcf96b2c70327cdde 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterNativeInterface.java @@ -124,6 +124,10 @@ public class AdapterNativeInterface { return cancelBondNative(address); } + boolean pairingIsBusy() { + return pairingIsBusyNative(); + } + void generateLocalOobData(int transport) { generateLocalOobDataNative(transport); } @@ -285,6 +289,8 @@ public class AdapterNativeInterface { private native boolean cancelBondNative(byte[] address); + private native boolean pairingIsBusyNative(); + private native void generateLocalOobDataNative(int transport); private native boolean sdpSearchNative(byte[] address, byte[] uuid); diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java index 1a5bee8c2f37b0a37847c20811976646851583c1..cf969747fbf7f24640a5ab596ea6463e90b1c8ae 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java @@ -816,7 +816,8 @@ class AdapterProperties { + " -> " + newAdapterState); if (!isNormalStateTransition(prevState, state)) { Log.w(TAG, "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile=" - + profile + ", device=" + device + ", " + prevState + " -> " + state); + + BluetoothProfile.getProfileName(profile) + + ", device=" + device + ", " + prevState + " -> " + state); } mService.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions()); diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index f8ae301b5b439a594a9d906a3311e41525f1079d..ba4cba433ca03c0622056922a43bd57316a9309d 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -76,6 +76,7 @@ import android.bluetooth.IBluetoothSocketManager; import android.bluetooth.IncomingRfcommSocketInfo; import android.bluetooth.OobData; import android.bluetooth.UidTraffic; +import android.bluetooth.rfcomm.BluetoothRfcommProtoEnums; import android.companion.CompanionDeviceManager; import android.content.AttributionSource; import android.content.Context; @@ -113,6 +114,8 @@ import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.a2dpsink.A2dpSinkService; +import com.android.bluetooth.avrcp.AvrcpTargetService; +import com.android.bluetooth.avrcpcontroller.AvrcpControllerService; import com.android.bluetooth.bas.BatteryService; import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.InteropUtil.InteropFeature; @@ -122,9 +125,8 @@ import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreServic import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.btservice.storage.MetadataDatabase; import com.android.bluetooth.csip.CsipSetCoordinatorService; -import com.android.bluetooth.flags.FeatureFlagsImpl; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.gatt.GattService; -import com.android.bluetooth.gatt.ScanManager; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; @@ -132,13 +134,17 @@ import com.android.bluetooth.hfpclient.HeadsetClientService; import com.android.bluetooth.hid.HidDeviceService; import com.android.bluetooth.hid.HidHostService; import com.android.bluetooth.le_audio.LeAudioService; +import com.android.bluetooth.le_scan.ScanManager; import com.android.bluetooth.map.BluetoothMapService; import com.android.bluetooth.mapclient.MapClientService; +import com.android.bluetooth.mcp.McpService; +import com.android.bluetooth.opp.BluetoothOppService; import com.android.bluetooth.pan.PanService; import com.android.bluetooth.pbap.BluetoothPbapService; import com.android.bluetooth.pbapclient.PbapClientService; import com.android.bluetooth.sap.SapService; import com.android.bluetooth.sdp.SdpManager; +import com.android.bluetooth.tbs.TbsService; import com.android.bluetooth.telephony.BluetoothInCallService; import com.android.bluetooth.vc.VolumeControlService; import com.android.internal.annotations.GuardedBy; @@ -169,8 +175,10 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; +import java.util.function.Function; import java.util.function.Predicate; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class AdapterService extends Service { private static final String TAG = "BluetoothAdapterService"; @@ -203,7 +211,7 @@ public class AdapterService extends Service { private long mEnergyUsedTotalVoltAmpSecMicro; private final SparseArray mUidTraffic = new SparseArray<>(); - private final ArrayList mStartedProfiles = new ArrayList<>(); + private final Map mStartedProfiles = new HashMap<>(); private final ArrayList mRegisteredProfiles = new ArrayList<>(); private final ArrayList mRunningProfiles = new ArrayList<>(); private HashSet mLeAudioAllowDevices = new HashSet<>(); @@ -278,6 +286,11 @@ public class AdapterService extends Service { mLooper = looper; } + @VisibleForTesting + AdapterService(Context ctx) { + attachBaseContext(ctx); + } + public static synchronized AdapterService getAdapterService() { return sAdapterService; } @@ -429,8 +442,8 @@ public class AdapterService extends Service { * @param serviceSampleName the service simple name. * @return true if the service is started expectedly, false otherwise. */ - public boolean isStartedProfile(String serviceSampleName) { - return mStartedProfiles.contains(serviceSampleName); + public boolean isStartedProfile(int profileId) { + return mStartedProfiles.containsKey(profileId); } private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1; @@ -671,9 +684,7 @@ public class AdapterService extends Service { mSdpManager = SdpManager.init(this); - FeatureFlagsImpl featureFlags = new FeatureFlagsImpl(); - - mDatabaseManager = new DatabaseManager(this, featureFlags); + mDatabaseManager = new DatabaseManager(this); mDatabaseManager.start(MetadataDatabase.createDatabase(this)); boolean isAutomotiveDevice = @@ -689,18 +700,16 @@ public class AdapterService extends Service { */ if (!isAutomotiveDevice && getResources().getBoolean(R.bool.enable_phone_policy)) { Log.i(TAG, "Phone policy enabled"); - mPhonePolicy = new PhonePolicy(this, new ServiceFactory(), featureFlags); + mPhonePolicy = new PhonePolicy(this, new ServiceFactory()); mPhonePolicy.start(); } else { Log.i(TAG, "Phone policy disabled"); } - if (featureFlags.audioRoutingCentralization()) { - mActiveDeviceManager = - new AudioRoutingManager(this, new ServiceFactory(), featureFlags); + if (Flags.audioRoutingCentralization()) { + mActiveDeviceManager = new AudioRoutingManager(this, new ServiceFactory()); } else { - mActiveDeviceManager = - new ActiveDeviceManager(this, new ServiceFactory(), featureFlags); + mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory()); } mActiveDeviceManager.start(); @@ -857,22 +866,23 @@ public class AdapterService extends Service { * @param port port of socket * @param isSecured if secured API is called * @param result transaction result of the connection - * @param socketCreationLatencyMillis latency of the connection + * @param socketCreationLatencyNanos latency of the connection */ public void logL2capcocClientConnection( BluetoothDevice device, int port, boolean isSecured, int result, - long socketCreationTimeMillis, - long socketCreationLatencyMillis, - long socketConnectionTimeMillis, + long socketCreationTimeNanos, + long socketCreationLatencyNanos, + long socketConnectionTimeNanos, int appUid) { int metricId = getMetricId(device); - long currentTime = System.currentTimeMillis(); - long endToEndLatencyMillis = currentTime - socketCreationTimeMillis; - long socketConnectionLatencyMillis = currentTime - socketConnectionTimeMillis; + long currentTime = System.nanoTime(); + long endToEndLatencyMillis = (currentTime - socketCreationTimeNanos) / 1000000; + long socketCreationLatencyMillis = socketCreationLatencyNanos / 1000000; + long socketConnectionLatencyMillis = (currentTime - socketConnectionTimeNanos) / 1000000; Log.i( TAG, "Statslog L2capcoc client connection." @@ -896,6 +906,37 @@ public class AdapterService extends Service { socketConnectionLatencyMillis); } + /** + * Log RFCOMM Connection Metrics + * + * @param device Bluetooth device + * @param isSecured if secured API is called + * @param resultCode transaction result of the connection + * @param isSerialPort true if service class UUID is 0x1101 + */ + public void logRfcommConnectionAttempt( + BluetoothDevice device, + boolean isSecured, + int resultCode, + long socketCreationTimeNanos, + boolean isSerialPort, + int appUid) { + + int metricId = getMetricId(device); + long currentTime = System.nanoTime(); + long endToEndLatencyNanos = currentTime - socketCreationTimeNanos; + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_RFCOMM_CONNECTION_ATTEMPTED, + metricId, + endToEndLatencyNanos, + isSecured + ? BluetoothRfcommProtoEnums.SOCKET_SECURITY_SECURE + : BluetoothRfcommProtoEnums.SOCKET_SECURITY_INSECURE, + resultCode, + isSerialPort, + appUid); + } + @RequiresPermission( allOf = { android.Manifest.permission.BLUETOOTH_CONNECT, @@ -964,14 +1005,12 @@ public class AdapterService extends Service { void startProfileServices() { debugLog("startCoreServices()"); - Class[] supportedProfileServices = Config.getSupportedProfiles(); + int[] supportedProfileServices = Config.getSupportedProfiles(); // TODO(b/228875190): GATT is assumed supported. If we support no other profiles then just // move on to BREDR_STARTED. Note that configuring GATT to NOT supported will cause adapter // initialization failures if (supportedProfileServices.length == 1 - && GattService.class - .getSimpleName() - .equals(supportedProfileServices[0].getSimpleName())) { + && supportedProfileServices[0] == BluetoothProfile.GATT) { mAdapterProperties.onBluetoothReady(); updateUuids(); mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED); @@ -985,7 +1024,7 @@ public class AdapterService extends Service { mNativeInterface.cancelDiscovery(); mAdapterProperties.setScanMode(BluetoothAdapter.SCAN_MODE_NONE); - Class[] supportedProfileServices = Config.getSupportedProfiles(); + int[] supportedProfileServices = Config.getSupportedProfiles(); // TODO(b/228875190): GATT is assumed supported. If we support no profiles then just move on // to BREDR_STOPPED if (supportedProfileServices.length == 1 @@ -1001,10 +1040,13 @@ public class AdapterService extends Service { } private void startGattProfileService() { - mStartedProfiles.add(GattService.class.getSimpleName()); - mGattService = new GattService(this); - ((ProfileService) mGattService).doStart(); + + mStartedProfiles.put(BluetoothProfile.GATT, mGattService); + addProfile(mGattService); + mGattService.start(); + mGattService.setAvailable(true); + onProfileServiceStateChanged(mGattService, BluetoothAdapter.STATE_ON); } private void stopGattProfileService() { @@ -1014,9 +1056,14 @@ public class AdapterService extends Service { mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED); } - mStartedProfiles.remove(GattService.class.getSimpleName()); + mStartedProfiles.remove(BluetoothProfile.GATT); if (mGattService != null) { - ((ProfileService) mGattService).doStop(); + mGattService.setAvailable(false); + onProfileServiceStateChanged(mGattService, BluetoothAdapter.STATE_OFF); + mGattService.stop(); + removeProfile(mGattService); + mGattService.cleanup(); + mGattService.getBinder().cleanup(); mGattService = null; } } @@ -1026,26 +1073,27 @@ public class AdapterService extends Service { } void updateLeAudioProfileServiceState() { - HashSet nonSupportedProfiles = new HashSet<>(); + Set nonSupportedProfiles = new HashSet<>(); if (!isLeConnectedIsochronousStreamCentralSupported()) { - nonSupportedProfiles.addAll(Config.getLeAudioUnicastProfiles()); + for (int profileId : Config.getLeAudioUnicastProfiles()) { + nonSupportedProfiles.add(profileId); + } } if (!isLeAudioBroadcastAssistantSupported()) { - nonSupportedProfiles.add(BassClientService.class); + nonSupportedProfiles.add(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); } if (!isLeAudioBroadcastSourceSupported()) { - Config.updateSupportedProfileMask( - false, LeAudioService.class, BluetoothProfile.LE_AUDIO_BROADCAST); + Config.setProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST, false); } // Disable the non-supported profiles service - for (Class profileService : nonSupportedProfiles) { - Config.setProfileEnabled(profileService, false); - if (isStartedProfile(profileService.getSimpleName())) { - setProfileServiceState(profileService, BluetoothAdapter.STATE_OFF); + for (int profileId : nonSupportedProfiles) { + Config.setProfileEnabled(profileId, false); + if (isStartedProfile(profileId)) { + setProfileServiceState(profileId, BluetoothAdapter.STATE_OFF); } } } @@ -1379,26 +1427,84 @@ public class AdapterService extends Service { BluetoothSap.invalidateBluetoothGetConnectionStateCache(); } - private void setProfileServiceState(Class service, int state) { + private static final Map> + PROFILE_CONSTRUCTORS = + Map.ofEntries( + Map.entry(BluetoothProfile.A2DP, A2dpService::new), + Map.entry(BluetoothProfile.A2DP_SINK, A2dpSinkService::new), + Map.entry(BluetoothProfile.AVRCP, AvrcpTargetService::new), + Map.entry( + BluetoothProfile.AVRCP_CONTROLLER, AvrcpControllerService::new), + Map.entry( + BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, + BassClientService::new), + Map.entry(BluetoothProfile.BATTERY, BatteryService::new), + Map.entry( + BluetoothProfile.CSIP_SET_COORDINATOR, + CsipSetCoordinatorService::new), + Map.entry(BluetoothProfile.HAP_CLIENT, HapClientService::new), + Map.entry(BluetoothProfile.HEADSET, HeadsetService::new), + Map.entry(BluetoothProfile.HEADSET_CLIENT, HeadsetClientService::new), + Map.entry(BluetoothProfile.HEARING_AID, HearingAidService::new), + Map.entry(BluetoothProfile.HID_DEVICE, HidDeviceService::new), + Map.entry(BluetoothProfile.HID_HOST, HidHostService::new), + Map.entry(BluetoothProfile.GATT, GattService::new), + Map.entry(BluetoothProfile.LE_AUDIO, LeAudioService::new), + Map.entry(BluetoothProfile.LE_CALL_CONTROL, TbsService::new), + Map.entry(BluetoothProfile.MAP, BluetoothMapService::new), + Map.entry(BluetoothProfile.MAP_CLIENT, MapClientService::new), + Map.entry(BluetoothProfile.MCP_SERVER, McpService::new), + Map.entry(BluetoothProfile.OPP, BluetoothOppService::new), + Map.entry(BluetoothProfile.PAN, PanService::new), + Map.entry(BluetoothProfile.PBAP, BluetoothPbapService::new), + Map.entry(BluetoothProfile.PBAP_CLIENT, PbapClientService::new), + Map.entry(BluetoothProfile.SAP, SapService::new), + Map.entry(BluetoothProfile.VOLUME_CONTROL, VolumeControlService::new)); + + @VisibleForTesting + void setProfileServiceState(int profileId, int state) { if (state == BluetoothAdapter.STATE_ON) { - mStartedProfiles.add(service.getSimpleName()); + if (!mStartedProfiles.containsKey(profileId)) { + ProfileService profileService = PROFILE_CONSTRUCTORS.get(profileId).apply(this); + mStartedProfiles.put(profileId, profileService); + addProfile(profileService); + profileService.start(); + profileService.setAvailable(true); + onProfileServiceStateChanged(profileService, BluetoothAdapter.STATE_ON); + } else { + Log.e( + TAG, + "setProfileServiceState(" + + BluetoothProfile.getProfileName(profileId) + + ", STATE_ON): profile is already started"); + } } else if (state == BluetoothAdapter.STATE_OFF) { - mStartedProfiles.remove(service.getSimpleName()); + ProfileService profileService = mStartedProfiles.remove(profileId); + if (profileService != null) { + profileService.setAvailable(false); + onProfileServiceStateChanged(profileService, BluetoothAdapter.STATE_OFF); + profileService.stop(); + removeProfile(profileService); + profileService.cleanup(); + profileService.getBinder().cleanup(); + } else { + Log.e( + TAG, + "setProfileServiceState(" + + BluetoothProfile.getProfileName(profileId) + + ", STATE_OFF): profile is already stopped"); + } } - Intent intent = new Intent(this, service); - intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED); - intent.putExtra(BluetoothAdapter.EXTRA_STATE, state); - startService(intent); } - private void setAllProfileServiceStates(Class[] services, int state) { - for (Class service : services) { + private void setAllProfileServiceStates(int[] profileIds, int state) { + for (int profileId : profileIds) { // TODO(b/228875190): GATT is assumed supported and treated differently as part of the // "BLE ON" state, despite GATT not being BLE specific. - if (GattService.class.getSimpleName().equals(service.getSimpleName())) { + if (profileId == BluetoothProfile.GATT) { continue; } - setProfileServiceState(service, state); + setProfileServiceState(profileId, state); } } @@ -2940,7 +3046,16 @@ public class AdapterService extends Service { return BluetoothDevice.CONNECTION_STATE_DISCONNECTED; } - return service.getConnectionState(device); + if (Flags.apiGetConnectionStateUsingIdentityAddress()) { + final long token = Binder.clearCallingIdentity(); + try { + return service.getConnectionState(device); + } finally { + Binder.restoreCallingIdentity(token); + } + } else { + return service.getConnectionState(device); + } } @Override @@ -3875,9 +3990,9 @@ public class AdapterService extends Service { int port, boolean isSecured, int result, - long socketCreationTimeMillis, - long socketCreationLatencyMillis, - long socketConnectionTimeMillis, + long socketCreationTimeNanos, + long socketCreationLatencyNanos, + long socketConnectionTimeNanos, SynchronousResultReceiver receiver) { AdapterService service = getService(); if (service == null) { @@ -3889,9 +4004,35 @@ public class AdapterService extends Service { port, isSecured, result, - socketCreationTimeMillis, - socketCreationLatencyMillis, - socketConnectionTimeMillis, + socketCreationTimeNanos, + socketCreationLatencyNanos, + socketConnectionTimeNanos, + Binder.getCallingUid()); + receiver.send(null); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + @Override + public void logRfcommConnectionAttempt( + BluetoothDevice device, + boolean isSecured, + int resultCode, + long socketCreationTimeNanos, + boolean isSerialPort, + SynchronousResultReceiver receiver) { + AdapterService service = getService(); + if (service == null) { + return; + } + try { + service.logRfcommConnectionAttempt( + device, + isSecured, + resultCode, + socketCreationTimeNanos, + isSerialPort, Binder.getCallingUid()); receiver.send(null); } catch (RuntimeException e) { @@ -4282,11 +4423,14 @@ public class AdapterService extends Service { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } - HashSet supportedProfileServices = - new HashSet(Arrays.asList(Config.getSupportedProfiles())); - HashSet leAudioUnicastProfiles = Config.getLeAudioUnicastProfiles(); + Set supportedProfileServices = + Arrays.stream(Config.getSupportedProfiles()) + .boxed() + .collect(Collectors.toSet()); + int[] leAudioUnicastProfiles = Config.getLeAudioUnicastProfiles(); - if (supportedProfileServices.containsAll(leAudioUnicastProfiles)) { + if (Arrays.stream(leAudioUnicastProfiles) + .allMatch(supportedProfileServices::contains)) { return BluetoothStatusCodes.FEATURE_SUPPORTED; } @@ -4331,10 +4475,12 @@ public class AdapterService extends Service { return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; } - HashSet supportedProfileServices = - new HashSet(Arrays.asList(Config.getSupportedProfiles())); + int[] supportedProfileServices = Config.getSupportedProfiles(); - if (supportedProfileServices.contains(BassClientService.class)) { + if (Arrays.stream(supportedProfileServices) + .anyMatch( + profileId -> + profileId == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)) { return BluetoothStatusCodes.FEATURE_SUPPORTED; } @@ -5247,6 +5393,100 @@ public class AdapterService extends Service { receiver.propagateException(e); } } + + @Override + public void getProfile(int profileId, SynchronousResultReceiver receiver) { + try { + receiver.send(getProfile(profileId)); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + private IBinder getProfile(int profileId) { + AdapterService service = getService(); + if (service == null) { + return null; + } + + return service.getProfile(profileId); + } + + @Override + public void setActiveAudioDevicePolicy( + BluetoothDevice device, + int activeAudioDevicePolicy, + AttributionSource source, + SynchronousResultReceiver receiver) { + try { + receiver.send(setActiveAudioDevicePolicy(device, activeAudioDevicePolicy, source)); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + private int setActiveAudioDevicePolicy( + BluetoothDevice device, int activeAudioDevicePolicy, AttributionSource source) { + AdapterService service = getService(); + if (service == null) { + return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; + } + if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "setActiveAudioDevicePolicy")) { + return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; + } + if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { + throw new IllegalArgumentException("device cannot have an invalid address"); + } + if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; + } + + enforceBluetoothPrivilegedPermission(service); + return service.mDatabaseManager.setActiveAudioDevicePolicy( + device, activeAudioDevicePolicy); + } + + @Override + public void getActiveAudioDevicePolicy( + BluetoothDevice device, + AttributionSource source, + SynchronousResultReceiver receiver) { + try { + receiver.send(getActiveAudioDevicePolicy(device, source)); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + private int getActiveAudioDevicePolicy(BluetoothDevice device, AttributionSource source) { + AdapterService service = getService(); + if (service == null) { + return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT; + } + if (!callerIsSystemOrActiveOrManagedUser(service, TAG, "getActiveAudioDevicePolicy")) { + throw new IllegalStateException( + "Caller is not the system or part of the active/managed user"); + } + if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) { + throw new IllegalArgumentException("device cannot have an invalid address"); + } + if (!Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { + return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT; + } + + enforceBluetoothPrivilegedPermission(service); + return service.mDatabaseManager.getActiveAudioDevicePolicy(device); + } } /** @@ -5756,6 +5996,11 @@ public class AdapterService extends Service { DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); if (deviceProp != null && deviceProp.getIdentityAddress() != null) { return Utils.getBytesFromAddress(deviceProp.getIdentityAddress()); + } + + if (Flags.identityAddressNullIfUnknown()) { + // Return null if identity address unknown + return null; } else { return Utils.getByteAddress(device); } @@ -5776,7 +6021,12 @@ public class AdapterService extends Service { if (deviceProp != null && deviceProp.getIdentityAddress() != null) { return deviceProp.getIdentityAddress(); } else { - return address; + if (Flags.identityAddressNullIfUnknown()) { + // Return null if identity address unknown + return null; + } else { + return address; + } } } @@ -5945,6 +6195,16 @@ public class AdapterService extends Service { } int getConnectionState(BluetoothDevice device) { + if (Flags.apiGetConnectionStateUsingIdentityAddress()) { + int connectionState = + mNativeInterface.getConnectionState(getBytesFromAddress(device.getAddress())); + final String identityAddress = device.getIdentityAddress(); + if (identityAddress != null) { + connectionState |= + mNativeInterface.getConnectionState(getBytesFromAddress(identityAddress)); + } + return connectionState; + } return mNativeInterface.getConnectionState(getBytesFromAddress(device.getAddress())); } @@ -6909,6 +7169,24 @@ public class AdapterService extends Service { } } + IBinder getProfile(int profileId) { + if (getState() == BluetoothAdapter.STATE_TURNING_ON) { + return null; + } + + // LE_AUDIO_BROADCAST is not associated with a service and use LE_AUDIO's Binder + if (profileId == BluetoothProfile.LE_AUDIO_BROADCAST) { + profileId = BluetoothProfile.LE_AUDIO; + } + + ProfileService profile = mStartedProfiles.get(profileId); + if (profile != null) { + return profile.getBinder(); + } else { + return null; + } + } + boolean isMediaProfileConnected() { if (mA2dpService != null && mA2dpService.getConnectedDevices().size() > 0) { debugLog("isMediaProfileConnected. A2dp is connected"); @@ -7104,7 +7382,7 @@ public class AdapterService extends Service { return true; } - void energyInfoCallback( + void energyInfoCallbackInternal( int status, int ctrlState, long txTime, @@ -7112,8 +7390,6 @@ public class AdapterService extends Service { long idleTime, long energyUsed, UidTraffic[] data) { - if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID - && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { // Energy is product of mA, V and ms. If the chipset doesn't // report it, we have to compute it from time if (energyUsed == 0) { @@ -7168,8 +7444,24 @@ public class AdapterService extends Service { } mEnergyInfoLock.notifyAll(); } - } + } + void energyInfoCallback( + int status, + int ctrlState, + long txTime, + long rxTime, + long idleTime, + long energyUsed, + UidTraffic[] data) { + if (Flags.btSystemContextReport()) { + energyInfoCallbackInternal( + status, ctrlState, txTime, rxTime, idleTime, energyUsed, data); + } else if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID + && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { + energyInfoCallbackInternal( + status, ctrlState, txTime, rxTime, idleTime, energyUsed, data); + } verboseLog( "energyInfoCallback()" + (" status = " + status) @@ -7177,7 +7469,7 @@ public class AdapterService extends Service { + (" rxTime = " + rxTime) + (" idleTime = " + idleTime) + (" energyUsed = " + energyUsed) - + (" ctrlState = " + ctrlState) + + (" ctrlState = " + String.format("0x%08x", ctrlState)) + (" traffic = " + Arrays.toString(data))); } @@ -7253,8 +7545,8 @@ public class AdapterService extends Service { writer.println(); writer.println("Enabled Profile Services:"); - for (Class profile : Config.getSupportedProfiles()) { - writer.println(" " + profile.getSimpleName()); + for (int profileId : Config.getSupportedProfiles()) { + writer.println(" " + BluetoothProfile.getProfileName(profileId)); } writer.println(); diff --git a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java index 369f4649946fdcc1eacffe8a558a9f28e78f156c..2dfed88129a99c4f672f017aec1b966d69260786 100644 --- a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java +++ b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java @@ -19,6 +19,7 @@ package com.android.bluetooth.btservice; import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; @@ -30,6 +31,7 @@ import android.bluetooth.BluetoothSinkAudioPolicy; import android.media.AudioDeviceCallback; import android.media.AudioDeviceInfo; import android.media.AudioManager; +import android.media.session.MediaSessionManager; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -41,17 +43,20 @@ import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.flags.FeatureFlags; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; import com.android.internal.annotations.VisibleForTesting; +import com.android.modules.utils.SynchronousResultReceiver; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Optional; import java.util.Set; public class AudioRoutingManager extends ActiveDeviceManager { @@ -65,6 +70,7 @@ public class AudioRoutingManager extends ActiveDeviceManager { private HandlerThread mHandlerThread = null; private AudioRoutingHandler mHandler = null; private final AudioManager mAudioManager; + private final MediaSessionManager mSessionManager; private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback; @Override @@ -95,12 +101,19 @@ public class AudioRoutingManager extends ActiveDeviceManager { * * @param device The device to be activated. * @param profile The profile to be activated + * @param receiver to post the results */ - public void activateDeviceProfile(BluetoothDevice device, int profile) { + public void activateDeviceProfile( + BluetoothDevice device, int profile, @Nullable SynchronousResultReceiver receiver) { mHandler.post( - () -> - mHandler.activateDeviceProfile( - mHandler.getAudioRoutingDevice(device), profile)); + () -> { + boolean result = + mHandler.activateDeviceProfile( + mHandler.getAudioRoutingDevice(device), profile); + if (receiver != null) { + receiver.send(result); + } + }); } /** @@ -132,12 +145,13 @@ public class AudioRoutingManager extends ActiveDeviceManager { } } - AudioRoutingManager(AdapterService service, ServiceFactory factory, FeatureFlags featureFlags) { - super(service, factory, featureFlags); + AudioRoutingManager(AdapterService service, ServiceFactory factory) { + super(service, factory); mAdapterService = service; mDbManager = mAdapterService.getDatabase(); mFactory = factory; mAudioManager = service.getSystemService(AudioManager.class); + mSessionManager = service.getSystemService(MediaSessionManager.class); mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback(); } @@ -190,47 +204,6 @@ public class AudioRoutingManager extends ActiveDeviceManager { return devices == null ? Collections.emptyList() : devices; } - /** - * Checks whether it is Okay to activate HFP when the device is connected. - * - * @param device the remote device - * @return {@code true} if the device should be activated when connected. - */ - private boolean shouldActivateWhenConnected(BluetoothDevice device) { - // Check CoD - BluetoothClass deviceClass = device.getBluetoothClass(); - if (deviceClass != null - && deviceClass.getDeviceClass() == BluetoothClass.Device.WEARABLE_WRIST_WATCH) { - Log.i(TAG, "Do not set profile active for watch device when connected: " + device); - return false; - } - // Check the audio device policy - HeadsetService service = mFactory.getHeadsetService(); - BluetoothSinkAudioPolicy audioPolicy = service.getHfpCallAudioPolicy(device); - if (audioPolicy != null - && audioPolicy.getActiveDevicePolicyAfterConnection() - == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { - Log.i( - TAG, - "The device's HFP call audio policy doesn't allow it to be activated when" - + " connected: " - + device); - return false; - } - - // Check metadata - byte[] deviceType = mDbManager.getCustomMeta(device, BluetoothDevice.METADATA_DEVICE_TYPE); - if (deviceType == null) { - return true; - } - String deviceTypeStr = new String(deviceType); - if (deviceTypeStr.equals(BluetoothDevice.DEVICE_TYPE_WATCH)) { - Log.i(TAG, "Do not set profile active for watch device when connected: " + device); - return false; - } - return true; - } - /** Notifications of audio device connection and disconnection events. */ @SuppressLint("AndroidFrameworkRequiresPermission") private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback { @@ -296,28 +269,28 @@ public class AudioRoutingManager extends ActiveDeviceManager { + BluetoothProfile.getProfileName(profile) + ")"); } - AudioRoutingDevice arDevice = getAudioRoutingDevice(device); - if (arDevice.connectedProfiles.contains(profile)) { + AudioRoutingDevice connectedDevice = getAudioRoutingDevice(device); + if (connectedDevice.connectedProfiles.contains(profile)) { if (DBG) { Log.d(TAG, "This device is already connected: " + device); } return; } - arDevice.connectedProfiles.add(profile); - if (!shouldActivateWhenConnected(device)) { + connectedDevice.connectedProfiles.add(profile); + if (!shouldActivateWhenConnected(connectedDevice)) { return; } - if (!arDevice.canActivateNow(profile)) { + if (!connectedDevice.canActivateNow(profile)) { if (DBG) { Log.d(TAG, "Can not activate now: " + BluetoothProfile.getProfileName(profile)); } mHandler.postDelayed( - () -> activateDeviceProfile(arDevice, profile), - arDevice, + () -> activateDeviceProfile(connectedDevice, profile), + connectedDevice, A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS); return; } - activateDeviceProfile(arDevice, profile); + activateDeviceProfile(connectedDevice, profile); } public void handleProfileDisconnected(int profile, BluetoothDevice device) { @@ -330,16 +303,16 @@ public class AudioRoutingManager extends ActiveDeviceManager { + BluetoothProfile.getProfileName(profile) + ")"); } - AudioRoutingDevice arDevice = getAudioRoutingDevice(device); - arDevice.connectedProfiles.remove(profile); - if (arDevice.connectedProfiles.isEmpty()) { + AudioRoutingDevice disconnectedDevice = getAudioRoutingDevice(device); + disconnectedDevice.connectedProfiles.remove(profile); + if (disconnectedDevice.connectedProfiles.isEmpty()) { mConnectedDevices.remove(device); } List activeDevices = mActiveDevices.get(profile); if (activeDevices != null && activeDevices.contains(device)) { activeDevices.remove(device); - if (activeDevices.size() == 0) { - if (!setFallbackDeviceActive()) { + if (activeDevices.isEmpty()) { + if (!setFallbackDeviceActive(profile)) { removeActiveDevice(profile, false); } } @@ -358,92 +331,108 @@ public class AudioRoutingManager extends ActiveDeviceManager { + device); } - private boolean setFallbackDeviceActive() { + private Optional getFallbackDevice( + Collection candidates) { + List activatableDevices = new ArrayList<>(); + for (AudioRoutingDevice d : candidates) { + if (d.isA2dpOnly() || d.isHfpOnly()) continue; + boolean canActivate = true; + for (int p : d.connectedProfiles) { + if (!d.canActivateNow(p)) { + canActivate = false; + break; + } else if (p != BluetoothProfile.A2DP && p != BluetoothProfile.HEADSET) { + break; + } + } + if (canActivate) { + activatableDevices.add(d.device); + } + } + return Optional.ofNullable( + mDbManager.getMostRecentlyConnectedDevicesInList(activatableDevices)); + } + + private boolean setFallbackDeviceActive(int profile) { if (DBG) { - Log.d(TAG, "setFallbackDeviceActive"); - } - List candidates = new ArrayList<>(); - int audioMode = mAudioManager.getMode(); - for (AudioRoutingDevice arDevice : mConnectedDevices.values()) { - for (int profile : arDevice.connectedProfiles) { - if (audioMode == AudioManager.MODE_NORMAL) { - if (profile != BluetoothProfile.HEADSET) { - candidates.add(arDevice.device); - break; - } + Log.d(TAG, "setFallbackDeviceActive: " + BluetoothProfile.getProfileName(profile)); + } + // 1. Activate the lastly activated device among currently activated devices. + Set candidates = new HashSet<>(); + for (int i = 0; i < mActiveDevices.size(); ++i) { + for (BluetoothDevice d : mActiveDevices.valueAt(i)) { + candidates.add(getAudioRoutingDevice(d)); + } + } + try { + // 2. Activate the lastly activated device for the profile + Optional fallbackDevice = + getFallbackDevice(candidates) + .or(() -> getFallbackDevice(mConnectedDevices.values())); + AudioRoutingDevice fallbackRoutingDevice = + getAudioRoutingDevice(fallbackDevice.get()); + int profileToActivate = profile; + if (!fallbackRoutingDevice.canActivateNow(profile)) { + // if it can't activate the given profile, try LE_AUDIO + if (fallbackRoutingDevice.canActivateNow(BluetoothProfile.LE_AUDIO)) { + profileToActivate = BluetoothProfile.LE_AUDIO; } else { - if (profile != BluetoothProfile.A2DP) { - candidates.add(arDevice.device); - break; + // if it can't activate both the given profile and LE_AUDIO, select any + for (int p : fallbackRoutingDevice.connectedProfiles) { + if (fallbackRoutingDevice.canActivateNow(p)) { + profileToActivate = p; + break; + } } } } - } - AudioRoutingDevice deviceToActivate = null; - BluetoothDevice device = mDbManager.getMostRecentlyConnectedDevicesInList(candidates); - if (device != null) { - deviceToActivate = getAudioRoutingDevice(device); - } - if (deviceToActivate != null) { + return activateDeviceProfile(fallbackRoutingDevice, profileToActivate); + } catch (NoSuchElementException e) { + // Thrown when no available fallback devices found if (DBG) { - Log.d(TAG, "activateDevice: device=" + deviceToActivate.device); + Log.d(TAG, "Found no available BT fallback devices."); } - // Try to activate hearing aid and LE audio first - if (deviceToActivate.connectedProfiles.contains(BluetoothProfile.HEARING_AID)) { - return activateDeviceProfile(deviceToActivate, BluetoothProfile.HEARING_AID); - } else if (deviceToActivate.connectedProfiles.contains(BluetoothProfile.LE_AUDIO)) { - return activateDeviceProfile(deviceToActivate, BluetoothProfile.LE_AUDIO); - } else if (deviceToActivate.connectedProfiles.contains(BluetoothProfile.A2DP)) { - return activateDeviceProfile(deviceToActivate, BluetoothProfile.A2DP); - } else if (deviceToActivate.connectedProfiles.contains(BluetoothProfile.HEADSET)) { - return activateDeviceProfile(deviceToActivate, BluetoothProfile.HEADSET); - } - Log.w( - TAG, - "Fail to activate the device: " - + deviceToActivate.device - + ", no connected audio profiles"); + return false; } - return false; } // TODO: handle the connection policy change events. private AudioRoutingDevice getAudioRoutingDevice(@NonNull BluetoothDevice device) { Objects.requireNonNull(device); - AudioRoutingDevice arDevice = mConnectedDevices.get(device); - if (arDevice != null) { - return arDevice; - } - arDevice = new AudioRoutingDevice(); - arDevice.device = device; - arDevice.supportedProfiles = new HashSet<>(); - arDevice.connectedProfiles = new HashSet<>(); + AudioRoutingDevice routingDevice = mConnectedDevices.get(device); + if (routingDevice != null) { + return routingDevice; + } + routingDevice = new AudioRoutingDevice(); + routingDevice.device = device; + routingDevice.supportedProfiles = new HashSet<>(); + routingDevice.connectedProfiles = new HashSet<>(); if (mDbManager.getProfileConnectionPolicy(device, BluetoothProfile.HEADSET) == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { - arDevice.supportedProfiles.add(BluetoothProfile.HEADSET); + routingDevice.supportedProfiles.add(BluetoothProfile.HEADSET); } else { - arDevice.supportedProfiles.remove(BluetoothProfile.HEADSET); + routingDevice.supportedProfiles.remove(BluetoothProfile.HEADSET); } if (mDbManager.getProfileConnectionPolicy(device, BluetoothProfile.A2DP) == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { - arDevice.supportedProfiles.add(BluetoothProfile.A2DP); + routingDevice.supportedProfiles.add(BluetoothProfile.A2DP); } else { - arDevice.supportedProfiles.remove(BluetoothProfile.A2DP); + routingDevice.supportedProfiles.remove(BluetoothProfile.A2DP); } if (mDbManager.getProfileConnectionPolicy(device, BluetoothProfile.HEARING_AID) == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { - arDevice.supportedProfiles.add(BluetoothProfile.HEARING_AID); + routingDevice.supportedProfiles.add(BluetoothProfile.HEARING_AID); } else { - arDevice.supportedProfiles.remove(BluetoothProfile.HEARING_AID); + routingDevice.supportedProfiles.remove(BluetoothProfile.HEARING_AID); } if (mDbManager.getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO) == BluetoothProfile.CONNECTION_POLICY_ALLOWED) { - arDevice.supportedProfiles.add(BluetoothProfile.LE_AUDIO); + routingDevice.supportedProfiles.add(BluetoothProfile.LE_AUDIO); } else { - arDevice.supportedProfiles.remove(BluetoothProfile.LE_AUDIO); + routingDevice.supportedProfiles.remove(BluetoothProfile.LE_AUDIO); } - mConnectedDevices.put(device, arDevice); - return arDevice; + mConnectedDevices.put(device, routingDevice); + return routingDevice; } /** @@ -451,25 +440,26 @@ public class AudioRoutingManager extends ActiveDeviceManager { * activated together if possible. If there are any activated profiles that can't be * activated together, they will be deactivated. * - * @param arDevice the device of which one or more profiles to be activated + * @param routingDevice the device of which one or more profiles to be activated * @param profile the profile requited to be activated * @return true if any profile was activated or the given profile was already active. */ @SuppressLint("MissingPermission") - public boolean activateDeviceProfile(@NonNull AudioRoutingDevice arDevice, int profile) { - mHandler.removeCallbacksAndMessages(arDevice); + public boolean activateDeviceProfile( + @NonNull AudioRoutingDevice routingDevice, int profile) { + mHandler.removeCallbacksAndMessages(routingDevice); if (DBG) { Log.d( TAG, "activateDeviceProfile(" - + arDevice.device + + routingDevice.device + ", " + BluetoothProfile.getProfileName(profile) + ")"); } List activeDevices = mActiveDevices.get(profile); - if (activeDevices != null && activeDevices.contains(arDevice.device)) { + if (activeDevices != null && activeDevices.contains(routingDevice.device)) { return true; } @@ -487,14 +477,15 @@ public class AudioRoutingManager extends ActiveDeviceManager { case BluetoothProfile.A2DP: profilesToDeactivate.remove(BluetoothProfile.HEADSET); checkLeAudioActive = - !arDevice.supportedProfiles.contains(BluetoothProfile.HEADSET); - if (arDevice.connectedProfiles.contains(BluetoothProfile.HEADSET)) { + !routingDevice.supportedProfiles.contains(BluetoothProfile.HEADSET); + if (routingDevice.connectedProfiles.contains(BluetoothProfile.HEADSET)) { profilesToActivate.add(BluetoothProfile.HEADSET); checkLeAudioActive = true; } if (checkLeAudioActive && Utils.isDualModeAudioEnabled() - && arDevice.connectedProfiles.contains(BluetoothProfile.LE_AUDIO)) { + && routingDevice.connectedProfiles.contains( + BluetoothProfile.LE_AUDIO)) { profilesToActivate.add(BluetoothProfile.LE_AUDIO); profilesToDeactivate.remove(BluetoothProfile.LE_AUDIO); } @@ -502,25 +493,26 @@ public class AudioRoutingManager extends ActiveDeviceManager { case BluetoothProfile.HEADSET: profilesToDeactivate.remove(BluetoothProfile.A2DP); checkLeAudioActive = - !arDevice.supportedProfiles.contains(BluetoothProfile.A2DP); - if (arDevice.connectedProfiles.contains(BluetoothProfile.A2DP)) { + !routingDevice.supportedProfiles.contains(BluetoothProfile.A2DP); + if (routingDevice.connectedProfiles.contains(BluetoothProfile.A2DP)) { profilesToActivate.add(BluetoothProfile.A2DP); checkLeAudioActive = true; } if (checkLeAudioActive && Utils.isDualModeAudioEnabled() - && arDevice.connectedProfiles.contains(BluetoothProfile.LE_AUDIO)) { + && routingDevice.connectedProfiles.contains( + BluetoothProfile.LE_AUDIO)) { profilesToActivate.add(BluetoothProfile.LE_AUDIO); profilesToDeactivate.remove(BluetoothProfile.LE_AUDIO); } break; case BluetoothProfile.LE_AUDIO: if (Utils.isDualModeAudioEnabled()) { - if (arDevice.connectedProfiles.contains(BluetoothProfile.A2DP)) { + if (routingDevice.connectedProfiles.contains(BluetoothProfile.A2DP)) { profilesToActivate.add(BluetoothProfile.A2DP); profilesToDeactivate.remove(BluetoothProfile.A2DP); } - if (arDevice.connectedProfiles.contains(BluetoothProfile.HEADSET)) { + if (routingDevice.connectedProfiles.contains(BluetoothProfile.HEADSET)) { profilesToActivate.add(BluetoothProfile.HEADSET); profilesToDeactivate.remove(BluetoothProfile.HEADSET); } @@ -530,8 +522,8 @@ public class AudioRoutingManager extends ActiveDeviceManager { boolean isAnyProfileActivated = false; for (int p : profilesToActivate) { activeDevices = mActiveDevices.get(p); - if (activeDevices == null || !activeDevices.contains(arDevice.device)) { - isAnyProfileActivated |= setActiveDevice(p, arDevice.device); + if (activeDevices == null || !activeDevices.contains(routingDevice.device)) { + isAnyProfileActivated |= setActiveDevice(p, routingDevice.device); } else { isAnyProfileActivated = true; } @@ -540,9 +532,9 @@ public class AudioRoutingManager extends ActiveDeviceManager { if (!isAnyProfileActivated) return false; if (profilesToActivate.contains(BluetoothProfile.LE_AUDIO) || profilesToActivate.contains(BluetoothProfile.HEARING_AID)) { - // Deactivate activated profiles if it doesn't contain the arDevice. + // Deactivate activated profiles if it doesn't contain the routingDevice. for (int i = 0; i < mActiveDevices.size(); i++) { - if (!mActiveDevices.valueAt(i).contains(arDevice.device)) { + if (!mActiveDevices.valueAt(i).contains(routingDevice.device)) { profilesToDeactivate.add(mActiveDevices.keyAt(i)); } } @@ -665,6 +657,72 @@ public class AudioRoutingManager extends ActiveDeviceManager { return false; } + /** + * Checks whether it is Okay to activate HFP when the device is connected. + * + * @param connectedDevice the connected device + * @return {@code true} if the device should be activated when connected. + */ + private boolean shouldActivateWhenConnected(AudioRoutingDevice connectedDevice) { + BluetoothDevice device = connectedDevice.device; + // HFP only and A2DP only devices should not be automatically activated when connected. + if (connectedDevice.isHfpOnly()) { + Log.i(TAG, "Do not activate HFP only device when connected: " + device); + return false; + } else if (connectedDevice.isA2dpOnly()) { + Log.i(TAG, "Do not activate A2DP only device when connected: " + device); + return false; + } + // If there is an active stream to a remote device, the audio should not be + // automatically activated when connected. + for (int p : connectedDevice.supportedProfiles) { + if (!getActiveDevices(p).isEmpty()) { + BluetoothMethodProxy mp = BluetoothMethodProxy.getInstance(); + if (!mp.mediaSessionManagerGetActiveSessions(mSessionManager).isEmpty() + || mAudioManager.getMode() == AudioManager.MODE_IN_CALL) { + Log.i( + TAG, + "Do not activate the connected device when another device is in" + + " use: " + + device); + return false; + } + } + } + BluetoothClass deviceClass = device.getBluetoothClass(); + if (deviceClass != null + && deviceClass.getDeviceClass() == BluetoothClass.Device.WEARABLE_WRIST_WATCH) { + Log.i(TAG, "Do not set profile active for watch device when connected: " + device); + return false; + } + // Check the audio device policy + HeadsetService service = mFactory.getHeadsetService(); + BluetoothSinkAudioPolicy audioPolicy = service.getHfpCallAudioPolicy(device); + if (audioPolicy != null + && audioPolicy.getActiveDevicePolicyAfterConnection() + == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { + Log.i( + TAG, + "The device's HFP call audio policy doesn't allow it to be activated when" + + " connected: " + + device); + return false; + } + + // Check metadata + byte[] deviceType = + mDbManager.getCustomMeta(device, BluetoothDevice.METADATA_DEVICE_TYPE); + if (deviceType == null) { + return true; + } + String deviceTypeStr = new String(deviceType); + if (deviceTypeStr.equals(BluetoothDevice.DEVICE_TYPE_WATCH)) { + Log.i(TAG, "Do not set profile active for watch device when connected: " + device); + return false; + } + return true; + } + /** * Called when a wired audio device is connected. It might be called multiple times each * time a wired audio device is connected. @@ -693,7 +751,6 @@ public class AudioRoutingManager extends ActiveDeviceManager { public boolean canActivateNow(int profile) { if (!connectedProfiles.contains(profile)) return false; - // TODO: Return false if there are another active remote streaming an audio. return switch (profile) { case BluetoothProfile.HEADSET -> !supportedProfiles.contains( BluetoothProfile.A2DP) @@ -711,6 +768,20 @@ public class AudioRoutingManager extends ActiveDeviceManager { default -> true; }; } + + public boolean isA2dpOnly() { + for (int p : supportedProfiles) { + if (p != BluetoothProfile.A2DP) return false; + } + return true; + } + + public boolean isHfpOnly() { + for (int p : supportedProfiles) { + if (p != BluetoothProfile.HEADSET) return false; + } + return true; + } } } } diff --git a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java index ef1b0011a3df83eaa6973cce1ec7ba579e3c0104..71b4d8d4e71a6be88a217404a7b02585c26a3664 100644 --- a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java +++ b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java @@ -39,6 +39,7 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.a2dpsink.A2dpSinkService; import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.hfpclient.HeadsetClientService; import com.android.bluetooth.hid.HidHostService; @@ -91,6 +92,9 @@ final class BondStateMachine extends StateMachine { public static final String OOBDATAP192 = "oobdatap192"; public static final String OOBDATAP256 = "oobdatap256"; public static final String DISPLAY_PASSKEY = "display_passkey"; + public static final String DELAY_RETRY_COUNT = "delay_retry_count"; + public static final short DELAY_MAX_RETRIES = 30; + public static final int BOND_RETRY_DELAY_MS = 500; @VisibleForTesting Set mPendingBondedDevices = new HashSet<>(); @@ -143,6 +147,41 @@ final class BondStateMachine extends StateMachine { switch (msg.what) { case CREATE_BOND: + /* BOND_BONDED event is send after keys are exchanged, but BTIF layer would + still use bonding control blocks until service discovery is finished. If + next pairing is started while previous still makes service discovery, it + would fail. Check the busy status of BTIF instead, and wait with starting + the bond. */ + if (Flags.delayBondingWhenBusy() + && mAdapterService.getNative().pairingIsBusy()) { + short retry_no = + (msg.getData() != null) + ? msg.getData().getShort(DELAY_RETRY_COUNT) + : 0; + Log.d( + TAG, + "Delay CREATE_BOND because native is busy - attempt no " + + retry_no); + + if (retry_no < DELAY_MAX_RETRIES) { + retry_no++; + + Message new_msg = obtainMessage(); + new_msg.copyFrom(msg); + + if (new_msg.getData() == null) { + Bundle bundle = new Bundle(); + new_msg.setData(bundle); + } + new_msg.getData().putShort(DELAY_RETRY_COUNT, retry_no); + + sendMessageDelayed(new_msg, BOND_RETRY_DELAY_MS); + return true; + } else { + Log.w(TAG, "Native was busy - the bond will most likely fail!"); + } + } + OobData p192Data = (msg.getData() != null) ? msg.getData().getParcelable(OOBDATAP192) : null; OobData p256Data = (msg.getData() != null) diff --git a/android/app/src/com/android/bluetooth/btservice/Config.java b/android/app/src/com/android/bluetooth/btservice/Config.java index c60e412feca0121a3a371296b4dc9db7e85e3347..341fb36cc1f7c543d0910558fd27875fe16c91c3 100644 --- a/android/app/src/com/android/bluetooth/btservice/Config.java +++ b/android/app/src/com/android/bluetooth/btservice/Config.java @@ -51,128 +51,108 @@ import com.android.bluetooth.vc.VolumeControlService; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; -import java.util.HashSet; public class Config { private static final String TAG = "AdapterServiceConfig"; private static final String LE_AUDIO_DYNAMIC_SWITCH_PROPERTY = "ro.bluetooth.leaudio_switcher.supported"; - private static final String LE_AUDIO_BROADCAST_DYNAMIC_SWITCH_PROPERTY = - "ro.bluetooth.leaudio_broadcast_switcher.supported"; private static final String LE_AUDIO_SWITCHER_DISABLED_PROPERTY = "persist.bluetooth.leaudio_switcher.disabled"; + // Three modes, 1. "disabled" - all LE audio feature off. 2. "unicast" - Unicast enabled only. + // 3. "broadcast" - Unicast + broadcast enabled + private static final String LE_AUDIO_DYNAMIC_SWITCHER_MODE_PROPERTY = + "persist.bluetooth.leaudio_dynamic_switcher.mode"; + private static class ProfileConfig { - Class mClass; boolean mSupported; - long mMask; + int mProfileId; - ProfileConfig(Class theClass, boolean supported, long mask) { - mClass = theClass; + ProfileConfig(boolean supported, int profileId) { mSupported = supported; - mMask = mask; + mProfileId = profileId; } } /** List of profile services related to LE audio */ - private static final HashSet LE_AUDIO_UNICAST_PROFILES = - new HashSet( - Arrays.asList( - LeAudioService.class, - VolumeControlService.class, - McpService.class, - CsipSetCoordinatorService.class, - TbsService.class)); - - /** - * List of profile services with the profile-supported resource flag and bit mask. - */ + private static final int[] LE_AUDIO_UNICAST_PROFILES = { + BluetoothProfile.LE_AUDIO, + BluetoothProfile.VOLUME_CONTROL, + BluetoothProfile.CSIP_SET_COORDINATOR, + BluetoothProfile.MCP_SERVER, + BluetoothProfile.LE_CALL_CONTROL, + }; + + /** List of profile services with the profile-supported resource flag and bit mask. */ private static final ProfileConfig[] PROFILE_SERVICES_AND_FLAGS = { - new ProfileConfig(A2dpService.class, A2dpService.isEnabled(), - (1 << BluetoothProfile.A2DP)), - new ProfileConfig(A2dpSinkService.class, A2dpSinkService.isEnabled(), - (1 << BluetoothProfile.A2DP_SINK)), - new ProfileConfig(AvrcpTargetService.class, AvrcpTargetService.isEnabled(), - (1 << BluetoothProfile.AVRCP)), - new ProfileConfig(AvrcpControllerService.class, AvrcpControllerService.isEnabled(), - (1 << BluetoothProfile.AVRCP_CONTROLLER)), - new ProfileConfig(BassClientService.class, BassClientService.isEnabled(), - (1 << BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)), - new ProfileConfig(BatteryService.class, BatteryService.isEnabled(), - (1 << BluetoothProfile.BATTERY)), - new ProfileConfig(CsipSetCoordinatorService.class, - CsipSetCoordinatorService.isEnabled(), - (1 << BluetoothProfile.CSIP_SET_COORDINATOR)), - new ProfileConfig(HapClientService.class, HapClientService.isEnabled(), - (1 << BluetoothProfile.HAP_CLIENT)), - new ProfileConfig(HeadsetService.class, HeadsetService.isEnabled(), - (1 << BluetoothProfile.HEADSET)), - new ProfileConfig(HeadsetClientService.class, HeadsetClientService.isEnabled(), - (1 << BluetoothProfile.HEADSET_CLIENT)), - new ProfileConfig(HearingAidService.class, HearingAidService.isEnabled(), - (1 << BluetoothProfile.HEARING_AID)), - new ProfileConfig(HidDeviceService.class, HidDeviceService.isEnabled(), - (1 << BluetoothProfile.HID_DEVICE)), - new ProfileConfig(HidHostService.class, HidHostService.isEnabled(), - (1 << BluetoothProfile.HID_HOST)), - new ProfileConfig(GattService.class, GattService.isEnabled(), - (1 << BluetoothProfile.GATT)), - new ProfileConfig(LeAudioService.class, LeAudioService.isEnabled(), - (1 << BluetoothProfile.LE_AUDIO)), - new ProfileConfig(TbsService.class, TbsService.isEnabled(), - (1 << BluetoothProfile.LE_CALL_CONTROL)), - new ProfileConfig(BluetoothMapService.class, BluetoothMapService.isEnabled(), - (1 << BluetoothProfile.MAP)), - new ProfileConfig(MapClientService.class, MapClientService.isEnabled(), - (1 << BluetoothProfile.MAP_CLIENT)), - new ProfileConfig(McpService.class, McpService.isEnabled(), - (1 << BluetoothProfile.MCP_SERVER)), - new ProfileConfig(BluetoothOppService.class, BluetoothOppService.isEnabled(), - (1 << BluetoothProfile.OPP)), - new ProfileConfig(PanService.class, PanService.isEnabled(), - (1 << BluetoothProfile.PAN)), - new ProfileConfig(BluetoothPbapService.class, BluetoothPbapService.isEnabled(), - (1 << BluetoothProfile.PBAP)), - new ProfileConfig(PbapClientService.class, PbapClientService.isEnabled(), - (1 << BluetoothProfile.PBAP_CLIENT)), - new ProfileConfig(SapService.class, SapService.isEnabled(), - (1 << BluetoothProfile.SAP)), - new ProfileConfig(VolumeControlService.class, VolumeControlService.isEnabled(), - (1 << BluetoothProfile.VOLUME_CONTROL)), + new ProfileConfig(A2dpService.isEnabled(), BluetoothProfile.A2DP), + new ProfileConfig(A2dpSinkService.isEnabled(), BluetoothProfile.A2DP_SINK), + new ProfileConfig(AvrcpTargetService.isEnabled(), BluetoothProfile.AVRCP), + new ProfileConfig(AvrcpControllerService.isEnabled(), BluetoothProfile.AVRCP_CONTROLLER), + new ProfileConfig( + BassClientService.isEnabled(), BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT), + new ProfileConfig(BatteryService.isEnabled(), BluetoothProfile.BATTERY), + new ProfileConfig( + CsipSetCoordinatorService.isEnabled(), BluetoothProfile.CSIP_SET_COORDINATOR), + new ProfileConfig(HapClientService.isEnabled(), BluetoothProfile.HAP_CLIENT), + new ProfileConfig(HeadsetService.isEnabled(), BluetoothProfile.HEADSET), + new ProfileConfig(HeadsetClientService.isEnabled(), BluetoothProfile.HEADSET_CLIENT), + new ProfileConfig(HearingAidService.isEnabled(), BluetoothProfile.HEARING_AID), + new ProfileConfig(HidDeviceService.isEnabled(), BluetoothProfile.HID_DEVICE), + new ProfileConfig(HidHostService.isEnabled(), BluetoothProfile.HID_HOST), + new ProfileConfig(GattService.isEnabled(), BluetoothProfile.GATT), + new ProfileConfig(LeAudioService.isEnabled(), BluetoothProfile.LE_AUDIO), + new ProfileConfig(LeAudioService.isBroadcastEnabled(), BluetoothProfile.LE_AUDIO_BROADCAST), + new ProfileConfig(TbsService.isEnabled(), BluetoothProfile.LE_CALL_CONTROL), + new ProfileConfig(BluetoothMapService.isEnabled(), BluetoothProfile.MAP), + new ProfileConfig(MapClientService.isEnabled(), BluetoothProfile.MAP_CLIENT), + new ProfileConfig(McpService.isEnabled(), BluetoothProfile.MCP_SERVER), + new ProfileConfig(BluetoothOppService.isEnabled(), BluetoothProfile.OPP), + new ProfileConfig(PanService.isEnabled(), BluetoothProfile.PAN), + new ProfileConfig(BluetoothPbapService.isEnabled(), BluetoothProfile.PBAP), + new ProfileConfig(PbapClientService.isEnabled(), BluetoothProfile.PBAP_CLIENT), + new ProfileConfig(SapService.isEnabled(), BluetoothProfile.SAP), + new ProfileConfig(VolumeControlService.isEnabled(), BluetoothProfile.VOLUME_CONTROL), }; - /** - * A test function to allow for dynamic enabled - */ + /** A test function to allow for dynamic enabled */ @VisibleForTesting - public static void setProfileEnabled(Class profileClass, boolean enabled) { - if (profileClass == null) { - return; - } + public static void setProfileEnabled(int profileId, boolean enabled) { for (ProfileConfig profile : PROFILE_SERVICES_AND_FLAGS) { - if (profileClass.equals(profile.mClass)) { + if (profileId == profile.mProfileId) { profile.mSupported = enabled; + break; } } } static void init(Context ctx) { if (LeAudioService.isBroadcastEnabled()) { - updateSupportedProfileMask( - true, LeAudioService.class, BluetoothProfile.LE_AUDIO_BROADCAST); - } - - final boolean leAudioDynamicSwitchSupported = - SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_SWITCH_PROPERTY, false); - - if (leAudioDynamicSwitchSupported) { - final String leAudioSwitcherDisabled = SystemProperties - .get(LE_AUDIO_SWITCHER_DISABLED_PROPERTY, "none"); - if (leAudioSwitcherDisabled.equals("true")) { + final String leAudioSwitcherMode = + SystemProperties.get(LE_AUDIO_DYNAMIC_SWITCHER_MODE_PROPERTY, "none"); + if (leAudioSwitcherMode.equals("disabled")) { setLeAudioProfileStatus(false); - } else if (leAudioSwitcherDisabled.equals("false")) { + setLeAudioBroadcastProfileStatus(false); + } else if (leAudioSwitcherMode.equals("unicast")) { + setLeAudioProfileStatus(true); + setLeAudioBroadcastProfileStatus(false); + } else if (leAudioSwitcherMode.equals("broadcast")) { setLeAudioProfileStatus(true); + setLeAudioBroadcastProfileStatus(true); + } + } else if (LeAudioService.isEnabled()) { + final boolean leAudioDynamicSwitchSupported = + SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_SWITCH_PROPERTY, false); + + if (leAudioDynamicSwitchSupported) { + final String leAudioSwitcherDisabled = + SystemProperties.get(LE_AUDIO_SWITCHER_DISABLED_PROPERTY, "none"); + if (leAudioSwitcherDisabled.equals("true")) { + setLeAudioProfileStatus(false); + } else if (leAudioSwitcherDisabled.equals("false")) { + setLeAudioProfileStatus(true); + } } } @@ -181,14 +161,14 @@ public class Config { // platforms can choose to enable ASHA themselves if (BluetoothProperties.isProfileAshaCentralEnabled().isEmpty()) { if (Utils.isAutomotive(ctx) || Utils.isTv(ctx) || Utils.isWatch(ctx)) { - setProfileEnabled(HearingAidService.class, false); + setProfileEnabled(BluetoothProfile.HEARING_AID, false); } } // Disable ASHA if BLE is not supported on this platform even if the platform enabled ASHA // accidentally if (!Utils.isBleSupported(ctx)) { - setProfileEnabled(HearingAidService.class, false); + setProfileEnabled(BluetoothProfile.HEARING_AID, false); } for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) { @@ -196,57 +176,42 @@ public class Config { TAG, String.format( "init: profile=%s, enabled=%s", - config.mClass.getSimpleName(), config.mSupported)); + BluetoothProfile.getProfileName(config.mProfileId), config.mSupported)); } } static void setLeAudioProfileStatus(Boolean enable) { - setProfileEnabled(CsipSetCoordinatorService.class, enable); - setProfileEnabled(HapClientService.class, enable); - setProfileEnabled(LeAudioService.class, enable); - setProfileEnabled(TbsService.class, enable); - setProfileEnabled(McpService.class, enable); - setProfileEnabled(VolumeControlService.class, enable); - - final boolean broadcastDynamicSwitchSupported = - SystemProperties.getBoolean(LE_AUDIO_BROADCAST_DYNAMIC_SWITCH_PROPERTY, false); - - if (broadcastDynamicSwitchSupported) { - setProfileEnabled(BassClientService.class, enable); - updateSupportedProfileMask( - enable, LeAudioService.class, BluetoothProfile.LE_AUDIO_BROADCAST); - } + setProfileEnabled(BluetoothProfile.CSIP_SET_COORDINATOR, enable); + setProfileEnabled(BluetoothProfile.HAP_CLIENT, enable); + setProfileEnabled(BluetoothProfile.LE_AUDIO, enable); + setProfileEnabled(BluetoothProfile.LE_CALL_CONTROL, enable); + setProfileEnabled(BluetoothProfile.MCP_SERVER, enable); + setProfileEnabled(BluetoothProfile.VOLUME_CONTROL, enable); } - static void updateSupportedProfileMask(Boolean enable, Class profile, int supportedProfile) { - for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) { - if (config.mClass == profile) { - if (enable) { - config.mMask |= 1 << supportedProfile; - } else { - config.mMask &= ~(1 << supportedProfile); - } - return; - } - } + static void setLeAudioBroadcastProfileStatus(Boolean enable) { + setProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, enable); + setProfileEnabled(BluetoothProfile.LE_AUDIO_BROADCAST, enable); } - static HashSet getLeAudioUnicastProfiles() { + static int[] getLeAudioUnicastProfiles() { return LE_AUDIO_UNICAST_PROFILES; } - static Class[] getSupportedProfiles() { + static int[] getSupportedProfiles() { return Arrays.stream(PROFILE_SERVICES_AND_FLAGS) .filter(config -> config.mSupported) - .map(config -> config.mClass) - .toArray(Class[]::new); + .mapToInt(config -> config.mProfileId) + // LE_AUDIO_BROADCAST don't have an associated class + .filter(profileId -> profileId != BluetoothProfile.LE_AUDIO_BROADCAST) + .toArray(); } static long getSupportedProfilesBitMask() { long mask = 0; for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) { if (config.mSupported) { - mask |= config.mMask; + mask |= (1L << config.mProfileId); } } return mask; diff --git a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java index de0e943972bbe70003eaabe5d66bbf4ad659c703..6f88f02ed6e6eed84d262a44746a3884ed999445 100644 --- a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java +++ b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java @@ -19,6 +19,8 @@ package com.android.bluetooth.btservice; import android.bluetooth.OobData; import android.bluetooth.UidTraffic; +import com.android.bluetooth.flags.Flags; + class JniCallbacks { private RemoteDevices mRemoteDevices; @@ -66,6 +68,9 @@ class JniCallbacks { void bondStateChangeCallback(int status, byte[] address, int newState, int hciReason) { mBondStateMachine.bondStateChangeCallback(status, address, newState, hciReason); + if (Flags.removeBondWithAddressMap()) { + mRemoteDevices.onBondStateChange(address, newState); + } } void addressConsolidateCallback(byte[] mainAddress, byte[] secondaryAddress) { @@ -82,6 +87,10 @@ class JniCallbacks { transportLinkType, hciReason, handle); } + void keyMissingCallback(byte[] address) { + mRemoteDevices.keyMissingCallback(address); + } + void stateChangeCallback(int status) { mAdapterService.stateChangeCallback(status); } diff --git a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java index ea4c1fd102e2af0d9040aab515e7a8d7817c15e8..f978c344aef40cd139a08f46f94eae2845e01242 100644 --- a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +++ b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java @@ -38,7 +38,7 @@ import com.android.bluetooth.bas.BatteryService; import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorService; -import com.android.bluetooth.flags.FeatureFlags; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; @@ -84,7 +84,6 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { @VisibleForTesting static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s private DatabaseManager mDatabaseManager; - private final FeatureFlags mFeatureFlags; private final AdapterService mAdapterService; private final ServiceFactory mFactory; private final Handler mHandler; @@ -158,7 +157,7 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { ; // Policy API functions for lifecycle management (protected) - protected void start() { + public void start() { mAdapterService.registerBluetoothStateCallback((command) -> mHandler.post(command), this); IntentFilter filter = new IntentFilter(); @@ -166,16 +165,15 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); } - protected void cleanup() { + public void cleanup() { mAdapterService.unregisterBluetoothStateCallback(this); resetStates(); } - PhonePolicy(AdapterService service, ServiceFactory factory, FeatureFlags featureFlags) { + PhonePolicy(AdapterService service, ServiceFactory factory) { mAdapterService = service; mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), "DatabaseManager cannot be null when PhonePolicy starts"); - mFeatureFlags = Objects.requireNonNull(featureFlags, "Feature Flags cannot be null"); mFactory = factory; mHandler = new PhonePolicyHandler(service.getMainLooper()); mAutoConnectProfilesSupported = @@ -646,12 +644,12 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { return; } - if (!mFeatureFlags.autoConnectOnHfpWhenNoA2dpDevice()) { + if (!Flags.autoConnectOnHfpWhenNoA2dpDevice()) { debugLog("HFP auto connect is not enabled"); return; } - if (mFeatureFlags.autoConnectOnMultipleHfpWhenNoA2dpDevice()) { + if (Flags.autoConnectOnMultipleHfpWhenNoA2dpDevice()) { final List mostRecentlyConnectedHfpDevices = mDatabaseManager.getMostRecentlyActiveHfpDevices(); for (BluetoothDevice hfpDevice : mostRecentlyConnectedHfpDevices) { diff --git a/android/app/src/com/android/bluetooth/btservice/ProfileService.java b/android/app/src/com/android/bluetooth/btservice/ProfileService.java index e0268a2b34f520f89c8095b8b18aeb562f0defe9..3190463e71306f9935cd47a8d2119a7c59987835 100644 --- a/android/app/src/com/android/bluetooth/btservice/ProfileService.java +++ b/android/app/src/com/android/bluetooth/btservice/ProfileService.java @@ -16,28 +16,22 @@ package com.android.bluetooth.btservice; -import static android.Manifest.permission.BLUETOOTH_CONNECT; import static java.util.Objects.requireNonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; -import android.app.Service; -import android.bluetooth.BluetoothAdapter; import android.content.ComponentName; import android.content.Context; -import android.content.Intent; +import android.content.ContextWrapper; import android.content.pm.PackageManager; import android.os.IBinder; import android.util.Log; import com.android.bluetooth.BluetoothMetricsProto; -import com.android.internal.annotations.VisibleForTesting; -/** - * Base class for a background service that runs a Bluetooth profile - */ -public abstract class ProfileService extends Service { +/** Base class for a background service that runs a Bluetooth profile */ +public abstract class ProfileService extends ContextWrapper { private static final boolean DBG = false; public static final String BLUETOOTH_PERM = @@ -46,20 +40,13 @@ public abstract class ProfileService extends Service { android.Manifest.permission.BLUETOOTH_PRIVILEGED; public interface IProfileServiceBinder extends IBinder { - /** - * Called in {@link #onDestroy()} - */ void cleanup(); } - //Profile services will not be automatically restarted. - //They must be explicitly restarted by AdapterService - private static final int PROFILE_SERVICE_MODE = Service.START_NOT_STICKY; - private BluetoothAdapter mAdapter; - private IProfileServiceBinder mBinder; + private final IProfileServiceBinder mBinder; private final String mName; private AdapterService mAdapterService; - private boolean mProfileStarted = false; + private boolean mAvailable = false; private volatile boolean mTestModeEnabled = false; public String getName() { @@ -67,7 +54,11 @@ public abstract class ProfileService extends Service { } public boolean isAvailable() { - return mProfileStarted; + return mAvailable; + } + + public void setAvailable(boolean available) { + mAvailable = available; } protected boolean isTestModeEnabled() { @@ -75,128 +66,42 @@ public abstract class ProfileService extends Service { } /** - * Called in {@link #onCreate()} to init binder interface for this profile service + * Called in ProfileService constructor to init binder interface for this profile service * * @return initialized binder interface for this profile service */ protected abstract IProfileServiceBinder initBinder(); - /** - * Called in {@link #onStartCommand(Intent, int, int)} when the service is started by intent - * - * @return True in successful condition, False otherwise - */ - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - protected abstract boolean start(); + /** Start service */ + public abstract void start(); - /** - * Called in {@link #onStartCommand(Intent, int, int)} when the service is stopped by intent - * - * @return True in successful condition, False otherwise - */ - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - protected abstract boolean stop(); + /** Stop service */ + public abstract void stop(); - /** - * Called in {@link #onDestroy()} when this object is completely discarded - */ - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - protected void cleanup() {} + /** Called when this object is completely discarded */ + public void cleanup() {} /** * @param testModeEnabled if the profile should enter or exit a testing mode */ - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") protected void setTestModeEnabled(boolean testModeEnabled) { mTestModeEnabled = testModeEnabled; } - protected ProfileService() { - mName = getName(); - } - protected ProfileService(Context ctx) { - this(); - attachBaseContext(ctx); - onCreate(); - } - - @Override - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - public void onCreate() { - if (DBG) { - Log.d(mName, "onCreate"); - } - super.onCreate(); - mAdapter = BluetoothAdapter.getDefaultAdapter(); - mBinder = initBinder(); - } - - @Override - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - public int onStartCommand(Intent intent, int flags, int startId) { - if (DBG) { - Log.d(mName, "onStartCommand()"); - } - - if (checkCallingOrSelfPermission(BLUETOOTH_CONNECT) - != PackageManager.PERMISSION_GRANTED) { - Log.e(mName, "Permission denied!"); - return PROFILE_SERVICE_MODE; - } - - if (intent == null) { - Log.d(mName, "onStartCommand ignoring null intent."); - return PROFILE_SERVICE_MODE; - } - - String action = intent.getStringExtra(AdapterService.EXTRA_ACTION); - if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) { - int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); - if (state == BluetoothAdapter.STATE_OFF) { - doStop(); - } else if (state == BluetoothAdapter.STATE_ON) { - doStart(); - } - } - return PROFILE_SERVICE_MODE; - } - - @Override - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - public IBinder onBind(Intent intent) { + super(ctx); + mName = getName(); if (DBG) { - Log.d(mName, "onBind"); + Log.d(mName, "Service created"); } - if (mAdapter != null && mBinder == null) { - // initBinder returned null, you can't bind - throw new UnsupportedOperationException("Cannot bind to " + mName); - } - return mBinder; + mBinder = requireNonNull(initBinder(), "Binder null is not allowed for " + mName); } - IBinder getBinder() { - requireNonNull(mBinder, "Binder is null. onCreate need to be called first"); + /** return the binder of the profile */ + public IProfileServiceBinder getBinder() { return mBinder; } - @Override - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - public boolean onUnbind(Intent intent) { - if (DBG) { - Log.d(mName, "onUnbind"); - } - return super.onUnbind(intent); - } - /** * Set the availability of an owned/managed component (Service, Activity, Provider, etc.) * using a string class name assumed to be in the Bluetooth package. @@ -282,76 +187,4 @@ public abstract class ProfileService extends Service { sb.append(s); sb.append("\n"); } - - @Override - // Suppressed since this is called from framework - @SuppressLint("AndroidFrameworkRequiresPermission") - public void onDestroy() { - Log.v(mName, "onDestroy"); - cleanup(); - if (mBinder != null) { - mBinder.cleanup(); - mBinder = null; - } - mAdapter = null; - super.onDestroy(); - } - - /** start the profile and inform AdapterService */ - @RequiresPermission( - anyOf = { - android.Manifest.permission.MANAGE_USERS, - android.Manifest.permission.INTERACT_ACROSS_USERS - }) - @VisibleForTesting - public void doStart() { - Log.v(mName, "doStart"); - if (mAdapter == null) { - Log.w(mName, "Can't start profile service: device does not have BT"); - return; - } - - mAdapterService = AdapterService.getAdapterService(); - if (mAdapterService == null) { - Log.w(mName, "Could not add this profile because AdapterService is null."); - return; - } - if (!mAdapterService.isStartedProfile(mName)) { - Log.w(mName, "Unexpectedly do Start, don't start"); - return; - } - mAdapterService.addProfile(this); - - mProfileStarted = start(); - if (!mProfileStarted) { - Log.e(mName, "Error starting profile. start() returned false."); - return; - } - mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON); - } - - /** stop the profile and inform AdapterService */ - @VisibleForTesting - public void doStop() { - Log.v(mName, "doStop"); - if (mAdapterService == null || mAdapterService.isStartedProfile(mName)) { - Log.w(mName, "Unexpectedly do Stop, don't stop."); - return; - } - if (!mProfileStarted) { - Log.w(mName, "doStop() called, but the profile is not running."); - return; - } - mProfileStarted = false; - if (mAdapterService != null) { - mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_OFF); - } - if (!stop()) { - Log.e(mName, "Unable to stop profile"); - } - if (mAdapterService != null) { - mAdapterService.removeProfile(this); - } - stopSelf(); - } } diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index 7d73eb889b4452b97b851bf257e6b34c43c9ab8d..78222668e33dd17b62d8400da60f5a9957b5d9df 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -17,6 +17,7 @@ package com.android.bluetooth.btservice; import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; import static android.Manifest.permission.BLUETOOTH_SCAN; import android.annotation.RequiresPermission; @@ -46,6 +47,7 @@ import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.bas.BatteryService; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetHalConstants; import com.android.internal.annotations.VisibleForTesting; @@ -232,6 +234,10 @@ public class RemoteDevices { } DeviceProperties getDeviceProperties(BluetoothDevice device) { + if (device == null) { + return null; + } + synchronized (mDevices) { String address = mDualDevicesMap.get(device.getAddress()); // If the device is not in the dual map, use its original address @@ -1149,13 +1155,7 @@ public class RemoteDevices { Utils.sendBroadcast(mAdapterService, intent, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions()); } else if (device.getBondState() == BluetoothDevice.BOND_NONE) { - String key = Utils.getAddressStringFromByte(address); - mDevices.remove(key); - mDeviceQueue.remove(key); // Remove from LRU cache - - // Remove from dual mode device mappings - mDualDevicesMap.values().remove(key); - mDualDevicesMap.remove(key); + removeAddressMapping(address); } if (state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_TURNING_OFF) { mAdapterService.notifyAclDisconnected(device, transportLinkType); @@ -1238,6 +1238,51 @@ public class RemoteDevices { } } + private void removeAddressMapping(byte[] address) { + String key = Utils.getAddressStringFromByte(address); + synchronized (mDevices) { + mDevices.remove(key); + mDeviceQueue.remove(key); // Remove from LRU cache + + // Remove from dual mode device mappings + mDualDevicesMap.values().remove(key); + mDualDevicesMap.remove(key); + } + } + + void onBondStateChange(byte[] address, int newState) { + if (newState == BluetoothDevice.BOND_NONE) { + removeAddressMapping(address); + } + } + + void keyMissingCallback(byte[] address) { + BluetoothDevice bluetoothDevice = getDevice(address); + if (bluetoothDevice == null) { + errorLog( + "keyMissingCallback: device is NULL, address=" + + Utils.getRedactedAddressStringFromByte(address)); + return; + } + Log.d(TAG, "keyMissingCallback device: " + bluetoothDevice); + + if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) { + if (!Flags.keyMissingBroadcast()) { + Log.d(TAG, "flag not set - don't send key missing broadcast"); + return; + } + Intent intent = + new Intent(BluetoothDevice.ACTION_KEY_MISSING) + .putExtra(BluetoothDevice.EXTRA_DEVICE, bluetoothDevice) + .addFlags( + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + mAdapterService.sendBroadcastMultiplePermissions( + intent, + new String[] {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}, + Utils.getTempBroadcastOptions()); + } + } void fetchUuids(BluetoothDevice device, int transport) { if (mSdpTracker.contains(device)) { diff --git a/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java index e2f076558dda129bd6f0927007a35bba4ea520f4..c100a45495873641366409ac70b86ccb31744c82 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/CustomizedMetadataEntity.java @@ -49,6 +49,7 @@ class CustomizedMetadataEntity { public byte[] le_audio; public byte[] gmcs_cccd; public byte[] gtbs_cccd; + public byte[] exclusive_manager; public String toString() { StringBuilder builder = new StringBuilder(); @@ -109,8 +110,9 @@ class CustomizedMetadataEntity { .append("|gmcs_cccd=") .append(metadataToString(gmcs_cccd)) .append("|gtbs_cccd=") - .append(metadataToString(gtbs_cccd)); - + .append(metadataToString(gtbs_cccd)) + .append("|exclusive_manager=") + .append(metadataToString(exclusive_manager)); return builder.toString(); } diff --git a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java index 7c9f1d8823f8d7f1c71430f12b6b977d76a2aba8..cf23cf706d4e31045abd2fcf44a936af91abc269 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java @@ -42,7 +42,7 @@ import android.util.Log; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; -import com.android.bluetooth.flags.FeatureFlags; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -68,7 +68,6 @@ public class DatabaseManager { private static final String TAG = "BluetoothDatabase"; private final AdapterService mAdapterService; - private final FeatureFlags mFeatureFlags; private HandlerThread mHandlerThread = null; private Handler mHandler = null; private final Object mDatabaseLock = new Object(); @@ -114,9 +113,8 @@ public class DatabaseManager { LEGACY_HEARING_AID_PRIORITY_PREFIX = "bluetooth_hearing_aid_priority_"; /** Constructor of the DatabaseManager */ - public DatabaseManager(AdapterService service, FeatureFlags featureFlags) { + public DatabaseManager(AdapterService service) { mAdapterService = Objects.requireNonNull(service, "Adapter service cannot be null"); - mFeatureFlags = Objects.requireNonNull(featureFlags, "Feature Flags cannot be null"); mMetadataChangedLog = EvictingQueue.create(METADATA_CHANGED_LOG_MAX_SIZE); } @@ -648,7 +646,7 @@ public class DatabaseManager { if (isA2dpDevice) { resetActiveA2dpDevice(); } - if (isHfpDevice && !mFeatureFlags.autoConnectOnMultipleHfpWhenNoA2dpDevice()) { + if (isHfpDevice && !Flags.autoConnectOnMultipleHfpWhenNoA2dpDevice()) { resetActiveHfpDevice(); } @@ -1014,6 +1012,60 @@ public class DatabaseManager { return modeToProfileBundle; } + /** + * Set the device active audio policy. See {@link + * BluetoothDevice#setActiveAudioDevicePolicy(activeAudioDevicePolicy)} for more details. + * + * @param device is the remote device for which we are setting the active audio device policy. + * @param activeAudioDevicePolicy active audio device policy. + * @return whether the policy was set properly + */ + public int setActiveAudioDevicePolicy(BluetoothDevice device, int activeAudioDevicePolicy) { + synchronized (mMetadataCache) { + String address = device.getAddress(); + + if (!mMetadataCache.containsKey(address)) { + Log.e(TAG, "device is not bonded"); + return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED; + } + + Metadata metadata = mMetadataCache.get(address); + Log.i( + TAG, + "Updating active_audio_device_policy setting for " + + "device " + + device + + " to: " + + activeAudioDevicePolicy); + metadata.active_audio_device_policy = activeAudioDevicePolicy; + + updateDatabase(metadata); + } + return BluetoothStatusCodes.SUCCESS; + } + + /** + * Get the active audio device policy for this device. See {@link + * BluetoothDevice#getActiveAudioDevicePolicy()} for more details. + * + * @param device is the device for which we want to get the policy + * @return active audio device policy for this device + */ + public int getActiveAudioDevicePolicy(BluetoothDevice device) { + synchronized (mMetadataCache) { + String address = device.getAddress(); + + if (!mMetadataCache.containsKey(address)) { + Log.e(TAG, "device is not bonded"); + return BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT; + } + + Metadata metadata = mMetadataCache.get(address); + + return metadata.active_audio_device_policy; + } + } + /** * Get the {@link Looper} for the handler thread. This is used in testing and helper * objects diff --git a/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java b/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java index 34d73cd690e68d3e2f6fb818a4aaffa3f62d3f1e..6dcf5546c0dedc9adc40c17e198a5e720221902d 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/Metadata.java @@ -79,6 +79,9 @@ public class Metadata { */ public int preferred_duplex_profile; + /** This is used to indicate whether device's active audio policy */ + public int active_audio_device_policy; + Metadata(String address) { this(address, false, false); } @@ -96,6 +99,7 @@ public class Metadata { audioPolicyMetadata = new AudioPolicyEntity(); preferred_output_only_profile = 0; preferred_duplex_profile = 0; + active_audio_device_policy = BluetoothDevice.ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT; } static final class Builder { @@ -349,6 +353,9 @@ public class Metadata { case BluetoothDevice.METADATA_GTBS_CCCD: publicMetadata.gtbs_cccd = value; break; + case BluetoothDevice.METADATA_EXCLUSIVE_MANAGER: + publicMetadata.exclusive_manager = value; + break; } } @@ -446,6 +453,9 @@ public class Metadata { case BluetoothDevice.METADATA_GTBS_CCCD: value = publicMetadata.gtbs_cccd; break; + case BluetoothDevice.METADATA_EXCLUSIVE_MANAGER: + value = publicMetadata.exclusive_manager; + break; } return value; } diff --git a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java index a27845c43d69ea9ffef5244d944ddebc8c0db81d..fd580b00fc5a979766750d142fe2bf4044da0795 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/MetadataDatabase.java @@ -33,7 +33,7 @@ import java.util.List; /** MetadataDatabase is a Room database stores Bluetooth persistence data */ @Database( entities = {Metadata.class}, - version = 118) + version = 120) public abstract class MetadataDatabase extends RoomDatabase { /** The metadata database file name */ public static final String DATABASE_NAME = "bluetooth_db"; @@ -68,6 +68,8 @@ public abstract class MetadataDatabase extends RoomDatabase { .addMigrations(MIGRATION_115_116) .addMigrations(MIGRATION_116_117) .addMigrations(MIGRATION_117_118) + .addMigrations(MIGRATION_118_119) + .addMigrations(MIGRATION_119_120) .allowMainThreadQueries() .build(); } @@ -630,4 +632,43 @@ public abstract class MetadataDatabase extends RoomDatabase { } } }; + + @VisibleForTesting + static final Migration MIGRATION_118_119 = + new Migration(118, 119) { + @Override + public void migrate(SupportSQLiteDatabase database) { + try { + database.execSQL( + "ALTER TABLE metadata ADD COLUMN `exclusive_manager` BLOB"); + } catch (SQLException ex) { + // Check if user has new schema, but is just missing the version update + Cursor cursor = database.query("SELECT * FROM metadata"); + if (cursor == null || cursor.getColumnIndex("exclusive_manager") == -1) { + throw ex; + } + } + } + }; + + @VisibleForTesting + static final Migration MIGRATION_119_120 = + new Migration(119, 120) { + @Override + public void migrate(SupportSQLiteDatabase database) { + try { + database.execSQL( + "ALTER TABLE metadata ADD COLUMN" + + " `active_audio_device_policy` INTEGER NOT NULL" + + " DEFAULT 0"); + } catch (SQLException ex) { + // Check if user has new schema, but is just missing the version update + Cursor cursor = database.query("SELECT * FROM metadata"); + if (cursor == null + || cursor.getColumnIndex("active_audio_device_policy") == -1) { + throw ex; + } + } + } + }; } diff --git a/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java b/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..e8a67acbb3d2047ece83aef398a42177611d9fce --- /dev/null +++ b/android/app/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtils.java @@ -0,0 +1,78 @@ +/* + * Copyright 2023 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.bluetooth.content_profiles; + +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; +import android.os.SystemClock; +import android.util.Log; + +import com.android.bluetooth.BluetoothStatsLog; +import com.android.internal.annotations.VisibleForTesting; + +/** + * Utility method to report exceptions and error/warn logs in content profiles. + */ +public class ContentProfileErrorReportUtils { + private static final String TAG = ContentProfileErrorReportUtils.class.getSimpleName(); + + /* Minimum period between two error reports */ + @VisibleForTesting static final long MIN_PERIOD_BETWEEN_TWO_ERROR_REPORTS_MILLIS = 1_000; + + @VisibleForTesting static long sLastReportTime = 0; + + /** + * Report error by writing BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED atom. A + * report will be skipped if not enough time has passed from the last report. + * + * @param profile One of: {@link BluetoothProfile#PBAP}, {@link BluetoothProfile#MAP}, {@link + * BluetoothProfile#OPP} + * @param fileNameEnum File name enum which is declared in {@link BluetoothProtoEnums} + * @param type One of the following: {@link + * BluetoothStatsLog#BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION}, {@link + * BluetoothStatsLog#BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR}, {@link + * BluetoothStatsLog#BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN} + * @param tag A tag which represents the code location of this error. The values are managed per + * each java file. + * @return true if successfully wrote the error, false otherwise + */ + public static synchronized boolean report(int profile, int fileNameEnum, int type, int tag) { + if (isTooFrequentReport()) { + Log.w( + TAG, + "Skipping reporting this error to prevent flooding." + + " fileNameEnum=" + + fileNameEnum + + ", tag=" + + tag); + return false; + } + + BluetoothStatsLog.write( + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED, + profile, + fileNameEnum, + type, + tag); + sLastReportTime = SystemClock.uptimeMillis(); + return true; + } + + private static boolean isTooFrequentReport() { + return SystemClock.uptimeMillis() - sLastReportTime + < MIN_PERIOD_BETWEEN_TWO_ERROR_REPORTS_MILLIS; + } +} diff --git a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java index 114193d8e1a475b6441f7c4043b9a4ecff86fd34..9494b10faa2c897835be6cfcdd4f66b6c9114d5d 100644 --- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java +++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java @@ -109,10 +109,7 @@ public class CsipSetCoordinatorService extends ProfileService { private final Map> mLocks = new ConcurrentHashMap<>(); - CsipSetCoordinatorService() {} - - @VisibleForTesting - CsipSetCoordinatorService(Context ctx) { + public CsipSetCoordinatorService(Context ctx) { super(ctx); } @@ -126,7 +123,7 @@ public class CsipSetCoordinatorService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -166,17 +163,16 @@ public class CsipSetCoordinatorService extends ProfileService { // Initialize native interface mCsipSetCoordinatorNativeInterface.init(); - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sCsipSetCoordinatorService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } // Cleanup native interface @@ -223,12 +219,10 @@ public class CsipSetCoordinatorService extends ProfileService { // Clear AdapterService, CsipSetCoordinatorNativeInterface mCsipSetCoordinatorNativeInterface = null; mAdapterService = null; - - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java index 46b1ef94fce3bb48d187a1c3c98c29613ff45b59..aa41bf5faa6a95ae34a8bd3c487d7a9697eee37d 100644 --- a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java +++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java @@ -184,7 +184,8 @@ public class AdvertiseManager { AppAdvertiseStats.recordAdvertiseErrorCount(LE_ADV_ERROR_ON_START_COUNT); } - callback.onAdvertisingSetStarted(advertiserId, txPower, status); + IBinder gattBinder = mService.getBinder(); + callback.onAdvertisingSetStarted(gattBinder, advertiserId, txPower, status); } void onAdvertisingEnabled(int advertiserId, boolean enable, int status) throws Exception { @@ -221,8 +222,9 @@ public class AdvertiseManager { != AdvertisingSetParameters.ADDRESS_TYPE_RANDOM_NON_RESOLVABLE) { Log.w(TAG, "Cannot advertise an isolated GATT server using a resolvable address"); try { + IBinder gattBinder = mService.getBinder(); callback.onAdvertisingSetStarted( - 0x00, 0x00, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR); + gattBinder, 0x00, 0x00, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR); } catch (RemoteException exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } @@ -231,7 +233,7 @@ public class AdvertiseManager { int appUid = Binder.getCallingUid(); String packageName = null; - if (mService != null && mService.getPackageManager() != null) { + if (mService.getPackageManager() != null) { packageName = mService.getPackageManager().getNameForUid(appUid); } if (packageName == null) { @@ -279,8 +281,9 @@ public class AdvertiseManager { } catch (IllegalArgumentException e) { try { binder.unlinkToDeath(deathRecipient, 0); - callback.onAdvertisingSetStarted(0x00, 0x00, - AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); + IBinder gattBinder = mService.getBinder(); + callback.onAdvertisingSetStarted( + gattBinder, 0x00, 0x00, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (RemoteException exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } diff --git a/android/app/src/com/android/bluetooth/gatt/ContextMap.java b/android/app/src/com/android/bluetooth/gatt/ContextMap.java index c68a06b53202c9c2f81e95f14d8d64919653a4d8..3457ed7e59865985e76be6dad2b3432c03a72cab 100644 --- a/android/app/src/com/android/bluetooth/gatt/ContextMap.java +++ b/android/app/src/com/android/bluetooth/gatt/ContextMap.java @@ -30,6 +30,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.le_scan.AppScanStats; import com.android.internal.annotations.GuardedBy; import com.google.common.collect.EvictingQueue; @@ -49,14 +50,13 @@ import java.util.UUID; * This class manages application callbacks and keeps track of GATT connections. * @hide */ -@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public class ContextMap { private static final String TAG = GattServiceConfig.TAG_PREFIX + "ContextMap"; /** * Connection class helps map connection IDs to device addresses. */ - static class Connection { + public static class Connection { public int connId; public String address; public int appId; @@ -73,7 +73,7 @@ public class ContextMap { /** * Application entry mapping UUIDs to appIDs and callbacks. */ - class App { + public class App { /** The UUID of the application */ public UUID uuid; @@ -210,7 +210,7 @@ public class ContextMap { private final Object mConnectionsLock = new Object(); /** Add an entry to the application context list. */ - App add( + protected App add( UUID uuid, WorkSource workSource, C callback, @@ -291,7 +291,7 @@ public class ContextMap { /** * Remove the context for a given application ID. */ - void remove(int id) { + protected void remove(int id) { boolean find = false; synchronized (mAppsLock) { Iterator i = mApps.iterator(); @@ -311,7 +311,7 @@ public class ContextMap { } } - List getAllAppsIds() { + protected List getAllAppsIds() { List appIds = new ArrayList(); synchronized (mAppsLock) { Iterator i = mApps.iterator(); @@ -369,7 +369,7 @@ public class ContextMap { /** * Get an application context by ID. */ - App getById(int id) { + protected App getById(int id) { synchronized (mAppsLock) { Iterator i = mApps.iterator(); while (i.hasNext()) { @@ -386,7 +386,7 @@ public class ContextMap { /** * Get an application context by UUID. */ - App getByUuid(UUID uuid) { + protected App getByUuid(UUID uuid) { synchronized (mAppsLock) { Iterator i = mApps.iterator(); while (i.hasNext()) { @@ -403,7 +403,7 @@ public class ContextMap { /** * Get an application context by the calling Apps name. */ - App getByName(String name) { + public App getByName(String name) { synchronized (mAppsLock) { Iterator i = mApps.iterator(); while (i.hasNext()) { @@ -420,7 +420,7 @@ public class ContextMap { /** * Get an application context by the context info object. */ - App getByContextInfo(T contextInfo) { + protected App getByContextInfo(T contextInfo) { synchronized (mAppsLock) { Iterator i = mApps.iterator(); while (i.hasNext()) { @@ -437,7 +437,7 @@ public class ContextMap { /** * Get Logging info by ID */ - AppScanStats getAppScanStatsById(int id) { + protected AppScanStats getAppScanStatsById(int id) { App temp = getById(id); if (temp != null) { return temp.appScanStats; @@ -448,7 +448,7 @@ public class ContextMap { /** * Get Logging info by application UID */ - AppScanStats getAppScanStatsByUid(int uid) { + public AppScanStats getAppScanStatsByUid(int uid) { return mAppScanStats.get(uid); } @@ -656,7 +656,7 @@ public class ContextMap { return null; } - List getConnectionByApp(int appId) { + public List getConnectionByApp(int appId) { List currentConnections = new ArrayList(); synchronized (mConnectionsLock) { Iterator i = mConnections.iterator(); @@ -673,7 +673,7 @@ public class ContextMap { /** * Erases all application context entries. */ - void clear() { + protected void clear() { synchronized (mAppsLock) { Iterator i = mApps.iterator(); while (i.hasNext()) { @@ -712,7 +712,7 @@ public class ContextMap { /** * Logs debug information. */ - void dump(StringBuilder sb) { + protected void dump(StringBuilder sb) { sb.append(" Entries: " + mAppScanStats.size() + "\n\n"); Iterator> it = mAppScanStats.entrySet().iterator(); diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java index 74679955639b5b1529c07ddacfa1e18c8f88caca..ef764619364fa9288fe0a988abeea61d700927da 100644 --- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java +++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementManager.java @@ -19,6 +19,7 @@ package com.android.bluetooth.gatt; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUtils; +import android.bluetooth.le.ChannelSoundingParams; import android.bluetooth.le.DistanceMeasurementMethod; import android.bluetooth.le.DistanceMeasurementParams; import android.bluetooth.le.DistanceMeasurementResult; @@ -30,12 +31,12 @@ import android.util.Log; import com.android.bluetooth.btservice.AdapterService; import com.android.internal.annotations.VisibleForTesting; -import java.util.HashSet; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; /** - * Manages distnace measurement operations and interacts with Gabeldorsche stack. + * Manages distance measurement operations and interacts with Gabeldorsche stack. * * @hide */ @@ -44,19 +45,22 @@ public class DistanceMeasurementManager { private static final boolean DBG = GattServiceConfig.DBG; private static final String TAG = "DistanceMeasurementManager"; - private static final int RSSI_FREQUENCY_LOW = 3000; - private static final int RSSI_FREQUENCY_MEDIUM = 1000; - private static final int RSSI_FREQUENCY_HIGH = 500; + private static final int RSSI_LOW_FREQUENCY_INTERVAL_MS = 3000; + private static final int RSSI_MEDIUM_FREQUENCY_INTERVAL_MS = 1000; + private static final int RSSI_HIGH_FREQUENCY_INTERVAL_MS = 500; + private static final int CS_LOW_FREQUENCY_INTERVAL_MS = 5000; + private static final int CS_MEDIUM_FREQUENCY_INTERVAL_MS = 3000; + private static final int CS_HIGH_FREQUENCY_INTERVAL_MS = 1000; private final AdapterService mAdapterService; private HandlerThread mHandlerThread; DistanceMeasurementNativeInterface mDistanceMeasurementNativeInterface; - private ConcurrentHashMap> mRssiTrackers = - new ConcurrentHashMap<>(); + private final ConcurrentHashMap> + mRssiTrackers = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> + mCsTrackers = new ConcurrentHashMap<>(); - /** - * Constructor of {@link DistanceMeasurementManager}. - */ + /** Constructor of {@link DistanceMeasurementManager}. */ DistanceMeasurementManager(AdapterService adapterService) { mAdapterService = adapterService; @@ -85,24 +89,39 @@ public class DistanceMeasurementManager { + ", method: " + params.getMethodId()); String identityAddress = mAdapterService.getIdentityAddress( params.getDevice().getAddress()); + if (identityAddress == null) { + identityAddress = params.getDevice().getAddress(); + } logd("Get identityAddress: " + params.getDevice().getAnonymizedAddress() + " => " + BluetoothUtils.toAnonymizedAddress(identityAddress)); - int frequencyValue = getFrequencyValue(params.getFrequency(), params.getMethodId()); - if (frequencyValue == -1) { + int interval = getIntervalValue(params.getFrequency(), params.getMethodId()); + if (interval == -1) { invokeStartFail(callback, params.getDevice(), BluetoothStatusCodes.ERROR_BAD_PARAMETERS); return; } - DistanceMeasurementTracker tracker = new DistanceMeasurementTracker( - this, params, identityAddress, uuid, frequencyValue, callback); + DistanceMeasurementTracker tracker = + new DistanceMeasurementTracker( + this, params, identityAddress, uuid, interval, callback); switch (params.getMethodId()) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO: case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: startRssiTracker(tracker); break; + case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: + if (!params.getDevice().isConnected()) { + Log.e(TAG, "no le connection"); + invokeStartFail( + callback, + params.getDevice(), + BluetoothStatusCodes.ERROR_NO_LE_CONNECTION); + return; + } + startCsTracker(tracker); + break; default: invokeStartFail(callback, params.getDevice(), BluetoothStatusCodes.ERROR_BAD_PARAMETERS); @@ -110,16 +129,31 @@ public class DistanceMeasurementManager { } private synchronized void startRssiTracker(DistanceMeasurementTracker tracker) { - mRssiTrackers.putIfAbsent(tracker.mIdentityAddress, - new HashSet()); - HashSet set = mRssiTrackers.get(tracker.mIdentityAddress); - if (set.contains(tracker)) { + mRssiTrackers.putIfAbsent(tracker.mIdentityAddress, new CopyOnWriteArraySet<>()); + CopyOnWriteArraySet set = + mRssiTrackers.get(tracker.mIdentityAddress); + if (!set.add(tracker)) { + Log.w(TAG, "Already registered"); + return; + } + mDistanceMeasurementNativeInterface.startDistanceMeasurement( + tracker.mIdentityAddress, + tracker.mInterval, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + } + + private synchronized void startCsTracker(DistanceMeasurementTracker tracker) { + mCsTrackers.putIfAbsent(tracker.mIdentityAddress, new CopyOnWriteArraySet<>()); + CopyOnWriteArraySet set = + mCsTrackers.get(tracker.mIdentityAddress); + if (!set.add(tracker)) { Log.w(TAG, "Already registered"); return; } - set.add(tracker); - mDistanceMeasurementNativeInterface.startDistanceMeasurement(tracker.mIdentityAddress, - tracker.mFrequency, DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI); + mDistanceMeasurementNativeInterface.startDistanceMeasurement( + tracker.mIdentityAddress, + tracker.mInterval, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING); } int stopDistanceMeasurement(UUID uuid, BluetoothDevice device, int method, @@ -127,6 +161,9 @@ public class DistanceMeasurementManager { Log.i(TAG, "stopDistanceMeasurement device:" + device.getAnonymizedAddress() + ", method: " + method + " timeout " + timeout); String identityAddress = mAdapterService.getIdentityAddress(device.getAddress()); + if (identityAddress == null) { + identityAddress = device.getAddress(); + } logd("Get identityAddress: " + device.getAnonymizedAddress() + " => " + BluetoothUtils.toAnonymizedAddress(identityAddress)); @@ -134,15 +171,25 @@ public class DistanceMeasurementManager { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO: case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: return stopRssiTracker(uuid, identityAddress, timeout); + case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: + return stopCsTracker(uuid, identityAddress, timeout); default: Log.w(TAG, "stopDistanceMeasurement with invalid method:" + method); return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL; } } + int getChannelSoundingMaxSupportedSecurityLevel(BluetoothDevice remoteDevice) { + return ChannelSoundingParams.CS_SECURITY_LEVEL_ONE; + } + + int getLocalChannelSoundingMaxSupportedSecurityLevel() { + return ChannelSoundingParams.CS_SECURITY_LEVEL_ONE; + } + private synchronized int stopRssiTracker(UUID uuid, String identityAddress, boolean timeout) { - HashSet set = mRssiTrackers.get(identityAddress); + CopyOnWriteArraySet set = mRssiTrackers.get(identityAddress); if (set == null) { Log.w(TAG, "Can't find rssi tracker"); return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL; @@ -168,6 +215,36 @@ public class DistanceMeasurementManager { return BluetoothStatusCodes.SUCCESS; } + private synchronized int stopCsTracker(UUID uuid, String identityAddress, boolean timeout) { + CopyOnWriteArraySet set = mCsTrackers.get(identityAddress); + if (set == null) { + Log.w(TAG, "Can't find CS tracker"); + return BluetoothStatusCodes.ERROR_DISTANCE_MEASUREMENT_INTERNAL; + } + + for (DistanceMeasurementTracker tracker : set) { + if (tracker.equals(uuid, identityAddress)) { + int reason = + timeout + ? BluetoothStatusCodes.ERROR_TIMEOUT + : BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST; + invokeOnStopped(tracker.mCallback, tracker.mDevice, reason); + tracker.cancelTimer(); + set.remove(tracker); + break; + } + } + + if (set.isEmpty()) { + logd("No CS tracker exists; stop CS"); + mCsTrackers.remove(identityAddress); + mDistanceMeasurementNativeInterface.stopDistanceMeasurement( + identityAddress, + DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING); + } + return BluetoothStatusCodes.SUCCESS; + } + private void invokeStartFail(IDistanceMeasurementCallback callback, BluetoothDevice device, int reason) { try { @@ -186,26 +263,33 @@ public class DistanceMeasurementManager { } } - /** - * Convert frequency into value in ms - */ - private int getFrequencyValue(int frequency, int method) { + /** Convert frequency into interval in ms */ + private int getIntervalValue(int frequency, int method) { switch (method) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO: case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: switch (frequency) { case DistanceMeasurementParams.REPORT_FREQUENCY_LOW: - return RSSI_FREQUENCY_LOW; + return RSSI_LOW_FREQUENCY_INTERVAL_MS; case DistanceMeasurementParams.REPORT_FREQUENCY_MEDIUM: - return RSSI_FREQUENCY_MEDIUM; + return RSSI_MEDIUM_FREQUENCY_INTERVAL_MS; case DistanceMeasurementParams.REPORT_FREQUENCY_HIGH: - return RSSI_FREQUENCY_HIGH; + return RSSI_HIGH_FREQUENCY_INTERVAL_MS; + } + break; + case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: + switch (frequency) { + case DistanceMeasurementParams.REPORT_FREQUENCY_LOW: + return CS_LOW_FREQUENCY_INTERVAL_MS; + case DistanceMeasurementParams.REPORT_FREQUENCY_MEDIUM: + return CS_MEDIUM_FREQUENCY_INTERVAL_MS; + case DistanceMeasurementParams.REPORT_FREQUENCY_HIGH: + return CS_HIGH_FREQUENCY_INTERVAL_MS; } break; default: - + Log.w(TAG, "getFrequencyValue fail frequency:" + frequency + ", method:" + method); } - Log.w(TAG, "getFrequencyValue fail frequency:" + frequency + ", method:" + method); return -1; } @@ -216,13 +300,16 @@ public class DistanceMeasurementManager { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiStarted(address); break; + case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: + handleCsStarted(address); + break; default: Log.w(TAG, "onDistanceMeasurementResult: invalid method " + method); } } void handleRssiStarted(String address) { - HashSet set = mRssiTrackers.get(address); + CopyOnWriteArraySet set = mRssiTrackers.get(address); if (set == null) { Log.w(TAG, "Can't find rssi tracker"); return; @@ -240,6 +327,25 @@ public class DistanceMeasurementManager { } } + void handleCsStarted(String address) { + CopyOnWriteArraySet set = mCsTrackers.get(address); + if (set == null) { + Log.w(TAG, "Can't find CS tracker"); + return; + } + for (DistanceMeasurementTracker tracker : set) { + try { + if (!tracker.mStarted) { + tracker.mStarted = true; + tracker.mCallback.onStarted(tracker.mDevice); + tracker.startTimer(mHandlerThread.getLooper()); + } + } catch (RemoteException e) { + Log.e(TAG, "Exception: " + e); + } + } + } + void onDistanceMeasurementStartFail(String address, int reason, int method) { logd("onDistanceMeasurementStartFail address:" + BluetoothUtils.toAnonymizedAddress(address) + ", method:" + method); @@ -247,13 +353,16 @@ public class DistanceMeasurementManager { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiStartFail(address, reason); break; + case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: + handleCsStartFail(address, reason); + break; default: Log.w(TAG, "onDistanceMeasurementStartFail: invalid method " + method); } } void handleRssiStartFail(String address, int reason) { - HashSet set = mRssiTrackers.get(address); + CopyOnWriteArraySet set = mRssiTrackers.get(address); if (set == null) { Log.w(TAG, "Can't find rssi tracker"); return; @@ -263,9 +372,21 @@ public class DistanceMeasurementManager { invokeStartFail(tracker.mCallback, tracker.mDevice, reason); } } - synchronized (set) { - set.removeIf(tracker -> !tracker.mStarted); + set.removeIf(tracker -> !tracker.mStarted); + } + + void handleCsStartFail(String address, int reason) { + CopyOnWriteArraySet set = mCsTrackers.get(address); + if (set == null) { + Log.w(TAG, "Can't find CS tracker"); + return; + } + for (DistanceMeasurementTracker tracker : set) { + if (!tracker.mStarted) { + invokeStartFail(tracker.mCallback, tracker.mDevice, reason); + } } + set.removeIf(tracker -> !tracker.mStarted); } void onDistanceMeasurementStopped(String address, int reason, int method) { @@ -275,13 +396,16 @@ public class DistanceMeasurementManager { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: handleRssiStopped(address, reason); break; + case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: + handleCsStopped(address, reason); + break; default: Log.w(TAG, "onDistanceMeasurementStopped: invalid method " + method); } } void handleRssiStopped(String address, int reason) { - HashSet set = mRssiTrackers.get(address); + CopyOnWriteArraySet set = mRssiTrackers.get(address); if (set == null) { Log.w(TAG, "Can't find rssi tracker"); return; @@ -292,9 +416,22 @@ public class DistanceMeasurementManager { invokeOnStopped(tracker.mCallback, tracker.mDevice, reason); } } - synchronized (set) { - set.removeIf(tracker -> tracker.mStarted); + set.removeIf(tracker -> tracker.mStarted); + } + + void handleCsStopped(String address, int reason) { + CopyOnWriteArraySet set = mCsTrackers.get(address); + if (set == null) { + Log.w(TAG, "Can't find CS tracker"); + return; + } + for (DistanceMeasurementTracker tracker : set) { + if (tracker.mStarted) { + tracker.cancelTimer(); + invokeOnStopped(tracker.mCallback, tracker.mDevice, reason); + } } + set.removeIf(tracker -> tracker.mStarted); } void onDistanceMeasurementResult(String address, int centimeter, int errorCentimeter, @@ -314,7 +451,7 @@ public class DistanceMeasurementManager { } void handleRssiResult(String address, DistanceMeasurementResult result) { - HashSet set = mRssiTrackers.get(address); + CopyOnWriteArraySet set = mRssiTrackers.get(address); if (set == null) { Log.w(TAG, "Can't find rssi tracker"); return; diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java index 62e15c9b5b1f601cd107bc041b0e8659081c2209..b71e172e82f83c17b7537a2b35accc9e2b04b182 100644 --- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java +++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementNativeInterface.java @@ -82,8 +82,8 @@ public class DistanceMeasurementNativeInterface { cleanupNative(); } - void startDistanceMeasurement(String address, int frequency, int method) { - startDistanceMeasurementNative(address, frequency, method); + void startDistanceMeasurement(String address, int interval, int method) { + startDistanceMeasurementNative(address, interval, method); } void stopDistanceMeasurement(String address, int method) { @@ -143,7 +143,7 @@ public class DistanceMeasurementNativeInterface { private native void cleanupNative(); - private native void startDistanceMeasurementNative(String address, int frequency, int method); + private native void startDistanceMeasurementNative(String address, int interval, int method); private native void stopDistanceMeasurementNative(String address, int method); } diff --git a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java index 4d5e87a2f190307d69d23fe34e815e74cd6928a8..e8b1a3e68919ad2c5078b740d41e8db15c2c3013 100644 --- a/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java +++ b/android/app/src/com/android/bluetooth/gatt/DistanceMeasurementTracker.java @@ -37,21 +37,25 @@ class DistanceMeasurementTracker { final BluetoothDevice mDevice; final String mIdentityAddress; final UUID mUuid; - final int mFrequency; // Report frequency in ms + final int mInterval; // Report interval in ms final int mDuration; // Report duration in s final int mMethod; final IDistanceMeasurementCallback mCallback; boolean mStarted = false; private Handler mHandler; - DistanceMeasurementTracker(DistanceMeasurementManager manager, DistanceMeasurementParams params, - String identityAddress, UUID uuid, int frequency, + DistanceMeasurementTracker( + DistanceMeasurementManager manager, + DistanceMeasurementParams params, + String identityAddress, + UUID uuid, + int interval, IDistanceMeasurementCallback callback) { mManager = manager; mDevice = params.getDevice(); mIdentityAddress = identityAddress; mUuid = uuid; - mFrequency = frequency; + mInterval = interval; mDuration = params.getDurationSeconds(); mMethod = params.getMethodId(); mCallback = callback; diff --git a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java index 9cb5996fb537e313217a5166823877157ed47607..3cc02b851b7a6e9a7f4089b59ab2c46030da7b74 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java +++ b/android/app/src/com/android/bluetooth/gatt/GattObjectsFactory.java @@ -22,6 +22,9 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.BluetoothAdapterProxy; +import com.android.bluetooth.le_scan.PeriodicScanManager; +import com.android.bluetooth.le_scan.ScanManager; +import com.android.bluetooth.le_scan.ScanNativeInterface; /** * Factory class for object initialization to help with unit testing @@ -53,7 +56,7 @@ public class GattObjectsFactory { * * @param objectsFactory a test instance of the GattObjectsFactory */ - static void setInstanceForTesting(GattObjectsFactory objectsFactory) { + public static void setInstanceForTesting(GattObjectsFactory objectsFactory) { Utils.enforceInstrumentationTestMode(); synchronized (INSTANCE_LOCK) { Log.d(TAG, "setInstanceForTesting(), set to " + objectsFactory); diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java index efa7294a37cdace2ec1f91e1774a16503fa1cb4b..4f4dab7325a6a385ab3c4b0cfdf1eb06358bea69 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattService.java +++ b/android/app/src/com/android/bluetooth/gatt/GattService.java @@ -27,7 +27,6 @@ import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.PendingIntent; -import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; @@ -44,6 +43,7 @@ import android.bluetooth.IBluetoothGattServerCallback; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertisingSetParameters; import android.bluetooth.le.BluetoothLeScanner; +import android.bluetooth.le.ChannelSoundingParams; import android.bluetooth.le.DistanceMeasurementMethod; import android.bluetooth.le.DistanceMeasurementParams; import android.bluetooth.le.IAdvertisingSetCallback; @@ -93,6 +93,12 @@ import com.android.bluetooth.btservice.BluetoothAdapterProxy; import com.android.bluetooth.btservice.CompanionManager; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; +import com.android.bluetooth.flags.Flags; +import com.android.bluetooth.le_scan.AppScanStats; +import com.android.bluetooth.le_scan.PeriodicScanManager; +import com.android.bluetooth.le_scan.ScanClient; +import com.android.bluetooth.le_scan.ScanManager; +import com.android.bluetooth.le_scan.TransitionalScanHelper; import com.android.bluetooth.util.NumberUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; @@ -206,7 +212,7 @@ public class GattService extends ProfileService { /** * Keep the arguments passed in for the PendingIntent. */ - class PendingIntentInfo { + public static class PendingIntentInfo { public PendingIntent intent; public ScanSettings settings; public List filters; @@ -230,12 +236,7 @@ public class GattService extends ProfileService { } }; - /** - * List of our registered scanners. - */ - class ScannerMap extends ContextMap {} - - ScannerMap mScannerMap = new ScannerMap(); + public final TransitionalScanHelper mTransitionalScanHelper = new TransitionalScanHelper(); /** * List of our registered advertisers. @@ -277,7 +278,7 @@ public class GattService extends ProfileService { /** * Set of restricted (which require a BLUETOOTH_PRIVILEGED permission) handles per connectionId. */ - private final Map> mRestrictedHandles = new HashMap<>(); + @VisibleForTesting final Map> mRestrictedHandles = new HashMap<>(); /** * HashMap used to synchronize writeCharacteristic calls mapping remote device address to @@ -338,7 +339,7 @@ public class GattService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -374,28 +375,27 @@ public class GattService extends ProfileService { mActivityManager = getSystemService(ActivityManager.class); mPackageManager = mAdapterService.getPackageManager(); - - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } - mScannerMap.clear(); + mTransitionalScanHelper.getScannerMap().clear(); mAdvertiserMap.clear(); mClientMap.clear(); + if (Flags.gattCleanupRestrictedHandles()) { + mRestrictedHandles.clear(); + } mServerMap.clear(); mHandleMap.clear(); mReliableQueue.clear(); cleanup(); - - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } @@ -493,14 +493,6 @@ public class GattService extends ProfileService { return restrictedHandles != null && restrictedHandles.contains(handle); } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (GattDebugUtils.handleDebugAction(this, intent)) { - return Service.START_NOT_STICKY; - } - return super.onStartCommand(intent, flags, startId); - } - /** Notify Scan manager of bluetooth profile connection state changes */ public void notifyProfileConnectionStateChange(int profile, int fromState, int toState) { if (mScanManager == null) { @@ -538,8 +530,12 @@ public class GattService extends ProfileService { ScanClient client = getScanClient(mScannerId); if (client != null) { - client.appDied = true; - stopScan(client.scannerId, getAttributionSource()); + if (Flags.leScanFixRemoteException()) { + handleDeadScanClient(client); + } else { + client.appDied = true; + stopScan(client.scannerId, getAttributionSource()); + } } } @@ -1862,6 +1858,64 @@ public class GattService extends ProfileService { enforceBluetoothPrivilegedPermission(service); return service.stopDistanceMeasurement(uuid.getUuid(), device, method); } + + @Override + public void getChannelSoundingMaxSupportedSecurityLevel( + BluetoothDevice remoteDevice, + AttributionSource attributionSource, + SynchronousResultReceiver receiver) { + try { + receiver.send( + getChannelSoundingMaxSupportedSecurityLevel( + remoteDevice, attributionSource)); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + private int getChannelSoundingMaxSupportedSecurityLevel( + BluetoothDevice remoteDevice, AttributionSource attributionSource) { + GattService service = getService(); + if (service == null + || !callerIsSystemOrActiveOrManagedUser( + service, TAG, "GattService getChannelSoundingMaxSupportedSecurityLevel") + || !Utils.checkConnectPermissionForDataDelivery( + service, + attributionSource, + "GattService getChannelSoundingMaxSupportedSecurityLevel")) { + return ChannelSoundingParams.CS_SECURITY_LEVEL_UNKNOWN; + } + enforceBluetoothPrivilegedPermission(service); + return service.getChannelSoundingMaxSupportedSecurityLevel(remoteDevice); + } + + @Override + public void getLocalChannelSoundingMaxSupportedSecurityLevel( + AttributionSource attributionSource, SynchronousResultReceiver receiver) { + try { + receiver.send(getLocalChannelSoundingMaxSupportedSecurityLevel(attributionSource)); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + private int getLocalChannelSoundingMaxSupportedSecurityLevel( + AttributionSource attributionSource) { + GattService service = getService(); + if (service == null + || !callerIsSystemOrActiveOrManagedUser( + service, + TAG, + "GattService getLocalChannelSoundingMaxSupportedSecurityLevel") + || !Utils.checkConnectPermissionForDataDelivery( + service, + attributionSource, + "GattService getLocalChannelSoundingMaxSupportedSecurityLevel")) { + return ChannelSoundingParams.CS_SECURITY_LEVEL_UNKNOWN; + } + enforceBluetoothPrivilegedPermission(service); + return service.getLocalChannelSoundingMaxSupportedSecurityLevel(); + } }; /************************************************************************** @@ -1954,7 +2008,8 @@ public class GattService extends ProfileService { byte[] legacyAdvData = Arrays.copyOfRange(advData, 0, 62); for (ScanClient client : mScanManager.getRegularScanQueue()) { - ScannerMap.App app = mScannerMap.getById(client.scannerId); + TransitionalScanHelper.ScannerMap.App app = + mTransitionalScanHelper.getScannerMap().getById(client.scannerId); if (app == null) { if (VDBG) { Log.d(TAG, "App is null; skip."); @@ -2043,8 +2098,12 @@ public class GattService extends ProfileService { } } catch (RemoteException | PendingIntent.CanceledException e) { Log.e(TAG, "Exception: " + e); - mScannerMap.remove(client.scannerId); - mScanManager.stopScan(client.scannerId); + if (Flags.leScanFixRemoteException()) { + handleDeadScanClient(client); + } else { + mTransitionalScanHelper.getScannerMap().remove(client.scannerId); + mScanManager.stopScan(client.scannerId); + } } } } @@ -2091,7 +2150,8 @@ public class GattService extends ProfileService { } // First check the callback map - ScannerMap.App cbApp = mScannerMap.getByUuid(uuid); + TransitionalScanHelper.ScannerMap.App cbApp = + mTransitionalScanHelper.getScannerMap().getByUuid(uuid); if (cbApp != null) { if (status == 0) { cbApp.id = scannerId; @@ -2103,7 +2163,7 @@ public class GattService extends ProfileService { continuePiStartScan(scannerId, cbApp); } } else { - mScannerMap.remove(scannerId); + mTransitionalScanHelper.getScannerMap().remove(scannerId); } if (cbApp.callback != null) { cbApp.callback.onScannerRegistered(status, scannerId); @@ -2149,6 +2209,15 @@ public class GattService extends ProfileService { return new MatchResult(false, MatchOrigin.PSEUDO_ADDRESS); } + private void handleDeadScanClient(ScanClient client) { + if (client.appDied) { + Log.w(TAG, "Already dead client " + client.scannerId); + return; + } + client.appDied = true; + stopScan(client.scannerId, getAttributionSource()); + } + void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb) throws RemoteException { UUID uuid = new UUID(uuidMsb, uuidLsb); @@ -2205,6 +2274,10 @@ public class GattService extends ProfileService { mClientMap.removeConnection(clientIf, connId); ClientMap.App app = mClientMap.getById(clientIf); + if (Flags.gattCleanupRestrictedHandles()) { + mRestrictedHandles.remove(connId); + } + // Remove AtomicBoolean representing permit if no other connections rely on this remote device. if (!mClientMap.getConnectedDevices().contains(address)) { synchronized (mPermits) { @@ -2719,7 +2792,8 @@ public class GattService extends ProfileService { Set results = parseBatchScanResults(numRecords, reportType, recordData); if (reportType == ScanManager.SCAN_RESULT_TYPE_TRUNCATED) { // We only support single client for truncated mode. - ScannerMap.App app = mScannerMap.getById(scannerId); + TransitionalScanHelper.ScannerMap.App app = + mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null) { return; } @@ -2770,7 +2844,7 @@ public class GattService extends ProfileService { mScanManager.callbackDone(scannerId, status); } - private void sendBatchScanResults(ScannerMap.App app, ScanClient client, + private void sendBatchScanResults(TransitionalScanHelper.ScannerMap.App app, ScanClient client, ArrayList results) { try { if (app.callback != null) { @@ -2794,15 +2868,19 @@ public class GattService extends ProfileService { } } catch (RemoteException | PendingIntent.CanceledException e) { Log.e(TAG, "Exception: " + e); - mScannerMap.remove(client.scannerId); - mScanManager.stopScan(client.scannerId); + if (Flags.leScanFixRemoteException()) { + handleDeadScanClient(client); + } else { + mTransitionalScanHelper.getScannerMap().remove(client.scannerId); + mScanManager.stopScan(client.scannerId); + } } } // Check and deliver scan results for different scan clients. private void deliverBatchScan(ScanClient client, Set allResults) throws RemoteException { - ScannerMap.App app = mScannerMap.getById(client.scannerId); + ContextMap.App app = mTransitionalScanHelper.getScannerMap().getById(client.scannerId); if (app == null) { return; } @@ -2963,7 +3041,8 @@ public class GattService extends ProfileService { + trackingInfo.getAdvState()); } - ScannerMap.App app = mScannerMap.getById(trackingInfo.getClientIf()); + TransitionalScanHelper.ScannerMap.App app = + mTransitionalScanHelper.getScannerMap().getById(trackingInfo.getClientIf()); if (app == null || (app.callback == null && app.info == null)) { Log.e(TAG, "app or callback is null"); return; @@ -3009,7 +3088,7 @@ public class GattService extends ProfileService { } void onScanParamSetupCompleted(int status, int scannerId) throws RemoteException { - ScannerMap.App app = mScannerMap.getById(scannerId); + ContextMap.App app = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null || app.callback == null) { Log.e(TAG, "Advertise app or callback is null"); return; @@ -3020,8 +3099,9 @@ public class GattService extends ProfileService { } // callback from ScanManager for dispatch of errors apps. - void onScanManagerErrorCallback(int scannerId, int errorCode) throws RemoteException { - ScannerMap.App app = mScannerMap.getById(scannerId); + public void onScanManagerErrorCallback(int scannerId, int errorCode) throws RemoteException { + TransitionalScanHelper.ScannerMap.App app = + mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app == null || (app.callback == null && app.info == null)) { Log.e(TAG, "App or callback is null"); return; @@ -3138,7 +3218,8 @@ public class GattService extends ProfileService { enforceImpersonatationPermissionIfNeeded(workSource); - AppScanStats app = mScannerMap.getAppScanStatsByUid(Binder.getCallingUid()); + AppScanStats app = mTransitionalScanHelper.getScannerMap() + .getAppScanStatsByUid(Binder.getCallingUid()); if (app != null && app.isScanningTooFrequently() && !Utils.checkCallerHasPrivilegedPermission(this)) { Log.e(TAG, "App '" + app.appName + "' is scanning too frequently"); @@ -3146,12 +3227,13 @@ public class GattService extends ProfileService { return; } - mScannerMap.add(uuid, workSource, callback, null, this); + mTransitionalScanHelper + .getScannerMap().add(uuid, workSource, callback, null, this); mScanManager.registerScanner(uuid); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) - void unregisterScanner(int scannerId, AttributionSource attributionSource) { + public void unregisterScanner(int scannerId, AttributionSource attributionSource) { if (!Utils.checkScanPermissionForDataDelivery( this, attributionSource, "GattService unregisterScanner")) { return; @@ -3160,7 +3242,7 @@ public class GattService extends ProfileService { if (DBG) { Log.d(TAG, "unregisterScanner() - scannerId=" + scannerId); } - mScannerMap.remove(scannerId); + mTransitionalScanHelper.getScannerMap().remove(scannerId); mScanManager.unregisterScanner(scannerId); } @@ -3232,8 +3314,8 @@ public class GattService extends ProfileService { Utils.checkCallerHasScanWithoutLocationPermission(this); scanClient.associatedDevices = getAssociatedDevices(callingPackage); - AppScanStats app = mScannerMap.getAppScanStatsById(scannerId); - ScannerMap.App cbApp = mScannerMap.getById(scannerId); + AppScanStats app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); + ContextMap.App cbApp = mTransitionalScanHelper.getScannerMap().getById(scannerId); if (app != null) { scanClient.stats = app; boolean isFilteredScan = (filters != null) && !filters.isEmpty(); @@ -3280,12 +3362,13 @@ public class GattService extends ProfileService { } // Don't start scan if the Pi scan already in mScannerMap. - if (mScannerMap.getByContextInfo(piInfo) != null) { + if (mTransitionalScanHelper.getScannerMap().getByContextInfo(piInfo) != null) { Log.d(TAG, "Don't startScan(PI) since the same Pi scan already in mScannerMap."); return; } - ScannerMap.App app = mScannerMap.add(uuid, null, null, piInfo, this); + ContextMap.App app = + mTransitionalScanHelper.getScannerMap().add(uuid, null, null, piInfo, this); app.mUserHandle = UserHandle.getUserHandleForUid(Binder.getCallingUid()); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); @@ -3325,7 +3408,7 @@ public class GattService extends ProfileService { } } - void continuePiStartScan(int scannerId, ScannerMap.App app) { + void continuePiStartScan(int scannerId, TransitionalScanHelper.ScannerMap.App app) { final PendingIntentInfo piInfo = app.info; final ScanClient scanClient = new ScanClient(scannerId, piInfo.settings, piInfo.filters, piInfo.callingUid); @@ -3340,7 +3423,8 @@ public class GattService extends ProfileService { scanClient.associatedDevices = app.mAssociatedDevices; scanClient.hasDisavowedLocation = app.mHasDisavowedLocation; - AppScanStats scanStats = mScannerMap.getAppScanStatsById(scannerId); + AppScanStats scanStats = + mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); if (scanStats != null) { scanClient.stats = scanStats; boolean isFilteredScan = (piInfo.filters != null) && !piInfo.filters.isEmpty(); @@ -3376,7 +3460,7 @@ public class GattService extends ProfileService { } AppScanStats app = null; - app = mScannerMap.getAppScanStatsById(scannerId); + app = mTransitionalScanHelper.getScannerMap().getAppScanStatsById(scannerId); if (app != null) { app.recordScanStop(scannerId); } @@ -3392,7 +3476,7 @@ public class GattService extends ProfileService { } PendingIntentInfo pii = new PendingIntentInfo(); pii.intent = intent; - ScannerMap.App app = mScannerMap.getByContextInfo(pii); + ContextMap.App app = mTransitionalScanHelper.getScannerMap().getByContextInfo(pii); if (VDBG) { Log.d(TAG, "stopScan(PendingIntent): app found = " + app); } @@ -3604,6 +3688,15 @@ public class GattService extends ProfileService { return mDistanceMeasurementManager.stopDistanceMeasurement(uuid, device, method, false); } + int getChannelSoundingMaxSupportedSecurityLevel(BluetoothDevice remoteDevice) { + return mDistanceMeasurementManager.getChannelSoundingMaxSupportedSecurityLevel( + remoteDevice); + } + + int getLocalChannelSoundingMaxSupportedSecurityLevel() { + return mDistanceMeasurementManager.getLocalChannelSoundingMaxSupportedSecurityLevel(); + } + /************************************************************************** * GATT Service functions - CLIENT *************************************************************************/ @@ -5006,8 +5099,9 @@ public class GattService extends ProfileService { void dumpRegisterId(StringBuilder sb) { sb.append(" Scanner:\n"); - for (Integer appId : mScannerMap.getAllAppsIds()) { - println(sb, " app_if: " + appId + ", appName: " + mScannerMap.getById(appId).name); + for (Integer appId : mTransitionalScanHelper.getScannerMap().getAllAppsIds()) { + println(sb, " app_if: " + appId + ", appName: " + + mTransitionalScanHelper.getScannerMap().getById(appId).name); } sb.append(" Client:\n"); for (Integer appId : mClientMap.getAllAppsIds()) { @@ -5034,7 +5128,7 @@ public class GattService extends ProfileService { dumpRegisterId(sb); sb.append("GATT Scanner Map\n"); - mScannerMap.dump(sb); + mTransitionalScanHelper.getScannerMap().dump(sb); sb.append("GATT Advertiser Map\n"); mAdvertiserMap.dumpAdvertiser(sb); @@ -5049,7 +5143,7 @@ public class GattService extends ProfileService { mHandleMap.dump(sb); } - void addScanEvent(BluetoothMetricsProto.ScanEvent event) { + public void addScanEvent(BluetoothMetricsProto.ScanEvent event) { synchronized (mScanEvents) { if (mScanEvents.size() == NUM_SCAN_EVENTS_KEPT) { mScanEvents.remove(); diff --git a/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java b/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java index 6723437e5eeb2e44aa4d5888b61363a5a183be8d..3855d976e1b269b2ff8c3f2ba4fa720bb7fabf5f 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java +++ b/android/app/src/com/android/bluetooth/gatt/GattServiceConfig.java @@ -21,7 +21,7 @@ import android.os.Build; /** * GattService configuration. */ -/*package*/ class GattServiceConfig { +public class GattServiceConfig { public static final boolean DBG = Build.TYPE.equals("userdebug") || Build.TYPE.equals("eng"); public static final boolean VDBG = false; public static final String TAG_PREFIX = "BtGatt."; diff --git a/android/app/src/com/android/bluetooth/hap/HapClientService.java b/android/app/src/com/android/bluetooth/hap/HapClientService.java index 2d968be7c1ca6e46d43744964a9c29f0af71ea42..dc8159fc774f190eb9329af709a2b3aa1a776d9d 100644 --- a/android/app/src/com/android/bluetooth/hap/HapClientService.java +++ b/android/app/src/com/android/bluetooth/hap/HapClientService.java @@ -33,7 +33,6 @@ import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothHapClient; import android.bluetooth.IBluetoothHapClientCallback; import android.content.AttributionSource; -import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; @@ -51,8 +50,7 @@ import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorService; -import com.android.bluetooth.flags.FeatureFlags; -import com.android.bluetooth.flags.FeatureFlagsImpl; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; @@ -90,7 +88,6 @@ public class HapClientService extends ProfileService { private final Map mDeviceFeaturesMap = new HashMap<>(); private final Map> mPresetsMap = new HashMap<>(); - private final FeatureFlags mFeatureFlags; @VisibleForTesting RemoteCallbackList mCallbacks; @@ -127,18 +124,13 @@ public class HapClientService extends ProfileService { return sHapClient; } - protected HapClientService() { - mFeatureFlags = new FeatureFlagsImpl(); - } - - @VisibleForTesting - HapClientService(Context ctx) { - super(ctx); - mFeatureFlags = new FeatureFlagsImpl(); + public HapClientService(AdapterService adapterService) { + super(adapterService); + mAdapterService = Objects.requireNonNull(adapterService); } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } @@ -150,7 +142,7 @@ public class HapClientService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -159,12 +151,12 @@ public class HapClientService extends ProfileService { throw new IllegalStateException("start() called twice"); } - // Get AdapterService, HapClientNativeInterface, DatabaseManager, AudioManager. + // Get HapClientNativeInterface, DatabaseManager, AudioManager. // None of them can be null. - mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), - "AdapterService cannot be null when HapClientService starts"); - mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), - "DatabaseManager cannot be null when HapClientService starts"); + mDatabaseManager = + Objects.requireNonNull( + mAdapterService.getDatabase(), + "DatabaseManager cannot be null when HapClientService starts"); mHapClientNativeInterface = Objects.requireNonNull( HapClientNativeInterface.getInstance(), "HapClientNativeInterface cannot be null when HapClientService starts"); @@ -182,18 +174,16 @@ public class HapClientService extends ProfileService { // Mark service as started setHapClient(this); - - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sHapClient == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } // Marks service as stopped @@ -236,11 +226,6 @@ public class HapClientService extends ProfileService { if (mCallbacks != null) { mCallbacks.kill(); } - - // Clear AdapterService - mAdapterService = null; - - return true; } /** Process a change in the bonding state for a device */ @@ -452,7 +437,7 @@ public class HapClientService extends ProfileService { removeStateMachine(device); } } - if (!mFeatureFlags.audioRoutingCentralization()) { + if (!Flags.audioRoutingCentralization()) { ActiveDeviceManager adManager = mAdapterService.getActiveDeviceManager(); if (adManager != null) { adManager.profileConnectionStateChanged( diff --git a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java index 2ab04c807b67e1316ef6c7afdd81b3da0fedd46c..5937b07dd6f36971a983494f1d0c49a8e07bf90b 100644 --- a/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +++ b/android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java @@ -46,11 +46,12 @@ import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.AudioRoutingManager; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; -import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; @@ -102,10 +103,7 @@ public class HearingAidService extends ProfileService { private final ServiceFactory mFactory = new ServiceFactory(); - HearingAidService() {} - - @VisibleForTesting - HearingAidService(Context ctx) { + public HearingAidService(Context ctx) { super(ctx); } @@ -119,7 +117,7 @@ public class HearingAidService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -152,17 +150,16 @@ public class HearingAidService extends ProfileService { // Initialize native interface mHearingAidNativeInterface.init(); - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sHearingAidService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } // Cleanup native interface mHearingAidNativeInterface.cleanup(); @@ -207,12 +204,10 @@ public class HearingAidService extends ProfileService { mAudioManager = null; mHearingAidNativeInterface = null; mAdapterService = null; - - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } @@ -1059,15 +1054,23 @@ public class HearingAidService extends ProfileService { SynchronousResultReceiver receiver) { try { HearingAidService service = getService(source); - boolean result = false; if (service != null) { - if (device == null) { - result = service.removeActiveDevice(false); + if (Flags.audioRoutingCentralization()) { + ((AudioRoutingManager) service.mAdapterService.getActiveDeviceManager()) + .activateDeviceProfile( + device, BluetoothProfile.HEARING_AID, receiver); } else { - result = service.setActiveDevice(device); + boolean result; + if (device == null) { + result = service.removeActiveDevice(false); + } else { + result = service.setActiveDevice(device); + } + receiver.send(result); } + } else { + receiver.send(false); } - receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); } diff --git a/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java b/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java index ac4620c2440fcf4f4ab46e43854665b016647208..d4872cc0d58a957c597e76088b6a210990e43287 100644 --- a/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java +++ b/android/app/src/com/android/bluetooth/hfp/AtPhonebook.java @@ -169,24 +169,24 @@ public class AtPhonebook { } public void handleCscsCommand(String atString, int type, BluetoothDevice device) { - log("handleCscsCommand - atString = " + atString); + Log.d(TAG, "handleCscsCommand - atString = " + atString); // Select Character Set int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR; int atCommandErrorCode = -1; String atCommandResponse = null; switch (type) { case TYPE_READ: // Read - log("handleCscsCommand - Read Command"); + Log.d(TAG, "handleCscsCommand - Read Command"); atCommandResponse = "+CSCS: \"" + mCharacterSet + "\""; atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; break; case TYPE_TEST: // Test - log("handleCscsCommand - Test Command"); + Log.d(TAG, "handleCscsCommand - Test Command"); atCommandResponse = ("+CSCS: (\"UTF-8\",\"IRA\",\"GSM\")"); atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; break; case TYPE_SET: // Set - log("handleCscsCommand - Set Command"); + Log.d(TAG, "handleCscsCommand - Set Command"); String[] args = atString.split("="); if (args.length < 2 || args[1] == null) { mNativeInterface.atResponseCode(device, atCommandResult, atCommandErrorCode); @@ -204,7 +204,7 @@ public class AtPhonebook { break; case TYPE_UNKNOWN: default: - log("handleCscsCommand - Invalid chars"); + Log.d(TAG, "handleCscsCommand - Invalid chars"); atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; } if (atCommandResponse != null) { @@ -215,13 +215,13 @@ public class AtPhonebook { public void handleCpbsCommand(String atString, int type, BluetoothDevice device) { // Select PhoneBook memory Storage - log("handleCpbsCommand - atString = " + atString); + Log.d(TAG, "handleCpbsCommand - atString = " + atString); int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR; int atCommandErrorCode = -1; String atCommandResponse = null; switch (type) { case TYPE_READ: // Read - log("handleCpbsCommand - read command"); + Log.d(TAG, "handleCpbsCommand - read command"); // Return current size and max size if ("SM".equals(mCurrentPhonebook)) { atCommandResponse = "+CPBS: \"SM\",0," + getMaxPhoneBookSize(0); @@ -242,12 +242,12 @@ public class AtPhonebook { atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; break; case TYPE_TEST: // Test - log("handleCpbsCommand - test command"); + Log.d(TAG, "handleCpbsCommand - test command"); atCommandResponse = ("+CPBS: (\"ME\",\"SM\",\"DC\",\"RC\",\"MC\")"); atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; break; case TYPE_SET: // Set - log("handleCpbsCommand - set command"); + Log.d(TAG, "handleCpbsCommand - set command"); String[] args = atString.split("="); // Select phonebook memory if (args.length < 2 || args[1] == null) { @@ -263,7 +263,7 @@ public class AtPhonebook { } if (getPhonebookResult(pb, false) == null && !"SM".equals(pb)) { if (DBG) { - log("Dont know phonebook: '" + pb + "'"); + Log.d(TAG, "Dont know phonebook: '" + pb + "'"); } atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED; break; @@ -273,7 +273,7 @@ public class AtPhonebook { break; case TYPE_UNKNOWN: default: - log("handleCpbsCommand - invalid chars"); + Log.d(TAG, "handleCpbsCommand - invalid chars"); atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; } if (atCommandResponse != null) { @@ -283,7 +283,7 @@ public class AtPhonebook { } void handleCpbrCommand(String atString, int type, BluetoothDevice remoteDevice) { - log("handleCpbrCommand - atString = " + atString); + Log.d(TAG, "handleCpbrCommand - atString = " + atString); int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR; int atCommandErrorCode = -1; String atCommandResponse = null; @@ -294,7 +294,7 @@ public class AtPhonebook { * Parrot CK3300. So instead send just the range of currently * valid index's. */ - log("handleCpbrCommand - test command"); + Log.d(TAG, "handleCpbrCommand - test command"); int size; if ("SM".equals(mCurrentPhonebook)) { size = 0; @@ -307,7 +307,7 @@ public class AtPhonebook { break; } size = pbr.cursor.getCount(); - log("handleCpbrCommand - size = " + size); + Log.d(TAG, "handleCpbrCommand - size = " + size); pbr.cursor.close(); pbr.cursor = null; } @@ -325,7 +325,7 @@ public class AtPhonebook { case TYPE_SET: // Set & read // Phone Book Read Request // AT+CPBR=[,] - log("handleCpbrCommand - set/read command"); + Log.d(TAG, "handleCpbrCommand - set/read command"); if (mCpbrIndex1 != -1) { /* handling a CPBR at the moment, reject this CPBR command */ atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_ALLOWED; @@ -355,7 +355,7 @@ public class AtPhonebook { index2 = Integer.parseInt(indices[1]); } } catch (Exception e) { - log("handleCpbrCommand - exception - invalid chars: " + e.toString()); + Log.d(TAG, "handleCpbrCommand - exception - invalid chars: " + e.toString()); atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; mNativeInterface.atResponseCode(remoteDevice, atCommandResult, atCommandErrorCode); @@ -386,7 +386,7 @@ public class AtPhonebook { break; case TYPE_UNKNOWN: default: - log("handleCpbrCommand - invalid chars"); + Log.d(TAG, "handleCpbrCommand - invalid chars"); atCommandErrorCode = BluetoothCmeError.TEXT_HAS_INVALID_CHARS; mNativeInterface.atResponseCode(remoteDevice, atCommandResult, atCommandErrorCode); } @@ -505,7 +505,7 @@ public class AtPhonebook { // process CPBR command after permission check /*package*/ int processCpbrCommand(BluetoothDevice device) { - log("processCpbrCommand"); + Log.d(TAG, "processCpbrCommand"); int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR; int atCommandErrorCode = -1; String atCommandResponse = null; @@ -546,7 +546,7 @@ public class AtPhonebook { atCommandResult = HeadsetHalConstants.AT_RESPONSE_OK; int errorDetected = -1; // no error pbr.cursor.moveToPosition(mCpbrIndex1 - 1); - log("mCpbrIndex1 = " + mCpbrIndex1 + " and mCpbrIndex2 = " + mCpbrIndex2); + Log.d(TAG, "mCpbrIndex1 = " + mCpbrIndex1 + " and mCpbrIndex2 = " + mCpbrIndex2); for (int index = mCpbrIndex1; index <= mCpbrIndex2; index++) { String number = pbr.cursor.getString(pbr.numberColumn); String name = null; @@ -573,14 +573,16 @@ public class AtPhonebook { } c.close(); } - if (DBG && name == null) { - log("Caller ID lookup failed for " + number); + if (name == null) { + if (DBG) { + Log.d(TAG, "Caller ID lookup failed for " + number); + } } } else if (pbr.nameColumn != -1) { name = pbr.cursor.getString(pbr.nameColumn); } else { - log("processCpbrCommand: empty name and number"); + Log.d(TAG, "processCpbrCommand: empty name and number"); } if (name == null) { name = ""; @@ -652,11 +654,11 @@ public class AtPhonebook { */ @VisibleForTesting int checkAccessPermission(BluetoothDevice remoteDevice) { - log("checkAccessPermission"); + Log.d(TAG, "checkAccessPermission"); int permission = remoteDevice.getPhonebookAccessPermission(); if (permission == BluetoothDevice.ACCESS_UNKNOWN) { - log("checkAccessPermission - ACTION_CONNECTION_ACCESS_REQUEST"); + Log.d(TAG, "checkAccessPermission - ACTION_CONNECTION_ACCESS_REQUEST"); Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); intent.setPackage(mPairingPackage); intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, @@ -690,8 +692,4 @@ public class AtPhonebook { return "O"; } } - - private static void log(String msg) { - Log.d(TAG, msg); - } } diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetHalConstants.java b/android/app/src/com/android/bluetooth/hfp/HeadsetHalConstants.java index 5d5d6966bb15986bbd7d708099bf6543f8333d8f..7e8bb06e3fed3e02518b26b601dc24559c7ffe66 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetHalConstants.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetHalConstants.java @@ -83,4 +83,21 @@ public final class HeadsetHalConstants { static final int BTHF_SWB_NONE = 0; static final int BTHF_SWB_NO = 1; static final int BTHF_SWB_YES = 2; + + static String getConnectionStateName(int state) { + switch (state) { + case CONNECTION_STATE_DISCONNECTED: + return "CONNECTION_STATE_DISCONNECTED"; + case CONNECTION_STATE_CONNECTING: + return "CONNECTION_STATE_CONNECTING"; + case CONNECTION_STATE_CONNECTED: + return "CONNECTION_STATE_CONNECTED"; + case CONNECTION_STATE_SLC_CONNECTED: + return "CONNECTION_STATE_SLC_CONNECTED"; + case CONNECTION_STATE_DISCONNECTING: + return "CONNECTION_STATE_DISCONNECTING"; + default: + return "UNKNOWN STATE!!!"; + } + } } diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java b/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java index cc7e3851a1c85eaa771aa3ec162796581636df4f..8bb016ff0e8ae944b2f45636ecdff94f935c0725 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetNativeInterface.java @@ -22,6 +22,7 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -91,7 +92,11 @@ public class HeadsetNativeInterface { // Set bt_stack's active device to default if java layer set active device to null return Utils.getBytesFromAddress("00:00:00:00:00:00"); } - return mAdapterService.getByteIdentityAddress(device); + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getByteBrEdrAddress(device); + } else { + return mAdapterService.getByteIdentityAddress(device); + } } void onConnectionStateChanged(int state, byte[] address) { diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java index 17b1fa194c5b4760cf968f887f9379a64a3046b0..d6354ddd0bc128ad22be9186ec7d1855f4f7835a 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java @@ -55,10 +55,12 @@ import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.AudioRoutingManager; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfpclient.HeadsetClientService; import com.android.bluetooth.hfpclient.HeadsetClientStateMachine; import com.android.bluetooth.le_audio.LeAudioService; @@ -152,10 +154,7 @@ public class HeadsetService extends ProfileService { private final ServiceFactory mFactory = new ServiceFactory(); - HeadsetService() {} - - @VisibleForTesting - HeadsetService(Context ctx) { + public HeadsetService(Context ctx) { super(ctx); } @@ -169,7 +168,7 @@ public class HeadsetService extends ProfileService { } @Override - protected boolean start() { + public void start() { Log.i(TAG, "start()"); if (mStarted) { throw new IllegalStateException("start() called twice"); @@ -209,17 +208,16 @@ public class HeadsetService extends ProfileService { registerReceiver(mHeadsetReceiver, filter); // Step 7: Mark service as started mStarted = true; - return true; } @Override - protected boolean stop() { + public void stop() { Log.i(TAG, "stop()"); if (!mStarted) { Log.w(TAG, "stop() called before start()"); // Still return true because it is considered "stopped" and doesn't have any functional // impact on the user - return true; + return; } // Step 7: Mark service as stopped mStarted = false; @@ -280,11 +278,10 @@ public class HeadsetService extends ProfileService { mAdapterService = null; } setComponentAvailable(HFP_AG_IN_CALL_SERVICE, false); - return true; } @Override - protected void cleanup() { + public void cleanup() { Log.i(TAG, "cleanup"); } @@ -851,11 +848,16 @@ public class HeadsetService extends ProfileService { SynchronousResultReceiver receiver) { try { HeadsetService service = getService(source); - boolean defaultValue = false; if (service != null) { - defaultValue = service.setActiveDevice(device); + if (Flags.audioRoutingCentralization()) { + ((AudioRoutingManager) service.mAdapterService.getActiveDeviceManager()) + .activateDeviceProfile(device, BluetoothProfile.HEADSET, receiver); + } else { + receiver.send(service.setActiveDevice(device)); + } + } else { + receiver.send(false); } - receiver.send(defaultValue); } catch (RuntimeException e) { receiver.propagateException(e); } diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java index 29856803a8e4a62ac2eca78b81eb7f80dfd85740..38db4dc656f7eafc8e2abe5ebdc4c9318280d6a3 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java @@ -36,6 +36,7 @@ import android.os.Build; import android.os.Looper; import android.os.Message; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.UserHandle; import android.telephony.PhoneNumberUtils; import android.telephony.PhoneStateListener; @@ -48,6 +49,7 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -166,6 +168,10 @@ public class HeadsetStateMachine extends StateMachine { private BluetoothSinkAudioPolicy mHsClientAudioPolicy; + static final boolean IS_APTX_SUPPORT_ENABLED = + Flags.hfpCodecAptxVoice() + && SystemProperties.getBoolean("bluetooth.hfp.codec_aptx_voice.enabled", false); + // Keys are AT commands, and values are the company IDs. private static final Map VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID; @@ -201,8 +207,11 @@ public class HeadsetStateMachine extends StateMachine { HeadsetService headsetService, AdapterService adapterService, HeadsetNativeInterface nativeInterface, HeadsetSystemInterface systemInterface) { super(TAG, Objects.requireNonNull(looper, "looper cannot be null")); - // Enable/Disable StateMachine debug logs - setDbg(DBG); + + // Let the logging framework enforce the log level. TAG is set above in the parent + // constructor. + setDbg(true); + mDevice = Objects.requireNonNull(device, "device cannot be null"); mHeadsetService = Objects.requireNonNull(headsetService, "headsetService cannot be null"); mNativeInterface = @@ -458,7 +467,14 @@ public class HeadsetStateMachine extends StateMachine { * @param message the current message for the event * @param state connection state to transition to */ - public abstract void processConnectionEvent(Message message, int state); + public void processConnectionEvent(Message message, int state) { + stateLogD( + "processConnectionEvent, state=" + + HeadsetHalConstants.getConnectionStateName(state) + + "[" + + state + + "]"); + } /** * Get a state value from {@link BluetoothProfile} that represents the connection state of @@ -577,7 +593,7 @@ public class HeadsetStateMachine extends StateMachine { @Override public void processConnectionEvent(Message message, int state) { - stateLogD("processConnectionEvent, state=" + state); + super.processConnectionEvent(message, state); switch (state) { case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED: stateLogW("ignore DISCONNECTED event"); @@ -772,7 +788,7 @@ public class HeadsetStateMachine extends StateMachine { @Override public void processConnectionEvent(Message message, int state) { - stateLogD("processConnectionEvent, state=" + state); + super.processConnectionEvent(message, state); switch (state) { case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED: stateLogW("Disconnected"); @@ -867,6 +883,7 @@ public class HeadsetStateMachine extends StateMachine { // in Disconnecting state @Override public void processConnectionEvent(Message message, int state) { + super.processConnectionEvent(message, state); switch (state) { case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED: stateLogD("processConnectionEvent: Disconnected"); @@ -1092,7 +1109,7 @@ public class HeadsetStateMachine extends StateMachine { @Override public void processConnectionEvent(Message message, int state) { - stateLogD("processConnectionEvent, state=" + state); + super.processConnectionEvent(message, state); switch (state) { case HeadsetHalConstants.CONNECTION_STATE_CONNECTED: stateLogE("processConnectionEvent: RFCOMM connected again, shouldn't happen"); @@ -1489,6 +1506,11 @@ public class HeadsetStateMachine extends StateMachine { private void processIntentScoVolume(Intent intent, BluetoothDevice device) { int volumeValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0); + stateLogD( + "processIntentScoVolume: mSpeakerVolume=" + + mSpeakerVolume + + ", volumeValue=" + + volumeValue); if (mSpeakerVolume != volumeValue) { mSpeakerVolume = volumeValue; mNativeInterface.setVolume(device, HeadsetHalConstants.VOLUME_TYPE_SPK, @@ -1677,8 +1699,10 @@ public class HeadsetStateMachine extends StateMachine { + (" hasSwbEnabled=" + mHasSwbLc3Enabled) + (" hasAptXSwbEnabled=" + mHasSwbAptXEnabled)); am.setParameters("bt_lc3_swb=" + (mHasSwbLc3Enabled ? "on" : "off")); - /* AptX bt_swb: 0 -> on, 65535 -> off */ - am.setParameters("bt_swb=" + (mHasSwbAptXEnabled ? "0" : "65535")); + if (IS_APTX_SUPPORT_ENABLED) { + /* AptX bt_swb: 0 -> on, 65535 -> off */ + am.setParameters("bt_swb=" + (mHasSwbAptXEnabled ? "0" : "65535")); + } am.setBluetoothHeadsetProperties(getCurrentDeviceName(), mHasNrecEnabled, mHasWbsEnabled); } @@ -1905,8 +1929,10 @@ public class HeadsetStateMachine extends StateMachine { } private void processAtCind(BluetoothDevice device) { - int call, callSetup; + logi("processAtCind: for device=" + device); final HeadsetPhoneState phoneState = mSystemInterface.getHeadsetPhoneState(); + int call, callSetup; + int service = phoneState.getCindService(), signal = phoneState.getCindSignal(); /* Handsfree carkits expect that +CIND is properly responded to Hence we ensure that a proper response is sent @@ -1920,8 +1946,36 @@ public class HeadsetStateMachine extends StateMachine { callSetup = phoneState.getNumHeldCall(); } - mNativeInterface.cindResponse(device, phoneState.getCindService(), call, callSetup, - phoneState.getCallState(), phoneState.getCindSignal(), phoneState.getCindRoam(), + if (Flags.pretendNetworkService()) { + logd("processAtCind: pretendNetworkService enabled"); + boolean isCallOngoing = + (phoneState.getNumActiveCall() > 0) + || (phoneState.getNumHeldCall() > 0) + || phoneState.getCallState() == HeadsetHalConstants.CALL_STATE_ALERTING + || phoneState.getCallState() == HeadsetHalConstants.CALL_STATE_DIALING + || phoneState.getCallState() == HeadsetHalConstants.CALL_STATE_INCOMING; + if ((isCallOngoing + && (!mHeadsetService.isVirtualCallStarted()) + && (phoneState.getCindService() + == HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE))) { + logi( + "processAtCind: If regular call is in progress/active/held while no network" + + " during BT-ON, pretend service availability and signal strength"); + service = HeadsetHalConstants.NETWORK_STATE_AVAILABLE; + signal = 3; + } else { + service = phoneState.getCindService(); + signal = phoneState.getCindSignal(); + } + } + mNativeInterface.cindResponse( + device, + service, + call, + callSetup, + phoneState.getCallState(), + signal, + phoneState.getCindRoam(), phoneState.getCindBatteryCharge()); } diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java index 7e2df29077315de39ec0171377a9fd6e09c306ea..0de2e0980f4d9cb9118592de48dab6a4864c23f0 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java @@ -87,10 +87,7 @@ public class HeadsetClientService extends ProfileService { public static final String HFP_CLIENT_STOP_TAG = "hfp_client_stop_tag"; - HeadsetClientService() {} - - @VisibleForTesting - HeadsetClientService(Context ctx) { + public HeadsetClientService(Context ctx) { super(ctx); } @@ -104,14 +101,13 @@ public class HeadsetClientService extends ProfileService { } @Override - protected boolean start() { + public void start() { synchronized (mStartStopLock) { if (DBG) { Log.d(TAG, "start()"); } if (getHeadsetClientService() != null) { - Log.w(TAG, "start(): start called without stop"); - return false; + throw new IllegalStateException("start() called twice"); } mDatabaseManager = Objects.requireNonNull( @@ -155,17 +151,16 @@ public class HeadsetClientService extends ProfileService { mSmThread.start(); setHeadsetClientService(this); - return true; } } @Override - protected boolean stop() { + public void stop() { synchronized (mStartStopLock) { synchronized (HeadsetClientService.class) { if (sHeadsetClientService == null) { Log.w(TAG, "stop() called without start()"); - return false; + return; } // Stop the HfpClientConnectionService for non-wearables devices. @@ -196,8 +191,6 @@ public class HeadsetClientService extends ProfileService { mNativeInterface.cleanup(); mNativeInterface = null; - - return true; } } diff --git a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java index bc9fa5d18729887abf39f926fd20da7852b75622..aa4e6f4a2b2c2ddfeea35565d92e376d3cc290db 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java @@ -1372,11 +1372,9 @@ public class HeadsetClientStateMachine extends StateMachine { @Override public synchronized boolean processMessage(Message message) { logD("Connected process message: " + message.what); - if (DBG) { - if (mCurrentDevice == null) { - Log.e(TAG, "ERROR: mCurrentDevice is null in Connected"); - return NOT_HANDLED; - } + if (mCurrentDevice == null) { + Log.e(TAG, "ERROR: mCurrentDevice is null in Connected"); + return NOT_HANDLED; } switch (message.what) { @@ -1886,11 +1884,9 @@ public class HeadsetClientStateMachine extends StateMachine { @Override public synchronized boolean processMessage(Message message) { logD("AudioOn process message: " + message.what); - if (DBG) { - if (mCurrentDevice == null) { - Log.e(TAG, "ERROR: mCurrentDevice is null in Connected"); - return NOT_HANDLED; - } + if (mCurrentDevice == null) { + Log.e(TAG, "ERROR: mCurrentDevice is null in Connected"); + return NOT_HANDLED; } switch (message.what) { diff --git a/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java b/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java index 347a534b7a7917100d6ae2d563fb3aadb4dcb4eb..f50405f842b4681175782e29027077162bf5ed11 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java +++ b/android/app/src/com/android/bluetooth/hfpclient/HfpClientDeviceBlock.java @@ -38,10 +38,11 @@ import java.util.UUID; // Lifecycle of a Device Block is managed entirely by the Service which creates it. In essence it // has only the active state otherwise the block should be GCed. public class HfpClientDeviceBlock { - private static final String KEY_SCO_STATE = "com.android.bluetooth.hfpclient.SCO_STATE"; + private static final String TAG = "HfpClientDeviceBlock"; private static final boolean DBG = false; - private final String mTAG; + private static final String KEY_SCO_STATE = "com.android.bluetooth.hfpclient.SCO_STATE"; + private final BluetoothDevice mDevice; private final PhoneAccount mPhoneAccount; private final Map mConnections = new HashMap<>(); @@ -56,7 +57,6 @@ public class HfpClientDeviceBlock { mDevice = device; mConnServ = connServ; mServiceInterface = serviceInterface; - mTAG = "HfpClientDeviceBlock." + mDevice; mPhoneAccount = mConnServ.createAccount(device); mTelecomManager = mConnServ.getSystemService(TelecomManager.class); @@ -66,20 +66,16 @@ public class HfpClientDeviceBlock { mTelecomManager.setUserSelectedOutgoingPhoneAccount(mPhoneAccount.getAccountHandle()); mScoState = getScoStateFromDevice(device); - if (DBG) { - Log.d(mTAG, "SCO state = " + mScoState); - } + debug("SCO state = " + mScoState); List calls = mServiceInterface.getCurrentCalls(mDevice); - if (DBG) { - Log.d(mTAG, "Got calls " + calls); - } + debug("Got calls " + calls); if (calls == null) { // We can get null as a return if we are not connected. Hence there may // be a race in getting the broadcast and HFP Client getting // disconnected before broadcast gets delivered. - Log.w(mTAG, "Got connected but calls were null, ignoring the broadcast"); + warn("Got connected but calls were null, ignoring the broadcast"); return; } @@ -106,7 +102,7 @@ public class HfpClientDeviceBlock { connection.onAdded(); return connection; } else { - Log.e(mTAG, "Call " + callUuid + " ignored: connection does not exist"); + error("Call " + callUuid + " ignored: connection does not exist"); return null; } } @@ -120,9 +116,7 @@ public class HfpClientDeviceBlock { } synchronized void onAudioStateChange(int newState, int oldState) { - if (DBG) { - Log.d(mTAG, "Call audio state changed " + oldState + " -> " + newState); - } + debug("Call audio state changed " + oldState + " -> " + newState); mScoState.putInt(KEY_SCO_STATE, newState); for (HfpClientConnection connection : mConnections.values()) { @@ -140,7 +134,7 @@ public class HfpClientDeviceBlock { connection.onAdded(); return connection; } else { - Log.e(mTAG, "Call " + callUuid + " ignored: connection does not exist"); + error("Call " + callUuid + " ignored: connection does not exist"); return null; } } @@ -164,16 +158,14 @@ public class HfpClientDeviceBlock { // Remove existing calls and the phone account associated, the object will get garbage // collected soon synchronized void cleanup() { - Log.d(mTAG, "Resetting state for device " + mDevice); + debug("Resetting state for device " + mDevice); disconnectAll(); mTelecomManager.unregisterPhoneAccount(mPhoneAccount.getAccountHandle()); } // Handle call change synchronized void handleCall(HfpClientCall call) { - if (DBG) { - Log.d(mTAG, "Got call " + call.toString()); - } + debug("Got call " + call.toString()); HfpClientConnection connection = findConnectionKey(call); @@ -217,9 +209,7 @@ public class HfpClientDeviceBlock { mTelecomManager.addNewIncomingCall(mPhoneAccount.getAccountHandle(), b); } } else if (call.getState() == HfpClientCall.CALL_STATE_TERMINATED) { - if (DBG) { - Log.d(mTAG, "Removing call " + call); - } + debug("Removing call " + call); mConnections.remove(call.getUUID()); } @@ -228,9 +218,7 @@ public class HfpClientDeviceBlock { // Find the connection specified by the key, also update the key with ID if present. private synchronized HfpClientConnection findConnectionKey(HfpClientCall call) { - if (DBG) { - Log.d(mTAG, "findConnectionKey local key set " + mConnections.toString()); - } + debug("findConnectionKey local key set " + mConnections.toString()); return mConnections.get(call.getUUID()); } @@ -250,9 +238,7 @@ public class HfpClientDeviceBlock { private boolean isDisconnectingToActive(HfpClientConnection prevConn, HfpClientCall newCall) { - if (DBG) { - Log.d(mTAG, "prevConn " + prevConn.isClosing() + " new call " + newCall.getState()); - } + debug("prevConn " + prevConn.isClosing() + " new call " + newCall.getState()); if (prevConn.isClosing() && prevConn.getCall().getState() != newCall.getState() && newCall.getState() != HfpClientCall.CALL_STATE_TERMINATED) { return true; @@ -263,21 +249,18 @@ public class HfpClientDeviceBlock { private synchronized HfpClientConnection buildConnection(HfpClientCall call, Uri number) { if (call == null && number == null) { - Log.e(mTAG, "Both call and number cannot be null."); + error("Both call and number cannot be null."); return null; } - if (DBG) { - Log.d(mTAG, "Creating connection on " + mDevice + " for " + call + "/" + number); - } + debug("Creating connection on " + mDevice + " for " + call + "/" + number); HfpClientConnection connection = (call != null ? new HfpClientConnection(mDevice, call, mConnServ, mServiceInterface) : new HfpClientConnection(mDevice, number, mConnServ, mServiceInterface)); connection.setExtras(mScoState); - if (DBG) { - Log.d(mTAG, "Connection extras = " + connection.getExtras().toString()); - } + + debug("Connection extras = " + connection.getExtras().toString()); if (connection.getState() != Connection.STATE_DISCONNECTED) { mConnections.put(connection.getUUID(), connection); @@ -289,19 +272,14 @@ public class HfpClientDeviceBlock { // Updates any conferencable connections. private void updateConferenceableConnections() { boolean addConf = false; - if (DBG) { - Log.d(mTAG, "Existing connections: " + mConnections + " existing conference " - + mConference); - } + debug("Existing connections: " + mConnections + " existing conference " + mConference); // If we have an existing conference call then loop through all connections and update any // connections that may have switched from conference -> non-conference. if (mConference != null) { for (Connection confConn : mConference.getConnections()) { if (!((HfpClientConnection) confConn).inConference()) { - if (DBG) { - Log.d(mTAG, "Removing connection " + confConn + " from conference."); - } + debug("Removing connection " + confConn + " from conference."); mConference.removeConnection(confConn); } } @@ -319,9 +297,7 @@ public class HfpClientDeviceBlock { mConference.setExtras(mScoState); } if (mConference.addConnection(otherConn)) { - if (DBG) { - Log.d(mTAG, "Adding connection " + otherConn + " to conference."); - } + debug("Adding connection " + otherConn + " to conference."); addConf = true; } } @@ -329,9 +305,7 @@ public class HfpClientDeviceBlock { // If we have no connections in the conference we should simply end it. if (mConference != null && mConference.getConnections().size() == 0) { - if (DBG) { - Log.d(mTAG, "Conference has no connection, destroying"); - } + debug("Conference has no connection, destroying"); mConference.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL)); mConference.destroy(); mConference = null; @@ -339,9 +313,7 @@ public class HfpClientDeviceBlock { // If we have a valid conference and not previously added then add it. if (mConference != null && addConf) { - if (DBG) { - Log.d(mTAG, "Adding conference to stack."); - } + debug("Adding conference to stack."); mConnServ.addConference(mConference); } } @@ -407,4 +379,20 @@ public class HfpClientDeviceBlock { } } + + // Per-Device logging + + public void debug(String message) { + if (DBG) { + Log.d(TAG, "[device=" + mDevice + "] " + message); + } + } + + public void warn(String message) { + Log.w(TAG, "[device=" + mDevice + "] " + message); + } + + public void error(String message) { + Log.e(TAG, "[device=" + mDevice + "] " + message); + } } diff --git a/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java b/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java index 4ef93e74bf23f4359d9e004d33f6d85b9f1f7f52..a152a61d1dd20a16e39f8b3ca4b6ad5f4a64a56b 100644 --- a/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java +++ b/android/app/src/com/android/bluetooth/hfpclient/NativeInterface.java @@ -23,7 +23,9 @@ package com.android.bluetooth.hfpclient; import android.bluetooth.BluetoothDevice; import android.util.Log; +import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -339,7 +341,11 @@ public class NativeInterface { } private byte[] getByteAddress(BluetoothDevice device) { - return mAdapterService.getByteIdentityAddress(device); + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getByteBrEdrAddress(device); + } else { + return mAdapterService.getByteIdentityAddress(device); + } } // Callbacks from the native back into the java framework. All callbacks are routed via the diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java b/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java index 5aa7d24fd69345eea3937343afaec47c364527b2..d7e1ec5e09f91248dc968e207d3af89ce1d0be4f 100644 --- a/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java +++ b/android/app/src/com/android/bluetooth/hid/HidDeviceNativeInterface.java @@ -26,7 +26,9 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.util.Log; +import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -261,7 +263,11 @@ public class HidDeviceNativeInterface { } private byte[] getByteAddress(BluetoothDevice device) { - return mAdapterService.getByteIdentityAddress(device); + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getByteBrEdrAddress(device); + } else { + return mAdapterService.getByteIdentityAddress(device); + } } private native void initNative(); diff --git a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java index 72df0599fe7e62e2a0d4cad8364c1e23df41a018..99f2beb00542edc4e3e5091ad0c7ec27b69966ca 100644 --- a/android/app/src/com/android/bluetooth/hid/HidDeviceService.java +++ b/android/app/src/com/android/bluetooth/hid/HidDeviceService.java @@ -88,10 +88,7 @@ public class HidDeviceService extends ProfileService { private HidDeviceServiceHandler mHandler; - HidDeviceService() {} - - @VisibleForTesting - HidDeviceService(Context ctx) { + public HidDeviceService(Context ctx) { super(ctx); } @@ -277,6 +274,7 @@ public class HidDeviceService extends ProfileService { } public void cleanup() { + mService.unregisterApp(); mService = null; } } @@ -775,7 +773,7 @@ public class HidDeviceService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -791,18 +789,17 @@ public class HidDeviceService extends ProfileService { mActivityManager.addOnUidImportanceListener(mUidImportanceListener, FOREGROUND_IMPORTANCE_CUTOFF); setHidDeviceService(this); - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sHidDeviceService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } setHidDeviceService(null); @@ -811,14 +808,6 @@ public class HidDeviceService extends ProfileService { mNativeAvailable = false; } mActivityManager.removeOnUidImportanceListener(mUidImportanceListener); - return true; - } - - @Override - public boolean onUnbind(Intent intent) { - Log.d(TAG, "Need to unregister app"); - unregisterApp(); - return super.onUnbind(intent); } /** diff --git a/android/app/src/com/android/bluetooth/hid/HidHostService.java b/android/app/src/com/android/bluetooth/hid/HidHostService.java index 6071316b7e400c32c620ac10eba7cfaecbbe6e21..433ab301606aa0361d431925f50c40dbfcbf4a65 100644 --- a/android/app/src/com/android/bluetooth/hid/HidHostService.java +++ b/android/app/src/com/android/bluetooth/hid/HidHostService.java @@ -46,6 +46,7 @@ import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.util.ArrayList; @@ -88,12 +89,7 @@ public class HidHostService extends ProfileService { private static final int MESSAGE_ON_GET_IDLE_TIME = 15; private static final int MESSAGE_SET_IDLE_TIME = 16; - HidHostService() { - mNativeInterface = requireNonNull(HidHostNativeInterface.getInstance()); - } - - @VisibleForTesting - HidHostService(Context ctx) { + public HidHostService(Context ctx) { super(ctx); mNativeInterface = requireNonNull(HidHostNativeInterface.getInstance()); } @@ -108,7 +104,7 @@ public class HidHostService extends ProfileService { } @Override - protected boolean start() { + public void start() { mDatabaseManager = requireNonNull( AdapterService.getAdapterService().getDatabase(), @@ -122,19 +118,17 @@ public class HidHostService extends ProfileService { mNativeInterface.init(this); mNativeAvailable = true; setHidHostService(this); - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "Stopping Bluetooth HidHostService"); } - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) Log.d(TAG, "Stopping Bluetooth HidHostService"); if (mNativeAvailable) { mNativeInterface.cleanup(); @@ -161,7 +155,11 @@ public class HidHostService extends ProfileService { return Utils.getByteAddress(device); } else { // if only classic HID is available, force usage of BREDR address - return mAdapterService.getByteIdentityAddress(device); + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getByteBrEdrAddress(device); + } else { + return mAdapterService.getByteIdentityAddress(device); + } } } @@ -485,6 +483,43 @@ public class HidHostService extends ProfileService { } } + @Override + public void setPreferredTransport( + BluetoothDevice device, + int transport, + AttributionSource source, + SynchronousResultReceiver receiver) { + try { + HidHostService service = getService(source); + boolean defaultValue = false; + if (service != null) { + enforceBluetoothPrivilegedPermission(service); + defaultValue = service.setPreferredTransport(device, transport); + } + receiver.send(defaultValue); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + @Override + public void getPreferredTransport( + BluetoothDevice device, + AttributionSource source, + SynchronousResultReceiver receiver) { + try { + HidHostService service = getService(source); + int defaultValue = BluetoothDevice.TRANSPORT_AUTO; + if (service != null) { + enforceBluetoothPrivilegedPermission(service); + defaultValue = service.getPreferredTransport(device); + } + receiver.send(defaultValue); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + /* The following APIs regarding test app for compliance */ @Override public void getProtocolMode(BluetoothDevice device, AttributionSource source, @@ -714,6 +749,37 @@ public class HidHostService extends ProfileService { return true; } + /** + * @see BluetoothHidHost#setPreferredTransport + */ + boolean setPreferredTransport(BluetoothDevice device, int transport) { + if (DBG) { + Log.i(TAG, "setPreferredTransport: " + device + " transport: " + transport); + } + + if (device.getBondState() != BluetoothDevice.BOND_BONDED) { + Log.w(TAG, "Device not bonded" + device); + return false; + } + + boolean hidSupported = Utils.arrayContains(device.getUuids(), BluetoothUuid.HID); + boolean hogpSupported = Utils.arrayContains(device.getUuids(), BluetoothUuid.HOGP); + if (transport == BluetoothDevice.TRANSPORT_BREDR && !hidSupported) { + Log.w(TAG, "HID not supported: " + device); + return false; + } else if (transport == BluetoothDevice.TRANSPORT_LE && !hogpSupported) { + Log.w(TAG, "HOGP not supported: " + device); + return false; + } + + /* TODO: b/324094542 - Implement setPreferredTransport API + * Save transport preference in the persistent storage + * If connection policy allows connection, ensure that the preferred transport is + * connected and not the other one. + */ + return false; + } + /** * Get the connection policy of the profile. * @@ -734,6 +800,18 @@ public class HidHostService extends ProfileService { .getProfileConnectionPolicy(device, BluetoothProfile.HID_HOST); } + /** + * @see BluetoothHidHost#getPreferredTransport + */ + int getPreferredTransport(BluetoothDevice device) { + if (DBG) { + Log.d(TAG, "getPreferredTransport: " + device); + } + + // TODO: b/324094542 - Implement getPreferredTransport API + return BluetoothDevice.TRANSPORT_AUTO; + } + /* The following APIs regarding test app for compliance */ boolean getProtocolMode(BluetoothDevice device) { if (DBG) { @@ -931,6 +1009,9 @@ public class HidHostService extends ProfileService { intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + /* TODO: b/324094542 - Set correct transport as EXTRA_TRANSPORT + * intent.putExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_AUTO); + */ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions()); diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java index 2134c87835336b6a8c6223ab8658dbc9b7b7d5a6..95a6b8bce83b00f6f44dc5d69fda1f006cdc32f2 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java @@ -272,6 +272,19 @@ public class LeAudioNativeInterface { sendMessageToService(event); } + @VisibleForTesting + void onGroupStreamStatus(int groupId, int groupStreamStatus) { + LeAudioStackEvent event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED); + event.valueInt1 = groupId; + event.valueInt2 = groupStreamStatus; + + if (DBG) { + Log.d(TAG, "onGroupStreamStatus: " + event); + } + sendMessageToService(event); + } + /** * Initializes the native interface. * @@ -394,6 +407,17 @@ public class LeAudioNativeInterface { setUnicastMonitorModeNative(direction, enable); } + /** + * Confirm streaming request by other profile if there were such request + */ + public void confirmUnicastStreamRequest() { + if (DBG) { + Log.d(TAG, "confirmUnicastStreamRequest"); + } + + confirmUnicastStreamRequestNative(); + } + /** * Sends the audio preferences for the groupId to the native stack. * @@ -428,6 +452,7 @@ public class LeAudioNativeInterface { private native void setInCallNative(boolean inCall); private native void setUnicastMonitorModeNative(int direction, boolean enable); + private native void confirmUnicastStreamRequestNative(); /*package*/ private native void sendAudioProfilePreferencesNative(int groupId, boolean isOutputPreferenceLeAudio, boolean isDuplexPreferenceLeAudio); 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 61e97ca7ba43ef916d71bab3e60d1ec80287b055..fa16b4ec7c4925ea455f209e2051e69c3144db7f 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java @@ -20,11 +20,13 @@ package com.android.bluetooth.le_audio; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID; +import static com.android.bluetooth.flags.Flags.leaudioBroadcastFeatureSupport; import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission; import static com.android.modules.utils.build.SdkLevel.isAtLeastU; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; +import android.app.ActivityManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeAudio; @@ -48,11 +50,13 @@ import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.content.AttributionSource; +import android.content.Context; import android.content.Intent; import android.media.AudioDeviceCallback; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.BluetoothProfileConnectionInfo; +import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -60,6 +64,8 @@ import android.os.Parcel; import android.os.ParcelUuid; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.os.UserHandle; +import android.provider.Settings; import android.sysprop.BluetoothProperties; import android.util.Log; import android.util.Pair; @@ -67,30 +73,33 @@ import android.util.Pair; import com.android.bluetooth.Utils; import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.AudioRoutingManager; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.csip.CsipSetCoordinatorService; -import com.android.bluetooth.flags.FeatureFlags; -import com.android.bluetooth.flags.FeatureFlagsImpl; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.mcp.McpService; import com.android.bluetooth.tbs.TbsGatt; import com.android.bluetooth.tbs.TbsService; import com.android.bluetooth.vc.VolumeControlService; -import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; /** @@ -104,8 +113,6 @@ public class LeAudioService extends ProfileService { // 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_DEVICES = 10; private static LeAudioService sLeAudioService; /** @@ -123,15 +130,38 @@ public class LeAudioService extends ProfileService { */ private static final int AUDIO_DIRECTION_INPUT_BIT = 0x02; + /** + * This is used by application read-only for checking the fallback active group id. + * + */ + public static final String BLUETOOTH_LE_BROADCAST_FALLBACK_ACTIVE_GROUP_ID = + "bluetooth_le_broadcast_fallback_active_group_id"; + + /** + * Per PBP 1.0 4.3. High Quality Public Broadcast Audio, Broadcast HIGH quality audio configs + * are with sampling frequency 48khz + */ + private static final BluetoothLeAudioCodecConfig BROADCAST_HIGH_QUALITY_CONFIG = + new BluetoothLeAudioCodecConfig.Builder() + .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) + .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000) + .build(); + + /* 5 seconds timeout for Broadcast streaming state transition */ + private static final int DIALING_OUT_TIMEOUT_MS = 5000; + private AdapterService mAdapterService; private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; private volatile BluetoothDevice mActiveAudioOutDevice; private volatile BluetoothDevice mActiveAudioInDevice; + private volatile BluetoothDevice mActiveBroadcastAudioDevice; private BluetoothDevice mExposedActiveDevice; private LeAudioCodecConfig mLeAudioCodecConfig; - private final Object mGroupLock = new Object(); - private FeatureFlags mFeatureFlags = new FeatureFlagsImpl(); + private final ReentrantLock mGroupLock = new ReentrantLock(); + private final ReentrantReadWriteLock mGroupReadWriteLock = new ReentrantReadWriteLock(); + private final Lock mGroupReadLock = mGroupReadWriteLock.readLock(); + private final Lock mGroupWriteLock = mGroupReadWriteLock.writeLock(); ServiceFactory mServiceFactory = new ServiceFactory(); LeAudioNativeInterface mLeAudioNativeInterface; @@ -140,6 +170,7 @@ public class LeAudioService extends ProfileService { boolean mBluetoothEnabled = false; BluetoothDevice mHfpHandoverDevice = null; LeAudioBroadcasterNativeInterface mLeAudioBroadcasterNativeInterface = null; + private DialingOutTimeoutEvent mDialingOutTimeoutEvent = null; @VisibleForTesting AudioManager mAudioManager; LeAudioTmapGattServer mTmapGattServer; @@ -151,6 +182,7 @@ public class LeAudioService extends ProfileService { private boolean mAwaitingBroadcastCreateResponse = false; private final LinkedList mCreateBroadcastQueue = new LinkedList<>(); + boolean mIsSourceStreamMonitorModeEnabled = false; @VisibleForTesting TbsService mTbsService; @@ -179,6 +211,16 @@ public class LeAudioService extends ProfileService { /* When mScanCallback is not null, it means scan is started. */ ScanCallback mScanCallback; + public LeAudioService(Context ctx) { + super(ctx); + } + + @VisibleForTesting + LeAudioService(Context ctx, LeAudioNativeInterface nativeInterface) { + super(ctx); + mLeAudioNativeInterface = nativeInterface; + } + private class LeAudioGroupDescriptor { LeAudioGroupDescriptor(boolean isInbandRingtonEnabled) { mIsConnected = false; @@ -243,7 +285,6 @@ public class LeAudioService extends ProfileService { List mInputLocalCodecCapabilities = new ArrayList<>(); List mOutputLocalCodecCapabilities = new ArrayList<>(); - @GuardedBy("mGroupLock") private final Map mGroupDescriptors = new LinkedHashMap<>(); private final Map mDeviceDescriptors = new LinkedHashMap<>(); @@ -264,7 +305,8 @@ public class LeAudioService extends ProfileService { } public static boolean isBroadcastEnabled() { - return BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false); + return leaudioBroadcastFeatureSupport() + && BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false); } private boolean registerTmap() { @@ -285,7 +327,7 @@ public class LeAudioService extends ProfileService { } @Override - protected boolean start() { + public void start() { Log.i(TAG, "start()"); if (sLeAudioService != null) { throw new IllegalStateException("start() called twice"); @@ -293,8 +335,12 @@ public class LeAudioService extends ProfileService { mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), "AdapterService cannot be null when LeAudioService starts"); - mLeAudioNativeInterface = Objects.requireNonNull(LeAudioNativeInterface.getInstance(), - "LeAudioNativeInterface cannot be null when LeAudioService starts"); + if (mLeAudioNativeInterface == null) { + mLeAudioNativeInterface = + Objects.requireNonNull( + LeAudioNativeInterface.getInstance(), + "LeAudioNativeInterface cannot be null when LeAudioService starts"); + } mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(), "DatabaseManager cannot be null when LeAudioService starts"); @@ -308,9 +354,12 @@ public class LeAudioService extends ProfileService { mBroadcastDescriptors.clear(); - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ false); + try { mDeviceDescriptors.clear(); mGroupDescriptors.clear(); + } finally { + groupMutexUnlock(/* isReadOnly */ false); } // Setup broadcast callbacks @@ -350,8 +399,6 @@ public class LeAudioService extends ProfileService { // Delay the call to init by posting it. This ensures TBS and MCS are fully initialized // before we start accepting connections mHandler.post(this::init); - - return true; } private void init() { @@ -373,16 +420,19 @@ public class LeAudioService extends ProfileService { } @Override - protected boolean stop() { + public void stop() { Log.i(TAG, "stop()"); if (sLeAudioService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } mQueuedInCallValue = Optional.empty(); mCreateBroadcastQueue.clear(); mAwaitingBroadcastCreateResponse = false; + mIsSourceStreamMonitorModeEnabled = false; + + clearBroadcastTimeoutCallback(); mHandler.removeCallbacks(this::init); removeActiveDevice(false); @@ -398,32 +448,48 @@ public class LeAudioService extends ProfileService { stopAudioServersBackgroundScan(); mAudioServersScanner = null; - //Don't wait for async call with INACTIVE group status, clean active - //device for active group. - synchronized (mGroupLock) { - for (Map.Entry entry : mGroupDescriptors.entrySet()) { - LeAudioGroupDescriptor descriptor = entry.getValue(); - Integer group_id = entry.getKey(); - if (descriptor.mIsActive) { - descriptor.mIsActive = false; - updateActiveDevices(group_id, descriptor.mDirection, AUDIO_DIRECTION_NONE, - descriptor.mIsActive, false, false); - break; + // Don't wait for async call with INACTIVE group status, clean active + // device for active group. + groupMutexLock(/* isReadOnly */ true); + try { + try { + for (Map.Entry entry : + mGroupDescriptors.entrySet()) { + LeAudioGroupDescriptor descriptor = entry.getValue(); + Integer group_id = entry.getKey(); + if (descriptor.mIsActive) { + descriptor.mIsActive = false; + updateActiveDevices( + group_id, + descriptor.mDirection, + AUDIO_DIRECTION_NONE, + descriptor.mIsActive, + false, + false); + break; + } } - } - // Destroy state machines and stop handler thread - for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) { - LeAudioStateMachine sm = descriptor.mStateMachine; - if (sm == null) { - continue; + // Destroy state machines and stop handler thread + for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) { + LeAudioStateMachine sm = descriptor.mStateMachine; + if (sm == null) { + continue; + } + sm.quit(); + sm.cleanup(); + } + } finally { + if (Flags.leaudioApiSynchronizedBlockFix()) { + // Upgrade to write lock + groupMutexUnlock(/* isReadOnly */ true); + groupMutexLock(/* isReadOnly */ false); } - sm.quit(); - sm.cleanup(); } - mDeviceDescriptors.clear(); mGroupDescriptors.clear(); + } finally { + groupMutexUnlock(/* isReadOnly */ false); } // Cleanup native interfaces @@ -476,12 +542,10 @@ public class LeAudioService extends ProfileService { mVolumeControlService = null; mCsipSetCoordinatorService = null; mBassClientService = null; - - return true; } @Override - protected void cleanup() { + public void cleanup() { Log.i(TAG, "cleanup()"); } @@ -505,11 +569,6 @@ public class LeAudioService extends ProfileService { sLeAudioService = instance; } - @VisibleForTesting - void setFeatureFlags(FeatureFlags featureFlags) { - mFeatureFlags = featureFlags; - } - VolumeControlService getVolumeControlService() { if (mVolumeControlService == null) { mVolumeControlService = mServiceFactory.getVolumeControlService(); @@ -543,14 +602,6 @@ public class LeAudioService extends ProfileService { boolean isInbandRingtoneEnabled) { LeAudioDeviceDescriptor descriptor = mDeviceDescriptors.get(device); if (descriptor == null) { - - // Limit the maximum number of devices to avoid DoS attack - if (mDeviceDescriptors.size() >= MAX_LE_AUDIO_DEVICES) { - Log.e(TAG, "Maximum number of LeAudio state machines reached: " - + MAX_LE_AUDIO_DEVICES); - return null; - } - mDeviceDescriptors.put(device, new LeAudioDeviceDescriptor(isInbandRingtoneEnabled)); descriptor = mDeviceDescriptors.get(device); Log.d(TAG, "Created descriptor for device: " + device); @@ -587,7 +638,10 @@ public class LeAudioService extends ProfileService { return false; } - synchronized (mGroupLock) { + LeAudioStateMachine sm = null; + + groupMutexLock(/* isReadOnly */ false); + try { boolean isInbandRingtoneEnabled = false; int groupId = getGroupId(device); if (groupId != LE_AUDIO_GROUP_ID_INVALID) { @@ -598,17 +652,62 @@ public class LeAudioService extends ProfileService { return false; } - LeAudioStateMachine sm = getOrCreateStateMachine(device); + sm = getOrCreateStateMachine(device); if (sm == null) { Log.e(TAG, "Ignored connect request for " + device + " : no state machine"); return false; } + + if (!Flags.leaudioApiSynchronizedBlockFix()) { + sm.sendMessage(LeAudioStateMachine.CONNECT); + } + + } finally { + groupMutexUnlock(/* isReadOnly */ false); + } + + if (Flags.leaudioApiSynchronizedBlockFix()) { sm.sendMessage(LeAudioStateMachine.CONNECT); } return true; } + /** + * Disconnects LE Audio for the remote bluetooth device + * + * @param device is the device with which we would like to disconnect LE Audio + * @return true if profile disconnected, false if device not connected over LE Audio + */ + boolean disconnectV2(BluetoothDevice device) { + if (DBG) { + Log.d(TAG, "disconnectV2(): " + device); + } + + LeAudioStateMachine sm = null; + + groupMutexLock(/* isReadOnly */ true); + try { + LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); + if (descriptor == null) { + Log.e(TAG, "disconnect: No valid descriptor for device: " + device); + return false; + } + sm = descriptor.mStateMachine; + } finally { + groupMutexUnlock(/* isReadOnly */ true); + } + + if (sm == null) { + Log.e(TAG, "Ignored disconnect request for " + device + " : no state machine"); + return false; + } + + sm.sendMessage(LeAudioStateMachine.DISCONNECT); + + return true; + } + /** * Disconnects LE Audio for the remote bluetooth device * @@ -616,11 +715,16 @@ public class LeAudioService extends ProfileService { * @return true if profile disconnected, false if device not connected over LE Audio */ public boolean disconnect(BluetoothDevice device) { + if (Flags.leaudioApiSynchronizedBlockFix()) { + return disconnectV2(device); + } + if (DBG) { Log.d(TAG, "disconnect(): " + device); } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); if (descriptor == null) { Log.e(TAG, "disconnect: No valid descriptor for device: " + device); @@ -633,14 +737,18 @@ public class LeAudioService extends ProfileService { + " : no state machine"); return false; } + sm.sendMessage(LeAudioStateMachine.DISCONNECT); + } finally { + groupMutexUnlock(/* isReadOnly */ true); } return true; } public List getConnectedDevices() { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { List devices = new ArrayList<>(); for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) { LeAudioStateMachine sm = descriptor.mStateMachine; @@ -649,6 +757,8 @@ public class LeAudioService extends ProfileService { } } return devices; + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -669,7 +779,8 @@ public class LeAudioService extends ProfileService { if (bondedDevices == null) { return devices; } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (BluetoothDevice device : bondedDevices) { final ParcelUuid[] featureUuids = device.getUuids(); if (!Utils.arrayContains(featureUuids, BluetoothUuid.LE_AUDIO)) { @@ -695,6 +806,8 @@ public class LeAudioService extends ProfileService { } } return devices; + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -706,13 +819,16 @@ public class LeAudioService extends ProfileService { @VisibleForTesting List getDevices() { List devices = new ArrayList<>(); - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) { if (descriptor.mStateMachine != null) { devices.add(descriptor.mStateMachine.getDevice()); } } return devices; + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -726,7 +842,8 @@ public class LeAudioService extends ProfileService { * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected */ public int getConnectionState(BluetoothDevice device) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); if (descriptor == null) { return BluetoothProfile.STATE_DISCONNECTED; @@ -737,6 +854,8 @@ public class LeAudioService extends ProfileService { return BluetoothProfile.STATE_DISCONNECTED; } return sm.getConnectionState(); + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -774,8 +893,11 @@ public class LeAudioService extends ProfileService { * @return true given group exists, otherwise false */ public boolean isValidDeviceGroup(int groupId) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { return groupId != LE_AUDIO_GROUP_ID_INVALID && mGroupDescriptors.containsKey(groupId); + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -791,13 +913,16 @@ public class LeAudioService extends ProfileService { return result; } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (Map.Entry entry : mDeviceDescriptors.entrySet()) { if (entry.getValue().mGroupId == groupId) { result.add(entry.getKey()); } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } return result; } @@ -815,13 +940,16 @@ public class LeAudioService extends ProfileService { return result; } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (Map.Entry entry : mDeviceDescriptors.entrySet()) { if (entry.getValue().mGroupId == groupId) { result.add(entry.getKey()); } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } return result; } @@ -830,13 +958,16 @@ public class LeAudioService extends ProfileService { * Get the active device group id */ public Integer getActiveGroupId() { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (Map.Entry entry : mGroupDescriptors.entrySet()) { LeAudioGroupDescriptor descriptor = entry.getValue(); if (descriptor.mIsActive) { return entry.getKey(); } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } return LE_AUDIO_GROUP_ID_INVALID; } @@ -872,7 +1003,7 @@ public class LeAudioService extends ProfileService { Log.i(TAG, "Unicast group is active, queueing Broadcast creation, while the Unicast" + " group is deactivated."); mCreateBroadcastQueue.add(broadcastSettings); - if (mFeatureFlags.leaudioBroadcastAudioHandoverPolicies()) { + if (Flags.leaudioBroadcastAudioHandoverPolicies()) { mLeAudioNativeInterface.setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SINK, true); } @@ -903,16 +1034,52 @@ public class LeAudioService extends ProfileService { Log.i(TAG, "createBroadcast: isEncrypted=" + (isEncrypted ? "true" : "false")); mAwaitingBroadcastCreateResponse = true; - mLeAudioBroadcasterNativeInterface.createBroadcast(broadcastSettings.isPublicBroadcast(), - broadcastSettings.getBroadcastName(), broadcastCode, + mLeAudioBroadcasterNativeInterface.createBroadcast( + broadcastSettings.isPublicBroadcast(), + broadcastSettings.getBroadcastName(), + broadcastCode, publicMetadata == null ? null : publicMetadata.getRawMetadata(), - settingsList.stream() - .mapToInt(s -> s.getPreferredQuality()).toArray(), + getBroadcastAudioQualityPerSinkCapabilities(settingsList), settingsList.stream() .map(s -> s.getContentMetadata().getRawMetadata()) .toArray(byte[][]::new)); } + private int[] getBroadcastAudioQualityPerSinkCapabilities( + List settingsList) { + int[] preferredQualityArray = + settingsList.stream().mapToInt(s -> s.getPreferredQuality()).toArray(); + + BassClientService bassClientService = getBassClientService(); + if (bassClientService == null) { + return preferredQualityArray; + } + + for (BluetoothDevice sink : bassClientService.getConnectedDevices()) { + int groupId = getGroupId(sink); + if (groupId == LE_AUDIO_GROUP_ID_INVALID) { + continue; + } + + BluetoothLeAudioCodecStatus codecStatus = getCodecStatus(groupId); + if (codecStatus != null + && !codecStatus.isInputCodecConfigSelectable(BROADCAST_HIGH_QUALITY_CONFIG)) { + // If any sink device does not support high quality audio config, + // set all subgroup audio quality to standard quality for now before multi codec + // config support is ready + Log.i( + TAG, + "Sink device doesn't support HIGH broadcast audio quality, use STANDARD" + + " quality"); + Arrays.fill( + preferredQualityArray, + BluetoothLeBroadcastSubgroupSettings.QUALITY_STANDARD); + break; + } + } + return preferredQualityArray; + } + /** * Start LeAudio Broadcast instance. * @param broadcastId broadcast instance identifier @@ -923,6 +1090,11 @@ public class LeAudioService extends ProfileService { return; } if (DBG) Log.d(TAG, "startBroadcast"); + + /* Start timeout to recover from stucked/error start Broadcast operation */ + mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(); + mHandler.postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS); + mLeAudioBroadcasterNativeInterface.startBroadcast(broadcastId); } @@ -1027,7 +1199,7 @@ public class LeAudioService extends ProfileService { } if (DBG) Log.d(TAG, "destroyBroadcast"); - if (mFeatureFlags.leaudioBroadcastAudioHandoverPolicies()) { + if (Flags.leaudioBroadcastAudioHandoverPolicies()) { mLeAudioNativeInterface.setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SINK, false); } mLeAudioBroadcasterNativeInterface.destroyBroadcast(broadcastId); @@ -1058,6 +1230,15 @@ public class LeAudioService extends ProfileService { .collect(Collectors.toList()); } + /** + * Check if broadcast is active + * + * @return true if there is active broadcast, false otherwise + */ + public boolean isBroadcastActive() { + return !mBroadcastDescriptors.isEmpty(); + } + /** * Get the maximum number of supported simultaneous broadcasts. * @return number of supported simultaneous broadcasts @@ -1087,6 +1268,39 @@ public class LeAudioService extends ProfileService { return 1; } + /** + * Active Broadcast Assistant notification handler + */ + public void activeBroadcastAssistantNotification(boolean active) { + if (getBassClientService() == null) { + Log.w(TAG, "Ignore active Broadcast Assistant notification"); + return; + } + + if (active) { + mIsSourceStreamMonitorModeEnabled = true; + mLeAudioNativeInterface + .setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SOURCE, true); + } else { + if (mIsSourceStreamMonitorModeEnabled) { + mLeAudioNativeInterface + .setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SOURCE, false); + } + + mIsSourceStreamMonitorModeEnabled = false; + } + } + + /** Return true if device is primary - is active or was active before switch to broadcast */ + public boolean isPrimaryDevice(BluetoothDevice device) { + LeAudioDeviceDescriptor descriptor = mDeviceDescriptors.get(device); + if (descriptor == null) { + return false; + } + + return descriptor.mGroupId == mUnicastGroupIdDeactivatedForBroadcastTransition; + } + private boolean areBroadcastsAllStopped() { if (mBroadcastDescriptors == null) { Log.e(TAG, "areBroadcastsAllStopped: Invalid Broadcast Descriptors"); @@ -1113,11 +1327,27 @@ public class LeAudioService extends ProfileService { return Optional.empty(); } + private boolean areAllGroupsInNotActiveState() { + groupMutexLock(/* isReadOnly */ true); + try { + for (Map.Entry entry : mGroupDescriptors.entrySet()) { + LeAudioGroupDescriptor descriptor = entry.getValue(); + if (descriptor.mIsActive) { + return false; + } + } + } finally { + groupMutexUnlock(/* isReadOnly */ true); + } + return true; + } + private BluetoothDevice getLeadDeviceForTheGroup(Integer groupId) { if (groupId == LE_AUDIO_GROUP_ID_INVALID) { return null; } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId); if (groupDescriptor == null) { Log.e(TAG, "Group " + groupId + " does not exist"); @@ -1142,6 +1372,8 @@ public class LeAudioService extends ProfileService { groupDescriptor.mCurrentLeadDevice = sm.getDevice(); return groupDescriptor.mCurrentLeadDevice; } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } return null; } @@ -1372,7 +1604,8 @@ public class LeAudioService extends ProfileService { } boolean allLeAudioDevicesConnected() { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (Map.Entry deviceEntry : mDeviceDescriptors.entrySet()) { LeAudioDeviceDescriptor deviceDescriptor = deviceEntry.getValue(); @@ -1387,6 +1620,8 @@ public class LeAudioService extends ProfileService { return false; } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } return true; } @@ -1527,10 +1762,20 @@ public class LeAudioService extends ProfileService { * @param previousDevice previous no longer supported broadcast audio device */ private void updateBroadcastActiveDevice( - BluetoothDevice newDevice, BluetoothDevice previousDevice) { - mActiveAudioOutDevice = newDevice; + BluetoothDevice newDevice, + BluetoothDevice previousDevice, + boolean suppressNoisyIntent) { + mActiveBroadcastAudioDevice = newDevice; + if (DBG) { + Log.d( + TAG, + "updateBroadcastActiveDevice: newDevice: " + + newDevice + + ", previousDevice: " + + previousDevice); + } mAudioManager.handleBluetoothActiveDeviceChanged( - newDevice, previousDevice, getBroadcastProfile(true)); + newDevice, previousDevice, getBroadcastProfile(suppressNoisyIntent)); } /* @@ -1577,8 +1822,7 @@ public class LeAudioService extends ProfileService { if (notifyAndUpdateInactiveOutDeviceOnly && ((newSupportedAudioDirections & AUDIO_DIRECTION_INPUT_BIT) != 0)) { newInDevice = getLeadDeviceForTheGroup(groupId); - } else if (mFeatureFlags.leaudioBroadcastAudioHandoverPolicies() - && wasSetSinkListeningMode()) { + } else if (Flags.leaudioBroadcastAudioHandoverPolicies() && wasSetSinkListeningMode()) { mLeAudioNativeInterface.setUnicastMonitorMode(LeAudioStackEvent.DIRECTION_SINK, false); } @@ -1643,7 +1887,8 @@ public class LeAudioService extends ProfileService { } private void clearInactiveDueToContextTypeFlags() { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (Map.Entry groupEntry : mGroupDescriptors.entrySet()) { LeAudioGroupDescriptor groupDescriptor = groupEntry.getValue(); @@ -1654,6 +1899,8 @@ public class LeAudioService extends ProfileService { groupDescriptor.mInactivatedDueToContextType = false; } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -1693,6 +1940,16 @@ public class LeAudioService extends ProfileService { + mExposedActiveDevice); } + if (isBroadcastActive() + && currentlyActiveGroupId == LE_AUDIO_GROUP_ID_INVALID + && mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID + && groupId != LE_AUDIO_GROUP_ID_INVALID) { + // If broadcast is ongoing and need to update unicast fallback active group + // we need to update the cached group id and skip changing the active device + updateFallbackUnicastGroupIdForBroadcast(groupId); + return; + } + LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(currentlyActiveGroupId); if (groupDescriptor != null && groupId == currentlyActiveGroupId) { /* Make sure active group is already exposed to audio framework. @@ -1768,7 +2025,7 @@ public class LeAudioService extends ProfileService { return false; } - if (!mFeatureFlags.audioRoutingCentralization()) { + if (!Flags.audioRoutingCentralization()) { // If AUDIO_ROUTING_CENTRALIZATION, this will be checked inside AudioRoutingManager. if (Utils.isDualModeAudioEnabled()) { if (!mAdapterService.isAllSupportedClassicAudioProfilesActive(device)) { @@ -1860,7 +2117,8 @@ public class LeAudioService extends ProfileService { Log.d(TAG, "connect(): " + storedDevice); } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioStateMachine sm = getOrCreateStateMachine(storedDevice); if (sm == null) { Log.e(TAG, "Ignored connect request for " + storedDevice @@ -1868,6 +2126,8 @@ public class LeAudioService extends ProfileService { continue; } sm.sendMessage(LeAudioStateMachine.CONNECT); + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } } @@ -1887,7 +2147,8 @@ public class LeAudioService extends ProfileService { } private void clearLostDevicesWhileStreaming(LeAudioGroupDescriptor descriptor) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { if (DBG) { Log.d(TAG, "Clearing lost dev: " + descriptor.mLostLeadDeviceWhileStreaming); } @@ -1910,6 +2171,8 @@ public class LeAudioService extends ProfileService { sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent); } descriptor.mLostLeadDeviceWhileStreaming = null; + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -1968,7 +2231,7 @@ public class LeAudioService extends ProfileService { 1); break; case LeAudioStackEvent.HEALTH_RECOMMENDATION_ACTION_INACTIVATE_GROUP: - if (mFeatureFlags.leaudioUnicastInactivateDeviceBasedOnContext()) { + if (Flags.leaudioUnicastInactivateDeviceBasedOnContext()) { LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId); if (groupDescriptor != null && groupDescriptor.mIsActive) { Log.i( @@ -1986,7 +2249,8 @@ public class LeAudioService extends ProfileService { } private void handleGroupTransitToActive(int groupId) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null || descriptor.mIsActive) { Log.e(TAG, "handleGroupTransitToActive: no descriptors for group: " + groupId @@ -2001,11 +2265,14 @@ public class LeAudioService extends ProfileService { notifyGroupStatusChanged(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); updateInbandRingtoneForTheGroup(groupId); } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } private void handleGroupTransitToInactive(int groupId) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null || !descriptor.mIsActive) { Log.e(TAG, "handleGroupTransitToInactive: no descriptors for group: " + groupId @@ -2018,11 +2285,21 @@ public class LeAudioService extends ProfileService { */ boolean leaveConnectedInputDevice = false; Integer newDirections = AUDIO_DIRECTION_NONE; - if (mFeatureFlags.leaudioBroadcastAudioHandoverPolicies() + if (Flags.leaudioBroadcastAudioHandoverPolicies() && (!mCreateBroadcastQueue.isEmpty() || mBroadcastIdDeactivatedForUnicastTransition.isPresent())) { leaveConnectedInputDevice = true; newDirections |= AUDIO_DIRECTION_INPUT_BIT; + + /* Update Broadcast device before streaming state in handover case to avoid switch + * to non LE Audio device in Audio Manager e.g. Phone Speaker. + */ + BluetoothDevice device = + mAdapterService.getDeviceFromByte( + Utils.getBytesFromAddress("FF:FF:FF:FF:FF:FF")); + if (!device.equals(mActiveBroadcastAudioDevice)) { + updateBroadcastActiveDevice(device, mActiveBroadcastAudioDevice, true); + } } descriptor.mIsActive = false; @@ -2039,10 +2316,12 @@ public class LeAudioService extends ProfileService { clearLostDevicesWhileStreaming(descriptor); notifyGroupStatusChanged(groupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE); updateInbandRingtoneForTheGroup(groupId); + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } - private void handleUnicastStreamStatusChange(int status) { + private void handleSinkStreamStatusChange(int status) { if (DBG) { Log.d(TAG, "status: " + status); } @@ -2064,7 +2343,47 @@ public class LeAudioService extends ProfileService { mBroadcastIdDeactivatedForUnicastTransition = Optional.of(broadcastId.get()); pauseBroadcast(broadcastId.get()); } else if (status == LeAudioStackEvent.STATUS_LOCAL_STREAM_SUSPENDED) { - removeActiveDevice(true); + if (!areAllGroupsInNotActiveState()) { + removeActiveDevice(true); + } + } + } + + private void handleSourceStreamStatusChange(int status) { + BassClientService bassClientService = getBassClientService(); + if (bassClientService == null) { + Log.e(TAG, "handleSourceStreamStatusChange: BASS Client service is not available"); + + mLeAudioNativeInterface.setUnicastMonitorMode( + LeAudioStackEvent.DIRECTION_SOURCE, false); + } + + bassClientService.handleUnicastSourceStreamStatusChange(status); + } + + private void handleUnicastStreamStatusChange(int direction, int status) { + if (direction == LeAudioStackEvent.DIRECTION_SINK) { + handleSinkStreamStatusChange(status); + } else if (direction == LeAudioStackEvent.DIRECTION_SOURCE) { + handleSourceStreamStatusChange(status); + } else { + Log.e(TAG, "handleUnicastStreamStatusChange: invalid direction: " + direction); + } + } + + private void notifyGroupStreamStatusChanged(int groupId, int groupStreamStatus) { + if (mLeAudioCallbacks != null) { + int n = mLeAudioCallbacks.beginBroadcast(); + for (int i = 0; i < n; i++) { + try { + mLeAudioCallbacks + .getBroadcastItem(i) + .onGroupStreamStatusChanged(groupId, groupStreamStatus); + } catch (RemoteException e) { + continue; + } + } + mLeAudioCallbacks.finishBroadcast(); } } @@ -2107,7 +2426,8 @@ public class LeAudioService extends ProfileService { return; } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId); if (groupDescriptor == null) { Log.e(TAG, "group descriptor for " + groupId + " does not exist"); @@ -2165,6 +2485,8 @@ public class LeAudioService extends ProfileService { } } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -2176,8 +2498,8 @@ public class LeAudioService extends ProfileService { if (mAudioServersScanner == null || mScanCallback == null) { if (DBG) { Log.d(TAG, "stopAudioServersBackgroundScan: already stopped"); - return; } + return; } try { @@ -2211,8 +2533,8 @@ public class LeAudioService extends ProfileService { if (mScanCallback != null) { if (DBG) { Log.d(TAG, "startAudioServersBackgroundScan: Scanning already enabled"); - return; } + return; } mScanCallback = new AudioServerScanCallback(); } @@ -2256,9 +2578,13 @@ public class LeAudioService extends ProfileService { BluetoothDevice unicastDevice = getLeadDeviceForTheGroup(mUnicastGroupIdDeactivatedForBroadcastTransition); if (unicastDevice == null) { - Log.e(TAG, "EVENT_TYPE_BROADCAST_DESTROYED: No valid unicast device for group ID: " - + mUnicastGroupIdDeactivatedForBroadcastTransition); - mUnicastGroupIdDeactivatedForBroadcastTransition = LE_AUDIO_GROUP_ID_INVALID; + /* All devices from group were disconnected in meantime */ + Log.w( + TAG, + "transitionFromBroadcastToUnicast: No valid unicast device for group ID: " + + mUnicastGroupIdDeactivatedForBroadcastTransition); + updateFallbackUnicastGroupIdForBroadcast(LE_AUDIO_GROUP_ID_INVALID); + updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false); return; } @@ -2269,11 +2595,25 @@ public class LeAudioService extends ProfileService { + unicastDevice); } - mUnicastGroupIdDeactivatedForBroadcastTransition = LE_AUDIO_GROUP_ID_INVALID; - + updateFallbackUnicastGroupIdForBroadcast(LE_AUDIO_GROUP_ID_INVALID); setActiveDevice(unicastDevice); } + void clearBroadcastTimeoutCallback() { + if (mHandler == null) { + Log.e(TAG, "No callback handler"); + return; + } + + /* Timeout callback already cleared */ + if (mDialingOutTimeoutEvent == null) { + return; + } + + mHandler.removeCallbacks(mDialingOutTimeoutEvent); + mDialingOutTimeoutEvent = null; + } + // Suppressed since this is part of a local process @SuppressLint("AndroidFrameworkRequiresPermission") void messageFromNative(LeAudioStackEvent stackEvent) { @@ -2282,7 +2622,8 @@ public class LeAudioService extends ProfileService { if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) { // Some events require device state machine - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); if (deviceDescriptor == null) { Log.e(TAG, "messageFromNative: No valid descriptor for device: " + device); @@ -2359,6 +2700,8 @@ public class LeAudioService extends ProfileService { sm.sendMessage(LeAudioStateMachine.STACK_EVENT, stackEvent); return; + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED) { int groupId = stackEvent.valueInt1; @@ -2428,7 +2771,8 @@ public class LeAudioService extends ProfileService { int src_audio_location = stackEvent.valueInt4; int available_contexts = stackEvent.valueInt5; - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor != null) { if (descriptor.mIsActive) { @@ -2455,6 +2799,8 @@ public class LeAudioService extends ProfileService { } else { Log.e(TAG, "messageFromNative: no descriptors for group: " + groupId); } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE) { Objects.requireNonNull(stackEvent.device, @@ -2481,6 +2827,11 @@ public class LeAudioService extends ProfileService { switch (groupStatus) { case LeAudioStackEvent.GROUP_STATUS_ACTIVE: { handleGroupTransitToActive(groupId); + + /* Clear possible exposed broadcast device after activating unicast */ + if (mActiveBroadcastAudioDevice != null) { + updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, true); + } break; } case LeAudioStackEvent.GROUP_STATUS_INACTIVE: { @@ -2488,14 +2839,14 @@ public class LeAudioService extends ProfileService { /* Check if broadcast was deactivated due to unicast */ if (mBroadcastIdDeactivatedForUnicastTransition.isPresent()) { - mUnicastGroupIdDeactivatedForBroadcastTransition = groupId; + updateFallbackUnicastGroupIdForBroadcast(groupId); mQueuedInCallValue = Optional.empty(); startBroadcast(mBroadcastIdDeactivatedForUnicastTransition.get()); mBroadcastIdDeactivatedForUnicastTransition = Optional.empty(); } if (!mCreateBroadcastQueue.isEmpty()) { - mUnicastGroupIdDeactivatedForBroadcastTransition = groupId; + updateFallbackUnicastGroupIdForBroadcast(groupId); BluetoothLeBroadcastSettings settings = mCreateBroadcastQueue.remove(); createBroadcast(settings); } @@ -2519,15 +2870,27 @@ public class LeAudioService extends ProfileService { boolean success = stackEvent.valueBool1; if (success) { Log.d(TAG, "Broadcast broadcastId: " + broadcastId + " created."); - notifyBroadcastStarted(broadcastId, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); - mBroadcastDescriptors.put(broadcastId, new LeAudioBroadcastDescriptor()); - + notifyBroadcastStarted(broadcastId, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); // Start sending the actual stream startBroadcast(broadcastId); } else { // TODO: Improve reason reporting or extend the native stack event with reason code + Log.e( + TAG, + "EVENT_TYPE_BROADCAST_CREATED: Failed to create broadcast: " + broadcastId); + + /* Disconnect Broadcast device which was connected to avoid non LE Audio sound + * leak in handover scenario. + */ + if ((mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID) + && mCreateBroadcastQueue.isEmpty() + && (!Objects.equals(device, mActiveBroadcastAudioDevice))) { + clearBroadcastTimeoutCallback(); + updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false); + } + notifyBroadcastStartFailed(broadcastId, BluetoothStatusCodes.ERROR_UNKNOWN); } @@ -2541,23 +2904,22 @@ public class LeAudioService extends ProfileService { } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_BROADCAST_DESTROYED) { Integer broadcastId = stackEvent.valueInt1; + LeAudioBroadcastDescriptor descriptor = mBroadcastDescriptors.get(broadcastId); + if (descriptor == null) { + Log.e( + TAG, + "EVENT_TYPE_BROADCAST_DESTROYED: No valid descriptor for broadcastId: " + + broadcastId); + } else { + mBroadcastDescriptors.remove(broadcastId); + } // TODO: Improve reason reporting or extend the native stack event with reason code notifyOnBroadcastStopped(broadcastId, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); - BassClientService bassClientService = getBassClientService(); if (bassClientService != null) { bassClientService.stopReceiversSourceSynchronization(broadcastId); } - - LeAudioBroadcastDescriptor descriptor = mBroadcastDescriptors.get(broadcastId); - if (descriptor == null) { - Log.e(TAG, "EVENT_TYPE_BROADCAST_DESTROYED: No valid descriptor for broadcastId: " - + broadcastId); - return; - } - mBroadcastDescriptors.remove(broadcastId); - } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE) { int broadcastId = stackEvent.valueInt1; int state = stackEvent.valueInt2; @@ -2587,19 +2949,21 @@ public class LeAudioService extends ProfileService { notifyPlaybackStopped(broadcastId, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); - // Notify audio manager - if (mBroadcastDescriptors.values().stream() - .noneMatch( - d -> - d.mState.equals( - LeAudioStackEvent.BROADCAST_STATE_STREAMING))) { - updateBroadcastActiveDevice(null, mActiveAudioOutDevice); - } /* Restore the Unicast stream from before the Broadcast was started. */ if (mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID) { transitionFromBroadcastToUnicast(); + } else { + // Notify audio manager + if (mBroadcastDescriptors.values().stream() + .noneMatch( + d -> + d.mState.equals( + LeAudioStackEvent + .BROADCAST_STATE_STREAMING))) { + updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false); + } } destroyBroadcast(broadcastId); break; @@ -2622,11 +2986,21 @@ public class LeAudioService extends ProfileService { bassClientService.suspendReceiversSourceSynchronization(broadcastId); } - // Notify audio manager - updateBroadcastActiveDevice(null, mActiveAudioOutDevice); - /* Restore the Unicast stream from before the Broadcast was started. */ - transitionFromBroadcastToUnicast(); + if (mUnicastGroupIdDeactivatedForBroadcastTransition + != LE_AUDIO_GROUP_ID_INVALID) { + transitionFromBroadcastToUnicast(); + } else { + // Notify audio manager + if (mBroadcastDescriptors.values().stream() + .noneMatch( + d -> + d.mState.equals( + LeAudioStackEvent + .BROADCAST_STATE_STREAMING))) { + updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false); + } + } break; case LeAudioStackEvent.BROADCAST_STATE_STOPPING: if (DBG) Log.d(TAG, "Broadcast broadcastId: " + broadcastId + " stopping."); @@ -2638,9 +3012,11 @@ public class LeAudioService extends ProfileService { notifyPlaybackStarted(broadcastId, BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST); + clearBroadcastTimeoutCallback(); + if (previousState == LeAudioStackEvent.BROADCAST_STATE_PAUSED) { if (bassClientService != null) { - bassClientService.resumeReceiversSourceSynchronization(broadcastId); + bassClientService.resumeReceiversSourceSynchronization(); } } @@ -2650,8 +3026,8 @@ public class LeAudioService extends ProfileService { d -> d.mState.equals( LeAudioStackEvent.BROADCAST_STATE_STREAMING))) { - if (!Objects.equals(device, mActiveAudioOutDevice)) { - updateBroadcastActiveDevice(device, mActiveAudioOutDevice); + if (!Objects.equals(device, mActiveBroadcastAudioDevice)) { + updateBroadcastActiveDevice(device, mActiveBroadcastAudioDevice, true); } } break; @@ -2659,6 +3035,13 @@ public class LeAudioService extends ProfileService { Log.e(TAG, "Invalid state of broadcast: " + descriptor.mState); break; } + + // Notify broadcast assistant + if (Flags.leaudioBroadcastAudioHandoverPolicies()) { + if (bassClientService != null) { + bassClientService.notifyBroadcastStateChanged(descriptor.mState, broadcastId); + } + } } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_BROADCAST_METADATA_CHANGED) { int broadcastId = stackEvent.valueInt1; if (stackEvent.broadcastMetadata == null) { @@ -2685,11 +3068,9 @@ public class LeAudioService extends ProfileService { mTmapStarted = registerTmap(); } } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS) { - if (stackEvent.valueInt1 == LeAudioStackEvent.DIRECTION_SINK) { - handleUnicastStreamStatusChange(stackEvent.valueInt2); - } else { - Log.e(TAG, "Invalid direction: " + stackEvent.valueInt2); - } + handleUnicastStreamStatusChange(stackEvent.valueInt1, stackEvent.valueInt2); + } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED) { + notifyGroupStreamStatusChanged(stackEvent.valueInt1, stackEvent.valueInt2); } } @@ -2716,11 +3097,7 @@ public class LeAudioService extends ProfileService { sm = LeAudioStateMachine.make( - device, - this, - mLeAudioNativeInterface, - mStateMachinesThread.getLooper(), - mFeatureFlags); + device, this, mLeAudioNativeInterface, mStateMachinesThread.getLooper()); descriptor.mStateMachine = sm; return sm; } @@ -2748,58 +3125,85 @@ public class LeAudioService extends ProfileService { return; } - synchronized (mGroupLock) { - LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); - if (descriptor == null) { - Log.e(TAG, "bondStateChanged: No valid descriptor for device: " + device); - return; - } + groupMutexLock(/* isReadOnly */ true); + try { + try { + LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); + if (descriptor == null) { + Log.e(TAG, "bondStateChanged: No valid descriptor for device: " + device); + return; + } - if (descriptor.mGroupId != LE_AUDIO_GROUP_ID_INVALID) { - /* In case device is still in the group, let's remove it */ - mLeAudioNativeInterface.groupRemoveNode(descriptor.mGroupId, device); - } + if (descriptor.mGroupId != LE_AUDIO_GROUP_ID_INVALID) { + /* In case device is still in the group, let's remove it */ + mLeAudioNativeInterface.groupRemoveNode(descriptor.mGroupId, device); + } - descriptor.mGroupId = LE_AUDIO_GROUP_ID_INVALID; - descriptor.mSinkAudioLocation = BluetoothLeAudio.AUDIO_LOCATION_INVALID; - descriptor.mDirection = AUDIO_DIRECTION_NONE; + descriptor.mGroupId = LE_AUDIO_GROUP_ID_INVALID; + descriptor.mSinkAudioLocation = BluetoothLeAudio.AUDIO_LOCATION_INVALID; + descriptor.mDirection = AUDIO_DIRECTION_NONE; - LeAudioStateMachine sm = descriptor.mStateMachine; - if (sm == null) { - return; - } - if (sm.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) { - Log.w(TAG, "Device is not disconnected yet."); - disconnect(device); - return; + LeAudioStateMachine sm = descriptor.mStateMachine; + if (sm == null) { + return; + } + if (sm.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) { + Log.w(TAG, "Device is not disconnected yet."); + disconnect(device); + return; + } + } finally { + // Reduce size of critical section when this feature is enabled + if (Flags.leaudioApiSynchronizedBlockFix()) { + groupMutexUnlock(/* isReadOnly */ true); + } } removeStateMachine(device); + removeAuthorizationInfoForRelatedProfiles(device); + } finally { + if (!Flags.leaudioApiSynchronizedBlockFix()) { + groupMutexUnlock(/* isReadOnly */ true); + } } } private void removeStateMachine(BluetoothDevice device) { - synchronized (mGroupLock) { - LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); - if (descriptor == null) { - Log.e(TAG, "removeStateMachine: No valid descriptor for device: " + device); - return; - } + groupMutexLock(/* isReadOnly */ true); + try { + try { + LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); + if (descriptor == null) { + Log.e(TAG, "removeStateMachine: No valid descriptor for device: " + device); + return; + } - LeAudioStateMachine sm = descriptor.mStateMachine; - if (sm == null) { - Log.w(TAG, "removeStateMachine: device " + device - + " does not have a state machine"); - return; + LeAudioStateMachine sm = descriptor.mStateMachine; + if (sm == null) { + Log.w( + TAG, + "removeStateMachine: device " + + device + + " does not have a state machine"); + return; + } + Log.i(TAG, "removeStateMachine: removing state machine for device: " + device); + sm.quit(); + sm.cleanup(); + descriptor.mStateMachine = null; + } finally { + if (Flags.leaudioApiSynchronizedBlockFix()) { + // Upgrade to write lock + groupMutexUnlock(/* isReadOnly */ true); + groupMutexLock(/* isReadOnly */ false); + } } - Log.i(TAG, "removeStateMachine: removing state machine for device: " + device); - sm.quit(); - sm.cleanup(); - descriptor.mStateMachine = null; - mDeviceDescriptors.remove(device); if (!isScannerNeeded()) { stopAudioServersBackgroundScan(); } + } finally { + /* Note, when flag is disabled, isReadyOnly param have no impact */ + groupMutexUnlock(/* isReadOnly */ false); } } @@ -2845,14 +3249,23 @@ public class LeAudioService extends ProfileService { } } - /** - * Process a change for disconnection of a device. - */ - public synchronized void deviceDisconnected(BluetoothDevice device, boolean hasFallbackDevice) { - LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); - if (deviceDescriptor == null) { - Log.e(TAG, "deviceDisconnected: No valid descriptor for device: " + device); - return; + /** Process a change for disconnection of a device. */ + synchronized void deviceDisconnectedV2(BluetoothDevice device, boolean hasFallbackDevice) { + if (DBG) { + Log.d(TAG, "deviceDisconnectedV2 " + device); + } + + int groupId = LE_AUDIO_GROUP_ID_INVALID; + groupMutexLock(/* isReadOnly */ true); + try { + LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); + if (deviceDescriptor == null) { + Log.e(TAG, "deviceDisconnected: No valid descriptor for device: " + device); + return; + } + groupId = deviceDescriptor.mGroupId; + } finally { + groupMutexUnlock(/* isReadOnly */ true); } int bondState = mAdapterService.getBondState(device); @@ -2860,14 +3273,100 @@ public class LeAudioService extends ProfileService { if (DBG) { Log.d(TAG, device + " is unbond. Remove state machine"); } + removeStateMachine(device); + removeAuthorizationInfoForRelatedProfiles(device); } if (!isScannerNeeded()) { stopAudioServersBackgroundScan(); } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { + LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); + if (descriptor == null) { + Log.e(TAG, "deviceDisconnected: no descriptors for group: " + groupId); + return; + } + + List connectedDevices = getConnectedPeerDevices(groupId); + /* Let's check if the last connected device is really connected */ + if (connectedDevices.size() == 1 + && Objects.equals( + connectedDevices.get(0), descriptor.mLostLeadDeviceWhileStreaming)) { + clearLostDevicesWhileStreaming(descriptor); + return; + } + + if (getConnectedPeerDevices(groupId).isEmpty()) { + descriptor.mIsConnected = false; + if (descriptor.mIsActive) { + /* Notify Native layer */ + removeActiveDevice(hasFallbackDevice); + descriptor.mIsActive = false; + /* Update audio framework */ + updateActiveDevices( + groupId, + descriptor.mDirection, + descriptor.mDirection, + descriptor.mIsActive, + hasFallbackDevice, + false); + return; + } + } + + if (descriptor.mIsActive + || Objects.equals(mActiveAudioOutDevice, device) + || Objects.equals(mActiveAudioInDevice, device)) { + updateActiveDevices( + groupId, + descriptor.mDirection, + descriptor.mDirection, + descriptor.mIsActive, + hasFallbackDevice, + false); + } + } finally { + groupMutexUnlock(/* isReadOnly */ true); + } + } + + /** + * Process a change for disconnection of a device. + */ + public synchronized void deviceDisconnected(BluetoothDevice device, boolean hasFallbackDevice) { + if (Flags.leaudioApiSynchronizedBlockFix()) { + deviceDisconnectedV2(device, hasFallbackDevice); + return; + } + + if (DBG) { + Log.d(TAG, "deviceDisconnected " + device); + } + + groupMutexLock(/* isReadOnly */ true); + try { + LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); + if (deviceDescriptor == null) { + Log.e(TAG, "deviceDisconnected: No valid descriptor for device: " + device); + return; + } + + int bondState = mAdapterService.getBondState(device); + if (bondState == BluetoothDevice.BOND_NONE) { + if (DBG) { + Log.d(TAG, device + " is unbond. Remove state machine"); + } + removeStateMachine(device); + removeAuthorizationInfoForRelatedProfiles(device); + } + + if (!isScannerNeeded()) { + stopAudioServersBackgroundScan(); + } + LeAudioGroupDescriptor descriptor = getGroupDescriptor(deviceDescriptor.mGroupId); if (descriptor == null) { Log.e(TAG, "deviceDisconnected: no descriptors for group: " @@ -2910,6 +3409,8 @@ public class LeAudioService extends ProfileService { hasFallbackDevice, false); } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -2992,21 +3493,25 @@ public class LeAudioService extends ProfileService { } /* For setting inCall mode */ - if (mFeatureFlags.leaudioBroadcastAudioHandoverPolicies() && inCall - && !areBroadcastsAllStopped()) { + if (Flags.leaudioBroadcastAudioHandoverPolicies() && inCall && !areBroadcastsAllStopped()) { mQueuedInCallValue = Optional.of(true); /* Request activation of unicast group */ - handleUnicastStreamStatusChange(LeAudioStackEvent.STATUS_LOCAL_STREAM_REQUESTED); + handleUnicastStreamStatusChange( + LeAudioStackEvent.DIRECTION_SINK, + LeAudioStackEvent.STATUS_LOCAL_STREAM_REQUESTED); return; } mLeAudioNativeInterface.setInCall(inCall); /* For clearing inCall mode */ - if (mFeatureFlags.leaudioBroadcastAudioHandoverPolicies() && !inCall + if (Flags.leaudioBroadcastAudioHandoverPolicies() + && !inCall && mBroadcastIdDeactivatedForUnicastTransition.isPresent()) { - handleUnicastStreamStatusChange(LeAudioStackEvent.STATUS_LOCAL_STREAM_SUSPENDED); + handleUnicastStreamStatusChange( + LeAudioStackEvent.DIRECTION_SINK, + LeAudioStackEvent.STATUS_LOCAL_STREAM_SUSPENDED); } } @@ -3155,7 +3660,8 @@ public class LeAudioService extends ProfileService { return LE_AUDIO_GROUP_ID_INVALID; } - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { LeAudioDeviceDescriptor descriptor = getDeviceDescriptor(device); if (descriptor == null) { Log.e(TAG, "getGroupId: No valid descriptor for device: " + device); @@ -3163,6 +3669,8 @@ public class LeAudioService extends ProfileService { } return descriptor.mGroupId; + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } @@ -3236,6 +3744,23 @@ public class LeAudioService extends ProfileService { } } + void removeAuthorizationInfoForRelatedProfiles(BluetoothDevice device) { + if (!Flags.leaudioMcsTbsAuthorizationRebondFix()) { + Log.i(TAG, "leaudio_mcs_tbs_authorization_rebond_fix is disabled"); + return; + } + + McpService mcpService = getMcpService(); + if (mcpService != null) { + mcpService.removeDeviceAuthorizationInfo(device); + } + + TbsService tbsService = getTbsService(); + if (tbsService != null) { + tbsService.removeDeviceAuthorizationInfo(device); + } + } + /** * This function is called when the framework registers a callback with the service for this * first time. This is used as an indication that Bluetooth has been enabled. @@ -3251,37 +3776,52 @@ public class LeAudioService extends ProfileService { mBluetoothEnabled = true; - synchronized (mGroupLock) { - if (mDeviceDescriptors.isEmpty()) { - return; + groupMutexLock(/* isReadOnly */ true); + try { + try { + if (mDeviceDescriptors.isEmpty()) { + return; + } + } finally { + if (!Flags.leaudioApiSynchronizedBlockFix()) { + // Keep previous behavior where a lock is released and acquired immediately + groupMutexUnlock(/* isReadOnly */ true); + groupMutexLock(/* isReadOnly */ true); + } } - } - - synchronized (mGroupLock) { for (BluetoothDevice device : mDeviceDescriptors.keySet()) { if (getConnectionPolicy(device) != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { setAuthorizationForRelatedProfiles(device, true); } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } startAudioServersBackgroundScan(/* retry = */ false); } private LeAudioGroupDescriptor getGroupDescriptor(int groupId) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { return mGroupDescriptors.get(groupId); + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } private LeAudioDeviceDescriptor getDeviceDescriptor(BluetoothDevice device) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { return mDeviceDescriptors.get(device); + } finally { + groupMutexUnlock(/* isReadOnly */ true); } } private void handleGroupNodeAdded(BluetoothDevice device, int groupId) { - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ false); + try { if (DBG) { Log.d(TAG, "Device " + device + " added to group " + groupId); } @@ -3315,6 +3855,8 @@ public class LeAudioService extends ProfileService { deviceDescriptor.mGroupId = groupId; notifyGroupNodeAdded(device, groupId); + } finally { + groupMutexUnlock(/* isReadOnly */ false); } if (mBluetoothEnabled) { @@ -3347,7 +3889,9 @@ public class LeAudioService extends ProfileService { Log.d(TAG, "Removing device " + device + " grom group " + groupId); } - synchronized (mGroupLock) { + boolean isGroupEmpty = true; + groupMutexLock(/* isReadOnly */ true); + try { LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(groupId); if (groupDescriptor == null) { Log.e(TAG, "handleGroupNodeRemoved: No valid descriptor for group: " + groupId); @@ -3367,8 +3911,6 @@ public class LeAudioService extends ProfileService { } deviceDescriptor.mGroupId = LE_AUDIO_GROUP_ID_INVALID; - boolean isGroupEmpty = true; - for (LeAudioDeviceDescriptor descriptor : mDeviceDescriptors.values()) { if (descriptor.mGroupId == groupId) { isGroupEmpty = false; @@ -3384,16 +3926,30 @@ public class LeAudioService extends ProfileService { || Objects.equals(device, mActiveAudioInDevice)) { handleGroupTransitToInactive(groupId); } - mGroupDescriptors.remove(groupId); + if (!Flags.leaudioApiSynchronizedBlockFix()) { + mGroupDescriptors.remove(groupId); + } if (mUnicastGroupIdDeactivatedForBroadcastTransition == groupId) { - mUnicastGroupIdDeactivatedForBroadcastTransition = LE_AUDIO_GROUP_ID_INVALID; + updateFallbackUnicastGroupIdForBroadcast(LE_AUDIO_GROUP_ID_INVALID); } } notifyGroupNodeRemoved(device, groupId); + } finally { + groupMutexUnlock(/* isReadOnly */ true); + } + + if (isGroupEmpty && Flags.leaudioApiSynchronizedBlockFix()) { + groupMutexLock(/* isReadOnly */ false); + try { + mGroupDescriptors.remove(groupId); + } finally { + groupMutexUnlock(/* isReadOnly */ false); + } } setAuthorizationForRelatedProfiles(device, false); + removeAuthorizationInfoForRelatedProfiles(device); } private void notifyGroupNodeRemoved(BluetoothDevice device, int groupId) { @@ -3567,6 +4123,37 @@ public class LeAudioService extends ProfileService { } } + /** + * Update the fallback unicast group id during the handover to broadcast Also store the fallback + * group id in Settings store. + * + * @param groupId group id to update + */ + private void updateFallbackUnicastGroupIdForBroadcast(int groupId) { + Log.i( + TAG, + "Update unicast fallback active group from: " + + mUnicastGroupIdDeactivatedForBroadcastTransition + + " to : " + + groupId); + mUnicastGroupIdDeactivatedForBroadcastTransition = groupId; + + // waive WRITE_SECURE_SETTINGS permission check + final long callingIdentity = Binder.clearCallingIdentity(); + try { + Context userContext = + getApplicationContext() + .createContextAsUser( + UserHandle.of(ActivityManager.getCurrentUser()), 0); + Settings.Secure.putInt( + userContext.getContentResolver(), + BLUETOOTH_LE_BROADCAST_FALLBACK_ACTIVE_GROUP_ID, + groupId); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + } + /** * Gets the current codec status (configuration and capability). * @@ -3735,6 +4322,24 @@ public class LeAudioService extends ProfileService { return audioFrameworkCalls; } + class DialingOutTimeoutEvent implements Runnable { + @Override + public void run() { + Log.w(TAG, "Failed to start Broadcast in time"); + + mDialingOutTimeoutEvent = null; + + if (getLeAudioService() == null) { + Log.e(TAG, "DialingOutTimeoutEvent: No LE Audio service"); + return; + } + + if (mActiveBroadcastAudioDevice != null) { + updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false); + } + } + } + /** * Binder object: must be a static class or memory leak may occur */ @@ -3882,17 +4487,23 @@ public class LeAudioService extends ProfileService { try { Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); - LeAudioService service = getService(source); - boolean result = false; if (service != null) { - if (device == null) { - result = service.removeActiveDevice(true); + if (Flags.audioRoutingCentralization()) { + ((AudioRoutingManager) service.mAdapterService.getActiveDeviceManager()) + .activateDeviceProfile(device, BluetoothProfile.LE_AUDIO, receiver); } else { - result = service.setActiveDevice(device); + boolean result; + if (device == null) { + result = service.removeActiveDevice(true); + } else { + result = service.setActiveDevice(device); + } + receiver.send(result); } + } else { + receiver.send(false); } - receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); } @@ -4383,6 +4994,22 @@ public class LeAudioService extends ProfileService { enforceBluetoothPrivilegedPermission(service); service.setCodecConfigPreference(groupId, inputCodecConfig, outputCodecConfig); } + + @Override + public void isBroadcastActive( + AttributionSource source, SynchronousResultReceiver receiver) { + try { + boolean result = false; + LeAudioService service = getService(source); + if (service != null) { + enforceBluetoothPrivilegedPermission(service); + result = service.isBroadcastActive(); + } + receiver.send(result); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } } @Override @@ -4403,7 +5030,8 @@ public class LeAudioService extends ProfileService { + mLeAudioInbandRingtoneSupportedByPlatform); int numberOfUngroupedDevs = 0; - synchronized (mGroupLock) { + groupMutexLock(/* isReadOnly */ true); + try { for (Map.Entry groupEntry : mGroupDescriptors.entrySet()) { LeAudioGroupDescriptor groupDescriptor = groupEntry.getValue(); @@ -4447,6 +5075,8 @@ public class LeAudioService extends ProfileService { ProfileService.println(sb, " mDirection: " + deviceDescriptor.mDirection); } } + } finally { + groupMutexUnlock(/* isReadOnly */ true); } if (numberOfUngroupedDevs > 0) { @@ -4468,4 +5098,28 @@ public class LeAudioService extends ProfileService { } } } + + private void groupMutexLock(boolean isReadOnly) { + if (Flags.leaudioApiSynchronizedBlockFix()) { + if (isReadOnly) { + mGroupReadLock.lock(); + } else { + mGroupWriteLock.lock(); + } + } else { + mGroupLock.lock(); + } + } + + private void groupMutexUnlock(boolean isReadOnly) { + if (Flags.leaudioApiSynchronizedBlockFix()) { + if (isReadOnly) { + mGroupReadLock.unlock(); + } else { + mGroupWriteLock.unlock(); + } + } else { + mGroupLock.unlock(); + } + } } diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java index 0a4e0270b5e9950fb879548c2b862b12f5014e07..a9d3f399ac8e1807d100c35eae7c1a95f575350e 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java @@ -42,8 +42,9 @@ public class LeAudioStackEvent { public static final int EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION = 10; public static final int EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION = 11; public static final int EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS = 12; + public static final int EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED = 13; // -------- DO NOT PUT ANY NEW UNICAST EVENTS BELOW THIS LINE------------- - public static final int EVENT_TYPE_UNICAST_MAX = 13; + public static final int EVENT_TYPE_UNICAST_MAX = 14; // Broadcast related events public static final int EVENT_TYPE_BROADCAST_CREATED = EVENT_TYPE_UNICAST_MAX + 1; @@ -90,6 +91,9 @@ public class LeAudioStackEvent { static final int DIRECTION_SINK = 1; static final int DIRECTION_SOURCE = 2; + static final int GROUP_STREAM_STATUS_IDLE = 0; + static final int GROUP_STREAM_STATUS_STREAMING = 1; + public int type = EVENT_TYPE_NONE; public BluetoothDevice device; public int valueInt1 = 0; @@ -185,6 +189,8 @@ public class LeAudioStackEvent { return "EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION"; case EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS: return "EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS"; + case EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED: + return "EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED"; default: return "EVENT_TYPE_UNKNOWN:" + type; } @@ -210,6 +216,8 @@ public class LeAudioStackEvent { case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: // same as EVENT_TYPE_GROUP_STATUS_CHANGED + case EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED: + // same as EVENT_TYPE_GROUP_STATUS_CHANGED case EVENT_TYPE_GROUP_STATUS_CHANGED: return "{group_id:" + Integer.toString(value) + "}"; case EVENT_TYPE_AUDIO_CONF_CHANGED: @@ -300,6 +308,15 @@ public class LeAudioStackEvent { default: return "UNKNOWN"; } + case EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED: + switch (value) { + case GROUP_STREAM_STATUS_IDLE: + return "GROUP_STREAM_STATUS_IDLE"; + case GROUP_STREAM_STATUS_STREAMING: + return "GROUP_STREAM_STATUS_STREAMING"; + default: + return "UNKNOWN"; + } default: break; } diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java index d7939a3e32a79b5daeead20dc4e906a26cbdb3f7..f9a240dbd18996fcd4f84e36a442717a5862db9b 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java @@ -53,7 +53,7 @@ import android.os.Message; import android.util.Log; import com.android.bluetooth.btservice.ProfileService; -import com.android.bluetooth.flags.FeatureFlags; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -88,19 +88,16 @@ final class LeAudioStateMachine extends StateMachine { private LeAudioNativeInterface mNativeInterface; private final BluetoothDevice mDevice; - private final FeatureFlags mFeatureFlags; LeAudioStateMachine( BluetoothDevice device, LeAudioService svc, LeAudioNativeInterface nativeInterface, - Looper looper, - FeatureFlags featureFlags) { + Looper looper) { super(TAG, looper); mDevice = device; mService = svc; mNativeInterface = nativeInterface; - mFeatureFlags = featureFlags; mDisconnected = new Disconnected(); mConnecting = new Connecting(); @@ -119,11 +116,10 @@ final class LeAudioStateMachine extends StateMachine { BluetoothDevice device, LeAudioService svc, LeAudioNativeInterface nativeInterface, - Looper looper, - FeatureFlags featureFlags) { + Looper looper) { Log.i(TAG, "make for device"); LeAudioStateMachine LeAudioSm = - new LeAudioStateMachine(device, svc, nativeInterface, looper, featureFlags); + new LeAudioStateMachine(device, svc, nativeInterface, looper); LeAudioSm.start(); return LeAudioSm; } @@ -151,7 +147,7 @@ final class LeAudioStateMachine extends StateMachine { // Don't broadcast during startup broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, mLastConnectionState); - if (mFeatureFlags.audioRoutingCentralization()) { + if (Flags.audioRoutingCentralization()) { mService.deviceDisconnected(mDevice, false); } } @@ -441,7 +437,7 @@ final class LeAudioStateMachine extends StateMachine { + messageWhatToString(getCurrentMessage().what)); mConnectionState = BluetoothProfile.STATE_CONNECTED; removeDeferredMessages(CONNECT); - if (mFeatureFlags.audioRoutingCentralization()) { + if (Flags.audioRoutingCentralization()) { mService.deviceConnected(mDevice); } broadcastConnectionState(BluetoothProfile.STATE_CONNECTED, mLastConnectionState); diff --git a/android/app/src/com/android/bluetooth/gatt/AppScanStats.java b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java similarity index 97% rename from android/app/src/com/android/bluetooth/gatt/AppScanStats.java rename to android/app/src/com/android/bluetooth/le_scan/AppScanStats.java index 931417ed5026c06f9459651ea4b8869850587ddd..e2ce19a0b76ee171f6140b5426d94ed6655e9228 100644 --- a/android/app/src/com/android/bluetooth/gatt/AppScanStats.java +++ b/android/app/src/com/android/bluetooth/le_scan/AppScanStats.java @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.bluetooth.gatt; + +package com.android.bluetooth.le_scan; import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.le.ScanFilter; @@ -27,6 +28,8 @@ import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; +import com.android.bluetooth.gatt.ContextMap; +import com.android.bluetooth.gatt.GattService; import com.android.bluetooth.util.WorkSourceUtil; import com.android.internal.annotations.GuardedBy; @@ -45,7 +48,7 @@ import java.util.Objects; * on a per application basis. * @hide */ -/*package*/ class AppScanStats { +public class AppScanStats { private static final String TAG = AppScanStats.class.getSimpleName(); static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss"); @@ -121,8 +124,8 @@ import java.util.Objects; } } public String appName; - public WorkSource mWorkSource; // Used for BatteryStatsManager - public final WorkSourceUtil mWorkSourceUtil; // Used for BluetoothStatsLog + private WorkSource mWorkSource; // Used for BatteryStatsManager + private final WorkSourceUtil mWorkSourceUtil; // Used for BluetoothStatsLog private int mScansStarted = 0; private int mScansStopped = 0; public boolean isRegistered = false; @@ -142,11 +145,11 @@ import java.util.Objects; private int mAmbientDiscoveryScan = 0; private List mLastScans = new ArrayList(); private HashMap mOngoingScans = new HashMap(); - public long startTime = 0; - public long stopTime = 0; - public int results = 0; + private long startTime = 0; + private long stopTime = 0; + private int results = 0; - AppScanStats(String name, WorkSource source, ContextMap map, GattService service) { + public AppScanStats(String name, WorkSource source, ContextMap map, GattService service) { appName = name; mContextMap = map; mGattService = service; @@ -161,7 +164,7 @@ import java.util.Objects; mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService()); } - synchronized void addResult(int scannerId) { + public synchronized void addResult(int scannerId) { LastScan scan = getScanFromScannerId(scannerId); if (scan != null) { scan.results++; @@ -210,7 +213,7 @@ import java.util.Objects; return scan.isAutoBatchScan; } - synchronized void recordScanStart(ScanSettings settings, List filters, + public synchronized void recordScanStart(ScanSettings settings, List filters, boolean isFilterScan, boolean isCallbackScan, int scannerId) { LastScan existingScan = getScanFromScannerId(scannerId); if (existingScan != null) { @@ -277,7 +280,7 @@ import java.util.Objects; mOngoingScans.put(scannerId, scan); } - synchronized void recordScanStop(int scannerId) { + public synchronized void recordScanStop(int scannerId) { LastScan scan = getScanFromScannerId(scannerId); if (scan == null) { return; @@ -396,6 +399,7 @@ import java.util.Objects; sIsRadioStarted = false; } } + static boolean recordScanRadioStart(int scanMode) { synchronized (sLock) { if (sIsRadioStarted) { @@ -473,7 +477,7 @@ import java.util.Objects; } } - static void recordScanRadioResultCount() { + public static void recordScanRadioResultCount() { synchronized (sLock) { if (!sIsRadioStarted) { return; @@ -488,7 +492,7 @@ import java.util.Objects; } } - static void recordBatchScanRadioResultCount(int numRecords) { + public static void recordBatchScanRadioResultCount(int numRecords) { boolean isScreenOn; synchronized (sLock) { isScreenOn = sIsScreenOn; @@ -572,7 +576,7 @@ import java.util.Objects; } } - synchronized boolean isScanningTooFrequently() { + public synchronized boolean isScanningTooFrequently() { if (mLastScans.size() < mAdapterService.getScanQuotaCount()) { return false; } @@ -695,7 +699,7 @@ import java.util.Objects; } } - synchronized void dumpToString(StringBuilder sb) { + public synchronized void dumpToString(StringBuilder sb) { long currentTime = System.currentTimeMillis(); long currTime = SystemClock.elapsedRealtime(); long Score = 0; diff --git a/android/app/src/com/android/bluetooth/gatt/PeriodicScanManager.java b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java similarity index 96% rename from android/app/src/com/android/bluetooth/gatt/PeriodicScanManager.java rename to android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java index 66b15055f76221016137b0cabd0a14ff20d21d8c..fd1ef8cc2fc7d551bce24787ff4bc55dfad8d64a 100644 --- a/android/app/src/com/android/bluetooth/gatt/PeriodicScanManager.java +++ b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -28,6 +28,7 @@ import android.os.RemoteException; import android.util.Log; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.gatt.GattServiceConfig; import com.android.internal.annotations.VisibleForTesting; import java.util.Collections; @@ -52,8 +53,9 @@ public class PeriodicScanManager { static int sTempRegistrationId = -1; private static final int PA_SOURCE_LOCAL = 1; private static final int PA_SOURCE_REMOTE = 2; + /** Constructor of {@link PeriodicScanManager}. */ - PeriodicScanManager(AdapterService adapterService) { + public PeriodicScanManager(AdapterService adapterService) { if (DBG) { Log.d(TAG, "periodic scan manager created"); } @@ -62,7 +64,7 @@ public class PeriodicScanManager { mNativeInterface.init(this); } - void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } @@ -263,7 +265,7 @@ public class PeriodicScanManager { } } - void startSync(ScanResult scanResult, int skip, int timeout, + public void startSync(ScanResult scanResult, int skip, int timeout, IPeriodicAdvertisingCallback callback) { SyncDeathRecipient deathRecipient = new SyncDeathRecipient(callback); IBinder binder = toBinder(callback); @@ -325,7 +327,7 @@ public class PeriodicScanManager { mNativeInterface.startSync(sid, address, skip, timeout, cbId); } - void stopSync(IPeriodicAdvertisingCallback callback) { + public void stopSync(IPeriodicAdvertisingCallback callback) { IBinder binder = toBinder(callback); if (DBG) { Log.d(TAG, "stopSync() " + binder); @@ -372,7 +374,7 @@ public class PeriodicScanManager { } } - void transferSync(BluetoothDevice bda, int serviceData, int syncHandle) { + public void transferSync(BluetoothDevice bda, int serviceData, int syncHandle) { Log.d(TAG, "transferSync()"); Map.Entry entry = findSync(syncHandle); if (entry == null) { @@ -385,7 +387,7 @@ public class PeriodicScanManager { mNativeInterface.syncTransfer(bda, serviceData, syncHandle); } - void transferSetInfo(BluetoothDevice bda, int serviceData, + public void transferSetInfo(BluetoothDevice bda, int serviceData, int advHandle, IPeriodicAdvertisingCallback callback) { SyncDeathRecipient deathRecipient = new SyncDeathRecipient(callback); IBinder binder = toBinder(callback); diff --git a/android/app/src/com/android/bluetooth/gatt/PeriodicScanNativeInterface.java b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java similarity index 98% rename from android/app/src/com/android/bluetooth/gatt/PeriodicScanNativeInterface.java rename to android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java index d6d31f2115755b8781cd39ae3ef63cc7ec8ae860..639e0eeaf48685443b87549f684d29ee6c933ce1 100644 --- a/android/app/src/com/android/bluetooth/gatt/PeriodicScanNativeInterface.java +++ b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanNativeInterface.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import android.bluetooth.BluetoothDevice; import android.util.Log; +import com.android.bluetooth.gatt.GattServiceConfig; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; diff --git a/android/app/src/com/android/bluetooth/gatt/ScanClient.java b/android/app/src/com/android/bluetooth/le_scan/ScanClient.java similarity index 91% rename from android/app/src/com/android/bluetooth/gatt/ScanClient.java rename to android/app/src/com/android/bluetooth/le_scan/ScanClient.java index bf4158872e3aa09b40c1c24d88c7bac633cd1eaf..18c2588dfd39439bbda773303f2d7f8da396bdd8 100644 --- a/android/app/src/com/android/bluetooth/gatt/ScanClient.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanClient.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanSettings; @@ -29,7 +29,7 @@ import java.util.Objects; * * @hide */ -/* package */class ScanClient { +public class ScanClient { public int scannerId; public ScanSettings settings; public int scanModeApp; @@ -53,15 +53,15 @@ import java.util.Objects; private static final ScanSettings DEFAULT_SCAN_SETTINGS = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); - ScanClient(int scannerId) { + public ScanClient(int scannerId) { this(scannerId, DEFAULT_SCAN_SETTINGS, null); } - ScanClient(int scannerId, ScanSettings settings, List filters) { + public ScanClient(int scannerId, ScanSettings settings, List filters) { this(scannerId, settings, filters, Binder.getCallingUid()); } - ScanClient(int scannerId, ScanSettings settings, List filters, int appUid) { + public ScanClient(int scannerId, ScanSettings settings, List filters, int appUid) { this.scannerId = scannerId; this.settings = settings; this.scanModeApp = settings.getScanMode(); @@ -104,7 +104,7 @@ import java.util.Objects; * @param newScanMode * @return true if scan settings are updated, false otherwise. */ - public boolean updateScanMode(int newScanMode) { + boolean updateScanMode(int newScanMode) { if (settings.getScanMode() == newScanMode) { return false; } diff --git a/android/app/src/com/android/bluetooth/gatt/ScanFilterQueue.java b/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java similarity index 99% rename from android/app/src/com/android/bluetooth/gatt/ScanFilterQueue.java rename to android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java index ee2d8efb511d5f94092216aa71b48a9dd92eabef..4e8b4484a41b6a9db1d3a94e39028813388ce3e7 100644 --- a/android/app/src/com/android/bluetooth/gatt/ScanFilterQueue.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanFilterQueue.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import android.bluetooth.BluetoothAssignedNumbers.OrganizationId; import android.bluetooth.BluetoothUuid; @@ -33,7 +33,7 @@ import java.util.UUID; * * @hide */ -/* package */class ScanFilterQueue { +/* package */ class ScanFilterQueue { public static final int TYPE_DEVICE_ADDRESS = 0; public static final int TYPE_SERVICE_DATA_CHANGED = 1; public static final int TYPE_SERVICE_UUID = 2; @@ -54,7 +54,7 @@ import java.util.UUID; public static final int TYPE_INVALID = 0x00; public static final int TYPE_WIFI_NAN_HASH = 0x01; // WIFI NAN HASH type - class Entry { + static class Entry { public byte type; public String address; public byte addr_type; diff --git a/android/app/src/com/android/bluetooth/gatt/ScanManager.java b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java similarity index 98% rename from android/app/src/com/android/bluetooth/gatt/ScanManager.java rename to android/app/src/com/android/bluetooth/le_scan/ScanManager.java index 909bb0fc3cf0ad3bb39e7d5b3cd1323684cc3078..f39115a34ef023dcfedfdd3dcf08095592c62cc7 100644 --- a/android/app/src/com/android/bluetooth/gatt/ScanManager.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import android.annotation.RequiresPermission; import android.app.ActivityManager; @@ -29,6 +29,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.hardware.display.DisplayManager; import android.location.LocationManager; import android.os.Handler; @@ -45,6 +46,11 @@ import android.view.Display; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.BluetoothAdapterProxy; +import com.android.bluetooth.flags.Flags; +import com.android.bluetooth.gatt.FilterParams; +import com.android.bluetooth.gatt.GattObjectsFactory; +import com.android.bluetooth.gatt.GattService; +import com.android.bluetooth.gatt.GattServiceConfig; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -83,8 +89,8 @@ public class ScanManager { public static final int SCAN_MODE_SCREEN_OFF_BALANCED_INTERVAL_MS = 730; // Result type defined in bt stack. Need to be accessed by GattService. - static final int SCAN_RESULT_TYPE_TRUNCATED = 1; - static final int SCAN_RESULT_TYPE_FULL = 2; + public static final int SCAN_RESULT_TYPE_TRUNCATED = 1; + public static final int SCAN_RESULT_TYPE_FULL = 2; static final int SCAN_RESULT_TYPE_BOTH = 3; // Messages for handling BLE scan operations. @@ -116,6 +122,7 @@ public class ScanManager { private final Object mCurUsedTrackableAdvertisementsLock = new Object(); @GuardedBy("mCurUsedTrackableAdvertisementsLock") private int mCurUsedTrackableAdvertisements = 0; + private final GattService mService; private final AdapterService mAdapterService; private BroadcastReceiver mBatchAlarmReceiver; @@ -156,7 +163,7 @@ public class ScanManager { } } - ScanManager( + public ScanManager( GattService service, AdapterService adapterService, BluetoothAdapterProxy bluetoothAdapterProxy, @@ -200,7 +207,7 @@ public class ScanManager { mService.registerReceiver(mLocationReceiver, locationIntentFilter); } - void cleanup() { + public void cleanup() { mRegularScanClients.clear(); mBatchClients.clear(); mSuspendedScanClients.clear(); @@ -235,19 +242,19 @@ public class ScanManager { } } - void registerScanner(UUID uuid) { + public void registerScanner(UUID uuid) { mScanNative.registerScanner(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits()); } - void unregisterScanner(int scannerId) { + public void unregisterScanner(int scannerId) { mScanNative.unregisterScanner(scannerId); } /** * Returns the regular scan queue. */ - Set getRegularScanQueue() { + public Set getRegularScanQueue() { return mRegularScanClients; } @@ -261,14 +268,14 @@ public class ScanManager { /** * Returns batch scan queue. */ - Set getBatchScanQueue() { + public Set getBatchScanQueue() { return mBatchClients; } /** * Returns a set of full batch scan clients. */ - Set getFullBatchScanQueue() { + public Set getFullBatchScanQueue() { // TODO: split full batch scan clients and truncated batch clients so we don't need to // construct this every time. Set fullBatchClients = new HashSet(); @@ -280,14 +287,14 @@ public class ScanManager { return fullBatchClients; } - void startScan(ScanClient client) { + public void startScan(ScanClient client) { if (DBG) { Log.d(TAG, "startScan() " + client); } sendMessage(MSG_START_BLE_SCAN, client); } - void stopScan(int scannerId) { + public void stopScan(int scannerId) { ScanClient client = mScanNative.getBatchScanClient(scannerId); if (client == null) { client = mScanNative.getRegularScanClient(scannerId); @@ -298,11 +305,11 @@ public class ScanManager { sendMessage(MSG_STOP_BLE_SCAN, client); } - void flushBatchScanResults(ScanClient client) { + public void flushBatchScanResults(ScanClient client) { sendMessage(MSG_FLUSH_BATCH_RESULTS, client); } - void callbackDone(int scannerId, int status) { + public void callbackDone(int scannerId, int status) { mScanNative.callbackDone(scannerId, status); } @@ -326,7 +333,7 @@ public class ScanManager { return mBluetoothAdapterProxy.isOffloadedScanFilteringSupported(); } - boolean isAutoBatchScanClientEnabled(ScanClient client) { + public boolean isAutoBatchScanClientEnabled(ScanClient client) { return mScanNative.isAutoBatchScanClientEnabled(client); } @@ -445,6 +452,9 @@ public class ScanManager { Message msg = obtainMessage(MSG_SCAN_TIMEOUT); msg.obj = client; // Only one timeout message should exist at any time + if (Flags.scanTimeoutReset()) { + removeMessages(MSG_SCAN_TIMEOUT, client); + } sendMessageDelayed(msg, mAdapterService.getScanTimeoutMillis()); if (DBG) { Log.d(TAG, @@ -736,12 +746,15 @@ public class ScanManager { } private void fetchAppForegroundState(ScanClient client) { - if (mActivityManager == null || mAdapterService.getPackageManager() == null) { + PackageManager packageManager = mAdapterService.getPackageManager(); + if (mActivityManager == null || packageManager == null) { + return; + } + String[] packages = packageManager.getPackagesForUid(client.appUid); + if (packages == null || packages.length == 0) { return; } - String packageName = - mAdapterService.getPackageManager().getPackagesForUid(client.appUid)[0]; - int importance = mActivityManager.getPackageImportance(packageName); + int importance = mActivityManager.getPackageImportance(packages[0]); boolean isForeground = importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; @@ -1906,7 +1919,8 @@ public class ScanManager { new ActivityManager.OnUidImportanceListener() { @Override public void onUidImportance(final int uid, final int importance) { - if (mService.mScannerMap.getAppScanStatsByUid(uid) != null) { + if (mService.mTransitionalScanHelper.getScannerMap().getAppScanStatsByUid(uid) + != null) { Message message = new Message(); message.what = MSG_IMPORTANCE_CHANGE; message.obj = new UidImportance(uid, importance); diff --git a/android/app/src/com/android/bluetooth/gatt/ScanNativeInterface.java b/android/app/src/com/android/bluetooth/le_scan/ScanNativeInterface.java similarity index 98% rename from android/app/src/com/android/bluetooth/gatt/ScanNativeInterface.java rename to android/app/src/com/android/bluetooth/le_scan/ScanNativeInterface.java index 23901205832c28cd00505705479982a5fef713f4..f228be66e65fb299520b4e96d3cfaac42c378c5b 100644 --- a/android/app/src/com/android/bluetooth/gatt/ScanNativeInterface.java +++ b/android/app/src/com/android/bluetooth/le_scan/ScanNativeInterface.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; + +import com.android.bluetooth.gatt.FilterParams; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; diff --git a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..913cc404788404f4ae4f36fa45a2bc21f9d14c9c --- /dev/null +++ b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bluetooth.le_scan; + +import android.bluetooth.le.IScannerCallback; + +import com.android.bluetooth.gatt.ContextMap; +import com.android.bluetooth.gatt.GattService; +import com.android.internal.annotations.VisibleForTesting; + +/** + * A helper class which contains all scan related functions extracted from {@link + * com.android.bluetooth.gatt.GattService}. The purpose of this class is to preserve scan + * functionality within GattService and provide the same functionality in a new scan dedicated + * {@link com.android.bluetooth.btservice.ProfileService} when introduced. + * + * @hide + */ +public class TransitionalScanHelper { + + /** List of our registered scanners. */ + public static class ScannerMap + extends ContextMap {} + + private ScannerMap mScannerMap = new ScannerMap(); + + public ScannerMap getScannerMap() { + return mScannerMap; + } + + @VisibleForTesting + public void setScannerMap(ScannerMap scannerMap) { + mScannerMap = scannerMap; + } +} diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java index 1fc4af99bf94413c086508e3929ca0883a71b33b..33f0ddaa04ea5b22c8fb3ca5b948223c022b4a2d 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java @@ -15,6 +15,8 @@ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; @@ -28,6 +30,8 @@ import android.os.RemoteException; import android.text.format.DateUtils; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.mapapi.BluetoothMapContract; @@ -36,6 +40,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Objects; +// Next tag value for ContentProfileErrorReportUtils.report(): 1 public class BluetoothMapAccountLoader { private static final String TAG = "BluetoothMapAccountLoader"; private static final boolean D = BluetoothMapService.DEBUG; @@ -174,10 +179,20 @@ public class BluetoothMapAccountLoader { c = mProviderClient.query(uri, BluetoothMapContract.BT_IM_ACCOUNT_PROJECTION, null, null, BluetoothMapContract.AccountColumns._ID + " DESC"); } else { - c = mProviderClient.query(uri, BluetoothMapContract.BT_ACCOUNT_PROJECTION, null, - null, BluetoothMapContract.AccountColumns._ID + " DESC"); + c = + mProviderClient.query( + uri, + BluetoothMapContract.BT_ACCOUNT_PROJECTION, + null, + null, + BluetoothMapContract.AccountColumns._ID + " DESC"); } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_ACCOUNT_LOADER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); if (D) { Log.d(TAG, "Could not establish ContentProviderClient for " + app.getPackageName() + " - returning empty account list"); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java index 48ee7aa83dd29aef10e9f2d9f6306e082e19f177..c8bebdc8e196f863762e40ae2670957f32e38c6f 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java @@ -14,6 +14,8 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -25,6 +27,8 @@ import android.database.ContentObserver; import android.net.Uri; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.mapapi.BluetoothMapContract; import java.util.ArrayList; @@ -32,12 +36,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Objects; -/** - * Class to construct content observers for for email applications on the system. - * - * - */ - +/** Class to construct content observers for email applications on the system. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 6 public class BluetoothMapAppObserver { private static final String TAG = "BluetoothMapAppObserver"; @@ -168,42 +168,57 @@ public class BluetoothMapAppObserver { } else { Log.e(TAG, "Received change notification on package not registered for notifications!"); - + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); } } /** - * Adds a new content observer to the list of content observers. - * The key for the observer is the uri as string + * Adds a new content observer to the list of content observers. The key for the observer is the + * uri as string + * * @param app app item for the package that supports MAP email */ - public void registerObserver(BluetoothMapAccountItem app) { Uri uri = BluetoothMapContract.buildAccountUri(app.getProviderAuthority()); if (V) { Log.d(TAG, "registerObserver for URI " + uri.toString() + "\n"); } - ContentObserver observer = new ContentObserver(null) { - @Override - public void onChange(boolean selfChange) { - onChange(selfChange, null); - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - if (V) { - Log.d(TAG, - "onChange on thread: " + Thread.currentThread().getId() + " Uri: " + uri - + " selfchange: " + selfChange); - } - if (uri != null) { - handleAccountChanges(uri.getHost()); - } else { - Log.e(TAG, "Unable to handle change as the URI is NULL!"); - } + ContentObserver observer = + new ContentObserver(null) { + @Override + public void onChange(boolean selfChange) { + onChange(selfChange, null); + } - } - }; + @Override + public void onChange(boolean selfChange, Uri uri) { + if (V) { + Log.d( + TAG, + "onChange on thread: " + + Thread.currentThread().getId() + + " Uri: " + + uri + + " selfchange: " + + selfChange); + } + if (uri != null) { + handleAccountChanges(uri.getHost()); + } else { + Log.e(TAG, "Unable to handle change as the URI is NULL!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); + } + } + }; mObserverMap.put(uri.toString(), observer); //False "notifyForDescendents" : Get notified whenever a change occurs to the exact URI. mResolver.registerContentObserver(uri, false, observer); @@ -245,95 +260,117 @@ public class BluetoothMapAppObserver { intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); - mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (D) { - Log.d(TAG, "onReceive\n"); - } - String action = intent.getAction(); - - if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { - Uri data = intent.getData(); - String packageName = data.getEncodedSchemeSpecificPart(); - if (D) { - Log.d(TAG, "The installed package is: " + packageName); - } - - BluetoothMapUtils.TYPE msgType = BluetoothMapUtils.TYPE.NONE; - ResolveInfo resolveInfo = null; - Intent[] searchIntents = new Intent[2]; - //Array searchIntents = new Array (); - searchIntents[0] = new Intent(BluetoothMapContract.PROVIDER_INTERFACE_EMAIL); - searchIntents[1] = new Intent(BluetoothMapContract.PROVIDER_INTERFACE_IM); - // Find all installed packages and filter out those that support Bluetooth Map. - - mPackageManager = mContext.getPackageManager(); + mReceiver = + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (D) { + Log.d(TAG, "onReceive\n"); + } + String action = intent.getAction(); - for (Intent searchIntent : searchIntents) { - List resInfos = - mPackageManager.queryIntentContentProviders(searchIntent, 0); - if (resInfos != null) { + if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { + Uri data = intent.getData(); + String packageName = data.getEncodedSchemeSpecificPart(); if (D) { - Log.d(TAG, - "Found " + resInfos.size() + " application(s) with intent " - + searchIntent.getAction()); + Log.d(TAG, "The installed package is: " + packageName); } - for (ResolveInfo rInfo : resInfos) { - if (rInfo != null) { - // Find out if package contain Bluetooth MAP support - if (packageName.equals(rInfo.providerInfo.packageName)) { - resolveInfo = rInfo; - if (Objects.equals(searchIntent.getAction(), - BluetoothMapContract.PROVIDER_INTERFACE_EMAIL)) { - msgType = BluetoothMapUtils.TYPE.EMAIL; - } else if (Objects.equals(searchIntent.getAction(), - BluetoothMapContract.PROVIDER_INTERFACE_IM)) { - msgType = BluetoothMapUtils.TYPE.IM; + + BluetoothMapUtils.TYPE msgType = BluetoothMapUtils.TYPE.NONE; + ResolveInfo resolveInfo = null; + Intent[] searchIntents = new Intent[2]; + // Array searchIntents = new Array (); + searchIntents[0] = + new Intent(BluetoothMapContract.PROVIDER_INTERFACE_EMAIL); + searchIntents[1] = + new Intent(BluetoothMapContract.PROVIDER_INTERFACE_IM); + // Find all installed packages and filter out those that support + // Bluetooth Map. + + mPackageManager = mContext.getPackageManager(); + + for (Intent searchIntent : searchIntents) { + List resInfos = + mPackageManager.queryIntentContentProviders( + searchIntent, 0); + if (resInfos != null) { + if (D) { + Log.d( + TAG, + "Found " + + resInfos.size() + + " application(s) with intent " + + searchIntent.getAction()); + } + for (ResolveInfo rInfo : resInfos) { + if (rInfo != null) { + // Find out if package contain Bluetooth MAP support + if (packageName.equals( + rInfo.providerInfo.packageName)) { + resolveInfo = rInfo; + if (Objects.equals( + searchIntent.getAction(), + BluetoothMapContract + .PROVIDER_INTERFACE_EMAIL)) { + msgType = BluetoothMapUtils.TYPE.EMAIL; + } else if (Objects.equals( + searchIntent.getAction(), + BluetoothMapContract + .PROVIDER_INTERFACE_IM)) { + msgType = BluetoothMapUtils.TYPE.IM; + } + break; + } } - break; } } } - } - } - // if application found with Bluetooth MAP support add to list - if (resolveInfo != null) { - if (D) { - Log.d(TAG, "Found " + resolveInfo.providerInfo.packageName - + " application of type " + msgType); - } - BluetoothMapAccountItem app = - mLoader.createAppItem(resolveInfo, false, msgType); - if (app != null) { - registerObserver(app); - // Add all accounts to mFullList - ArrayList newAccountList = - mLoader.parseAccounts(app); - mFullList.put(app, newAccountList); - } - } + // if application found with Bluetooth MAP support add to list + if (resolveInfo != null) { + if (D) { + Log.d( + TAG, + "Found " + + resolveInfo.providerInfo.packageName + + " application of type " + + msgType); + } + BluetoothMapAccountItem app = + mLoader.createAppItem(resolveInfo, false, msgType); + if (app != null) { + registerObserver(app); + // Add all accounts to mFullList + ArrayList newAccountList = + mLoader.parseAccounts(app); + mFullList.put(app, newAccountList); + } + } - } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { - Uri data = intent.getData(); - String packageName = data.getEncodedSchemeSpecificPart(); - if (D) { - Log.d(TAG, "The removed package is: " + packageName); - } - BluetoothMapAccountItem app = getApp(packageName); - /* Find the object and remove from fullList */ - if (app != null) { - unregisterObserver(app); - mFullList.remove(app); + } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { + Uri data = intent.getData(); + String packageName = data.getEncodedSchemeSpecificPart(); + if (D) { + Log.d(TAG, "The removed package is: " + packageName); + } + BluetoothMapAccountItem app = getApp(packageName); + /* Find the object and remove from fullList */ + if (app != null) { + unregisterObserver(app); + mFullList.remove(app); + } + } } - } - } - }; + }; if (!mRegisteredReceiver) { try { mContext.registerReceiver(mReceiver, intentFilter); mRegisteredReceiver = true; } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "Unable to register MapAppObserver receiver", e); } } @@ -348,14 +385,19 @@ public class BluetoothMapAppObserver { mRegisteredReceiver = false; mContext.unregisterReceiver(mReceiver); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, "Unable to unregister mapAppObserver receiver", e); } } } /** - * Method to get a list of the accounts (across all apps) that are set to be shared - * through MAP. + * Method to get a list of the accounts (across all apps) that are set to be shared through MAP. + * * @return Arraylist containing all enabled accounts */ public ArrayList getEnabledAccountItems() { @@ -374,9 +416,20 @@ public class BluetoothMapAppObserver { } } else { Log.w(TAG, "getEnabledAccountItems() - No AccountList enabled\n"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 4); } } else { Log.w(TAG, "getEnabledAccountItems() - No Account in App enabled\n"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); } } return list; diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java index e48b5e2cceb8dab43cc227384bf6156cd4f47ba2..cc343c98d38f9e26244e7ef9e01895e762380304 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java @@ -14,9 +14,13 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.SignedLongLong; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; @@ -26,9 +30,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; -/** - * This class encapsulates the appParams needed for MAP. - */ +/** This class encapsulates the appParams needed for MAP. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 41 public class BluetoothMapAppParams { private static final String TAG = "BluetoothMapAppParams"; @@ -232,8 +235,18 @@ public class BluetoothMapAppParams { switch (tagId) { case MAX_LIST_COUNT: if (tagLength != MAX_LIST_COUNT_LEN) { - Log.w(TAG, "MAX_LIST_COUNT: Wrong length received: " + tagLength - + " expected: " + MAX_LIST_COUNT_LEN); + Log.w( + TAG, + "MAX_LIST_COUNT: Wrong length received: " + + tagLength + + " expected: " + + MAX_LIST_COUNT_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); } else { setMaxListCount(appParamBuf.getShort(i) & 0xffff); // Make it unsigned } @@ -243,6 +256,12 @@ public class BluetoothMapAppParams { Log.w(TAG, "START_OFFSET: Wrong length received: " + tagLength + " expected: " + START_OFFSET_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); } else { setStartOffset(appParamBuf.getShort(i) & 0xffff); // Make it unsigned } @@ -251,6 +270,12 @@ public class BluetoothMapAppParams { if (tagLength != FILTER_MESSAGE_TYPE_LEN) { Log.w(TAG, "FILTER_MESSAGE_TYPE: Wrong length received: " + tagLength + " expected: " + FILTER_MESSAGE_TYPE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 2); } else { setFilterMessageType(appParams[i] & 0x1f); } @@ -261,6 +286,12 @@ public class BluetoothMapAppParams { } else { Log.w(TAG, "FILTER_PERIOD_BEGIN: Wrong length received: " + tagLength + " expected to be more than 0"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); } break; case FILTER_PERIOD_END: @@ -269,12 +300,28 @@ public class BluetoothMapAppParams { } else { Log.w(TAG, "FILTER_PERIOD_END: Wrong length received: " + tagLength + " expected to be more than 0"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 4); } break; case FILTER_READ_STATUS: if (tagLength != FILTER_READ_STATUS_LEN) { - Log.w(TAG, "FILTER_READ_STATUS: Wrong length received: " + tagLength - + " expected: " + FILTER_READ_STATUS_LEN); + Log.w( + TAG, + "FILTER_READ_STATUS: Wrong length received: " + + tagLength + + " expected: " + + FILTER_READ_STATUS_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); } else { setFilterReadStatus(appParams[i] & 0x03); // Lower two bits } @@ -285,20 +332,41 @@ public class BluetoothMapAppParams { } else { Log.w(TAG, "FILTER_RECIPIENT: Wrong length received: " + tagLength + " expected to be more than 0"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 6); } break; case FILTER_ORIGINATOR: if (tagLength != 0) { setFilterOriginator(new String(appParams, i, tagLength)); } else { - Log.w(TAG, "FILTER_ORIGINATOR: Wrong length received: " + tagLength - + " expected to be more than 0"); + Log.w( + TAG, + "FILTER_ORIGINATOR: Wrong length received: " + + tagLength + + " expected to be more than 0"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 7); } break; case FILTER_PRIORITY: if (tagLength != FILTER_PRIORITY_LEN) { Log.w(TAG, "FILTER_PRIORITY: Wrong length received: " + tagLength + " expected: " + FILTER_PRIORITY_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 8); } else { setFilterPriority(appParams[i] & 0x03); // Lower two bits } @@ -307,15 +375,30 @@ public class BluetoothMapAppParams { if (tagLength != ATTACHMENT_LEN) { Log.w(TAG, "ATTACHMENT: Wrong length received: " + tagLength + " expected: " + ATTACHMENT_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 9); } else { setAttachment(appParams[i] & 0x01); // Lower bit } break; case TRANSPARENT: if (tagLength != TRANSPARENT_LEN) { - Log.w(TAG, - "TRANSPARENT: Wrong length received: " + tagLength + " expected: " + Log.w( + TAG, + "TRANSPARENT: Wrong length received: " + + tagLength + + " expected: " + TRANSPARENT_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 10); } else { setTransparent(appParams[i] & 0x01); // Lower bit } @@ -324,15 +407,30 @@ public class BluetoothMapAppParams { if (tagLength != RETRY_LEN) { Log.w(TAG, "RETRY: Wrong length received: " + tagLength + " expected: " + RETRY_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 11); } else { setRetry(appParams[i] & 0x01); // Lower bit } break; case NEW_MESSAGE: if (tagLength != NEW_MESSAGE_LEN) { - Log.w(TAG, - "NEW_MESSAGE: Wrong length received: " + tagLength + " expected: " + Log.w( + TAG, + "NEW_MESSAGE: Wrong length received: " + + tagLength + + " expected: " + NEW_MESSAGE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 12); } else { setNewMessage(appParams[i] & 0x01); // Lower bit } @@ -341,6 +439,12 @@ public class BluetoothMapAppParams { if (tagLength != NOTIFICATION_STATUS_LEN) { Log.w(TAG, "NOTIFICATION_STATUS: Wrong length received: " + tagLength + " expected: " + NOTIFICATION_STATUS_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 13); } else { setNotificationStatus(appParams[i] & 0x01); // Lower bit } @@ -349,14 +453,30 @@ public class BluetoothMapAppParams { if (tagLength != NOTIFICATION_FILTER_LEN) { Log.w(TAG, "NOTIFICATION_FILTER: Wrong length received: " + tagLength + " expected: " + NOTIFICATION_FILTER_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 14); } else { setNotificationFilter(appParamBuf.getInt(i) & 0xffffffffL); // 4 bytes } break; case MAS_INSTANCE_ID: if (tagLength != MAS_INSTANCE_ID_LEN) { - Log.w(TAG, "MAS_INSTANCE_ID: Wrong length received: " + tagLength - + " expected: " + MAS_INSTANCE_ID_LEN); + Log.w( + TAG, + "MAS_INSTANCE_ID: Wrong length received: " + + tagLength + + " expected: " + + MAS_INSTANCE_ID_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 15); } else { setMasInstanceId(appParams[i] & 0xff); } @@ -365,6 +485,12 @@ public class BluetoothMapAppParams { if (tagLength != PARAMETER_MASK_LEN) { Log.w(TAG, "PARAMETER_MASK: Wrong length received: " + tagLength + " expected: " + PARAMETER_MASK_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 16); } else { setParameterMask(appParamBuf.getInt(i) & 0xffffffffL); // Make it unsigned } @@ -373,14 +499,30 @@ public class BluetoothMapAppParams { if (tagLength != FOLDER_LISTING_SIZE_LEN) { Log.w(TAG, "FOLDER_LISTING_SIZE: Wrong length received: " + tagLength + " expected: " + FOLDER_LISTING_SIZE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 17); } else { setFolderListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned } break; case MESSAGE_LISTING_SIZE: if (tagLength != MESSAGE_LISTING_SIZE_LEN) { - Log.w(TAG, "MESSAGE_LISTING_SIZE: Wrong length received: " + tagLength - + " expected: " + MESSAGE_LISTING_SIZE_LEN); + Log.w( + TAG, + "MESSAGE_LISTING_SIZE: Wrong length received: " + + tagLength + + " expected: " + + MESSAGE_LISTING_SIZE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 18); } else { setMessageListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned } @@ -389,6 +531,12 @@ public class BluetoothMapAppParams { if (tagLength != SUBJECT_LENGTH_LEN) { Log.w(TAG, "SUBJECT_LENGTH: Wrong length received: " + tagLength + " expected: " + SUBJECT_LENGTH_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 19); } else { setSubjectLength(appParams[i] & 0xff); } @@ -397,6 +545,12 @@ public class BluetoothMapAppParams { if (tagLength != CHARSET_LEN) { Log.w(TAG, "CHARSET: Wrong length received: " + tagLength + " expected: " + CHARSET_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 20); } else { setCharset(appParams[i] & 0x01); // Lower bit } @@ -405,6 +559,12 @@ public class BluetoothMapAppParams { if (tagLength != FRACTION_REQUEST_LEN) { Log.w(TAG, "FRACTION_REQUEST: Wrong length received: " + tagLength + " expected: " + FRACTION_REQUEST_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 21); } else { setFractionRequest(appParams[i] & 0x01); // Lower bit } @@ -413,6 +573,12 @@ public class BluetoothMapAppParams { if (tagLength != FRACTION_DELIVER_LEN) { Log.w(TAG, "FRACTION_DELIVER: Wrong length received: " + tagLength + " expected: " + FRACTION_DELIVER_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 22); } else { setFractionDeliver(appParams[i] & 0x01); // Lower bit } @@ -421,15 +587,30 @@ public class BluetoothMapAppParams { if (tagLength != STATUS_INDICATOR_LEN) { Log.w(TAG, "STATUS_INDICATOR: Wrong length received: " + tagLength + " expected: " + STATUS_INDICATOR_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 23); } else { setStatusIndicator(appParams[i] & 0x01); // Lower bit } break; case STATUS_VALUE: if (tagLength != STATUS_VALUE_LEN) { - Log.w(TAG, - "STATUS_VALUER: Wrong length received: " + tagLength + " expected: " + Log.w( + TAG, + "STATUS_VALUER: Wrong length received: " + + tagLength + + " expected: " + STATUS_VALUE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 24); } else { setStatusValue(appParams[i] & 0x01); // Lower bit } @@ -441,6 +622,12 @@ public class BluetoothMapAppParams { if ((tagLength != DATABASE_INDETIFIER_LEN)) { Log.w(TAG, "DATABASE_IDENTIFIER: Wrong length received: " + tagLength + " expected: " + DATABASE_INDETIFIER_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 25); } else { setDatabaseIdentifier(appParamBuf.getLong(i)/*MSB*/, appParamBuf.getLong(i + 8)/*LSB*/); @@ -450,15 +637,27 @@ public class BluetoothMapAppParams { if ((tagLength != CONVO_LIST_VER_COUNTER_LEN)) { Log.w(TAG, "CONVO_LIST_VER_COUNTER: Wrong length received: " + tagLength + " expected: " + CONVO_LIST_VER_COUNTER_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 26); } else { - setConvoListingVerCounter(appParamBuf.getLong(i)/*MSB*/, - appParamBuf.getLong(i + 8)/*LSB*/); + setConvoListingVerCounter( + appParamBuf.getLong(i) /*MSB*/, appParamBuf.getLong(i + 8) /*LSB*/); } break; case PRESENCE_AVAILABLE: if ((tagLength != PRESENCE_AVAILABLE_LEN)) { Log.w(TAG, "PRESENCE_AVAILABLE: Wrong length received: " + tagLength + " expected: " + PRESENCE_AVAILABLE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 27); } else { setPresenceAvailability(appParams[i]); } @@ -469,6 +668,12 @@ public class BluetoothMapAppParams { } else { Log.w(TAG, "PRESENCE_STATUS: Wrong length received: " + tagLength + " expected to be more than 0"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 28); } break; case LAST_ACTIVITY: @@ -477,12 +682,24 @@ public class BluetoothMapAppParams { } else { Log.w(TAG, "LAST_ACTIVITY: Wrong length received: " + tagLength + " expected to be more than 0"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 29); } break; case CHAT_STATE: if ((tagLength != CHAT_STATE_LEN)) { Log.w(TAG, "CHAT_STATE: Wrong length received: " + tagLength + " expected: " + CHAT_STATE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 30); } else { setChatState(appParams[i]); } @@ -493,6 +710,12 @@ public class BluetoothMapAppParams { } else { Log.w(TAG, "FILTER_CONVO_ID: Wrong length received: " + tagLength + " expected: " + FILTER_CONVO_ID_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 31); } break; case CONVO_LISTING_SIZE: @@ -500,7 +723,12 @@ public class BluetoothMapAppParams { Log.w(TAG, "LISTING_SIZE: Wrong length received: " + tagLength + " expected: " + CONVO_LISTING_SIZE_LEN); - + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 32); } else { setConvoListingSize(appParamBuf.getShort(i) & 0xffff); } @@ -509,6 +737,12 @@ public class BluetoothMapAppParams { if ((tagLength != FILTER_PRESENCE_LEN)) { Log.w(TAG, "FILTER_PRESENCE: Wrong length received: " + tagLength + " expected: " + FILTER_PRESENCE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 33); } else { setFilterPresence(appParams[i]); } @@ -517,6 +751,12 @@ public class BluetoothMapAppParams { if ((tagLength != FILTER_UID_PRESENT_LEN)) { Log.w(TAG, "FILTER_UID_PRESENT: Wrong length received: " + tagLength + " expected: " + FILTER_UID_PRESENT_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 34); } else { setFilterUidPresent(appParams[i] & 0x1); } @@ -525,6 +765,12 @@ public class BluetoothMapAppParams { if ((tagLength != CHAT_STATE_CONVO_ID_LEN)) { Log.w(TAG, "CHAT_STATE_CONVO_ID: Wrong length received: " + tagLength + " expected: " + CHAT_STATE_CONVO_ID_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 35); } else { /* TODO: Is this correct convoId handling? */ setChatStateConvoId(appParamBuf.getLong(i)/*MSB*/, @@ -544,6 +790,12 @@ public class BluetoothMapAppParams { } else { Log.w(TAG, "FILTER_MESSAGE_HANDLE: Wrong length received: " + tagLength + " expected: " + FILTER_MESSAGE_HANDLE_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 36); } break; @@ -551,6 +803,12 @@ public class BluetoothMapAppParams { if (tagLength != CONVO_PARAMETER_MASK_LEN) { Log.w(TAG, "CONVO_PARAMETER_MASK: Wrong length received: " + tagLength + " expected: " + CONVO_PARAMETER_MASK_LEN); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 37); } else { setConvoParameterMask( appParamBuf.getInt(i) & 0xffffffffL); // Make it unsigned @@ -560,6 +818,12 @@ public class BluetoothMapAppParams { // Just skip unknown Tags, no need to report error Log.w(TAG, "Unknown TagId received ( 0x" + Integer.toString(tagId, 16) + "), skipping..."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 38); break; } i += tagLength; // Offset to next TagId @@ -1047,6 +1311,11 @@ public class BluetoothMapAppParams { try { mFilterMsgHandle = BluetoothMapUtils.getLongFromString(handle); } catch (UnsupportedEncodingException | NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 39); Log.w(TAG, "Error creating long from handle string", e); } } @@ -1101,6 +1370,11 @@ public class BluetoothMapAppParams { try { mFilterConvoId = SignedLongLong.fromString(id); } catch (UnsupportedEncodingException | NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 40); Log.w(TAG, "Error creating long from id string", e); } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java index 376e505b2bdd721b8ae9e192811f1fe5ea88ce3e..bfdf559cabae3b589c30a596b426cf9f00f847a3 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java @@ -14,6 +14,8 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; @@ -36,9 +38,11 @@ import android.text.util.Rfc822Tokenizer; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.DeviceWorkArounds; import com.android.bluetooth.SignedLongLong; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.map.BluetoothMapbMessageMime.MimePart; import com.android.bluetooth.mapapi.BluetoothMapContract; @@ -59,6 +63,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +// Next tag value for ContentProfileErrorReportUtils.report(): 15 public class BluetoothMapContent { private static final String TAG = "BluetoothMapContent"; @@ -456,6 +461,11 @@ public class BluetoothMapContent { c.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, e); } } @@ -1722,6 +1732,11 @@ public class BluetoothMapContent { where = BluetoothMapContract.MessageColumns.FOLDER_ID + " = " + folderId; } else { Log.e(TAG, "setWhereFilterFolderTypeEmail: not valid!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); throw new IllegalArgumentException("Invalid folder ID"); } return where; @@ -1733,6 +1748,11 @@ public class BluetoothMapContent { where = BluetoothMapContract.MessageColumns.FOLDER_ID + " = " + folderId; } else { Log.e(TAG, "setWhereFilterFolderTypeIm: not valid!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); throw new IllegalArgumentException("Invalid folder ID"); } return where; @@ -3195,6 +3215,12 @@ public class BluetoothMapContent { // TODO: Not sure this is how to convert to UTF-8 summary = new String(summary.getBytes(cs), "UTF-8"); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, "populateSmsMmsConvoElement: " + e); } } @@ -3381,6 +3407,11 @@ public class BluetoothMapContent { } foundContact = true; } catch (NumberFormatException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); // skip this id continue; } @@ -3674,9 +3705,9 @@ public class BluetoothMapContent { } } - /** * Read out a mime data part and return the data in a byte array. + * * @param contentPartUri TODO * @param partid the content provider id of the Mime Part. */ @@ -3697,6 +3728,11 @@ public class BluetoothMapContent { } retVal = os.toByteArray(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); // do nothing for now Log.w(TAG, "Error reading part data", e); } finally { @@ -3777,6 +3813,12 @@ public class BluetoothMapContent { text = sb.toString(); part.mContentType = "text"; } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); Log.d(TAG, "extractMmsParts", e); } } @@ -3794,10 +3836,22 @@ public class BluetoothMapContent { } } } catch (NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.d(TAG, "extractMmsParts", e); part.mData = null; part.mCharsetName = null; } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); Log.d(TAG, "extractMmsParts", e); part.mData = null; part.mCharsetName = null; @@ -3886,11 +3940,13 @@ public class BluetoothMapContent { public byte[] getEmailMessage(long id, BluetoothMapAppParams appParams, BluetoothMapFolderElement currentFolder) throws UnsupportedEncodingException { // Log print out of application parameters set - if (D && appParams != null) { - Log.d(TAG, - "TYPE_MESSAGE (GET): Attachment = " + appParams.getAttachment() + ", Charset = " - + appParams.getCharset() + ", FractionRequest = " - + appParams.getFractionRequest()); + if (D) { + if (appParams != null) { + Log.d(TAG, "TYPE_MESSAGE (GET): Attachment = " + appParams.getAttachment() + + ", Charset = " + + appParams.getCharset() + ", FractionRequest = " + + appParams.getFractionRequest()); + } } // Throw exception if requester NATIVE charset for Email @@ -3925,6 +3981,12 @@ public class BluetoothMapContent { // TODO: request message from server Log.w(TAG, "getEmailMessage - receptionState not COMPLETE - Not " + "Implemented!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 9); } } // Set read status: @@ -4015,10 +4077,28 @@ public class BluetoothMapContent { // Set email message body: message.setEmailBody(email.toString()); } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); Log.w(TAG, e); } catch (NullPointerException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); Log.w(TAG, e); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); Log.w(TAG, e); } finally { try { @@ -4026,6 +4106,12 @@ public class BluetoothMapContent { is.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 13); Log.w(TAG, e); } try { @@ -4033,6 +4119,12 @@ public class BluetoothMapContent { fd.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 14); Log.w(TAG, e); } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index f591c7f0d03586a210af90170ec9268c2f1bcb0d..d79ab14c589d559a5c483a6b8a3acd4becc343aa 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -16,6 +16,8 @@ package com.android.bluetooth.map; import android.app.Activity; import android.app.PendingIntent; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.BroadcastReceiver; import android.content.ContentProviderClient; import android.content.ContentResolver; @@ -52,7 +54,9 @@ import android.util.Log; import android.util.Xml; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.map.BluetoothMapbMessageMime.MimePart; import com.android.bluetooth.mapapi.BluetoothMapContract; @@ -81,6 +85,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; +// Next tag value for ContentProfileErrorReportUtils.report(): 41 public class BluetoothMapContentObserver { private static final String TAG = "BluetoothMapContentObserver"; @@ -344,9 +349,17 @@ public class BluetoothMapContentObserver { | BluetoothMapUtils.MAP_FEATURE_PARTICIPANT_CHAT_STATE_CHANGE_BIT) & mMapSupportedFeatures) != 0) { // Warning according to page 46/123 of MAP 1.3 spec - Log.w(TAG, "setObserverRemoteFeatureMask: Extended Event Reports 1.2 is not set even" - + "though PARTICIPANT_PRESENCE_CHANGE_BIT or PARTICIPANT_CHAT_STATE_CHANGE_BIT" - + " were set, mMapSupportedFeatures=" + mMapSupportedFeatures); + Log.w( + TAG, + "setObserverRemoteFeatureMask: Extended Event Reports 1.2 is not set eventhough" + + " PARTICIPANT_PRESENCE_CHANGE_BIT or PARTICIPANT_CHAT_STATE_CHANGE_BIT" + + " were set, mMapSupportedFeatures=" + + mMapSupportedFeatures); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); } if (D) { Log.d(TAG, @@ -479,36 +492,49 @@ public class BluetoothMapContentObserver { return smsType; } - private final ContentObserver mObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - onChange(selfChange, null); - } + private final ContentObserver mObserver = + new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + onChange(selfChange, null); + } - @Override - public void onChange(boolean selfChange, Uri uri) { - if (uri == null) { - Log.w(TAG, "onChange() with URI == null - not handled."); - return; - } + @Override + public void onChange(boolean selfChange, Uri uri) { + if (uri == null) { + Log.w(TAG, "onChange() with URI == null - not handled."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); + return; + } - if (!mStorageUnlocked) { - Log.v(TAG, "Ignore events until storage is completely unlocked"); - return; - } + if (!mStorageUnlocked) { + Log.v(TAG, "Ignore events until storage is completely unlocked"); + return; + } - if (V) { - Log.d(TAG, "onChange on thread: " + Thread.currentThread().getId() + " Uri: " - + uri.toString() + " selfchange: " + selfChange); - } + if (V) { + Log.d( + TAG, + "onChange on thread: " + + Thread.currentThread().getId() + + " Uri: " + + uri.toString() + + " selfchange: " + + selfChange); + } - if (uri.toString().contains(BluetoothMapContract.TABLE_CONVOCONTACT)) { - handleContactListChanges(uri); - } else { - handleMsgListChanges(uri); - } - } - }; + if (uri.toString().contains(BluetoothMapContract.TABLE_CONVOCONTACT)) { + handleContactListChanges(uri); + } else { + handleMsgListChanges(uri); + } + } + }; private static final HashMap FOLDER_SMS_MAP; @@ -528,6 +554,11 @@ public class BluetoothMapContentObserver { return name; } Log.e(TAG, "New SMS mailbox types have been introduced, without an update in BT..."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); return "Unknown"; } @@ -548,6 +579,11 @@ public class BluetoothMapContentObserver { return name; } Log.e(TAG, "New MMS mailboxes have been introduced, without an update in BT..."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 3); return "Unknown"; } @@ -814,9 +850,13 @@ public class BluetoothMapContentObserver { } if (presenceStatus != null) { // Convert provider conversation handle to string incl type - xmlEvtReport.attribute("", "presence_status", - presenceStatus.substring(0, - presenceStatus.length() < 256 ? subject.length() + xmlEvtReport.attribute( + "", + "presence_status", + presenceStatus.substring( + 0, + presenceStatus.length() < 256 + ? subject.length() : 256)); } } @@ -832,14 +872,29 @@ public class BluetoothMapContentObserver { xmlEvtReport.endTag("", "MAP-event-report"); xmlEvtReport.endDocument(); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); if (D) { Log.w(TAG, e); } } catch (IllegalStateException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); if (D) { Log.w(TAG, e); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); if (D) { Log.w(TAG, e); } @@ -1085,8 +1140,8 @@ public class BluetoothMapContentObserver { } /** - * Per design it is only possible to call the refreshXxxx functions sequentially, hence it - * is safe to modify mTransmitEvents without synchronization. + * Per design it is only possible to call the refreshXxxx functions sequentially, hence it is + * safe to modify mTransmitEvents without synchronization. */ /* package */ void refreshFolderVersionCounter() { if (mObserverRegistered) { @@ -1108,6 +1163,12 @@ public class BluetoothMapContentObserver { try { handleMsgListChangesMsg(mMessageUri); } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.e(TAG, "Unable to update FolderVersionCounter. - Not fatal, but can cause" + " undesirable user experience!", e); } @@ -1255,6 +1316,11 @@ public class BluetoothMapContentObserver { try { mMnsClient.sendEvent(evt.encode(), mMasId); } catch (UnsupportedEncodingException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); /* do nothing */ if (D) { Log.e(TAG, "Exception - should not happen: ", ex); @@ -1280,6 +1346,11 @@ public class BluetoothMapContentObserver { c = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, Sms.CONTENT_URI, SMS_PROJECTION_SHORT, null, null, null); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); Log.e(TAG, "Failed to initialize the list of messages: " + e.toString()); return; } @@ -1444,6 +1515,12 @@ public class BluetoothMapContentObserver { int idIndex = c.getColumnIndexOrThrow(Sms._ID); if (c.isNull(idIndex)) { Log.w(TAG, "handleMsgListChangesSms, ID is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 10); continue; } long id = c.getLong(idIndex); @@ -1613,6 +1690,12 @@ public class BluetoothMapContentObserver { int idIndex = c.getColumnIndexOrThrow(Mms._ID); if (c.isNull(idIndex)) { Log.w(TAG, "handleMsgListChangesMms, ID is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 11); continue; } long id = c.getLong(idIndex); @@ -1970,6 +2053,11 @@ public class BluetoothMapContentObserver { } handleMsgListChangesMsg(uri); } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); mMasInstance.restartObexServerSession(); Log.w(TAG, "Problems contacting the ContentProvider in mas Instance " + mMasId + " restaring ObexServerSession"); @@ -2176,6 +2264,11 @@ public class BluetoothMapContentObserver { } } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 13); mMasInstance.restartObexServerSession(); Log.w(TAG, "Problems contacting the ContentProvider in mas Instance " + mMasId + " restaring ObexServerSession"); @@ -2223,6 +2316,12 @@ public class BluetoothMapContentObserver { } else { Log.w(TAG, "Msg: " + handle + " - Set delete status " + status + " failed for folderId " + folderId); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 14); } } else if (status == BluetoothMapAppParams.STATUS_VALUE_NO) { /* Undelete message. move to old folder if we know it, @@ -2283,6 +2382,11 @@ public class BluetoothMapContentObserver { } if (!res) { Log.w(TAG, "Set delete status " + status + " failed."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 15); } return res; } @@ -2628,9 +2732,13 @@ public class BluetoothMapContentObserver { * @param date the timestamp for the message * @return the URI for the new message */ - private static Uri addMessageToUri(ContentResolver resolver, Uri uri, - String address, String body, String subject, - Long date) { + private static Uri addMessageToUri( + ContentResolver resolver, + Uri uri, + String address, + String body, + String subject, + Long date) { ContentValues values = new ContentValues(7); final int statusPending = 32; final int subId = SubscriptionManager.getDefaultSmsSubscriptionId(); @@ -2668,8 +2776,18 @@ public class BluetoothMapContentObserver { recipientList = new ArrayList(); recipientList.add(empty); Log.w(TAG, "Added empty recipient to draft message"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 16); } else { Log.e(TAG, "Trying to send a message with no recipients"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 17); return -1; } } @@ -2711,9 +2829,21 @@ public class BluetoothMapContentObserver { // Write Email to DB os.write(msgBody.getBytes(), 0, msgBody.getBytes().length); } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 18); Log.w(TAG, e); throw (new IOException("Unable to open file stream")); } catch (NullPointerException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 19); Log.w(TAG, e); throw (new IllegalArgumentException("Unable to parse message.")); } finally { @@ -2722,6 +2852,12 @@ public class BluetoothMapContentObserver { os.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 20); Log.w(TAG, e); } try { @@ -2729,6 +2865,12 @@ public class BluetoothMapContentObserver { fdOut.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 21); Log.w(TAG, e); } } @@ -2845,6 +2987,12 @@ public class BluetoothMapContentObserver { c.close(); } else { Log.w(TAG, "Message: " + uri + " no longer exist!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 22); /* This can only happen, if the message is deleted * just as it is added */ return -1; @@ -2943,8 +3091,9 @@ public class BluetoothMapContentObserver { if (handle != -1) { String whereClause = " _id= " + handle; Uri uri = Mms.CONTENT_URI; - Cursor queryResult = BluetoothMethodProxy.getInstance().contentResolverQuery(resolver, - uri, null, whereClause, null, null); + Cursor queryResult = + BluetoothMethodProxy.getInstance() + .contentResolverQuery(resolver, uri, null, whereClause, null, null); try { if (queryResult != null) { if (queryResult.getCount() > 0) { @@ -2960,6 +3109,12 @@ public class BluetoothMapContentObserver { } } else { Log.w(TAG, "Could not move MMS message to " + getMmsFolderName(folder)); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 23); } } finally { if (queryResult != null) { @@ -2971,13 +3126,9 @@ public class BluetoothMapContentObserver { private long pushMmsToFolder(int folder, String[] toAddress, BluetoothMapbMessageMime msg) { /** - * strategy: - * 1) parse msg into parts + header - * 2) create thread id (abuse the ease of adding an SMS to get id for thread) - * 3) push parts into content://mms/parts/ table - * 3) + * strategy: 1) parse msg into parts + header 2) create thread id (abuse the ease of adding + * an SMS to get id for thread) 3) push parts into content://mms/parts/ table 3) */ - ContentValues values = new ContentValues(); values.put(Mms.MESSAGE_BOX, folder); values.put(Mms.READ, 0); @@ -3019,6 +3170,11 @@ public class BluetoothMapContentObserver { if (uri == null) { // unable to insert MMS Log.e(TAG, "Unabled to insert MMS " + values + "Uri: " + uri); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 24); return -1; } /* As we already have all the values we need, we could skip the query, but @@ -3057,6 +3213,11 @@ public class BluetoothMapContentObserver { /* Perhaps this message have been deleted, and no longer have any content, * but only headers */ Log.w(TAG, "No MMS parts present..."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 25); } else { if (V) { Log.v(TAG, "Adding " + msg.getMimeParts().size() + " parts to the data base."); @@ -3065,8 +3226,8 @@ public class BluetoothMapContentObserver { int count = 0; count++; values.clear(); - if (part.mContentType != null && part.mContentType.toUpperCase() - .contains("TEXT")) { + if (part.mContentType != null + && part.mContentType.toUpperCase().contains("TEXT")) { values.put(Mms.Part.CONTENT_TYPE, "text/plain"); values.put(Mms.Part.CHARSET, 106); if (part.mPartName != null) { @@ -3150,8 +3311,18 @@ public class BluetoothMapContentObserver { } } } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 26); Log.w(TAG, e); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 27); Log.w(TAG, e); } @@ -3163,8 +3334,10 @@ public class BluetoothMapContentObserver { uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/addr"); uri = mResolver.insert(uri, values); - if (uri != null && V) { - Log.v(TAG, " NEW URI " + uri.toString()); + if (uri != null) { + if (V) { + Log.v(TAG, " NEW URI " + uri.toString()); + } } values.clear(); @@ -3175,8 +3348,10 @@ public class BluetoothMapContentObserver { values.put(Mms.Addr.ADDRESS, address); uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/addr"); uri = mResolver.insert(uri, values); - if (uri != null && V) { - Log.v(TAG, " NEW URI " + uri.toString()); + if (uri != null) { + if (V) { + Log.v(TAG, " NEW URI " + uri.toString()); + } } } return handle; @@ -3190,6 +3365,11 @@ public class BluetoothMapContentObserver { values.put(Mms.Part.CONTENT_TYPE, part.mContentType); } else { Log.w(TAG, "MMS has no CONTENT_TYPE for part " + count); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 28); } if (part.mContentId != null) { values.put(Mms.Part.CONTENT_ID, part.mContentId); @@ -3291,8 +3471,12 @@ public class BluetoothMapContentObserver { Log.d(TAG, "sendMessage to " + msgInfo.phone); if (parts.size() == 1) { - smsMng.sendTextMessageWithoutPersisting(msgInfo.phone, null, parts.get(0), - sentIntents.get(0), deliveryIntents.get(0)); + smsMng.sendTextMessageWithoutPersisting( + msgInfo.phone, + null, + parts.get(0), + sentIntents.get(0), + deliveryIntents.get(0)); } else { smsMng.sendMultipartTextMessageWithoutPersisting(msgInfo.phone, null, parts, sentIntents, deliveryIntents); @@ -3310,6 +3494,11 @@ public class BluetoothMapContentObserver { try { intentFilter.addDataType("message/*"); } catch (MalformedMimeTypeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 29); Log.e(TAG, "Wrong mime type!!!", e); } @@ -3320,6 +3509,11 @@ public class BluetoothMapContentObserver { try { mContext.unregisterReceiver(this); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 30); /* do nothing */ } } @@ -3384,6 +3578,12 @@ public class BluetoothMapContentObserver { if (msgInfo.transparent == 0) { if (!Utils.moveMessageToFolder(context, msgInfo.uri, true)) { Log.w(TAG, "Failed to move " + msgInfo.uri + " to SENT"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 31); } } else { delete = true; @@ -3406,6 +3606,12 @@ public class BluetoothMapContentObserver { if (msgInfo.transparent == 0) { if (!Utils.moveMessageToFolder(context, msgInfo.uri, false)) { Log.w(TAG, "Failed to move " + msgInfo.uri + " to FAILED"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 32); } } else { delete = true; @@ -3426,7 +3632,11 @@ public class BluetoothMapContentObserver { /* Delete from DB */ Uri msgUri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); int nRows = mResolver.delete(msgUri, null, null); - if (V && nRows > 0) Log.v(TAG, "Deleted message with Uri = " + msgUri); + if (nRows > 0) { + if (V) { + Log.v(TAG, "Deleted message with Uri = " + msgUri); + } + } } } } @@ -3450,6 +3660,11 @@ public class BluetoothMapContentObserver { try { mContext.unregisterReceiver(this); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 33); /* do nothing */ } } @@ -3463,6 +3678,12 @@ public class BluetoothMapContentObserver { try { initMsgList(); } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 34); Log.e(TAG, "Error initializing SMS/MMS message lists."); } @@ -3504,6 +3725,11 @@ public class BluetoothMapContentObserver { long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1); if (handle < 0) { Log.w(TAG, "Intent received for an invalid handle"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 35); return; } ContentResolver resolver = context.getContentResolver(); @@ -3558,6 +3784,11 @@ public class BluetoothMapContentObserver { if ((Binder.getCallingPid() != Process.myPid()) || !Utils.checkCallerHasWriteSmsPermission(context)) { Log.w(TAG, "actionSmsSentDisconnected: Not allowed to delete SMS/MMS messages"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 36); return; } @@ -3603,6 +3834,11 @@ public class BluetoothMapContentObserver { BluetoothMethodProxy.getInstance().contentResolverDelete(resolver, uri, null, null); } else { Log.w(TAG, "Unable to get resolver"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 37); } } } @@ -3675,6 +3911,11 @@ public class BluetoothMapContentObserver { /* Remove messages from virtual "deleted" folder (thread_id -1) */ mResolver.delete(Sms.CONTENT_URI, "thread_id = " + DELETED_THREAD_ID, null); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 38); // TODO: Include this unexpected exception in Bluetooth metrics Log.w("SQLite exception while removing deleted messages.", e); } @@ -3732,13 +3973,18 @@ public class BluetoothMapContentObserver { public boolean handleMmsSendIntent(Context context, Intent intent) { if (D) { - Log.w(TAG, "handleMmsSendIntent()"); + Log.d(TAG, "handleMmsSendIntent()"); } if (!mMnsClient.isConnected()) { // No need to handle notifications, just use default handling if (D) { Log.w(TAG, "MNS not connected - use static handling"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 39); return false; } long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1); @@ -3746,6 +3992,11 @@ public class BluetoothMapContentObserver { actionMmsSent(context, intent, result, getMsgListMms()); if (handle < 0) { Log.w(TAG, "Intent received for an invalid handle"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 40); return true; } if (result != Activity.RESULT_OK) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java index f3898657a95d486a41a07799a047a8313d38404d..fee6d24c24e8a1c34ccd673bd02692e5f90b3b04 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java @@ -14,9 +14,13 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.SignedLongLong; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -28,6 +32,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +// Next tag value for ContentProfileErrorReportUtils.report(): 1 public class BluetoothMapConvoContactElement implements Comparable { @@ -85,6 +90,11 @@ public class BluetoothMapConvoContactElement try { this.mBtUid = SignedLongLong.fromString(btUid); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_CONTACT_ELEMENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, e); } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java index 1995783f4131739db914638f7dc3209d64b6c0ac..e5a00d6c17754b4094423b3f860ae6dd12286ce8 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java @@ -14,10 +14,14 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; import android.util.Xml; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -32,6 +36,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +// Next tag value for ContentProfileErrorReportUtils.report(): 3 public class BluetoothMapConvoListing { private boolean mHasUnread = false; private static final String TAG = "BluetoothMapConvoListing"; @@ -105,10 +110,25 @@ public class BluetoothMapConvoListing { xmlConvoElement.endTag(null, XML_TAG); xmlConvoElement.endDocument(); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_LISTING, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, e); } catch (IllegalStateException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_LISTING, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.w(TAG, e); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_LISTING, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.w(TAG, e); } return sw.toString().getBytes("UTF-8"); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java index 8905beb6b5346a92dfce27bf62bc75ea47651daa..384506232690aa834cc4e67df8c35cf424595127 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java @@ -14,10 +14,14 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.SignedLongLong; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import org.xmlpull.v1.XmlPullParser; @@ -32,6 +36,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class BluetoothMapConvoListingElement implements Comparable { @@ -93,6 +98,11 @@ public class BluetoothMapConvoListingElement try { this.mVersionCounter = Long.parseLong(vcount); } catch (NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_LISTING_ELEMENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, "unable to parse XML versionCounter:" + vcount); mVersionCounter = -1; } @@ -228,6 +238,11 @@ public class BluetoothMapConvoListingElement try { return BluetoothMapUtils.truncateUtf8StringToString(mSummary, 256); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_LISTING_ELEMENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); // This cannot happen on an Android platform - UTF-8 is mandatory Log.e(TAG, "Missing UTF-8 support on platform", e); } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java index 4a34a2200f1bf7be7fe294d7a626b93a6df031c6..01fdada4397347fae4f12ac6f315fe88d01a9c30 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java @@ -14,10 +14,14 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; import android.util.Xml; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -30,10 +34,8 @@ import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Locale; -/** - * Class to contain a single folder element representation. - * - */ +/** Class to contain a single folder element representation. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 3 public class BluetoothMapFolderElement implements Comparable { private String mName; private BluetoothMapFolderElement mParent = null; @@ -293,16 +295,31 @@ public class BluetoothMapFolderElement implements Comparable= 0 && nativeInterface.isAvailable()) { - if (V) { - Log.d(mTag, "Removing SDP record for MAS instance: " + mMasInstanceId - + " Object reference: " + this + "SDP handle: " + mSdpHandle); - } + verbose("Removing SDP record for MAS instance: " + mMasInstanceId + + " Object reference: " + this + ", SDP handle: " + mSdpHandle); boolean status = nativeInterface.removeSdpRecord(mSdpHandle); - Log.d(mTag, "RemoveSDPrecord returns " + status); + debug("RemoveSDPrecord returns " + status); mSdpHandle = -1; } } - /* Needed only for test */ - @VisibleForTesting - BluetoothMapMasInstance() { - mTag = "BluetoothMapMasInstance" + sInstanceCounter++; - } - @Override public String toString() { return "MasId: " + mMasInstanceId + " Uri:" + mBaseUri + " SMS/MMS:" + mEnableSmsMms; @@ -274,21 +272,15 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { * Start Obex Server Sockets and create the SDP record. */ public synchronized void startSocketListeners() { - if (D) { - Log.d(mTag, "Map Service startSocketListeners"); - } + debug("Map Service startSocketListeners"); if (mServerSession != null) { - if (D) { - Log.d(mTag, "mServerSession exists - shutting it down..."); - } + debug("mServerSession exists - shutting it down..."); mServerSession.close(); mServerSession = null; } if (mObserver != null) { - if (D) { - Log.d(mTag, "mObserver exists - shutting it down..."); - } + debug("mObserver exists - shutting it down..."); mObserver.deinit(); mObserver = null; } @@ -304,17 +296,20 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { if (mServerSockets == null) { // TODO: Handle - was not handled before - Log.e(mTag, "Failed to start the listeners"); + error("Failed to start the listeners"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_MAS_INSTANCE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); return; } removeSdpRecord(); mSdpHandle = createMasSdpRecord(mServerSockets.getRfcommChannel(), mServerSockets.getL2capPsm()); // Here we might have changed crucial data, hence reset DB identifier - if (V) { - Log.d(mTag, "Creating new SDP record for MAS instance: " + mMasInstanceId - + " Object reference: " + this + "SDP handle: " + mSdpHandle); - } + verbose("Creating new SDP record for MAS instance: " + mMasInstanceId + + " Object reference: " + this + ", SDP handle: " + mSdpHandle); updateDbIdentifier(); } } @@ -388,9 +383,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { * Returns true at success. */ public boolean startObexServerSession(BluetoothMnsObexClient mnsClient) throws IOException, RemoteException { - if (D) { - Log.d(mTag, "Map Service startObexServerSession masid = " + mMasInstanceId); - } + debug("Map Service startObexServerSession masid = " + mMasInstanceId); if (mConnSocket != null) { if (mServerSession != null) { @@ -409,15 +402,11 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { // setup transport BluetoothObexTransport transport = new BluetoothObexTransport(mConnSocket); mServerSession = new ServerSession(transport, mMapServer, null); - if (D) { - Log.d(mTag, " ServerSession started."); - } + debug(" ServerSession started."); return true; } - if (D) { - Log.d(mTag, " No connection for this instance"); - } + debug(" No connection for this instance"); return false; } @@ -437,9 +426,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { } public void shutdown() { - if (D) { - Log.d(mTag, "MAP Service shutdown"); - } + debug("MAP Service shutdown"); if (mServerSession != null) { mServerSession.close(); @@ -462,9 +449,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { * Signal to the ServerSockets handler that a new connection may be accepted. */ public void restartObexServerSession() { - if (D) { - Log.d(mTag, "MAP Service restartObexServerSession()"); - } + debug("MAP Service restartObexServerSession()"); startSocketListeners(); } @@ -483,7 +468,12 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { try { mConnSocket.close(); } catch (IOException e) { - Log.e(mTag, "Close Connection Socket error: ", e); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_MAS_INSTANCE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); + error("Close Connection Socket error: ", e); } finally { mConnSocket = null; } @@ -491,17 +481,13 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { } public void setRemoteFeatureMask(int supportedFeatures) { - if (V) { - Log.v(mTag, "setRemoteFeatureMask : Curr: " + mRemoteFeatureMask); - } + verbose("setRemoteFeatureMask : Curr: " + mRemoteFeatureMask); mRemoteFeatureMask = supportedFeatures & sFeatureMask; BluetoothMapUtils.savePeerSupportUtcTimeStamp(mRemoteFeatureMask); if (mObserver != null) { mObserver.setObserverRemoteFeatureMask(mRemoteFeatureMask); mMapServer.setRemoteFeatureMask(mRemoteFeatureMask); - if (V) { - Log.v(mTag, "setRemoteFeatureMask : set: " + mRemoteFeatureMask); - } + verbose("setRemoteFeatureMask : set: " + mRemoteFeatureMask); } } @@ -532,19 +518,48 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { } /** - * Called when an unrecoverable error occurred in an accept thread. - * Close down the server socket, and restart. - * TODO: Change to message, to call start in correct context. + * Called when an unrecoverable error occurred in an accept thread. Close down the server + * socket, and restart. TODO: Change to message, to call start in correct context. */ @Override public synchronized void onAcceptFailed() { mServerSockets = null; // Will cause a new to be created when calling start. if (mShutdown) { - Log.e(mTag, "Failed to accept incomming connection - " + "shutdown"); + error("Failed to accept incoming connection - shutdown"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_MAS_INSTANCE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); } else { - Log.e(mTag, "Failed to accept incomming connection - " + "restarting"); + error("Failed to accept incoming connection - restarting"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_MAS_INSTANCE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 3); startSocketListeners(); } } + // Per-Instance logging + public void verbose(String message) { + if (V) { + Log.v(TAG, "[instance=" + mObjectInstanceId + "] " + message); + } + } + + public void debug(String message) { + if (D) { + Log.d(TAG, "[instance=" + mObjectInstanceId + "] " + message); + } + } + + public void error(String message) { + Log.e(TAG, "[instance=" + mObjectInstanceId + "] " + message); + } + + public void error(String message, Exception e) { + Log.e(TAG, "[instance=" + mObjectInstanceId + "] " + message, e); + } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java index 96427be11c7000e9cb708c919349c621251ceb28..11f6e3caad54c7545e5223a32d0e75e0f733e4ea 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapMessageListing.java @@ -14,11 +14,15 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; import android.util.Xml; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.DeviceWorkArounds; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import org.xmlpull.v1.XmlSerializer; @@ -29,6 +33,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +// Next tag value for ContentProfileErrorReportUtils.report(): 3 public class BluetoothMapMessageListing { private boolean mHasUnread = false; private static final String TAG = "BluetoothMapMessageListing"; @@ -121,10 +126,25 @@ public class BluetoothMapMessageListing { xmlMsgElement.endTag(null, "MAP-msg-listing"); xmlMsgElement.endDocument(); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_MESSAGE_LISTING, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, e); } catch (IllegalStateException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_MESSAGE_LISTING, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.w(TAG, e); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_MESSAGE_LISTING, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.w(TAG, e); } /* Fix IOT issue to replace '&' by '&', < by < and '> by '>' in MessageListing */ diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java index c9c9be6958d1e102dfff4bf82ecb26e959eccb0b..69651eb38baf8b5ea24651a06cbad32b4e18e2e1 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java @@ -14,6 +14,8 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; @@ -30,7 +32,9 @@ import android.text.format.DateUtils; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.SignedLongLong; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.mapapi.BluetoothMapContract; import com.android.internal.annotations.VisibleForTesting; @@ -46,6 +50,7 @@ import java.text.ParseException; import java.util.Arrays; import java.util.Calendar; +// Next tag value for ContentProfileErrorReportUtils.report(): 74 public class BluetoothMapObexServer extends ServerRequestHandler { private static final String TAG = "BluetoothMapObexServer"; @@ -355,16 +360,32 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (uuid.length != UUID_LENGTH) { Log.w(TAG, "Wrong UUID length"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } for (int i = 0; i < UUID_LENGTH; i++) { if (uuid[i] != MAP_TARGET[i]) { Log.w(TAG, "Wrong UUID"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } reply.setHeader(HeaderSet.WHO, uuid); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "Exception during onConnect:", e); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -385,6 +406,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { reply.setHeader(THREADED_MAIL_HEADER_ID, THREAD_MAIL_KEY); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, "Exception during onConnect:", e); mThreadIdSupport = false; return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; @@ -492,31 +518,57 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 4); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } mObserver.setNotificationFilter(appParams.getNotificationFilter()); return ResponseCodes.OBEX_HTTP_OK; } else if (type.equals(TYPE_SET_MESSAGE_STATUS)) { if (V) { - Log.d(TAG, "TYPE_SET_MESSAGE_STATUS: " + "StatusIndicator: " - + appParams.getStatusIndicator() + ", StatusValue: " - + appParams.getStatusValue() - + ", ExtentedData: "); // TODO: appParams.getExtendedImData()); + Log.d( + TAG, + "TYPE_SET_MESSAGE_STATUS: " + + "StatusIndicator: " + + appParams.getStatusIndicator() + + ", StatusValue: " + + appParams.getStatusValue() + + ", ExtentedData: "); // TODO: appParams.getExtendedImData()); } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 5); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } return setMessageStatus(name, appParams); } else if (type.equals(TYPE_MESSAGE)) { if (V) { - Log.d(TAG, - "TYPE_MESSAGE: Transparet: " + appParams.getTransparent() + ", retry: " - + appParams.getRetry() + ", charset: " + Log.d( + TAG, + "TYPE_MESSAGE: Transparet: " + + appParams.getTransparent() + + ", retry: " + + appParams.getRetry() + + ", charset: " + appParams.getCharset()); } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 6); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } return pushMessage(op, name, appParams, mMessageVersion); @@ -533,20 +585,30 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); //reload the providerClient and return error try { mProviderClient = acquireUnstableContentProviderOrThrow(); } catch (RemoteException e2) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); //should not happen } return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } catch (Exception e) { - - if (D) { - Log.e(TAG, "Exception occured while handling request", e); - } else { - Log.e(TAG, "Exception occured while handling request"); - } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); + Log.e(TAG, "Exception occurred while handling request", e); if (mIsAborted) { return ResponseCodes.OBEX_HTTP_OK; } else { @@ -572,8 +634,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (D) { Log.d(TAG, "updateInbox accountId=" + accountId); } - extras.putLong(BluetoothMapContract.EXTRA_UPDATE_FOLDER_ID, - inboxFolder.getFolderId()); + extras.putLong( + BluetoothMapContract.EXTRA_UPDATE_FOLDER_ID, inboxFolder.getFolderId()); extras.putLong(BluetoothMapContract.EXTRA_UPDATE_ACCOUNT_ID, accountId); } else { // Only error code allowed on an UpdateInbox is OBEX_HTTP_NOT_IMPLEMENTED, @@ -604,15 +666,33 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); mProviderClient = acquireUnstableContentProviderOrThrow(); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } catch (NullPointerException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); if (D) { Log.e(TAG, "UpdateInbox - if uri or method is null", e); } return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); if (D) { Log.e(TAG, "UpdateInbox - if uri is not known", e); } @@ -659,12 +739,17 @@ public class BluetoothMapObexServer extends ServerRequestHandler { BluetoothMapFolderElement folderElement = getFolderElementFromName(folderName); if (folderElement == null) { Log.w(TAG, "pushMessage: folderElement == null - sending OBEX_HTTP_PRECON_FAILED"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 13); return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } else { folderName = folderElement.getName(); } - if (!folderName.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX) && !folderName - .equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT)) { + if (!folderName.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX) + && !folderName.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT)) { if (D) { Log.d(TAG, "pushMessage: Is only allowed to outbox and draft. " + "folderName=" + folderName); @@ -704,16 +789,27 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (D) { Log.w(TAG, "mObserver or parsed message not available"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 14); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } - if ((message.getType().equals(TYPE.EMAIL) && (folderElement.getFolderId() == -1)) || ( - (message.getType().equals(TYPE.SMS_GSM) || message.getType() - .equals(TYPE.SMS_CDMA) || message.getType().equals(TYPE.MMS)) + if ((message.getType().equals(TYPE.EMAIL) && (folderElement.getFolderId() == -1)) + || ((message.getType().equals(TYPE.SMS_GSM) + || message.getType().equals(TYPE.SMS_CDMA) + || message.getType().equals(TYPE.MMS)) && !folderElement.hasSmsMmsContent())) { if (D) { Log.w(TAG, "Wrong message type recieved"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 15); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } @@ -725,6 +821,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (D) { Log.w(TAG, "Message handle not created"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 16); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; // Should not happen. } HeaderSet replyHeaders = new HeaderSet(); @@ -736,24 +837,44 @@ public class BluetoothMapObexServer extends ServerRequestHandler { op.sendHeaders(replyHeaders); } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 17); //reload the providerClient and return error try { mProviderClient = acquireUnstableContentProviderOrThrow(); } catch (RemoteException e2) { - //should not happen + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 18); + // should not happen if (D) { Log.w(TAG, "acquireUnstableContentProviderOrThrow FAILED"); } } return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 19); if (D) { Log.e(TAG, "Wrongly formatted bMessage received", e); } return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 20); if (D) { - Log.e(TAG, "Exception occured: ", e); + Log.e(TAG, "Exception occurred: ", e); } if (mIsAborted) { if (D) { @@ -764,6 +885,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 21); if (D) { Log.e(TAG, "Exception:", e); } @@ -773,6 +899,12 @@ public class BluetoothMapObexServer extends ServerRequestHandler { try { bMsgStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 22); if (D) Log.d(TAG, "", e); } } @@ -799,6 +931,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (D) { Log.e(TAG, "Error: no mObserver!"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 23); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; // Should not happen. } @@ -809,9 +946,19 @@ public class BluetoothMapObexServer extends ServerRequestHandler { Log.d(TAG, "setMessageStatus. Handle:" + handle + ", MsgType: " + msgType); } } catch (NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 24); Log.w(TAG, "Wrongly formatted message handle: " + msgHandle); return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 25); Log.w(TAG, "Message type not found in handle string: " + msgHandle); return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } @@ -822,6 +969,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (D) { Log.w(TAG, "setMessageStatusDeleted failed"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 26); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } } else if (indicator == BluetoothMapAppParams.STATUS_INDICATOR_READ) { @@ -830,9 +982,20 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (D) { Log.w(TAG, "not able to update the message"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 27); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 28); if (D) { Log.w(TAG, "Error in setMessageStatusRead()", e); } @@ -898,14 +1061,29 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 29); mProviderClient = acquireUnstableContentProviderOrThrow(); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } catch (NullPointerException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 30); if (D) { Log.e(TAG, "setOwnerStatus - if uri or method is null", e); } return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 31); if (D) { Log.e(TAG, "setOwnerStatus - if uri is not known", e); } @@ -924,11 +1102,12 @@ public class BluetoothMapObexServer extends ServerRequestHandler { try { folderName = (String) request.getHeader(HeaderSet.NAME); } catch (Exception e) { - if (D) { - Log.e(TAG, "request headers error", e); - } else { - Log.e(TAG, "request headers error"); - } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 32); + Log.e(TAG, "request headers error", e); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } @@ -982,7 +1161,6 @@ public class BluetoothMapObexServer extends ServerRequestHandler { mProviderClient.close(); mProviderClient = null; } - } @Override @@ -1018,39 +1196,48 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } if (type.equals(TYPE_GET_FOLDER_LISTING)) { - if (V && appParams != null) { - Log.d(TAG, - "TYPE_GET_FOLDER_LISTING: MaxListCount = " + appParams.getMaxListCount() - + ", ListStartOffset = " + appParams.getStartOffset()); + if (V) { + if (appParams != null) { + Log.d(TAG, "TYPE_GET_FOLDER_LISTING: MaxListCount = " + + appParams.getMaxListCount() + ", ListStartOffset = " + + appParams.getStartOffset()); + } } // Block until all packets have been send. return sendFolderListingRsp(op, appParams); } else if (type.equals(TYPE_GET_MESSAGE_LISTING)) { name = (String) request.getHeader(HeaderSet.NAME); - if (V && appParams != null) { - Log.d(TAG, "TYPE_GET_MESSAGE_LISTING: folder name is: " + name - + ", MaxListCount = " + appParams.getMaxListCount() - + ", ListStartOffset = " + appParams.getStartOffset()); - Log.d(TAG, - "SubjectLength = " + appParams.getSubjectLength() + ", ParameterMask = " - + appParams.getParameterMask()); - Log.d(TAG, "FilterMessageType = " + appParams.getFilterMessageType()); - Log.d(TAG, "FilterPeriodBegin = " + appParams.getFilterPeriodBeginString() - + ", FilterPeriodEnd = " + appParams.getFilterPeriodEndString() - + ", FilterReadStatus = " + appParams.getFilterReadStatus()); - Log.d(TAG, "FilterRecipient = " + appParams.getFilterRecipient() - + ", FilterOriginator = " + appParams.getFilterOriginator()); - Log.d(TAG, "FilterPriority = " + appParams.getFilterPriority()); - long tmpLong = appParams.getFilterMsgHandle(); - Log.d(TAG, "FilterMsgHandle = " + ( - (tmpLong == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? "" - : Long.toHexString(tmpLong))); - SignedLongLong tmpLongLong = appParams.getFilterConvoId(); - Log.d(TAG, "FilterConvoId = " + ((tmpLongLong == null) ? "" - : Long.toHexString(tmpLongLong.getLeastSignificantBits()))); + if (V) { + if (appParams != null) { + Log.d(TAG, "TYPE_GET_MESSAGE_LISTING: folder name is: " + name + + ", MaxListCount = " + appParams.getMaxListCount() + + ", ListStartOffset = " + appParams.getStartOffset()); + Log.d(TAG, "SubjectLength = " + appParams.getSubjectLength() + + ", ParameterMask = " + appParams.getParameterMask()); + Log.d(TAG, "FilterMessageType = " + appParams.getFilterMessageType()); + Log.d(TAG, "FilterPeriodBegin = " + appParams.getFilterPeriodBeginString() + + ", FilterPeriodEnd = " + appParams.getFilterPeriodEndString() + + ", FilterReadStatus = " + appParams.getFilterReadStatus()); + Log.d(TAG, "FilterRecipient = " + appParams.getFilterRecipient() + + ", FilterOriginator = " + appParams.getFilterOriginator()); + Log.d(TAG, "FilterPriority = " + appParams.getFilterPriority()); + long tmpLong = appParams.getFilterMsgHandle(); + Log.d(TAG, "FilterMsgHandle = " + ( + (tmpLong == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? "" + : Long.toHexString(tmpLong))); + SignedLongLong tmpLongLong = appParams.getFilterConvoId(); + Log.d(TAG, "FilterConvoId = " + ((tmpLongLong == null) ? "" + : Long.toHexString(tmpLongLong.getLeastSignificantBits()))); + } } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 33); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } // Block until all packets have been send. @@ -1058,59 +1245,95 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } else if (type.equals(TYPE_GET_CONVO_LISTING)) { name = (String) request.getHeader(HeaderSet.NAME); - if (V && appParams != null) { - Log.d(TAG, "TYPE_GET_CONVO_LISTING: name is" + name + ", MaxListCount = " - + appParams.getMaxListCount() + ", ListStartOffset = " - + appParams.getStartOffset()); - Log.d(TAG, - "FilterLastActivityBegin = " + appParams.getFilterLastActivityBegin()); - Log.d(TAG, "FilterLastActivityEnd = " + appParams.getFilterLastActivityEnd()); - Log.d(TAG, "FilterReadStatus = " + appParams.getFilterReadStatus()); - Log.d(TAG, "FilterRecipient = " + appParams.getFilterRecipient()); + if (V) { + if (appParams != null) { + Log.d(TAG, "TYPE_GET_CONVO_LISTING: name is" + name + ", MaxListCount = " + + appParams.getMaxListCount() + ", ListStartOffset = " + + appParams.getStartOffset()); + Log.d(TAG, "FilterLastActivityBegin = " + + appParams.getFilterLastActivityBegin()); + Log.d(TAG, "FilterLastActivityEnd = " + + appParams.getFilterLastActivityEnd()); + Log.d(TAG, "FilterReadStatus = " + appParams.getFilterReadStatus()); + Log.d(TAG, "FilterRecipient = " + appParams.getFilterRecipient()); + } } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 34); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } // Block until all packets have been send. return sendConvoListingRsp(op, appParams); } else if (type.equals(TYPE_GET_MAS_INSTANCE_INFORMATION)) { - if (V && appParams != null) { - Log.d(TAG, - "TYPE_MESSAGE (GET): MASInstandeId = " + appParams.getMasInstanceId()); + if (V) { + if (appParams != null) { + Log.d(TAG, "TYPE_MESSAGE (GET): MASInstandeId = " + + appParams.getMasInstanceId()); + } } // Block until all packets have been send. return sendMASInstanceInformationRsp(op, appParams); } else if (type.equals(TYPE_MESSAGE)) { name = (String) request.getHeader(HeaderSet.NAME); - if (V && appParams != null) { - Log.d(TAG, "TYPE_MESSAGE (GET): name is" + name + ", Attachment = " - + appParams.getAttachment() + ", Charset = " + appParams.getCharset() - + ", FractionRequest = " + appParams.getFractionRequest()); + if (V) { + if (appParams != null) { + Log.d(TAG, "TYPE_MESSAGE (GET): name is" + name + ", Attachment = " + + appParams.getAttachment() + ", Charset = " + + appParams.getCharset() + ", FractionRequest = " + + appParams.getFractionRequest()); + } } if (!isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 35); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } // Block until all packets have been send. return sendGetMessageRsp(op, name, appParams, mMessageVersion); } else { Log.w(TAG, "unknown type request: " + type); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 36); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 37); Log.e(TAG, "Exception:", e); return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } catch (ParseException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 38); Log.e(TAG, "Exception:", e); return ResponseCodes.OBEX_HTTP_PRECON_FAILED; } catch (Exception e) { - if (D) { - Log.e(TAG, "Exception occured while handling request", e); - } else { - Log.e(TAG, "Exception occured while handling request"); - } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 39); + Log.e(TAG, "Exception occurred while handling request", e); if (mIsAborted) { if (D) { Log.d(TAG, "onGet Operation Aborted"); @@ -1123,20 +1346,17 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } /** - * Generate and send the message listing response based on an application - * parameter header. This function call will block until complete or aborted - * by the peer. Fragmentation of packets larger than the obex packet size - * will be handled by this function. + * Generate and send the message listing response based on an application parameter header. This + * function call will block until complete or aborted by the peer. Fragmentation of packets + * larger than the obex packet size will be handled by this function. * - * @param op - * The OBEX operation. - * @param appParams - * The application parameter header - * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or - * {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. + * @param op The OBEX operation. + * @param appParams The application parameter header + * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or {@link + * ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. */ - private int sendMessageListingRsp(Operation op, BluetoothMapAppParams appParams, - String folderName) { + private int sendMessageListingRsp( + Operation op, BluetoothMapAppParams appParams, String folderName) { OutputStream outStream = null; byte[] outBytes = null; int maxChunkSize, bytesToWrite, bytesWritten = 0, listSize; @@ -1171,6 +1391,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (folderToList == null) { Log.w(TAG, "sendMessageListingRsp: folderToList == " + "null-sending OBEX_HTTP_BAD_REQUEST"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 40); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } Log.v(TAG, "sendMessageListingRsp: has sms " + folderToList.hasSmsMmsContent() @@ -1234,11 +1459,22 @@ public class BluetoothMapObexServer extends ServerRequestHandler { // Open the OBEX body stream outStream = op.openOutputStream(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 41); Log.w(TAG, "sendMessageListingRsp: IOException - sending OBEX_HTTP_BAD_REQUEST", e); if (outStream != null) { try { outStream.close(); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 42); if (D) Log.d(TAG, "", ex); } } @@ -1251,12 +1487,23 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 43); Log.w(TAG, "sendMessageListingRsp: IllegalArgumentException" + " - sending OBEX_HTTP_BAD_REQUEST", e); if (outStream != null) { try { outStream.close(); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 44); if (D) Log.d(TAG, "", ex); } } @@ -1272,6 +1519,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { bytesWritten += bytesToWrite; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 45); if (D) { Log.w(TAG, e); } @@ -1281,6 +1533,12 @@ public class BluetoothMapObexServer extends ServerRequestHandler { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 46); if (D) Log.d(TAG, "", e); } } @@ -1288,6 +1546,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (bytesWritten != outBytes.length && !mIsAborted) { Log.w(TAG, "sendMessageListingRsp: bytesWritten != outBytes.length" + " - sending OBEX_HTTP_BAD_REQUEST"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 47); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } else { @@ -1295,6 +1558,12 @@ public class BluetoothMapObexServer extends ServerRequestHandler { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 48); if (D) Log.d(TAG, "", e); } } @@ -1304,11 +1573,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { /** * Update the {@link BluetoothMapAppParams} object message type filter mask to only contain - * message types supported by this mas instance. - * Could the folder be used in stead? + * message types supported by this mas instance. Could the folder be used in stead? + * * @param appParams Reference to the object to update * @param overwrite True: The msgType will be overwritten to match the message types supported - * by this MAS instance. False: any unsupported message types will be masked out. + * by this MAS instance. False: any unsupported message types will be masked out. */ @VisibleForTesting void setMsgTypeFilterParams(BluetoothMapAppParams appParams, boolean overwrite) { @@ -1424,11 +1693,22 @@ public class BluetoothMapObexServer extends ServerRequestHandler { // Open the OBEX body stream outStream = op.openOutputStream(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 49); Log.w(TAG, "sendConvoListingRsp: IOException - sending OBEX_HTTP_BAD_REQUEST", e); if (outStream != null) { try { outStream.close(); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 50); if (D) Log.d(TAG, "", ex); } } @@ -1441,12 +1721,23 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 51); Log.w(TAG, "sendConvoListingRsp: IllegalArgumentException" + " - sending OBEX_HTTP_BAD_REQUEST", e); if (outStream != null) { try { outStream.close(); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 52); if (D) Log.d(TAG, "", ex); } } @@ -1462,6 +1753,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { bytesWritten += bytesToWrite; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 53); if (D) { Log.w(TAG, e); } @@ -1478,6 +1774,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { if (bytesWritten != outBytes.length && !mIsAborted) { Log.w(TAG, "sendConvoListingRsp: bytesWritten != outBytes.length" + " - sending OBEX_HTTP_BAD_REQUEST"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 54); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } else { @@ -1485,6 +1786,12 @@ public class BluetoothMapObexServer extends ServerRequestHandler { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 55); if (D) Log.d(TAG, "", e); } } @@ -1493,17 +1800,14 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } /** - * Generate and send the Folder listing response based on an application - * parameter header. This function call will block until complete or aborted - * by the peer. Fragmentation of packets larger than the obex packet size - * will be handled by this function. + * Generate and send the Folder listing response based on an application parameter header. This + * function call will block until complete or aborted by the peer. Fragmentation of packets + * larger than the obex packet size will be handled by this function. * - * @param op - * The OBEX operation. - * @param appParams - * The application parameter header - * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or - * {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. + * @param op The OBEX operation. + * @param appParams The application parameter header + * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or {@link + * ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. */ private int sendFolderListingRsp(Operation op, BluetoothMapAppParams appParams) { OutputStream outStream = null; @@ -1549,12 +1853,23 @@ public class BluetoothMapObexServer extends ServerRequestHandler { outStream = op.openOutputStream(); } } catch (IOException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 56); Log.w(TAG, "sendFolderListingRsp: IOException" + " - sending OBEX_HTTP_BAD_REQUEST Exception:", e1); if (outStream != null) { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 57); if (D) Log.d(TAG, "", e); } } @@ -1567,12 +1882,23 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } catch (IllegalArgumentException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 58); Log.w(TAG, "sendFolderListingRsp: IllegalArgumentException" + " - sending OBEX_HTTP_BAD_REQUEST Exception:", e1); if (outStream != null) { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 59); if (D) Log.d(TAG, "", e); } } @@ -1589,12 +1915,23 @@ public class BluetoothMapObexServer extends ServerRequestHandler { bytesWritten += bytesToWrite; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 60); // We were probably aborted or disconnected } finally { if (outStream != null) { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 61); if (D) Log.d(TAG, "", e); } } @@ -1616,12 +1953,10 @@ public class BluetoothMapObexServer extends ServerRequestHandler { /** * Generate and send the get MAS Instance Information response based on an MAS Instance * - * @param op - * The OBEX operation. - * @param appParams - * The application parameter header - * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or - * {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. + * @param op The OBEX operation. + * @param appParams The application parameter header + * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or {@link + * ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error. */ private int sendMASInstanceInformationRsp(Operation op, BluetoothMapAppParams appParams) { @@ -1672,6 +2007,11 @@ public class BluetoothMapObexServer extends ServerRequestHandler { outStream = op.openOutputStream(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 62); Log.w(TAG, "sendMASInstanceInformationRsp: IOException" + " - sending OBEX_HTTP_BAD_REQUEST", e); if (mIsAborted) { @@ -1694,12 +2034,23 @@ public class BluetoothMapObexServer extends ServerRequestHandler { bytesWritten += bytesToWrite; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 63); // We were probably aborted or disconnected } finally { if (outStream != null) { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 64); if (D) Log.d(TAG, "", e); } } @@ -1761,11 +2112,22 @@ public class BluetoothMapObexServer extends ServerRequestHandler { outStream = op.openOutputStream(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 65); Log.w(TAG, "sendGetMessageRsp: IOException - sending OBEX_HTTP_BAD_REQUEST", e); if (outStream != null) { try { outStream.close(); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 66); if (D) Log.d(TAG, "", ex); } } @@ -1778,12 +2140,23 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 67); Log.w(TAG, "sendGetMessageRsp: IllegalArgumentException (e.g. invalid handle) - " + "sending OBEX_HTTP_BAD_REQUEST", e); if (outStream != null) { try { outStream.close(); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 68); if (D) Log.d(TAG, "", ex); } } @@ -1800,15 +2173,28 @@ public class BluetoothMapObexServer extends ServerRequestHandler { bytesWritten += bytesToWrite; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 69); // We were probably aborted or disconnected - if (D && e.getMessage().equals("Abort Received")) { - Log.w(TAG, "getMessage() Aborted...", e); + if (e.getMessage().equals("Abort Received")) { + if (D) { + Log.d(TAG, "getMessage() Aborted...", e); + } } } finally { if (outStream != null) { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 70); if (D) Log.d(TAG, "", e); } } @@ -1866,20 +2252,30 @@ public class BluetoothMapObexServer extends ServerRequestHandler { } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 71); //reload the providerClient and return error try { mProviderClient = acquireUnstableContentProviderOrThrow(); } catch (RemoteException e2) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 72); //should not happen } return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } catch (Exception e) { - - if (D) { - Log.e(TAG, "Exception occured while handling request", e); - } else { - Log.e(TAG, "Exception occured while handling request"); - } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 73); + Log.e(TAG, "Exception occurred while handling request", e); if (mIsAborted) { return ResponseCodes.OBEX_HTTP_OK; } else { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java index 2c0dd666b8de8e1148da9ae432e12c7c5a556fa8..f1499c61c870e802a0088cc40d350973b0ef6ee3 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java @@ -26,6 +26,7 @@ import android.app.PendingIntent; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothMap; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothMap; import android.bluetooth.SdpMnsRecord; @@ -51,12 +52,14 @@ import android.util.Log; import android.util.SparseArray; import com.android.bluetooth.BluetoothMetricsProto; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; @@ -66,6 +69,7 @@ import java.util.HashMap; import java.util.List; import java.util.Objects; +// Next tag value for ContentProfileErrorReportUtils.report(): 25 public class BluetoothMapService extends ProfileService { private static final String TAG = "BluetoothMapService"; @@ -168,12 +172,7 @@ public class BluetoothMapService extends ProfileService { return BluetoothProperties.isProfileMapServerEnabled().orElse(false); } - public BluetoothMapService() { - BluetoothMap.invalidateBluetoothGetConnectionStateCache(); - } - - @VisibleForTesting - BluetoothMapService(Context ctx) { + public BluetoothMapService(Context ctx) { super(ctx); BluetoothMap.invalidateBluetoothGetConnectionStateCache(); } @@ -241,6 +240,11 @@ public class BluetoothMapService extends ProfileService { masInst.startSocketListeners(); } else { Log.w(TAG, "startSocketListeners(): Invalid MasId: " + masId); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); } } } @@ -277,10 +281,20 @@ public class BluetoothMapService extends ProfileService { connected = true; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.w(TAG, "IOException occured while starting an obexServerSession restarting" + " the listener", e); mMasInstances.valueAt(i).restartObexServerSession(); } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.w(TAG, "RemoteException occured while starting an obexServerSession restarting" + " the listener", e); mMasInstances.valueAt(i).restartObexServerSession(); @@ -460,6 +474,12 @@ public class BluetoothMapService extends ProfileService { sRemoteDevice.sdpSearch(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS); } else { Log.w(TAG, "remoteDevice info not available"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); } break; case MSG_OBSERVER_REGISTRATION: @@ -476,6 +496,12 @@ public class BluetoothMapService extends ProfileService { masInst.mObserver.unregisterObserver(); } } catch (RemoteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); Log.e(TAG, "ContentObserverRegistarion Failed: " + e); } } @@ -507,8 +533,18 @@ public class BluetoothMapService extends ProfileService { startObexServerSessions(); } } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); Log.e(TAG, "catch IOException starting obex server session", ex); } catch (RemoteException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); Log.e(TAG, "catch RemoteException starting obex server session", ex); } } @@ -681,7 +717,7 @@ public class BluetoothMapService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DEBUG) { Log.d(TAG, "start()"); } @@ -709,6 +745,11 @@ public class BluetoothMapService extends ProfileService { try { filterMessageSent.addDataType("message/*"); } catch (MalformedMimeTypeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.e(TAG, "Wrong mime type!!!", e); } if (!mRegisteredMapReceiver) { @@ -728,7 +769,6 @@ public class BluetoothMapService extends ProfileService { sendStartListenerMessage(-1); setBluetoothMapService(this); mServiceStarted = true; - return true; } /** @@ -740,10 +780,20 @@ public class BluetoothMapService extends ProfileService { public static synchronized BluetoothMapService getBluetoothMapService() { if (sBluetoothMapService == null) { Log.w(TAG, "getBluetoothMapService(): service is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 8); return null; } if (!sBluetoothMapService.isAvailable()) { Log.w(TAG, "getBluetoothMapService(): service is not available"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 9); return null; } return sBluetoothMapService; @@ -895,7 +945,7 @@ public class BluetoothMapService extends ProfileService { } @Override - protected boolean stop() { + public void stop() { if (DEBUG) { Log.d(TAG, "stop()"); } @@ -903,7 +953,7 @@ public class BluetoothMapService extends ProfileService { if (DEBUG) { Log.d(TAG, "mServiceStarted is false - Ignoring"); } - return true; + return; } setBluetoothMapService(null); mServiceStarted = false; @@ -915,11 +965,11 @@ public class BluetoothMapService extends ProfileService { sendShutdownMessage(); setComponentAvailable(MAP_SETTINGS_ACTIVITY, false); setComponentAvailable(MAP_FILE_PROVIDER, false); - return true; } /** * Called from each MAS instance when a connection is received. + * * @param remoteDevice The device connecting * @param masInst a reference to the calling MAS instance. * @return true if the connection was accepted, false otherwise @@ -955,6 +1005,11 @@ public class BluetoothMapService extends ProfileService { } else if (!sRemoteDevice.equals(remoteDevice)) { Log.w(TAG, "Unexpected connection from a second Remote Device received. name: " + ( (remoteDevice == null) ? "unknown" : Utils.getName(remoteDevice))); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 10); return false; } // Else second connection to same device, just continue @@ -1032,6 +1087,11 @@ public class BluetoothMapService extends ProfileService { if (DEBUG) { Log.w(TAG, "mSessionStatusHandler START_LISTENER message already in Queue"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 11); } } @@ -1071,12 +1131,22 @@ public class BluetoothMapService extends ProfileService { } if (mSessionStatusHandler == null) { Log.w(TAG, "mSessionStatusHandler is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 12); return; } if (mSessionStatusHandler.hasMessages(SHUTDOWN)) { if (DEBUG) { Log.w(TAG, "mSessionStatusHandler shutdown message already in Queue"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 13); return; } mSessionStatusHandler.removeCallbacksAndMessages(null); @@ -1084,6 +1154,11 @@ public class BluetoothMapService extends ProfileService { Message msg = mSessionStatusHandler.obtainMessage(SHUTDOWN); if (!mSessionStatusHandler.sendMessage(msg)) { Log.w(TAG, "mSessionStatusHandler shutdown message could not be sent"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 14); } } @@ -1182,6 +1257,11 @@ public class BluetoothMapService extends ProfileService { } if (sRemoteDevice == null || device == null) { Log.e(TAG, "Unexpected error!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 15); return; } @@ -1282,6 +1362,11 @@ public class BluetoothMapService extends ProfileService { } receiver.send(result); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 16); receiver.propagateException(e); } } @@ -1302,12 +1387,19 @@ public class BluetoothMapService extends ProfileService { } receiver.send(client); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 17); receiver.propagateException(e); } } @Override - public void isConnected(BluetoothDevice device, AttributionSource source, + public void isConnected( + BluetoothDevice device, + AttributionSource source, SynchronousResultReceiver receiver) { if (VERBOSE) { Log.v(TAG, "isConnected()"); @@ -1321,6 +1413,11 @@ public class BluetoothMapService extends ProfileService { } receiver.send(result); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 18); receiver.propagateException(e); } } @@ -1340,6 +1437,11 @@ public class BluetoothMapService extends ProfileService { } receiver.send(result); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 19); receiver.propagateException(e); } } @@ -1359,13 +1461,18 @@ public class BluetoothMapService extends ProfileService { } receiver.send(connectedDevices); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 20); receiver.propagateException(e); } } @Override - public void getDevicesMatchingConnectionStates(int[] states, - AttributionSource source, SynchronousResultReceiver receiver) { + public void getDevicesMatchingConnectionStates( + int[] states, AttributionSource source, SynchronousResultReceiver receiver) { if (VERBOSE) { Log.v(TAG, "getDevicesMatchingConnectionStates()"); } @@ -1377,6 +1484,11 @@ public class BluetoothMapService extends ProfileService { } receiver.send(devices); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 21); receiver.propagateException(e); } } @@ -1395,6 +1507,11 @@ public class BluetoothMapService extends ProfileService { } receiver.send(state); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 22); receiver.propagateException(e); } } @@ -1410,6 +1527,11 @@ public class BluetoothMapService extends ProfileService { } receiver.send(result); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 23); receiver.propagateException(e); } } @@ -1425,6 +1547,11 @@ public class BluetoothMapService extends ProfileService { } receiver.send(policy); } catch (RuntimeException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 24); receiver.propagateException(e); } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java index b105331a8cc344847ec7861bece1468079ca3bee..192685cb5012470247779ded8912e295774e64a8 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java @@ -16,6 +16,8 @@ package com.android.bluetooth.map; import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.Context; import android.telephony.PhoneNumberUtils; import android.telephony.SmsManager; @@ -23,6 +25,8 @@ import android.telephony.SmsMessage; import android.telephony.TelephonyManager; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.util.GsmAlphabet; import java.io.ByteArrayInputStream; @@ -35,6 +39,7 @@ import java.util.Calendar; import java.util.Date; import java.util.Random; +// Next tag value for ContentProfileErrorReportUtils.report(): 10 public class BluetoothMapSmsPdu { private static final String TAG = "BluetoothMapSmsPdu"; @@ -190,6 +195,11 @@ public class BluetoothMapSmsPdu { } pdu.close(); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "cdmaGetParameterOffset: ", e); } @@ -225,6 +235,11 @@ public class BluetoothMapSmsPdu { } pdu.close(); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "cdmaGetParameterOffset: ", e); } @@ -346,6 +361,12 @@ public class BluetoothMapSmsPdu { try { pdu.read(udh); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.w(TAG, "unable to read userDataHeader", e); } int[] tableValue = getTableFromByteArray(udh); @@ -458,6 +479,11 @@ public class BluetoothMapSmsPdu { newPdu.write(mData, gsmSubmitGetTpUdOffset(), mData.length - gsmSubmitGetTpUdOffset()); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, "", e); throw new IllegalArgumentException("Failed to change type to deliver PDU."); } @@ -641,7 +667,7 @@ public class BluetoothMapSmsPdu { * - extract user data header to get the language properties * - extract user data * - decode the string */ - //Strip off the SC-address before parsing + // Strip off the SC-address before parsing SmsPdu pdu = new SmsPdu(gsmStripOffScAddress(data), SMS_TYPE_GSM); boolean userDataCompressed = false; int dataCodingScheme = pdu.gsmSubmitGetTpDcs(); @@ -656,6 +682,11 @@ public class BluetoothMapSmsPdu { if (userDataCompressed) { Log.w(TAG, "4 - Unsupported SMS data coding scheme " + "(compression) " + ( dataCodingScheme & 0xff)); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 4); } else { switch ((dataCodingScheme >> 2) & 0x3) { case 0: // GSM 7 bit default alphabet @@ -670,6 +701,12 @@ public class BluetoothMapSmsPdu { case 3: // reserved Log.w(TAG, "1 - Unsupported SMS data coding scheme " + (dataCodingScheme & 0xff)); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); encodingType = SmsConstants.ENCODING_8BIT; break; } @@ -709,9 +746,19 @@ public class BluetoothMapSmsPdu { encodingType = SmsConstants.ENCODING_KSC5601; } else { Log.w(TAG, "5 - Unsupported SMS data coding scheme " + (dataCodingScheme & 0xff)); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 6); } } else { Log.w(TAG, "3 - Unsupported SMS data coding scheme " + (dataCodingScheme & 0xff)); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 7); } pdu.setEncoding(encodingType); @@ -722,6 +769,12 @@ public class BluetoothMapSmsPdu { case SmsConstants.ENCODING_UNKNOWN: case SmsConstants.ENCODING_8BIT: Log.w(TAG, "Unknown encoding type: " + encodingType); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 8); messageBody = null; break; @@ -747,6 +800,11 @@ public class BluetoothMapSmsPdu { break; } } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_SMS_PDU, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); Log.e(TAG, "Unsupported encoding type???", e); // This should never happen. return null; } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java index 604f6cae88186bf12d52c9f07ede2d6d71d18945..0abf16b3efe7fa58195b87308e3d1af1a139fbdc 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java @@ -14,10 +14,14 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.database.Cursor; import android.util.Base64; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.mapapi.BluetoothMapContract; import java.io.ByteArrayOutputStream; @@ -36,9 +40,8 @@ import java.util.Calendar; import java.util.regex.Matcher; import java.util.regex.Pattern; -/** - * Various utility methods and generic defines that can be used throughout MAPS - */ +/** Various utility methods and generic defines that can be used throughout MAPS */ +// Next tag value for ContentProfileErrorReportUtils.report(): 11 public class BluetoothMapUtils { private static final String TAG = "BluetoothMapUtils"; @@ -296,6 +299,11 @@ public class BluetoothMapUtils { if (D) { Log.e(TAG, " Invalid messageType input"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); } return mapHandle; @@ -425,6 +433,11 @@ public class BluetoothMapUtils { try { System.arraycopy(utf8String.getBytes("UTF-8"), 0, utf8Bytes, 0, utf8String.length()); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "truncateUtf8StringToBytearray: getBytes exception ", e); throw e; } @@ -510,18 +523,38 @@ public class BluetoothMapUtils { try { Log.d(TAG, "StripEncoding: base64 string : " + encodedText); - str = new String( - Base64.decode(encodedText.getBytes(charset), Base64.DEFAULT), - charset); + str = + new String( + Base64.decode( + encodedText.getBytes(charset), Base64.DEFAULT), + charset); Log.d(TAG, "StripEncoding: decoded string : " + str); in = in.replace(match, str); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "stripEncoding: Unsupported charset: " + charset); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, "stripEncoding: string not encoded as base64: " + encodedText); } } else { Log.e(TAG, "stripEncoding: Hit unknown encoding: " + encoding); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 4); } } } @@ -542,6 +575,11 @@ public class BluetoothMapUtils { try { input = text.getBytes("US-ASCII"); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); /* This cannot happen as "US-ASCII" is supported for all Java implementations */ } @@ -597,6 +635,11 @@ public class BluetoothMapUtils { } Log.w(TAG, "Received wrongly quoted printable encoded text. " + "Continuing at best effort..."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 6); /* If we get a '=' without either a hex value or CRLF following, just add it and * rewind the in counter. */ output[out++] = b0; @@ -626,6 +669,11 @@ public class BluetoothMapUtils { charset = "UTF-8"; } } catch (IllegalCharsetNameException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.w(TAG, "Received unknown charset: " + charset + " - using UTF-8."); charset = "UTF-8"; } @@ -633,10 +681,20 @@ public class BluetoothMapUtils { try { result = new String(output, 0, out, charset); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); /* This cannot happen unless Charset.isSupported() is out of sync with String */ try { result = new String(output, 0, out, "UTF-8"); } catch (UnsupportedEncodingException e2) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); Log.e(TAG, "quotedPrintableToUtf8: " + e); } } @@ -691,6 +749,11 @@ public class BluetoothMapUtils { try { return buffer.toString("UTF-8"); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); //cannot happen return ""; } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java index 9930f12b5d3414f40176e1ca9367aaf3ebc335dd..9fa60296b078132f76c9dca0a8b5d444ecc70d76 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java @@ -14,10 +14,14 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.os.Environment; import android.telephony.PhoneNumberUtils; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.internal.annotations.VisibleForTesting; @@ -31,6 +35,7 @@ import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +// Next tag value for ContentProfileErrorReportUtils.report(): 10 public abstract class BluetoothMapbMessage { protected static final String TAG = "BluetoothMapbMessage"; @@ -359,6 +364,11 @@ public abstract class BluetoothMapbMessage { output.write(readByte); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, e); return null; } @@ -378,6 +388,11 @@ public abstract class BluetoothMapbMessage { return new String(line, "UTF-8"); } } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.w(TAG, e); return null; } @@ -445,14 +460,19 @@ public abstract class BluetoothMapbMessage { try { int bytesRead; int offset = 0; - while ((bytesRead = mInStream.read(data, offset, length - offset)) != (length - - offset)) { + while ((bytesRead = mInStream.read(data, offset, length - offset)) + != (length - offset)) { if (bytesRead == -1) { return null; } offset += bytesRead; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.w(TAG, e); return null; } @@ -513,8 +533,18 @@ public abstract class BluetoothMapbMessage { writtenLen += len; } } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, "Unable to create output stream", e); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); Log.e(TAG, "Failed to copy the received message", e); if (writtenLen != 0) { failed = true; /* We failed to write the complete file, @@ -525,6 +555,12 @@ public abstract class BluetoothMapbMessage { try { outStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); Log.w(TAG, e); } } @@ -548,6 +584,12 @@ public abstract class BluetoothMapbMessage { try { bMsgStream = new FileInputStream(file); } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); Log.e(TAG, "Failed to open the bMessage file", e); /* terminate this function with an error */ throw new IllegalArgumentException(); @@ -663,6 +705,11 @@ public abstract class BluetoothMapbMessage { try { bMsgStream.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); /* Ignore if we cannot close the stream. */ } @@ -711,6 +758,12 @@ public abstract class BluetoothMapbMessage { try { Long unusedId = Long.parseLong(arg[1].trim()); } catch (NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); throw new IllegalArgumentException("Wrong value in 'PARTID': " + arg[1]); } } else { @@ -1048,6 +1101,11 @@ public abstract class BluetoothMapbMessage { } return stream.toByteArray(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); Log.w(TAG, e); return null; } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java index 630133d0144f0d990cfa8890d557dc0a59808d2d..ea1b09067a4d4c694ae0b0b1637a1841f82d0262 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java @@ -14,11 +14,17 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; + import java.io.UnsupportedEncodingException; import java.util.ArrayList; +// Next tag value for ContentProfileErrorReportUtils.report(): 1 public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { private String mEmailBody = null; @@ -59,11 +65,18 @@ public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { a generic way. * We use byte[] since we need to extract the length in bytes. */ if (mEmailBody != null) { - String tmpBody = mEmailBody.replaceAll("END:MSG", - "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG + String tmpBody = + mEmailBody.replaceAll( + "END:MSG", + "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG bodyFragments.add(tmpBody.getBytes("UTF-8")); } else { Log.e(TAG, "Email has no body - this should not be possible"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_EMAIL, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); bodyFragments.add(new byte[0]); // An empty message - this should not be possible } return encodeGeneric(bodyFragments); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java index a2a81fc6c09d2ffc0194641a8640ba38de461f5f..2d1709673ae05f45a32fc4e529c8855de51794b2 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java @@ -14,11 +14,16 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.text.util.Rfc822Token; import android.text.util.Rfc822Tokenizer; import android.util.Base64; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; + import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; @@ -29,6 +34,7 @@ import java.util.Date; import java.util.Locale; import java.util.UUID; +// Next tag value for ContentProfileErrorReportUtils.report(): 8 public class BluetoothMapbMessageMime extends BluetoothMapbMessage { public static class MimePart { @@ -60,6 +66,12 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { charset = "UTF-8"; } } catch (IllegalCharsetNameException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, "Received unknown charset: " + charset + " - using UTF-8."); charset = "UTF-8"; } @@ -67,10 +79,21 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { try { result = new String(mData, charset); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); /* This cannot happen unless Charset.isSupported() is out of sync with String */ try { result = new String(mData, "UTF-8"); } catch (UnsupportedEncodingException e2) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "getDataAsString: " + e); } } @@ -641,6 +664,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { if (D) { Log.w(TAG, "Skipping unknown header: " + headerType + " (" + header + ")"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); } } return null; @@ -672,6 +700,12 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { if (D) { Log.w(TAG, "part-Header not formatted correctly: "); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 4); continue; } if (D) { @@ -706,6 +740,12 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { Log.w(TAG, "Skipping unknown part-header: " + headerType + " (" + header + ")"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); } } body = parts[1]; @@ -737,6 +777,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { return body.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); // This will never happen, as UTF-8 is mandatory on Android platforms } } @@ -747,6 +792,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { // Check for null String, otherwise NPE will cause BT to crash if (message == null) { Log.e(TAG, "parseMime called with a NULL message, terminating early"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 7); return; } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java b/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java index 6aa546919f8c06b26ce05f0d350de89de2a45e0b..275a186b7929fc3e06263867712014c03fa700f1 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMnsObexClient.java @@ -15,6 +15,8 @@ package com.android.bluetooth.map; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSocket; import android.bluetooth.SdpMnsRecord; import android.os.Handler; @@ -26,6 +28,8 @@ import android.util.Log; import android.util.SparseBooleanArray; import com.android.bluetooth.BluetoothObexTransport; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.obex.ClientOperation; import com.android.obex.ClientSession; import com.android.obex.HeaderSet; @@ -36,12 +40,11 @@ import java.io.IOException; import java.io.OutputStream; /** - * The Message Notification Service class runs its own message handler thread, - * to avoid executing long operations on the MAP service Thread. - * This handler context is passed to the content observers, - * hence all call-backs (and thereby transmission of data) is executed - * from this thread. + * The Message Notification Service class runs its own message handler thread, to avoid executing + * long operations on the MAP service Thread. This handler context is passed to the content + * observers, hence all call-backs (and thereby transmission of data) is executed from this thread. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 16 public class BluetoothMnsObexClient { private static final String TAG = "BluetoothMnsObexClient"; @@ -174,6 +177,11 @@ public class BluetoothMnsObexClient { } } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, "OBEX session disconnect error " + e.getMessage()); } try { @@ -188,6 +196,11 @@ public class BluetoothMnsObexClient { } } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.w(TAG, "OBEX session close error:" + e.getMessage()); } if (mTransport != null) { @@ -202,6 +215,11 @@ public class BluetoothMnsObexClient { Log.d(TAG, "Obex Transport Closed"); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "mTransport.close error: " + e.getMessage()); } } @@ -293,6 +311,11 @@ public class BluetoothMnsObexClient { } if (isValidMnsRecord()) { Log.w(TAG, "MNS Record already available. Still update."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); } mMnsRecord = mnsRecord; if (mMnsLstRegRqst != null) { @@ -344,12 +367,23 @@ public class BluetoothMnsObexClient { } else { // This should not happen... Log.e(TAG, "Invalid SDP content - attempt a connect to UUID..."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 4); // TODO: Why insecure? - is it because the link is already encrypted? - btSocket = mRemoteDevice.createInsecureRfcommSocketToServiceRecord( - BLUETOOTH_UUID_OBEX_MNS.getUuid()); + btSocket = + mRemoteDevice.createInsecureRfcommSocketToServiceRecord( + BLUETOOTH_UUID_OBEX_MNS.getUuid()); } btSocket.connect(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); Log.e(TAG, "BtSocket Connect error " + e.getMessage(), e); // TODO: do we need to report error somewhere? mConnected = false; @@ -361,6 +395,11 @@ public class BluetoothMnsObexClient { try { mClientSession = new ClientSession(mTransport); } catch (IOException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); Log.e(TAG, "OBEX session create error " + e1.getMessage()); mConnected = false; } @@ -369,22 +408,22 @@ public class BluetoothMnsObexClient { HeaderSet hs = new HeaderSet(); // bb582b41-420c-11db-b0de-0800200c9a66 byte[] mnsTarget = { - (byte) 0xbb, - (byte) 0x58, - (byte) 0x2b, - (byte) 0x41, - (byte) 0x42, - (byte) 0x0c, - (byte) 0x11, - (byte) 0xdb, - (byte) 0xb0, - (byte) 0xde, - (byte) 0x08, - (byte) 0x00, - (byte) 0x20, - (byte) 0x0c, - (byte) 0x9a, - (byte) 0x66 + (byte) 0xbb, + (byte) 0x58, + (byte) 0x2b, + (byte) 0x41, + (byte) 0x42, + (byte) 0x0c, + (byte) 0x11, + (byte) 0xdb, + (byte) 0xb0, + (byte) 0xde, + (byte) 0x08, + (byte) 0x00, + (byte) 0x20, + (byte) 0x0c, + (byte) 0x9a, + (byte) 0x66 }; hs.setHeader(HeaderSet.TARGET, mnsTarget); @@ -398,6 +437,11 @@ public class BluetoothMnsObexClient { } connected = true; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.e(TAG, "OBEX session connect error " + e.getMessage()); } mConnected = connected; @@ -441,6 +485,11 @@ public class BluetoothMnsObexClient { if ((!mConnected) || (clientSession == null)) { Log.w(TAG, "sendEvent after disconnect:" + mConnected); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 8); return responseCode; } @@ -460,6 +509,11 @@ public class BluetoothMnsObexClient { System.arraycopy(mHsConnect.mConnectionID, 0, request.mConnectionID, 0, 4); } else { Log.w(TAG, "sendEvent: no connection ID"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 9); } synchronized (this) { @@ -474,6 +528,11 @@ public class BluetoothMnsObexClient { // TODO - Should this be kept or Removed } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); Log.e(TAG, "Error when put HeaderSet " + e.getMessage()); error = true; } @@ -487,6 +546,12 @@ public class BluetoothMnsObexClient { } outputStream = putOperation.openOutputStream(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); Log.e(TAG, "Error when opening OutputStream " + e.getMessage()); error = true; } @@ -511,9 +576,19 @@ public class BluetoothMnsObexClient { } } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); handleSendException(e.toString()); error = true; } catch (IndexOutOfBoundsException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 13); handleSendException(e.toString()); error = true; } finally { @@ -522,6 +597,11 @@ public class BluetoothMnsObexClient { outputStream.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 14); Log.e(TAG, "Error when closing stream after send " + e.getMessage()); } try { @@ -540,6 +620,11 @@ public class BluetoothMnsObexClient { putOperation.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MNS_OBEX_CLIENT, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 15); Log.e(TAG, "Error when closing stream after send " + e.getMessage()); } } diff --git a/android/app/src/com/android/bluetooth/map/MmsFileProvider.java b/android/app/src/com/android/bluetooth/map/MmsFileProvider.java index 0aec9c5419c519cf1acc75cb1a3e18c087d5d401..00420f9528e893a47da433cfb27c6521aba44137 100644 --- a/android/app/src/com/android/bluetooth/map/MmsFileProvider.java +++ b/android/app/src/com/android/bluetooth/map/MmsFileProvider.java @@ -14,6 +14,8 @@ */ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; @@ -23,6 +25,9 @@ import android.os.ParcelFileDescriptor; import android.provider.Telephony.Mms; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; + import com.google.android.mms.MmsException; import com.google.android.mms.pdu.GenericPdu; import com.google.android.mms.pdu.PduComposer; @@ -33,9 +38,10 @@ import java.io.FileOutputStream; import java.io.IOException; /** - * Provider to let the MMS subsystem read data from it own database from another process. - * Workaround for missing access to sendStoredMessage(). + * Provider to let the MMS subsystem read data from it own database from another process. Workaround + * for missing access to sendStoredMessage(). */ +// Next tag value for ContentProfileErrorReportUtils.report(): 5 public class MmsFileProvider extends ContentProvider { static final String TAG = "BluetoothMmsFileProvider"; private PipeWriter mPipeWriter = new PipeWriter(); @@ -88,6 +94,11 @@ public class MmsFileProvider extends ContentProvider { try { long id = Long.parseLong(idStr); } catch (NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MMS_FILE_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.w(TAG, e); throw new FileNotFoundException("Unable to extract message handle from: " + uri); } @@ -122,11 +133,21 @@ public class MmsFileProvider extends ContentProvider { fout.write(bytes); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MMS_FILE_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.w(TAG, e); /* TODO: How to signal the error to the calling entity? Had expected writeDataToPipe * to throw IOException? */ } catch (MmsException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MMS_FILE_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.w(TAG, e); /* TODO: How to signal the error to the calling entity? Had expected writeDataToPipe * to throw IOException? @@ -138,11 +159,23 @@ public class MmsFileProvider extends ContentProvider { try { fout.flush(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MMS_FILE_PROVIDER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.w(TAG, "IOException: ", e); } try { fout.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_MMS_FILE_PROVIDER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); Log.w(TAG, "IOException: ", e); } } diff --git a/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java b/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java index f222b1e983ab93951469faaba5054bdf54a0706f..f45e0ad3f84355733d8263cbf461aa3d65e07812 100644 --- a/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java +++ b/android/app/src/com/android/bluetooth/map/SmsMmsContacts.java @@ -15,6 +15,8 @@ package com.android.bluetooth.map; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; @@ -26,6 +28,8 @@ import android.provider.Telephony.MmsSms; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; @@ -33,9 +37,10 @@ import java.util.HashMap; import java.util.regex.Pattern; /** - * Use these functions when extracting data for listings. It caches frequently used data to - * speed up building large listings - e.g. before applying filtering. + * Use these functions when extracting data for listings. It caches frequently used data to speed up + * building large listings - e.g. before applying filtering. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class SmsMmsContacts { private static final String TAG = "SmsMmsContacts"; @@ -91,6 +96,11 @@ public class SmsMmsContacts { } } Log.e(TAG, "query failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_SMS_MMS_CONTACTS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); } finally { if (c != null) { c.close(); @@ -141,6 +151,11 @@ public class SmsMmsContacts { } } else { Log.e(TAG, "query failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.MAP, + BluetoothProtoEnums.BLUETOOTH_SMS_MMS_CONTACTS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); } } finally { if (c != null) { diff --git a/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java b/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java index c552a1e0c69d474da56afafb2c765b25dcf85129..4034afd060d1b528674597031a2bd388d62ddd67 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java +++ b/android/app/src/com/android/bluetooth/mapclient/MapClientContent.java @@ -24,6 +24,7 @@ import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; +import android.provider.BaseColumns; import android.provider.Telephony; import android.provider.Telephony.Mms; import android.provider.Telephony.MmsSms; @@ -45,7 +46,12 @@ import com.android.vcard.VCardProperty; import com.google.android.mms.pdu.PduHeaders; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Set; @@ -58,6 +64,20 @@ class MapClientContent { private static final int ORIGINATOR_ADDRESS_TYPE = 137; private static final int RECIPIENT_ADDRESS_TYPE = 151; + private static final int NUM_RECENT_MSGS_TO_DUMP = 5; + + private enum Type { + UNKNOWN, + SMS, + MMS + } + + private enum Folder { + UNKNOWN, + INBOX, + SENT + } + final BluetoothDevice mDevice; private final Context mContext; private final Callbacks mCallbacks; @@ -81,18 +101,16 @@ class MapClientContent { /** * MapClientContent manages all interactions between Bluetooth and the messaging provider. * - * Changes to the database are mirrored between the remote and local providers, specifically new - * messages, changes to read status, and removal of messages. + *

Changes to the database are mirrored between the remote and local providers, specifically + * new messages, changes to read status, and removal of messages. * - * Object is invalid after cleanUp() is called. + *

Object is invalid after cleanUp() is called. * - * context: the context that all content provider interactions are conducted - * MceStateMachine: the interface to send outbound updates such as when a message is read - * locally - * device: the associated Bluetooth device used for associating messages with a subscription + *

context: the context that all content provider interactions are conducted MceStateMachine: + * the interface to send outbound updates such as when a message is read locally device: the + * associated Bluetooth device used for associating messages with a subscription */ - MapClientContent(Context context, Callbacks callbacks, - BluetoothDevice device) { + MapClientContent(Context context, Callbacks callbacks, BluetoothDevice device) { mContext = context; mDevice = device; mCallbacks = callbacks; @@ -187,9 +205,20 @@ class MapClientContent { * The handle is used to associate the local message with the remote message. */ void storeMessage(Bmessage message, String handle, Long timestamp, boolean seen) { - logI("storeMessage(device=" + Utils.getLoggableAddress(mDevice) + ", time=" + timestamp - + ", handle=" + handle + ", type=" + message.getType() - + ", folder=" + message.getFolder()); + logI( + "storeMessage(device=" + + Utils.getLoggableAddress(mDevice) + + ", time=" + + timestamp + + "[" + + toDatetimeString(timestamp) + + "]" + + ", handle=" + + handle + + ", type=" + + message.getType() + + ", folder=" + + message.getFolder()); switch (message.getType()) { case MMS: @@ -609,6 +638,146 @@ class MapClientContent { return count; } + private List getRecentMessagesFromFolder(Folder folder) { + Uri smsUri = null; + Uri mmsUri = null; + if (folder == Folder.INBOX) { + smsUri = Sms.Inbox.CONTENT_URI; + mmsUri = Mms.Inbox.CONTENT_URI; + } else if (folder == Folder.SENT) { + smsUri = Sms.Sent.CONTENT_URI; + mmsUri = Mms.Sent.CONTENT_URI; + } else { + Log.w(TAG, "getRecentMessagesFromFolder: Failed, unsupported folder=" + folder); + return null; + } + + ArrayList messages = new ArrayList(); + for (Uri uri : new Uri[] {smsUri, mmsUri}) { + messages.addAll(getMessagesFromUri(uri)); + } + logV( + "getRecentMessagesFromFolder: " + + folder + + ", " + + messages.size() + + " messages found."); + + Collections.sort(messages); + if (messages.size() > NUM_RECENT_MSGS_TO_DUMP) { + return messages.subList(0, NUM_RECENT_MSGS_TO_DUMP); + } + return messages; + } + + private List getMessagesFromUri(Uri uri) { + logD("getMessagesFromUri: uri=" + uri); + ArrayList messages = new ArrayList(); + + if (mSubscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + Log.w(TAG, "getMessagesFromUri: Failed, no subscription ID"); + return messages; + } + + Type type = getMessageTypeFromUri(uri); + if (type == Type.UNKNOWN) { + Log.w(TAG, "getMessagesFromUri: unknown message type"); + return messages; + } + + String[] selectionArgs = new String[] {Integer.toString(mSubscriptionId)}; + String limit = " LIMIT " + NUM_RECENT_MSGS_TO_DUMP; + String[] projection = null; + String selectionClause = null; + String threadIdColumnName = null; + String timestampColumnName = null; + + if (type == Type.SMS) { + projection = new String[] {BaseColumns._ID, Sms.THREAD_ID, Sms.DATE}; + selectionClause = Sms.SUBSCRIPTION_ID + " =? "; + threadIdColumnName = Sms.THREAD_ID; + timestampColumnName = Sms.DATE; + } else if (type == Type.MMS) { + projection = new String[] {BaseColumns._ID, Mms.THREAD_ID, Mms.DATE}; + selectionClause = Mms.SUBSCRIPTION_ID + " =? "; + threadIdColumnName = Mms.THREAD_ID; + timestampColumnName = Mms.DATE; + } + + Cursor cursor = + mResolver.query( + uri, + projection, + selectionClause, + selectionArgs, + timestampColumnName + " DESC" + limit); + + try { + if (cursor == null) { + Log.w(TAG, "getMessagesFromUri: null cursor for uri=" + uri); + return messages; + } + logV("Number of rows in cursor = " + cursor.getCount() + ", for uri=" + uri); + + cursor.moveToPosition(-1); + while (cursor.moveToNext()) { + // Even though {@link storeSms} and {@link storeMms} use Uris that contain the + // folder name (e.g., {@code Sms.Inbox.CONTENT_URI}), the Uri returned by + // {@link ContentResolver#insert} does not (e.g., {@code Sms.CONTENT_URI}). + // Therefore, the Uris in the keyset of {@code mUriToHandleMap} do not contain + // the folder name, but unfortunately, the Uri passed in to query the database + // does contains the folder name, so we can't simply append messageId to the + // passed-in Uri. + String messageId = cursor.getString(cursor.getColumnIndex(BaseColumns._ID)); + Uri messageUri = + Uri.withAppendedPath( + type == Type.SMS ? Sms.CONTENT_URI : Mms.CONTENT_URI, messageId); + + MessageStatus handleAndStatus = mUriToHandleMap.get(messageUri); + String messageHandle = ""; + if (handleAndStatus == null) { + Log.w(TAG, "getMessagesFromUri: no entry for message uri=" + messageUri); + } else { + messageHandle = handleAndStatus.mHandle; + } + + long timestamp = cursor.getLong(cursor.getColumnIndex(timestampColumnName)); + // TODO: why does `storeMms` truncate down to the seconds instead of keeping it + // millisec, like `storeSms`? + if (type == Type.MMS) { + timestamp *= 1000L; + } + + messages.add( + new MessageDumpElement( + messageHandle, + messageUri, + timestamp, + cursor.getLong(cursor.getColumnIndex(threadIdColumnName)), + type)); + } + } catch (Exception e) { + Log.w(TAG, "Exception when querying db for dumpsys", e); + } finally { + cursor.close(); + } + return messages; + } + + private Type getMessageTypeFromUri(Uri uri) { + if (Sms.CONTENT_URI.equals(uri) + || Sms.Inbox.CONTENT_URI.equals(uri) + || Sms.Sent.CONTENT_URI.equals(uri)) { + return Type.SMS; + } else if (Mms.CONTENT_URI.equals(uri) + || Mms.Inbox.CONTENT_URI.equals(uri) + || Mms.Sent.CONTENT_URI.equals(uri)) { + return Type.MMS; + } else { + return Type.UNKNOWN; + } + } + public void dump(StringBuilder sb) { sb.append(" Device Message DB:"); sb.append("\n Subscription ID: " + mSubscriptionId); @@ -624,6 +793,17 @@ class MapClientContent { + " / " + getStoredMessagesCount(Mms.CONTENT_URI)); sb.append("\n Threads: " + getStoredMessagesCount(Threads.CONTENT_URI)); + + sb.append("\n Most recent 'Sent' messages:"); + sb.append("\n " + MessageDumpElement.getFormattedColumnNames()); + for (MessageDumpElement e : getRecentMessagesFromFolder(Folder.SENT)) { + sb.append("\n " + e); + } + sb.append("\n Most recent 'Inbox' messages:"); + sb.append("\n " + MessageDumpElement.getFormattedColumnNames()); + for (MessageDumpElement e : getRecentMessagesFromFolder(Folder.INBOX)) { + sb.append("\n " + e); + } } sb.append("\n"); } @@ -650,4 +830,53 @@ class MapClientContent { .equals(mHandle)); } } + + @SuppressWarnings("GoodTime") // Use system time zone to render times for logging + private static String toDatetimeString(long epochMillis) { + return DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS") + .format( + Instant.ofEpochMilli(epochMillis) + .atZone(ZoneId.systemDefault()) + .toLocalDateTime()); + } + + private static class MessageDumpElement implements Comparable { + private String mMessageHandle; + private long mTimestamp; + private Type mType; + private long mThreadId; + private Uri mUri; + + MessageDumpElement(String handle, Uri uri, long timestamp, long threadId, Type type) { + mMessageHandle = handle; + mTimestamp = timestamp; + mUri = uri; + mThreadId = threadId; + mType = type; + } + + public static String getFormattedColumnNames() { + return String.format( + "%-19s %s %-16s %s %s", "Timestamp", "ThreadId", "Handle", "Type", "Uri"); + } + + @Override + public String toString() { + return String.format( + "%-19s %8d %-16s %-4s %s", + toDatetimeString(mTimestamp), mThreadId, mMessageHandle, mType, mUri); + } + + @Override + public int compareTo(MessageDumpElement e) { + // we want reverse chronological. + if (this.mTimestamp < e.mTimestamp) { + return 1; + } else if (this.mTimestamp > e.mTimestamp) { + return -1; + } else { + return 0; + } + } + } } diff --git a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java index 772a31b2307a243f74df07f888c638b7e129de2e..cc259099f4e76dfa1d6259a1c7ed40c9d6c956a5 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MapClientService.java +++ b/android/app/src/com/android/bluetooth/mapclient/MapClientService.java @@ -58,7 +58,8 @@ public class MapClientService extends ProfileService { static final int MAXIMUM_CONNECTED_DEVICES = 4; - private Map mMapInstanceMap = new ConcurrentHashMap<>(1); + private final Map mMapInstanceMap = + new ConcurrentHashMap<>(1); private MnsService mMnsServer; private AdapterService mAdapterService; @@ -69,17 +70,15 @@ public class MapClientService extends ProfileService { private Looper mSmLooper; - MapClientService() {} - - @VisibleForTesting - MapClientService(Context ctx) { + public MapClientService(Context ctx) { super(ctx); } @VisibleForTesting - MapClientService(Context ctx, Looper looper) { + MapClientService(Context ctx, Looper looper, MnsService mnsServer) { this(ctx); mSmLooper = looper; + mMnsServer = mnsServer; } public static boolean isEnabled() { @@ -125,10 +124,7 @@ public class MapClientService extends ProfileService { throw new IllegalArgumentException("Null device"); } if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "MAP connect device: " + device - + ", InstanceMap start state: " + sb.toString()); + Log.d(TAG, "connect(device= " + device + "): devices=" + mMapInstanceMap.keySet()); } if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { Log.w(TAG, "Connection not allowed: <" + device.getAddress() @@ -174,10 +170,7 @@ public class MapClientService extends ProfileService { addDeviceToMapAndConnect(device); if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "MAP connect device: " + device - + ", InstanceMap end state: " + sb.toString()); + Log.d(TAG, "connect(device= " + device + "): end devices=" + mMapInstanceMap.keySet()); } return true; } @@ -196,10 +189,7 @@ public class MapClientService extends ProfileService { enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "MAP disconnect device: " + device - + ", InstanceMap start state: " + sb.toString()); + Log.d(TAG, "disconnect(device= " + device + "): devices=" + mMapInstanceMap.keySet()); } MceStateMachine mapStateMachine = mMapInstanceMap.get(device); // a map state machine instance doesn't exist. maybe it is already gone? @@ -213,10 +203,8 @@ public class MapClientService extends ProfileService { } mapStateMachine.disconnect(); if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "MAP disconnect device: " + device - + ", InstanceMap start state: " + sb.toString()); + Log.d(TAG, "disconnect(device= " + device + "): end devices=" + + mMapInstanceMap.keySet()); } return true; } @@ -322,7 +310,7 @@ public class MapClientService extends ProfileService { } @Override - protected synchronized boolean start() { + public synchronized void start() { Log.e(TAG, "start()"); mAdapterService = AdapterService.getAdapterService(); @@ -332,22 +320,16 @@ public class MapClientService extends ProfileService { mHandler = new Handler(Looper.getMainLooper()); if (mMnsServer == null) { - mMnsServer = MapUtils.newMnsServiceInstance(this); - if (mMnsServer == null) { - // this can't happen - Log.w(TAG, "MnsService is *not* created!"); - return false; - } + mMnsServer = new MnsService(this); } removeUncleanAccounts(); MapClientContent.clearAllContent(this); setMapClientService(this); - return true; } @Override - protected synchronized boolean stop() { + public synchronized void stop() { if (DBG) { Log.d(TAG, "stop()"); } @@ -368,11 +350,10 @@ public class MapClientService extends ProfileService { mHandler.removeCallbacksAndMessages(null); mHandler = null; } - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "in Cleanup"); } @@ -390,10 +371,7 @@ public class MapClientService extends ProfileService { @VisibleForTesting public void cleanupDevice(BluetoothDevice device, MceStateMachine sm) { if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "Cleanup device: " + device + ", InstanceMap start state: " - + sb.toString()); + Log.d(TAG, "cleanup(device= " + device + "): devices=" + mMapInstanceMap.keySet()); } synchronized (mMapInstanceMap) { MceStateMachine stateMachine = mMapInstanceMap.get(device); @@ -407,20 +385,14 @@ public class MapClientService extends ProfileService { } } if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "Cleanup device: " + device + ", InstanceMap end state: " - + sb.toString()); + Log.d(TAG, "cleanup(device= " + device + "): end devices=" + mMapInstanceMap.keySet()); } } @VisibleForTesting void removeUncleanAccounts() { if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "removeUncleanAccounts:InstanceMap end state: " - + sb.toString()); + Log.d(TAG, "removeUncleanAccounts(): devices=" + mMapInstanceMap.keySet()); } Iterator iterator = mMapInstanceMap.entrySet().iterator(); while (iterator.hasNext()) { @@ -431,10 +403,7 @@ public class MapClientService extends ProfileService { } } if (DBG) { - StringBuilder sb = new StringBuilder(); - dump(sb); - Log.d(TAG, "removeUncleanAccounts:InstanceMap end state: " - + sb.toString()); + Log.d(TAG, "removeUncleanAccounts(): end devices=" + mMapInstanceMap.keySet()); } } @@ -499,8 +468,8 @@ public class MapClientService extends ProfileService { return mService; } if (!Utils.checkServiceAvailable(mService, TAG) - || !(MapUtils.isSystemUser() - || Utils.checkCallerIsSystemOrActiveOrManagedUser(mService, TAG)) + || !(getCallingUserHandle().isSystem() + || Utils.checkCallerIsSystemOrActiveOrManagedUser(mService, TAG)) || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) { return null; } diff --git a/android/app/src/com/android/bluetooth/mapclient/MapUtils.java b/android/app/src/com/android/bluetooth/mapclient/MapUtils.java deleted file mode 100644 index 7696484bb97f30ae3b6689b2773897a942f08101..0000000000000000000000000000000000000000 --- a/android/app/src/com/android/bluetooth/mapclient/MapUtils.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.bluetooth.mapclient; - -import android.os.Binder; -import android.os.SystemProperties; - -import com.android.bluetooth.Utils; -import com.android.internal.annotations.VisibleForTesting; - -class MapUtils { - private static MnsService sMnsService = null; - private static final String FETCH_MESSAGE_TYPE = - "persist.bluetooth.pts.mapclient.fetchmessagetype"; - private static final String SEND_MESSAGE_TYPE = - "persist.bluetooth.pts.mapclient.sendmessagetype"; - - @VisibleForTesting - static void setMnsService(MnsService service) { - sMnsService = service; - } - - static boolean isSystemUser() { - return Binder.getCallingUserHandle().isSystem(); - } - - static MnsService newMnsServiceInstance(MapClientService mapClientService) { - return (sMnsService == null) ? new MnsService(mapClientService) : sMnsService; - } - static byte fetchMessageType() { - if (Utils.isPtsTestMode()) { - return (byte) SystemProperties.getInt(FETCH_MESSAGE_TYPE, - MessagesFilter.MESSAGE_TYPE_ALL); - } else { - return MessagesFilter.MESSAGE_TYPE_ALL; - } - } - - static Bmessage.Type sendMessageType() { - if (Utils.isPtsTestMode()) { - int messageType = SystemProperties.getInt(SEND_MESSAGE_TYPE, -1); - if (messageType > 0 && messageType < Bmessage.Type.values().length) { - return Bmessage.Type.values()[messageType]; - } - } - return Bmessage.Type.MMS; - } -} diff --git a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java index 189dd8962fcf96ded04d4172fa8da27fe64db34d..f1a4844e0f8b79f4fb71233623915474a2987922 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +++ b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java @@ -66,6 +66,7 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.map.BluetoothMapbMessageMime; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.State; @@ -140,6 +141,11 @@ class MceStateMachine extends StateMachine { // URI Scheme for messages with email contact private static final String SCHEME_MAILTO = "mailto"; + private static final String FETCH_MESSAGE_TYPE = + "persist.bluetooth.pts.mapclient.fetchmessagetype"; + private static final String SEND_MESSAGE_TYPE = + "persist.bluetooth.pts.mapclient.sendmessagetype"; + // Connectivity States private int mPreviousState = BluetoothProfile.STATE_DISCONNECTED; private int mMostRecentState = BluetoothProfile.STATE_DISCONNECTED; @@ -492,7 +498,10 @@ class MceStateMachine extends StateMachine { Bmessage.Type getDefaultMessageType() { synchronized (mDefaultMessageType) { if (Utils.isPtsTestMode()) { - return MapUtils.sendMessageType(); + int messageType = SystemProperties.getInt(SEND_MESSAGE_TYPE, -1); + if (messageType > 0 && messageType < Bmessage.Type.values().length) { + return Bmessage.Type.values()[messageType]; + } } return mDefaultMessageType; } @@ -717,13 +726,30 @@ class MceStateMachine extends StateMachine { case MSG_GET_MESSAGE_LISTING: // Get latest 50 Unread messages in the last week - MessagesFilter filter = new MessagesFilter(); - filter.setMessageType(MapUtils.fetchMessageType()); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, -7); - filter.setPeriod(calendar.getTime(), null); - mMasClient.makeRequest(new RequestGetMessagesListing( - (String) message.obj, 0, filter, 0, 50, 0)); + byte messageType; + if (Utils.isPtsTestMode()) { + messageType = + (byte) + SystemProperties.getInt( + FETCH_MESSAGE_TYPE, + MessagesFilter.MESSAGE_TYPE_ALL); + } else { + messageType = MessagesFilter.MESSAGE_TYPE_ALL; + } + + mMasClient.makeRequest( + new RequestGetMessagesListing( + (String) message.obj, + 0, + new MessagesFilter.Builder() + .setPeriod(calendar.getTime(), null) + .setMessageType(messageType) + .build(), + 0, + 50, + 0)); break; case MSG_SET_MESSAGE_STATUS: @@ -838,7 +864,15 @@ class MceStateMachine extends StateMachine { mMasClient.makeRequest(new RequestGetMessage(event.getHandle(), MasClient.CharsetType.UTF_8, false)); break; + case DELIVERY_FAILURE: + // fall through + case SENDING_FAILURE: + if (!Flags.handleDeliverySendingFailureEvents()) { + break; + } + // fall through case DELIVERY_SUCCESS: + // fall through case SENDING_SUCCESS: notifySentMessageStatus(event.getHandle(), event.getType()); break; @@ -848,6 +882,10 @@ class MceStateMachine extends StateMachine { case MESSAGE_DELETED: mDatabase.deleteMessage(event.getHandle()); break; + default: + if (DBG) { + Log.d(TAG, "processNotification: ignoring event type=" + event.getType()); + } } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java b/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java index 6442e9fe4695ae3c73cb2f833b18d8e1acd0e967..0c5ef677088bf17e82318c59ca8f4b6465e7f79e 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/BmessageParser.java @@ -293,8 +293,10 @@ class BmessageParser { * 2020-06-01: we could now expect MMS to be more than text, e.g., image-only, so charset * not always UTF-8, downgrading log message from ERROR to DEBUG. */ - if (DBG && !"UTF-8".equals(mBmsg.mBbodyCharset)) { - Log.d(TAG, "The charset was not set to charset UTF-8: " + mBmsg.mBbodyCharset); + if (!"UTF-8".equals(mBmsg.mBbodyCharset)) { + if (DBG) { + Log.d(TAG, "The charset was not set to charset UTF-8: " + mBmsg.mBbodyCharset); + } } /* diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java b/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java index c2a7f78b2b4be6b271a21c1815ef752568e5bbe4..918b0a98fe836444fb0801fed95816f198c91eca 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/MessagesFilter.java @@ -41,6 +41,16 @@ public final class MessagesFilter { public MessagesFilter() { } + public MessagesFilter(MessagesFilter filter) { + this.messageType = filter.messageType; + this.periodBegin = filter.periodBegin; + this.periodEnd = filter.periodEnd; + this.readStatus = filter.readStatus; + this.recipient = filter.recipient; + this.originator = filter.originator; + this.priority = filter.priority; + } + public void setMessageType(byte filter) { messageType = filter; } @@ -78,4 +88,87 @@ public final class MessagesFilter { public void setPriority(byte filter) { priority = filter; } + + /** Builder for a {@link MessagesFilter}. */ + public static class Builder { + private MessagesFilter mMessagesFilter = new MessagesFilter(); + + /** + * Sets the `Message Type` field of the filter. + * + * @param messageType to filter on. + * @return This {@link Builder} object. + */ + public Builder setMessageType(byte messageType) { + mMessagesFilter.setMessageType(messageType); + return this; + } + + /** + * Sets the `Originator` field of the filter. + * + * @param originator to filter on. + * @return This {@link Builder} object. + */ + public Builder setOriginator(String originator) { + mMessagesFilter.setOriginator(originator); + return this; + } + + /** + * Sets the `Period` field of the filter. + * + * @param filterBegin filter out messages that arrive before this time instance. Can be + * {@code null}, in which case no limit on how old a message can be. + * @param filterEnd filter out messages that arrive after this time instance. Can be {@code + * null}, in which case no limit on how new a message can be. + * @return This {@link Builder} object. + */ + public Builder setPeriod(Date filterBegin, Date filterEnd) { + mMessagesFilter.setPeriod(filterBegin, filterEnd); + return this; + } + + /** + * Sets the `Priority` field of the filter. + * + * @param priority to filter on. + * @return This {@link Builder} object. + */ + public Builder setPriority(byte priority) { + mMessagesFilter.setPriority(priority); + return this; + } + + /** + * Sets the `Read Status` field of the filter. + * + * @param status to filter on. + * @return This {@link Builder} object. + */ + public Builder setReadStatus(byte status) { + mMessagesFilter.setReadStatus(status); + return this; + } + + /** + * Sets the `Recipient` field of the filter. + * + * @param recipient to filter on. + * @return This {@link Builder} object. + */ + public Builder setRecipient(String recipient) { + mMessagesFilter.setRecipient(recipient); + return this; + } + + /** + * Build the {@link MessagesFilter}. + * + * @return A {@link MessagesFilter} object. + */ + public MessagesFilter build() { + return new MessagesFilter(mMessagesFilter); + } + } } diff --git a/android/app/src/com/android/bluetooth/mcp/McpService.java b/android/app/src/com/android/bluetooth/mcp/McpService.java index f26793906342bbe3c2640929b5d6067b1745dc38..dd56a341217e0c9a7b7462a5d5b0cabc1014ec8e 100644 --- a/android/app/src/com/android/bluetooth/mcp/McpService.java +++ b/android/app/src/com/android/bluetooth/mcp/McpService.java @@ -57,10 +57,7 @@ public class McpService extends ProfileService { private Map mDeviceAuthorizations = new HashMap<>(); private Handler mHandler = new Handler(Looper.getMainLooper()); - McpService() {} - - @VisibleForTesting - McpService(Context ctx) { + public McpService(Context ctx) { super(ctx); } @@ -104,7 +101,7 @@ public class McpService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -133,19 +130,17 @@ public class McpService extends ProfileService { }); } } - - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sMcpService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } synchronized (mLock) { @@ -163,11 +158,10 @@ public class McpService extends ProfileService { // Mark service as stopped setMcpService(null); - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } @@ -206,6 +200,17 @@ public class McpService extends ProfileService { setDeviceAuthorized(device, false); } + /** + * Remove authorization information for the device. + * + * @param device device to remove from the service information + * @hide + */ + public void removeDeviceAuthorizationInfo(BluetoothDevice device) { + Log.i(TAG, "removeDeviceAuthorizationInfo(): device: " + device); + mDeviceAuthorizations.remove(device); + } + public void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized) { Log.i(TAG, "\tsetDeviceAuthorized(): device: " + device + ", isAuthorized: " + isAuthorized); diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java index 9fc5caa985b437cf10167ac3c173ff66d0925ad4..36c46bc9213baaf1688f5a458c5ce81918ef7fa1 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java @@ -2,7 +2,7 @@ * 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"); + * Licensed under the Apache License,mu Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -47,6 +47,7 @@ import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.le_audio.LeAudioService; import com.android.internal.annotations.VisibleForTesting; @@ -129,6 +130,17 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private static final int INTERVAL_UNAVAILABLE = 0xFFFFFFFF; + /* This is to match AVRCP behavior */ + @VisibleForTesting + static final int INITIAL_SUPPORTED_OPCODES = + Request.SupportedOpcodes.PLAY + | Request.SupportedOpcodes.STOP + | Request.SupportedOpcodes.PAUSE + | Request.SupportedOpcodes.FAST_REWIND + | Request.SupportedOpcodes.FAST_FORWARD + | Request.SupportedOpcodes.NEXT_TRACK + | Request.SupportedOpcodes.PREVIOUS_TRACK; + private final int mCcid; private Map> mCccDescriptorValues = new HashMap<>(); private long mFeatures; @@ -596,7 +608,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface ? op.mDescriptor.getCharacteristic().getUuid() : null)); mEventLogger.logd( - DBG, TAG, "onAuthorizedGattOperation: device= " + device @@ -788,7 +799,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface for (BluetoothDevice device : mAdapterService.getBondedDevices()) { List uuidList = mMcpService.getNotificationSubscriptions(mCcid, device); mEventLogger.logd( - DBG, TAG, "restoreCccValuesForStoredDevices: device= " + device @@ -798,7 +808,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface /* Restore CCCD values for device */ for (ParcelUuid uuid : uuidList) { mEventLogger.logd( - DBG, TAG, "restoreCccValuesForStoredDevices: device= " + device + ", char= " + uuid); setCcc(device, uuid.getUuid(), 0, @@ -1014,7 +1023,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private void setInitialCharacteristicValues(boolean notify) { - mEventLogger.logd(DBG, TAG, "setInitialCharacteristicValues"); + mEventLogger.logd(TAG, "setInitialCharacteristicValues"); updateMediaStateChar(mCurrentMediaState.getValue()); updatePlayerNameChar("", notify); updatePlayerIconUrlChar(""); @@ -1034,7 +1043,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface updateSeekingSpeedChar(1, notify); updatePlayingOrderSupportedChar(SupportedPlayingOrder.SINGLE_ONCE); updatePlayingOrderChar(PlayingOrder.SINGLE_ONCE, notify); - updateSupportedOpcodesChar(Request.SupportedOpcodes.NONE, notify); + updateSupportedOpcodesChar(INITIAL_SUPPORTED_OPCODES, notify); } private void setInitialCharacteristicValues() { @@ -1204,24 +1213,25 @@ public class MediaControlGattService implements MediaControlGattServiceInterface Request req = new Request(opcode, intVal); mEventLogger.logd( - DBG, TAG, "handleMediaControlPointRequest: sending " + Request.Opcodes.toString(opcode) + " request up"); // TODO: Activate/deactivate devices with ActiveDeviceManager - if (req.getOpcode() == Request.Opcodes.PLAY) { + if (mLeAudioService == null) { + mLeAudioService = LeAudioService.getLeAudioService(); + } + if (!isBroadcastActive() && req.getOpcode() == Request.Opcodes.PLAY) { if (mAdapterService.getActiveDevices(BluetoothProfile.A2DP).size() > 0) { A2dpService.getA2dpService().removeActiveDevice(false); } if (mAdapterService.getActiveDevices(BluetoothProfile.HEARING_AID).size() > 0) { HearingAidService.getHearingAidService().removeActiveDevice(false); } - if (mLeAudioService == null) { - mLeAudioService = LeAudioService.getLeAudioService(); + if (mLeAudioService != null) { + mLeAudioService.setActiveDevice(device); } - mLeAudioService.setActiveDevice(device); } mCallbacks.onMediaControlRequest(req); @@ -1248,7 +1258,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private boolean initGattService(UUID serviceUuid) { - mEventLogger.logd(DBG, TAG, "initGattService: uuid= " + serviceUuid); + mEventLogger.logd(TAG, "initGattService: uuid= " + serviceUuid); if (mBluetoothGattServer == null) { BluetoothManager manager = mContext.getSystemService(BluetoothManager.class); @@ -1320,10 +1330,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } if (Arrays.equals(value, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) { - mEventLogger.logd(DBG, TAG, "setCcc: device= " + device + ", notify: " + true); + mEventLogger.logd(TAG, "setCcc: device= " + device + ", notify: " + true); mMcpService.setNotificationSubscription(mCcid, device, new ParcelUuid(charUuid), true); } else if (Arrays.equals(value, BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)) { - mEventLogger.logd(DBG, TAG, "setCcc: device= " + device + ", notify: " + false); + mEventLogger.logd(TAG, "setCcc: device= " + device + ", notify: " + false); mMcpService.setNotificationSubscription(mCcid, device, new ParcelUuid(charUuid), false); } else { mEventLogger.loge(TAG, "Not handled CCC value: " + Arrays.toString(value)); @@ -1377,7 +1387,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (!isFeatureSupported(ServiceFeature.MEDIA_STATE)) return; - mEventLogger.logd(DBG, TAG, "updateMediaStateChar: state= " + MediaState.toString(state)); + mEventLogger.logd(TAG, "updateMediaStateChar: state= " + MediaState.toString(state)); BluetoothGattCharacteristic stateChar = mCharacteristics.get(CharId.MEDIA_STATE); @@ -1394,7 +1404,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (!isFeatureSupported(feature)) return; mEventLogger.logd( - DBG, TAG, "updateObjectIdChar: charId= " + CharId.FromFeature(feature) @@ -1611,7 +1620,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface public void onDeviceAuthorizationSet(BluetoothDevice device) { int auth = getDeviceAuthorization(device); mEventLogger.logd( - DBG, TAG, "onDeviceAuthorizationSet: device= " + device @@ -1670,7 +1678,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (notify && isFeatureSupported(ServiceFeature.PLAYING_ORDER_NOTIFY)) { notifyCharacteristic(orderChar, null); } - mEventLogger.logd(DBG, TAG, "updatePlayingOrderChar: order= " + order); + mEventLogger.logd(TAG, "updatePlayingOrderChar: order= " + order); } } @@ -1760,7 +1768,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface notifyCharacteristic(characteristic, null); } mEventLogger.logd( - DBG, TAG, "updateSeekingSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); } @@ -1801,7 +1808,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface notifyCharacteristic(characteristic, null); } mEventLogger.logd( - DBG, TAG, "updatePlaybackSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); } @@ -1833,7 +1839,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } } mEventLogger.logd( - DBG, TAG, "updateTrackPositionChar: positionMs= " + positionMs + ", position= " + position); } @@ -1869,7 +1874,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface notifyCharacteristic(characteristic, null); } mEventLogger.logd( - DBG, TAG, "updateTrackDurationChar: durationMs= " + durationMs @@ -1902,7 +1906,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (notify && isFeatureSupported(ServiceFeature.TRACK_TITLE_NOTIFY)) { notifyCharacteristic(characteristic, null); } - mEventLogger.logd(DBG, TAG, "updateTrackTitleChar: title= '" + title + "'"); + mEventLogger.logd(TAG, "updateTrackTitleChar: title= '" + title + "'"); } } @@ -1931,7 +1935,6 @@ public class MediaControlGattService implements MediaControlGattServiceInterface notifyCharacteristic(characteristic, null); } mEventLogger.logd( - DBG, TAG, "updateSupportedOpcodesChar: opcodes= " + Request.SupportedOpcodes.toString(opcodes)); @@ -1945,15 +1948,13 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (isFeatureSupported(ServiceFeature.PLAYING_ORDER_SUPPORTED)) { mCharacteristics.get(CharId.PLAYING_ORDER_SUPPORTED) .setValue(supportedOrder, BluetoothGattCharacteristic.FORMAT_UINT16, 0); - mEventLogger.logd( - DBG, TAG, "updatePlayingOrderSupportedChar: order= " + supportedOrder); + mEventLogger.logd(TAG, "updatePlayingOrderSupportedChar: order= " + supportedOrder); } } private void updateIconObjIdChar(Long objId) { if (isFeatureSupported(ServiceFeature.PLAYER_ICON_OBJ_ID)) { mEventLogger.logd( - DBG, TAG, "updateObjectIdChar charId= " + CharId.PLAYER_ICON_OBJ_ID @@ -2003,7 +2004,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } if (isFeatureSupported(ServiceFeature.PLAYER_ICON_URL)) { mCharacteristics.get(CharId.PLAYER_ICON_URL).setValue(url); - mEventLogger.logd(DBG, TAG, "updatePlayerIconUrlChar: " + url); + mEventLogger.logd(TAG, "updatePlayerIconUrlChar: " + url); } } @@ -2028,7 +2029,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.PLAYER_NAME); characteristic.setValue(name); - mEventLogger.logd(DBG, TAG, "updatePlayerNameChar: name= '" + name + "'"); + mEventLogger.logd(TAG, "updatePlayerNameChar: name= '" + name + "'"); if (notify && isFeatureSupported(ServiceFeature.PLAYER_NAME_NOTIFY)) { notifyCharacteristic(characteristic, null); } @@ -2042,6 +2043,20 @@ public class MediaControlGattService implements MediaControlGattServiceInterface return (mFeatures & featureBit) != 0; } + /** + * Checks if le audio broadcasting is ON + * + * @return {@code true} if is broadcasting audio, {@code false} otherwise + */ + private boolean isBroadcastActive() { + if (!Flags.leaudioBroadcastFeatureSupport()) { + // disable this if feature flag is false + return false; + } + + return mLeAudioService != null && mLeAudioService.isBroadcastActive(); + } + @VisibleForTesting boolean isOpcodeSupported(int opcode) { if (opcode < Request.Opcodes.PLAY || opcode > Request.Opcodes.GOTO_GROUP) { diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java index c88b72c37a510c3415bdc1db53faa3c195e6fa27..6c7219eff6136b13fa0c04c4a52880ec69b36159 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java @@ -114,7 +114,6 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { if (metadata || state || queue) { mEventLogger.logd( - DBG, TAG, "onMediaUpdated: track_changed=" + metadata @@ -134,7 +133,6 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { @Override public void run(boolean availablePlayers, boolean addressedPlayers, boolean uids) { mEventLogger.logd( - DBG, TAG, "onFolderUpdated: available_players= " + availablePlayers @@ -200,7 +198,6 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { } mEventLogger.logd( - DBG, TAG, "onCurrentPlayerStateUpdated state= " + playback_state @@ -220,7 +217,6 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { if (metadataChanged) { if (mCurrentData.metadata != null) { mEventLogger.logd( - DBG, TAG, "onCurrentPlayerStateUpdated metadata: title= '" + mCurrentData.metadata.title @@ -288,13 +284,13 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { @Override public void onServiceInstanceRegistered(ServiceStatus status, MediaControlGattServiceInterface service) { - mEventLogger.logd(DBG, TAG, "onServiceInstanceRegistered: status= " + status); + mEventLogger.logd(TAG, "onServiceInstanceRegistered: status= " + status); mGMcsService = service; } @Override public void onServiceInstanceUnregistered(ServiceStatus status) { - mEventLogger.logd(DBG, TAG, "onServiceInstanceUnregistered: status= " + status); + mEventLogger.logd(TAG, "onServiceInstanceUnregistered: status= " + status); mGMcsService = null; } @@ -345,13 +341,13 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { @Override public long onGetCurrentTrackPosition() { - mEventLogger.logd(DBG, TAG, "getCurrentTrackPosition"); + mEventLogger.logd(TAG, "getCurrentTrackPosition"); return getLatestTrackPosition(); } @Override public void onTrackPositionSetRequest(long position) { - mEventLogger.logd(DBG, TAG, "GMCS onTrackPositionSetRequest"); + mEventLogger.logd(TAG, "GMCS onTrackPositionSetRequest"); if (mMediaPlayerList.getActivePlayer() == null) return; if ((getCurrentPlayerSupportedActions() & PlaybackState.ACTION_SEEK_TO) != 0) { @@ -369,40 +365,39 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { @Override public void onCurrentTrackMetadataRequest() { - mEventLogger.logd(DBG, TAG, "GMCS onCurrentTrackMetadataRequest"); + mEventLogger.logd(TAG, "GMCS onCurrentTrackMetadataRequest"); // FIXME: Seems to be not used right now } @Override public void onPlayingOrderSetRequest(int order) { - mEventLogger.logd(DBG, TAG, "GMCS onPlayingOrderSetRequest"); + mEventLogger.logd(TAG, "GMCS onPlayingOrderSetRequest"); // Notice: MediaPlayerWrapper does not support play order control. // Ignore the request for now. } @Override public void onPlaybackSpeedSetRequest(float speed) { - mEventLogger.logd(DBG, TAG, "GMCS onPlaybackSpeedSetRequest"); + mEventLogger.logd(TAG, "GMCS onPlaybackSpeedSetRequest"); if (mMediaPlayerList.getActivePlayer() == null) return; mMediaPlayerList.getActivePlayer().setPlaybackSpeed(speed); } @Override public void onSetObjectIdRequest(int objField, long objectId) { - mEventLogger.logd(DBG, TAG, "GMCS onSetObjectIdRequest"); + mEventLogger.logd(TAG, "GMCS onSetObjectIdRequest"); // TODO: Implement once we have the Object Transfer Service } @Override public void onSearchRequest(SearchRequest request) { - mEventLogger.logd(DBG, TAG, "GMCS onSearchRequest"); + mEventLogger.logd(TAG, "GMCS onSearchRequest"); // TODO: Implement once we have the Object Transfer Service } @Override public void onMediaControlRequest(Request request) { mEventLogger.logd( - DBG, TAG, "GMCS onMediaControlRequest: opcode= " + Request.Opcodes.toString(request.getOpcode())); @@ -655,7 +650,6 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { getCurrentPlayerSupportedActions()); handled_request_map.put(settings_field, opcodes); mEventLogger.logd( - DBG, TAG, "updateSupportedOpcodes setting supported opcodes to: " + opcodes); @@ -763,7 +757,6 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { boolean isGenericMcs = appToken.equals(mContext.getPackageName()); mEventLogger.logd( - DBG, TAG, "Register MediaControlGattService instance ccid= " + ccid @@ -839,7 +832,7 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { private final Map mServiceMap; public void unregisterServiceInstance(String appToken) { - mEventLogger.logd(DBG, TAG, "unregisterServiceInstance"); + mEventLogger.logd(TAG, "unregisterServiceInstance"); synchronized (mServiceMap) { MediaControlGattServiceInterface service = mServiceMap.get(appToken); diff --git a/android/app/src/com/android/bluetooth/airplane/NotificationHelperService.java b/android/app/src/com/android/bluetooth/notification/NotificationHelperService.java similarity index 52% rename from android/app/src/com/android/bluetooth/airplane/NotificationHelperService.java rename to android/app/src/com/android/bluetooth/notification/NotificationHelperService.java index b8c2d07a45ed445f54b64963b5795e93fdb1f3e6..07bb45e94dd6acc5262af56779bf6edb82c92259 100644 --- a/android/app/src/com/android/bluetooth/airplane/NotificationHelperService.java +++ b/android/app/src/com/android/bluetooth/notification/NotificationHelperService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.airplane; +package com.android.bluetooth.notification; import static java.util.Objects.requireNonNull; @@ -23,7 +23,9 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; +import android.bluetooth.BluetoothManager; import android.content.Intent; +import android.graphics.drawable.Icon; import android.net.Uri; import android.os.IBinder; import android.provider.Settings; @@ -45,10 +47,22 @@ public class NotificationHelperService extends Service { private static final String APM_BT_NOTIFICATION = "apm_bt_notification"; // Keeps track of whether user enabling bt notification was shown private static final String APM_BT_ENABLED_NOTIFICATION = "apm_bt_enabled_notification"; + // Keeps track of whether auto on enabling bt notification was shown + private static final String AUTO_ON_BT_ENABLED_NOTIFICATION = "auto_on_bt_enabled_notification"; private static final String NOTIFICATION_TAG = "com.android.bluetooth"; - private static final String APM_NOTIFICATION_CHANNEL = "apm_notification_channel"; - private static final String APM_NOTIFICATION_GROUP = "apm_notification_group"; + private static final String NOTIFICATION_CHANNEL = "notification_toggle_channel"; + private static final int NOTIFICATION_GROUP = R.string.bluetooth_notification_group; + + private static final String NOTIFICATION_ACTION = + "android.bluetooth.notification.action.SEND_TOGGLE_NOTIFICATION"; + private static final String NOTIFICATION_EXTRA = + "android.bluetooth.notification.extra.NOTIFICATION_REASON"; + + private static final String AUTO_ON_USER_ACTION = + "android.bluetooth.notification.action.AUTO_ON_USER_ACTION"; + private static final String AUTO_ON_USER_EXTRA = + "android.bluetooth.notification.extra.AUTO_ON_DISABLE"; private static final Map> NOTIFICATION_MAP = @@ -64,7 +78,11 @@ public class NotificationHelperService extends Service { APM_BT_ENABLED_NOTIFICATION, Pair.create( R.string.bluetooth_enabled_apm_title, - R.string.bluetooth_enabled_apm_message)); + R.string.bluetooth_enabled_apm_message), + AUTO_ON_BT_ENABLED_NOTIFICATION, + Pair.create( + R.string.bluetooth_enabled_auto_on_title, + R.string.bluetooth_enabled_auto_on_message)); @Override public IBinder onBind(Intent intent) { @@ -73,69 +91,103 @@ public class NotificationHelperService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - sendAirplaneModeNotification( - intent.getStringExtra("android.bluetooth.airplane.extra.NOTIFICATION_STATE")); + switch (intent.getAction()) { + case NOTIFICATION_ACTION -> { + sendToggleNotification(intent.getStringExtra(NOTIFICATION_EXTRA)); + } + case AUTO_ON_USER_ACTION -> { + autoOnUserAction(intent.getBooleanExtra(AUTO_ON_USER_EXTRA, false)); + } + } return Service.START_NOT_STICKY; } - private void sendAirplaneModeNotification(String notificationState) { - String logHeader = "sendAirplaneModeNotification(" + notificationState + "): "; - Pair notificationContent = NOTIFICATION_MAP.get(notificationState); + private void sendToggleNotification(String notificationReason) { + String logHeader = "sendToggleNotification(" + notificationReason + "): "; + Pair notificationContent = NOTIFICATION_MAP.get(notificationReason); if (notificationContent == null) { Log.e(TAG, logHeader + "unknown action"); return; } - if (!isFirstTimeNotification(notificationState)) { + if (!isFirstTimeNotification(notificationReason)) { Log.d(TAG, logHeader + "already displayed"); return; } - Settings.Secure.putInt(getContentResolver(), notificationState, 1); + Settings.Secure.putInt(getContentResolver(), notificationReason, 1); Log.d(TAG, logHeader + "sending"); NotificationManager notificationManager = requireNonNull(getSystemService(NotificationManager.class)); + String tag = NOTIFICATION_TAG + "/" + notificationReason; for (StatusBarNotification notification : notificationManager.getActiveNotifications()) { - if (NOTIFICATION_TAG.equals(notification.getTag())) { - notificationManager.cancel(NOTIFICATION_TAG, notification.getId()); + if (tag.equals(notification.getTag())) { + notificationManager.cancel(tag, notification.getId()); } } notificationManager.createNotificationChannel( new NotificationChannel( - APM_NOTIFICATION_CHANNEL, - APM_NOTIFICATION_GROUP, + NOTIFICATION_CHANNEL, + getString(NOTIFICATION_GROUP), NotificationManager.IMPORTANCE_HIGH)); String title = getString(notificationContent.first); String message = getString(notificationContent.second); - String helpLinkUrl = getString(R.string.config_apmLearnMoreLink); - notificationManager.notify( - NOTIFICATION_TAG, - SystemMessage.ID.NOTE_BT_APM_NOTIFICATION_VALUE, - new Notification.Builder(this, APM_NOTIFICATION_CHANNEL) + Notification.Builder builder = + new Notification.Builder(this, NOTIFICATION_CHANNEL) .setAutoCancel(true) .setLocalOnly(true) .setContentTitle(title) .setContentText(message) - .setContentIntent( - PendingIntent.getActivity( - this, - PendingIntent.FLAG_UPDATE_CURRENT, - new Intent(Intent.ACTION_VIEW) - .setData(Uri.parse(helpLinkUrl)) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), - PendingIntent.FLAG_IMMUTABLE)) .setVisibility(Notification.VISIBILITY_PUBLIC) .setStyle(new Notification.BigTextStyle().bigText(message)) - .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth) - .build()); + .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth); + + if (!notificationReason.equals(AUTO_ON_BT_ENABLED_NOTIFICATION)) { + // Do not display airplane link when the notification is due to auto_on feature + String helpLinkUrl = getString(R.string.config_apmLearnMoreLink); + builder.setContentIntent( + PendingIntent.getActivity( + this, + PendingIntent.FLAG_UPDATE_CURRENT, + new Intent(Intent.ACTION_VIEW) + .setData(Uri.parse(helpLinkUrl)) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), + PendingIntent.FLAG_IMMUTABLE)); + } else { + Intent baseIntent = + new Intent() + .setAction(AUTO_ON_USER_ACTION) + .setClass(this, NotificationHelperService.class); + PendingIntent disablePendingIntent = + PendingIntent.getService( + this, + 0, + new Intent(baseIntent).putExtra(AUTO_ON_USER_EXTRA, true), + PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT); + builder.addAction( + new Notification.Action.Builder( + Icon.createWithResource(this, R.drawable.ic_bluetooth_settings), + getString(R.string.bluetooth_disable_auto_on), + disablePendingIntent) + .build()); + } + + notificationManager.notify( + tag, SystemMessage.ID.NOTE_BT_APM_NOTIFICATION_VALUE, builder.build()); } /** Return whether the notification has been shown */ private boolean isFirstTimeNotification(String name) { return Settings.Secure.getInt(getContentResolver(), name, 0) == 0; } + + private void autoOnUserAction(boolean disableAutoOn) { + if (disableAutoOn) { + getSystemService(BluetoothManager.class).getAdapter().setAutoOnEnabled(false); + } + } } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java index 825571b5b78883032c0105a802df4957c899bf65..9860b9281c84dc49d864cc312027a886efbf2d88 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java @@ -35,6 +35,8 @@ package com.android.bluetooth.opp; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import android.bluetooth.AlertActivity; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; @@ -53,12 +55,13 @@ import android.widget.TextView; import android.widget.Toast; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; -/** - * This class is designed to ask user to confirm if accept incoming file; - */ +/** This class is designed to ask user to confirm if accept incoming file; */ +// Next tag value for ContentProfileErrorReportUtils.report(): 1 public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { private static final String TAG = "BluetoothIncomingFileConfirmActivity"; private static final boolean D = Constants.DEBUG; @@ -99,6 +102,11 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity { if (V) { Log.e(TAG, "Error: Can not get data from db"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_INCOMING_FILE_CONFIRM_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); finish(); return; } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java index 301b39f568bfcac281e4917d70a6dc7a7846eae4..8ac766083f2653d85f9619b02800b8a89aaf7d38 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java @@ -36,6 +36,8 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import android.app.Activity; import android.bluetooth.BluetoothDevicePicker; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -47,8 +49,10 @@ import android.util.Patterns; import android.widget.Toast; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import java.io.File; @@ -61,10 +65,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * This class is designed to act as the entry point of handling the share intent - * via BT from other APPs. and also make "Bluetooth" available in sharing method - * selection dialog. + * This class is designed to act as the entry point of handling the share intent via BT from other + * APPs. and also make "Bluetooth" available in sharing method selection dialog. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 11 public class BluetoothOppLauncherActivity extends Activity { private static final String TAG = "BluetoothOppLauncherActivity"; private static final boolean D = Constants.DEBUG; @@ -83,6 +87,11 @@ public class BluetoothOppLauncherActivity extends Activity { String action = intent.getAction(); if (action == null) { Log.w(TAG, " Received " + intent + " with null action"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); finish(); return; } @@ -150,11 +159,23 @@ public class BluetoothOppLauncherActivity extends Activity { return; } else { Log.w(TAG, "Error trying to do set text...File not created!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); finish(); return; } } else { Log.e(TAG, "type is null; or sending file URI is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); finish(); return; } @@ -166,27 +187,46 @@ public class BluetoothOppLauncherActivity extends Activity { Log.v(TAG, "Get ACTION_SHARE_MULTIPLE intent: uris " + uris + "\n Type= " + mimeType); } - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this) - .saveSendingFileInfo(mimeType, uris, false /* isHandover */, - true /* fromExternal */); - //Done getting file info..Launch device picker - //and finish this activity - launchDevicePicker(); - finish(); - } catch (IllegalArgumentException exception) { - showToast(exception.getMessage()); - finish(); - } - } - }); + Thread t = + new Thread( + new Runnable() { + @Override + public void run() { + try { + BluetoothOppManager.getInstance( + BluetoothOppLauncherActivity.this) + .saveSendingFileInfo( + mimeType, + uris, + false /* isHandover */, + true /* fromExternal */); + // Done getting file info..Launch device picker + // and finish this activity + launchDevicePicker(); + finish(); + } catch (IllegalArgumentException exception) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums + .BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); + showToast(exception.getMessage()); + finish(); + } + } + }); t.start(); return; } else { Log.e(TAG, "type is null; or sending files URIs are null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 4); finish(); return; } @@ -203,6 +243,11 @@ public class BluetoothOppLauncherActivity extends Activity { finish(); } else { Log.w(TAG, "Unsupported action: " + action); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); // To prevent activity to finish immediately in testing mode if (!Utils.isInstrumentationTestMode()) { finish(); @@ -355,11 +400,26 @@ public class BluetoothOppLauncherActivity extends Activity { } } } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); Log.e(TAG, "FileNotFoundException: " + e.toString()); e.printStackTrace(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.e(TAG, "IOException: " + e.toString()); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); Log.e(TAG, "Exception: " + e.toString()); } finally { try { @@ -367,6 +427,11 @@ public class BluetoothOppLauncherActivity extends Activity { outStream.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); e.printStackTrace(); } } @@ -422,6 +487,11 @@ public class BluetoothOppLauncherActivity extends Activity { launchDevicePicker(); finish(); } catch (IllegalArgumentException exception) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_LAUNCHER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); showToast(exception.getMessage()); finish(); } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java index 5e57c4f0cfbcf15982e604b25cfa66a7b21d841c..e7180c572342b1993fc39cb9c1c5e0c3597e9de1 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java @@ -34,6 +34,8 @@ package com.android.bluetooth.opp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; @@ -47,7 +49,9 @@ import android.util.Log; import android.util.Pair; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; @@ -55,10 +59,11 @@ import java.util.Iterator; import java.util.List; /** - * This class provides a simplified interface on top of other Bluetooth service - * layer components; Also it handles some Opp application level variables. It's - * a singleton got from BluetoothOppManager.getInstance(context); + * This class provides a simplified interface on top of other Bluetooth service layer components; + * Also it handles some Opp application level variables. It's a singleton got from + * BluetoothOppManager.getInstance(context); */ +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class BluetoothOppManager { private static final String TAG = "BluetoothOppManager"; private static final boolean V = Constants.VERBOSE; @@ -384,6 +389,11 @@ public class BluetoothOppManager { synchronized (BluetoothOppManager.this) { if (mInsertShareThreadNum > ALLOWED_INSERT_SHARE_THREAD_NUMBER) { Log.e(TAG, "Too many shares user triggered concurrently!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); // Notice user Intent in = new Intent(mContext, BluetoothOppBtErrorActivity.class); @@ -454,6 +464,11 @@ public class BluetoothOppManager { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); if (mRemoteDevice == null) { Log.e(TAG, "Target bt device is null!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); return; } if (mIsMultiple) { diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java index 6be378375fe36aec54b5ee252ae27bda4fca1926..895437fc8d278afefe1172363dae12c726e82575 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java @@ -51,6 +51,7 @@ import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.R; import com.android.bluetooth.Utils; +import com.android.bluetooth.flags.Flags; import com.google.common.annotations.VisibleForTesting; @@ -87,15 +88,25 @@ class BluetoothOppNotification { BluetoothShare.STATUS + " >= '200' AND " + VISIBLE + " AND " + NOT_THROUGH_HANDOVER; // Don't show handover-initiated transfers - private static final String WHERE_COMPLETED_OUTBOUND = - WHERE_COMPLETED + " AND " + "(" + BluetoothShare.DIRECTION + " == " - + BluetoothShare.DIRECTION_OUTBOUND + ")"; - - private static final String WHERE_COMPLETED_INBOUND = - WHERE_COMPLETED + " AND " + "(" + BluetoothShare.DIRECTION + " == " - + BluetoothShare.DIRECTION_INBOUND + ")"; - - static final String WHERE_CONFIRM_PENDING = + static final String WHERE_COMPLETED_OUTBOUND = + WHERE_COMPLETED + + " AND " + + "(" + + BluetoothShare.DIRECTION + + " == " + + BluetoothShare.DIRECTION_OUTBOUND + + ")"; + + static final String WHERE_COMPLETED_INBOUND = + WHERE_COMPLETED + + " AND " + + "(" + + BluetoothShare.DIRECTION + + " == " + + BluetoothShare.DIRECTION_INBOUND + + ")"; + + private static final String WHERE_CONFIRM_PENDING = BluetoothShare.USER_CONFIRMATION + " == '" + BluetoothShare.USER_CONFIRMATION_PENDING + "'" + " AND " + VISIBLE; @@ -120,6 +131,15 @@ class BluetoothOppNotification { @VisibleForTesting static final int NOTIFICATION_ID_INBOUND_COMPLETE = -1000006; + static final int NOTIFICATION_ID_COMPLETE_SUMMARY = -1000007; + + private static final String NOTIFICATION_GROUP_KEY_PROGRESS = "PROGRESS"; + + private static final String NOTIFICATION_GROUP_KEY_TRANSFER_COMPLETE = "TRANSFER_COMPLETE"; + + private static final String NOTIFICATION_GROUP_KEY_INCOMING_FILE_CONFIRM = + "INCOMING_FILE_CONFIRM"; + private boolean mUpdateCompleteNotification = true; private ContentResolver mContentResolver = null; @@ -397,6 +417,9 @@ class BluetoothOppNotification { intent.setDataAndNormalize(Uri.parse(BluetoothShare.CONTENT_URI + "/" + item.id)); b.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE)); + if (Flags.oppFixMultipleNotificationsIssues()) { + b.setGroup(NOTIFICATION_GROUP_KEY_PROGRESS); + } mNotificationMgr.notify(NOTIFICATION_ID_PROGRESS, b.build()); } } @@ -445,11 +468,28 @@ class BluetoothOppNotification { if (outboundNum > 0) { String caption = BluetoothOppUtility.formatResultText(outboundSuccNumber, outboundFailNumber, mContext); - Intent contentIntent = new Intent(Constants.ACTION_OPEN_OUTBOUND_TRANSFER).setClassName( - mContext, BluetoothOppReceiver.class.getName()); - Intent deleteIntent = new Intent(Constants.ACTION_COMPLETE_HIDE).setClassName( - mContext, BluetoothOppReceiver.class.getName()); - Notification outNoti = + + PendingIntent pi; + if (Flags.oppStartActivityDirectlyFromNotification()) { + Intent in = new Intent(Constants.ACTION_OPEN_OUTBOUND_TRANSFER); + in.setClass(mContext, BluetoothOppTransferHistory.class); + in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + pi = PendingIntent.getActivity(mContext, 0, in, PendingIntent.FLAG_IMMUTABLE); + } else { + Intent in = + new Intent(Constants.ACTION_OPEN_OUTBOUND_TRANSFER) + .setClassName(mContext, BluetoothOppReceiver.class.getName()); + pi = PendingIntent.getBroadcast(mContext, 0, in, PendingIntent.FLAG_IMMUTABLE); + } + + Intent deleteIntent = new Intent(mContext, BluetoothOppReceiver.class); + if (Flags.oppFixMultipleNotificationsIssues()) { + deleteIntent.setAction(Constants.ACTION_HIDE_COMPLETED_OUTBOUND_TRANSFER); + } else { + deleteIntent.setAction(Constants.ACTION_COMPLETE_HIDE); + } + + Notification.Builder b = new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( true) .setContentTitle(mContext.getString(R.string.outbound_noti_title)) @@ -460,16 +500,16 @@ class BluetoothOppNotification { android.R.color .system_notification_accent_color, mContext.getTheme())) - .setContentIntent( - PendingIntent.getBroadcast(mContext, 0, contentIntent, - PendingIntent.FLAG_IMMUTABLE)) + .setContentIntent(pi) .setDeleteIntent( PendingIntent.getBroadcast(mContext, 0, deleteIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(timeStamp) - .setLocalOnly(true) - .build(); - mNotificationMgr.notify(NOTIFICATION_ID_OUTBOUND_COMPLETE, outNoti); + .setLocalOnly(true); + if (Flags.oppFixMultipleNotificationsIssues()) { + b.setGroup(NOTIFICATION_GROUP_KEY_TRANSFER_COMPLETE); + } + mNotificationMgr.notify(NOTIFICATION_ID_OUTBOUND_COMPLETE, b.build()); } else { if (mNotificationMgr != null) { mNotificationMgr.cancel(NOTIFICATION_ID_OUTBOUND_COMPLETE); @@ -510,11 +550,28 @@ class BluetoothOppNotification { if (inboundNum > 0) { String caption = BluetoothOppUtility.formatResultText(inboundSuccNumber, inboundFailNumber, mContext); - Intent contentIntent = new Intent(Constants.ACTION_OPEN_INBOUND_TRANSFER).setClassName( - mContext, BluetoothOppReceiver.class.getName()); - Intent deleteIntent = new Intent(Constants.ACTION_COMPLETE_HIDE).setClassName( - mContext, BluetoothOppReceiver.class.getName()); - Notification inNoti = + + PendingIntent pi; + if (Flags.oppStartActivityDirectlyFromNotification()) { + Intent in = new Intent(Constants.ACTION_OPEN_INBOUND_TRANSFER); + in.setClass(mContext, BluetoothOppTransferHistory.class); + in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + pi = PendingIntent.getActivity(mContext, 0, in, PendingIntent.FLAG_IMMUTABLE); + } else { + Intent in = + new Intent(Constants.ACTION_OPEN_INBOUND_TRANSFER) + .setClassName(mContext, BluetoothOppReceiver.class.getName()); + pi = PendingIntent.getBroadcast(mContext, 0, in, PendingIntent.FLAG_IMMUTABLE); + } + + Intent deleteIntent = new Intent(mContext, BluetoothOppReceiver.class); + if (Flags.oppFixMultipleNotificationsIssues()) { + deleteIntent.setAction(Constants.ACTION_HIDE_COMPLETED_INBOUND_TRANSFER); + } else { + deleteIntent.setAction(Constants.ACTION_COMPLETE_HIDE); + } + + Notification.Builder b = new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( true) .setContentTitle(mContext.getString(R.string.inbound_noti_title)) @@ -526,16 +583,16 @@ class BluetoothOppNotification { .system_notification_accent_color, mContext.getTheme())) - .setContentIntent( - PendingIntent.getBroadcast(mContext, 0, contentIntent, - PendingIntent.FLAG_IMMUTABLE)) + .setContentIntent(pi) .setDeleteIntent( PendingIntent.getBroadcast(mContext, 0, deleteIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(timeStamp) - .setLocalOnly(true) - .build(); - mNotificationMgr.notify(NOTIFICATION_ID_INBOUND_COMPLETE, inNoti); + .setLocalOnly(true); + if (Flags.oppFixMultipleNotificationsIssues()) { + b.setGroup(NOTIFICATION_GROUP_KEY_TRANSFER_COMPLETE); + } + mNotificationMgr.notify(NOTIFICATION_ID_INBOUND_COMPLETE, b.build()); } else { if (mNotificationMgr != null) { mNotificationMgr.cancel(NOTIFICATION_ID_INBOUND_COMPLETE); @@ -544,6 +601,24 @@ class BluetoothOppNotification { } } } + + if (Flags.oppFixMultipleNotificationsIssues() && inboundNum > 0 && outboundNum > 0) { + Notification.Builder b = + new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL) + .setGroup(NOTIFICATION_GROUP_KEY_TRANSFER_COMPLETE) + .setGroupSummary(true) + .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN) + .setSmallIcon(R.drawable.ic_bluetooth_file_transfer_notification) + .setColor( + mContext.getResources() + .getColor( + android.R.color + .system_notification_accent_color, + mContext.getTheme())) + .setLocalOnly(true); + + mNotificationMgr.notify(NOTIFICATION_ID_COMPLETE_SUMMARY, b.build()); + } } @VisibleForTesting @@ -577,15 +652,31 @@ class BluetoothOppNotification { PendingIntent.getBroadcast(mContext, 0, new Intent(baseIntent).setAction(Constants.ACTION_ACCEPT), PendingIntent.FLAG_IMMUTABLE)).build(); - Notification public_n = + + PendingIntent contentIntent; + if (Flags.oppStartActivityDirectlyFromNotification()) { + Intent intent = new Intent(mContext, BluetoothOppIncomingFileConfirmActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setDataAndNormalize(contentUri); + contentIntent = + PendingIntent.getActivity( + mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE); + } else { + contentIntent = + PendingIntent.getBroadcast( + mContext, + 0, + new Intent(baseIntent) + .setAction(Constants.ACTION_INCOMING_FILE_CONFIRM), + PendingIntent.FLAG_IMMUTABLE); + } + + Notification.Builder publicNotificationBuilder = new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( true) .setOngoing(true) .setWhen(info.mTimeStamp) - .setContentIntent(PendingIntent.getBroadcast(mContext, 0, - new Intent(baseIntent).setAction( - Constants.ACTION_INCOMING_FILE_CONFIRM), - PendingIntent.FLAG_IMMUTABLE)) + .setContentIntent(contentIntent) .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, new Intent(baseIntent).setAction(Constants.ACTION_HIDE), PendingIntent.FLAG_IMMUTABLE)) @@ -601,18 +692,18 @@ class BluetoothOppNotification { R.string.incoming_file_confirm_Notification_content, info.mDeviceName, fileNameSafe))) .setSubText(Formatter.formatFileSize(mContext, info.mTotalBytes)) - .setSmallIcon(R.drawable.bt_incomming_file_notification) - .setLocalOnly(true) - .build(); - Notification n = + .setSmallIcon(R.drawable.ic_bluetooth_file_transfer_notification) + .setLocalOnly(true); + if (Flags.oppFixMultipleNotificationsIssues()) { + publicNotificationBuilder.setGroup(NOTIFICATION_GROUP_KEY_INCOMING_FILE_CONFIRM); + } + + Notification.Builder builder = new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce( true) .setOngoing(true) .setWhen(info.mTimeStamp) - .setContentIntent(PendingIntent.getBroadcast(mContext, 0, - new Intent(baseIntent).setAction( - Constants.ACTION_INCOMING_FILE_CONFIRM), - PendingIntent.FLAG_IMMUTABLE)) + .setContentIntent(contentIntent) .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, new Intent(baseIntent).setAction(Constants.ACTION_HIDE), PendingIntent.FLAG_IMMUTABLE)) @@ -628,14 +719,16 @@ class BluetoothOppNotification { R.string.incoming_file_confirm_Notification_content, info.mDeviceName, fileNameSafe))) .setSubText(Formatter.formatFileSize(mContext, info.mTotalBytes)) - .setSmallIcon(R.drawable.bt_incomming_file_notification) + .setSmallIcon(R.drawable.ic_bluetooth_file_transfer_notification) .setLocalOnly(true) .setVisibility(Notification.VISIBILITY_PRIVATE) .addAction(actionDecline) .addAction(actionAccept) - .setPublicVersion(public_n) - .build(); - mNotificationMgr.notify(NOTIFICATION_ID_PROGRESS, n); + .setPublicVersion(publicNotificationBuilder.build()); + if (Flags.oppFixMultipleNotificationsIssues()) { + builder.setGroup(NOTIFICATION_GROUP_KEY_INCOMING_FILE_CONFIRM); + } + mNotificationMgr.notify(NOTIFICATION_ID_PROGRESS, builder.build()); } cursor.close(); } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java index cde9148347886cd9b91f44db2d7b15c4de6295d7..1dfc3ad33f2fdb8e245f42e7bb2167f2ef29b9d7 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java @@ -32,6 +32,8 @@ package com.android.bluetooth.opp; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentValues; import android.content.Context; import android.net.Uri; @@ -45,7 +47,9 @@ import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothMetricsProto; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.btservice.MetricsLogger; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.obex.ClientOperation; import com.android.obex.ClientSession; import com.android.obex.HeaderSet; @@ -59,9 +63,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -/** - * This class runs as an OBEX client - */ +/** This class runs as an OBEX client */ +// Next tag value for ContentProfileErrorReportUtils.report(): 17 public class BluetoothOppObexClientSession implements BluetoothOppObexSession { private static final String TAG = "BtOppObexClient"; @@ -188,6 +191,11 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { try { Thread.sleep(100); } catch (InterruptedException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); if (V) { Log.v(TAG, "Client thread was interrupted (1), exiting"); } @@ -209,7 +217,12 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { - + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); } } } @@ -242,6 +255,11 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { Log.d(TAG, "OBEX session disconnected"); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.w(TAG, "OBEX session disconnect error" + e); } try { @@ -255,12 +273,23 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.w(TAG, "OBEX session close error" + e); } if (mTransport1 != null) { try { mTransport1.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); Log.e(TAG, "mTransport.close error"); } @@ -275,6 +304,11 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { mCs = new ClientSession(mTransport1); mConnected = true; } catch (IOException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); Log.e(TAG, "OBEX session create error"); } if (mConnected) { @@ -291,6 +325,12 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } mConnected = true; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); Log.e(TAG, "OBEX session connect error"); } } @@ -308,6 +348,12 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { try { Thread.sleep(50); } catch (InterruptedException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); status = BluetoothShare.STATUS_CANCELED; } } @@ -407,12 +453,24 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } putOperation = (ClientOperation) mCs.put(request); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); status = BluetoothShare.STATUS_OBEX_DATA_ERROR; Constants.updateShareStatus(mContext1, mInfo.mId, status); Log.e(TAG, "Error setting header items for request: " + e); error = true; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); status = BluetoothShare.STATUS_OBEX_DATA_ERROR; Constants.updateShareStatus(mContext1, mInfo.mId, status); @@ -431,6 +489,12 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { outputStream = putOperation.openOutputStream(); inputStream = putOperation.openInputStream(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); status = BluetoothShare.STATUS_OBEX_DATA_ERROR; Constants.updateShareStatus(mContext1, mInfo.mId, status); Log.e(TAG, "Error when openOutputStream"); @@ -566,10 +630,25 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); handleSendException(e.toString()); } catch (NullPointerException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); handleSendException(e.toString()); } catch (IndexOutOfBoundsException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 13); handleSendException(e.toString()); } finally { try { @@ -577,6 +656,12 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { outputStream.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 14); Log.e(TAG, "Error when closing output stream after send"); } @@ -615,6 +700,12 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { putOperation.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 15); Log.e(TAG, "Error when closing stream after send"); // Socket has been closed due to the response timeout in the framework, @@ -649,6 +740,12 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { try { mTransport1.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_CLIENT_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 16); Log.e(TAG, "mTransport.close error"); } Message msg = Message.obtain(mCallbackHandler); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java index eff27c47e6f77dbfc6b28e0b284446ff96d89882..37674ef254024296005219836681fb4792693fcb 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java @@ -32,6 +32,8 @@ package com.android.bluetooth.opp; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentValues; import android.content.Context; import android.content.Intent; @@ -47,8 +49,10 @@ import android.webkit.MimeTypeMap; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothObexTransport; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.MetricsLogger; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.obex.HeaderSet; import com.android.obex.ObexTransport; import com.android.obex.Operation; @@ -64,9 +68,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; -/** - * This class runs as an OBEX server - */ +/** This class runs as an OBEX server */ +// Next tag value for ContentProfileErrorReportUtils.report(): 15 public class BluetoothOppObexServerSession extends ServerRequestHandler implements BluetoothOppObexSession { @@ -143,6 +146,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler } mSession = new ServerSession(mTransport, this, null); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "Create server session error" + e); } } @@ -178,6 +186,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler mSession.close(); mTransport.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "close mTransport error" + e); } } @@ -226,6 +239,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler length = (Long) request.getHeader(HeaderSet.LENGTH); mimeType = (String) request.getHeader(HeaderSet.TYPE); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "onPut: getReceivedHeaders error " + e); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } @@ -234,6 +252,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (D) { Log.w(TAG, "length is 0, reject the transfer"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); return ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED; } @@ -241,6 +264,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (D) { Log.w(TAG, "name is null or empty, reject the transfer"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 4); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } @@ -251,6 +279,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (D) { Log.w(TAG, "There is no file extension or mime type, reject the transfer"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } else { extension = name.substring(dotIndex + 1).toLowerCase(); @@ -266,6 +299,12 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (D) { Log.w(TAG, "Can't get mimetype, reject the transfer"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 6); return ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE; } } @@ -278,6 +317,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler if (D) { Log.w(TAG, "mimeType is null or in unacceptable list, reject the transfer"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 7); return ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE; } @@ -328,6 +372,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler } } } catch (InterruptedException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); if (V) { Log.v(TAG, "Interrupted in onPut blocking"); } @@ -350,6 +399,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler */ if (mInfo.mId != mLocalShareInfoId) { Log.e(TAG, "Unexpected error!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 9); } mAccepted = mInfo.mConfirm; @@ -450,6 +504,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler try { is = op.openInputStream(); } catch (IOException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); Log.e(TAG, "Error when openInputStream"); status = BluetoothShare.STATUS_OBEX_DATA_ERROR; error = true; @@ -473,6 +532,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler os = BluetoothMethodProxy.getInstance().contentResolverOpenOutputStream( mContext.getContentResolver(), fileInfo.mInsertUri); } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); Log.e(TAG, "Error when openOutputStream"); error = true; } @@ -526,6 +590,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler } } } catch (IOException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); Log.e(TAG, "Error when receiving file: " + e1); /* OBEX Abort packet received from remote device */ if ("Abort Received".equals(e1.getMessage())) { @@ -563,6 +632,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler os.flush(); os.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 13); Log.e(TAG, "Error when closing stream after send"); } } @@ -606,6 +680,11 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler objectCount = (Long) request.getHeader(HeaderSet.COUNT); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_OBEX_SERVER_SESSION, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 14); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java index 6505305c1b68077f11c21ca888d8d8408ab2a38d..b6b18410ca9e93dac787c12a529806bc4655ba03 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppProvider.java @@ -32,6 +32,8 @@ package com.android.bluetooth.opp; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentProvider; import android.content.ContentValues; import android.content.Context; @@ -44,14 +46,15 @@ import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; -/** - * This provider allows application to interact with Bluetooth OPP manager - */ - +/** This provider allows application to interact with Bluetooth OPP manager */ +// Next tag value for ContentProfileErrorReportUtils.report(): 5 public final class BluetoothOppProvider extends ContentProvider { private static final String TAG = "BluetoothOppProvider"; @@ -154,6 +157,11 @@ public final class BluetoothOppProvider extends ContentProvider { + BluetoothShare.TIMESTAMP + " INTEGER," + Constants.MEDIA_SCANNED + " INTEGER); "); } catch (SQLException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "createTable: Failed."); throw ex; } @@ -163,6 +171,11 @@ public final class BluetoothOppProvider extends ContentProvider { try { db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE); } catch (SQLException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "dropTable: Failed."); throw ex; } @@ -251,6 +264,11 @@ public final class BluetoothOppProvider extends ContentProvider { db.insert(DB_TABLE, null, values); Log.d(TAG, "One item migrated: " + values); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "Failed to migrate one item: " + e); result = false; } @@ -308,6 +326,11 @@ public final class BluetoothOppProvider extends ContentProvider { if (rowID == -1) { Log.w(TAG, "couldn't insert " + uri + "into btopp database"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); return null; } @@ -390,6 +413,11 @@ public final class BluetoothOppProvider extends ContentProvider { if (ret == null) { Log.w(TAG, "query failed in downloads database"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_PROVIDER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 4); return null; } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java index 4545179872135c8e3afd5af5cd6d116b41f3a0ee..a86cae87f9133e780500055d5687c1d6b76cb3fb 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java @@ -32,6 +32,8 @@ package com.android.bluetooth.opp; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; @@ -42,6 +44,8 @@ import android.provider.MediaStore; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import java.io.UnsupportedEncodingException; import java.text.DateFormat; @@ -49,10 +53,10 @@ import java.text.SimpleDateFormat; import java.util.Calendar; /** - * This class stores information about a single receiving file. It will only be - * used for inbounds share, e.g. receive a file to determine a correct save file - * name + * This class stores information about a single receiving file. It will only be used for inbounds + * share, e.g. receive a file to determine a correct save file name */ +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class BluetoothOppReceiveFileInfo { private static final boolean D = Constants.DEBUG; private static final boolean V = Constants.VERBOSE; @@ -160,6 +164,11 @@ public class BluetoothOppReceiveFileInfo { System.arraycopy(oldfilename, 0, newfilename, 0, OPP_LENGTH_OF_FILE_NAME); filename = new String(newfilename, "UTF-8"); } catch (UnsupportedEncodingException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_RECEIVE_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(Constants.TAG, "Exception: " + e); } if (D) { @@ -188,6 +197,11 @@ public class BluetoothOppReceiveFileInfo { if (D) { Log.e(Constants.TAG, "Error when creating file " + fullfilename); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_RECEIVE_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); return new BluetoothOppReceiveFileInfo(BluetoothShare.STATUS_FILE_ERROR); } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java index 393e789437cd0d2e4231353faaa1fe5d4f655680..889ce809b6aa7eadbb96f9de1dbc6f3700ed59e9 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java @@ -35,6 +35,8 @@ package com.android.bluetooth.opp; import android.app.NotificationManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevicePicker; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; @@ -45,13 +47,17 @@ import android.util.Log; import android.widget.Toast; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; +import com.android.bluetooth.flags.Flags; /** - * Receives and handles: system broadcasts; Intents from other applications; - * Intents from OppService; Intents from modules in Opp application layer. + * Receives and handles: system broadcasts; Intents from other applications; Intents from + * OppService; Intents from modules in Opp application layer. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class BluetoothOppReceiver extends BroadcastReceiver { private static final String TAG = "BluetoothOppReceiver"; private static final boolean D = Constants.DEBUG; @@ -73,7 +79,10 @@ public class BluetoothOppReceiver extends BroadcastReceiver { } if (D) { - Log.d(TAG, "Received BT device selected intent, bt device: " + remoteDevice.getIdentityAddress()); + Log.d( + TAG, + "Received BT device selected intent, bt device: " + + remoteDevice.getIdentityAddress()); } // Insert transfer session record to database @@ -90,7 +99,8 @@ public class BluetoothOppReceiver extends BroadcastReceiver { toastMsg = context.getString(R.string.bt_toast_4, deviceName); } Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show(); - } else if (action.equals(Constants.ACTION_INCOMING_FILE_CONFIRM)) { + } else if (action.equals(Constants.ACTION_INCOMING_FILE_CONFIRM) + && !Flags.oppStartActivityDirectlyFromNotification()) { if (V) { Log.v(TAG, "Receiver ACTION_INCOMING_FILE_CONFIRM"); } @@ -100,7 +110,6 @@ public class BluetoothOppReceiver extends BroadcastReceiver { in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); in.setDataAndNormalize(uri); context.startActivity(in); - } else if (action.equals(Constants.ACTION_DECLINE)) { if (V) { Log.v(TAG, "Receiver ACTION_DECLINE"); @@ -138,6 +147,11 @@ public class BluetoothOppReceiver extends BroadcastReceiver { transInfo = BluetoothOppUtility.queryRecord(context, uri); if (transInfo == null) { Log.e(TAG, "Error: Can not get data from db"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_RECEIVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); return; } @@ -154,33 +168,25 @@ public class BluetoothOppReceiver extends BroadcastReceiver { context.startActivity(in); } - } else if (action.equals(Constants.ACTION_OPEN_OUTBOUND_TRANSFER)) { + } else if (action.equals(Constants.ACTION_OPEN_OUTBOUND_TRANSFER) + && !Flags.oppStartActivityDirectlyFromNotification()) { if (V) { Log.v(TAG, "Received ACTION_OPEN_OUTBOUND_TRANSFER."); } Intent in = new Intent(context, BluetoothOppTransferHistory.class); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - in.putExtra("direction", BluetoothShare.DIRECTION_OUTBOUND); + in.putExtra(Constants.EXTRA_DIRECTION, BluetoothShare.DIRECTION_OUTBOUND); context.startActivity(in); - } else if (action.equals(Constants.ACTION_OPEN_INBOUND_TRANSFER)) { + } else if (action.equals(Constants.ACTION_OPEN_INBOUND_TRANSFER) + && !Flags.oppStartActivityDirectlyFromNotification()) { if (V) { Log.v(TAG, "Received ACTION_OPEN_INBOUND_TRANSFER."); } Intent in = new Intent(context, BluetoothOppTransferHistory.class); in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - in.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); - context.startActivity(in); - } else if (action.equals(Constants.ACTION_OPEN_RECEIVED_FILES)) { - if (V) { - Log.v(TAG, "Received ACTION_OPEN_RECEIVED_FILES."); - } - - Intent in = new Intent(context, BluetoothOppTransferHistory.class); - in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - in.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); - in.putExtra(Constants.EXTRA_SHOW_ALL_FILES, true); + in.putExtra(Constants.EXTRA_DIRECTION, BluetoothShare.DIRECTION_INBOUND); context.startActivity(in); } else if (action.equals(Constants.ACTION_HIDE)) { if (V) { @@ -209,7 +215,8 @@ public class BluetoothOppReceiver extends BroadcastReceiver { } cursor.close(); } - } else if (action.equals(Constants.ACTION_COMPLETE_HIDE)) { + } else if (action.equals(Constants.ACTION_COMPLETE_HIDE) + && !Flags.oppFixMultipleNotificationsIssues()) { if (V) { Log.v(TAG, "Receiver ACTION_COMPLETE_HIDE"); } @@ -218,6 +225,34 @@ public class BluetoothOppReceiver extends BroadcastReceiver { BluetoothMethodProxy.getInstance().contentResolverUpdate( context.getContentResolver(), BluetoothShare.CONTENT_URI, updateValues, BluetoothOppNotification.WHERE_COMPLETED, null); + } else if (action.equals(Constants.ACTION_HIDE_COMPLETED_INBOUND_TRANSFER) + && Flags.oppFixMultipleNotificationsIssues()) { + if (V) { + Log.v(TAG, "Received ACTION_HIDE_COMPLETED_INBOUND_TRANSFER"); + } + ContentValues updateValues = new ContentValues(); + updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + context.getContentResolver(), + BluetoothShare.CONTENT_URI, + updateValues, + BluetoothOppNotification.WHERE_COMPLETED_INBOUND, + null); + } else if (action.equals(Constants.ACTION_HIDE_COMPLETED_OUTBOUND_TRANSFER) + && Flags.oppFixMultipleNotificationsIssues()) { + if (V) { + Log.v(TAG, "Received ACTION_HIDE_COMPLETED_OUTBOUND_TRANSFER"); + } + ContentValues updateValues = new ContentValues(); + updateValues.put(BluetoothShare.VISIBILITY, BluetoothShare.VISIBILITY_HIDDEN); + BluetoothMethodProxy.getInstance() + .contentResolverUpdate( + context.getContentResolver(), + BluetoothShare.CONTENT_URI, + updateValues, + BluetoothOppNotification.WHERE_COMPLETED_OUTBOUND, + null); } else if (action.equals(BluetoothShare.TRANSFER_COMPLETED_ACTION)) { if (V) { Log.v(TAG, "Receiver Transfer Complete Intent for " + intent.getData()); @@ -228,6 +263,11 @@ public class BluetoothOppReceiver extends BroadcastReceiver { transInfo = BluetoothOppUtility.queryRecord(context, intent.getData()); if (transInfo == null) { Log.e(TAG, "Error: Can not get data from db"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_RECEIVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); return; } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java index 2adb8e5f44c278b60bcf23c04b5b9f2f3e81430c..d71e69910c439c2bb234f0d896eaf6fe47aa9cf6 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java @@ -32,6 +32,8 @@ package com.android.bluetooth.opp; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.Context; import android.content.res.AssetFileDescriptor; @@ -43,7 +45,9 @@ import android.util.EventLog; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import java.io.File; import java.io.FileInputStream; @@ -51,9 +55,10 @@ import java.io.FileNotFoundException; import java.io.IOException; /** - * This class stores information about a single sending file It will only be - * used for outbound share. + * This class stores information about a single sending file It will only be used for outbound + * share. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 15 public class BluetoothOppSendFileInfo { private static final String TAG = "BluetoothOppSendFileInfo"; @@ -114,6 +119,11 @@ public class BluetoothOppSendFileInfo { if (fromExternal && BluetoothOppUtility.isForbiddenContent(uri)) { EventLog.writeEvent(0x534e4554, "179910660", -1, uri.toString()); Log.e(TAG, "Content from forbidden URI is not allowed."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); return SEND_FILE_INFO_ERROR; } @@ -125,9 +135,19 @@ public class BluetoothOppSendFileInfo { OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE }, null, null, null); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); // some content providers don't support the DISPLAY_NAME or SIZE columns metadataCursor = null; } catch (SecurityException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "generateFileInfo: Permission error, could not access URI: " + uri); return SEND_FILE_INFO_ERROR; } @@ -159,12 +179,22 @@ public class BluetoothOppSendFileInfo { } else if ("file".equals(scheme)) { if (uri.getPath() == null) { Log.e(TAG, "Invalid URI path: " + uri); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 3); return SEND_FILE_INFO_ERROR; } if (fromExternal && !BluetoothOppUtility.isInExternalStorageDir(uri)) { EventLog.writeEvent(0x534e4554, "35310991", -1, uri.getPath()); Log.e(TAG, "File based URI not in Environment.getExternalStorageDirectory() is not " + "allowed."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 4); return SEND_FILE_INFO_ERROR; } fileName = uri.getLastPathSegment(); @@ -188,6 +218,12 @@ public class BluetoothOppSendFileInfo { if (length != statLength && statLength > 0) { Log.e(TAG, "Content provider length is wrong (" + Long.toString(length) + "), using stat length (" + Long.toString(statLength) + ")"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 5); length = statLength; } @@ -202,21 +238,49 @@ public class BluetoothOppSendFileInfo { if (length == 0) { length = getStreamSize(is); Log.w(TAG, "File length not provided. Length from stream = " + length); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 6); // Reset the stream fd = BluetoothMethodProxy.getInstance() .contentResolverOpenAssetFileDescriptor(contentResolver, uri, "r"); is = fd.createInputStream(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); try { fd.close(); } catch (IOException e2) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); // Ignore } } } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); // Ignore } catch (SecurityException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); return SEND_FILE_INFO_ERROR; } } @@ -235,17 +299,37 @@ public class BluetoothOppSendFileInfo { .contentResolverOpenInputStream(contentResolver, uri); } } catch (FileNotFoundException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); return SEND_FILE_INFO_ERROR; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); return SEND_FILE_INFO_ERROR; } } if (length == 0) { Log.e(TAG, "Could not determine size of file"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 13); return SEND_FILE_INFO_ERROR; } else if (length > 0xffffffffL) { Log.e(TAG, "File of size: " + length + " bytes can't be transferred"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SEND_FILE_INFO, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 14); throw new IllegalArgumentException(context .getString(R.string.bluetooth_opp_file_limit_exceeded)); } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java index e63618573e2ea8593db28c40777f65d8c3334a62..1d025b6c511b3feb30de7696f8edee5cb3d78b18 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java @@ -35,6 +35,8 @@ package com.android.bluetooth.opp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevicePicker; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSocket; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -57,10 +59,13 @@ import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothObexTransport; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.IObexConnectionHandler; import com.android.bluetooth.ObexServerSockets; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.sdp.SdpManagerNativeInterface; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.ObexTransport; @@ -72,10 +77,10 @@ import java.util.Date; import java.util.Locale; /** - * Performs the background Bluetooth OPP transfer. It also starts thread to - * accept incoming OPP connection. + * Performs the background Bluetooth OPP transfer. It also starts thread to accept incoming OPP + * connection. */ - +// Next tag value for ContentProfileErrorReportUtils.report(): 22 public class BluetoothOppService extends ProfileService implements IObexConnectionHandler { private static final boolean D = Constants.DEBUG; private static final boolean V = Constants.VERBOSE; @@ -201,39 +206,9 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti */ private BluetoothOppObexServerSession mServerSession; - BluetoothOppService() {} - - @VisibleForTesting - BluetoothOppService(Context ctx) { - attachBaseContext(ctx); - onCreate(); - } - - public static boolean isEnabled() { - return BluetoothProperties.isProfileOppEnabled().orElse(false); - } - - @Override - protected IProfileServiceBinder initBinder() { - return new OppBinder(this); - } + public BluetoothOppService(Context ctx) { + super(ctx); - private static class OppBinder extends Binder implements IProfileServiceBinder { - - OppBinder(BluetoothOppService service) { - } - - @Override - public void cleanup() { - } - } - - @Override - public void onCreate() { - super.onCreate(); - if (V) { - Log.v(TAG, "onCreate"); - } mShares = new ArrayList(); mBatches = new ArrayList(); mBatchId = 1; @@ -248,12 +223,34 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti preference.dump(); } else { Log.w(TAG, "BluetoothOppPreference.getInstance returned null."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); } } } + public static boolean isEnabled() { + return BluetoothProperties.isProfileOppEnabled().orElse(false); + } + @Override - public boolean start() { + protected IProfileServiceBinder initBinder() { + return new OppBinder(this); + } + + private static class OppBinder extends Binder implements IProfileServiceBinder { + + OppBinder(BluetoothOppService service) {} + + @Override + public void cleanup() {} + } + + @Override + public void start() { if (V) { Log.v(TAG, "start()"); } @@ -280,17 +277,24 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti mNotifier.mNotificationMgr.cancelAll(); updateFromProvider(); setBluetoothOppService(this); - return true; } @Override - public boolean stop() { + public void stop() { if (sBluetoothOppService == null) { Log.w(TAG, "stop() called before start()"); - return true; + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); } setBluetoothOppService(null); - mHandler.sendMessage(mHandler.obtainMessage(STOP_LISTENER)); + if (Flags.oppServiceFixIndexOutOfBoundsExceptionInUpdateThread()) { + stopInternal(); + } else { + mHandler.sendMessage(mHandler.obtainMessage(STOP_LISTENER)); + } setComponentAvailable(OPP_PROVIDER, false); setComponentAvailable(INCOMING_FILE_CONFIRM_ACTIVITY, false); @@ -298,8 +302,6 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti setComponentAvailable(TRANSFER_HISTORY_ACTIVITY, false); setComponentAvailable(OPP_RECEIVER, false); setComponentAvailable(OPP_HANDOFF_RECEIVER, false); - - return true; } private void startListener() { @@ -338,10 +340,20 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti public static synchronized BluetoothOppService getBluetoothOppService() { if (sBluetoothOppService == null) { Log.w(TAG, "getBluetoothOppService(): service is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 2); return null; } if (!sBluetoothOppService.isAvailable()) { Log.w(TAG, "getBluetoothOppService(): service is not available"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); return null; } return sBluetoothOppService; @@ -366,147 +378,142 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti private static final int STOP_LISTENER = 200; - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case STOP_LISTENER: - stopListeners(); - mListenStarted = false; - //Stop Active INBOUND Transfer - if (mServerTransfer != null) { - mServerTransfer.onBatchCanceled(); - mServerTransfer = null; - } - //Stop Active OUTBOUND Transfer - if (mTransfer != null) { - mTransfer.onBatchCanceled(); - mTransfer = null; - } - unregisterReceivers(); - synchronized (BluetoothOppService.this) { - if (mUpdateThread != null) { - mUpdateThread.interrupt(); - } - } - while (mUpdateThread != null && mUpdateThreadRunning) { - try { - Thread.sleep(50); - } catch (Exception e) { - Log.e(TAG, "Thread sleep", e); - } - } - synchronized (BluetoothOppService.this) { - if (mUpdateThread != null) { - try { - mUpdateThread.join(); - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted", e); + private Handler mHandler = + new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case STOP_LISTENER: + stopInternal(); + break; + case START_LISTENER: + if (mAdapterService.isEnabled()) { + startSocketListener(); } - mUpdateThread = null; - } - } - - if (mNotifier != null) { - mNotifier.cancelNotifications(); - } - break; - case START_LISTENER: - if (mAdapterService.isEnabled()) { - startSocketListener(); - } - break; - case MEDIA_SCANNED: - if (V) { - Log.v(TAG, "Update mInfo.id " + msg.arg1 + " for data uri= " - + msg.obj.toString()); - } - ContentValues updateValues = new ContentValues(); - Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + msg.arg1); - updateValues.put(Constants.MEDIA_SCANNED, Constants.MEDIA_SCANNED_SCANNED_OK); - updateValues.put(BluetoothShare.URI, msg.obj.toString()); // update - updateValues.put(BluetoothShare.MIMETYPE, - getContentResolver().getType(Uri.parse(msg.obj.toString()))); - getContentResolver().update(contentUri, updateValues, null, null); - synchronized (BluetoothOppService.this) { - mMediaScanInProgress = false; - } - break; - case MEDIA_SCANNED_FAILED: - Log.v(TAG, "Update mInfo.id " + msg.arg1 + " for MEDIA_SCANNED_FAILED"); - ContentValues updateValues1 = new ContentValues(); - Uri contentUri1 = Uri.parse(BluetoothShare.CONTENT_URI + "/" + msg.arg1); - updateValues1.put(Constants.MEDIA_SCANNED, - Constants.MEDIA_SCANNED_SCANNED_FAILED); - getContentResolver().update(contentUri1, updateValues1, null, null); - synchronized (BluetoothOppService.this) { - mMediaScanInProgress = false; - } - break; - case MSG_INCOMING_BTOPP_CONNECTION: - if (D) { - Log.d(TAG, "Get incoming connection"); - } - ObexTransport transport = (ObexTransport) msg.obj; - - /* - * Strategy for incoming connections: - * 1. If there is no ongoing transfer, no on-hold connection, start it - * 2. If there is ongoing transfer, hold it for 20 seconds(1 seconds * 20 times) - * 3. If there is on-hold connection, reject directly - */ - if (mBatches.size() == 0 && mPendingConnection == null) { - Log.i(TAG, "Start Obex Server"); - createServerSession(transport); - } else { - if (mPendingConnection != null) { - Log.w(TAG, "OPP busy! Reject connection"); - try { - transport.close(); - } catch (IOException e) { - Log.e(TAG, "close tranport error"); + break; + case MEDIA_SCANNED: + if (V) { + Log.v( + TAG, + "Update mInfo.id " + + msg.arg1 + + " for data uri= " + + msg.obj.toString()); } - } else { - Log.i(TAG, "OPP busy! Retry after 1 second"); - mIncomingRetries = mIncomingRetries + 1; - mPendingConnection = transport; - Message msg1 = Message.obtain(mHandler); - msg1.what = MSG_INCOMING_CONNECTION_RETRY; - mHandler.sendMessageDelayed(msg1, 1000); - } - } - break; - case MSG_INCOMING_CONNECTION_RETRY: - if (mBatches.size() == 0) { - Log.i(TAG, "Start Obex Server"); - createServerSession(mPendingConnection); - mIncomingRetries = 0; - mPendingConnection = null; - } else { - if (mIncomingRetries == 20) { - Log.w(TAG, "Retried 20 seconds, reject connection"); - try { - mPendingConnection.close(); - } catch (IOException e) { - Log.e(TAG, "close tranport error"); + ContentValues updateValues = new ContentValues(); + Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + msg.arg1); + updateValues.put( + Constants.MEDIA_SCANNED, Constants.MEDIA_SCANNED_SCANNED_OK); + updateValues.put(BluetoothShare.URI, msg.obj.toString()); // update + updateValues.put( + BluetoothShare.MIMETYPE, + getContentResolver().getType(Uri.parse(msg.obj.toString()))); + getContentResolver().update(contentUri, updateValues, null, null); + synchronized (BluetoothOppService.this) { + mMediaScanInProgress = false; } - if (mServerSocket != null) { - acceptNewConnections(); + break; + case MEDIA_SCANNED_FAILED: + Log.v(TAG, "Update mInfo.id " + msg.arg1 + " for MEDIA_SCANNED_FAILED"); + ContentValues updateValues1 = new ContentValues(); + Uri contentUri1 = + Uri.parse(BluetoothShare.CONTENT_URI + "/" + msg.arg1); + updateValues1.put( + Constants.MEDIA_SCANNED, + Constants.MEDIA_SCANNED_SCANNED_FAILED); + getContentResolver().update(contentUri1, updateValues1, null, null); + synchronized (BluetoothOppService.this) { + mMediaScanInProgress = false; } - mIncomingRetries = 0; - mPendingConnection = null; - } else { - Log.i(TAG, "OPP busy! Retry after 1 second"); - mIncomingRetries = mIncomingRetries + 1; - Message msg2 = Message.obtain(mHandler); - msg2.what = MSG_INCOMING_CONNECTION_RETRY; - mHandler.sendMessageDelayed(msg2, 1000); - } + break; + case MSG_INCOMING_BTOPP_CONNECTION: + if (D) { + Log.d(TAG, "Get incoming connection"); + } + ObexTransport transport = (ObexTransport) msg.obj; + + /* + * Strategy for incoming connections: + * 1. If there is no ongoing transfer, no on-hold connection, start it + * 2. If there is ongoing transfer, hold it for 20 seconds(1 seconds * 20 times) + * 3. If there is on-hold connection, reject directly + */ + if (mBatches.size() == 0 && mPendingConnection == null) { + Log.i(TAG, "Start Obex Server"); + createServerSession(transport); + } else { + if (mPendingConnection != null) { + Log.w(TAG, "OPP busy! Reject connection"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 6); + try { + transport.close(); + } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); + Log.e(TAG, "close tranport error"); + } + } else { + Log.i(TAG, "OPP busy! Retry after 1 second"); + mIncomingRetries = mIncomingRetries + 1; + mPendingConnection = transport; + Message msg1 = Message.obtain(mHandler); + msg1.what = MSG_INCOMING_CONNECTION_RETRY; + mHandler.sendMessageDelayed(msg1, 1000); + } + } + break; + case MSG_INCOMING_CONNECTION_RETRY: + if (mBatches.size() == 0) { + Log.i(TAG, "Start Obex Server"); + createServerSession(mPendingConnection); + mIncomingRetries = 0; + mPendingConnection = null; + } else { + if (mIncomingRetries == 20) { + Log.w(TAG, "Retried 20 seconds, reject connection"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 8); + try { + mPendingConnection.close(); + } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); + Log.e(TAG, "close tranport error"); + } + if (mServerSocket != null) { + acceptNewConnections(); + } + mIncomingRetries = 0; + mPendingConnection = null; + } else { + Log.i(TAG, "OPP busy! Retry after 1 second"); + mIncomingRetries = mIncomingRetries + 1; + Message msg2 = Message.obtain(mHandler); + msg2.what = MSG_INCOMING_CONNECTION_RETRY; + mHandler.sendMessageDelayed(msg2, 1000); + } + } + break; } - break; - } - } - }; + } + }; private ObexServerSockets mServerSocket; @@ -520,10 +527,20 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti SdpManagerNativeInterface nativeInterface = SdpManagerNativeInterface.getInstance(); if (!nativeInterface.isAvailable()) { Log.e(TAG, "ERROR:serversocket: SdpManagerNativeInterface is not available"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 10); return; } if (mServerSocket == null) { Log.e(TAG, "ERROR:serversocket: mServerSocket is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 11); return; } mOppSdpHandle = @@ -539,11 +556,13 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } @Override - protected void cleanup() { + public void cleanup() { if (V) { Log.v(TAG, "onDestroy"); } - stopListeners(); + if (!Flags.oppServiceFixIndexOutOfBoundsExceptionInUpdateThread()) { + stopListeners(); + } if (mBatches != null) { mBatches.clear(); } @@ -563,10 +582,68 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } unregisterReceiver(mBluetoothReceiver); } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 12); Log.w(TAG, "unregisterReceivers " + e.toString()); } } + private void stopInternal() { + stopListeners(); + mListenStarted = false; + // Stop Active INBOUND Transfer + if (mServerTransfer != null) { + mServerTransfer.onBatchCanceled(); + mServerTransfer = null; + } + // Stop Active OUTBOUND Transfer + if (mTransfer != null) { + mTransfer.onBatchCanceled(); + mTransfer = null; + } + unregisterReceivers(); + synchronized (BluetoothOppService.this) { + if (mUpdateThread != null) { + mUpdateThread.interrupt(); + } + } + while (mUpdateThread != null && mUpdateThreadRunning) { + try { + Thread.sleep(50); + } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); + Log.e(TAG, "Thread sleep", e); + } + } + synchronized (BluetoothOppService.this) { + if (mUpdateThread != null) { + try { + mUpdateThread.join(); + } catch (InterruptedException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); + Log.e(TAG, "Interrupted", e); + } + mUpdateThread = null; + } + } + + if (mNotifier != null) { + mNotifier.cancelNotifications(); + } + } + /* suppose we auto accept an incoming OPUSH connection */ private void createServerSession(ObexTransport transport) { mServerSession = new BluetoothOppObexServerSession(this, transport, this); @@ -615,7 +692,9 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti if (V) { Log.v(TAG, "Bluetooth state changed: STATE_TURNING_OFF"); } - mHandler.sendMessage(mHandler.obtainMessage(STOP_LISTENER)); + if (!Flags.oppServiceFixIndexOutOfBoundsExceptionInUpdateThread()) { + mHandler.sendMessage(mHandler.obtainMessage(STOP_LISTENER)); + } break; } } @@ -780,6 +859,11 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } else { uri = null; Log.e(TAG, "insertShare found null URI at cursor!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 13); } BluetoothOppShareInfo info = new BluetoothOppShareInfo( cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)), uri, @@ -839,6 +923,12 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti BluetoothOppUtility.getSendFileInfo(info.mUri); if (sendFileInfo == null || sendFileInfo.mInputStream == null) { Log.e(TAG, "Can't open file for OUTBOUND info " + info.mId); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 14); Constants.updateShareStatus(this, info.mId, BluetoothShare.STATUS_BAD_REQUEST); BluetoothOppUtility.closeSendFileInfo(info.mUri); return; @@ -914,6 +1004,11 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } } else { Log.w(TAG, "updateShare() called for ID " + info.mId + " with null URI"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 15); } info.mHint = stringFromCursor(info.mHint, cursor, BluetoothShare.FILENAME_HINT); info.mFilename = stringFromCursor(info.mFilename, cursor, BluetoothShare._DATA); @@ -979,22 +1074,46 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti if (batch.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { if (mTransfer == null) { Log.e(TAG, "Unexpected error! mTransfer is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 16); } else if (batch.mId == mTransfer.getBatchId()) { mTransfer.stop(); } else { Log.e(TAG, "Unexpected error! batch id " + batch.mId + " doesn't match mTransfer id " + mTransfer.getBatchId()); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 17); } mTransfer = null; } else { if (mServerTransfer == null) { Log.e(TAG, "Unexpected error! mServerTransfer is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 18); } else if (batch.mId == mServerTransfer.getBatchId()) { mServerTransfer.stop(); } else { Log.e(TAG, "Unexpected error! batch id " + batch.mId + " doesn't match mServerTransfer id " + mServerTransfer.getBatchId()); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 19); } mServerTransfer = null; } @@ -1181,6 +1300,11 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti } cursor.close(); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 20); Log.e(TAG, "Exception when trimming database: ", e); } } @@ -1237,6 +1361,11 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti msg.sendToTarget(); } } catch (NullPointerException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 21); Log.v(TAG, "!!!MediaScannerConnection exception: " + ex); } finally { if (V) { diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java index c43eef01bb31c5948b721c1c1f15e91184f0fe15..013e3c730a42b437e0db30e48f12b9448a3cd86e 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java @@ -35,6 +35,8 @@ package com.android.bluetooth.opp; import android.app.NotificationManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothUuid; import android.bluetooth.SdpOppOpsRecord; @@ -54,16 +56,16 @@ import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothObexTransport; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.ObexTransport; import java.io.IOException; -/** - * This class run an actual Opp transfer session (from connect target device to - * disconnect) - */ +/** This class run an actual Opp transfer session (from connect target device to disconnect) */ +// Next tag value for ContentProfileErrorReportUtils.report(): 24 public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatchListener { private static final String TAG = "BtOppTransfer"; @@ -123,16 +125,40 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (device == null) { Log.e(TAG, "Device is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); return; } else if (mBatch == null || mCurrentShare == null) { - Log.e(TAG, "device : " + device.getIdentityAddress() + " mBatch :" + mBatch + " mCurrentShare :" - + mCurrentShare); + Log.e( + TAG, + "device : " + + device.getIdentityAddress() + + " mBatch :" + + mBatch + + " mCurrentShare :" + + mCurrentShare); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); return; } try { if (V) { - Log.v(TAG, "Device :" + device.getIdentityAddress() + "- OPP device: " + mBatch.mDestination - + " \n mCurrentShare.mConfirm == " + mCurrentShare.mConfirm); + Log.v( + TAG, + "Device :" + + device.getIdentityAddress() + + "- OPP device: " + + mBatch.mDestination + + " \n mCurrentShare.mConfirm == " + + mCurrentShare.mConfirm); } if ((device.equals(mBatch.mDestination)) && (mCurrentShare.mConfirm == BluetoothShare.USER_CONFIRMATION_PENDING)) { @@ -147,6 +173,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); } } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); e.printStackTrace(); } } else if (action.equals(BluetoothDevice.ACTION_SDP_RECORD)) { @@ -162,6 +194,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (mDevice == null) { Log.w(TAG, "OPP SDP search, target device is null, ignoring result"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); return; } String deviceIdentityAddress = device.getIdentityAddress(); @@ -170,12 +208,24 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch || !deviceIdentityAddress.equalsIgnoreCase( transferDeviceIdentityAddress)) { Log.w(TAG, " OPP SDP search for wrong device, ignoring!!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 4); return; } SdpOppOpsRecord record = intent.getParcelableExtra(BluetoothDevice.EXTRA_SDP_RECORD); if (record == null) { Log.w(TAG, " Invalid SDP , ignoring !!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); markConnectionFailed(null); return; } @@ -324,6 +374,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch markBatchFailed(info2.mStatus); tickShareStatus(mCurrentShare); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); Log.e(TAG, "Exception while handling MSG_SESSION_ERROR"); e.printStackTrace(); } @@ -342,6 +398,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch mTransport.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.e(TAG, "failed to close mTransport"); } if (V) { @@ -372,6 +434,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch mTransport.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); Log.e(TAG, "failed to close mTransport"); } if (V) { @@ -412,6 +480,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch try { wait(1000); } catch (InterruptedException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); if (V) { Log.v(TAG, "Interrupted waiting for markBatchFailed"); } @@ -500,6 +573,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch */ if (!BluetoothMethodProxy.getInstance().bluetoothAdapterIsEnabled(mAdapter)) { Log.e(TAG, "Can't start transfer when Bluetooth is disabled for " + mBatch.mId); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 10); markBatchFailed(BluetoothShare.STATUS_UNKNOWN_ERROR); mBatch.mStatus = Constants.BATCH_STATUS_FAILED; return; @@ -552,6 +630,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } mConnectThread.join(); } catch (InterruptedException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); if (V) { Log.v(TAG, "Interrupted waiting for connect thread to join"); } @@ -579,6 +663,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch * TODO catch this error */ Log.e(TAG, "Unexpected error happened !"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 12); return; } if (V) { @@ -599,6 +688,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch if (mSession == null) { /** set current share as error */ Log.e(TAG, "Unexpected error happened !"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 13); markBatchFailed(BluetoothShare.STATUS_UNKNOWN_ERROR); mBatch.mStatus = Constants.BATCH_STATUS_FAILED; return; @@ -631,6 +725,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } } } catch (IllegalArgumentException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 14); Log.e(TAG, "mBluetoothReceiver Registered already ", e); } } @@ -743,6 +842,12 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch try { mBtSocket.close(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 15); Log.v(TAG, "Error when close socket"); } } @@ -761,6 +866,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch mBtSocket = mDevice.createInsecureRfcommSocketToServiceRecord( BluetoothUuid.OBEX_OBJECT_PUSH.getUuid()); } catch (IOException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 16); Log.e(TAG, "Rfcomm socket create error", e1); markConnectionFailed(mBtSocket); return; @@ -785,6 +895,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch mSessionHandler.obtainMessage(TRANSPORT_CONNECTED, transport).sendToTarget(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 17); Log.e(TAG, "Rfcomm socket connect exception", e); // If the devices were paired before, but unpaired on the // remote end, it will return an error for the auth request @@ -825,12 +940,23 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch try { if (mIsInterrupted) { Log.e(TAG, "btSocket connect interrupted "); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 18); markConnectionFailed(mBtSocket); return; } else { mBtSocket = mDevice.createInsecureL2capSocket(mL2cChannel); } } catch (IOException e1) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 19); Log.e(TAG, "L2cap socket create error", e1); connectRfcommSocket(); return; @@ -850,10 +976,21 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } mSessionHandler.obtainMessage(TRANSPORT_CONNECTED, transport).sendToTarget(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 20); Log.e(TAG, "L2cap socket connect exception", e); try { mBtSocket.close(); } catch (IOException e3) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 21); Log.e(TAG, "Bluetooth socket close error ", e3); } connectRfcommSocket(); @@ -871,6 +1008,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch s.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 22); if (V) { Log.e(TAG, "Error when close socket"); } @@ -964,6 +1106,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch mBluetoothReceiver = null; } } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 23); Log.e(TAG, "Exception:unregisterReceiver"); e.printStackTrace(); } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java index 5f5989066731eed28ac064c95ab341ff5ac3277f..a071b93e16a7eaae3e56f7fe33ea99edf7401252 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java @@ -37,6 +37,8 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import android.app.NotificationManager; import android.bluetooth.AlertActivity; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.DialogInterface; import android.content.Intent; import android.database.ContentObserver; @@ -50,20 +52,21 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.google.common.annotations.VisibleForTesting; /** - * Handle all transfer related dialogs: -Ongoing transfer -Receiving one file - * dialog -Sending one file dialog -sending multiple files dialog -Complete - * transfer -receive -receive success, will trigger corresponding handler - * -receive fail dialog -send -send success dialog -send fail dialog -Other - * dialogs - - DIALOG_RECEIVE_ONGOING will transition to - * DIALOG_RECEIVE_COMPLETE_SUCCESS or DIALOG_RECEIVE_COMPLETE_FAIL - * DIALOG_SEND_ONGOING will transition to DIALOG_SEND_COMPLETE_SUCCESS or - * DIALOG_SEND_COMPLETE_FAIL + * Handle all transfer related dialogs: -Ongoing transfer -Receiving one file dialog -Sending one + * file dialog -sending multiple files dialog -Complete transfer -receive -receive success, will + * trigger corresponding handler -receive fail dialog -send -send success dialog -send fail dialog + * -Other dialogs - - DIALOG_RECEIVE_ONGOING will transition to DIALOG_RECEIVE_COMPLETE_SUCCESS or + * DIALOG_RECEIVE_COMPLETE_FAIL DIALOG_SEND_ONGOING will transition to DIALOG_SEND_COMPLETE_SUCCESS + * or DIALOG_SEND_COMPLETE_FAIL */ +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class BluetoothOppTransferActivity extends AlertActivity implements DialogInterface.OnClickListener { private static final String TAG = "BluetoothOppTransferActivity"; @@ -145,6 +148,11 @@ public class BluetoothOppTransferActivity extends AlertActivity if (V) { Log.e(TAG, "Error: Can not get data from db"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); finish(); return; } @@ -402,6 +410,11 @@ public class BluetoothOppTransferActivity extends AlertActivity if (V) { Log.e(TAG, "Error: Can not get data from db"); } + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); return; } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java index 6d9d9d3ce22e3a65ca2d67e82f7a9625a352ff54..8ff0043f8e6687e188c96b3a09d6bcff07f1d2ee 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java @@ -35,6 +35,8 @@ package com.android.bluetooth.opp; import android.app.Activity; import android.app.AlertDialog; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; @@ -53,13 +55,16 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; +import com.android.bluetooth.flags.Flags; /** - * View showing the user's finished bluetooth opp transfers that the user does - * not confirm. Including outbound and inbound transfers, both successful and - * failed. * + * View showing the user's finished bluetooth opp transfers that the user does not confirm. + * Including outbound and inbound transfers, both successful and failed. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class BluetoothOppTransferHistory extends Activity implements View.OnCreateContextMenuListener, OnItemClickListener { private static final String TAG = "BluetoothOppTransferHistory"; @@ -90,31 +95,32 @@ public class BluetoothOppTransferHistory extends Activity mListView = (ListView) findViewById(R.id.list); mListView.setEmptyView(findViewById(R.id.empty)); - mShowAllIncoming = getIntent().getBooleanExtra(Constants.EXTRA_SHOW_ALL_FILES, false); - String direction; - int dir = getIntent().getIntExtra("direction", 0); - if (dir == BluetoothShare.DIRECTION_OUTBOUND) { + + boolean isOutbound = false; + + if (Flags.oppStartActivityDirectlyFromNotification()) { + String action = getIntent().getAction(); + isOutbound = Constants.ACTION_OPEN_OUTBOUND_TRANSFER.equals(action); + } else { + int dir = getIntent().getIntExtra(Constants.EXTRA_DIRECTION, 0); + isOutbound = (dir == BluetoothShare.DIRECTION_OUTBOUND); + } + + if (isOutbound) { setTitle(getText(R.string.outbound_history_title)); direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_OUTBOUND + ")"; } else { - if (mShowAllIncoming) { - setTitle(getText(R.string.btopp_live_folder)); - } else { - setTitle(getText(R.string.inbound_history_title)); - } + setTitle(getText(R.string.inbound_history_title)); direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_INBOUND + ")"; } - String selection = BluetoothShare.STATUS + " >= '200' AND " + direction; - - if (!mShowAllIncoming) { - selection = selection + " AND (" + BluetoothShare.VISIBILITY + " IS NULL OR " + String selection = BluetoothShare.STATUS + " >= '200' AND " + direction + " AND (" + + BluetoothShare.VISIBILITY + " IS NULL OR " + BluetoothShare.VISIBILITY + " == '" + BluetoothShare.VISIBILITY_VISIBLE + "')"; - } final String sortOrder = BluetoothShare.TIMESTAMP + " DESC"; mTransferCursor = BluetoothMethodProxy.getInstance().contentResolverQuery( @@ -150,7 +156,7 @@ public class BluetoothOppTransferHistory extends Activity @Override public boolean onCreateOptionsMenu(Menu menu) { - if (mTransferCursor != null && !mShowAllIncoming) { + if (mTransferCursor != null) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.transferhistory, menu); } @@ -159,9 +165,7 @@ public class BluetoothOppTransferHistory extends Activity @Override public boolean onPrepareOptionsMenu(Menu menu) { - if (!mShowAllIncoming) { - menu.findItem(R.id.transfer_menu_clear_all).setEnabled(isTransferComplete()); - } + menu.findItem(R.id.transfer_menu_clear_all).setEnabled(isTransferComplete()); return super.onPrepareOptionsMenu(menu); } @@ -220,13 +224,7 @@ public class BluetoothOppTransferHistory extends Activity fileName = this.getString(R.string.unknown_file); } menu.setHeaderTitle(fileName); - - MenuInflater inflater = getMenuInflater(); - if (mShowAllIncoming) { - inflater.inflate(R.menu.receivedfilescontextfinished, menu); - } else { - inflater.inflate(R.menu.transferhistorycontextfinished, menu); - } + getMenuInflater().inflate(R.menu.transferhistorycontextfinished, menu); } } @@ -263,6 +261,11 @@ public class BluetoothOppTransferHistory extends Activity } } } catch (StaleDataException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER_HISTORY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); } return false; } @@ -313,6 +316,11 @@ public class BluetoothOppTransferHistory extends Activity BluetoothOppTransferInfo transInfo = BluetoothOppUtility.queryRecord(this, contentUri); if (transInfo == null) { Log.e(TAG, "Error: Can not get data from db"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_TRANSFER_HISTORY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); return; } if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java index c03e91171f587755a903fae4475fc2a1c7788aa3..5a117052fb91c0fa2602ac03dbd25470a4185be8 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java @@ -35,6 +35,8 @@ package com.android.bluetooth.opp; import android.app.NotificationManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ActivityNotFoundException; import android.content.ContentResolver; import android.content.ContentValues; @@ -52,7 +54,9 @@ import android.util.EventLog; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import java.io.File; @@ -68,9 +72,8 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; -/** - * This class has some utilities for Opp application; - */ +/** This class has some utilities for Opp application; */ +// Next tag value for ContentProfileErrorReportUtils.report(): 10 public class BluetoothOppUtility { private static final String TAG = "BluetoothOppUtility"; private static final boolean D = Constants.DEBUG; @@ -201,11 +204,21 @@ public class BluetoothOppUtility { Long timeStamp, Uri uri) { if (fileName == null || mimetype == null) { Log.e(TAG, "ERROR: Para fileName ==null, or mimetype == null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); return; } if (!isBluetoothShareUri(uri)) { Log.e(TAG, "Trying to open a file that wasn't transfered over Bluetooth"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 1); return; } @@ -226,6 +239,11 @@ public class BluetoothOppUtility { if (path == null) { Log.e(TAG, "file uri not exist"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); return; } @@ -262,6 +280,11 @@ public class BluetoothOppUtility { } context.startActivity(activityIntent); } catch (ActivityNotFoundException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); if (V) { Log.d(TAG, "no activity for handling ACTION_VIEW intent: " + mimetype, ex); } @@ -285,6 +308,11 @@ public class BluetoothOppUtility { .contentResolverOpenFileDescriptor(resolver, uri, readOnlyMode); return true; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); e.printStackTrace(); } return false; @@ -453,6 +481,11 @@ public class BluetoothOppUtility { } if (sendFileInfo == BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR) { Log.e(TAG, "putSendFileInfo: bad sendFileInfo, URI: " + uri); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 5); } sSendFileMap.put(uri, sendFileInfo); } @@ -474,6 +507,11 @@ public class BluetoothOppUtility { try { info.mInputStream.close(); } catch (IOException ignored) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 6); } } } @@ -486,6 +524,11 @@ public class BluetoothOppUtility { static boolean isInExternalStorageDir(Uri uri) { if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { Log.e(TAG, "Not a file URI: " + uri); + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 7); return false; } @@ -494,6 +537,11 @@ public class BluetoothOppUtility { try { canonicalPath = new File(uri.getPath()).getCanonicalPath(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); canonicalPath = uri.getPath(); } File file = new File(canonicalPath); @@ -539,6 +587,11 @@ public class BluetoothOppUtility { } return false; } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_UTILITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); Log.e(TAG, "Error while accessing file", ex); return false; } diff --git a/android/app/src/com/android/bluetooth/opp/Constants.java b/android/app/src/com/android/bluetooth/opp/Constants.java index 1f0ec59b6251f69c40683b7dc43e58ab012b9ef7..606d34c0e747cf1dd5c5c16226a8f3b2b954d761 100644 --- a/android/app/src/com/android/bluetooth/opp/Constants.java +++ b/android/app/src/com/android/bluetooth/opp/Constants.java @@ -32,6 +32,8 @@ package com.android.bluetooth.opp; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentValues; import android.content.Context; import android.content.Intent; @@ -39,14 +41,15 @@ import android.net.Uri; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.obex.HeaderSet; import java.io.IOException; import java.util.regex.Pattern; -/** - * Bluetooth OPP internal constant definitions - */ +/** Bluetooth OPP internal constant definitions */ +// Next tag value for ContentProfileErrorReportUtils.report(): 1 public class Constants { /** Tag used for debugging/logging */ public static final String TAG = "BluetoothOpp"; @@ -70,18 +73,17 @@ public class Constants { /** the intent that gets sent when clicking a inbound transfer notification */ static final String ACTION_OPEN_INBOUND_TRANSFER = "android.btopp.intent.action.OPEN_INBOUND"; - /** the intent that gets sent from the Settings app to show the received files */ - static final String ACTION_OPEN_RECEIVED_FILES = - "android.btopp.intent.action.OPEN_RECEIVED_FILES"; - /** the intent that acceptlists a remote bluetooth device for auto-receive confirmation (NFC) */ static final String ACTION_ACCEPTLIST_DEVICE = "android.btopp.intent.action.ACCEPTLIST_DEVICE"; /** the intent that can be sent by handover requesters to stop a BTOPP transfer */ static final String ACTION_STOP_HANDOVER = "android.btopp.intent.action.STOP_HANDOVER_TRANSFER"; - /** the intent extra to show all received files in the transfer history */ - static final String EXTRA_SHOW_ALL_FILES = "android.btopp.intent.extra.SHOW_ALL"; + /** + * the intent extra to show the direction of a transfer. Value should be one of {@link + * BluetoothShare#DIRECTION_INBOUND} or {@link BluetoothShare#DIRECTION_OUTBOUND} + */ + static final String EXTRA_DIRECTION = "android.btopp.intent.extra.DIRECTION"; /** the intent that gets sent when clicking an incomplete/failed transfer */ static final String ACTION_LIST = "android.btopp.intent.action.LIST"; @@ -156,11 +158,21 @@ public class Constants { static final String ACTION_DECLINE = "android.btopp.intent.action.DECLINE"; /** - * the intent that gets sent when deleting the notifications of outbound and - * inbound completed transfer + * The intent that gets sent when deleting the notifications of outbound and inbound completed + * transfer. */ + // TODO(b/323096132): Remove this variable when the flag + // opp_fix_multiple_notifications_issues is ramped up. static final String ACTION_COMPLETE_HIDE = "android.btopp.intent.action.HIDE_COMPLETE"; + /** The intent that gets sent when deleting the notifications of completed inbound transfer. */ + static final String ACTION_HIDE_COMPLETED_INBOUND_TRANSFER = + "android.btopp.intent.action.HIDE_COMPLETED_INBOUND_TRANSFER"; + + /** The intent that gets sent when deleting the notifications of completed outbound transfer. */ + static final String ACTION_HIDE_COMPLETED_OUTBOUND_TRANSFER = + "android.btopp.intent.action.HIDE_COMPLETED_OUTBOUND_TRANSFER"; + /** the intent that gets sent when clicking a incoming file confirm notification */ static final String ACTION_INCOMING_FILE_CONFIRM = "android.btopp.intent.action.CONFIRM"; @@ -280,6 +292,11 @@ public class Constants { Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS)); Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER)); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.OPP, + BluetoothProtoEnums.BLUETOOTH_OPP_CONSTANTS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "dump HeaderSet error " + e); } } diff --git a/android/app/src/com/android/bluetooth/pan/PanService.java b/android/app/src/com/android/bluetooth/pan/PanService.java index dc7f706521efe07ba2ec68588a53b8f6f5746f6d..e7fa79e3b3bd592cc5a775e5c3a98777919e9e96 100644 --- a/android/app/src/com/android/bluetooth/pan/PanService.java +++ b/android/app/src/com/android/bluetooth/pan/PanService.java @@ -47,6 +47,7 @@ import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.HandlerExecutor; import com.android.modules.utils.SynchronousResultReceiver; @@ -114,10 +115,7 @@ public class PanService extends ProfileService { } }; - PanService() {} - - @VisibleForTesting - PanService(Context ctx) { + public PanService(Context ctx) { super(ctx); } @@ -151,7 +149,7 @@ public class PanService extends ProfileService { } @Override - protected boolean start() { + public void start() { mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), "AdapterService cannot be null when PanService starts"); mDatabaseManager = Objects.requireNonNull(AdapterService.getAdapterService().getDatabase(), @@ -178,15 +176,13 @@ public class PanService extends ProfileService { new HandlerExecutor(new Handler(Looper.getMainLooper())), mTetheringCallback); setPanService(this); mStarted = true; - - return true; } @Override - protected boolean stop() { + public void stop() { if (!mStarted) { Log.w(TAG, "stop() called before start()"); - return true; + return; } if (mTetheringManager != null) { mTetheringManager.unregisterTetheringEventCallback(mTetheringCallback); @@ -194,11 +190,10 @@ public class PanService extends ProfileService { } mNativeInterface.cleanup(); mHandler.removeCallbacksAndMessages(null); - return true; } @Override - protected void cleanup() { + public void cleanup() { // TODO(b/72948646): this should be moved to stop() setPanService(null); @@ -230,7 +225,10 @@ public class PanService extends ProfileService { case MESSAGE_CONNECT: BluetoothDevice connectDevice = (BluetoothDevice) msg.obj; if (!mNativeInterface.connect( - mAdapterService.getByteIdentityAddress(connectDevice))) { + Flags.identityAddressNullIfUnknown() + ? Utils.getByteBrEdrAddress(connectDevice) + : mAdapterService.getByteIdentityAddress( + connectDevice))) { handlePanDeviceStateChange( connectDevice, null, @@ -248,7 +246,10 @@ public class PanService extends ProfileService { case MESSAGE_DISCONNECT: BluetoothDevice disconnectDevice = (BluetoothDevice) msg.obj; if (!mNativeInterface.disconnect( - mAdapterService.getByteIdentityAddress(disconnectDevice))) { + Flags.identityAddressNullIfUnknown() + ? Utils.getByteBrEdrAddress(disconnectDevice) + : mAdapterService.getByteIdentityAddress( + disconnectDevice))) { handlePanDeviceStateChange( disconnectDevice, mPanIfName, diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java index 6e3f253731a26f2a1146492a21e4c9a7b1e552ab..778cd5b44956a1c335bc6ce4135f076fbad641d8 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java @@ -1,33 +1,17 @@ /* - * Copyright (c) 2008-2009, Motorola, Inc. + * Copyright (C) 2024 The Android Open Source Project * - * All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the Motorola, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.bluetooth.pbap; @@ -36,6 +20,8 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import android.bluetooth.AlertActivity; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -54,14 +40,16 @@ import android.widget.EditText; import android.widget.TextView; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; /** - * PbapActivity shows two dialogues: One for accepting incoming pbap request and - * the other prompts the user to enter a session key for authentication with a - * remote Bluetooth device. + * PbapActivity shows two dialogues: One for accepting incoming pbap request and the other prompts + * the user to enter a session key for authentication with a remote Bluetooth device. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 1 public class BluetoothPbapActivity extends AlertActivity implements Preference.OnPreferenceChangeListener, TextWatcher { private static final String TAG = "BluetoothPbapActivity"; @@ -117,8 +105,15 @@ public class BluetoothPbapActivity extends AlertActivity showPbapDialog(DIALOG_YES_NO_AUTH); mCurrentDialog = DIALOG_YES_NO_AUTH; } else { - Log.e(TAG, "Error: this activity may be started only with intent " - + "PBAP_ACCESS_REQUEST or PBAP_AUTH_CHALL "); + Log.e( + TAG, + "Error: this activity may be started only with intent " + + "PBAP_ACCESS_REQUEST or PBAP_AUTH_CHALL "); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_ACTIVITY, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); finish(); } IntentFilter filter = new IntentFilter(BluetoothPbapService.USER_CONFIRM_TIMEOUT_ACTION); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java index 79aa4a60a3c64e243ba1d131dc1db1ab5ea88cee..3e98bf4aaa9f81795e69368e93295848c329545a 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapAuthenticator.java @@ -1,47 +1,35 @@ /* - * Copyright (c) 2008-2009, Motorola, Inc. + * Copyright (C) 2024 The Android Open Source Project * - * All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the Motorola, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.Authenticator; import com.android.obex.PasswordAuthentication; /** - * BluetoothPbapAuthenticator is a used by BluetoothObexServer for obex - * authentication procedure. + * BluetoothPbapAuthenticator is a used by BluetoothObexServer for obex authentication procedure. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 1 public class BluetoothPbapAuthenticator implements Authenticator { private static final String TAG = "PbapAuthenticator"; @@ -80,6 +68,12 @@ public class BluetoothPbapAuthenticator implements Authenticator { try { wait(); } catch (InterruptedException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_AUTHENTICATOR, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "Interrupted while waiting on isChallenged or AuthCancelled"); } } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java index 123f145f901537adac54c98601b7f1e6f2452b1b..b60f1a38c17c02aac84f8c8b5e82edcd957d2f2b 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java @@ -15,6 +15,8 @@ */ package com.android.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteException; @@ -25,7 +27,9 @@ import android.text.TextUtils; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.vcard.VCardBuilder; import com.android.vcard.VCardConfig; @@ -36,9 +40,8 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; -/** - * VCard composer especially for Call Log used in Bluetooth. - */ +/** VCard composer especially for Call Log used in Bluetooth. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 3 public class BluetoothPbapCallLogComposer { private static final String TAG = "PbapCallLogComposer"; @@ -121,6 +124,11 @@ public class BluetoothPbapCallLogComposer { try { mCursor.close(); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_CALL_LOG_COMPOSER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "SQLiteException on Cursor#close(): " + e.getMessage()); } finally { mErrorReason = FAILURE_REASON_NO_ENTRY; @@ -243,12 +251,20 @@ public class BluetoothPbapCallLogComposer { } default: { Log.w(TAG, "Call log type not correct."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_CALL_LOG_COMPOSER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); return; } } final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX); - builder.appendLine(VCARD_PROPERTY_X_TIMESTAMP, Arrays.asList(callLogTypeStr), + builder.appendLine( + VCARD_PROPERTY_X_TIMESTAMP, + Arrays.asList(callLogTypeStr), toRfc2455Format(dateAsLong)); } @@ -257,6 +273,12 @@ public class BluetoothPbapCallLogComposer { try { mCursor.close(); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_CALL_LOG_COMPOSER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); + Log.e(TAG, "SQLiteException on Cursor#close(): " + e.getMessage()); } mCursor = null; diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java index 01c1e9ad4b25200e4281f33160aa79bd84aea34d..0ea493b85febfa0c0ccbc17a2ddb71489caec8ae 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapConfig.java @@ -1,29 +1,32 @@ -/************************************************************************************ +/* + * Copyright (C) 2024 The Android Open Source Project * - * Copyright (C) 2009-2012 Broadcom Corporation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.Context; import android.content.res.Resources; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class BluetoothPbapConfig { private static boolean sUseProfileForOwnerVcard = true; private static boolean sIncludePhotosInVcard = false; @@ -34,11 +37,22 @@ public class BluetoothPbapConfig { try { sUseProfileForOwnerVcard = r.getBoolean(R.bool.pbap_use_profile_for_owner_vcard); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_CONFIG, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); + Log.e("BluetoothPbapConfig", "", e); } try { sIncludePhotosInVcard = r.getBoolean(R.bool.pbap_include_photos_in_vcard); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_CONFIG, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e("BluetoothPbapConfig", "", e); } } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java index fa324eade6c83f97fad723880a07b6f64ed87850..d1529ee64f5430a9e2165415015a9eea4f441c99 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java @@ -1,37 +1,23 @@ /* - * Copyright (c) 2008-2009, Motorola, Inc. + * Copyright (C) 2024 The Android Open Source Project * - * All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the Motorola, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; @@ -44,6 +30,8 @@ import android.text.TextUtils; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.ApplicationParameter; import com.android.obex.HeaderSet; @@ -60,6 +48,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +// Next tag value for ContentProfileErrorReportUtils.report(): 34 public class BluetoothPbapObexServer extends ServerRequestHandler { private static final String TAG = "BluetoothPbapObexServer"; @@ -294,16 +283,32 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (uuid.length != UUID_LENGTH) { Log.w(TAG, "Wrong UUID length"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } for (int i = 0; i < UUID_LENGTH; i++) { if (uuid[i] != PBAP_TARGET[i]) { Log.w(TAG, "Wrong UUID"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } reply.setHeader(HeaderSet.WHO, uuid); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -317,6 +322,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { reply.setHeader(HeaderSet.TARGET, remote); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -330,6 +340,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_BAD_REQUEST; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -396,6 +411,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { try { tmpPath = (String) mPbapMethodProxy.getHeader(request, HeaderSet.NAME); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 5); Log.e(TAG, "Get name header fail"); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -422,9 +442,19 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if ((currentPathTmp.length() != 0) && (!isLegalPath(currentPathTmp))) { if (create) { Log.w(TAG, "path create is forbidden!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 6); return ResponseCodes.OBEX_HTTP_FORBIDDEN; } else { Log.w(TAG, "path is not legal"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 7); return ResponseCodes.OBEX_HTTP_NOT_FOUND; } } @@ -458,6 +488,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { appParam = (byte[]) mPbapMethodProxy.getHeader( request, HeaderSet.APPLICATION_PARAMETER); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); Log.e(TAG, "request headers error"); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -477,6 +512,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (!mPbapMethodProxy.getSystemService(mContext, UserManager.class).isUserUnlocked()) { Log.e(TAG, "Storage locked, " + type + " failed"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 9); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; } @@ -497,7 +537,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (!validName || (validName && type.equals(TYPE_VCARD))) { if (D) { - Log.d(TAG, + Log.d( + TAG, "Guess what carkit actually want from current path (" + mCurrentPath + ")"); } @@ -523,12 +564,23 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { /* PBAP 1.1.1 change */ if (!validName && type.equals(TYPE_LISTING)) { Log.e(TAG, "invalid vcard listing request in default folder"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 10); return ResponseCodes.OBEX_HTTP_NOT_FOUND; } } else if (isSimEnabled && mCurrentPath.equals(SIM_PB_PATH)) { appParamValue.needTag = ContentType.SIM_PHONEBOOK; } else { Log.w(TAG, "mCurrentpath is not valid path!!!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 11); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } if (D) { @@ -545,6 +597,12 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (!isSimEnabled) { // Not support SIM card currently Log.w(TAG, "Not support access SIM card info!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 12); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } else if (isNameMatchTarget(name, PB)) { @@ -592,6 +650,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } } else { Log.w(TAG, "Input name doesn't contain valid info!!!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 13); return ResponseCodes.OBEX_HTTP_NOT_FOUND; } } @@ -611,6 +674,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { return pullPhonebook(appParam, appParamValue, reply, op, name); } else { Log.w(TAG, "unknown type request!!!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 14); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } @@ -814,6 +882,12 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { default: parseOk = false; Log.e(TAG, "Parse Application Parameter error"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 15); break; } } @@ -1007,6 +1081,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { outputStream = op.openOutputStream(); outputStream.flush(); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 16); Log.e(TAG, e.toString()); pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } finally { @@ -1033,6 +1112,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { Log.v(TAG, "Send Data complete!"); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 17); Log.e(TAG, "open/write outputstrem failed" + e.toString()); pushResult = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -1161,6 +1245,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { try { op.sendHeaders(reply); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 18); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -1172,6 +1261,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { try { op.sendHeaders(reply); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 19); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -1183,6 +1277,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { try { op.sendHeaders(reply); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 20); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -1194,6 +1293,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { try { op.sendHeaders(reply); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 21); Log.e(TAG, e.toString()); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -1217,6 +1321,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (searchAttr.equals("2")) { // search by sound is not supported currently Log.w(TAG, "do not support search by sound"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 22); return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } return ResponseCodes.OBEX_HTTP_PRECON_FAILED; @@ -1253,6 +1362,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (orderPara.equals("2")) { // Order by sound is not supported currently Log.w(TAG, "Do not support order by sound"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 23); return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED; } return ResponseCodes.OBEX_HTTP_PRECON_FAILED; @@ -1283,6 +1397,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { try { intIndex = Integer.parseInt(strIndex); } catch (NumberFormatException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 24); Log.e(TAG, "catch number format exception " + e.toString()); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } @@ -1300,11 +1419,21 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { boolean vcard21 = appParamValue.vcard21; if (appParamValue.needTag == 0) { Log.w(TAG, "wrong path!"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 25); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } else if ((appParamValue.needTag == ContentType.PHONEBOOK) || (appParamValue.needTag == ContentType.FAVORITES)) { if (intIndex < 0 || intIndex >= size) { Log.w(TAG, "The requested vcard is not acceptable! name= " + name); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 26); return ResponseCodes.OBEX_HTTP_NOT_FOUND; } else if ((intIndex == 0) && (appParamValue.needTag == ContentType.PHONEBOOK)) { // For PB_PATH, 0.vcf is the phone number of this phone. @@ -1312,12 +1441,23 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { appParamValue.ignorefilter ? null : appParamValue.propertySelector); return pushBytes(op, ownerVcard); } else { - return mVcardManager.composeAndSendPhonebookOneVcard(op, intIndex, vcard21, null, - mOrderBy, appParamValue.ignorefilter, appParamValue.propertySelector); + return mVcardManager.composeAndSendPhonebookOneVcard( + op, + intIndex, + vcard21, + null, + mOrderBy, + appParamValue.ignorefilter, + appParamValue.propertySelector); } } else if (appParamValue.needTag == ContentType.SIM_PHONEBOOK) { if (intIndex < 0 || intIndex >= size) { Log.w(TAG, "The requested vcard is not acceptable! name= " + name); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 27); return ResponseCodes.OBEX_HTTP_NOT_FOUND; } else if (intIndex == 0) { // For PB_PATH, 0.vcf is the phone number of this phone. @@ -1331,6 +1471,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } else { if (intIndex <= 0 || intIndex > size) { Log.w(TAG, "The requested vcard is not acceptable! name= " + name); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 28); return ResponseCodes.OBEX_HTTP_NOT_FOUND; } // For others (ich/och/cch/mch), 0.vcf is meaningless, and must @@ -1354,6 +1499,12 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (dotIndex >= 0 && dotIndex <= name.length()) { if (!name.regionMatches(dotIndex + 1, vcf, 0, vcf.length())) { Log.w(TAG, "name is not .vcf"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 29); return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; } } @@ -1376,12 +1527,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { int requestSize = pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount : pbSize; /** - * startIndex (resp., lastIndex) corresponds to the index of the first (resp., last) - * vcard entry in the phonebook object. - * PBAP v1.2.3: only pb starts indexing at 0.vcf (owner card), the other phonebook - * objects (e.g., fav) start at 1.vcf. Additionally, the owner card is included in - * pb's pbSize. This means pbSize corresponds to the index of the last vcf in the fav - * phonebook object, but does not for the pb phonebook object. + * startIndex (resp., lastIndex) corresponds to the index of the first (resp., last) vcard + * entry in the phonebook object. PBAP v1.2.3: only pb starts indexing at 0.vcf (owner + * card), the other phonebook objects (e.g., fav) start at 1.vcf. Additionally, the owner + * card is included in pb's pbSize. This means pbSize corresponds to the index of the last + * vcf in the fav phonebook object, but does not for the pb phonebook object. */ int startIndex = 1; int lastIndex = pbSize; @@ -1394,6 +1544,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { int endPoint = startPoint + requestSize - 1; if (appParamValue.listStartOffset < 0 || startPoint > lastIndex) { Log.w(TAG, "listStartOffset is not correct! " + startPoint); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 30); return ResponseCodes.OBEX_HTTP_OK; } if (endPoint > lastIndex) { @@ -1466,6 +1621,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { out.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 31); Log.e(TAG, "outputStream close failed" + e.toString()); returnvalue = false; } @@ -1474,6 +1634,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { op.close(); } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 32); Log.e(TAG, "operation close failed" + e.toString()); returnvalue = false; } @@ -1570,6 +1735,11 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS)); Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER)); } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_OBEX_SERVER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 33); Log.e(TAG, "dump HeaderSet error " + e); } } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java index d52fc717ec687993c04f90d15421da1f451cdaba..f87e345c87dfec4464803d745a956ff23ce64b78 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapService.java @@ -1,34 +1,17 @@ /* - * Copyright (c) 2017, The Linux Foundation. - * Copyright (c) 2008-2009, Motorola, Inc. + * Copyright (C) 2024 The Android Open Source Project * - * All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the Motorola, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.bluetooth.pbap; @@ -43,6 +26,7 @@ import android.app.NotificationManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothUtils; import android.bluetooth.IBluetoothPbap; @@ -66,6 +50,7 @@ import android.telephony.TelephonyManager; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.IObexConnectionHandler; import com.android.bluetooth.ObexServerSockets; import com.android.bluetooth.R; @@ -74,6 +59,7 @@ import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.InteropUtil; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.sdp.SdpManagerNativeInterface; import com.android.bluetooth.util.DevicePolicyUtils; import com.android.internal.annotations.VisibleForTesting; @@ -83,6 +69,7 @@ import java.util.HashMap; import java.util.List; import java.util.Objects; +// Next tag value for ContentProfileErrorReportUtils.report(): 12 public class BluetoothPbapService extends ProfileService implements IObexConnectionHandler { private static final String TAG = "BluetoothPbapService"; @@ -198,10 +185,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect private static boolean sIsPseDynamicVersionUpgradeEnabled; - BluetoothPbapService() {} - - @VisibleForTesting - BluetoothPbapService(Context ctx) { + public BluetoothPbapService(Context ctx) { super(ctx); } @@ -253,6 +237,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect PbapStateMachine sm = mPbapStateMachineMap.get(device); if (sm == null) { Log.w(TAG, "device not connected! device=" + device); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 0); return; } mSessionStatusHandler.removeMessages(USER_TIMEOUT, sm); @@ -301,6 +291,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } } else { Log.w(TAG, "Unhandled intent action: " + action); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 1); } } @@ -326,6 +321,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect BluetoothUtils.USER_HANDLE_NULL.getIdentifier()); if (userId == BluetoothUtils.USER_HANDLE_NULL.getIdentifier()) { Log.e(TAG, "userChangeReceiver received an invalid EXTRA_USER_HANDLE"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); return; } Log.d(TAG, "Got " + action + " to userId " + userId); @@ -382,6 +383,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect private void createSdpRecord() { if (mSdpHandle > -1) { Log.w(TAG, "createSdpRecord, SDP record already created"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); return; } @@ -401,7 +407,6 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect if (DEBUG) { Log.d(TAG, "created Sdp record, mSdpHandle=" + mSdpHandle); } - } private void cleanUpSdpRecord() { @@ -417,8 +422,18 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } if (!nativeInterface.isAvailable()) { Log.e(TAG, "SdpManagerNativeInterface is not available"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 4); } else if (!nativeInterface.removeSdpRecord(sdpHandle)) { Log.w(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 5); } } @@ -444,6 +459,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect sNotificationManager.notify(notificationId, notification); } else { Log.e(TAG, "sNotificationManager is null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 6); } } @@ -489,6 +509,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect mServerSockets = ObexServerSockets.create(BluetoothPbapService.this); if (mServerSockets == null) { Log.w(TAG, "ObexServerSockets.create() returned null"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 7); break; } createSdpRecord(); @@ -516,6 +542,12 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect mWakeLock.setReferenceCounted(false); mWakeLock.acquire(); Log.w(TAG, "Acquire Wake Lock"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 8); } mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); mSessionStatusHandler.sendMessageDelayed( @@ -693,7 +725,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect } @Override - protected boolean start() { + public void start() { if (VERBOSE) { Log.v(TAG, "start()"); } @@ -728,8 +760,18 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect DevicePolicyUtils.getEnterprisePhoneUri(this), false, mContactChangeObserver); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); Log.e(TAG, "SQLite exception: " + e); } catch (IllegalStateException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 10); Log.e(TAG, "Illegal state exception, content observer is already registered"); } @@ -746,11 +788,10 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect adapterService.pbapPseDynamicVersionUpgradeIsEnabled(); Log.d(TAG, "sIsPseDynamicVersionUpgradeEnabled: " + sIsPseDynamicVersionUpgradeEnabled); } - return true; } @Override - protected boolean stop() { + public void stop() { if (VERBOSE) { Log.v(TAG, "stop()"); } @@ -764,7 +805,7 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect mContactsLoaded = false; if (mContactChangeObserver == null) { Log.i(TAG, "Avoid unregister when receiver it is not registered"); - return true; + return; } unregisterReceiver(mPbapReceiver); getContentResolver().unregisterContentObserver(mContactChangeObserver); @@ -774,7 +815,6 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect mPbapStateMachineMap.clear(); } getApplicationContext().unregisterReceiver(mUserChangeReceiver); - return true; } /** @@ -967,6 +1007,11 @@ public class BluetoothPbapService extends ProfileService implements IObexConnect @Override public synchronized void onAcceptFailed() { Log.w(TAG, "PBAP server socket accept thread failed. Restarting the server socket"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SERVICE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 11); if (mWakeLock != null) { mWakeLock.release(); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java index 6d5446067fb2e160ee23d846f701be9d91c2e487..b6161fa6c7403bf4c16b68d6dcba1d951ef79df3 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java @@ -1,20 +1,23 @@ /* -* Copyright (c) 2015, The Linux Foundation. All rights reserved. -* Copyright (C) 2014 Samsung System LSI -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.android.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; @@ -29,7 +32,9 @@ import android.text.TextUtils; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.Operation; import com.android.obex.ResponseCodes; @@ -43,9 +48,8 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; -/** - * VCard composer especially for Call Log used in Bluetooth. - */ +/** VCard composer especially for Call Log used in Bluetooth. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 6 public class BluetoothPbapSimVcardManager { private static final String TAG = "PbapSIMvCardComposer"; @@ -122,6 +126,11 @@ public class BluetoothPbapSimVcardManager { try { mCursor.close(); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "SQLiteException on Cursor#close(): " + e.getMessage()); } finally { mErrorReason = FAILURE_REASON_NO_ENTRY; @@ -188,6 +197,11 @@ public class BluetoothPbapSimVcardManager { try { mCursor.close(); } catch (SQLiteException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "SQLiteException on Cursor#close(): " + e.getMessage()); } mCursor = null; @@ -376,6 +390,11 @@ public class BluetoothPbapSimVcardManager { String ownerVCard) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } BluetoothPbapSimVcardManager composer = null; @@ -387,7 +406,7 @@ public class BluetoothPbapSimVcardManager { if (!composer.init(SIM_URI, null, null, null) || !buffer.init()) { return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } - composer.moveToPosition(startPoint -1, false); + composer.moveToPosition(startPoint - 1, false); for (int count =startPoint -1; count < endPoint; count++) { if (BluetoothPbapObexServer.sIsAborted) { ((ServerOperation)op).setAborted(true); @@ -398,6 +417,12 @@ public class BluetoothPbapSimVcardManager { if (vcard == null) { Log.e(TAG, "Failed to read a contact. Error reason: " + composer.getErrorReason() + ", count:" + count); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 3); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } buffer.writeVCard(vcard); @@ -418,6 +443,11 @@ public class BluetoothPbapSimVcardManager { int orderByWhat) { if (offset < 1) { Log.e(TAG, "Internal error: offset is not correct."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 4); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } if (V) Log.v(TAG, "composeAndSendSIMPhonebookOneVcard orderByWhat " + orderByWhat); @@ -442,6 +472,11 @@ public class BluetoothPbapSimVcardManager { if (vcard == null) { Log.e(TAG, "Failed to read a contact. Error reason: " + composer.getErrorReason()); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_SIM_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 5); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } buffer.writeVCard(vcard); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java index fc72889a75e06c22bdb8e96a32eb361388b22f06..79aca2d59b0bf392e0e2516971f12e4799d5ee1a 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java @@ -1,22 +1,23 @@ -/************************************************************************************ +/* + * Copyright (C) 2024 The Android Open Source Project * - * Copyright (C) 2009-2012 Broadcom Corporation + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; @@ -35,6 +36,8 @@ import android.provider.ContactsContract.RawContactsEntity; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.vcard.VCardComposer; import com.android.vcard.VCardConfig; @@ -47,6 +50,7 @@ import java.util.HashSet; import java.util.Objects; import java.util.concurrent.atomic.AtomicLong; +// Next tag value for ContentProfileErrorReportUtils.report(): 4 class BluetoothPbapUtils { private static final String TAG = "BluetoothPbapUtils"; private static final boolean V = BluetoothPbapService.VERBOSE; @@ -210,10 +214,22 @@ class BluetoothPbapUtils { RawContactsEntity.CONTENT_URI.getLastPathSegment()))) { vcard = composer.createOneEntry(); } else { - Log.e(TAG, "Unable to create profile vcard. Error initializing composer: " - + composer.getErrorReason()); + Log.e( + TAG, + "Unable to create profile vcard. Error initializing composer: " + + composer.getErrorReason()); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 0); } } catch (Throwable t) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_UTILS, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "Unable to create profile vcard.", t); } if (composer != null) { @@ -425,6 +441,12 @@ class BluetoothPbapUtils { ContactData currentContactData = sContactDataset.get(contact); if (currentContactData == null) { Log.e(TAG, "Null contact in the updateList: " + contact); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_UTILS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 2); continue; } @@ -531,6 +553,12 @@ class BluetoothPbapUtils { while (c.moveToNext()) { if (c.isNull(indexCId)) { Log.w(TAG, "_id column is null. Row was deleted during iteration, skipping"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_UTILS, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_WARN, + 3); continue; } contactId = c.getString(indexCId); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java index 1769f2400230db4864f319ea29cc78da3db19c60..264b3a4f4cbe5dc415883f9dc16fa90871267517 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java @@ -1,38 +1,23 @@ /* - * Copyright (c) 2008-2009, Motorola, Inc. - * Copyright (C) 2009-2012, Broadcom Corporation + * Copyright (C) 2024 The Android Open Source Project * - * All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * - Neither the name of the Motorola, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; @@ -52,7 +37,9 @@ import android.text.TextUtils; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.R; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.bluetooth.util.DevicePolicyUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.Operation; @@ -66,6 +53,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; +// Next tag value for ContentProfileErrorReportUtils.report(): 22 public class BluetoothPbapVcardManager { private static final String TAG = "BluetoothPbapVcardManager"; @@ -193,6 +181,11 @@ public class BluetoothPbapVcardManager { } return contactsSize; } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "CursorWindowAllocationException while getting Contacts size"); } finally { if (contactCursor != null) { @@ -208,12 +201,24 @@ public class BluetoothPbapVcardManager { int size = 0; Cursor callCursor = null; try { - callCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, null, selection, null, CallLog.Calls.DEFAULT_SORT_ORDER); + callCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + null, + selection, + null, + CallLog.Calls.DEFAULT_SORT_ORDER); if (callCursor != null) { size = callCursor.getCount(); } } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "CursorWindowAllocationException while getting CallHistory size"); } finally { if (callCursor != null) { @@ -261,6 +266,11 @@ public class BluetoothPbapVcardManager { } } } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "CursorWindowAllocationException while loading CallHistory"); } finally { if (callCursor != null) { @@ -294,15 +304,32 @@ public class BluetoothPbapVcardManager { if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { orderBy = Phone.DISPLAY_NAME; } - contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, - myUri, PHONES_CONTACTS_PROJECTION, null, null, orderBy); + contactCursor = + BluetoothMethodProxy.getInstance() + .contentResolverQuery( + mResolver, + myUri, + PHONES_CONTACTS_PROJECTION, + null, + null, + orderBy); if (contactCursor != null) { appendDistinctNameIdList(nameList, mContext.getString(android.R.string.unknownName), contactCursor); } } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 3); Log.e(TAG, "CursorWindowAllocationException while getting phonebook name list"); } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 4); Log.e(TAG, "Exception while getting phonebook name list", e); } finally { if (contactCursor != null) { @@ -380,6 +407,12 @@ public class BluetoothPbapVcardManager { } if (vcard == null) { Log.e(TAG, "Failed to read a contact."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 5); return nameList; } else if (vcard.isEmpty()) { Log.i(TAG, "Contact may have been deleted during operation"); @@ -391,6 +424,12 @@ public class BluetoothPbapVcardManager { if (!vcardselector.checkVCardSelector(vcard, vCardSelectorOperator)) { Log.e(TAG, "vcard selector check fail"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 6); vcard = null; pbSize--; continue; @@ -416,6 +455,11 @@ public class BluetoothPbapVcardManager { } } } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 7); Log.e(TAG, "CursorWindowAllocationException while getting Phonebook name list"); } finally { if (contactCursor != null) { @@ -455,6 +499,11 @@ public class BluetoothPbapVcardManager { } } } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 8); Log.e(TAG, "CursorWindowAllocationException while getting contact names"); } finally { if (contactCursor != null) { @@ -483,6 +532,11 @@ public class BluetoothPbapVcardManager { count = count + 1; } } catch (Exception e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 9); Log.e(TAG, "exception while fetching callHistory pvc"); } finally { if (callCursor != null) { @@ -505,12 +559,26 @@ public class BluetoothPbapVcardManager { }; private static final int ID_COLUMN_INDEX = 0; - final int composeAndSendSelectedCallLogVcards(final int type, Operation op, - final int startPoint, final int endPoint, final boolean vcardType21, int needSendBody, - int pbSize, boolean ignorefilter, byte[] filter, byte[] vcardselector, - String vcardselectorop, boolean vcardselect) { + final int composeAndSendSelectedCallLogVcards( + final int type, + Operation op, + final int startPoint, + final int endPoint, + final boolean vcardType21, + int needSendBody, + int pbSize, + boolean ignorefilter, + byte[] filter, + byte[] vcardselector, + String vcardselectorop, + boolean vcardselect) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 10); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } String typeSelection = BluetoothPbapObexServer.createSelectionPara(type); @@ -541,6 +609,11 @@ public class BluetoothPbapVcardManager { } } } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 11); Log.e(TAG, "CursorWindowAllocationException while composing calllog vcards"); } finally { if (callsCursor != null) { @@ -580,6 +653,11 @@ public class BluetoothPbapVcardManager { boolean vcardselect, boolean favorites) { if (startPoint < 1 || startPoint > endPoint) { Log.e(TAG, "internal error: startPoint or endPoint is not correct."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 12); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } @@ -603,6 +681,11 @@ public class BluetoothPbapVcardManager { ContactCursorFilter.filterByRange(contactCursor, startPoint, endPoint); } } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 13); Log.e(TAG, "CursorWindowAllocationException while composing phonebook vcards"); } finally { if (contactCursor != null) { @@ -625,6 +708,11 @@ public class BluetoothPbapVcardManager { byte[] filter) { if (offset < 1) { Log.e(TAG, "Internal error: offset is not correct."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 14); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); @@ -642,6 +730,11 @@ public class BluetoothPbapVcardManager { contactCursor = BluetoothMethodProxy.getInstance().contentResolverQuery(mResolver, myUri, PHONES_CONTACTS_PROJECTION, null, null, orderBy); } catch (CursorWindowAllocationException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 15); Log.e(TAG, "CursorWindowAllocationException while composing phonebook one vcard"); } finally { if (contactCursor != null) { @@ -771,6 +864,12 @@ public class BluetoothPbapVcardManager { } if (vcard == null) { Log.e(TAG, "Failed to read a contact."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 16); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } else if (vcard.isEmpty()) { Log.i(TAG, "Contact may have been deleted during operation"); @@ -876,6 +975,12 @@ public class BluetoothPbapVcardManager { } if (vcard == null) { Log.e(TAG, "Failed to read a contact."); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 17); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } else if (vcard.isEmpty()) { Log.i(TAG, "Contact may have been deleted during operation"); @@ -887,12 +992,18 @@ public class BluetoothPbapVcardManager { if (!vcardselector.checkVCardSelector(vcard, vcardselectorop)) { Log.e(TAG, "vcard selector check fail"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 18); vcard = null; pbSize--; continue; } - Log.e(TAG, "vcard selector check pass"); + Log.i(TAG, "vcard selector check pass"); if (needSendBody == NEED_SEND_BODY) { vcard = vcardfilter.apply(vcard, vcardType21); @@ -961,6 +1072,12 @@ public class BluetoothPbapVcardManager { if (vCardSelct) { if (!vcardselector.checkVCardSelector(vcard, vcardselectorop)) { Log.e(TAG, "Checking vcard selector for call log"); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 19); vcard = null; pbSize--; continue; @@ -969,6 +1086,12 @@ public class BluetoothPbapVcardManager { if (vcard == null) { Log.e(TAG, "Failed to read a contact. Error reason: " + composer.getErrorReason()); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 20); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } else if (vcard.isEmpty()) { Log.i(TAG, "Call Log may have been deleted during operation"); @@ -986,6 +1109,12 @@ public class BluetoothPbapVcardManager { if (vcard == null) { Log.e(TAG, "Failed to read a contact. Error reason: " + composer.getErrorReason()); + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_VCARD_MANAGER, + BluetoothStatsLog + .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__LOG_ERROR, + 21); return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; } if (V) { diff --git a/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java b/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java index 4a4a52050eff2344d5788d3faf0937ec7c403476..371f63ce7a25403bc071e57879cd28a4a5207eb0 100644 --- a/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java +++ b/android/app/src/com/android/bluetooth/pbap/HandlerForStringBuffer.java @@ -16,16 +16,19 @@ package com.android.bluetooth.pbap; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.util.Log; +import com.android.bluetooth.BluetoothStatsLog; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.obex.Operation; import java.io.IOException; import java.io.OutputStream; -/** - * Handler to emit vCards to PCE. - */ +/** Handler to emit vCards to PCE. */ +// Next tag value for ContentProfileErrorReportUtils.report(): 2 public class HandlerForStringBuffer { private static final String TAG = "HandlerForStringBuffer"; @@ -50,6 +53,11 @@ public class HandlerForStringBuffer { } return true; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_HANDLER_FOR_STRING_BUFFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "openOutputStream failed", e); } return false; @@ -62,6 +70,11 @@ public class HandlerForStringBuffer { return true; } } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_HANDLER_FOR_STRING_BUFFER, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "write failed", e); } return false; diff --git a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java index 9363b2dfa863794a1fe75aa9097160c1d50cdec2..c18f6a84443fc5c2492888aa45b6d755e08f9be4 100644 --- a/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java +++ b/android/app/src/com/android/bluetooth/pbap/PbapStateMachine.java @@ -26,6 +26,7 @@ import android.app.PendingIntent; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothPbap; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSocket; import android.content.Intent; import android.os.Handler; @@ -36,12 +37,14 @@ import android.util.Log; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.BluetoothObexTransport; +import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.IObexConnectionHandler; import com.android.bluetooth.ObexRejectServer; import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.MetricsLogger; +import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; import com.android.internal.util.State; @@ -64,6 +67,7 @@ import java.io.IOException; * CONNECTED -----> FINISHED * (OBEX Server done) */ +// Next tag value for ContentProfileErrorReportUtils.report(): 3 @VisibleForTesting(visibility = Visibility.PACKAGE) public class PbapStateMachine extends StateMachine { private static final String TAG = "PbapStateMachine"; @@ -265,6 +269,11 @@ public class PbapStateMachine extends StateMachine { try { mServerSession = new ServerSession(transport, server, null); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_STATE_MACHINE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 0); Log.e(TAG, "Caught exception starting OBEX reject server session" + ex.toString()); } } @@ -290,6 +299,11 @@ public class PbapStateMachine extends StateMachine { mConnSocket.close(); mConnSocket = null; } catch (IOException e) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_STATE_MACHINE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 1); Log.e(TAG, "Close Connection Socket error: " + e.toString()); } @@ -310,6 +324,11 @@ public class PbapStateMachine extends StateMachine { try { startObexServerSession(); } catch (IOException ex) { + ContentProfileErrorReportUtils.report( + BluetoothProfile.PBAP, + BluetoothProtoEnums.BLUETOOTH_PBAP_STATE_MACHINE, + BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, + 2); Log.e(TAG, "Caught exception starting OBEX server session" + ex.toString()); } broadcastStateTransitions(); diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java index b3ce847e70feafb417c9fe2cf6758a5c360f10a7..abd92ee18ff62781f05dc995516f6fb9370f68b2 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java @@ -120,10 +120,7 @@ public class PbapClientService extends ProfileService { } }; - PbapClientService() {} - - @VisibleForTesting - PbapClientService(Context ctx) { + public PbapClientService(Context ctx) { super(ctx); } @@ -137,7 +134,7 @@ public class PbapClientService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (VDBG) { Log.v(TAG, "onStart"); } @@ -163,11 +160,10 @@ public class PbapClientService extends ProfileService { initializeAuthenticationService(); registerSdpRecord(); setPbapClientService(this); - return true; } @Override - protected boolean stop() { + public void stop() { setPbapClientService(null); cleanUpSdpRecord(); try { @@ -188,7 +184,6 @@ public class PbapClientService extends ProfileService { cleanupAuthenicationService(); setComponentAvailable(AUTHENTICATOR_SERVICE, false); - return true; } void cleanupDevice(BluetoothDevice device) { diff --git a/android/app/src/com/android/bluetooth/sap/SapMessage.java b/android/app/src/com/android/bluetooth/sap/SapMessage.java index c88b61b3b0271095d935ec8541e3f9d4c6b0dc0d..b1f947ce224bf4608b73061b0ec31ae007448c04 100644 --- a/android/app/src/com/android/bluetooth/sap/SapMessage.java +++ b/android/app/src/com/android/bluetooth/sap/SapMessage.java @@ -1187,67 +1187,63 @@ public class SapMessage { public static String getMsgTypeName(int msgType) { - if (DEBUG || VERBOSE) { - switch (msgType) { - case ID_CONNECT_REQ: - return "ID_CONNECT_REQ"; - case ID_CONNECT_RESP: - return "ID_CONNECT_RESP"; - case ID_DISCONNECT_REQ: - return "ID_DISCONNECT_REQ"; - case ID_DISCONNECT_RESP: - return "ID_DISCONNECT_RESP"; - case ID_DISCONNECT_IND: - return "ID_DISCONNECT_IND"; - case ID_TRANSFER_APDU_REQ: - return "ID_TRANSFER_APDU_REQ"; - case ID_TRANSFER_APDU_RESP: - return "ID_TRANSFER_APDU_RESP"; - case ID_TRANSFER_ATR_REQ: - return "ID_TRANSFER_ATR_REQ"; - case ID_TRANSFER_ATR_RESP: - return "ID_TRANSFER_ATR_RESP"; - case ID_POWER_SIM_OFF_REQ: - return "ID_POWER_SIM_OFF_REQ"; - case ID_POWER_SIM_OFF_RESP: - return "ID_POWER_SIM_OFF_RESP"; - case ID_POWER_SIM_ON_REQ: - return "ID_POWER_SIM_ON_REQ"; - case ID_POWER_SIM_ON_RESP: - return "ID_POWER_SIM_ON_RESP"; - case ID_RESET_SIM_REQ: - return "ID_RESET_SIM_REQ"; - case ID_RESET_SIM_RESP: - return "ID_RESET_SIM_RESP"; - case ID_TRANSFER_CARD_READER_STATUS_REQ: - return "ID_TRANSFER_CARD_READER_STATUS_REQ"; - case ID_TRANSFER_CARD_READER_STATUS_RESP: - return "ID_TRANSFER_CARD_READER_STATUS_RESP"; - case ID_STATUS_IND: - return "ID_STATUS_IND"; - case ID_ERROR_RESP: - return "ID_ERROR_RESP"; - case ID_SET_TRANSPORT_PROTOCOL_REQ: - return "ID_SET_TRANSPORT_PROTOCOL_REQ"; - case ID_SET_TRANSPORT_PROTOCOL_RESP: - return "ID_SET_TRANSPORT_PROTOCOL_RESP"; - case ID_RIL_UNSOL_CONNECTED: - return "ID_RIL_UNSOL_CONNECTED"; - case ID_RIL_UNSOL_DISCONNECT_IND: - return "ID_RIL_UNSOL_DISCONNECT_IND"; - case ID_RIL_UNKNOWN: - return "ID_RIL_UNKNOWN"; - case ID_RIL_GET_SIM_STATUS_REQ: - return "ID_RIL_GET_SIM_STATUS_REQ"; - case ID_RIL_SIM_ACCESS_TEST_REQ: - return "ID_RIL_SIM_ACCESS_TEST_REQ"; - case ID_RIL_SIM_ACCESS_TEST_RESP: - return "ID_RIL_SIM_ACCESS_TEST_RESP"; - default: - return "Unknown Message Type (" + msgType + ")"; - } - } else { - return null; + switch (msgType) { + case ID_CONNECT_REQ: + return "ID_CONNECT_REQ"; + case ID_CONNECT_RESP: + return "ID_CONNECT_RESP"; + case ID_DISCONNECT_REQ: + return "ID_DISCONNECT_REQ"; + case ID_DISCONNECT_RESP: + return "ID_DISCONNECT_RESP"; + case ID_DISCONNECT_IND: + return "ID_DISCONNECT_IND"; + case ID_TRANSFER_APDU_REQ: + return "ID_TRANSFER_APDU_REQ"; + case ID_TRANSFER_APDU_RESP: + return "ID_TRANSFER_APDU_RESP"; + case ID_TRANSFER_ATR_REQ: + return "ID_TRANSFER_ATR_REQ"; + case ID_TRANSFER_ATR_RESP: + return "ID_TRANSFER_ATR_RESP"; + case ID_POWER_SIM_OFF_REQ: + return "ID_POWER_SIM_OFF_REQ"; + case ID_POWER_SIM_OFF_RESP: + return "ID_POWER_SIM_OFF_RESP"; + case ID_POWER_SIM_ON_REQ: + return "ID_POWER_SIM_ON_REQ"; + case ID_POWER_SIM_ON_RESP: + return "ID_POWER_SIM_ON_RESP"; + case ID_RESET_SIM_REQ: + return "ID_RESET_SIM_REQ"; + case ID_RESET_SIM_RESP: + return "ID_RESET_SIM_RESP"; + case ID_TRANSFER_CARD_READER_STATUS_REQ: + return "ID_TRANSFER_CARD_READER_STATUS_REQ"; + case ID_TRANSFER_CARD_READER_STATUS_RESP: + return "ID_TRANSFER_CARD_READER_STATUS_RESP"; + case ID_STATUS_IND: + return "ID_STATUS_IND"; + case ID_ERROR_RESP: + return "ID_ERROR_RESP"; + case ID_SET_TRANSPORT_PROTOCOL_REQ: + return "ID_SET_TRANSPORT_PROTOCOL_REQ"; + case ID_SET_TRANSPORT_PROTOCOL_RESP: + return "ID_SET_TRANSPORT_PROTOCOL_RESP"; + case ID_RIL_UNSOL_CONNECTED: + return "ID_RIL_UNSOL_CONNECTED"; + case ID_RIL_UNSOL_DISCONNECT_IND: + return "ID_RIL_UNSOL_DISCONNECT_IND"; + case ID_RIL_UNKNOWN: + return "ID_RIL_UNKNOWN"; + case ID_RIL_GET_SIM_STATUS_REQ: + return "ID_RIL_GET_SIM_STATUS_REQ"; + case ID_RIL_SIM_ACCESS_TEST_REQ: + return "ID_RIL_SIM_ACCESS_TEST_REQ"; + case ID_RIL_SIM_ACCESS_TEST_RESP: + return "ID_RIL_SIM_ACCESS_TEST_RESP"; + default: + return "Unknown Message Type (" + msgType + ")"; } } } diff --git a/android/app/src/com/android/bluetooth/sap/SapService.java b/android/app/src/com/android/bluetooth/sap/SapService.java index 75ae9edb5b08ec2d27b874936766960cae08cbc4..68dfc155c616cc76c5bf74e0b69a98063559f4c9 100644 --- a/android/app/src/com/android/bluetooth/sap/SapService.java +++ b/android/app/src/com/android/bluetooth/sap/SapService.java @@ -107,12 +107,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo BluetoothUuid.SAP, }; - public SapService() { - BluetoothSap.invalidateBluetoothGetConnectionStateCache(); - } - - @VisibleForTesting - SapService(Context ctx) { + public SapService(Context ctx) { super(ctx); BluetoothSap.invalidateBluetoothGetConnectionStateCache(); } @@ -685,7 +680,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo } @Override - protected boolean start() { + public void start() { Log.v(TAG, "start()"); IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); @@ -704,15 +699,14 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo // start RFCOMM listener mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER)); setSapService(this); - return true; } @Override - protected boolean stop() { + public void stop() { Log.v(TAG, "stop()"); if (!mIsRegistered) { Log.i(TAG, "Avoid unregister when receiver it is not registered"); - return true; + return; } setSapService(null); try { @@ -724,7 +718,6 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo mAdapterService.unregisterBluetoothStateCallback(this); setState(BluetoothSap.STATE_DISCONNECTED, BluetoothSap.RESULT_CANCELED); sendShutdownMessage(); - return true; } @Override diff --git a/android/app/src/com/android/bluetooth/sdp/SdpManager.java b/android/app/src/com/android/bluetooth/sdp/SdpManager.java index 9ce9037bc4a808afbede01b13720a457c19ace9c..93cb2289005f6efa1d27af4bc49aee451b9fe23e 100644 --- a/android/app/src/com/android/bluetooth/sdp/SdpManager.java +++ b/android/app/src/com/android/bluetooth/sdp/SdpManager.java @@ -34,6 +34,7 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AbstractionLayer; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import java.util.ArrayList; import java.util.Arrays; @@ -436,7 +437,9 @@ public class SdpManager { inst.startSearch(); // Trigger timeout message mNativeInterface.sdpSearch( - sAdapterService.getByteIdentityAddress(inst.getDevice()), + Flags.identityAddressNullIfUnknown() + ? Utils.getByteBrEdrAddress(inst.getDevice()) + : sAdapterService.getByteIdentityAddress(inst.getDevice()), Utils.uuidToByteArray(inst.getUuid())); } else { // Else queue is empty. if (D) { diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java index 50b5f645aa6e0f6832dc2416948cbf1b5eff62cc..9ecefafccabb3b05742c97a755608e57d14c6aaa 100644 --- a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java +++ b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java @@ -1197,7 +1197,7 @@ public class TbsGatt { UUID charUuid = (op.mCharacteristic != null ? op.mCharacteristic.getUuid() : (op.mDescriptor != null ? op.mDescriptor.getCharacteristic().getUuid() : null)); - mEventLogger.logd(DBG, TAG, "onAuthorizedGattOperation device: " + device + mEventLogger.logd(TAG, "onAuthorizedGattOperation device: " + device + ", opcode= " + op.mOperation + ", characteristic= " + (charUuid != null ? tbsUuidToString(charUuid) : "UNKNOWN")); @@ -1362,7 +1362,7 @@ public class TbsGatt { */ public void onDeviceAuthorizationSet(BluetoothDevice device) { int auth = getDeviceAuthorization(device); - mEventLogger.logd(DBG, TAG, "onDeviceAuthorizationSet: device= " + device + mEventLogger.logd(TAG, "onDeviceAuthorizationSet: device= " + device + ", authorization= " + (auth == BluetoothDevice.ACCESS_ALLOWED ? "ALLOWED" : (auth == BluetoothDevice.ACCESS_REJECTED ? "REJECTED" : "UNKNOWN"))); processPendingGattOperations(device); diff --git a/android/app/src/com/android/bluetooth/tbs/TbsService.java b/android/app/src/com/android/bluetooth/tbs/TbsService.java index 9ceba89c8cabea5247c54e225dcebc9246e18b55..676958808cac4caa004361956e58cebd66d23b10 100644 --- a/android/app/src/com/android/bluetooth/tbs/TbsService.java +++ b/android/app/src/com/android/bluetooth/tbs/TbsService.java @@ -25,6 +25,7 @@ import android.bluetooth.BluetoothProfile; import android.bluetooth.IBluetoothLeCallControl; import android.bluetooth.IBluetoothLeCallControlCallback; import android.content.AttributionSource; +import android.content.Context; import android.os.ParcelUuid; import android.os.RemoteException; import android.sysprop.BluetoothProperties; @@ -50,6 +51,10 @@ public class TbsService extends ProfileService { private final TbsGeneric mTbsGeneric = new TbsGeneric(); + public TbsService(Context ctx) { + super(ctx); + } + public static boolean isEnabled() { return BluetoothProperties.isProfileCcpServerEnabled().orElse(false); } @@ -60,7 +65,7 @@ public class TbsService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); @@ -73,18 +78,16 @@ public class TbsService extends ProfileService { setTbsService(this); mTbsGeneric.init(new TbsGatt(this)); - - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sTbsService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } // Mark service as stopped @@ -93,12 +96,10 @@ public class TbsService extends ProfileService { if (mTbsGeneric != null) { mTbsGeneric.cleanup(); } - - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } @@ -142,6 +143,17 @@ public class TbsService extends ProfileService { setDeviceAuthorized(device, false); } + /** + * Remove authorization information for the device. + * + * @param device device to remove from the service information + * @hide + */ + public void removeDeviceAuthorizationInfo(BluetoothDevice device) { + Log.i(TAG, "removeDeviceAuthorizationInfo(): device: " + device); + mDeviceAuthorizations.remove(device); + } + /** * Sets device authorization for TBS. * diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java index 044112d072b968d7bc6070933e9ef54fce09953b..388bb9304dc8a79f1d748cde8c497252888e670f 100644 --- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java +++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java @@ -63,8 +63,8 @@ import java.util.Objects; import java.util.Optional; public class VolumeControlService extends ProfileService { - private static final boolean DBG = false; private static final String TAG = "VolumeControlService"; + private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); // Timeout for state machine thread join, to prevent potential ANR. private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000; @@ -124,24 +124,6 @@ public class VolumeControlService extends ProfileService { return true; } - int getFirstOffsetValue() { - if (size() == 0) { - return 0; - } - Descriptor[] descriptors = mVolumeOffsets.values().toArray(new Descriptor[size()]); - - if (DBG) { - Log.d( - TAG, - "Number of offsets: " - + size() - + ", first offset value: " - + descriptors[0].mValue); - } - - return descriptors[0].mValue; - } - int getValue(int id) { Descriptor d = mVolumeOffsets.get(id); if (d == null) { @@ -218,15 +200,15 @@ public class VolumeControlService extends ProfileService { @VisibleForTesting ServiceFactory mFactory = new ServiceFactory(); - VolumeControlService() { + public VolumeControlService(Context ctx) { + super(ctx); mFeatureFlags = new FeatureFlagsImpl(); } @VisibleForTesting VolumeControlService(Context ctx, FeatureFlags featureFlags) { - attachBaseContext(ctx); + super(ctx); mFeatureFlags = featureFlags; - onCreate(); } public static boolean isEnabled() { @@ -239,7 +221,7 @@ public class VolumeControlService extends ProfileService { } @Override - protected boolean start() { + public void start() { if (DBG) { Log.d(TAG, "start()"); } @@ -277,18 +259,16 @@ public class VolumeControlService extends ProfileService { // Initialize native interface mVolumeControlNativeInterface.init(); - - return true; } @Override - protected boolean stop() { + public void stop() { if (DBG) { Log.d(TAG, "stop()"); } if (sVolumeControlService == null) { Log.w(TAG, "stop() called before start()"); - return true; + return; } // Mark service as stopped @@ -337,12 +317,10 @@ public class VolumeControlService extends ProfileService { mCallbacks.kill(); mCallbacks = null; } - - return true; } @Override - protected void cleanup() { + public void cleanup() { if (DBG) { Log.d(TAG, "cleanup()"); } @@ -426,10 +404,7 @@ public class VolumeControlService extends ProfileService { return true; } - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public List getConnectedDevices() { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); synchronized (mStateMachines) { List devices = new ArrayList<>(); for (VolumeControlStateMachine sm : mStateMachines.values()) { @@ -555,10 +530,7 @@ public class VolumeControlService extends ProfileService { * @param connectionPolicy is the connection policy to set to for this profile * @return true on success, otherwise false */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); if (DBG) { Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy); } @@ -572,10 +544,7 @@ public class VolumeControlService extends ProfileService { return true; } - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(BluetoothDevice device) { - enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.VOLUME_CONTROL); } @@ -589,21 +558,46 @@ public class VolumeControlService extends ProfileService { return true; } - void setVolumeOffset(BluetoothDevice device, int volumeOffset) { + int getNumberOfVolumeOffsetInstances(BluetoothDevice device) { + VolumeControlOffsetDescriptor offsets = mAudioOffsets.get(device); + if (offsets == null) { + Log.i(TAG, " There is no offset service for device: " + device); + return 0; + } + + int numberOfInstances = offsets.size(); + + Log.i(TAG, "Number of VOCS: " + numberOfInstances + ", for device: " + device); + return numberOfInstances; + } + + void setVolumeOffset(BluetoothDevice device, int instanceId, int volumeOffset) { VolumeControlOffsetDescriptor offsets = mAudioOffsets.get(device); if (offsets == null) { Log.e(TAG, " There is no offset service for device: " + device); return; } - /* Use first offset always */ - int value = offsets.getValue(1); + int numberOfInstances = offsets.size(); + if (instanceId > numberOfInstances) { + Log.e( + TAG, + "Selected VOCS instance ID: " + + instanceId + + ", exceed available IDs: " + + numberOfInstances + + ", for device: " + + device); + return; + } + + int value = offsets.getValue(instanceId); if (value == volumeOffset) { /* Nothing to do - offset already applied */ return; } - mVolumeControlNativeInterface.setExtAudioOutVolumeOffset(device, 1, volumeOffset); + mVolumeControlNativeInterface.setExtAudioOutVolumeOffset(device, instanceId, volumeOffset); } void setDeviceVolume(BluetoothDevice device, int volume, boolean isGroupOp) { @@ -721,7 +715,8 @@ public class VolumeControlService extends ProfileService { Boolean groupMute = getGroupMute(groupId); if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) { - updateGroupCacheAndAudioSystem(groupId, groupVolume, groupMute); + /* Don't need to show volume when activating known device. */ + updateGroupCacheAndAudioSystem(groupId, groupVolume, groupMute, /* showInUI*/ false); } } @@ -788,44 +783,82 @@ public class VolumeControlService extends ProfileService { for (Map.Entry entry : mAudioOffsets.entrySet()) { VolumeControlOffsetDescriptor descriptor = entry.getValue(); - if (descriptor.size() == 0) { - continue; - } - - BluetoothDevice device = entry.getKey(); - int offset = descriptor.getFirstOffsetValue(); - if (DBG) { - Log.d( - TAG, - "notifyNewCallbackOfKnownVolumeInfo offset: " + device + ", " + offset); - } + for (int id = 1; id <= descriptor.size(); id++) { + BluetoothDevice device = entry.getKey(); + int offset = descriptor.getValue(id); + int location = descriptor.getLocation(id); + String description = descriptor.getDescription(id); + + if (DBG) { + Log.d( + TAG, + "notifyNewCallbackOfKnownVolumeInfo, device: " + + device + + ", id: " + + id + + ", offset: " + + offset + + ", location: " + + location + + ", description: " + + description); + } - try { - tempCallbackList.getBroadcastItem(i).onVolumeOffsetChanged(device, offset); - } catch (RemoteException e) { - continue; + try { + tempCallbackList + .getBroadcastItem(i) + .onVolumeOffsetChanged(device, id, offset); + } catch (RemoteException e) { + // Not every callback had to be defined; just continue + } + if (mFeatureFlags.leaudioMultipleVocsInstancesApi()) { + try { + tempCallbackList + .getBroadcastItem(i) + .onVolumeOffsetAudioLocationChanged(device, id, location); + } catch (RemoteException e) { + // Not every callback had to be defined; just continue + } + try { + tempCallbackList + .getBroadcastItem(i) + .onVolumeOffsetAudioDescriptionChanged(device, id, description); + } catch (RemoteException e) { + // Not every callback had to be defined; just continue + } + } } } - // notify volume level for all vc devices - if (mFeatureFlags.leaudioBroadcastVolumeControlForConnectedDevices()) { - notifyDevicesVolumeChanged(getDevices(), Optional.empty()); - } } tempCallbackList.finishBroadcast(); + if (mFeatureFlags.leaudioBroadcastVolumeControlForConnectedDevices()) { + notifyDevicesVolumeChanged(tempCallbackList, getDevices(), Optional.empty()); + } + /* User is notified, remove callback from temporary list */ tempCallbackList.unregister(callback); } void registerCallback(IBluetoothVolumeControlCallback callback) { + if (DBG) { + Log.d(TAG, "registerCallback: " + callback); + } /* Here we keep all the user callbacks */ mCallbacks.register(callback); notifyNewCallbackOfKnownVolumeInfo(callback); } + void notifyNewRegisteredCallback(IBluetoothVolumeControlCallback callback) { + if (DBG) { + Log.d(TAG, "notifyNewRegisteredCallback: " + callback); + } + notifyNewCallbackOfKnownVolumeInfo(callback); + } + /** * {@hide} */ @@ -870,7 +903,7 @@ public class VolumeControlService extends ProfileService { } } - void updateGroupCacheAndAudioSystem(int groupId, int volume, boolean mute) { + void updateGroupCacheAndAudioSystem(int groupId, int volume, boolean mute, boolean showInUI) { Log.d( TAG, " updateGroupCacheAndAudioSystem: groupId: " @@ -878,7 +911,9 @@ public class VolumeControlService extends ProfileService { + ", vol: " + volume + ", mute: " - + mute); + + mute + + ", showInUI" + + showInUI); mGroupVolumeCache.put(groupId, volume); mGroupMuteCache.put(groupId, mute); @@ -901,7 +936,11 @@ public class VolumeControlService extends ProfileService { } int streamType = getBluetoothContextualVolumeStream(); - int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME; + int flags = AudioManager.FLAG_BLUETOOTH_ABS_VOLUME; + if (showInUI) { + flags |= AudioManager.FLAG_SHOW_UI; + } + mAudioManager.setStreamVolume(streamType, getAudioDeviceVolume(streamType, volume), flags); if (mAudioManager.isStreamMute(streamType) != mute) { @@ -942,13 +981,15 @@ public class VolumeControlService extends ProfileService { LeAudioService leAudioService = mFactory.getLeAudioService(); if (leAudioService != null) { notifyDevicesVolumeChanged( - leAudioService.getGroupDevices(groupId), Optional.of(volume)); + mCallbacks, + leAudioService.getGroupDevices(groupId), + Optional.of(volume)); } else { Log.w(TAG, "leAudioService not available"); } } else { // notify device volume changed - notifyDevicesVolumeChanged(Arrays.asList(device), Optional.of(volume)); + notifyDevicesVolumeChanged(mCallbacks, Arrays.asList(device), Optional.of(volume)); } } @@ -956,8 +997,9 @@ public class VolumeControlService extends ProfileService { /* We are here, because system was just started and LeAudio device just connected. * In such case, we take Volume stored on remote device and apply it to our cache and * audio system. + * Note, to match BR/EDR behavior, don't show volume change in UI here */ - updateGroupCacheAndAudioSystem(groupId, volume, mute); + updateGroupCacheAndAudioSystem(groupId, volume, mute, false); return; } @@ -1002,7 +1044,7 @@ public class VolumeControlService extends ProfileService { } } else { /* Received group notification for autonomous change. Update cache and audio system. */ - updateGroupCacheAndAudioSystem(groupId, volume, mute); + updateGroupCacheAndAudioSystem(groupId, volume, mute, true); } } @@ -1032,10 +1074,23 @@ public class VolumeControlService extends ProfileService { // Copied from AudioService.getBluetoothContextualVolumeStream() and modified it. int getBluetoothContextualVolumeStream() { int mode = mAudioManager.getMode(); + + if (DBG) { + Log.d(TAG, "Volume mode: " + mode + "0: normal, 1: ring, 2,3: call"); + } + switch (mode) { case AudioManager.MODE_IN_COMMUNICATION: case AudioManager.MODE_IN_CALL: return AudioManager.STREAM_VOICE_CALL; + case AudioManager.MODE_RINGTONE: + if (mFeatureFlags.leaudioVolumeChangeOnRingtoneFix()) { + if (DBG) { + Log.d(TAG, " Update during ringtone applied to voice call"); + } + return AudioManager.STREAM_VOICE_CALL; + } + // fall through case AudioManager.MODE_NORMAL: default: // other conditions will influence the stream type choice, read on... @@ -1064,6 +1119,7 @@ public class VolumeControlService extends ProfileService { for (int i = 1; i <= numberOfExternalOutputs; i++) { offsets.add(i); mVolumeControlNativeInterface.getExtAudioOutVolumeOffset(device, i); + mVolumeControlNativeInterface.getExtAudioOutLocation(device, i); mVolumeControlNativeInterface.getExtAudioOutDescription(device, i); } } @@ -1086,7 +1142,7 @@ public class VolumeControlService extends ProfileService { int n = mCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - mCallbacks.getBroadcastItem(i).onVolumeOffsetChanged(device, value); + mCallbacks.getBroadcastItem(i).onVolumeOffsetChanged(device, id, value); } catch (RemoteException e) { continue; } @@ -1106,10 +1162,28 @@ public class VolumeControlService extends ProfileService { return; } offsets.setLocation(id, location); + + if (mFeatureFlags.leaudioMultipleVocsInstancesApi()) { + if (mCallbacks == null) { + return; + } + + int n = mCallbacks.beginBroadcast(); + for (int i = 0; i < n; i++) { + try { + mCallbacks + .getBroadcastItem(i) + .onVolumeOffsetAudioLocationChanged(device, id, location); + } catch (RemoteException e) { + continue; + } + } + mCallbacks.finishBroadcast(); + } } - void handleDeviceExtAudioDescriptionChanged(BluetoothDevice device, int id, - String description) { + void handleDeviceExtAudioDescriptionChanged( + BluetoothDevice device, int id, String description) { if (DBG) { Log.d(TAG, " device: " + device + " offset_id: " + id + " description: " + description); @@ -1121,6 +1195,24 @@ public class VolumeControlService extends ProfileService { return; } offsets.setDescription(id, description); + + if (mFeatureFlags.leaudioMultipleVocsInstancesApi()) { + if (mCallbacks == null) { + return; + } + + int n = mCallbacks.beginBroadcast(); + for (int i = 0; i < n; i++) { + try { + mCallbacks + .getBroadcastItem(i) + .onVolumeOffsetAudioDescriptionChanged(device, id, description); + } catch (RemoteException e) { + continue; + } + } + mCallbacks.finishBroadcast(); + } } void messageFromNative(VolumeControlStackEvent stackEvent) { @@ -1230,13 +1322,16 @@ public class VolumeControlService extends ProfileService { * newly registered callback, volume level is unknown from caller, notify the clients with * cached volume level from either device or group. * + * @param callbacks list of callbacks * @param devices list of devices to notify volume changed * @param volume volume level */ private void notifyDevicesVolumeChanged( - List devices, Optional volume) { - if (mCallbacks == null) { - Log.e(TAG, "mCallbacks is null"); + RemoteCallbackList callbacks, + List devices, + Optional volume) { + if (callbacks == null) { + Log.e(TAG, "callbacks is null"); return; } @@ -1260,20 +1355,20 @@ public class VolumeControlService extends ProfileService { cachedVolume = getGroupVolume(groupId); } } - int n = mCallbacks.beginBroadcast(); + int broadcastVolume = cachedVolume; + if (volume.isPresent()) { + broadcastVolume = volume.get(); + mDeviceVolumeCache.put(dev, broadcastVolume); + } + int n = callbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { - if (!volume.isPresent()) { - mCallbacks.getBroadcastItem(i).onDeviceVolumeChanged(dev, cachedVolume); - } else { - mDeviceVolumeCache.put(dev, volume.get()); - mCallbacks.getBroadcastItem(i).onDeviceVolumeChanged(dev, volume.get()); - } + callbacks.getBroadcastItem(i).onDeviceVolumeChanged(dev, broadcastVolume); } catch (RemoteException e) { continue; } } - mCallbacks.finishBroadcast(); + callbacks.finishBroadcast(); } } @@ -1524,6 +1619,7 @@ public class VolumeControlService extends ProfileService { VolumeControlService service = getService(source); boolean defaultValue = false; if (service != null) { + enforceBluetoothPrivilegedPermission(service); defaultValue = service.setConnectionPolicy(device, connectionPolicy); } receiver.send(defaultValue); @@ -1543,6 +1639,7 @@ public class VolumeControlService extends ProfileService { VolumeControlService service = getService(source); int defaultValue = BluetoothProfile.CONNECTION_POLICY_UNKNOWN; if (service != null) { + enforceBluetoothPrivilegedPermission(service); defaultValue = service.getConnectionPolicy(device); } receiver.send(defaultValue); @@ -1552,8 +1649,10 @@ public class VolumeControlService extends ProfileService { } @Override - public void isVolumeOffsetAvailable(BluetoothDevice device, - AttributionSource source, SynchronousResultReceiver receiver) { + public void isVolumeOffsetAvailable( + BluetoothDevice device, + AttributionSource source, + SynchronousResultReceiver receiver) { try { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); @@ -1562,6 +1661,7 @@ public class VolumeControlService extends ProfileService { boolean defaultValue = false; VolumeControlService service = getService(source); if (service != null) { + enforceBluetoothPrivilegedPermission(service); defaultValue = service.isVolumeOffsetAvailable(device); } receiver.send(defaultValue); @@ -1571,16 +1671,43 @@ public class VolumeControlService extends ProfileService { } @Override - public void setVolumeOffset(BluetoothDevice device, int volumeOffset, - AttributionSource source, SynchronousResultReceiver receiver) { + public void getNumberOfVolumeOffsetInstances( + BluetoothDevice device, + AttributionSource source, + SynchronousResultReceiver receiver) { try { Objects.requireNonNull(device, "device cannot be null"); Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(receiver, "receiver cannot be null"); + int defaultValue = 0; VolumeControlService service = getService(source); if (service != null) { - service.setVolumeOffset(device, volumeOffset); + enforceBluetoothPrivilegedPermission(service); + defaultValue = service.getNumberOfVolumeOffsetInstances(device); + } + receiver.send(defaultValue); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + + @Override + public void setVolumeOffset( + BluetoothDevice device, + int instanceId, + int volumeOffset, + AttributionSource source, + SynchronousResultReceiver receiver) { + try { + Objects.requireNonNull(device, "device cannot be null"); + Objects.requireNonNull(source, "source cannot be null"); + Objects.requireNonNull(receiver, "receiver cannot be null"); + + VolumeControlService service = getService(source); + if (service != null) { + enforceBluetoothPrivilegedPermission(service); + service.setVolumeOffset(device, instanceId, volumeOffset); } receiver.send(null); } catch (RuntimeException e) { @@ -1602,6 +1729,7 @@ public class VolumeControlService extends ProfileService { VolumeControlService service = getService(source); if (service != null) { + enforceBluetoothPrivilegedPermission(service); service.setDeviceVolume(device, volume, isGroupOp); } receiver.send(null); @@ -1763,6 +1891,36 @@ public class VolumeControlService extends ProfileService { } } + @Override + public void notifyNewRegisteredCallback( + IBluetoothVolumeControlCallback callback, + AttributionSource source, + SynchronousResultReceiver receiver) { + try { + Objects.requireNonNull(callback, "callback cannot be null"); + Objects.requireNonNull(source, "source cannot be null"); + Objects.requireNonNull(receiver, "receiver cannot be null"); + + VolumeControlService service = getService(source); + if (service == null) { + throw new IllegalStateException("Service is unavailable"); + } + + enforceBluetoothPrivilegedPermission(service); + service.mHandler.post( + () -> { + try { + service.notifyNewRegisteredCallback(callback); + receiver.send(null); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + }); + } catch (RuntimeException e) { + receiver.propagateException(e); + } + } + @Override public void unregisterCallback(IBluetoothVolumeControlCallback callback, AttributionSource source, SynchronousResultReceiver receiver) { diff --git a/android/app/tests/unit/Android.bp b/android/app/tests/unit/Android.bp index ab75ba59a5779bdbca850556bc08b0b2916d61c1..258629c88e366a4f28074d0851837e015abc2f22 100644 --- a/android/app/tests/unit/Android.bp +++ b/android/app/tests/unit/Android.bp @@ -27,10 +27,12 @@ java_defaults { "androidx.test.ext.truth", "androidx.test.rules", "androidx.test.uiautomator_uiautomator", + "flag-junit", "framework-bluetooth-pre-jarjar", "frameworks-base-testutils", "gson", "mockito-target", + "platform-test-annotations", "truth", ], diff --git a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java index 24f43bc9f22426be038a34cd07e9c4669ba6a5e8..06011af362dcfa33869355285a112364a1f57321 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java +++ b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java @@ -136,82 +136,6 @@ public class TestUtils { return mockedService; } - /** - * Start a profile service using the given {@link ServiceTestRule} and verify through - * {@link AdapterService#getAdapterService()} that the service is actually started within - * {@link TestUtils#SERVICE_TOGGLE_TIMEOUT_MS} milliseconds. - * {@link #setAdapterService(AdapterService)} must be called with a mocked - * {@link AdapterService} before calling this method - * - * @param serviceTestRule the {@link ServiceTestRule} used to execute the service start - * request - * @param profileServiceClass a class from one of {@link ProfileService}'s child classes - * @throws TimeoutException when service failed to start within either default timeout of - * {@link ServiceTestRule#DEFAULT_TIMEOUT} (normally 5s) or user - * specified time when creating - * {@link ServiceTestRule} through - * {@link ServiceTestRule#withTimeout(long, TimeUnit)} method - */ - public static void startService(ServiceTestRule serviceTestRule, - Class profileServiceClass) throws TimeoutException { - if (profileServiceClass == GattService.class) { - Assert.assertFalse("GattService cannot be started as a service", true); - } - AdapterService adapterService = AdapterService.getAdapterService(); - Assert.assertNotNull("Adapter service should not be null", adapterService); - Assert.assertTrue("AdapterService.getAdapterService() must return a mocked or spied object" - + " before calling this method", MockUtil.isMock(adapterService)); - Intent startIntent = - new Intent(InstrumentationRegistry.getTargetContext(), profileServiceClass); - startIntent.putExtra(AdapterService.EXTRA_ACTION, - AdapterService.ACTION_SERVICE_STATE_CHANGED); - startIntent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON); - serviceTestRule.startService(startIntent); - ArgumentCaptor profile = ArgumentCaptor.forClass(profileServiceClass); - verify(adapterService, timeout(SERVICE_TOGGLE_TIMEOUT_MS)).onProfileServiceStateChanged( - profile.capture(), eq(BluetoothAdapter.STATE_ON)); - Assert.assertEquals(profileServiceClass.getName(), profile.getValue().getClass().getName()); - } - - /** - * Stop a profile service using the given {@link ServiceTestRule} and verify through - * {@link AdapterService#getAdapterService()} that the service is actually stopped within - * {@link TestUtils#SERVICE_TOGGLE_TIMEOUT_MS} milliseconds. - * {@link #setAdapterService(AdapterService)} must be called with a mocked - * {@link AdapterService} before calling this method - * - * @param serviceTestRule the {@link ServiceTestRule} used to execute the service start - * request - * @param profileServiceClass a class from one of {@link ProfileService}'s child classes - * @throws TimeoutException when service failed to start within either default timeout of - * {@link ServiceTestRule#DEFAULT_TIMEOUT} (normally 5s) or user - * specified time when creating - * {@link ServiceTestRule} through - * {@link ServiceTestRule#withTimeout(long, TimeUnit)} method - */ - public static void stopService(ServiceTestRule serviceTestRule, - Class profileServiceClass) throws TimeoutException { - AdapterService adapterService = AdapterService.getAdapterService(); - Assert.assertNotNull(adapterService); - Assert.assertTrue("AdapterService.getAdapterService() must return a mocked or spied object" - + " before calling this method", MockUtil.isMock(adapterService)); - Intent stopIntent = - new Intent(InstrumentationRegistry.getTargetContext(), profileServiceClass); - stopIntent.putExtra(AdapterService.EXTRA_ACTION, - AdapterService.ACTION_SERVICE_STATE_CHANGED); - stopIntent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF); - serviceTestRule.startService(stopIntent); - ArgumentCaptor profile = ArgumentCaptor.forClass(profileServiceClass); - verify(adapterService, timeout(SERVICE_TOGGLE_TIMEOUT_MS)).onProfileServiceStateChanged( - profile.capture(), eq(BluetoothAdapter.STATE_OFF)); - Assert.assertEquals(profileServiceClass.getName(), profile.getValue().getClass().getName()); - ArgumentCaptor profile2 = ArgumentCaptor.forClass(profileServiceClass); - verify(adapterService, timeout(SERVICE_TOGGLE_TIMEOUT_MS)).removeProfile( - profile2.capture()); - Assert.assertEquals(profileServiceClass.getName(), - profile2.getValue().getClass().getName()); - } - /** * Create a test device. * diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java index b85024558b3c0863be5f6a7f8e5489c0a63a7d19..58655f6a2c42432f185b874849a9ff8ff297fced 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceBinderTest.java @@ -18,6 +18,8 @@ package com.android.bluetooth.a2dp; import static android.bluetooth.BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; @@ -29,14 +31,18 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BufferConstraints; import android.content.AttributionSource; - -import androidx.test.InstrumentationRegistry; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.platform.test.flag.junit.SetFlagsRule; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.btservice.AudioRoutingManager; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -44,242 +50,225 @@ import org.mockito.MockitoAnnotations; import java.util.List; public class A2dpServiceBinderTest { - @Mock private A2dpService mService; + private static final AttributionSource sSource = new AttributionSource.Builder(0).build(); + private static final BluetoothAdapter sAdapter = BluetoothAdapter.getDefaultAdapter(); + private static final BluetoothDevice sDevice = TestUtils.getTestDevice(sAdapter, 0); + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + @Mock private A2dpService mA2dpService; + @Mock private AudioRoutingManager mAudioRoutingManager; + @Mock private PackageManager mPackageManager; private A2dpService.BluetoothA2dpBinder mBinder; - private BluetoothAdapter mAdapter; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + doReturn(mAudioRoutingManager).when(mA2dpService).getActiveDeviceManager(); + doReturn(mPackageManager).when(mA2dpService).getPackageManager(); + ApplicationInfo appInfo = new ApplicationInfo(); + appInfo.targetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; + doReturn(appInfo).when(mPackageManager).getApplicationInfo(any(), anyInt()); - mAdapter = BluetoothAdapter.getDefaultAdapter(); - mBinder = new A2dpService.BluetoothA2dpBinder(mService); - doReturn(InstrumentationRegistry.getTargetContext().getPackageManager()) - .when(mService).getPackageManager(); + mBinder = new A2dpService.BluetoothA2dpBinder(mA2dpService); } @After - public void cleaUp() { + public void cleanUp() { mBinder.cleanup(); } @Test public void connect() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.connect(device, source, recv); - verify(mService).connect(device); + mBinder.connect(sDevice, sSource, recv); + verify(mA2dpService).connect(sDevice); } @Test public void disconnect() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.disconnect(device, source, recv); - verify(mService).disconnect(device); + mBinder.disconnect(sDevice, sSource, recv); + verify(mA2dpService).disconnect(sDevice); } @Test public void getConnectedDevices() { - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver> recv = SynchronousResultReceiver.get(); - mBinder.getConnectedDevices(source, recv); - verify(mService).getConnectedDevices(); + mBinder.getConnectedDevices(sSource, recv); + verify(mA2dpService).getConnectedDevices(); } @Test public void getDevicesMatchingConnectionStates() { int[] states = new int[] {BluetoothProfile.STATE_CONNECTED }; - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver> recv = SynchronousResultReceiver.get(); - mBinder.getDevicesMatchingConnectionStates(states, source, recv); - verify(mService).getDevicesMatchingConnectionStates(states); + mBinder.getDevicesMatchingConnectionStates(states, sSource, recv); + verify(mA2dpService).getDevicesMatchingConnectionStates(states); } @Test public void getConnectionState() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver> recv = SynchronousResultReceiver.get(); - mBinder.getConnectionState(device, source, recv); - verify(mService).getConnectionState(device); + mBinder.getConnectionState(sDevice, sSource, recv); + verify(mA2dpService).getConnectionState(sDevice); } @Test public void setActiveDevice() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + + SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mBinder.setActiveDevice(sDevice, sSource, recv); + verify(mA2dpService).setActiveDevice(sDevice); + } + + @Test + public void setActiveDeviceWithAudioRouting() { + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); - mBinder.setActiveDevice(device, source, recv); - verify(mService).setActiveDevice(device); + SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mBinder.setActiveDevice(sDevice, sSource, recv); + verify(mAudioRoutingManager).activateDeviceProfile(sDevice, BluetoothProfile.A2DP, recv); } @Test public void setActiveDevice_withNull_callsRemoveActiveDevice() { - BluetoothDevice device = null; - AttributionSource source = new AttributionSource.Builder(0).build(); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.setActiveDevice(device, source, recv); - verify(mService).removeActiveDevice(false); + mBinder.setActiveDevice(null, sSource, recv); + verify(mA2dpService).removeActiveDevice(false); } @Test public void getActiveDevice() { - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.getActiveDevice(source, recv); - verify(mService).getActiveDevice(); + mBinder.getActiveDevice(sSource, recv); + verify(mA2dpService).getActiveDevice(); } @Test public void setConnectionPolicy() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); int connectionPolicy = BluetoothProfile.CONNECTION_POLICY_ALLOWED; - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.setConnectionPolicy(device, connectionPolicy, source, recv); - verify(mService).setConnectionPolicy(device, connectionPolicy); + mBinder.setConnectionPolicy(sDevice, connectionPolicy, sSource, recv); + verify(mA2dpService).setConnectionPolicy(sDevice, connectionPolicy); } @Test public void getConnectionPolicy() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.getConnectionPolicy(device, source, recv); - verify(mService).getConnectionPolicy(device); + mBinder.getConnectionPolicy(sDevice, sSource, recv); + verify(mA2dpService).getConnectionPolicy(sDevice); } @Test public void setAvrcpAbsoluteVolume() { int volume = 3; - AttributionSource source = new AttributionSource.Builder(0).build(); - mBinder.setAvrcpAbsoluteVolume(volume, source); - verify(mService).setAvrcpAbsoluteVolume(volume); + mBinder.setAvrcpAbsoluteVolume(volume, sSource); + verify(mA2dpService).setAvrcpAbsoluteVolume(volume); } @Test public void isA2dpPlaying() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.isA2dpPlaying(device, source, recv); - verify(mService).isA2dpPlaying(device); + mBinder.isA2dpPlaying(sDevice, sSource, recv); + verify(mA2dpService).isA2dpPlaying(sDevice); } @Test public void getCodecStatus() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.getCodecStatus(device, source, recv); - verify(mService).getCodecStatus(device); + mBinder.getCodecStatus(sDevice, sSource, recv); + verify(mA2dpService).getCodecStatus(sDevice); } @Test public void setCodecConfigPreference() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); BluetoothCodecConfig config = new BluetoothCodecConfig(SOURCE_CODEC_TYPE_INVALID); - AttributionSource source = new AttributionSource.Builder(0).build(); - mBinder.setCodecConfigPreference(device, config, source); - verify(mService).setCodecConfigPreference(device, config); + mBinder.setCodecConfigPreference(sDevice, config, sSource); + verify(mA2dpService).setCodecConfigPreference(sDevice, config); } @Test public void enableOptionalCodecs() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); - mBinder.enableOptionalCodecs(device, source); - verify(mService).enableOptionalCodecs(device); + mBinder.enableOptionalCodecs(sDevice, sSource); + verify(mA2dpService).enableOptionalCodecs(sDevice); } @Test public void disableOptionalCodecs() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); - mBinder.disableOptionalCodecs(device, source); - verify(mService).disableOptionalCodecs(device); + mBinder.disableOptionalCodecs(sDevice, sSource); + verify(mA2dpService).disableOptionalCodecs(sDevice); } @Test public void isOptionalCodecsSupported() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.isOptionalCodecsSupported(device, source, recv); - verify(mService).getSupportsOptionalCodecs(device); + mBinder.isOptionalCodecsSupported(sDevice, sSource, recv); + verify(mA2dpService).getSupportsOptionalCodecs(sDevice); } @Test public void isOptionalCodecsEnabled() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.isOptionalCodecsEnabled(device, source, recv); - verify(mService).getOptionalCodecsEnabled(device); + mBinder.isOptionalCodecsEnabled(sDevice, sSource, recv); + verify(mA2dpService).getOptionalCodecsEnabled(sDevice); } @Test public void setOptionalCodecsEnabled() { - BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); int value = BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN; - AttributionSource source = new AttributionSource.Builder(0).build(); - mBinder.setOptionalCodecsEnabled(device, value, source); - verify(mService).setOptionalCodecsEnabled(device, value); + mBinder.setOptionalCodecsEnabled(sDevice, value, sSource); + verify(mA2dpService).setOptionalCodecsEnabled(sDevice, value); } @Test public void getDynamicBufferSupport() { - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.getDynamicBufferSupport(source, recv); - verify(mService).getDynamicBufferSupport(); + mBinder.getDynamicBufferSupport(sSource, recv); + verify(mA2dpService).getDynamicBufferSupport(); } @Test public void getBufferConstraints() { - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.getBufferConstraints(source, recv); - verify(mService).getBufferConstraints(); + mBinder.getBufferConstraints(sSource, recv); + verify(mA2dpService).getBufferConstraints(); } @Test public void setBufferLengthMillis() { int codec = 0; int value = BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN; - AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBinder.setBufferLengthMillis(codec, value, source, recv); - verify(mService).setBufferLengthMillis(codec, value); + mBinder.setBufferLengthMillis(codec, value, sSource, recv); + verify(mA2dpService).setBufferLengthMillis(codec, value); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java index c2b0da8cc77dbf570628a5b171b25967174c2974..faa2833dfcefc09c64fcaae7371322a7a3a6dea7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpServiceTest.java @@ -16,6 +16,9 @@ package com.android.bluetooth.a2dp; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; + import static org.mockito.Mockito.*; import android.bluetooth.BluetoothA2dp; @@ -25,10 +28,8 @@ import android.bluetooth.BluetoothCodecStatus; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.media.AudioManager; import android.media.BluetoothProfileConnectionInfo; import android.os.Looper; @@ -36,7 +37,6 @@ import android.os.ParcelUuid; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; -import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; @@ -44,195 +44,100 @@ import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.SilenceDeviceManager; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.flags.FakeFeatureFlagsImpl; -import com.android.bluetooth.flags.Flags; +import org.hamcrest.Matcher; +import org.hamcrest.core.AllOf; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.hamcrest.MockitoHamcrest; +import java.time.Duration; import java.util.Arrays; import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; @MediumTest @RunWith(AndroidJUnit4.class) public class A2dpServiceTest { private static final int MAX_CONNECTED_AUDIO_DEVICES = 5; + private static final Duration TIMEOUT = Duration.ofSeconds(1); - private BluetoothAdapter mAdapter; - private Context mTargetContext; - private A2dpService mA2dpService; - private BluetoothDevice mTestDevice; - private static final int TIMEOUT_MS = 1000; // 1s - - private BroadcastReceiver mA2dpIntentReceiver; - private final BlockingQueue mConnectionStateChangedQueue = new LinkedBlockingQueue<>(); - private final BlockingQueue mAudioStateChangedQueue = new LinkedBlockingQueue<>(); - private final BlockingQueue mCodecConfigChangedQueue = new LinkedBlockingQueue<>(); - private final BlockingQueue mActiveDeviceQueue = new LinkedBlockingQueue<>(); + private static final BluetoothAdapter sAdapter = BluetoothAdapter.getDefaultAdapter(); + private static final BluetoothDevice sTestDevice = + sAdapter.getRemoteDevice("00:01:02:03:04:05"); - private FakeFeatureFlagsImpl mFakeFlagsImpl; - @Mock private AdapterService mAdapterService; - @Mock private ActiveDeviceManager mActiveDeviceManager; @Mock private A2dpNativeInterface mMockNativeInterface; + @Mock private ActiveDeviceManager mActiveDeviceManager; + @Mock private AdapterService mAdapterService; + @Mock private AudioManager mAudioManager; @Mock private DatabaseManager mDatabaseManager; @Mock private SilenceDeviceManager mSilenceDeviceManager; + private InOrder mInOrder = null; - @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); + private A2dpService mA2dpService; @Before public void setUp() throws Exception { - mTargetContext = InstrumentationRegistry.getTargetContext(); // Set up mocks and test assets MockitoAnnotations.initMocks(this); + mInOrder = inOrder(mAdapterService); + + TestUtils.mockGetSystemService( + mAdapterService, Context.AUDIO_SERVICE, AudioManager.class, mAudioManager); + doReturn(InstrumentationRegistry.getTargetContext().getResources()) + .when(mAdapterService) + .getResources(); if (Looper.myLooper() == null) { Looper.prepare(); } - TestUtils.setAdapterService(mAdapterService); doReturn(true).when(mAdapterService).isA2dpOffloadEnabled(); doReturn(MAX_CONNECTED_AUDIO_DEVICES).when(mAdapterService).getMaxConnectedAudioDevices(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); doReturn(false).when(mAdapterService).isQuietModeEnabled(); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager(); doReturn(mSilenceDeviceManager).when(mAdapterService).getSilenceDeviceManager(); - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, false); - mAdapter = BluetoothAdapter.getDefaultAdapter(); - mA2dpService = new A2dpService(mTargetContext, mMockNativeInterface, mFakeFlagsImpl); - mA2dpService.doStart(); + mA2dpService = new A2dpService(mAdapterService, mMockNativeInterface); + mA2dpService.start(); + mA2dpService.setAvailable(true); // Override the timeout value to speed up the test - A2dpStateMachine.sConnectTimeoutMs = TIMEOUT_MS; // 1s - - // Set up the Connection State Changed receiver - IntentFilter filter = new IntentFilter(); - filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); - filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); - filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED); - filter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED); - mA2dpIntentReceiver = new A2dpIntentReceiver(); - mTargetContext.registerReceiver(mA2dpIntentReceiver, filter); + A2dpStateMachine.sConnectTimeoutMs = (int) TIMEOUT.toMillis(); // Get a device for testing - mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); - doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); - doReturn(new ParcelUuid[]{BluetoothUuid.A2DP_SINK}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.A2DP_SINK}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); } @After public void tearDown() throws Exception { - mA2dpService.doStop(); - mTargetContext.unregisterReceiver(mA2dpIntentReceiver); - mConnectionStateChangedQueue.clear(); - mAudioStateChangedQueue.clear(); - mCodecConfigChangedQueue.clear(); - mActiveDeviceQueue.clear(); - TestUtils.clearAdapterService(mAdapterService); - } - - private class A2dpIntentReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) { - try { - mConnectionStateChangedQueue.put(intent); - } catch (InterruptedException e) { - Assert.fail("Cannot add Intent to the Connection State queue: " - + e.getMessage()); - } - } - if (BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED.equals(intent.getAction())) { - try { - mAudioStateChangedQueue.put(intent); - } catch (InterruptedException e) { - Assert.fail("Cannot add Intent to the Audio State queue: " + e.getMessage()); - } - } - if (BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED.equals(intent.getAction())) { - try { - mCodecConfigChangedQueue.put(intent); - } catch (InterruptedException e) { - Assert.fail("Cannot add Intent to the Codec Config queue: " + e.getMessage()); - } - } - if (BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED.equals(intent.getAction())) { - try { - mActiveDeviceQueue.put(intent); - } catch (InterruptedException e) { - Assert.fail("Cannot add Intent to the device queue: " + e.getMessage()); - } - } - } - } - - private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device, - int newState, int prevState) { - Intent intent = TestUtils.waitForIntent(timeoutMs, mConnectionStateChangedQueue); - Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, - intent.getAction()); - Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertEquals(prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, - -1)); + mA2dpService.stop(); } - private void verifyNoConnectionStateIntent(int timeoutMs) { - Intent intent = TestUtils.waitForNoIntent(timeoutMs, mConnectionStateChangedQueue); - Assert.assertNull(intent); + @SafeVarargs + private void verifyIntentSent(Matcher... matchers) { + mInOrder.verify(mAdapterService, timeout(TIMEOUT.toMillis() * 2)) + .sendBroadcast(MockitoHamcrest.argThat(AllOf.allOf(matchers)), any(), any()); } - private void verifyAudioStateIntent(int timeoutMs, BluetoothDevice device, - int newState, int prevState) { - Intent intent = TestUtils.waitForIntent(timeoutMs, mAudioStateChangedQueue); - Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED, intent.getAction()); - Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertEquals(prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, - -1)); - } - - private void verifyNoAudioStateIntent(int timeoutMs) { - Intent intent = TestUtils.waitForNoIntent(timeoutMs, mAudioStateChangedQueue); - Assert.assertNull(intent); - } - - private void verifyCodecConfigIntent(int timeoutMs, BluetoothDevice device, - BluetoothCodecStatus codecStatus) { - Intent intent = TestUtils.waitForIntent(timeoutMs, mCodecConfigChangedQueue); - Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED, intent.getAction()); - Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(codecStatus, - intent.getParcelableExtra(BluetoothCodecStatus.EXTRA_CODEC_STATUS)); - } - - private void verifyNoCodecConfigIntent(int timeoutMs) { - Intent intent = TestUtils.waitForNoIntent(timeoutMs, mCodecConfigChangedQueue); - Assert.assertNull(intent); - } - - private void veifyActiveDeviceIntent(int timeoutMs, BluetoothDevice device) { - Intent intent = TestUtils.waitForIntent(timeoutMs, mActiveDeviceQueue); - Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, intent.getAction()); - Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); + private void verifyConnectionStateIntent(BluetoothDevice device, int newState, int prevState) { + verifyIntentSent( + hasAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, device), + hasExtra(BluetoothProfile.EXTRA_STATE, newState), + hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState)); } @Test @@ -244,211 +149,232 @@ public class A2dpServiceTest { public void testStopA2dpService() { // Prepare: connect and set active device doReturn(true).when(mMockNativeInterface).setActiveDevice(any(BluetoothDevice.class)); - connectDevice(mTestDevice); - Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); - verify(mMockNativeInterface).setActiveDevice(mTestDevice); + connectDevice(sTestDevice); + Assert.assertTrue(mA2dpService.setActiveDevice(sTestDevice)); + verify(mMockNativeInterface).setActiveDevice(sTestDevice); - Assert.assertTrue(mA2dpService.stop()); + mA2dpService.stop(); // Verify that setActiveDevice(null) was called during shutdown verify(mMockNativeInterface).setActiveDevice(null); - Assert.assertTrue(mA2dpService.start()); + mA2dpService.start(); } - /** - * Test get priority for BluetoothDevice - */ + /** Test get priority for BluetoothDevice */ @Test public void testGetPriority() { - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); - Assert.assertEquals("Initial device priority", - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, - mA2dpService.getConnectionPolicy(mTestDevice)); + Assert.assertEquals( + "Initial device priority", + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + mA2dpService.getConnectionPolicy(sTestDevice)); - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - Assert.assertEquals("Setting device priority to PRIORITY_OFF", - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, - mA2dpService.getConnectionPolicy(mTestDevice)); + Assert.assertEquals( + "Setting device priority to PRIORITY_OFF", + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + mA2dpService.getConnectionPolicy(sTestDevice)); - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - Assert.assertEquals("Setting device priority to PRIORITY_ON", - BluetoothProfile.CONNECTION_POLICY_ALLOWED, - mA2dpService.getConnectionPolicy(mTestDevice)); + Assert.assertEquals( + "Setting device priority to PRIORITY_ON", + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + mA2dpService.getConnectionPolicy(sTestDevice)); } - /** - * Test okToConnect method using various test cases - */ + /** Test okToConnect method using various test cases */ @Test public void testOkToConnect() { int badPriorityValue = 1024; int badBondState = 42; - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_NONE, badPriorityValue, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDING, badPriorityValue, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testOkToConnectCase(mTestDevice, - BluetoothDevice.BOND_BONDED, badPriorityValue, false); - testOkToConnectCase(mTestDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mTestDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mTestDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mTestDevice, - badBondState, badPriorityValue, false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(sTestDevice, BluetoothDevice.BOND_NONE, badPriorityValue, false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(sTestDevice, BluetoothDevice.BOND_BONDING, badPriorityValue, false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + sTestDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testOkToConnectCase(sTestDevice, BluetoothDevice.BOND_BONDED, badPriorityValue, false); + testOkToConnectCase( + sTestDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testOkToConnectCase( + sTestDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); + testOkToConnectCase( + sTestDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testOkToConnectCase(sTestDevice, badBondState, badPriorityValue, false); } - - /** - * Test that an outgoing connection to device that does not have A2DP Sink UUID is rejected - */ + /** Test that an outgoing connection to device that does not have A2DP Sink UUID is rejected */ @Test public void testOutgoingConnectMissingAudioSinkUuid() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // Return AudioSource UUID instead of AudioSink - doReturn(new ParcelUuid[]{BluetoothUuid.A2DP_SOURCE}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.A2DP_SOURCE}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request - Assert.assertFalse("Connect expected to fail", mA2dpService.connect(mTestDevice)); + Assert.assertFalse("Connect expected to fail", mA2dpService.connect(sTestDevice)); } - /** - * Test that an outgoing connection to device with PRIORITY_OFF is rejected - */ + /** Test that an outgoing connection to device with PRIORITY_OFF is rejected */ @Test public void testOutgoingConnectPriorityOff() { doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // Set the device priority to PRIORITY_OFF so connect() should fail - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Send a connect request - Assert.assertFalse("Connect expected to fail", mA2dpService.connect(mTestDevice)); + Assert.assertFalse("Connect expected to fail", mA2dpService.connect(sTestDevice)); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingConnectTimeout() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mA2dpService.connect(mTestDevice)); + Assert.assertTrue("Connect failed", mA2dpService.connect(sTestDevice)); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(mTestDevice)); + verifyConnectionStateIntent( + sTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(sTestDevice)); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(A2dpStateMachine.sConnectTimeoutMs * 2, - mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); + verifyConnectionStateIntent( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); } - /** - * Test that an outgoing connection/disconnection succeeds - */ + /** Test that an outgoing connection/disconnection succeeds */ @Test public void testOutgoingConnectDisconnectSuccess() { A2dpStackEvent connCompletedEvent; // Update the device priority so okToConnect() returns true - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mA2dpService.connect(mTestDevice)); + Assert.assertTrue("Connect failed", mA2dpService.connect(sTestDevice)); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(mTestDevice)); + verifyConnectionStateIntent( + sTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(sTestDevice)); // Send a message to trigger connection completed connCompletedEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - connCompletedEvent.device = mTestDevice; + connCompletedEvent.device = sTestDevice; connCompletedEvent.valueInt = A2dpStackEvent.CONNECTION_STATE_CONNECTED; mA2dpService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(mTestDevice)); + verifyConnectionStateIntent( + sTestDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(sTestDevice)); // Verify the list of connected devices - Assert.assertTrue(mA2dpService.getConnectedDevices().contains(mTestDevice)); + Assert.assertTrue(mA2dpService.getConnectedDevices().contains(sTestDevice)); // Send a disconnect request - Assert.assertTrue("Disconnect failed", mA2dpService.disconnect(mTestDevice)); + Assert.assertTrue("Disconnect failed", mA2dpService.disconnect(sTestDevice)); // Verify the connection state broadcast, and that we are in Disconnecting state - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_DISCONNECTING, - BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, - mA2dpService.getConnectionState(mTestDevice)); + verifyConnectionStateIntent( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTING, mA2dpService.getConnectionState(sTestDevice)); // Send a message to trigger disconnection completed connCompletedEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); - connCompletedEvent.device = mTestDevice; + connCompletedEvent.device = sTestDevice; connCompletedEvent.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED; mA2dpService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_DISCONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); + verifyConnectionStateIntent( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_DISCONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); // Verify the list of connected devices - Assert.assertFalse(mA2dpService.getConnectedDevices().contains(mTestDevice)); + Assert.assertFalse(mA2dpService.getConnectedDevices().contains(sTestDevice)); } - /** - * Test that an outgoing connection/disconnection succeeds - */ + /** Test that an outgoing connection/disconnection succeeds */ @Test public void testMaxConnectDevices() { A2dpStackEvent connCompletedEvent; @@ -460,35 +386,39 @@ public class A2dpServiceTest { // Prepare and connect all test devices for (int i = 0; i < MAX_CONNECTED_AUDIO_DEVICES; i++) { - BluetoothDevice testDevice = TestUtils.getTestDevice(mAdapter, i); + BluetoothDevice testDevice = TestUtils.getTestDevice(sAdapter, i); testDevices[i] = testDevice; when(mDatabaseManager.getProfileConnectionPolicy(testDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Send a connect request Assert.assertTrue("Connect failed", mA2dpService.connect(testDevice)); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, testDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(testDevice)); + verifyConnectionStateIntent( + testDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(testDevice)); // Send a message to trigger connection completed connCompletedEvent = - new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = testDevice; connCompletedEvent.valueInt = A2dpStackEvent.CONNECTION_STATE_CONNECTED; mA2dpService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, testDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(testDevice)); + verifyConnectionStateIntent( + testDevice, + BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(testDevice)); // Verify the list of connected devices Assert.assertTrue(mA2dpService.getConnectedDevices().contains(testDevice)); } // Prepare and connect the extra test device. The connect request should fail - extraTestDevice = TestUtils.getTestDevice(mAdapter, MAX_CONNECTED_AUDIO_DEVICES); + extraTestDevice = TestUtils.getTestDevice(sAdapter, MAX_CONNECTED_AUDIO_DEVICES); when(mDatabaseManager.getProfileConnectionPolicy(extraTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); // Send a connect request @@ -501,70 +431,79 @@ public class A2dpServiceTest { */ @Test public void testCreateStateMachineStackEvents() { - A2dpStackEvent stackEvent; - // Update the device priority so okToConnect() returns true - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // A2DP stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_CONNECTED - state machine should be created - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); + + // A2DP stack event: EVENT_TYPE_AUDIO_STATE_CHANGED - Intent broadcast should be generated + // NOTE: The first message (STATE_PLAYING -> STATE_NOT_PLAYING) is generated internally + // by the state machine when Connected, and needs to be extracted first before generating + // the actual message from native. + verifyIntentSent( + hasAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, sTestDevice), + hasExtra(BluetoothProfile.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING), + hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothA2dp.STATE_PLAYING)); // A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTING - state machine should not be created - generateUnexpectedConnectionMessageFromNative(mTestDevice, - BluetoothProfile.STATE_DISCONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateUnexpectedConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_DISCONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine should not be created - generateUnexpectedConnectionMessageFromNative(mTestDevice, - BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateUnexpectedConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); } /** - * Test that EVENT_TYPE_AUDIO_STATE_CHANGED and EVENT_TYPE_CODEC_CONFIG_CHANGED events - * are processed. + * Test that EVENT_TYPE_AUDIO_STATE_CHANGED and EVENT_TYPE_CODEC_CONFIG_CHANGED events are + * processed. */ @Test public void testProcessAudioStateChangedCodecConfigChangedEvents() { - A2dpStackEvent stackEvent; BluetoothCodecConfig codecConfigSbc = buildBluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, @@ -572,71 +511,79 @@ public class A2dpServiceTest { BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0); // Codec-specific fields + 0, + 0, + 0, + 0); // Codec-specific fields BluetoothCodecConfig codecConfig = codecConfigSbc; BluetoothCodecConfig[] codecsLocalCapabilities = new BluetoothCodecConfig[1]; BluetoothCodecConfig[] codecsSelectableCapabilities = new BluetoothCodecConfig[1]; codecsLocalCapabilities[0] = codecConfigSbc; codecsSelectableCapabilities[0] = codecConfigSbc; - BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(codecConfig, - Arrays.asList(codecsLocalCapabilities), - Arrays.asList(codecsSelectableCapabilities)); + BluetoothCodecStatus codecStatus = + new BluetoothCodecStatus( + codecConfig, + Arrays.asList(codecsLocalCapabilities), + Arrays.asList(codecsSelectableCapabilities)); // Update the device priority so okToConnect() returns true - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // A2DP stack event: EVENT_TYPE_AUDIO_STATE_CHANGED - state machine should not be created - generateUnexpectedAudioMessageFromNative(mTestDevice, A2dpStackEvent.AUDIO_STATE_STARTED, - BluetoothA2dp.STATE_PLAYING, - BluetoothA2dp.STATE_NOT_PLAYING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateUnexpectedAudioMessageFromNative(sTestDevice, A2dpStackEvent.AUDIO_STATE_STARTED); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: EVENT_TYPE_CODEC_CONFIG_CHANGED - state machine should not be created - generateUnexpectedCodecMessageFromNative(mTestDevice, codecStatus); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateUnexpectedCodecMessageFromNative(sTestDevice, codecStatus); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_CONNECTED - state machine should be created - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: EVENT_TYPE_AUDIO_STATE_CHANGED - Intent broadcast should be generated // NOTE: The first message (STATE_PLAYING -> STATE_NOT_PLAYING) is generated internally // by the state machine when Connected, and needs to be extracted first before generating // the actual message from native. - verifyAudioStateIntent(TIMEOUT_MS, mTestDevice, BluetoothA2dp.STATE_NOT_PLAYING, - BluetoothA2dp.STATE_PLAYING); - generateAudioMessageFromNative(mTestDevice, - A2dpStackEvent.AUDIO_STATE_STARTED, - BluetoothA2dp.STATE_PLAYING, - BluetoothA2dp.STATE_NOT_PLAYING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + verifyIntentSent( + hasAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, sTestDevice), + hasExtra(BluetoothProfile.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING), + hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothA2dp.STATE_PLAYING)); + + generateAudioMessageFromNative( + sTestDevice, + A2dpStackEvent.AUDIO_STATE_STARTED, + BluetoothA2dp.STATE_PLAYING, + BluetoothA2dp.STATE_NOT_PLAYING); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: EVENT_TYPE_CODEC_CONFIG_CHANGED - Intent broadcast should be generated - generateCodecMessageFromNative(mTestDevice, codecStatus); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateCodecMessageFromNative(sTestDevice, codecStatus); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); } /** @@ -644,113 +591,122 @@ public class A2dpServiceTest { */ @Test public void testDeleteStateMachineUnbondEvents() { - A2dpStackEvent stackEvent; - // Update the device priority so okToConnect() returns true - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // A2DP stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // Device unbond - state machine is not removed - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_NONE); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_CONNECTED - state machine is not removed - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_BONDED); + generateConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // Device unbond - state machine is not removed - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_NONE); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTING - state machine is not removed - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTING, - BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_BONDED); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTING, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // Device unbond - state machine is not removed - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_NONE); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_DISCONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_BONDED); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_DISCONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // Device unbond - state machine is removed - mA2dpService.bondStateChanged(mTestDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + mA2dpService.bondStateChanged(sTestDevice, BluetoothDevice.BOND_NONE); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); } /** - * Test that a CONNECTION_STATE_DISCONNECTED A2DP stack event will remove the state machine - * only if the device is unbond. + * Test that a CONNECTION_STATE_DISCONNECTED A2DP stack event will remove the state machine only + * if the device is unbond. */ @Test public void testDeleteStateMachineDisconnectEvents() { - A2dpStackEvent stackEvent; - // Update the device priority so okToConnect() returns true - when(mDatabaseManager.getProfileConnectionPolicy(mTestDevice, BluetoothProfile.A2DP)) + when(mDatabaseManager.getProfileConnectionPolicy(sTestDevice, BluetoothProfile.A2DP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mMockNativeInterface).connectA2dp(any(BluetoothDevice.class)); doReturn(true).when(mMockNativeInterface).disconnectA2dp(any(BluetoothDevice.class)); // A2DP stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_CONNECTING - state machine remains - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // Device bond state marked as unbond - state machine is not removed - doReturn(BluetoothDevice.BOND_NONE).when(mAdapterService) + doReturn(BluetoothDevice.BOND_NONE) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); - Assert.assertTrue(mA2dpService.getDevices().contains(mTestDevice)); + Assert.assertTrue(mA2dpService.getDevices().contains(sTestDevice)); // A2DP stack event: CONNECTION_STATE_DISCONNECTED - state machine is removed - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mA2dpService.getConnectionState(mTestDevice)); - Assert.assertFalse(mA2dpService.getDevices().contains(mTestDevice)); + generateConnectionMessageFromNative( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_DISCONNECTED, mA2dpService.getConnectionState(sTestDevice)); + Assert.assertFalse(mA2dpService.getDevices().contains(sTestDevice)); } - /** - * Test that whether active device been removed after enable silence mode - */ + /** Test that whether active device been removed after enable silence mode */ @Test public void testSetSilenceMode() { - BluetoothDevice otherDevice = mAdapter.getRemoteDevice("05:04:03:02:01:00"); - connectDevice(mTestDevice); + BluetoothDevice otherDevice = sAdapter.getRemoteDevice("05:04:03:02:01:00"); + connectDevice(sTestDevice); connectDevice(otherDevice); doReturn(true).when(mMockNativeInterface).setActiveDevice(any(BluetoothDevice.class)); doReturn(true) @@ -758,28 +714,28 @@ public class A2dpServiceTest { .setSilenceDevice(any(BluetoothDevice.class), anyBoolean()); // Test whether active device been removed after enable silence mode. - Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); - Assert.assertTrue(mA2dpService.setSilenceMode(mTestDevice, true)); - verify(mMockNativeInterface).setSilenceDevice(mTestDevice, true); + Assert.assertTrue(mA2dpService.setActiveDevice(sTestDevice)); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); + Assert.assertTrue(mA2dpService.setSilenceMode(sTestDevice, true)); + verify(mMockNativeInterface).setSilenceDevice(sTestDevice, true); Assert.assertNull(mA2dpService.getActiveDevice()); // Test whether active device been resumeed after disable silence mode. - Assert.assertTrue(mA2dpService.setSilenceMode(mTestDevice, false)); - verify(mMockNativeInterface).setSilenceDevice(mTestDevice, false); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); + Assert.assertTrue(mA2dpService.setSilenceMode(sTestDevice, false)); + verify(mMockNativeInterface).setSilenceDevice(sTestDevice, false); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); // Test that active device should not be changed when silence a non-active device - Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); + Assert.assertTrue(mA2dpService.setActiveDevice(sTestDevice)); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); Assert.assertTrue(mA2dpService.setSilenceMode(otherDevice, true)); verify(mMockNativeInterface).setSilenceDevice(otherDevice, true); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); // Test that active device should not be changed when another device exits silence mode Assert.assertTrue(mA2dpService.setSilenceMode(otherDevice, false)); verify(mMockNativeInterface).setSilenceDevice(otherDevice, false); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); } @Test @@ -789,66 +745,64 @@ public class A2dpServiceTest { } /** - * Test whether removeActiveDevice(false) suppresses noisy intent. - * Music should keep playing. + * Test whether removeActiveDevice(false) suppresses noisy intent. Music should keep playing. * (e.g. user selected LE headset via UI) */ @Test public void testRemoveActiveDevice_whenStopAudioIsFalse_suppressNoisyIntent() { - connectDevice(mTestDevice); + connectDevice(sTestDevice); doReturn(true).when(mMockNativeInterface).setActiveDevice(any(BluetoothDevice.class)); - Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); - AudioManager audioManager = mock(AudioManager.class); - mA2dpService.mAudioManager = audioManager; + Assert.assertTrue(mA2dpService.setActiveDevice(sTestDevice)); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); - Assert.assertTrue(mA2dpService.disconnect(mTestDevice)); - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_DISCONNECTING, + Assert.assertTrue(mA2dpService.disconnect(sTestDevice)); + verifyConnectionStateIntent( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); mA2dpService.removeActiveDevice(false); ArgumentCaptor connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); - verify(audioManager).handleBluetoothActiveDeviceChanged( - isNull(), eq(mTestDevice), connectionInfoArgumentCaptor.capture()); - BluetoothProfileConnectionInfo connectionInfo = - connectionInfoArgumentCaptor.getValue(); + verify(mAudioManager) + .handleBluetoothActiveDeviceChanged( + isNull(), eq(sTestDevice), connectionInfoArgumentCaptor.capture()); + BluetoothProfileConnectionInfo connectionInfo = connectionInfoArgumentCaptor.getValue(); // Should suppress noisy intent. (i.e. Music should keep playing) Assert.assertTrue(connectionInfo.isSuppressNoisyIntent()); } /** - * Test whether removeActiveDevice(true) does not suppress noisy intent. - * Music should pause. + * Test whether removeActiveDevice(true) does not suppress noisy intent. Music should pause. * (e.g. The solely connected BT device is disconnected) */ @Test public void testRemoveActiveDevice_whenStopAudioIsFalse_doesNotSuppressNoisyIntent() { - connectDevice(mTestDevice); + connectDevice(sTestDevice); doReturn(true).when(mMockNativeInterface).setActiveDevice(any(BluetoothDevice.class)); - Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); - AudioManager audioManager = mock(AudioManager.class); - mA2dpService.mAudioManager = audioManager; + Assert.assertTrue(mA2dpService.setActiveDevice(sTestDevice)); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); - Assert.assertTrue(mA2dpService.disconnect(mTestDevice)); - verifyConnectionStateIntent(TIMEOUT_MS, mTestDevice, BluetoothProfile.STATE_DISCONNECTING, + Assert.assertTrue(mA2dpService.disconnect(sTestDevice)); + verifyConnectionStateIntent( + sTestDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); mA2dpService.removeActiveDevice(true); ArgumentCaptor connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); - verify(audioManager).handleBluetoothActiveDeviceChanged( - isNull(), eq(mTestDevice), connectionInfoArgumentCaptor.capture()); - BluetoothProfileConnectionInfo connectionInfo = - connectionInfoArgumentCaptor.getValue(); + verify(mAudioManager) + .handleBluetoothActiveDeviceChanged( + isNull(), eq(sTestDevice), connectionInfoArgumentCaptor.capture()); + BluetoothProfileConnectionInfo connectionInfo = connectionInfoArgumentCaptor.getValue(); // Should not suppress noisy intent. (i.e. Music should pause) Assert.assertFalse(connectionInfo.isSuppressNoisyIntent()); } /** - * Test that whether updateOptionalCodecsSupport() method is working as intended - * when a Bluetooth device is connected with A2DP. + * Test that whether updateOptionalCodecsSupport() method is working as intended when a + * Bluetooth device is connected with A2DP. */ @Test public void testUpdateOptionalCodecsSupport() { @@ -857,79 +811,133 @@ public class A2dpServiceTest { int verifyEnabledTime = 0; // Test for device supports optional codec testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, true, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - ++verifySupportTime, verifyNotSupportTime, ++verifyEnabledTime); + ++verifySupportTime, + verifyNotSupportTime, + ++verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, true, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, - ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + ++verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, true, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, - ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + ++verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, true, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - verifySupportTime, verifyNotSupportTime, ++verifyEnabledTime); + verifySupportTime, + verifyNotSupportTime, + ++verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, true, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, - verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, true, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, - verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, true, + BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - ++verifySupportTime, verifyNotSupportTime, ++verifyEnabledTime); + ++verifySupportTime, + verifyNotSupportTime, + ++verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, true, + BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, - ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + ++verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, true, + BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, + true, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, - ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + ++verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); // Test for device not supports optional codec testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, false, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + ++verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, false, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, - verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + ++verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, false, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, - verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + ++verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, false, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + ++verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, false, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, - verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + ++verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, false, + BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, - verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + ++verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, false, + BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN, - verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, false, + BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED, - verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); testUpdateOptionalCodecsSupportCase( - BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, false, + BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, + false, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED, - verifySupportTime, verifyNotSupportTime, verifyEnabledTime); + verifySupportTime, + verifyNotSupportTime, + verifyEnabledTime); } /** @@ -946,9 +954,9 @@ public class A2dpServiceTest { Assert.assertEquals(0, mA2dpService.sendPreferredAudioProfileChangeToAudioFramework()); // Send 1 request when there is an A2DP active device - connectDevice(mTestDevice); - Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); + connectDevice(sTestDevice); + Assert.assertTrue(mA2dpService.setActiveDevice(sTestDevice)); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); Assert.assertEquals(1, mA2dpService.sendPreferredAudioProfileChangeToAudioFramework()); } @@ -963,25 +971,27 @@ public class A2dpServiceTest { @Test public void testActiveDevice() { - connectDevice(mTestDevice); + connectDevice(sTestDevice); /* Trigger setting active device */ doReturn(true).when(mMockNativeInterface).setActiveDevice(any(BluetoothDevice.class)); - Assert.assertTrue(mA2dpService.setActiveDevice(mTestDevice)); + Assert.assertTrue(mA2dpService.setActiveDevice(sTestDevice)); /* Check if setting active devices sets right device */ - Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice()); + Assert.assertEquals(sTestDevice, mA2dpService.getActiveDevice()); - /* Since A2dpService called AudioManager - assume Audio manager calles properly callback + /* Since A2dpService called AudioManager - assume Audio manager calls properly callback * mAudioManager.onAudioDeviceAdded */ - mA2dpService.updateAndBroadcastActiveDevice(mTestDevice); + mA2dpService.updateAndBroadcastActiveDevice(sTestDevice); - veifyActiveDeviceIntent(TIMEOUT_MS, mTestDevice); + verifyIntentSent( + hasAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, sTestDevice)); } - private void connectDeviceWithCodecStatus(BluetoothDevice device, - BluetoothCodecStatus codecStatus) { + private void connectDeviceWithCodecStatus( + BluetoothDevice device, BluetoothCodecStatus codecStatus) { A2dpStackEvent connCompletedEvent; List prevConnectedDevices = mA2dpService.getConnectedDevices(); @@ -1000,10 +1010,10 @@ public class A2dpServiceTest { Assert.assertTrue("Connect failed", mA2dpService.connect(device)); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mA2dpService.getConnectionState(device)); + verifyConnectionStateIntent( + device, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTING, mA2dpService.getConnectionState(device)); if (codecStatus != null) { generateCodecMessageFromNative(device, codecStatus); @@ -1016,10 +1026,10 @@ public class A2dpServiceTest { mA2dpService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mA2dpService.getConnectionState(device)); + verifyConnectionStateIntent( + device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mA2dpService.getConnectionState(device)); // Verify that the device is in the list of connected devices Assert.assertTrue(mA2dpService.getConnectedDevices().contains(device)); @@ -1029,72 +1039,79 @@ public class A2dpServiceTest { } } - private void generateConnectionMessageFromNative(BluetoothDevice device, int newConnectionState, - int oldConnectionState) { + private void generateConnectionMessageFromNative( + BluetoothDevice device, int newConnectionState, int oldConnectionState) { A2dpStackEvent stackEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); stackEvent.device = device; stackEvent.valueInt = newConnectionState; mA2dpService.messageFromNative(stackEvent); // Verify the connection state broadcast - verifyConnectionStateIntent(TIMEOUT_MS, device, newConnectionState, oldConnectionState); + verifyConnectionStateIntent(device, newConnectionState, oldConnectionState); } - private void generateUnexpectedConnectionMessageFromNative(BluetoothDevice device, - int newConnectionState, - int oldConnectionState) { + private void generateUnexpectedConnectionMessageFromNative( + BluetoothDevice device, int newConnectionState) { A2dpStackEvent stackEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); stackEvent.device = device; stackEvent.valueInt = newConnectionState; mA2dpService.messageFromNative(stackEvent); // Verify the connection state broadcast - verifyNoConnectionStateIntent(TIMEOUT_MS); + mInOrder.verify(mAdapterService, timeout(TIMEOUT.toMillis()).times(0)) + .sendBroadcast(any(), any(), any()); } - private void generateAudioMessageFromNative(BluetoothDevice device, int audioStackEvent, - int newAudioState, int oldAudioState) { + private void generateAudioMessageFromNative( + BluetoothDevice device, int audioStackEvent, int newAudioState, int oldAudioState) { A2dpStackEvent stackEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED); stackEvent.device = device; stackEvent.valueInt = audioStackEvent; mA2dpService.messageFromNative(stackEvent); // Verify the audio state broadcast - verifyAudioStateIntent(TIMEOUT_MS, device, newAudioState, oldAudioState); + verifyIntentSent( + hasAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, device), + hasExtra(BluetoothProfile.EXTRA_STATE, newAudioState), + hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, oldAudioState)); } - private void generateUnexpectedAudioMessageFromNative(BluetoothDevice device, - int audioStackEvent, int newAudioState, - int oldAudioState) { + private void generateUnexpectedAudioMessageFromNative( + BluetoothDevice device, int audioStackEvent) { A2dpStackEvent stackEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_AUDIO_STATE_CHANGED); stackEvent.device = device; stackEvent.valueInt = audioStackEvent; mA2dpService.messageFromNative(stackEvent); // Verify the audio state broadcast - verifyNoAudioStateIntent(TIMEOUT_MS); + mInOrder.verify(mAdapterService, timeout(TIMEOUT.toMillis()).times(0)) + .sendBroadcast(any(), any(), any()); } - private void generateCodecMessageFromNative(BluetoothDevice device, - BluetoothCodecStatus codecStatus) { + private void generateCodecMessageFromNative( + BluetoothDevice device, BluetoothCodecStatus codecStatus) { A2dpStackEvent stackEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED); stackEvent.device = device; stackEvent.codecStatus = codecStatus; mA2dpService.messageFromNative(stackEvent); - // Verify the codec status broadcast - verifyCodecConfigIntent(TIMEOUT_MS, device, codecStatus); + verifyIntentSent( + hasAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, device), + hasExtra(BluetoothCodecStatus.EXTRA_CODEC_STATUS, codecStatus)); } - private void generateUnexpectedCodecMessageFromNative(BluetoothDevice device, - BluetoothCodecStatus codecStatus) { + private void generateUnexpectedCodecMessageFromNative( + BluetoothDevice device, BluetoothCodecStatus codecStatus) { A2dpStackEvent stackEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED); stackEvent.device = device; stackEvent.codecStatus = codecStatus; mA2dpService.messageFromNative(stackEvent); // Verify the codec status broadcast - verifyNoCodecConfigIntent(TIMEOUT_MS); + mInOrder.verify(mAdapterService, timeout(TIMEOUT.toMillis()).times(0)) + .sendBroadcast(any(), any(), any()); } /** @@ -1102,11 +1119,11 @@ public class A2dpServiceTest { * * @param device test device * @param bondState bond state value, could be invalid - * @param priority value, could be invalid, coudl be invalid + * @param priority value, could be invalid, could be invalid * @param expected expected result from okToConnect() */ - private void testOkToConnectCase(BluetoothDevice device, int bondState, int priority, - boolean expected) { + private void testOkToConnectCase( + BluetoothDevice device, int bondState, int priority, boolean expected) { doReturn(bondState).when(mAdapterService).getBondState(device); when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.A2DP)) .thenReturn(priority); @@ -1114,13 +1131,13 @@ public class A2dpServiceTest { // Test when the AdapterService is in non-quiet mode: the result should not depend // on whether the connection request is outgoing or incoming. doReturn(false).when(mAdapterService).isQuietModeEnabled(); - Assert.assertEquals(expected, mA2dpService.okToConnect(device, true)); // Outgoing + Assert.assertEquals(expected, mA2dpService.okToConnect(device, true)); // Outgoing Assert.assertEquals(expected, mA2dpService.okToConnect(device, false)); // Incoming // Test when the AdapterService is in quiet mode: the result should always be // false when the connection request is incoming. doReturn(true).when(mAdapterService).isQuietModeEnabled(); - Assert.assertEquals(expected, mA2dpService.okToConnect(device, true)); // Outgoing + Assert.assertEquals(expected, mA2dpService.okToConnect(device, true)); // Outgoing Assert.assertEquals(false, mA2dpService.okToConnect(device, false)); // Incoming } @@ -1134,8 +1151,12 @@ public class A2dpServiceTest { * @param verifyNotSupportTime verify times of optional codec set to not support * @param verifyEnabledTime verify times of optional codec set to enabled */ - private void testUpdateOptionalCodecsSupportCase(int previousSupport, boolean support, - int previousEnabled, int verifySupportTime, int verifyNotSupportTime, + private void testUpdateOptionalCodecsSupportCase( + int previousSupport, + boolean support, + int previousEnabled, + int verifySupportTime, + int verifyNotSupportTime, int verifyEnabledTime) { doReturn(true).when(mMockNativeInterface).setActiveDevice(any(BluetoothDevice.class)); @@ -1146,7 +1167,10 @@ public class A2dpServiceTest { BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0); // Codec-specific fields + 0, + 0, + 0, + 0); // Codec-specific fields BluetoothCodecConfig codecConfigAac = buildBluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, @@ -1154,7 +1178,10 @@ public class A2dpServiceTest { BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, - 0, 0, 0, 0); // Codec-specific fields + 0, + 0, + 0, + 0); // Codec-specific fields BluetoothCodecConfig[] codecsLocalCapabilities; BluetoothCodecConfig[] codecsSelectableCapabilities; @@ -1175,50 +1202,64 @@ public class A2dpServiceTest { badCodecsSelectableCapabilities = new BluetoothCodecConfig[1]; badCodecsSelectableCapabilities[0] = codecConfigAac; - BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(codecConfigSbc, - Arrays.asList(codecsLocalCapabilities), - Arrays.asList(codecsSelectableCapabilities)); - BluetoothCodecStatus badCodecStatus = new BluetoothCodecStatus(codecConfigAac, - Arrays.asList(codecsLocalCapabilities), - Arrays.asList(badCodecsSelectableCapabilities)); - - when(mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice)) + BluetoothCodecStatus codecStatus = + new BluetoothCodecStatus( + codecConfigSbc, + Arrays.asList(codecsLocalCapabilities), + Arrays.asList(codecsSelectableCapabilities)); + BluetoothCodecStatus badCodecStatus = + new BluetoothCodecStatus( + codecConfigAac, + Arrays.asList(codecsLocalCapabilities), + Arrays.asList(badCodecsSelectableCapabilities)); + + when(mDatabaseManager.getA2dpSupportsOptionalCodecs(sTestDevice)) .thenReturn(previousSupport); - when(mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice)) + when(mDatabaseManager.getA2dpOptionalCodecsEnabled(sTestDevice)) .thenReturn(previousEnabled); // Generate connection request from native with bad codec status - connectDeviceWithCodecStatus(mTestDevice, badCodecStatus); - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTED); + connectDeviceWithCodecStatus(sTestDevice, badCodecStatus); + generateConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); // Generate connection request from native with good codec status - connectDeviceWithCodecStatus(mTestDevice, codecStatus); - generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTED); + connectDeviceWithCodecStatus(sTestDevice, codecStatus); + generateConnectionMessageFromNative( + sTestDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); // Check optional codec status is set properly - verify(mDatabaseManager, times(verifyNotSupportTime)).setA2dpSupportsOptionalCodecs( - mTestDevice, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED); - verify(mDatabaseManager, times(verifySupportTime)).setA2dpSupportsOptionalCodecs( - mTestDevice, BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED); - verify(mDatabaseManager, times(verifyEnabledTime)).setA2dpOptionalCodecsEnabled( - mTestDevice, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); + verify(mDatabaseManager, times(verifyNotSupportTime)) + .setA2dpSupportsOptionalCodecs( + sTestDevice, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED); + verify(mDatabaseManager, times(verifySupportTime)) + .setA2dpSupportsOptionalCodecs( + sTestDevice, BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED); + verify(mDatabaseManager, times(verifyEnabledTime)) + .setA2dpOptionalCodecsEnabled( + sTestDevice, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); } - private BluetoothCodecConfig buildBluetoothCodecConfig(int sourceCodecType, - int codecPriority, int sampleRate, int bitsPerSample, int channelMode, - long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4) { + private BluetoothCodecConfig buildBluetoothCodecConfig( + int sourceCodecType, + int codecPriority, + int sampleRate, + int bitsPerSample, + int channelMode, + long codecSpecific1, + long codecSpecific2, + long codecSpecific3, + long codecSpecific4) { return new BluetoothCodecConfig.Builder() - .setCodecType(sourceCodecType) - .setCodecPriority(codecPriority) - .setSampleRate(sampleRate) - .setBitsPerSample(bitsPerSample) - .setChannelMode(channelMode) - .setCodecSpecific1(codecSpecific1) - .setCodecSpecific2(codecSpecific2) - .setCodecSpecific3(codecSpecific3) - .setCodecSpecific4(codecSpecific4) - .build(); + .setCodecType(sourceCodecType) + .setCodecPriority(codecPriority) + .setSampleRate(sampleRate) + .setBitsPerSample(bitsPerSample) + .setChannelMode(channelMode) + .setCodecSpecific1(codecSpecific1) + .setCodecSpecific2(codecSpecific2) + .setCodecSpecific3(codecSpecific3) + .setCodecSpecific4(codecSpecific4) + .build(); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java index 3a08995064a5865abc75aa29edb12b828664fd5c..6f546daa9d7f5a592bf076b3464a0713363d51e5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkServiceTest.java @@ -95,7 +95,6 @@ public class A2dpSinkServiceTest { doReturn(true).when(mDatabaseManager).setProfileConnectionPolicy(any(), anyInt(), anyInt()); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); doReturn(bondedDevices).when(mAdapterService).getBondedDevices(); doReturn(1).when(mAdapterService).getMaxConnectedAudioDevices(); @@ -104,7 +103,7 @@ public class A2dpSinkServiceTest { doReturn(true).when(mNativeInterface).setActiveDevice(any()); mService = new A2dpSinkService(mTargetContext, mNativeInterface, mLooper.getLooper()); - mService.doStart(); + mService.start(); assertThat(mLooper.nextMessage()).isNull(); } @@ -112,7 +111,7 @@ public class A2dpSinkServiceTest { public void tearDown() throws Exception { assertThat(mLooper.nextMessage()).isNull(); - mService.doStop(); + mService.stop(); assertThat(A2dpSinkService.getA2dpSinkService()).isNull(); TestUtils.clearAdapterService(mAdapterService); } @@ -296,6 +295,26 @@ public class A2dpSinkServiceTest { assertThat(config).isEqualTo(expected); } + /** Make sure we ignore audio configuration changes for disconnected/unknown devices */ + @Test + public void testOnAudioConfigChanged_withNullDevice_eventDropped() { + StackEvent audioConfigChanged = + StackEvent.audioConfigChanged(null, TEST_SAMPLE_RATE, TEST_CHANNEL_COUNT); + mService.messageFromNative(audioConfigChanged); + assertThat(mService.getAudioConfig(null)).isNull(); + } + + /** Make sure we ignore audio configuration changes for disconnected/unknown devices */ + @Test + public void testOnAudioConfigChanged_withUnknownDevice_eventDropped() { + assertThat(mService.getConnectionState(mDevice1)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + StackEvent audioConfigChanged = + StackEvent.audioConfigChanged(mDevice1, TEST_SAMPLE_RATE, TEST_CHANNEL_COUNT); + mService.messageFromNative(audioConfigChanged); + assertThat(mService.getAudioConfig(mDevice1)).isNull(); + } + /** * Getting an audio config for a device that hasn't received one yet should return null */ diff --git a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java index dc8df3c654f95a6501c17a46e5fdb1dfd35d36de..4b25bbba1d8b5ea7d0f719865e1cbd3ee696a489 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java @@ -82,10 +82,9 @@ public class A2dpSinkStreamHandlerTest { Looper.prepare(); } TestUtils.setAdapterService(mAdapterService); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); AvrcpControllerNativeInterface.setInstance(mMockAvrcpControllerNativeInterface); mService = new AvrcpControllerService(mTargetContext, mMockAvrcpControllerNativeInterface); - mService.doStart(); + mService.start(); final Intent bluetoothBrowserMediaServiceStartIntent = TestUtils.prepareIntentToStartBluetoothBrowserMediaService(); mBluetoothBrowserMediaServiceTestRule.startService(bluetoothBrowserMediaServiceStartIntent); @@ -112,7 +111,7 @@ public class A2dpSinkStreamHandlerTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); AvrcpControllerNativeInterface.setInstance(null); TestUtils.clearAdapterService(mAdapterService); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java index 424da9a3cd11ef253b945c8fd7e585095a6df420..e3dd565833018255b290137ca8066a088a1d391b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClientTest.java @@ -19,8 +19,6 @@ package com.android.bluetooth.avrcpcontroller; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -66,10 +64,9 @@ public class AvrcpBipClientTest { Context targetContext = InstrumentationRegistry.getTargetContext(); MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); AvrcpControllerNativeInterface.setInstance(mNativeInterface); mService = new AvrcpControllerService(targetContext, mNativeInterface); - mService.doStart(); + mService.start(); final Intent bluetoothBrowserMediaServiceStartIntent = TestUtils.prepareIntentToStartBluetoothBrowserMediaService(); mBluetoothBrowserMediaServiceTestRule.startService(bluetoothBrowserMediaServiceStartIntent); @@ -87,7 +84,7 @@ public class AvrcpBipClientTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); AvrcpControllerNativeInterface.setInstance(null); mService = AvrcpControllerService.getAvrcpControllerService(); assertThat(mService).isNull(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java index 175ce227ae61c2bc674dd48ff5233f9be1444b5f..19b8f6c95e40f34e5c1507d643f8b1e60041de7e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerServiceTest.java @@ -18,9 +18,7 @@ package com.android.bluetooth.avrcpcontroller; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -80,10 +78,9 @@ public class AvrcpControllerServiceTest { Context targetContext = InstrumentationRegistry.getTargetContext(); MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); AvrcpControllerNativeInterface.setInstance(mNativeInterface); mService = new AvrcpControllerService(targetContext, mNativeInterface); - mService.doStart(); + mService.start(); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); assertThat(mAdapter).isNotNull(); @@ -96,7 +93,7 @@ public class AvrcpControllerServiceTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); AvrcpControllerNativeInterface.setInstance(null); mService = AvrcpControllerService.getAvrcpControllerService(); assertThat(mService).isNull(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java index ec21d0ac0d753faca7472430beb8ee424400f754..d01d565524370e6c361a43709ff32c02b3adce58 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java @@ -101,18 +101,14 @@ public class AvrcpControllerStateMachineTest { // Start a real A2dpSinkService so we can replace the static instance with our mock doReturn(mDatabaseManager).when(mA2dpAdapterService).getDatabase(); - doReturn(true).when(mA2dpAdapterService).isStartedProfile(anyString()); TestUtils.setAdapterService(mA2dpAdapterService); A2dpSinkNativeInterface.setInstance(mA2dpSinkNativeInterface); - TestUtils.startService(mA2dpServiceRule, A2dpSinkService.class); A2dpSinkService.setA2dpSinkService(mA2dpSinkService); TestUtils.clearAdapterService(mA2dpAdapterService); // Start an AvrcpControllerService to get a real BluetoothMediaBrowserService up - doReturn(true).when(mAvrcpAdapterService).isStartedProfile(anyString()); TestUtils.setAdapterService(mAvrcpAdapterService); AvrcpControllerNativeInterface.setInstance(mNativeInterface); - TestUtils.startService(mAvrcpServiceRule, AvrcpControllerService.class); // Mock an AvrcpControllerService to give to all state machines doReturn(BluetoothProfile.STATE_DISCONNECTED).when(mCoverArtManager).getState(any()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java index 28a8dd6a47241e2f025b2d3c491f7fa336469ef5..d55695d9497989f25b8dc31e219f14bd3ad23cff 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProviderTest.java @@ -19,8 +19,6 @@ package com.android.bluetooth.avrcpcontroller; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; @@ -65,9 +63,7 @@ public class AvrcpCoverArtProviderTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); AvrcpControllerNativeInterface.setInstance(mNativeInterface); - TestUtils.startService(mServiceRule, AvrcpControllerService.class); mAdapter = BluetoothAdapter.getDefaultAdapter(); mTestDevice = mAdapter.getRemoteDevice(mTestAddress); mArtProvider = new AvrcpCoverArtProvider(); @@ -75,7 +71,6 @@ public class AvrcpCoverArtProviderTest { @After public void tearDown() throws Exception { - TestUtils.stopService(mServiceRule, AvrcpControllerService.class); AvrcpControllerNativeInterface.setInstance(null); TestUtils.clearAdapterService(mAdapterService); } @@ -149,4 +144,4 @@ public class AvrcpCoverArtProviderTest { public void getType() { assertThat(mArtProvider.getType(null)).isNull(); } -} \ No newline at end of file +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java index 826db6f37bb8fa292ba10beea3078e90d29a7064..64753a466d67ea18be58b8c9a808db230e1987b0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bas/BatteryServiceTest.java @@ -17,7 +17,6 @@ package com.android.bluetooth.bas; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; @@ -73,7 +72,6 @@ public class BatteryServiceTest { TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -96,11 +94,12 @@ public class BatteryServiceTest { private void startService() throws TimeoutException { mService = new BatteryService(mTargetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); } private void stopService() throws TimeoutException { - mService.doStop(); + mService.stop(); mService = BatteryService.getBatteryService(); Assert.assertNull(mService); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java index b57b4bf0c9edfbf2a982453507a9259ab0b2ec16..ca5c6e527d0f40635dd4c0e7739012bc6ec5e1e6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.after; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; @@ -69,7 +68,9 @@ 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.flags.FeatureFlagsImpl; +import com.android.bluetooth.flags.FakeFeatureFlagsImpl; +import com.android.bluetooth.flags.Flags; +import com.android.bluetooth.le_audio.LeAudioService; import org.junit.After; import org.junit.Assert; @@ -78,6 +79,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @@ -137,6 +139,7 @@ public class BassClientServiceTest { private BluetoothDevice mCurrentDevice; private BluetoothDevice mCurrentDevice1; private BassIntentReceiver mBassIntentReceiver; + private FakeFeatureFlagsImpl mFakeFlagsImpl; @Spy private BassObjectsFactory mObjectsFactory = BassObjectsFactory.getInstance(); @Mock private AdapterService mAdapterService; @@ -144,6 +147,7 @@ public class BassClientServiceTest { @Mock private BluetoothLeScannerWrapper mBluetoothLeScannerWrapper; @Mock private ServiceFactory mServiceFactory; @Mock private CsipSetCoordinatorService mCsipService; + @Mock private LeAudioService mLeAudioService; @Mock private IBluetoothLeBroadcastAssistantCallback mCallback; @Mock private Binder mBinder; @@ -213,7 +217,6 @@ public class BassClientServiceTest { doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) .getBondState(any(BluetoothDevice.class)); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); doAnswer(invocation -> { Set keys = mStateMachines.keySet(); return keys.toArray(new BluetoothDevice[keys.size()]); @@ -237,15 +240,20 @@ public class BassClientServiceTest { return stateMachine; }) .when(mObjectsFactory) - .makeStateMachine(any(), any(), any(), any()); + .makeStateMachine(any(), any(), any(), any(), any()); doReturn(mBluetoothLeScannerWrapper).when(mObjectsFactory) .getBluetoothLeScannerWrapper(any()); - mBassClientService = new BassClientService(mTargetContext, new FeatureFlagsImpl()); - mBassClientService.doStart(); + mFakeFlagsImpl = new FakeFeatureFlagsImpl(); + mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false); + + mBassClientService = new BassClientService(mTargetContext, mFakeFlagsImpl); + mBassClientService.start(); + mBassClientService.setAvailable(true); mBassClientService.mServiceFactory = mServiceFactory; doReturn(mCsipService).when(mServiceFactory).getCsipSetCoordinatorService(); + doReturn(mLeAudioService).when(mServiceFactory).getLeAudioService(); when(mCallback.asBinder()).thenReturn(mBinder); mBassClientService.registerCallback(mCallback); @@ -270,7 +278,7 @@ public class BassClientServiceTest { } mBassClientService.unregisterCallback(mCallback); - mBassClientService.doStop(); + mBassClientService.stop(); mBassClientService = BassClientService.getBassClientService(); assertThat(mBassClientService).isNull(); mStateMachines.clear(); @@ -343,7 +351,12 @@ public class BassClientServiceTest { assertThat(mBassClientService.connect(mCurrentDevice)).isTrue(); verify(mObjectsFactory) - .makeStateMachine(eq(mCurrentDevice), eq(mBassClientService), any(), any()); + .makeStateMachine( + eq(mCurrentDevice), + eq(mBassClientService), + eq(mAdapterService), + any(), + any()); BassClientStateMachine stateMachine = mStateMachines.get(mCurrentDevice); assertThat(stateMachine).isNotNull(); verify(stateMachine).sendMessage(BassClientStateMachine.CONNECT); @@ -383,10 +396,20 @@ public class BassClientServiceTest { */ @Test public void testStartSearchingForSources() { + prepareConnectedDeviceGroup(); List scanFilters = new ArrayList<>(); + + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + Mockito.clearInvocations(sm); + } + mBassClientService.startSearchingForSources(scanFilters); verify(mBluetoothLeScannerWrapper).startScan(notNull(), notNull(), notNull()); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm).sendMessage(BassClientStateMachine.START_SCAN_OFFLOAD); + } } /** @@ -446,7 +469,7 @@ public class BassClientServiceTest { // Inject initial broadcast source state BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -454,7 +477,7 @@ public class BassClientServiceTest { null); injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID); - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -495,9 +518,9 @@ public class BassClientServiceTest { } } - private void injectRemoteSourceState(BassClientStateMachine sm, + private BluetoothLeBroadcastReceiveState injectRemoteSourceState(BassClientStateMachine sm, BluetoothLeBroadcastMetadata meta, int sourceId, int paSynState, int encryptionState, - byte[] badCode) { + byte[] badCode, long bisSyncState) { BluetoothLeBroadcastReceiveState recvState = new BluetoothLeBroadcastReceiveState( sourceId, meta.getSourceAddressType(), @@ -510,7 +533,7 @@ public class BassClientServiceTest { meta.getSubgroups().size(), // Bis sync states meta.getSubgroups().stream() - .map(e -> (long) 0x00000002) + .map(e -> bisSyncState) .collect(Collectors.toList()), meta.getSubgroups().stream() .map(e -> e.getContentMetadata()) @@ -527,9 +550,35 @@ public class BassClientServiceTest { stateList.add(recvState); doReturn(stateList).when(sm).getAllSources(); + return recvState; + } + + private BluetoothLeBroadcastReceiveState injectRemoteSourceStateSourceAdded( + BassClientStateMachine sm, BluetoothLeBroadcastMetadata meta, int sourceId, + int paSynState, int encryptionState, byte[] badCode) { + BluetoothLeBroadcastReceiveState recvState = + injectRemoteSourceState(sm, meta, sourceId, paSynState, encryptionState, badCode, + (long) 0x00000002); + mBassClientService.getCallbacks().notifySourceAdded(sm.getDevice(), recvState, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST); TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper()); + + return recvState; + } + + private BluetoothLeBroadcastReceiveState injectRemoteSourceStateChanged( + BassClientStateMachine sm, BluetoothLeBroadcastMetadata meta, int sourceId, + int paSynState, int encryptionState, byte[] badCode, long bisSyncState) { + BluetoothLeBroadcastReceiveState recvState = + injectRemoteSourceState(sm, meta, sourceId, paSynState, encryptionState, badCode, + bisSyncState); + + mBassClientService.getCallbacks().notifyReceiveStateChanged(sm.getDevice(), + recvState.getSourceId(), recvState); + TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper()); + + return recvState; } private void injectRemoteSourceStateRemoval(BassClientStateMachine sm, int sourceId) { @@ -583,7 +632,7 @@ public class BassClientServiceTest { verifyAddSourceForGroup(meta); for (BassClientStateMachine sm: mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -598,7 +647,7 @@ public class BassClientServiceTest { throw e.rethrowFromSystemServer(); } } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -626,14 +675,14 @@ public class BassClientServiceTest { verifyAddSourceForGroup(meta); for (BassClientStateMachine sm: mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -680,14 +729,14 @@ public class BassClientServiceTest { verifyAddSourceForGroup(meta); for (BassClientStateMachine sm: mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -719,6 +768,89 @@ public class BassClientServiceTest { } } + /** + * Test whether service.removeSource() does send modify source to all the state machines if + * either PA or BIS is synced + */ + @Test + public void testRemoveSourceForGroupAndTriggerModifySource() { + prepareConnectedDeviceGroup(); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + doReturn(meta).when(sm).getCurrentBroadcastMetadata(eq(TEST_SOURCE_ID)); + doReturn(true).when(sm).isSyncedToTheSource(eq(TEST_SOURCE_ID)); + } + + // Remove broadcast source + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + + // Verify all group members getting UPDATE_BCAST_SOURCE message + // because PA state is synced + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) + .findFirst(); + assertThat(msg.isPresent()).isEqualTo(true); + + // Verify using the right sourceId on each device + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID); + } + + for (BassClientStateMachine sm : mStateMachines.values()) { + // Update receiver state + injectRemoteSourceStateChanged( + sm, + meta, + TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, + (long) 0x00000001); + verify(mLeAudioService).activeBroadcastAssistantNotification(eq(true)); + } + + // Remove broadcast source + mBassClientService.removeSource(mCurrentDevice, TEST_SOURCE_ID); + + // Verify all group members getting UPDATE_BCAST_SOURCE message if + // bis sync state is non-zero and pa sync state is not synced + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Optional msg = + messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.UPDATE_BCAST_SOURCE) + .findFirst(); + assertThat(msg.isPresent()).isEqualTo(true); + + // Verify using the right sourceId on each device + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID); + } + + for (BassClientStateMachine sm : mStateMachines.values()) { + injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID); + } + } + /** * Test whether the group operation flag is set on addSource() and removed on removeSource */ @@ -731,14 +863,14 @@ public class BassClientServiceTest { // Inject source added for (BassClientStateMachine sm: mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -793,6 +925,58 @@ public class BassClientServiceTest { assertThat(msg.isPresent()).isFalse(); } + /** Test switch source will be triggered if adding new source when sink has source */ + @Test + public void testSwitchSourceAfterSourceAdded() { + prepareConnectedDeviceGroup(); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + BluetoothLeBroadcastMetadata newMeta = createBroadcastMetadata(TEST_BROADCAST_ID + 1); + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + } + + // Add another new broadcast source + mBassClientService.addSource(mCurrentDevice, newMeta, true); + + // Verify all group members getting SWITCH_BCAST_SOURCE message and first source got + // selected + // to remove + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Optional msg = + messageCaptor.getAllValues().stream() + .filter( + m -> + (m.what == BassClientStateMachine.SWITCH_BCAST_SOURCE) + && (m.obj == newMeta) + && (m.arg1 == TEST_SOURCE_ID)) + .findFirst(); + assertThat(msg.isPresent()).isTrue(); + assertThat(msg.orElse(null)).isNotNull(); + } + } + /** * Test that after multiple calls to service.addSource() with a group operation flag set, * there are two call to service.removeSource() needed to clear the flag @@ -805,14 +989,14 @@ public class BassClientServiceTest { assertThat(mStateMachines.size()).isEqualTo(2); for (BassClientStateMachine sm: mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -831,14 +1015,14 @@ public class BassClientServiceTest { assertThat(mStateMachines.size()).isEqualTo(2); for (BassClientStateMachine sm: mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceState(sm, meta1, TEST_SOURCE_ID + 2, + injectRemoteSourceStateSourceAdded(sm, meta1, TEST_SOURCE_ID + 2, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta1.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceState(sm, meta1, TEST_SOURCE_ID + 3, + injectRemoteSourceStateSourceAdded(sm, meta1, TEST_SOURCE_ID + 3, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta1.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -930,7 +1114,7 @@ public class BassClientServiceTest { BluetoothLeBroadcastMetadata metaOther = createBroadcastMetadata(TEST_BROADCAST_ID + 20); - injectRemoteSourceState(sm, metaOther, TEST_SOURCE_ID + 20, + injectRemoteSourceStateSourceAdded(sm, metaOther, TEST_SOURCE_ID + 20, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -962,18 +1146,27 @@ public class BassClientServiceTest { public void testInvalidRequestForGroup() { // Prepare the initial state prepareConnectedDeviceGroup(); + + // Verify errors are reported for the entire group + mBassClientService.addSource(mCurrentDevice1, null, true); + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm : mStateMachines.values()) { + verify(sm, times(0)).sendMessage(any()); + } + + // Prepare valid source for group BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); verifyAddSourceForGroup(meta); for (BassClientStateMachine sm: mStateMachines.values()) { if (sm.getDevice().equals(mCurrentDevice)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, null); } else if (sm.getDevice().equals(mCurrentDevice1)) { - injectRemoteSourceState(sm, meta, TEST_SOURCE_ID + 1, + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, meta.isEncrypted() ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : @@ -982,19 +1175,6 @@ public class BassClientServiceTest { } } - // Verify errors are reported for the entire group - mBassClientService.addSource(mCurrentDevice1, null, true); - assertThat(mStateMachines.size()).isEqualTo(2); - for (BassClientStateMachine sm: mStateMachines.values()) { - BluetoothDevice dev = sm.getDevice(); - try { - verify(mCallback, after(TIMEOUT_MS).times(1)).onSourceAddFailed(eq(dev), - eq(null), eq(BluetoothStatusCodes.ERROR_BAD_PARAMETERS)); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - // Verify errors are reported for the entire group mBassClientService.modifySource(mCurrentDevice, TEST_SOURCE_ID, null); assertThat(mStateMachines.size()).isEqualTo(2); @@ -1238,4 +1418,409 @@ public class BassClientServiceTest { assertThat(mBassClientService.getBroadcastIdForSyncHandle(testSyncHandle)) .isEqualTo(testBroadcastId); } + + @Test + public void testSuspendResumeSourceSynchronization() { + prepareConnectedDeviceGroup(); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm: mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + } + } + + mBassClientService.suspendAllReceiversSourceSynchronization(); + + // Inject source removed + for (BassClientStateMachine sm: mStateMachines.values()) { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Optional msg = messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) + .findFirst(); + assertThat(msg.isPresent()).isEqualTo(true); + + if (sm.getDevice().equals(mCurrentDevice)) { + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID); + injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 1); + injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID + 1); + } + } + + mBassClientService.resumeReceiversSourceSynchronization(); + + // Verify all group members getting ADD_BCAST_SOURCE message + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm: mStateMachines.values()) { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + long count = messageCaptor.getAllValues().stream() + .filter(m -> (m.what == BassClientStateMachine.ADD_BCAST_SOURCE) + && (m.obj == meta)) + .count(); + assertThat(count).isEqualTo(2); + } + } + + @Test + public void testHandleUnicastSourceStreamStatusChange() { + prepareConnectedDeviceGroup(); + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm: mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + + // Update receiver state + injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, (long) 0x00000001); + verify(mLeAudioService).activeBroadcastAssistantNotification(eq(true)); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + injectRemoteSourceStateSourceAdded(sm, meta, TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + + // Update receiver state + injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, (long) 0x00000002); + } + } + + /* Unicast would like to stream */ + mBassClientService.handleUnicastSourceStreamStatusChange( + 0 /* STATUS_LOCAL_STREAM_REQUESTED */); + + // Inject source removed + for (BassClientStateMachine sm: mStateMachines.values()) { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + Optional msg = messageCaptor.getAllValues().stream() + .filter(m -> m.what == BassClientStateMachine.REMOVE_BCAST_SOURCE) + .findFirst(); + assertThat(msg.isPresent()).isEqualTo(true); + + if (sm.getDevice().equals(mCurrentDevice)) { + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID); + injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + assertThat(msg.get().arg1).isEqualTo(TEST_SOURCE_ID + 1); + injectRemoteSourceStateRemoval(sm, TEST_SOURCE_ID + 1); + } + } + + /* Unicast finished streaming */ + mBassClientService.handleUnicastSourceStreamStatusChange( + 2 /* STATUS_LOCAL_STREAM_SUSPENDED */); + + // Verify all group members getting ADD_BCAST_SOURCE message + assertThat(mStateMachines.size()).isEqualTo(2); + for (BassClientStateMachine sm: mStateMachines.values()) { + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(Message.class); + verify(sm, atLeast(1)).sendMessage(messageCaptor.capture()); + + long count = messageCaptor.getAllValues().stream() + .filter(m -> (m.what == BassClientStateMachine.ADD_BCAST_SOURCE) + && (m.obj == meta)) + .count(); + assertThat(count).isEqualTo(2); + } + + // Update receiver state with lost BIS sync + for (BassClientStateMachine sm: mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, (long) 0x00000000); + verify(mLeAudioService).activeBroadcastAssistantNotification(eq(false)); + } else if (sm.getDevice().equals(mCurrentDevice1)) { + injectRemoteSourceStateChanged(sm, meta, TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() ? + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING : + BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null, (long) 0x00000000); + } + } + } + + private void prepareTwoSynchronizedDevices() { + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + + doReturn(new ArrayList(Arrays.asList(meta))) + .when(mLeAudioService) + .getAllBroadcastMetadata(); + prepareConnectedDeviceGroup(); + + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + // verify source id + try { + verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()) + .onSourceAdded( + eq(mCurrentDevice), + eq(TEST_SOURCE_ID), + eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } else if (sm.getDevice().equals(mCurrentDevice1)) { + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + // verify source id + try { + verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()) + .onSourceAdded( + eq(mCurrentDevice1), + eq(TEST_SOURCE_ID + 1), + eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + } + + @Test + public void testPrivateBroadcastIntentionalDisconnection() { + prepareTwoSynchronizedDevices(); + + /* Imitate broadcast being active */ + doReturn(true).when(mLeAudioService).isPlaying(TEST_BROADCAST_ID); + /* Imitate devices being primary */ + doReturn(true).when(mLeAudioService).isPrimaryDevice(mCurrentDevice); + doReturn(true).when(mLeAudioService).isPrimaryDevice(mCurrentDevice1); + + /* Imitate device 1/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice, true); + + /* After first device disconnection and de-synchronization expect not stopping broadcast */ + verify(mLeAudioService, times(0)).stopBroadcast(eq(TEST_BROADCAST_ID)); + + /* Imitate first device being in disconnected state */ + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + + /* Imitate device 2/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice1, true); + + /* After second device disconnection and de-synchronization expect stopping broadcast */ + verify(mLeAudioService, times(1)).stopBroadcast(eq(TEST_BROADCAST_ID)); + } + + @Test + public void testPrivateBroadcastUnintentionalDisconnection() { + prepareTwoSynchronizedDevices(); + + /* Imitate broadcast being active */ + doReturn(true).when(mLeAudioService).isPlaying(TEST_BROADCAST_ID); + /* Imitate devices being primary */ + doReturn(true).when(mLeAudioService).isPrimaryDevice(mCurrentDevice); + doReturn(true).when(mLeAudioService).isPrimaryDevice(mCurrentDevice1); + + /* Imitate device 1/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice, false); + + /* After first device disconnection and de-synchronization expect not stopping broadcast */ + verify(mLeAudioService, times(0)).stopBroadcast(eq(TEST_BROADCAST_ID)); + + /* Imitate first device being in disconnected state */ + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + + /* Imitate device 2/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice1, false); + + /* After second device disconnection and de-synchronization expect stopping broadcast */ + verify(mLeAudioService, times(1)).stopBroadcast(eq(TEST_BROADCAST_ID)); + } + + @Test + public void testAudioSharingIntentionalDisconnection() { + prepareTwoSynchronizedDevices(); + + /* Imitate broadcast being active */ + doReturn(true).when(mLeAudioService).isPlaying(TEST_BROADCAST_ID); + /* Imitate devices being primary */ + doReturn(true).when(mLeAudioService).isPrimaryDevice(mCurrentDevice); + doReturn(false).when(mLeAudioService).isPrimaryDevice(mCurrentDevice1); + + /* Imitate device 1/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice, true); + + /* After first device disconnection and de-synchronization expect stopping broadcast */ + verify(mLeAudioService, times(1)).stopBroadcast(eq(TEST_BROADCAST_ID)); + + /* Imitate first device being in disconnected state */ + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + + /* Imitate device 2/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice1, true); + + /* After second device disconnection and de-synchronization expect not stopping broadcast */ + verify(mLeAudioService, times(1)).stopBroadcast(eq(TEST_BROADCAST_ID)); + } + + @Test + public void testAudioSharingUnintentionalDisconnection() { + prepareTwoSynchronizedDevices(); + + /* Imitate broadcast being active */ + doReturn(true).when(mLeAudioService).isPlaying(TEST_BROADCAST_ID); + /* Imitate devices being primary */ + doReturn(true).when(mLeAudioService).isPrimaryDevice(mCurrentDevice); + doReturn(false).when(mLeAudioService).isPrimaryDevice(mCurrentDevice1); + + /* Imitate device 1/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice, false); + + /* After first device disconnection and de-synchronization expect not stopping broadcast */ + verify(mLeAudioService, times(0)).stopBroadcast(eq(TEST_BROADCAST_ID)); + + /* Imitate first device being in disconnected state */ + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + + /* Imitate device 2/2 disconnection from StateMachine context */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice1, false); + + /* After second device disconnection and de-synchronization timeout to be fired */ + verify(mLeAudioService, times(0)).stopBroadcast(eq(TEST_BROADCAST_ID)); + } + + @Test + public void testNotifyBroadcastStateChangedStopped() { + BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID); + + doReturn(new ArrayList(Arrays.asList(meta))) + .when(mLeAudioService) + .getAllBroadcastMetadata(); + prepareConnectedDeviceGroup(); + + verifyAddSourceForGroup(meta); + for (BassClientStateMachine sm : mStateMachines.values()) { + if (sm.getDevice().equals(mCurrentDevice)) { + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + // verify source id + try { + verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()) + .onSourceAdded( + eq(mCurrentDevice), + eq(TEST_SOURCE_ID), + eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } else if (sm.getDevice().equals(mCurrentDevice1)) { + injectRemoteSourceStateSourceAdded( + sm, + meta, + TEST_SOURCE_ID + 1, + BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + meta.isEncrypted() + ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING + : BluetoothLeBroadcastReceiveState + .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED, + null); + // verify source id + try { + verify(mCallback, timeout(TIMEOUT_MS).atLeastOnce()) + .onSourceAdded( + eq(mCurrentDevice1), + eq(TEST_SOURCE_ID + 1), + eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST)); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /* Imitate broadcast being not active */ + doReturn(false).when(mLeAudioService).isPlaying(TEST_BROADCAST_ID); + + mBassClientService.notifyBroadcastStateChanged( + 0 /* BROADCAST_STATE_STOPPED */, TEST_BROADCAST_ID); + + /* Imitiate scenario when if there would be broadcast - stop would be called */ + mBassClientService.handleDeviceDisconnection(mCurrentDevice, true); + mBassClientService.handleDeviceDisconnection(mCurrentDevice1, true); + + /* Imitate first device being in disconnected state */ + doReturn(BluetoothProfile.STATE_DISCONNECTED) + .when(mStateMachines.get(mCurrentDevice)) + .getConnectionState(); + + /* After second device disconnection and de-synchronization expect not calling broadcast to + * stop due to previous broadcast stream stopped */ + verify(mLeAudioService, times(0)).stopBroadcast(eq(TEST_BROADCAST_ID)); + } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java index 50df170d2ff4271464a3d3762913cbc63d606954..2c41a652c8004b4842510115b0547053097c6dbe 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java @@ -36,6 +36,7 @@ import static com.android.bluetooth.bass_client.BassClientStateMachine.SELECT_BC import static com.android.bluetooth.bass_client.BassClientStateMachine.SET_BCAST_CODE; import static com.android.bluetooth.bass_client.BassClientStateMachine.START_SCAN_OFFLOAD; import static com.android.bluetooth.bass_client.BassClientStateMachine.STOP_SCAN_OFFLOAD; +import static com.android.bluetooth.bass_client.BassClientStateMachine.SWITCH_BCAST_SOURCE; import static com.android.bluetooth.bass_client.BassClientStateMachine.UPDATE_BCAST_SOURCE; import static com.android.bluetooth.bass_client.BassConstants.CLIENT_CHARACTERISTIC_CONFIG; @@ -51,6 +52,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.after; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; @@ -69,20 +71,25 @@ import android.bluetooth.BluetoothLeBroadcastChannel; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastSubgroup; +import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.le.PeriodicAdvertisingCallback; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; +import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.flags.FakeFeatureFlagsImpl; import com.android.bluetooth.flags.FeatureFlags; @@ -99,7 +106,6 @@ import org.junit.runners.JUnit4; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.Spy; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -118,29 +124,55 @@ public class BassClientStateMachineTest { private static final int TIMEOUT_MS = 2_000; private static final int WAIT_MS = 1_200; private static final String TEST_BROADCAST_NAME = "Test"; + private static final String EMPTY_BLUETOOTH_DEVICE_ADDRESS = "00:00:00:00:00:00"; + private Context mTargetContext; private BluetoothAdapter mAdapter; private HandlerThread mHandlerThread; private StubBassClientStateMachine mBassClientStateMachine; private BluetoothDevice mTestDevice; + private BluetoothDevice mSourceTestDevice; + private BluetoothDevice mEmptyTestDevice; private FakeFeatureFlagsImpl mFakeFlagsImpl; @Mock private AdapterService mAdapterService; @Mock private BassClientService mBassClientService; - @Spy private BluetoothMethodProxy mMethodProxy; + @Mock private BluetoothMethodProxy mMethodProxy; @Before public void setUp() throws Exception { + mTargetContext = InstrumentationRegistry.getTargetContext(); + BluetoothManager manager = mTargetContext.getSystemService(BluetoothManager.class); + assertThat(manager).isNotNull(); + mAdapter = manager.getAdapter(); + + mEmptyTestDevice = mAdapter.getRemoteDevice(EMPTY_BLUETOOTH_DEVICE_ADDRESS); + assertThat(mEmptyTestDevice).isNotNull(); + TestUtils.setAdapterService(mAdapterService); - mAdapter = BluetoothAdapter.getDefaultAdapter(); mFakeFlagsImpl = new FakeFeatureFlagsImpl(); mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_MONITOR_SOURCE_SYNC_STATUS, false); + mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false); BluetoothMethodProxy.setInstanceForTesting(mMethodProxy); doNothing().when(mMethodProxy).periodicAdvertisingManagerTransferSync( any(), any(), anyInt(), anyInt()); // Get a device for testing - mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); + mTestDevice = TestUtils.getTestDevice(mAdapter, 0); + mSourceTestDevice = TestUtils.getTestDevice(mAdapter, 1); + + doReturn(mEmptyTestDevice) + .when(mAdapterService) + .getDeviceFromByte(Utils.getBytesFromAddress(EMPTY_BLUETOOTH_DEVICE_ADDRESS)); + doReturn(mTestDevice) + .when(mAdapterService) + .getDeviceFromByte(Utils.getBytesFromAddress(mTestDevice.getAddress())); + doReturn(mSourceTestDevice) + .when(mAdapterService) + .getDeviceFromByte(Utils.getBytesFromAddress(mSourceTestDevice.getAddress())); + doReturn(mEmptyTestDevice) + .when(mAdapterService) + .getDeviceFromByte(Utils.getBytesFromAddress(mEmptyTestDevice.getAddress())); // Set up thread and looper mHandlerThread = new HandlerThread("BassClientStateMachineTestHandlerThread"); @@ -149,14 +181,20 @@ public class BassClientStateMachineTest { new StubBassClientStateMachine( mTestDevice, mBassClientService, + mAdapterService, mHandlerThread.getLooper(), CONNECTION_TIMEOUT_MS, mFakeFlagsImpl); + assertThat(mBassClientStateMachine).isNotNull(); mBassClientStateMachine.start(); } @After public void tearDown() throws Exception { + if (mBassClientStateMachine == null) { + return; + } + mBassClientStateMachine.doQuit(); mHandlerThread.quit(); TestUtils.clearAdapterService(mAdapterService); @@ -704,23 +742,49 @@ public class BassClientStateMachineTest { mBassClientStateMachine.mPendingMetadata = createBroadcastMetadata(); sourceId = 1; - value = new byte[] { - (byte) sourceId, // sourceId - 0x00, // sourceAddressType - 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, // sourceAddress - 0x00, // sourceAdvSid - 0x00, 0x00, 0x00, // broadcastIdBytes - (byte) BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_NO_PAST, - (byte) BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE, - // 16 bytes badBroadcastCode - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, // numSubGroups - // SubGroup #1 - 0x00, 0x00, 0x00, 0x00, // audioSyncIndex - 0x02, // metaDataLength - 0x00, 0x00, // metadata - }; + value = + new byte[] { + (byte) sourceId, // sourceId + (byte) (mSourceTestDevice.getAddressType() & 0xFF), // sourceAddressType + Utils.getByteAddress(mSourceTestDevice)[5], + Utils.getByteAddress(mSourceTestDevice)[4], + Utils.getByteAddress(mSourceTestDevice)[3], + Utils.getByteAddress(mSourceTestDevice)[2], + Utils.getByteAddress(mSourceTestDevice)[1], + Utils.getByteAddress(mSourceTestDevice)[0], // sourceAddress + 0x00, // sourceAdvSid + 0x00, + 0x00, + 0x00, // broadcastIdBytes + (byte) BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_NO_PAST, + (byte) BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE, + // 16 bytes badBroadcastCode + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, // numSubGroups + // SubGroup #1 + 0x00, + 0x00, + 0x00, + 0x00, // audioSyncIndex + 0x02, // metaDataLength + 0x00, + 0x00, // metadata + }; when(characteristic.getValue()).thenReturn(value); when(characteristic.getInstanceId()).thenReturn(sourceId); @@ -730,7 +794,6 @@ public class BassClientStateMachineTest { verify(callbacks).notifySourceAdded(any(), any(), anyInt()); verify(callbacks).notifyReceiveStateChanged(any(), anyInt(), any()); - assertThat(mBassClientStateMachine.mMsgWhats).contains(STOP_SCAN_OFFLOAD); // set some values for covering more lines of processPASyncState() mBassClientStateMachine.mPendingMetadata = null; @@ -761,15 +824,20 @@ public class BassClientStateMachineTest { value[BassConstants.BCAST_RCVR_STATE_SRC_ADDR_START_IDX + i] = 0x00; } when(mBassClientService.getPeriodicAdvertisementResult(any(), anyInt())).thenReturn(null); - when(mBassClientService.isLocalBroadcast(any())).thenReturn(true); + when(mBassClientService.isLocalBroadcast(any(BluetoothLeBroadcastMetadata.class))) + .thenReturn(true); when(characteristic.getValue()).thenReturn(value); + mBassClientStateMachine.mPendingSourceToSwitch = mBassClientStateMachine.mPendingMetadata; Mockito.clearInvocations(callbacks); cb.onCharacteristicRead(null, characteristic, GATT_SUCCESS); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - verify(callbacks).notifySourceRemoved(any(), anyInt(), anyInt()); + verify(callbacks) + .notifySourceRemoved( + any(), anyInt(), eq(BluetoothStatusCodes.REASON_LOCAL_STACK_REQUEST)); verify(callbacks).notifyReceiveStateChanged(any(), anyInt(), any()); + assertThat(mBassClientStateMachine.mPendingSourceToSwitch).isEqualTo(null); } @Test @@ -1173,7 +1241,8 @@ public class BassClientStateMachineTest { BluetoothLeBroadcastMetadata metadata = createBroadcastMetadata(); // verify local broadcast doesn't require active synced source - when(mBassClientService.isLocalBroadcast(any())).thenReturn(true); + when(mBassClientService.isLocalBroadcast(any(BluetoothLeBroadcastMetadata.class))) + .thenReturn(true); mBassClientStateMachine.sendMessage(ADD_BCAST_SOURCE, metadata); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -1206,6 +1275,24 @@ public class BassClientStateMachineTest { verify(mBassClientService).getActiveSyncedSources(any()); } + @Test + public void sendSwitchSourceMessage_inConnectedState() { + initToConnectedState(); + BluetoothLeBroadcastMetadata metadata = createBroadcastMetadata(); + Integer sourceId = 1; + + BassClientStateMachine.BluetoothGattTestableWrapper btGatt = + Mockito.mock(BassClientStateMachine.BluetoothGattTestableWrapper.class); + mBassClientStateMachine.mBluetoothGatt = btGatt; + BluetoothGattCharacteristic scanControlPoint = + Mockito.mock(BluetoothGattCharacteristic.class); + mBassClientStateMachine.mBroadcastScanControlPoint = scanControlPoint; + + mBassClientStateMachine.sendMessage(SWITCH_BCAST_SOURCE, sourceId, 0, metadata); + TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); + assertThat(mBassClientStateMachine.mPendingSourceToSwitch).isEqualTo(metadata); + } + @Test public void sendUpdateBcastSourceMessage_inConnectedState() { initToConnectedState(); @@ -1217,23 +1304,49 @@ public class BassClientStateMachineTest { when(mBassClientService.getCallbacks()).thenReturn(callbacks); int sourceId = 1; int paSync = BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE; - byte[] value = new byte[] { - (byte) sourceId, // sourceId - 0x00, // sourceAddressType - 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, // sourceAddress - 0x00, // sourceAdvSid - 0x00, 0x00, 0x00, // broadcastIdBytes - (byte) paSync, - (byte) BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE, - // 16 bytes badBroadcastCode - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, // numSubGroups - // SubGroup #1 - 0x00, 0x00, 0x00, 0x00, // audioSyncIndex - 0x02, // metaDataLength - 0x00, 0x00, // metadata - }; + byte[] value = + new byte[] { + (byte) sourceId, // sourceId + (byte) (mSourceTestDevice.getAddressType() & 0xFF), // sourceAddressType + Utils.getByteAddress(mSourceTestDevice)[5], + Utils.getByteAddress(mSourceTestDevice)[4], + Utils.getByteAddress(mSourceTestDevice)[3], + Utils.getByteAddress(mSourceTestDevice)[2], + Utils.getByteAddress(mSourceTestDevice)[1], + Utils.getByteAddress(mSourceTestDevice)[0], // sourceAddress + 0x00, // sourceAdvSid + 0x00, + 0x00, + 0x00, // broadcastIdBytes + (byte) paSync, + (byte) BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE, + // 16 bytes badBroadcastCode + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, // numSubGroups + // SubGroup #1 + 0x00, + 0x00, + 0x00, + 0x00, // audioSyncIndex + 0x02, // metaDataLength + 0x00, + 0x00, // metadata + }; BluetoothGattCharacteristic characteristic = Mockito.mock(BluetoothGattCharacteristic.class); when(characteristic.getValue()).thenReturn(value); @@ -1298,23 +1411,49 @@ public class BassClientStateMachineTest { // Prepare mBluetoothLeBroadcastReceiveStates with metadata for test mBassClientStateMachine.mShouldHandleMessage = false; int sourceId = 1; - byte[] value = new byte[] { - (byte) sourceId, // sourceId - 0x00, // sourceAddressType - 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, // sourceAddress - 0x00, // sourceAdvSid - 0x00, 0x00, 0x00, // broadcastIdBytes - (byte) BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, - (byte) BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED, - // 16 bytes badBroadcastCode - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, // numSubGroups - // SubGroup #1 - 0x00, 0x00, 0x00, 0x00, // audioSyncIndex - 0x02, // metaDataLength - 0x00, 0x00, // metadata - }; + byte[] value = + new byte[] { + (byte) sourceId, // sourceId + (byte) (mSourceTestDevice.getAddressType() & 0xFF), // sourceAddressType + Utils.getByteAddress(mSourceTestDevice)[5], + Utils.getByteAddress(mSourceTestDevice)[4], + Utils.getByteAddress(mSourceTestDevice)[3], + Utils.getByteAddress(mSourceTestDevice)[2], + Utils.getByteAddress(mSourceTestDevice)[1], + Utils.getByteAddress(mSourceTestDevice)[0], // sourceAddress + 0x00, // sourceAdvSid + 0x00, + 0x00, + 0x00, // broadcastIdBytes + (byte) BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_IDLE, + (byte) BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED, + // 16 bytes badBroadcastCode + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, // numSubGroups + // SubGroup #1 + 0x00, + 0x00, + 0x00, + 0x00, // audioSyncIndex + 0x02, // metaDataLength + 0x00, + 0x00, // metadata + }; mBassClientStateMachine.mPendingOperation = REMOVE_BCAST_SOURCE; mBassClientStateMachine.mPendingSourceId = (byte) sourceId; BluetoothGattCharacteristic characteristic = @@ -1500,6 +1639,7 @@ public class BassClientStateMachineTest { // Test sendPendingCallbacks(ADD_BCAST_SOURCE, ERROR_UNKNOWN) moveConnectedStateToConnectedProcessingState(); + mBassClientStateMachine.mPendingMetadata = createBroadcastMetadata(); mBassClientStateMachine.mPendingOperation = ADD_BCAST_SOURCE; sendMessageAndVerifyTransition( mBassClientStateMachine.obtainMessage(GATT_TXN_PROCESSED, GATT_FAILURE), @@ -1609,6 +1749,10 @@ public class BassClientStateMachineTest { TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(REACHED_MAX_SOURCE_LIMIT)) .isTrue(); + + mBassClientStateMachine.sendMessage(SWITCH_BCAST_SOURCE); + TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); + assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(SWITCH_BCAST_SOURCE)).isTrue(); } @Test @@ -1637,7 +1781,8 @@ public class BassClientStateMachineTest { BluetoothLeBroadcastMetadata metadata = createBroadcastMetadata(); // verify local broadcast doesn't require active synced source - when(mBassClientService.isLocalBroadcast(any())).thenReturn(true); + when(mBassClientService.isLocalBroadcast(any(BluetoothLeBroadcastMetadata.class))) + .thenReturn(true); mBassClientStateMachine.sendMessage(ADD_BCAST_SOURCE, metadata); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -1671,7 +1816,8 @@ public class BassClientStateMachineTest { BluetoothLeBroadcastMetadata metadata = createBroadcastMetadata(); // verify local broadcast doesn't require active synced source - when(mBassClientService.isLocalBroadcast(any())).thenReturn(true); + when(mBassClientService.isLocalBroadcast(any(BluetoothLeBroadcastMetadata.class))) + .thenReturn(true); mBassClientStateMachine.sendMessage(ADD_BCAST_SOURCE, metadata); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -1713,25 +1859,16 @@ public class BassClientStateMachineTest { }; ScanRecord record = ScanRecord.parseFromBytes(scanRecord); ScanResult scanResult = new ScanResult(mTestDevice, 0, 0, 0, 0, 0, 0, 0, record, 0); - // validate pending duplicated request will be skipped - mBassClientStateMachine.mPendingSourceToAdd = createBroadcastMetadata(); - - doNothing().when(mMethodProxy).periodicAdvertisingManagerRegisterSync( - any(), any(), anyInt(), anyInt(), any(), any()); - mBassClientStateMachine.sendMessage( - SELECT_BCAST_SOURCE, BassConstants.AUTO, 0, scanResult); - TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); - verify(mBassClientService, never()).updatePeriodicAdvertisementResultMap( - any(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), - any(), any()); - - mBassClientStateMachine.mPendingSourceToAdd = null; List activeSyncedSrc = new ArrayList<>(); activeSyncedSrc.add(testSyncHandle); // need this to ensure expected mock behavior for getActiveSyncedSource when(mBassClientService.getActiveSyncedSources(any())).thenReturn(activeSyncedSrc); when(mBassClientService.getSyncHandleForBroadcastId(anyInt())).thenReturn(testSyncHandle); + doNothing() + .when(mMethodProxy) + .periodicAdvertisingManagerRegisterSync( + any(), any(), anyInt(), anyInt(), any(), any()); mBassClientStateMachine.sendMessage(SELECT_BCAST_SOURCE, BassConstants.AUTO, 0, scanResult); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); @@ -1758,7 +1895,8 @@ public class BassClientStateMachineTest { when(mBassClientService.getCallbacks()).thenReturn(callbacks); BluetoothLeBroadcastMetadata metadata = createBroadcastMetadata(); - when(mBassClientService.isLocalBroadcast(any())).thenReturn(false); + when(mBassClientService.isLocalBroadcast(any(BluetoothLeBroadcastMetadata.class))) + .thenReturn(false); when(mBassClientService.getActiveSyncedSources(any())).thenReturn(null); when(mBassClientService.getCachedBroadcast(anyInt())).thenReturn(null); mBassClientStateMachine.sendMessage(ADD_BCAST_SOURCE, metadata); @@ -2038,10 +2176,11 @@ public class BassClientStateMachineTest { StubBassClientStateMachine( BluetoothDevice device, BassClientService service, + AdapterService adapterService, Looper looper, int connectTimeout, FeatureFlags featureFlags) { - super(device, service, looper, connectTimeout, featureFlags); + super(device, service, adapterService, looper, connectTimeout, featureFlags); } @Override diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java index 0546ff481aafe0cedb1593b61f7cf8bc13bc1c31..7cc9aecb6c4544db8c7b4feda07eb619a49b4c76 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java @@ -41,6 +41,7 @@ import android.bluetooth.BluetoothSinkAudioPolicy; import android.content.Context; import android.media.AudioManager; import android.os.test.TestLooper; +import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArrayMap; import android.util.SparseIntArray; @@ -52,8 +53,6 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.flags.FakeFeatureFlagsImpl; -import com.android.bluetooth.flags.FeatureFlags; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; @@ -63,6 +62,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -98,7 +98,7 @@ public class ActiveDeviceManagerTest { private boolean mOriginalDualModeAudioState; private TestDatabaseManager mDatabaseManager; private TestLooper mTestLooper; - private FakeFeatureFlagsImpl mFakeFlagsImpl; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; @@ -120,9 +120,7 @@ public class ActiveDeviceManagerTest { mTestLooper.startAutoDispatch(); TestUtils.setAdapterService(mAdapterService); - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false); - mDatabaseManager = new TestDatabaseManager(mAdapterService, mFakeFlagsImpl); + mDatabaseManager = new TestDatabaseManager(mAdapterService); when(mAdapterService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); when(mAdapterService.getSystemServiceName(AudioManager.class)) @@ -133,8 +131,7 @@ public class ActiveDeviceManagerTest { when(mServiceFactory.getHearingAidService()).thenReturn(mHearingAidService); when(mServiceFactory.getLeAudioService()).thenReturn(mLeAudioService); - mActiveDeviceManager = - new ActiveDeviceManager(mAdapterService, mServiceFactory, mFakeFlagsImpl); + mActiveDeviceManager = new ActiveDeviceManager(mAdapterService, mServiceFactory); mActiveDeviceManager.start(); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -160,6 +157,11 @@ public class ActiveDeviceManagerTest { when(mLeAudioService.setActiveDevice(any())).thenReturn(true); when(mLeAudioService.removeActiveDevice(anyBoolean())).thenReturn(true); + when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); + when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice2); + when(mLeAudioService.getLeadDevice(mDualModeAudioDevice)).thenReturn(mDualModeAudioDevice); + when(mLeAudioService.getLeadDevice(mLeHearingAidDevice)).thenReturn(mLeHearingAidDevice); + List connectedHearingAidDevices = new ArrayList<>(); connectedHearingAidDevices.add(mHearingAidDevice); when(mHearingAidService.getHiSyncId(mHearingAidDevice)).thenReturn(mHearingAidHiSyncId); @@ -742,11 +744,11 @@ public class ActiveDeviceManagerTest { leAudioConnected(mLeAudioDevice); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); - leAudioConnected(mSecondaryAudioDevice); - verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice); + leAudioConnected(mLeAudioDevice2); + verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice2); Mockito.clearInvocations(mLeAudioService); - leAudioDisconnected(mSecondaryAudioDevice); + leAudioDisconnected(mLeAudioDevice2); verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); } @@ -905,6 +907,35 @@ public class ActiveDeviceManagerTest { verify(mLeAudioService, timeout(TIMEOUT_MS)).deviceDisconnected(mLeAudioDevice2, true); } + @Test + public void leAudioSetConnectedGroupThenDisconnected_noFallback() { + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_ACTIVE_DEVICE_MANAGER_GROUP_HANDLING_FIX); + when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); + + leAudioConnected(mLeAudioDevice); + TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); + verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice); + + Mockito.clearInvocations(mLeAudioService); + + when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice); + leAudioConnected(mLeAudioDevice2); + TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); + verify(mLeAudioService, never()).setActiveDevice(any()); + + Mockito.clearInvocations(mLeAudioService); + + leAudioDisconnected(mLeAudioDevice2); + TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); + verify(mLeAudioService, never()).setActiveDevice(any()); + verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); + + leAudioDisconnected(mLeAudioDevice); + TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); + verify(mLeAudioService, timeout(TIMEOUT_MS)).removeActiveDevice(false); + verify(mLeAudioService, timeout(TIMEOUT_MS)).deviceDisconnected(mLeAudioDevice2, false); + } + /** * An A2DP connected. An LE Audio connected. The LE Audio disconnected. * Then the A2DP should be the active one. @@ -1089,15 +1120,24 @@ public class ActiveDeviceManagerTest { when(mLeAudioService.setActiveDevice(any())).thenReturn(true); when(mLeAudioService.removeActiveDevice(anyBoolean())).thenReturn(true); + when(mLeAudioService.getLeadDevice(mDualModeAudioDevice)).thenReturn(mDualModeAudioDevice); + + Mockito.clearInvocations(mLeAudioService); // Ensure we make LEA active after all supported classic profiles are active a2dpActiveDeviceChanged(mDualModeAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); + when(mAdapterService.isAllSupportedClassicAudioProfilesActive(mDualModeAudioDevice)) .thenReturn(true); headsetActiveDeviceChanged(mDualModeAudioDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); - verify(mLeAudioService, times(2)).setActiveDevice(mDualModeAudioDevice); + + // When A2DP device is getting active, first LeAudio device is removed from active devices + // and later added + verify(mLeAudioService, times(1)).removeActiveDevice(anyBoolean()); + verify(mLeAudioService, times(1)).setActiveDevice(mDualModeAudioDevice); + Assert.assertEquals(mDualModeAudioDevice, mActiveDeviceManager.getA2dpActiveDevice()); Assert.assertEquals(mDualModeAudioDevice, mActiveDeviceManager.getHfpActiveDevice()); Assert.assertEquals(mDualModeAudioDevice, mActiveDeviceManager.getLeAudioActiveDevice()); @@ -1187,7 +1227,7 @@ public class ActiveDeviceManagerTest { */ @Test public void a2dpConnectedWhenBroadcasting_notSetA2dpActive() { - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, true); + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES); final List metadataList = mock(List.class); when(mLeAudioService.getAllBroadcastMetadata()).thenReturn(metadataList); a2dpConnected(mA2dpDevice, false); @@ -1202,7 +1242,7 @@ public class ActiveDeviceManagerTest { */ @Test public void headsetConnectedWhenBroadcasting_notSetHeadsetActive() { - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, true); + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES); final List metadataList = mock(List.class); when(mLeAudioService.getAllBroadcastMetadata()).thenReturn(metadataList); headsetConnected(mHeadsetDevice, false); @@ -1217,7 +1257,7 @@ public class ActiveDeviceManagerTest { */ @Test public void hearingAidConnectedWhenBroadcasting_notSetHearingAidActive() { - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, true); + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES); final List metadataList = mock(List.class); when(mLeAudioService.getAllBroadcastMetadata()).thenReturn(metadataList); hearingAidConnected(mHearingAidDevice); @@ -1230,7 +1270,7 @@ public class ActiveDeviceManagerTest { */ @Test public void leHearingAidConnectedWhenBroadcasting_notSetLeHearingAidActive() { - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, true); + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES); final List metadataList = mock(List.class); when(mLeAudioService.getAllBroadcastMetadata()).thenReturn(metadataList); leHearingAidConnected(mLeHearingAidDevice); @@ -1434,8 +1474,8 @@ public class ActiveDeviceManagerTest { private class TestDatabaseManager extends DatabaseManager { ArrayMap mProfileConnectionPolicy; - TestDatabaseManager(AdapterService service, FeatureFlags featureFlags) { - super(service, featureFlags); + TestDatabaseManager(AdapterService service) { + super(service); mProfileConnectionPolicy = new ArrayMap<>(); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java index 1794e381fd9237a9fb38aae92a0c368f6c2c8377..099c29970a471a206c1a0d8adaa6b88440d4592e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java @@ -64,7 +64,7 @@ import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreNative import com.android.bluetooth.gatt.AdvertiseManagerNativeInterface; import com.android.bluetooth.gatt.DistanceMeasurementNativeInterface; import com.android.bluetooth.gatt.GattNativeInterface; -import com.android.bluetooth.gatt.PeriodicScanNativeInterface; +import com.android.bluetooth.le_scan.PeriodicScanNativeInterface; import com.android.bluetooth.sdp.SdpManagerNativeInterface; import com.android.internal.app.IBatteryStats; diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java index ff715a078426c65f0720042635dbab17a83d1c74..cc84dbc68fcd74589ad1d6a355a71074887d2410 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java @@ -36,6 +36,7 @@ import android.app.admin.DevicePolicyManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; import android.bluetooth.IBluetoothCallback; import android.companion.CompanionDeviceManager; import android.content.Context; @@ -58,6 +59,7 @@ import android.os.UserManager; import android.os.test.TestLooper; import android.permission.PermissionCheckerManager; import android.permission.PermissionManager; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.sysprop.BluetoothProperties; import android.test.mock.MockContentProvider; @@ -70,37 +72,13 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; -import com.android.bluetooth.a2dp.A2dpService; -import com.android.bluetooth.a2dpsink.A2dpSinkService; -import com.android.bluetooth.avrcp.AvrcpTargetService; -import com.android.bluetooth.avrcpcontroller.AvrcpControllerService; -import com.android.bluetooth.bas.BatteryService; -import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreNativeInterface; -import com.android.bluetooth.csip.CsipSetCoordinatorService; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.gatt.AdvertiseManagerNativeInterface; import com.android.bluetooth.gatt.DistanceMeasurementNativeInterface; import com.android.bluetooth.gatt.GattNativeInterface; -import com.android.bluetooth.gatt.GattService; -import com.android.bluetooth.gatt.PeriodicScanNativeInterface; -import com.android.bluetooth.hap.HapClientService; -import com.android.bluetooth.hearingaid.HearingAidService; -import com.android.bluetooth.hfp.HeadsetService; -import com.android.bluetooth.hfpclient.HeadsetClientService; -import com.android.bluetooth.hid.HidDeviceService; -import com.android.bluetooth.hid.HidHostService; -import com.android.bluetooth.le_audio.LeAudioService; -import com.android.bluetooth.map.BluetoothMapService; -import com.android.bluetooth.mapclient.MapClientService; -import com.android.bluetooth.mcp.McpService; -import com.android.bluetooth.opp.BluetoothOppService; -import com.android.bluetooth.pan.PanService; -import com.android.bluetooth.pbap.BluetoothPbapService; -import com.android.bluetooth.pbapclient.PbapClientService; -import com.android.bluetooth.sap.SapService; +import com.android.bluetooth.le_scan.PeriodicScanNativeInterface; import com.android.bluetooth.sdp.SdpManagerNativeInterface; -import com.android.bluetooth.tbs.TbsService; -import com.android.bluetooth.vc.VolumeControlService; import com.android.internal.app.IBatteryStats; import libcore.util.HexEncoding; @@ -108,6 +86,7 @@ import libcore.util.HexEncoding; import org.junit.After; import org.junit.Before; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -156,6 +135,8 @@ public class AdapterServiceTest { private @Mock PeriodicScanNativeInterface mPeriodicNativeInterface; private @Mock JniCallbacks mJniCallbacks; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + // SystemService that are not mocked private BluetoothManager mBluetoothManager; private CompanionDeviceManager mCompanionDeviceManager; @@ -183,32 +164,15 @@ public class AdapterServiceTest { static void configureEnabledProfiles() { Log.e(TAG, "configureEnabledProfiles"); - Config.setProfileEnabled(PanService.class, true); - Config.setProfileEnabled(BluetoothPbapService.class, true); - Config.setProfileEnabled(GattService.class, true); - - Config.setProfileEnabled(A2dpService.class, false); - Config.setProfileEnabled(A2dpSinkService.class, false); - Config.setProfileEnabled(AvrcpTargetService.class, false); - Config.setProfileEnabled(AvrcpControllerService.class, false); - Config.setProfileEnabled(BassClientService.class, false); - Config.setProfileEnabled(BatteryService.class, false); - Config.setProfileEnabled(CsipSetCoordinatorService.class, false); - Config.setProfileEnabled(HapClientService.class, false); - Config.setProfileEnabled(HeadsetService.class, false); - Config.setProfileEnabled(HeadsetClientService.class, false); - Config.setProfileEnabled(HearingAidService.class, false); - Config.setProfileEnabled(HidDeviceService.class, false); - Config.setProfileEnabled(HidHostService.class, false); - Config.setProfileEnabled(LeAudioService.class, false); - Config.setProfileEnabled(TbsService.class, false); - Config.setProfileEnabled(BluetoothMapService.class, false); - Config.setProfileEnabled(MapClientService.class, false); - Config.setProfileEnabled(McpService.class, false); - Config.setProfileEnabled(BluetoothOppService.class, false); - Config.setProfileEnabled(PbapClientService.class, false); - Config.setProfileEnabled(SapService.class, false); - Config.setProfileEnabled(VolumeControlService.class, false); + + for (int profileId = 0; profileId <= BluetoothProfile.MAX_PROFILE_ID; profileId++) { + boolean enabled = + profileId == BluetoothProfile.PAN + || profileId == BluetoothProfile.PBAP + || profileId == BluetoothProfile.GATT; + + Config.setProfileEnabled(profileId, enabled); + } } void mockGetSystemService(String serviceName, Class serviceClass, T mockService) { @@ -239,10 +203,12 @@ public class AdapterServiceTest { PeriodicScanNativeInterface.setInstance(mPeriodicNativeInterface); // Post the creation of AdapterService since it rely on Looper.myLooper() - handler.post(() -> mAdapterService = new AdapterService(mLooper.getLooper())); + handler.post(() -> mAdapterService = spy(new AdapterService(mLooper.getLooper()))); assertThat(mLooper.dispatchAll()).isEqualTo(1); assertThat(mAdapterService).isNotNull(); + doNothing().when(mAdapterService).setProfileServiceState(anyInt(), anyInt()); + mMockPackageManager = mock(PackageManager.class); when(mMockPackageManager.getPermissionInfo(any(), anyInt())) .thenReturn(new PermissionInfo()); @@ -445,7 +411,7 @@ public class AdapterServiceTest { if (!onlyGatt) { // Stop PBAP and PAN services - verify(ctx, times(4)).startService(any()); + verify(adapter, times(4)).setProfileServiceState(anyInt(), anyInt()); for (ProfileService service : services) { adapter.onProfileServiceStateChanged(service, STATE_OFF); @@ -495,7 +461,7 @@ public class AdapterServiceTest { if (!onlyGatt) { // Start Mock PBAP and PAN services - verify(ctx, times(2)).startService(any()); + verify(adapter, times(2)).setProfileServiceState(anyInt(), anyInt()); for (ProfileService service : services) { adapter.addProfile(service); @@ -614,8 +580,8 @@ public class AdapterServiceTest { when(mockContext.getPackageManager()).thenReturn(mMockPackageManager); // Config is set to PBAP, PAN and GATT by default. Turn off PAN and PBAP. - Config.setProfileEnabled(PanService.class, false); - Config.setProfileEnabled(BluetoothPbapService.class, false); + Config.setProfileEnabled(BluetoothProfile.PAN, false); + Config.setProfileEnabled(BluetoothProfile.PBAP, false); Config.init(mockContext); doEnable(true); @@ -702,7 +668,8 @@ public class AdapterServiceTest { mAdapterService.startBrEdr(); syncHandler(AdapterState.USER_TURN_ON); verifyStateChange(STATE_BLE_ON, STATE_TURNING_ON); - verify(mMockContext, times(2)).startService(any()); // Register Mock PBAP and PAN services + verify(mAdapterService, times(2)) + .setProfileServiceState(anyInt(), anyInt()); // Register Mock PBAP and PAN services mAdapterService.addProfile(mMockService); syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED); @@ -717,7 +684,8 @@ public class AdapterServiceTest { syncHandler(AdapterState.BREDR_START_TIMEOUT); verifyStateChange(STATE_TURNING_ON, STATE_TURNING_OFF); - verify(mMockContext, times(4)).startService(any()); // Stop PBAP and PAN services + verify(mAdapterService, times(4)) + .setProfileServiceState(anyInt(), anyInt()); // Stop PBAP and PAN services mAdapterService.onProfileServiceStateChanged(mMockService, STATE_OFF); syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); @@ -739,7 +707,7 @@ public class AdapterServiceTest { mAdapterService.disable(); syncHandler(AdapterState.USER_TURN_OFF); verifyStateChange(STATE_ON, STATE_TURNING_OFF); - verify(mMockContext, times(4)).startService(any()); + verify(mAdapterService, times(4)).setProfileServiceState(anyInt(), anyInt()); mAdapterService.onProfileServiceStateChanged(mMockService, STATE_OFF); syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); @@ -897,7 +865,9 @@ public class AdapterServiceTest { RemoteDevices remoteDevices = mAdapterService.getRemoteDevices(); remoteDevices.addDeviceProperties(Utils.getBytesFromAddress((TEST_BT_ADDR_1))); String identityAddress = mAdapterService.getIdentityAddress(TEST_BT_ADDR_1); - assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_1); + if (!Flags.identityAddressNullIfUnknown()) { + assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_1); + } // Trigger address consolidate callback remoteDevices.addressConsolidateCallback(Utils.getBytesFromAddress(TEST_BT_ADDR_1), @@ -908,6 +878,16 @@ public class AdapterServiceTest { assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_2); } + @Test + public void testIdentityAddressNullIfUnknown() { + mSetFlagsRule.enableFlags(Flags.FLAG_IDENTITY_ADDRESS_NULL_IF_UNKNOWN); + + BluetoothDevice device = TestUtils.getTestDevice(BluetoothAdapter.getDefaultAdapter(), 0); + + assertThat(mAdapterService.getByteIdentityAddress(device)).isNull(); + assertThat(mAdapterService.getIdentityAddress(device.getAddress())).isNull(); + } + public static byte[] getMetricsSalt(HashMap> adapterConfig) { HashMap metricsSection = adapterConfig.get("Metrics"); if (metricsSection == null) { diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java index 5401c88f077d6e0a5beb85de2aed341eef60cbd7..d294c33e77c544b418628608e258efeccba38b18 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AudioRoutingManagerTest.java @@ -49,8 +49,6 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.flags.FakeFeatureFlagsImpl; -import com.android.bluetooth.flags.FeatureFlags; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; @@ -66,6 +64,7 @@ import org.mockito.MockitoAnnotations; import org.mockito.Spy; import java.util.ArrayList; +import java.util.Collections; import java.util.List; @MediumTest @@ -91,7 +90,6 @@ public class AudioRoutingManagerTest { private boolean mOriginalDualModeAudioState; private TestDatabaseManager mDatabaseManager; private TestLooper mTestLooper; - private FakeFeatureFlagsImpl mFakeFlagsImpl; @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; @@ -109,11 +107,13 @@ public class AudioRoutingManagerTest { mTestLooper = new TestLooper(); BluetoothMethodProxy.setInstanceForTesting(mMethodProxy); doReturn(mTestLooper.getLooper()).when(mMethodProxy).handlerThreadGetLooper(any()); + doReturn(Collections.EMPTY_LIST) + .when(mMethodProxy) + .mediaSessionManagerGetActiveSessions(any()); doNothing().when(mMethodProxy).threadStart(any()); TestUtils.setAdapterService(mAdapterService); - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - mDatabaseManager = new TestDatabaseManager(mAdapterService, mFakeFlagsImpl); + mDatabaseManager = new TestDatabaseManager(mAdapterService); when(mAdapterService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager); when(mAdapterService.getSystemServiceName(AudioManager.class)) @@ -124,8 +124,7 @@ public class AudioRoutingManagerTest { when(mServiceFactory.getHearingAidService()).thenReturn(mHearingAidService); when(mServiceFactory.getLeAudioService()).thenReturn(mLeAudioService); - mAudioRoutingManager = - new AudioRoutingManager(mAdapterService, mServiceFactory, mFakeFlagsImpl); + mAudioRoutingManager = new AudioRoutingManager(mAdapterService, mServiceFactory); mAudioRoutingManager.start(); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -171,10 +170,10 @@ public class AudioRoutingManagerTest { /** One A2DP is connected. */ @Test - public void onlyA2dpConnected_setA2dpActive() { + public void onlyA2dpConnected_setA2dpActiveShouldNotCalled() { a2dpConnected(mA2dpDevice, false); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpDevice); + verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); } @Test @@ -192,7 +191,7 @@ public class AudioRoutingManagerTest { } @Test - public void a2dpAndHfpConnectedAtTheSameTime_setA2dpActiveShouldBeCalled() { + public void a2dpAndHfpConnectedAtTheSameTime_setA2dpActiveShouldNotBeCalled() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL); a2dpConnected(mA2dpHeadsetDevice, true); @@ -204,20 +203,21 @@ public class AudioRoutingManagerTest { /** Two A2DP are connected. Should set the second one active. */ @Test - public void secondA2dpConnected_setSecondA2dpActive() { + public void secondA2dpConnected_setA2dpActiveShouldNotBeCalled() { a2dpConnected(mA2dpDevice, false); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpDevice); + verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); a2dpConnected(mSecondaryAudioDevice, false); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mSecondaryAudioDevice); + verify(mA2dpService, never()).setActiveDevice(mSecondaryAudioDevice); } /** One A2DP is connected and disconnected later. Should then set active device to null. */ @Test public void lastA2dpDisconnected_clearA2dpActive() { a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); @@ -228,16 +228,15 @@ public class AudioRoutingManagerTest { /** Two A2DP are connected and active device is explicitly set. */ @Test - public void a2dpActiveDeviceSelected_setActive() { + public void a2dpOnlyDeviceConnected_setActiveShouldNotBeCalled() { a2dpConnected(mA2dpDevice, false); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpDevice); + verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); a2dpConnected(mSecondaryAudioDevice, false); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mSecondaryAudioDevice); + verify(mA2dpService, never()).setActiveDevice(mSecondaryAudioDevice); - Mockito.clearInvocations(mA2dpService); switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); @@ -246,49 +245,53 @@ public class AudioRoutingManagerTest { } /** - * Two A2DP devices are connected and the current active is then disconnected. Should then set - * active device to fallback device. + * A2DP Headset and A2DP only devices are connected and the current activated A2DP only is then + * disconnected. Should then set active device to fallback device. */ @Test - public void a2dpSecondDeviceDisconnected_fallbackDeviceActive() { - a2dpConnected(mA2dpDevice, false); + public void a2dpDeviceDisconnected_fallbackA2dpHeadset() { + a2dpConnected(mA2dpHeadsetDevice, true); + headsetConnected(mA2dpHeadsetDevice, true); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpDevice); + verify(mA2dpService).setActiveDevice(mA2dpHeadsetDevice); + verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice); - a2dpConnected(mSecondaryAudioDevice, false); + a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mSecondaryAudioDevice); + verify(mA2dpService).setActiveDevice(mA2dpDevice); - Mockito.clearInvocations(mA2dpService); - a2dpDisconnected(mSecondaryAudioDevice); + Mockito.clearInvocations(mA2dpService, mHeadsetService); + a2dpDisconnected(mA2dpDevice); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpDevice); + verify(mA2dpService).setActiveDevice(mA2dpHeadsetDevice); } /** One Headset is connected. */ @Test - public void onlyHeadsetConnected_setHeadsetActive() { + public void onlyHeadsetConnected_setHeadsetActiveShouldNotBeCalled() { headsetConnected(mHeadsetDevice, false); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService, never()).setActiveDevice(mHeadsetDevice); } /** Two Headset are connected. Should set the second one active. */ @Test - public void secondHeadsetConnected_setSecondHeadsetActive() { + public void secondHeadsetConnected_noDeviceActivated() { headsetConnected(mHeadsetDevice, false); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService, never()).setActiveDevice(mHeadsetDevice); headsetConnected(mSecondaryAudioDevice, false); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mSecondaryAudioDevice); + verify(mHeadsetService, never()).setActiveDevice(mSecondaryAudioDevice); } /** One Headset is connected and disconnected later. Should then set active device to null. */ @Test public void lastHeadsetDisconnected_clearHeadsetActive() { headsetConnected(mHeadsetDevice, false); + switchHeadsetActiveDevice(mHeadsetDevice); mTestLooper.dispatchAll(); verify(mHeadsetService).setActiveDevice(mHeadsetDevice); @@ -297,18 +300,17 @@ public class AudioRoutingManagerTest { verify(mHeadsetService).setActiveDevice(isNull()); } - /** Two Headset are connected and active device is explicitly set. */ + /** Two Headsets are connected and active device is explicitly set. */ @Test public void headsetActiveDeviceSelected_setActive() { headsetConnected(mHeadsetDevice, false); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService, never()).setActiveDevice(mHeadsetDevice); headsetConnected(mSecondaryAudioDevice, false); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mSecondaryAudioDevice); + verify(mHeadsetService, never()).setActiveDevice(mSecondaryAudioDevice); - Mockito.clearInvocations(mHeadsetService); switchHeadsetActiveDevice(mHeadsetDevice); mTestLooper.dispatchAll(); verify(mHeadsetService).setActiveDevice(mHeadsetDevice); @@ -317,71 +319,70 @@ public class AudioRoutingManagerTest { } /** - * Two Headsets are connected and the current active is then disconnected. Should then set - * active device to fallback device. + * Two Headset only devices are connected and the current active is then disconnected. Then it + * should be fallback to phone. */ @Test - public void headsetSecondDeviceDisconnected_fallbackDeviceActive() { + public void headsetSecondDeviceDisconnected_fallbackToPhone() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL); headsetConnected(mHeadsetDevice, false); + switchHeadsetActiveDevice(mHeadsetDevice); mTestLooper.dispatchAll(); verify(mHeadsetService).setActiveDevice(mHeadsetDevice); headsetConnected(mSecondaryAudioDevice, false); + switchHeadsetActiveDevice(mSecondaryAudioDevice); mTestLooper.dispatchAll(); verify(mHeadsetService).setActiveDevice(mSecondaryAudioDevice); Mockito.clearInvocations(mHeadsetService); headsetDisconnected(mSecondaryAudioDevice); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService, never()).setActiveDevice(mHeadsetDevice); } @Test public void headsetSecondDeviceDisconnected_fallbackDeviceActiveWhileRinging() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_RINGTONE); - headsetConnected(mHeadsetDevice, false); + headsetConnected(mA2dpHeadsetDevice, true); + a2dpConnected(mA2dpHeadsetDevice, true); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice); + verify(mA2dpService).setActiveDevice(mA2dpHeadsetDevice); - headsetConnected(mSecondaryAudioDevice, false); + headsetConnected(mHeadsetDevice, false); + switchHeadsetActiveDevice(mHeadsetDevice); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mSecondaryAudioDevice); + verify(mHeadsetService).setActiveDevice(mHeadsetDevice); Mockito.clearInvocations(mHeadsetService); - headsetDisconnected(mSecondaryAudioDevice); + headsetDisconnected(mHeadsetDevice); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice); } @Test - public void a2dpConnectedButHeadsetNotConnected_setA2dpActive() { + public void a2dpConnectedButHeadsetNotConnected_setA2dpActiveShouldNotBeCalled() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL); a2dpConnected(mA2dpHeadsetDevice, true); mTestLooper.moveTimeForward(AudioRoutingManager.A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS / 2); - mTestLooper.dispatchAll(); - verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); - mTestLooper.moveTimeForward(A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpHeadsetDevice); + verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); } @Test - public void headsetConnectedButA2dpNotConnected_setHeadsetActive() { + public void headsetConnectedButA2dpNotConnected_setHeadsetActiveShouldNotBeCalled() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); headsetConnected(mA2dpHeadsetDevice, true); mTestLooper.moveTimeForward(AudioRoutingManager.A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS / 2); - mTestLooper.dispatchAll(); - verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); - mTestLooper.moveTimeForward(A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS); mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice); + verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); } @Test @@ -414,23 +415,17 @@ public class AudioRoutingManagerTest { @Test public void hfpConnectedAfterTimeout_shouldActivateA2dpAndHeadsetWhenConnected() { - mTestLooper.stopAutoDispatchAndIgnoreExceptions(); a2dpConnected(mA2dpHeadsetDevice, true); - mTestLooper.dispatchAll(); mTestLooper.moveTimeForward(A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpHeadsetDevice); + verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); - assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.A2DP)) - .contains(mA2dpHeadsetDevice); + assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.A2DP)).isEmpty(); assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.HEADSET)).isEmpty(); - Mockito.clearInvocations(mHeadsetService); - Mockito.clearInvocations(mA2dpService); headsetConnected(mA2dpHeadsetDevice, true); mTestLooper.dispatchAll(); - mTestLooper.moveTimeForward(A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS); - mTestLooper.dispatchAll(); + verify(mA2dpService).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice); assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.A2DP)) .contains(mA2dpHeadsetDevice); @@ -480,6 +475,7 @@ public class AudioRoutingManagerTest { verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); headsetConnected(mHeadsetDevice, false); + switchHeadsetActiveDevice(mHeadsetDevice); mTestLooper.dispatchAll(); verify(mHeadsetService).setActiveDevice(mHeadsetDevice); assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.HEADSET)) @@ -498,6 +494,7 @@ public class AudioRoutingManagerTest { verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); @@ -575,12 +572,13 @@ public class AudioRoutingManagerTest { verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice); } - /** A Hearing Aid is connected. Then an A2DP connected. */ + /** A Hearing Aid is connected. Then an A2DP activated. */ @Test public void hearingAidActive_setA2dpActiveExplicitly() { when(mHearingAidService.removeActiveDevice(anyBoolean())).thenReturn(true); hearingAidConnected(mHearingAidDevice); a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mHearingAidService).removeActiveDevice(false); @@ -595,6 +593,7 @@ public class AudioRoutingManagerTest { when(mHearingAidService.removeActiveDevice(anyBoolean())).thenReturn(true); hearingAidConnected(mHearingAidDevice); headsetConnected(mHeadsetDevice, false); + switchHeadsetActiveDevice(mHeadsetDevice); mTestLooper.dispatchAll(); verify(mHearingAidService).removeActiveDevice(false); @@ -742,11 +741,11 @@ public class AudioRoutingManagerTest { } /** - * An LE Audio connected. An A2DP connected. The A2DP disconnected. Then the LE Audio should be + * An LE Audio connected. An A2DP activated. The A2DP disconnected. Then the LE Audio should be * the active one. */ @Test - public void leAudioAndA2dpConnectedThenA2dpDisconnected_fallbackToLeAudio() { + public void leAudioAndA2dpActivatedThenA2dpDisconnected_fallbackToLeAudio() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); leAudioConnected(mLeAudioDevice); @@ -754,6 +753,7 @@ public class AudioRoutingManagerTest { verify(mLeAudioService).setActiveDevice(mLeAudioDevice); a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); @@ -839,14 +839,15 @@ public class AudioRoutingManagerTest { } /** - * An A2DP connected. An LE Audio connected. The LE Audio disconnected. Then the A2DP should be - * the active one. + * An A2DP only device connected. An LE Audio connected. The LE Audio disconnected. Then it + * should be fallback to phone instead of the A2DP only device. */ @Test - public void a2dpAndLeAudioConnectedThenLeAudioDisconnected_fallbackToA2dp() { + public void a2dpAndLeAudioConnectedThenLeAudioDisconnected_fallbackToPhone() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); @@ -857,8 +858,34 @@ public class AudioRoutingManagerTest { Mockito.clearInvocations(mA2dpService); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); + verify(mLeAudioService).removeActiveDevice(false); + verify(mA2dpService, never()).setActiveDevice(mA2dpDevice); + } + + /** + * An A2DP headset connected. An LE Audio connected. The LE Audio disconnected. Then the A2DP + * headset should be the active one. + */ + @Test + public void a2dpHeadsetAndLeAudioConnectedThenLeAudioDisconnected_fallbackToA2dpHeadset() { + when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); + + a2dpConnected(mHeadsetDevice, true); + headsetConnected(mHeadsetDevice, true); + mTestLooper.dispatchAll(); + verify(mA2dpService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService).setActiveDevice(mHeadsetDevice); + + leAudioConnected(mLeAudioDevice); + mTestLooper.dispatchAll(); + verify(mLeAudioService).setActiveDevice(mLeAudioDevice); + + Mockito.clearInvocations(mA2dpService, mHeadsetService); + leAudioDisconnected(mLeAudioDevice); + mTestLooper.dispatchAll(); verify(mLeAudioService).removeActiveDevice(true); - verify(mA2dpService).setActiveDevice(mA2dpDevice); + verify(mA2dpService).setActiveDevice(mHeadsetDevice); + verify(mHeadsetService).setActiveDevice(mHeadsetDevice); } /** @@ -902,6 +929,7 @@ public class AudioRoutingManagerTest { verify(mHearingAidService).setActiveDevice(mHearingAidDevice); a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); verify(mHearingAidService).removeActiveDevice(false); @@ -915,7 +943,7 @@ public class AudioRoutingManagerTest { Mockito.clearInvocations(mHearingAidService, mA2dpService, mLeAudioService); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); - verify(mA2dpService).setActiveDevice(mA2dpDevice); + verify(mHearingAidService).setActiveDevice(mHearingAidDevice); verify(mLeAudioService).removeActiveDevice(true); } @@ -1018,6 +1046,7 @@ public class AudioRoutingManagerTest { when(mLeAudioService.setActiveDevice(any())).thenReturn(false); a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); @@ -1037,15 +1066,6 @@ public class AudioRoutingManagerTest { assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.LE_AUDIO)) .contains(mLeAudioDevice); - Mockito.clearInvocations(mHeadsetService, mLeAudioService); - headsetConnected(mHeadsetDevice, false); - mTestLooper.dispatchAll(); - verify(mHeadsetService).setActiveDevice(mHeadsetDevice); - verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); - assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.HEADSET)).isEmpty(); - assertThat(mAudioRoutingManager.getActiveDevices(BluetoothProfile.LE_AUDIO)) - .contains(mLeAudioDevice); - Mockito.clearInvocations(mLeAudioService); hearingAidConnected(mHearingAidDevice); mTestLooper.dispatchAll(); @@ -1067,7 +1087,9 @@ public class AudioRoutingManagerTest { @Test public void wiredAudioDeviceConnected_setAllActiveDevicesNull() { a2dpConnected(mA2dpDevice, false); + switchA2dpActiveDevice(mA2dpDevice); headsetConnected(mHeadsetDevice, false); + switchHeadsetActiveDevice(mHeadsetDevice); mTestLooper.dispatchAll(); verify(mA2dpService).setActiveDevice(mA2dpDevice); verify(mHeadsetService).setActiveDevice(mHeadsetDevice); @@ -1081,6 +1103,8 @@ public class AudioRoutingManagerTest { /** Helper to indicate A2dp connected for a device. */ private void a2dpConnected(BluetoothDevice device, boolean supportHfp) { + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_ALLOWED); mDatabaseManager.setProfileConnectionPolicy( device, BluetoothProfile.HEADSET, @@ -1122,12 +1146,14 @@ public class AudioRoutingManagerTest { if (device == null) { mAudioRoutingManager.removeActiveDevice(BluetoothProfile.A2DP, false); } else { - mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.A2DP); + mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.A2DP, null); } } /** Helper to indicate Headset connected for a device. */ private void headsetConnected(BluetoothDevice device, boolean supportA2dp) { + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_ALLOWED); mDatabaseManager.setProfileConnectionPolicy( device, BluetoothProfile.A2DP, @@ -1169,12 +1195,15 @@ public class AudioRoutingManagerTest { if (device == null) { mAudioRoutingManager.removeActiveDevice(BluetoothProfile.HEADSET, false); } else { - mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.HEADSET); + mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.HEADSET, null); } } /** Helper to indicate Hearing Aid connected for a device. */ private void hearingAidConnected(BluetoothDevice device) { + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.HEARING_AID, BluetoothProfile.CONNECTION_POLICY_ALLOWED); + mDeviceConnectionStack.add(device); mMostRecentDevice = device; @@ -1209,12 +1238,14 @@ public class AudioRoutingManagerTest { if (device == null) { mAudioRoutingManager.removeActiveDevice(BluetoothProfile.HEARING_AID, false); } else { - mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.HEARING_AID); + mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.HEARING_AID, null); } } /** Helper to indicate LE Audio connected for a device. */ private void leAudioConnected(BluetoothDevice device) { + mDatabaseManager.setProfileConnectionPolicy( + device, BluetoothProfile.LE_AUDIO, BluetoothProfile.CONNECTION_POLICY_ALLOWED); mMostRecentDevice = device; mAudioRoutingManager.profileConnectionStateChanged( @@ -1248,15 +1279,15 @@ public class AudioRoutingManagerTest { if (device == null) { mAudioRoutingManager.removeActiveDevice(BluetoothProfile.LE_AUDIO, false); } else { - mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.LE_AUDIO); + mAudioRoutingManager.activateDeviceProfile(device, BluetoothProfile.LE_AUDIO, null); } } private class TestDatabaseManager extends DatabaseManager { ArrayMap mProfileConnectionPolicy; - TestDatabaseManager(AdapterService service, FeatureFlags featureFlags) { - super(service, featureFlags); + TestDatabaseManager(AdapterService service) { + super(service); mProfileConnectionPolicy = new ArrayMap<>(); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java index 7b97035ed550b6412637b67290e03610712c26a4..de1c706db2fa11074cf02abeb021cd766d094ddf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java @@ -18,7 +18,7 @@ package com.android.bluetooth.btservice; import static com.google.common.truth.Truth.assertThat; -import com.android.bluetooth.csip.CsipSetCoordinatorService; +import android.bluetooth.BluetoothProfile; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,20 +32,24 @@ public final class ConfigTest { public void setProfileEnabled() { boolean enabled = Arrays.stream(Config.getSupportedProfiles()) - .anyMatch(cls -> cls == CsipSetCoordinatorService.class); + .anyMatch(profileId -> profileId == BluetoothProfile.CSIP_SET_COORDINATOR); - Config.setProfileEnabled(CsipSetCoordinatorService.class, false); + Config.setProfileEnabled(BluetoothProfile.CSIP_SET_COORDINATOR, false); assertThat( Arrays.stream(Config.getSupportedProfiles()) - .anyMatch(cls -> cls == CsipSetCoordinatorService.class)) + .anyMatch( + profileId -> + profileId == BluetoothProfile.CSIP_SET_COORDINATOR)) .isFalse(); - Config.setProfileEnabled(CsipSetCoordinatorService.class, true); + Config.setProfileEnabled(BluetoothProfile.CSIP_SET_COORDINATOR, true); assertThat( Arrays.stream(Config.getSupportedProfiles()) - .anyMatch(cls -> cls == CsipSetCoordinatorService.class)) + .anyMatch( + profileId -> + profileId == BluetoothProfile.CSIP_SET_COORDINATOR)) .isTrue(); - Config.setProfileEnabled(CsipSetCoordinatorService.class, enabled); + Config.setProfileEnabled(BluetoothProfile.CSIP_SET_COORDINATOR, enabled); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java index 95e2d700f709e88b4f5cd1c015505d207b958cc5..f08886106a19bfcbb25d7c93881f9bbb2f9c49d3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java @@ -28,6 +28,7 @@ import android.bluetooth.BluetoothUuid; import android.os.HandlerThread; import android.os.ParcelUuid; import android.os.SystemProperties; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.room.Room; import androidx.test.filters.MediumTest; @@ -39,13 +40,13 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.btservice.storage.MetadataDatabase; -import com.android.bluetooth.flags.FakeFeatureFlagsImpl; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetService; import com.android.bluetooth.le_audio.LeAudioService; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -64,18 +65,18 @@ public class PhonePolicyTest { private static final int CONNECT_OTHER_PROFILES_TIMEOUT_WAIT_MILLIS = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS * 3; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private HandlerThread mHandlerThread; private BluetoothAdapter mAdapter; private PhonePolicy mPhonePolicy; private boolean mOriginalDualModeState; - private FakeFeatureFlagsImpl mFakeFlagsImpl; @Mock private AdapterService mAdapterService; @Mock private ServiceFactory mServiceFactory; @Mock private HeadsetService mHeadsetService; @Mock private A2dpService mA2dpService; @Mock private LeAudioService mLeAudioService; - @Mock private DatabaseManager mDatabaseManager; @Before @@ -104,9 +105,7 @@ public class PhonePolicyTest { mAdapter = BluetoothAdapter.getDefaultAdapter(); PhonePolicy.sConnectOtherProfilesTimeoutMillis = CONNECT_OTHER_PROFILES_TIMEOUT_MILLIS; - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - - mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); + mPhonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); mOriginalDualModeState = Utils.isDualModeAudioEnabled(); } @@ -633,8 +632,8 @@ public class PhonePolicyTest { */ @Test public void testAutoConnectHfpOnly() { - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE, false); + mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE); + mSetFlagsRule.disableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); // Return desired values from the mocked object(s) doReturn(BluetoothAdapter.STATE_ON).when(mAdapterService).getState(); @@ -645,9 +644,9 @@ public class PhonePolicyTest { InstrumentationRegistry.getInstrumentation().getTargetContext(), MetadataDatabase.class) .build(); - DatabaseManager db = new DatabaseManager(mAdapterService, mFakeFlagsImpl); + DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); - PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); + PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); @@ -671,8 +670,8 @@ public class PhonePolicyTest { @Test public void autoConnect_whenMultiHfp_startConnection() { - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE, true); + mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE); + mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); // Return desired values from the mocked object(s) doReturn(BluetoothAdapter.STATE_ON).when(mAdapterService).getState(); @@ -683,9 +682,9 @@ public class PhonePolicyTest { InstrumentationRegistry.getInstrumentation().getTargetContext(), MetadataDatabase.class) .build(); - DatabaseManager db = new DatabaseManager(mAdapterService, mFakeFlagsImpl); + DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); - PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); + PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); @@ -715,8 +714,8 @@ public class PhonePolicyTest { @Test public void autoConnect_whenMultiHfpAndDeconnection_startConnection() { - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE, true); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE, true); + mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); + mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE); // Return desired values from the mocked object(s) doReturn(BluetoothAdapter.STATE_ON).when(mAdapterService).getState(); @@ -727,9 +726,9 @@ public class PhonePolicyTest { InstrumentationRegistry.getInstrumentation().getTargetContext(), MetadataDatabase.class) .build(); - DatabaseManager db = new DatabaseManager(mAdapterService, mFakeFlagsImpl); + DatabaseManager db = new DatabaseManager(mAdapterService); doReturn(db).when(mAdapterService).getDatabase(); - PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory, mFakeFlagsImpl); + PhonePolicy phonePolicy = new PhonePolicy(mAdapterService, mServiceFactory); db.start(mDatabase); TestUtils.waitForLooperToFinishScheduledTask(db.getHandlerLooper()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java index e82606c5cbad6130c53fe8ab707cb25cba694cdd..660fdb78dcee755484bae654fa007047dd847d24 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java @@ -18,75 +18,60 @@ package com.android.bluetooth.btservice; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; import android.bluetooth.BluetoothAdapter; -import android.content.Context; -import android.content.Intent; -import android.location.LocationManager; +import android.bluetooth.BluetoothProfile; +import android.os.Handler; import android.os.Looper; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; -import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.a2dp.A2dpNativeInterface; import com.android.bluetooth.avrcp.AvrcpNativeInterface; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.gatt.GattService; +import com.android.bluetooth.csip.CsipSetCoordinatorNativeInterface; +import com.android.bluetooth.hap.HapClientNativeInterface; import com.android.bluetooth.hearingaid.HearingAidNativeInterface; import com.android.bluetooth.hfp.HeadsetNativeInterface; import com.android.bluetooth.hid.HidDeviceNativeInterface; import com.android.bluetooth.hid.HidHostNativeInterface; +import com.android.bluetooth.le_audio.LeAudioNativeInterface; import com.android.bluetooth.pan.PanNativeInterface; +import com.android.bluetooth.vc.VolumeControlNativeInterface; import org.junit.After; import org.junit.Assert; 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 org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; +import org.mockito.Spy; import java.lang.reflect.InvocationTargetException; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeoutException; +import java.util.Map; +import java.util.concurrent.FutureTask; +import java.util.stream.Collectors; @MediumTest @RunWith(AndroidJUnit4.class) public class ProfileServiceTest { - private static final int PROFILE_START_MILLIS = 1250; private static final int NUM_REPEATS = 5; - @Rule public final ServiceTestRule mServiceTestRule = new ServiceTestRule(); - @Mock private AdapterService mMockAdapterService; - @Mock private DatabaseManager mDatabaseManager; - @Mock private LocationManager mLocationManager; + @Spy + private AdapterService mAdapterService = + new AdapterService(InstrumentationRegistry.getTargetContext()); - private Class[] mProfiles; - ConcurrentHashMap mStartedProfileMap = new ConcurrentHashMap(); + @Mock private DatabaseManager mDatabaseManager; - private void setProfileState(Class profile, int state) throws TimeoutException { - if (state == BluetoothAdapter.STATE_ON) { - mStartedProfileMap.put(profile.getSimpleName(), true); - } else if (state == BluetoothAdapter.STATE_OFF) { - mStartedProfileMap.put(profile.getSimpleName(), false); - } - Intent startIntent = new Intent(InstrumentationRegistry.getTargetContext(), profile); - startIntent.putExtra( - AdapterService.EXTRA_ACTION, AdapterService.ACTION_SERVICE_STATE_CHANGED); - startIntent.putExtra(BluetoothAdapter.EXTRA_STATE, state); - mServiceTestRule.startService(startIntent); - } + private int[] mProfiles; @Mock private A2dpNativeInterface mA2dpNativeInterface; @Mock private AvrcpNativeInterface mAvrcpNativeInterface; @@ -95,11 +80,26 @@ public class ProfileServiceTest { @Mock private HidDeviceNativeInterface mHidDeviceNativeInterface; @Mock private HidHostNativeInterface mHidHostNativeInterface; @Mock private PanNativeInterface mPanNativeInterface; + @Mock private CsipSetCoordinatorNativeInterface mCsipSetCoordinatorInterface; + @Mock private HapClientNativeInterface mHapClientInterface; + @Mock private LeAudioNativeInterface mLeAudioInterface; + @Mock private VolumeControlNativeInterface mVolumeControlInterface; + + private void setProfileState(int profile, int state) { + FutureTask task = + new FutureTask(() -> mAdapterService.setProfileServiceState(profile, state), null); + new Handler(Looper.getMainLooper()).post(task); + try { + task.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - private void setAllProfilesState(int state, int invocationNumber) throws TimeoutException { + private void setAllProfilesState(int state, int invocationNumber) { int profileCount = mProfiles.length; - for (Class profile : mProfiles) { - if (profile == GattService.class) { + for (int profile : mProfiles) { + if (profile == BluetoothProfile.GATT) { // GattService is no longer a service to be start independently profileCount--; continue; @@ -107,28 +107,21 @@ public class ProfileServiceTest { setProfileState(profile, state); } if (invocationNumber == 0) { - verify(mMockAdapterService, after(PROFILE_START_MILLIS).never()) - .onProfileServiceStateChanged(any(), anyInt()); + verify(mAdapterService, never()).onProfileServiceStateChanged(any(), anyInt()); return; } ArgumentCaptor argument = ArgumentCaptor.forClass(ProfileService.class); - verify( - mMockAdapterService, - timeout(PROFILE_START_MILLIS).times(profileCount * invocationNumber)) + verify(mAdapterService, times(profileCount * invocationNumber)) .onProfileServiceStateChanged(argument.capture(), eq(state)); - List argumentProfiles = argument.getAllValues(); - for (Class profile : mProfiles) { - if (profile == GattService.class) { - continue; - } - int matches = 0; - for (ProfileService arg : argumentProfiles) { - if (arg.getClass().getName().equals(profile.getName())) { - matches += 1; - } - } - Assert.assertEquals(invocationNumber, matches); - } + + Map counts = + argument.getAllValues().stream() + .collect(Collectors.groupingBy(Object::getClass, Collectors.counting())); + + counts.forEach( + (clazz, count) -> + Assert.assertEquals( + clazz.getSimpleName(), (long) invocationNumber, count.longValue())); } @Before @@ -140,22 +133,17 @@ public class ProfileServiceTest { Assert.assertNotNull(Looper.myLooper()); MockitoAnnotations.initMocks(this); - when(mMockAdapterService.isStartedProfile(anyString())).thenAnswer(new Answer() { - @Override - public Boolean answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - return mStartedProfileMap.get((String) args[0]); - } - }); - doReturn(mDatabaseManager).when(mMockAdapterService).getDatabase(); - when(mMockAdapterService.getSystemService(Context.LOCATION_SERVICE)) - .thenReturn(mLocationManager); - when(mMockAdapterService.getSystemServiceName(LocationManager.class)) - .thenReturn(Context.LOCATION_SERVICE); + doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); + doNothing().when(mAdapterService).addProfile(any()); + doNothing().when(mAdapterService).removeProfile(any()); + doNothing().when(mAdapterService).onProfileServiceStateChanged(any(), anyInt()); + doReturn(42).when(mAdapterService).getMaxConnectedAudioDevices(); + doReturn(false).when(mAdapterService).isA2dpOffloadEnabled(); + doReturn(false).when(mAdapterService).pbapPseDynamicVersionUpgradeIsEnabled(); mProfiles = Config.getSupportedProfiles(); - TestUtils.setAdapterService(mMockAdapterService); + TestUtils.setAdapterService(mAdapterService); Assert.assertNotNull(AdapterService.getAdapterService()); @@ -166,13 +154,17 @@ public class ProfileServiceTest { HidDeviceNativeInterface.setInstance(mHidDeviceNativeInterface); HidHostNativeInterface.setInstance(mHidHostNativeInterface); PanNativeInterface.setInstance(mPanNativeInterface); + CsipSetCoordinatorNativeInterface.setInstance(mCsipSetCoordinatorInterface); + HapClientNativeInterface.setInstance(mHapClientInterface); + LeAudioNativeInterface.setInstance(mLeAudioInterface); + VolumeControlNativeInterface.setInstance(mVolumeControlInterface); } @After public void tearDown() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - TestUtils.clearAdapterService(mMockAdapterService); - mMockAdapterService = null; + TestUtils.clearAdapterService(mAdapterService); + mAdapterService = null; mProfiles = null; A2dpNativeInterface.setInstance(null); AvrcpNativeInterface.setInstance(null); @@ -181,13 +173,17 @@ public class ProfileServiceTest { HidDeviceNativeInterface.setInstance(null); HidHostNativeInterface.setInstance(null); PanNativeInterface.setInstance(null); + CsipSetCoordinatorNativeInterface.setInstance(null); + HapClientNativeInterface.setInstance(null); + LeAudioNativeInterface.setInstance(null); + VolumeControlNativeInterface.setInstance(null); } /** * Test: Start the Bluetooth services that are configured. Verify that the same services start. */ @Test - public void testEnableDisable() throws TimeoutException { + public void testEnableDisable() { setAllProfilesState(BluetoothAdapter.STATE_ON, 1); setAllProfilesState(BluetoothAdapter.STATE_OFF, 1); } @@ -196,7 +192,7 @@ public class ProfileServiceTest { * Test: Start the Bluetooth services that are configured twice. Verify that the services start. */ @Test - public void testEnableDisableTwice() throws TimeoutException { + public void testEnableDisableTwice() { setAllProfilesState(BluetoothAdapter.STATE_ON, 1); setAllProfilesState(BluetoothAdapter.STATE_OFF, 1); setAllProfilesState(BluetoothAdapter.STATE_ON, 2); @@ -204,14 +200,14 @@ public class ProfileServiceTest { } /** - * Test: Start the Bluetooth services that are configured. - * Verify that each profile starts and stops. + * Test: Start the Bluetooth services that are configured. Verify that each profile starts and + * stops. */ @Test - public void testEnableDisableInterleaved() throws TimeoutException { + public void testEnableDisableInterleaved() { int invocationNumber = mProfiles.length; - for (Class profile : mProfiles) { - if (profile == GattService.class) { + for (int profile : mProfiles) { + if (profile == BluetoothProfile.GATT) { // GattService is no longer a service to be start independently invocationNumber--; continue; @@ -221,12 +217,10 @@ public class ProfileServiceTest { } ArgumentCaptor starts = ArgumentCaptor.forClass(ProfileService.class); ArgumentCaptor stops = ArgumentCaptor.forClass(ProfileService.class); - verify(mMockAdapterService, - timeout(PROFILE_START_MILLIS).times(invocationNumber)).onProfileServiceStateChanged( - starts.capture(), eq(BluetoothAdapter.STATE_ON)); - verify(mMockAdapterService, - timeout(PROFILE_START_MILLIS).times(invocationNumber)).onProfileServiceStateChanged( - stops.capture(), eq(BluetoothAdapter.STATE_OFF)); + verify(mAdapterService, times(invocationNumber)) + .onProfileServiceStateChanged(starts.capture(), eq(BluetoothAdapter.STATE_ON)); + verify(mAdapterService, times(invocationNumber)) + .onProfileServiceStateChanged(stops.capture(), eq(BluetoothAdapter.STATE_OFF)); List startedArguments = starts.getAllValues(); List stoppedArguments = stops.getAllValues(); @@ -239,14 +233,13 @@ public class ProfileServiceTest { } /** - * Test: Start and stop a single profile repeatedly. - * Verify that the profiles start and stop. + * Test: Start and stop a single profile repeatedly. Verify that the profiles start and stop. */ @Test - public void testRepeatedEnableDisableSingly() throws TimeoutException { + public void testRepeatedEnableDisableSingly() { int profileNumber = 0; - for (Class profile : mProfiles) { - if (profile == GattService.class) { + for (int profile : mProfiles) { + if (profile == BluetoothProfile.GATT) { // GattService is no longer a service to be start independently continue; } @@ -254,14 +247,14 @@ public class ProfileServiceTest { setProfileState(profile, BluetoothAdapter.STATE_ON); ArgumentCaptor start = ArgumentCaptor.forClass(ProfileService.class); - verify(mMockAdapterService, timeout(PROFILE_START_MILLIS).times( - NUM_REPEATS * profileNumber + i + 1)).onProfileServiceStateChanged( - start.capture(), eq(BluetoothAdapter.STATE_ON)); + verify(mAdapterService, times(NUM_REPEATS * profileNumber + i + 1)) + .onProfileServiceStateChanged( + start.capture(), eq(BluetoothAdapter.STATE_ON)); setProfileState(profile, BluetoothAdapter.STATE_OFF); ArgumentCaptor stop = ArgumentCaptor.forClass(ProfileService.class); - verify(mMockAdapterService, timeout(PROFILE_START_MILLIS).times( - NUM_REPEATS * profileNumber + i + 1)).onProfileServiceStateChanged( - stop.capture(), eq(BluetoothAdapter.STATE_OFF)); + verify(mAdapterService, times(NUM_REPEATS * profileNumber + i + 1)) + .onProfileServiceStateChanged( + stop.capture(), eq(BluetoothAdapter.STATE_OFF)); Assert.assertEquals(start.getValue(), stop.getValue()); } profileNumber += 1; @@ -273,10 +266,10 @@ public class ProfileServiceTest { * registered and unregistered accordingly. */ @Test - public void testProfileServiceRegisterUnregister() throws TimeoutException { + public void testProfileServiceRegisterUnregister() { int profileNumber = 0; - for (Class profile : mProfiles) { - if (profile == GattService.class) { + for (int profile : mProfiles) { + if (profile == BluetoothProfile.GATT) { // GattService is no longer a service to be start independently continue; } @@ -284,14 +277,12 @@ public class ProfileServiceTest { setProfileState(profile, BluetoothAdapter.STATE_ON); ArgumentCaptor start = ArgumentCaptor.forClass(ProfileService.class); - verify(mMockAdapterService, timeout(PROFILE_START_MILLIS).times( - NUM_REPEATS * profileNumber + i + 1)).addProfile( - start.capture()); + verify(mAdapterService, times(NUM_REPEATS * profileNumber + i + 1)) + .addProfile(start.capture()); setProfileState(profile, BluetoothAdapter.STATE_OFF); ArgumentCaptor stop = ArgumentCaptor.forClass(ProfileService.class); - verify(mMockAdapterService, timeout(PROFILE_START_MILLIS).times( - NUM_REPEATS * profileNumber + i + 1)).removeProfile( - stop.capture()); + verify(mAdapterService, times(NUM_REPEATS * profileNumber + i + 1)) + .removeProfile(stop.capture()); Assert.assertEquals(start.getValue(), stop.getValue()); } profileNumber += 1; @@ -299,11 +290,11 @@ public class ProfileServiceTest { } /** - * Test: Stop the Bluetooth profile services that are not started. - * Verify that the profile service state is not changed. + * Test: Stop the Bluetooth profile services that are not started. Verify that the profile + * service state is not changed. */ @Test - public void testDisable() throws TimeoutException { + public void testDisable() { setAllProfilesState(BluetoothAdapter.STATE_OFF, 0); } } 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 0045e71a1ce1fd3ba11302665be8fadb97483cc4..54d3e7bf105d310b0b09d7ed6e78d834030eeab4 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 @@ -742,6 +742,12 @@ public class RemoteDevicesTest { Assert.assertFalse(deviceProp.isCoordinatedSetMember()); } + @Test + public void testIsDeviceNull() { + Assert.assertNull(mRemoteDevices.getDeviceProperties(null)); + } + + private static void verifyBatteryLevelChangedIntent(BluetoothDevice device, int batteryLevel, ArgumentCaptor intentArgument) { verifyBatteryLevelChangedIntent(device, batteryLevel, intentArgument.getValue()); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java index 711daa94da93708a125dbd9de22a488ede96b998..679850bed72640c94db96bc1cb6369a31e394a4f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/DatabaseManagerTest.java @@ -37,6 +37,7 @@ import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.room.Room; import androidx.room.testing.MigrationTestHelper; @@ -48,7 +49,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; -import com.android.bluetooth.flags.FakeFeatureFlagsImpl; import com.android.bluetooth.flags.Flags; import com.google.common.truth.Truth; @@ -81,7 +81,6 @@ public final class DatabaseManagerTest { private BluetoothDevice mTestDevice; private BluetoothDevice mTestDevice2; private BluetoothDevice mTestDevice3; - private FakeFeatureFlagsImpl mFakeFlagsImpl; private static final String LOCAL_STORAGE = "LocalStorage"; private static final String TEST_BT_ADDR = "11:22:33:44:55:66"; @@ -95,6 +94,8 @@ public final class DatabaseManagerTest { private static final int MAX_META_ID = 16; private static final byte[] TEST_BYTE_ARRAY = "TEST_VALUE".getBytes(); + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule public MigrationTestHelper testHelper = new MigrationTestHelper( InstrumentationRegistry.getInstrumentation(), @@ -116,9 +117,7 @@ public final class DatabaseManagerTest { when(mAdapterService.getPackageManager()).thenReturn( InstrumentationRegistry.getTargetContext().getPackageManager()); - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - - mDatabaseManager = new DatabaseManager(mAdapterService, mFakeFlagsImpl); + mDatabaseManager = new DatabaseManager(mAdapterService); BluetoothDevice[] bondedDevices = {mTestDevice}; doReturn(bondedDevices).when(mAdapterService).getBondedDevices(); @@ -408,6 +407,7 @@ public final class DatabaseManagerTest { testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_GTBS_CCCD, value, true); testSetGetCustomMetaCase(false, badKey, value, false); + testSetGetCustomMetaCase(false, BluetoothDevice.METADATA_EXCLUSIVE_MANAGER, value, true); // Device is in database testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_MANUFACTURER_NAME, @@ -471,6 +471,7 @@ public final class DatabaseManagerTest { value, true); testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_GTBS_CCCD, value, true); + testSetGetCustomMetaCase(true, BluetoothDevice.METADATA_EXCLUSIVE_MANAGER, value, true); } @Test public void testSetGetAudioPolicyMetaData() { @@ -489,7 +490,7 @@ public final class DatabaseManagerTest { @Test public void testSetConnectionHeadset() { - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE, false); + mSetFlagsRule.disableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); // Verify pre-conditions to ensure a fresh test Assert.assertEquals(0, mDatabaseManager.mMetadataCache.size()); Assert.assertNotNull(mTestDevice); @@ -542,7 +543,7 @@ public final class DatabaseManagerTest { @Test public void testSetConnection() { - mFakeFlagsImpl.setFlag(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE, false); + mSetFlagsRule.disableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); // Verify pre-conditions to ensure a fresh test Assert.assertEquals(0, mDatabaseManager.mMetadataCache.size()); Assert.assertNotNull(mTestDevice); @@ -1427,6 +1428,55 @@ public final class DatabaseManagerTest { } } + @Test + public void testDatabaseMigration_118_119() throws IOException { + // Create a database with version 118 + SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 118); + // insert a device to the database + ContentValues device = new ContentValues(); + device.put("address", TEST_BT_ADDR); + device.put("migrated", false); + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + CoreMatchers.not(-1)); + + // Migrate database from 118 to 119 + db.close(); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 119, true, MetadataDatabase.MIGRATION_118_119); + Cursor cursor = db.query("SELECT * FROM metadata"); + assertHasColumn(cursor, "exclusive_manager", true); + while (cursor.moveToNext()) { + // Check the new column was added with default value + assertColumnBlobData(cursor, "exclusive_manager", null); + } + } + + @Test + public void testDatabaseMigration_119_120() throws IOException { + // Create a database with version 119 + SupportSQLiteDatabase db = testHelper.createDatabase(DB_NAME, 119); + // insert a device to the database + ContentValues device = new ContentValues(); + device.put("address", TEST_BT_ADDR); + device.put("migrated", false); + assertThat( + db.insert("metadata", SQLiteDatabase.CONFLICT_IGNORE, device), + CoreMatchers.not(-1)); + // Migrate database from 119 to 120 + db.close(); + db = + testHelper.runMigrationsAndValidate( + DB_NAME, 120, true, MetadataDatabase.MIGRATION_119_120); + Cursor cursor = db.query("SELECT * FROM metadata"); + assertHasColumn(cursor, "active_audio_device_policy", true); + while (cursor.moveToNext()) { + // Check the new columns was added with default value + assertColumnIntData(cursor, "active_audio_device_policy", 0); + } + } + /** * Helper function to check whether the database has the expected column */ diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/119.json b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/119.json new file mode 100644 index 0000000000000000000000000000000000000000..3019b1038e24478403ddbcf8d1e2969f1d9b6b62 --- /dev/null +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/119.json @@ -0,0 +1,394 @@ +{ + "formatVersion": 1, + "database": { + "version": 119, + "identityHash": "7f463dc18499d33a731e823f5d522892", + "entities": [ + { + "tableName": "metadata", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `migrated` INTEGER NOT NULL, `a2dpSupportsOptionalCodecs` INTEGER NOT NULL, `a2dpOptionalCodecsEnabled` INTEGER NOT NULL, `last_active_time` INTEGER NOT NULL, `is_active_a2dp_device` INTEGER NOT NULL, `isActiveHfpDevice` INTEGER NOT NULL, `preferred_output_only_profile` INTEGER NOT NULL, `preferred_duplex_profile` INTEGER NOT NULL, `a2dp_connection_policy` INTEGER, `a2dp_sink_connection_policy` INTEGER, `hfp_connection_policy` INTEGER, `hfp_client_connection_policy` INTEGER, `hid_host_connection_policy` INTEGER, `pan_connection_policy` INTEGER, `pbap_connection_policy` INTEGER, `pbap_client_connection_policy` INTEGER, `map_connection_policy` INTEGER, `sap_connection_policy` INTEGER, `hearing_aid_connection_policy` INTEGER, `hap_client_connection_policy` INTEGER, `map_client_connection_policy` INTEGER, `le_audio_connection_policy` INTEGER, `volume_control_connection_policy` INTEGER, `csip_set_coordinator_connection_policy` INTEGER, `le_call_control_connection_policy` INTEGER, `bass_client_connection_policy` INTEGER, `battery_connection_policy` INTEGER, `manufacturer_name` BLOB, `model_name` BLOB, `software_version` BLOB, `hardware_version` BLOB, `companion_app` BLOB, `main_icon` BLOB, `is_untethered_headset` BLOB, `untethered_left_icon` BLOB, `untethered_right_icon` BLOB, `untethered_case_icon` BLOB, `untethered_left_battery` BLOB, `untethered_right_battery` BLOB, `untethered_case_battery` BLOB, `untethered_left_charging` BLOB, `untethered_right_charging` BLOB, `untethered_case_charging` BLOB, `enhanced_settings_ui_uri` BLOB, `device_type` BLOB, `main_battery` BLOB, `main_charging` BLOB, `main_low_battery_threshold` BLOB, `untethered_left_low_battery_threshold` BLOB, `untethered_right_low_battery_threshold` BLOB, `untethered_case_low_battery_threshold` BLOB, `spatial_audio` BLOB, `fastpair_customized` BLOB, `le_audio` BLOB, `gmcs_cccd` BLOB, `gtbs_cccd` BLOB, `exclusive_manager` BLOB, `call_establish_audio_policy` INTEGER, `connecting_time_audio_policy` INTEGER, `in_band_ringtone_audio_policy` INTEGER, PRIMARY KEY(`address`))", + "fields": [ + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "migrated", + "columnName": "migrated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "a2dpSupportsOptionalCodecs", + "columnName": "a2dpSupportsOptionalCodecs", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "a2dpOptionalCodecsEnabled", + "columnName": "a2dpOptionalCodecsEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "last_active_time", + "columnName": "last_active_time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "is_active_a2dp_device", + "columnName": "is_active_a2dp_device", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isActiveHfpDevice", + "columnName": "isActiveHfpDevice", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "preferred_output_only_profile", + "columnName": "preferred_output_only_profile", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "preferred_duplex_profile", + "columnName": "preferred_duplex_profile", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "profileConnectionPolicies.a2dp_connection_policy", + "columnName": "a2dp_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.a2dp_sink_connection_policy", + "columnName": "a2dp_sink_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hfp_connection_policy", + "columnName": "hfp_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hfp_client_connection_policy", + "columnName": "hfp_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hid_host_connection_policy", + "columnName": "hid_host_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.pan_connection_policy", + "columnName": "pan_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.pbap_connection_policy", + "columnName": "pbap_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.pbap_client_connection_policy", + "columnName": "pbap_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.map_connection_policy", + "columnName": "map_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.sap_connection_policy", + "columnName": "sap_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hearing_aid_connection_policy", + "columnName": "hearing_aid_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hap_client_connection_policy", + "columnName": "hap_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.map_client_connection_policy", + "columnName": "map_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.le_audio_connection_policy", + "columnName": "le_audio_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.volume_control_connection_policy", + "columnName": "volume_control_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.csip_set_coordinator_connection_policy", + "columnName": "csip_set_coordinator_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.le_call_control_connection_policy", + "columnName": "le_call_control_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.bass_client_connection_policy", + "columnName": "bass_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.battery_connection_policy", + "columnName": "battery_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "publicMetadata.manufacturer_name", + "columnName": "manufacturer_name", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.model_name", + "columnName": "model_name", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.software_version", + "columnName": "software_version", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.hardware_version", + "columnName": "hardware_version", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.companion_app", + "columnName": "companion_app", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_icon", + "columnName": "main_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.is_untethered_headset", + "columnName": "is_untethered_headset", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_icon", + "columnName": "untethered_left_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_icon", + "columnName": "untethered_right_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_icon", + "columnName": "untethered_case_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_battery", + "columnName": "untethered_left_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_battery", + "columnName": "untethered_right_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_battery", + "columnName": "untethered_case_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_charging", + "columnName": "untethered_left_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_charging", + "columnName": "untethered_right_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_charging", + "columnName": "untethered_case_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.enhanced_settings_ui_uri", + "columnName": "enhanced_settings_ui_uri", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.device_type", + "columnName": "device_type", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_battery", + "columnName": "main_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_charging", + "columnName": "main_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_low_battery_threshold", + "columnName": "main_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_low_battery_threshold", + "columnName": "untethered_left_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_low_battery_threshold", + "columnName": "untethered_right_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_low_battery_threshold", + "columnName": "untethered_case_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.spatial_audio", + "columnName": "spatial_audio", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.fastpair_customized", + "columnName": "fastpair_customized", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.le_audio", + "columnName": "le_audio", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.gmcs_cccd", + "columnName": "gmcs_cccd", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.gtbs_cccd", + "columnName": "gtbs_cccd", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.exclusive_manager", + "columnName": "exclusive_manager", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "audioPolicyMetadata.callEstablishAudioPolicy", + "columnName": "call_establish_audio_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "audioPolicyMetadata.connectingTimeAudioPolicy", + "columnName": "connecting_time_audio_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "audioPolicyMetadata.inBandRingtoneAudioPolicy", + "columnName": "in_band_ringtone_audio_policy", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "address" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7f463dc18499d33a731e823f5d522892')" + ] + } +} \ No newline at end of file diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/120.json b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/120.json new file mode 100644 index 0000000000000000000000000000000000000000..889402da6302f889eeedc3862059d9201e9957d6 --- /dev/null +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/schemas/com.android.bluetooth.btservice.storage.MetadataDatabase/120.json @@ -0,0 +1,400 @@ +{ + "formatVersion": 1, + "database": { + "version": 120, + "identityHash": "5e9dc09807d50827ab4928ae23ac4173", + "entities": [ + { + "tableName": "metadata", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `migrated` INTEGER NOT NULL, `a2dpSupportsOptionalCodecs` INTEGER NOT NULL, `a2dpOptionalCodecsEnabled` INTEGER NOT NULL, `last_active_time` INTEGER NOT NULL, `is_active_a2dp_device` INTEGER NOT NULL, `isActiveHfpDevice` INTEGER NOT NULL, `preferred_output_only_profile` INTEGER NOT NULL, `preferred_duplex_profile` INTEGER NOT NULL, `active_audio_device_policy` INTEGER NOT NULL, `a2dp_connection_policy` INTEGER, `a2dp_sink_connection_policy` INTEGER, `hfp_connection_policy` INTEGER, `hfp_client_connection_policy` INTEGER, `hid_host_connection_policy` INTEGER, `pan_connection_policy` INTEGER, `pbap_connection_policy` INTEGER, `pbap_client_connection_policy` INTEGER, `map_connection_policy` INTEGER, `sap_connection_policy` INTEGER, `hearing_aid_connection_policy` INTEGER, `hap_client_connection_policy` INTEGER, `map_client_connection_policy` INTEGER, `le_audio_connection_policy` INTEGER, `volume_control_connection_policy` INTEGER, `csip_set_coordinator_connection_policy` INTEGER, `le_call_control_connection_policy` INTEGER, `bass_client_connection_policy` INTEGER, `battery_connection_policy` INTEGER, `manufacturer_name` BLOB, `model_name` BLOB, `software_version` BLOB, `hardware_version` BLOB, `companion_app` BLOB, `main_icon` BLOB, `is_untethered_headset` BLOB, `untethered_left_icon` BLOB, `untethered_right_icon` BLOB, `untethered_case_icon` BLOB, `untethered_left_battery` BLOB, `untethered_right_battery` BLOB, `untethered_case_battery` BLOB, `untethered_left_charging` BLOB, `untethered_right_charging` BLOB, `untethered_case_charging` BLOB, `enhanced_settings_ui_uri` BLOB, `device_type` BLOB, `main_battery` BLOB, `main_charging` BLOB, `main_low_battery_threshold` BLOB, `untethered_left_low_battery_threshold` BLOB, `untethered_right_low_battery_threshold` BLOB, `untethered_case_low_battery_threshold` BLOB, `spatial_audio` BLOB, `fastpair_customized` BLOB, `le_audio` BLOB, `gmcs_cccd` BLOB, `gtbs_cccd` BLOB, `exclusive_manager` BLOB, `call_establish_audio_policy` INTEGER, `connecting_time_audio_policy` INTEGER, `in_band_ringtone_audio_policy` INTEGER, PRIMARY KEY(`address`))", + "fields": [ + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "migrated", + "columnName": "migrated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "a2dpSupportsOptionalCodecs", + "columnName": "a2dpSupportsOptionalCodecs", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "a2dpOptionalCodecsEnabled", + "columnName": "a2dpOptionalCodecsEnabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "last_active_time", + "columnName": "last_active_time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "is_active_a2dp_device", + "columnName": "is_active_a2dp_device", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isActiveHfpDevice", + "columnName": "isActiveHfpDevice", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "preferred_output_only_profile", + "columnName": "preferred_output_only_profile", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "preferred_duplex_profile", + "columnName": "preferred_duplex_profile", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "active_audio_device_policy", + "columnName": "active_audio_device_policy", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "profileConnectionPolicies.a2dp_connection_policy", + "columnName": "a2dp_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.a2dp_sink_connection_policy", + "columnName": "a2dp_sink_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hfp_connection_policy", + "columnName": "hfp_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hfp_client_connection_policy", + "columnName": "hfp_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hid_host_connection_policy", + "columnName": "hid_host_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.pan_connection_policy", + "columnName": "pan_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.pbap_connection_policy", + "columnName": "pbap_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.pbap_client_connection_policy", + "columnName": "pbap_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.map_connection_policy", + "columnName": "map_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.sap_connection_policy", + "columnName": "sap_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hearing_aid_connection_policy", + "columnName": "hearing_aid_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.hap_client_connection_policy", + "columnName": "hap_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.map_client_connection_policy", + "columnName": "map_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.le_audio_connection_policy", + "columnName": "le_audio_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.volume_control_connection_policy", + "columnName": "volume_control_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.csip_set_coordinator_connection_policy", + "columnName": "csip_set_coordinator_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.le_call_control_connection_policy", + "columnName": "le_call_control_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.bass_client_connection_policy", + "columnName": "bass_client_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "profileConnectionPolicies.battery_connection_policy", + "columnName": "battery_connection_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "publicMetadata.manufacturer_name", + "columnName": "manufacturer_name", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.model_name", + "columnName": "model_name", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.software_version", + "columnName": "software_version", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.hardware_version", + "columnName": "hardware_version", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.companion_app", + "columnName": "companion_app", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_icon", + "columnName": "main_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.is_untethered_headset", + "columnName": "is_untethered_headset", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_icon", + "columnName": "untethered_left_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_icon", + "columnName": "untethered_right_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_icon", + "columnName": "untethered_case_icon", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_battery", + "columnName": "untethered_left_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_battery", + "columnName": "untethered_right_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_battery", + "columnName": "untethered_case_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_charging", + "columnName": "untethered_left_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_charging", + "columnName": "untethered_right_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_charging", + "columnName": "untethered_case_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.enhanced_settings_ui_uri", + "columnName": "enhanced_settings_ui_uri", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.device_type", + "columnName": "device_type", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_battery", + "columnName": "main_battery", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_charging", + "columnName": "main_charging", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.main_low_battery_threshold", + "columnName": "main_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_left_low_battery_threshold", + "columnName": "untethered_left_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_right_low_battery_threshold", + "columnName": "untethered_right_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.untethered_case_low_battery_threshold", + "columnName": "untethered_case_low_battery_threshold", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.spatial_audio", + "columnName": "spatial_audio", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.fastpair_customized", + "columnName": "fastpair_customized", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.le_audio", + "columnName": "le_audio", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.gmcs_cccd", + "columnName": "gmcs_cccd", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.gtbs_cccd", + "columnName": "gtbs_cccd", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "publicMetadata.exclusive_manager", + "columnName": "exclusive_manager", + "affinity": "BLOB", + "notNull": false + }, + { + "fieldPath": "audioPolicyMetadata.callEstablishAudioPolicy", + "columnName": "call_establish_audio_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "audioPolicyMetadata.connectingTimeAudioPolicy", + "columnName": "connecting_time_audio_policy", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "audioPolicyMetadata.inBandRingtoneAudioPolicy", + "columnName": "in_band_ringtone_audio_policy", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "address" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5e9dc09807d50827ab4928ae23ac4173')" + ] + } +} \ No newline at end of file diff --git a/android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java b/android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bdfe10d5dcfa07c486953a7d24f1af11273bc2fa --- /dev/null +++ b/android/app/tests/unit/src/com/android/bluetooth/content_profiles/ContentProfileErrorReportUtilsTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2023 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.bluetooth.content_profiles; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.SystemClock; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class ContentProfileErrorReportUtilsTest { + + @Test + public void tooFrequentErrorReportIsSkipped() { + // Set the last report time to the current time. + long lastReportTimeMillisToSet = SystemClock.uptimeMillis(); + ContentProfileErrorReportUtils.sLastReportTime = lastReportTimeMillisToSet; + + assertThat(ContentProfileErrorReportUtils.report(0, 0, 0, 0)).isFalse(); + // The last report time should not be changed. + assertThat(ContentProfileErrorReportUtils.sLastReportTime) + .isEqualTo(lastReportTimeMillisToSet); + } + + @Test + public void successfulReport() { + // Set the last report time to much earlier than the current time. + long lastReportTimeMillisToSet = + SystemClock.uptimeMillis() + - (ContentProfileErrorReportUtils + .MIN_PERIOD_BETWEEN_TWO_ERROR_REPORTS_MILLIS + * 2); + ContentProfileErrorReportUtils.sLastReportTime = lastReportTimeMillisToSet; + + assertThat(ContentProfileErrorReportUtils.report(0, 0, 0, 0)).isTrue(); + // After the successful report, the last report time should be changed. + assertThat(ContentProfileErrorReportUtils.sLastReportTime) + .isGreaterThan(lastReportTimeMillisToSet); + } +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java index eeb0bd519b4b597755e530deb58c81774dd108f7..7c3bd07096e9be956799a094ecdefebf6788245b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorServiceTest.java @@ -97,7 +97,6 @@ public class CsipSetCoordinatorServiceTest { TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -164,11 +163,12 @@ public class CsipSetCoordinatorServiceTest { private void startService() throws TimeoutException { mService = new CsipSetCoordinatorService(mTargetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); } private void stopService() throws TimeoutException { - mService.doStop(); + mService.stop(); mService = CsipSetCoordinatorService.getCsipSetCoordinatorService(); Assert.assertNull(mService); } @@ -188,21 +188,11 @@ public class CsipSetCoordinatorServiceTest { public void testStopService() { Assert.assertEquals(mService, CsipSetCoordinatorService.getCsipSetCoordinatorService()); - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.stop()); - } - }); - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.start()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::start); } - /** - * Test get/set policy for BluetoothDevice - */ + /** Test get/set policy for BluetoothDevice */ @Test public void testGetSetPolicy() { when(mDatabaseManager.getProfileConnectionPolicy( @@ -416,6 +406,8 @@ public class CsipSetCoordinatorServiceTest { // Send a connect request Assert.assertTrue("Connect expected to succeed", mService.connect(mTestDevice)); + + TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mTestDevice)); } /** @@ -672,6 +664,8 @@ public class CsipSetCoordinatorServiceTest { // add state machines for testing dump() mService.connect(mTestDevice); + TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(mTestDevice)); + mService.dump(new StringBuilder()); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java index 1ba0431bdc1bab61bf0d083d42d14f675a581421..0c09204d334fbfd5f251b0a957d30528dd06fc1d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/csip/CsipSetCoordinatorStateMachineTest.java @@ -21,7 +21,6 @@ import static android.bluetooth.BluetoothProfile.STATE_CONNECTED; import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -34,13 +33,10 @@ import android.content.Intent; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; -import android.test.suitebuilder.annotation.MediumTest; - +import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; - import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; - import org.hamcrest.core.IsInstanceOf; import org.junit.*; import org.junit.runner.RunWith; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java index d940b9098709779b37a3707a92885fbd1968be4c..9f2390e44c0d8e20305f187fa0ebf3b060a058d1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java @@ -45,6 +45,7 @@ import android.location.LocationManager; import android.os.Binder; import android.os.RemoteException; import android.os.WorkSource; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -54,6 +55,13 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.CompanionManager; +import com.android.bluetooth.le_scan.AppScanStats; +import com.android.bluetooth.le_scan.PeriodicScanManager; +import com.android.bluetooth.le_scan.ScanClient; +import com.android.bluetooth.le_scan.ScanManager; +import com.android.bluetooth.le_scan.TransitionalScanHelper; + +import com.android.bluetooth.flags.Flags; import org.junit.After; import org.junit.Assert; @@ -66,6 +74,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -87,8 +96,12 @@ public class GattServiceTest { private Context mTargetContext; private GattService mService; @Mock private GattService.ClientMap mClientMap; - @Mock private GattService.ScannerMap mScannerMap; - @Mock private GattService.ScannerMap.App mApp; + @Mock private TransitionalScanHelper.ScannerMap mScannerMap; + + @SuppressWarnings("NonCanonicalType") + @Mock + private TransitionalScanHelper.ScannerMap.App mApp; + @Mock private GattService.PendingIntentInfo mPiInfo; @Mock private PeriodicScanManager mPeriodicScanManager; @Mock private ScanManager mScanManager; @@ -98,6 +111,7 @@ public class GattServiceTest { @Mock private AdvertiseManagerNativeInterface mAdvertiseManagerNativeInterface; @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private BluetoothDevice mDevice; private BluetoothAdapter mAdapter; @@ -145,7 +159,7 @@ public class GattServiceTest { mService.start(); mService.mClientMap = mClientMap; - mService.mScannerMap = mScannerMap; + mService.mTransitionalScanHelper.setScannerMap(mScannerMap); mService.mReliableQueue = mReliableQueue; mService.mServerMap = mServerMap; } @@ -233,7 +247,7 @@ public class GattServiceTest { mService.connectionParameterUpdate(clientIf, address, connectionPriority, mAttributionSource); - connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_BALANCED;; + connectionPriority = BluetoothGatt.CONNECTION_PRIORITY_BALANCED; mService.connectionParameterUpdate(clientIf, address, connectionPriority, mAttributionSource); @@ -487,6 +501,63 @@ public class GattServiceTest { verify(mScanManager).flushBatchScanResults(new ScanClient(scannerId)); } + @Test + public void onScanResult_remoteException_clientDied() throws Exception { + mSetFlagsRule.enableFlags(Flags.FLAG_LE_SCAN_FIX_REMOTE_EXCEPTION); + int scannerId = 1; + + int eventType = 0; + int addressType = 0; + String address = "02:00:00:00:00:00"; + int primaryPhy = 0; + int secondPhy = 0; + int advertisingSid = 0; + int txPower = 0; + int rssi = 0; + int periodicAdvInt = 0; + byte[] advData = new byte[0]; + + ScanClient scanClient = new ScanClient(scannerId); + scanClient.scannerId = scannerId; + scanClient.hasNetworkSettingsPermission = true; + scanClient.settings = + new ScanSettings.Builder() + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setLegacy(false) + .build(); + + AppScanStats appScanStats = mock(AppScanStats.class); + IScannerCallback callback = mock(IScannerCallback.class); + + mApp.callback = callback; + mApp.appScanStats = appScanStats; + Set scanClientSet = Collections.singleton(scanClient); + + doReturn(address).when(mAdapterService).getIdentityAddress(anyString()); + doReturn(scanClientSet).when(mScanManager).getRegularScanQueue(); + doReturn(mApp).when(mScannerMap).getById(scanClient.scannerId); + doReturn(appScanStats).when(mScannerMap).getAppScanStatsById(scanClient.scannerId); + + // Simulate remote client crash + doThrow(new RemoteException()).when(callback).onScanResult(any()); + + mService.onScanResult( + eventType, + addressType, + address, + primaryPhy, + secondPhy, + advertisingSid, + txPower, + rssi, + periodicAdvInt, + advData, + address); + + assertThat(scanClient.appDied).isTrue(); + verify(appScanStats).recordScanStop(scannerId); + } + @Test public void readCharacteristic() { int clientIf = 1; @@ -685,7 +756,7 @@ public class GattServiceTest { String address = REMOTE_DEVICE_ADDRESS; int handle = 2; boolean confirm = true; - byte[] value = new byte[] {5, 6};; + byte[] value = new byte[] {5, 6}; Integer connId = 1; doReturn(connId).when(mServerMap).connIdByAddress(serverIf, address); @@ -819,4 +890,47 @@ public class GattServiceTest { BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED); } + + @Test + public void restrictedHandles() throws Exception { + mSetFlagsRule.enableFlags(Flags.FLAG_GATT_CLEANUP_RESTRICTED_HANDLES); + int clientIf = 1; + int connId = 1; + ArrayList db = new ArrayList<>(); + + @SuppressWarnings("NonCanonicalType") + GattService.ClientMap.App app = mock(GattService.ClientMap.App.class); + IBluetoothGattCallback callback = mock(IBluetoothGattCallback.class); + + doReturn(app).when(mClientMap).getByConnId(connId); + app.callback = callback; + + GattDbElement hidService = + GattDbElement.createPrimaryService( + UUID.fromString("00001812-0000-1000-8000-00805F9B34FB")); + hidService.id = 1; + + GattDbElement hidInfoChar = + GattDbElement.createCharacteristic( + UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"), 0, 0); + hidInfoChar.id = 2; + + GattDbElement randomChar = + GattDbElement.createCharacteristic( + UUID.fromString("0000FFFF-0000-1000-8000-00805F9B34FB"), 0, 0); + randomChar.id = 3; + + db.add(hidService); + db.add(hidInfoChar); + db.add(randomChar); + + mService.onGetGattDb(connId, db); + // HID characteristics should be restricted + assertThat(mService.mRestrictedHandles.get(connId)).contains(hidInfoChar.id); + assertThat(mService.mRestrictedHandles.get(connId)).doesNotContain(randomChar.id); + + mService.onDisconnected( + clientIf, connId, BluetoothGatt.GATT_SUCCESS, REMOTE_DEVICE_ADDRESS); + assertThat(mService.mRestrictedHandles).doesNotContainKey(connId); + } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java index 6ce340c9507f22002718611ea30606f718a42c68..8e1024dbdb82af6942502baea3bb9a71f643805d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hap/HapClientStateMachineTest.java @@ -31,13 +31,10 @@ import android.bluetooth.BluetoothProfile; import android.content.Intent; import android.os.HandlerThread; import android.os.Message; -import android.test.suitebuilder.annotation.MediumTest; - +import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; - import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; - import org.hamcrest.core.IsInstanceOf; import org.junit.After; import org.junit.Assert; 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 51145712f8afdaee44a7a421c60954de27339695..8fc9fbe179fdc3d3600b65d91125c611bb881335 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 @@ -17,16 +17,31 @@ package com.android.bluetooth.hap; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; + import static org.mockito.Mockito.after; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.times; +import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; +import static org.hamcrest.core.AllOf.allOf; + +import static android.bluetooth.BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED; +import static android.bluetooth.BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE; + +import static android.bluetooth.BluetoothProfile.EXTRA_STATE; +import static android.bluetooth.BluetoothProfile.EXTRA_PREVIOUS_STATE; +import static android.bluetooth.BluetoothProfile.STATE_CONNECTED; +import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; +import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -37,12 +52,7 @@ import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetoothHapClientCallback; import android.content.AttributionSource; -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; @@ -64,6 +74,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @@ -75,7 +86,6 @@ 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; @MediumTest @@ -88,12 +98,9 @@ public class HapClientTest { private BluetoothDevice mDevice; private BluetoothDevice mDevice2; private BluetoothDevice mDevice3; - private Context mTargetContext; private HapClientService mService; private HapClientService.BluetoothHapClientBinder mServiceBinder; private AttributionSource mAttributionSource; - private HasIntentReceiver mHasIntentReceiver; - private HashMap> mIntentQueue; @Mock private AdapterService mAdapterService; @Mock private DatabaseManager mDatabaseManager; @@ -109,19 +116,12 @@ public class HapClientTest { System.setProperty("dexmaker.share_classloader", "true"); } - mTargetContext = InstrumentationRegistry.getTargetContext(); // Set up mocks and test assets MockitoAnnotations.initMocks(this); - if (Looper.myLooper() == null) { - Looper.prepare(); - } - HapClientStateMachine.sConnectTimeoutMs = TIMEOUT_MS; - TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mAdapter = BluetoothAdapter.getDefaultAdapter(); mAttributionSource = mAdapter.getAttributionSource(); @@ -133,18 +133,9 @@ public class HapClientTest { mServiceBinder = (HapClientService.BluetoothHapClientBinder) mService.initBinder(); mServiceBinder.mIsTesting = true; - // Set up the State Changed receiver - IntentFilter filter = new IntentFilter(); - filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - filter.addAction(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); - filter.addAction(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE); - when(mCallback.asBinder()).thenReturn(mBinder); mService.mCallbacks.register(mCallback); - mHasIntentReceiver = new HasIntentReceiver(); - mTargetContext.registerReceiver(mHasIntentReceiver, filter, Context.RECEIVER_EXPORTED); - mDevice = TestUtils.getTestDevice(mAdapter, 0); when(mNativeInterface.getDevice(getByteAddress(mDevice))).thenReturn(mDevice); mDevice2 = TestUtils.getTestDevice(mAdapter, 1); @@ -194,11 +185,6 @@ public class HapClientTest { doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - - mIntentQueue = new HashMap<>(); - mIntentQueue.put(mDevice, new LinkedBlockingQueue<>()); - mIntentQueue.put(mDevice2, new LinkedBlockingQueue<>()); - mIntentQueue.put(mDevice3, new LinkedBlockingQueue<>()); } @After @@ -216,27 +202,17 @@ public class HapClientTest { stopService(); HapClientNativeInterface.setInstance(null); - if (mHasIntentReceiver != null) { - mTargetContext.unregisterReceiver(mHasIntentReceiver); - } - mAdapter = null; - - if (mAdapterService != null) { - TestUtils.clearAdapterService(mAdapterService); - } - - if (mIntentQueue != null) - mIntentQueue.clear(); } private void startService() throws TimeoutException { - mService = new HapClientService(mTargetContext); - mService.doStart(); + mService = new HapClientService(mAdapterService); + mService.start(); + mService.setAvailable(true); } private void stopService() throws TimeoutException { - mService.doStop(); + mService.stop(); mService = HapClientService.getHapClientService(); Assert.assertNull(mService); } @@ -256,21 +232,11 @@ public class HapClientTest { public void testStopHapService() { Assert.assertEquals(mService, HapClientService.getHapClientService()); - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.stop()); - } - }); - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.start()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::start); } - /** - * Test get/set policy for BluetoothDevice - */ + /** Test get/set policy for BluetoothDevice */ @Test public void testGetSetPolicy() throws Exception { when(mDatabaseManager @@ -392,6 +358,8 @@ public class HapClientTest { // Send a connect request Assert.assertTrue("Connect expected to succeed", mService.connect(mDevice)); + + verify(mAdapterService, timeout(TIMEOUT_MS)).sendBroadcast(any(), any()); } /** @@ -416,6 +384,8 @@ public class HapClientTest { */ @Test public void testOutgoingConnectTimeout() throws Exception { + InOrder order = inOrder(mAdapterService); + // Update the device policy so okToConnect() returns true when(mDatabaseManager .getProfileConnectionPolicy(mDevice, BluetoothProfile.HAP_CLIENT)) @@ -426,15 +396,30 @@ public class HapClientTest { // Send a connect request Assert.assertTrue("Connect failed", mService.connect(mDevice)); - // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mDevice, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); + order.verify(mAdapterService, timeout(TIMEOUT_MS)) + .sendBroadcast( + argThat( + allOf( + hasAction(ACTION_HAP_CONNECTION_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice), + hasExtra(EXTRA_STATE, STATE_CONNECTING), + hasExtra(EXTRA_PREVIOUS_STATE, STATE_DISCONNECTED))), + any()); + Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice)); // Verify the connection state broadcast, and that we are in Disconnected state via binder - verifyConnectionStateIntent(HapClientStateMachine.sConnectTimeoutMs * 2, - mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); + order.verify(mAdapterService, timeout(HapClientStateMachine.sConnectTimeoutMs * 2)) + .sendBroadcast( + argThat( + allOf( + hasAction(ACTION_HAP_CONNECTION_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice), + hasExtra(EXTRA_STATE, STATE_DISCONNECTED), + hasExtra(EXTRA_PREVIOUS_STATE, STATE_CONNECTING))), + any()); + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getConnectionState(mDevice, mAttributionSource, recv); @@ -448,15 +433,16 @@ public class HapClientTest { */ @Test public void testConnectTwo() throws Exception { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request for the 1st device - testConnectingDevice(mDevice); + testConnectingDevice(order, mDevice); // Send a connect request for the 2nd device BluetoothDevice Device2 = TestUtils.getTestDevice(mAdapter, 1); - testConnectingDevice(Device2); + testConnectingDevice(order, Device2); // indirect call of mService.getConnectedDevices to test BluetoothHearingAidBinder final SynchronousResultReceiver> recv = @@ -483,11 +469,12 @@ public class HapClientTest { */ @Test public void testGetHapGroupCoordinatedOps() throws Exception { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice); - testConnectingDevice(mDevice2); - testConnectingDevice(mDevice3); + testConnectingDevice(order, mDevice); + testConnectingDevice(order, mDevice2); + testConnectingDevice(order, mDevice3); int flags = 0x04; mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags); @@ -520,9 +507,10 @@ public class HapClientTest { */ @Test public void testSelectPresetNative() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice); + testConnectingDevice(order, mDevice); // Verify Native Interface call mService.selectPreset(mDevice, 0x00); @@ -545,9 +533,10 @@ public class HapClientTest { */ @Test public void testGroupSelectActivePresetNative() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice3); + testConnectingDevice(order, mDevice3); int flags = 0x01; mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice3), flags); @@ -571,9 +560,10 @@ public class HapClientTest { */ @Test public void testSwitchToNextPreset() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice); + testConnectingDevice(order, mDevice); // Verify Native Interface call mServiceBinder.switchToNextPreset(mDevice, mAttributionSource); @@ -586,9 +576,10 @@ public class HapClientTest { */ @Test public void testSwitchToNextPresetForGroup() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice3); + testConnectingDevice(order, mDevice3); int flags = 0x01; mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice3), flags); @@ -602,9 +593,10 @@ public class HapClientTest { */ @Test public void testSwitchToPreviousPreset() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice); + testConnectingDevice(order, mDevice); // Verify Native Interface call mServiceBinder.switchToPreviousPreset(mDevice, mAttributionSource); @@ -617,10 +609,11 @@ public class HapClientTest { */ @Test public void testSwitchToPreviousPresetForGroup() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice); - testConnectingDevice(mDevice2); + testConnectingDevice(order, mDevice); + testConnectingDevice(order, mDevice2); int flags = 0x01; mNativeInterface.onFeaturesUpdate(getByteAddress(mDevice), flags); @@ -635,9 +628,10 @@ public class HapClientTest { */ @Test public void testGetActivePresetIndex() throws Exception { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice); + testConnectingDevice(order, mDevice); testOnPresetSelected(mDevice, 0x01); // Verify cached value via binder @@ -654,9 +648,10 @@ public class HapClientTest { */ @Test public void testGetPresetInfoAndActivePresetInfo() throws Exception { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice2); + testConnectingDevice(order, mDevice2); // Check when active preset is not known yet final SynchronousResultReceiver> presetListRecv = @@ -696,9 +691,10 @@ public class HapClientTest { */ @Test public void testSetPresetNameNative() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - testConnectingDevice(mDevice); + testConnectingDevice(order, mDevice); mServiceBinder.setPresetName(mDevice, 0x00, "ExamplePresetName", mAttributionSource); verify(mNativeInterface, times(0)) @@ -721,11 +717,12 @@ public class HapClientTest { */ @Test public void testSetPresetNameForGroup() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); int test_group = 0x02; for (BluetoothDevice device : mCsipService.getGroupDevicesOrdered(test_group)) { - testConnectingDevice(device); + testConnectingDevice(order, device); } int flags = 0x21; @@ -767,12 +764,14 @@ public class HapClientTest { .onDeviceAvailable(any(byte[].class), anyInt()); mNativeInterface.onDeviceAvailable(getByteAddress(mDevice), 0x03); - 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, 0x00)); + verify(mAdapterService, timeout(TIMEOUT_MS)) + .sendBroadcast( + argThat( + allOf( + hasAction(ACTION_HAP_DEVICE_AVAILABLE), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice), + hasExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, 0x03))), + any()); } /** @@ -827,11 +826,12 @@ public class HapClientTest { */ @Test public void testStackEventOnPresetInfo() { + InOrder order = inOrder(mAdapterService); doReturn(new ParcelUuid[]{BluetoothUuid.HAS}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Connect and inject initial presets - testConnectingDevice(mDevice); + testConnectingDevice(order, mDevice); int info_reason = HapClientStackEvent.PRESET_INFO_REASON_PRESET_INFO_UPDATE; BluetoothHapPresetInfo[] info = @@ -1057,6 +1057,8 @@ public class HapClientTest { // Add state machine for testing dump() mService.connect(mDevice); + verify(mAdapterService, timeout(TIMEOUT_MS)).sendBroadcast(any(), any()); + mService.dump(new StringBuilder()); } @@ -1065,7 +1067,6 @@ public class HapClientTest { */ private void prepareConnectingDevice(BluetoothDevice device) { // Prepare intent queue and all the mocks - mIntentQueue.put(device, new LinkedBlockingQueue<>()); when(mNativeInterface.getDevice(getByteAddress(device))).thenReturn(device); when(mDatabaseManager .getProfileConnectionPolicy(device, BluetoothProfile.HAP_CLIENT)) @@ -1074,23 +1075,26 @@ public class HapClientTest { doReturn(true).when(mNativeInterface).disconnectHapClient(any(BluetoothDevice.class)); } - /** - * Helper function to test device connecting - */ - private void testConnectingDevice(BluetoothDevice device) { + /** Helper function to test device connecting */ + private void testConnectingDevice(InOrder order, BluetoothDevice device) { prepareConnectingDevice(device); // Send a connect request Assert.assertTrue("Connect expected to succeed", mService.connect(device)); - verifyConnectingDevice(device); + verifyConnectingDevice(order, device); } - /** - * Helper function to test device connecting - */ - private void verifyConnectingDevice(BluetoothDevice device) { + /** Helper function to test device connecting */ + private void verifyConnectingDevice(InOrder order, BluetoothDevice device) { // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); + order.verify(mAdapterService, timeout(TIMEOUT_MS)) + .sendBroadcast( + argThat( + allOf( + hasAction(ACTION_HAP_CONNECTION_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, device), + hasExtra(EXTRA_STATE, STATE_CONNECTING), + hasExtra(EXTRA_PREVIOUS_STATE, STATE_DISCONNECTED))), + any()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(device)); // Send a message to trigger connection completed @@ -1101,8 +1105,15 @@ public class HapClientTest { mService.messageFromNative(evt); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); + order.verify(mAdapterService, timeout(TIMEOUT_MS)) + .sendBroadcast( + argThat( + allOf( + hasAction(ACTION_HAP_CONNECTION_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, device), + hasExtra(EXTRA_STATE, STATE_CONNECTED), + hasExtra(EXTRA_PREVIOUS_STATE, STATE_CONNECTING))), + any()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(device)); evt = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); @@ -1110,12 +1121,14 @@ public class HapClientTest { evt.valueInt1 = 0x01; // features mService.messageFromNative(evt); - Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mIntentQueue.get(device)); - Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothHapClient.ACTION_HAP_DEVICE_AVAILABLE, intent.getAction()); - Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(evt.valueInt1, - intent.getIntExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, -1)); + order.verify(mAdapterService, timeout(TIMEOUT_MS)) + .sendBroadcast( + argThat( + allOf( + hasAction(ACTION_HAP_DEVICE_AVAILABLE), + hasExtra(BluetoothDevice.EXTRA_DEVICE, device), + hasExtra(BluetoothHapClient.EXTRA_HAP_FEATURES, 0x01))), + any()); evt = new HapClientStackEvent(HapClientStackEvent.EVENT_TYPE_DEVICE_FEATURES); evt.device = device; @@ -1156,21 +1169,6 @@ public class HapClientTest { } } - /** - * Helper function to test ConnectionStateIntent() method - */ - private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device, - int newState, int prevState) { - Intent intent = TestUtils.waitForIntent(timeoutMs, mIntentQueue.get(device)); - Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED, - intent.getAction()); - Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertEquals(prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, - -1)); - } - /** * Helper function to test okToConnect() method */ @@ -1191,20 +1189,4 @@ public class HapClientTest { } return Utils.getBytesFromAddress(device.getAddress()); } - - private class HasIntentReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - try { - BluetoothDevice device = intent.getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE); - Assert.assertNotNull(device); - LinkedBlockingQueue queue = mIntentQueue.get(device); - Assert.assertNotNull(queue); - queue.put(intent); - } catch (InterruptedException e) { - Assert.fail("Cannot add Intent to the queue: " + e.getMessage()); - } - } - } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java index 7c357166e0f33afe923137c5f87415629d213c95..f690d6502cb4a41b439084727aea18caf774abc6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java @@ -16,11 +16,18 @@ package com.android.bluetooth.hearingaid; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; + +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -29,33 +36,38 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.media.AudioManager; import android.media.BluetoothProfileConnectionInfo; import android.os.Looper; import android.os.ParcelUuid; +import android.platform.test.flag.junit.SetFlagsRule; -import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; +import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.AudioRoutingManager; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver; +import org.hamcrest.Matcher; +import org.hamcrest.core.AllOf; import org.junit.After; -import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.hamcrest.MockitoHamcrest; import java.time.Duration; import java.util.HashMap; @@ -66,138 +78,108 @@ import java.util.concurrent.TimeoutException; @MediumTest @RunWith(AndroidJUnit4.class) public class HearingAidServiceTest { - private BluetoothAdapter mAdapter; - private Context mTargetContext; + private static final Duration TIMEOUT = Duration.ofSeconds(1); + + private static final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter(); + private static final BluetoothDevice mLeftDevice = TestUtils.getTestDevice(mAdapter, 0); + private static final BluetoothDevice mRightDevice = TestUtils.getTestDevice(mAdapter, 1); + private static final BluetoothDevice mSingleDevice = TestUtils.getTestDevice(mAdapter, 2); + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private HearingAidService mService; private HearingAidService.BluetoothHearingAidBinder mServiceBinder; - private BluetoothDevice mLeftDevice; - private BluetoothDevice mRightDevice; - private BluetoothDevice mSingleDevice; private HashMap> mDeviceQueueMap; - private static final int TIMEOUT_MS = 1000; - - private HearingAidIntentReceiver mHearingAidIntentReceiver; @Mock private AdapterService mAdapterService; @Mock private ActiveDeviceManager mActiveDeviceManager; + @Mock private AudioRoutingManager mAudioRoutingManager; + @Mock private Context mContext; @Mock private DatabaseManager mDatabaseManager; @Mock private HearingAidNativeInterface mNativeInterface; @Mock private AudioManager mAudioManager; + private InOrder mInOrder = null; + @Before public void setUp() throws Exception { - mTargetContext = InstrumentationRegistry.getTargetContext(); // Set up mocks and test assets MockitoAnnotations.initMocks(this); + mInOrder = inOrder(mContext); + + TestUtils.mockGetSystemService( + mContext, Context.AUDIO_SERVICE, AudioManager.class, mAudioManager); if (Looper.myLooper() == null) { Looper.prepare(); } TestUtils.setAdapterService(mAdapterService); - doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager(); + doAnswer( + invocation -> { + if (Flags.audioRoutingCentralization()) { + return mAudioRoutingManager; + } else { + return mActiveDeviceManager; + } + }) + .when(mAdapterService) + .getActiveDeviceManager(); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); - mAdapter = BluetoothAdapter.getDefaultAdapter(); HearingAidNativeInterface.setInstance(mNativeInterface); startService(); - mService.mAudioManager = mAudioManager; mServiceBinder = (HearingAidService.BluetoothHearingAidBinder) mService.initBinder(); mServiceBinder.mIsTesting = true; // Override the timeout value to speed up the test - HearingAidStateMachine.sConnectTimeoutMs = TIMEOUT_MS; // 1s - - // Get a device for testing - mLeftDevice = TestUtils.getTestDevice(mAdapter, 0); - mRightDevice = TestUtils.getTestDevice(mAdapter, 1); - mSingleDevice = TestUtils.getTestDevice(mAdapter, 2); - mDeviceQueueMap = new HashMap<>(); - mDeviceQueueMap.put(mLeftDevice, new LinkedBlockingQueue<>()); - mDeviceQueueMap.put(mRightDevice, new LinkedBlockingQueue<>()); - mDeviceQueueMap.put(mSingleDevice, new LinkedBlockingQueue<>()); - doReturn(BluetoothDevice.BOND_BONDED).when(mAdapterService) + HearingAidStateMachine.sConnectTimeoutMs = (int) TIMEOUT.toMillis(); // 1s + + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); - doReturn(new ParcelUuid[]{BluetoothUuid.HEARING_AID}).when(mAdapterService) + doReturn(new ParcelUuid[] {BluetoothUuid.HEARING_AID}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); - - // Set up the Connection State Changed receiver - IntentFilter filter = new IntentFilter(); - filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); - mHearingAidIntentReceiver = new HearingAidIntentReceiver(mDeviceQueueMap); - mTargetContext.registerReceiver(mHearingAidIntentReceiver, filter); } @After public void tearDown() throws Exception { stopService(); HearingAidNativeInterface.setInstance(null); - mTargetContext.unregisterReceiver(mHearingAidIntentReceiver); - mHearingAidIntentReceiver.clear(); - mDeviceQueueMap.clear(); TestUtils.clearAdapterService(mAdapterService); - reset(mAudioManager); } private void startService() throws TimeoutException { - mService = new HearingAidService(mTargetContext); - mService.doStart(); + mService = new HearingAidService(mContext); + mService.start(); + mService.setAvailable(true); } private void stopService() throws TimeoutException { - mService.doStop(); + mService.stop(); mService = HearingAidService.getHearingAidService(); - Assert.assertNull(mService); + assertThat(mService).isNull(); } - private static class HearingAidIntentReceiver extends BroadcastReceiver { - HashMap> mDeviceQueueMap; - - public HearingAidIntentReceiver( - HashMap> deviceQueueMap) { - mDeviceQueueMap = deviceQueueMap; - } - - public void clear() { - mDeviceQueueMap = null; - } - - @Override - public void onReceive(Context context, Intent intent) { - if (BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction()) - && mDeviceQueueMap != null) { - try { - BluetoothDevice device = intent.getParcelableExtra( - BluetoothDevice.EXTRA_DEVICE); - Assert.assertNotNull(device); - LinkedBlockingQueue queue = mDeviceQueueMap.get(device); - Assert.assertNotNull(queue); - queue.put(intent); - } catch (InterruptedException e) { - Assert.fail("Cannot add Intent to the Connection State queue: " - + e.getMessage()); - } - } - } + @SafeVarargs + private void verifyIntentSent(Matcher... matchers) { + mInOrder.verify(mContext, timeout(TIMEOUT.toMillis() * 2)) + .sendBroadcast(MockitoHamcrest.argThat(AllOf.allOf(matchers)), any(), any()); } - private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device, - int newState, int prevState) { - verifyConnectionStateIntent(timeoutMs, device, newState, prevState, true); + private void verifyConnectionStateIntent(BluetoothDevice device, int newState, int prevState) { + verifyConnectionStateIntent(device, newState, prevState, true); } - private void verifyConnectionStateIntent(int timeoutMs, BluetoothDevice device, - int newState, int prevState, boolean stopAudio) { - Intent intent = TestUtils.waitForIntent(timeoutMs, mDeviceQueueMap.get(device)); - Assert.assertNotNull(intent); - Assert.assertEquals(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED, - intent.getAction()); - Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); - Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1)); - Assert.assertEquals(prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, - -1)); + private void verifyConnectionStateIntent( + BluetoothDevice device, int newState, int prevState, boolean stopAudio) { + verifyIntentSent( + hasAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, device), + hasExtra(BluetoothProfile.EXTRA_STATE, newState), + hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState)); + if (newState == BluetoothProfile.STATE_CONNECTED) { // ActiveDeviceManager calls setActiveDevice when connected. mService.setActiveDevice(device); @@ -208,43 +190,24 @@ public class HearingAidServiceTest { } } - private void verifyNoConnectionStateIntent(int timeoutMs, BluetoothDevice device) { - Intent intent = TestUtils.waitForNoIntent(timeoutMs, mDeviceQueueMap.get(device)); - Assert.assertNull(intent); - } - - /** - * Test getting HearingAid Service: getHearingAidService() - */ + /** Test getting HearingAid Service: getHearingAidService() */ @Test public void testGetHearingAidService() { - Assert.assertEquals(mService, HearingAidService.getHearingAidService()); + assertThat(mService).isEqualTo(HearingAidService.getHearingAidService()); } - /** - * Test stop HearingAid Service - */ + /** Test stop HearingAid Service */ @Test public void testStopHearingAidService() { // Prepare: connect connectDevice(mLeftDevice); // HearingAid Service is already running: test stop(). Note: must be done on the main thread - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.stop()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop); // Try to restart the service. Note: must be done on the main thread - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.start()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::start); } - /** - * Test get/set priority for BluetoothDevice - */ + /** Test get/set priority for BluetoothDevice */ @Test public void testGetSetPriority() throws Exception { when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) @@ -253,63 +216,80 @@ public class HearingAidServiceTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); final int defaultRecvValue = -1000; mServiceBinder.getConnectionPolicy(mLeftDevice, null, recv); - int connectionPolicy = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue); - Assert.assertEquals("Initial device priority", - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, connectionPolicy); + int connectionPolicy = recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue); + assertThat(connectionPolicy).isEqualTo(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - Assert.assertEquals("Setting device priority to PRIORITY_OFF", - BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, - mService.getConnectionPolicy(mLeftDevice)); + assertThat(mService.getConnectionPolicy(mLeftDevice)) + .isEqualTo(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - Assert.assertEquals("Setting device priority to PRIORITY_ON", - BluetoothProfile.CONNECTION_POLICY_ALLOWED, - mService.getConnectionPolicy(mLeftDevice)); + assertThat(mService.getConnectionPolicy(mLeftDevice)) + .isEqualTo(BluetoothProfile.CONNECTION_POLICY_ALLOWED); } - /** - * Test okToConnect method using various test cases - */ + /** Test okToConnect method using various test cases */ @Test public void testOkToConnect() { int badPriorityValue = 1024; int badBondState = 42; - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_NONE, badPriorityValue, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDING, badPriorityValue, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, true); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, BluetoothProfile.CONNECTION_POLICY_ALLOWED, true); - testOkToConnectCase(mSingleDevice, - BluetoothDevice.BOND_BONDED, badPriorityValue, false); - testOkToConnectCase(mSingleDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); - testOkToConnectCase(mSingleDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); - testOkToConnectCase(mSingleDevice, - badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); - testOkToConnectCase(mSingleDevice, - badBondState, badPriorityValue, false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_NONE, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mSingleDevice, BluetoothDevice.BOND_NONE, badPriorityValue, false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDING, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + false); + testOkToConnectCase(mSingleDevice, BluetoothDevice.BOND_BONDING, badPriorityValue, false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN, + true); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, + false); + testOkToConnectCase( + mSingleDevice, + BluetoothDevice.BOND_BONDED, + BluetoothProfile.CONNECTION_POLICY_ALLOWED, + true); + testOkToConnectCase(mSingleDevice, BluetoothDevice.BOND_BONDED, badPriorityValue, false); + testOkToConnectCase( + mSingleDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false); + testOkToConnectCase( + mSingleDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false); + testOkToConnectCase( + mSingleDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false); + testOkToConnectCase(mSingleDevice, badBondState, badPriorityValue, false); } /** @@ -320,316 +300,328 @@ public class HearingAidServiceTest { // Update the device priority so okToConnect() returns true when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Return No UUID - doReturn(new ParcelUuid[]{}).when(mAdapterService) + doReturn(new ParcelUuid[] {}) + .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); // Send a connect request - Assert.assertFalse("Connect expected to fail", mService.connect(mLeftDevice)); + assertThat(mService.connect(mLeftDevice)).isFalse(); } - /** - * Test that an outgoing connection to device with PRIORITY_OFF is rejected - */ + /** Test that an outgoing connection to device with PRIORITY_OFF is rejected */ @Test public void testOutgoingConnectPriorityOff() throws Exception { doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Set the device priority to PRIORITY_OFF so connect() should fail - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); // Send a connect request via BluetoothHearingAidBinder final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); boolean defaultRecvValue = true; mServiceBinder.connect(mLeftDevice, null, recv); - Assert.assertFalse("Connect expected to fail", recv.awaitResultNoInterrupt( - Duration.ofMillis(TIMEOUT_MS)).getValue(defaultRecvValue)); + assertThat(recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue)).isFalse(); } - /** - * Test that an outgoing connection times out - */ + /** Test that an outgoing connection times out */ @Test public void testOutgoingConnectTimeout() throws Exception { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mService.connect(mLeftDevice)); + assertThat(mService.connect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); // indirect call of mService.getConnectionState to test BluetoothHearingAidBinder final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); int defaultRecvValue = -1000; mServiceBinder.getConnectionState(mLeftDevice, null, recv); - int connectionState = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, connectionState); + int connectionState = recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue); + assertThat(connectionState).isEqualTo(BluetoothProfile.STATE_CONNECTING); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(HearingAidStateMachine.sConnectTimeoutMs * 2, - mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); } - /** - * Test that the Hearing Aid Service connects to left and right device at the same time. - */ + /** Test that the Hearing Aid Service connects to left and right device at the same time. */ @Test public void testConnectAPair_connectBothDevices() { // Update hiSyncId map getHiSyncIdFromNative(); // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mService.connect(mLeftDevice)); + assertThat(mService.connect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING, + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mRightDevice)); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); } - /** - * Test that the service disconnects the current pair before connecting to another pair. - */ + /** Test that the service disconnects the current pair before connecting to another pair. */ @Test public void testConnectAnotherPair_disconnectCurrentPair() throws Exception { // Update hiSyncId map getHiSyncIdFromNative(); // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mService.connect(mLeftDevice)); + assertThat(mService.connect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); HearingAidStackEvent connCompletedEvent; // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mRightDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state for right side - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); + verifyConnectionStateIntent( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + verifyConnectionStateIntent( + mRightDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); // Send a connect request for another pair - Assert.assertTrue("Connect failed", mService.connect(mSingleDevice)); + assertThat(mService.connect(mSingleDevice)).isTrue(); // Verify the connection state broadcast, and that the first pair is in Disconnecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); // indirect call of mService.getConnectedDevices to test BluetoothHearingAidBinder final SynchronousResultReceiver> recv = SynchronousResultReceiver.get(); List defaultRecvValue = null; mServiceBinder.getConnectedDevices(null, recv); - Assert.assertFalse(recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue).contains(mLeftDevice)); - Assert.assertFalse(mService.getConnectedDevices().contains(mRightDevice)); + assertThat(recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue)) + .doesNotContain(mLeftDevice); + assertThat(mService.getConnectedDevices()).doesNotContain(mRightDevice); // Verify the connection state broadcast, and that the second device is in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mSingleDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mSingleDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mSingleDevice)); + assertThat(mService.getConnectionState(mSingleDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); } - /** - * Test that the outgoing connect/disconnect and audio switch is successful. - */ + /** Test that the outgoing connect/disconnect and audio switch is successful. */ @Test public void testAudioManagerConnectDisconnect() throws Exception { // Update hiSyncId map getHiSyncIdFromNative(); // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mService.connect(mLeftDevice)); - Assert.assertTrue("Connect failed", mService.connect(mRightDevice)); + assertThat(mService.connect(mLeftDevice)).isTrue(); + assertThat(mService.connect(mRightDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING, + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mRightDevice)); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); HearingAidStackEvent connCompletedEvent; // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + verifyConnectionStateIntent( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Send a message to trigger connection completed for right side - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mRightDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state for right side - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mRightDevice)); + verifyConnectionStateIntent( + mRightDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Verify the list of connected devices - Assert.assertTrue(mService.getConnectedDevices().contains(mLeftDevice)); - Assert.assertTrue(mService.getConnectedDevices().contains(mRightDevice)); + assertThat(mService.getConnectedDevices()).containsAtLeast(mLeftDevice, mRightDevice); // Verify the audio is routed to Hearing Aid Profile - verify(mAudioManager).handleBluetoothActiveDeviceChanged( - eq(mLeftDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager) + .handleBluetoothActiveDeviceChanged( + eq(mLeftDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); // Send a disconnect request - Assert.assertTrue("Disconnect failed", mService.disconnect(mLeftDevice)); + assertThat(mService.disconnect(mLeftDevice)).isTrue(); // Send a disconnect request via BluetoothHearingAidBinder final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); boolean revalueRecvValue = false; mServiceBinder.disconnect(mRightDevice, null, recv); - Assert.assertTrue("Disconnect failed", recv.awaitResultNoInterrupt( - Duration.ofMillis(TIMEOUT_MS)).getValue(revalueRecvValue)); + assertThat(recv.awaitResultNoInterrupt(TIMEOUT).getValue(revalueRecvValue)).isTrue(); // Verify the connection state broadcast, and that we are in Disconnecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTING, + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, - mService.getConnectionState(mLeftDevice)); - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_DISCONNECTING, + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTING); + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, - mService.getConnectionState(mRightDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTING); // Send a message to trigger disconnection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_DISCONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); // Send a message to trigger disconnection completed to the right device - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mRightDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_DISCONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Disconnected state - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_DISCONNECTED, + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mRightDevice)); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); // Verify the list of connected devices - Assert.assertFalse(mService.getConnectedDevices().contains(mLeftDevice)); - Assert.assertFalse(mService.getConnectedDevices().contains(mRightDevice)); + assertThat(mService.getConnectedDevices()).containsNoneOf(mLeftDevice, mRightDevice); // Verify the audio is not routed to Hearing Aid Profile. // Music should be paused (i.e. should not suppress noisy intent) ArgumentCaptor connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); - verify(mAudioManager).handleBluetoothActiveDeviceChanged( - eq(null), eq(mLeftDevice), connectionInfoArgumentCaptor.capture()); + verify(mAudioManager) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(mLeftDevice), connectionInfoArgumentCaptor.capture()); BluetoothProfileConnectionInfo connectionInfo = connectionInfoArgumentCaptor.getValue(); - Assert.assertFalse(connectionInfo.isSuppressNoisyIntent()); + assertThat(connectionInfo.isSuppressNoisyIntent()).isFalse(); } /** @@ -641,60 +633,66 @@ public class HearingAidServiceTest { // Update hiSyncId map getHiSyncIdFromNative(); // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mService.connect(mLeftDevice)); + assertThat(mService.connect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); HearingAidStackEvent connCompletedEvent; // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + verifyConnectionStateIntent( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Verify the list of connected devices - Assert.assertTrue(mService.getConnectedDevices().contains(mLeftDevice)); + assertThat(mService.getConnectedDevices()).contains(mLeftDevice); // Verify the audio is routed to Hearing Aid Profile - verify(mAudioManager).handleBluetoothActiveDeviceChanged( - eq(mLeftDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager) + .handleBluetoothActiveDeviceChanged( + eq(mLeftDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); // Send a disconnect request - Assert.assertTrue("Disconnect failed", mService.disconnect(mLeftDevice)); + assertThat(mService.disconnect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Disconnecting state // Note that we call verifyConnectionStateIntent() with (stopAudio == false). - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_DISCONNECTING, - BluetoothProfile.STATE_CONNECTED, false); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, - mService.getConnectionState(mLeftDevice)); + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED, + false); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTING); // Verify the audio is not routed to Hearing Aid Profile. // Note that music should be not paused (i.e. should suppress noisy intent) ArgumentCaptor connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); - verify(mAudioManager).handleBluetoothActiveDeviceChanged( - eq(null), eq(mLeftDevice), connectionInfoArgumentCaptor.capture()); + verify(mAudioManager) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(mLeftDevice), connectionInfoArgumentCaptor.capture()); BluetoothProfileConnectionInfo connectionInfo = connectionInfoArgumentCaptor.getValue(); - Assert.assertTrue(connectionInfo.isSuppressNoisyIntent()); + assertThat(connectionInfo.isSuppressNoisyIntent()).isTrue(); } /** @@ -704,65 +702,66 @@ public class HearingAidServiceTest { @Test public void testCreateStateMachineStackEvents() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Hearing Aid stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getDevices()).contains(mLeftDevice); // HearingAid stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getDevices()).contains(mLeftDevice); mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getDevices()).doesNotContain(mLeftDevice); // stack event: CONNECTION_STATE_CONNECTED - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getDevices()).contains(mLeftDevice); // stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getDevices()).contains(mLeftDevice); mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getDevices()).doesNotContain(mLeftDevice); // stack event: CONNECTION_STATE_DISCONNECTING - state machine should not be created - generateUnexpectedConnectionMessageFromNative(mLeftDevice, - BluetoothProfile.STATE_DISCONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertFalse(mService.getDevices().contains(mLeftDevice)); + generateUnexpectedConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_DISCONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getDevices()).doesNotContain(mLeftDevice); // stack event: CONNECTION_STATE_DISCONNECTED - state machine should not be created - generateUnexpectedConnectionMessageFromNative(mLeftDevice, - BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertFalse(mService.getDevices().contains(mLeftDevice)); + generateUnexpectedConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getDevices()).doesNotContain(mLeftDevice); } /** @@ -771,60 +770,65 @@ public class HearingAidServiceTest { @Test public void testDeleteStateMachineUnbondEvents() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // HearingAid stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getDevices()).contains(mLeftDevice); // Device unbond - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getDevices()).contains(mLeftDevice); // HearingAid stack event: CONNECTION_STATE_CONNECTED - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getDevices()).contains(mLeftDevice); // Device unbond - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getDevices()).contains(mLeftDevice); // HearingAid stack event: CONNECTION_STATE_DISCONNECTING - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTING, BluetoothProfile.STATE_CONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTING, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTING); + assertThat(mService.getDevices()).contains(mLeftDevice); // Device unbond - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getDevices()).contains(mLeftDevice); // HearingAid stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_BONDED); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getDevices()).contains(mLeftDevice); // Device unbond - state machine is removed mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getDevices()).doesNotContain(mLeftDevice); } /** @@ -834,50 +838,58 @@ public class HearingAidServiceTest { @Test public void testDeleteStateMachineDisconnectEvents() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // HearingAid stack event: CONNECTION_STATE_CONNECTING - state machine should be created - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getDevices()).contains(mLeftDevice); // HearingAid stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getDevices()).contains(mLeftDevice); // HearingAid stack event: CONNECTION_STATE_CONNECTING - state machine remains - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTING, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getDevices()).contains(mLeftDevice); // Device bond state marked as unbond - state machine is not removed - doReturn(BluetoothDevice.BOND_NONE).when(mAdapterService) + doReturn(BluetoothDevice.BOND_NONE) + .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); - Assert.assertTrue(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getDevices()).contains(mLeftDevice); // HearingAid stack event: CONNECTION_STATE_DISCONNECTED - state machine is removed - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mLeftDevice)); - Assert.assertFalse(mService.getDevices().contains(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getDevices()).doesNotContain(mLeftDevice); } @Test @@ -885,42 +897,43 @@ public class HearingAidServiceTest { // Update hiSyncId map getHiSyncIdFromNative(); // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); - generateConnectionMessageFromNative(mRightDevice, BluetoothProfile.STATE_CONNECTED, + generateConnectionMessageFromNative( + mRightDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertTrue(mService.getActiveDevices().contains(mRightDevice)); + assertThat(mService.getActiveDevices()).contains(mRightDevice); // indirect call of mService.getActiveDevices to test BluetoothHearingAidBinder final SynchronousResultReceiver> recv = SynchronousResultReceiver.get(); List defaultRecvValue = null; mServiceBinder.getActiveDevices(null, recv); - Assert.assertFalse(recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue).contains(mLeftDevice)); + assertThat(recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue)) + .doesNotContain(mLeftDevice); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertTrue(mService.getActiveDevices().contains(mRightDevice)); - Assert.assertTrue(mService.getActiveDevices().contains(mLeftDevice)); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getActiveDevices()).containsExactly(mRightDevice, mLeftDevice); - generateConnectionMessageFromNative(mRightDevice, BluetoothProfile.STATE_DISCONNECTED, + generateConnectionMessageFromNative( + mRightDevice, + BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); - Assert.assertFalse(mService.getActiveDevices().contains(mRightDevice)); - Assert.assertTrue(mService.getActiveDevices().contains(mLeftDevice)); + assertThat(mService.getActiveDevices()).doesNotContain(mRightDevice); + assertThat(mService.getActiveDevices()).contains(mLeftDevice); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, - BluetoothProfile.STATE_CONNECTED); - Assert.assertFalse(mService.getActiveDevices().contains(mRightDevice)); - Assert.assertFalse(mService.getActiveDevices().contains(mLeftDevice)); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getActiveDevices()).containsNoneOf(mRightDevice, mLeftDevice); } @Test @@ -928,290 +941,289 @@ public class HearingAidServiceTest { // Update hiSyncId map getHiSyncIdFromNative(); // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - generateConnectionMessageFromNative(mRightDevice, BluetoothProfile.STATE_CONNECTED, + generateConnectionMessageFromNative( + mRightDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertTrue(mService.getActiveDevices().contains(mRightDevice)); - Assert.assertFalse(mService.getActiveDevices().contains(mLeftDevice)); + assertThat(mService.getActiveDevices()).contains(mRightDevice); + assertThat(mService.getActiveDevices()).doesNotContain(mLeftDevice); - generateConnectionMessageFromNative(mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertTrue(mService.getActiveDevices().contains(mRightDevice)); - Assert.assertTrue(mService.getActiveDevices().contains(mLeftDevice)); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getActiveDevices()).containsExactly(mRightDevice, mLeftDevice); - generateConnectionMessageFromNative(mSingleDevice, BluetoothProfile.STATE_CONNECTED, + generateConnectionMessageFromNative( + mSingleDevice, + BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertFalse(mService.getActiveDevices().contains(mRightDevice)); - Assert.assertFalse(mService.getActiveDevices().contains(mLeftDevice)); - Assert.assertTrue(mService.getActiveDevices().contains(mSingleDevice)); + assertThat(mService.getActiveDevices()).containsNoneOf(mRightDevice, mLeftDevice); + assertThat(mService.getActiveDevices()).contains(mSingleDevice); - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + SynchronousResultReceiver recv = SynchronousResultReceiver.get(); boolean defaultRecvValue = false; mServiceBinder.setActiveDevice(null, null, recv); - Assert.assertTrue(recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue)); - Assert.assertFalse(mService.getActiveDevices().contains(mSingleDevice)); + assertThat(recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue)).isTrue(); + assertThat(mService.getActiveDevices()).doesNotContain(mSingleDevice); + + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + recv = SynchronousResultReceiver.get(); + mServiceBinder.setActiveDevice(null, null, recv); + verify(mAudioRoutingManager) + .activateDeviceProfile(null, BluetoothProfile.HEARING_AID, recv); } /** - * Verify the correctness during first time connection. - * Connect to left device -> Get left device hiSyncId -> Connect to right device -> - * Get right device hiSyncId -> Both devices should be always connected + * Verify the correctness during first time connection. Connect to left device -> Get left + * device hiSyncId -> Connect to right device -> Get right device hiSyncId -> Both devices + * should be always connected */ @Test public void firstTimeConnection_shouldConnectToBothDevices() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Send a connect request for left device - Assert.assertTrue("Connect failed", mService.connect(mLeftDevice)); + assertThat(mService.connect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); HearingAidStackEvent connCompletedEvent; // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + verifyConnectionStateIntent( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Get hiSyncId for left device - HearingAidStackEvent hiSyncIdEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + HearingAidStackEvent hiSyncIdEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); hiSyncIdEvent.device = mLeftDevice; hiSyncIdEvent.valueInt1 = 0x02; hiSyncIdEvent.valueLong2 = 0x0101; mService.messageFromNative(hiSyncIdEvent); // Send a connect request for right device - Assert.assertTrue("Connect failed", mService.connect(mRightDevice)); + assertThat(mService.connect(mRightDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mRightDevice)); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); // Verify the left device is still connected - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mRightDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mRightDevice)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + verifyConnectionStateIntent( + mRightDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Get hiSyncId for right device - hiSyncIdEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + hiSyncIdEvent = new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); hiSyncIdEvent.device = mRightDevice; hiSyncIdEvent.valueInt1 = 0x02; hiSyncIdEvent.valueLong2 = 0x0101; mService.messageFromNative(hiSyncIdEvent); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mRightDevice)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); } - /** - * Get the HiSyncId from native stack after connecting to left device, then connect right - */ + /** Get the HiSyncId from native stack after connecting to left device, then connect right */ @Test public void getHiSyncId_afterFirstDeviceConnected() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mRightDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mRightDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectHearingAid(any(BluetoothDevice.class)); // Send a connect request - Assert.assertTrue("Connect failed", mService.connect(mLeftDevice)); + assertThat(mService.connect(mLeftDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mLeftDevice)); - Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, - mService.getConnectionState(mRightDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTED); HearingAidStackEvent connCompletedEvent; // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mLeftDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mLeftDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + verifyConnectionStateIntent( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Get hiSyncId update from native stack getHiSyncIdFromNative(); // Send a connect request for right - Assert.assertTrue("Connect failed", mService.connect(mRightDevice)); + assertThat(mService.connect(mRightDevice)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTING, + verifyConnectionStateIntent( + mRightDevice, + BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(mRightDevice)); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); // Verify the left device is still connected - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = mRightDevice; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, mRightDevice, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mRightDevice)); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(mLeftDevice)); + verifyConnectionStateIntent( + mRightDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mRightDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); } - /** - * Test that the service can update HiSyncId from native message - */ + /** Test that the service can update HiSyncId from native message */ @Test public void getHiSyncIdFromNative_addToMap() throws Exception { getHiSyncIdFromNative(); - Assert.assertTrue("hiSyncIdMap should contain mLeftDevice", - mService.getHiSyncIdMap().containsKey(mLeftDevice)); - Assert.assertTrue("hiSyncIdMap should contain mRightDevice", - mService.getHiSyncIdMap().containsKey(mRightDevice)); - Assert.assertTrue("hiSyncIdMap should contain mSingleDevice", - mService.getHiSyncIdMap().containsKey(mSingleDevice)); + assertThat(mService.getHiSyncIdMap()).containsKey(mLeftDevice); + assertThat(mService.getHiSyncIdMap()).containsKey(mRightDevice); + assertThat(mService.getHiSyncIdMap()).containsKey(mSingleDevice); SynchronousResultReceiver recv = SynchronousResultReceiver.get(); long defaultRecvValue = -1000; mServiceBinder.getHiSyncId(mLeftDevice, null, recv); - long id = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue); - Assert.assertNotEquals(BluetoothHearingAid.HI_SYNC_ID_INVALID, id); + long id = recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue); + assertThat(id).isNotEqualTo(BluetoothHearingAid.HI_SYNC_ID_INVALID); recv = SynchronousResultReceiver.get(); mServiceBinder.getHiSyncId(mRightDevice, null, recv); - id = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue); - Assert.assertNotEquals(BluetoothHearingAid.HI_SYNC_ID_INVALID, id); + id = recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue); + assertThat(id).isNotEqualTo(BluetoothHearingAid.HI_SYNC_ID_INVALID); recv = SynchronousResultReceiver.get(); mServiceBinder.getHiSyncId(mSingleDevice, null, recv); - id = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue); - Assert.assertNotEquals(BluetoothHearingAid.HI_SYNC_ID_INVALID, id); + id = recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue); + assertThat(id).isNotEqualTo(BluetoothHearingAid.HI_SYNC_ID_INVALID); } - /** - * Test that the service removes the device from HiSyncIdMap when it's unbonded - */ + /** Test that the service removes the device from HiSyncIdMap when it's unbonded */ @Test public void deviceUnbonded_removeHiSyncId() { getHiSyncIdFromNative(); mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); - Assert.assertFalse("hiSyncIdMap shouldn't contain mLeftDevice", - mService.getHiSyncIdMap().containsKey(mLeftDevice)); + assertThat(mService.getHiSyncIdMap()).doesNotContainKey(mLeftDevice); } @Test public void serviceBinder_callGetDeviceMode() throws Exception { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mServiceBinder.getDeviceMode(mSingleDevice, null, recv); - int mode = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(BluetoothHearingAid.MODE_UNKNOWN); - + int mode = recv.awaitResultNoInterrupt(TIMEOUT).getValue(BluetoothHearingAid.MODE_UNKNOWN); // return unknown value if no device connected - Assert.assertEquals(BluetoothHearingAid.MODE_UNKNOWN, mode); + assertThat(mode).isEqualTo(BluetoothHearingAid.MODE_UNKNOWN); } @Test public void serviceBinder_callGetDeviceSide() throws Exception { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mServiceBinder.getDeviceSide(mSingleDevice, null, recv); - int side = recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(BluetoothHearingAid.SIDE_UNKNOWN); + int side = recv.awaitResultNoInterrupt(TIMEOUT).getValue(BluetoothHearingAid.SIDE_UNKNOWN); // return unknown value if no device connected - Assert.assertEquals(BluetoothHearingAid.SIDE_UNKNOWN, side); + assertThat(side).isEqualTo(BluetoothHearingAid.SIDE_UNKNOWN); } @Test public void serviceBinder_setConnectionPolicy() throws Exception { - when(mDatabaseManager.setProfileConnectionPolicy(mSingleDevice, - BluetoothProfile.HEARING_AID, BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) + when(mDatabaseManager.setProfileConnectionPolicy( + mSingleDevice, + BluetoothProfile.HEARING_AID, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) .thenReturn(true); final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); boolean defaultRecvValue = false; - mServiceBinder.setConnectionPolicy(mSingleDevice, - BluetoothProfile.CONNECTION_POLICY_UNKNOWN, null, recv); - Assert.assertTrue(recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue)); - verify(mDatabaseManager).setProfileConnectionPolicy(mSingleDevice, - BluetoothProfile.HEARING_AID, BluetoothProfile.CONNECTION_POLICY_UNKNOWN); + mServiceBinder.setConnectionPolicy( + mSingleDevice, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, null, recv); + assertThat(recv.awaitResultNoInterrupt(TIMEOUT).getValue(defaultRecvValue)).isTrue(); + verify(mDatabaseManager) + .setProfileConnectionPolicy( + mSingleDevice, + BluetoothProfile.HEARING_AID, + BluetoothProfile.CONNECTION_POLICY_UNKNOWN); } @Test public void serviceBinder_setVolume() throws Exception { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mServiceBinder.setVolume(0, null, recv); - recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)); + recv.awaitResultNoInterrupt(TIMEOUT); verify(mNativeInterface).setVolume(0); } @Test public void dump_doesNotCrash() { // Update the device priority so okToConnect() returns true - when(mDatabaseManager - .getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.HEARING_AID)) + when(mDatabaseManager.getProfileConnectionPolicy( + mSingleDevice, BluetoothProfile.HEARING_AID)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectHearingAid(any(BluetoothDevice.class)); @@ -1233,76 +1245,80 @@ public class HearingAidServiceTest { doReturn(true).when(mNativeInterface).disconnectHearingAid(device); // Send a connect request - Assert.assertTrue("Connect failed", mService.connect(device)); + assertThat(mService.connect(device)).isTrue(); // Verify the connection state broadcast, and that we are in Connecting state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTED); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, - mService.getConnectionState(device)); + verifyConnectionStateIntent( + device, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(device)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); // Send a message to trigger connection completed - connCompletedEvent = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); + connCompletedEvent = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); connCompletedEvent.device = device; connCompletedEvent.valueInt1 = HearingAidStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(connCompletedEvent); // Verify the connection state broadcast, and that we are in Connected state - verifyConnectionStateIntent(TIMEOUT_MS, device, BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING); - Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, - mService.getConnectionState(device)); + verifyConnectionStateIntent( + device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(device)).isEqualTo(BluetoothProfile.STATE_CONNECTED); // Verify that the device is in the list of connected devices - Assert.assertTrue(mService.getConnectedDevices().contains(device)); + assertThat(mService.getConnectedDevices()).contains(device); // Verify the list of previously connected devices for (BluetoothDevice prevDevice : prevConnectedDevices) { - Assert.assertTrue(mService.getConnectedDevices().contains(prevDevice)); + assertThat(mService.getConnectedDevices()).contains(prevDevice); } } - private void generateConnectionMessageFromNative(BluetoothDevice device, int newConnectionState, - int oldConnectionState) { + private void generateConnectionMessageFromNative( + BluetoothDevice device, int newConnectionState, int oldConnectionState) { HearingAidStackEvent stackEvent = new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); stackEvent.device = device; stackEvent.valueInt1 = newConnectionState; mService.messageFromNative(stackEvent); // Verify the connection state broadcast - verifyConnectionStateIntent(TIMEOUT_MS, device, newConnectionState, oldConnectionState); + verifyConnectionStateIntent(device, newConnectionState, oldConnectionState); } - private void generateUnexpectedConnectionMessageFromNative(BluetoothDevice device, - int newConnectionState, int oldConnectionState) { + private void generateUnexpectedConnectionMessageFromNative( + BluetoothDevice device, int newConnectionState) { HearingAidStackEvent stackEvent = new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); stackEvent.device = device; stackEvent.valueInt1 = newConnectionState; mService.messageFromNative(stackEvent); // Verify the connection state broadcast - verifyNoConnectionStateIntent(TIMEOUT_MS, device); + mInOrder.verify(mContext, times(0)) + .sendBroadcast( + MockitoHamcrest.argThat( + hasAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED)), + any(), + any()); } /** - * Helper function to test okToConnect() method + * Helper function to test okToConnect() method * - * @param device test device - * @param bondState bond state value, could be invalid - * @param priority value, could be invalid, coudl be invalid - * @param expected expected result from okToConnect() + * @param device test device + * @param bondState bond state value, could be invalid + * @param priority value, could be invalid, could be invalid + * @param expected expected result from okToConnect() */ - private void testOkToConnectCase(BluetoothDevice device, int bondState, int priority, - boolean expected) { + private void testOkToConnectCase( + BluetoothDevice device, int bondState, int priority, boolean expected) { doReturn(bondState).when(mAdapterService).getBondState(device); when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.HEARING_AID)) .thenReturn(priority); - Assert.assertEquals(expected, mService.okToConnect(device)); + assertThat(mService.okToConnect(device)).isEqualTo(expected); } private void getHiSyncIdFromNative() { - HearingAidStackEvent event = new HearingAidStackEvent( - HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); + HearingAidStackEvent event = + new HearingAidStackEvent(HearingAidStackEvent.EVENT_TYPE_DEVICE_AVAILABLE); event.device = mLeftDevice; event.valueInt1 = 0x02; event.valueLong2 = 0x0101; diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java index 08e5c2f1fc36a64f27360391c4cece9838f0ea4c..86d5bacd70e99172d33950185db4ed587e2908af 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java @@ -171,7 +171,6 @@ public class HeadsetServiceAndStateMachineTest { doReturn(new ParcelUuid[]{BluetoothUuid.HFP}).when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); // We cannot mock HeadsetObjectsFactory.getInstance() with Mockito. // Hence we need to use reflection to call a private method to // initialize properly the HeadsetObjectsFactory.sInstance field. @@ -221,7 +220,8 @@ public class HeadsetServiceAndStateMachineTest { mOriginalVrTimeoutMs = HeadsetService.sStartVrTimeoutMs; HeadsetService.sStartVrTimeoutMs = START_VR_TIMEOUT_MILLIS; mHeadsetService = new HeadsetService(mTargetContext); - mHeadsetService.doStart(); + mHeadsetService.start(); + mHeadsetService.setAvailable(true); mIsHeadsetServiceStarted = true; Assert.assertNotNull(mHeadsetService); verify(mObjectsFactory).makeSystemInterface(mHeadsetService); @@ -248,7 +248,7 @@ public class HeadsetServiceAndStateMachineTest { if (mIsHeadsetServiceStarted) { mTargetContext.unregisterReceiver(mHeadsetIntentReceiver); - mHeadsetService.doStop(); + mHeadsetService.stop(); mHeadsetService = HeadsetService.getHeadsetService(); Assert.assertNull(mHeadsetService); // Clear classes that is spied on and has static life time diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java index abc6f1e2ada4c1190517f50ac5e48d1b6d636803..2aa1e1ff0d9f49837f8a9b1651f6404cbb247e04 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceTest.java @@ -19,7 +19,6 @@ package com.android.bluetooth.hfp; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -125,7 +124,6 @@ public class HeadsetServiceTest { doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager(); doReturn(mSilenceDeviceManager).when(mAdapterService).getSilenceDeviceManager(); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); doReturn(mRemoteDevices).when(mAdapterService).getRemoteDevices(); doAnswer(invocation -> { Set keys = mStateMachines.keySet(); @@ -160,7 +158,8 @@ public class HeadsetServiceTest { doReturn(mNativeInterface).when(mObjectsFactory).getNativeInterface(); HeadsetNativeInterface.setInstance(mNativeInterface); mHeadsetService = new HeadsetService(mTargetContext); - mHeadsetService.doStart(); + mHeadsetService.start(); + mHeadsetService.setAvailable(true); verify(mObjectsFactory).makeSystemInterface(mHeadsetService); verify(mObjectsFactory).getNativeInterface(); mHeadsetService.setForceScoAudio(true); @@ -168,7 +167,7 @@ public class HeadsetServiceTest { @After public void tearDown() throws Exception { - mHeadsetService.doStop(); + mHeadsetService.stop(); HeadsetNativeInterface.setInstance(null); mHeadsetService = HeadsetService.getHeadsetService(); Assert.assertNull(mHeadsetService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java index 5c90a026a7fa97daff46cb3efaba7252b8323a3e..cc5119997de9f5388b454e053a0a5f2f80096abe 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java @@ -19,6 +19,7 @@ package com.android.bluetooth.hfp; import static android.Manifest.permission.BLUETOOTH_CONNECT; import static org.mockito.Mockito.*; +import static org.junit.Assume.assumeTrue; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -36,7 +37,9 @@ import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.HandlerThread; +import android.os.SystemProperties; import android.os.UserHandle; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.CallLog; import android.provider.CallLog.Calls; import android.telephony.PhoneNumberUtils; @@ -55,12 +58,14 @@ import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.RemoteDevices; import com.android.bluetooth.btservice.SilenceDeviceManager; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import org.hamcrest.core.IsInstanceOf; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -81,6 +86,9 @@ public class HeadsetStateMachineTest { private static final int ASYNC_CALL_TIMEOUT_MILLIS = 250; private static final String TEST_PHONE_NUMBER = "1234567890"; private static final int MAX_RETRY_DISCONNECT_AUDIO = 3; + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private Context mTargetContext; private BluetoothAdapter mAdapter; private HandlerThread mHandlerThread; @@ -108,8 +116,8 @@ public class HeadsetStateMachineTest { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); // Stub system interface - when(mSystemInterface.getHeadsetPhoneState()).thenReturn(mPhoneState); - when(mSystemInterface.getAudioManager()).thenReturn(mAudioManager); + doReturn(mPhoneState).when(mSystemInterface).getHeadsetPhoneState(); + doReturn(mAudioManager).when(mSystemInterface).getAudioManager(); // This line must be called to make sure relevant objects are initialized properly mAdapter = BluetoothAdapter.getDefaultAdapter(); // Get a device for testing @@ -1011,6 +1019,46 @@ public class HeadsetStateMachineTest { verify(mSystemInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).hangupCall(mTestDevice); } + /** A test to verify that we correctly send CIND response when a call is in progress */ + @Test + public void testCindEventWhenCallIsInProgress() { + mSetFlagsRule.enableFlags(Flags.FLAG_PRETEND_NETWORK_SERVICE); + when(mPhoneState.getCindService()) + .thenReturn(HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE); + when(mHeadsetService.isVirtualCallStarted()).thenReturn(false); + when(mPhoneState.getNumActiveCall()).thenReturn(1); + + setUpAudioOnState(); + + mHeadsetStateMachine.sendMessage( + HeadsetStateMachine.STACK_EVENT, + new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_AT_CIND, mTestDevice)); + // wait state machine to process the message + if (Flags.pretendNetworkService()) { + verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .cindResponse( + eq(mTestDevice), + eq(HeadsetHalConstants.NETWORK_STATE_AVAILABLE), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyInt()); + } else { + verify(mNativeInterface, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .cindResponse( + eq(mTestDevice), + eq(HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyInt()); + } + } + /** * A test to verify that we correctly handles key pressed event from a HSP headset */ @@ -1614,6 +1662,8 @@ public class HeadsetStateMachineTest { /** Test setting audio parameters according to received SWB event. SWB AptX is enabled. */ @Test public void testSetAudioParameters_SwbAptxEnabled() { + mSetFlagsRule.enableFlags(Flags.FLAG_HFP_CODEC_APTX_VOICE); + assumeTrue(SystemProperties.getBoolean("bluetooth.hfp.codec_aptx_voice.enabled", false)); setUpConnectedState(); mHeadsetStateMachine.sendMessage( HeadsetStateMachine.STACK_EVENT, @@ -1683,8 +1733,11 @@ public class HeadsetStateMachineTest { private void verifyAudioSystemSetParametersInvocation(boolean lc3Enabled, boolean aptxEnabled) { verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) .setParameters(lc3Enabled ? "bt_lc3_swb=on" : "bt_lc3_swb=off"); - verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) - .setParameters(aptxEnabled ? "bt_swb=0" : "bt_swb=65535"); + + if (mHeadsetStateMachine.IS_APTX_SUPPORT_ENABLED) { + verify(mAudioManager, timeout(ASYNC_CALL_TIMEOUT_MILLIS)) + .setParameters(aptxEnabled ? "bt_swb=0" : "bt_swb=65535"); + } } /** diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java index 4e0da2f1c468c69ba917d3c137c8b4259992679e..a6288f647f2db816075b7fc23753d5326c0bd19b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientServiceTest.java @@ -20,7 +20,6 @@ import static android.content.pm.PackageManager.FEATURE_WATCH; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; @@ -80,7 +79,6 @@ public class HeadsetClientServiceTest { mIsAdapterServiceSet = true; doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); doReturn(mRemoteDevices).when(mAdapterService).getRemoteDevices(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); NativeInterface.setInstance(mNativeInterface); } @@ -177,11 +175,11 @@ public class HeadsetClientServiceTest { doReturn(packageManager).when(context).getPackageManager(); HeadsetClientService service = new HeadsetClientService(context); - service.doStart(); + service.start(); verify(context).startService(any(Intent.class)); - service.doStop(); + service.stop(); } @Test @@ -193,17 +191,18 @@ public class HeadsetClientServiceTest { doReturn(packageManager).when(context).getPackageManager(); HeadsetClientService service = new HeadsetClientService(context); - service.doStart(); + service.start(); verify(context, never()).startService(any(Intent.class)); - service.doStop(); + service.stop(); } private void startService() throws Exception { // At this point the service should have started so check NOT null mService = new HeadsetClientService(mTargetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); Assert.assertNotNull(mAdapter); @@ -212,7 +211,7 @@ public class HeadsetClientServiceTest { private void stopServiceIfStarted() throws Exception { if (mIsHeadsetClientServiceStarted) { - mService.doStop(); + mService.stop(); mService = HeadsetClientService.getHeadsetClientService(); Assert.assertNull(mService); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java index f1ec21059cc3a3b52a8b824f5c66c95bf92a97d5..f95bd870e66b55562f19c3d4d0cfbd9e0cd64512 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachineTest.java @@ -1356,9 +1356,9 @@ public class HeadsetClientStateMachineTest { @Test public void testProcessConnectMessage_onConnectingState() { initToConnectingState(); - mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.CONNECT); assertThat(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( HeadsetClientStateMachine.CONNECT)).isFalse(); + mHeadsetClientStateMachine.sendMessage(HeadsetClientStateMachine.CONNECT); TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper()); Assert.assertTrue(mHeadsetClientStateMachine.doesSuperHaveDeferredMessages( HeadsetClientStateMachine.CONNECT)); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java index 5f923650b0999b0c1c8d3fca61181dedff6e2add..db4a62ee35465b80be9ace8f0cbf822de82c2597 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidDeviceTest.java @@ -104,7 +104,6 @@ public class HidDeviceTest { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); setHidDeviceNativeInterfaceInstance(mHidDeviceNativeInterface); // This line must be called to make sure relevant objects are initialized properly mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -112,7 +111,8 @@ public class HidDeviceTest { mTestDevice = mAdapter.getRemoteDevice("10:11:12:13:14:15"); mHidDeviceService = new HidDeviceService(mTargetContext); - mHidDeviceService.doStart(); + mHidDeviceService.start(); + mHidDeviceService.setAvailable(true); // Force unregister app first mHidDeviceService.unregisterApp(); @@ -138,7 +138,7 @@ public class HidDeviceTest { @After public void tearDown() throws Exception { - mHidDeviceService.doStop(); + mHidDeviceService.stop(); mHidDeviceService = HidDeviceService.getHidDeviceService(); Assert.assertNull(mHidDeviceService); mTargetContext.unregisterReceiver(mConnectionStateChangedReceiver); diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java index f90f867d5b9227dac0daf4bd3ace16f43ed0e706..8bedfb3e2ad32aa3c89d17cc03a6dc5648ed5f6b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceBinderTest.java @@ -17,17 +17,16 @@ package com.android.bluetooth.hid; import static org.mockito.Mockito.verify; - +import android.platform.test.flag.junit.SetFlagsRule; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; - import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; - +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver; - import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -36,7 +35,7 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidJUnit4.class) public class HidHostServiceBinderTest { - + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private static final String REMOTE_DEVICE_ADDRESS = "00:00:00:00:00:00"; @Mock @@ -106,6 +105,24 @@ public class HidHostServiceBinderTest { verify(mService).getConnectionPolicy(mRemoteDevice); } + @Test + public void setPreferredTransport_callsServiceMethod() { + mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_SWITCHING_HID_AND_HOGP); + int preferredTransport = BluetoothDevice.TRANSPORT_AUTO; + mBinder.setPreferredTransport( + mRemoteDevice, preferredTransport, null, SynchronousResultReceiver.get()); + + verify(mService).setPreferredTransport(mRemoteDevice, preferredTransport); + } + + @Test + public void getPreferredTransport_callsServiceMethod() { + mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_SWITCHING_HID_AND_HOGP); + mBinder.getPreferredTransport(mRemoteDevice, null, SynchronousResultReceiver.get()); + + verify(mService).getPreferredTransport(mRemoteDevice); + } + @Test public void getProtocolMode_callsServiceMethod() { mBinder.getProtocolMode(mRemoteDevice, null, diff --git a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java index d75bdf11ab4b4ed21adfb87b86978269a1c9946e..41652ab67321f260333d3d9852ca00144c59e4b9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hid/HidHostServiceTest.java @@ -56,10 +56,10 @@ public class HidHostServiceTest { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); - when(mAdapterService.isStartedProfile(anyString())).thenReturn(true); HidHostNativeInterface.setInstance(mNativeInterface); mService = new HidHostService(mTargetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); Assert.assertNotNull(mAdapter); @@ -70,8 +70,8 @@ public class HidHostServiceTest { @After public void tearDown() throws Exception { - when(mAdapterService.isStartedProfile(anyString())).thenReturn(false); - mService.doStop(); + mService.stop(); + mService.cleanup(); HidHostNativeInterface.setInstance(null); mService = HidHostService.getHidHostService(); Assert.assertNull(mService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java index 864c09f853983380997e771dc22162dd10aae095..d7f7d419d3869bb462647117b5f68d0b600df41a 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java @@ -16,6 +16,8 @@ package com.android.bluetooth.le_audio; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothAdapter; @@ -33,12 +35,20 @@ import android.bluetooth.IBluetoothLeBroadcastCallback; import android.content.AttributionSource; import android.os.ParcelUuid; import android.os.RemoteCallbackList; +import android.platform.test.flag.junit.SetFlagsRule; + +import androidx.test.InstrumentationRegistry; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.AudioRoutingManager; +import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.x.com.android.modules.utils.SynchronousResultReceiver; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; @@ -48,12 +58,17 @@ import java.util.List; import java.util.UUID; public class LeAudioBinderTest { - @Mock - private LeAudioService mMockService; - @Mock - private RemoteCallbackList mLeAudioCallbacks; - @Mock - private RemoteCallbackList mBroadcastCallbacks; + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private LeAudioService mLeAudioService; + @Mock private AdapterService mAdapterService; + @Mock private LeAudioNativeInterface mNativeInterface; + @Mock private DatabaseManager mDatabaseManager; + @Mock private AudioRoutingManager mAudioRoutingManager; + + @Mock private RemoteCallbackList mLeAudioCallbacks; + @Mock private RemoteCallbackList mBroadcastCallbacks; private LeAudioService.BluetoothLeAudioBinder mBinder; private BluetoothAdapter mAdapter; @@ -65,15 +80,27 @@ public class LeAudioBinderTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + TestUtils.setAdapterService(mAdapterService); + doReturn(false).when(mAdapterService).isQuietModeEnabled(); + doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); + doReturn(mAudioRoutingManager).when(mAdapterService).getActiveDeviceManager(); + + mLeAudioService = + spy( + new LeAudioService( + InstrumentationRegistry.getTargetContext(), mNativeInterface)); + mLeAudioService.start(); mAdapter = BluetoothAdapter.getDefaultAdapter(); - mBinder = new LeAudioService.BluetoothLeAudioBinder(mMockService); - mMockService.mLeAudioCallbacks = mLeAudioCallbacks; - mMockService.mBroadcastCallbacks = mBroadcastCallbacks; + mBinder = new LeAudioService.BluetoothLeAudioBinder(mLeAudioService); + mLeAudioService.mLeAudioCallbacks = mLeAudioCallbacks; + mLeAudioService.mBroadcastCallbacks = mBroadcastCallbacks; } @After public void cleanUp() { mBinder.cleanup(); + mLeAudioService.stop(); + TestUtils.clearAdapterService(mAdapterService); } @Test @@ -83,7 +110,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.connect(device, source, recv); - verify(mMockService).connect(device); + verify(mLeAudioService).connect(device); } @Test @@ -93,7 +120,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.disconnect(device, source, recv); - verify(mMockService).disconnect(device); + verify(mLeAudioService).disconnect(device); } @Test @@ -103,7 +130,7 @@ public class LeAudioBinderTest { SynchronousResultReceiver.get(); mBinder.getConnectedDevices(source, recv); - verify(mMockService).getConnectedDevices(); + verify(mLeAudioService).getConnectedDevices(); } @Test @@ -114,7 +141,7 @@ public class LeAudioBinderTest { SynchronousResultReceiver.get(); mBinder.getConnectedGroupLeadDevice(groupId, source, recv); - verify(mMockService).getConnectedGroupLeadDevice(groupId); + verify(mLeAudioService).getConnectedGroupLeadDevice(groupId); } @Test @@ -125,7 +152,7 @@ public class LeAudioBinderTest { SynchronousResultReceiver.get(); mBinder.getDevicesMatchingConnectionStates(states, source, recv); - verify(mMockService).getDevicesMatchingConnectionStates(states); + verify(mLeAudioService).getDevicesMatchingConnectionStates(states); } @Test @@ -135,26 +162,38 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getConnectionState(device, source, recv); - verify(mMockService).getConnectionState(device); + verify(mLeAudioService).getConnectionState(device); } @Test public void setActiveDevice() { BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); AttributionSource source = new AttributionSource.Builder(0).build(); - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.setActiveDevice(device, source, recv); - verify(mMockService).setActiveDevice(device); + verify(mLeAudioService).setActiveDevice(device); + + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + recv = SynchronousResultReceiver.get(); + mBinder.setActiveDevice(device, source, recv); + verify(mAudioRoutingManager).activateDeviceProfile(device, BluetoothProfile.LE_AUDIO, recv); } @Test public void setActiveDevice_withNullDevice_callsRemoveActiveDevice() { AttributionSource source = new AttributionSource.Builder(0).build(); - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mBinder.setActiveDevice(null, source, recv); + verify(mLeAudioService).removeActiveDevice(true); + + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + recv = SynchronousResultReceiver.get(); mBinder.setActiveDevice(null, source, recv); - verify(mMockService).removeActiveDevice(true); + verify(mAudioRoutingManager).activateDeviceProfile(null, BluetoothProfile.LE_AUDIO, recv); } @Test @@ -163,7 +202,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getActiveDevices(source, recv); - verify(mMockService).getActiveDevices(); + verify(mLeAudioService).getActiveDevices(); } @Test @@ -173,7 +212,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getAudioLocation(device, source, recv); - verify(mMockService).getAudioLocation(device); + verify(mLeAudioService).getAudioLocation(device); } @Test @@ -184,7 +223,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.setConnectionPolicy(device, connectionPolicy, source, recv); - verify(mMockService).setConnectionPolicy(device, connectionPolicy); + verify(mLeAudioService).setConnectionPolicy(device, connectionPolicy); } @Test @@ -194,7 +233,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getConnectionPolicy(device, source, recv); - verify(mMockService).getConnectionPolicy(device); + verify(mLeAudioService).getConnectionPolicy(device); } @Test @@ -206,7 +245,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.setCcidInformation(uuid, ccid, contextType, source, recv); - verify(mMockService).setCcidInformation(uuid, ccid, contextType); + verify(mLeAudioService).setCcidInformation(uuid, ccid, contextType); } @Test @@ -216,7 +255,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getGroupId(device, source, recv); - verify(mMockService).getGroupId(device); + verify(mLeAudioService).getGroupId(device); } @Test @@ -227,7 +266,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.groupAddNode(groupId, device, source, recv); - verify(mMockService).groupAddNode(groupId, device); + verify(mLeAudioService).groupAddNode(groupId, device); } @Test @@ -237,7 +276,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.setInCall(inCall, source, recv); - verify(mMockService).setInCall(inCall); + verify(mLeAudioService).setInCall(inCall); } @Test @@ -247,7 +286,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.setInactiveForHfpHandover(device, source, recv); - verify(mMockService).setInactiveForHfpHandover(device); + verify(mLeAudioService).setInactiveForHfpHandover(device); } @Test @@ -258,7 +297,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.groupRemoveNode(groupId, device, source, recv); - verify(mMockService).groupRemoveNode(groupId, device); + verify(mLeAudioService).groupRemoveNode(groupId, device); } @Test @@ -268,7 +307,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.setVolume(volume, source, recv); - verify(mMockService).setVolume(volume); + verify(mLeAudioService).setVolume(volume); } @Test @@ -278,7 +317,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.registerCallback(callback, source, recv); - verify(mMockService.mLeAudioCallbacks).register(callback); + verify(mLeAudioService.mLeAudioCallbacks).register(callback); } @Test @@ -288,7 +327,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.unregisterCallback(callback, source, recv); - verify(mMockService.mLeAudioCallbacks).unregister(callback); + verify(mLeAudioService.mLeAudioCallbacks).unregister(callback); } @Test @@ -298,7 +337,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.registerLeBroadcastCallback(callback, source, recv); - verify(mMockService.mBroadcastCallbacks).register(callback); + verify(mLeAudioService.mBroadcastCallbacks).register(callback); } @Test @@ -308,7 +347,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.unregisterLeBroadcastCallback(callback, source, recv); - verify(mMockService.mBroadcastCallbacks).unregister(callback); + verify(mLeAudioService.mBroadcastCallbacks).unregister(callback); } @Test @@ -318,7 +357,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.startBroadcast(broadcastSettings, source, recv); - verify(mMockService).createBroadcast(broadcastSettings); + verify(mLeAudioService).createBroadcast(broadcastSettings); } @Test @@ -328,7 +367,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.stopBroadcast(id, source, recv); - verify(mMockService).stopBroadcast(id); + verify(mLeAudioService).stopBroadcast(id); } @Test @@ -339,7 +378,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.updateBroadcast(id, broadcastSettings, source, recv); - verify(mMockService).updateBroadcast(id, broadcastSettings); + verify(mLeAudioService).updateBroadcast(id, broadcastSettings); } @Test @@ -351,7 +390,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.isPlaying(id, source, recv); - verify(mMockService).isPlaying(id); + verify(mLeAudioService).isPlaying(id); } @Test @@ -361,7 +400,7 @@ public class LeAudioBinderTest { SynchronousResultReceiver.get(); mBinder.getAllBroadcastMetadata(source, recv); - verify(mMockService).getAllBroadcastMetadata(); + verify(mLeAudioService).getAllBroadcastMetadata(); } @Test @@ -370,7 +409,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getMaximumNumberOfBroadcasts(source, recv); - verify(mMockService).getMaximumNumberOfBroadcasts(); + verify(mLeAudioService).getMaximumNumberOfBroadcasts(); } @Test @@ -379,7 +418,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getMaximumStreamsPerBroadcast(source, recv); - verify(mMockService).getMaximumStreamsPerBroadcast(); + verify(mLeAudioService).getMaximumStreamsPerBroadcast(); } @Test @@ -388,7 +427,7 @@ public class LeAudioBinderTest { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); mBinder.getMaximumSubgroupsPerBroadcast(source, recv); - verify(mMockService).getMaximumSubgroupsPerBroadcast(); + verify(mLeAudioService).getMaximumSubgroupsPerBroadcast(); } @Test @@ -399,7 +438,7 @@ public class LeAudioBinderTest { SynchronousResultReceiver.get(); mBinder.getCodecStatus(groupId, source, recv); - verify(mMockService).getCodecStatus(groupId); + verify(mLeAudioService).getCodecStatus(groupId); } @Test @@ -412,7 +451,7 @@ public class LeAudioBinderTest { AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.setCodecConfigPreference(groupId, inputConfig, outputConfig, source); - verify(mMockService).setCodecConfigPreference(groupId, inputConfig, outputConfig); + verify(mLeAudioService).setCodecConfigPreference(groupId, inputConfig, outputConfig); } private BluetoothLeBroadcastSettings buildBroadcastSettingsFromMetadata() { diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java index de7604499e5c270480936603915b5344f1294c2a..17057c9f3e931e5d4467f697ceadd38f6c251009 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java @@ -28,19 +28,22 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; +import android.media.BluetoothProfileConnectionInfo; import android.os.Looper; import android.os.ParcelUuid; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; -import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.Utils; +import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; -import com.android.bluetooth.flags.FakeFeatureFlagsImpl; import com.android.bluetooth.flags.Flags; import org.junit.After; @@ -50,6 +53,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @@ -61,10 +65,13 @@ import java.util.concurrent.TimeoutException; @RunWith(AndroidJUnit4.class) public class LeAudioBroadcastServiceTest { private static final int TIMEOUT_MS = 1000; - @Rule - public final ServiceTestRule mServiceRule = new ServiceTestRule(); + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private BluetoothAdapter mAdapter; private BluetoothDevice mDevice; + private BluetoothDevice mBroadcastDevice; + private Context mTargetContext; private LeAudioService mService; private LeAudioIntentReceiver mLeAudioIntentReceiver; @@ -79,7 +86,9 @@ public class LeAudioBroadcastServiceTest { @Mock private LeAudioBroadcasterNativeInterface mLeAudioBroadcasterNativeInterface; @Mock private LeAudioNativeInterface mLeAudioNativeInterface; @Mock private LeAudioTmapGattServer mTmapGattServer; + @Mock private BassClientService mBassClientService; @Spy private LeAudioObjectsFactory mObjectsFactory = LeAudioObjectsFactory.getInstance(); + @Spy private ServiceFactory mServiceFactory = new ServiceFactory(); private static final String TEST_MAC_ADDRESS = "00:11:22:33:44:55"; private static final int TEST_BROADCAST_ID = 42; @@ -100,6 +109,27 @@ public class LeAudioBroadcastServiceTest { private static final String TEST_LANGUAGE = "deu"; private static final String TEST_BROADCAST_NAME = "Name Test"; + private static final BluetoothLeAudioCodecConfig LC3_16KHZ_CONFIG = + new BluetoothLeAudioCodecConfig.Builder() + .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) + .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_16000) + .build(); + private static final BluetoothLeAudioCodecConfig LC3_48KHZ_CONFIG = + new BluetoothLeAudioCodecConfig.Builder() + .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) + .setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000) + .build(); + + private static final List INPUT_SELECTABLE_CONFIG_STANDARD = + List.of(LC3_16KHZ_CONFIG); + private static final List OUTPUT_SELECTABLE_CONFIG_STANDARD = + List.of(LC3_16KHZ_CONFIG); + + private static final List INPUT_SELECTABLE_CONFIG_HIGH = + List.of(LC3_48KHZ_CONFIG); + private static final List OUTPUT_SELECTABLE_CONFIG_HIGH = + List.of(LC3_48KHZ_CONFIG); + private boolean mOnBroadcastStartedCalled = false; private boolean mOnBroadcastStartFailedCalled = false; private boolean mOnBroadcastStoppedCalled = false; @@ -110,7 +140,6 @@ public class LeAudioBroadcastServiceTest { private boolean mOnBroadcastUpdateFailedCalled = false; private boolean mOnBroadcastMetadataChangedCalled = false; private int mOnBroadcastStartFailedReason = BluetoothStatusCodes.SUCCESS; - private FakeFeatureFlagsImpl mFakeFlagsImpl; private final IBluetoothLeBroadcastCallback mCallbacks = new IBluetoothLeBroadcastCallback.Stub() { @@ -181,7 +210,6 @@ public class LeAudioBroadcastServiceTest { TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); doReturn(true).when(mAdapterService).isLeAudioBroadcastSourceSupported(); doReturn((long)(1 << BluetoothProfile.LE_AUDIO_BROADCAST) | (1 << BluetoothProfile.LE_AUDIO)) .when(mAdapterService).getSupportedProfilesBitMask(); @@ -193,14 +221,9 @@ public class LeAudioBroadcastServiceTest { LeAudioNativeInterface.setInstance(mLeAudioNativeInterface); startService(); - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_UNICAST_INACTIVATE_DEVICE_BASED_ON_CONTEXT, false); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, false); - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false); - mService.setFeatureFlags(mFakeFlagsImpl); - mService.mAudioManager = mAudioManager; - + mService.mServiceFactory = mServiceFactory; + when(mServiceFactory.getBassClientService()).thenReturn(mBassClientService); // Set up the State Changed receiver IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); @@ -210,33 +233,37 @@ public class LeAudioBroadcastServiceTest { mTargetContext.registerReceiver(mLeAudioIntentReceiver, filter); mDevice = TestUtils.getTestDevice(mAdapter, 0); - when(mLeAudioBroadcasterNativeInterface.getDevice(any(byte[].class))).thenReturn(mDevice); + mBroadcastDevice = TestUtils.getTestDevice(mAdapter, 1); + when(mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress("FF:FF:FF:FF:FF:FF"))) + .thenReturn(mBroadcastDevice); mIntentQueue = new LinkedBlockingQueue(); } @After public void tearDown() throws Exception { - if (mService == null) { + if (mService == null || mAdapter == null) { return; } + if (mLeAudioIntentReceiver != null) { + mTargetContext.unregisterReceiver(mLeAudioIntentReceiver); + } stopService(); LeAudioBroadcasterNativeInterface.setInstance(null); LeAudioNativeInterface.setInstance(null); - mTargetContext.unregisterReceiver(mLeAudioIntentReceiver); TestUtils.clearAdapterService(mAdapterService); reset(mAudioManager); } private void startService() throws TimeoutException { - TestUtils.startService(mServiceRule, LeAudioService.class); - mService = LeAudioService.getLeAudioService(); - Assert.assertNotNull(mService); + mService = new LeAudioService(mTargetContext); + mService.start(); + mService.setAvailable(true); } private void stopService() throws TimeoutException { - TestUtils.stopService(mServiceRule, LeAudioService.class); + mService.stop(); mService = LeAudioService.getLeAudioService(); Assert.assertNull(mService); } @@ -253,16 +280,8 @@ public class LeAudioBroadcastServiceTest { public void testStopLeAudioService() { Assert.assertEquals(mService, LeAudioService.getLeAudioService()); - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.stop()); - } - }); - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.start()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::start); } void verifyBroadcastStarted(int broadcastId, BluetoothLeBroadcastSettings settings) { @@ -410,6 +429,44 @@ public class LeAudioBroadcastServiceTest { Assert.assertTrue(mOnBroadcastStartFailedCalled); } + @Test + public void testCreateBroadcast_updateQualityToStandard() { + byte[] code = {0x00, 0x01, 0x00, 0x02}; + int groupId = 1; + prepareConnectedUnicastDevice(groupId); + + mService.mBroadcastCallbacks.register(mCallbacks); + + BluetoothLeAudioContentMetadata.Builder meta_builder = + new BluetoothLeAudioContentMetadata.Builder(); + BluetoothLeAudioContentMetadata meta = meta_builder.build(); + BluetoothLeBroadcastSettings settings = buildBroadcastSettingsFromMetadata(meta, code, 1); + + when(mBassClientService.getConnectedDevices()).thenReturn(List.of(mDevice)); + // update selectable configs to be STANDARD quality + injectGroupSelectableCodecConfigChanged( + groupId, INPUT_SELECTABLE_CONFIG_STANDARD, OUTPUT_SELECTABLE_CONFIG_STANDARD); + injectGroupCurrentCodecConfigChanged(groupId, LC3_16KHZ_CONFIG, LC3_48KHZ_CONFIG); + + mService.createBroadcast(settings); + + // Test data with only one subgroup + // Verify quality is updated to standard per sinks capabilities + int[] expectedQualityArray = {BluetoothLeBroadcastSubgroupSettings.QUALITY_STANDARD}; + byte[][] expectedDataArray = { + settings.getSubgroupSettings().get(0).getContentMetadata().getRawMetadata() + }; + + verify(mLeAudioBroadcasterNativeInterface, times(1)) + .createBroadcast( + eq(true), + eq(TEST_BROADCAST_NAME), + eq(code), + eq(settings.getPublicBroadcastMetadata().getRawMetadata()), + eq(expectedQualityArray), + eq(expectedDataArray)); + } + @Test public void testStartStopBroadcastNative() { int broadcastId = 243; @@ -524,6 +581,52 @@ public class LeAudioBroadcastServiceTest { Assert.assertEquals(meta_list.get(0), state_event.broadcastMetadata); } + @Test + public void testIsBroadcastActive() { + int broadcastId = 243; + byte[] code = {0x00, 0x01, 0x00, 0x02}; + + BluetoothLeAudioContentMetadata.Builder meta_builder = + new BluetoothLeAudioContentMetadata.Builder(); + meta_builder.setLanguage("ENG"); + meta_builder.setProgramInfo("Public broadcast info"); + BluetoothLeAudioContentMetadata meta = meta_builder.build(); + mService.createBroadcast(buildBroadcastSettingsFromMetadata(meta, code, 1)); + + LeAudioStackEvent create_event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_CREATED); + create_event.valueInt1 = broadcastId; + create_event.valueBool1 = true; + mService.messageFromNative(create_event); + + // Inject metadata stack event and verify if getter API works as expected + LeAudioStackEvent state_event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_METADATA_CHANGED); + state_event.valueInt1 = broadcastId; + state_event.broadcastMetadata = createBroadcastMetadata(); + mService.messageFromNative(state_event); + + // Verify if broadcast is active + Assert.assertTrue(mService.isBroadcastActive()); + + mService.stopBroadcast(broadcastId); + verify(mLeAudioBroadcasterNativeInterface, times(1)).stopBroadcast(eq(broadcastId)); + + state_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE); + state_event.valueInt1 = broadcastId; + state_event.valueInt2 = LeAudioStackEvent.BROADCAST_STATE_STOPPED; + mService.messageFromNative(state_event); + + verify(mLeAudioBroadcasterNativeInterface, times(1)).destroyBroadcast(eq(broadcastId)); + + state_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_DESTROYED); + state_event.valueInt1 = broadcastId; + mService.messageFromNative(state_event); + + // Verify if broadcast is not active + Assert.assertFalse(mService.isBroadcastActive()); + } + private void verifyConnectionStateIntent( int timeoutMs, BluetoothDevice device, int newState, int prevState) { Intent intent = TestUtils.waitForIntent(timeoutMs, mIntentQueue); @@ -606,6 +709,11 @@ public class LeAudioBroadcastServiceTest { create_event.valueInt4 = srcAudioLocation; create_event.valueInt5 = availableContexts; mService.messageFromNative(create_event); + + // Set default codec config to HIGH quality + injectGroupSelectableCodecConfigChanged( + groupId, INPUT_SELECTABLE_CONFIG_HIGH, OUTPUT_SELECTABLE_CONFIG_HIGH); + injectGroupCurrentCodecConfigChanged(groupId, LC3_16KHZ_CONFIG, LC3_48KHZ_CONFIG); } @Test @@ -613,7 +721,7 @@ public class LeAudioBroadcastServiceTest { int groupId = 1; byte[] code = {0x00, 0x01, 0x00, 0x02}; - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, true); + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); prepareConnectedUnicastDevice(groupId); @@ -693,14 +801,9 @@ public class LeAudioBroadcastServiceTest { mOnBroadcastStartFailedReason); } - @Test - public void testInCallDrivenBroadcastSwitch() { - int groupId = 1; - int broadcastId = 243; - byte[] code = {0x00, 0x01, 0x00, 0x02}; - - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, true); - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, true); + private void prepareHandoverStreamingBroadcast(int groupId, int broadcastId, byte[] code) { + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES); mService.mBroadcastCallbacks.register(mCallbacks); @@ -712,6 +815,14 @@ public class LeAudioBroadcastServiceTest { create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_ACTIVE; mService.messageFromNative(create_event); + /* Verify Unicast input and output devices changed from null to mDevice */ + verify(mAudioManager, times(2)) + .handleBluetoothActiveDeviceChanged( + eq(mDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + Mockito.clearInvocations(mAudioManager); + + mService.notifyActiveDeviceChanged(mDevice); + /* Prepare create broadcast */ BluetoothLeAudioContentMetadata.Builder meta_builder = new BluetoothLeAudioContentMetadata.Builder(); @@ -722,6 +833,10 @@ public class LeAudioBroadcastServiceTest { BluetoothLeBroadcastSettings settings = buildBroadcastSettingsFromMetadata(meta, code, 1); mService.createBroadcast(settings); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + /* Active group should become inactive */ int activeGroup = mService.getActiveGroupId(); Assert.assertEquals(activeGroup, LE_AUDIO_GROUP_ID_INVALID); @@ -732,6 +847,11 @@ public class LeAudioBroadcastServiceTest { create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_INACTIVE; mService.messageFromNative(create_event); + /* Only one Unicast device should become inactive due to Sink monitor mode */ + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(mDevice), any(BluetoothProfileConnectionInfo.class)); + Mockito.clearInvocations(mAudioManager); List settingsList = settings.getSubgroupSettings(); int[] expectedQualityArray = @@ -749,6 +869,8 @@ public class LeAudioBroadcastServiceTest { eq(settings.getPublicBroadcastMetadata().getRawMetadata()), eq(expectedQualityArray), eq(expectedDataArray)); + verify(mLeAudioNativeInterface, times(1)) + .setUnicastMonitorMode(eq(LeAudioStackEvent.DIRECTION_SINK), eq(true)); activeGroup = mService.getActiveGroupId(); Assert.assertEquals(LE_AUDIO_GROUP_ID_INVALID, activeGroup); @@ -764,9 +886,19 @@ public class LeAudioBroadcastServiceTest { /* Switch to active streaming */ create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE); + create_event.device = mBroadcastDevice; create_event.valueInt1 = broadcastId; create_event.valueInt2 = LeAudioStackEvent.BROADCAST_STATE_STREAMING; mService.messageFromNative(create_event); + } + + @Test + public void testInCallDrivenBroadcastSwitch() { + int groupId = 1; + int broadcastId = 243; + byte[] code = {0x00, 0x01, 0x00, 0x02}; + + prepareHandoverStreamingBroadcast(groupId, broadcastId, code); /* Imitate setting device in call */ mService.setInCall(true); @@ -782,13 +914,21 @@ public class LeAudioBroadcastServiceTest { verify(mLeAudioNativeInterface, times(1)).setInCall(eq(true)); - create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); + LeAudioStackEvent create_event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); create_event.valueInt1 = groupId; create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_ACTIVE; mService.messageFromNative(create_event); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(mDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(mBroadcastDevice), any(BluetoothProfileConnectionInfo.class)); + /* Active group should become the one that was active before broadcasting */ - activeGroup = mService.getActiveGroupId(); + int activeGroup = mService.getActiveGroupId(); Assert.assertEquals(activeGroup, groupId); /* Imitate setting device not in call */ @@ -802,6 +942,14 @@ public class LeAudioBroadcastServiceTest { create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_INACTIVE; mService.messageFromNative(create_event); + /* Only one Unicast device should become inactive due to Sink monitor mode */ + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(mDevice), any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + /* Verify if broadcast is auto-started on start */ verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId)); } @@ -812,82 +960,14 @@ public class LeAudioBroadcastServiceTest { int broadcastId = 243; byte[] code = {0x00, 0x01, 0x00, 0x02}; - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, true); - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, true); - - mService.mBroadcastCallbacks.register(mCallbacks); - - prepareConnectedUnicastDevice(groupId); - - LeAudioStackEvent create_event = - new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); - create_event.valueInt1 = groupId; - create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_ACTIVE; - mService.messageFromNative(create_event); - - /* Prepare create broadcast */ - BluetoothLeAudioContentMetadata.Builder meta_builder = - new BluetoothLeAudioContentMetadata.Builder(); - meta_builder.setLanguage("ENG"); - meta_builder.setProgramInfo("Public broadcast info"); - BluetoothLeAudioContentMetadata meta = meta_builder.build(); - - BluetoothLeBroadcastSettings settings = buildBroadcastSettingsFromMetadata(meta, code, 1); - mService.createBroadcast(settings); - - /* Active group should become inactive */ - int activeGroup = mService.getActiveGroupId(); - Assert.assertEquals(activeGroup, LE_AUDIO_GROUP_ID_INVALID); - - /* Imitate group inactivity to cause create broadcast */ - create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); - create_event.valueInt1 = groupId; - create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_INACTIVE; - mService.messageFromNative(create_event); - - List settingsList = settings.getSubgroupSettings(); - - int[] expectedQualityArray = - settingsList.stream().mapToInt(setting -> setting.getPreferredQuality()).toArray(); - byte[][] expectedDataArray = - settingsList.stream() - .map(setting -> setting.getContentMetadata().getRawMetadata()) - .toArray(byte[][]::new); - - verify(mLeAudioBroadcasterNativeInterface, times(1)) - .createBroadcast( - eq(true), - eq(TEST_BROADCAST_NAME), - eq(settings.getBroadcastCode()), - eq(settings.getPublicBroadcastMetadata().getRawMetadata()), - eq(expectedQualityArray), - eq(expectedDataArray)); - verify(mLeAudioNativeInterface, times(1)) - .setUnicastMonitorMode(eq(LeAudioStackEvent.DIRECTION_SINK),eq(true)); - - activeGroup = mService.getActiveGroupId(); - Assert.assertEquals(LE_AUDIO_GROUP_ID_INVALID, activeGroup); - - /* Check if broadcast is started automatically when created */ - create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_CREATED); - create_event.valueInt1 = broadcastId; - create_event.valueBool1 = true; - mService.messageFromNative(create_event); - - /* Verify if broadcast is auto-started on start */ - verify(mLeAudioBroadcasterNativeInterface, times(1)).startBroadcast(eq(broadcastId)); - - /* Switch to active streaming */ - create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE); - create_event.valueInt1 = broadcastId; - create_event.valueInt2 = LeAudioStackEvent.BROADCAST_STATE_STREAMING; - mService.messageFromNative(create_event); + prepareHandoverStreamingBroadcast(groupId, broadcastId, code); /* Verify if broadcast is auto-started on start */ verify(mLeAudioBroadcasterNativeInterface, times(1)).startBroadcast(eq(broadcastId)); /* Imitate group change request by Bluetooth Sink HAL resume request */ - create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS); + LeAudioStackEvent create_event = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS); create_event.valueInt1 = LeAudioStackEvent.DIRECTION_SINK; create_event.valueInt2 = LeAudioStackEvent.STATUS_LOCAL_STREAM_REQUESTED; mService.messageFromNative(create_event); @@ -906,8 +986,15 @@ public class LeAudioBroadcastServiceTest { create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_ACTIVE; mService.messageFromNative(create_event); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(mDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(mBroadcastDevice), any(BluetoothProfileConnectionInfo.class)); + /* Active group should become the one that was active before broadcasting */ - activeGroup = mService.getActiveGroupId(); + int activeGroup = mService.getActiveGroupId(); Assert.assertEquals(activeGroup, groupId); /* Imitate group change request by Bluetooth Sink HAL suspend request */ @@ -924,6 +1011,14 @@ public class LeAudioBroadcastServiceTest { create_event.valueInt2 = LeAudioStackEvent.GROUP_STATUS_INACTIVE; mService.messageFromNative(create_event); + /* Only one Unicast device should become inactive due to Sink monitor mode */ + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(null), eq(mDevice), any(BluetoothProfileConnectionInfo.class)); + verify(mAudioManager, times(1)) + .handleBluetoothActiveDeviceChanged( + eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class)); + /* Verify if broadcast is auto-started on start */ verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId)); } @@ -949,7 +1044,8 @@ public class LeAudioBroadcastServiceTest { BluetoothLeBroadcastSubgroupSettings.Builder subgroupBuilder = new BluetoothLeBroadcastSubgroupSettings.Builder() - .setContentMetadata(contentMetadata); + .setContentMetadata(contentMetadata) + .setPreferredQuality(BluetoothLeBroadcastSubgroupSettings.QUALITY_HIGH); BluetoothLeBroadcastSettings.Builder builder = new BluetoothLeBroadcastSettings.Builder() .setPublicBroadcast(true) @@ -963,4 +1059,30 @@ public class LeAudioBroadcastServiceTest { } return builder.build(); } + + private void injectGroupCurrentCodecConfigChanged( + int groupId, + BluetoothLeAudioCodecConfig inputCodecConfig, + BluetoothLeAudioCodecConfig outputCodecConfig) { + int eventType = LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED; + + LeAudioStackEvent groupCodecConfigChangedEvent = new LeAudioStackEvent(eventType); + groupCodecConfigChangedEvent.valueInt1 = groupId; + groupCodecConfigChangedEvent.valueCodec1 = inputCodecConfig; + groupCodecConfigChangedEvent.valueCodec2 = outputCodecConfig; + mService.messageFromNative(groupCodecConfigChangedEvent); + } + + private void injectGroupSelectableCodecConfigChanged( + int groupId, + List inputSelectableCodecConfig, + List outputSelectableCodecConfig) { + int eventType = LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED; + + LeAudioStackEvent groupCodecConfigChangedEvent = new LeAudioStackEvent(eventType); + groupCodecConfigChangedEvent.valueInt1 = groupId; + groupCodecConfigChangedEvent.valueCodecList1 = inputSelectableCodecConfig; + groupCodecConfigChangedEvent.valueCodecList2 = outputSelectableCodecConfig; + mService.messageFromNative(groupCodecConfigChangedEvent); + } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java index d1cfb5de25d8503eea29b837d23549ec5b21a1aa..30bb834a44ad4da722dd305e1417f89497565b53 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java @@ -22,7 +22,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -49,11 +48,13 @@ import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; import android.media.BluetoothProfileConnectionInfo; +import android.os.Handler; +import android.os.Looper; import android.os.ParcelUuid; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; -import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; @@ -62,7 +63,6 @@ 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.flags.FakeFeatureFlagsImpl; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hap.HapClientService; import com.android.bluetooth.hfp.HeadsetService; @@ -87,6 +87,7 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeoutException; +import java.util.concurrent.FutureTask; @MediumTest @RunWith(AndroidJUnit4.class) @@ -97,6 +98,8 @@ public class LeAudioServiceTest { private static final int MAX_LE_AUDIO_CONNECTIONS = 5; private static final int LE_AUDIO_GROUP_ID_INVALID = -1; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private BluetoothAdapter mAdapter; private Context mTargetContext; private LeAudioService mService; @@ -109,9 +112,9 @@ public class LeAudioServiceTest { private LinkedBlockingQueue mGroupIntentQueue = new LinkedBlockingQueue<>(); private int testGroupId = 1; private boolean onGroupStatusCallbackCalled = false; + private boolean onGroupStreamStatusCallbackCalled = false; private boolean onGroupCodecConfChangedCallbackCalled = false; private BluetoothLeAudioCodecStatus testCodecStatus = null; - private FakeFeatureFlagsImpl mFakeFlagsImpl; private BroadcastReceiver mLeAudioIntentReceiver; @@ -129,8 +132,6 @@ public class LeAudioServiceTest { @Spy private LeAudioObjectsFactory mObjectsFactory = LeAudioObjectsFactory.getInstance(); @Spy private ServiceFactory mServiceFactory = new ServiceFactory(); - @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); - private static final BluetoothLeAudioCodecConfig LC3_16KHZ_CONFIG = new BluetoothLeAudioCodecConfig.Builder() .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) @@ -185,7 +186,6 @@ public class LeAudioServiceTest { .getRemoteUuids(any(BluetoothDevice.class)); doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager(); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); BluetoothManager manager = mTargetContext.getSystemService(BluetoothManager.class); assertThat(manager).isNotNull(); @@ -197,12 +197,6 @@ public class LeAudioServiceTest { LeAudioNativeInterface.setInstance(mNativeInterface); startService(); - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_UNICAST_INACTIVATE_DEVICE_BASED_ON_CONTEXT, false); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, false); - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false); - mService.setFeatureFlags(mFakeFlagsImpl); - mService.mAudioManager = mAudioManager; mService.mMcpService = mMcpService; mService.mTbsService = mTbsService; @@ -271,14 +265,20 @@ public class LeAudioServiceTest { LeAudioNativeInterface.setInstance(null); } - private void startService() throws TimeoutException { - TestUtils.startService(mServiceRule, LeAudioService.class); - mService = LeAudioService.getLeAudioService(); - assertThat(mService).isNotNull(); + private void startService() throws Exception { + mService = new LeAudioService(mTargetContext); + // LeAudioService#start post on the main Looper a call to + // LeAudioService#init and expect it to be run after start + // has finished. + // To ensure that we run start on the main looper as well. + mService.setAvailable(true); + FutureTask task = new FutureTask(mService::start, null); + new Handler(Looper.getMainLooper()).post(task); + task.get(); } private void stopService() throws TimeoutException { - TestUtils.stopService(mServiceRule, LeAudioService.class); + mService.stop(); mService = LeAudioService.getLeAudioService(); assertThat(mService).isNull(); } @@ -357,11 +357,7 @@ public class LeAudioServiceTest { // Prepare: connect connectDevice(mLeftDevice); // LeAudio Service is already running: test stop(). Note: must be done on the main thread - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - assertThat(mService.stop()).isTrue(); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop); } /** @@ -369,19 +365,17 @@ public class LeAudioServiceTest { */ @Test public void testStopStartStopService() throws Exception { - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - assertThat(mService.stop()).isTrue(); - assertThat(mService.start()).isTrue(); - assertThat(mService.stop()).isTrue(); - assertThat(mService.start()).isTrue(); - } - }); + InstrumentationRegistry.getInstrumentation() + .runOnMainSync( + () -> { + mService.stop(); + mService.start(); + mService.stop(); + mService.start(); + }); } - /** - * Test get/set priority for BluetoothDevice - */ + /** Test get/set priority for BluetoothDevice */ @Test public void testGetSetPriority() { when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) @@ -808,6 +802,144 @@ public class LeAudioServiceTest { assertThat(mService.getDevices().contains(mLeftDevice)).isFalse(); } + /** Test that authorization info is removed from TBS and MCS after the device is unbond. */ + @Test + public void testAuthorizationInfoRemovedFromTbsMcsOnUnbondEvents() { + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_MCS_TBS_AUTHORIZATION_REBOND_FIX); + + // Update the device priority so okToConnect() returns true + when(mDatabaseManager.getProfileConnectionPolicy(mLeftDevice, BluetoothProfile.LE_AUDIO)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + when(mDatabaseManager.getProfileConnectionPolicy(mRightDevice, BluetoothProfile.LE_AUDIO)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + when(mDatabaseManager.getProfileConnectionPolicy(mSingleDevice, BluetoothProfile.LE_AUDIO)) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN); + doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + doReturn(true).when(mNativeInterface).disconnectLeAudio(any(BluetoothDevice.class)); + + // Create device descriptor with connect request + assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); + + // Unbond received in CONNECTION_STATE_CONNECTING state + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); + + // Device unbond + doReturn(BluetoothDevice.BOND_NONE) + .when(mAdapterService) + .getBondState(any(BluetoothDevice.class)); + mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); + + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_CONNECTING); + verify(mTbsService, times(1)).removeDeviceAuthorizationInfo(mLeftDevice); + verify(mMcpService, times(1)).removeDeviceAuthorizationInfo(mLeftDevice); + + reset(mTbsService); + reset(mMcpService); + + assertThat(mService.getDevices().contains(mLeftDevice)).isFalse(); + + // Unbond received in CONNECTION_STATE_CONNECTED + // Create device descriptor with connect request. To connect service, + // device needs to be bonded + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) + .getBondState(any(BluetoothDevice.class)); + assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); + + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + + assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); + + // Device unbond + doReturn(BluetoothDevice.BOND_NONE) + .when(mAdapterService) + .getBondState(any(BluetoothDevice.class)); + mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); + + assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); + verifyConnectionStateIntent( + TIMEOUT_MS, + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTING, + BluetoothProfile.STATE_CONNECTED); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_DISCONNECTING); + assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); + verify(mTbsService, times(0)).removeDeviceAuthorizationInfo(mLeftDevice); + verify(mMcpService, times(0)).removeDeviceAuthorizationInfo(mLeftDevice); + + reset(mTbsService); + reset(mMcpService); + + // Inject CONNECTION_STATE_DISCONNECTED + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_DISCONNECTED, + BluetoothProfile.STATE_DISCONNECTING); + + verify(mTbsService, times(1)).removeDeviceAuthorizationInfo(mLeftDevice); + verify(mMcpService, times(1)).removeDeviceAuthorizationInfo(mLeftDevice); + + reset(mTbsService); + reset(mMcpService); + + // Unbond received in CONNECTION_STATE_DISCONNECTED + // Create device descriptor with connect request. To connect service, + // device needs to be bonded + doReturn(BluetoothDevice.BOND_BONDED) + .when(mAdapterService) + .getBondState(any(BluetoothDevice.class)); + assertWithMessage("Connect failed").that(mService.connect(mLeftDevice)).isTrue(); + + generateConnectionMessageFromNative( + mLeftDevice, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTED); + generateConnectionMessageFromNative( + mLeftDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); + assertThat(mService.getConnectionState(mLeftDevice)) + .isEqualTo(BluetoothProfile.STATE_CONNECTED); + + injectAndVerifyDeviceDisconnected(mLeftDevice); + assertThat(mService.getDevices().contains(mLeftDevice)).isTrue(); + + verify(mTbsService, times(0)).removeDeviceAuthorizationInfo(mLeftDevice); + verify(mMcpService, times(0)).removeDeviceAuthorizationInfo(mLeftDevice); + + reset(mTbsService); + reset(mMcpService); + + // Device unbond + mService.bondStateChanged(mLeftDevice, BluetoothDevice.BOND_NONE); + + verify(mTbsService, times(1)).removeDeviceAuthorizationInfo(mLeftDevice); + verify(mMcpService, times(1)).removeDeviceAuthorizationInfo(mLeftDevice); + } + + @Test + public void testAuthorizationInfoRemovedFromTbsMcsOnUnbondEventsWithSynchBlockFixFlag() { + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_API_SYNCHRONIZED_BLOCK_FIX); + + testAuthorizationInfoRemovedFromTbsMcsOnUnbondEvents(); + } /** * Test that a CONNECTION_STATE_DISCONNECTED Le Audio stack event will remove the state * machine only if the device is unbond. @@ -1374,6 +1506,49 @@ public class LeAudioServiceTest { verify(mTbsService, times(0)).clearInbandRingtoneSupport(mSingleDevice); } + /** Test update unicast fallback active group when broadcast is ongoing */ + @Test + public void testUpdateUnicastFallbackActiveDeviceGroupDuringBroadcast() { + int groupId = 1; + int preGroupId = 2; + /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */ + int direction = 1; + int snkAudioLocation = 3; + int srcAudioLocation = 4; + int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; + + // Not connected device + assertThat(mService.setActiveDevice(mSingleDevice)).isFalse(); + + // Connected device + doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + connectTestDevice(mSingleDevice, testGroupId); + + mService.mUnicastGroupIdDeactivatedForBroadcastTransition = preGroupId; + // mock create broadcast and currentlyActiveGroupId remains LE_AUDIO_GROUP_ID_INVALID + LeAudioStackEvent broadcastCreatedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_CREATED); + broadcastCreatedEvent.device = mSingleDevice; + broadcastCreatedEvent.valueInt1 = 1; + broadcastCreatedEvent.valueBool1 = true; + mService.messageFromNative(broadcastCreatedEvent); + + LeAudioStackEvent audioConfChangedEvent = + new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); + audioConfChangedEvent.device = mSingleDevice; + audioConfChangedEvent.valueInt1 = direction; + audioConfChangedEvent.valueInt2 = groupId; + audioConfChangedEvent.valueInt3 = snkAudioLocation; + audioConfChangedEvent.valueInt4 = srcAudioLocation; + audioConfChangedEvent.valueInt5 = availableContexts; + mService.messageFromNative(audioConfChangedEvent); + + // Verify only update the fallback group and not proceed to change active + assertThat(mService.setActiveDevice(mSingleDevice)).isTrue(); + assertThat(mService.mUnicastGroupIdDeactivatedForBroadcastTransition).isEqualTo(groupId); + verify(mNativeInterface, times(0)).groupSetActive(anyInt()); + } + /** * Test getting active device */ @@ -1442,6 +1617,14 @@ public class LeAudioServiceTest { mService.messageFromNative(groupStatusChangedEvent); } + private void injectGroupStreamStatusChange(int groupId, int groupStreamStatus) { + int eventType = LeAudioStackEvent.EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED; + LeAudioStackEvent groupStreamStatusChangedEvent = new LeAudioStackEvent(eventType); + groupStreamStatusChangedEvent.valueInt1 = groupId; + groupStreamStatusChangedEvent.valueInt2 = groupStreamStatus; + mService.messageFromNative(groupStreamStatusChangedEvent); + } + private void injectAudioConfChanged(int groupId, Integer availableContexts, int direction) { int snkAudioLocation = 3; int srcAudioLocation = 4; @@ -1548,8 +1731,8 @@ public class LeAudioServiceTest { @Test public void testMediaContextUnavailableForAWhile() { - mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_UNICAST_INACTIVATE_DEVICE_BASED_ON_CONTEXT, true); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, true); + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_UNICAST_INACTIVATE_DEVICE_BASED_ON_CONTEXT); + mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); @@ -1588,20 +1771,26 @@ public class LeAudioServiceTest { onGroupStatusCallbackCalled = false; IBluetoothLeAudioCallback leAudioCallbacks = - new IBluetoothLeAudioCallback.Stub() { - @Override - public void onCodecConfigChanged(int gid, BluetoothLeAudioCodecStatus status) {} - @Override - public void onGroupStatusChanged(int gid, int gStatus) { - onGroupStatusCallbackCalled = true; - assertThat(gid == groupId).isTrue(); - assertThat(gStatus == groupStatus).isTrue(); - } - @Override - public void onGroupNodeAdded(BluetoothDevice device, int gid) {} - @Override - public void onGroupNodeRemoved(BluetoothDevice device, int gid) {} - }; + new IBluetoothLeAudioCallback.Stub() { + @Override + public void onCodecConfigChanged(int gid, BluetoothLeAudioCodecStatus status) {} + + @Override + public void onGroupStatusChanged(int gid, int gStatus) { + onGroupStatusCallbackCalled = true; + assertThat(gid == groupId).isTrue(); + assertThat(gStatus == groupStatus).isTrue(); + } + + @Override + public void onGroupNodeAdded(BluetoothDevice device, int gid) {} + + @Override + public void onGroupNodeRemoved(BluetoothDevice device, int gid) {} + + @Override + public void onGroupStreamStatusChanged(int groupId, int groupStreamStatus) {} + }; mService.mLeAudioCallbacks.register(leAudioCallbacks); @@ -1629,6 +1818,60 @@ public class LeAudioServiceTest { sendEventAndVerifyIntentForGroupStatusChanged(testGroupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE); } + private void sendEventAndVerifyGroupStreamStatusChanged(int groupId, int groupStreamStatus) { + + onGroupStreamStatusCallbackCalled = false; + + IBluetoothLeAudioCallback leAudioCallbacks = + new IBluetoothLeAudioCallback.Stub() { + @Override + public void onCodecConfigChanged(int gid, BluetoothLeAudioCodecStatus status) {} + + @Override + public void onGroupStatusChanged(int gid, int gStatus) {} + + @Override + public void onGroupNodeAdded(BluetoothDevice device, int gid) {} + + @Override + public void onGroupNodeRemoved(BluetoothDevice device, int gid) {} + + @Override + public void onGroupStreamStatusChanged(int gid, int gStreamStatus) { + onGroupStreamStatusCallbackCalled = true; + assertThat(gid == groupId).isTrue(); + assertThat(gStreamStatus == groupStreamStatus).isTrue(); + } + }; + + mService.mLeAudioCallbacks.register(leAudioCallbacks); + + injectGroupStreamStatusChange(groupId, groupStreamStatus); + + TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper()); + assertThat(onGroupStreamStatusCallbackCalled).isTrue(); + + onGroupStreamStatusCallbackCalled = false; + mService.mLeAudioCallbacks.unregister(leAudioCallbacks); + } + + /** Test native interface group stream status message handling */ + @Test + public void testMessageFromNativeGroupStreamStatusChanged() { + doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); + connectTestDevice(mSingleDevice, testGroupId); + + injectAudioConfChanged( + testGroupId, + BluetoothLeAudio.CONTEXT_TYPE_MEDIA | BluetoothLeAudio.CONTEXT_TYPE_CONVERSATIONAL, + 3); + + sendEventAndVerifyGroupStreamStatusChanged( + testGroupId, LeAudioStackEvent.GROUP_STREAM_STATUS_IDLE); + sendEventAndVerifyGroupStreamStatusChanged( + testGroupId, LeAudioStackEvent.GROUP_STREAM_STATUS_STREAMING); + } + private void injectLocalCodecConfigCapaChanged(List inputCodecCapa, List outputCodecCapa) { int eventType = LeAudioStackEvent.EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED; @@ -1686,19 +1929,25 @@ public class LeAudioServiceTest { OUTPUT_SELECTABLE_CONFIG); IBluetoothLeAudioCallback leAudioCallbacks = - new IBluetoothLeAudioCallback.Stub() { - @Override - public void onCodecConfigChanged(int gid, BluetoothLeAudioCodecStatus status) { - onGroupCodecConfChangedCallbackCalled = true; - assertThat(status.equals(testCodecStatus)).isTrue(); - } - @Override - public void onGroupStatusChanged(int gid, int gStatus) {} - @Override - public void onGroupNodeAdded(BluetoothDevice device, int gid) {} - @Override - public void onGroupNodeRemoved(BluetoothDevice device, int gid) {} - }; + new IBluetoothLeAudioCallback.Stub() { + @Override + public void onCodecConfigChanged(int gid, BluetoothLeAudioCodecStatus status) { + onGroupCodecConfChangedCallbackCalled = true; + assertThat(status.equals(testCodecStatus)).isTrue(); + } + + @Override + public void onGroupStatusChanged(int gid, int gStatus) {} + + @Override + public void onGroupNodeAdded(BluetoothDevice device, int gid) {} + + @Override + public void onGroupNodeRemoved(BluetoothDevice device, int gid) {} + + @Override + public void onGroupStreamStatusChanged(int groupId, int groupStreamStatus) {} + }; mService.mLeAudioCallbacks.register(leAudioCallbacks); diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java index baee9ab3bb3ce6018966d6501e8566e7e330a3c1..d372c172fd4bc9125b9150f4f36fb3244177c45c 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java @@ -42,8 +42,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; -import com.android.bluetooth.flags.FakeFeatureFlagsImpl; -import com.android.bluetooth.flags.Flags; import org.junit.After; import org.junit.Before; @@ -60,7 +58,6 @@ public class LeAudioStateMachineTest { private HandlerThread mHandlerThread; private LeAudioStateMachine mLeAudioStateMachine; private BluetoothDevice mTestDevice; - private FakeFeatureFlagsImpl mFakeFlagsImpl; private static final int TIMEOUT_MS = 1000; @Mock private AdapterService mAdapterService; @@ -75,8 +72,6 @@ public class LeAudioStateMachineTest { TestUtils.setAdapterService(mAdapterService); mAdapter = BluetoothAdapter.getDefaultAdapter(); - mFakeFlagsImpl = new FakeFeatureFlagsImpl(); - mFakeFlagsImpl.setFlag(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION, false); // Get a device for testing mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); @@ -91,8 +86,7 @@ public class LeAudioStateMachineTest { mTestDevice, mLeAudioService, mLeAudioNativeInterface, - mHandlerThread.getLooper(), - mFakeFlagsImpl); + mHandlerThread.getLooper()); } @After diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java similarity index 96% rename from android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java rename to android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java index 347ee7d93be6ad6ef2fc182ea112003e96512652..4f0b434cac6d8181396adf7cc62b40cfc7b4a9d3 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/AppScanStatsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import static com.google.common.truth.Truth.assertThat; @@ -32,6 +32,8 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.gatt.ContextMap; +import com.android.bluetooth.gatt.GattService; import com.android.internal.app.IBatteryStats; import org.junit.After; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/PeriodicScanManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java similarity index 99% rename from android/app/tests/unit/src/com/android/bluetooth/gatt/PeriodicScanManagerTest.java rename to android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java index e6ae7da2c085c26eac1ad77360e298120af37e0c..61517270c30c654d3cce63e84d79e09c61b90bd0 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/PeriodicScanManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/PeriodicScanManagerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import static com.google.common.truth.Truth.assertThat; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanFilterQueueTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java similarity index 99% rename from android/app/tests/unit/src/com/android/bluetooth/gatt/ScanFilterQueueTest.java rename to android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java index e272a8d85e5937f1dfca54c6d52311ac0db1aae6..973ae19496491ee77158df97506526794ad11e5f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanFilterQueueTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanFilterQueueTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import static com.google.common.truth.Truth.assertThat; diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java similarity index 92% rename from android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java rename to android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java index 558499eed138b78819a1c115d902919ce6ab518e..97dfb0326f3c5d23c58022f7c77aa2dac48b0ff9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/ScanManagerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.bluetooth.gatt; +package com.android.bluetooth.le_scan; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES_AUTO_BATCH; import static android.bluetooth.le.ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY; @@ -34,6 +34,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -53,6 +54,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.test.TestLooper; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; @@ -68,6 +70,10 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.BluetoothAdapterProxy; import com.android.bluetooth.btservice.MetricsLogger; +import com.android.bluetooth.flags.Flags; +import com.android.bluetooth.gatt.GattNativeInterface; +import com.android.bluetooth.gatt.GattObjectsFactory; +import com.android.bluetooth.gatt.GattService; import com.android.internal.app.IBatteryStats; import org.junit.After; @@ -95,7 +101,7 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class ScanManagerTest { private static final String TAG = ScanManagerTest.class.getSimpleName(); - private static final int DELAY_ASYNC_MS = 40; + private static final int DELAY_ASYNC_MS = 50; private static final int DELAY_DEFAULT_SCAN_TIMEOUT_MS = 1500000; private static final int DELAY_SCAN_TIMEOUT_MS = 100; private static final int DEFAULT_SCAN_REPORT_DELAY_MS = 100; @@ -117,6 +123,8 @@ public class ScanManagerTest { new BatteryStatsManager(mock(IBatteryStats.class)); @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Mock private AdapterService mAdapterService; @Mock private GattService mMockGattService; @Mock private BluetoothAdapterProxy mBluetoothAdapterProxy; @@ -125,6 +133,7 @@ public class ScanManagerTest { @Mock private GattNativeInterface mNativeInterface; @Mock private ScanNativeInterface mScanNativeInterface; @Mock private MetricsLogger mMetricsLogger; + private AppScanStats mMockAppScanStats; private MockContentResolver mMockContentResolver; @Captor ArgumentCaptor mScanDurationCaptor; @@ -199,6 +208,7 @@ public class ScanManagerTest { assertThat(mLatch).isNotNull(); mScanReportDelay = DEFAULT_SCAN_REPORT_DELAY_MS; + mMockAppScanStats = spy(new AppScanStats("Test", null, null, mMockGattService)); } @After @@ -240,7 +250,7 @@ public class ScanManagerTest { ScanSettings scanSettings = createScanSettings(scanMode, isBatch, isAutoBatch); ScanClient client = new ScanClient(id, scanSettings, scanFilterList); - client.stats = new AppScanStats("Test", null, null, mMockGattService); + client.stats = mMockAppScanStats; client.stats.recordScanStart(scanSettings, scanFilterList, isFiltered, false, id); return client; } @@ -572,6 +582,7 @@ public class ScanManagerTest { assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); // Wait for scan timeout testSleep(DELAY_SCAN_TIMEOUT_MS + DELAY_ASYNC_MS); + TestUtils.waitForLooperToFinishScheduledTask(mHandler.getLooper()); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); assertThat(client.stats.isScanTimeout(client.scannerId)).isTrue(); // Turn off screen @@ -580,7 +591,7 @@ public class ScanManagerTest { // Turn on screen sendMessageWaitForProcessed(createScreenOnOffMessage(true)); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); - // Set as backgournd app + // Set as background app sendMessageWaitForProcessed(createImportanceMessage(false)); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); // Set as foreground app @@ -591,6 +602,7 @@ public class ScanManagerTest { @Test public void testFilteredScanTimeout() { + mTestLooper.stopAutoDispatchAndIgnoreExceptions(); // Set filtered scan flag final boolean isFiltered = true; // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} @@ -609,31 +621,77 @@ public class ScanManagerTest { + " expectedScanMode: " + String.valueOf(expectedScanMode)); // Turn on screen - sendMessageWaitForProcessed(createScreenOnOffMessage(true)); + mHandler.sendMessage(createScreenOnOffMessage(true)); + mTestLooper.dispatchAll(); // Create scan client ScanClient client = createScanClient(i, isFiltered, ScanMode); - // Start scan - sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); + // Start scan, this sends scan timeout message with delay of DELAY_SCAN_TIMEOUT_MS + mHandler.sendMessage(createStartStopScanMessage(true, client)); + mTestLooper.dispatchAll(); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); - // Wait for scan timeout - testSleep(DELAY_SCAN_TIMEOUT_MS + DELAY_ASYNC_MS); + // Move time forward so scan timeout message can be dispatched + mTestLooper.moveTimeForward(DELAY_SCAN_TIMEOUT_MS + 1); + // We can check that MSG_SCAN_TIMEOUT is in the message queue + assertThat(mHandler.hasMessages(ScanManager.MSG_SCAN_TIMEOUT)).isTrue(); + // Since we are using a TestLooper, need to mock AppScanStats.isScanningTooLong to + // return true because no real time is elapsed + doReturn(true).when(mMockAppScanStats).isScanningTooLong(); + mTestLooper.dispatchAll(); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); assertThat(client.stats.isScanTimeout(client.scannerId)).isTrue(); // Turn off screen - sendMessageWaitForProcessed(createScreenOnOffMessage(false)); + mHandler.sendMessage(createScreenOnOffMessage(false)); + mTestLooper.dispatchAll(); assertThat(client.settings.getScanMode()).isEqualTo(SCAN_MODE_SCREEN_OFF); // Set as background app - sendMessageWaitForProcessed(createImportanceMessage(false)); + mHandler.sendMessage(createImportanceMessage(false)); + mTestLooper.dispatchAll(); assertThat(client.settings.getScanMode()).isEqualTo(SCAN_MODE_SCREEN_OFF); // Turn on screen - sendMessageWaitForProcessed(createScreenOnOffMessage(true)); + mHandler.sendMessage(createScreenOnOffMessage(true)); + mTestLooper.dispatchAll(); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); // Set as foreground app - sendMessageWaitForProcessed(createImportanceMessage(true)); + mHandler.sendMessage(createImportanceMessage(true)); + mTestLooper.dispatchAll(); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); } } + @Test + public void testScanTimeoutResetForNewScan() { + mSetFlagsRule.enableFlags(Flags.FLAG_SCAN_TIMEOUT_RESET); + + mTestLooper.stopAutoDispatchAndIgnoreExceptions(); + // Set filtered scan flag + final boolean isFiltered = false; + when(mAdapterService.getScanTimeoutMillis()).thenReturn((long) DELAY_SCAN_TIMEOUT_MS); + // Turn on screen + mHandler.sendMessage(createScreenOnOffMessage(true)); + mTestLooper.dispatchAll(); + // Create scan client + ScanClient client = createScanClient(0, isFiltered, SCAN_MODE_LOW_POWER); + + // Put a timeout message in the queue to emulate the scan being started already + Message timeoutMessage = mHandler.obtainMessage(ScanManager.MSG_SCAN_TIMEOUT, client); + mHandler.sendMessageDelayed(timeoutMessage, DELAY_SCAN_TIMEOUT_MS / 2); + mHandler.sendMessage(createStartStopScanMessage(true, client)); + + // Dispatching all messages only runs start scan + assertThat(mTestLooper.dispatchAll()).isEqualTo(1); + mTestLooper.moveTimeForward(DELAY_SCAN_TIMEOUT_MS / 2); + assertThat(mHandler.hasMessages(ScanManager.MSG_SCAN_TIMEOUT, client)).isTrue(); + + // After restarting the scan, we can check that the initial timeout message is not triggered + assertThat(mTestLooper.dispatchAll()).isEqualTo(0); + + // After timeout, the next message that is run should be a timeout message + mTestLooper.moveTimeForward(DELAY_SCAN_TIMEOUT_MS / 2 + 1); + Message nextMessage = mTestLooper.nextMessage(); + assertThat(nextMessage.what).isEqualTo(ScanManager.MSG_SCAN_TIMEOUT); + assertThat(nextMessage.obj).isEqualTo(client); + } + @Test public void testSwitchForeBackgroundUnfilteredScan() { // Set filtered scan flag @@ -660,7 +718,7 @@ public class ScanManagerTest { assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue(); assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); - // Set as backgournd app + // Set as background app sendMessageWaitForProcessed(createImportanceMessage(false)); assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue(); assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); @@ -699,7 +757,7 @@ public class ScanManagerTest { assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue(); assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); - // Set as backgournd app + // Set as background app sendMessageWaitForProcessed(createImportanceMessage(false)); assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue(); assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); @@ -745,6 +803,7 @@ public class ScanManagerTest { assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); // Wait for upgrade duration testSleep(DELAY_SCAN_UPGRADE_DURATION_MS + DELAY_ASYNC_MS); + TestUtils.waitForLooperToFinishScheduledTask(mHandler.getLooper()); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); } } @@ -789,6 +848,7 @@ public class ScanManagerTest { int max_duration = DELAY_SCAN_UPGRADE_DURATION_MS > DELAY_SCAN_DOWNGRADE_DURATION_MS ? DELAY_SCAN_UPGRADE_DURATION_MS : DELAY_SCAN_DOWNGRADE_DURATION_MS; testSleep(max_duration + DELAY_ASYNC_MS); + TestUtils.waitForLooperToFinishScheduledTask(mHandler.getLooper()); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); } } @@ -829,12 +889,14 @@ public class ScanManagerTest { assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); // Wait for downgrade duration testSleep(DELAY_SCAN_DOWNGRADE_DURATION_MS + DELAY_ASYNC_MS); + TestUtils.waitForLooperToFinishScheduledTask(mHandler.getLooper()); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); } } @Test public void testDowngradeDuringScanForConcurrencyScreenOff() { + mTestLooper.stopAutoDispatchAndIgnoreExceptions(); // Set filtered scan flag final boolean isFiltered = true; // Set scan mode map {original scan mode (ScanMode) : expected scan mode (expectedScanMode)} @@ -854,22 +916,30 @@ public class ScanManagerTest { + " expectedScanMode: " + String.valueOf(expectedScanMode)); // Turn on screen - sendMessageWaitForProcessed(createScreenOnOffMessage(true)); + mHandler.sendMessage(createScreenOnOffMessage(true)); // Set as foreground app - sendMessageWaitForProcessed(createImportanceMessage(true)); + mHandler.sendMessage(createImportanceMessage(true)); + mTestLooper.dispatchAll(); // Create scan client ScanClient client = createScanClient(i, isFiltered, ScanMode); // Start scan - sendMessageWaitForProcessed(createStartStopScanMessage(true, client)); + mHandler.sendMessage(createStartStopScanMessage(true, client)); + mTestLooper.dispatchAll(); assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue(); assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); assertThat(client.settings.getScanMode()).isEqualTo(ScanMode); // Set connecting state - sendMessageWaitForProcessed(createConnectingMessage(true)); + mHandler.sendMessage(createConnectingMessage(true)); // Turn off screen - sendMessageWaitForProcessed(createScreenOnOffMessage(false)); - // Wait for downgrade duration - testSleep(DELAY_SCAN_DOWNGRADE_DURATION_MS + DELAY_ASYNC_MS); + mHandler.sendMessage(createScreenOnOffMessage(false)); + // Dispatching all messages doesn't run MSG_STOP_CONNECTING which is sent with delay + // during handling MSG_START_CONNECTING + assertThat(mTestLooper.dispatchAll()).isEqualTo(2); + // Move time forward so that MSG_STOP_CONNECTING can be dispatched + mTestLooper.moveTimeForward(DELAY_SCAN_DOWNGRADE_DURATION_MS + 1); + // We can check that MSG_STOP_CONNECTING is in the message queue + assertThat(mHandler.hasMessages(ScanManager.MSG_STOP_CONNECTING)).isTrue(); + mTestLooper.dispatchAll(); assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue(); assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); @@ -913,6 +983,7 @@ public class ScanManagerTest { sendMessageWaitForProcessed(createImportanceMessage(false)); // Wait for downgrade duration testSleep(DELAY_SCAN_DOWNGRADE_DURATION_MS + DELAY_ASYNC_MS); + TestUtils.waitForLooperToFinishScheduledTask(mHandler.getLooper()); assertThat(mScanManager.getRegularScanQueue().contains(client)).isTrue(); assertThat(mScanManager.getSuspendedScanQueue().contains(client)).isFalse(); assertThat(client.settings.getScanMode()).isEqualTo(expectedScanMode); @@ -1316,8 +1387,8 @@ public class ScanManagerTest { mScanDurationCaptor.capture()); long capturedDuration = mScanDurationCaptor.getValue(); Log.d(TAG, "capturedDuration: " + String.valueOf(capturedDuration)); - assertThat(weightedScanDuration <= capturedDuration - && capturedDuration <= weightedScanDuration + DELAY_ASYNC_MS).isTrue(); + assertThat(capturedDuration).isAtLeast(weightedScanDuration); + assertThat(capturedDuration).isAtMost(weightedScanDuration + DELAY_ASYNC_MS); Mockito.clearInvocations(mMetricsLogger); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java index 621c991bd7e20c0935868bcdca39b9f6e2e4bf28..34105afb67c881b94778594b42a9a5a0b2e91d16 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java @@ -60,14 +60,6 @@ public class BluetoothMapMasInstanceTest { TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); } - @Test - public void constructor_withNoParameters() { - BluetoothMapMasInstance instance = new BluetoothMapMasInstance(); - - assertThat(instance.mTag).isEqualTo( - "BluetoothMapMasInstance" + (BluetoothMapMasInstance.sInstanceCounter - 1)); - } - @Test public void toString_returnsInfo() { BluetoothMapMasInstance instance = new BluetoothMapMasInstance(mMapService, mContext, diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java index 919f38e79f59853a780f6a0af6b288d58a81268f..5989177b8092b2e5df9bac7bf135692b362965e4 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapServiceTest.java @@ -23,7 +23,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.spy; @@ -73,9 +72,9 @@ public class BluetoothMapServiceTest { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mService = new BluetoothMapService(targetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); assertThat(mAdapter).isNotNull(); @@ -84,7 +83,7 @@ public class BluetoothMapServiceTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); mService = BluetoothMapService.getBluetoothMapService(); assertThat(mService).isNull(); TestUtils.clearAdapterService(mAdapterService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java index ccb83411b4f95be62fa6457c45664f2ff86725a3..f57f1bd0b32416cfd2bd60faec0a00bb41db4d2b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSettingsTest.java @@ -25,14 +25,21 @@ import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static com.google.common.truth.Truth.assertThat; + import android.content.ComponentName; import android.content.Context; import android.content.Intent; import androidx.test.core.app.ActivityScenario; +import androidx.test.filters.FlakyTest; import androidx.test.filters.LargeTest; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.UiDevice; +import androidx.test.uiautomator.UiObject2; +import androidx.test.uiautomator.Until; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; @@ -64,15 +71,23 @@ public class BluetoothMapSettingsTest { public void tearDown() throws Exception { TestUtils.tearDownUiTest(); if (mActivityScenario != null) { - // Workaround for b/159805732. Without this, test hangs for 45 seconds. - Thread.sleep(1_000); mActivityScenario.close(); } enableActivity(false); } @Test + @FlakyTest public void initialize() throws Exception { + UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + + long timeoutMs = 5_000; + String activityLabel = mTargetContext.getString(R.string.bluetooth_map_settings_title); + UiObject2 object = device.wait(Until.findObject(By.text(activityLabel)), timeoutMs); + assertThat(object).isNotNull(); + + object.click(); + onView(withId(R.id.bluetooth_map_settings_list_view)).check(matches(isDisplayed())); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java index 8db436104eead5fdbd796528ea69a5e069fc5881..5c735c9d4543aac9f038dcec7181e4609a4dee32 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientContentTest.java @@ -31,7 +31,6 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothMapClient; import android.content.ContentValues; import android.content.Context; -import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -44,7 +43,6 @@ import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; import android.util.Log; -import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; @@ -56,7 +54,6 @@ import com.android.vcard.VCardProperty; import org.junit.After; import org.junit.Assert; -import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -78,7 +75,6 @@ public class MapClientContentTest { private BluetoothAdapter mAdapter; private BluetoothDevice mTestDevice; - private Context mTargetContext; private Handler mHandler; private Bmessage mTestMessage1; @@ -120,17 +116,10 @@ public class MapClientContentTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mTargetContext = InstrumentationRegistry.getTargetContext(); - - // Do not run test if there is no telephony feature (no support for sms) - PackageManager packageManager = mTargetContext.getPackageManager(); - Assume.assumeTrue(packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)); - - mMockSmsContentProvider = Mockito.spy(new FakeContentProvider(mTargetContext)); - - mMockMmsContentProvider = Mockito.spy(new FakeContentProvider(mTargetContext)); - mMockThreadContentProvider = Mockito.spy(new FakeContentProvider(mTargetContext)); + mMockSmsContentProvider = new FakeContentProvider(mMockContext); + mMockMmsContentProvider = new FakeContentProvider(mMockContext); + mMockThreadContentProvider = new FakeContentProvider(mMockContext); mAdapter = BluetoothAdapter.getDefaultAdapter(); mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05"); @@ -473,6 +462,20 @@ public class MapClientContentTest { MapClientContent.clearAllContent(mMockContext); } + /** + * Test verifying dumpsys does not cause Bluetooth to crash (esp since we're querying the + * database to generate dump). + */ + @Test + public void testDumpsysDoesNotCauseCrash() { + testStoreOneSMSOneMMS(); + // mMapClientContent is set in testStoreOneSMSOneMMS + StringBuilder sb = new StringBuilder("Hello world!\n"); + mMapClientContent.dump(sb); + + assertThat(sb.toString()).isNotNull(); + } + void createTestMessages() { mOriginator = new VCardEntry(); VCardProperty property = new VCardProperty(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java index 8b06004f94666e6d5eaad56fe00c76589ba46199..0622a7eba3d614d717d2d09d9cfb3412c38cbb3f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientServiceTest.java @@ -17,7 +17,6 @@ package com.android.bluetooth.mapclient; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; @@ -70,12 +69,13 @@ public class MapClientServiceTest { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mTestLooper = new TestLooper(); - mService = new MapClientService(targetContext, mTestLooper.getLooper()); - mService.doStart(); + MnsService mnsServer = null; + mService = new MapClientService(targetContext, mTestLooper.getLooper(), mnsServer); + mService.start(); + mService.setAvailable(true); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -85,7 +85,8 @@ public class MapClientServiceTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); + mService.cleanup(); mService = MapClientService.getMapClientService(); assertThat(mService).isNull(); TestUtils.clearAdapterService(mAdapterService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java index a2d08e612038da84755bdf5496f07539d7496b75..baadbd75e73d0f8cacf1f28b5e0afcb61abdb68f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java @@ -22,21 +22,27 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; +import android.app.Activity; import android.app.BroadcastOptions; +import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothMapClient; import android.bluetooth.BluetoothProfile; import android.bluetooth.SdpMasRecord; +import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Telephony.Sms; +import android.telephony.SmsManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.test.mock.MockContentProvider; @@ -51,6 +57,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.storage.DatabaseManager; +import com.android.bluetooth.flags.Flags; import com.android.obex.HeaderSet; import com.android.vcard.VCardConstants; import com.android.vcard.VCardEntry; @@ -74,17 +81,24 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; @MediumTest @RunWith(AndroidJUnit4.class) public class MapClientStateMachineTest { private static final String TAG = "MapStateMachineTest"; + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private static final String FOLDER_SENT = "sent"; private static final int ASYNC_CALL_TIMEOUT_MILLIS = 100; private static final int DISCONNECT_TIMEOUT = 3000; + private static final long PENDING_INTENT_TIMEOUT_MS = 3_000; + private Bmessage mTestIncomingSmsBmessage; private Bmessage mTestIncomingMmsBmessage; private String mTestMessageSmsHandle = "0001"; @@ -95,6 +109,12 @@ public class MapClientStateMachineTest { private static final boolean MESSAGE_SEEN = true; private static final boolean MESSAGE_NOT_SEEN = false; + private static final String TEST_MESSAGE_HANDLE = "0123456789000032"; + private static final String TEST_MESSAGE = "Hello World!"; + private static final String SENT_PATH = "telecom/msg/sent"; + private static final Uri[] TEST_CONTACTS_ONE_PHONENUM = new Uri[] {Uri.parse("tel://5551234")}; + private static final String TEST_DATETIME = "19991231T235959"; + private VCardEntry mOriginator; @Rule @@ -143,6 +163,42 @@ public class MapClientStateMachineTest { MapClientStateMachineTest::getFolderNameFromRequestGetMessagesListing, "has folder name of"); + private static final String ACTION_MESSAGE_SENT = + "com.android.bluetooth.mapclient.MapClientStateMachineTest.action.MESSAGE_SENT"; + private static final String ACTION_MESSAGE_DELIVERED = + "com.android.bluetooth.mapclient.MapClientStateMachineTest.action.MESSAGE_DELIVERED"; + + private SentDeliveryReceiver mSentDeliveryReceiver; + + private static class SentDeliveryReceiver extends BroadcastReceiver { + private CountDownLatch mActionReceivedLatch; + + SentDeliveryReceiver() { + mActionReceivedLatch = new CountDownLatch(1); + } + + @Override + public void onReceive(Context context, Intent intent) { + Log.i(TAG, "onReceive: Action=" + intent.getAction()); + if (ACTION_MESSAGE_SENT.equals(intent.getAction()) + || ACTION_MESSAGE_DELIVERED.equals(intent.getAction())) { + mActionReceivedLatch.countDown(); + } else { + Log.i(TAG, "unhandled action."); + } + } + + public boolean isActionReceived(long timeout) { + boolean result = false; + try { + result = mActionReceivedLatch.await(timeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Log.e(TAG, "Latch await", e); + } + return result; + } + } + @Before public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getTargetContext(); @@ -152,8 +208,6 @@ public class MapClientStateMachineTest { mMockContentProvider = new MockSmsContentProvider(); mMockContentResolver = new MockContentResolver(); when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); - TestUtils.startService(mServiceRule, MapClientService.class); mIsMapClientServiceStarted = true; mMockContentResolver.addProvider("sms", mMockContentProvider); mMockContentResolver.addProvider("mms", mMockContentProvider); @@ -197,6 +251,13 @@ public class MapClientStateMachineTest { mMockTelephonyManager); when(mMockTelephonyManager.isSmsCapable()).thenReturn(false); + // Set up receiver for 'Sent' and 'Delivered' PendingIntents + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(ACTION_MESSAGE_DELIVERED); + filter.addAction(ACTION_MESSAGE_SENT); + mSentDeliveryReceiver = new SentDeliveryReceiver(); + mTargetContext.registerReceiver(mSentDeliveryReceiver, filter, Context.RECEIVER_EXPORTED); } @After @@ -205,12 +266,10 @@ public class MapClientStateMachineTest { mMceStateMachine.doQuit(); } - if (mIsMapClientServiceStarted) { - TestUtils.stopService(mServiceRule, MapClientService.class); - } if (mIsAdapterServiceSet) { TestUtils.clearAdapterService(mAdapterService); } + mTargetContext.unregisterReceiver(mSentDeliveryReceiver); } /** @@ -949,6 +1008,194 @@ public class MapClientStateMachineTest { assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_DISCONNECTING); } + /** + * Preconditions: + * - In {@code STATE_CONNECTED}. + * + * Actions: + * - {@link #sendMapMessage} with 'Sent' {@link PendingIntents}. + * - {@link #receiveEvent} of type {@link SENDING_SUCCESS}. + * + * Outcome: + * - SENT_STATUS Intent was broadcast with 'Success' result code. + */ + @Test + public void testSendMapMessageSentPendingIntent_notifyStatusSuccess() { + mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_DELIVERY_SENDING_FAILURE_EVENTS); + testSendMapMessagePendingIntents_base( + ACTION_MESSAGE_SENT, EventReport.Type.SENDING_SUCCESS); + + assertThat(mSentDeliveryReceiver.isActionReceived(PENDING_INTENT_TIMEOUT_MS)).isTrue(); + assertThat(mSentDeliveryReceiver.getResultCode()).isEqualTo(Activity.RESULT_OK); + } + + /** + * Preconditions: + * - In {@code STATE_CONNECTED}. + * + * Actions: + * - {@link #sendMapMessage} with 'Delivery' {@link PendingIntents}. + * - {@link #receiveEvent} of type {@link DELIVERY_SUCCESS}. + * + * Outcome: + * - DELIVERY_STATUS Intent was broadcast with 'Success' result code. + */ + @Test + public void testSendMapMessageDeliveryPendingIntent_notifyStatusSuccess() { + mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_DELIVERY_SENDING_FAILURE_EVENTS); + testSendMapMessagePendingIntents_base( + ACTION_MESSAGE_DELIVERED, EventReport.Type.DELIVERY_SUCCESS); + + assertThat(mSentDeliveryReceiver.isActionReceived(PENDING_INTENT_TIMEOUT_MS)).isTrue(); + assertThat(mSentDeliveryReceiver.getResultCode()).isEqualTo(Activity.RESULT_OK); + } + + /** + * Preconditions: + * - In {@code STATE_CONNECTED}. + * + * Actions: + * - {@link #sendMapMessage} with 'null' {@link PendingIntents}. + * - {@link #receiveEvent} of type {@link SENDING_SUCCESS}. + * - {@link #receiveEvent} of type {@link DELIVERY_SUCCESS}. + * + * Outcome: + * - No Intent was broadcast. + */ + @Test + public void testSendMapMessageNullPendingIntent_noNotifyStatus() { + mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_DELIVERY_SENDING_FAILURE_EVENTS); + testSendMapMessagePendingIntents_base(null, EventReport.Type.SENDING_SUCCESS); + + assertThat(mSentDeliveryReceiver.isActionReceived(PENDING_INTENT_TIMEOUT_MS)).isFalse(); + } + + /** + * Preconditions: + * - In {@code STATE_CONNECTED}. + * + * Actions: + * - {@link #sendMapMessage} with 'Sent' {@link PendingIntents}. + * - {@link #receiveEvent} of type {@link SENDING_FAILURE}. + * + * Outcome: + * - SENT_STATUS Intent was broadcast with 'Failure' result code. + */ + @Test + public void testSendMapMessageSentPendingIntent_notifyStatusFailure() { + mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_DELIVERY_SENDING_FAILURE_EVENTS); + testSendMapMessagePendingIntents_base( + ACTION_MESSAGE_SENT, EventReport.Type.SENDING_FAILURE); + + assertThat(mSentDeliveryReceiver.isActionReceived(PENDING_INTENT_TIMEOUT_MS)).isTrue(); + assertThat(mSentDeliveryReceiver.getResultCode()) + .isEqualTo(SmsManager.RESULT_ERROR_GENERIC_FAILURE); + } + + /** + * Preconditions: + * - In {@code STATE_CONNECTED}. + * + * Actions: + * - {@link #sendMapMessage} with 'Delivery' {@link PendingIntents}. + * - {@link #receiveEvent} of type {@link DELIVERY_FAILURE}. + * + * Outcome: + * - DELIVERY_STATUS Intent was broadcast with 'Failure' result code. + */ + @Test + public void testSendMapMessageDeliveryPendingIntent_notifyStatusFailure() { + mSetFlagsRule.enableFlags(Flags.FLAG_HANDLE_DELIVERY_SENDING_FAILURE_EVENTS); + testSendMapMessagePendingIntents_base( + ACTION_MESSAGE_DELIVERED, EventReport.Type.DELIVERY_FAILURE); + + assertThat(mSentDeliveryReceiver.isActionReceived(PENDING_INTENT_TIMEOUT_MS)).isTrue(); + assertThat(mSentDeliveryReceiver.getResultCode()) + .isEqualTo(SmsManager.RESULT_ERROR_GENERIC_FAILURE); + } + + /** + * @param action corresponding to the {@link PendingIntent} you want to create/register for + * when pushing a MAP message, e.g., for 'Sent' or 'Delivery' status. + * @param type the EventReport type of the new notification, e.g., 'Sent'/'Delivery' + * 'Success'/'Failure'. + */ + private void testSendMapMessagePendingIntents_base(String action, EventReport.Type type) { + transitionToConnected(); + + PendingIntent pendingIntentSent; + PendingIntent pendingIntentDelivered; + if (ACTION_MESSAGE_SENT.equals(action)) { + pendingIntentSent = createPendingIntent(action); + pendingIntentDelivered = null; + } else if (ACTION_MESSAGE_DELIVERED.equals(action)) { + pendingIntentSent = null; + pendingIntentDelivered = createPendingIntent(action); + } else { + pendingIntentSent = null; + pendingIntentDelivered = null; + } + sendMapMessageWithPendingIntents( + pendingIntentSent, pendingIntentDelivered, TEST_MESSAGE_HANDLE); + + receiveSentDeliveryEvent(type, TEST_MESSAGE_HANDLE); + } + + private void transitionToConnected() { + Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); + mMceStateMachine.sendMessage(msg); + TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); + assertThat(mMceStateMachine.getState()).isEqualTo(BluetoothProfile.STATE_CONNECTED); + } + + private PendingIntent createPendingIntent(String action) { + return PendingIntent.getBroadcast( + mTargetContext, 1, new Intent(action), PendingIntent.FLAG_IMMUTABLE); + } + + private void sendMapMessageWithPendingIntents( + PendingIntent pendingIntentSent, + PendingIntent pendingIntentDelivered, + String messageHandle) { + mMceStateMachine.sendMapMessage( + TEST_CONTACTS_ONE_PHONENUM, TEST_MESSAGE, + pendingIntentSent, pendingIntentDelivered); + TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); + + // {@link sendMapMessage} leads to a new {@link RequestPushMessage}, which contains + // a {@link Bmessage} object that is used as a key to a map to retrieve the corresponding + // {@link PendingIntent} that was provided. + // Thus, we need to intercept this Bmessage and inject it back in for + // MSG_MAS_REQUEST_COMPLETED. We also need to spy/mock it in order to inject our + // TEST_MESSAGE_HANDLE (message handles are normally provided by the remote device). + // The message handle injected here needs to match the handle of the SENT/DELIVERY + // SUCCESS/FAILURE events. + + ArgumentCaptor requestCaptor = + ArgumentCaptor.forClass(RequestPushMessage.class); + verify(mMockMasClient, atLeastOnce()).makeRequest(requestCaptor.capture()); + RequestPushMessage spyRequestPushMessage = spy(requestCaptor.getValue()); + when(spyRequestPushMessage.getMsgHandle()).thenReturn(messageHandle); + + Message msgSent = + Message.obtain( + mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, spyRequestPushMessage); + + mMceStateMachine.sendMessage(msgSent); + TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); + } + + private void receiveSentDeliveryEvent(EventReport.Type type, String messageHandle) { + mMceStateMachine.receiveEvent( + createNewEventReport( + type.toString(), + TEST_DATETIME, + messageHandle, + SENT_PATH, + null, + Bmessage.Type.SMS_GSM.toString())); + } + private void setupSdpRecordReceipt() { // Perform first part of MAP connection logic. verify(mMockMapClientService, diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java index c716b3260bf1fefced9a80034da8c0ad2ada8810..ab5f97b95d236506ecfd6970240abed5462cdb46 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientTest.java @@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; +import android.os.Looper; import android.os.UserHandle; import androidx.test.InstrumentationRegistry; @@ -67,18 +68,19 @@ public class MapClientTest { TestUtils.setAdapterService(mAdapterService); mIsAdapterServiceSet = true; when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); - MapUtils.setMnsService(mMockMnsService); mIsMapClientServiceStarted = true; - mService = new MapClientService(mTargetContext); - mService.doStart(); + Looper looper = null; + mService = new MapClientService(mTargetContext, looper, mMockMnsService); + mService.start(); + mService.setAvailable(true); mAdapter = BluetoothAdapter.getDefaultAdapter(); } @After public void tearDown() throws Exception { if (mIsMapClientServiceStarted) { - mService.doStop(); + mService.stop(); + mService.cleanup(); mService = MapClientService.getMapClientService(); Assert.assertNull(mService); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java index 9c6a30756bd993ee16cd448071d5b02617150c11..3ba4decf8f12df4ab4bd9651bfa72e6115da4dc9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mapclient/MessagesFilterTest.java @@ -21,6 +21,8 @@ import static com.google.common.truth.Truth.assertThat; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import java.util.Calendar; + import org.junit.Test; import org.junit.runner.RunWith; @@ -78,4 +80,35 @@ public class MessagesFilterTest { assertThat(filter.recipient).isEqualTo(null); } + /** Test Builder creates and sets everything correctly. */ + @Test + public void testBuilder() { + String originator = "test_originator"; + String recipient = "test_recipient"; + byte messageType = MessagesFilter.MESSAGE_TYPE_EMAIL; + byte readStatus = MessagesFilter.READ_STATUS_READ; + byte priority = MessagesFilter.PRIORITY_HIGH; + Calendar begin = Calendar.getInstance(); + begin.add(Calendar.DATE, -14); + Calendar end = Calendar.getInstance(); + end.add(Calendar.DATE, -7); + + MessagesFilter filter = + new MessagesFilter.Builder() + .setOriginator(originator) + .setRecipient(recipient) + .setMessageType(messageType) + .setReadStatus(readStatus) + .setPriority(priority) + .setPeriod(begin.getTime(), end.getTime()) + .build(); + + assertThat(filter.originator).isEqualTo(originator); + assertThat(filter.recipient).isEqualTo(recipient); + assertThat(filter.messageType).isEqualTo(messageType); + assertThat(filter.readStatus).isEqualTo(readStatus); + assertThat(filter.priority).isEqualTo(priority); + assertThat(filter.periodBegin).isEqualTo((new ObexTime(begin.getTime())).toString()); + assertThat(filter.periodEnd).isEqualTo((new ObexTime(end.getTime())).toString()); + } } 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 4a4d8d8c3a58570c40cb19174ce707bfd164c3a1..5c77c88ba553a96ae277994931edae18fe78640c 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 @@ -65,10 +65,10 @@ public class McpServiceTest { mAdapter = BluetoothAdapter.getDefaultAdapter(); - doReturn(true).when(mAdapterService).isStartedProfile(anyString()); McpService.setMediaControlProfileForTesting(mMediaControlProfile); mMcpService = new McpService(mTargetContext); - mMcpService.doStart(); + mMcpService.start(); + mMcpService.setAvailable(true); } @After @@ -77,8 +77,7 @@ public class McpServiceTest { return; } - doReturn(false).when(mAdapterService).isStartedProfile(anyString()); - mMcpService.doStop(); + mMcpService.stop(); mMcpService = McpService.getMcpService(); Assert.assertNull(mMcpService); reset(mMediaControlProfile); @@ -112,21 +111,13 @@ public class McpServiceTest { @Test public void testStopMcpService() { - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mMcpService.stop()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(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()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mMcpService::start); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java index 80f8775b072d344ce48f2129adc8287c2ef97664..6f16c76557884a2f08b104fa0bbe9e29a9bbc5a1 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java @@ -25,6 +25,7 @@ import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothLeBroadcastMetadata; import android.content.Context; import android.os.Looper; @@ -34,11 +35,14 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; import com.android.bluetooth.le_audio.LeAudioService; +import android.platform.test.flag.junit.SetFlagsRule; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -65,6 +69,8 @@ public class MediaControlGattServiceTest { private static final UUID UUID_CCCD = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); public static final int TEST_CCID = 1; + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private MediaControlGattService mMcpService; @Mock private AdapterService mAdapterService; @@ -355,8 +361,10 @@ public class MediaControlGattServiceTest { Assert.assertEquals(characteristic.getProperties(), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY); - Assert.assertEquals(Request.SupportedOpcodes.NONE, - characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) + Assert.assertEquals( + MediaControlGattService.INITIAL_SUPPORTED_OPCODES, + characteristic + .getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0) .intValue()); characteristic = service.getCharacteristic( @@ -938,12 +946,19 @@ public class MediaControlGattServiceTest { @Test public void testMediaControlPointeRequest_OpcodePlayCallLeAudioServiceSetActiveDevice() { + mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_FEATURE_SUPPORT); BluetoothGattService service = initAllFeaturesGattService(); prepareConnectedDevice(); mMcpService.updateSupportedOpcodesChar(Request.SupportedOpcodes.PLAY, true); verifyMediaControlPointRequest(service, Request.Opcodes.PLAY, null, BluetoothGatt.GATT_SUCCESS, 1); - verify(mMockLeAudioService).setActiveDevice(any(BluetoothDevice.class)); + if (!Flags.leaudioBroadcastFeatureSupport()) { + verify(mMockLeAudioService).setActiveDevice(any(BluetoothDevice.class)); + } else { + final List metadataList = mock(List.class); + when(mMockLeAudioService.getAllBroadcastMetadata()).thenReturn(metadataList); + verify(mMockMcsCallbacks, times(1)).onMediaControlRequest(any(Request.class)); + } } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java index 3a5de2a82fb9f8bb5f8b9786beed43a3b7e5e6c2..7156c70804fab7ac5b345227ede8dcadac8f2e17 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivityTest.java @@ -61,7 +61,6 @@ public class BluetoothOppBtEnableActivityTest { mIntent = new Intent(); mIntent.setClass(mTargetContext, BluetoothOppBtEnableActivity.class); Intents.init(); - BluetoothOppTestUtils.enableOppActivities(true, mTargetContext); TestUtils.setUpUiTest(); } @@ -69,7 +68,6 @@ public class BluetoothOppBtEnableActivityTest { public void tearDown() throws Exception { TestUtils.tearDownUiTest(); Intents.release(); - BluetoothOppTestUtils.enableOppActivities(false, mTargetContext); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java index b2f75889e57fa9c4503f244e83be060f24e40e94..c4abf9a2921dfc4621a0f591520298159a1f7ebf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivityTest.java @@ -80,7 +80,6 @@ public class BluetoothOppBtEnablingActivityTest { mIntent.setClass(mTargetContext, BluetoothOppBtEnablingActivity.class); mRealTimeoutValue = BluetoothOppBtEnablingActivity.sBtEnablingTimeoutMs; - BluetoothOppTestUtils.enableOppActivities(true, mTargetContext); TestUtils.setUpUiTest(); } @@ -89,7 +88,6 @@ public class BluetoothOppBtEnablingActivityTest { TestUtils.tearDownUiTest(); BluetoothMethodProxy.setInstanceForTesting(null); BluetoothOppBtEnablingActivity.sBtEnablingTimeoutMs = mRealTimeoutValue; - BluetoothOppTestUtils.enableOppActivities(false, mTargetContext); } @Ignore("b/277594572") diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java index 24267f64e58a82ecf17566ed5eadf9970d8ea0d7..58ee1b60679d8c1279f1d2961178d2858f1309c2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppLauncherActivityTest.java @@ -87,7 +87,6 @@ public class BluetoothOppLauncherActivityTest { mIntent = new Intent(); mIntent.setClass(mTargetContext, BluetoothOppLauncherActivity.class); - BluetoothOppTestUtils.enableOppActivities(true, mTargetContext); TestUtils.setUpUiTest(); BluetoothOppManager.setInstance(mBluetoothOppManager); @@ -100,7 +99,6 @@ public class BluetoothOppLauncherActivityTest { BluetoothMethodProxy.setInstanceForTesting(null); BluetoothOppManager.setInstance(null); Intents.release(); - BluetoothOppTestUtils.enableOppActivities(false, mTargetContext); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java index d711280fceb41a17f094b672c7b40ae9081e594a..faadf25f6e453373cc40a11237d00abcd980f9c8 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppReceiverTest.java @@ -42,6 +42,7 @@ import android.content.ContextWrapper; import android.content.Intent; import android.database.Cursor; import android.net.Uri; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.core.app.ActivityScenario; import androidx.test.espresso.intent.Intents; @@ -50,12 +51,14 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.flags.Flags; import com.google.common.base.Objects; import org.junit.After; import org.junit.Before; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -66,6 +69,9 @@ import java.util.List; @RunWith(AndroidJUnit4.class) public class BluetoothOppReceiverTest { + + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + Context mContext; @Mock @@ -84,8 +90,6 @@ public class BluetoothOppReceiverTest { mReceiver = new BluetoothOppReceiver(); Intents.init(); - - BluetoothOppTestUtils.enableOppActivities(true, mContext); TestUtils.setUpUiTest(); } @@ -108,23 +112,41 @@ public class BluetoothOppReceiverTest { Intent intent = new Intent(); intent.setAction(BluetoothDevicePicker.ACTION_DEVICE_SELECTED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); - ActivityScenario activityScenario - = ActivityScenario.launch(BluetoothOppBtEnableActivity.class); - activityScenario.onActivity(activity -> { - mReceiver.onReceive(mContext, intent); - }); - doNothing().when(bluetoothOppManager).startTransfer(eq(device)); - verify(bluetoothOppManager).startTransfer(eq(device)); - BluetoothOppManager.setInstance(null); + + try { + BluetoothOppTestUtils.enableActivity( + BluetoothOppBtEnableActivity.class, true, mContext); + ActivityScenario activityScenario = + ActivityScenario.launch(BluetoothOppBtEnableActivity.class); + activityScenario.onActivity( + activity -> { + mReceiver.onReceive(mContext, intent); + }); + doNothing().when(bluetoothOppManager).startTransfer(eq(device)); + verify(bluetoothOppManager).startTransfer(eq(device)); + BluetoothOppManager.setInstance(null); + } finally { + BluetoothOppTestUtils.enableActivity( + BluetoothOppBtEnableActivity.class, false, mContext); + } } @Test public void onReceive_withActionIncomingFileConfirm_startsIncomingFileConfirmActivity() { - Intent intent = new Intent(); - intent.setAction(Constants.ACTION_INCOMING_FILE_CONFIRM); - intent.setData(Uri.parse("content:///not/important")); - mReceiver.onReceive(mContext, intent); - intended(hasComponent(BluetoothOppIncomingFileConfirmActivity.class.getName())); + mSetFlagsRule.disableFlags(Flags.FLAG_OPP_START_ACTIVITY_DIRECTLY_FROM_NOTIFICATION); + try { + BluetoothOppTestUtils.enableActivity( + BluetoothOppIncomingFileConfirmActivity.class, true, mContext); + + Intent intent = new Intent(); + intent.setAction(Constants.ACTION_INCOMING_FILE_CONFIRM); + intent.setData(Uri.parse("content:///not/important")); + mReceiver.onReceive(mContext, intent); + intended(hasComponent(BluetoothOppIncomingFileConfirmActivity.class.getName())); + } finally { + BluetoothOppTestUtils.enableActivity( + BluetoothOppIncomingFileConfirmActivity.class, false, mContext); + } } @Test @@ -153,38 +175,45 @@ public class BluetoothOppReceiverTest { @Test public void onReceive_withActionOutboundTransfer_startsTransferHistoryActivity() { - Intent intent = new Intent(); - intent.setAction(Constants.ACTION_OPEN_OUTBOUND_TRANSFER); - intent.setData(Uri.parse("content:///not/important")); - intending(anyIntent()).respondWith( - new Instrumentation.ActivityResult(Activity.RESULT_OK, new Intent())); + mSetFlagsRule.disableFlags(Flags.FLAG_OPP_START_ACTIVITY_DIRECTLY_FROM_NOTIFICATION); + try { + BluetoothOppTestUtils.enableActivity(BluetoothOppTransferHistory.class, true, mContext); - mReceiver.onReceive(mContext, intent); - intended(hasComponent(BluetoothOppTransferHistory.class.getName())); - intended(hasExtra("direction", BluetoothShare.DIRECTION_OUTBOUND)); - } + Intent intent = new Intent(); + intent.setAction(Constants.ACTION_OPEN_OUTBOUND_TRANSFER); + intent.setData(Uri.parse("content:///not/important")); + intending(anyIntent()) + .respondWith( + new Instrumentation.ActivityResult(Activity.RESULT_OK, new Intent())); - @Test - public void onReceive_withActionInboundTransfer_startsTransferHistoryActivity() { - Intent intent = new Intent(); - intent.setAction(Constants.ACTION_OPEN_INBOUND_TRANSFER); - intent.setData(Uri.parse("content:///not/important")); - intending(anyIntent()).respondWith( - new Instrumentation.ActivityResult(Activity.RESULT_OK, new Intent())); - mReceiver.onReceive(mContext, intent); - intended(hasComponent(BluetoothOppTransferHistory.class.getName())); - intended(hasExtra("direction", BluetoothShare.DIRECTION_INBOUND)); + mReceiver.onReceive(mContext, intent); + intended(hasComponent(BluetoothOppTransferHistory.class.getName())); + intended(hasExtra(Constants.EXTRA_DIRECTION, BluetoothShare.DIRECTION_OUTBOUND)); + } finally { + BluetoothOppTestUtils.enableActivity( + BluetoothOppTransferHistory.class, false, mContext); + } } @Test - public void onReceive_withActionOpenReceivedFile_startsTransferHistoryActivity() { - Intent intent = new Intent(); - intent.setAction(Constants.ACTION_OPEN_RECEIVED_FILES); - intent.setData(Uri.parse("content:///not/important")); - mReceiver.onReceive(mContext, intent); - intended(hasComponent(BluetoothOppTransferHistory.class.getName())); - intended(hasExtra("direction", BluetoothShare.DIRECTION_INBOUND)); - intended(hasExtra(Constants.EXTRA_SHOW_ALL_FILES, true)); + public void onReceive_withActionInboundTransfer_startsTransferHistoryActivity() { + mSetFlagsRule.disableFlags(Flags.FLAG_OPP_START_ACTIVITY_DIRECTLY_FROM_NOTIFICATION); + try { + BluetoothOppTestUtils.enableActivity(BluetoothOppTransferHistory.class, true, mContext); + + Intent intent = new Intent(); + intent.setAction(Constants.ACTION_OPEN_INBOUND_TRANSFER); + intent.setData(Uri.parse("content:///not/important")); + intending(anyIntent()) + .respondWith( + new Instrumentation.ActivityResult(Activity.RESULT_OK, new Intent())); + mReceiver.onReceive(mContext, intent); + intended(hasComponent(BluetoothOppTransferHistory.class.getName())); + intended(hasExtra(Constants.EXTRA_DIRECTION, BluetoothShare.DIRECTION_INBOUND)); + } finally { + BluetoothOppTestUtils.enableActivity( + BluetoothOppTransferHistory.class, false, mContext); + } } @Test @@ -214,7 +243,8 @@ public class BluetoothOppReceiverTest { } @Test - public void onReceive_withActionCompleteHide_contentUpdate() { + public void onReceive_withActionCompleteHide_makeAllVisibilityHidden() { + mSetFlagsRule.disableFlags(Flags.FLAG_OPP_FIX_MULTIPLE_NOTIFICATIONS_ISSUES); Intent intent = new Intent(); intent.setAction(Constants.ACTION_COMPLETE_HIDE); mReceiver.onReceive(mContext, intent); @@ -223,6 +253,44 @@ public class BluetoothOppReceiverTest { arg.get(BluetoothShare.VISIBILITY))), any(), any()); } + @Test + public void onReceive_withActionHideCompletedInboundTransfer_makesInboundVisibilityHidden() { + mSetFlagsRule.enableFlags(Flags.FLAG_OPP_FIX_MULTIPLE_NOTIFICATIONS_ISSUES); + Intent intent = new Intent(); + intent.setAction(Constants.ACTION_HIDE_COMPLETED_INBOUND_TRANSFER); + mReceiver.onReceive(mContext, intent); + verify(mBluetoothMethodProxy) + .contentResolverUpdate( + any(), + eq(BluetoothShare.CONTENT_URI), + argThat( + arg -> + Objects.equal( + BluetoothShare.VISIBILITY_HIDDEN, + arg.get(BluetoothShare.VISIBILITY))), + eq(BluetoothOppNotification.WHERE_COMPLETED_INBOUND), + any()); + } + + @Test + public void onReceive_withActionHideCompletedOutboundTransfer_makesOutboundVisibilityHidden() { + mSetFlagsRule.enableFlags(Flags.FLAG_OPP_FIX_MULTIPLE_NOTIFICATIONS_ISSUES); + Intent intent = new Intent(); + intent.setAction(Constants.ACTION_HIDE_COMPLETED_OUTBOUND_TRANSFER); + mReceiver.onReceive(mContext, intent); + verify(mBluetoothMethodProxy) + .contentResolverUpdate( + any(), + eq(BluetoothShare.CONTENT_URI), + argThat( + arg -> + Objects.equal( + BluetoothShare.VISIBILITY_HIDDEN, + arg.get(BluetoothShare.VISIBILITY))), + eq(BluetoothOppNotification.WHERE_COMPLETED_OUTBOUND), + any()); + } + @Test public void onReceive_withActionTransferCompletedAndHandoverInitiated_contextSendBroadcast() { List cursorMockDataList; diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java new file mode 100644 index 0000000000000000000000000000000000000000..04ab4ee821d0cbfc98fab54506853b5b0976eafb --- /dev/null +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java @@ -0,0 +1,117 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bluetooth.opp; + +import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; +import static android.content.pm.PackageManager.DONT_KILL_APP; + +import android.content.ComponentName; +import android.content.ContentValues; +import android.content.Context; +import android.platform.test.flag.junit.SetFlagsRule; + +import androidx.test.annotation.UiThreadTest; +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import com.android.bluetooth.BluetoothMethodProxy; +import com.android.bluetooth.TestUtils; +import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.flags.Flags; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class BluetoothOppServiceCleanupTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private boolean mIsAdapterServiceSet; + + private Context mTargetContext; + + @Mock private AdapterService mAdapterService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + TestUtils.setAdapterService(mAdapterService); + mIsAdapterServiceSet = true; + } + + @After + public void tearDown() throws Exception { + BluetoothMethodProxy.setInstanceForTesting(null); + + if (mIsAdapterServiceSet) { + TestUtils.clearAdapterService(mAdapterService); + } + } + + @Test + @UiThreadTest + public void testStopAndCleanup() { + mSetFlagsRule.enableFlags( + Flags.FLAG_OPP_SERVICE_FIX_INDEX_OUT_OF_BOUNDS_EXCEPTION_IN_UPDATE_THREAD); + + // Don't need to disable again since it will be handled in OppService.stop + enableBtOppProvider(); + + // Add thousands of placeholder rows + for (int i = 0; i < 2000; i++) { + ContentValues values = new ContentValues(); + mTargetContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values); + } + + try { + BluetoothOppService service = new BluetoothOppService(mTargetContext); + service.start(); + service.setAvailable(true); + + // Call stop while UpdateThread is running. + service.stop(); + service.cleanup(); + } finally { + mTargetContext.getContentResolver().delete(BluetoothShare.CONTENT_URI, null, null); + } + } + + private void enableBtOppProvider() { + mTargetContext + .getPackageManager() + .setApplicationEnabledSetting( + mTargetContext.getPackageName(), + COMPONENT_ENABLED_STATE_ENABLED, + DONT_KILL_APP); + + ComponentName activityName = + new ComponentName(mTargetContext, BluetoothOppProvider.class.getCanonicalName()); + mTargetContext + .getPackageManager() + .setComponentEnabledSetting( + activityName, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP); + } +} diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java index 1de252b7c556265007e63100d855027d62d54be9..05b0460834578bf44b2c92013c3ad2aa75382e66 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java @@ -79,9 +79,9 @@ public class BluetoothOppServiceTest { TestUtils.setAdapterService(mAdapterService); mIsAdapterServiceSet = true; - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mService = new BluetoothOppService(targetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); mIsBluetoothOppServiceStarted = true; // Try getting the Bluetooth adapter @@ -113,7 +113,7 @@ public class BluetoothOppServiceTest { BluetoothMethodProxy.setInstanceForTesting(null); if (mIsBluetoothOppServiceStarted) { - mService.doStop(); + mService.stop(); } if (mIsAdapterServiceSet) { TestUtils.clearAdapterService(mAdapterService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java index c8174be7a6aa5f09f92e533579900552e6ad7b53..0c23856311844a10093419384b422512690d1065 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTestUtils.java @@ -31,7 +31,6 @@ import android.database.Cursor; import org.mockito.internal.util.MockUtil; -import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -115,35 +114,25 @@ public class BluetoothOppTestUtils { } /** - * Enable/Disable all activities in Opp for testing + * Enable/Disable an activity for testing * + * @param activityClass the activity class to enable/disable * @param enable true to enable, false to disable * @param mTargetContext target context */ - public static void enableOppActivities(boolean enable, Context mTargetContext) { - int enabledState = enable ? COMPONENT_ENABLED_STATE_ENABLED - : COMPONENT_ENABLED_STATE_DEFAULT; - - mTargetContext.getPackageManager().setApplicationEnabledSetting( - mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); - - // All activities to be test - Class[] activities = { - BluetoothOppTransferActivity.class, - BluetoothOppBtEnableActivity.class, - BluetoothOppBtEnablingActivity.class, - BluetoothOppBtErrorActivity.class, - BluetoothOppIncomingFileConfirmActivity.class, - BluetoothOppTransferHistory.class, - BluetoothOppLauncherActivity.class, - }; - - Arrays.stream(activities).forEach(activityClass -> { - ComponentName activityName = new ComponentName(mTargetContext, activityClass); - mTargetContext.getPackageManager().setComponentEnabledSetting( - activityName, enabledState, DONT_KILL_APP); - }); - + public static void enableActivity(Class activityClass, boolean enable, Context mTargetContext) { + int enabledState = + enable ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DEFAULT; + + mTargetContext + .getPackageManager() + .setApplicationEnabledSetting( + mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); + + ComponentName activityName = new ComponentName(mTargetContext, activityClass); + mTargetContext + .getPackageManager() + .setComponentEnabledSetting(activityName, enabledState, DONT_KILL_APP); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java index 0a158a5e45eddb587eca0ea1b3e281427808e1f0..40580e651f33a9c7d03b38130fa83718079de47e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferActivityTest.java @@ -110,7 +110,8 @@ public class BluetoothOppTransferActivityTest { new CursorMockData(BluetoothShare.USER_CONFIRMATION, 11, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED) )); - BluetoothOppTestUtils.enableOppActivities(true, mTargetContext); + BluetoothOppTestUtils.enableActivity( + BluetoothOppTransferActivity.class, true, mTargetContext); TestUtils.setUpUiTest(); } @@ -119,7 +120,8 @@ public class BluetoothOppTransferActivityTest { TestUtils.tearDownUiTest(); BluetoothMethodProxy.setInstanceForTesting(null); - BluetoothOppTestUtils.enableOppActivities(false, mTargetContext); + BluetoothOppTestUtils.enableActivity( + BluetoothOppTransferActivity.class, false, mTargetContext); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java index 7bb08cac2e6065198b4d411267b03fb19446e31f..7739c3109d2e1fae45c412a72f2e2e3e20d466cc 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppTransferHistoryTest.java @@ -44,6 +44,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.flags.Flags; import com.google.common.base.Objects; @@ -125,7 +126,8 @@ public class BluetoothOppTransferHistoryTest { BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED) )); - BluetoothOppTestUtils.enableOppActivities(true, mTargetContext); + BluetoothOppTestUtils.enableActivity( + BluetoothOppTransferHistory.class, true, mTargetContext); TestUtils.setUpUiTest(); } @@ -133,33 +135,21 @@ public class BluetoothOppTransferHistoryTest { public void tearDown() throws Exception { TestUtils.tearDownUiTest(); BluetoothMethodProxy.setInstanceForTesting(null); - BluetoothOppTestUtils.enableOppActivities(false, mTargetContext); + BluetoothOppTestUtils.enableActivity( + BluetoothOppTransferHistory.class, false, mTargetContext); } @Test - public void onCreate_withDirectionInbound_withExtraShowAllFileIsTrue_displayLiveFolder() - throws Exception { + public void onCreate_withDirectionInbound_displayInboundHistory() { Assume.assumeFalse( mTargetContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)); BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList); - mIntent.putExtra(Constants.EXTRA_SHOW_ALL_FILES, true); - mIntent.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); - ActivityScenario scenario = ActivityScenario.launch(mIntent); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - - onView(withText(mTargetContext.getText(R.string.btopp_live_folder).toString())).check( - matches(isDisplayed())); - } - - @Test - public void onCreate_withDirectionInbound_withExtraShowAllFileIsFalse_displayInboundHistory() { - Assume.assumeFalse( - mTargetContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)); - - BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList); - mIntent.putExtra(Constants.EXTRA_SHOW_ALL_FILES, false); - mIntent.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); + if (Flags.oppStartActivityDirectlyFromNotification()) { + mIntent.setAction(Constants.ACTION_OPEN_INBOUND_TRANSFER); + } else { + mIntent.putExtra(Constants.EXTRA_DIRECTION, BluetoothShare.DIRECTION_INBOUND); + } ActivityScenario scenario = ActivityScenario.launch(mIntent); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); @@ -177,8 +167,11 @@ public class BluetoothOppTransferHistoryTest { mCursorMockDataList.set(1, new BluetoothOppTestUtils.CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_OUTBOUND)); - mIntent.putExtra(Constants.EXTRA_SHOW_ALL_FILES, true); - mIntent.putExtra("direction", BluetoothShare.DIRECTION_OUTBOUND); + if (Flags.oppStartActivityDirectlyFromNotification()) { + mIntent.setAction(Constants.ACTION_OPEN_OUTBOUND_TRANSFER); + } else { + mIntent.putExtra(Constants.EXTRA_DIRECTION, BluetoothShare.DIRECTION_OUTBOUND); + } ActivityScenario scenario = ActivityScenario.launch(mIntent); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); @@ -192,8 +185,7 @@ public class BluetoothOppTransferHistoryTest { @Test public void onOptionsItemSelected_clearAllSelected_promptWarning() { BluetoothOppTestUtils.setUpMockCursor(mCursor, mCursorMockDataList); - mIntent.putExtra(Constants.EXTRA_SHOW_ALL_FILES, false); - mIntent.putExtra("direction", BluetoothShare.DIRECTION_INBOUND); + mIntent.putExtra(Constants.EXTRA_DIRECTION, BluetoothShare.DIRECTION_INBOUND); ActivityScenario scenario = ActivityScenario.launch(mIntent); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java index 377dd3b1c357772b0e6e7999cbf2eddcbbbd29f8..c3897b1168c8fcbcf71dc10b579275dca2390923 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java @@ -79,7 +79,6 @@ public class BluetoothOppUtilityTest { MockitoAnnotations.initMocks(this); mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); BluetoothMethodProxy.setInstanceForTesting(mCallProxy); - BluetoothOppTestUtils.enableOppActivities(true, mContext); TestUtils.setUpUiTest(); } @@ -87,7 +86,6 @@ public class BluetoothOppUtilityTest { public void tearDown() throws Exception { TestUtils.tearDownUiTest(); - BluetoothOppTestUtils.enableOppActivities(false, mContext); BluetoothMethodProxy.setInstanceForTesting(null); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java index 9b748947d878e2080a2c8ba9dc9faa7ed7c24116..77872410ce675c8b87c368a13aa92666ba8c13c9 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/IncomingFileConfirmActivityTest.java @@ -135,7 +135,8 @@ public class IncomingFileConfirmActivityTest { BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED) )); - BluetoothOppTestUtils.enableOppActivities(true, mTargetContext); + BluetoothOppTestUtils.enableActivity( + BluetoothOppIncomingFileConfirmActivity.class, true, mTargetContext); TestUtils.setUpUiTest(); } @@ -144,7 +145,8 @@ public class IncomingFileConfirmActivityTest { TestUtils.tearDownUiTest(); BluetoothMethodProxy.setInstanceForTesting(null); - BluetoothOppTestUtils.enableOppActivities(false, mTargetContext); + BluetoothOppTestUtils.enableActivity( + BluetoothOppIncomingFileConfirmActivity.class, false, mTargetContext); } @Test diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java b/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java index 65c945f68c0957fcec3029404a1dcd032673c87e..2710aa1821143df57415fd491bb4c6c89627a42d 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/TestActivity.java @@ -359,9 +359,9 @@ class TestTcpListener { private static final String TAG = "BtOppRfcommListener"; - private static final boolean D = Constants.DEBUG; + private static final boolean D = Log.isLoggable(TAG, Log.DEBUG); - private static final boolean V = Constants.VERBOSE; + private static final boolean V = Log.isLoggable(TAG, Log.VERBOSE); private volatile boolean mInterrupted; @@ -477,7 +477,7 @@ class TestTcpListener { class TestTcpServer extends ServerRequestHandler implements Runnable { private static final String TAG = "ServerRequestHandler"; - private static final boolean V = Constants.VERBOSE; + private static final boolean V = Log.isLoggable(TAG, Log.VERBOSE); static final int PORT = 6500; diff --git a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java index c41d397490445917a3f727b75c87bdbc03c41d6d..e08f5207d91877b8ebd157238d58dd049f2cf46e 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java @@ -21,7 +21,6 @@ import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; @@ -70,10 +69,10 @@ public class PanServiceTest { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); PanNativeInterface.setInstance(mNativeInterface); mService = new PanService(targetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -84,7 +83,8 @@ public class PanServiceTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); + mService.cleanup(); PanNativeInterface.setInstance(null); mService = PanService.getPanService(); assertThat(mService).isNull(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java index 218241f2383f2ffeb6669abb80c56ea4eddf1f23..69dac461ad3053cde35b0bf1fb655f646dde5512 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapServiceTest.java @@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -81,9 +80,9 @@ public class BluetoothPbapServiceTest { TestUtils.setAdapterService(mAdapterService); mIsAdapterServiceSet = true; doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mService = new BluetoothPbapService(targetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); mIsBluetoothPabpServiceStarted = true; // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -99,7 +98,7 @@ public class BluetoothPbapServiceTest { return; } if (mIsBluetoothPabpServiceStarted) { - mService.doStop(); + mService.stop(); mService = BluetoothPbapService.getBluetoothPbapService(); assertThat(mService).isNull(); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java index 3d761fa5a51cbf1ccfe72073e8062044a9e956ae..50f96db865d0b4a1b37caf2c562c2d99628dc338 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandlerTest.java @@ -18,7 +18,6 @@ package com.android.bluetooth.pbapclient; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -81,10 +80,8 @@ public class PbapClientConnectionHandlerTest { MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService) - .isStartedProfile(anyString()); mService = new PbapClientService(mTargetContext); - mService.doStart(); + mService.start(); mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -104,7 +101,7 @@ public class PbapClientConnectionHandlerTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); mService = PbapClientService.getPbapClientService(); assertThat(mService).isNull(); TestUtils.clearAdapterService(mAdapterService); diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java index 3c838bb32ebef939ed12c33fa3bed8767e377d15..06e63c9519ccd4a26c21e2097b1e92f84d03222b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbapclient/PbapClientServiceTest.java @@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; @@ -78,9 +77,9 @@ public class PbapClientServiceTest { TestUtils.setAdapterService(mAdapterService); mIsAdapterServiceSet = true; doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mService = new PbapClientService(mTargetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); mIsPbapClientServiceStarted = true; // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -94,7 +93,7 @@ public class PbapClientServiceTest { return; } if (mIsPbapClientServiceStarted) { - mService.doStop(); + mService.stop(); mService = PbapClientService.getPbapClientService(); Assert.assertNull(mService); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java index 78a5084165bfe701d1c2598e10dae3449a55202e..27cb3a96dce1571b0f7866fc8869a812b32139da 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java @@ -18,8 +18,6 @@ package com.android.bluetooth.sap; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; @@ -43,9 +41,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; @MediumTest @RunWith(AndroidJUnit4.class) @@ -65,9 +60,9 @@ public class SapServiceTest { mTargetContext = InstrumentationRegistry.getTargetContext(); MockitoAnnotations.initMocks(this); TestUtils.setAdapterService(mAdapterService); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mService = new SapService(mTargetContext); - mService.doStart(); + mService.start(); + mService.setAvailable(true); // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); assertThat(mAdapter).isNotNull(); @@ -76,7 +71,7 @@ public class SapServiceTest { @After public void tearDown() throws Exception { - mService.doStop(); + mService.stop(); mService = SapService.getSapService(); assertThat(mService).isNull(); TestUtils.clearAdapterService(mAdapterService); @@ -93,32 +88,20 @@ public class SapServiceTest { */ @Test public void testStopSapService() throws Exception { - AtomicBoolean stopResult = new AtomicBoolean(); - AtomicBoolean startResult = new AtomicBoolean(); - CountDownLatch latch = new CountDownLatch(1); - // SAP Service is already running: test stop(). Note: must be done on the main thread - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - stopResult.set(mService.stop()); - startResult.set(mService.start()); - latch.countDown(); - } - }); - - assertThat(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue(); - assertThat(stopResult.get()).isTrue(); - assertThat(startResult.get()).isTrue(); + InstrumentationRegistry.getInstrumentation() + .runOnMainSync( + () -> { + mService.stop(); + mService.start(); + }); } - /** - * Test get connection policy for BluetoothDevice - */ + /** Test get connection policy for BluetoothDevice */ @Test public void testGetConnectionPolicy() { when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); - when(mDatabaseManager - .getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP)) + when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.SAP)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); assertThat(mService.getConnectionPolicy(mDevice)) .isEqualTo(BluetoothProfile.CONNECTION_POLICY_UNKNOWN); diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java index a500d36dc39768f0be10de19c93f2458ea2c64a5..79a327cd7a76f3fb442be15e7b0d1bb2797cacb5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java @@ -110,7 +110,6 @@ public class VolumeControlServiceTest { TestUtils.setAdapterService(mAdapterService); doReturn(mDatabaseManager).when(mAdapterService).getDatabase(); - doReturn(true, false).when(mAdapterService).isStartedProfile(anyString()); mAdapter = BluetoothAdapter.getDefaultAdapter(); mAttributionSource = mAdapter.getAttributionSource(); @@ -127,10 +126,12 @@ public class VolumeControlServiceTest { mFakeFlagsImpl = new FakeFeatureFlagsImpl(); mFakeFlagsImpl.setFlag( Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_FOR_CONNECTED_DEVICES, false); + mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_MULTIPLE_VOCS_INSTANCES_API, false); VolumeControlNativeInterface.setInstance(mNativeInterface); mService = new VolumeControlService(mTargetContext, mFakeFlagsImpl); - mService.doStart(); + mService.start(); + mService.setAvailable(true); mService.mAudioManager = mAudioManager; mService.mFactory = mServiceFactory; @@ -169,7 +170,7 @@ public class VolumeControlServiceTest { return; } - mService.doStop(); + mService.stop(); VolumeControlNativeInterface.setInstance(null); mTargetContext.unregisterReceiver(mVolumeControlIntentReceiver); mDeviceQueueMap.clear(); @@ -228,22 +229,12 @@ public class VolumeControlServiceTest { connectDevice(mDevice); // VolumeControl Service is already running: test stop(). // Note: must be done on the main thread - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.stop()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop); // Try to restart the service. Note: must be done on the main thread - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - public void run() { - Assert.assertTrue(mService.start()); - } - }); + InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::start); } - /** - * Test get/set policy for BluetoothDevice - */ + /** Test get/set policy for BluetoothDevice */ @Test public void testGetSetPolicy() { when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); @@ -1022,17 +1013,28 @@ public class VolumeControlServiceTest { public void testServiceBinderVolumeOffsetMethods() throws Exception { // Send a message to trigger connection completed generateDeviceAvailableMessageFromNative(mDevice, 2); + final SynchronousResultReceiver boolRecv = SynchronousResultReceiver.get(); - boolean defaultRecvValue = false; + boolean defaultAvailability = false; mServiceBinder.isVolumeOffsetAvailable(mDevice, mAttributionSource, boolRecv); - Assert.assertTrue(boolRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) - .getValue(defaultRecvValue)); + Assert.assertTrue( + boolRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) + .getValue(defaultAvailability)); + final SynchronousResultReceiver intRecv = SynchronousResultReceiver.get(); + int defaultNumberOfInstances = 0; + mServiceBinder.getNumberOfVolumeOffsetInstances(mDevice, mAttributionSource, intRecv); + int numberOfInstances = + intRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)) + .getValue(defaultNumberOfInstances); + Assert.assertEquals(2, numberOfInstances); + + int id = 1; int volumeOffset = 100; final SynchronousResultReceiver voidRecv = SynchronousResultReceiver.get(); - mServiceBinder.setVolumeOffset(mDevice, volumeOffset, mAttributionSource, voidRecv); + mServiceBinder.setVolumeOffset(mDevice, id, volumeOffset, mAttributionSource, voidRecv); voidRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)); - verify(mNativeInterface).setExtAudioOutVolumeOffset(mDevice, 1, volumeOffset); + verify(mNativeInterface).setExtAudioOutVolumeOffset(mDevice, id, volumeOffset); } @Test @@ -1107,6 +1109,8 @@ public class VolumeControlServiceTest { @Test public void testServiceBinderRegisterCallbackWhenDeviceAlreadyConnected() throws Exception { + mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_MULTIPLE_VOCS_INSTANCES_API, true); + int groupId = 1; int groupVolume = 56; @@ -1122,7 +1126,7 @@ public class VolumeControlServiceTest { doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class)); - generateDeviceAvailableMessageFromNative(mDevice, 1); + generateDeviceAvailableMessageFromNative(mDevice, 2); generateConnectionMessageFromNative( mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); @@ -1141,9 +1145,21 @@ public class VolumeControlServiceTest { Assert.assertTrue(mService.getDevices().contains(mDeviceTwo)); verify(mNativeInterface, times(1)).setVolume(eq(mDeviceTwo), eq(groupVolume)); - // Set different offset to both devices + // Generate events for both devices generateDeviceOffsetChangedMessageFromNative(mDevice, 1, 100); - generateDeviceOffsetChangedMessageFromNative(mDeviceTwo, 1, 200); + generateDeviceLocationChangedMessageFromNative(mDevice, 1, 1); + final String testDevice1Desc1 = "testDevice1Desc1"; + generateDeviceDescriptionChangedMessageFromNative(mDevice, 1, testDevice1Desc1); + + generateDeviceOffsetChangedMessageFromNative(mDevice, 2, 200); + generateDeviceLocationChangedMessageFromNative(mDevice, 2, 2); + final String testDevice1Desc2 = "testDevice1Desc2"; + generateDeviceDescriptionChangedMessageFromNative(mDevice, 2, testDevice1Desc2); + + generateDeviceOffsetChangedMessageFromNative(mDeviceTwo, 1, 250); + generateDeviceLocationChangedMessageFromNative(mDeviceTwo, 1, 3); + final String testDevice2Desc = "testDevice2Desc"; + generateDeviceDescriptionChangedMessageFromNative(mDeviceTwo, 1, testDevice2Desc); // Register callback and verify it is called with known devices IBluetoothVolumeControlCallback callback = @@ -1157,12 +1173,30 @@ public class VolumeControlServiceTest { recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)).getValue(null); Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount()); - verify(callback).onVolumeOffsetChanged(eq(mDeviceTwo), eq(200)); - verify(callback).onVolumeOffsetChanged(eq(mDevice), eq(100)); + verify(callback).onVolumeOffsetChanged(eq(mDevice), eq(1), eq(100)); + verify(callback).onVolumeOffsetAudioLocationChanged(eq(mDevice), eq(1), eq(1)); + verify(callback) + .onVolumeOffsetAudioDescriptionChanged(eq(mDevice), eq(1), eq(testDevice1Desc1)); - generateDeviceOffsetChangedMessageFromNative(mDevice, 1, 50); + verify(callback).onVolumeOffsetChanged(eq(mDevice), eq(2), eq(200)); + verify(callback).onVolumeOffsetAudioLocationChanged(eq(mDevice), eq(2), eq(2)); + verify(callback) + .onVolumeOffsetAudioDescriptionChanged(eq(mDevice), eq(2), eq(testDevice1Desc2)); + + verify(callback).onVolumeOffsetChanged(eq(mDeviceTwo), eq(1), eq(250)); + verify(callback).onVolumeOffsetAudioLocationChanged(eq(mDeviceTwo), eq(1), eq(3)); + verify(callback) + .onVolumeOffsetAudioDescriptionChanged(eq(mDeviceTwo), eq(1), eq(testDevice2Desc)); - verify(callback).onVolumeOffsetChanged(eq(mDevice), eq(50)); + generateDeviceOffsetChangedMessageFromNative(mDevice, 1, 50); + generateDeviceLocationChangedMessageFromNative(mDevice, 1, 0); + final String testDevice1Desc3 = "testDevice1Desc3"; + generateDeviceDescriptionChangedMessageFromNative(mDevice, 1, testDevice1Desc3); + + verify(callback).onVolumeOffsetChanged(eq(mDevice), eq(1), eq(50)); + verify(callback).onVolumeOffsetAudioLocationChanged(eq(mDevice), eq(1), eq(0)); + verify(callback) + .onVolumeOffsetAudioDescriptionChanged(eq(mDevice), eq(1), eq(testDevice1Desc3)); } @Test @@ -1220,6 +1254,77 @@ public class VolumeControlServiceTest { verify(callback, times(1)).onDeviceVolumeChanged(eq(mDeviceTwo), eq(deviceTwoVolume)); } + @Test + public void testServiceBinderTestNotifyNewRegisteredCallback() throws Exception { + mFakeFlagsImpl.setFlag( + Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_FOR_CONNECTED_DEVICES, true); + int groupId = 1; + int deviceOneVolume = 46; + int deviceTwoVolume = 36; + + // Update the device policy so okToConnect() returns true + when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); + when(mDatabaseManager.getProfileConnectionPolicy( + any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL))) + .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); + doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class)); + doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class)); + + generateDeviceAvailableMessageFromNative(mDevice, 1); + generateConnectionMessageFromNative( + mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); + Assert.assertTrue(mService.getDevices().contains(mDevice)); + mService.setDeviceVolume(mDevice, deviceOneVolume, false); + verify(mNativeInterface, times(1)).setVolume(eq(mDevice), eq(deviceOneVolume)); + + // Verify that second device gets the proper group volume level when connected + generateDeviceAvailableMessageFromNative(mDeviceTwo, 1); + generateConnectionMessageFromNative( + mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); + Assert.assertEquals( + BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo)); + Assert.assertTrue(mService.getDevices().contains(mDeviceTwo)); + mService.setDeviceVolume(mDeviceTwo, deviceTwoVolume, false); + verify(mNativeInterface, times(1)).setVolume(eq(mDeviceTwo), eq(deviceTwoVolume)); + + // Both devices are in the same group + when(mLeAudioService.getGroupId(mDevice)).thenReturn(groupId); + when(mLeAudioService.getGroupId(mDeviceTwo)).thenReturn(groupId); + + // Register callback and verify it is called with known devices + IBluetoothVolumeControlCallback callback = + Mockito.mock(IBluetoothVolumeControlCallback.class); + Binder binder = Mockito.mock(Binder.class); + when(callback.asBinder()).thenReturn(binder); + + int size = mService.mCallbacks.getRegisteredCallbackCount(); + SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mServiceBinder.registerCallback(callback, mAttributionSource, recv); + recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)).getValue(null); + Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount()); + + IBluetoothVolumeControlCallback callback_new_client = + Mockito.mock(IBluetoothVolumeControlCallback.class); + Binder binder_new_client = Mockito.mock(Binder.class); + when(callback_new_client.asBinder()).thenReturn(binder_new_client); + + recv = SynchronousResultReceiver.get(); + mServiceBinder.notifyNewRegisteredCallback(callback_new_client, mAttributionSource, recv); + recv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS)).getValue(null); + Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount()); + + // This shall be done only once after mServiceBinder.registerCallback + verify(callback, times(1)).onDeviceVolumeChanged(eq(mDevice), eq(deviceOneVolume)); + verify(callback, times(1)).onDeviceVolumeChanged(eq(mDeviceTwo), eq(deviceTwoVolume)); + + // This shall be done only once after mServiceBinder.updateNewRegistedCallback + verify(callback_new_client, times(1)) + .onDeviceVolumeChanged(eq(mDevice), eq(deviceOneVolume)); + verify(callback_new_client, times(1)) + .onDeviceVolumeChanged(eq(mDeviceTwo), eq(deviceTwoVolume)); + } + @Test public void testServiceBinderMuteMethods() throws Exception { SynchronousResultReceiver voidRecv = SynchronousResultReceiver.get(); @@ -1451,6 +1556,30 @@ public class VolumeControlServiceTest { mService.messageFromNative(event); } + private void generateDeviceLocationChangedMessageFromNative( + BluetoothDevice device, int extOffsetIndex, int location) { + // Send a message to trigger connection completed + VolumeControlStackEvent event = + new VolumeControlStackEvent( + VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_LOCATION_CHANGED); + event.device = device; + event.valueInt1 = extOffsetIndex; // external output index + event.valueInt2 = location; // location + mService.messageFromNative(event); + } + + private void generateDeviceDescriptionChangedMessageFromNative( + BluetoothDevice device, int extOffsetIndex, String description) { + // Send a message to trigger connection completed + VolumeControlStackEvent event = + new VolumeControlStackEvent( + VolumeControlStackEvent.EVENT_TYPE_EXT_AUDIO_OUT_DESCRIPTION_CHANGED); + event.device = device; + event.valueInt1 = extOffsetIndex; // external output index + event.valueString1 = description; // description + mService.messageFromNative(event); + } + /** * Helper function to test okToConnect() method * diff --git a/android/pandora/mmi2grpc/__init__.py b/android/pandora/mmi2grpc/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3d7a6ca725e19386657a63482fc24f611b2b7450 100644 --- a/android/pandora/mmi2grpc/__init__.py +++ b/android/pandora/mmi2grpc/__init__.py @@ -0,0 +1,13 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/android/pandora/mmi2grpc/mmi2grpc/__init__.py b/android/pandora/mmi2grpc/mmi2grpc/__init__.py index a0adfe14949fd3c42787d88ee7b091c621135405..6272b209bc0bfdf6a3924691da6f970cd4ef9294 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/__init__.py +++ b/android/pandora/mmi2grpc/mmi2grpc/__init__.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/_audio.py b/android/pandora/mmi2grpc/mmi2grpc/_audio.py index 11936731ba18e83d1b9d90517ba0e26208f711f5..7bc97167a87ca88b25e7bfc0f3a3bc3936bf56e0 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/_audio.py +++ b/android/pandora/mmi2grpc/mmi2grpc/_audio.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/_helpers.py b/android/pandora/mmi2grpc/mmi2grpc/_helpers.py index 208a7298425fba870f7979d4b9fe800a5741c56b..9bc9dc0b026a29dead55a99ef8442e3c770d5dff 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/_helpers.py +++ b/android/pandora/mmi2grpc/mmi2grpc/_helpers.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/_modem.py b/android/pandora/mmi2grpc/mmi2grpc/_modem.py index f0b7c4bacdb101a1cfad14f02121e2038a09bc0c..217b3853295bd04f836c374b1bb0f56cd995418f 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/_modem.py +++ b/android/pandora/mmi2grpc/mmi2grpc/_modem.py @@ -1,3 +1,17 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import os import socket diff --git a/android/pandora/mmi2grpc/mmi2grpc/_proxy.py b/android/pandora/mmi2grpc/mmi2grpc/_proxy.py index 41dbd1aba1174e42f45d33f9e16d66b6dbffb4d3..711b1c9aeec6dd3ed3b9ac99afd98411ec537410 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/_proxy.py +++ b/android/pandora/mmi2grpc/mmi2grpc/_proxy.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py b/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py index 79d0270747d585c0c811d8b2a097bc73f462ede7..e346647dd776fff40cf6b3bcbe6eb40067d6917a 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py +++ b/android/pandora/mmi2grpc/mmi2grpc/_rootcanal.py @@ -1,3 +1,16 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Copied from tools/rootcanal/scripts/test_channel.py """ diff --git a/android/pandora/mmi2grpc/mmi2grpc/a2dp.py b/android/pandora/mmi2grpc/mmi2grpc/a2dp.py index b2c8acfdc6c46d676dd637ffd23752f9d5f7ca9f..0f27cd19dd892b9344d10ab791c3c33a3e7f5049 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/a2dp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/a2dp.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/avrcp.py b/android/pandora/mmi2grpc/mmi2grpc/avrcp.py index d707c8314c1da700dfc57d4fa3e3dad2e00844cb..3ed97ce97e463e493225343a1fcea2fc43aae5a5 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/avrcp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/avrcp.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/gap.py b/android/pandora/mmi2grpc/mmi2grpc/gap.py index d856dac4ecfaecda25ffc6ee3c79db086751c2ba..4fd58b94bbd16d6795afa616c084aadd67381d13 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/gap.py +++ b/android/pandora/mmi2grpc/mmi2grpc/gap.py @@ -1,3 +1,17 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from threading import Thread from mmi2grpc._helpers import assert_description, match_description from mmi2grpc._rootcanal import Dongle diff --git a/android/pandora/mmi2grpc/mmi2grpc/gatt.py b/android/pandora/mmi2grpc/mmi2grpc/gatt.py index 911c4c4f41a5cc6e9223a1c8bfd5d77f347d5971..5593f59dc22b1e77d4c0bd1dccb16420ef05bffb 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/gatt.py +++ b/android/pandora/mmi2grpc/mmi2grpc/gatt.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/hfp.py b/android/pandora/mmi2grpc/mmi2grpc/hfp.py index 44d2d129ac75f23c55a3bc5c95acb01181db2b83..5fdfe023fbd2548370e67b9f3e2a8a32909f33c6 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/hfp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/hfp.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/hid.py b/android/pandora/mmi2grpc/mmi2grpc/hid.py index 886e1267ecc3ea6d1681698156724d9de3386e08..421da8683f37b00271c3281257d072d4a861876c 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/hid.py +++ b/android/pandora/mmi2grpc/mmi2grpc/hid.py @@ -1,3 +1,17 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from threading import Thread from time import sleep from mmi2grpc._helpers import assert_description, match_description diff --git a/android/pandora/mmi2grpc/mmi2grpc/hogp.py b/android/pandora/mmi2grpc/mmi2grpc/hogp.py index 1dbac3d0d97ccdc6812e5bc53f4ded8abc5c1d52..7f4e56dedef7e01795c7ce8debcfac811355137d 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/hogp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/hogp.py @@ -1,3 +1,17 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import threading import textwrap import uuid diff --git a/android/pandora/mmi2grpc/mmi2grpc/l2cap.py b/android/pandora/mmi2grpc/mmi2grpc/l2cap.py index ae63f2440854adf79644ac5d6f3ed84f2a106e13..09ef10d751755686d9e0bc2fc187eba89bf17360 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/l2cap.py +++ b/android/pandora/mmi2grpc/mmi2grpc/l2cap.py @@ -1,3 +1,17 @@ +# Copyright (C) 2024 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import time import sys diff --git a/android/pandora/mmi2grpc/mmi2grpc/map.py b/android/pandora/mmi2grpc/mmi2grpc/map.py index 8eee4a6d8d0a6e6e386b6a6fe8bb034252fbce1e..04bdcbb139a3c47481a42f18fc7c5f501405384f 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/map.py +++ b/android/pandora/mmi2grpc/mmi2grpc/map.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/opp.py b/android/pandora/mmi2grpc/mmi2grpc/opp.py index e041f3597e968e1f4a4b5d6f8c6aa3e854b0b9e8..29af9924e7927f74f6916c285937b09c0a4188bd 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/opp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/opp.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/pan.py b/android/pandora/mmi2grpc/mmi2grpc/pan.py index 5c1709debf247e5d4546cbb972dd2a40376bbdee..7654658f194c400fe86725733a6dd9c864f4a8f1 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/pan.py +++ b/android/pandora/mmi2grpc/mmi2grpc/pan.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/pbap.py b/android/pandora/mmi2grpc/mmi2grpc/pbap.py index 362f0de98985b384acddfd17151ce6079926d591..1453e7edac8e3019cafe777ff97dbbc7e42a31f6 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/pbap.py +++ b/android/pandora/mmi2grpc/mmi2grpc/pbap.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/rfcomm.py b/android/pandora/mmi2grpc/mmi2grpc/rfcomm.py index 00262698fe2c394832cd703cc0521548d9ae9ecc..6c3eb58f4073036864585de007b186534f1db347 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/rfcomm.py +++ b/android/pandora/mmi2grpc/mmi2grpc/rfcomm.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/sdp.py b/android/pandora/mmi2grpc/mmi2grpc/sdp.py index b22d06b8ee391c0802e3b96fcc841fcfd0c1a11b..670024408a9e2824a46606f079469300885300c8 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/sdp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/sdp.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/sm.py b/android/pandora/mmi2grpc/mmi2grpc/sm.py index 069fb5882e379755576e75b6a83b6ef29c305425..09bd855a25639d713577d327ab0b3bb8a363f00c 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/sm.py +++ b/android/pandora/mmi2grpc/mmi2grpc/sm.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/mmi2grpc/mmi2grpc/vcp.py b/android/pandora/mmi2grpc/mmi2grpc/vcp.py index 423feae758b3e1f115e8093972bb73e13b3e46c5..f952024d27ae7974d134137cf56bc2acf9e62b8a 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/vcp.py +++ b/android/pandora/mmi2grpc/mmi2grpc/vcp.py @@ -1,10 +1,10 @@ -# Copyright 2022 Google LLC +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/android/pandora/server/configs/PtsBotTest.xml b/android/pandora/server/configs/PtsBotTest.xml index 8068835d0e2419b2de2e08e4ef816f3cb0ecbb61..af626890a3b5ef85c299d7959e2c94a9c7482394 100644 --- a/android/pandora/server/configs/PtsBotTest.xml +++ b/android/pandora/server/configs/PtsBotTest.xml @@ -1,3 +1,17 @@ +

Some applications need to use Bluetooth for short periods of time to transfer data but - * don't want all the associated implications like automatic connection to headsets etc. - * - *

Multiple applications can call this. This is reference counted and Bluetooth disabled only - * when no one else is using it. There will be no UI shown to the user while bluetooth is being - * enabled. Any user action will override this call. For example, if user wants Bluetooth on and - * the last user of this API wanted to disable Bluetooth, Bluetooth will not be turned off. - * - *

This API is only meant to be used by internal applications. Third party applications but - * use {@link #enable} and {@link #disable} APIs. - * - *

If this API returns true, it means the callback will be called. The callback will be - * called with the current state of Bluetooth. If the state is not what was requested, an - * internal error would be the reason. If Bluetooth is already on and if this function is called - * to turn it on, the api will return true and a callback will be called. - * - * @param on True for on, false for off. - * @param callback The callback to notify changes to the state. - * @hide - */ - @RequiresLegacyBluetoothPermission - @RequiresBluetoothConnectPermission - @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - @SuppressLint("AndroidFrameworkRequiresPermission") - public boolean changeApplicationBluetoothState( - boolean on, BluetoothStateChangeCallback callback) { - return false; - } - - /** @hide */ - public interface BluetoothStateChangeCallback { - /** @hide */ - void onBluetoothStateChange(boolean on); - } - - /** @hide */ - public static class StateChangeCallbackWrapper extends IBluetoothStateChangeCallback.Stub { - private BluetoothStateChangeCallback mCallback; - - StateChangeCallbackWrapper(BluetoothStateChangeCallback callback) { - mCallback = callback; - } - - @Override - public void onBluetoothStateChange(boolean on) { - mCallback.onBluetoothStateChange(on); - } - } - private Set toDeviceSet(List devices) { Set deviceSet = new HashSet(devices); return Collections.unmodifiableSet(deviceSet); @@ -4297,6 +4355,24 @@ public final class BluetoothAdapter { return defaultValue; } + /** Return a binder to a Profile service */ + private @Nullable IBinder getProfile(int profile) { + IBinder defaultValue = null; + mServiceLock.readLock().lock(); + try { + if (mService != null) { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + mService.getProfile(profile, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); + } + } catch (RemoteException | TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } finally { + mServiceLock.readLock().unlock(); + } + return defaultValue; + } + /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) { requireNonNull(cb); synchronized (sServiceLock) { @@ -5722,6 +5798,60 @@ public final class BluetoothAdapter { return BT_SNOOP_LOG_MODE_DISABLED; } + /** + * Returns true if the auto on feature is supported on the device + * + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_AUTO_ON_FEATURE) + @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + public boolean isAutoOnSupported() { + try { + return mManagerService.isAutoOnSupported(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + return false; + } + + /** + * Get the value of the automatic restart of the Bluetooth stack for the current user + * + * @return true if the auto on feature is enabled for the current user + * @throws IllegalStateException if feature is not supported + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_AUTO_ON_FEATURE) + @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + public boolean isAutoOnEnabled() { + try { + return mManagerService.isAutoOnEnabled(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + return false; + } + + /** + * Set the value of the automatic restart of the Bluetooth stack for the current user + * + * @param status true if the feature is enabled + * @throws IllegalStateException if feature is not supported + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_AUTO_ON_FEATURE) + @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + public void setAutoOnEnabled(boolean status) { + try { + mManagerService.setAutoOnEnabled(status); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef( diff --git a/framework/java/android/bluetooth/BluetoothCodecConfig.java b/framework/java/android/bluetooth/BluetoothCodecConfig.java index f8a5f6b59df1f3b26c5a42ddb86ed8f8a8540799..d806e10eba27ecc66e5dac46421969fc5bf086d2 100644 --- a/framework/java/android/bluetooth/BluetoothCodecConfig.java +++ b/framework/java/android/bluetooth/BluetoothCodecConfig.java @@ -25,6 +25,8 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; @@ -547,7 +549,7 @@ public final class BluetoothCodecConfig implements Parcelable { } /** Returns the source codec type of this config. */ - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public @Nullable BluetoothCodecType getExtendedCodecType() { return mCodecType; } @@ -857,7 +859,7 @@ public final class BluetoothCodecConfig implements Parcelable { * @param codecType of this codec * @return the same Builder instance */ - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public @NonNull Builder setCodecType(@Nullable BluetoothCodecType codecType) { mCodecType = codecType; return this; diff --git a/framework/java/android/bluetooth/BluetoothCodecType.java b/framework/java/android/bluetooth/BluetoothCodecType.java index 26db506b7ff3eb78b268d7190143ee4915e9e1a8..ece44abe9a0d8dc57d5a8b9d209ddf312f29217e 100644 --- a/framework/java/android/bluetooth/BluetoothCodecType.java +++ b/framework/java/android/bluetooth/BluetoothCodecType.java @@ -23,12 +23,14 @@ import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + /** * Represents a supported source codec type for a Bluetooth A2DP device. See {@link * BluetoothA2dp#getSupportedCodecTypes}. The codec type is uniquely identified by its name and * codec identifier. */ -@FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") +@FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public final class BluetoothCodecType implements Parcelable { private final int mNativeCodecType; private final long mCodecId; @@ -44,7 +46,7 @@ public final class BluetoothCodecType implements Parcelable { public static final long CODEC_ID_SBC = 0x0000000000; /** AAC codec identifier. See {@link BluetoothCodecType#getCodecId}. */ - public static final long CODEC_ID_AAC = 0x0000000001; + public static final long CODEC_ID_AAC = 0x0000000002; /** AptX codec identifier. See {@link BluetoothCodecType#getCodecId}. */ public static final long CODEC_ID_APTX = 0x0001004fff; @@ -86,7 +88,7 @@ public final class BluetoothCodecType implements Parcelable { } /** Returns if the codec type is mandatory in the Bluetooth specification. */ - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public boolean isMandatoryCodec() { return mNativeCodecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC; } @@ -97,13 +99,13 @@ public final class BluetoothCodecType implements Parcelable { * 0, if octet 0 is not 0xFF. - Bits 24-39: Vendor-defined codec ID, set to 0, if octet 0 is not * 0xFF. */ - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public long getCodecId() { return mCodecId; } /** Returns the codec name. */ - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public @NonNull String getCodecName() { return mCodecName; } @@ -144,7 +146,7 @@ public final class BluetoothCodecType implements Parcelable { /** @hide */ @Override - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mNativeCodecType); dest.writeLong(mCodecId); @@ -159,7 +161,7 @@ public final class BluetoothCodecType implements Parcelable { * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public static @Nullable BluetoothCodecType createFromType( @BluetoothCodecConfig.SourceCodecType int codecType) { long codecId = @@ -185,12 +187,12 @@ public final class BluetoothCodecType implements Parcelable { * @hide */ @Override - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public int describeContents() { return 0; } - @FlaggedApi("com.android.bluetooth.flags.a2dp_offload_codec_extensibility") + @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public static final @NonNull Creator CREATOR = new Creator<>() { public BluetoothCodecType createFromParcel(Parcel in) { diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java index 9f9512b9b056421183f3919ef428c0ed303450f5..679b45080fe51bd90d4dffeef5f3c6414d6e75be 100644 --- a/framework/java/android/bluetooth/BluetoothDevice.java +++ b/framework/java/android/bluetooth/BluetoothDevice.java @@ -52,6 +52,7 @@ import android.os.RemoteException; import android.util.Log; import android.util.Pair; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.io.IOException; @@ -304,7 +305,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { * * @hide */ - @FlaggedApi("com.android.bluetooth.flags.key_missing_broadcast") + @FlaggedApi(Flags.FLAG_KEY_MISSING_BROADCAST) @SuppressLint("ActionValue") @RequiresPermission( allOf = { @@ -549,7 +550,8 @@ public final class BluetoothDevice implements Parcelable, Attributable { METADATA_FAST_PAIR_CUSTOMIZED_FIELDS, METADATA_LE_AUDIO, METADATA_GMCS_CCCD, - METADATA_GTBS_CCCD + METADATA_GTBS_CCCD, + METADATA_EXCLUSIVE_MANAGER }) @Retention(RetentionPolicy.SOURCE) public @interface MetadataKey {} @@ -795,7 +797,24 @@ public final class BluetoothDevice implements Parcelable, Attributable { */ public static final int METADATA_GTBS_CCCD = 28; - private static final int METADATA_MAX_KEY = METADATA_GTBS_CCCD; + /** + * Specify the exclusive manager app for this BluetoothDevice. + * + *

If there's a manager app specified for this BluetoothDevice, and the app is currently + * installed on the device, that manager app shall be responsible for providing the + * BluetoothDevice management functionality (e.g. connect, disconnect, forget, etc.). Android + * Settings app shall not provide any management functionality for such BluetoothDevice. + * + *

Data type should be a {@link String} representing the package name of the app (e.g. + * "com.android.settings"), provided as a {@link Byte} array. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_SUPPORT_EXCLUSIVE_MANAGER) + @SystemApi + public static final int METADATA_EXCLUSIVE_MANAGER = 29; + + private static final int METADATA_MAX_KEY = METADATA_EXCLUSIVE_MANAGER; /** * Device type which is used in METADATA_DEVICE_TYPE Indicates this Bluetooth device is a @@ -834,7 +853,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { * * @hide */ - @FlaggedApi("com.android.bluetooth.flags.support_metadata_device_types_apis") + @FlaggedApi(Flags.FLAG_SUPPORT_METADATA_DEVICE_TYPES_APIS) @SystemApi public static final String DEVICE_TYPE_SPEAKER = "Speaker"; @@ -844,7 +863,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { * * @hide */ - @FlaggedApi("com.android.bluetooth.flags.support_metadata_device_types_apis") + @FlaggedApi(Flags.FLAG_SUPPORT_METADATA_DEVICE_TYPES_APIS) @SystemApi public static final String DEVICE_TYPE_HEADSET = "Headset"; @@ -854,7 +873,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { * * @hide */ - @FlaggedApi("com.android.bluetooth.flags.support_metadata_device_types_apis") + @FlaggedApi(Flags.FLAG_SUPPORT_METADATA_DEVICE_TYPES_APIS) @SystemApi public static final String DEVICE_TYPE_CARKIT = "Carkit"; @@ -864,7 +883,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { * * @hide */ - @FlaggedApi("com.android.bluetooth.flags.support_metadata_device_types_apis") + @FlaggedApi(Flags.FLAG_SUPPORT_METADATA_DEVICE_TYPES_APIS) @SystemApi public static final String DEVICE_TYPE_HEARING_AID = "HearingAid"; @@ -1326,6 +1345,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { value = { ADDRESS_TYPE_PUBLIC, ADDRESS_TYPE_RANDOM, + ADDRESS_TYPE_ANONYMOUS, ADDRESS_TYPE_UNKNOWN, }) public @interface AddressType {} @@ -1339,6 +1359,41 @@ public final class BluetoothDevice implements Parcelable, Attributable { /** Address type is unknown or unavailable */ public static final int ADDRESS_TYPE_UNKNOWN = 0xFFFF; + /** Address type used to indicate an anonymous advertisement. */ + @FlaggedApi(Flags.FLAG_GET_ADDRESS_TYPE_API) + public static final int ADDRESS_TYPE_ANONYMOUS = 0xFF; + + /** + * Indicates default active audio device policy is applied to this device + * + * @hide + */ + @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION) + @SystemApi + public static final int ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT = 0; + + /** + * Indicates all profiles active audio device policy is applied to this device + * + *

all profiles are active upon device connection + * + * @hide + */ + @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION) + @SystemApi + public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_ACTIVE_UPON_CONNECTION = 1; + + /** + * Indicates all profiles inactive audio device policy is applied to this device + * + *

all profiles are inactive upon device connection + * + * @hide + */ + @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION) + @SystemApi + public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_INACTIVE_UPON_CONNECTION = 2; + private static final String NULL_MAC_ADDRESS = "00:00:00:00:00:00"; private final String mAddress; @@ -1368,10 +1423,17 @@ public final class BluetoothDevice implements Parcelable, Attributable { throw new IllegalArgumentException(address + " is not a valid Bluetooth address"); } - if (addressType != ADDRESS_TYPE_PUBLIC && addressType != ADDRESS_TYPE_RANDOM) { + if (addressType != ADDRESS_TYPE_PUBLIC + && addressType != ADDRESS_TYPE_RANDOM + && addressType != ADDRESS_TYPE_ANONYMOUS) { throw new IllegalArgumentException(addressType + " is not a Bluetooth address type"); } + if (addressType == ADDRESS_TYPE_ANONYMOUS && !NULL_MAC_ADDRESS.equals(address)) { + throw new IllegalArgumentException( + "Invalid address for anonymous address type: " + getAnonymizedAddress()); + } + mAddress = address; mAddressType = addressType; mAttributionSource = AttributionSource.myAttributionSource(); @@ -1539,12 +1601,13 @@ public final class BluetoothDevice implements Parcelable, Attributable { } /** - * Returns the address type of this BluetoothDevice. + * Returns the address type of this BluetoothDevice, one of {@link ADDRESS_TYPE_PUBLIC}, {@link + * ADDRESS_TYPE_RANDOM}, {@link ADDRESS_TYPE_ANONYMOUS}, or {@link ADDRESS_TYPE_UNKNOWN}. * * @return Bluetooth address type - * @hide */ - public int getAddressType() { + @FlaggedApi(Flags.FLAG_GET_ADDRESS_TYPE_API) + public @AddressType int getAddressType() { if (DBG) Log.d(TAG, "mAddressType: " + mAddressType); return mAddressType; } @@ -3635,6 +3698,118 @@ public final class BluetoothDevice implements Parcelable, Attributable { return defaultValue; } + /** @hide */ + @IntDef( + value = { + BluetoothStatusCodes.SUCCESS, + BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED, + BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED, + BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION, + BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SetActiveAudioDevicePolicyReturnValues {} + + /** + * Active audio device policy for this device + * + * @hide + */ + @IntDef( + prefix = "ACTIVE_AUDIO_DEVICE_POLICY_", + value = { + ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT, + ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_ACTIVE_UPON_CONNECTION, + ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_INACTIVE_UPON_CONNECTION + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ActiveAudioDevicePolicy {} + + /** + * Set the active audio device policy for this {@link BluetoothDevice} to indicate what {@link + * ActiveAudioDevicePolicy} is applied upon device connection. + * + *

This API allows application to set the audio device profiles active policy upon + * connection, only bonded device's policy will be persisted across Bluetooth restart. Policy + * setting will be removed when the device's bond state is moved to {@link #BOND_NONE}. + * + * @param activeAudioDevicePolicy is the active audio device policy to set for this device + * @return whether the policy was set properly + * @throws IllegalArgumentException if this BluetoothDevice object has an invalid address + * @hide + */ + @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION) + @SystemApi + @RequiresBluetoothConnectPermission + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public @SetActiveAudioDevicePolicyReturnValues int setActiveAudioDevicePolicy( + @ActiveAudioDevicePolicy int activeAudioDevicePolicy) { + if (DBG) log("setActiveAudioDevicePolicy(" + activeAudioDevicePolicy + ")"); + if (!BluetoothAdapter.checkBluetoothAddress(getAddress())) { + throw new IllegalArgumentException("device cannot have an invalid address"); + } + + final IBluetooth service = getService(); + final int defaultValue = BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; + if (service == null || !isBluetoothEnabled()) { + Log.e(TAG, "Bluetooth is not enabled. Cannot set active audio device policy."); + if (DBG) log(Log.getStackTraceString(new Throwable())); + } else { + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + service.setActiveAudioDevicePolicy( + this, activeAudioDevicePolicy, mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + } catch (TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } catch (RemoteException e) { + Log.e(TAG, "", e); + throw e.rethrowAsRuntimeException(); + } + } + return defaultValue; + } + + /** + * Get the active audio device policy for this {@link BluetoothDevice}. + * + * @return active audio device policy of the device + * @hide + */ + @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION) + @SystemApi + @RequiresBluetoothConnectPermission + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public @ActiveAudioDevicePolicy int getActiveAudioDevicePolicy() { + if (DBG) log("getActiveAudioDevicePolicy"); + final IBluetooth service = getService(); + final int defaultValue = ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT; + if (service == null || !isBluetoothEnabled()) { + Log.e(TAG, "Bluetooth is not enabled. Cannot get active audio device policy."); + if (DBG) log(Log.getStackTraceString(new Throwable())); + } else { + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + service.getActiveAudioDevicePolicy(this, mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + } catch (TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } catch (RemoteException e) { + Log.e(TAG, "", e); + throw e.rethrowAsRuntimeException(); + } + } + return defaultValue; + } + private static void log(String msg) { Log.d(TAG, msg); } diff --git a/framework/java/android/bluetooth/BluetoothGatt.java b/framework/java/android/bluetooth/BluetoothGatt.java index e09aa434b9e9c2c7765db0162c7bf3e0d0ec75a4..76d1cf420f37416dca0f5e7c3bdac710e6eeeae1 100644 --- a/framework/java/android/bluetooth/BluetoothGatt.java +++ b/framework/java/android/bluetooth/BluetoothGatt.java @@ -18,6 +18,7 @@ package android.bluetooth; import static android.bluetooth.BluetoothUtils.getSyncTimeout; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresNoPermission; @@ -35,6 +36,7 @@ import android.os.ParcelUuid; import android.os.RemoteException; import android.util.Log; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.lang.annotation.Retention; @@ -44,6 +46,7 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.TimeoutException; + /** * Public API for the Bluetooth GATT Profile. * @@ -128,6 +131,13 @@ public final class BluetoothGatt implements BluetoothProfile { /** A remote device connection is congested. */ public static final int GATT_CONNECTION_CONGESTED = 0x8f; + /** + * GATT connection timed out, likely due to the remote device being out of range or not + * advertising as connectable. + */ + @FlaggedApi(Flags.FLAG_ENUMERATE_GATT_ERRORS) + public static final int GATT_CONNECTION_TIMEOUT = 0x93; + /** A GATT operation failed, errors other than the above */ public static final int GATT_FAILURE = 0x101; @@ -1677,6 +1687,13 @@ public final class BluetoothGatt implements BluetoothProfile { } throw e.rethrowAsRuntimeException(); } + if (Flags.gattFixDeviceBusy()) { + if (requestStatus != BluetoothStatusCodes.SUCCESS) { + synchronized (mDeviceBusyLock) { + mDeviceBusy = false; + } + } + } return requestStatus; } @@ -1828,6 +1845,11 @@ public final class BluetoothGatt implements BluetoothProfile { } throw e.rethrowAsRuntimeException(); } + if (Flags.gattFixDeviceBusy()) { + synchronized (mDeviceBusyLock) { + mDeviceBusy = false; + } + } return BluetoothStatusCodes.ERROR_UNKNOWN; } diff --git a/framework/java/android/bluetooth/BluetoothHapClient.java b/framework/java/android/bluetooth/BluetoothHapClient.java index 92c651bfb7de024cb5acb990b31bd0ba049183dd..185c00e94f7bc3da7554386c410e9e59d2470b9a 100644 --- a/framework/java/android/bluetooth/BluetoothHapClient.java +++ b/framework/java/android/bluetooth/BluetoothHapClient.java @@ -36,6 +36,7 @@ import android.os.RemoteException; import android.util.CloseGuard; import android.util.Log; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.lang.annotation.Retention; @@ -385,7 +386,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) public static final int PRESET_INDEX_UNAVAILABLE = IBluetoothHapClient.PRESET_INDEX_UNAVAILABLE; /** @@ -874,7 +875,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { @@ -909,7 +910,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { @@ -1051,7 +1052,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { @@ -1085,7 +1086,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { @@ -1116,7 +1117,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { @@ -1150,7 +1151,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { @@ -1180,7 +1181,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable * @hide */ @SystemApi - @FlaggedApi("com.android.bluetooth.flags.settings_can_control_hap_preset") + @FlaggedApi(Flags.FLAG_SETTINGS_CAN_CONTROL_HAP_PRESET) @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { diff --git a/framework/java/android/bluetooth/BluetoothHidHost.java b/framework/java/android/bluetooth/BluetoothHidHost.java index 4c55ad19dcd0d477cdb2ceedb9fbc2d19262918a..69bdf2115ac46a96e9640db75f71c7a569a38295 100644 --- a/framework/java/android/bluetooth/BluetoothHidHost.java +++ b/framework/java/android/bluetooth/BluetoothHidHost.java @@ -19,12 +19,14 @@ package android.bluetooth; import static android.bluetooth.BluetoothUtils.getSyncTimeout; import android.Manifest; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SuppressLint; import android.annotation.SystemApi; +import android.bluetooth.BluetoothDevice.Transport; import android.bluetooth.annotations.RequiresBluetoothConnectPermission; import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission; import android.bluetooth.annotations.RequiresLegacyBluetoothPermission; @@ -34,10 +36,12 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.concurrent.TimeoutException; /** @@ -64,12 +68,16 @@ public final class BluetoothHidHost implements BluetoothProfile { *

    *
  • {@link #EXTRA_STATE} - The current state of the profile. *
  • {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. + *
  • {@link BluetoothDevice#EXTRA_TRANSPORT} - Transport of the connection. *
  • {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. *
* *

{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of {@link * #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, {@link #STATE_CONNECTED}, {@link * #STATE_DISCONNECTING}. + * + *

{@link BluetoothDevice#EXTRA_TRANSPORT} can be any of {@link + * BluetoothDevice#TRANSPORT_BREDR}, {@link BluetoothDevice#TRANSPORT_LE}. */ @SuppressLint("ActionValue") @RequiresLegacyBluetoothPermission @@ -464,6 +472,60 @@ public final class BluetoothHidHost implements BluetoothProfile { return defaultValue; } + /** + * Set preferred transport for the device + * + *

The device should already be paired, services must have been discovered. This API is + * effective only if both the HID and HOGP are supported on the remote device. + * + * @param device paired bluetooth device + * @param transport the preferred transport to set for this device + * @return true if preferred transport is set, false on error + * @throws IllegalArgumentException if the {@code device} invalid. + * @hide + */ + @FlaggedApi(Flags.FLAG_ALLOW_SWITCHING_HID_AND_HOGP) + @SystemApi + @RequiresBluetoothConnectPermission + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public boolean setPreferredTransport( + @NonNull BluetoothDevice device, @Transport int transport) { + if (DBG) log("setPreferredTransport(" + device + ", " + transport + ")"); + + Objects.requireNonNull(device, "device must not be null"); + + if (transport != BluetoothDevice.TRANSPORT_AUTO + && transport != BluetoothDevice.TRANSPORT_BREDR + && transport != BluetoothDevice.TRANSPORT_LE) { + throw new IllegalArgumentException("Invalid transport value"); + } + + final IBluetoothHidHost 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()) { + Log.w(TAG, "Not ready"); + } else if (!isValidDevice(device)) { + throw new IllegalArgumentException("Invalid device"); + } else { + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + service.setPreferredTransport(device, transport, mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + } catch (RemoteException | TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } + } + return defaultValue; + } + /** * Get the priority of the profile. * @@ -524,6 +586,48 @@ public final class BluetoothHidHost implements BluetoothProfile { return defaultValue; } + /** + * Get the preferred transport for the device. + * + * @param device Bluetooth device + * @return preferred transport for the device + * @throws IllegalArgumentException if the {@code device} invalid. + * @hide + */ + @FlaggedApi(Flags.FLAG_ALLOW_SWITCHING_HID_AND_HOGP) + @SystemApi + @RequiresBluetoothConnectPermission + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public @Transport int getPreferredTransport(@NonNull BluetoothDevice device) { + if (VDBG) log("getPreferredTransport(" + device + ")"); + + Objects.requireNonNull(device, "device must not be null"); + + final IBluetoothHidHost service = getService(); + final int defaultValue = BluetoothDevice.TRANSPORT_AUTO; + if (service == null) { + Log.w(TAG, "Proxy not attached to service"); + if (DBG) log(Log.getStackTraceString(new Throwable())); + } else if (!isEnabled()) { + Log.w(TAG, "Not ready"); + } else if (!isValidDevice(device)) { + throw new IllegalArgumentException("Invalid device"); + } else { + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + service.getPreferredTransport(device, mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + } catch (RemoteException | TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } + } + return defaultValue; + } + private boolean isEnabled() { return mAdapter.getState() == BluetoothAdapter.STATE_ON; } diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java index 5a538d1145607cd8c980592870550743e4d0f50d..ae0883b9b9b47aebf2899d002560495b06e0101e 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudio.java +++ b/framework/java/android/bluetooth/BluetoothLeAudio.java @@ -20,6 +20,7 @@ package android.bluetooth; import static android.bluetooth.BluetoothUtils.getSyncTimeout; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -38,6 +39,7 @@ import android.os.RemoteException; import android.util.CloseGuard; import android.util.Log; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.lang.annotation.Retention; @@ -61,7 +63,7 @@ import java.util.concurrent.TimeoutException; */ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { private static final String TAG = "BluetoothLeAudio"; - private static final boolean DBG = false; + private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean VDBG = false; private final Map mCallbackExecutorMap = new HashMap<>(); @@ -85,6 +87,15 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { }) @interface GroupStatus {} + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + value = { + GROUP_STREAM_STATUS_IDLE, + GROUP_STREAM_STATUS_STREAMING, + }) + @interface GroupStreamStatus {} + /** * Callback invoked when callback is registered and when codec config changes on the remote * device. @@ -127,6 +138,22 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { */ @SystemApi void onGroupStatusChanged(int groupId, @GroupStatus int groupStatus); + + /** + * Callback invoked when the group's stream status changes. + * + * @param groupId the group id + * @param groupStreamStatus streaming or idle state. + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_CALLBACK_ON_GROUP_STREAM_STATUS) + @SystemApi + default void onGroupStreamStatusChanged( + int groupId, @GroupStreamStatus int groupStreamStatus) { + if (DBG) { + Log.d(TAG, " onGroupStreamStatusChanged is not implemented."); + } + } } @SuppressLint("AndroidFrameworkBluetoothPermission") @@ -174,6 +201,21 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { executor.execute(() -> callback.onGroupStatusChanged(groupId, groupStatus)); } } + + @Override + public void onGroupStreamStatusChanged(int groupId, int groupStreamStatus) { + if (Flags.leaudioCallbackOnGroupStreamStatus()) { + for (Map.Entry callbackExecutorEntry : + mCallbackExecutorMap.entrySet()) { + BluetoothLeAudio.Callback callback = callbackExecutorEntry.getKey(); + Executor executor = callbackExecutorEntry.getValue(); + executor.execute( + () -> + callback.onGroupStreamStatusChanged( + groupId, groupStreamStatus)); + } + } + } }; /** @@ -620,6 +662,23 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable { */ public static final int GROUP_STATUS_INACTIVE = IBluetoothLeAudio.GROUP_STATUS_INACTIVE; + /** + * Indicating that group stream is in IDLE (not streaming) + * + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_CALLBACK_ON_GROUP_STREAM_STATUS) + public static final int GROUP_STREAM_STATUS_IDLE = IBluetoothLeAudio.GROUP_STREAM_STATUS_IDLE; + + /** + * Indicating that group is STREAMING + * + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_CALLBACK_ON_GROUP_STREAM_STATUS) + public static final int GROUP_STREAM_STATUS_STREAMING = + IBluetoothLeAudio.GROUP_STREAM_STATUS_STREAMING; + private IBluetoothLeAudio mService; /** diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java index acf95c77e7c3240acd503c0f6393c56dc866c02f..4c820b68d363ef2c37b8311a6a348433a7db880d 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java +++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java @@ -16,12 +16,15 @@ package android.bluetooth; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; @@ -73,11 +76,18 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable { value = { SAMPLE_RATE_NONE, SAMPLE_RATE_8000, + SAMPLE_RATE_11025, SAMPLE_RATE_16000, + SAMPLE_RATE_22050, SAMPLE_RATE_24000, SAMPLE_RATE_32000, SAMPLE_RATE_44100, - SAMPLE_RATE_48000 + SAMPLE_RATE_48000, + SAMPLE_RATE_88200, + SAMPLE_RATE_96000, + SAMPLE_RATE_176400, + SAMPLE_RATE_192000, + SAMPLE_RATE_384000 }) @Retention(RetentionPolicy.SOURCE) public @interface SampleRate {} @@ -85,16 +95,24 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable { /** * Codec sample rate 0 Hz. Default value used for codec sample rate. Values are the bit mask as * defined in the Bluetooth Assigned Numbers, Generic Audio, Supported_Sampling_Frequencies - * table Note: We use only part of it. + * table. */ public static final int SAMPLE_RATE_NONE = 0; /** Codec sample rate 8000 Hz. */ public static final int SAMPLE_RATE_8000 = 0x01 << 0; + /** Codec sample rate 11025 Hz. */ + @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_SAMPLING_FREQUENCIES) + public static final int SAMPLE_RATE_11025 = 0x01 << 1; + /** Codec sample rate 16000 Hz. */ public static final int SAMPLE_RATE_16000 = 0x01 << 2; + /** Codec sample rate 22050 Hz. */ + @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_SAMPLING_FREQUENCIES) + public static final int SAMPLE_RATE_22050 = 0x01 << 3; + /** Codec sample rate 24000 Hz. */ public static final int SAMPLE_RATE_24000 = 0x01 << 4; @@ -107,6 +125,26 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable { /** Codec sample rate 48000 Hz. */ public static final int SAMPLE_RATE_48000 = 0x01 << 7; + /** Codec sample rate 88200 Hz. */ + @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_SAMPLING_FREQUENCIES) + public static final int SAMPLE_RATE_88200 = 0x01 << 8; + + /** Codec sample rate 96000 Hz. */ + @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_SAMPLING_FREQUENCIES) + public static final int SAMPLE_RATE_96000 = 0x01 << 9; + + /** Codec sample rate 176400 Hz. */ + @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_SAMPLING_FREQUENCIES) + public static final int SAMPLE_RATE_176400 = 0x01 << 10; + + /** Codec sample rate 192000 Hz. */ + @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_SAMPLING_FREQUENCIES) + public static final int SAMPLE_RATE_192000 = 0x01 << 11; + + /** Codec sample rate 384000 Hz. */ + @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_SAMPLING_FREQUENCIES) + public static final int SAMPLE_RATE_384000 = 0x01 << 12; + /** @hide */ @IntDef( flag = true, diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java index 0cff465a462df175077851b770b1154046642ef5..680c15dfca721528c75831a5d47195e4cc7ebab2 100644 --- a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java +++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfigMetadata.java @@ -29,13 +29,18 @@ import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_8000; import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE; import static android.bluetooth.BluetoothLeAudioCodecConfig.SampleRate; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.bluetooth.BluetoothLeAudioCodecConfig.FrameDuration; +import android.bluetooth.BluetoothLeAudioCodecConfig.SampleRate; import android.bluetooth.BluetoothUtils.TypeValueEntry; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; @@ -70,6 +75,13 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable { private static final int CONFIG_SAMPLING_FREQUENCY_32000 = 0x06; private static final int CONFIG_SAMPLING_FREQUENCY_44100 = 0x07; private static final int CONFIG_SAMPLING_FREQUENCY_48000 = 0x08; + private static final int CONFIG_SAMPLING_FREQUENCY_11025 = 0x09; + private static final int CONFIG_SAMPLING_FREQUENCY_22050 = 0x0a; + private static final int CONFIG_SAMPLING_FREQUENCY_88200 = 0x0b; + private static final int CONFIG_SAMPLING_FREQUENCY_96000 = 0x0c; + private static final int CONFIG_SAMPLING_FREQUENCY_176400 = 0x0d; + private static final int CONFIG_SAMPLING_FREQUENCY_192000 = 0x0e; + private static final int CONFIG_SAMPLING_FREQUENCY_384000 = 0x0f; /** Audio codec config frame duration from metadata. */ private static final int CONFIG_FRAME_DURATION_UNKNOWN = -1; @@ -375,7 +387,20 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable { && sampleRate != SAMPLE_RATE_32000 && sampleRate != SAMPLE_RATE_44100 && sampleRate != SAMPLE_RATE_48000) { - throw new IllegalArgumentException("Invalid sample rate " + sampleRate); + + if (Flags.leaudioAddSamplingFrequencies()) { + if (sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_11025 + && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_22050 + && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_88200 + && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_96000 + && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_176400 + && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_192000 + && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_384000) { + throw new IllegalArgumentException("Invalid sample rate " + sampleRate); + } + } else { + throw new IllegalArgumentException("Invalid sample rate " + sampleRate); + } } mSampleRate = sampleRate; return this; @@ -504,6 +529,24 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable { case CONFIG_SAMPLING_FREQUENCY_48000: return SAMPLE_RATE_48000; default: + if (Flags.leaudioAddSamplingFrequencies()) { + switch (samplingFrequencyValue) { + case CONFIG_SAMPLING_FREQUENCY_11025: + return BluetoothLeAudioCodecConfig.SAMPLE_RATE_11025; + case CONFIG_SAMPLING_FREQUENCY_22050: + return BluetoothLeAudioCodecConfig.SAMPLE_RATE_22050; + case CONFIG_SAMPLING_FREQUENCY_88200: + return BluetoothLeAudioCodecConfig.SAMPLE_RATE_88200; + case CONFIG_SAMPLING_FREQUENCY_96000: + return BluetoothLeAudioCodecConfig.SAMPLE_RATE_96000; + case CONFIG_SAMPLING_FREQUENCY_176400: + return BluetoothLeAudioCodecConfig.SAMPLE_RATE_176400; + case CONFIG_SAMPLING_FREQUENCY_192000: + return BluetoothLeAudioCodecConfig.SAMPLE_RATE_192000; + case CONFIG_SAMPLING_FREQUENCY_384000: + return BluetoothLeAudioCodecConfig.SAMPLE_RATE_384000; + } + } return SAMPLE_RATE_NONE; } } @@ -523,6 +566,24 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable { case SAMPLE_RATE_48000: return CONFIG_SAMPLING_FREQUENCY_48000; default: + if (Flags.leaudioAddSamplingFrequencies()) { + switch (sampleRateBitSet) { + case BluetoothLeAudioCodecConfig.SAMPLE_RATE_11025: + return CONFIG_SAMPLING_FREQUENCY_11025; + case BluetoothLeAudioCodecConfig.SAMPLE_RATE_22050: + return CONFIG_SAMPLING_FREQUENCY_22050; + case BluetoothLeAudioCodecConfig.SAMPLE_RATE_88200: + return CONFIG_SAMPLING_FREQUENCY_88200; + case BluetoothLeAudioCodecConfig.SAMPLE_RATE_96000: + return CONFIG_SAMPLING_FREQUENCY_96000; + case BluetoothLeAudioCodecConfig.SAMPLE_RATE_176400: + return CONFIG_SAMPLING_FREQUENCY_176400; + case BluetoothLeAudioCodecConfig.SAMPLE_RATE_192000: + return CONFIG_SAMPLING_FREQUENCY_192000; + case BluetoothLeAudioCodecConfig.SAMPLE_RATE_384000: + return CONFIG_SAMPLING_FREQUENCY_384000; + } + } return CONFIG_SAMPLING_FREQUENCY_UNKNOWN; } } diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java index 4c3d957c05bae7e38e65dc2a1d32aa81a99bfb70..a74917af044294fd8db2b355d36167f9027da22c 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java @@ -35,6 +35,8 @@ import android.os.RemoteException; import android.util.CloseGuard; import android.util.Log; +import com.android.bluetooth.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -433,7 +435,7 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile, Au * @param broadcastId broadcast ID as defined in the BASS specification * @hide */ - @FlaggedApi("com.android.bluetooth.flags.leaudio_broadcast_monitor_source_sync_status") + @FlaggedApi(Flags.FLAG_LEAUDIO_BROADCAST_MONITOR_SOURCE_SYNC_STATUS) @SystemApi default void onSourceLost(int broadcastId) {} } diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java b/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java index bdfb0678714fb3b4fab6c554b05baf9f26866350..2d7db9199c42139957d636afc787238de4a8bae4 100644 --- a/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java +++ b/framework/java/android/bluetooth/BluetoothLeBroadcastMetadata.java @@ -25,6 +25,8 @@ import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -337,7 +339,7 @@ public final class BluetoothLeBroadcastMetadata implements Parcelable { * * @hide */ - @FlaggedApi("com.android.bluetooth.flags.leaudio_broadcast_monitor_source_sync_status") + @FlaggedApi(Flags.FLAG_LEAUDIO_BROADCAST_MONITOR_SOURCE_SYNC_STATUS) @SystemApi public static final int RSSI_UNKNOWN = 0x7F; @@ -351,7 +353,7 @@ public final class BluetoothLeBroadcastMetadata implements Parcelable { * @return the RSSI {@link #RSSI_UNKNOWN} if unknown * @hide */ - @FlaggedApi("com.android.bluetooth.flags.leaudio_broadcast_monitor_source_sync_status") + @FlaggedApi(Flags.FLAG_LEAUDIO_BROADCAST_MONITOR_SOURCE_SYNC_STATUS) @SystemApi public @IntRange(from = -127, to = 127) int getRssi() { return mRssi; @@ -490,7 +492,7 @@ public final class BluetoothLeBroadcastMetadata implements Parcelable { private BluetoothDevice mSourceDevice = null; private int mSourceAdvertisingSid = UNKNOWN_VALUE_PLACEHOLDER; private int mBroadcastId = UNKNOWN_VALUE_PLACEHOLDER; - private int mPaSyncInterval = UNKNOWN_VALUE_PLACEHOLDER; + private int mPaSyncInterval = PA_SYNC_INTERVAL_UNKNOWN; private boolean mIsEncrypted = false; private boolean mIsPublicBroadcast = false; private String mBroadcastName = null; @@ -729,7 +731,7 @@ public final class BluetoothLeBroadcastMetadata implements Parcelable { * @throws IllegalArgumentException if rssi is not in the range [-127, 127]. * @hide */ - @FlaggedApi("com.android.bluetooth.flags.leaudio_broadcast_monitor_source_sync_status") + @FlaggedApi(Flags.FLAG_LEAUDIO_BROADCAST_MONITOR_SOURCE_SYNC_STATUS) @SystemApi @NonNull public Builder setRssi(@IntRange(from = -127, to = 127) int rssi) { diff --git a/framework/java/android/bluetooth/BluetoothManager.java b/framework/java/android/bluetooth/BluetoothManager.java index dd6b86dd2a3e0a6ca8e3af86088fc57ae21f0e00..d9ff0dac015209297de41c158abba098bd73a14d 100644 --- a/framework/java/android/bluetooth/BluetoothManager.java +++ b/framework/java/android/bluetooth/BluetoothManager.java @@ -63,10 +63,7 @@ public final class BluetoothManager { /** @hide */ public BluetoothManager(Context context) { - mAttributionSource = - (context != null) - ? context.getAttributionSource() - : AttributionSource.myAttributionSource(); + mAttributionSource = context.getAttributionSource(); mAdapter = BluetoothAdapter.createAdapter(mAttributionSource); } diff --git a/framework/java/android/bluetooth/BluetoothProfileConnector.java b/framework/java/android/bluetooth/BluetoothProfileConnector.java deleted file mode 100644 index a5c94f6d99f07b3ea46cad332c0979bb5418749e..0000000000000000000000000000000000000000 --- a/framework/java/android/bluetooth/BluetoothProfileConnector.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.bluetooth; - -import android.annotation.SuppressLint; -import android.content.ComponentName; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.RemoteException; -import android.util.CloseGuard; -import android.util.Log; - -import java.util.Objects; - -/** - * Connector for Bluetooth profile proxies to bind manager service and profile services - * - * @hide - */ -@SuppressLint("AndroidFrameworkBluetoothPermission") -public final class BluetoothProfileConnector extends Handler { - private static final String TAG = BluetoothProfileConnector.class.getSimpleName(); - private final CloseGuard mCloseGuard = new CloseGuard(); - private final int mProfileId; - private BluetoothProfile.ServiceListener mServiceListener; - private final BluetoothProfile mProfileProxy; - private String mPackageName; - private final IBluetoothManager mBluetoothManager; - private boolean mBound = false; - - private static final int MESSAGE_SERVICE_CONNECTED = 100; - private static final int MESSAGE_SERVICE_DISCONNECTED = 101; - - private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback = - new IBluetoothStateChangeCallback.Stub() { - public void onBluetoothStateChange(boolean up) { - if (up) { - doBind(); - } else { - doUnbind(); - } - } - }; - - private final IBluetoothProfileServiceConnection mConnection = - new IBluetoothProfileServiceConnection.Stub() { - @Override - public void onServiceConnected(ComponentName className, IBinder service) { - Log.d( - TAG, - "Proxy object connected for " - + BluetoothProfile.getProfileName(mProfileId)); - mProfileProxy.onServiceConnected(service); - sendEmptyMessage(MESSAGE_SERVICE_CONNECTED); - } - - @Override - public void onServiceDisconnected(ComponentName className) { - Log.d( - TAG, - "Proxy object disconnected for " - + BluetoothProfile.getProfileName(mProfileId)); - boolean bound = mBound; - doUnbind(); - if (bound) { - sendEmptyMessage(MESSAGE_SERVICE_DISCONNECTED); - } - } - }; - - /** @hide */ - public BluetoothProfileConnector( - Looper looper, - BluetoothProfile profile, - int profileId, - IBluetoothManager bluetoothManager) { - super(looper); - mProfileId = profileId; - mProfileProxy = profile; - mBluetoothManager = Objects.requireNonNull(bluetoothManager); - } - - BluetoothProfileConnector(BluetoothProfile profile, int profileId) { - this( - Looper.getMainLooper(), - profile, - profileId, - BluetoothAdapter.getDefaultAdapter().getBluetoothManager()); - } - - /** @hide */ - @Override - @SuppressWarnings("Finalize") // TODO(b/314811467) - public void finalize() { - mCloseGuard.warnIfOpen(); - doUnbind(); - } - - private void doBind() { - synchronized (mConnection) { - if (!mBound) { - Log.d( - TAG, - "Binding service " - + BluetoothProfile.getProfileName(mProfileId) - + " for " - + mPackageName); - mCloseGuard.open("doUnbind"); - try { - mBluetoothManager.bindBluetoothProfileService(mProfileId, mConnection); - mBound = true; - } catch (RemoteException re) { - Log.e( - TAG, - "Failed to bind service. " - + BluetoothProfile.getProfileName(mProfileId), - re); - } - } - } - } - - private void doUnbind() { - synchronized (mConnection) { - if (mBound) { - Log.d( - TAG, - "Unbinding service " - + BluetoothProfile.getProfileName(mProfileId) - + " for " - + mPackageName); - mCloseGuard.close(); - try { - mBluetoothManager.unbindBluetoothProfileService(mProfileId, mConnection); - mBound = false; - } catch (RemoteException re) { - Log.e( - TAG, - "Unable to unbind service " - + BluetoothProfile.getProfileName(mProfileId), - re); - } finally { - mProfileProxy.onServiceDisconnected(); - } - } - } - } - - /** @hide */ - public void connect(String packageName, BluetoothProfile.ServiceListener listener) { - mPackageName = packageName; - mServiceListener = listener; - - try { - mBluetoothManager.registerStateChangeCallback(mBluetoothStateChangeCallback); - } catch (RemoteException re) { - Log.e(TAG, "Failed to register state change callback.", re); - } - } - - /** @hide */ - public void disconnect() { - if (mServiceListener != null) { - BluetoothProfile.ServiceListener listener = mServiceListener; - mServiceListener = null; - listener.onServiceDisconnected(mProfileId); - } - try { - mBluetoothManager.unregisterStateChangeCallback(mBluetoothStateChangeCallback); - } catch (RemoteException re) { - Log.e(TAG, "Failed to unregister state change callback", re); - } - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MESSAGE_SERVICE_CONNECTED: - if (mServiceListener != null) { - mServiceListener.onServiceConnected(mProfileId, mProfileProxy); - } - break; - case MESSAGE_SERVICE_DISCONNECTED: - if (mServiceListener != null) { - mServiceListener.onServiceDisconnected(mProfileId); - } - break; - } - } -} diff --git a/framework/java/android/bluetooth/BluetoothServerSocket.java b/framework/java/android/bluetooth/BluetoothServerSocket.java index 540df737a6c9161020b1b5a926f79ea18d0abb18..867180dd8d939c47ec6da3a78f4269435d0747b9 100644 --- a/framework/java/android/bluetooth/BluetoothServerSocket.java +++ b/framework/java/android/bluetooth/BluetoothServerSocket.java @@ -16,20 +16,16 @@ package android.bluetooth; -import static android.bluetooth.BluetoothUtils.getSyncTimeout; import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; import android.os.Handler; import android.os.ParcelUuid; -import android.os.RemoteException; import android.util.Log; -import com.android.modules.utils.SynchronousResultReceiver; import java.io.Closeable; import java.io.IOException; -import java.util.concurrent.TimeoutException; /** * A listening Bluetooth socket. @@ -192,54 +188,32 @@ public final class BluetoothServerSocket implements Closeable { BluetoothSocket acceptedSocket = null; try { acceptedSocket = mSocket.accept(timeout); - logL2capcocServerConnection( + SocketMetrics.logSocketAccept( acceptedSocket, + mSocket, + mType, + mChannel, timeout, - BluetoothSocket.RESULT_L2CAP_CONN_SUCCESS, + SocketMetrics.RESULT_L2CAP_CONN_SUCCESS, + mSocketCreationTimeMillis, + mSocketCreationLatencyMillis, socketConnectionTime); return acceptedSocket; } catch (IOException e) { - logL2capcocServerConnection( + SocketMetrics.logSocketAccept( acceptedSocket, + mSocket, + mType, + mChannel, timeout, - BluetoothSocket.RESULT_L2CAP_CONN_SERVER_FAILURE, + SocketMetrics.RESULT_L2CAP_CONN_SERVER_FAILURE, + mSocketCreationTimeMillis, + mSocketCreationLatencyMillis, socketConnectionTime); throw e; } } - private void logL2capcocServerConnection( - BluetoothSocket acceptedSocket, - int timeout, - int result, - long socketConnectionTimeMillis) { - if (mType != BluetoothSocket.TYPE_L2CAP_LE) { - return; - } - IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(); - if (bluetoothProxy == null) { - Log.w(TAG, "bluetoothProxy is null while trying to log l2cap soc server connection"); - return; - } - try { - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - bluetoothProxy.logL2capcocServerConnection( - acceptedSocket == null ? null : acceptedSocket.getRemoteDevice(), - getPsm(), - mSocket.isAuth(), - result, - mSocketCreationTimeMillis, // pass creation time to calculate end to end latency - mSocketCreationLatencyMillis, // socket creation latency - socketConnectionTimeMillis, // send connection start time for connection latency - timeout, - recv); - recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); - - } catch (RemoteException | TimeoutException e) { - Log.w(TAG, "logL2capcocServerConnection failed due to remote exception"); - } - } - /** * Immediately close this socket, and release all associated resources. * diff --git a/framework/java/android/bluetooth/BluetoothSocket.java b/framework/java/android/bluetooth/BluetoothSocket.java index 6527056433952999887efc961cf08c0d0a427d10..6f6bab0baaa11a3b864bab69139ff091bce34c69 100644 --- a/framework/java/android/bluetooth/BluetoothSocket.java +++ b/framework/java/android/bluetooth/BluetoothSocket.java @@ -16,8 +16,6 @@ package android.bluetooth; -import static android.bluetooth.BluetoothUtils.getSyncTimeout; - import android.annotation.RequiresNoPermission; import android.annotation.RequiresPermission; import android.bluetooth.annotations.RequiresBluetoothConnectPermission; @@ -29,8 +27,6 @@ import android.os.ParcelUuid; import android.os.RemoteException; import android.util.Log; -import com.android.modules.utils.SynchronousResultReceiver; - import java.io.Closeable; import java.io.FileDescriptor; import java.io.IOException; @@ -41,7 +37,6 @@ import java.nio.ByteOrder; import java.util.Arrays; import java.util.Locale; import java.util.UUID; -import java.util.concurrent.TimeoutException; /** * A connected or connecting Bluetooth socket. @@ -129,16 +124,6 @@ public final class BluetoothSocket implements Closeable { /*package*/ static final int SEC_FLAG_AUTH_MITM = 1 << 3; /*package*/ static final int SEC_FLAG_AUTH_16_DIGIT = 1 << 4; - // Defined in BluetoothProtoEnums.L2capCocConnectionResult of proto logging - /*package*/ static final int RESULT_L2CAP_CONN_SUCCESS = 1; - private static final int RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_FAILED = 1000; - private static final int RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED = 1001; - private static final int RESULT_L2CAP_CONN_BLUETOOTH_UNABLE_TO_SEND_RPC = 1002; - private static final int RESULT_L2CAP_CONN_BLUETOOTH_NULL_BLUETOOTH_DEVICE = 1003; - private static final int RESULT_L2CAP_CONN_BLUETOOTH_GET_SOCKET_MANAGER_FAILED = 1004; - private static final int RESULT_L2CAP_CONN_BLUETOOTH_NULL_FILE_DESCRIPTOR = 1005; - /*package*/ static final int RESULT_L2CAP_CONN_SERVER_FAILURE = 2000; - private final int mType; /* one of TYPE_RFCOMM etc */ private BluetoothDevice mDevice; /* remote device */ private String mAddress; /* remote address */ @@ -172,8 +157,8 @@ public final class BluetoothSocket implements Closeable { private int mMaxTxPacketSize = 0; // The l2cap maximum packet size supported by the peer. private int mMaxRxPacketSize = 0; // The l2cap maximum packet size that can be received. - private long mSocketCreationTimeMillis = 0; - private long mSocketCreationLatencyMillis = 0; + private long mSocketCreationTimeNanos = 0; + private long mSocketCreationLatencyNanos = 0; private enum SocketState { INIT, @@ -234,7 +219,7 @@ public final class BluetoothSocket implements Closeable { boolean min16DigitPin) throws IOException { if (VDBG) Log.d(TAG, "Creating new BluetoothSocket of type: " + type); - mSocketCreationTimeMillis = System.currentTimeMillis(); + mSocketCreationTimeNanos = System.nanoTime(); if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && port != BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP) { @@ -266,7 +251,7 @@ public final class BluetoothSocket implements Closeable { } mInputStream = new BluetoothInputStream(this); mOutputStream = new BluetoothOutputStream(this); - mSocketCreationLatencyMillis = System.currentTimeMillis() - mSocketCreationTimeMillis; + mSocketCreationLatencyNanos = System.nanoTime() - mSocketCreationTimeNanos; } /** @@ -312,8 +297,8 @@ public final class BluetoothSocket implements Closeable { mExcludeSdp = s.mExcludeSdp; mAuthMitm = s.mAuthMitm; mMin16DigitPin = s.mMin16DigitPin; - mSocketCreationTimeMillis = s.mSocketCreationTimeMillis; - mSocketCreationLatencyMillis = s.mSocketCreationLatencyMillis; + mSocketCreationTimeNanos = s.mSocketCreationTimeNanos; + mSocketCreationLatencyNanos = s.mSocketCreationLatencyNanos; } private BluetoothSocket acceptSocket(String remoteAddr) throws IOException { @@ -445,52 +430,32 @@ public final class BluetoothSocket implements Closeable { @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void connect() throws IOException { IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(); - long socketConnectionTimeMillis = System.currentTimeMillis(); + long socketConnectionTimeNanos = System.nanoTime(); if (bluetoothProxy == null) { throw new BluetoothSocketException(BluetoothSocketException.BLUETOOTH_OFF_FAILURE); } - if (mDevice == null) { - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_NULL_BLUETOOTH_DEVICE, - socketConnectionTimeMillis); - throw new BluetoothSocketException(BluetoothSocketException.NULL_DEVICE); - } try { + if (mDevice == null) { + throw new BluetoothSocketException(BluetoothSocketException.NULL_DEVICE); + } if (mSocketState == SocketState.CLOSED) { - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED, - socketConnectionTimeMillis); throw new BluetoothSocketException(BluetoothSocketException.SOCKET_CLOSED); } IBluetoothSocketManager socketManager = bluetoothProxy.getSocketManager(); if (socketManager == null) { - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_GET_SOCKET_MANAGER_FAILED, - socketConnectionTimeMillis); throw new BluetoothSocketException(BluetoothSocketException.SOCKET_MANAGER_FAILURE); } mPfd = socketManager.connectSocket(mDevice, mType, mUuid, mPort, getSecurityFlags()); synchronized (this) { if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd); if (mSocketState == SocketState.CLOSED) { - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED, - socketConnectionTimeMillis); throw new BluetoothSocketException( - BluetoothSocketException.SOCKET_CONNECTION_FAILURE); + BluetoothSocketException.SOCKET_CLOSED); } if (mPfd == null) { - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_NULL_FILE_DESCRIPTOR, - socketConnectionTimeMillis); throw new BluetoothSocketException( - BluetoothSocketException.SOCKET_CONNECTION_FAILURE); + BluetoothSocketException.UNIX_FILE_SOCKET_CREATION_FAILURE); } FileDescriptor fd = mPfd.getFileDescriptor(); mSocket = new LocalSocket(fd); @@ -500,14 +465,9 @@ public final class BluetoothSocket implements Closeable { int channel = readInt(mSocketIS); if (channel == 0) { int errCode = (int) mSocketIS.read(); - logL2capcocClientConnection(bluetoothProxy, errCode, socketConnectionTimeMillis); throw new BluetoothSocketException(errCode); } if (channel < 0) { - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_FAILED, - socketConnectionTimeMillis); throw new BluetoothSocketException( BluetoothSocketException.SOCKET_CONNECTION_FAILURE); } @@ -515,26 +475,45 @@ public final class BluetoothSocket implements Closeable { waitSocketSignal(mSocketIS); synchronized (this) { if (mSocketState == SocketState.CLOSED) { - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED, - socketConnectionTimeMillis); throw new BluetoothSocketException(BluetoothSocketException.SOCKET_CLOSED); } mSocketState = SocketState.CONNECTED; if (DBG) Log.d(TAG, "connect(), socket connected"); } - logL2capcocClientConnection( - bluetoothProxy, RESULT_L2CAP_CONN_SUCCESS, socketConnectionTimeMillis); + } catch (BluetoothSocketException e) { + SocketMetrics.logSocketConnect( + e.getErrorCode(), + socketConnectionTimeNanos, + mType, + mDevice, + mPort, + mAuth, + mSocketCreationTimeNanos, + mSocketCreationLatencyNanos); + throw e; } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - logL2capcocClientConnection( - bluetoothProxy, - RESULT_L2CAP_CONN_BLUETOOTH_UNABLE_TO_SEND_RPC, - socketConnectionTimeMillis); + SocketMetrics.logSocketConnect( + BluetoothSocketException.RPC_FAILURE, + socketConnectionTimeNanos, + mType, + mDevice, + mPort, + mAuth, + mSocketCreationTimeNanos, + mSocketCreationLatencyNanos); throw new BluetoothSocketException( BluetoothSocketException.RPC_FAILURE, "unable to send RPC: " + e.getMessage()); } + SocketMetrics.logSocketConnect( + SocketMetrics.SOCKET_NO_ERROR, + socketConnectionTimeNanos, + mType, + mDevice, + mPort, + mAuth, + mSocketCreationTimeNanos, + mSocketCreationLatencyNanos); } /** @@ -759,28 +738,6 @@ public final class BluetoothSocket implements Closeable { } } - private void logL2capcocClientConnection( - IBluetooth bluetoothProxy, int errCode, long socketConnectionTimeMillis) { - if (mType != TYPE_L2CAP_LE) { - return; - } - try { - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - bluetoothProxy.logL2capcocClientConnection( - mDevice, - mPort, - mAuth, - errCode, - mSocketCreationTimeMillis, // to calculate end to end latency - mSocketCreationLatencyMillis, // latency of the constructor - socketConnectionTimeMillis, // to calculate the latency of connect() - recv); - recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); - } catch (RemoteException | TimeoutException e) { - Log.w(TAG, "logL2capcocClientConnection failed due to remote exception"); - } - } - /*package */ void removeChannel() {} /*package */ int getPort() { @@ -788,7 +745,7 @@ public final class BluetoothSocket implements Closeable { } /*package */ long getSocketCreationTime() { - return mSocketCreationTimeMillis; + return mSocketCreationTimeNanos; } /** diff --git a/framework/java/android/bluetooth/BluetoothSocketException.java b/framework/java/android/bluetooth/BluetoothSocketException.java index 75c21588c1b28879dffc1a843522f24a87a45f11..84348fa009c321e21a80070a6acac29c484ca3ce 100644 --- a/framework/java/android/bluetooth/BluetoothSocketException.java +++ b/framework/java/android/bluetooth/BluetoothSocketException.java @@ -18,9 +18,12 @@ package android.bluetooth; import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; +import com.android.bluetooth.flags.Flags; + import java.io.IOException; import java.lang.annotation.Retention; @@ -54,7 +57,8 @@ public class BluetoothSocketException extends IOException { SOCKET_CLOSED, SOCKET_CONNECTION_FAILURE, NULL_DEVICE, - RPC_FAILURE + RPC_FAILURE, + UNIX_FILE_SOCKET_CREATION_FAILURE, }) private @interface ErrorCode {} @@ -154,6 +158,10 @@ public class BluetoothSocketException extends IOException { /** Error code during connect when a Runtime RPC exception occurs. */ public static final int RPC_FAILURE = 20; + /** Error code during connect when the UNIX socket connection creation fails. */ + @FlaggedApi(Flags.FLAG_UNIX_FILE_SOCKET_CREATION_FAILURE) + public static final int UNIX_FILE_SOCKET_CREATION_FAILURE = 21; + /* Corresponding messages for respective error codes. */ private static final String UNSPECIFIED_MSG = "A Bluetooth Socket failure occurred"; private static final String L2CAP_UNKNOWN_MSG = "Connection failed for unknown reason"; @@ -179,6 +187,8 @@ public class BluetoothSocketException extends IOException { private static final String SOCKET_CLOSED_MSG = "socket closed"; private static final String SOCKET_CONNECTION_FAILURE_MSG = "bt socket connect failed"; private static final String NULL_DEVICE_MSG = "Connect is called on null device"; + private static final String UNIX_FILE_SOCKET_CREATION_FAILURE_MSG = + "Null file descriptor returned"; @ErrorCode private final int mErrorCode; @@ -220,6 +230,8 @@ public class BluetoothSocketException extends IOException { return SOCKET_CONNECTION_FAILURE_MSG; case NULL_DEVICE: return NULL_DEVICE_MSG; + case UNIX_FILE_SOCKET_CREATION_FAILURE: + return UNIX_FILE_SOCKET_CREATION_FAILURE_MSG; case L2CAP_ACL_FAILURE: return L2CAP_ACL_FAILURE_MSG; case L2CAP_CLIENT_SECURITY_FAILURE: diff --git a/framework/java/android/bluetooth/BluetoothUuid.java b/framework/java/android/bluetooth/BluetoothUuid.java index 97228ef9ade7a698fe8170fb4ec63c2d8b9ad9ee..613f1bf623c007d3ea8913924be268a61f716b2c 100644 --- a/framework/java/android/bluetooth/BluetoothUuid.java +++ b/framework/java/android/bluetooth/BluetoothUuid.java @@ -24,6 +24,8 @@ import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.os.ParcelUuid; +import com.android.bluetooth.flags.Flags; + import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; @@ -264,7 +266,7 @@ public final class BluetoothUuid { */ @NonNull @SystemApi - @FlaggedApi("com.android.bluetooth.flags.mfi_has_uuid") + @FlaggedApi(Flags.FLAG_MFI_HAS_UUID) public static final ParcelUuid MFI_HAS = ParcelUuid.fromString("7D74F4BD-C74A-4431-862C-CCE884371592"); diff --git a/framework/java/android/bluetooth/BluetoothVolumeControl.java b/framework/java/android/bluetooth/BluetoothVolumeControl.java index aa7f748bdd11313226b29813ada2139c3184f2a5..76c92ed2b63a366a1b98832d399ca413ffd5284f 100644 --- a/framework/java/android/bluetooth/BluetoothVolumeControl.java +++ b/framework/java/android/bluetooth/BluetoothVolumeControl.java @@ -38,6 +38,7 @@ import android.os.RemoteException; import android.util.CloseGuard; import android.util.Log; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.util.ArrayList; @@ -84,12 +85,64 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose * * @param device remote device whose volume offset changed * @param volumeOffset latest volume offset for this device + * @deprecated Use new callback which give information about a VOCS instance ID * @hide */ + @Deprecated @SystemApi void onVolumeOffsetChanged( @NonNull BluetoothDevice device, @IntRange(from = -255, to = 255) int volumeOffset); + /** + * Callback invoked when callback is registered and when volume offset changes on the remote + * device. Change can be triggered autonomously by the remote device or after volume offset + * change on the user request done by calling {@link #setVolumeOffset(device, instanceId, + * volumeOffset)} + * + * @param device remote device whose volume offset changed + * @param instanceId identifier of VOCS instance on the remote device + * @param volumeOffset latest volume offset for this VOCS instance + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_MULTIPLE_VOCS_INSTANCES_API) + @SystemApi + default void onVolumeOffsetChanged( + @NonNull BluetoothDevice device, + @IntRange(from = 1, to = 255) int instanceId, + @IntRange(from = -255, to = 255) int volumeOffset) {} + + /** + * Callback invoked when callback is registered and when audio location changes on the + * remote device. Change can be triggered autonomously by the remote device. + * + * @param device remote device whose audio location changed + * @param instanceId identifier of VOCS instance on the remote device + * @param audioLocation latest audio location for this VOCS instance + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_MULTIPLE_VOCS_INSTANCES_API) + @SystemApi + default void onVolumeOffsetAudioLocationChanged( + @NonNull BluetoothDevice device, + @IntRange(from = 1, to = 255) int instanceId, + @IntRange(from = -255, to = 255) int audioLocation) {} + + /** + * Callback invoked when callback is registered and when audio description changes on the + * remote device. Change can be triggered autonomously by the remote device. + * + * @param device remote device whose audio description changed + * @param instanceId identifier of VOCS instance on the remote device + * @param audioDescription latest audio description for this VOCS instance + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_MULTIPLE_VOCS_INSTANCES_API) + @SystemApi + default void onVolumeOffsetAudioDescriptionChanged( + @NonNull BluetoothDevice device, + @IntRange(from = 1, to = 255) int instanceId, + @NonNull String audioDescription) {} + /** * Callback for le audio connected device volume level change * @@ -100,8 +153,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose * @param volume level * @hide */ - @FlaggedApi( - "com.android.bluetooth.flags.leaudio_broadcast_volume_control_for_connected_devices") + @FlaggedApi(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_FOR_CONNECTED_DEVICES) @SystemApi default void onDeviceVolumeChanged( @NonNull BluetoothDevice device, @IntRange(from = 0, to = 255) int volume) {} @@ -112,14 +164,64 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose new IBluetoothVolumeControlCallback.Stub() { @Override public void onVolumeOffsetChanged( - @NonNull BluetoothDevice device, int volumeOffset) { + @NonNull BluetoothDevice device, int instanceId, int volumeOffset) { Attributable.setAttributionSource(device, mAttributionSource); for (Map.Entry callbackExecutorEntry : mCallbackExecutorMap.entrySet()) { BluetoothVolumeControl.Callback callback = callbackExecutorEntry.getKey(); Executor executor = callbackExecutorEntry.getValue(); - executor.execute( - () -> callback.onVolumeOffsetChanged(device, volumeOffset)); + + // The old API operates on the first instance only + if (instanceId == 1) { + try { + executor.execute( + () -> callback.onVolumeOffsetChanged(device, volumeOffset)); + } finally { + // As this deprecated callback, might not be defined; continue + } + } + if (Flags.leaudioMultipleVocsInstancesApi()) { + executor.execute( + () -> + callback.onVolumeOffsetChanged( + device, instanceId, volumeOffset)); + } + } + } + + @Override + public void onVolumeOffsetAudioLocationChanged( + @NonNull BluetoothDevice device, int instanceId, int audioLocation) { + if (Flags.leaudioMultipleVocsInstancesApi()) { + Attributable.setAttributionSource(device, mAttributionSource); + for (Map.Entry + callbackExecutorEntry : mCallbackExecutorMap.entrySet()) { + BluetoothVolumeControl.Callback callback = + callbackExecutorEntry.getKey(); + Executor executor = callbackExecutorEntry.getValue(); + executor.execute( + () -> + callback.onVolumeOffsetAudioLocationChanged( + device, instanceId, audioLocation)); + } + } + } + + @Override + public void onVolumeOffsetAudioDescriptionChanged( + @NonNull BluetoothDevice device, int instanceId, String audioDescription) { + if (Flags.leaudioMultipleVocsInstancesApi()) { + Attributable.setAttributionSource(device, mAttributionSource); + for (Map.Entry + callbackExecutorEntry : mCallbackExecutorMap.entrySet()) { + BluetoothVolumeControl.Callback callback = + callbackExecutorEntry.getKey(); + Executor executor = callbackExecutorEntry.getValue(); + executor.execute( + () -> + callback.onVolumeOffsetAudioDescriptionChanged( + device, instanceId, audioDescription)); + } } } @@ -361,36 +463,116 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose Objects.requireNonNull(callback, "callback cannot be null"); if (DBG) log("registerCallback"); synchronized (mCallbackExecutorMap) { - // If the callback map is empty, we register the service-to-app callback - if (mCallbackExecutorMap.isEmpty()) { - if (!mAdapter.isEnabled()) { - /* If Bluetooth is off, just store callback and it will be registered - * when Bluetooth is on - */ - mCallbackExecutorMap.put(callback, executor); - return; - } - try { - final IBluetoothVolumeControl service = getService(); - if (service != null) { - final SynchronousResultReceiver recv = - SynchronousResultReceiver.get(); - service.registerCallback(mCallback, mAttributionSource, recv); - recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); - } - } catch (RemoteException e) { - Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowAsRuntimeException(); - } catch (TimeoutException e) { - Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - } + if (!mAdapter.isEnabled()) { + /* If Bluetooth is off, just store callback and it will be registered + * when Bluetooth is on + */ + mCallbackExecutorMap.put(callback, executor); + return; } // 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); + + final IBluetoothVolumeControl service = getService(); + if (service == null) { + return; + } + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + + /* If the callback map is empty, we register the service-to-app callback. + * Otherwise, callback is registered in mCallbackExecutorMap and we just notify + * user over callback with current values. + */ + boolean isRegisterCallbackRequired = mCallbackExecutorMap.isEmpty(); + mCallbackExecutorMap.put(callback, executor); + + if (isRegisterCallbackRequired) { + service.registerCallback(mCallback, mAttributionSource, recv); + } else { + service.notifyNewRegisteredCallback( + new IBluetoothVolumeControlCallback.Stub() { + @Override + public void onVolumeOffsetChanged( + BluetoothDevice device, int instanceId, int volumeOffset) + throws RemoteException { + Attributable.setAttributionSource(device, mAttributionSource); + + // The old API operates on the first instance only + if (instanceId == 1) { + try { + executor.execute( + () -> + callback.onVolumeOffsetChanged( + device, volumeOffset)); + } finally { + // As this deprecated callback, might not be + // defined; continue + } + } + if (Flags.leaudioMultipleVocsInstancesApi()) { + executor.execute( + () -> + callback.onVolumeOffsetChanged( + device, instanceId, volumeOffset)); + } + } + + @Override + public void onVolumeOffsetAudioLocationChanged( + BluetoothDevice device, int instanceId, int location) + throws RemoteException { + if (Flags.leaudioMultipleVocsInstancesApi()) { + Attributable.setAttributionSource( + device, mAttributionSource); + executor.execute( + () -> + callback.onVolumeOffsetAudioLocationChanged( + device, instanceId, location)); + } + } + + @Override + public void onVolumeOffsetAudioDescriptionChanged( + BluetoothDevice device, + int instanceId, + String audioDescription) + throws RemoteException { + if (Flags.leaudioMultipleVocsInstancesApi()) { + Attributable.setAttributionSource( + device, mAttributionSource); + executor.execute( + () -> + callback + .onVolumeOffsetAudioDescriptionChanged( + device, + instanceId, + audioDescription)); + } + } + + @Override + public void onDeviceVolumeChanged( + BluetoothDevice device, int volume) throws RemoteException { + Attributable.setAttributionSource(device, mAttributionSource); + executor.execute( + () -> callback.onDeviceVolumeChanged(device, volume)); + } + }, + mAttributionSource, + recv); + } + recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); + } catch (RemoteException e) { + mCallbackExecutorMap.remove(callback); + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + throw e.rethrowAsRuntimeException(); + } catch (TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } } } @@ -422,21 +604,23 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose } } + if (!mCallbackExecutorMap.isEmpty()) { + return; + } + // If the callback map is empty, we unregister the service-to-app callback - if (mCallbackExecutorMap.isEmpty()) { - try { - final IBluetoothVolumeControl service = getService(); - if (service != null) { - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - service.unregisterCallback(mCallback, mAttributionSource, recv); - recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); - } - } catch (RemoteException e) { - Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - throw e.rethrowAsRuntimeException(); - } catch (IllegalStateException | TimeoutException e) { - Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + try { + final IBluetoothVolumeControl service = getService(); + if (service != null) { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + service.unregisterCallback(mCallback, mAttributionSource, recv); + recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); } + } catch (RemoteException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + throw e.rethrowAsRuntimeException(); + } catch (IllegalStateException | TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } } @@ -445,8 +629,11 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose * * @param device {@link BluetoothDevice} representing the remote device * @param volumeOffset volume offset to be set on the remote device + * @deprecated Use new method which allows for choosing a VOCS instance. This method will always + * use the first instance. * @hide */ + @Deprecated @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission( @@ -456,7 +643,67 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose }) public void setVolumeOffset( @NonNull BluetoothDevice device, @IntRange(from = -255, to = 255) int volumeOffset) { - if (DBG) log("setVolumeOffset(" + device + " volumeOffset: " + volumeOffset + ")"); + final int defaultInstanceId = 1; + setVolumeOffsetInternal(device, defaultInstanceId, volumeOffset); + } + + /** + * Tells the remote device to set a volume offset to the absolute volume. One device might have + * multiple VOCS instances. This instances could be i.e. different speakers or sound types as + * media/voice/notification. + * + * @param device {@link BluetoothDevice} representing the remote device + * @param instanceId identifier of VOCS instance on the remote device. Identifiers are numerated + * from 1. Number of them was notified by callbacks and it can be read using {@link + * #getNumberOfVolumeOffsetInstances(BluetoothDevice)}. Providing non existing instance ID + * will be ignored + * @param volumeOffset volume offset to be set on VOCS instance + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_MULTIPLE_VOCS_INSTANCES_API) + @SystemApi + @RequiresBluetoothConnectPermission + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public void setVolumeOffset( + @NonNull BluetoothDevice device, + @IntRange(from = 1, to = 255) int instanceId, + @IntRange(from = -255, to = 255) int volumeOffset) { + setVolumeOffsetInternal(device, instanceId, volumeOffset); + } + + /** + * INTERNAL HELPER METHOD, DO NOT MAKE PUBLIC + * + *

Tells the remote device to set a volume offset to the absolute volume. One device might + * have multiple VOCS instances. This instances could be i.e. different speakers or sound types + * as media/voice/notification. + * + * @param device {@link BluetoothDevice} representing the remote device + * @param instanceId identifier of VOCS instance on the remote device. Identifiers are numerated + * from 1. Number of them was notified by callbacks and it can be read using {@link + * #getNumberOfVolumeOffsetInstances(BluetoothDevice)}. Providing non existing instance ID + * will be ignored + * @param volumeOffset volume offset to be set on VOCS instance + * @hide + */ + private void setVolumeOffsetInternal( + @NonNull BluetoothDevice device, + @IntRange(from = 1, to = 255) int instanceId, + @IntRange(from = -255, to = 255) int volumeOffset) { + if (DBG) { + log( + "setVolumeOffset(" + + device + + "/" + + instanceId + + " volumeOffset: " + + volumeOffset + + ")"); + } final IBluetoothVolumeControl service = getService(); if (service == null) { Log.w(TAG, "Proxy not attached to service"); @@ -464,7 +711,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose } else if (isEnabled()) { try { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - service.setVolumeOffset(device, volumeOffset, mAttributionSource, recv); + service.setVolumeOffset(device, instanceId, volumeOffset, mAttributionSource, recv); recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); } catch (RemoteException | TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); @@ -503,9 +750,49 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose final boolean defaultValue = false; try { - final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); service.isVolumeOffsetAvailable(device, mAttributionSource, recv); - recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + } catch (RemoteException | TimeoutException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } + + return defaultValue; + } + + /** + * Provides information about the number of volume offset instances + * + * @param device {@link BluetoothDevice} representing the remote device + * @return number of VOCS instances. When Bluetooth is off, the return value is 0. + * @hide + */ + @FlaggedApi(Flags.FLAG_LEAUDIO_MULTIPLE_VOCS_INSTANCES_API) + @SystemApi + @RequiresBluetoothConnectPermission + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public int getNumberOfVolumeOffsetInstances(@NonNull BluetoothDevice device) { + if (DBG) log("getNumberOfVolumeOffsetInstances(" + device + ")"); + final IBluetoothVolumeControl service = getService(); + final int defaultValue = 0; + + if (service == null) { + Log.w(TAG, "Proxy not attached to service"); + if (DBG) log(Log.getStackTraceString(new Throwable())); + return defaultValue; + } + + if (!isEnabled()) { + return defaultValue; + } + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + service.getNumberOfVolumeOffsetInstances(device, mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); } catch (RemoteException | TimeoutException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } @@ -609,8 +896,7 @@ public final class BluetoothVolumeControl implements BluetoothProfile, AutoClose * @throws IllegalArgumentException if volume is not in the range [0, 255]. * @hide */ - @FlaggedApi( - "com.android.bluetooth.flags.leaudio_broadcast_volume_control_for_connected_devices") + @FlaggedApi(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_FOR_CONNECTED_DEVICES) @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission( diff --git a/android/app/aidl/android/bluetooth/IBluetoothStateChangeCallback.aidl b/framework/java/android/bluetooth/IBluetoothStateChangeCallback.java similarity index 63% rename from android/app/aidl/android/bluetooth/IBluetoothStateChangeCallback.aidl rename to framework/java/android/bluetooth/IBluetoothStateChangeCallback.java index 171680165d97a04f91de39a48c73ba9f332bc827..ad47b7bad4198ddc877ba20b2b770dfcc8429fdf 100644 --- a/android/app/aidl/android/bluetooth/IBluetoothStateChangeCallback.aidl +++ b/framework/java/android/bluetooth/IBluetoothStateChangeCallback.java @@ -1,11 +1,11 @@ /* - * Copyright 2011, The Android Open Source Project + * Copyright (C) 2023 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -17,11 +17,13 @@ package android.bluetooth; /** - * System private API for Bluetooth state change callback. + * Non-SDK interface used by apps, was previously an AIDL interface. This class is only here for + * compatibility. * - * {@hide} + * @hide */ -oneway interface IBluetoothStateChangeCallback -{ - void onBluetoothStateChange(boolean on); +public interface IBluetoothStateChangeCallback { + class Stub { + public Stub() {} + } } diff --git a/framework/java/android/bluetooth/OWNERS b/framework/java/android/bluetooth/OWNERS index af162a5de5dca0c3cd28b68be5b40230a7dcb1d8..757ed738192edef5494925958e5775b8f81af493 100644 --- a/framework/java/android/bluetooth/OWNERS +++ b/framework/java/android/bluetooth/OWNERS @@ -1 +1,5 @@ per-file BluetoothHearingAid.java=file:/OWNERS_hearingaid +per-file BluetoothCsipSetCoordinator.java=file:/OWNERS_leaudio +per-file BluetoothLeAudio*.java=file:/OWNERS_leaudio +per-file BluetoothLeBroadcast*.java=file:/OWNERS_leaudio +per-file BluetoothVolumeControl.java=file:/OWNERS_leaudio diff --git a/framework/java/android/bluetooth/SocketMetrics.java b/framework/java/android/bluetooth/SocketMetrics.java new file mode 100644 index 0000000000000000000000000000000000000000..c911c2694d507c6a2ce15ff951ca6e91b0b57072 --- /dev/null +++ b/framework/java/android/bluetooth/SocketMetrics.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2023 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 static android.bluetooth.BluetoothUtils.getSyncTimeout; + +import android.os.RemoteException; +import android.util.Log; + +import com.android.modules.utils.SynchronousResultReceiver; + +import java.util.concurrent.TimeoutException; + +/** Utility class for socket metrics */ +class SocketMetrics { + private static final String TAG = SocketMetrics.class.getSimpleName(); + + /*package*/ static final int SOCKET_NO_ERROR = -1; + + // Defined in BluetoothProtoEnums.L2capCocConnectionResult of proto logging + private static final int RESULT_L2CAP_CONN_UNKNOWN = 0; + /*package*/ static final int RESULT_L2CAP_CONN_SUCCESS = 1; + private static final int RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_FAILED = 1000; + private static final int RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED = 1001; + private static final int RESULT_L2CAP_CONN_BLUETOOTH_UNABLE_TO_SEND_RPC = 1002; + private static final int RESULT_L2CAP_CONN_BLUETOOTH_NULL_BLUETOOTH_DEVICE = 1003; + private static final int RESULT_L2CAP_CONN_BLUETOOTH_GET_SOCKET_MANAGER_FAILED = 1004; + private static final int RESULT_L2CAP_CONN_BLUETOOTH_NULL_FILE_DESCRIPTOR = 1005; + /*package*/ static final int RESULT_L2CAP_CONN_SERVER_FAILURE = 2000; + + // Defined in BluetoothRfcommProtoEnums.RfcommConnectionResult of proto logging + private static final int RFCOMM_CONN_RESULT_FAILURE_UNKNOWN = 0; + private static final int RFCOMM_CONN_RESULT_SUCCESS = 1; + private static final int RFCOMM_CONN_RESULT_SOCKET_CONNECTION_FAILED = 2; + private static final int RFCOMM_CONN_RESULT_SOCKET_CONNECTION_CLOSED = 3; + private static final int RFCOMM_CONN_RESULT_UNABLE_TO_SEND_RPC = 4; + private static final int RFCOMM_CONN_RESULT_NULL_BLUETOOTH_DEVICE = 5; + private static final int RFCOMM_CONN_RESULT_GET_SOCKET_MANAGER_FAILED = 6; + private static final int RFCOMM_CONN_RESULT_NULL_FILE_DESCRIPTOR = 7; + + static void logSocketConnect( + int socketExceptionCode, + long socketConnectionTimeNanos, + int connType, + BluetoothDevice device, + int port, + boolean auth, + long socketCreationTimeNanos, + long socketCreationLatencyNanos) { + IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(); + if (bluetoothProxy == null) { + Log.w(TAG, "logSocketConnect: bluetoothProxy is null"); + return; + } + if (connType == BluetoothSocket.TYPE_L2CAP_LE) { + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + bluetoothProxy.logL2capcocClientConnection( + device, + port, + auth, + getL2capLeConnectStatusCode(socketExceptionCode), + socketCreationTimeNanos, // to calculate end to end latency + socketCreationLatencyNanos, // latency of the constructor + socketConnectionTimeNanos, // to calculate the latency of connect() + recv); + recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); + } catch (RemoteException | TimeoutException e) { + Log.w(TAG, "logL2capcocServerConnection failed", e); + } + } else if (connType == BluetoothSocket.TYPE_RFCOMM) { + boolean isSerialPort = true; // BluetoothSocket#connect API always uses serial port uuid + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + bluetoothProxy.logRfcommConnectionAttempt( + device, + auth, + getRfcommConnectStatusCode(socketExceptionCode), + socketCreationTimeNanos, // to calculate end to end latency + isSerialPort, + recv); + recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); + } catch (RemoteException | TimeoutException e) { + Log.w(TAG, "logL2capcocServerConnection failed", e); + } + } else { + Log.d(TAG, "No metrics for connection type " + connType); + } + } + + static void logSocketAccept( + BluetoothSocket acceptedSocket, + BluetoothSocket socket, + int connType, + int channel, + int timeout, + int result, + long socketCreationTimeMillis, + long socketCreationLatencyMillis, + long socketConnectionTimeMillis) { + if (connType != BluetoothSocket.TYPE_L2CAP_LE) { + return; + } + IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(); + if (bluetoothProxy == null) { + Log.w(TAG, "logSocketConnect: bluetoothProxy is null"); + return; + } + try { + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + bluetoothProxy.logL2capcocServerConnection( + acceptedSocket == null ? null : acceptedSocket.getRemoteDevice(), + channel, + socket.isAuth(), + result, + socketCreationTimeMillis, // pass creation time to calculate end to end latency + socketCreationLatencyMillis, // socket creation latency + socketConnectionTimeMillis, // send connection start time for connection latency + timeout, + recv); + recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); + + } catch (RemoteException | TimeoutException e) { + Log.w(TAG, "logL2capcocServerConnection failed", e); + } + } + + private static int getL2capLeConnectStatusCode(int socketExceptionCode) { + switch (socketExceptionCode) { + case (SOCKET_NO_ERROR): + return RESULT_L2CAP_CONN_SUCCESS; + case (BluetoothSocketException.NULL_DEVICE): + return RESULT_L2CAP_CONN_BLUETOOTH_NULL_BLUETOOTH_DEVICE; + case (BluetoothSocketException.SOCKET_MANAGER_FAILURE): + return RESULT_L2CAP_CONN_BLUETOOTH_GET_SOCKET_MANAGER_FAILED; + case (BluetoothSocketException.SOCKET_CLOSED): + return RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_CLOSED; + case (BluetoothSocketException.SOCKET_CONNECTION_FAILURE): + return RESULT_L2CAP_CONN_BLUETOOTH_SOCKET_CONNECTION_FAILED; + case (BluetoothSocketException.RPC_FAILURE): + return RESULT_L2CAP_CONN_BLUETOOTH_UNABLE_TO_SEND_RPC; + case (BluetoothSocketException.UNIX_FILE_SOCKET_CREATION_FAILURE): + return RESULT_L2CAP_CONN_BLUETOOTH_NULL_FILE_DESCRIPTOR; + default: + return RESULT_L2CAP_CONN_UNKNOWN; + } + } + + private static int getRfcommConnectStatusCode(int socketExceptionCode) { + switch (socketExceptionCode) { + case (SOCKET_NO_ERROR): + return RFCOMM_CONN_RESULT_SUCCESS; + case (BluetoothSocketException.NULL_DEVICE): + return RFCOMM_CONN_RESULT_NULL_BLUETOOTH_DEVICE; + case (BluetoothSocketException.SOCKET_MANAGER_FAILURE): + return RFCOMM_CONN_RESULT_GET_SOCKET_MANAGER_FAILED; + case (BluetoothSocketException.SOCKET_CLOSED): + return RFCOMM_CONN_RESULT_SOCKET_CONNECTION_CLOSED; + case (BluetoothSocketException.SOCKET_CONNECTION_FAILURE): + return RFCOMM_CONN_RESULT_SOCKET_CONNECTION_FAILED; + case (BluetoothSocketException.RPC_FAILURE): + return RFCOMM_CONN_RESULT_UNABLE_TO_SEND_RPC; + case (BluetoothSocketException.UNIX_FILE_SOCKET_CREATION_FAILURE): + return RFCOMM_CONN_RESULT_NULL_FILE_DESCRIPTOR; + default: + return RFCOMM_CONN_RESULT_FAILURE_UNKNOWN; + } + } +} diff --git a/framework/java/android/bluetooth/le/AdvertisingSet.java b/framework/java/android/bluetooth/le/AdvertisingSet.java index 299f0b900e4fddb6ea508297e1107fac37b3f800..be6b647917ecc4e44be41cca0dde7d063bd0e395 100644 --- a/framework/java/android/bluetooth/le/AdvertisingSet.java +++ b/framework/java/android/bluetooth/le/AdvertisingSet.java @@ -50,13 +50,14 @@ public final class AdvertisingSet { private int mAdvertiserId; private AttributionSource mAttributionSource; - /* package */ AdvertisingSet( + AdvertisingSet( + IBluetoothGatt gatt, int advertiserId, BluetoothAdapter bluetoothAdapter, AttributionSource attributionSource) { mAdvertiserId = advertiserId; mAttributionSource = attributionSource; - mGatt = requireNonNull(bluetoothAdapter.getBluetoothGatt(), "Failed to get Bluetooth gatt"); + mGatt = requireNonNull(gatt, "Bluetooth gatt cannot be null"); } /* package */ void setAdvertiserId(int advertiserId) { diff --git a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java index 50b3a82d2136e165028c4ff79d0b575616ae071b..4f1b340c3ce8f37be5b75827f09f367a71b7e714 100644 --- a/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java +++ b/framework/java/android/bluetooth/le/BluetoothLeAdvertiser.java @@ -33,6 +33,7 @@ import android.bluetooth.annotations.RequiresBluetoothAdvertisePermission; import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission; import android.content.AttributionSource; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.ParcelUuid; import android.os.RemoteException; @@ -750,138 +751,108 @@ public final class BluetoothLeAdvertiser { IAdvertisingSetCallback wrap(AdvertisingSetCallback callback, Handler handler) { return new IAdvertisingSetCallback.Stub() { @Override - public void onAdvertisingSetStarted(int advertiserId, int txPower, int status) { + public void onAdvertisingSetStarted( + IBinder gattBinder, int advertiserId, int txPower, int status) { handler.post( - new Runnable() { - @Override - public void run() { - if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) { - callback.onAdvertisingSetStarted(null, 0, status); - mCallbackWrappers.remove(callback); - return; - } - - AdvertisingSet advertisingSet = - new AdvertisingSet( - advertiserId, - mBluetoothAdapter, - mAttributionSource); - mAdvertisingSets.put(advertiserId, advertisingSet); - callback.onAdvertisingSetStarted(advertisingSet, txPower, status); + () -> { + if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) { + callback.onAdvertisingSetStarted(null, 0, status); + mCallbackWrappers.remove(callback); + return; } + + AdvertisingSet advertisingSet = + new AdvertisingSet( + IBluetoothGatt.Stub.asInterface(gattBinder), + advertiserId, + mBluetoothAdapter, + mAttributionSource); + mAdvertisingSets.put(advertiserId, advertisingSet); + callback.onAdvertisingSetStarted(advertisingSet, txPower, status); }); } @Override public void onOwnAddressRead(int advertiserId, int addressType, String address) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onOwnAddressRead(advertisingSet, addressType, address); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onOwnAddressRead(advertisingSet, addressType, address); }); } @Override public void onAdvertisingSetStopped(int advertiserId) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onAdvertisingSetStopped(advertisingSet); - mAdvertisingSets.remove(advertiserId); - mCallbackWrappers.remove(callback); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onAdvertisingSetStopped(advertisingSet); + mAdvertisingSets.remove(advertiserId); + mCallbackWrappers.remove(callback); }); } @Override public void onAdvertisingEnabled(int advertiserId, boolean enabled, int status) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onAdvertisingEnabled(advertisingSet, enabled, status); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onAdvertisingEnabled(advertisingSet, enabled, status); }); } @Override public void onAdvertisingDataSet(int advertiserId, int status) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onAdvertisingDataSet(advertisingSet, status); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onAdvertisingDataSet(advertisingSet, status); }); } @Override public void onScanResponseDataSet(int advertiserId, int status) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onScanResponseDataSet(advertisingSet, status); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onScanResponseDataSet(advertisingSet, status); }); } @Override public void onAdvertisingParametersUpdated(int advertiserId, int txPower, int status) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onAdvertisingParametersUpdated( - advertisingSet, txPower, status); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onAdvertisingParametersUpdated( + advertisingSet, txPower, status); }); } @Override public void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onPeriodicAdvertisingParametersUpdated( - advertisingSet, status); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onPeriodicAdvertisingParametersUpdated(advertisingSet, status); }); } @Override public void onPeriodicAdvertisingDataSet(int advertiserId, int status) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onPeriodicAdvertisingDataSet(advertisingSet, status); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onPeriodicAdvertisingDataSet(advertisingSet, status); }); } @Override public void onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status) { handler.post( - new Runnable() { - @Override - public void run() { - AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); - callback.onPeriodicAdvertisingEnabled( - advertisingSet, enable, status); - } + () -> { + AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId); + callback.onPeriodicAdvertisingEnabled(advertisingSet, enable, status); }); } }; diff --git a/framework/java/android/bluetooth/le/BluetoothLeScanner.java b/framework/java/android/bluetooth/le/BluetoothLeScanner.java index e5820f05ecbd42ebf26f3961585802b146ea7bac..b0c3228c9fe9fd919fae4d4c65366a0ab0f6a6d8 100644 --- a/framework/java/android/bluetooth/le/BluetoothLeScanner.java +++ b/framework/java/android/bluetooth/le/BluetoothLeScanner.java @@ -323,9 +323,12 @@ public final class BluetoothLeScanner { @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopScan(PendingIntent callbackIntent) { BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter); - IBluetoothGatt gatt; try { - gatt = mBluetoothAdapter.getBluetoothGatt(); + IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt(); + if (gatt == null) { + Log.w(TAG, "stopScan called after bluetooth has been turned off"); + return; + } final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); gatt.stopScanForIntent(callbackIntent, mAttributionSource, recv); recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); diff --git a/framework/java/android/bluetooth/le/ChannelSoundingParams.java b/framework/java/android/bluetooth/le/ChannelSoundingParams.java new file mode 100644 index 0000000000000000000000000000000000000000..7c6baf1cff0bd83231f0581646fa3edc0cacfc95 --- /dev/null +++ b/framework/java/android/bluetooth/le/ChannelSoundingParams.java @@ -0,0 +1,322 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.bluetooth.le; + +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.bluetooth.flags.Flags; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * The {@link ChannelSoundingParams} provide a way to adjust distance measurement preferences for + * {@link DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING}. Use {@link ChannelSoundingParams.Builder} + * to create an instance of this class. + * + * @hide + */ +@FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) +@SystemApi +public final class ChannelSoundingParams implements Parcelable { + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + value = { + SIGHT_TYPE_UNKNOWN, + SIGHT_TYPE_LINE_OF_SIGHT, + SIGHT_TYPE_NON_LINE_OF_SIGHT, + }) + @interface SightType {} + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = {LOCATION_TYPE_UNKNOWN, LOCATION_TYPE_INDOOR, LOCATION_TYPE_OUTDOOR}) + @interface LocationType {} + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + value = { + CS_SECURITY_LEVEL_UNKNOWN, + CS_SECURITY_LEVEL_ONE, + CS_SECURITY_LEVEL_TWO, + CS_SECURITY_LEVEL_THREE, + CS_SECURITY_LEVEL_FOUR + }) + @interface CsSecurityLevel {} + + /** + * Sight type is unknown. + * + * @hide + */ + @SystemApi public static final int SIGHT_TYPE_UNKNOWN = 0; + + /** + * Remote device is in line of sight. + * + * @hide + */ + @SystemApi public static final int SIGHT_TYPE_LINE_OF_SIGHT = 1; + + /** + * Remote device is not in line of sight. + * + * @hide + */ + @SystemApi public static final int SIGHT_TYPE_NON_LINE_OF_SIGHT = 2; + + /** + * Location type is unknown. + * + * @hide + */ + @SystemApi public static final int LOCATION_TYPE_UNKNOWN = 0; + + /** + * The location of the usecase is indoor. + * + * @hide + */ + @SystemApi public static final int LOCATION_TYPE_INDOOR = 1; + + /** + * The location of the usecase is outdoor. + * + * @hide + */ + @SystemApi public static final int LOCATION_TYPE_OUTDOOR = 2; + + /** + * Return value for {@link + * DistanceMeasurementManager#getChannelSoundingMaxSupportedSecurityLevel(BluetoothDevice)} and + * {@link DistanceMeasurementManager#getLocalChannelSoundingMaxSupportedSecurityLevel()} when + * Channel Sounding is not supported, or encounters an internal error. + * + * @hide + */ + @SystemApi public static final int CS_SECURITY_LEVEL_UNKNOWN = 0; + + /** + * Either CS tone or CS RTT. + * + * @hide + */ + @SystemApi public static final int CS_SECURITY_LEVEL_ONE = 1; + + /** + * 150 ns CS RTT accuracy and CS tones. + * + * @hide + */ + @SystemApi public static final int CS_SECURITY_LEVEL_TWO = 2; + + /** + * 10 ns CS RTT accuracy and CS tones. + * + * @hide + */ + @SystemApi public static final int CS_SECURITY_LEVEL_THREE = 3; + + /** + * Level 3 with the addition of CS RTT sounding sequence or random sequence payloads, and + * support of the Normalized Attack Detector Metric requirements. + * + * @hide + */ + @SystemApi public static final int CS_SECURITY_LEVEL_FOUR = 4; + + private int mSightType; + private int mLocationType; + private int mCsSecurityLevel; + + /** @hide */ + public ChannelSoundingParams(int sightType, int locationType, int csSecurityLevel) { + mSightType = sightType; + mLocationType = locationType; + mCsSecurityLevel = csSecurityLevel; + } + + /** + * Returns sight type of this ChannelSoundingParams. + * + * @hide + */ + @SystemApi + @SightType + public int getSightType() { + return mSightType; + } + + /** + * Returns location type of this ChannelSoundingParams. + * + * @hide + */ + @SystemApi + @LocationType + public int getLocationType() { + return mLocationType; + } + + /** + * Returns CS security level of this ChannelSoundingParams. + * + * @hide + */ + @SystemApi + @CsSecurityLevel + public int getCsSecurityLevel() { + return mCsSecurityLevel; + } + + /** + * {@inheritDoc} + * + * @hide + */ + @Override + public int describeContents() { + return 0; + } + + /** + * {@inheritDoc} + * + * @hide + */ + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mSightType); + out.writeInt(mLocationType); + out.writeInt(mCsSecurityLevel); + } + + /** A {@link Parcelable.Creator} to create {@link ChannelSoundingParams} from parcel. */ + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public @NonNull ChannelSoundingParams createFromParcel(@NonNull Parcel in) { + Builder builder = new Builder(); + builder.setSightType(in.readInt()); + builder.setLocationType(in.readInt()); + builder.setCsSecurityLevel(in.readInt()); + return builder.build(); + } + + @Override + public @NonNull ChannelSoundingParams[] newArray(int size) { + return new ChannelSoundingParams[size]; + } + }; + + /** + * Builder for {@link ChannelSoundingParams}. + * + * @hide + */ + @SystemApi + public static final class Builder { + private int mSightType = SIGHT_TYPE_UNKNOWN; + private int mLocationType = LOCATION_TYPE_UNKNOWN; + private int mCsSecurityLevel = CS_SECURITY_LEVEL_ONE; + + /** + * Set sight type for the ChannelSoundingParams. + * + * @param sightType sight type of this ChannelSoundingParams + * @return the same Builder instance + * @hide + */ + @SystemApi + public @NonNull Builder setSightType(@SightType int sightType) { + switch (sightType) { + case SIGHT_TYPE_UNKNOWN: + case SIGHT_TYPE_LINE_OF_SIGHT: + case SIGHT_TYPE_NON_LINE_OF_SIGHT: + mSightType = sightType; + break; + default: + throw new IllegalArgumentException("unknown sight type " + sightType); + } + return this; + } + + /** + * Set location type for the ChannelSoundingParams. + * + * @param locationType location type of this ChannelSoundingParams + * @return the same Builder instance + * @hide + */ + @SystemApi + public @NonNull Builder setLocationType(@LocationType int locationType) { + switch (locationType) { + case LOCATION_TYPE_UNKNOWN: + case LOCATION_TYPE_INDOOR: + case LOCATION_TYPE_OUTDOOR: + mLocationType = locationType; + break; + default: + throw new IllegalArgumentException("unknown location type " + locationType); + } + return this; + } + + /** + * Set CS security level for the ChannelSoundingParams. + * + *

See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/ + * + * @param csSecurityLevel cs security level of this ChannelSoundingParams + * @return the same Builder instance + * @hide + */ + @SystemApi + public @NonNull Builder setCsSecurityLevel(@CsSecurityLevel int csSecurityLevel) { + switch (csSecurityLevel) { + case CS_SECURITY_LEVEL_ONE: + case CS_SECURITY_LEVEL_TWO: + case CS_SECURITY_LEVEL_THREE: + case CS_SECURITY_LEVEL_FOUR: + mCsSecurityLevel = csSecurityLevel; + break; + default: + throw new IllegalArgumentException( + "unknown CS security level " + csSecurityLevel); + } + return this; + } + + /** + * Build the {@link ChannelSoundingParams} object. + * + * @hide + */ + @SystemApi + public @NonNull ChannelSoundingParams build() { + return new ChannelSoundingParams(mSightType, mLocationType, mCsSecurityLevel); + } + } +} diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java index 55245d7b4e3c33a0373b2d1d72c753235df1e3c2..1245acdcce505d7c36dba8f3ff910e4dc856d7b7 100644 --- a/framework/java/android/bluetooth/le/DistanceMeasurementManager.java +++ b/framework/java/android/bluetooth/le/DistanceMeasurementManager.java @@ -18,6 +18,7 @@ package android.bluetooth.le; import static android.bluetooth.le.BluetoothLeUtils.getSyncTimeout; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -26,12 +27,14 @@ import android.annotation.SystemApi; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.IBluetoothGatt; +import android.bluetooth.le.ChannelSoundingParams.CsSecurityLevel; import android.content.AttributionSource; import android.os.CancellationSignal; import android.os.ParcelUuid; import android.os.RemoteException; import android.util.Log; +import com.android.bluetooth.flags.Flags; import com.android.modules.utils.SynchronousResultReceiver; import java.util.ArrayList; @@ -171,6 +174,78 @@ public final class DistanceMeasurementManager { } } + /** + * Get the maximum supported security level of channel sounding between the local device and a + * specific remote device. + * + *

See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/ + * + * @param remoteDevice remote device of channel sounding + * @return max supported security level, {@link ChannelSoundingParams#CS_SECURITY_LEVEL_UNKNOWN} + * when Channel Sounding is not supported or encounters an internal error. + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @CsSecurityLevel + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public int getChannelSoundingMaxSupportedSecurityLevel(@NonNull BluetoothDevice remoteDevice) { + Objects.requireNonNull(remoteDevice, "remote device is null"); + final int defaultValue = ChannelSoundingParams.CS_SECURITY_LEVEL_UNKNOWN; + try { + IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt(); + if (gatt == null) { + Log.e(TAG, "Bluetooth GATT is null"); + return defaultValue; + } + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + gatt.getChannelSoundingMaxSupportedSecurityLevel( + remoteDevice, mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + } catch (TimeoutException | RemoteException e) { + Log.e(TAG, "Failed to get supported security Level - ", e); + } + return defaultValue; + } + + /** + * Get the maximum supported security level of channel sounding of the local device. + * + *

See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/ + * + * @return max supported security level, {@link ChannelSoundingParams#CS_SECURITY_LEVEL_UNKNOWN} + * when Channel Sounding is not supported or encounters an internal error. + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @CsSecurityLevel + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + public int getLocalChannelSoundingMaxSupportedSecurityLevel() { + final int defaultValue = ChannelSoundingParams.CS_SECURITY_LEVEL_UNKNOWN; + try { + IBluetoothGatt gatt = mBluetoothAdapter.getBluetoothGatt(); + if (gatt == null) { + Log.e(TAG, "Bluetooth GATT is null"); + return defaultValue; + } + final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); + gatt.getLocalChannelSoundingMaxSupportedSecurityLevel(mAttributionSource, recv); + return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue); + } catch (TimeoutException | RemoteException e) { + Log.e(TAG, "Failed to get supported security Level - ", e); + } + return defaultValue; + } + @SuppressLint("AndroidFrameworkBluetoothPermission") private final IDistanceMeasurementCallback mCallbackWrapper = new IDistanceMeasurementCallback.Stub() { diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java b/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java index b4a49075fdc5e20e4f62f212042a885bd3dbd15d..a6fcff8c4d395d2217d993a5b459254808f1c19b 100644 --- a/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java +++ b/framework/java/android/bluetooth/le/DistanceMeasurementMethod.java @@ -16,12 +16,15 @@ package android.bluetooth.le; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; @@ -42,7 +45,12 @@ public final class DistanceMeasurementMethod implements Parcelable { /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(value = {DISTANCE_MEASUREMENT_METHOD_AUTO, DISTANCE_MEASUREMENT_METHOD_RSSI}) + @IntDef( + value = { + DISTANCE_MEASUREMENT_METHOD_AUTO, + DISTANCE_MEASUREMENT_METHOD_RSSI, + DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING + }) @interface DistanceMeasurementMethodId {} /** @@ -60,6 +68,15 @@ public final class DistanceMeasurementMethod implements Parcelable { */ @SystemApi public static final int DISTANCE_MEASUREMENT_METHOD_RSSI = 1; + /** + * Use Channel Sounding to measure the distance. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING = 2; + private DistanceMeasurementMethod( int id, boolean isAzimuthAngleSupported, boolean isAltitudeAngleSupported) { mId = id; @@ -194,6 +211,7 @@ public final class DistanceMeasurementMethod implements Parcelable { switch (id) { case DISTANCE_MEASUREMENT_METHOD_AUTO: case DISTANCE_MEASUREMENT_METHOD_RSSI: + case DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: mId = id; break; default: diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementParams.java b/framework/java/android/bluetooth/le/DistanceMeasurementParams.java index 5ff40a28719e88c0be73d43d4b48926f1c1302df..4a44c12145f2a405a0c90ec36226c02a2458af2d 100644 --- a/framework/java/android/bluetooth/le/DistanceMeasurementParams.java +++ b/framework/java/android/bluetooth/le/DistanceMeasurementParams.java @@ -16,15 +16,19 @@ package android.bluetooth.le; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.DistanceMeasurementMethod.DistanceMeasurementMethodId; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; @@ -74,14 +78,20 @@ public final class DistanceMeasurementParams implements Parcelable { private int mDuration; private int mFrequency; private int mMethodId; + private ChannelSoundingParams mChannelSoundingParams = null; /** @hide */ public DistanceMeasurementParams( - BluetoothDevice device, int duration, int frequency, int methodId) { + BluetoothDevice device, + int duration, + int frequency, + int methodId, + ChannelSoundingParams channelSoundingParams) { mDevice = Objects.requireNonNull(device); mDuration = duration; mFrequency = frequency; mMethodId = methodId; + mChannelSoundingParams = channelSoundingParams; } /** @@ -128,6 +138,17 @@ public final class DistanceMeasurementParams implements Parcelable { return mMethodId; } + /** + * Returns {@link ChannelSoundingParams} of this DistanceMeasurementParams. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public @Nullable ChannelSoundingParams getChannelSoundingParams() { + return mChannelSoundingParams; + } + /** * Get the default duration in seconds of the parameter. * @@ -169,6 +190,7 @@ public final class DistanceMeasurementParams implements Parcelable { out.writeInt(mDuration); out.writeInt(mFrequency); out.writeInt(mMethodId); + out.writeParcelable(mChannelSoundingParams, 0); } /** A {@link Parcelable.Creator} to create {@link DistanceMeasurementParams} from parcel. */ @@ -180,6 +202,8 @@ public final class DistanceMeasurementParams implements Parcelable { builder.setDurationSeconds(in.readInt()); builder.setFrequency(in.readInt()); builder.setMethodId(in.readInt()); + builder.setChannelSoundingParams( + (ChannelSoundingParams) in.readParcelable(null)); return builder.build(); } @@ -200,6 +224,7 @@ public final class DistanceMeasurementParams implements Parcelable { private int mDuration = REPORT_DURATION_DEFAULT; private int mFrequency = REPORT_FREQUENCY_LOW; private int mMethodId = DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI; + private ChannelSoundingParams mChannelSoundingParams = null; /** * Constructor of the Builder. @@ -265,6 +290,7 @@ public final class DistanceMeasurementParams implements Parcelable { switch (methodId) { case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_AUTO: case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_RSSI: + case DistanceMeasurementMethod.DISTANCE_MEASUREMENT_METHOD_CHANNEL_SOUNDING: mMethodId = methodId; break; default: @@ -273,6 +299,21 @@ public final class DistanceMeasurementParams implements Parcelable { return this; } + /** + * Set {@link ChannelSoundingParams} for the DistanceMeasurementParams. + * + * @param channelSoundingParams parameters for Channel Sounding + * @return the same Builder instance + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public @NonNull Builder setChannelSoundingParams( + @NonNull ChannelSoundingParams channelSoundingParams) { + mChannelSoundingParams = channelSoundingParams; + return this; + } + /** * Build the {@link DistanceMeasurementParams} object. * @@ -280,7 +321,8 @@ public final class DistanceMeasurementParams implements Parcelable { */ @SystemApi public @NonNull DistanceMeasurementParams build() { - return new DistanceMeasurementParams(mDevice, mDuration, mFrequency, mMethodId); + return new DistanceMeasurementParams( + mDevice, mDuration, mFrequency, mMethodId, mChannelSoundingParams); } } } diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementResult.java b/framework/java/android/bluetooth/le/DistanceMeasurementResult.java index 513bab6c07549cb2523921ca95c20aab19986ce3..7c2815f52edb3e96c9e62cec99886ec708a55c2f 100644 --- a/framework/java/android/bluetooth/le/DistanceMeasurementResult.java +++ b/framework/java/android/bluetooth/le/DistanceMeasurementResult.java @@ -16,12 +16,19 @@ package android.bluetooth.le; +import android.annotation.FlaggedApi; import android.annotation.FloatRange; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import com.android.bluetooth.flags.Flags; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Result of distance measurement. * @@ -30,12 +37,109 @@ import android.os.Parcelable; @SystemApi public final class DistanceMeasurementResult implements Parcelable { + /** + * Normalized Attack Detector Metric. See Channel Sounding CR_PR, 3.13.24 for details. + * + *

Specification: https://www.bluetooth.com/specifications/specs/channel-sounding-cr-pr/ + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef( + value = { + NADM_ATTACK_IS_EXTREMELY_UNLIKELY, + NADM_ATTACK_IS_VERY_UNLIKELY, + NADM_ATTACK_IS_UNLIKELY, + NADM_ATTACK_IS_POSSIBLE, + NADM_ATTACK_IS_LIKELY, + NADM_ATTACK_IS_VERY_LIKELY, + NADM_ATTACK_IS_EXTREMELY_LIKELY, + NADM_UNKNOWN + }) + @interface Nadm {} + + /** + * Attack is extremely unlikely. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_ATTACK_IS_EXTREMELY_UNLIKELY = 0; + + /** + * Attack is very unlikely. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_ATTACK_IS_VERY_UNLIKELY = 1; + + /** + * Attack is unlikely. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_ATTACK_IS_UNLIKELY = 2; + + /** + * Attack is possible. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_ATTACK_IS_POSSIBLE = 3; + + /** + * Attack is likely. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_ATTACK_IS_LIKELY = 4; + + /** + * Attack is very likely. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_ATTACK_IS_VERY_LIKELY = 5; + + /** + * Attack is extremely likely. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_ATTACK_IS_EXTREMELY_LIKELY = 6; + + /** + * Unknown NADM, if a device is unable to determine a NADM value, then it shall report this. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public static final int NADM_UNKNOWN = 0xFF; + private final double mMeters; private final double mErrorMeters; private final double mAzimuthAngle; private final double mErrorAzimuthAngle; private final double mAltitudeAngle; private final double mErrorAltitudeAngle; + private final double mDelaySpreadMeters; + private final double mConfidenceLevel; + private final int mDetectedAttackLevel; + private final double mVelocityMetersPerSecond; private DistanceMeasurementResult( double meters, @@ -43,13 +147,21 @@ public final class DistanceMeasurementResult implements Parcelable { double azimuthAngle, double errorAzimuthAngle, double altitudeAngle, - double errorAltitudeAngle) { + double errorAltitudeAngle, + double delaySpreadMeters, + double confidenceLevel, + @Nadm int detectedAttackLevel, + double velocityMetersPerSecond) { mMeters = meters; mErrorMeters = errorMeters; mAzimuthAngle = azimuthAngle; mErrorAzimuthAngle = errorAzimuthAngle; mAltitudeAngle = altitudeAngle; mErrorAltitudeAngle = errorAltitudeAngle; + mDelaySpreadMeters = delaySpreadMeters; + mConfidenceLevel = confidenceLevel; + mDetectedAttackLevel = detectedAttackLevel; + mVelocityMetersPerSecond = velocityMetersPerSecond; } /** @@ -146,6 +258,60 @@ public final class DistanceMeasurementResult implements Parcelable { return mErrorAltitudeAngle; } + /** + * Get estimated delay spread in meters of the measured channel. This is a measure of multipath + * richness of the channel. + * + * @return delay spread in meters in degrees or Double.NaN if not available + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public double getDelaySpreadMeters() { + return mDelaySpreadMeters; + } + + /** + * Get a normalized value from 0.0 (low confidence) to 1.0 (high confidence) representing the + * confidence of estimated distance. + * + * @return confidence of estimated distance or Double.NaN if not available + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @FloatRange(from = 0.0, to = 1.0) + public double getConfidenceLevel() { + return mConfidenceLevel; + } + + /** + * Get a value that represents the chance of being attacked for the measurement. + * + * @return Nadm that represents the chance of being attacked for the measurement. + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @Nadm + public int getDetectedAttackLevel() { + return mDetectedAttackLevel; + } + + /** + * Get estimated velocity, in the direction of line between two devices, of the moving object in + * meters/sec. + * + * @return Estimated velocity, in the direction of line between two devices, of the moving + * object in meters/sec. + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + public double getVelocityMetersPerSecond() { + return mVelocityMetersPerSecond; + } + /** * {@inheritDoc} * @@ -169,6 +335,10 @@ public final class DistanceMeasurementResult implements Parcelable { out.writeDouble(mErrorAzimuthAngle); out.writeDouble(mAltitudeAngle); out.writeDouble(mErrorAltitudeAngle); + out.writeDouble(mDelaySpreadMeters); + out.writeDouble(mConfidenceLevel); + out.writeInt(mDetectedAttackLevel); + out.writeDouble(mVelocityMetersPerSecond); } /** @@ -189,6 +359,14 @@ public final class DistanceMeasurementResult implements Parcelable { + mAltitudeAngle + ", errorAltitudeAngle: " + mErrorAltitudeAngle + + ", delaySpreadMeters: " + + mDelaySpreadMeters + + ", confidenceLevel: " + + mConfidenceLevel + + ", detectedAttackLevel: " + + mDetectedAttackLevel + + ", velocityMetersPerSecond: " + + mVelocityMetersPerSecond + "]"; } @@ -202,6 +380,10 @@ public final class DistanceMeasurementResult implements Parcelable { .setErrorAzimuthAngle(in.readDouble()) .setAltitudeAngle(in.readDouble()) .setErrorAltitudeAngle(in.readDouble()) + .setDelaySpreadMeters(in.readDouble()) + .setConfidenceLevel(in.readDouble()) + .setDetectedAttackLevel(in.readInt()) + .setVelocityMetersPerSecond(in.readDouble()) .build(); } @@ -224,6 +406,10 @@ public final class DistanceMeasurementResult implements Parcelable { private double mErrorAzimuthAngle = Double.NaN; private double mAltitudeAngle = Double.NaN; private double mErrorAltitudeAngle = Double.NaN; + private double mDelaySpreadMeters = Double.NaN; + private double mConfidenceLevel = Double.NaN; + private int mDetectedAttackLevel = NADM_UNKNOWN; + private double mVelocityMetersPerSecond = Double.NaN; /** * Constructor of the Builder. @@ -317,6 +503,90 @@ public final class DistanceMeasurementResult implements Parcelable { return this; } + /** + * Set the estimated delay spread in meters. + * + * @param delaySpreadMeters estimated delay spread in meters + * @throws IllegalArgumentException if value is invalid + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @NonNull + public Builder setDelaySpreadMeters(double delaySpreadMeters) { + if (delaySpreadMeters < 0.0) { + throw new IllegalArgumentException("delaySpreadMeters must be > 0.0"); + } + mDelaySpreadMeters = delaySpreadMeters; + return this; + } + + /** + * Set the confidence of estimated distance. + * + * @param confidenceLevel a normalized value from 0.0 (low confidence) to 1.0 (high + * confidence) representing the confidence of estimated distance + * @throws IllegalArgumentException if value is invalid + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @NonNull + public Builder setConfidenceLevel( + @FloatRange(from = 0.0, to = 1.0) double confidenceLevel) { + if (confidenceLevel > 1.0 || confidenceLevel < 0.0) { + throw new IllegalArgumentException( + "error confidenceLevel must be in the range from 0.0 to 100.0 : " + + confidenceLevel); + } + mConfidenceLevel = confidenceLevel; + return this; + } + + /** + * Set the value that represents the chance of being attacked for the measurement. + * + * @param detectedAttackLevel a value that represents the chance of being attacked for the + * measurement. + * @throws IllegalArgumentException if value is invalid + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @NonNull + public Builder setDetectedAttackLevel(@Nadm int detectedAttackLevel) { + switch (detectedAttackLevel) { + case NADM_ATTACK_IS_EXTREMELY_UNLIKELY: + case NADM_ATTACK_IS_VERY_UNLIKELY: + case NADM_ATTACK_IS_UNLIKELY: + case NADM_ATTACK_IS_POSSIBLE: + case NADM_ATTACK_IS_LIKELY: + case NADM_ATTACK_IS_VERY_LIKELY: + case NADM_ATTACK_IS_EXTREMELY_LIKELY: + case NADM_UNKNOWN: + mDetectedAttackLevel = detectedAttackLevel; + break; + default: + throw new IllegalArgumentException("Invalid value " + detectedAttackLevel); + } + return this; + } + + /** + * Set estimated velocity, in the direction of line between two devices, of the moving + * object in meters/sec. + * + * @param velocityMetersPerSecond estimated velocity in meters/sec. + * @hide + */ + @FlaggedApi(Flags.FLAG_CHANNEL_SOUNDING) + @SystemApi + @NonNull + public Builder setVelocityMetersPerSecond(double velocityMetersPerSecond) { + mVelocityMetersPerSecond = velocityMetersPerSecond; + return this; + } + /** * Builds the {@link DistanceMeasurementResult} object. * @@ -332,7 +602,11 @@ public final class DistanceMeasurementResult implements Parcelable { mAzimuthAngle, mErrorAzimuthAngle, mAltitudeAngle, - mErrorAltitudeAngle); + mErrorAltitudeAngle, + mDelaySpreadMeters, + mConfidenceLevel, + mDetectedAttackLevel, + mVelocityMetersPerSecond); } } } diff --git a/framework/tests/bumble/Android.bp b/framework/tests/bumble/Android.bp index d1cfa300155fa9e58d64f77a0e5607439769ef42..21d4a62884e6b066a64cfa0839681ba673a06fc2 100644 --- a/framework/tests/bumble/Android.bp +++ b/framework/tests/bumble/Android.bp @@ -19,13 +19,16 @@ android_test_helper_app { ], static_libs: [ + "TestParameterInjector", "androidx.core_core", "androidx.test.espresso.intents", "androidx.test.ext.junit", "androidx.test.ext.truth", "androidx.test.rules", "bluetooth-test-util-lib", + "bluetooth_flags_java_lib", "compatibility-device-util-axt", + "flag-junit", "grpc-java-lite", "grpc-java-okhttp-client-lite", "mockito-kotlin2", diff --git a/framework/tests/bumble/src/android/bluetooth/DckTest.kt b/framework/tests/bumble/src/android/bluetooth/DckGattTest.kt similarity index 51% rename from framework/tests/bumble/src/android/bluetooth/DckTest.kt rename to framework/tests/bumble/src/android/bluetooth/DckGattTest.kt index fe7095682f31aa6534e8f57b0782905aaf4c4524..afec94e7c5673140c120ac2ff4a933658a81c0a9 100644 --- a/framework/tests/bumble/src/android/bluetooth/DckTest.kt +++ b/framework/tests/bumble/src/android/bluetooth/DckGattTest.kt @@ -16,32 +16,56 @@ package android.bluetooth +import android.bluetooth.le.ScanCallback +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanResult +import android.bluetooth.le.ScanSettings import android.content.Context +import android.os.ParcelUuid import androidx.test.core.app.ApplicationProvider -import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.compatibility.common.util.AdoptShellPermissionsRule +import com.google.common.collect.Sets import com.google.common.truth.Truth.assertThat import com.google.protobuf.Empty import io.grpc.Deadline import java.util.UUID import java.util.concurrent.TimeUnit +import org.junit.After +import org.junit.Assume.assumeFalse +import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.clearInvocations +import org.mockito.kotlin.doAnswer import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.timeout import org.mockito.kotlin.verify +import pandora.HostProto import pandora.HostProto.AdvertiseRequest import pandora.HostProto.OwnAddressType -@RunWith(AndroidJUnit4::class) -public class DckTest { +/** DCK GATT Tests */ +@RunWith(Parameterized::class) +public class DckGattTest(private val connected: Boolean) { private val context: Context = ApplicationProvider.getApplicationContext() private val bluetoothManager = context.getSystemService(BluetoothManager::class.java)!! private val bluetoothAdapter = bluetoothManager.adapter + private val leScanner = bluetoothAdapter.bluetoothLeScanner + + private val scanResultCaptor = argumentCaptor() + private val scanCallbackMock = mock() + private val gattCaptor = argumentCaptor() + private val gattCallbackMock = + mock { + on { onConnectionStateChange(gattCaptor.capture(), any(), any()) } doAnswer {} + } // A Rule live from a test setup through it's teardown. // Gives shell permissions during the test. @@ -51,6 +75,36 @@ public class DckTest { // Acting as a Pandora client, it can be interacted with through the Pandora APIs. @Rule @JvmField val mBumble = PandoraDevice() + @Before + fun setUp() { + if (connected) { + advertiseWithBumble() + + // Connect DUT to Ref as prerequisite + val device = + bluetoothAdapter.getRemoteLeDevice( + Utils.BUMBLE_RANDOM_ADDRESS, + BluetoothDevice.ADDRESS_TYPE_RANDOM + ) + val gatt = device.connectGatt(context, false, gattCallbackMock) + verify(gattCallbackMock, timeout(TIMEOUT)) + .onConnectionStateChange( + eq(gatt), + eq(BluetoothGatt.GATT_SUCCESS), + eq(BluetoothProfile.STATE_CONNECTED) + ) + } + + clearInvocations(gattCallbackMock) + } + + @After + fun tearDown() { + for (gatt in gattCaptor.allValues.toSet()) { + gatt.close() + } + } + /** * Tests the discovery of the Digital Car Key (DCK) GATT service via Bluetooth on an Android * device. @@ -154,11 +208,130 @@ public class DckTest { ) } + /* + * 2.1 GATT Connect - discovered using scan with Identity Address and IRK + * + * http://docs/document/d/1oQOpgI83HSJBdr5mBU00za_6XrDGo2KDGnCcX-hXPHk#heading=h.9nvtna3zum23 + */ + @Test + fun testGattConnect_fromIrkScan() { + // TODO(b/317091743): Enable test when bug is fixed. + assumeFalse(connected) + + // Start advertisement on Ref + advertiseWithBumble() + + // Start IRK scan for Ref on DUT + val scanSettings = + ScanSettings.Builder() + .setScanMode(ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY) + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .build() + val scanFilter = + ScanFilter.Builder() + .setDeviceAddress( + TEST_ADDRESS_RANDOM_STATIC, + BluetoothDevice.ADDRESS_TYPE_RANDOM, + Utils.BUMBLE_IRK + ) + .build() + leScanner.startScan(listOf(scanFilter), scanSettings, scanCallbackMock) + + // Await scan results + verify(scanCallbackMock, timeout(TIMEOUT).atLeastOnce()) + .onScanResult(eq(ScanSettings.CALLBACK_TYPE_ALL_MATCHES), scanResultCaptor.capture()) + + // Verify correct scan result as prerequisite + val scanResult = scanResultCaptor.firstValue + assertThat(scanResult).isNotNull() + assertThat(scanResult.device.identityAddress).isEqualTo(TEST_ADDRESS_RANDOM_STATIC) + + // Verify successful GATT connection + val device = scanResult.device + val gatt = device.connectGatt(context, false, gattCallbackMock) + verify(gattCallbackMock, timeout(TIMEOUT)) + .onConnectionStateChange( + eq(gatt), + eq(BluetoothGatt.GATT_SUCCESS), + eq(BluetoothProfile.STATE_CONNECTED) + ) + + // Stop scan on DUT after GATT connect + leScanner.stopScan(scanCallbackMock) + } + + /* + * 2.3 GATT Connect - discovered using scan with UUID + * + * http://docs/document/d/1oQOpgI83HSJBdr5mBU00za_6XrDGo2KDGnCcX-hXPHk#heading=h.7ofaj7vwknsr + */ + @Test + fun testGattConnect_fromUuidScan() { + // Start UUID advertisement on Ref + advertiseWithBumble(withUuid = true) + + // Start UUID scan for Ref on DUT + val scanSettings = + ScanSettings.Builder() + .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .build() + val scanFilter = ScanFilter.Builder().setServiceUuid(ParcelUuid(CCC_DK_UUID)).build() + leScanner.startScan(listOf(scanFilter), scanSettings, scanCallbackMock) + + // Await scan results + verify(scanCallbackMock, timeout(TIMEOUT).atLeastOnce()) + .onScanResult(eq(ScanSettings.CALLBACK_TYPE_ALL_MATCHES), scanResultCaptor.capture()) + + // Stop scan on DUT before GATT connect + leScanner.stopScan(scanCallbackMock) + + // Verify correct scan result as prerequisite + val scanResult = scanResultCaptor.firstValue + assertThat(scanResult).isNotNull() + assertThat(scanResult.scanRecord?.serviceUuids).contains(ParcelUuid(CCC_DK_UUID)) + + // Verify successful GATT connection + val device = scanResult.device + val gatt = device.connectGatt(context, false, gattCallbackMock) + verify(gattCallbackMock, timeout(TIMEOUT)) + .onConnectionStateChange( + eq(gatt), + eq(BluetoothGatt.GATT_SUCCESS), + eq(BluetoothProfile.STATE_CONNECTED) + ) + } + + private fun advertiseWithBumble(withUuid: Boolean = false) { + val requestBuilder = + AdvertiseRequest.newBuilder() + .setLegacy(true) + .setConnectable(true) + .setOwnAddressType(OwnAddressType.RANDOM) + + if (withUuid) { + requestBuilder.data = + HostProto.DataTypes.newBuilder() + .addCompleteServiceClassUuids128(CCC_DK_UUID.toString()) + .build() + } + mBumble.hostBlocking().advertise(requestBuilder.build()) + } + companion object { private const val TAG = "DckTest" private const val TIMEOUT: Long = 2000 + private const val TEST_ADDRESS_RANDOM_STATIC = "F0:43:A8:23:10:11" // CCC DK Specification R3 1.2.0 r14 section 19.2.1.2 Bluetooth Le Pairing private val CCC_DK_UUID = UUID.fromString("0000FFF5-0000-1000-8000-00805f9b34fb") + + @Parameters(name = "connected = {0}") + @JvmStatic + fun parameters(): Iterable> = + Sets.cartesianProduct( + setOf(false, true), // connected + ) + .map { it.toTypedArray() } } } diff --git a/framework/tests/bumble/src/android/bluetooth/DckScanTest.kt b/framework/tests/bumble/src/android/bluetooth/DckScanTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..3895368d8d84e609cbd05d718c9ea722faad884d --- /dev/null +++ b/framework/tests/bumble/src/android/bluetooth/DckScanTest.kt @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2023 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.DckTestRule.LeScanResult +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanSettings +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import com.android.compatibility.common.util.AdoptShellPermissionsRule +import com.google.common.collect.Sets +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withTimeout +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters + +/** DCK LE Scan Tests */ +@RunWith(Parameterized::class) +class DckScanTest( + isRemoteAdvertisingWithUuid: Boolean, + isBluetoothToggled: Boolean, + isGattConnected: Boolean, +) { + private val context: Context = ApplicationProvider.getApplicationContext() + + // Gives shell permissions during the test. + @Rule(order = 0) @JvmField val shellPermissionRule = AdoptShellPermissionsRule() + + // Setup a Bumble Pandora device for the duration of the test. + // Acting as a Pandora client, it can be interacted with through the Pandora APIs. + @Rule(order = 1) @JvmField val bumble = PandoraDevice() + + // Test rule for common DCK test setup and teardown procedures, along with utility APIs. + @Rule(order = 2) + @JvmField + val dck = + DckTestRule( + context, + bumble, + isBluetoothToggled = isBluetoothToggled, + isRemoteAdvertisingWithUuid = isRemoteAdvertisingWithUuid, + isGattConnected = isGattConnected + ) + + @Test + fun scanForIrkAndIdentityAddress_remoteFound() { + // TODO(316001793): Retrieve identity address from Bumble + val scanFilter = + ScanFilter.Builder() + .setDeviceAddress( + TEST_ADDRESS_RANDOM_STATIC, + BluetoothDevice.ADDRESS_TYPE_RANDOM, + Utils.BUMBLE_IRK + ) + .build() + val scanSettings = + ScanSettings.Builder() + .setScanMode(ScanSettings.SCAN_MODE_AMBIENT_DISCOVERY) + .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setMatchMode(ScanSettings.MATCH_MODE_STICKY) + .build() + + val result: LeScanResult = runBlocking { + withTimeout(TIMEOUT_MS) { dck.scanWithPendingIntent(scanFilter, scanSettings).first() } + } + + assertThat(result).isInstanceOf(LeScanResult.Success::class.java) + assertThat((result as LeScanResult.Success).callbackType) + .isEqualTo(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + assertThat((result as LeScanResult.Success).scanResult.device.address) + .isEqualTo(TEST_ADDRESS_RANDOM_STATIC) + } + + companion object { + private const val TIMEOUT_MS = 3000L + private const val TEST_ADDRESS_RANDOM_STATIC = "F0:43:A8:23:10:11" + + // TODO(315852141): Include variations for LE only vs. Dual mode Bumble when supported + // TODO(315852141): Include variations for two advertisements at the same time + // TODO(303502437): Include variations for other callback types when supported in rootcanal + @Parameters( + name = + "{index}: isRemoteAdvertisingWithUuid = {0}, " + + "isBluetoothToggled = {1}, isGattConnected = {2}" + ) + @JvmStatic + fun parameters(): Iterable> { + val booleanVariations = setOf(true, false) + + return Sets.cartesianProduct( + listOf( + /* isRemoteAdvertisingWithUuid */ booleanVariations, + /* isBluetoothToggled */ booleanVariations, + /* isGattConnected */ booleanVariations + ) + ) + .map { it.toTypedArray() } + } + } +} diff --git a/framework/tests/bumble/src/android/bluetooth/DckTestRule.kt b/framework/tests/bumble/src/android/bluetooth/DckTestRule.kt new file mode 100644 index 0000000000000000000000000000000000000000..bd1d042f8eddf85a469fe31da86005ed7e734a2c --- /dev/null +++ b/framework/tests/bumble/src/android/bluetooth/DckTestRule.kt @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.bluetooth + +import android.app.PendingIntent +import android.bluetooth.le.BluetoothLeScanner +import android.bluetooth.le.ScanCallback +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanResult +import android.bluetooth.le.ScanSettings +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import com.google.protobuf.Empty +import io.grpc.Deadline +import java.util.UUID +import java.util.concurrent.TimeUnit +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.shareIn +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withTimeout +import org.junit.rules.TestRule +import org.junit.runner.Description +import org.junit.runners.model.Statement +import pandora.HostProto +import pandora.HostProto.AdvertiseRequest +import pandora.HostProto.OwnAddressType + +/** Test rule for DCK specific device and Bumble setup and teardown procedures */ +class DckTestRule( + private val context: Context, + private val bumble: PandoraDevice, + private val isBluetoothToggled: Boolean = false, + private val isRemoteAdvertisingWithUuid: Boolean = false, + private val isGattConnected: Boolean = false, +) : TestRule { + private val bluetoothManager = context.getSystemService(BluetoothManager::class.java)!! + private val bluetoothAdapter = bluetoothManager.adapter + private val leScanner = bluetoothAdapter.bluetoothLeScanner + + private val scope = CoroutineScope(Dispatchers.Default) + private val ioScope = CoroutineScope(Dispatchers.IO) + + // Internal Types + + /** Wrapper for [ScanResult] */ + sealed class LeScanResult { + + /** Represents a [ScanResult] with the associated [callbackType] */ + data class Success(val scanResult: ScanResult, val callbackType: Int) : LeScanResult() + + /** Represents a scan failure with an [errorCode] */ + data class Failure(val errorCode: Int) : LeScanResult() + } + + /** Wrapper for [BluetoothGatt] along with its [state] and [status] */ + data class GattState(val gatt: BluetoothGatt, val status: Int, val state: Int) + + // Public Methods + + /** + * Starts an LE scan with the given [scanFilter] and [scanSettings], using [ScanCallback] within + * the given [coroutine]. + * + * The caller can stop the scan at any time by cancelling the coroutine they used to start the + * scan. If no coroutine was provided, a default coroutine is used and the scan will be stopped + * at the end of the test. + * + * @return SharedFlow of [LeScanResult] with a buffer of size 1 + */ + fun scanWithCallback( + scanFilter: ScanFilter, + scanSettings: ScanSettings, + coroutine: CoroutineScope = scope + ) = + callbackFlow { + val callback = + object : ScanCallback() { + override fun onScanResult(callbackType: Int, result: ScanResult) { + trySend(LeScanResult.Success(result, callbackType)) + } + + override fun onScanFailed(errorCode: Int) { + trySend(LeScanResult.Failure(errorCode)) + channel.close() + } + } + + leScanner.startScan(listOf(scanFilter), scanSettings, callback) + + awaitClose { leScanner.stopScan(callback) } + } + .conflate() + .shareIn(coroutine, SharingStarted.Lazily) + + /** + * Starts an LE scan with the given [scanFilter] and [scanSettings], using [PendingIntent] + * within the given [coroutine]. + * + * The caller can stop the scan at any time by cancelling the coroutine they used to start the + * scan. If no coroutine was provided, a default coroutine is used and the scan will be stopped + * at the end of the test. + * + * @return SharedFlow of [LeScanResult] with a buffer of size 1 + */ + fun scanWithPendingIntent( + scanFilter: ScanFilter, + scanSettings: ScanSettings, + coroutine: CoroutineScope = scope + ) = + callbackFlow { + val intentFilter = IntentFilter(ACTION_DYNAMIC_RECEIVER_SCAN_RESULT) + val broadcastReceiver = + object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (ACTION_DYNAMIC_RECEIVER_SCAN_RESULT == intent.action) { + val results = + intent.getParcelableArrayListExtra( + BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT + ) + ?: return + + val callbackType = + intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, -1) + + for (result in results) { + trySend(LeScanResult.Success(result, callbackType)) + } + } + } + } + + context.registerReceiver(broadcastReceiver, intentFilter) + + val scanIntent = Intent(ACTION_DYNAMIC_RECEIVER_SCAN_RESULT) + val pendingIntent = + PendingIntent.getBroadcast( + context, + 0, + scanIntent, + PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + ) + + leScanner.startScan(listOf(scanFilter), scanSettings, pendingIntent) + + awaitClose { + context.unregisterReceiver(broadcastReceiver) + leScanner.stopScan(pendingIntent) + } + } + .conflate() + .shareIn(coroutine, SharingStarted.Lazily) + + /** + * Requests a GATT connection to the given [device] within the given [coroutine]. + * + * Cancelling the coroutine will close the GATT client. If no coroutine was provided, a default + * coroutine is used and the GATT client will be closed at the end of the test. + * + * @return SharedFlow of [GattState] with a buffer of size 1 + */ + fun connectGatt(device: BluetoothDevice, coroutine: CoroutineScope = ioScope) = + callbackFlow { + val callback = + object : BluetoothGattCallback() { + override fun onConnectionStateChange( + gatt: BluetoothGatt, + status: Int, + newState: Int + ) { + trySend(GattState(gatt, status, newState)) + } + } + + val gatt = device.connectGatt(context, false, callback) + + awaitClose { gatt.close() } + } + .conflate() + .shareIn(coroutine, SharingStarted.Lazily) + + // TestRule Overrides + + override fun apply(base: Statement, description: Description): Statement { + return object : Statement() { + override fun evaluate() { + setup(base) + } + } + } + + // Private Methods + + private fun setup(base: Statement) { + // Register Bumble's DCK (Digital Car Key) service + registerDckService() + // Start LE advertisement on Bumble + advertiseWithBumble() + + try { + if (isBluetoothToggled) { + toggleBluetooth() + } + + if (isGattConnected) { + connectGatt() + } + + base.evaluate() + } finally { + reset() + } + } + + private fun registerDckService() { + bumble + .dckBlocking() + .withDeadline(Deadline.after(TIMEOUT_MS, TimeUnit.MILLISECONDS)) + .register(Empty.getDefaultInstance()) + } + + private fun advertiseWithBumble() { + val requestBuilder = + AdvertiseRequest.newBuilder() + .setLegacy(true) // Bumble currently only supports legacy advertising. + .setOwnAddressType(OwnAddressType.RANDOM) + .setConnectable(true) + + if (isRemoteAdvertisingWithUuid) { + val advertisementData = + HostProto.DataTypes.newBuilder() + .addCompleteServiceClassUuids128(CCC_DK_UUID.toString()) + .build() + requestBuilder.setData(advertisementData) + } + + bumble.hostBlocking().advertise(requestBuilder.build()) + } + + private fun toggleBluetooth() = runBlocking { + val scope = CoroutineScope(Dispatchers.Default) + val bluetoothStateFlow = getBluetoothStateFlow(scope) + + try { + withTimeout(TIMEOUT_MS * 2) { // Combined timeout for enabling and disabling BT + if (bluetoothAdapter.isEnabled()) { + // Disable Bluetooth + bluetoothAdapter.disable() + // Wait for the BT state change to STATE_OFF + bluetoothStateFlow.first { it == BluetoothAdapter.STATE_OFF } + } + + // Enable Bluetooth + bluetoothAdapter.enable() + // Wait for the BT state change to STATE_ON + bluetoothStateFlow.first { it == BluetoothAdapter.STATE_ON } + } + } finally { + // Close the BT state change flow + scope.cancel("Done") + } + } + + private fun getBluetoothStateFlow(coroutine: CoroutineScope) = + callbackFlow { + val bluetoothStateFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) + val bluetoothStateReceiver = + object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (BluetoothAdapter.ACTION_STATE_CHANGED == intent.action) { + trySend( + intent.getIntExtra( + BluetoothAdapter.EXTRA_STATE, + BluetoothAdapter.ERROR + ) + ) + } + } + } + + context.registerReceiver(bluetoothStateReceiver, bluetoothStateFilter) + + awaitClose { context.unregisterReceiver(bluetoothStateReceiver) } + } + .conflate() + .shareIn(coroutine, SharingStarted.Lazily) + + private fun connectGatt() = runBlocking { + // TODO(315852141): Use supported Bumble for the given type (LE Only vs. Dual Mode) + val bumbleDevice = + bluetoothAdapter.getRemoteLeDevice( + Utils.BUMBLE_RANDOM_ADDRESS, + BluetoothDevice.ADDRESS_TYPE_RANDOM + ) + + withTimeout(TIMEOUT_MS) { + connectGatt(bumbleDevice).first { it.state == BluetoothProfile.STATE_CONNECTED } + } + } + + private fun reset() { + scope.cancel("Test Completed") + ioScope.cancel("Test Completed") + } + + companion object { + private const val TIMEOUT_MS = 3000L + private const val ACTION_DYNAMIC_RECEIVER_SCAN_RESULT = + "android.bluetooth.test.ACTION_DYNAMIC_RECEIVER_SCAN_RESULT" + // CCC DK Specification R3 1.2.0 r14 section 19.2.1.2 Bluetooth Le Pairing + private val CCC_DK_UUID = UUID.fromString("0000FFF5-0000-1000-8000-00805f9b34fb") + } +} diff --git a/framework/tests/bumble/src/android/bluetooth/GattClientTest.java b/framework/tests/bumble/src/android/bluetooth/GattClientTest.java index 051a3e33a93dcf8b59d39c5042f77e7d81f5f4bb..3e24ca5ce4c1228a7d72996b04a55824fe829cd7 100644 --- a/framework/tests/bumble/src/android/bluetooth/GattClientTest.java +++ b/framework/tests/bumble/src/android/bluetooth/GattClientTest.java @@ -25,18 +25,27 @@ import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockingDetails; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import android.bluetooth.le.BluetoothLeScanner; import android.content.Context; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; +import android.util.Log; import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.bluetooth.flags.Flags; import com.android.compatibility.common.util.AdoptShellPermissionsRule; +import com.google.protobuf.ByteString; +import com.google.testing.junit.testparameterinjector.TestParameter; +import com.google.testing.junit.testparameterinjector.TestParameterInjector; + +import org.junit.Assume; import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Rule; @@ -45,29 +54,44 @@ import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.invocation.Invocation; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.UUID; + +import pandora.GattProto.AttStatusCode; import pandora.GattProto.GattCharacteristicParams; import pandora.GattProto.GattServiceParams; +import pandora.GattProto.IndicateOnCharacteristicRequest; +import pandora.GattProto.IndicateOnCharacteristicResponse; +import pandora.GattProto.NotifyOnCharacteristicRequest; +import pandora.GattProto.NotifyOnCharacteristicResponse; import pandora.GattProto.RegisterServiceRequest; import pandora.HostProto.AdvertiseRequest; import pandora.HostProto.AdvertiseResponse; import pandora.HostProto.OwnAddressType; -import java.util.Collection; -import java.util.UUID; - -@RunWith(AndroidJUnit4.class) +@RunWith(TestParameterInjector.class) public class GattClientTest { private static final String TAG = "GattClientTest"; private static final int ANDROID_MTU = 517; private static final int MTU_REQUESTED = 23; private static final int ANOTHER_MTU_REQUESTED = 42; + private static final String NOTIFICATION_VALUE = "hello world"; private static final UUID GAP_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb"); + private static final UUID CCCD_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); + private static final UUID TEST_SERVICE_UUID = + UUID.fromString("00000000-0000-0000-0000-00000000000"); + private static final UUID TEST_CHARACTERISTIC_UUID = + UUID.fromString("00010001-0000-0000-0000-000000000000"); @ClassRule public static final AdoptShellPermissionsRule PERM = new AdoptShellPermissionsRule(); @Rule public final PandoraDevice mBumble = new PandoraDevice(); + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + private final Context mContext = ApplicationProvider.getApplicationContext(); private final BluetoothManager mManager = mContext.getSystemService(BluetoothManager.class); private final BluetoothAdapter mAdapter = mManager.getAdapter(); @@ -81,28 +105,25 @@ public class GattClientTest { mAdapter.getRemoteLeDevice( Utils.BUMBLE_RANDOM_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM); - for (int i = 0; i < 10; i++) { - BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class); - BluetoothGatt gatt = device.connectGatt(mContext, false, gattCallback); - gatt.close(); + BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class); + BluetoothGatt gatt = device.connectGatt(mContext, false, gattCallback); + gatt.close(); - // Save the number of call in the callback to be checked later - Collection invocations = mockingDetails(gattCallback).getInvocations(); - int numberOfCalls = invocations.size(); + // Save the number of call in the callback to be checked later + Collection invocations = mockingDetails(gattCallback).getInvocations(); + int numberOfCalls = invocations.size(); - BluetoothGattCallback gattCallback2 = mock(BluetoothGattCallback.class); - BluetoothGatt gatt2 = device.connectGatt(mContext, false, gattCallback2); - verify(gattCallback2, timeout(1000)) - .onConnectionStateChange(any(), anyInt(), eq(BluetoothProfile.STATE_CONNECTED)); - gatt2.close(); - - // After reconnecting with the second set of callback, check that nothing happened on - // the first set of callback - Collection invocationsAfterSomeTimes = - mockingDetails(gattCallback).getInvocations(); - int numberOfCallsAfterSomeTimes = invocationsAfterSomeTimes.size(); - assertThat(numberOfCallsAfterSomeTimes).isEqualTo(numberOfCalls); - } + BluetoothGattCallback gattCallback2 = mock(BluetoothGattCallback.class); + BluetoothGatt gatt2 = device.connectGatt(mContext, false, gattCallback2); + verify(gattCallback2, timeout(1000)) + .onConnectionStateChange(any(), anyInt(), eq(BluetoothProfile.STATE_CONNECTED)); + disconnectAndWaitDisconnection(gatt2, gattCallback2); + + // After reconnecting, verify the first callback was not invoked. + Collection invocationsAfterSomeTimes = + mockingDetails(gattCallback).getInvocations(); + int numberOfCallsAfterSomeTimes = invocationsAfterSomeTimes.size(); + assertThat(numberOfCallsAfterSomeTimes).isEqualTo(numberOfCalls); } @Test @@ -134,8 +155,12 @@ public class GattClientTest { inOrder.verify(gattCallback, timeout(1000)) .onConnectionStateChange(any(), anyInt(), eq(BluetoothProfile.STATE_CONNECTED)); + // TODO(323889717): Fix callback being called after gatt.close(). This disconnect shouldn't + // be necessary. + gatt.disconnect(); + inOrder.verify(gattCallback, timeout(1000)) + .onConnectionStateChange(any(), anyInt(), eq(BluetoothProfile.STATE_DISCONNECTED)); gatt.close(); - verifyNoMoreInteractions(gattCallback); } @Test @@ -192,50 +217,182 @@ public class GattClientTest { verify(gattCallback, timeout(10000)) .onServicesDiscovered(any(), eq(BluetoothGatt.GATT_SUCCESS)); - BluetoothGattCharacteristic characteristic = null; - - outer: - for (BluetoothGattService candidateService : gatt.getServices()) { - for (BluetoothGattCharacteristic candidateCharacteristic : - candidateService.getCharacteristics()) { - if ((candidateCharacteristic.getProperties() - & BluetoothGattCharacteristic.PROPERTY_WRITE) - != 0) { - characteristic = candidateCharacteristic; - break outer; - } - } + BluetoothGattCharacteristic characteristic = + gatt.getService(TEST_SERVICE_UUID).getCharacteristic(TEST_CHARACTERISTIC_UUID); + + byte[] newValue = new byte[] {13}; + + gatt.writeCharacteristic( + characteristic, newValue, BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + + verify(gattCallback, timeout(5000)) + .onCharacteristicWrite( + any(), eq(characteristic), eq(BluetoothGatt.GATT_SUCCESS)); + + } finally { + disconnectAndWaitDisconnection(gatt, gattCallback); + } + } + + @Test + public void clientGattNotifyOrIndicateCharacteristic(@TestParameter boolean isIndicate) + throws Exception { + registerNotificationIndicationGattService(isIndicate); + + BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class); + BluetoothGatt gatt = connectGattAndWaitConnection(gattCallback); + + try { + gatt.discoverServices(); + verify(gattCallback, timeout(10000)) + .onServicesDiscovered(any(), eq(BluetoothGatt.GATT_SUCCESS)); + + BluetoothGattCharacteristic characteristic = + gatt.getService(TEST_SERVICE_UUID).getCharacteristic(TEST_CHARACTERISTIC_UUID); + + BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CCCD_UUID); + descriptor.setValue( + isIndicate + ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE + : BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + assertThat(gatt.writeDescriptor(descriptor)).isTrue(); + + verify(gattCallback, timeout(5000)) + .onDescriptorWrite(any(), eq(descriptor), eq(BluetoothGatt.GATT_SUCCESS)); + + gatt.setCharacteristicNotification(characteristic, true); + + if (isIndicate) { + Log.i(TAG, "Triggering characteristic indication"); + triggerCharacteristicIndication(characteristic.getInstanceId()); + } else { + Log.i(TAG, "Triggering characteristic notification"); + triggerCharacteristicNotification(characteristic.getInstanceId()); } + verify(gattCallback, timeout(5000)) + .onCharacteristicChanged( + any(), any(), eq(NOTIFICATION_VALUE.getBytes(StandardCharsets.UTF_8))); + + } finally { + disconnectAndWaitDisconnection(gatt, gattCallback); + } + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENUMERATE_GATT_ERRORS) + public void connectTimeout() { + BluetoothDevice device = + mAdapter.getRemoteLeDevice( + Utils.BUMBLE_RANDOM_ADDRESS, BluetoothDevice.ADDRESS_TYPE_RANDOM); + BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class); + + // Connecting to a device not advertising results in connection timeout after 30 seconds + device.connectGatt(mContext, false, gattCallback); + + verify(gattCallback, timeout(35000)) + .onConnectionStateChange( + any(), + eq(BluetoothGatt.GATT_CONNECTION_TIMEOUT), + eq(BluetoothProfile.STATE_DISCONNECTED)); + } + + @RequiresFlagsEnabled(Flags.FLAG_GATT_FIX_DEVICE_BUSY) + @Test + public void consecutiveWriteCharacteristicFails_thenSuccess() throws Exception { + Assume.assumeTrue(Flags.gattFixDeviceBusy()); + + registerWritableGattService(); + + BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class); + BluetoothGattCallback gattCallback2 = mock(BluetoothGattCallback.class); + + BluetoothGatt gatt = connectGattAndWaitConnection(gattCallback); + BluetoothGatt gatt2 = connectGattAndWaitConnection(gattCallback2); + + try { + gatt.discoverServices(); + gatt2.discoverServices(); + verify(gattCallback, timeout(10000)) + .onServicesDiscovered(any(), eq(BluetoothGatt.GATT_SUCCESS)); + verify(gattCallback2, timeout(10000)) + .onServicesDiscovered(any(), eq(BluetoothGatt.GATT_SUCCESS)); + + BluetoothGattCharacteristic characteristic = + gatt.getService(TEST_SERVICE_UUID).getCharacteristic(TEST_CHARACTERISTIC_UUID); + + BluetoothGattCharacteristic characteristic2 = + gatt2.getService(TEST_SERVICE_UUID).getCharacteristic(TEST_CHARACTERISTIC_UUID); + byte[] newValue = new byte[] {13}; gatt.writeCharacteristic( characteristic, newValue, BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); + // TODO: b/324355496 - Make the test consistent when Bumble supports holding a response. + // Skip the test if the second write succeeded. + Assume.assumeFalse( + gatt2.writeCharacteristic( + characteristic2, + newValue, + BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT) + == BluetoothStatusCodes.SUCCESS); + verify(gattCallback, timeout(5000)) .onCharacteristicWrite( any(), eq(characteristic), eq(BluetoothGatt.GATT_SUCCESS)); + verify(gattCallback2, never()) + .onCharacteristicWrite( + any(), eq(characteristic), eq(BluetoothGatt.GATT_SUCCESS)); + assertThat( + gatt2.writeCharacteristic( + characteristic2, + newValue, + BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT)) + .isEqualTo(BluetoothStatusCodes.SUCCESS); + verify(gattCallback2, timeout(5000)) + .onCharacteristicWrite( + any(), eq(characteristic2), eq(BluetoothGatt.GATT_SUCCESS)); } finally { disconnectAndWaitDisconnection(gatt, gattCallback); + disconnectAndWaitDisconnection(gatt2, gattCallback2); } } private void registerWritableGattService() { + GattCharacteristicParams characteristicParams = + GattCharacteristicParams.newBuilder() + .setProperties(BluetoothGattCharacteristic.PROPERTY_WRITE) + .setUuid(TEST_CHARACTERISTIC_UUID.toString()) + .build(); + + GattServiceParams serviceParams = + GattServiceParams.newBuilder() + .addCharacteristics(characteristicParams) + .setUuid(TEST_SERVICE_UUID.toString()) + .build(); - String characteristicUuidString = "11111111-1111-1111-1111-111111111111"; - String serviceUuidString = "00000000-0000-0000-0000-000000000000"; + RegisterServiceRequest request = + RegisterServiceRequest.newBuilder().setService(serviceParams).build(); + mBumble.gattBlocking().registerService(request); + } + + private void registerNotificationIndicationGattService(boolean isIndicate) { GattCharacteristicParams characteristicParams = GattCharacteristicParams.newBuilder() - .setProperties(BluetoothGattCharacteristic.PROPERTY_WRITE) - .setUuid(characteristicUuidString) + .setProperties( + isIndicate + ? BluetoothGattCharacteristic.PROPERTY_INDICATE + : BluetoothGattCharacteristic.PROPERTY_NOTIFY) + .setUuid(TEST_CHARACTERISTIC_UUID.toString()) .build(); GattServiceParams serviceParams = GattServiceParams.newBuilder() .addCharacteristics(characteristicParams) - .setUuid(serviceUuidString) + .setUuid(TEST_SERVICE_UUID.toString()) .build(); RegisterServiceRequest request = @@ -244,6 +401,27 @@ public class GattClientTest { mBumble.gattBlocking().registerService(request); } + private void triggerCharacteristicNotification(int instanceId) { + NotifyOnCharacteristicRequest req = + NotifyOnCharacteristicRequest.newBuilder() + .setHandle(instanceId) + .setValue(ByteString.copyFromUtf8(NOTIFICATION_VALUE)) + .build(); + NotifyOnCharacteristicResponse resp = mBumble.gattBlocking().notifyOnCharacteristic(req); + assertThat(resp.getStatus()).isEqualTo(AttStatusCode.SUCCESS); + } + + private void triggerCharacteristicIndication(int instanceId) { + IndicateOnCharacteristicRequest req = + IndicateOnCharacteristicRequest.newBuilder() + .setHandle(instanceId) + .setValue(ByteString.copyFromUtf8(NOTIFICATION_VALUE)) + .build(); + IndicateOnCharacteristicResponse resp = + mBumble.gattBlocking().indicateOnCharacteristic(req); + assertThat(resp.getStatus()).isEqualTo(AttStatusCode.SUCCESS); + } + private void advertiseWithBumble() { AdvertiseRequest request = AdvertiseRequest.newBuilder() diff --git a/framework/tests/bumble/src/android/bluetooth/LeScanningTest.java b/framework/tests/bumble/src/android/bluetooth/LeScanningTest.java index 3f0b38668c108daf49c3237dfea3b050ded2dd78..4e71d3fd523f7a064811a7962324b56918fd90c7 100644 --- a/framework/tests/bumble/src/android/bluetooth/LeScanningTest.java +++ b/framework/tests/bumble/src/android/bluetooth/LeScanningTest.java @@ -16,7 +16,6 @@ package android.bluetooth; -import static com.google.common.io.BaseEncoding.base16; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; @@ -68,27 +67,21 @@ import pandora.HostProto.OwnAddressType; public class LeScanningTest { private static final String TAG = "LeScanningTest"; private static final int TIMEOUT_SCANNING_MS = 2000; + private static final String TEST_UUID_STRING = "00001805-0000-1000-8000-00805f9b34fb"; + private static final String TEST_ADDRESS_RANDOM_STATIC = "F0:43:A8:23:10:11"; + private static final String ACTION_DYNAMIC_RECEIVER_SCAN_RESULT = + "android.bluetooth.test.ACTION_DYNAMIC_RECEIVER_SCAN_RESULT"; @Rule public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); @Rule public final PandoraDevice mBumble = new PandoraDevice(); - private static final String TEST_ADDRESS_RANDOM_STATIC = "F0:43:A8:23:10:11"; - - // IRK must match what's defined in bumble_config.json - private static final byte[] TEST_IRK = base16().decode("1F66F4B5F0C742F807DD0DDBF64E9213"); - private final Context mContext = ApplicationProvider.getApplicationContext(); private final BluetoothManager mBluetoothManager = mContext.getSystemService(BluetoothManager.class); private final BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter(); private final BluetoothLeScanner mLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); - private static final String TEST_UUID_STRING = "00001805-0000-1000-8000-00805f9b34fb"; - - private static final String ACTION_DYNAMIC_RECEIVER_SCAN_RESULT = - "android.bluetooth.test.ACTION_DYNAMIC_RECEIVER_SCAN_RESULT"; - @Test public void startBleScan_withCallbackTypeAllMatches() { advertiseWithBumble(TEST_UUID_STRING, OwnAddressType.PUBLIC); @@ -117,7 +110,7 @@ public class LeScanningTest { .setDeviceAddress( TEST_ADDRESS_RANDOM_STATIC, BluetoothDevice.ADDRESS_TYPE_RANDOM, - TEST_IRK) + Utils.BUMBLE_IRK) .build(); List results = diff --git a/framework/tests/bumble/src/android/bluetooth/PairingTest.java b/framework/tests/bumble/src/android/bluetooth/PairingTest.java deleted file mode 100644 index 847d78d68ff2665128386dd396662fba70dcbbda..0000000000000000000000000000000000000000 --- a/framework/tests/bumble/src/android/bluetooth/PairingTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2023 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 static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; -import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.bluetooth.test_utils.EnableBluetoothRule; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.compatibility.common.util.AdoptShellPermissionsRule; - -import io.grpc.stub.StreamObserver; - -import org.hamcrest.Matcher; -import org.hamcrest.core.AllOf; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.hamcrest.MockitoHamcrest; - -import pandora.SecurityProto.PairingEvent; -import pandora.SecurityProto.PairingEventAnswer; - -import java.time.Duration; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -@RunWith(AndroidJUnit4.class) -public class PairingTest { - private static final Duration BOND_INTENT_TIMEOUT = Duration.ofSeconds(10); - - private static final Context sTargetContext = - InstrumentationRegistry.getInstrumentation().getTargetContext(); - private static final BluetoothAdapter sAdapter = - sTargetContext.getSystemService(BluetoothManager.class).getAdapter(); - - @Rule public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); - - @Rule public final PandoraDevice mBumble = new PandoraDevice(); - - @Rule - public final EnableBluetoothRule mEnableBluetoothRule = - new EnableBluetoothRule(false /* enableTestMode */, true /* toggleBluetooth */); - - @Mock private BroadcastReceiver mReceiver; - private InOrder mInOrder = null; - private BluetoothDevice mBumbleDevice; - - private final StreamObserverSpliterator mPairingEventStreamObserver = - new StreamObserverSpliterator<>(); - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mInOrder = inOrder(mReceiver); - - IntentFilter filter = new IntentFilter(); - filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); - filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST); - sTargetContext.registerReceiver(mReceiver, filter); - - mBumbleDevice = mBumble.getRemoteDevice(); - Set bondedDevices = sAdapter.getBondedDevices(); - if (bondedDevices.contains(mBumbleDevice)) { - removeBond(mBumbleDevice); - } - } - - @After - public void tearDown() throws Exception { - Set bondedDevices = sAdapter.getBondedDevices(); - if (bondedDevices.contains(mBumbleDevice)) { - removeBond(mBumbleDevice); - } - mBumbleDevice = null; - sTargetContext.unregisterReceiver(mReceiver); - } - - /** - * Test a simple BR/EDR just works pairing flow in the follow steps: - * - *

    - *
  1. 1. Bumble resets, enables inquiry and page scan, and sets I/O cap to no display no - * input - *
  2. 2. Android connects to Bumble via its MAC address - *
  3. 3. Android tries to create bond, emitting bonding intent 4. Android confirms the - * pairing via pairing request intent - *
  4. 5. Bumble confirms the pairing internally (optional, added only for test confirmation) - *
  5. 6. Android verifies bonded intent - *
- */ - @Test - public void testBrEdrPairing_phoneInitiatedBrEdrInquiryOnlyJustWorks() { - StreamObserver pairingEventAnswerObserver = - mBumble.security() - .withDeadlineAfter(BOND_INTENT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) - .onPairing(mPairingEventStreamObserver); - - assertThat(mBumbleDevice.createBond()).isTrue(); - verifyIntentReceived( - hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), - hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), - hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING)); - - verifyIntentReceived( - hasAction(BluetoothDevice.ACTION_PAIRING_REQUEST), - hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), - hasExtra( - BluetoothDevice.EXTRA_PAIRING_VARIANT, - BluetoothDevice.PAIRING_VARIANT_CONSENT)); - mBumbleDevice.setPairingConfirmation(true); - - PairingEvent pairingEvent = mPairingEventStreamObserver.iterator().next(); - assertThat(pairingEvent.hasJustWorks()).isTrue(); - pairingEventAnswerObserver.onNext( - PairingEventAnswer.newBuilder().setEvent(pairingEvent).setConfirm(true).build()); - - verifyIntentReceived( - hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), - hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), - hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED)); - - verifyNoMoreInteractions(mReceiver); - } - - private void removeBond(BluetoothDevice device) { - assertThat(device.removeBond()).isTrue(); - verifyIntentReceived( - hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), - hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), - hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE)); - verifyNoMoreInteractions(mReceiver); - } - - @SafeVarargs - private void verifyIntentReceived(Matcher... matchers) { - mInOrder.verify(mReceiver, timeout(BOND_INTENT_TIMEOUT.toMillis())) - .onReceive(any(Context.class), MockitoHamcrest.argThat(AllOf.allOf(matchers))); - } -} diff --git a/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java b/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java index a03115aae34c74cf77819ed5e3a9ff7c6270853a..0b67929273095a3b66ab788105dcb3bf4a50d1c0 100644 --- a/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java +++ b/framework/tests/bumble/src/android/bluetooth/PandoraDevice.java @@ -23,18 +23,20 @@ import androidx.test.core.app.ApplicationProvider; import com.google.protobuf.Empty; import io.grpc.ManagedChannel; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; import io.grpc.okhttp.OkHttpChannelBuilder; import org.junit.rules.ExternalResource; +import java.util.concurrent.TimeUnit; + import pandora.DckGrpc; import pandora.GATTGrpc; import pandora.HostGrpc; import pandora.HostProto; import pandora.SecurityGrpc; -import java.util.concurrent.TimeUnit; - public final class PandoraDevice extends ExternalResource { private static final String TAG = PandoraDevice.class.getSimpleName(); private final String mNetworkAddress; @@ -59,7 +61,16 @@ public final class PandoraDevice extends ExternalResource { ManagedChannel channel = OkHttpChannelBuilder.forAddress(mNetworkAddress, mPort).usePlaintext().build(); HostGrpc.HostBlockingStub stub = HostGrpc.newBlockingStub(channel); - stub.factoryReset(Empty.getDefaultInstance()); + try { + stub.factoryReset(Empty.getDefaultInstance()); + } catch (StatusRuntimeException e) { + if (e.getStatus().getCode() == Status.Code.UNAVAILABLE) { + // Server is shutting down, the call might be canceled with an UNAVAILABLE status + // because the stream is closed. + } else { + throw e; + } + } try { // terminate the channel channel.shutdown().awaitTermination(1, TimeUnit.SECONDS); diff --git a/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java b/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java index c4238ceea4ea070c4e62220883db72977e72762b..60b1b3820694ff5345c2526a84741c5293766535 100644 --- a/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java +++ b/framework/tests/bumble/src/android/bluetooth/SdpClientTest.java @@ -23,7 +23,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.ParcelUuid; -import android.os.Parcelable; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -40,9 +39,6 @@ import org.junit.runner.RunWith; import pandora.HostProto.ConnectRequest; import pandora.HostProto.WaitConnectionRequest; -import java.util.ArrayList; -import java.util.UUID; - /** Test cases for {@link ServiceDiscoveryManager}. */ @RunWith(AndroidJUnit4.class) public class SdpClientTest { @@ -52,7 +48,7 @@ public class SdpClientTest { private final BluetoothManager mManager = mContext.getSystemService(BluetoothManager.class); private final BluetoothAdapter mAdapter = mManager.getAdapter(); - private SettableFuture> mFutureIntent; + private SettableFuture mFutureIntent; @Rule public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); @@ -63,16 +59,10 @@ public class SdpClientTest { @Override public void onReceive(Context context, Intent intent) { if (BluetoothDevice.ACTION_UUID.equals(intent.getAction())) { - Parcelable[] parcelable = - (Parcelable[]) intent.getExtra(BluetoothDevice.EXTRA_UUID); - if (parcelable != null) { - ArrayList list = new ArrayList(); - for (Parcelable p : parcelable) { - ParcelUuid uuid = (ParcelUuid) p; - list.add(uuid.getUuid()); - } - mFutureIntent.set(list); - } + ParcelUuid[] parcelUuids = + intent.getParcelableArrayExtra( + BluetoothDevice.EXTRA_UUID, ParcelUuid.class); + mFutureIntent.set(parcelUuids); } } }; @@ -107,8 +97,8 @@ public class SdpClientTest { // Execute service discovery procedure assertThat(device.fetchUuidsWithSdp()).isTrue(); - ArrayList list = mFutureIntent.get(); - assertThat(list.isEmpty()).isFalse(); + ParcelUuid[] arr = mFutureIntent.get(); + assertThat(arr).asList().contains(BluetoothUuid.HFP); mContext.unregisterReceiver(mConnectionStateReceiver); } diff --git a/framework/tests/bumble/src/android/bluetooth/Utils.java b/framework/tests/bumble/src/android/bluetooth/Utils.java index 09e32814cf44a71d652ae04bb98c1b96f726bb4e..bea9e5aeab43cd41815b7deb9f5b1a57818e3a9e 100644 --- a/framework/tests/bumble/src/android/bluetooth/Utils.java +++ b/framework/tests/bumble/src/android/bluetooth/Utils.java @@ -23,7 +23,9 @@ import com.google.protobuf.ByteString; import java.util.Locale; public final class Utils { + // From bumble_config.json public static final String BUMBLE_RANDOM_ADDRESS = "51:F7:A8:75:AC:5E"; + public static final byte[] BUMBLE_IRK = base16().decode("1F66F4B5F0C742F807DD0DDBF64E9213"); public static String addressStringFromByteString(ByteString bs) { StringBuilder refAddrBuilder = new StringBuilder(); diff --git a/framework/tests/bumble/src/android/bluetooth/pairing/OWNERS b/framework/tests/bumble/src/android/bluetooth/pairing/OWNERS new file mode 100644 index 0000000000000000000000000000000000000000..75539edb096453c46f9ce6348cf4e716e31d7a28 --- /dev/null +++ b/framework/tests/bumble/src/android/bluetooth/pairing/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 27441 +# Project owners +rwt@google.com diff --git a/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java b/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..585c0d893e95cecb82f21727d6e129a8d79afd3a --- /dev/null +++ b/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java @@ -0,0 +1,526 @@ +/* + * Copyright (C) 2023 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.pairing; + +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; +import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.bluetooth.PandoraDevice; +import android.bluetooth.StreamObserverSpliterator; +import android.bluetooth.test_utils.EnableBluetoothRule; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.ParcelUuid; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; +import android.util.Log; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.bluetooth.flags.Flags; +import com.android.compatibility.common.util.AdoptShellPermissionsRule; + +import io.grpc.stub.StreamObserver; + +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.hamcrest.core.AllOf; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.hamcrest.MockitoHamcrest; + +import java.time.Duration; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import pandora.GattProto; +import pandora.HostProto.AdvertiseRequest; +import pandora.HostProto.AdvertiseResponse; +import pandora.HostProto.OwnAddressType; +import pandora.SecurityProto.LESecurityLevel; +import pandora.SecurityProto.PairingEvent; +import pandora.SecurityProto.PairingEventAnswer; +import pandora.SecurityProto.SecureRequest; +import pandora.SecurityProto.SecureResponse; + +@RunWith(AndroidJUnit4.class) +public class PairingTest { + private static final String TAG = "PairingTest"; + private static final Duration BOND_INTENT_TIMEOUT = Duration.ofSeconds(10); + + private static final ParcelUuid BATTERY_UUID = + ParcelUuid.fromString("0000180F-0000-1000-8000-00805F9B34FB"); + + private static final Context sTargetContext = + InstrumentationRegistry.getInstrumentation().getTargetContext(); + private static final BluetoothAdapter sAdapter = + sTargetContext.getSystemService(BluetoothManager.class).getAdapter(); + + @Rule(order = 0) + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + + @Rule(order = 1) + public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); + + @Rule(order = 2) + public final PandoraDevice mBumble = new PandoraDevice(); + + @Rule(order = 3) + public final EnableBluetoothRule mEnableBluetoothRule = + new EnableBluetoothRule(false /* enableTestMode */, true /* toggleBluetooth */); + + @Mock private BroadcastReceiver mReceiver; + private final Map mActionRegistrationCounts = new HashMap<>(); + private InOrder mInOrder = null; + private BluetoothDevice mBumbleDevice; + + private final StreamObserverSpliterator mPairingEventStreamObserver = + new StreamObserverSpliterator<>(); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + doAnswer( + inv -> { + Log.d( + TAG, + "onReceive(): intent=" + Arrays.toString(inv.getArguments())); + Intent intent = inv.getArgument(1); + String action = intent.getAction(); + if (BluetoothDevice.ACTION_UUID.equals(action)) { + ParcelUuid[] uuids = + intent.getParcelableArrayExtra( + BluetoothDevice.EXTRA_UUID, ParcelUuid.class); + Log.d(TAG, "onReceive(): UUID=" + Arrays.toString(uuids)); + } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) { + int bondState = + intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1); + Log.d(TAG, "onReceive(): bondState=" + bondState); + } + return null; + }) + .when(mReceiver) + .onReceive(any(), any()); + + mInOrder = inOrder(mReceiver); + + mBumbleDevice = mBumble.getRemoteDevice(); + Set bondedDevices = sAdapter.getBondedDevices(); + if (bondedDevices.contains(mBumbleDevice)) { + removeBond(mBumbleDevice); + } + } + + @After + public void tearDown() throws Exception { + Set bondedDevices = sAdapter.getBondedDevices(); + if (bondedDevices.contains(mBumbleDevice)) { + removeBond(mBumbleDevice); + } + mBumbleDevice = null; + if (getTotalActionRegistrationCounts() > 0) { + sTargetContext.unregisterReceiver(mReceiver); + mActionRegistrationCounts.clear(); + } + } + + /** + * Test a simple BR/EDR just works pairing flow in the follow steps: + * + *
    + *
  1. 1. Bumble resets, enables inquiry and page scan, and sets I/O cap to no display no + * input + *
  2. 2. Android connects to Bumble via its MAC address + *
  3. 3. Android tries to create bond, emitting bonding intent 4. Android confirms the + * pairing via pairing request intent + *
  4. 5. Bumble confirms the pairing internally (optional, added only for test confirmation) + *
  5. 6. Android verifies bonded intent + *
+ */ + @Test + public void testBrEdrPairing_phoneInitiatedBrEdrInquiryOnlyJustWorks() { + registerIntentActions( + BluetoothDevice.ACTION_BOND_STATE_CHANGED, BluetoothDevice.ACTION_PAIRING_REQUEST); + + StreamObserver pairingEventAnswerObserver = + mBumble.security() + .withDeadlineAfter(BOND_INTENT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) + .onPairing(mPairingEventStreamObserver); + + assertThat(mBumbleDevice.createBond()).isTrue(); + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING)); + + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_PAIRING_REQUEST), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra( + BluetoothDevice.EXTRA_PAIRING_VARIANT, + BluetoothDevice.PAIRING_VARIANT_CONSENT)); + mBumbleDevice.setPairingConfirmation(true); + + PairingEvent pairingEvent = mPairingEventStreamObserver.iterator().next(); + assertThat(pairingEvent.hasJustWorks()).isTrue(); + pairingEventAnswerObserver.onNext( + PairingEventAnswer.newBuilder().setEvent(pairingEvent).setConfirm(true).build()); + + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED)); + + verifyNoMoreInteractions(mReceiver); + + unregisterIntentActions( + BluetoothDevice.ACTION_BOND_STATE_CHANGED, BluetoothDevice.ACTION_PAIRING_REQUEST); + } + + /** + * Test if parallel GATT service discovery interrupts cancelling LE pairing + * + *

Prerequisites: + * + *

    + *
  1. Bumble and Android are not bonded + *
  2. Bumble has GATT services in addition to GAP and GATT services + *
+ * + *

Steps: + * + *

    + *
  1. Bumble is discoverable and connectable over LE + *
  2. Android connects to Bumble over LE + *
  3. Android starts GATT service discovery + *
  4. Bumble initiates pairing + *
  5. Android does not confirm the pairing immediately + *
  6. Service discovery completes + *
  7. Android cancels the pairing + *
+ * + * Expectation: Pairing gets cancelled instead of getting timed out + */ + @Test + @RequiresFlagsEnabled(Flags.FLAG_RESET_PAIRING_ONLY_FOR_RELATED_SERVICE_DISCOVERY) + public void testCancelBondLe_WithGattServiceDiscovery() { + registerIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + + // Outgoing GATT service discovery and incoming LE pairing in parallel + StreamObserverSpliterator responseObserver = + helper_OutgoingGattServiceDiscoveryWithIncomingLePairing(); + + // Cancel pairing from Android + assertThat(mBumbleDevice.cancelBondProcess()).isTrue(); + + SecureResponse secureResponse = responseObserver.iterator().next(); + assertThat(secureResponse.hasPairingFailure()).isTrue(); + + // Pairing should be cancelled in a moment instead of timing out in 30 + // seconds + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE)); + + verifyNoMoreInteractions(mReceiver); + + unregisterIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + } + + /** + * Test if parallel GATT service discovery interrupts the LE pairing + * + *

Prerequisites: + * + *

    + *
  1. Bumble and Android are not bonded + *
  2. Bumble has GATT services in addition to GAP and GATT services + *
+ * + *

Steps: + * + *

    + *
  1. Bumble is discoverable and connectable over LE + *
  2. Android connects to Bumble over LE + *
  3. Android starts GATT service discovery + *
  4. Bumble starts pairing + *
  5. Service discovery completes + *
  6. Android does confirms the pairing + *
  7. Pairing is successful + *
+ * + * Expectation: Pairing succeeds + */ + @Test + @RequiresFlagsEnabled(Flags.FLAG_RESET_PAIRING_ONLY_FOR_RELATED_SERVICE_DISCOVERY) + public void testBondLe_WithGattServiceDiscovery() { + registerIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + + // Outgoing GATT service discovery and incoming LE pairing in parallel + StreamObserverSpliterator responseObserver = + helper_OutgoingGattServiceDiscoveryWithIncomingLePairing(); + + // Approve pairing from Android + assertThat(mBumbleDevice.setPairingConfirmation(true)).isTrue(); + + SecureResponse secureResponse = responseObserver.iterator().next(); + assertThat(secureResponse.hasSuccess()).isTrue(); + + // Ensure that pairing succeeds + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED)); + + verifyNoMoreInteractions(mReceiver); + + unregisterIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + } + + /* Starts outgoing GATT service discovery and incoming LE pairing in parallel */ + private StreamObserverSpliterator + helper_OutgoingGattServiceDiscoveryWithIncomingLePairing() { + // Setup intent filters + registerIntentActions( + BluetoothDevice.ACTION_BOND_STATE_CHANGED, + BluetoothDevice.ACTION_PAIRING_REQUEST, + BluetoothDevice.ACTION_UUID, + BluetoothDevice.ACTION_ACL_CONNECTED); + + // Register lots of interesting GATT services on Bumble + for (int i = 0; i < 40; i++) { + mBumble.gattBlocking() + .registerService( + GattProto.RegisterServiceRequest.newBuilder() + .setService( + GattProto.GattServiceParams.newBuilder() + .setUuid(BATTERY_UUID.toString()) + .build()) + .build()); + } + + // Start GATT service discovery, this will establish LE ACL + assertThat(mBumbleDevice.fetchUuidsWithSdp(BluetoothDevice.TRANSPORT_LE)).isTrue(); + + // Make Bumble connectable + AdvertiseResponse advertiseResponse = + mBumble.hostBlocking() + .advertise( + AdvertiseRequest.newBuilder() + .setLegacy(true) + .setConnectable(true) + .setOwnAddressType(OwnAddressType.PUBLIC) + .build()) + .next(); + + // Todo: Unexpected empty ACTION_UUID intent is generated + verifyIntentReceived(hasAction(BluetoothDevice.ACTION_UUID)); + + // Wait for connection on Android + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_ACL_CONNECTED), + hasExtra(BluetoothDevice.EXTRA_TRANSPORT, BluetoothDevice.TRANSPORT_LE)); + + // Start pairing from Bumble + StreamObserverSpliterator responseObserver = + new StreamObserverSpliterator<>(); + mBumble.security() + .secure( + SecureRequest.newBuilder() + .setConnection(advertiseResponse.getConnection()) + .setLe(LESecurityLevel.LE_LEVEL3) + .build(), + responseObserver); + + // Wait for incoming pairing notification on Android + // TODO: Order of these events is not deterministic + verifyIntentReceivedUnordered( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING)); + verifyIntentReceivedUnordered( + hasAction(BluetoothDevice.ACTION_PAIRING_REQUEST), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra( + BluetoothDevice.EXTRA_PAIRING_VARIANT, + BluetoothDevice.PAIRING_VARIANT_CONSENT)); + + // Allow participating in the incoming pairing on Android + assertThat(mBumbleDevice.setPairingConfirmation(true)).isTrue(); + + // Wait for pairing approval notification on Android + verifyIntentReceivedUnordered( + 2, + hasAction(BluetoothDevice.ACTION_PAIRING_REQUEST), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra( + BluetoothDevice.EXTRA_PAIRING_VARIANT, + BluetoothDevice.PAIRING_VARIANT_CONSENT)); + + // Wait for GATT service discovery to complete on Android + // so that ACTION_UUID is received here. + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_UUID), + hasExtra( + BluetoothDevice.EXTRA_UUID, + Matchers.arrayContainingInAnyOrder(BATTERY_UUID))); + + unregisterIntentActions( + BluetoothDevice.ACTION_BOND_STATE_CHANGED, + BluetoothDevice.ACTION_PAIRING_REQUEST, + BluetoothDevice.ACTION_UUID, + BluetoothDevice.ACTION_ACL_CONNECTED); + + return responseObserver; + } + + private void removeBond(BluetoothDevice device) { + registerIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + + assertThat(device.removeBond()).isTrue(); + verifyIntentReceived( + hasAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED), + hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice), + hasExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE)); + + unregisterIntentActions(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + } + + @SafeVarargs + private void verifyIntentReceived(Matcher... matchers) { + mInOrder.verify(mReceiver, timeout(BOND_INTENT_TIMEOUT.toMillis())) + .onReceive(any(Context.class), MockitoHamcrest.argThat(AllOf.allOf(matchers))); + } + + @SafeVarargs + private void verifyIntentReceivedUnordered(int num, Matcher... matchers) { + verify(mReceiver, timeout(BOND_INTENT_TIMEOUT.toMillis()).times(num)) + .onReceive(any(Context.class), MockitoHamcrest.argThat(AllOf.allOf(matchers))); + } + + @SafeVarargs + private void verifyIntentReceivedUnordered(Matcher... matchers) { + verifyIntentReceivedUnordered(1, matchers); + } + + /** + * Helper function to add reference count to registered intent actions + * + * @param actions new intent actions to add. If the array is empty, it is a no-op. + */ + private void registerIntentActions(String... actions) { + if (actions.length == 0) { + return; + } + if (getTotalActionRegistrationCounts() > 0) { + Log.d(TAG, "registerIntentActions(): unregister ALL intents"); + sTargetContext.unregisterReceiver(mReceiver); + } + for (String action : actions) { + mActionRegistrationCounts.merge(action, 1, Integer::sum); + } + IntentFilter filter = new IntentFilter(); + mActionRegistrationCounts.entrySet().stream() + .filter(entry -> entry.getValue() > 0) + .forEach( + entry -> { + Log.d( + TAG, + "registerIntentActions(): Registering action = " + + entry.getKey()); + filter.addAction(entry.getKey()); + }); + sTargetContext.registerReceiver(mReceiver, filter); + } + + /** + * Helper function to reduce reference count to registered intent actions If total reference + * count is zero after removal, no broadcast receiver will be registered. + * + * @param actions intent actions to be removed. If some action is not registered, it is no-op + * for that action. If the actions array is empty, it is also a no-op. + */ + private void unregisterIntentActions(String... actions) { + if (actions.length == 0) { + return; + } + if (getTotalActionRegistrationCounts() <= 0) { + return; + } + Log.d(TAG, "unregisterIntentActions(): unregister ALL intents"); + sTargetContext.unregisterReceiver(mReceiver); + for (String action : actions) { + if (!mActionRegistrationCounts.containsKey(action)) { + continue; + } + mActionRegistrationCounts.put(action, mActionRegistrationCounts.get(action) - 1); + if (mActionRegistrationCounts.get(action) <= 0) { + mActionRegistrationCounts.remove(action); + } + } + if (getTotalActionRegistrationCounts() > 0) { + IntentFilter filter = new IntentFilter(); + mActionRegistrationCounts.entrySet().stream() + .filter(entry -> entry.getValue() > 0) + .forEach( + entry -> { + Log.d( + TAG, + "unregisterIntentActions(): Registering action = " + + entry.getKey()); + filter.addAction(entry.getKey()); + }); + sTargetContext.registerReceiver(mReceiver, filter); + } + } + + /** + * Get sum of reference count from all registered actions + * + * @return sum of reference count from all registered actions + */ + private int getTotalActionRegistrationCounts() { + return mActionRegistrationCounts.values().stream().reduce(0, Integer::sum); + } +} diff --git a/framework/tests/metrics/device/android/bluetooth/BluetoothMetricsHelperTest.kt b/framework/tests/metrics/device/android/bluetooth/BluetoothMetricsHelperTest.kt index e105366e4d239770ca86ed285164b8dd014ce543..5b4ab8246c501d53a3fe1a339881894234ddd00b 100644 --- a/framework/tests/metrics/device/android/bluetooth/BluetoothMetricsHelperTest.kt +++ b/framework/tests/metrics/device/android/bluetooth/BluetoothMetricsHelperTest.kt @@ -16,6 +16,8 @@ package android.bluetooth +import android.content.BroadcastReceiver +import android.content.Context import android.content.Intent import android.content.IntentFilter import android.net.MacAddress @@ -30,10 +32,12 @@ import io.grpc.okhttp.OkHttpChannelBuilder import java.util.concurrent.TimeUnit import kotlinx.coroutines.async import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.shareIn +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -46,6 +50,7 @@ import pandora.HostGrpc import pandora.HostProto.ConnectRequest import pandora.HostProto.DisconnectRequest +@Suppress("DEPRECATION") @kotlinx.coroutines.ExperimentalCoroutinesApi @RunWith(AndroidJUnit4::class) class BluetoothMetricsHelperTest { @@ -68,7 +73,23 @@ class BluetoothMetricsHelperTest { private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) private val context = InstrumentationRegistry.getInstrumentation().getContext() - private val bluetoothAdapter = context.getSystemService(BluetoothManager::class.java)!!.adapter + + private val bluetoothAdapter: BluetoothAdapter = + context.getSystemService(BluetoothManager::class.java)!!.adapter + private val adapterState = MutableStateFlow(bluetoothAdapter.state) + + init { + context.registerReceiver( + object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + adapterState.tryEmit( + intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) + ) + } + }, + IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED) + ) + } @Before fun setUp() { @@ -92,6 +113,10 @@ class BluetoothMetricsHelperTest { mHostBlockingStub = HostGrpc.newBlockingStub(mChannel) mHostStub = HostGrpc.newStub(mChannel) mHostBlockingStub.withWaitForReady()?.readLocalAddress(Empty.getDefaultInstance()) + + // Make sure the Adapter is on. + bluetoothAdapter.enable() + runBlocking { adapterState.first { it == BluetoothAdapter.STATE_ON } } } @After @@ -132,4 +157,12 @@ class BluetoothMetricsHelperTest { DisconnectRequest.newBuilder().setConnection(connectResponse.connection).build() mHostBlockingStub.disconnect(disconnectRequest) } + + @Test + fun testBluetoothDisableEnable() = runTest { + bluetoothAdapter.disable() + adapterState.first { it == BluetoothAdapter.STATE_OFF } + bluetoothAdapter.enable() + adapterState.first { it == BluetoothAdapter.STATE_ON } + } } diff --git a/framework/tests/metrics/host/Android.bp b/framework/tests/metrics/host/Android.bp index 818e88ac4054909e3d927a5eed6a11986060bd4b..f90e35a29d795e6ecfa8122d4876fab7a97d5429 100644 --- a/framework/tests/metrics/host/Android.bp +++ b/framework/tests/metrics/host/Android.bp @@ -20,6 +20,10 @@ java_test_host { ":BluetoothMetricsTestApp", ], + data_native_bins: [ + "bumble_pandora_server", + ], + required: ["bumble_pandora_server"], test_suites: [ diff --git a/framework/tests/metrics/host/AndroidTest.xml b/framework/tests/metrics/host/AndroidTest.xml index 860fb0a02066d8052270245962ce215927fba54a..752a6d1e11c5faf6d00e545f9b2a0d384d386f13 100644 --- a/framework/tests/metrics/host/AndroidTest.xml +++ b/framework/tests/metrics/host/AndroidTest.xml @@ -20,8 +20,10 @@ diff --git a/framework/tests/metrics/host/android/bluetooth/MetricsTest.kt b/framework/tests/metrics/host/android/bluetooth/MetricsTest.kt index a8c0674da6b14e067cff09dad29bcfd265e6c430..cd0619fec9e3b92b479577cb18fb2b4360969e6a 100644 --- a/framework/tests/metrics/host/android/bluetooth/MetricsTest.kt +++ b/framework/tests/metrics/host/android/bluetooth/MetricsTest.kt @@ -20,10 +20,12 @@ import android.cts.statsdatom.lib.ConfigUtils import android.cts.statsdatom.lib.DeviceUtils import android.cts.statsdatom.lib.ReportUtils import com.android.os.AtomsProto +import com.android.os.AtomsProto.BluetoothEnabledStateChanged import com.android.os.StatsLog import com.android.tradefed.testtype.DeviceJUnit4ClassRunner import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test import com.google.common.truth.Truth.assertThat +import java.time.Duration import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -44,25 +46,38 @@ class MetricsTest : BaseHostJUnit4Test() { } @Test - fun aclMetricTest() { - val data = uploadAtomConfigAndTriggerTest("incomingClassicConnectionTest") - assertThat(data.size).isAtLeast(2) - val atom1 = data.get(0).getAtom().getBluetoothAclConnectionStateChanged() - assertThat(atom1.getState()).isEqualTo(ConnectionStateEnum.CONNECTION_STATE_CONNECTED) - assertThat(atom1.getTransport()).isEqualTo(TransportTypeEnum.TRANSPORT_TYPE_BREDR) - val atom2 = data.get(1).getAtom().getBluetoothAclConnectionStateChanged() - assertThat(atom2.getState()).isEqualTo(ConnectionStateEnum.CONNECTION_STATE_DISCONNECTED) - assertThat(atom2.getTransport()).isEqualTo(TransportTypeEnum.TRANSPORT_TYPE_BREDR) - assertThat(atom2.getMetricId()).isEqualTo(atom1.getMetricId()) + fun testBluetoothDisableEnable_shouldProduceEnabledStateChanged() { + val data = + uploadAtomConfigAndTriggerTest( + "testBluetoothDisableEnable", + intArrayOf(AtomsProto.Atom.BLUETOOTH_ENABLED_STATE_CHANGED_FIELD_NUMBER) + ) + // First atom might be the setup one. + val offset = + data[0].atom.bluetoothEnabledStateChanged.let { + if (it.state == BluetoothEnabledStateChanged.State.ENABLED) { + 1 + } else { + 0 + } + } + data[offset].atom.bluetoothEnabledStateChanged.apply { + assertThat(state).isEqualTo(BluetoothEnabledStateChanged.State.DISABLED) + assertThat(previousState).isEqualTo(BluetoothEnabledStateChanged.State.ENABLED) + assertThat(timeSinceLastChangedMillis).isGreaterThan(Duration.ofMillis(1).toMillis()) + } + data[offset + 1].atom.bluetoothEnabledStateChanged.apply { + assertThat(state).isEqualTo(BluetoothEnabledStateChanged.State.ENABLED) + assertThat(previousState).isEqualTo(BluetoothEnabledStateChanged.State.DISABLED) + assertThat(timeSinceLastChangedMillis).isGreaterThan(Duration.ofMillis(1).toMillis()) + } } - private fun uploadAtomConfigAndTriggerTest(testName: String): List { - val device = getDevice() - ConfigUtils.uploadConfigForPushedAtoms( - device, - TEST_APP_PKG_NAME, - intArrayOf(AtomsProto.Atom.BLUETOOTH_ACL_CONNECTION_STATE_CHANGED_FIELD_NUMBER) - ) + private fun uploadAtomConfigAndTriggerTest( + testName: String, + atoms: IntArray + ): List { + ConfigUtils.uploadConfigForPushedAtoms(device, TEST_APP_PKG_NAME, atoms) DeviceUtils.runDeviceTests(device, TEST_APP_PKG_NAME, TEST_APP_CLASS_NAME, testName) diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java index b75b8f9476529f4cf4b207827da2b5470266c31e..e2c8c193d8312707df46f051efeafd42e1b56914 100644 --- a/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java +++ b/framework/tests/unit/src/android/bluetooth/BluetoothCodecConfigTest.java @@ -16,8 +16,7 @@ package android.bluetooth; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import junit.framework.TestCase; /** Unit test cases for {@link BluetoothCodecConfig}. */ diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java index 48d5265762c97776a39b354810c428ad8aa7317e..6f53cb363326a1e77136a01a37b0c3c814e1eaa2 100644 --- a/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java +++ b/framework/tests/unit/src/android/bluetooth/BluetoothCodecStatusTest.java @@ -16,12 +16,10 @@ package android.bluetooth; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.TestCase; - +import androidx.test.filters.SmallTest; import java.util.List; import java.util.Objects; +import junit.framework.TestCase; /** Unit test cases for {@link BluetoothCodecStatus}. */ public class BluetoothCodecStatusTest extends TestCase { diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothLeAudioCodecConfigTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothLeAudioCodecConfigTest.java index b3e88970f2d47f5dfeea9fec2c8f2ae037d837df..fa0bbc6e566c235d1fe4a70d26c2094795ca085f 100644 --- a/framework/tests/unit/src/android/bluetooth/BluetoothLeAudioCodecConfigTest.java +++ b/framework/tests/unit/src/android/bluetooth/BluetoothLeAudioCodecConfigTest.java @@ -16,8 +16,7 @@ package android.bluetooth; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import junit.framework.TestCase; /** Unit test cases for {@link BluetoothLeAudioCodecConfig}. */ diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothProfileConnectorTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothProfileConnectorTest.java deleted file mode 100644 index 63fbcabe23e55c8577ae7ea3c935122f0fb205a4..0000000000000000000000000000000000000000 --- a/framework/tests/unit/src/android/bluetooth/BluetoothProfileConnectorTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2023 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 static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verifyZeroInteractions; - -import android.content.ComponentName; -import android.os.Binder; -import android.os.Handler; -import android.os.Looper; -import android.os.RemoteException; -import android.os.test.TestLooper; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InOrder; - -/** Test cases for {@link BluetoothProfileConnector}. */ -@SmallTest -@RunWith(AndroidJUnit4.class) -public class BluetoothProfileConnectorTest { - static class FakeBluetoothManager extends IBluetoothManager.Default { - private IBluetoothStateChangeCallback mStateChangeCallback; - private IBluetoothProfileServiceConnection mServiceConnection; - private final Handler mHandler; - - private FakeBluetoothManager(Looper looper) { - mHandler = new Handler(looper); - } - - Looper getLooper() { - return mHandler.getLooper(); - } - - @Override - public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) { - mStateChangeCallback = callback; - } - - @Override - public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) - throws RemoteException { - if (callback != mStateChangeCallback) throw new IllegalStateException(); - - mStateChangeCallback.onBluetoothStateChange(false); - - mStateChangeCallback = null; - } - - @Override - public boolean bindBluetoothProfileService( - int profile, IBluetoothProfileServiceConnection proxy) { - mServiceConnection = proxy; - return true; - } - - @Override - public void unbindBluetoothProfileService( - int profile, IBluetoothProfileServiceConnection proxy) { - if (proxy != mServiceConnection) throw new IllegalStateException(); - - mHandler.post( - () -> { - try { - proxy.onServiceDisconnected(new ComponentName("pkg", "cls")); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - }); - - mServiceConnection = null; - } - } - - private BluetoothProfileConnector createBluetoothProfileConnector( - BluetoothProfile profile, FakeBluetoothManager bluetoothManager) { - return new BluetoothProfileConnector( - bluetoothManager.getLooper(), profile, BluetoothProfile.HEADSET, bluetoothManager); - } - - @Test - public void bind_registerServiceConnection() throws RemoteException { - TestLooper looper = new TestLooper(); - FakeBluetoothManager bluetoothManager = new FakeBluetoothManager(looper.getLooper()); - BluetoothProfileConnector connector = - createBluetoothProfileConnector(null, bluetoothManager); - BluetoothProfile.ServiceListener listener = mock(BluetoothProfile.ServiceListener.class); - - connector.connect("test.package", listener); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(true); - looper.dispatchAll(); - - assertThat(bluetoothManager.mServiceConnection).isNotNull(); - verifyZeroInteractions(listener); - } - - @Test - public void unbind_unregisterServiceConnection() throws RemoteException { - TestLooper looper = new TestLooper(); - FakeBluetoothManager bluetoothManager = new FakeBluetoothManager(looper.getLooper()); - BluetoothProfile profile = mock(BluetoothProfile.class); - BluetoothProfileConnector connector = - createBluetoothProfileConnector(profile, bluetoothManager); - ComponentName componentName = new ComponentName("pkg", "cls"); - BluetoothProfile.ServiceListener listener = mock(BluetoothProfile.ServiceListener.class); - - connector.connect("test.package", listener); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(true); - bluetoothManager.mServiceConnection.onServiceConnected(componentName, new Binder()); - looper.dispatchAll(); - bluetoothManager.mServiceConnection.onServiceDisconnected(componentName); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(false); - looper.dispatchAll(); - - assertThat(bluetoothManager.mServiceConnection).isNull(); - InOrder order = inOrder(listener, profile); - order.verify(profile).onServiceConnected(any()); - order.verify(listener).onServiceConnected(anyInt(), any()); - order.verify(profile).onServiceDisconnected(); - order.verify(listener).onServiceDisconnected(anyInt()); - verifyNoMoreInteractions(listener); - } - - @Test - public void upThenDown_unregisterServiceConnection() throws RemoteException { - TestLooper looper = new TestLooper(); - FakeBluetoothManager bluetoothManager = new FakeBluetoothManager(looper.getLooper()); - BluetoothProfile profile = mock(BluetoothProfile.class); - BluetoothProfileConnector connector = - createBluetoothProfileConnector(profile, bluetoothManager); - BluetoothProfile.ServiceListener listener = mock(BluetoothProfile.ServiceListener.class); - - connector.connect("test.package", listener); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(true); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(false); - looper.dispatchAll(); - - assertThat(bluetoothManager.mServiceConnection).isNull(); - verifyZeroInteractions(listener); - } - - @Test - public void disconnectAfterConnect_unregisterCallbacks() { - TestLooper looper = new TestLooper(); - FakeBluetoothManager bluetoothManager = new FakeBluetoothManager(looper.getLooper()); - BluetoothProfileConnector connector = - createBluetoothProfileConnector(null, bluetoothManager); - BluetoothProfile.ServiceListener listener = mock(BluetoothProfile.ServiceListener.class); - - connector.connect("test.package", listener); - connector.disconnect(); - looper.dispatchAll(); - - assertThat(bluetoothManager.mServiceConnection).isNull(); - assertThat(bluetoothManager.mStateChangeCallback).isNull(); - InOrder order = inOrder(listener); - // TODO(b/309635805): This should not be here - order.verify(listener).onServiceDisconnected(anyInt()); - verifyNoMoreInteractions(listener); - } - - @Test - public void disconnectAfterBind_unregisterCallbacks() throws RemoteException { - TestLooper looper = new TestLooper(); - FakeBluetoothManager bluetoothManager = new FakeBluetoothManager(looper.getLooper()); - BluetoothProfile profile = mock(BluetoothProfile.class); - BluetoothProfileConnector connector = - createBluetoothProfileConnector(profile, bluetoothManager); - BluetoothProfile.ServiceListener listener = mock(BluetoothProfile.ServiceListener.class); - - connector.connect("test.package", listener); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(true); - looper.dispatchAll(); - connector.disconnect(); - looper.dispatchAll(); - - assertThat(bluetoothManager.mServiceConnection).isNull(); - assertThat(bluetoothManager.mStateChangeCallback).isNull(); - InOrder order = inOrder(listener, profile); - // TODO(b/309635805): This should not be here - order.verify(listener).onServiceDisconnected(anyInt()); - order.verify(profile).onServiceDisconnected(); - verifyNoMoreInteractions(listener); - } - - @Test - public void disconnectAfterUnbind_unregisterCallbacks() throws RemoteException { - TestLooper looper = new TestLooper(); - FakeBluetoothManager bluetoothManager = new FakeBluetoothManager(looper.getLooper()); - BluetoothProfile profile = mock(BluetoothProfile.class); - BluetoothProfileConnector connector = - createBluetoothProfileConnector(profile, bluetoothManager); - ComponentName componentName = new ComponentName("pkg", "cls"); - BluetoothProfile.ServiceListener listener = mock(BluetoothProfile.ServiceListener.class); - - connector.connect("test.package", listener); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(true); - bluetoothManager.mServiceConnection.onServiceConnected(componentName, new Binder()); - looper.dispatchAll(); - bluetoothManager.mServiceConnection.onServiceDisconnected(componentName); - bluetoothManager.mStateChangeCallback.onBluetoothStateChange(false); - looper.dispatchAll(); - connector.disconnect(); - looper.dispatchAll(); - - assertThat(bluetoothManager.mServiceConnection).isNull(); - assertThat(bluetoothManager.mStateChangeCallback).isNull(); - InOrder order = inOrder(listener, profile); - order.verify(profile).onServiceConnected(any()); - order.verify(listener).onServiceConnected(anyInt(), any()); - order.verify(profile).onServiceDisconnected(); - // TODO(b/309635805): Should be only one - order.verify(listener, times(2)).onServiceDisconnected(anyInt()); - verifyNoMoreInteractions(listener); - } -} diff --git a/framework/tests/unit/src/android/bluetooth/BluetoothUuidTest.java b/framework/tests/unit/src/android/bluetooth/BluetoothUuidTest.java index b3d7758396e3689f1eceb6f08462aabb3505f9ff..745b73e9582cead5922d4594bdd002e6ebe0311e 100644 --- a/framework/tests/unit/src/android/bluetooth/BluetoothUuidTest.java +++ b/framework/tests/unit/src/android/bluetooth/BluetoothUuidTest.java @@ -17,8 +17,7 @@ package android.bluetooth; import android.os.ParcelUuid; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import junit.framework.TestCase; /** Unit test cases for {@link BluetoothUuid}. */ diff --git a/framework/tests/unit/src/android/bluetooth/le/ScanFilterTest.java b/framework/tests/unit/src/android/bluetooth/le/ScanFilterTest.java index fa50315ef015372024a85f9c909fd93a28f96fa4..120034c565ac63afd9e8327ce1c74f8a8c500c8e 100644 --- a/framework/tests/unit/src/android/bluetooth/le/ScanFilterTest.java +++ b/framework/tests/unit/src/android/bluetooth/le/ScanFilterTest.java @@ -18,8 +18,7 @@ package android.bluetooth.le; import android.bluetooth.BluetoothDevice; import android.os.Parcel; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import junit.framework.TestCase; public class ScanFilterTest extends TestCase { diff --git a/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java b/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java index 879ac56c7796d5538e8897e1693dfd9aea687f52..f226c94a026116761b64a9658df2d55deeab19da 100644 --- a/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java +++ b/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java @@ -17,17 +17,14 @@ package android.bluetooth.le; import android.os.ParcelUuid; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import com.android.internal.util.HexDump; import com.android.modules.utils.BytesMatcher; - -import junit.framework.TestCase; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; +import junit.framework.TestCase; /** * Unit test cases for {@link ScanRecord}. diff --git a/framework/tests/unit/src/android/bluetooth/le/ScanSettingsTest.java b/framework/tests/unit/src/android/bluetooth/le/ScanSettingsTest.java index 8848c7273c80a81974d782cf8170f3e4e131a5ad..e6c85f66909e14c61851bc9c6dc788cea856bea4 100644 --- a/framework/tests/unit/src/android/bluetooth/le/ScanSettingsTest.java +++ b/framework/tests/unit/src/android/bluetooth/le/ScanSettingsTest.java @@ -16,8 +16,7 @@ package android.bluetooth.le; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import junit.framework.TestCase; /** Test for Bluetooth LE {@link ScanSettings}. */ diff --git a/framework/tests/util/Android.bp b/framework/tests/util/Android.bp index 274746b2e22e2e4df4ad9d673ccde3dc163d2be5..73a83d71172b01a8a7a900f03181167230f5dd7f 100644 --- a/framework/tests/util/Android.bp +++ b/framework/tests/util/Android.bp @@ -22,6 +22,7 @@ java_library { static_libs: [ "PlatformProperties", "androidx.test.ext.truth", + "bluetooth_flags_java_lib", "compatibility-device-util-axt", "junit", ], diff --git a/framework/tests/util/src/android/bluetooth/cts/TestUtils.java b/framework/tests/util/src/android/bluetooth/cts/TestUtils.java index 35a391692a4f358cd2d643d4fa2a83793eed3a54..8f97811a2811b8d6d0e32ad16cafb9ff9cc83994 100644 --- a/framework/tests/util/src/android/bluetooth/cts/TestUtils.java +++ b/framework/tests/util/src/android/bluetooth/cts/TestUtils.java @@ -16,6 +16,9 @@ package android.bluetooth.cts; +import static com.android.bluetooth.flags.Flags.leaudioBroadcastFeatureSupport; +import static com.android.modules.utils.build.SdkLevel.isAtLeastV; + import static com.google.common.truth.Truth.assertThat; import android.bluetooth.BluetoothAdapter; @@ -95,10 +98,14 @@ public class TestUtils extends android.bluetooth.test_utils.TestUtils { return BluetoothProperties.isProfileBapUnicastClientEnabled().orElse(false); } case BluetoothProfile.LE_AUDIO_BROADCAST -> { - return BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false); + return isAtLeastV() + && leaudioBroadcastFeatureSupport() + && BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false); } case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT -> { - return BluetoothProperties.isProfileBapBroadcastAssistEnabled().orElse(false); + return isAtLeastV() + && leaudioBroadcastFeatureSupport() + && BluetoothProperties.isProfileBapBroadcastAssistEnabled().orElse(false); } // Hidden profile // case BluetoothProfile.LE_CALL_CONTROL: diff --git a/pandora/interfaces/pandora_experimental/gatt.proto b/pandora/interfaces/pandora_experimental/gatt.proto index 9e8388fa0b4cf5342339ef2d4499e4197fd156a0..f0e385b741201a6327dec9e4ec3f4d7f2cbddf1f 100644 --- a/pandora/interfaces/pandora_experimental/gatt.proto +++ b/pandora/interfaces/pandora_experimental/gatt.proto @@ -43,6 +43,12 @@ service GATT { // Wait for characteristic notification/indication rpc WaitCharacteristicNotification(WaitCharacteristicNotificationRequest) returns (WaitCharacteristicNotificationResponse); + + // Notify on characteristic + rpc NotifyOnCharacteristic(NotifyOnCharacteristicRequest) returns (NotifyOnCharacteristicResponse); + + // Indicate on characteristic + rpc IndicateOnCharacteristic(IndicateOnCharacteristicRequest) returns (IndicateOnCharacteristicResponse); } enum AttStatusCode { @@ -252,3 +258,21 @@ message RegisterServiceRequest { message RegisterServiceResponse { GattService service = 1; } + +message NotifyOnCharacteristicRequest { + uint32 handle = 1; + bytes value = 2; +} + +message NotifyOnCharacteristicResponse { + AttStatusCode status = 1; +} + +message IndicateOnCharacteristicRequest { + uint32 handle = 1; + bytes value = 2; +} + +message IndicateOnCharacteristicResponse { + AttStatusCode status = 1; +} diff --git a/pandora/server/bumble_experimental/gatt.py b/pandora/server/bumble_experimental/gatt.py index 211d11ca1a3b1ae0b78a4a9e4feb7582f1b3b2ad..90f50884301aaa8258e1589925fa5a0900569f4b 100644 --- a/pandora/server/bumble_experimental/gatt.py +++ b/pandora/server/bumble_experimental/gatt.py @@ -24,6 +24,7 @@ from bumble.gatt_client import CharacteristicProxy, ServiceProxy from bumble.pandora import utils from pandora_experimental.gatt_grpc_aio import GATTServicer from pandora_experimental.gatt_pb2 import ( + ATTRIBUTE_NOT_FOUND, SUCCESS, AttStatusCode, AttValue, @@ -37,6 +38,10 @@ from pandora_experimental.gatt_pb2 import ( GattCharacteristic, GattCharacteristicDescriptor, GattService, + IndicateOnCharacteristicRequest, + IndicateOnCharacteristicResponse, + NotifyOnCharacteristicRequest, + NotifyOnCharacteristicResponse, ReadCharacteristicDescriptorRequest, ReadCharacteristicDescriptorResponse, ReadCharacteristicRequest, @@ -283,3 +288,25 @@ class GATTService(GATTServicer): logging.info(f"RegisterService complete") return RegisterServiceResponse() + + @utils.rpc + async def NotifyOnCharacteristic(self, request: NotifyOnCharacteristicRequest, + context: grpc.ServicerContext) -> NotifyOnCharacteristicResponse: + logging.info(f"NotifyOnCharacteristic") + + attr = self.device.gatt_server.get_attribute(request.handle) + if not attr: + return NotifyOnCharacteristicResponse(status=ATTRIBUTE_NOT_FOUND) + await self.device.notify_subscribers(attr, request.value) + return NotifyOnCharacteristicResponse(status=SUCCESS) + + @utils.rpc + async def IndicateOnCharacteristic(self, request: IndicateOnCharacteristicRequest, + context: grpc.ServicerContext) -> IndicateOnCharacteristicResponse: + logging.info(f"IndicateOnCharacteristic") + + attr = self.device.gatt_server.get_attribute(request.handle) + if not attr: + return IndicateOnCharacteristicResponse(status=ATTRIBUTE_NOT_FOUND) + await self.device.indicate_subscribers(attr, request.value) + return IndicateOnCharacteristicResponse(status=SUCCESS) diff --git a/service/Android.bp b/service/Android.bp index 5a6665388d0dcb15275ba4ba1da01d5a96ee6640..b2c2a06dcc73b753e564ad6cc80a36b5562fffb8 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -22,6 +22,7 @@ filegroup { ":statslog-bluetooth-java-gen", "src/**/*.java", "src/AdapterState.kt", + "src/AutoOnFeature.kt", "src/Log.kt", "src/RadioModeListener.kt", "src/airplane/ModeListener.kt", @@ -34,9 +35,7 @@ filegroup { // pre-jarjar version of service-bluetooth that builds against pre-jarjar version of framework-bluetooth java_defaults { name: "service-bluetooth-pre-jarjar", - srcs: [ - ":services.bluetooth-sources", - ], + srcs: [":services.bluetooth-sources"], errorprone: { javacflags: [ @@ -82,6 +81,7 @@ java_defaults { "bluetooth-nano-protos", "bluetooth-proto-enums-java-gen", "bluetooth_flags_java_lib", + "modules-utils-build_system", "modules-utils-shell-command-handler", ], @@ -95,10 +95,6 @@ java_library { defaults: ["service-bluetooth-pre-jarjar"], installable: true, - libs: [ - "framework-bluetooth.impl", - ], - jarjar_rules: ":bluetooth-jarjar-rules", optimize: { @@ -113,6 +109,9 @@ java_library { "com.android.btservices", ], min_sdk_version: "Tiramisu", + lint: { + baseline_filename: "lint-baseline.xml", + }, } java_library { @@ -146,6 +145,7 @@ java_library { libs: ["libprotobuf-java-nano"], lint: { strict_updatability_linting: true, + }, sdk_version: "system_current", apex_available: [ @@ -162,6 +162,8 @@ android_robolectric_test { ":statslog-bluetooth-java-gen", "src/AdapterState.kt", "src/AdapterStateTest.kt", + "src/AutoOnFeature.kt", + "src/AutoOnFeatureTest.kt", "src/Log.kt", "src/LogTest.kt", "src/RadioModeListener.kt", @@ -174,6 +176,7 @@ android_robolectric_test { static_libs: [ "androidx.test.core", + "kotlin-test", "kotlinx_coroutines", "kotlinx_coroutines_test", "mockito-robolectric-prebuilt", diff --git a/service/aidl/Android.bp b/service/aidl/Android.bp index 28abb8ecac0dcc8d2c9d0389c509c36dced4ab2e..98da8c998e1626acebe246dc74e8f27105bcb06a 100644 --- a/service/aidl/Android.bp +++ b/service/aidl/Android.bp @@ -10,9 +10,7 @@ package { // AIDL interface used in service-bluetooth filegroup { name: "service-bluetooth-binder-aidl", - visibility: [ - "//packages/modules/Bluetooth:__subpackages__", - ], + visibility: ["//packages/modules/Bluetooth:__subpackages__"], srcs: [ "android/bluetooth/IBluetoothManager.aidl", "android/bluetooth/IBluetoothManagerCallback.aidl", diff --git a/service/aidl/android/bluetooth/IBluetoothManager.aidl b/service/aidl/android/bluetooth/IBluetoothManager.aidl index df32f2a2680da23e2ee28dae4c339234e3b61cfc..338a9ca1e01eff535074bbe3a7d1d0e1de1eda56 100644 --- a/service/aidl/android/bluetooth/IBluetoothManager.aidl +++ b/service/aidl/android/bluetooth/IBluetoothManager.aidl @@ -18,8 +18,6 @@ package android.bluetooth; import android.bluetooth.IBluetooth; import android.bluetooth.IBluetoothManagerCallback; -import android.bluetooth.IBluetoothProfileServiceConnection; -import android.bluetooth.IBluetoothStateChangeCallback; import android.content.AttributionSource; /** @@ -33,8 +31,6 @@ interface IBluetoothManager IBluetooth registerAdapter(in IBluetoothManagerCallback callback); @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") void unregisterAdapter(in IBluetoothManagerCallback callback); - void registerStateChangeCallback(in IBluetoothStateChangeCallback callback); - void unregisterStateChangeCallback(in IBluetoothStateChangeCallback callback); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") boolean enable(in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") @@ -44,11 +40,6 @@ interface IBluetoothManager @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") int getState(); - @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") - boolean bindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy); - @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission") - void unbindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy); - @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.LOCAL_MAC_ADDRESS})") String getAddress(in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)") @@ -72,4 +63,12 @@ interface IBluetoothManager int setBtHciSnoopLogMode(int mode); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)") int getBtHciSnoopLogMode(); + + // AutoOnFeature + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)") + boolean isAutoOnSupported(); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)") + boolean isAutoOnEnabled(); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)") + void setAutoOnEnabled(boolean status); } diff --git a/service/aidl/android/bluetooth/IBluetoothManagerCallback.aidl b/service/aidl/android/bluetooth/IBluetoothManagerCallback.aidl index 01b686709e6cf0f43237aae4b1a609c6b3cade3f..057ecd375357a7ca5ad47211c5f0a5d2dd8f780a 100644 --- a/service/aidl/android/bluetooth/IBluetoothManagerCallback.aidl +++ b/service/aidl/android/bluetooth/IBluetoothManagerCallback.aidl @@ -26,4 +26,6 @@ import android.bluetooth.IBluetooth; oneway interface IBluetoothManagerCallback { void onBluetoothServiceUp(in IBluetooth bluetoothService); void onBluetoothServiceDown(); + void onBluetoothOn(); + void onBluetoothOff(); } diff --git a/service/build.gradle.kts b/service/build.gradle.kts new file mode 100644 index 0000000000000000000000000000000000000000..5cae44f79185ce6269c365c9bc5e3488e584d884 --- /dev/null +++ b/service/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. + id("org.jetbrains.kotlin.jvm") version "1.8.20" + + // Apply the java-library plugin for API and implementation separation. + `java-library` +} + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +sourceSets.main { + java { + exclude("**/*.bp") + srcDirs("src", "aidl", "change-ids") + } +} + +dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2") + implementation(files("../../../../external/kotlinc/lib/kotlin-stdlib.jar")) + implementation(files("../../../../out/soong/.intermediates/frameworks/libs/modules-utils/java/com/android/modules/utils/build/modules-utils-build_system/android_common_apex33/turbine-combined/modules-utils-build_system.jar")) + implementation(files("../../../../out/soong/.intermediates/frameworks/libs/modules-utils/java/com/android/modules/utils/modules-utils-shell-command-handler/android_common_apex33/turbine-combined/modules-utils-shell-command-handler.jar")) + implementation(files("../../../../out/soong/.intermediates/frameworks/libs/modules-utils/java/framework-annotations-lib/android_common/turbine-combined/framework-annotations-lib.jar")) + implementation(files("../../../../out/soong/.intermediates/packages/modules/Bluetooth/framework/framework-bluetooth-pre-jarjar/android_common/turbine-combined/framework-bluetooth-pre-jarjar.jar")) + implementation(files("../../../../out/soong/.intermediates/packages/modules/Bluetooth/service/change-ids/service-bluetooth.change-ids/android_common/turbine-combined/service-bluetooth.change-ids.jar")) + implementation(files("../../../../prebuilts/sdk/33/system-server/android.jar")) +} + diff --git a/service/generate_local_coverage.sh b/service/generate_local_coverage.sh index 38dbc88ace1cf0db5d63ef95f142f00edd6ad8d3..83e1138cbd6143743c04d32f5d7ce51f0d001bed 100755 --- a/service/generate_local_coverage.sh +++ b/service/generate_local_coverage.sh @@ -13,7 +13,7 @@ script -q ${COVERAGE_TMP_FOLDER}/atest_log \ --jacocoagent-path gs://tradefed_test_resources/teams/code_coverage/jacocoagent.jar \ --coverage --coverage-toolchain JACOCO' -COVERAGE_COLLECTED=$(rg 'Test Logs have saved in ' ${COVERAGE_TMP_FOLDER}/atest_log | sed -e 's/^.* //' -e 's/log.*$/log/') +COVERAGE_COLLECTED=$(rg 'Test Logs have been saved in ' ${COVERAGE_TMP_FOLDER}/atest_log | sed -e 's/^.* //' -e 's/log.*$/log/') # Link source into the tmp folder ln -s "${ANDROID_BUILD_TOP}"/packages/modules/Bluetooth/service/src ${COVERAGE_TMP_FOLDER}/com/android/server/bluetooth diff --git a/service/kls-classpath b/service/kls-classpath new file mode 100755 index 0000000000000000000000000000000000000000..94c74875ad9b17b9b83878e9e94f65f79d6412a4 --- /dev/null +++ b/service/kls-classpath @@ -0,0 +1,32 @@ +#!/bin/bash + + +ROOT="$PWD/../../../../" +CLASSPATH="" +CLASSPATH+="$ROOT/external/kotlinc/lib/kotlin-stdlib.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/frameworks/base/api/android_system_server_stubs_current/android_common/turbine-combined/android_system_server_stubs_current.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/prebuilts/sdk/current/androidx/m2repository/androidx/appcompat/appcompat/1.7.0-alpha04/androidx.appcompat_appcompat/android_common_apex33/turbine-combined/androidx.appcompat_appcompat.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/framework/framework-bluetooth-pre-jarjar/android_common/turbine-combined/framework-bluetooth-pre-jarjar.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/libcore/core-lambda-stubs/android_common/turbine-combined/core-lambda-stubs.jar" + +CLASSPATH+=":$ROOT/out/soong/.intermediates/frameworks/libs/modules-utils/java/framework-annotations-lib/android_common/turbine-combined/framework-annotations-lib.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/ConfigInfrastructure/framework/framework-configinfrastructure.stubs.module_lib/android_common/turbine-combined/framework-configinfrastructure.stubs.module_lib.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/StatsD/framework/framework-statsd.stubs.module_lib/android_common/turbine-combined/framework-statsd.stubs.module_lib.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/service/change-ids/service-bluetooth.change-ids/android_common/turbine-combined/service-bluetooth.change-ids.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/framework/framework-bluetooth.impl/android_common/turbine-jarjar/framework-bluetooth.impl.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/prebuilts/sdk/current/androidx/m2repository/androidx/annotation/annotation-jvm/1.8.0-alpha01/androidx.annotation_annotation/android_common_apex33/turbine-combined/androidx.annotation_annotation.jar" + +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/service/bluetooth-manager-service-proto-java-gen/android_common_apex33/turbine-combined/bluetooth-manager-service-proto-java-gen.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/service/bluetooth-nano-protos/android_common_apex33/turbine-combined/bluetooth-nano-protos.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/android/app/bluetooth-proto-enums-java-gen/android_common_apex33/turbine-combined/bluetooth-proto-enums-java-gen.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/packages/modules/Bluetooth/flags/bluetooth_flags_java_lib/android_common_apex33/turbine-combined/bluetooth_flags_java_lib.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/frameworks/libs/modules-utils/java/com/android/modules/utils/modules-utils-shell-command-handler/android_common_apex33/turbine-combined/modules-utils-shell-command-handler.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/frameworks/libs/modules-utils/java/com/android/modules/utils/build/modules-utils-build_system/android_common_apex33/turbine-combined/modules-utils-build_system.jar" + +CLASSPATH+=":$ROOT/out/soong/.intermediates/prebuilts/misc/common/androidx-test/androidx.test.core/android_common/combined/androidx.test.core.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/external/truth/truth/android_common/turbine-combined/truth.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/external/junit/junit/android_common/turbine-combined/junit.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/prebuilts/tools/common/m2/mockito-robolectric-prebuilt/android_common/turbine-combined/mockito-robolectric-prebuilt.jar" +CLASSPATH+=":$ROOT/out/soong/.intermediates/external/robolectric/Robolectric_all_upstream/linux_glibc_common/6da2cb1db6f5106f6cbbfb5faa1ac779/javac-header/Robolectric_all_upstream.jar" + +echo "$CLASSPATH" diff --git a/service/lint-baseline.xml b/service/lint-baseline.xml index 1bd04e6790d9b13bc5468d888ec1a90ff0157fdc..d779fbc95a41995a3ab804a8340138b5b55e529b 100644 --- a/service/lint-baseline.xml +++ b/service/lint-baseline.xml @@ -1,5 +1,5 @@ - + - + \ No newline at end of file diff --git a/service/settings.gradle.kts b/service/settings.gradle.kts new file mode 100644 index 0000000000000000000000000000000000000000..74ad68df30f2dd5bcf409a1fc963a845fdfceb6d --- /dev/null +++ b/service/settings.gradle.kts @@ -0,0 +1,8 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.5/userguide/building_swift_projects.html in the Gradle documentation. + */ + +rootProject.name = "service" diff --git a/service/src/AutoOnFeature.kt b/service/src/AutoOnFeature.kt new file mode 100644 index 0000000000000000000000000000000000000000..efc2759f1a622f88036fbee026b0522eafc9b390 --- /dev/null +++ b/service/src/AutoOnFeature.kt @@ -0,0 +1,348 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:JvmName("AutoOnFeature") + +package com.android.server.bluetooth + +import android.bluetooth.BluetoothAdapter.STATE_ON +import android.content.BroadcastReceiver +import android.content.ContentResolver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.database.ContentObserver +import android.os.Handler +import android.os.Looper +import android.provider.Settings +import androidx.annotation.VisibleForTesting +import com.android.modules.expresslog.Counter +import com.android.server.bluetooth.airplane.hasUserToggledApm as hasUserToggledApm +import com.android.server.bluetooth.airplane.isOn as isAirplaneModeOn +import com.android.server.bluetooth.satellite.isOn as isSatelliteModeOn +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.temporal.ChronoUnit +import kotlin.time.Duration +import kotlin.time.DurationUnit +import kotlin.time.toDuration + +private const val TAG = "AutoOnFeature" + +public fun resetAutoOnTimerForUser( + looper: Looper, + context: Context, + state: BluetoothAdapterState, + callback_on: () -> Unit +) { + // Remove any previous timer + timer?.cancel() + timer = null + + if (!isFeatureEnabledForUser(context.contentResolver)) { + Log.d(TAG, "Not Enabled for current user: ${context.getUser()}") + return + } + if (state.oneOf(STATE_ON)) { + Log.d(TAG, "Bluetooth already in ${state}, no need for timer") + return + } + if (isSatelliteModeOn) { + Log.d(TAG, "Satellite prevent feature activation") + return + } + if (isAirplaneModeOn) { + if (!hasUserToggledApm(context)) { + Log.d(TAG, "Airplane prevent feature activation") + return + } + Log.d(TAG, "Airplane bypassed as airplane enhanced mode has been activated previously") + } + + val receiver = + object : BroadcastReceiver() { + override fun onReceive(ctx: Context, intent: Intent) { + Log.i(TAG, "Received ${intent.action} that trigger a new alarm scheduling") + pause() + resetAutoOnTimerForUser(looper, context, state, callback_on) + } + } + + timer = Timer.start(looper, context, receiver, callback_on) +} + +public fun pause() { + timer?.pause() + timer = null +} + +public fun notifyBluetoothOn(resolver: ContentResolver) { + timer?.cancel() + timer = null + + if (!isFeatureSupportedForUser(resolver)) { + val defaultFeatureValue = true + Log.i(TAG, "Feature was set to its default value ${defaultFeatureValue}") + setFeatureEnabledForUserUnchecked(resolver, defaultFeatureValue) + } +} + +public fun isUserSupported(resolver: ContentResolver) = isFeatureSupportedForUser(resolver) + +public fun isUserEnabled(context: Context): Boolean { + if (!isUserSupported(context.contentResolver)) { + throw IllegalStateException("AutoOnFeature not supported for user: ${context.getUser()}") + } + return isFeatureEnabledForUser(context.contentResolver) +} + +public fun setUserEnabled( + looper: Looper, + context: Context, + state: BluetoothAdapterState, + status: Boolean, + callback_on: () -> Unit, +) { + if (!isUserSupported(context.contentResolver)) { + throw IllegalStateException("AutoOnFeature not supported for user: ${context.getUser()}") + } + setFeatureEnabledForUserUnchecked(context.contentResolver, status) + Counter.logIncrement( + if (status) "bluetooth.value_auto_on_enabled" else "bluetooth.value_auto_on_disabled" + ) + resetAutoOnTimerForUser(looper, context, state, callback_on) +} + +// Listener is needed because code should be actionable prior to V API release +public fun registerHiddenApiListener( + looper: Looper, + context: Context, + state: BluetoothAdapterState, + callback_on: () -> Unit +) { + HiddenApiListener.registerUser(looper, context, state, callback_on) +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////// PRIVATE METHODS ///////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +@VisibleForTesting internal var timer: Timer? = null + +@VisibleForTesting +internal class Timer +private constructor( + looper: Looper, + private val context: Context, + private val receiver: BroadcastReceiver, + callback_on: () -> Unit, + private val now: LocalDateTime, + private val target: LocalDateTime, + private val timeToSleep: Duration +) { + private val handler = Handler(looper) + + init { + writeDateToStorage(target, context.contentResolver) + handler.postDelayed( + { + Log.i(TAG, "[${this}]: Bluetooth restarting now") + callback_on() + cancel() + // Set global instance to null to prevent further action. Job is done here + timer = null + }, + timeToSleep.inWholeMilliseconds + ) + Log.i(TAG, "[${this}]: Scheduling next Bluetooth restart") + + context.registerReceiver( + receiver, + IntentFilter().apply { + addAction(Intent.ACTION_DATE_CHANGED) + addAction(Intent.ACTION_TIMEZONE_CHANGED) + addAction(Intent.ACTION_TIME_CHANGED) + }, + null, + handler + ) + } + + companion object { + @VisibleForTesting internal val STORAGE_KEY = "bluetooth_internal_automatic_turn_on_timer" + + private fun writeDateToStorage(date: LocalDateTime, resolver: ContentResolver): Boolean { + return Settings.Secure.putString(resolver, STORAGE_KEY, date.toString()) + } + + private fun getDateFromStorage(resolver: ContentResolver): LocalDateTime? { + val date = Settings.Secure.getString(resolver, STORAGE_KEY) + return date?.let { LocalDateTime.parse(it) } + } + + private fun resetStorage(resolver: ContentResolver) { + Settings.Secure.putString(resolver, STORAGE_KEY, null) + } + + fun start( + looper: Looper, + context: Context, + receiver: BroadcastReceiver, + callback_on: () -> Unit + ): Timer? { + val now = LocalDateTime.now() + val target = getDateFromStorage(context.contentResolver) ?: nextTimeout(now) + val timeToSleep = + now.until(target, ChronoUnit.NANOS).toDuration(DurationUnit.NANOSECONDS) + + if (timeToSleep.isNegative()) { + Log.i(TAG, "Starting now (${now}) as it was scheduled for ${target}") + callback_on() + resetStorage(context.contentResolver) + return null + } + + return Timer(looper, context, receiver, callback_on, now, target, timeToSleep) + } + + /** Return a LocalDateTime for tomorrow 5 am */ + private fun nextTimeout(now: LocalDateTime) = + LocalDateTime.of(now.toLocalDate(), LocalTime.of(5, 0)).plusDays(1) + } + + /** Save timer to storage and stop it */ + internal fun pause() { + Log.i(TAG, "[${this}]: Pausing timer") + context.unregisterReceiver(receiver) + handler.removeCallbacksAndMessages(null) + } + + /** Stop timer and reset storage */ + @VisibleForTesting + internal fun cancel() { + Log.i(TAG, "[${this}]: Cancelling timer") + context.unregisterReceiver(receiver) + handler.removeCallbacksAndMessages(null) + resetStorage(context.contentResolver) + } + + override fun toString() = "Timer scheduled ${now} for target=${target} (=${timeToSleep} delay)." +} + +@VisibleForTesting internal val USER_SETTINGS_KEY = "bluetooth_automatic_turn_on" + +/** + * *Do not use outside of this file to avoid async issues* + * + * @return whether the auto on feature is enabled for this user + */ +private fun isFeatureEnabledForUser(resolver: ContentResolver): Boolean { + return Settings.Secure.getInt(resolver, USER_SETTINGS_KEY, 0) == 1 +} + +/** + * *Do not use outside of this file to avoid async issues* + * + * @return whether the auto on feature is supported for the user + */ +private fun isFeatureSupportedForUser(resolver: ContentResolver): Boolean { + return Settings.Secure.getInt(resolver, USER_SETTINGS_KEY, -1) != -1 +} + +/** + * *Do not use outside of this file to avoid async issues* + * + * @return whether the auto on feature is enabled for this user + */ +private fun setFeatureEnabledForUserUnchecked(resolver: ContentResolver, status: Boolean) { + Settings.Secure.putInt(resolver, USER_SETTINGS_KEY, if (status) 1 else 0) +} + +// Listener is needed because code should be actionable prior to V API release +@VisibleForTesting +internal class HiddenApiListener +private constructor( + looper: Looper, + private val context: Context, + state: BluetoothAdapterState, + callback_on: () -> Unit +) { + companion object { + @VisibleForTesting internal var listener: HiddenApiListener? = null + + fun registerUser( + looper: Looper, + context: Context, + state: BluetoothAdapterState, + callback_on: () -> Unit + ) { + // Remove observer on previous user + listener?.remove() + listener = HiddenApiListener(looper, context, state, callback_on) + } + } + + private val handler = Handler(looper) + + private val observer = + object : ContentObserver(handler) { + override fun onChange(selfChange: Boolean) { + var previousState = featureState + var newState = + Settings.Secure.getInt(context.contentResolver, USER_SETTINGS_KEY, -1) + featureState = newState + + if (previousState == newState) { + Log.d(TAG, "HiddenApi: State is unchanged: ${newState}") + return + } + + if (previousState == -1) { + Log.d(TAG, "HiddenApi: Feature default state got setup to ${newState}") + return + } + + Log.d(TAG, "HiddenApi: Feature state change from ${previousState} to ${newState}") + + Counter.logIncrement("bluetooth.value_auto_on_hidden_usage") + Counter.logIncrement( + if (newState == 1) "bluetooth.value_auto_on_enabled" + else "bluetooth.value_auto_on_disabled" + ) + + resetAutoOnTimerForUser(looper, context, state, callback_on) + } + } + + private var featureState = + Settings.Secure.getInt(context.contentResolver, USER_SETTINGS_KEY, -1) + + init { + val notifyForDescendants = false + + context.contentResolver.registerContentObserver( + Settings.Secure.getUriFor(USER_SETTINGS_KEY), + notifyForDescendants, + observer + ) + } + + @VisibleForTesting + internal fun remove() { + context.contentResolver.unregisterContentObserver(observer) + handler.removeCallbacksAndMessages(null) + } +} diff --git a/service/src/AutoOnFeatureTest.kt b/service/src/AutoOnFeatureTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..b18314ec52c5a0910029cb2533c0f841a6139b7a --- /dev/null +++ b/service/src/AutoOnFeatureTest.kt @@ -0,0 +1,511 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.bluetooth.test + +import android.bluetooth.BluetoothAdapter +import android.content.Context +import android.content.Intent +import android.os.Looper +import android.provider.Settings +import androidx.test.core.app.ApplicationProvider +import com.android.server.bluetooth.BluetoothAdapterState +import com.android.server.bluetooth.HiddenApiListener +import com.android.server.bluetooth.Log +import com.android.server.bluetooth.Timer +import com.android.server.bluetooth.USER_SETTINGS_KEY +import com.android.server.bluetooth.airplane.isOn as isAirplaneModeOn +import com.android.server.bluetooth.airplane.test.ModeListenerTest as AirplaneListener +import com.android.server.bluetooth.isUserEnabled +import com.android.server.bluetooth.isUserSupported +import com.android.server.bluetooth.notifyBluetoothOn +import com.android.server.bluetooth.pause +import com.android.server.bluetooth.registerHiddenApiListener +import com.android.server.bluetooth.resetAutoOnTimerForUser +import com.android.server.bluetooth.satellite.isOn as isSatelliteModeOn +import com.android.server.bluetooth.satellite.test.ModeListenerTest as SatelliteListener +import com.android.server.bluetooth.setUserEnabled +import com.android.server.bluetooth.timer +import com.google.common.truth.Expect +import com.google.common.truth.Truth.assertThat +import java.time.LocalDateTime +import java.time.LocalTime +import kotlin.test.assertFailsWith +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestName +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.Shadows.shadowOf + +@RunWith(RobolectricTestRunner::class) +@kotlinx.coroutines.ExperimentalCoroutinesApi +class AutoOnFeatureTest { + private val SETTING_URI = Settings.Secure.getUriFor(USER_SETTINGS_KEY) + + private val looper = Looper.getMainLooper() + private val state = BluetoothAdapterState() + private val context = ApplicationProvider.getApplicationContext() + private val resolver = context.contentResolver + private val now = LocalDateTime.now() + private val timerTarget = LocalDateTime.of(now.toLocalDate(), LocalTime.of(5, 0)).plusDays(1) + + private var callback_count = 0 + + @JvmField @Rule val testName = TestName() + @JvmField @Rule val expect = Expect.create() + + @Before + fun setUp() { + Log.i("AutoOnFeatureTest", "\t--> setUp(${testName.getMethodName()})") + + enableUserSettings() + } + + @After + fun tearDown() { + HiddenApiListener.listener?.let { it.remove() } + HiddenApiListener.listener = null + + callback_count = 0 + timer?.cancel() + timer = null + restoreSavedTimer() + } + + private fun setupTimer() { + resetAutoOnTimerForUser(looper, context, state, this::callback_on) + } + + private fun setUserEnabled(status: Boolean) { + setUserEnabled(looper, context, state, status, this::callback_on) + } + + private fun enableUserSettings() { + Settings.Secure.putInt(resolver, USER_SETTINGS_KEY, 1) + shadowOf(looper).idle() + } + + private fun disableUserSettings() { + Settings.Secure.putInt(resolver, USER_SETTINGS_KEY, 0) + shadowOf(looper).idle() + } + + private fun restoreSettings() { + Settings.Secure.putString(resolver, USER_SETTINGS_KEY, null) + shadowOf(looper).idle() + } + + private fun restoreSavedTimer() { + Settings.Secure.putString(resolver, Timer.STORAGE_KEY, null) + shadowOf(looper).idle() + } + + private fun expectStorageTime() { + shadowOf(looper).idle() + expect + .that(Settings.Secure.getString(resolver, Timer.STORAGE_KEY)) + .isEqualTo(timerTarget.toString()) + } + + private fun expectNoStorageTime() { + shadowOf(looper).idle() + expect.that(Settings.Secure.getString(resolver, Timer.STORAGE_KEY)).isNull() + } + + private fun callback_on() { + callback_count++ + } + + @Test + fun setupTimer_whenItWasNeverUsed_isNotScheduled() { + restoreSettings() + + setupTimer() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + } + + @Test + fun setupTimer_whenBtOn_isNotScheduled() { + state.set(BluetoothAdapter.STATE_ON) + + setupTimer() + + state.set(BluetoothAdapter.STATE_OFF) + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + } + + @Test + fun setupTimer_whenBtOffAndUserEnabled_isScheduled() { + setupTimer() + + expect.that(timer).isNotNull() + } + + @Test + fun setupTimer_whenBtOffAndUserEnabled_triggerCallback() { + setupTimer() + + shadowOf(looper).runToEndOfTasks() + expect.that(callback_count).isEqualTo(1) + expect.that(timer).isNull() + } + + @Test + fun setupTimer_whenAlreadySetup_triggerCallbackOnce() { + setupTimer() + setupTimer() + setupTimer() + + shadowOf(looper).runToEndOfTasks() + expect.that(callback_count).isEqualTo(1) + expect.that(timer).isNull() + } + + @Test + fun notifyBluetoothOn_whenNoTimer_noCrash() { + notifyBluetoothOn(resolver) + + assertThat(timer).isNull() + } + + @Test + fun notifyBluetoothOn_whenTimer_isNotScheduled() { + setupTimer() + notifyBluetoothOn(resolver) + + shadowOf(looper).runToEndOfTasks() + expect.that(callback_count).isEqualTo(0) + expect.that(timer).isNull() + } + + @Test + fun notifyBluetoothOn_whenItWasNeverUsed_enableSettings() { + restoreSettings() + + notifyBluetoothOn(resolver) + + assertThat(isUserSupported(resolver)).isTrue() + } + + @Test + fun apiIsUserEnable_whenItWasNeverUsed_throwException() { + restoreSettings() + + assertFailsWith { isUserEnabled(context) } + } + + @Test + fun apiSetUserEnabled_whenItWasNeverUsed_throwException() { + restoreSettings() + + assertFailsWith { setUserEnabled(true) } + } + + @Test + fun apiIsUserEnable_whenEnabled_isTrue() { + assertThat(isUserEnabled(context)).isTrue() + } + + @Test + fun apiIsUserEnable_whenDisabled_isFalse() { + disableUserSettings() + assertThat(isUserEnabled(context)).isFalse() + } + + @Test + fun apiSetUserEnableToFalse_whenScheduled_isNotScheduled() { + setupTimer() + + setUserEnabled(false) + + assertThat(isUserEnabled(context)).isFalse() + assertThat(callback_count).isEqualTo(0) + assertThat(timer).isNull() + } + + @Test + fun apiSetUserEnableToFalse_whenIdle_isNotScheduled() { + setUserEnabled(false) + + assertThat(isUserEnabled(context)).isFalse() + assertThat(callback_count).isEqualTo(0) + assertThat(timer).isNull() + } + + @Test + fun apiSetUserEnableToTrue_whenIdle_canSchedule() { + disableUserSettings() + + setUserEnabled(true) + setupTimer() + + assertThat(timer).isNotNull() + } + + @Test + fun pause_whenIdle_noTimeSave() { + pause() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } + + @Test + fun pause_whenTimer_timeIsSaved() { + setupTimer() + + pause() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectStorageTime() + } + + @Test + fun setupTimer_whenIdle_timeIsSave() { + setupTimer() + + expect.that(timer).isNotNull() + expect.that(callback_count).isEqualTo(0) + expectStorageTime() + } + + @Test + fun setupTimer_whenPaused_isResumed() { + val now = LocalDateTime.now() + val alarmTime = LocalDateTime.of(now.toLocalDate(), LocalTime.of(5, 0)).plusDays(1) + Settings.Secure.putString(resolver, Timer.STORAGE_KEY, alarmTime.toString()) + shadowOf(looper).idle() + + setupTimer() + + expect.that(timer).isNotNull() + expect.that(callback_count).isEqualTo(0) + expectStorageTime() + } + + @Test + fun setupTimer_whenSaveTimerIsExpired_triggerCallback() { + val pastTime = timerTarget.minusDays(3) + Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) + shadowOf(looper).idle() + + setupTimer() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(1) + expectNoStorageTime() + } + + @Test + fun setupTimer_whenSatelliteIsOn_isNotScheduled() { + val satelliteCallback: (m: Boolean) -> Unit = { _: Boolean -> } + + SatelliteListener.setupSatelliteModeToOn(resolver, looper, satelliteCallback) + assertThat(isSatelliteModeOn).isTrue() + + setupTimer() + + SatelliteListener.setupSatelliteModeToOff(resolver, looper) + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } + + @Test + fun updateTimezone_whenTimerSchedule_isReScheduled() { + setupTimer() + + // Fake storaged time so when receiving the intent, the test think we jump in the futur + val pastTime = timerTarget.minusDays(3) + Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) + + context.sendBroadcast(Intent(Intent.ACTION_TIMEZONE_CHANGED)) + shadowOf(looper).idle() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(1) + expectNoStorageTime() + } + + @Test + fun updateTime_whenTimerSchedule_isReScheduled() { + setupTimer() + + // Fake stored time so when receiving the intent, the test think we jumped in the future + val pastTime = timerTarget.minusDays(3) + Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) + + context.sendBroadcast(Intent(Intent.ACTION_TIME_CHANGED)) + shadowOf(looper).idle() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(1) + expectNoStorageTime() + } + + @Test + fun updateDate_whenTimerSchedule_isReScheduled() { + setupTimer() + + // Fake stored time so when receiving the intent, the test think we jumped in the future + val pastTime = timerTarget.minusDays(3) + Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) + + context.sendBroadcast(Intent(Intent.ACTION_DATE_CHANGED)) + shadowOf(looper).idle() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(1) + expectNoStorageTime() + } + + @Test + @kotlin.time.ExperimentalTime + fun setupTimer_whenLegacyAirplaneIsOn_isNotSchedule() { + val userCallback: () -> Context = { -> context } + AirplaneListener.setupAirplaneModeToOn(resolver, looper, userCallback, false) + assertThat(isAirplaneModeOn).isTrue() + + setupTimer() + + AirplaneListener.setupAirplaneModeToOff(resolver, looper) + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } + + @Test + @kotlin.time.ExperimentalTime + fun setupTimer_whenApmAirplaneIsOn_isSchedule() { + val userCallback: () -> Context = { -> context } + AirplaneListener.setupAirplaneModeToOn(resolver, looper, userCallback, true) + assertThat(isAirplaneModeOn).isTrue() + + setupTimer() + + AirplaneListener.setupAirplaneModeToOff(resolver, looper) + expect.that(timer).isNotNull() + expect.that(callback_count).isEqualTo(0) + expectStorageTime() + } + + @Test + fun registerHiddenListener_whenNothing_isRegistered() { + registerHiddenApiListener(looper, context, state, this::callback_on) + + assertThat(HiddenApiListener.listener).isNotNull() + } + + @Test + fun unregisterHiddenListener_whenRegistered_isNotRegistered() { + registerHiddenApiListener(looper, context, state, this::callback_on) + + HiddenApiListener.listener?.let { it.remove() } + + assertThat(shadowOf(resolver).getContentObservers(SETTING_URI).size).isEqualTo(0) + } + + @Test + fun registerHiddenListener_whenAlreadyRegistered_isRegisteredOnce() { + registerHiddenApiListener(looper, context, state, this::callback_on) + + registerHiddenApiListener(looper, context, state, this::callback_on) + + expect.that(shadowOf(resolver).getContentObservers(SETTING_URI).size).isEqualTo(1) + expect.that(HiddenApiListener.listener).isNotNull() + } + + @Test + fun changeSettingsToDisabled_whenHiddenApiIsRegisteredandNotScheduled_isNotSchedule() { + registerHiddenApiListener(looper, context, state, this::callback_on) + + disableUserSettings() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } + + @Test + fun changeSettingsToDisabled_whenHiddenApiIsRegisteredandScheduled_isNotSchedule() { + setupTimer() + registerHiddenApiListener(looper, context, state, this::callback_on) + + disableUserSettings() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } + + @Test + fun changeSettingsToEnabled_whenHiddenApiIsRegisteredandNotScheduled_isSchedule() { + disableUserSettings() + registerHiddenApiListener(looper, context, state, this::callback_on) + + enableUserSettings() + + expect.that(timer).isNotNull() + expect.that(callback_count).isEqualTo(0) + expectStorageTime() + } + + @Test + fun setSettingsToSameValue_whenHiddenApiIsRegisteredandNotScheduled_isNotSchedule() { + restoreSettings() + registerHiddenApiListener(looper, context, state, this::callback_on) + + Settings.Secure.putInt(resolver, USER_SETTINGS_KEY, -1) + shadowOf(looper).idle() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } + + @Test + fun setSettingsToEnabled_whenHiddenApiIsRegisteredandNotSupported_isNotSchedule() { + restoreSettings() + registerHiddenApiListener(looper, context, state, this::callback_on) + + enableUserSettings() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } + + @Test + fun setSettingsToDisable_whenHiddenApiIsRegisteredandNotSupported_isNotSchedule() { + // Current design will set the feature to enabled, but there is no reason to not support + // having a default value to disabled + restoreSettings() + registerHiddenApiListener(looper, context, state, this::callback_on) + + disableUserSettings() + + expect.that(timer).isNull() + expect.that(callback_count).isEqualTo(0) + expectNoStorageTime() + } +} diff --git a/service/src/Log.kt b/service/src/Log.kt index 72a423662d6d1cd7bc0580b80b8c520a9b1d22db..09e90aff35ecda11df4e9cf21be935f3654edc1e 100644 --- a/service/src/Log.kt +++ b/service/src/Log.kt @@ -21,16 +21,31 @@ private const val SYSTEM_SERVER_TAG = "BluetoothSystemServer" public class Log private constructor() { companion object { + + // Kotlin could shorten below method by having a Throwable? that is default to null but the + // current implementation of util.Log is behaving differently depending if it is called with + // 2 or 3 parameters. We do not want to change the behavior in this class, just add a common + // TAG to all the Bluetooth System Server logs. + @JvmStatic fun v(subtag: String, msg: String) = Log.v(SYSTEM_SERVER_TAG, "${subtag}: ${msg}") + @JvmStatic fun d(subtag: String, msg: String) = Log.d(SYSTEM_SERVER_TAG, "${subtag}: ${msg}") + @JvmStatic fun i(subtag: String, msg: String) = Log.i(SYSTEM_SERVER_TAG, "${subtag}: ${msg}") + @JvmStatic fun w(subtag: String, msg: String) = Log.w(SYSTEM_SERVER_TAG, "${subtag}: ${msg}") + + @JvmStatic + fun w(subtag: String, msg: String, tr: Throwable) = + Log.w(SYSTEM_SERVER_TAG, "${subtag}: ${msg}", tr) + @JvmStatic fun e(subtag: String, msg: String) = Log.e(SYSTEM_SERVER_TAG, "${subtag}: ${msg}") + @JvmStatic fun e(subtag: String, msg: String, tr: Throwable) = Log.e(SYSTEM_SERVER_TAG, "${subtag}: ${msg}", tr) diff --git a/service/src/LogTest.kt b/service/src/LogTest.kt index 86ced2230efcba1b586e3459a1db36fc03d25cbb..19d25ad6464406cd66d696b1e5a6b8c836970a64 100644 --- a/service/src/LogTest.kt +++ b/service/src/LogTest.kt @@ -44,6 +44,11 @@ class LogTest { Log.w(TAG, "Logging warning") } + @Test + fun log_warningThrowable() { + Log.w(TAG, "Logging warning", RuntimeException("With a Throwable")) + } + @Test fun log_error() { Log.e(TAG, "Logging error") diff --git a/service/src/RadioModeListener.kt b/service/src/RadioModeListener.kt index 472fa0480e847946427beba09e80a446e448e121..9f21d25d7fb3bbc21bbdacdd28efb6485789e154 100644 --- a/service/src/RadioModeListener.kt +++ b/service/src/RadioModeListener.kt @@ -63,7 +63,7 @@ internal fun initializeRadioModeListener( /** * Check if Bluetooth is impacted by the radio and fetch global mode status * - * @return weither Bluetooth should consider this radio or not + * @return whether Bluetooth should consider this radio or not */ private fun getRadioModeValue(resolver: ContentResolver, radio: String, modeKey: String): Boolean { return if (isSensitive(resolver, radio)) { diff --git a/service/src/RadioModeListenerTest.kt b/service/src/RadioModeListenerTest.kt index a393bc2770f8af66a3aaadfcc5c83eb56a053beb..4bd761593a33383edc8e3ad165b516cb62e0269f 100644 --- a/service/src/RadioModeListenerTest.kt +++ b/service/src/RadioModeListenerTest.kt @@ -180,7 +180,7 @@ class RadioModeListenerTest { } @Test - fun disable_whenDisabled_isDicarded() { + fun disable_whenDisabled_isDiscarded() { enableSensitive() disableMode() diff --git a/service/src/airplane/ModeListener.kt b/service/src/airplane/ModeListener.kt index c53b27e54673134687957ff1eb378d7d2a4de989..2d92e6c1c68f83ad6a7538d31923be11a0d4bf81 100644 --- a/service/src/airplane/ModeListener.kt +++ b/service/src/airplane/ModeListener.kt @@ -161,7 +161,7 @@ private fun airplaneModeValueOverride( return currentAirplaneMode } // If "Airplane Enhancement Mode" is on and the user already used the feature … - if (isApmEnhancementEnabled(resolver) && hasUserToggledApm(getUser)) { + if (isApmEnhancementEnabled(resolver) && hasUserToggledApm(getUser())) { // … Staying on only depend on its last action in airplane mode if (isBluetoothOnAPM(getUser)) { Log.i(TAG, "Bluetooth stay on during airplane mode because of last user action") @@ -179,9 +179,9 @@ private fun airplaneModeValueOverride( // Note: Once the "Airplane Enhancement Mode" has been used, media override no longer apply // This has been done on purpose to avoid complexe scenario like: // 1. User wants Bt off according to "Airplane Enhancement Mode" - // 2. User swithes airplane while there is media => so Bt stays on + // 2. User switches airplane while there is media => so Bt stays on // 3. User turns airplane off, stops media and toggles airplane back on - // Should we turn Bt off like asked initialy ? Or keep it `on` like the toggle ? + // Should we turn Bt off like asked initially ? Or keep it `on` like the toggle ? if (isMediaConnected) { Log.i(TAG, "Bluetooth stay on during airplane mode because media profile are connected") ToastNotification.displayIfNeeded(resolver, getUser) @@ -299,7 +299,7 @@ private class AirplaneMetricSession( isBluetoothOnBeforeApmToggle, isBluetoothOnAfterApmToggle, isBluetoothOn, - hasUserToggledApm(getUser), + hasUserToggledApm(getUser()), userToggledBluetoothDuringApm, userToggledBluetoothDuringApmWithinMinute, isMediaProfileConnectedBeforeApmToggle, @@ -344,8 +344,8 @@ private fun isWifiOnApm(resolver: ContentResolver, getUser: () -> Context) = Settings.Secure.getInt(getUser().contentResolver, WIFI_APM_STATE, 0) == 1 /** Airplane Enhancement Mode: Return true if this user already toggled (aka used) the feature */ -private fun hasUserToggledApm(getUser: () -> Context) = - Settings.Secure.getInt(getUser().contentResolver, APM_USER_TOGGLED_BLUETOOTH, 0) == 1 +fun hasUserToggledApm(userContext: Context) = + Settings.Secure.getInt(userContext.contentResolver, APM_USER_TOGGLED_BLUETOOTH, 0) == 1 /** Airplane Enhancement Mode: Return true if the bluetooth should stays on during airplane mode */ private fun isBluetoothOnAPM(getUser: () -> Context) = diff --git a/service/src/airplane/ModeListenerTest.kt b/service/src/airplane/ModeListenerTest.kt index 2180cc430ad3114be477a77ff20e1f121d45ee93..aeb1cb6ad767af0dbcdd4dd292a60aa1471ab16d 100644 --- a/service/src/airplane/ModeListenerTest.kt +++ b/service/src/airplane/ModeListenerTest.kt @@ -56,6 +56,40 @@ import org.robolectric.shadows.ShadowToast @RunWith(RobolectricTestRunner::class) @kotlin.time.ExperimentalTime class ModeListenerTest { + companion object { + internal fun setupAirplaneModeToOn( + resolver: ContentResolver, + looper: Looper, + user: () -> Context, + enableEnhancedMode: Boolean + ) { + enableSensitive(resolver, looper, Settings.Global.AIRPLANE_MODE_RADIOS) + enableMode(resolver, looper, Settings.Global.AIRPLANE_MODE_ON) + val mode: (m: Boolean) -> Unit = { _: Boolean -> } + val notif: (m: String) -> Unit = { _: String -> } + val media: () -> Boolean = { -> false } + if (enableEnhancedMode) { + Settings.Secure.putInt(resolver, APM_USER_TOGGLED_BLUETOOTH, 1) + } + + initialize( + looper, + resolver, + BluetoothAdapterState(), + mode, + notif, + media, + user, + TimeSource.Monotonic, + ) + } + + internal fun setupAirplaneModeToOff(resolver: ContentResolver, looper: Looper) { + disableSensitive(resolver, looper, Settings.Global.AIRPLANE_MODE_RADIOS) + disableMode(resolver, looper, Settings.Global.AIRPLANE_MODE_ON) + } + } + private val looper: Looper = Looper.getMainLooper() private val state = BluetoothAdapterState() private val mContext = ApplicationProvider.getApplicationContext() diff --git a/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java b/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java index 45aa7365e1eef2cac58f843466f0a92ad2aeb72e..64eefcb311618d7b623e99b51c58a7f99b37f214 100644 --- a/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java +++ b/service/src/com/android/server/bluetooth/BluetoothAirplaneModeListener.java @@ -227,9 +227,9 @@ class BluetoothAirplaneModeListener extends Handler { } else { if (mFeatureFlags.airplaneRessourcesInApp()) { if (isWifiEnabledOnApm()) { - mBluetoothManager.sendAirplaneModeNotification(APM_WIFI_BT_NOTIFICATION); + mBluetoothManager.sendToggleNotification(APM_WIFI_BT_NOTIFICATION); } else { - mBluetoothManager.sendAirplaneModeNotification(APM_BT_NOTIFICATION); + mBluetoothManager.sendToggleNotification(APM_BT_NOTIFICATION); } return; } @@ -330,7 +330,7 @@ class BluetoothAirplaneModeListener extends Handler { setSettingsSecureInt(APM_USER_TOGGLED_BLUETOOTH, USED); if (mFeatureFlags.airplaneRessourcesInApp()) { if (isOn) { - mBluetoothManager.sendAirplaneModeNotification(APM_BT_ENABLED_NOTIFICATION); + mBluetoothManager.sendToggleNotification(APM_BT_ENABLED_NOTIFICATION); } return; } diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index 2658568c376c8471e792945a45a52ad6cb624ba5..13172e86d8d48933853d0e2ff1563df796bcfb4c 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -25,6 +25,7 @@ import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF; import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; +import static com.android.modules.utils.build.SdkLevel.isAtLeastV; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_ENHANCEMENT; import static java.util.Objects.requireNonNull; @@ -34,15 +35,12 @@ import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.BroadcastOptions; import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.IBluetooth; import android.bluetooth.IBluetoothCallback; import android.bluetooth.IBluetoothManager; import android.bluetooth.IBluetoothManagerCallback; -import android.bluetooth.IBluetoothProfileServiceConnection; -import android.bluetooth.IBluetoothStateChangeCallback; import android.content.AttributionSource; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -77,8 +75,10 @@ import android.util.proto.ProtoOutputStream; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.flags.FeatureFlags; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.modules.expresslog.Counter; import com.android.server.BluetoothManagerServiceDumpProto; import com.android.server.bluetooth.airplane.AirplaneModeListener; import com.android.server.bluetooth.satellite.SatelliteModeListener; @@ -89,17 +89,18 @@ import kotlin.time.TimeSource; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.time.Duration; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.NoSuchElementException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -116,11 +117,11 @@ class BluetoothManagerService { private static final int DEFAULT_REBIND_COUNT = 3; // Maximum msec to wait for a bind private static final int TIMEOUT_BIND_MS = - 3000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + 3000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Timeout value for synchronous binder call private static final Duration SYNC_CALLS_TIMEOUT = - Duration.ofSeconds(3 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1)); + Duration.ofSeconds(3 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1)); /** * @return timeout value for synchronous binder call @@ -130,27 +131,25 @@ class BluetoothManagerService { } // Maximum msec to wait for service restart - private static final int SERVICE_RESTART_TIME_MS - = 400 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + private static final int SERVICE_RESTART_TIME_MS = + 400 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Maximum msec to wait for restart due to error - private static final int ERROR_RESTART_TIME_MS - = 3000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + private static final int ERROR_RESTART_TIME_MS = + 3000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Maximum msec to delay MESSAGE_USER_SWITCHED - private static final int USER_SWITCHED_TIME_MS - = 200 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + private static final int USER_SWITCHED_TIME_MS = + 200 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Delay for the addProxy function in msec - private static final int ADD_PROXY_DELAY_MS - = 100 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + private static final int ADD_PROXY_DELAY_MS = + 100 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Delay for retrying enable and disable in msec - private static final int ENABLE_DISABLE_DELAY_MS - = 300 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + private static final int ENABLE_DISABLE_DELAY_MS = + 300 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); @VisibleForTesting static final int MESSAGE_ENABLE = 1; @VisibleForTesting static final int MESSAGE_DISABLE = 2; @VisibleForTesting static final int MESSAGE_HANDLE_ENABLE_DELAYED = 3; @VisibleForTesting static final int MESSAGE_HANDLE_DISABLE_DELAYED = 4; - @VisibleForTesting static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30; - @VisibleForTesting static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31; @VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40; @VisibleForTesting static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41; @VisibleForTesting static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42; @@ -159,8 +158,6 @@ class BluetoothManagerService { @VisibleForTesting static final int MESSAGE_GET_NAME_AND_ADDRESS = 200; @VisibleForTesting static final int MESSAGE_USER_SWITCHED = 300; @VisibleForTesting static final int MESSAGE_USER_UNLOCKED = 301; - @VisibleForTesting static final int MESSAGE_ADD_PROXY_DELAYED = 400; - @VisibleForTesting static final int MESSAGE_BIND_PROFILE_SERVICE = 401; @VisibleForTesting static final int MESSAGE_RESTORE_USER_SETTING = 500; private static final int RESTORE_SETTING_TO_ON = 1; @@ -187,46 +184,6 @@ class BluetoothManagerService { // Set this value to 0 to disable the feature private static final int DEFAULT_APM_ENHANCEMENT_STATE = 1; - private static final Map PROFILE_TO_SERVICE_NAME = - Map.ofEntries( - Map.entry(BluetoothProfile.HEADSET, "android.bluetooth.IBluetoothHeadset"), - Map.entry(BluetoothProfile.A2DP, "android.bluetooth.IBluetoothA2dp"), - Map.entry(BluetoothProfile.HID_HOST, "android.bluetooth.IBluetoothHidHost"), - Map.entry(BluetoothProfile.PAN, "android.bluetooth.IBluetoothPan"), - Map.entry(BluetoothProfile.PBAP, "android.bluetooth.IBluetoothPbap"), - Map.entry(BluetoothProfile.MAP, "android.bluetooth.IBluetoothMap"), - Map.entry(BluetoothProfile.SAP, "android.bluetooth.IBluetoothSap"), - Map.entry(BluetoothProfile.A2DP_SINK, "android.bluetooth.IBluetoothA2dpSink"), - Map.entry( - BluetoothProfile.AVRCP_CONTROLLER, - "android.bluetooth.IBluetoothAvrcpController"), - Map.entry( - BluetoothProfile.HEADSET_CLIENT, - "android.bluetooth.IBluetoothHeadsetClient"), - Map.entry( - BluetoothProfile.PBAP_CLIENT, "android.bluetooth.IBluetoothPbapClient"), - Map.entry(BluetoothProfile.MAP_CLIENT, "android.bluetooth.IBluetoothMapClient"), - Map.entry(BluetoothProfile.HID_DEVICE, "android.bluetooth.IBluetoothHidDevice"), - Map.entry( - BluetoothProfile.HEARING_AID, "android.bluetooth.IBluetoothHearingAid"), - Map.entry(BluetoothProfile.LE_AUDIO, "android.bluetooth.IBluetoothLeAudio"), - Map.entry( - BluetoothProfile.VOLUME_CONTROL, - "android.bluetooth.IBluetoothVolumeControl"), - Map.entry( - BluetoothProfile.CSIP_SET_COORDINATOR, - "android.bluetooth.IBluetoothCsipSetCoordinator"), - Map.entry( - BluetoothProfile.LE_AUDIO_BROADCAST, - "android.bluetooth.IBluetoothLeAudio"), - Map.entry( - BluetoothProfile.LE_CALL_CONTROL, - "android.bluetooth.IBluetoothLeCallControl"), - Map.entry(BluetoothProfile.HAP_CLIENT, "android.bluetooth.IBluetoothHapClient"), - Map.entry( - BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, - "android.bluetooth.IBluetoothLeBroadcastAssistant")); - private final Context mContext; private final Looper mLooper; @@ -244,8 +201,6 @@ class BluetoothManagerService { private final ContentResolver mContentResolver; private final RemoteCallbackList mCallbacks = new RemoteCallbackList(); - private final RemoteCallbackList mStateChangeCallbacks = - new RemoteCallbackList(); private final BluetoothServiceBinder mBinder; private final ReentrantReadWriteLock mAdapterLock = new ReentrantReadWriteLock(); @@ -307,6 +262,14 @@ class BluetoothManagerService { + mPackageName; } + long getTimestamp() { + return mTimestamp; + } + + boolean getEnable() { + return mEnable; + } + void dump(ProtoOutputStream proto) { proto.write(BluetoothManagerServiceDumpProto.ActiveLog.TIMESTAMP_MS, mTimestamp); proto.write(BluetoothManagerServiceDumpProto.ActiveLog.ENABLE, mEnable); @@ -336,10 +299,6 @@ class BluetoothManagerService { private final boolean mIsHearingAidProfileSupported; - // Save a ProfileServiceConnections object for each of the bound - // bluetooth profile services - private final Map mProfileServices = new HashMap<>(); - private volatile boolean mUnbindingAll = false; private final IBluetoothCallback mBluetoothCallback = @@ -428,8 +387,7 @@ class BluetoothManagerService { || mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED) || mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED) || mHandler.hasMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE) - || mHandler.hasMessages(MESSAGE_TIMEOUT_BIND) - || mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE)) { + || mHandler.hasMessages(MESSAGE_TIMEOUT_BIND)) { Log.d( TAG, "Busy reason:" @@ -444,9 +402,7 @@ class BluetoothManagerService { + " RESTART_BLUETOOTH_SERVICE=" + mHandler.hasMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE) + " TIMEOUT_BIND=" - + mHandler.hasMessages(MESSAGE_TIMEOUT_BIND) - + " BIND_PROFILE_SERVICE=" - + mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE)); + + mHandler.hasMessages(MESSAGE_TIMEOUT_BIND)); // Bluetooth is restarting return SERVICE_RESTART_TIME_MS; } @@ -475,11 +431,13 @@ class BluetoothManagerService { } /** Send Intent to the Notification Service in the Bluetooth app */ - Unit sendAirplaneModeNotification(String notificationState) { - Intent intent = new Intent("android.bluetooth.airplane.action.SEND_NOTIFICATION"); + Unit sendToggleNotification(String notificationReason) { + Intent intent = + new Intent("android.bluetooth.notification.action.SEND_TOGGLE_NOTIFICATION"); intent.setComponent(resolveSystemService(intent)); - intent.putExtra("android.bluetooth.airplane.extra.NOTIFICATION_STATE", notificationState); - mContext.startService(intent); + intent.putExtra( + "android.bluetooth.notification.extra.NOTIFICATION_REASON", notificationReason); + mCurrentUserContext.startService(intent); return Unit.INSTANCE; } @@ -550,6 +508,10 @@ class BluetoothManagerService { // Clear registered LE apps to force shut-off clearBleApps(); + if (!AirplaneModeListener.hasUserToggledApm(mCurrentUserContext)) { + AutoOnFeature.pause(); + } + // If state is BLE_ON make sure we trigger stopBle if (st == STATE_BLE_ON) { mAdapterLock.readLock().lock(); @@ -578,6 +540,8 @@ class BluetoothManagerService { mQuietEnableExternal, BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE, mContext.getPackageName()); + } else if (st != STATE_ON) { + autoOnSetupTimer(); } } } @@ -589,9 +553,14 @@ class BluetoothManagerService { BluetoothProtoEnums.ENABLE_DISABLE_REASON_SATELLITE_MODE, mContext.getPackageName()); } else if (!shouldBluetoothBeOn(isSatelliteModeOn) && getState() != STATE_OFF) { + AutoOnFeature.pause(); sendDisableMsg( BluetoothProtoEnums.ENABLE_DISABLE_REASON_SATELLITE_MODE, mContext.getPackageName()); + } else if (!isSatelliteModeOn + && !shouldBluetoothBeOn(isSatelliteModeOn) + && getState() != STATE_ON) { + autoOnSetupTimer(); } } @@ -695,10 +664,9 @@ class BluetoothManagerService { mContext.getSystemService(UserManager.class), "UserManager system service cannot be null"); - mBinder = new BluetoothServiceBinder(this, mContext, mUserManager); + mBinder = new BluetoothServiceBinder(this, mLooper, mContext, mUserManager); mHandler = new BluetoothHandler(mLooper); - // Observe BLE scan only mode settings change. registerForBleScanModeChange(); @@ -782,6 +750,18 @@ class BluetoothManagerService { mBluetoothSatelliteModeListener = new BluetoothSatelliteModeListener(this, mLooper, mContext); } + + { // AutoOn feature initialization of flag guarding + final boolean autoOnFlag = Flags.autoOnFeature(); + final boolean autoOnProperty = + SystemProperties.getBoolean("bluetooth.server.automatic_turn_on", false); + Log.d(TAG, "AutoOnFeature status: flag=" + autoOnFlag + ", property=" + autoOnProperty); + + mDeviceConfigAllowAutoOn = autoOnFlag && autoOnProperty; + if (mDeviceConfigAllowAutoOn) { + Counter.logIncrement("bluetooth.value_auto_on_supported"); + } + } } IBluetoothManager.Stub getBinder() { @@ -916,14 +896,6 @@ class BluetoothManagerService { } } - void registerStateChangeCallback(IBluetoothStateChangeCallback callback) { - mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK, callback).sendToTarget(); - } - - void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) { - mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK, callback).sendToTarget(); - } - boolean isEnabled() { return getState() == STATE_ON; } @@ -1095,7 +1067,6 @@ class BluetoothManagerService { return false; } - // TODO(b/262605980): enableBle/disableBle should be on handler thread updateBleAppCount(token, true, packageName); @@ -1230,6 +1201,17 @@ class BluetoothManagerService { } } + private Unit enableFromAutoOn() { + if (isBluetoothDisallowed()) { + Log.d(TAG, "Bluetooth is not allowed, preventing AutoOn"); + return Unit.INSTANCE; + } + Counter.logIncrement("bluetooth.value_auto_on_triggered"); + sendToggleNotification("auto_on_bt_enabled_notification"); + enable("BluetoothSystemServer/AutoOn"); + return Unit.INSTANCE; + } + boolean enableNoAutoConnect(String packageName) { if (isSatelliteModeOn()) { Log.d(TAG, "enableNoAutoConnect(" + packageName + "): Blocked by satellite mode"); @@ -1322,7 +1304,6 @@ class BluetoothManagerService { mAdapterLock.writeLock().lock(); try { mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); - mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE); if (mAdapter != null) { // Unregister callback object try { @@ -1340,92 +1321,6 @@ class BluetoothManagerService { } } - boolean bindBluetoothProfileService( - int bluetoothProfile, IBluetoothProfileServiceConnection proxy) { - String header = "bindBluetoothProfileService(" + bluetoothProfile + ", " + proxy + "):"; - - if (!mState.oneOf(BluetoothAdapter.STATE_ON)) { - Log.d(TAG, header + " Invalid state, Bluetooth is disabled"); - return false; - } - synchronized (mProfileServices) { - if (!mSupportedProfileList.contains(bluetoothProfile)) { - Log.w(TAG, header + " Profile is not supported"); - return false; - } - ProfileServiceConnections psc = mProfileServices.get(bluetoothProfile); - if (psc == null) { - Log.d(TAG, header + " Creating new ProfileServiceConnections"); - psc = - new ProfileServiceConnections( - new Intent(PROFILE_TO_SERVICE_NAME.get(bluetoothProfile))); - - // TODO: b/291815510 or b/288450479 - Remove clearCallingIdentity - // bindService is using bindServiceAsUser that require permission to interact - // across users. - // Because this method is called on the binderThread, we need to clear identity - // before attempting to bind - final long callingIdentity = Binder.clearCallingIdentity(); - try { - if (!psc.bindService(DEFAULT_REBIND_COUNT)) { - return false; - } - } finally { - Binder.restoreCallingIdentity(callingIdentity); - } - - mProfileServices.put(bluetoothProfile, psc); - } - } - - // Introducing a delay to give the client app time to prepare - Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED); - addProxyMsg.arg1 = bluetoothProfile; - addProxyMsg.obj = proxy; - mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS); - return true; - } - - void unbindBluetoothProfileService( - int bluetoothProfile, IBluetoothProfileServiceConnection proxy) { - if (mUnbindingAll) { - return; - } - synchronized (mProfileServices) { - ProfileServiceConnections psc = mProfileServices.get(bluetoothProfile); - if (psc == null) { - return; - } - psc.removeProxy(proxy); - if (psc.isEmpty()) { - // All proxies are disconnected, unbind with the service. - try { - mContext.unbindService(psc); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e); - } - mProfileServices.remove(bluetoothProfile); - } - } - } - - private void unbindAllBluetoothProfileServices() { - mUnbindingAll = true; - synchronized (mProfileServices) { - for (Integer i : mProfileServices.keySet()) { - ProfileServiceConnections psc = mProfileServices.get(i); - try { - mContext.unbindService(psc); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e); - } - psc.removeAllProxies(); - } - mProfileServices.clear(); - } - mUnbindingAll = false; - } - /** * Send enable message and set adapter name and address. Called when the boot phase becomes * PHASE_SYSTEM_SERVICES_READY. @@ -1436,17 +1331,17 @@ class BluetoothManagerService { @VisibleForTesting void initialize(UserHandle userHandle) { + mCurrentUserContext = + requireNonNull( + mContext.createContextAsUser(userHandle, 0), + "Current User Context cannot be null"); if (mUseNewAirplaneMode) { - mCurrentUserContext = - requireNonNull( - mContext.createContextAsUser(userHandle, 0), - "Current User Context cannot be null"); AirplaneModeListener.initialize( mLooper, mContentResolver, mState, this::onAirplaneModeChanged, - this::sendAirplaneModeNotification, + this::sendToggleNotification, this::isMediaProfileConnected, this::getCurrentUserContext, TimeSource.Monotonic.INSTANCE); @@ -1477,8 +1372,12 @@ class BluetoothManagerService { } else if (!isNameAndAddressSet()) { Log.i(TAG, "internalHandleOnBootPhase: Getting adapter name and address"); mHandler.sendEmptyMessage(MESSAGE_GET_NAME_AND_ADDRESS); + } else { + autoOnSetupTimer(); } + autoOnHiddenListener(); + if (!mUseNewAirplaneMode) { mBluetoothAirplaneModeListener.start(new BluetoothModeChangeHelper(mContext)); setApmEnhancementState(); @@ -1504,163 +1403,38 @@ class BluetoothManagerService { mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle).sendToTarget(); } - /** - * This class manages the clients connected to a given ProfileService and maintains the - * connection with that service. - */ - private final class ProfileServiceConnections - implements ServiceConnection, IBinder.DeathRecipient { - final RemoteCallbackList mProxies = - new RemoteCallbackList(); - IBinder mService; - ComponentName mClassName; - Intent mIntent; - - ProfileServiceConnections(Intent intent) { - mService = null; - mClassName = null; - mIntent = intent; - } - - private boolean bindService(int rebindCount) { - if (!mState.oneOf(STATE_ON)) { - Log.e(TAG, "bindService: Invalid state, Bluetooth is disabled"); - return false; - } - - if (mIntent != null - && mService == null - && doBind(mIntent, this, 0, USER_HANDLE_CURRENT_OR_SELF)) { - Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE, this); - msg.arg1 = rebindCount; - mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS); - return true; - } - Log.w(TAG, "bindService: Unable to bind. intent=" + mIntent); - return false; - } - - private void addProxy(IBluetoothProfileServiceConnection proxy) { - mProxies.register(proxy); - if (mService != null) { - try { - proxy.onServiceConnected(mClassName, mService); - } catch (RemoteException e) { - Log.e(TAG, "Unable to connect to proxy", e); - } - } else { - if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) { - Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE, this); - msg.arg1 = DEFAULT_REBIND_COUNT; - mHandler.sendMessage(msg); - } - } - } - - private void removeProxy(IBluetoothProfileServiceConnection proxy) { - if (proxy == null) { - Log.w(TAG, "removeProxy: null proxy for " + mIntent); - return; - } - if (mProxies.unregister(proxy)) { - try { - proxy.onServiceDisconnected(mClassName); - } catch (RemoteException e) { - Log.e(TAG, "Unable to disconnect proxy", e); - } - } - } - - private void removeAllProxies() { - onServiceDisconnected(mClassName); - mProxies.kill(); - } - - private boolean isEmpty() { - return mProxies.getRegisteredCallbackCount() == 0; - } - - @Override - public void onServiceConnected(ComponentName className, IBinder service) { - // remove timeout message - mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this); - mService = service; - mClassName = className; - try { - mService.linkToDeath(this, 0); - } catch (RemoteException e) { - Log.e(TAG, "Unable to linkToDeath", e); - } - - synchronized (mProxies) { - final int n = mProxies.beginBroadcast(); - try { - for (int i = 0; i < n; i++) { - try { - mProxies.getBroadcastItem(i).onServiceConnected(className, service); - } catch (RemoteException e) { - Log.e(TAG, "Unable to connect to proxy", e); - } - } - } finally { - mProxies.finishBroadcast(); - } - } - } - - @Override - public void onServiceDisconnected(ComponentName className) { - if (mService == null) { - return; - } + private void sendBluetoothOnCallback() { + synchronized (mCallbacks) { try { - mService.unlinkToDeath(this, 0); - } catch (NoSuchElementException e) { - Log.e(TAG, "error unlinking to death", e); - } - mService = null; - mClassName = null; - - synchronized (mProxies) { - final int n = mProxies.beginBroadcast(); - try { - for (int i = 0; i < n; i++) { - try { - mProxies.getBroadcastItem(i).onServiceDisconnected(className); - } catch (RemoteException e) { - Log.e(TAG, "Unable to disconnect from proxy #" + i, e); - } + int n = mCallbacks.beginBroadcast(); + Log.d(TAG, "Broadcasting onBluetoothOn() to " + n + " receivers."); + for (int i = 0; i < n; i++) { + try { + mCallbacks.getBroadcastItem(i).onBluetoothOn(); + } catch (RemoteException e) { + Log.e(TAG, "Unable to call onBluetoothOn() on callback #" + i, e); } - } finally { - mProxies.finishBroadcast(); } + } finally { + mCallbacks.finishBroadcast(); } } - - @Override - public void binderDied() { - Log.w(TAG, "binderDied(): profile=" + mClassName); - onServiceDisconnected(mClassName); - // Trigger rebind - Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE, this); - mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS); - } } - private void sendBluetoothStateCallback(boolean isUp) { - synchronized (mStateChangeCallbacks) { + private void sendBluetoothOffCallback() { + synchronized (mCallbacks) { try { - int n = mStateChangeCallbacks.beginBroadcast(); - Log.d(TAG, "sendBluetoothStateCallback(" + isUp + "): to " + n + " receivers"); + int n = mCallbacks.beginBroadcast(); + Log.d(TAG, "Broadcasting onBluetoothOff() to " + n + " receivers."); for (int i = 0; i < n; i++) { try { - mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp); + mCallbacks.getBroadcastItem(i).onBluetoothOff(); } catch (RemoteException e) { - Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i, e); + Log.e(TAG, "Unable to call onBluetoothOff() on callback #" + i, e); } } } finally { - mStateChangeCallbacks.finishBroadcast(); + mCallbacks.finishBroadcast(); } } } @@ -2014,59 +1788,6 @@ class BluetoothManagerService { } break; - case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: - IBluetoothStateChangeCallback regCallback = - (IBluetoothStateChangeCallback) msg.obj; - if (mState.oneOf(STATE_ON)) { - try { - regCallback.onBluetoothStateChange(true); - } catch (RemoteException e) { - Log.e(TAG, "REGISTER_STATE_CHANGE_CALLBACK: callback failed", e); - break; - } - } - mStateChangeCallbacks.register(regCallback); - break; - - case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: - IBluetoothStateChangeCallback unregCallback = - (IBluetoothStateChangeCallback)msg.obj; - try { - // LINT.IfChange - unregCallback.onBluetoothStateChange(false); - // LINT.ThenChange(/framework/tests/unit/src/android/bluetooth/BluetoothProfileConnectorTest.java) - } catch (RemoteException e) { - Log.e(TAG, "UNREGISTER_STATE_CHANGE_CALLBACK: callback failed", e); - } - mStateChangeCallbacks.unregister(unregCallback); - break; - - case MESSAGE_ADD_PROXY_DELAYED: - ProfileServiceConnections connection = mProfileServices.get(msg.arg1); - if (connection == null) { - break; - } - IBluetoothProfileServiceConnection proxy = - (IBluetoothProfileServiceConnection) msg.obj; - connection.addProxy(proxy); - break; - - case MESSAGE_BIND_PROFILE_SERVICE: - ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj; - removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj); - if (psc == null) { - break; - } - if (msg.arg1 > 0) { - try { - mContext.unbindService(psc); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e); - } - psc.bindService(msg.arg1 - 1); - } - break; - case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: IBinder service = (IBinder) msg.obj; Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: service=" + service); @@ -2255,9 +1976,9 @@ class BluetoothManagerService { mBluetoothNotificationManager.createNotificationChannels(); } - if (mUseNewAirplaneMode) { - mCurrentUserContext = mContext.createContextAsUser(userTo, 0); - } + AutoOnFeature.pause(); + + mCurrentUserContext = mContext.createContextAsUser(userTo, 0); /* disable and enable BT when detect a user switch */ if (mAdapter != null && mState.oneOf(STATE_ON)) { @@ -2274,7 +1995,12 @@ class BluetoothManagerService { + (" number of retry attempt=" + userMsg.arg1) + (" isBinding=" + isBinding()) + (" mAdapter=" + mAdapter)); + } else { + autoOnSetupTimer(); } + + autoOnHiddenListener(); + break; case MESSAGE_USER_UNLOCKED: @@ -2313,7 +2039,6 @@ class BluetoothManagerService { // This method is always called while bluetooth is in STATE_ON assert (mState.oneOf(STATE_ON)); - unbindAllBluetoothProfileServices(); // disable addActiveLog( BluetoothProtoEnums.ENABLE_DISABLE_REASON_USER_SWITCH, @@ -2451,9 +2176,16 @@ class BluetoothManagerService { return; } + if (prevState == STATE_ON) { + autoOnSetupTimer(); + } + // Notify all proxy objects first of adapter state change if (newState == STATE_ON) { - sendBluetoothStateCallback(true); + if (mDeviceConfigAllowAutoOn) { + AutoOnFeature.notifyBluetoothOn(mCurrentUserContext.getContentResolver()); + } + sendBluetoothOnCallback(); } else if (newState == STATE_OFF) { // If Bluetooth is off, send service down event to proxy objects, and unbind Log.d(TAG, "bluetoothStateChangeHandler: Bluetooth is OFF send Service Down"); @@ -2471,7 +2203,7 @@ class BluetoothManagerService { if (prevBrEdrState != newBrEdrState) { // Only broadcast when there is a BrEdr state change. if (newBrEdrState == STATE_OFF) { - sendBluetoothStateCallback(false); + sendBluetoothOffCallback(); sendBrEdrDownCallback(mContext.getAttributionSource()); } broadcastIntentStateChange( @@ -2503,6 +2235,7 @@ class BluetoothManagerService { } private void addActiveLog(int reason, String packageName, boolean enable) { + ActiveLog lastActiveLog = mActiveLogs.peekLast(); synchronized (mActiveLogs) { if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) { mActiveLogs.remove(); @@ -2514,13 +2247,29 @@ class BluetoothManagerService { ? BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED : BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED; + int lastState; + long timeSinceLastChanged; + if (lastActiveLog == null) { + lastState = BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__UNKNOWN; + timeSinceLastChanged = 0; + } else { + lastState = + lastActiveLog.getEnable() + ? BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED + : BluetoothStatsLog + .BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED; + timeSinceLastChanged = System.currentTimeMillis() - lastActiveLog.getTimestamp(); + } + BluetoothStatsLog.write_non_chained( BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED, Binder.getCallingUid(), null, state, reason, - packageName); + packageName, + lastState, + timeSinceLastChanged); } } @@ -2761,12 +2510,17 @@ class BluetoothManagerService { args[0] = "--print"; } + try { + dumpBluetoothFlags(writer); + } catch (Exception e) { + writer.println("Exception while dumping Bluetooth Flags"); + } + if (mAdapter == null) { errorMsg = "Bluetooth Service not connected"; } else { try { - // TODO(b/239890880): system_server cannot make non-oneway call - mAdapter.getAdapterBinder().asBinder().dump(fd, args); + mAdapter.getAdapterBinder().asBinder().dumpAsync(fd, args); } catch (RemoteException re) { errorMsg = "RemoteException while dumping Bluetooth Service"; } @@ -2776,6 +2530,30 @@ class BluetoothManagerService { } } + private void dumpBluetoothFlags(PrintWriter writer) + throws IllegalAccessException, InvocationTargetException { + writer.println("🚩Flag dump:"); + + // maxLen is used to align the flag output + int maxLen = + Arrays.stream(Flags.class.getDeclaredMethods()) + .map(Method::getName) + .map(String::length) + .max(Integer::compare) + .get(); + + String fmt = "\t%s: %-" + maxLen + "s %s"; + + for (Method m : Flags.class.getDeclaredMethods()) { + String flagStatus = ((Boolean) m.invoke(null)) ? "[■]" : "[ ]"; + String name = m.getName(); + String snakeCaseName = + name.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase(Locale.US); + writer.println(String.format(fmt, flagStatus, name, snakeCaseName)); + } + writer.println(""); + } + private void dumpProto(FileDescriptor fd) { final ProtoOutputStream proto = new ProtoOutputStream(new FileOutputStream(fd)); proto.write(BluetoothManagerServiceDumpProto.ENABLED, isEnabled()); @@ -2916,6 +2694,57 @@ class BluetoothManagerService { return BluetoothAdapter.BT_SNOOP_LOG_MODE_DISABLED; } + private final boolean mDeviceConfigAllowAutoOn; + + private void autoOnSetupTimer() { + if (!mDeviceConfigAllowAutoOn) { + Log.d(TAG, "No support for AutoOn feature: Not creating a timer"); + return; + } + AutoOnFeature.resetAutoOnTimerForUser( + mLooper, mCurrentUserContext, mState, this::enableFromAutoOn); + } + + private void autoOnHiddenListener() { + if (!mDeviceConfigAllowAutoOn) { + Log.d(TAG, "No support for AutoOn feature: Not listening on hidden api"); + return; + } + if (isAtLeastV()) { + Log.d(TAG, "AutoOn feature: prevent listening on hidden api. Use proper API in V+"); + return; + } + AutoOnFeature.registerHiddenApiListener( + mLooper, mCurrentUserContext, mState, this::enableFromAutoOn); + } + + boolean isAutoOnSupported() { + return mDeviceConfigAllowAutoOn + && AutoOnFeature.isUserSupported(mCurrentUserContext.getContentResolver()); + } + + boolean isAutoOnEnabled() { + if (!mDeviceConfigAllowAutoOn) { + throw new IllegalStateException("AutoOnFeature is not supported in current config"); + } + return AutoOnFeature.isUserEnabled(mCurrentUserContext); + } + + void setAutoOnEnabled(boolean status) { + if (!mDeviceConfigAllowAutoOn) { + throw new IllegalStateException("AutoOnFeature is not supported in current config"); + } + // Call coming from binder thread need to be posted before exec + mHandler.post( + () -> + AutoOnFeature.setUserEnabled( + mLooper, + mCurrentUserContext, + mState, + status, + this::enableFromAutoOn)); + } + /** * Check if BLE is supported by this platform * diff --git a/service/src/com/android/server/bluetooth/BluetoothServiceBinder.java b/service/src/com/android/server/bluetooth/BluetoothServiceBinder.java index 352364022b8c73be63df884ec248c4551428c956..99d94e76105ac448a732e88ab1641c4fe1a63912 100644 --- a/service/src/com/android/server/bluetooth/BluetoothServiceBinder.java +++ b/service/src/com/android/server/bluetooth/BluetoothServiceBinder.java @@ -36,11 +36,10 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.IBluetooth; import android.bluetooth.IBluetoothManager; import android.bluetooth.IBluetoothManagerCallback; -import android.bluetooth.IBluetoothProfileServiceConnection; -import android.bluetooth.IBluetoothStateChangeCallback; import android.content.AttributionSource; import android.content.Context; import android.os.IBinder; +import android.os.Looper; import android.os.ParcelFileDescriptor; import android.os.UserManager; import android.permission.PermissionManager; @@ -57,9 +56,12 @@ class BluetoothServiceBinder extends IBluetoothManager.Stub { private final AppOpsManager mAppOpsManager; private final PermissionManager mPermissionManager; private final BtPermissionUtils mPermissionUtils; + private final Looper mLooper; - BluetoothServiceBinder(BluetoothManagerService bms, Context ctx, UserManager userManager) { + BluetoothServiceBinder( + BluetoothManagerService bms, Looper looper, Context ctx, UserManager userManager) { mBluetoothManagerService = bms; + mLooper = looper; mContext = ctx; mUserManager = userManager; mAppOpsManager = @@ -86,18 +88,6 @@ class BluetoothServiceBinder extends IBluetoothManager.Stub { mBluetoothManagerService.unregisterAdapter(callback); } - @Override - public void registerStateChangeCallback(@NonNull IBluetoothStateChangeCallback callback) { - requireNonNull(callback, "Callback cannot be null in registerStateChangeCallback"); - mBluetoothManagerService.registerStateChangeCallback(callback); - } - - @Override - public void unregisterStateChangeCallback(@NonNull IBluetoothStateChangeCallback callback) { - requireNonNull(callback, "Callback cannot be null in unregisterStateChangeCallback"); - mBluetoothManagerService.unregisterStateChangeCallback(callback); - } - @Override public boolean enable(@NonNull AttributionSource source) { requireNonNull(source, "AttributionSource cannot be null in enable"); @@ -180,22 +170,6 @@ class BluetoothServiceBinder extends IBluetoothManager.Stub { return mBluetoothManagerService.getState(); } - @Override - public boolean bindBluetoothProfileService( - int bluetoothProfile, IBluetoothProfileServiceConnection proxy) { - requireNonNull( - proxy, - "IBluetoothProfileServiceConnection cannot be null in bindBluetoothProfileService"); - - return mBluetoothManagerService.bindBluetoothProfileService(bluetoothProfile, proxy); - } - - @Override - public void unbindBluetoothProfileService( - int bluetoothProfile, IBluetoothProfileServiceConnection proxy) { - mBluetoothManagerService.unbindBluetoothProfileService(bluetoothProfile, proxy); - } - @Override @RequiresPermission(allOf = {BLUETOOTH_CONNECT, LOCAL_MAC_ADDRESS}) public String getAddress(AttributionSource source) { @@ -347,6 +321,27 @@ class BluetoothServiceBinder extends IBluetoothManager.Stub { args); } + @Override + @RequiresPermission(BLUETOOTH_PRIVILEGED) + public boolean isAutoOnSupported() { + BtPermissionUtils.enforcePrivileged(mContext); + return mBluetoothManagerService.isAutoOnSupported(); + } + + @Override + @RequiresPermission(BLUETOOTH_PRIVILEGED) + public boolean isAutoOnEnabled() { + BtPermissionUtils.enforcePrivileged(mContext); + return mBluetoothManagerService.isAutoOnEnabled(); + } + + @Override + @RequiresPermission(BLUETOOTH_PRIVILEGED) + public void setAutoOnEnabled(boolean status) { + BtPermissionUtils.enforcePrivileged(mContext); + mBluetoothManagerService.setAutoOnEnabled(status); + } + @Override @RequiresPermission(DUMP) public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { diff --git a/service/src/satellite/ModeListenerTest.kt b/service/src/satellite/ModeListenerTest.kt index f3adeeaf919886c2cbedd871d192cb44536edf2e..f3d858d58cc527b20d220a5af935c1e11e356a94 100644 --- a/service/src/satellite/ModeListenerTest.kt +++ b/service/src/satellite/ModeListenerTest.kt @@ -40,6 +40,24 @@ import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class ModeListenerTest { + companion object { + internal fun setupSatelliteModeToOn( + resolver: ContentResolver, + looper: Looper, + callback: (m: Boolean) -> Unit + ) { + enableSensitive(resolver, looper, SETTINGS_SATELLITE_MODE_RADIOS) + enableMode(resolver, looper, SETTINGS_SATELLITE_MODE_ENABLED) + + initialize(looper, resolver, callback) + } + + internal fun setupSatelliteModeToOff(resolver: ContentResolver, looper: Looper) { + disableSensitive(resolver, looper, SETTINGS_SATELLITE_MODE_RADIOS) + disableMode(resolver, looper, SETTINGS_SATELLITE_MODE_ENABLED) + } + } + private val resolver: ContentResolver = ApplicationProvider.getApplicationContext().getContentResolver() @JvmField @Rule val testName = TestName() diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java index d25ba428a7b455a09f9275b3d01fd163bf475b83..1c60d8a5a8861ffa2f062bf5c3827e5656a3a7f3 100644 --- a/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java +++ b/service/tests/src/com/android/server/bluetooth/BluetoothAirplaneModeListenerTest.java @@ -241,7 +241,7 @@ public class BluetoothAirplaneModeListenerTest { mBluetoothAirplaneModeListener.handleAirplaneModeChange(true); - verify(mBluetoothManagerService).sendAirplaneModeNotification(eq(APM_WIFI_BT_NOTIFICATION)); + verify(mBluetoothManagerService).sendToggleNotification(eq(APM_WIFI_BT_NOTIFICATION)); } @Test @@ -287,7 +287,7 @@ public class BluetoothAirplaneModeListenerTest { mBluetoothAirplaneModeListener.handleAirplaneModeChange(true); - verify(mBluetoothManagerService).sendAirplaneModeNotification(eq(APM_BT_NOTIFICATION)); + verify(mBluetoothManagerService).sendToggleNotification(eq(APM_BT_NOTIFICATION)); } @Test diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java index 6c78346493b30003fa0f17a5627f2f7f76db1900..268e866780d82a73ce62183c38f29b2764e84cf5 100644 --- a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java +++ b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java @@ -25,7 +25,6 @@ import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUET import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUETOOTH_STATE_CHANGE; import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_DISABLE; import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_ENABLE; -import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_REGISTER_STATE_CHANGE_CALLBACK; import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_TIMEOUT_BIND; import static com.google.common.truth.Truth.assertThat; @@ -192,7 +191,6 @@ public class BluetoothManagerServiceTest { doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); doReturn(mBinder).when(mManagerCallback).asBinder(); - doReturn(mBinder).when(mStateChangeCallback).asBinder(); doReturn(mAdapterBinder).when(mBluetoothServerProxy).createAdapterBinder(any()); doReturn(mAdapterService).when(mAdapterBinder).getAdapterBinder(); @@ -420,15 +418,11 @@ public class BluetoothManagerServiceTest { .when(mBluetoothServerProxy) .getBluetoothPersistedState(any(), anyInt()); - mManagerService.registerStateChangeCallback(mStateChangeCallback); - syncHandler(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK); - mManagerService.enable("test_offToOn"); syncHandler(MESSAGE_ENABLE); transition_offToOn(); - verify(mStateChangeCallback).onBluetoothStateChange(eq(true)); assertThat(mManagerService.getState()).isEqualTo(STATE_ON); } } diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java index cd31a27ffadbf605527c97e86ede325b0bb53423..296e60a425004c808c5629a0d8fce6389606dfe2 100644 --- a/service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java +++ b/service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java @@ -41,8 +41,6 @@ import static org.mockito.quality.Strictness.STRICT_STUBS; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.bluetooth.IBluetoothManagerCallback; -import android.bluetooth.IBluetoothProfileServiceConnection; -import android.bluetooth.IBluetoothStateChangeCallback; import android.compat.testing.PlatformCompatChangeRule; import android.content.AttributionSource; import android.content.Context; @@ -114,7 +112,7 @@ public class BluetoothServiceBinderTest { doReturn(mAppOpsManager).when(mContext).getSystemService(eq(appops)); doReturn(mDevicePolicyManager).when(mContext).getSystemService(eq(devicePolicy)); - mBinder = new BluetoothServiceBinder(mManagerService, mContext, mUserManager); + mBinder = new BluetoothServiceBinder(mManagerService, null, mContext, mUserManager); } @After @@ -141,22 +139,6 @@ public class BluetoothServiceBinderTest { verifyMock(); } - @Test - public void registerStateChangeCallback() { - assertThrows(NullPointerException.class, () -> mBinder.registerStateChangeCallback(null)); - mBinder.registerStateChangeCallback(mock(IBluetoothStateChangeCallback.class)); - verify(mManagerService).registerStateChangeCallback(any()); - verifyMock(); - } - - @Test - public void unregisterStateChangeCallback() { - assertThrows(NullPointerException.class, () -> mBinder.unregisterStateChangeCallback(null)); - mBinder.unregisterStateChangeCallback(mock(IBluetoothStateChangeCallback.class)); - verify(mManagerService).unregisterStateChangeCallback(any()); - verifyMock(); - } - @Test @DisableCompatChanges({ChangeIds.RESTRICT_ENABLE_DISABLE}) public void enableNoRestrictEnable() { @@ -245,25 +227,6 @@ public class BluetoothServiceBinderTest { verifyMock(); } - @Test - public void bindBluetoothProfileService() { - assertThrows( - NullPointerException.class, () -> mBinder.bindBluetoothProfileService(0, null)); - // No permission needed for this call - - mBinder.bindBluetoothProfileService(0, mock(IBluetoothProfileServiceConnection.class)); - verify(mManagerService).bindBluetoothProfileService(anyInt(), any()); - verifyMock(); - } - - @Test - public void unbindBluetoothProfileService() { - // No permission needed for this call - mBinder.unbindBluetoothProfileService(0, null); - verify(mManagerService).unbindBluetoothProfileService(anyInt(), any()); - verifyMock(); - } - @Test public void getAddress() { assertThrows(NullPointerException.class, () -> mBinder.getAddress(null)); diff --git a/sysprop/ble.sysprop b/sysprop/ble.sysprop index 50723897c6fd16241e35440ee3a35bab940c4bb1..ad2208f0b18bb01e61903bacd5a4c50fc6dd1d3c 100644 --- a/sysprop/ble.sysprop +++ b/sysprop/ble.sysprop @@ -8,3 +8,19 @@ prop { access: Readonly prop_name: "bluetooth.ble.vnd.included" } + +prop { + api_name: "random_address_rotation_interval_min" + type: Integer + scope: Internal + access: Readonly + prop_name: "bluetooth.ble.random_address_rotation_interval_min" +} + +prop { + api_name: "random_address_rotation_interval_max" + type: Integer + scope: Internal + access: Readonly + prop_name: "bluetooth.ble.random_address_rotation_interval_max" +} diff --git a/system/Android.bp b/system/Android.bp index 326e2efad65421894a6f0879f31e619addb377f0..cd272d4651cb644b75e8b9a7bf5460b37683bb9f 100644 --- a/system/Android.bp +++ b/system/Android.bp @@ -161,7 +161,6 @@ rust_protobuf { "com.android.btservices", ], min_sdk_version: "30", - use_protobuf3: true, } rust_protobuf { @@ -170,7 +169,6 @@ rust_protobuf { source_stem: "topshim_facade", host_supported: true, grpc_protos: ["blueberry/facade/topshim/facade.proto"], - use_protobuf3: true, } genrule { diff --git a/system/BUILD.gn b/system/BUILD.gn index 02b92d245b2a8e475f70452f08ec6c79ffd2c252..62ced34597ed9684315876667bb53c5ebbe70540 100644 --- a/system/BUILD.gn +++ b/system/BUILD.gn @@ -174,6 +174,10 @@ config("external_flatbuffers") { libs = [ "flatbuffers" ] } +config("external_fmtlib") { + configs = [ ":pkg_fmtlib" ] +} + # Package configurations to extract dependencies from env pkg_config("pkg_gtest") { pkg_deps = [ "gtest" ] @@ -203,6 +207,10 @@ pkg_config("pkg_tinyxml2") { pkg_deps = [ "tinyxml2" ] } +pkg_config("pkd_fmtlib") { + pkg_deps = [ "fmt" ] +} + # To include ChroemOS-specific libraries and build dependencies. if (target_os == "chromeos") { config("external_chromeos") { diff --git a/system/OWNERS b/system/OWNERS index ca3ea8ae667e6603a7c8c150421153ea31c2165f..d9f728419601a6b26d12ac35e48ede734b2ba605 100644 --- a/system/OWNERS +++ b/system/OWNERS @@ -7,4 +7,5 @@ jpawlowski@google.com mylesgw@google.com rwt@google.com wescande@google.com -yuyangh@google.com \ No newline at end of file +yuyangh@google.com +rongxuan@google.com diff --git a/system/audio/Android.bp b/system/audio/Android.bp new file mode 100644 index 0000000000000000000000000000000000000000..2fc5464fd4fac866228655a3af20b3049258c71d --- /dev/null +++ b/system/audio/Android.bp @@ -0,0 +1,61 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "system_bt_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["system_bt_license"], +} + +cc_library_static { + name: "libbt-audio-asrc", + defaults: [], + srcs: [ + "asrc/asrc_resampler.cc", + "asrc/asrc_tables.cc", + ], + shared_libs: [ + "libchrome", + ], + static_libs: [ + "libflatbuffers-cpp", + ], + host_supported: true, + min_sdk_version: "33", + apex_available: [ + "com.android.btservices", + ], +} + +cc_library_host_shared { + name: "libasrc_resampler_test", + defaults: ["bluetooth_cflags"], + srcs: [ + "asrc/asrc_resampler_test.cc", + "asrc/asrc_tables.cc", + ], + static_libs: [ + "libchrome", + "libflatbuffers-cpp", + ], + stl: "libc++_static", + include_dirs: [ + "packages/modules/Bluetooth/system", + ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + ], +} + +python_test_host { + name: "asrc_resampler_test", + main: "asrc/asrc_resampler_test.py", + srcs: ["asrc/asrc_resampler_test.py"], + libs: ["mobly"], + data: [":libasrc_resampler_test"], + test_config: "asrc/asrc_resampler_test.config", + test_suites: ["general-tests"], + test_options: { + unit_test: false, + }, +} diff --git a/system/audio/BUILD.gn b/system/audio/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..6c04716e90f8c0fdb97a37ee948115495e20c9ef --- /dev/null +++ b/system/audio/BUILD.gn @@ -0,0 +1,34 @@ +# +# Copyright 2015 Google, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +source_set("libbt-audio-asrc") { + sources = [ + "asrc/asrc_tables.cc", + "asrc/asrc_resampler.cc", + ] + + include_dirs = [ + "asrc", + ] + + configs += [ + "//bt/system:target_defaults", + ] + + deps = [ + "//bt/system/gd:gd_default_deps" + ] +} diff --git a/system/bta/le_audio/audio_hal_client/asrc_butter.py b/system/audio/asrc/asrc_butter.py similarity index 100% rename from system/bta/le_audio/audio_hal_client/asrc_butter.py rename to system/audio/asrc/asrc_butter.py diff --git a/system/bta/le_audio/audio_hal_client/audio_source_hal_asrc.cc b/system/audio/asrc/asrc_resampler.cc similarity index 81% rename from system/bta/le_audio/audio_hal_client/audio_source_hal_asrc.cc rename to system/audio/asrc/asrc_resampler.cc index 43b5e8f4df4104b882ed8acb25c4f02ca0537fbe..09e59584c7e8b487960f869d81eeb5e05f8474ef 100644 --- a/system/bta/le_audio/audio_hal_client/audio_source_hal_asrc.cc +++ b/system/audio/asrc/asrc_resampler.cc @@ -14,41 +14,47 @@ * limitations under the License. */ -#include "audio_source_hal_asrc.h" +#include "asrc_resampler.h" #include #include +#include #include #include #include "asrc_tables.h" -#include "gd/hal/nocp_iso_clocker.h" -namespace le_audio { +namespace bluetooth::audio::asrc { -class SourceAudioHalAsrc::ClockRecovery : ::bluetooth::hal::NocpIsoHandler { +class SourceAudioHalAsrc::ClockRecovery : public ClockHandler { const int interval_; std::mutex mutex_; unsigned num_produced_; - unsigned num_completed_; - int min_buffer_level_; - int max_buffer_level_; - enum class StateId { RESET, WARMUP, RUNNING }; + enum class LinkState { RESET, WARMUP, RUNNING }; struct { - StateId id; + struct { + LinkState state; + + uint32_t local_time; + uint32_t decim_t0; + int decim_dt[2]; + + unsigned num_completed; + int min_buffer_level; + + } link[2]; + + int active_link_id; uint32_t t0; uint32_t local_time; uint32_t stream_time; - uint32_t decim_t0; - int decim_dt[2]; - double butter_drift; double butter_s[2]; } state_; @@ -65,18 +71,26 @@ class SourceAudioHalAsrc::ClockRecovery : ::bluetooth::hal::NocpIsoHandler { } output_stats_; __attribute__((no_sanitize("integer"))) void OnEvent( - uint32_t timestamp_us, int num_completed) override { + uint32_t timestamp_us, int link_id, int num_completed) override { auto& state = state_; + auto& link = state.link[link_id]; // Setup the start point of the streaming - if (state.id == StateId::RESET) { - state.t0 = timestamp_us; - state.local_time = state.stream_time = state.t0; + if (link.state == LinkState::RESET) { + if (state.link[link_id ^ 1].state == LinkState::RESET) { + state.t0 = timestamp_us; + state.local_time = timestamp_us; + } - state.decim_t0 = state.t0; - state.decim_dt[1] = INT_MAX; - state.id = StateId::WARMUP; + link.local_time = timestamp_us; + link.decim_t0 = timestamp_us; + link.decim_dt[1] = INT_MAX; + + link.num_completed = 0; + link.min_buffer_level = INT_MAX; + + link.state = LinkState::WARMUP; } // Update buffering level measure @@ -84,45 +98,82 @@ class SourceAudioHalAsrc::ClockRecovery : ::bluetooth::hal::NocpIsoHandler { { const std::lock_guard lock(mutex_); - num_completed_ += num_completed; - min_buffer_level_ = - std::min(min_buffer_level_, int(num_produced_ - num_completed_)); + link.num_completed += num_completed; + link.min_buffer_level = std::min(link.min_buffer_level, + int(num_produced_ - link.num_completed)); } // Update timing informations, and compute the minimum deviation // in the interval of the decimation (1 second). - state.local_time += num_completed * interval_; - state.stream_time += num_completed * interval_; + link.local_time += num_completed * interval_; + if (link_id == state.active_link_id) { + state.local_time += num_completed * interval_; + state.stream_time += num_completed * interval_; + } - int dt_current = int(timestamp_us - state.local_time); - state.decim_dt[1] = std::min(state.decim_dt[1], dt_current); + int dt_current = int(timestamp_us - link.local_time); + link.decim_dt[1] = std::min(link.decim_dt[1], dt_current); - if (state.local_time - state.decim_t0 < 1000 * 1000) return; + if (link.local_time - link.decim_t0 < 1000 * 1000) return; - state.decim_t0 += 1000 * 1000; + link.decim_t0 += 1000 * 1000; // The first decimation interval is used to adjust the start point. // The deviation between local time and stream time in this interval can be // ignored. - if (state.id == StateId::WARMUP) { - state.decim_t0 += state.decim_dt[1]; - state.local_time += state.decim_dt[1]; - state.stream_time += state.decim_dt[1]; + if (link.state == LinkState::WARMUP) { + link.decim_t0 += link.decim_dt[1]; + link.local_time += link.decim_dt[1]; + if (state.active_link_id < 0) { + state.active_link_id = link_id; + state.local_time = link.local_time; + state.stream_time = link.local_time; + } - state.decim_dt[0] = 0; - state.decim_dt[1] = INT_MAX; - state.id = StateId::RUNNING; + link.decim_dt[0] = 0; + link.decim_dt[1] = INT_MAX; + link.state = LinkState::RUNNING; return; } // Deduct the derive of the deviation, from the difference between // the two consecutives decimated deviations. - int drift = state.decim_dt[1] - state.decim_dt[0]; - state.decim_dt[0] = state.decim_dt[1]; - state.decim_dt[1] = INT_MAX; + int drift = link.decim_dt[1] - link.decim_dt[0]; + link.decim_dt[0] = link.decim_dt[1]; + link.decim_dt[1] = INT_MAX; + + // Sanity check, limit the instant derive to +/- 50 ms / second, + // and the gap between the 2 links to +/- 250ms. Reset the link state + // with out of range drift, and eventually active the other link. + + int dt_link = state.link[link_id ^ 1].state == LinkState::RUNNING + ? link.local_time - state.link[link_id ^ 1].local_time + : 0; + bool stalled = std::abs(dt_link) > 250 * 1000; + + if (std::abs(drift) > 50 * 1000 || stalled) { + int bad_link_id = link_id ^ stalled; + auto& bad_link = state.link[bad_link_id]; + + bool resetting = (bad_link.state != LinkState::RUNNING); + bool switching = + state.active_link_id == bad_link_id && + (state.link[bad_link_id ^ 1].state == LinkState::RUNNING); + + bad_link.state = LinkState::RESET; + if (bad_link_id == state.active_link_id) state.active_link_id = -1; + + if (switching) state.active_link_id = bad_link_id ^ 1; + + if (resetting || switching) + LOG(WARNING) << "Link unstable or stalled, " + << (switching ? "switching" : "resetting") << std::endl; + } + + if (link_id != state.active_link_id) return; // Let's filter the derive, with a low-pass Butterworth filter. // The cut-off frequency is set to 1/60th seconds. @@ -140,7 +191,7 @@ class SourceAudioHalAsrc::ClockRecovery : ::bluetooth::hal::NocpIsoHandler { // the difference between the instant stream time, and the local time // corrected by the decimated deviation. - int err = state.stream_time - (state.local_time + state.decim_dt[0]); + int err = state.stream_time - (state.local_time + link.decim_dt[0]); state.stream_time += (int(ldexpf(state.butter_drift, 8)) - err + (1 << 7)) >> 8; @@ -158,9 +209,6 @@ class SourceAudioHalAsrc::ClockRecovery : ::bluetooth::hal::NocpIsoHandler { ref.drift = state.butter_drift * 1e-6; output_stats = output_stats_; - min_buffer_level = min_buffer_level_; - min_buffer_level_ = INT_MAX; - max_buffer_level_ = INT_MIN; } LOG(INFO) << base::StringPrintf("Deviation: %6d us (%3.0f ppm)", @@ -171,23 +219,26 @@ class SourceAudioHalAsrc::ClockRecovery : ::bluetooth::hal::NocpIsoHandler { output_stats.sample_rate, output_stats.drift_us) << " | " - << base::StringPrintf("Buffer level: %d", min_buffer_level) + << base::StringPrintf( + "Buffer level: %d:%d", + std::min(state.link[0].min_buffer_level, 99), + std::min(state.link[1].min_buffer_level, 99)) << std::endl; + + state.link[0].min_buffer_level = INT_MAX; + state.link[1].min_buffer_level = INT_MAX; } public: ClockRecovery(unsigned interval_us) : interval_(interval_us), num_produced_(0), - num_completed_(0), - min_buffer_level_(INT_MAX), - max_buffer_level_(INT_MIN), - state_{.id = StateId::RESET}, - reference_timing_{0, 0, 0} { - ::bluetooth::hal::NocpIsoClocker::Register(this); - } + state_{ + .link = {{.state = LinkState::RESET}, {.state = LinkState::RESET}}, + .active_link_id = -1}, + reference_timing_{0, 0, 0} {} - ~ClockRecovery() override { ::bluetooth::hal::NocpIsoClocker::Unregister(); } + ~ClockRecovery() override {} __attribute__((no_sanitize("integer"))) uint32_t Convert( uint32_t stream_time) { @@ -210,9 +261,6 @@ class SourceAudioHalAsrc::ClockRecovery : ::bluetooth::hal::NocpIsoHandler { const std::lock_guard lock(mutex_); num_produced_ += out_count; - max_buffer_level_ = - std::max(max_buffer_level_, int(num_produced_ - num_completed_)); - output_stats_ = {sample_rate, drift_us}; } }; @@ -415,16 +463,16 @@ inline int32_t SourceAudioHalAsrc::Resampler::Filter(const int32_t* in, #endif -SourceAudioHalAsrc::SourceAudioHalAsrc(int channels, int sample_rate, - int bit_depth, int interval_us, - int num_burst_buffers, - int burst_delay_ms) +SourceAudioHalAsrc::SourceAudioHalAsrc( + std::shared_ptr clock_source, int channels, int sample_rate, + int bit_depth, int interval_us, int num_burst_buffers, int burst_delay_ms) : sample_rate_(sample_rate), bit_depth_(bit_depth), interval_us_(interval_us), stream_us_(0), drift_us_(0), out_counter_(0), + clock_source_(std::move(clock_source)), resampler_pos_{0, 0} { buffers_size_ = 0; @@ -458,6 +506,7 @@ SourceAudioHalAsrc::SourceAudioHalAsrc(int channels, int sample_rate, // when the PCM bit_depth is higher than 16 bits. clock_recovery_ = std::make_unique(interval_us_); + clock_source_->Bind(clock_recovery_.get()); resamplers_ = std::make_unique>(channels, bit_depth_); // Deduct from the PCM stream characteristics, the size of the pool buffers @@ -621,4 +670,4 @@ SourceAudioHalAsrc::Run(const std::vector& in) { return out; } -} // namespace le_audio +} // namespace bluetooth::audio::asrc diff --git a/system/bta/le_audio/audio_hal_client/audio_source_hal_asrc.h b/system/audio/asrc/asrc_resampler.h similarity index 80% rename from system/bta/le_audio/audio_hal_client/audio_source_hal_asrc.h rename to system/audio/asrc/asrc_resampler.h index f5595390a43650f950590e489e2a50116584d9a6..400c51c7be8fe3888da2a215bff98f580abaebb0 100644 --- a/system/bta/le_audio/audio_hal_client/audio_source_hal_asrc.h +++ b/system/audio/asrc/asrc_resampler.h @@ -21,7 +21,20 @@ #include #include -namespace le_audio { +namespace bluetooth::audio::asrc { + +class ClockHandler { + public: + virtual ~ClockHandler() = default; + virtual void OnEvent(uint32_t timestamp, int link_id, + int num_of_completed_packets) = 0; +}; + +class ClockSource { + public: + virtual ~ClockSource() = default; + virtual void Bind(ClockHandler*) = 0; +}; class SourceAudioHalAsrc { public: @@ -36,9 +49,9 @@ class SourceAudioHalAsrc { // `burst_delay_ms` helps to ensure that the synchronization with the // transmission intervals is done. - SourceAudioHalAsrc(int channels, int sample_rate, int bit_depth, - int interval_us, int num_burst_buffers = 2, - int burst_delay_ms = 500); + SourceAudioHalAsrc(std::shared_ptr clock_source, int channels, + int sample_rate, int bit_depth, int interval_us, + int num_burst_buffers = 2, int burst_delay_ms = 500); ~SourceAudioHalAsrc(); @@ -74,6 +87,7 @@ class SourceAudioHalAsrc { class ClockRecovery; std::unique_ptr clock_recovery_; + std::shared_ptr clock_source_; class Resampler; std::unique_ptr> resamplers_; @@ -89,4 +103,4 @@ class SourceAudioHalAsrc { friend class SourceAudioHalAsrcTest; }; -} // namespace le_audio +} // namespace bluetooth::audio::asrc diff --git a/system/bta/le_audio/audio_hal_client/asrc_resampler_test.cc b/system/audio/asrc/asrc_resampler_test.cc similarity index 83% rename from system/bta/le_audio/audio_hal_client/asrc_resampler_test.cc rename to system/audio/asrc/asrc_resampler_test.cc index 72af3e3b3e047db33eb42fc75e008190d4ffaca9..1b90e0a803180877cdd56769f4bd19c788ccbab5 100644 --- a/system/bta/le_audio/audio_hal_client/asrc_resampler_test.cc +++ b/system/audio/asrc/asrc_resampler_test.cc @@ -14,22 +14,22 @@ * limitations under the License. */ +#include "asrc_resampler.cc" + #include #include -#include "audio_source_hal_asrc.cc" - -namespace bluetooth::hal { -void NocpIsoClocker::Register(NocpIsoHandler*) {} -void NocpIsoClocker::Unregister() {} -} // namespace bluetooth::hal +namespace bluetooth::audio::asrc { -namespace le_audio { +class MockClockSource : public ClockSource { + void Bind(ClockHandler*) override {} +}; class SourceAudioHalAsrcTest : public SourceAudioHalAsrc { public: SourceAudioHalAsrcTest(int channels, int bitdepth) - : SourceAudioHalAsrc(channels, 48000, bitdepth, 10000) {} + : SourceAudioHalAsrc(std::make_unique(), channels, 48000, + bitdepth, 10000) {} template void Resample(double ratio, const T* in, size_t in_length, size_t* in_count, @@ -55,7 +55,7 @@ extern "C" void resample_i16(int channels, int bitdepth, double ratio, &out_count); if (out_count < out_length) - fprintf(stderr, "wrong output size: %zd:%zd %zd:%zd\n", in_length, in_count, + fprintf(stderr, "wrong output size: %zu:%zu %zu:%zu\n", in_length, in_count, out_length, out_count); return; @@ -71,10 +71,10 @@ extern "C" void resample_i32(int channels, int bitdepth, double ratio, &out_count); if (out_count < out_length) - fprintf(stderr, "wrong output size: %zd:%zd %zd:%zd\n", in_length, in_count, + fprintf(stderr, "wrong output size: %zu:%zu %zu:%zu\n", in_length, in_count, out_length, out_count); return; } -} // namespace le_audio +} // namespace bluetooth::audio::asrc diff --git a/system/bta/le_audio/audio_hal_client/asrc_resampler_test.config b/system/audio/asrc/asrc_resampler_test.config similarity index 100% rename from system/bta/le_audio/audio_hal_client/asrc_resampler_test.config rename to system/audio/asrc/asrc_resampler_test.config diff --git a/system/bta/le_audio/audio_hal_client/asrc_resampler_test.py b/system/audio/asrc/asrc_resampler_test.py similarity index 100% rename from system/bta/le_audio/audio_hal_client/asrc_resampler_test.py rename to system/audio/asrc/asrc_resampler_test.py diff --git a/system/bta/le_audio/audio_hal_client/asrc_tables.cc b/system/audio/asrc/asrc_tables.cc similarity index 99% rename from system/bta/le_audio/audio_hal_client/asrc_tables.cc rename to system/audio/asrc/asrc_tables.cc index 06eb501edc0e9d78ddf6496cf9feb356fbff863e..b8ecd01c3e8e9d172460a287ef0becbc769c49cd 100644 --- a/system/bta/le_audio/audio_hal_client/asrc_tables.cc +++ b/system/audio/asrc/asrc_tables.cc @@ -18,7 +18,7 @@ #include "asrc_tables.h" -namespace le_audio::asrc { +namespace bluetooth::audio::asrc { // clang-format off const ResamplerTables resampler_tables = { @@ -3619,4 +3619,4 @@ const ResamplerTables resampler_tables = { }; // clang-format off -} // namespace le_audio::asrc +} // namespace bluetooth::audio::asrc diff --git a/system/bta/le_audio/audio_hal_client/asrc_tables.h b/system/audio/asrc/asrc_tables.h similarity index 93% rename from system/bta/le_audio/audio_hal_client/asrc_tables.h rename to system/audio/asrc/asrc_tables.h index ab13da249ed76a678b9e30beeddb8b8381c38c9d..1af63f2e41b5fb59143a9b5344265e9b12c5deeb 100644 --- a/system/bta/le_audio/audio_hal_client/asrc_tables.h +++ b/system/audio/asrc/asrc_tables.h @@ -18,7 +18,7 @@ #include -namespace le_audio::asrc { +namespace bluetooth::audio::asrc { extern const struct ResamplerTables { static const int KERNEL_Q = 512; @@ -31,4 +31,4 @@ extern const struct ResamplerTables { } resampler_tables; -} // namespace le_audio::asrc +} // namespace bluetooth::audio::asrc diff --git a/system/bta/le_audio/audio_hal_client/asrc_tables.py b/system/audio/asrc/asrc_tables.py similarity index 97% rename from system/bta/le_audio/audio_hal_client/asrc_tables.py rename to system/audio/asrc/asrc_tables.py index e3dd208c2190895512f037019318464c469e8cd3..2bdc5797cdba72b1667f7f20515502a9eaac8c91 100755 --- a/system/bta/le_audio/audio_hal_client/asrc_tables.py +++ b/system/audio/asrc/asrc_tables.py @@ -66,7 +66,7 @@ print("""\ #include "asrc_tables.h" -namespace le_audio::asrc {{ +namespace bluetooth::audio::asrc {{ """.format(sys.argv[0])) # @@ -110,4 +110,4 @@ print(""" # print(""" -} // namespace le_audio::asrc""") +} // namespace bluetooth::audio::asrc""") diff --git a/system/audio_a2dp_hw/Android.bp b/system/audio_a2dp_hw/Android.bp index d75554928dba47d582be3a0cf12de12ed2037bcf..63b486093ab41b52a05a8fd76491e15f06b58190 100644 --- a/system/audio_a2dp_hw/Android.bp +++ b/system/audio_a2dp_hw/Android.bp @@ -38,6 +38,7 @@ cc_library { ], static_libs: [ "libbluetooth_gd", + "libbluetooth_log", "libosi", ], } @@ -52,6 +53,9 @@ cc_library_static { apex_available: [ "com.android.btservices", ], + static_libs: [ + "libbluetooth_log", + ], min_sdk_version: "29", } @@ -71,6 +75,7 @@ cc_test { ], static_libs: [ "audio.a2dp.default", + "libbluetooth_log", "libosi", ], min_sdk_version: "29", diff --git a/system/audio_bluetooth_hw/device_port_proxy.cc b/system/audio_bluetooth_hw/device_port_proxy.cc index 3e361b854278fc5f2a69c227b950d84eae494e40..85054204472a4b88522006731001200d0e484857 100644 --- a/system/audio_bluetooth_hw/device_port_proxy.cc +++ b/system/audio_bluetooth_hw/device_port_proxy.cc @@ -21,13 +21,13 @@ #include #include #include -#include #include #include +#include + #include "BluetoothAudioSessionControl.h" #include "stream_apis.h" -#include "utils.h" namespace android { namespace bluetooth { @@ -657,4 +657,4 @@ void BluetoothAudioPortAidl::SetState(BluetoothStreamState state) { } // namespace aidl } // namespace audio } // namespace bluetooth -} // namespace android \ No newline at end of file +} // namespace android diff --git a/system/audio_hal_interface/Android.bp b/system/audio_hal_interface/Android.bp index b25a88c6c7f21ecfc3089d087a3b728210e166a8..0a4814e6301a80254d9470ab710948eac35e08c1 100644 --- a/system/audio_hal_interface/Android.bp +++ b/system/audio_hal_interface/Android.bp @@ -15,7 +15,6 @@ cc_library_static { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/sys", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/stack/include", ], @@ -26,6 +25,7 @@ cc_library_static { "libutils", ], static_libs: [ + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libosi", @@ -40,12 +40,14 @@ cc_library_static { srcs: [ "a2dp_encoding.cc", "aidl/a2dp_encoding_aidl.cc", + "aidl/a2dp_provider_info.cc", "aidl/bluetooth_audio_port_impl.cc", "aidl/client_interface_aidl.cc", "aidl/codec_status_aidl.cc", "aidl/hearing_aid_software_encoding_aidl.cc", "aidl/hfp_client_interface_aidl.cc", "aidl/le_audio_software_aidl.cc", + "aidl/provider_info.cc", "hal_version_manager.cc", "hearing_aid_software_encoding.cc", "hfp_client_interface.cc", @@ -62,14 +64,15 @@ cc_library_static { "a2dp_encoding_host.cc", "hal_version_manager_host.cc", "hearing_aid_software_encoding_host.cc", + "hfp_client_interface_host.cc", "le_audio_software_host.cc", ], }, }, host_supported: true, cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", + "-Wthread-safety", ], apex_available: [ "com.android.btservices", @@ -83,7 +86,9 @@ cc_test { name: "bluetooth-test-audio-hal-interface", defaults: [ "fluoride_defaults", - "latest_android_hardware_bluetooth_audio_ndk_shared", + "latest_android_hardware_audio_common_ndk_static", + "latest_android_hardware_bluetooth_audio_ndk_static", + "latest_android_media_audio_common_types_ndk_static", ], include_dirs: [ "packages/modules/Bluetooth/system", @@ -94,8 +99,7 @@ cc_test { "hidl/client_interface_hidl_unittest.cc", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", + "libbase", "libbinder_ndk", "libcutils", "libfmq", @@ -104,13 +108,97 @@ cc_test { "libutils", ], static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-common", "libbt_shim_bridge", "libchrome", ], + header_libs: ["libbluetooth_headers"], +} + +// Bluetooth Audio Provider Info unit tests for target and host +cc_test { + name: "bluetooth-test-audio-hal-a2dp-provider-info", + test_suites: ["general-tests"], + defaults: [ + "fluoride_defaults", + "latest_android_hardware_audio_common_ndk_static", + "latest_android_hardware_bluetooth_audio_ndk_static", + "latest_android_media_audio_common_types_ndk_static", + "mts_defaults", + ], cflags: [ - "-DBUILDCFG", + "-DUNIT_TESTS", + "-Wno-unused-parameter", + ], + host_supported: true, + test_options: { + unit_test: true, + }, + include_dirs: [ + "packages/modules/Bluetooth/system", + "packages/modules/Bluetooth/system/gd", + "packages/modules/Bluetooth/system/stack/include", + ], + target: { + host: { + srcs: [ + ":BluetoothHostTestingLogCapture", + ], + }, + android: { + srcs: [ + ":BluetoothAndroidTestingLogCapture", + ], + }, + }, + sanitize: { + cfi: true, + scs: true, + address: true, + all_undefined: true, + integer_overflow: true, + diag: { + undefined: true, + }, + }, + srcs: [ + ":TestCommonMockFunctions", + ":TestMockAudioHalInterface", + "aidl/a2dp_provider_info.cc", + "aidl/a2dp_provider_info_unittest.cc", + ], + shared_libs: [ + "libbinder_ndk", + "libcutils", + "libhidlbase", + "liblog", + "libutils", + "server_configurable_flags", + ], + static_libs: [ + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.bluetooth@1.0", + "android.hardware.bluetooth@1.1", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", + "bluetooth_flags_c_lib", + "libbase", + "libbluetooth_log", + "libbt-common", + "libbt_shim_bridge", + "libchrome", + "libflagtest", + "libfmq", + "libgmock", + "libosi", ], header_libs: ["libbluetooth_headers"], } diff --git a/system/audio_hal_interface/BUILD.gn b/system/audio_hal_interface/BUILD.gn index 7c250ab864a2fe4d2782915f4409aa22c69949ad..2d56ef3356dbafc9dedaf50875d3599f823b44e9 100644 --- a/system/audio_hal_interface/BUILD.gn +++ b/system/audio_hal_interface/BUILD.gn @@ -24,12 +24,14 @@ static_library("audio_hal_interface") { include_dirs = [ "//bt/system/bta/include", "//bt/system/btif/include", - "//bt/system/internal_include", "//bt/system/stack/include", "//bt/system/gd/rust/shim", ] - configs += [ "//bt/system:target_defaults" ] + configs += [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/common", diff --git a/system/audio_hal_interface/a2dp_encoding.cc b/system/audio_hal_interface/a2dp_encoding.cc index a234b0aaa6eb89c8e219bd65c80a85c9a5f74f80..590ea1c70fc9dad7a01a9c3fd07e086338cd2f3e 100644 --- a/system/audio_hal_interface/a2dp_encoding.cc +++ b/system/audio_hal_interface/a2dp_encoding.cc @@ -16,6 +16,8 @@ #include "a2dp_encoding.h" +#include + #include "aidl/a2dp_encoding_aidl.h" #include "hal_version_manager.h" #include "hidl/a2dp_encoding_hidl.h" @@ -25,13 +27,15 @@ namespace audio { namespace a2dp { bool update_codec_offloading_capabilities( - const std::vector& framework_preference) { + const std::vector& framework_preference, + bool supports_a2dp_hw_offload_v2) { if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) { return hidl::a2dp::update_codec_offloading_capabilities( framework_preference); } - return aidl::a2dp::update_codec_offloading_capabilities(framework_preference); + return aidl::a2dp::update_codec_offloading_capabilities( + framework_preference, supports_a2dp_hw_offload_v2); } // Check if new bluetooth_audio is enabled @@ -155,6 +159,93 @@ bool is_opus_supported() { return false; } +namespace provider { + +// Lookup the codec info in the list of supported offloaded sink codecs. +std::optional sink_codec_index( + const uint8_t* p_codec_info) { + return (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::AIDL) + ? aidl::a2dp::provider::sink_codec_index(p_codec_info) + : std::nullopt; +} + +// Lookup the codec info in the list of supported offloaded source codecs. +std::optional source_codec_index( + const uint8_t* p_codec_info) { + return (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::AIDL) + ? aidl::a2dp::provider::source_codec_index(p_codec_info) + : std::nullopt; +} + +// Return the name of the codec which is assigned to the input index. +// The codec index must be in the ranges +// BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or +// BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX. +// Returns nullopt if the codec_index is not assigned or codec extensibility +// is not supported or enabled. +std::optional codec_index_str( + btav_a2dp_codec_index_t codec_index) { + return (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::AIDL) + ? aidl::a2dp::provider::codec_index_str(codec_index) + : std::nullopt; +} + +// Return true if the codec is supported for the session type +// A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH. +bool supports_codec(btav_a2dp_codec_index_t codec_index) { + return (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::AIDL) + ? aidl::a2dp::provider::supports_codec(codec_index) + : false; +} + +// Return the A2DP capabilities for the selected codec. +bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id, + uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) { + return (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::AIDL) + ? aidl::a2dp::provider::codec_info(codec_index, codec_id, + codec_info, codec_config) + : false; +} + +// Query the codec selection fromt the audio HAL. +// The HAL is expected to pick the best audio configuration based on the +// discovered remote SEPs. +std::optional get_a2dp_configuration( + RawAddress peer_address, + std::vector const& remote_seps, + btav_a2dp_codec_config_t const& user_preferences) { + return (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::AIDL) + ? aidl::a2dp::provider::get_a2dp_configuration( + peer_address, remote_seps, user_preferences) + : std::nullopt; +} + +// Query the codec parameters from the audio HAL. +// The HAL performs a two part validation: +// - check if the configuration is valid +// - check if the configuration is supported by the audio provider +// In case any of these checks fails, the corresponding A2DP +// status is returned. If the configuration is valid and supported, +// A2DP_OK is returned. +tA2DP_STATUS parse_a2dp_configuration( + btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_parameters, + std::vector* vendor_specific_parameters) { + return (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::AIDL) + ? aidl::a2dp::provider::parse_a2dp_configuration( + codec_index, codec_info, codec_parameters, + vendor_specific_parameters) + : A2DP_FAIL; +} + +} // namespace provider } // namespace a2dp } // namespace audio } // namespace bluetooth diff --git a/system/audio_hal_interface/a2dp_encoding.h b/system/audio_hal_interface/a2dp_encoding.h index 740855a3a3debe500c457b073a4c5744580192b6..f6205f69ac7566716d936e70e560ad9f380d8aef 100644 --- a/system/audio_hal_interface/a2dp_encoding.h +++ b/system/audio_hal_interface/a2dp_encoding.h @@ -16,9 +16,13 @@ #pragma once +#include +#include #include +#include "a2dp_error_codes.h" #include "audio_a2dp_hw/include/audio_a2dp_hw.h" +#include "avdt_api.h" #include "common/message_loop_thread.h" namespace bluetooth { @@ -26,7 +30,8 @@ namespace audio { namespace a2dp { bool update_codec_offloading_capabilities( - const std::vector& framework_preference); + const std::vector& framework_preference, + bool supports_a2dp_hw_offload_v2); // Check if new bluetooth_audio is enabled bool is_hal_enabled(); @@ -62,6 +67,98 @@ void set_remote_delay(uint16_t delay_report); // Check whether OPUS is supported bool is_opus_supported(); +// Definitions for A2DP hardware offload codec extensibility. +namespace provider { + +// Lookup the codec info in the list of supported offloaded sink codecs. +std::optional sink_codec_index( + const uint8_t* p_codec_info); + +// Lookup the codec info in the list of supported offloaded source codecs. +std::optional source_codec_index( + const uint8_t* p_codec_info); + +// Return the name of the codec which is assigned to the input index. +// The codec index must be in the ranges +// BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or +// BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX. +// Returns nullopt if the codec_index is not assigned or codec extensibility +// is not supported or enabled. +std::optional codec_index_str(btav_a2dp_codec_index_t codec_index); + +// Return true if the codec is supported for the session type +// A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH. +bool supports_codec(btav_a2dp_codec_index_t codec_index); + +// Return the A2DP capabilities for the selected codec. +// `codec_info` returns the OTA codec capabilities, `codec_config` +// returns the supported capabilities in a generic format. +bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id, + uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config); + +struct a2dp_configuration { + int remote_seid; + uint8_t codec_config[AVDT_CODEC_SIZE]; + btav_a2dp_codec_config_t codec_parameters; + std::vector vendor_specific_parameters; + + inline std::string toString() const { + std::ostringstream os; + os << "A2dpConfiguration{"; + os << "remote_seid: " << remote_seid; + os << ", codec_index: " << codec_parameters.codec_type; + os << ", codec_config: {"; + for (int i = 0; i < AVDT_CODEC_SIZE; i++) { + os << "0x" << std::hex << std::setw(2) << std::setfill('0') + << static_cast(codec_config[i]); + if (i != AVDT_CODEC_SIZE - 1) os << ","; + } + os << "}"; + os << "}"; + return os.str(); + } +}; + +struct a2dp_remote_capabilities { + int seid; + uint8_t const* capabilities; + + inline std::string toString() const { + std::ostringstream os; + os << "A2dpRemoteCapabilities{"; + os << "seid: " << seid; + os << ", capabilities: {"; + if (capabilities != nullptr) { + for (int i = 0; i < AVDT_CODEC_SIZE; i++) { + os << "0x" << std::hex << std::setw(2) << std::setfill('0') + << static_cast(capabilities[i]); + if (i != AVDT_CODEC_SIZE - 1) os << ","; + } + } + os << "}"; + os << "}"; + return os.str(); + } +}; + +// Query the codec selection fromt the audio HAL. +// The HAL is expected to pick the best audio configuration based on the +// discovered remote SEPs. +std::optional get_a2dp_configuration( + RawAddress peer_address, + std::vector const& remote_seps, + btav_a2dp_codec_config_t const& user_preferences); + +// Query the codec parameters from the audio HAL. +// The HAL is expected to parse the codec configuration +// received from the peer and decide whether accept +// the it or not. +tA2DP_STATUS parse_a2dp_configuration( + btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_parameters, + std::vector* vendor_specific_parameters); + +} // namespace provider } // namespace a2dp } // namespace audio } // namespace bluetooth diff --git a/system/audio_hal_interface/a2dp_encoding_host.cc b/system/audio_hal_interface/a2dp_encoding_host.cc index fcf8dc780f4fb75e4db79d177c7d23b3835dcefc..ec38b28f05d263f8c760557f97911f76eb5f2e30 100644 --- a/system/audio_hal_interface/a2dp_encoding_host.cc +++ b/system/audio_hal_interface/a2dp_encoding_host.cc @@ -20,11 +20,12 @@ #include #include +#include #include "a2dp_encoding.h" -#include "btif_a2dp_source.h" -#include "btif_av.h" -#include "btif_hf.h" +#include "btif/include/btif_a2dp_source.h" +#include "btif/include/btif_av.h" +#include "btif/include/btif_hf.h" #include "os/log.h" #include "stack/include/avdt_api.h" #include "types/raw_address.h" @@ -201,7 +202,8 @@ void set_remote_delay(uint16_t delay_report) { // Inform audio server about offloading codec; not used for now bool update_codec_offloading_capabilities( - const std::vector& framework_preference) { + const std::vector& framework_preference, + bool supports_a2dp_hw_offload_v2) { return false; } @@ -281,6 +283,67 @@ size_t read(uint8_t* p_buf, uint32_t len) { // Check if OPUS codec is supported bool is_opus_supported() { return true; } +namespace provider { + +// Lookup the codec info in the list of supported offloaded sink codecs. +std::optional sink_codec_index( + const uint8_t* p_codec_info) { + return std::nullopt; +} + +// Lookup the codec info in the list of supported offloaded source codecs. +std::optional source_codec_index( + const uint8_t* p_codec_info) { + return std::nullopt; +} + +// Return the name of the codec which is assigned to the input index. +// The codec index must be in the ranges +// BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or +// BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX. +// Returns nullopt if the codec_index is not assigned or codec extensibility +// is not supported or enabled. +std::optional codec_index_str( + btav_a2dp_codec_index_t codec_index) { + return std::nullopt; +} + +// Return true if the codec is supported for the session type +// A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH. +bool supports_codec(btav_a2dp_codec_index_t codec_index) { return false; } + +// Return the A2DP capabilities for the selected codec. +bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id, + uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) { + return false; +} + +// Query the codec selection fromt the audio HAL. +// The HAL is expected to pick the best audio configuration based on the +// discovered remote SEPs. +std::optional get_a2dp_configuration( + RawAddress peer_address, + std::vector const& remote_seps, + btav_a2dp_codec_config_t const& user_preferences) { + return std::nullopt; +} + +// Query the codec parameters from the audio HAL. +// The HAL performs a two part validation: +// - check if the configuration is valid +// - check if the configuration is supported by the audio provider +// In case any of these checks fails, the corresponding A2DP +// status is returned. If the configuration is valid and supported, +// A2DP_OK is returned. +tA2DP_STATUS parse_a2dp_configuration( + btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_parameters, + std::vector* vendor_specific_parameters) { + return A2DP_FAIL; +} + +} // namespace provider + } // namespace a2dp } // namespace audio } // namespace bluetooth diff --git a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc index 1300ac1c99b038887c46b4efd5987c7978587066..a929d802b8b9bfa0cf0add67480fcdeadc4fc47e 100644 --- a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc +++ b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc @@ -17,8 +17,12 @@ #include "a2dp_encoding_aidl.h" +#include + +#include "a2dp_provider_info.h" #include "a2dp_transport.h" #include "audio_aidl_interfaces.h" +#include "bta/av/bta_av_int.h" #include "btif/include/btif_common.h" #include "codec_status_aidl.h" #include "transport_instance.h" @@ -30,6 +34,7 @@ namespace a2dp { namespace { +using ::aidl::android::hardware::bluetooth::audio::A2dpStreamConfiguration; using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration; using ::aidl::android::hardware::bluetooth::audio::ChannelMode; using ::aidl::android::hardware::bluetooth::audio::CodecConfiguration; @@ -211,6 +216,11 @@ BluetoothAudioSinkClientInterface* software_hal_interface = nullptr; BluetoothAudioSinkClientInterface* offloading_hal_interface = nullptr; BluetoothAudioSinkClientInterface* active_hal_interface = nullptr; +// ProviderInfo for A2DP hardware offload encoding and decoding data paths, +// if supported by the HAL and enabled. nullptr if not supported +// or disabled. +std::unique_ptr<::bluetooth::audio::aidl::a2dp::ProviderInfo> provider_info; + // Save the value if the remote reports its delay before this interface is // initialized uint16_t remote_delay = 0; @@ -238,6 +248,39 @@ BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) { } } +/// Return the MTU for the active peer audio connection. +static uint16_t a2dp_get_peer_mtu(btav_a2dp_codec_index_t codec_index, + uint8_t const* codec_info) { + RawAddress peer_addr = btif_av_source_active_peer(); + tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; + bta_av_co_get_peer_params(peer_addr, &peer_params); + uint16_t peer_mtu = peer_params.peer_mtu; + uint16_t effective_mtu = bta_av_co_get_encoder_effective_frame_size(); + + if (effective_mtu > 0 && effective_mtu < peer_mtu) { + peer_mtu = effective_mtu; + } + + // b/188020925 + // When SBC headsets report middle quality bitpool under a larger MTU, we + // reduce the packet size to prevent the hardware encoder from putting too + // many frames in one packet. + if (codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_SBC && + codec_info[2] /* maxBitpool */ <= A2DP_SBC_BITPOOL_MIDDLE_QUALITY) { + peer_mtu = MAX_2MBPS_AVDTP_MTU; + } + + // b/177205770 + // Fix the MTU value not to be greater than an AVDTP packet, so the data + // encoded by A2DP hardware encoder can be fitted into one AVDTP packet + // without fragmented + if (peer_mtu > MAX_3MBPS_AVDTP_MTU) { + peer_mtu = MAX_3MBPS_AVDTP_MTU; + } + + return peer_mtu; +} + bool a2dp_get_selected_hal_codec_config(CodecConfiguration* codec_config) { A2dpCodecConfig* a2dp_config = bta_av_get_a2dp_current_codec(); if (a2dp_config == nullptr) { @@ -341,7 +384,11 @@ bool is_hal_force_disabled() { } // namespace bool update_codec_offloading_capabilities( - const std::vector& framework_preference) { + const std::vector& framework_preference, + bool supports_a2dp_hw_offload_v2) { + /* Load the provider information if supported by the HAL. */ + provider_info = ::bluetooth::audio::aidl::a2dp::ProviderInfo::GetProviderInfo( + supports_a2dp_hw_offload_v2); return ::bluetooth::audio::aidl::codec::UpdateOffloadingCapabilities( framework_preference); } @@ -358,10 +405,43 @@ bool is_hal_offloading() { SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH; } +// Opens the HAL client interface of the specified session type and check +// that is is valid. Returns nullptr if the client interface did not open +// properly. +static BluetoothAudioSinkClientInterface* new_hal_interface( + SessionType session_type) { + auto a2dp_transport = new A2dpTransport(session_type); + auto hal_interface = new BluetoothAudioSinkClientInterface(a2dp_transport); + if (hal_interface->IsValid()) { + return hal_interface; + } else { + LOG(ERROR) << __func__ << "BluetoothAudio HAL for a2dp is invalid"; + delete a2dp_transport; + delete hal_interface; + return nullptr; + } +} + +/// Delete the selected HAL client interface. +static void delete_hal_interface( + BluetoothAudioSinkClientInterface* hal_interface) { + if (hal_interface == nullptr) { + return; + } + auto a2dp_transport = + static_cast(hal_interface->GetTransportInstance()); + delete a2dp_transport; + delete hal_interface; +} + // Initialize BluetoothAudio HAL: openProvider -bool init(bluetooth::common::MessageLoopThread* message_loop) { +bool init(bluetooth::common::MessageLoopThread* /*message_loop*/) { LOG(INFO) << __func__; + if (software_hal_interface != nullptr) { + return true; + } + if (is_hal_force_disabled()) { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled"; return false; @@ -373,34 +453,19 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) { return false; } - auto a2dp_sink = - new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH); software_hal_interface = - new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop); - if (!software_hal_interface->IsValid()) { - LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!"; - delete software_hal_interface; - software_hal_interface = nullptr; - delete a2dp_sink; + new_hal_interface(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH); + if (software_hal_interface == nullptr) { return false; } - if (btif_av_is_a2dp_offload_enabled()) { - a2dp_sink = - new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH); + if (btif_av_is_a2dp_offload_enabled() && + offloading_hal_interface == nullptr) { offloading_hal_interface = - new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop); - if (!offloading_hal_interface->IsValid()) { - LOG(FATAL) << __func__ - << ": BluetoothAudio HAL for A2DP offloading is invalid?!"; - delete offloading_hal_interface; - offloading_hal_interface = nullptr; - delete a2dp_sink; - a2dp_sink = static_cast( - software_hal_interface->GetTransportInstance()); - delete software_hal_interface; + new_hal_interface(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH); + if (offloading_hal_interface == nullptr) { + delete_hal_interface(software_hal_interface); software_hal_interface = nullptr; - delete a2dp_sink; return false; } } @@ -449,11 +514,63 @@ bool setup_codec() { LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled"; return false; } + + A2dpCodecConfig* a2dp_config = bta_av_get_a2dp_current_codec(); + if (a2dp_config == nullptr) { + LOG(ERROR) << __func__ << ": the current codec is not configured"; + return false; + } + + if (provider::supports_codec(a2dp_config->codecIndex())) { + // The codec is supported in the provider info (AIDL v4). + // In this case, the codec is offloaded, and the configuration passed + // as A2dpStreamConfiguration to the UpdateAudioConfig() interface + // method. + uint8_t codec_info[AVDT_CODEC_SIZE]; + A2dpStreamConfiguration a2dp_stream_configuration; + + a2dp_config->copyOutOtaCodecConfig(codec_info); + a2dp_stream_configuration.peerMtu = + a2dp_get_peer_mtu(a2dp_config->codecIndex(), codec_info); + a2dp_stream_configuration.codecId = + provider_info->GetCodec(a2dp_config->codecIndex()).value()->id; + + size_t parameters_start = 0; + size_t parameters_end = 0; + switch (a2dp_config->codecIndex()) { + case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: + case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC: + parameters_start = 3; + parameters_end = 1 + codec_info[0]; + break; + default: + parameters_start = 9; + parameters_end = 1 + codec_info[0]; + break; + } + + a2dp_stream_configuration.configuration.insert( + a2dp_stream_configuration.configuration.end(), + codec_info + parameters_start, codec_info + parameters_end); + + if (!is_hal_offloading()) { + LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Hardware"; + end_session(); + active_hal_interface = offloading_hal_interface; + } + + return active_hal_interface->UpdateAudioConfig( + AudioConfiguration(a2dp_stream_configuration)); + } + + // Fallback to legacy offloading path. CodecConfiguration codec_config{}; + if (!a2dp_get_selected_hal_codec_config(&codec_config)) { LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration"; return false; } + bool should_codec_offloading = bluetooth::audio::aidl::codec::IsCodecOffloadingEnabled(codec_config); if (should_codec_offloading && !is_hal_offloading()) { @@ -478,6 +595,7 @@ bool setup_codec() { } audio_config.set(pcm_config); } + return active_hal_interface->UpdateAudioConfig(audio_config); } @@ -587,6 +705,326 @@ void set_low_latency_mode_allowed(bool allowed) { active_hal_interface->SetAllowedLatencyModes(latency_modes); } +/*** + * Lookup the codec info in the list of supported offloaded sink codecs. + ***/ +std::optional provider::sink_codec_index( + const uint8_t* p_codec_info) { + return provider_info ? provider_info->SinkCodecIndex(p_codec_info) + : std::nullopt; +} + +/*** + * Lookup the codec info in the list of supported offloaded source codecs. + ***/ +std::optional provider::source_codec_index( + const uint8_t* p_codec_info) { + return provider_info ? provider_info->SourceCodecIndex(p_codec_info) + : std::nullopt; +} + +/*** + * Return the name of the codec which is assigned to the input index. + * The codec index must be in the ranges + * BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or + * BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX. + * Returns nullopt if the codec_index is not assigned or codec extensibility + * is not supported or enabled. + ***/ +std::optional provider::codec_index_str( + btav_a2dp_codec_index_t codec_index) { + return provider_info ? provider_info->CodecIndexStr(codec_index) + : std::nullopt; +} + +/*** + * Return true if the codec is supported for the session type + * A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH. + ***/ +bool provider::supports_codec(btav_a2dp_codec_index_t codec_index) { + return provider_info ? provider_info->SupportsCodec(codec_index) : false; +} + +/*** + * Return the A2DP capabilities for the selected codec. + ***/ +bool provider::codec_info(btav_a2dp_codec_index_t codec_index, + uint64_t* codec_id, uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_config) { + return provider_info ? provider_info->CodecCapabilities( + codec_index, codec_id, codec_info, codec_config) + : false; +} + +static btav_a2dp_codec_channel_mode_t convert_channel_mode( + ChannelMode channel_mode) { + switch (channel_mode) { + case ChannelMode::MONO: + return BTAV_A2DP_CODEC_CHANNEL_MODE_MONO; + case ChannelMode::STEREO: + return BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO; + default: + LOG(ERROR) << "unknown channel mode"; + break; + } + return BTAV_A2DP_CODEC_CHANNEL_MODE_NONE; +} + +static btav_a2dp_codec_sample_rate_t convert_sampling_frequency_hz( + int sampling_frequency_hz) { + switch (sampling_frequency_hz) { + case 44100: + return BTAV_A2DP_CODEC_SAMPLE_RATE_44100; + case 48000: + return BTAV_A2DP_CODEC_SAMPLE_RATE_48000; + case 88200: + return BTAV_A2DP_CODEC_SAMPLE_RATE_88200; + case 96000: + return BTAV_A2DP_CODEC_SAMPLE_RATE_96000; + case 176400: + return BTAV_A2DP_CODEC_SAMPLE_RATE_176400; + case 192000: + return BTAV_A2DP_CODEC_SAMPLE_RATE_192000; + case 16000: + return BTAV_A2DP_CODEC_SAMPLE_RATE_16000; + case 24000: + return BTAV_A2DP_CODEC_SAMPLE_RATE_24000; + default: + LOG(ERROR) << "unknown sampling frequency " << sampling_frequency_hz; + break; + } + return BTAV_A2DP_CODEC_SAMPLE_RATE_NONE; +} + +static btav_a2dp_codec_bits_per_sample_t convert_bitdepth(int bitdepth) { + switch (bitdepth) { + case 16: + return BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16; + case 24: + return BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24; + case 32: + return BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32; + default: + LOG(ERROR) << "unknown bit depth " << bitdepth; + break; + } + return BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE; +} + +/*** + * Query the codec selection fromt the audio HAL. + * The HAL is expected to pick the best audio configuration based on the + * discovered remote SEPs. + ***/ +std::optional<::bluetooth::audio::a2dp::provider::a2dp_configuration> +provider::get_a2dp_configuration( + RawAddress peer_address, + std::vector< + ::bluetooth::audio::a2dp::provider::a2dp_remote_capabilities> const& + remote_seps, + btav_a2dp_codec_config_t const& user_preferences) { + if (provider_info == nullptr) { + return std::nullopt; + } + + using ::aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities; + using ::aidl::android::hardware::bluetooth::audio::CodecId; + + // Convert the remote audio capabilities to the exchange format used + // by the HAL. + std::vector a2dp_remote_capabilities; + for (auto const& sep : remote_seps) { + size_t capabilities_start = 0; + size_t capabilities_end = 0; + CodecId id; + switch (sep.capabilities[2]) { + case A2DP_MEDIA_CT_SBC: + case A2DP_MEDIA_CT_AAC: { + id = CodecId::make( + static_cast(sep.capabilities[2])); + capabilities_start = 3; + capabilities_end = 1 + sep.capabilities[0]; + break; + } + case A2DP_MEDIA_CT_NON_A2DP: { + uint32_t vendor_id = + (static_cast(sep.capabilities[3]) << 0) | + (static_cast(sep.capabilities[4]) << 8) | + (static_cast(sep.capabilities[5]) << 16) | + (static_cast(sep.capabilities[6]) << 24); + uint16_t codec_id = (static_cast(sep.capabilities[7]) << 0) | + (static_cast(sep.capabilities[8]) << 8); + id = CodecId::make( + CodecId::Vendor({.id = (int32_t)vendor_id, .codecId = codec_id})); + capabilities_start = 9; + capabilities_end = 1 + sep.capabilities[0]; + break; + } + default: + continue; + } + A2dpRemoteCapabilities& capabilities = + a2dp_remote_capabilities.emplace_back(); + capabilities.seid = sep.seid; + capabilities.id = id; + capabilities.capabilities.insert(capabilities.capabilities.end(), + sep.capabilities + capabilities_start, + sep.capabilities + capabilities_end); + } + + // Convert the user preferences into a configuration hint. + A2dpConfigurationHint hint; + hint.bdAddr = peer_address.ToArray(); + auto& codecParameters = hint.codecParameters.emplace(); + switch (user_preferences.channel_mode) { + case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO: + codecParameters.channelMode = ChannelMode::MONO; + break; + case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO: + codecParameters.channelMode = ChannelMode::STEREO; + break; + default: + break; + } + switch (user_preferences.sample_rate) { + case BTAV_A2DP_CODEC_SAMPLE_RATE_44100: + codecParameters.samplingFrequencyHz = 44100; + break; + case BTAV_A2DP_CODEC_SAMPLE_RATE_48000: + codecParameters.samplingFrequencyHz = 48000; + break; + case BTAV_A2DP_CODEC_SAMPLE_RATE_88200: + codecParameters.samplingFrequencyHz = 88200; + break; + case BTAV_A2DP_CODEC_SAMPLE_RATE_96000: + codecParameters.samplingFrequencyHz = 96000; + break; + case BTAV_A2DP_CODEC_SAMPLE_RATE_176400: + codecParameters.samplingFrequencyHz = 176400; + break; + case BTAV_A2DP_CODEC_SAMPLE_RATE_192000: + codecParameters.samplingFrequencyHz = 192000; + break; + case BTAV_A2DP_CODEC_SAMPLE_RATE_16000: + codecParameters.samplingFrequencyHz = 16000; + break; + case BTAV_A2DP_CODEC_SAMPLE_RATE_24000: + codecParameters.samplingFrequencyHz = 24000; + break; + default: + break; + } + switch (user_preferences.bits_per_sample) { + case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16: + codecParameters.bitdepth = 16; + break; + case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24: + codecParameters.bitdepth = 24; + break; + case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32: + codecParameters.bitdepth = 32; + break; + default: + break; + } + + LOG(INFO) << __func__; + LOG(INFO) << "remote capabilities:"; + for (auto const& sep : a2dp_remote_capabilities) { + LOG(INFO) << " - " << sep.toString(); + } + LOG(INFO) << "hint: " << hint.toString(); + + if (offloading_hal_interface == nullptr && + (offloading_hal_interface = new_hal_interface( + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH)) == nullptr) { + LOG(ERROR) << __func__ << "the offloading HAL interface cannot be opened"; + return std::nullopt; + } + + // Invoke the HAL GetAdpCapabilities method with the + // remote capabilities. + auto result = offloading_hal_interface->GetA2dpConfiguration( + a2dp_remote_capabilities, hint); + + // Convert the result configuration back to the stack's format. + if (!result.has_value()) { + LOG(INFO) << __func__ << ": provider cannot resolve the a2dp configuration"; + return std::nullopt; + } + + LOG(INFO) << __func__ << ": provider selected " << result->toString(); + + ::bluetooth::audio::a2dp::provider::a2dp_configuration a2dp_configuration; + a2dp_configuration.remote_seid = result->remoteSeid; + a2dp_configuration.vendor_specific_parameters = + result->parameters.vendorSpecificParameters; + ProviderInfo::BuildCodecCapabilities(result->id, result->configuration, + a2dp_configuration.codec_config); + a2dp_configuration.codec_parameters.codec_type = + provider_info->SourceCodecIndex(result->id).value(); + a2dp_configuration.codec_parameters.channel_mode = + convert_channel_mode(result->parameters.channelMode); + a2dp_configuration.codec_parameters.sample_rate = + convert_sampling_frequency_hz(result->parameters.samplingFrequencyHz); + a2dp_configuration.codec_parameters.bits_per_sample = + convert_bitdepth(result->parameters.bitdepth); + + return std::make_optional(a2dp_configuration); +} + +/*** + * Query the codec parameters from the audio HAL. + * The HAL is expected to parse the codec configuration + * received from the peer and decide whether accept + * the it or not. + ***/ +tA2DP_STATUS provider::parse_a2dp_configuration( + btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_parameters, + std::vector* vendor_specific_parameters) { + std::vector configuration; + CodecParameters codec_parameters_aidl; + + if (provider_info == nullptr) { + LOG(ERROR) << __func__ << "provider_info is null"; + return A2DP_FAIL; + } + + auto codec = provider_info->GetCodec(codec_index); + if (!codec.has_value()) { + LOG(ERROR) << __func__ << ": codec index not recognized by provider"; + return A2DP_FAIL; + } + + std::copy(codec_info, codec_info + AVDT_CODEC_SIZE, + std::back_inserter(configuration)); + + auto a2dp_status = offloading_hal_interface->ParseA2dpConfiguration( + codec.value()->id, configuration, &codec_parameters_aidl); + + if (!a2dp_status.has_value()) { + LOG(ERROR) << __func__ << ": provider failed to parse configuration"; + return A2DP_FAIL; + } + + if (codec_parameters != nullptr) { + codec_parameters->channel_mode = + convert_channel_mode(codec_parameters_aidl.channelMode); + codec_parameters->sample_rate = convert_sampling_frequency_hz( + codec_parameters_aidl.samplingFrequencyHz); + codec_parameters->bits_per_sample = + convert_bitdepth(codec_parameters_aidl.bitdepth); + } + + if (vendor_specific_parameters != nullptr) { + *vendor_specific_parameters = + codec_parameters_aidl.vendorSpecificParameters; + } + + return static_cast(a2dp_status.value()); +} + } // namespace a2dp } // namespace aidl } // namespace audio diff --git a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.h b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.h index a49c767589bbaf4950202bf4a0a19186aae34ca0..bc615790e5ed3b88157ce8f1ae988c579eabf9fa 100644 --- a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.h +++ b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.h @@ -18,14 +18,15 @@ #include +#include "a2dp_encoding.h" #include "a2dp_sbc_constants.h" #include "audio_a2dp_hw/include/audio_a2dp_hw.h" -#include "btif_a2dp_source.h" -#include "btif_av.h" -#include "btif_av_co.h" -#include "btif_hf.h" +#include "btif/include/btif_a2dp_source.h" +#include "btif/include/btif_av.h" +#include "btif/include/btif_av_co.h" +#include "btif/include/btif_hf.h" #include "common/message_loop_thread.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" #include "types/raw_address.h" @@ -35,7 +36,8 @@ namespace aidl { namespace a2dp { bool update_codec_offloading_capabilities( - const std::vector& framework_preference); + const std::vector& framework_preference, + bool supports_a2dp_hw_offload_v2); /*** * Check if new bluetooth_audio is enabled @@ -85,6 +87,71 @@ 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 provider { + +/*** + * Lookup the codec info in the list of supported offloaded sink codecs. + * Should not be called before update_codec_offloading_capabilities. + ***/ +std::optional sink_codec_index( + const uint8_t* p_codec_info); + +/*** + * Lookup the codec info in the list of supported offloaded source codecs. + * Should not be called before update_codec_offloading_capabilities. + ***/ +std::optional source_codec_index( + const uint8_t* p_codec_info); + +/*** + * Return the name of the codec which is assigned to the input index. + * The codec index must be in the ranges + * BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or + * BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX. + * Returns nullopt if the codec_index is not assigned or codec extensibility + * is not supported or enabled. + * Should not be called before update_codec_offloading_capabilities. + ***/ +std::optional codec_index_str(btav_a2dp_codec_index_t codec_index); + +/*** + * Return true if the codec is supported for the session type + * A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH. + ***/ +bool supports_codec(btav_a2dp_codec_index_t codec_index); + +/*** + * Return the A2DP capabilities for the selected codec. + ***/ +bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id, + uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config); + +/*** + * Query the codec selection fromt the audio HAL. + * The HAL is expected to pick the best audio configuration based on the + * discovered remote SEPs. + ***/ +std::optional<::bluetooth::audio::a2dp::provider::a2dp_configuration> +get_a2dp_configuration( + RawAddress peer_address, + std::vector< + ::bluetooth::audio::a2dp::provider::a2dp_remote_capabilities> const& + remote_seps, + btav_a2dp_codec_config_t const& user_preferences); + +/*** + * Query the codec parameters from the audio HAL. + * The HAL is expected to parse the codec configuration + * received from the peer and decide whether accept + * the it or not. + ***/ +uint8_t parse_a2dp_configuration( + btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_parameters, + std::vector* vendor_specific_parameters); + +} // namespace provider } // namespace a2dp } // namespace aidl } // namespace audio diff --git a/system/audio_hal_interface/aidl/a2dp_provider_info.cc b/system/audio_hal_interface/aidl/a2dp_provider_info.cc new file mode 100644 index 0000000000000000000000000000000000000000..f7ecca871e5815e0e830ca8bd5fe1b0ca158874f --- /dev/null +++ b/system/audio_hal_interface/aidl/a2dp_provider_info.cc @@ -0,0 +1,468 @@ +/* + * Copyright 2023 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 "AIDLA2dpProviderInfo" + +#include "a2dp_provider_info.h" + +#include +#include + +#include +#include + +#include "a2dp_codec_api.h" +#include "a2dp_constants.h" +#include "a2dp_vendor.h" +#include "a2dp_vendor_aptx_constants.h" +#include "a2dp_vendor_aptx_hd_constants.h" +#include "a2dp_vendor_ldac_constants.h" +#include "a2dp_vendor_opus_constants.h" +#include "client_interface_aidl.h" +#include "os/log.h" + +namespace bluetooth::audio::aidl::a2dp { + +using ::aidl::android::hardware::bluetooth::audio::ChannelMode; +using ::aidl::android::hardware::bluetooth::audio::CodecId; +using ::aidl::android::hardware::bluetooth::audio::CodecInfo; +using ::aidl::android::hardware::bluetooth::audio:: + IBluetoothAudioProviderFactory; +using ::aidl::android::hardware::bluetooth::audio::SessionType; + +/*** + * Reads the provider information from the HAL. + * May return nullptr if the HAL does not implement + * getProviderInfo, or if the feature flag for codec + * extensibility is disabled. + ***/ +std::unique_ptr ProviderInfo::GetProviderInfo( + bool supports_a2dp_hw_offload_v2) { + if (!IS_FLAG_ENABLED(a2dp_offload_codec_extensibility)) { + LOG(INFO) << "a2dp offload codec extensibility is disabled;" + << " not going to load the ProviderInfo"; + return nullptr; + } + + if (!supports_a2dp_hw_offload_v2) { + LOG(INFO) << "a2dp hw offload v2 is not supported by the controller;" + << " not going to load the ProviderInfo"; + return nullptr; + } + + auto source_provider_info = BluetoothAudioClientInterface::GetProviderInfo( + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH, nullptr); + + auto sink_provider_info = BluetoothAudioClientInterface::GetProviderInfo( + SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH, nullptr); + + if (!source_provider_info.has_value() && !sink_provider_info.has_value()) { + LOG(INFO) << "a2dp offload codec extensibility is enabled;" + << " but the provider info is empty"; + return nullptr; + } + + std::vector source_codecs; + std::vector sink_codecs; + + if (source_provider_info.has_value()) { + source_codecs = std::move(source_provider_info->codecInfos); + } + + if (sink_provider_info.has_value()) { + sink_codecs = std::move(sink_provider_info->codecInfos); + } + + LOG(INFO) << "successfully loaded provider info"; + return std::make_unique(std::move(source_codecs), + std::move(sink_codecs)); +} + +/*** + * Returns the codec with the selected index if supported + * by the provider. + ***/ +std::optional ProviderInfo::GetCodec( + btav_a2dp_codec_index_t codec_index) const { + auto it = assigned_codec_indexes.find(codec_index); + return it == assigned_codec_indexes.end() ? std::nullopt + : std::make_optional(it->second); +} + +/*** + * Return the assigned source codec index if the codec + * matches a known codec, or pick a new codec index starting from + * ext_index. + ***/ +static std::optional assignSourceCodecIndex( + CodecInfo const& codec, btav_a2dp_codec_index_t* ext_index) { + switch (codec.id.getTag()) { + case CodecId::core: + default: + return std::nullopt; + case CodecId::a2dp: + switch (codec.id.get()) { + case CodecId::A2dp::SBC: + return BTAV_A2DP_CODEC_INDEX_SOURCE_SBC; + case CodecId::A2dp::AAC: + return BTAV_A2DP_CODEC_INDEX_SOURCE_AAC; + default: + return std::nullopt; + } + break; + case CodecId::vendor: { + int vendor_id = codec.id.get().id; + int codec_id = codec.id.get().codecId; + + /* match know vendor codecs */ + if (vendor_id == A2DP_APTX_VENDOR_ID && + codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) { + return BTAV_A2DP_CODEC_INDEX_SOURCE_APTX; + } + if (vendor_id == A2DP_APTX_HD_VENDOR_ID && + codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) { + return BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD; + } + if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) { + return BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC; + } + if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) { + return BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS; + } + + /* out of extension codec indexes */ + if (*ext_index >= BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX) { + LOG(ERROR) << "unable to assign a source codec index for vendorId=" + << vendor_id << ", codecId=" << codec_id; + } + + /* assign a new codec index for the + unknown vendor codec */ + return *(ext_index++); + } + } +} + +/*** + * Return the assigned source codec index if the codec + * matches a known codec, or pick a new codec index starting from + * ext_index. + ***/ +static std::optional assignSinkCodecIndex( + CodecInfo const& codec, btav_a2dp_codec_index_t* ext_index) { + switch (codec.id.getTag()) { + case CodecId::core: + default: + return std::nullopt; + case CodecId::a2dp: + switch (codec.id.get()) { + case CodecId::A2dp::SBC: + return BTAV_A2DP_CODEC_INDEX_SINK_SBC; + case CodecId::A2dp::AAC: + return BTAV_A2DP_CODEC_INDEX_SINK_AAC; + default: + return std::nullopt; + } + break; + case CodecId::vendor: { + int vendor_id = codec.id.get().id; + int codec_id = codec.id.get().codecId; + + /* match know vendor codecs */ + if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) { + return BTAV_A2DP_CODEC_INDEX_SINK_LDAC; + } + if (vendor_id == A2DP_OPUS_VENDOR_ID && codec_id == A2DP_OPUS_CODEC_ID) { + return BTAV_A2DP_CODEC_INDEX_SINK_OPUS; + } + + /* out of extension codec indexes */ + if (*ext_index >= BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX) { + LOG(ERROR) << "unable to assign a sink codec index for vendorId=" + << vendor_id << ", codecId=" << codec_id; + } + + /* assign a new codec index for the + unknown vendor codec */ + return *(ext_index++); + } + } +} + +ProviderInfo::ProviderInfo(std::vector source_codecs, + std::vector sink_codecs) + : source_codecs(std::move(source_codecs)), + sink_codecs(std::move(sink_codecs)) { + btav_a2dp_codec_index_t ext_source_index = + BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN; + for (size_t i = 0; i < this->source_codecs.size(); i++) { + auto& codec = this->source_codecs[i]; + LOG(INFO) << "supported source codec " << codec.name; + auto index = assignSourceCodecIndex(codec, &ext_source_index); + if (index.has_value()) { + assigned_codec_indexes[index.value()] = &codec; + } + } + + btav_a2dp_codec_index_t ext_sink_index = BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN; + for (size_t i = 0; i < this->sink_codecs.size(); i++) { + auto& codec = this->sink_codecs[i]; + LOG(INFO) << "supports sink codec " << codec.name; + auto index = assignSinkCodecIndex(codec, &ext_sink_index); + if (index.has_value()) { + assigned_codec_indexes[index.value()] = &codec; + } + } +} + +std::optional ProviderInfo::SourceCodecIndex( + CodecId const& codec_id) const { + for (auto const& [index, codec] : assigned_codec_indexes) { + if (codec->id == codec_id && index >= BTAV_A2DP_CODEC_INDEX_SOURCE_MIN && + index < BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX) { + return index; + } + } + return std::nullopt; +} + +std::optional ProviderInfo::SourceCodecIndex( + uint32_t vendor_id, uint16_t codec_id) const { + for (auto const& [index, codec] : assigned_codec_indexes) { + if (codec->id.getTag() == CodecId::vendor && + codec->id.get().id == (int)vendor_id && + codec->id.get().codecId == codec_id && + index >= BTAV_A2DP_CODEC_INDEX_SOURCE_MIN && + index < BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX) { + return index; + } + } + return std::nullopt; +} + +std::optional ProviderInfo::SourceCodecIndex( + uint8_t const* codec_info) const { + LOG_ASSERT(codec_info != nullptr) << "codec_info is unexpectedly null"; + auto codec_type = A2DP_GetCodecType(codec_info); + switch (codec_type) { + case A2DP_MEDIA_CT_SBC: { + return SourceCodecIndex(CodecId::A2dp(CodecId::A2dp::SBC)); + } + case A2DP_MEDIA_CT_AAC: { + return SourceCodecIndex(CodecId::A2dp(CodecId::A2dp::AAC)); + } + case A2DP_MEDIA_CT_NON_A2DP: { + uint32_t vendor_id = A2DP_VendorCodecGetVendorId(codec_info); + uint16_t codec_id = A2DP_VendorCodecGetCodecId(codec_info); + return SourceCodecIndex(vendor_id, codec_id); + } + default: { + return std::nullopt; + } + } +} + +std::optional ProviderInfo::SinkCodecIndex( + CodecId const& codec_id) const { + for (auto const& [index, codec] : assigned_codec_indexes) { + if (codec->id == codec_id && index >= BTAV_A2DP_CODEC_INDEX_SINK_MIN && + index < BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX) { + return index; + } + } + return std::nullopt; +} + +std::optional ProviderInfo::SinkCodecIndex( + uint32_t vendor_id, uint16_t codec_id) const { + for (auto const& [index, codec] : assigned_codec_indexes) { + if (codec->id.getTag() == CodecId::vendor && + codec->id.get().id == (int)vendor_id && + codec->id.get().codecId == codec_id && + index >= BTAV_A2DP_CODEC_INDEX_SINK_MIN && + index < BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX) { + return index; + } + } + return std::nullopt; +} + +std::optional ProviderInfo::SinkCodecIndex( + uint8_t const* codec_info) const { + LOG_ASSERT(codec_info != nullptr) << "codec_info is unexpectedly null"; + auto codec_type = A2DP_GetCodecType(codec_info); + switch (codec_type) { + case A2DP_MEDIA_CT_SBC: { + return SinkCodecIndex(CodecId::A2dp(CodecId::A2dp::SBC)); + } + case A2DP_MEDIA_CT_AAC: { + return SinkCodecIndex(CodecId::A2dp(CodecId::A2dp::AAC)); + } + case A2DP_MEDIA_CT_NON_A2DP: { + uint32_t vendor_id = A2DP_VendorCodecGetVendorId(codec_info); + uint16_t codec_id = A2DP_VendorCodecGetCodecId(codec_info); + return SinkCodecIndex(vendor_id, codec_id); + } + default: { + return std::nullopt; + } + } +} + +std::optional ProviderInfo::CodecIndexStr( + btav_a2dp_codec_index_t codec_index) const { + auto it = assigned_codec_indexes.find(codec_index); + return it != assigned_codec_indexes.end() + ? std::make_optional(it->second->name.c_str()) + : std::nullopt; +} + +bool ProviderInfo::SupportsCodec(btav_a2dp_codec_index_t codec_index) const { + return assigned_codec_indexes.find(codec_index) != + assigned_codec_indexes.end(); +} + +bool ProviderInfo::BuildCodecCapabilities( + CodecId const& codec_id, std::vector const& capabilities, + uint8_t* codec_info) { + switch (codec_id.getTag()) { + case CodecId::a2dp: { + auto id = codec_id.get(); + codec_info[0] = 2 + capabilities.size(); + codec_info[1] = AVDT_MEDIA_TYPE_AUDIO << 4; + codec_info[2] = static_cast(id); + memcpy(codec_info + 3, capabilities.data(), capabilities.size()); + return true; + } + case CodecId::vendor: { + auto id = codec_id.get(); + uint32_t vendor_id = static_cast(id.id); + uint16_t codec_id = static_cast(id.codecId); + codec_info[0] = 8 + capabilities.size(); + codec_info[1] = AVDT_MEDIA_TYPE_AUDIO << 4; + codec_info[2] = A2DP_MEDIA_CT_NON_A2DP; + codec_info[3] = static_cast(vendor_id >> 0); + codec_info[4] = static_cast(vendor_id >> 8); + codec_info[5] = static_cast(vendor_id >> 16); + codec_info[6] = static_cast(vendor_id >> 24); + codec_info[7] = static_cast(codec_id >> 0); + codec_info[8] = static_cast(codec_id >> 8); + memcpy(codec_info + 9, capabilities.data(), capabilities.size()); + return true; + } + case CodecId::core: + default: + break; + } + return false; +} + +bool ProviderInfo::CodecCapabilities( + btav_a2dp_codec_index_t codec_index, uint64_t* codec_id, + uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) const { + auto it = assigned_codec_indexes.find(codec_index); + if (it == assigned_codec_indexes.end()) { + return false; + } + + CodecInfo const* codec = it->second; + auto transport = codec->transport.get(); + + if (codec_id != nullptr) { + switch (codec->id.getTag()) { + case CodecId::a2dp: { + auto id = codec->id.get(); + *codec_id = static_cast(id); + break; + } + case CodecId::vendor: { + auto id = codec->id.get(); + *codec_id = 0xff | (static_cast(id.id) << 8) | + (static_cast(id.codecId) << 24); + break; + } + default: + break; + } + } + if (codec_config != nullptr) { + memset(codec_config, 0, sizeof(*codec_config)); + for (auto const& channel_mode : transport.channelMode) { + switch (channel_mode) { + case ChannelMode::MONO: + codec_config->channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_MONO; + break; + case ChannelMode::STEREO: + codec_config->channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO; + break; + case ChannelMode::DUALMONO: + case ChannelMode::UNKNOWN: + default: + break; + } + } + for (auto const& sample_rate : transport.samplingFrequencyHz) { + switch (sample_rate) { + case 44100: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100; + break; + case 48000: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_48000; + break; + case 88200: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_88200; + break; + case 96000: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_96000; + break; + case 176400: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_176400; + break; + case 192000: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_192000; + break; + case 16000: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_16000; + break; + case 24000: + codec_config->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_24000; + break; + default: + break; + } + } + for (auto const& bitdepth : transport.bitdepth) { + switch (bitdepth) { + case 16: + codec_config->bits_per_sample |= BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16; + break; + case 24: + codec_config->bits_per_sample |= BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24; + break; + case 32: + codec_config->bits_per_sample |= BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32; + break; + default: + break; + } + } + } + + return codec_info == nullptr || + BuildCodecCapabilities(codec->id, transport.capabilities, codec_info); +} + +} // namespace bluetooth::audio::aidl::a2dp diff --git a/system/audio_hal_interface/aidl/a2dp_provider_info.h b/system/audio_hal_interface/aidl/a2dp_provider_info.h new file mode 100644 index 0000000000000000000000000000000000000000..786c77e7d5f7276d38b470ede02b5764770a306e --- /dev/null +++ b/system/audio_hal_interface/aidl/a2dp_provider_info.h @@ -0,0 +1,113 @@ +/* + * Copyright 2023 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 +#include + +#include "audio_aidl_interfaces.h" +#include "include/hardware/bt_av.h" + +namespace bluetooth::audio::aidl::a2dp { + +using ::aidl::android::hardware::bluetooth::audio::CodecId; +using ::aidl::android::hardware::bluetooth::audio::CodecInfo; + +/*** + * Record the provider info returned by the HAL implementer. + ***/ +class ProviderInfo { + public: + /*** + * Reads the provider information from the HAL. + * May return nullptr if the HAL does not implement + * getProviderInfo, or if the feature flag for codec + * extensibility is disabled. + ***/ + static std::unique_ptr GetProviderInfo( + bool supports_a2dp_hw_offload_v2); + + ProviderInfo(std::vector source_codecs, + std::vector sink_codecs); + ~ProviderInfo() = default; + + /*** + * Returns the codec with the selected index if supported + * by the provider. + ***/ + std::optional GetCodec( + btav_a2dp_codec_index_t codec_index) const; + + /*** + * Find the source codec index by codec capabilities. + ***/ + std::optional SourceCodecIndex( + CodecId const& codec_id) const; + std::optional SourceCodecIndex( + uint32_t vendor_id, uint16_t codec_id) const; + std::optional SourceCodecIndex( + uint8_t const* codec_info) const; + + /*** + * Find the sink codec index by codec capabilities. + ***/ + std::optional SinkCodecIndex( + CodecId const& codec_id) const; + std::optional SinkCodecIndex( + uint32_t vendor_id, uint16_t codec_id) const; + std::optional SinkCodecIndex( + uint8_t const* codec_info) const; + + /*** + * Return the name of the codec with the assigned + * input index. + ***/ + std::optional CodecIndexStr( + btav_a2dp_codec_index_t codec_index) const; + + /*** + * Return true if the codec is supported by the + * provider. + ***/ + bool SupportsCodec(btav_a2dp_codec_index_t codec_index) const; + + /*** + * Helper to convert CodecId and byte[] configuration to + * the Media Codec Capabilities format. + * Returns true if the capabilities were successfully converted. + ***/ + static bool BuildCodecCapabilities(CodecId const& codec_id, + std::vector const& capabilities, + uint8_t* codec_info); + + /*** + * Return the A2DP capabilities for the selected codec. + * Returns true if the codec is supported, false otherwise. + ***/ + bool CodecCapabilities(btav_a2dp_codec_index_t codec_index, + uint64_t* codec_id, uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_config) const; + + const std::vector source_codecs; + const std::vector sink_codecs; + + private: + std::unordered_map + assigned_codec_indexes; +}; + +} // namespace bluetooth::audio::aidl::a2dp diff --git a/system/audio_hal_interface/aidl/a2dp_provider_info_unittest.cc b/system/audio_hal_interface/aidl/a2dp_provider_info_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..5a61a630775e834c501fbf7cae4241c8a3f37c73 --- /dev/null +++ b/system/audio_hal_interface/aidl/a2dp_provider_info_unittest.cc @@ -0,0 +1,773 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "TestAIDLA2dpProviderInfo" + +#include "a2dp_provider_info.h" + +#include +#include +#include +#include + +#include "a2dp_constants.h" +#include "a2dp_vendor.h" +#include "a2dp_vendor_opus_constants.h" +#include "avdt_api.h" +#include "client_interface_aidl.h" + +#define TEST_BT com::android::bluetooth::flags + +using aidl::android::hardware::bluetooth::audio::ChannelMode; +using aidl::android::hardware::bluetooth::audio::CodecId; +using aidl::android::hardware::bluetooth::audio::CodecInfo; +using bluetooth::audio::aidl::BluetoothAudioClientInterface; +using bluetooth::audio::aidl::IBluetoothAudioProviderFactory; +using bluetooth::audio::aidl::SessionType; +using bluetooth::audio::aidl::a2dp::ProviderInfo; +using ::testing::_; +using ::testing::Return; +using ::testing::Test; + +tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info) { + return (tA2DP_CODEC_TYPE)(p_codec_info[AVDT_CODEC_TYPE_INDEX]); +} + +uint16_t A2DP_VendorCodecGetCodecId(const uint8_t* p_codec_info) { + const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_CODEC_ID_START_IDX]; + + uint16_t codec_id = (p[0] & 0x00ff) | ((p[1] << 8) & 0xff00); + + return codec_id; +} + +uint32_t A2DP_VendorCodecGetVendorId(const uint8_t* p_codec_info) { + const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_VENDOR_ID_START_IDX]; + + uint32_t vendor_id = (p[0] & 0x000000ff) | ((p[1] << 8) & 0x0000ff00) | + ((p[2] << 16) & 0x00ff0000) | + ((p[3] << 24) & 0xff000000); + + return vendor_id; +} + +class MockBluetoothAudioClientInterface { + public: + MOCK_METHOD( + std::optional, + GetProviderInfo, + (SessionType session_type, + std::shared_ptr provider_factory)); +}; + +static MockBluetoothAudioClientInterface* mock_bt_audio_client_itf = nullptr; + +namespace bluetooth { +namespace audio { +namespace aidl { + +std::optional +BluetoothAudioClientInterface::GetProviderInfo( + SessionType session_type, + std::shared_ptr provider_factory) { + return mock_bt_audio_client_itf->GetProviderInfo(session_type, + provider_factory); +} + +} // namespace aidl +} // namespace audio +} // namespace bluetooth + +namespace { + +std::vector test_sbc_codec_info = {0x06, 0x00, 0x00, 0x3f, + 0xff, 0x02, 0x25}; +std::vector test_aac_codec_info = {0x08, 0x00, 0x02, 0x80, 0x01, + 0x8c, 0x83, 0xe8, 0x00}; +std::vector test_opus_codec_info = {0x09, 0x00, 0xff, 0xe0, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x3c}; +std::vector test_foobar_codec_info = {0x09, 0x00, 0xff, 0x44, 0x33, + 0x00, 0x00, 0x22, 0x11, 0x3c}; + +CodecId::Vendor test_opus_codec_id = {.id = A2DP_OPUS_VENDOR_ID, + .codecId = A2DP_OPUS_CODEC_ID}; +CodecId::Vendor test_foobar_codec_id = {.id = 0x00003344, .codecId = 0x1122}; +CodecId::Vendor test_unknown_vendor_codec_id = {.id = 0x12345678, + .codecId = 0x1234}; + +IBluetoothAudioProviderFactory::ProviderInfo test_source_provider_info = { + .name = "TEST_PROVIDER_SOURCE_CODECS", +}; + +IBluetoothAudioProviderFactory::ProviderInfo test_sink_provider_info = { + .name = "TEST_PROVIDER_SINK_CODECS", +}; + +class ProviderInfoTest : public Test { + public: + std::unique_ptr provider_info; + MockBluetoothAudioClientInterface client_itf_mock; + + void CreateTestA2dpCodecInfo(CodecInfo& codecInfo, CodecId codecId, + std::string codecName, + std::vector capabilities, + std::vector channelMode, + std::vector samplingFrequencyHz, + std::vector bitdepth, bool lossless) { + codecInfo.id = codecId; + codecInfo.name = codecName; + codecInfo.transport.set(); + auto& a2dpInfo = codecInfo.transport.get(); + a2dpInfo.capabilities.resize(capabilities.size()); + a2dpInfo.capabilities = capabilities; + a2dpInfo.channelMode = channelMode; + a2dpInfo.samplingFrequencyHz = samplingFrequencyHz; + a2dpInfo.bitdepth = bitdepth; + a2dpInfo.lossless = lossless; + } + + void GetProviderInfoForTesting(bool include_source_codecs, + bool include_sink_codecs) { + if (include_source_codecs) { + EXPECT_CALL(client_itf_mock, + GetProviderInfo( + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH, _)) + .WillOnce(Return(std::make_optional(test_source_provider_info))); + } else { + EXPECT_CALL(client_itf_mock, + GetProviderInfo( + SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH, _)); + } + + if (include_sink_codecs) { + EXPECT_CALL(client_itf_mock, + GetProviderInfo( + SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH, _)) + .WillOnce(Return(std::make_optional(test_sink_provider_info))); + } else { + EXPECT_CALL(client_itf_mock, + GetProviderInfo( + SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH, _)); + } + + provider_info = ProviderInfo::GetProviderInfo(true); + if (include_source_codecs || include_sink_codecs) { + ASSERT_NE(provider_info, nullptr); + } else { + ASSERT_EQ(provider_info, nullptr); + } + } + + protected: + void SetUp() override { + mock_bt_audio_client_itf = &client_itf_mock; + + auto& codec_info_sbc = test_source_provider_info.codecInfos.emplace_back(); + CreateTestA2dpCodecInfo( + codec_info_sbc, CodecId::A2dp::SBC, std::string("SBC"), + std::vector{0x3f, 0xff, 0x02, 0x25}, /* capabilities */ + std::vector{ChannelMode::MONO, ChannelMode::STEREO, + ChannelMode::DUALMONO}, /* channelMode */ + std::vector{44100, 48000}, /* samplingFrequencyHz */ + std::vector{16, 24, 32}, /* bitdepth */ + false /* lossless */ + ); + + auto& codec_info_aac = test_source_provider_info.codecInfos.emplace_back(); + CreateTestA2dpCodecInfo( + codec_info_aac, CodecId::A2dp::AAC, std::string("AAC"), + std::vector{0x80, 0x01, 0x8c, 0x83, 0xe8, + 0x00}, /* capabilities */ + std::vector{ChannelMode::MONO, ChannelMode::STEREO, + ChannelMode::DUALMONO}, /* channelMode */ + std::vector{44100, 48000}, /* samplingFrequencyHz */ + std::vector{16, 24, 32}, /* bitdepth */ + false /* lossless */ + ); + + auto& codec_info_opus = test_source_provider_info.codecInfos.emplace_back(); + CreateTestA2dpCodecInfo( + codec_info_opus, test_opus_codec_id, std::string("Opus"), + std::vector{0x3c}, /* capabilities */ + std::vector{ChannelMode::MONO, ChannelMode::STEREO, + ChannelMode::DUALMONO}, /* channelMode */ + std::vector{44100, 48000}, /* samplingFrequencyHz */ + std::vector{16, 24, 32}, /* bitdepth */ + false /* lossless */ + ); + + auto& codec_info_foobar = + test_source_provider_info.codecInfos.emplace_back(); + CreateTestA2dpCodecInfo( + codec_info_foobar, test_foobar_codec_id, std::string("FooBar"), + std::vector{0x3c}, /* capabilities */ + std::vector{ChannelMode::MONO, ChannelMode::STEREO, + ChannelMode::DUALMONO}, /* channelMode */ + std::vector{44100, 48000}, /* samplingFrequencyHz */ + std::vector{16, 24, 32}, /* bitdepth */ + false /* lossless */ + ); + + test_sink_provider_info.codecInfos = test_source_provider_info.codecInfos; + } + + void TearDown() override { + test_source_provider_info.codecInfos.clear(); + test_sink_provider_info.codecInfos.clear(); + } +}; +} // namespace + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetProviderInfoFlagDisabled, + REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + EXPECT_CALL( + client_itf_mock, + GetProviderInfo(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH, _)) + .Times(0); + EXPECT_CALL( + client_itf_mock, + GetProviderInfo(SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH, _)) + .Times(0); + + provider_info = ProviderInfo::GetProviderInfo(true); + ASSERT_EQ(provider_info, nullptr); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetProviderInfoEmptyProviderInfo, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(false, false); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetProviderInfo, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetCodecSbc, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + auto received_codec_info_sbc = + provider_info->GetCodec(BTAV_A2DP_CODEC_INDEX_SOURCE_SBC); + ASSERT_TRUE(received_codec_info_sbc.has_value()); + auto codec_info = received_codec_info_sbc.value(); + LOG(ERROR) << codec_info->toString(); + LOG(ERROR) << test_source_provider_info.codecInfos[0].toString(); + ASSERT_EQ(*codec_info, test_source_provider_info.codecInfos[0]); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetCodecAac, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + auto received_codec_info_aac = + provider_info->GetCodec(BTAV_A2DP_CODEC_INDEX_SOURCE_AAC); + ASSERT_TRUE(received_codec_info_aac.has_value()); + auto codec_info = received_codec_info_aac.value(); + LOG(ERROR) << codec_info->toString(); + LOG(ERROR) << test_source_provider_info.codecInfos[1].toString(); + ASSERT_EQ(*codec_info, test_source_provider_info.codecInfos[1]); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetCodecOpus, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + auto received_codec_info_opus = + provider_info->GetCodec(BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS); + ASSERT_TRUE(received_codec_info_opus.has_value()); + auto codec_info = received_codec_info_opus.value(); + LOG(ERROR) << codec_info->toString(); + LOG(ERROR) << test_source_provider_info.codecInfos[2].toString(); + ASSERT_EQ(*codec_info, test_source_provider_info.codecInfos[2]); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetCodecFoobar, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + auto received_codec_info_foobar = + provider_info->GetCodec(BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN); + ASSERT_TRUE(received_codec_info_foobar.has_value()); + auto codec_info = received_codec_info_foobar.value(); + LOG(ERROR) << codec_info->toString(); + LOG(ERROR) << test_source_provider_info.codecInfos[3].toString(); + ASSERT_EQ(*codec_info, test_source_provider_info.codecInfos[3]); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestGetCodecNotSupported, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + auto received_codec_info_not_supported_codec = + provider_info->GetCodec(BTAV_A2DP_CODEC_INDEX_SINK_LDAC); + ASSERT_FALSE(received_codec_info_not_supported_codec.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestSourceCodecIndexByCodecId, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + std::optional a2dp_codec_index_opt; + auto codecInfoArray = test_source_provider_info.codecInfos; + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[0].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_SBC); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[1].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_AAC); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[2].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[3].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN); + + a2dp_codec_index_opt = + provider_info->SourceCodecIndex(test_unknown_vendor_codec_id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestSourceCodecIndexByVendorAndCodecId, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + std::optional a2dp_codec_index_opt; + auto codecInfoArray = test_source_provider_info.codecInfos; + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[2].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[3].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN); + + a2dp_codec_index_opt = + provider_info->SourceCodecIndex(test_unknown_vendor_codec_id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestSourceCodecIndexByCapabilities, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + std::optional a2dp_codec_index_opt; + + a2dp_codec_index_opt = + provider_info->SourceCodecIndex(test_sbc_codec_info.data()); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_SBC); + + a2dp_codec_index_opt = + provider_info->SourceCodecIndex(test_aac_codec_info.data()); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_AAC); + + a2dp_codec_index_opt = + provider_info->SourceCodecIndex(test_opus_codec_info.data()); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS); + + a2dp_codec_index_opt = + provider_info->SourceCodecIndex(test_foobar_codec_info.data()); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex( + std::vector({0xde, 0xad, 0xbe, 0xef}).data()); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, + TestSourceCodecIndexByCodecIdAssertNoSources, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(false, true); + + std::optional a2dp_codec_index_opt; + auto codecInfoArray = test_source_provider_info.codecInfos; + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[0].id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[1].id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[2].id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex(codecInfoArray[3].id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = + provider_info->SourceCodecIndex(test_unknown_vendor_codec_id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, + TestSourceCodecIndexByVendorAndCodecIdAssertNoSources, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(false, true); + + std::optional a2dp_codec_index_opt; + + a2dp_codec_index_opt = provider_info->SourceCodecIndex( + 0, static_cast(CodecId::A2dp::SBC)); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex( + 0, static_cast(CodecId::A2dp::AAC)); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex( + test_opus_codec_id.id, test_opus_codec_id.codecId); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex( + test_foobar_codec_id.id, test_foobar_codec_id.codecId); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SourceCodecIndex( + test_unknown_vendor_codec_id.id, test_unknown_vendor_codec_id.codecId); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestSinkCodecIndexByCodecId, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(false, true); + + std::optional a2dp_codec_index_opt; + auto codecInfoArray = test_sink_provider_info.codecInfos; + + a2dp_codec_index_opt = provider_info->SinkCodecIndex(codecInfoArray[0].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SINK_SBC); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex(codecInfoArray[1].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SINK_AAC); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex(codecInfoArray[2].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SINK_OPUS); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex(codecInfoArray[3].id); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN); + + a2dp_codec_index_opt = + provider_info->SinkCodecIndex(test_unknown_vendor_codec_id); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestSinkCodecIndexByVendorAndCodecId, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(false, true); + + std::optional a2dp_codec_index_opt; + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + test_opus_codec_id.id, test_opus_codec_id.codecId); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SINK_OPUS); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + test_foobar_codec_id.id, test_foobar_codec_id.codecId); + ASSERT_TRUE(a2dp_codec_index_opt.has_value()); + ASSERT_EQ(a2dp_codec_index_opt.value(), BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + test_unknown_vendor_codec_id.id, test_unknown_vendor_codec_id.codecId); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, + TestSinkCodecIndexByVendorAndCodecIdAssertNoSinks, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + std::optional a2dp_codec_index_opt; + auto codecInfoArray = test_sink_provider_info.codecInfos; + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + 0, static_cast(CodecId::A2dp::SBC)); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + 0, static_cast(CodecId::A2dp::AAC)); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + test_opus_codec_id.id, test_opus_codec_id.codecId); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + test_foobar_codec_id.id, test_foobar_codec_id.codecId); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); + + a2dp_codec_index_opt = provider_info->SinkCodecIndex( + test_unknown_vendor_codec_id.id, test_unknown_vendor_codec_id.codecId); + ASSERT_FALSE(a2dp_codec_index_opt.has_value()); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestCodecIndexStr, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + auto codecInfoArray = test_source_provider_info.codecInfos; + + ASSERT_EQ(provider_info->CodecIndexStr(BTAV_A2DP_CODEC_INDEX_SOURCE_SBC), + codecInfoArray[0].name); + + ASSERT_EQ(provider_info->CodecIndexStr(BTAV_A2DP_CODEC_INDEX_SOURCE_AAC), + codecInfoArray[1].name); + + ASSERT_EQ(provider_info->CodecIndexStr(BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS), + codecInfoArray[2].name); + + ASSERT_EQ(provider_info->CodecIndexStr(BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN), + codecInfoArray[3].name); + + ASSERT_EQ(provider_info->CodecIndexStr(static_cast( + test_unknown_vendor_codec_id.id)), + std::nullopt); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestSupportsCodec, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, true); + + for (int i = static_cast(BTAV_A2DP_CODEC_INDEX_SOURCE_MIN); + i <= static_cast(BTAV_A2DP_CODEC_INDEX_MAX); i++) { + switch (i) { + case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: + case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC: + case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS: + case BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN: + case BTAV_A2DP_CODEC_INDEX_SINK_SBC: + case BTAV_A2DP_CODEC_INDEX_SINK_AAC: + case BTAV_A2DP_CODEC_INDEX_SINK_OPUS: + case BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN: + ASSERT_TRUE(provider_info->SupportsCodec( + static_cast(i))); + break; + default: + ASSERT_FALSE(provider_info->SupportsCodec( + static_cast(i))); + break; + } + } +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestBuildCodecCapabilitiesSbc, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + std::vector sbc_caps = {0x3f, 0xff, 0x02, 0x25}; + uint8_t result_sbc_codec_info[7]; + + ASSERT_TRUE(ProviderInfo::BuildCodecCapabilities( + CodecId::A2dp(CodecId::A2dp::SBC), sbc_caps, result_sbc_codec_info)); + ASSERT_EQ(std::memcmp(result_sbc_codec_info, test_sbc_codec_info.data(), + test_sbc_codec_info.size()), + 0); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestBuildCodecCapabilitiesAac, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + std::vector aac_caps = {0x80, 0x01, 0x8c, 0x83, 0xe8, 0x00}; + uint8_t result_aac_codec_info[9]; + + ASSERT_TRUE(ProviderInfo::BuildCodecCapabilities( + CodecId::A2dp(CodecId::A2dp::AAC), aac_caps, result_aac_codec_info)); + ASSERT_EQ(std::memcmp(result_aac_codec_info, test_aac_codec_info.data(), + test_aac_codec_info.size()), + 0); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestBuildCodecCapabilitiesOpus, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + std::vector opus_caps = {0x3c}; + uint8_t result_opus_codec_info[10]; + + ASSERT_TRUE(ProviderInfo::BuildCodecCapabilities( + test_opus_codec_id, opus_caps, result_opus_codec_info)); + ASSERT_EQ(std::memcmp(result_opus_codec_info, test_opus_codec_info.data(), + test_opus_codec_info.size()), + 0); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestBuildCodecCapabilitiesFoobar, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + std::vector foobar_caps = {0x3c}; + uint8_t result_foobar_codec_info[10]; + + ASSERT_TRUE(ProviderInfo::BuildCodecCapabilities( + test_foobar_codec_id, foobar_caps, result_foobar_codec_info)); + ASSERT_EQ(std::memcmp(result_foobar_codec_info, test_foobar_codec_info.data(), + test_foobar_codec_info.size()), + 0); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestBuildCodecCapabilitiesNotSupported, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + std::vector foobar_caps = {0x3c}; + uint8_t result_foobar_codec_info[10]; + + ASSERT_FALSE(ProviderInfo::BuildCodecCapabilities( + CodecId::Core(CodecId::Core::CVSD), foobar_caps, + result_foobar_codec_info)); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestCodecCapabilitiesSbc, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + uint8_t result_codec_info[20]; + btav_a2dp_codec_config_t result_codec_config; + uint64_t result_codec_id; + + ASSERT_TRUE(provider_info->CodecCapabilities( + BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, &result_codec_id, result_codec_info, + &result_codec_config)); + ASSERT_EQ(result_codec_id, A2DP_CODEC_ID_SBC); + ASSERT_EQ(std::memcmp(result_codec_info, test_sbc_codec_info.data(), + test_sbc_codec_info.size()), + 0); + ASSERT_TRUE(result_codec_config.channel_mode == + (BTAV_A2DP_CODEC_CHANNEL_MODE_MONO | + BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO)); + ASSERT_TRUE( + result_codec_config.sample_rate == + (BTAV_A2DP_CODEC_SAMPLE_RATE_44100 | BTAV_A2DP_CODEC_SAMPLE_RATE_48000)); + ASSERT_TRUE(result_codec_config.bits_per_sample == + (BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32)); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestCodecCapabilitiesAac, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + uint8_t result_codec_info[20]; + btav_a2dp_codec_config_t result_codec_config; + uint64_t result_codec_id; + + ASSERT_TRUE(provider_info->CodecCapabilities( + BTAV_A2DP_CODEC_INDEX_SOURCE_AAC, &result_codec_id, result_codec_info, + &result_codec_config)); + ASSERT_EQ(result_codec_id, A2DP_CODEC_ID_AAC); + ASSERT_EQ(std::memcmp(result_codec_info, test_aac_codec_info.data(), + test_aac_codec_info.size()), + 0); + ASSERT_TRUE(result_codec_config.channel_mode == + (BTAV_A2DP_CODEC_CHANNEL_MODE_MONO | + BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO)); + ASSERT_TRUE( + result_codec_config.sample_rate == + (BTAV_A2DP_CODEC_SAMPLE_RATE_44100 | BTAV_A2DP_CODEC_SAMPLE_RATE_48000)); + ASSERT_TRUE(result_codec_config.bits_per_sample == + (BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32)); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestCodecCapabilitiesOpus, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + uint8_t result_codec_info[20]; + btav_a2dp_codec_config_t result_codec_config; + uint64_t result_codec_id; + + ASSERT_TRUE(provider_info->CodecCapabilities( + BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS, &result_codec_id, result_codec_info, + &result_codec_config)); + ASSERT_EQ(result_codec_id, A2DP_CODEC_ID_OPUS); + ASSERT_EQ(std::memcmp(result_codec_info, test_opus_codec_info.data(), + test_opus_codec_info.size()), + 0); + ASSERT_TRUE(result_codec_config.channel_mode == + (BTAV_A2DP_CODEC_CHANNEL_MODE_MONO | + BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO)); + ASSERT_TRUE( + result_codec_config.sample_rate == + (BTAV_A2DP_CODEC_SAMPLE_RATE_44100 | BTAV_A2DP_CODEC_SAMPLE_RATE_48000)); + ASSERT_TRUE(result_codec_config.bits_per_sample == + (BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32)); +} + +TEST_F_WITH_FLAGS(ProviderInfoTest, TestCodecCapabilitiesFoobar, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, a2dp_offload_codec_extensibility))) { + GetProviderInfoForTesting(true, false); + + uint8_t result_codec_info[20]; + btav_a2dp_codec_config_t result_codec_config; + uint64_t result_codec_id; + + ASSERT_TRUE(provider_info->CodecCapabilities( + BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN, &result_codec_id, result_codec_info, + &result_codec_config)); + ASSERT_EQ(result_codec_id, static_cast(0x11223344ff)); + ASSERT_EQ(std::memcmp(result_codec_info, test_foobar_codec_info.data(), + test_foobar_codec_info.size()), + 0); + ASSERT_TRUE(result_codec_config.channel_mode == + (BTAV_A2DP_CODEC_CHANNEL_MODE_MONO | + BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO)); + ASSERT_TRUE( + result_codec_config.sample_rate == + (BTAV_A2DP_CODEC_SAMPLE_RATE_44100 | BTAV_A2DP_CODEC_SAMPLE_RATE_48000)); + ASSERT_TRUE(result_codec_config.bits_per_sample == + (BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24 | + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32)); +} \ No newline at end of file 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 2250b76184fe3c884392b1d71b1b3f989ff03b50..9cc829fef5f4fbf7227915d7f86ffbf1e54e919c 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,8 @@ #include "bluetooth_audio_port_impl.h" +#include + #include "btif/include/btif_common.h" #include "common/stop_watch_legacy.h" diff --git a/system/audio_hal_interface/aidl/client_interface_aidl.cc b/system/audio_hal_interface/aidl/client_interface_aidl.cc index 9faa725022661e6eba95c73fb71de39d6823a7eb..76e8788d021891c9363b17df0601cae896aa3b9c 100644 --- a/system/audio_hal_interface/aidl/client_interface_aidl.cc +++ b/system/audio_hal_interface/aidl/client_interface_aidl.cc @@ -21,6 +21,11 @@ #include #include +#include +#include + +#include "include/check.h" + namespace bluetooth { namespace audio { namespace aidl { @@ -91,6 +96,92 @@ BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) { return capabilities; } +std::optional +BluetoothAudioClientInterface::GetProviderInfo( + SessionType session_type, + std::shared_ptr provider_factory) { + if (!is_aidl_available() || + !IS_FLAG_ENABLED(a2dp_offload_codec_extensibility)) { + return std::nullopt; + } + + if (provider_factory == nullptr) { + provider_factory = IBluetoothAudioProviderFactory::fromBinder( + ::ndk::SpAIBinder(AServiceManager_waitForService( + kDefaultAudioProviderFactoryInterface.c_str()))); + } + + if (provider_factory == nullptr) { + LOG(ERROR) << __func__ << ", can't get provider info from unknown factory"; + return std::nullopt; + } + + std::optional provider_info = + {}; + auto aidl_retval = + provider_factory->getProviderInfo(session_type, &provider_info); + + if (!aidl_retval.isOk()) { + LOG(ERROR) << __func__ << ": BluetoothAudioHal::getProviderInfo failure: " + << aidl_retval.getDescription(); + return std::nullopt; + } + + return provider_info; +} + +std::optional +BluetoothAudioClientInterface::GetA2dpConfiguration( + std::vector const& remote_capabilities, + A2dpConfigurationHint const& hint) const { + if (!is_aidl_available() || + !IS_FLAG_ENABLED(a2dp_offload_codec_extensibility)) { + return std::nullopt; + } + + if (provider_ == nullptr) { + LOG(ERROR) << __func__ + << ", can't get a2dp configuration from unknown provider"; + return std::nullopt; + } + + std::optional configuration = std::nullopt; + auto aidl_retval = provider_->getA2dpConfiguration(remote_capabilities, hint, + &configuration); + + if (!aidl_retval.isOk()) { + LOG(ERROR) << __func__ << ", getA2dpConfiguration failure: " + << aidl_retval.getDescription(); + return std::nullopt; + } + + return configuration; +} + +std::optional BluetoothAudioClientInterface::ParseA2dpConfiguration( + const CodecId& codec_id, const std::vector& configuration, + CodecParameters* codec_parameters) const { + A2dpStatus a2dp_status; + + if (provider_ == nullptr) { + LOG(ERROR) + << __func__ + << ", can not parse A2DP configuration because of unknown provider"; + return std::nullopt; + } + + auto aidl_retval = provider_->parseA2dpConfiguration( + codec_id, configuration, codec_parameters, &a2dp_status); + + if (!aidl_retval.isOk()) { + LOG(ERROR) << __func__ << ", parseA2dpConfiguration failure: " + << aidl_retval.getDescription(); + return std::nullopt; + } + + return std::make_optional(a2dp_status); +} + void BluetoothAudioClientInterface::FetchAudioProvider() { if (!is_aidl_available()) { LOG(ERROR) << __func__ << ": aidl is not supported on this platform."; @@ -148,8 +239,7 @@ void BluetoothAudioClientInterface::FetchAudioProvider() { } BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface( - IBluetoothSinkTransportInstance* sink, - bluetooth::common::MessageLoopThread* message_loop) + IBluetoothSinkTransportInstance* sink) : BluetoothAudioClientInterface{sink}, sink_(sink) { FetchAudioProvider(); } @@ -162,8 +252,7 @@ BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() { } BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface( - IBluetoothSourceTransportInstance* source, - bluetooth::common::MessageLoopThread* message_loop) + IBluetoothSourceTransportInstance* source) : BluetoothAudioClientInterface{source}, source_(source) { FetchAudioProvider(); } @@ -220,7 +309,8 @@ bool BluetoothAudioClientInterface::UpdateAudioConfig( audio_config_tag == AudioConfiguration::pcmConfig); bool is_a2dp_offload_audio_config = (is_a2dp_offload_session && - audio_config_tag == AudioConfiguration::a2dpConfig); + (audio_config_tag == AudioConfiguration::a2dpConfig || + audio_config_tag == AudioConfiguration::a2dp)); bool is_leaudio_unicast_offload_audio_config = (is_leaudio_unicast_offload_session && audio_config_tag == AudioConfiguration::leAudioConfig); @@ -261,11 +351,16 @@ bool BluetoothAudioClientInterface::SetAllowedLatencyModes( return false; } - /* Ensure that FREE is always included and remove duplicates if any */ - std::set temp_set(latency_modes.begin(), latency_modes.end()); - temp_set.insert(LatencyMode::FREE); - latency_modes_.clear(); - latency_modes_.assign(temp_set.begin(), temp_set.end()); + if (latency_modes.empty()) { + latency_modes_.clear(); + latency_modes_.push_back(LatencyMode::FREE); + } else { + /* Ensure that FREE is always included and remove duplicates if any */ + std::set temp_set(latency_modes.begin(), latency_modes.end()); + temp_set.insert(LatencyMode::FREE); + latency_modes_.clear(); + latency_modes_.assign(temp_set.begin(), temp_set.end()); + } for (auto latency_mode : latency_modes) { LOG(INFO) << "Latency mode allowed: " @@ -275,6 +370,7 @@ bool BluetoothAudioClientInterface::SetAllowedLatencyModes( /* Low latency mode is used if modes other than FREE are present */ bool allowed = (latency_modes_.size() > 1); + LOG(INFO) << __func__ << ": Latency mode allowed: " << allowed; auto aidl_retval = provider_->setLowLatencyModeAllowed(allowed); if (!aidl_retval.isOk()) { LOG(WARNING) << __func__ << ": BluetoothAudioHal is not ready: " @@ -560,22 +656,6 @@ size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf, return total_written; } -std::optional -BluetoothAudioClientInterface::GetProviderInfo(SessionType session_type) { - if (provider_factory_ == nullptr) { - LOG(WARNING) << __func__ << ": No provider factory"; - return std::nullopt; - } - std::optional provider_info; - auto aidl_retval = - provider_factory_->getProviderInfo(session_type, &provider_info); - if (!aidl_retval.isOk()) { - LOG(FATAL) << __func__ << ": BluetoothAudioHal::getProviderInfo failure: " - << aidl_retval.getDescription(); - } - return provider_info; -} - void BluetoothAudioClientInterface::SetCodecPriority(CodecId codec_id, int32_t priority) { CHECK(provider_ != nullptr); diff --git a/system/audio_hal_interface/aidl/client_interface_aidl.h b/system/audio_hal_interface/aidl/client_interface_aidl.h index 0dd9575acba81f8330b7e685d251bee223729cb7..c191e4054efaba00756011f61411a6e4b92a4d30 100644 --- a/system/audio_hal_interface/aidl/client_interface_aidl.h +++ b/system/audio_hal_interface/aidl/client_interface_aidl.h @@ -26,7 +26,6 @@ #include "audio_aidl_interfaces.h" #include "audio_ctrl_ack.h" #include "bluetooth_audio_port_impl.h" -#include "common/message_loop_thread.h" #include "transport_instance.h" #define BLUETOOTH_AUDIO_HAL_PROP_DISABLED \ @@ -36,11 +35,16 @@ namespace bluetooth { namespace audio { namespace aidl { +using ::aidl::android::hardware::bluetooth::audio::A2dpConfiguration; +using ::aidl::android::hardware::bluetooth::audio::A2dpConfigurationHint; +using ::aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities; +using ::aidl::android::hardware::bluetooth::audio::A2dpStatus; using ::aidl::android::hardware::bluetooth::audio::AudioCapabilities; using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration; using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus; using ::aidl::android::hardware::bluetooth::audio::CodecId; using ::aidl::android::hardware::bluetooth::audio::CodecInfo; +using ::aidl::android::hardware::bluetooth::audio::CodecParameters; using ::aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv; using ::aidl::android::hardware::bluetooth::audio:: CodecSpecificConfigurationLtv; @@ -74,8 +78,22 @@ class BluetoothAudioClientInterface { bool IsValid() const { return provider_ != nullptr; } std::vector GetAudioCapabilities() const; + static std::vector GetAudioCapabilities( SessionType session_type); + static std::optional + GetProviderInfo(SessionType session_type, + std::shared_ptr + provider_factory = nullptr); + + std::optional ParseA2dpConfiguration( + const CodecId& codec_id, const std::vector& configuration, + CodecParameters* codec_parameters) const; + + std::optional GetA2dpConfiguration( + std::vector const& remote_capabilities, + A2dpConfigurationHint const& hint) const; + void StreamStarted(const BluetoothAudioCtrlAck& ack); void StreamSuspended(const BluetoothAudioCtrlAck& ack); @@ -95,9 +113,6 @@ class BluetoothAudioClientInterface { void FlushAudioData(); - std::optional GetProviderInfo( - SessionType session_type); - void SetCodecPriority(CodecId codec_id, int32_t priority); std::vector @@ -176,12 +191,9 @@ class BluetoothAudioSinkClientInterface : public BluetoothAudioClientInterface { public: /*** * Constructs an BluetoothAudioSinkClientInterface to communicate to - * BluetoothAudio HAL. |sink| is the implementation for the transport, and - * |message_loop| is the thread where callbacks are invoked. + * BluetoothAudio HAL. |sink| is the implementation for the transport. ***/ - BluetoothAudioSinkClientInterface( - IBluetoothSinkTransportInstance* sink, - bluetooth::common::MessageLoopThread* message_loop); + BluetoothAudioSinkClientInterface(IBluetoothSinkTransportInstance* sink); virtual ~BluetoothAudioSinkClientInterface(); IBluetoothSinkTransportInstance* GetTransportInstance() const { @@ -205,12 +217,10 @@ class BluetoothAudioSourceClientInterface public: /*** * Constructs an BluetoothAudioSourceClientInterface to communicate to - * BluetoothAudio HAL. |source| is the implementation for the transport, and - * |message_loop| is the thread where callbacks are invoked. + * BluetoothAudio HAL. |source| is the implementation for the transport. ***/ BluetoothAudioSourceClientInterface( - IBluetoothSourceTransportInstance* source, - bluetooth::common::MessageLoopThread* message_loop); + IBluetoothSourceTransportInstance* source); virtual ~BluetoothAudioSourceClientInterface(); IBluetoothSourceTransportInstance* GetTransportInstance() const { diff --git a/system/audio_hal_interface/aidl/codec_status_aidl.cc b/system/audio_hal_interface/aidl/codec_status_aidl.cc index 25161e80dccdab0b006219bd53d74bbd45a56f7e..55297bbaab6abc5be185e1f7f7c88313cf3b704e 100644 --- a/system/audio_hal_interface/aidl/codec_status_aidl.cc +++ b/system/audio_hal_interface/aidl/codec_status_aidl.cc @@ -19,6 +19,7 @@ #include "codec_status_aidl.h" #include +#include #include "a2dp_aac_constants.h" #include "a2dp_sbc_constants.h" @@ -580,6 +581,7 @@ bool UpdateOffloadingCapabilities( << ": disabled offloading capability=" << capability.toString(); } } + // TODO: Bluetooth SoC and runtime property return true; } diff --git a/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc b/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc index 813de3b31079c7029bc381e0aa925810ec96a838..e6fbd1622ad462711b146ef9aea382a8d6dd2112 100644 --- a/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc +++ b/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc @@ -20,7 +20,7 @@ #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h" #include "client_interface_aidl.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" namespace { @@ -179,7 +179,7 @@ namespace hearing_aid { bool is_hal_enabled() { return hearing_aid_hal_clientinterface != nullptr; } bool init(StreamCallbacks stream_cb, - bluetooth::common::MessageLoopThread* message_loop) { + bluetooth::common::MessageLoopThread* /*message_loop*/) { LOG(INFO) << __func__; if (is_hal_force_disabled()) { @@ -196,7 +196,7 @@ bool init(StreamCallbacks stream_cb, hearing_aid_sink = new HearingAidTransport(std::move(stream_cb)); hearing_aid_hal_clientinterface = new bluetooth::audio::aidl::BluetoothAudioSinkClientInterface( - hearing_aid_sink, message_loop); + hearing_aid_sink); if (!hearing_aid_hal_clientinterface->IsValid()) { LOG(WARNING) << __func__ << ": BluetoothAudio HAL for Hearing Aid is invalid?!"; diff --git a/system/audio_hal_interface/aidl/hfp_client_interface_aidl.cc b/system/audio_hal_interface/aidl/hfp_client_interface_aidl.cc index 63bfc917bd74c1b4772d49b378444ad56a0db191..f5df063d651e2fc79ad982af65b8c04eb431073c 100644 --- a/system/audio_hal_interface/aidl/hfp_client_interface_aidl.cc +++ b/system/audio_hal_interface/aidl/hfp_client_interface_aidl.cc @@ -22,10 +22,11 @@ #include "aidl/android/hardware/bluetooth/audio/AudioConfiguration.h" #include "aidl/transport_instance.h" #include "bta/ag/bta_ag_int.h" -#include "btif_hf.h" +#include "btif/include/btif_hf.h" #include "btm_api_types.h" #include "hardware/bluetooth.h" #include "hardware/bluetooth_headset_interface.h" +#include "provider_info.h" #include "types/raw_address.h" namespace bluetooth { @@ -61,6 +62,13 @@ tBTA_AG_SCB* get_hfp_active_device_callback() { return cb; } +std::unordered_map HfpTransport::GetHfpScoConfig( + SessionType sessionType) { + auto providerInfo = + ::bluetooth::audio::aidl::ProviderInfo::GetProviderInfo(sessionType); + return providerInfo->GetHfpScoConfig(); +} + HfpTransport::HfpTransport() { hfp_pending_cmd_ = HFP_CTRL_CMD_NONE; } BluetoothAudioCtrlAck HfpTransport::StartRequest() { @@ -82,15 +90,21 @@ BluetoothAudioCtrlAck HfpTransport::StartRequest() { /* Post start SCO event and wait for sco to open */ hfp_pending_cmd_ = HFP_CTRL_CMD_START; + // as ConnectAudio only queues the command into main thread, keep PENDING + // status auto status = bluetooth::headset::GetInterface()->ConnectAudio(&cb->peer_addr, 0); - hfp_pending_cmd_ = HFP_CTRL_CMD_NONE; LOG(INFO) << __func__ << ": ConnectAudio status = " << status << " - " << bt_status_text(status).c_str(); auto ctrl_ack = status_to_ack_map.find(status); - if (ctrl_ack == status_to_ack_map.end()) + if (ctrl_ack == status_to_ack_map.end()) { + LOG_WARN("Unmapped status=%d", status); return BluetoothAudioCtrlAck::FAILURE; - return ctrl_ack->second; + } + if (ctrl_ack->second != BluetoothAudioCtrlAck::SUCCESS_FINISHED) { + return ctrl_ack->second; + } + return BluetoothAudioCtrlAck::PENDING; } void HfpTransport::StopRequest() { @@ -121,12 +135,6 @@ BluetoothAudioCtrlAck HfpTransport::SuspendRequest() { void HfpTransport::SetLatencyMode(LatencyMode latency_mode) {} -bool GetPresentationPosition(uint64_t* remote_delay_report_ns, - uint64_t* total_bytes_read, - timespec* data_position) { - return false; -} - void HfpTransport::SourceMetadataChanged( const source_metadata_v7_t& source_metadata) {} @@ -134,6 +142,12 @@ void HfpTransport::SinkMetadataChanged(const sink_metadata_v7_t&) {} void HfpTransport::ResetPresentationPosition() {} +bool HfpTransport::GetPresentationPosition(uint64_t* remote_delay_report_ns, + uint64_t* total_bytes_read, + timespec* data_position) { + return false; +} + // Source / sink functions HfpDecodingTransport::HfpDecodingTransport(SessionType session_type) : IBluetoothSinkTransportInstance(session_type, (AudioConfiguration){}) { @@ -185,6 +199,8 @@ uint8_t HfpDecodingTransport::GetPendingCmd() const { void HfpDecodingTransport::ResetPendingCmd() { transport_->ResetPendingCmd(); } +void HfpDecodingTransport::StopRequest() { transport_->StopRequest(); } + HfpEncodingTransport::HfpEncodingTransport(SessionType session_type) : IBluetoothSourceTransportInstance(session_type, (AudioConfiguration){}) { transport_ = new HfpTransport(); @@ -200,6 +216,8 @@ BluetoothAudioCtrlAck HfpEncodingTransport::SuspendRequest() { return transport_->SuspendRequest(); } +void HfpEncodingTransport::StopRequest() { transport_->StopRequest(); } + void HfpEncodingTransport::SetLatencyMode(LatencyMode latency_mode) { transport_->SetLatencyMode(latency_mode); } diff --git a/system/audio_hal_interface/aidl/hfp_client_interface_aidl.h b/system/audio_hal_interface/aidl/hfp_client_interface_aidl.h index 8db6b5f48c07e58a0d20d382927c9c7110cd960a..2e11ee083e69126b37d7c5c20f4f13f5959f2bea 100644 --- a/system/audio_hal_interface/aidl/hfp_client_interface_aidl.h +++ b/system/audio_hal_interface/aidl/hfp_client_interface_aidl.h @@ -17,9 +17,10 @@ #pragma once #include +#include +#include "bta/ag/bta_ag_int.h" #include "client_interface_aidl.h" -#include "common/message_loop_thread.h" namespace bluetooth { namespace audio { @@ -29,7 +30,7 @@ namespace hfp { using ::aidl::android::hardware::bluetooth::audio::LatencyMode; typedef enum { - HFP_CTRL_CMD_NONE, + HFP_CTRL_CMD_NONE = 0, HFP_CTRL_CMD_CHECK_READY, HFP_CTRL_CMD_START, HFP_CTRL_CMD_STOP, @@ -69,6 +70,9 @@ class HfpTransport { void LogBytesProcessed(size_t bytes_read); + static std::unordered_map GetHfpScoConfig( + SessionType sessionType); + private: tHFP_CTRL_CMD hfp_pending_cmd_; }; diff --git a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc index 3168bea2494029aaa2d4aa180be4c28773b270ac..dc30bbff695a5dc7f0b990636938a76b170bc414 100644 --- a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc +++ b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc @@ -25,7 +25,7 @@ #include "codec_status_aidl.h" #include "hal_version_manager.h" -#include "osi/include/log.h" +#include "os/log.h" namespace bluetooth { namespace audio { @@ -66,7 +66,8 @@ LeAudioTransport::LeAudioTransport(void (*flush)(void), total_bytes_processed_(0), data_position_({}), pcm_config_(std::move(pcm_config)), - start_request_state_(StartRequestState::IDLE){}; + start_request_state_(StartRequestState::IDLE), + dsa_mode_(DsaMode::DISABLED){}; BluetoothAudioCtrlAck LeAudioTransport::StartRequest(bool is_low_latency) { // Check if operation is pending already @@ -107,6 +108,43 @@ BluetoothAudioCtrlAck LeAudioTransport::StartRequest(bool is_low_latency) { return BluetoothAudioCtrlAck::FAILURE; } +BluetoothAudioCtrlAck LeAudioTransport::StartRequestV2(bool is_low_latency) { + // Check if operation is pending already + if (GetStartRequestState() == StartRequestState::PENDING_AFTER_RESUME) { + LOG_INFO("Start request is already pending. Ignore the request"); + return BluetoothAudioCtrlAck::PENDING; + } + + SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME); + if (stream_cb_.on_resume_(true)) { + std::lock_guard guard(start_request_state_mutex_); + + switch (start_request_state_) { + case StartRequestState::CONFIRMED: + LOG_INFO("Start completed."); + SetStartRequestState(StartRequestState::IDLE); + return BluetoothAudioCtrlAck::SUCCESS_FINISHED; + case StartRequestState::CANCELED: + LOG_INFO("Start request failed."); + SetStartRequestState(StartRequestState::IDLE); + return BluetoothAudioCtrlAck::FAILURE; + case StartRequestState::PENDING_BEFORE_RESUME: + LOG_INFO("Start pending."); + SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME); + return BluetoothAudioCtrlAck::PENDING; + default: + SetStartRequestState(StartRequestState::IDLE); + LOG_ERROR("Unexpected state %d", + static_cast(start_request_state_.load())); + return BluetoothAudioCtrlAck::FAILURE; + } + } + + SetStartRequestState(StartRequestState::IDLE); + LOG_INFO("On resume failed."); + return BluetoothAudioCtrlAck::FAILURE; +} + BluetoothAudioCtrlAck LeAudioTransport::SuspendRequest() { LOG(INFO) << __func__; if (stream_cb_.on_suspend_()) { @@ -125,6 +163,9 @@ void LeAudioTransport::StopRequest() { } void LeAudioTransport::SetLatencyMode(LatencyMode latency_mode) { + LOG_DEBUG("Latency mode: %s", + ::aidl::android::hardware::bluetooth::audio::toString(latency_mode) + .c_str()); switch (latency_mode) { case LatencyMode::FREE: dsa_mode_ = DsaMode::DISABLED; @@ -244,6 +285,23 @@ LeAudioTransport::LeAudioGetBroadcastConfig() { return broadcast_config_; } +bool LeAudioTransport::IsRequestCompletedAfterUpdate( + const std::function(StartRequestState)>& + lambda) { + std::lock_guard guard(start_request_state_mutex_); + auto result = lambda(start_request_state_); + auto new_state = std::get<0>(result); + if (new_state != start_request_state_) { + start_request_state_ = new_state; + } + + auto ret = std::get<1>(result); + LOG_VERBOSE(" new state: %d, return %s", (int)(start_request_state_.load()), + ret ? "true" : "false"); + + return ret; +} + StartRequestState LeAudioTransport::GetStartRequestState(void) { return start_request_state_; } @@ -289,6 +347,9 @@ LeAudioSinkTransport::LeAudioSinkTransport(SessionType session_type, LeAudioSinkTransport::~LeAudioSinkTransport() { delete transport_; } BluetoothAudioCtrlAck LeAudioSinkTransport::StartRequest(bool is_low_latency) { + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + return transport_->StartRequestV2(is_low_latency); + } return transport_->StartRequest(is_low_latency); } @@ -352,6 +413,12 @@ LeAudioSinkTransport::LeAudioGetBroadcastConfig() { return transport_->LeAudioGetBroadcastConfig(); } +bool LeAudioSinkTransport::IsRequestCompletedAfterUpdate( + const std::function(StartRequestState)>& + lambda) { + return transport_->IsRequestCompletedAfterUpdate(lambda); +} + StartRequestState LeAudioSinkTransport::GetStartRequestState(void) { return transport_->GetStartRequestState(); } @@ -379,6 +446,9 @@ LeAudioSourceTransport::~LeAudioSourceTransport() { delete transport_; } BluetoothAudioCtrlAck LeAudioSourceTransport::StartRequest( bool is_low_latency) { + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + return transport_->StartRequestV2(is_low_latency); + } return transport_->StartRequest(is_low_latency); } @@ -433,6 +503,12 @@ void LeAudioSourceTransport::LeAudioSetSelectedHalPcmConfig( channels_count, data_interval); } +bool LeAudioSourceTransport::IsRequestCompletedAfterUpdate( + const std::function(StartRequestState)>& + lambda) { + return transport_->IsRequestCompletedAfterUpdate(lambda); +} + StartRequestState LeAudioSourceTransport::GetStartRequestState(void) { return transport_->GetStartRequestState(); } diff --git a/system/audio_hal_interface/aidl/le_audio_software_aidl.h b/system/audio_hal_interface/aidl/le_audio_software_aidl.h index c75a76d6b24f32b3d2e19887d61e1b06555097b0..98f0dfd9079b5e6eacf04d998f2460a518c2252d 100644 --- a/system/audio_hal_interface/aidl/le_audio_software_aidl.h +++ b/system/audio_hal_interface/aidl/le_audio_software_aidl.h @@ -71,6 +71,7 @@ class LeAudioTransport { PcmConfiguration pcm_config); BluetoothAudioCtrlAck StartRequest(bool is_low_latency); + BluetoothAudioCtrlAck StartRequestV2(bool is_low_latency); BluetoothAudioCtrlAck SuspendRequest(); @@ -103,6 +104,9 @@ class LeAudioTransport { const LeAudioBroadcastConfiguration& LeAudioGetBroadcastConfig(); + bool IsRequestCompletedAfterUpdate( + const std::function< + std::pair(StartRequestState)>& lambda); StartRequestState GetStartRequestState(void); void ClearStartRequestState(void); void SetStartRequestState(StartRequestState state); @@ -115,6 +119,7 @@ class LeAudioTransport { timespec data_position_; PcmConfiguration pcm_config_; LeAudioBroadcastConfiguration broadcast_config_; + mutable std::mutex start_request_state_mutex_; std::atomic start_request_state_; DsaMode dsa_mode_; }; @@ -128,6 +133,7 @@ class LeAudioSinkTransport ~LeAudioSinkTransport(); BluetoothAudioCtrlAck StartRequest(bool is_low_latency) override; + BluetoothAudioCtrlAck StartRequestV2(bool is_low_latency); BluetoothAudioCtrlAck SuspendRequest() override; @@ -161,6 +167,9 @@ class LeAudioSinkTransport const LeAudioBroadcastConfiguration& LeAudioGetBroadcastConfig(); + bool IsRequestCompletedAfterUpdate( + const std::function< + std::pair(StartRequestState)>& lambda); StartRequestState GetStartRequestState(void); void ClearStartRequestState(void); void SetStartRequestState(StartRequestState state); @@ -184,6 +193,7 @@ class LeAudioSourceTransport ~LeAudioSourceTransport(); BluetoothAudioCtrlAck StartRequest(bool is_low_latency) override; + BluetoothAudioCtrlAck StartRequestV2(bool is_low_latency); BluetoothAudioCtrlAck SuspendRequest() override; @@ -212,6 +222,10 @@ class LeAudioSourceTransport uint8_t channels_count, uint32_t data_interval); + bool IsRequestCompletedAfterUpdate( + const std::function< + std::pair(StartRequestState)>& lambda); + StartRequestState GetStartRequestState(void); void ClearStartRequestState(void); void SetStartRequestState(StartRequestState state); diff --git a/system/audio_hal_interface/aidl/provider_info.cc b/system/audio_hal_interface/aidl/provider_info.cc new file mode 100644 index 0000000000000000000000000000000000000000..0829f9f589c90a03952606abcb2eb548ffaaef46 --- /dev/null +++ b/system/audio_hal_interface/aidl/provider_info.cc @@ -0,0 +1,78 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AIDLProviderInfo" + +#include "provider_info.h" + +#include +#include + +#include + +#include "client_interface_aidl.h" + +namespace bluetooth::audio::aidl { +using ::aidl::android::hardware::bluetooth::audio::CodecId; +using ::aidl::android::hardware::bluetooth::audio::CodecInfo; +using ::aidl::android::hardware::bluetooth::audio::SessionType; + +::hfp::sco_config recordHfpCodecInfo(CodecInfo codecInfo) { + auto hfp_transport = codecInfo.transport.get(); + ::hfp::sco_config config{ + .inputDataPath = hfp_transport.inputDataPath, + .outputDataPath = hfp_transport.outputDataPath, + .useControllerCodec = hfp_transport.useControllerCodec, + }; + return config; +} + +std::unique_ptr +bluetooth::audio::aidl::ProviderInfo::GetProviderInfo(SessionType sessionType) { + auto provider_info = + BluetoothAudioClientInterface::GetProviderInfo(sessionType); + + std::vector codecInfos; + if (provider_info.has_value()) { + codecInfos = std::move(provider_info->codecInfos); + } + + return std::make_unique(sessionType, std::move(codecInfos)); +} + +ProviderInfo::ProviderInfo(SessionType sessionType, + std::vector codecs) + : codecInfos(std::move(codecs)) { + for (auto codecInfo : codecInfos) { + if (codecInfo.id == CodecId::Core::CVSD) { + hfpScoConfigMap[UUID_CODEC_CVSD] = recordHfpCodecInfo(codecInfo); + } else if (codecInfo.id == CodecId::Core::MSBC) { + hfpScoConfigMap[UUID_CODEC_MSBC] = recordHfpCodecInfo(codecInfo); + } else if (codecInfo.id == CodecId::Core::LC3) { + if (sessionType == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH || + sessionType == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH || + sessionType == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) { + hfpScoConfigMap[UUID_CODEC_LC3] = recordHfpCodecInfo(codecInfo); + } + } + } +} + +const std::unordered_map& +ProviderInfo::GetHfpScoConfig() { + return hfpScoConfigMap; +} +} // namespace bluetooth::audio::aidl diff --git a/system/audio_hal_interface/aidl/provider_info.h b/system/audio_hal_interface/aidl/provider_info.h new file mode 100644 index 0000000000000000000000000000000000000000..443a93e800fd16a463f2d83159cb1f224578ebee --- /dev/null +++ b/system/audio_hal_interface/aidl/provider_info.h @@ -0,0 +1,46 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "audio_aidl_interfaces.h" +#include "bta/ag/bta_ag_int.h" + +namespace bluetooth::audio::aidl { + +using ::aidl::android::hardware::bluetooth::audio::CodecId; +using ::aidl::android::hardware::bluetooth::audio::CodecInfo; +using ::aidl::android::hardware::bluetooth::audio::SessionType; + +class ProviderInfo { + public: + static std::unique_ptr GetProviderInfo(SessionType sessionType); + + ProviderInfo(SessionType sessionType, std::vector codecs); + + ~ProviderInfo() = default; + + const std::unordered_map& GetHfpScoConfig(); + + private: + const std::vector codecInfos; + std::unordered_map + hfpScoConfigMap; +}; +} // namespace bluetooth::audio::aidl diff --git a/system/audio_hal_interface/fuzzer/Android.bp b/system/audio_hal_interface/fuzzer/Android.bp index 2528fa893cfec72c46871aa613f28eafe0df0a9b..a3c3d4e7678b25d2d9ac5011cded02717fc2395d 100644 --- a/system/audio_hal_interface/fuzzer/Android.bp +++ b/system/audio_hal_interface/fuzzer/Android.bp @@ -30,16 +30,11 @@ cc_defaults { "libbluetooth_headers", ], defaults: [ - "latest_android_hardware_bluetooth_audio_ndk_shared", + "latest_android_hardware_audio_common_ndk_static", + "latest_android_hardware_bluetooth_audio_ndk_static", + "latest_android_media_audio_common_types_ndk_static", ], shared_libs: [ - "android.hardware.bluetooth.a2dp@1.0", - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", - "android.hardware.bluetooth@1.0", - "android.hardware.bluetooth@1.1", - "android.system.suspend-V1-ndk", - "android.system.suspend.control-V1-ndk", "libPlatformProperties", "libaaudio", "libbinder_ndk", @@ -51,15 +46,27 @@ cc_defaults { "server_configurable_flags", ], static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.a2dp@1.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.bluetooth@1.0", + "android.hardware.bluetooth@1.1", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", + "android.system.suspend-V1-ndk", + "android.system.suspend.control-V1-ndk", "libFraunhoferAAC", "libaudio-a2dp-hw-utils", "libbase", "libbluetooth-dumpsys", + "libbluetooth-gdx", "libbluetooth-protos", "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbluetooth_rust_interop", "libbt-audio-hal-interface", "libbt-bta", @@ -67,6 +74,7 @@ cc_defaults { "libbt-btu-main-thread", "libbt-common", "libbt-hci", + "libbt-jni-thread", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", diff --git a/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp b/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp index 4f7954e01c1bf746d5ace0ae95d227de47a29766..baf77f98b8666b4fa85ec515d37bac43f4b9f92c 100644 --- a/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp +++ b/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp @@ -88,7 +88,7 @@ void A2dpEncodingFuzzer::process(const uint8_t* data, size_t size) { std::string name = fdp.ConsumeRandomLengthString(kRandomStringLength); bluetooth::common::MessageLoopThread messageLoopThread(name); messageLoopThread.StartUp(); - messageLoopThread.DoInThread(FROM_HERE, base::Bind(&source_init_delayed)); + messageLoopThread.DoInThread(FROM_HERE, base::BindOnce(&source_init_delayed)); uint16_t delayReport = fdp.ConsumeIntegral(); bluetooth::audio::a2dp::set_remote_delay(delayReport); @@ -107,7 +107,7 @@ void A2dpEncodingFuzzer::process(const uint8_t* data, size_t size) { bluetooth::audio::a2dp::ack_stream_started(status); for (auto offloadingPreference : CodecOffloadingPreferenceGenerator()) { - update_codec_offloading_capabilities(offloadingPreference); + update_codec_offloading_capabilities(offloadingPreference, false); } status = fdp.PickValueInArray(kCtrlAckStatus); bluetooth::audio::a2dp::ack_stream_suspended(status); 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 9f43485ed7be8556f0ce05d01352a4b97efe6eea..365897991af69935a948f793ce2944714d0a1fff 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 @@ -414,7 +414,7 @@ void ClientInterfaceFuzzer::process(const uint8_t* data, size_t size) { for (auto codec_offloading_preference : CodecOffloadingPreferenceGenerator()) { UpdateOffloadingCapabilities(codec_offloading_preference); - update_codec_offloading_capabilities(codec_offloading_preference); + update_codec_offloading_capabilities(codec_offloading_preference, false); } IsCodecOffloadingEnabled(codecConfig); } diff --git a/system/audio_hal_interface/fuzzer/libbt_audio_hal_hearing_aid_software_encoding_fuzzer.cpp b/system/audio_hal_interface/fuzzer/libbt_audio_hal_hearing_aid_software_encoding_fuzzer.cpp index 5b0215472a124bc91e6cbccb8aa890f36a62ecf9..4fc80f888e7d6ad52b93f9763f629b22d810fe7c 100644 --- a/system/audio_hal_interface/fuzzer/libbt_audio_hal_hearing_aid_software_encoding_fuzzer.cpp +++ b/system/audio_hal_interface/fuzzer/libbt_audio_hal_hearing_aid_software_encoding_fuzzer.cpp @@ -37,7 +37,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string name = fdp.ConsumeRandomLengthString(kRandomStringLength); bluetooth::common::MessageLoopThread messageLoopThread(name); messageLoopThread.StartUp(); - messageLoopThread.DoInThread(FROM_HERE, base::Bind(&source_init_delayed)); + messageLoopThread.DoInThread(FROM_HERE, base::BindOnce(&source_init_delayed)); uint16_t delay = fdp.ConsumeIntegral(); bluetooth::audio::hearing_aid::set_remote_delay(delay); diff --git a/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp b/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp index 4fa4c79cbfc9a601acd8b994a56e306c0ba252eb..fc7421f4254c9d72ba673f6185046a297a67bfce 100644 --- a/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp +++ b/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp @@ -55,7 +55,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string name = fdp.ConsumeRandomLengthString(kRandomStringLength); bluetooth::common::MessageLoopThread messageLoopThread(name); messageLoopThread.StartUp(); - messageLoopThread.DoInThread(FROM_HERE, base::Bind(&source_init_delayed)); + messageLoopThread.DoInThread(FROM_HERE, base::BindOnce(&source_init_delayed)); LeAudioClientInterface* interface = LeAudioClientInterface::Get(); diff --git a/system/audio_hal_interface/hal_version_manager.cc b/system/audio_hal_interface/hal_version_manager.cc index 275bbb067eef77e14bf33b5adaa062533cc7611d..36672cb32c69d31e00f00279e1c30234779bc75a 100644 --- a/system/audio_hal_interface/hal_version_manager.cc +++ b/system/audio_hal_interface/hal_version_manager.cc @@ -24,7 +24,8 @@ #include #include "aidl/audio_aidl_interfaces.h" -#include "osi/include/log.h" +#include "include/check.h" +#include "os/log.h" namespace bluetooth { namespace audio { @@ -35,16 +36,75 @@ using ::aidl::android::hardware::bluetooth::audio:: static const std::string kDefaultAudioProviderFactoryInterface = std::string() + IBluetoothAudioProviderFactory::descriptor + "/default"; +std::string toString(BluetoothAudioHalTransport transport) { + switch (transport) { + case BluetoothAudioHalTransport::UNKNOWN: + return "UNKNOWN"; + case BluetoothAudioHalTransport::HIDL: + return "HIDL"; + case BluetoothAudioHalTransport::AIDL: + return "AIDL"; + default: + return std::to_string(static_cast(transport)); + } +} + +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_UNAVAILABLE = + BluetoothAudioHalVersion(); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_0 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_1 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 1); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V1 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 1, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V2 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 2, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V3 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 3, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V4 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 4, 0); + +// Ideally HalVersionManager can be a singleton class std::unique_ptr HalVersionManager::instance_ptr = std::make_unique(); -BluetoothAudioHalVersion HalVersionManager::GetHalVersion() { - std::lock_guard guard(instance_ptr->mutex_); - return instance_ptr->hal_version_; +/** + * A singleton implementation to get the AIDL interface version. + */ +BluetoothAudioHalVersion GetAidlInterfaceVersion() { + static auto aidl_version = []() -> BluetoothAudioHalVersion { + int version = 0; + auto provider_factory = IBluetoothAudioProviderFactory::fromBinder( + ::ndk::SpAIBinder(AServiceManager_waitForService( + kDefaultAudioProviderFactoryInterface.c_str()))); + + if (provider_factory == nullptr) { + LOG_ERROR( + "getInterfaceVersion: Can't get aidl version from unknown factory"); + return BluetoothAudioHalVersion::VERSION_UNAVAILABLE; + } + + auto aidl_retval = provider_factory->getInterfaceVersion(&version); + if (!aidl_retval.isOk()) { + LOG_ERROR("BluetoothAudioHal::getInterfaceVersion failure: %s", + aidl_retval.getDescription().c_str()); + return BluetoothAudioHalVersion::VERSION_UNAVAILABLE; + } + + return BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, version, + 0); + }(); + + return aidl_version; } BluetoothAudioHalTransport HalVersionManager::GetHalTransport() { - return instance_ptr->hal_transport_; + return instance_ptr->hal_version_.getTransport(); +} + +BluetoothAudioHalVersion HalVersionManager::GetHalVersion() { + std::lock_guard guard(instance_ptr->mutex_); + return instance_ptr->hal_version_; } android::sp @@ -83,42 +143,6 @@ HalVersionManager::GetProvidersFactory_2_0() { return providers_factory; } -BluetoothAudioHalVersion GetAidlInterfaceVersion() { - int aidl_version = 0; - - auto provider_factory = IBluetoothAudioProviderFactory::fromBinder( - ::ndk::SpAIBinder(AServiceManager_waitForService( - kDefaultAudioProviderFactoryInterface.c_str()))); - - if (provider_factory == nullptr) { - LOG_ERROR("Can't get aidl version from unknown factory"); - return BluetoothAudioHalVersion::VERSION_UNAVAILABLE; - } - - auto aidl_retval = provider_factory->getInterfaceVersion(&aidl_version); - if (!aidl_retval.isOk()) { - LOG_ERROR("BluetoothAudioHal::getInterfaceVersion failure: %s", - aidl_retval.getDescription().c_str()); - return BluetoothAudioHalVersion::VERSION_UNAVAILABLE; - } - - switch (aidl_version) { - case 1: - return BluetoothAudioHalVersion::VERSION_AIDL_V1; - case 2: - return BluetoothAudioHalVersion::VERSION_AIDL_V2; - case 3: - return BluetoothAudioHalVersion::VERSION_AIDL_V3; - case 4: - return BluetoothAudioHalVersion::VERSION_AIDL_V4; - default: - LOG_ERROR("Unknown AIDL version %d", aidl_version); - return BluetoothAudioHalVersion::VERSION_UNAVAILABLE; - } - - return BluetoothAudioHalVersion::VERSION_UNAVAILABLE; -} - HalVersionManager::HalVersionManager() { hal_transport_ = BluetoothAudioHalTransport::UNKNOWN; if (AServiceManager_checkService( diff --git a/system/audio_hal_interface/hal_version_manager.h b/system/audio_hal_interface/hal_version_manager.h index f08cbe10aa5a0ef37ad601aa75008d5b0e60c513..8743219025b01937b256e5200670c853d953a59b 100644 --- a/system/audio_hal_interface/hal_version_manager.h +++ b/system/audio_hal_interface/hal_version_manager.h @@ -34,21 +34,83 @@ constexpr char kFullyQualifiedInterfaceName_2_0[] = constexpr char kFullyQualifiedInterfaceName_2_1[] = "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory"; -enum class BluetoothAudioHalVersion : uint8_t { - VERSION_UNAVAILABLE = 0, - VERSION_2_0, - VERSION_2_1, - VERSION_AIDL_V1, - VERSION_AIDL_V2, - VERSION_AIDL_V3, - VERSION_AIDL_V4, -}; - +/** + * The type of HAL transport, it's important to have + * BluetoothAudioHalTransport::HIDL value defined smaller than + * BluetoothAudioHalTransport::AIDL. + */ enum class BluetoothAudioHalTransport : uint8_t { // Uninit, default value UNKNOWN, - AIDL, HIDL, + AIDL, +}; + +std::string toString(BluetoothAudioHalTransport transport); + +/** + * A hal version class with built-in comparison operators. + */ +class BluetoothAudioHalVersion { + public: + BluetoothAudioHalVersion(BluetoothAudioHalTransport transport = + BluetoothAudioHalTransport::UNKNOWN, + uint16_t major = 0, uint16_t minor = 0) + : mTransport(transport), mMajor(major), mMinor(minor) {} + + bool isHIDL() const { return mTransport == BluetoothAudioHalTransport::HIDL; } + bool isAIDL() const { return mTransport == BluetoothAudioHalTransport::AIDL; } + + BluetoothAudioHalTransport getTransport() const { return mTransport; } + + inline bool operator!=(const BluetoothAudioHalVersion& rhs) const { + return std::tie(mTransport, mMajor, mMinor) != + std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor); + } + inline bool operator<(const BluetoothAudioHalVersion& rhs) const { + return std::tie(mTransport, mMajor, mMinor) < + std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor); + } + inline bool operator<=(const BluetoothAudioHalVersion& rhs) const { + return std::tie(mTransport, mMajor, mMinor) <= + std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor); + } + inline bool operator==(const BluetoothAudioHalVersion& rhs) const { + return std::tie(mTransport, mMajor, mMinor) == + std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor); + } + inline bool operator>(const BluetoothAudioHalVersion& rhs) const { + return std::tie(mTransport, mMajor, mMinor) > + std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor); + } + inline bool operator>=(const BluetoothAudioHalVersion& rhs) const { + return std::tie(mTransport, mMajor, mMinor) >= + std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor); + } + + inline std::string toString() const { + std::ostringstream os; + os << "BluetoothAudioHalVersion: {"; + os << "transport: " << bluetooth::audio::toString(mTransport); + os << ", major: " << std::to_string(mMajor); + os << ", minor: " << std::to_string(mMinor); + os << "}"; + return os.str(); + } + + /* Known HalVersion definitions */ + static const BluetoothAudioHalVersion VERSION_UNAVAILABLE; + static const BluetoothAudioHalVersion VERSION_2_0; + static const BluetoothAudioHalVersion VERSION_2_1; + static const BluetoothAudioHalVersion VERSION_AIDL_V1; + static const BluetoothAudioHalVersion VERSION_AIDL_V2; + static const BluetoothAudioHalVersion VERSION_AIDL_V3; + static const BluetoothAudioHalVersion VERSION_AIDL_V4; + + private: + BluetoothAudioHalTransport mTransport = BluetoothAudioHalTransport::UNKNOWN; + uint16_t mMajor = 0; + uint16_t mMinor = 0; }; class HalVersionManager { diff --git a/system/audio_hal_interface/hal_version_manager_host.cc b/system/audio_hal_interface/hal_version_manager_host.cc index 35aadbce98af6397825f80fbe0344dd34df8d72e..4cf8d80ba6e61c1abbd76ff2d04054746ddae870 100644 --- a/system/audio_hal_interface/hal_version_manager_host.cc +++ b/system/audio_hal_interface/hal_version_manager_host.cc @@ -19,6 +19,21 @@ namespace bluetooth { namespace audio { +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_UNAVAILABLE = + BluetoothAudioHalVersion(); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_0 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_1 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 1); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V1 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 1, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V2 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 2, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V3 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 3, 0); +const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V4 = + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 4, 0); + std::unique_ptr HalVersionManager::instance_ptr = nullptr; BluetoothAudioHalVersion HalVersionManager::GetHalVersion() { diff --git a/system/audio_hal_interface/hfp_client_interface.cc b/system/audio_hal_interface/hfp_client_interface.cc index 5613157786fbf5fc6bc3f0fe516a98d3996481d2..5a42fa29fb0a30a9d04f2d653c192108f13c3900 100644 --- a/system/audio_hal_interface/hfp_client_interface.cc +++ b/system/audio_hal_interface/hfp_client_interface.cc @@ -22,7 +22,7 @@ #include "aidl/hfp_client_interface_aidl.h" #include "hal_version_manager.h" #include "hfp_client_interface.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" using ::bluetooth::audio::aidl::hfp::HfpDecodingTransport; @@ -186,8 +186,42 @@ size_t HfpClientInterface::Decode::Read(uint8_t* p_buf, uint32_t len) { return get_decode_client_interface()->ReadAudioData(p_buf, len); } +void HfpClientInterface::Decode::ConfirmStreamingRequest() { + auto instance = aidl::hfp::HfpDecodingTransport::instance_; + auto pending_cmd = instance->GetPendingCmd(); + switch (pending_cmd) { + case aidl::hfp::HFP_CTRL_CMD_START: + aidl::hfp::HfpDecodingTransport::software_hal_interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED); + instance->ResetPendingCmd(); + return; + case aidl::hfp::HFP_CTRL_CMD_NONE: + LOG_WARN("no pending start stream request"); + return; + default: + LOG_WARN("Invalid state, %d", pending_cmd); + } +} + +void HfpClientInterface::Decode::CancelStreamingRequest() { + auto instance = aidl::hfp::HfpDecodingTransport::instance_; + auto pending_cmd = instance->GetPendingCmd(); + switch (pending_cmd) { + case aidl::hfp::HFP_CTRL_CMD_START: + aidl::hfp::HfpDecodingTransport::software_hal_interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::FAILURE); + instance->ResetPendingCmd(); + return; + case aidl::hfp::HFP_CTRL_CMD_NONE: + LOG_WARN("no pending start stream request"); + return; + default: + LOG_WARN("Invalid state, %d", pending_cmd); + } +} + HfpClientInterface::Decode* HfpClientInterface::GetDecode( - bluetooth::common::MessageLoopThread* message_loop) { + bluetooth::common::MessageLoopThread* /*message_loop*/) { if (!is_aidl_support_hfp()) { LOG(WARNING) << __func__ << ": Unsupported HIDL or AIDL version"; return nullptr; @@ -206,7 +240,7 @@ HfpClientInterface::Decode* HfpClientInterface::GetDecode( aidl::SessionType::HFP_SOFTWARE_DECODING_DATAPATH); HfpDecodingTransport::software_hal_interface = new aidl::BluetoothAudioSinkClientInterface( - HfpDecodingTransport::instance_, message_loop); + HfpDecodingTransport::instance_); if (!HfpDecodingTransport::software_hal_interface->IsValid()) { LOG(WARNING) << __func__ << ": BluetoothAudio HAL for HFP is invalid"; delete HfpDecodingTransport::software_hal_interface; @@ -300,8 +334,42 @@ size_t HfpClientInterface::Encode::Write(const uint8_t* p_buf, uint32_t len) { return get_encode_client_interface()->WriteAudioData(p_buf, len); } +void HfpClientInterface::Encode::ConfirmStreamingRequest() { + auto instance = aidl::hfp::HfpEncodingTransport::instance_; + auto pending_cmd = instance->GetPendingCmd(); + switch (pending_cmd) { + case aidl::hfp::HFP_CTRL_CMD_START: + aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED); + instance->ResetPendingCmd(); + return; + case aidl::hfp::HFP_CTRL_CMD_NONE: + LOG_WARN("no pending start stream request"); + return; + default: + LOG_WARN("Invalid state, %d", pending_cmd); + } +} + +void HfpClientInterface::Encode::CancelStreamingRequest() { + auto instance = aidl::hfp::HfpEncodingTransport::instance_; + auto pending_cmd = instance->GetPendingCmd(); + switch (pending_cmd) { + case aidl::hfp::HFP_CTRL_CMD_START: + aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::FAILURE); + instance->ResetPendingCmd(); + return; + case aidl::hfp::HFP_CTRL_CMD_NONE: + LOG_WARN("no pending start stream request"); + return; + default: + LOG_WARN("Invalid state, %d", pending_cmd); + } +} + HfpClientInterface::Encode* HfpClientInterface::GetEncode( - bluetooth::common::MessageLoopThread* message_loop) { + bluetooth::common::MessageLoopThread* /*message_loop*/) { if (!is_aidl_support_hfp()) { LOG(WARNING) << __func__ << ": Unsupported HIDL or AIDL version"; return nullptr; @@ -320,7 +388,7 @@ HfpClientInterface::Encode* HfpClientInterface::GetEncode( aidl::SessionType::HFP_SOFTWARE_ENCODING_DATAPATH); HfpEncodingTransport::software_hal_interface = new aidl::BluetoothAudioSourceClientInterface( - HfpEncodingTransport::instance_, message_loop); + HfpEncodingTransport::instance_); if (!HfpEncodingTransport::software_hal_interface->IsValid()) { LOG(WARNING) << __func__ << ": BluetoothAudio HAL for HFP is invalid"; delete HfpEncodingTransport::software_hal_interface; @@ -404,8 +472,48 @@ void HfpClientInterface::Offload::UpdateAudioConfigToHal( offload_config_to_hal_audio_config(offload_config)); } +void HfpClientInterface::Offload::ConfirmStreamingRequest() { + auto instance = aidl::hfp::HfpEncodingTransport::instance_; + auto pending_cmd = instance->GetPendingCmd(); + switch (pending_cmd) { + case aidl::hfp::HFP_CTRL_CMD_START: + aidl::hfp::HfpEncodingTransport::offloading_hal_interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED); + instance->ResetPendingCmd(); + return; + case aidl::hfp::HFP_CTRL_CMD_NONE: + LOG_WARN("no pending start stream request"); + return; + default: + LOG_WARN("Invalid state, %d", pending_cmd); + } +} + +void HfpClientInterface::Offload::CancelStreamingRequest() { + auto instance = aidl::hfp::HfpEncodingTransport::instance_; + auto pending_cmd = instance->GetPendingCmd(); + switch (pending_cmd) { + case aidl::hfp::HFP_CTRL_CMD_START: + aidl::hfp::HfpEncodingTransport::offloading_hal_interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::FAILURE); + instance->ResetPendingCmd(); + return; + case aidl::hfp::HFP_CTRL_CMD_NONE: + LOG_WARN("no pending start stream request"); + return; + default: + LOG_WARN("Invalid state, %d", pending_cmd); + } +} + +std::unordered_map +HfpClientInterface::Offload::GetHfpScoConfig() { + return aidl::hfp::HfpTransport::GetHfpScoConfig( + aidl::SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH); +} + HfpClientInterface::Offload* HfpClientInterface::GetOffload( - bluetooth::common::MessageLoopThread* message_loop) { + bluetooth::common::MessageLoopThread* /*message_loop*/) { if (!is_aidl_support_hfp()) { LOG(WARNING) << __func__ << ": Unsupported HIDL or AIDL version"; return nullptr; @@ -426,7 +534,7 @@ HfpClientInterface::Offload* HfpClientInterface::GetOffload( aidl::SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH); HfpEncodingTransport::offloading_hal_interface = new aidl::BluetoothAudioSourceClientInterface( - HfpEncodingTransport::instance_, message_loop); + HfpEncodingTransport::instance_); if (!HfpEncodingTransport::offloading_hal_interface->IsValid()) { LOG(FATAL) << __func__ << ": BluetoothAudio HAL for HFP offloading is invalid"; diff --git a/system/audio_hal_interface/hfp_client_interface.h b/system/audio_hal_interface/hfp_client_interface.h index 0f52b06acc865aacd36ef82bd79207c3d6be8085..081f9cc57c244a88df79f91468b56e3469937938 100644 --- a/system/audio_hal_interface/hfp_client_interface.h +++ b/system/audio_hal_interface/hfp_client_interface.h @@ -37,6 +37,8 @@ class HfpClientInterface { virtual void StopSession() = 0; virtual void UpdateAudioConfigToHal( const ::hfp::offload_config& config) = 0; + virtual void ConfirmStreamingRequest() = 0; + virtual void CancelStreamingRequest() = 0; }; public: @@ -49,6 +51,8 @@ class HfpClientInterface { void StartSession() override; void StopSession() override; void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override; + void ConfirmStreamingRequest() override; + void CancelStreamingRequest() override; size_t Read(uint8_t* p_buf, uint32_t len); }; @@ -60,6 +64,8 @@ class HfpClientInterface { void StartSession() override; void StopSession() override; void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override; + void ConfirmStreamingRequest() override; + void CancelStreamingRequest() override; size_t Write(const uint8_t* p_buf, uint32_t len); }; @@ -71,6 +77,9 @@ class HfpClientInterface { void StartSession() override; void StopSession() override; void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override; + void ConfirmStreamingRequest() override; + void CancelStreamingRequest() override; + std::unordered_map GetHfpScoConfig(); }; // Get HFP software decoding client interface if it's not previously acquired diff --git a/system/audio_hal_interface/hfp_client_interface_host.cc b/system/audio_hal_interface/hfp_client_interface_host.cc new file mode 100644 index 0000000000000000000000000000000000000000..86872d65928814f0d7138cc720bcb1c365ad82c3 --- /dev/null +++ b/system/audio_hal_interface/hfp_client_interface_host.cc @@ -0,0 +1,59 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hfp_client_interface.h" + +namespace bluetooth { +namespace audio { +namespace hfp { + +HfpClientInterface::Decode* HfpClientInterface::GetDecode( + bluetooth::common::MessageLoopThread* message_loop) { + return nullptr; +} + +bool HfpClientInterface::ReleaseDecode(HfpClientInterface::Decode* decode) { + return false; +} + +HfpClientInterface::Encode* HfpClientInterface::GetEncode( + bluetooth::common::MessageLoopThread* message_loop) { + return nullptr; +} + +bool HfpClientInterface::ReleaseEncode(HfpClientInterface::Encode* encode) { + return false; +} + +HfpClientInterface::Offload* HfpClientInterface::GetOffload( + bluetooth::common::MessageLoopThread* message_loop) { + return nullptr; +} + +bool HfpClientInterface::ReleaseOffload(HfpClientInterface::Offload* offload) { + return false; +} + +HfpClientInterface* HfpClientInterface::Get() { return nullptr; } + +std::unordered_map +HfpClientInterface::Offload::GetHfpScoConfig() { + return std::unordered_map(); +} + +} // namespace hfp +} // namespace audio +} // namespace bluetooth diff --git a/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc b/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc index e0118b813ecde99bea14f825816d63c60f422f3c..77d3a434ed505b9584ede142e55beaae097ac789 100644 --- a/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc +++ b/system/audio_hal_interface/hidl/a2dp_encoding_hidl.cc @@ -17,14 +17,15 @@ #include "a2dp_encoding_hidl.h" +#include + #include "a2dp_sbc_constants.h" -#include "btif_a2dp_source.h" -#include "btif_av.h" -#include "btif_av_co.h" -#include "btif_hf.h" +#include "btif/include/btif_a2dp_source.h" +#include "btif/include/btif_av.h" +#include "btif/include/btif_av_co.h" +#include "btif/include/btif_hf.h" #include "client_interface_hidl.h" #include "codec_status_hidl.h" -#include "osi/include/log.h" #include "osi/include/properties.h" #include "types/raw_address.h" diff --git a/system/audio_hal_interface/hidl/client_interface_hidl.cc b/system/audio_hal_interface/hidl/client_interface_hidl.cc index 4f70dc3abfc1a6b79a0e1629ba5b96532c6e350d..6c510915ecc6e219a128b8989e470a8ef37e815b 100644 --- a/system/audio_hal_interface/hidl/client_interface_hidl.cc +++ b/system/audio_hal_interface/hidl/client_interface_hidl.cc @@ -23,10 +23,11 @@ #include #include +#include #include "common/stop_watch_legacy.h" #include "hal_version_manager.h" -#include "osi/include/log.h" +#include "include/check.h" namespace bluetooth { namespace audio { 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 7f45cb050e6ba1acb12ba060c5b4b687a49bf8bf..59c7982563d1ea0623ed81aeb4be35af687951e3 100644 --- a/system/audio_hal_interface/hidl/client_interface_hidl_unittest.cc +++ b/system/audio_hal_interface/hidl/client_interface_hidl_unittest.cc @@ -20,6 +20,8 @@ #include +#include + #include "codec_status_hidl.h" namespace { diff --git a/system/audio_hal_interface/hidl/codec_status_hidl.cc b/system/audio_hal_interface/hidl/codec_status_hidl.cc index a5a43480ce7b4694b3fc484e9502660090325c36..b79e9ff4037182f62a4251aad8c2f6e1b007d950 100644 --- a/system/audio_hal_interface/hidl/codec_status_hidl.cc +++ b/system/audio_hal_interface/hidl/codec_status_hidl.cc @@ -18,6 +18,8 @@ #include "codec_status_hidl.h" +#include + #include "a2dp_aac_constants.h" #include "a2dp_sbc_constants.h" #include "a2dp_vendor_aptx_constants.h" 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 9599cc940d977e6348e9ce107247aeb37f52de51..48abb4a5b9678d6bcdba393882fcf227e0e0d3cb 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 @@ -20,7 +20,7 @@ #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h" #include "client_interface_hidl.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" namespace { 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 d938c695dd5b40b86a403a77ade644000093ff66..8362dc5edde186e3a9b67a8cb6720eff676ba13b 100644 --- a/system/audio_hal_interface/hidl/le_audio_software_hidl.cc +++ b/system/audio_hal_interface/hidl/le_audio_software_hidl.cc @@ -19,7 +19,7 @@ #include "le_audio_software_hidl.h" -#include "osi/include/log.h" +#include "os/log.h" namespace bluetooth { namespace audio { @@ -134,6 +134,32 @@ BluetoothAudioCtrlAck LeAudioTransport::StartRequest() { return BluetoothAudioCtrlAck::FAILURE; } +BluetoothAudioCtrlAck LeAudioTransport::StartRequestV2() { + SetStartRequestState(StartRequestState::PENDING_BEFORE_RESUME); + if (stream_cb_.on_resume_(true)) { + std::lock_guard guard(start_request_state_mutex_); + if (start_request_state_ == StartRequestState::CONFIRMED) { + LOG_INFO("Start completed."); + SetStartRequestState(StartRequestState::IDLE); + return BluetoothAudioCtrlAck::SUCCESS_FINISHED; + } + + if (start_request_state_ == StartRequestState::CANCELED) { + LOG_INFO("Start request failed."); + SetStartRequestState(StartRequestState::IDLE); + return BluetoothAudioCtrlAck::FAILURE; + } + + LOG_INFO("Start pending."); + SetStartRequestState(StartRequestState::PENDING_AFTER_RESUME); + return BluetoothAudioCtrlAck::PENDING; + } + + LOG_ERROR("Start request failed."); + SetStartRequestState(StartRequestState::IDLE); + return BluetoothAudioCtrlAck::FAILURE; +} + BluetoothAudioCtrlAck LeAudioTransport::SuspendRequest() { LOG(INFO) << __func__; if (stream_cb_.on_suspend_()) { @@ -227,6 +253,23 @@ void LeAudioTransport::LeAudioSetSelectedHalPcmConfig(uint32_t sample_rate_hz, pcm_config_.dataIntervalUs = data_interval; } +bool LeAudioTransport::IsRequestCompletedAfterUpdate( + const std::function(StartRequestState)>& + lambda) { + std::lock_guard guard(start_request_state_mutex_); + auto result = lambda(start_request_state_); + auto new_state = std::get<0>(result); + if (new_state != start_request_state_) { + start_request_state_ = new_state; + } + + auto ret = std::get<1>(result); + LOG_VERBOSE("new state: %d, return: %s", + static_cast(start_request_state_.load()), + ret ? "true" : "false"); + return ret; +} + StartRequestState LeAudioTransport::GetStartRequestState(void) { return start_request_state_; } @@ -255,6 +298,9 @@ LeAudioSinkTransport::LeAudioSinkTransport(SessionType_2_1 session_type, LeAudioSinkTransport::~LeAudioSinkTransport() { delete transport_; } BluetoothAudioCtrlAck LeAudioSinkTransport::StartRequest() { + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + return transport_->StartRequestV2(); + } return transport_->StartRequest(); } @@ -299,6 +345,12 @@ void LeAudioSinkTransport::LeAudioSetSelectedHalPcmConfig( channels_count, data_interval); } +bool LeAudioSinkTransport::IsRequestCompletedAfterUpdate( + const std::function(StartRequestState)>& + lambda) { + return transport_->IsRequestCompletedAfterUpdate(lambda); +} + StartRequestState LeAudioSinkTransport::GetStartRequestState(void) { return transport_->GetStartRequestState(); } @@ -327,6 +379,9 @@ LeAudioSourceTransport::LeAudioSourceTransport(SessionType_2_1 session_type, LeAudioSourceTransport::~LeAudioSourceTransport() { delete transport_; } BluetoothAudioCtrlAck LeAudioSourceTransport::StartRequest() { + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + return transport_->StartRequestV2(); + } return transport_->StartRequest(); } @@ -371,6 +426,11 @@ void LeAudioSourceTransport::LeAudioSetSelectedHalPcmConfig( channels_count, data_interval); } +bool LeAudioSourceTransport::IsRequestCompletedAfterUpdate( + const std::function(StartRequestState)>& + lambda) { + return transport_->IsRequestCompletedAfterUpdate(lambda); +} StartRequestState LeAudioSourceTransport::GetStartRequestState(void) { return transport_->GetStartRequestState(); } 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 80051f8d0ae8c53c8723c5bfaa39fac556f41771..058888b1ecfd7f2910cea5494b323637398def76 100644 --- a/system/audio_hal_interface/hidl/le_audio_software_hidl.h +++ b/system/audio_hal_interface/hidl/le_audio_software_hidl.h @@ -60,6 +60,7 @@ class LeAudioTransport { PcmParameters pcm_config); BluetoothAudioCtrlAck StartRequest(); + BluetoothAudioCtrlAck StartRequestV2(); BluetoothAudioCtrlAck SuspendRequest(); @@ -83,6 +84,10 @@ class LeAudioTransport { uint8_t channels_count, uint32_t data_interval); + bool IsRequestCompletedAfterUpdate( + const std::function< + std::pair(StartRequestState)>& lambda); + StartRequestState GetStartRequestState(void); void ClearStartRequestState(void); void SetStartRequestState(StartRequestState state); @@ -94,6 +99,7 @@ class LeAudioTransport { uint64_t total_bytes_processed_; timespec data_position_; PcmParameters pcm_config_; + mutable std::mutex start_request_state_mutex_; std::atomic start_request_state_; }; @@ -106,6 +112,7 @@ class LeAudioSinkTransport ~LeAudioSinkTransport(); BluetoothAudioCtrlAck StartRequest() override; + BluetoothAudioCtrlAck StartRequestV2(); BluetoothAudioCtrlAck SuspendRequest() override; @@ -129,6 +136,10 @@ class LeAudioSinkTransport uint8_t channels_count, uint32_t data_interval); + bool IsRequestCompletedAfterUpdate( + const std::function< + std::pair(StartRequestState)>& lambda); + StartRequestState GetStartRequestState(void); void ClearStartRequestState(void); void SetStartRequestState(StartRequestState state); @@ -172,6 +183,9 @@ class LeAudioSourceTransport uint8_t channels_count, uint32_t data_interval); + bool IsRequestCompletedAfterUpdate( + const std::function< + std::pair(StartRequestState)>& lambda); StartRequestState GetStartRequestState(void); void ClearStartRequestState(void); void SetStartRequestState(StartRequestState state); diff --git a/system/audio_hal_interface/le_audio_software.cc b/system/audio_hal_interface/le_audio_software.cc index 50844ffd71c9844ec4e9c7813b17236442ccf567..9ec3b214073c0ce80af2743909a8046834db0db4 100644 --- a/system/audio_hal_interface/le_audio_software.cc +++ b/system/audio_hal_interface/le_audio_software.cc @@ -19,6 +19,8 @@ #include "le_audio_software.h" +#include + #include #include @@ -26,7 +28,7 @@ #include "bta/le_audio/codec_manager.h" #include "hal_version_manager.h" #include "hidl/le_audio_software_hidl.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" namespace bluetooth { @@ -260,6 +262,44 @@ void LeAudioClientInterface::Sink::ConfirmStreamingRequest() { } } +void LeAudioClientInterface::Sink::ConfirmStreamingRequestV2() { + auto lambda = [&](StartRequestState currect_start_request_state) + -> std::pair { + switch (currect_start_request_state) { + case StartRequestState::IDLE: + LOG_WARN(", no pending start stream request"); + return std::make_pair(StartRequestState::IDLE, false); + case StartRequestState::PENDING_BEFORE_RESUME: + LOG_INFO("Response before sending PENDING to audio HAL"); + return std::make_pair(StartRequestState::CONFIRMED, false); + case StartRequestState::PENDING_AFTER_RESUME: + LOG_INFO("Response after sending PENDING to audio HAL"); + return std::make_pair(StartRequestState::IDLE, true); + case StartRequestState::CONFIRMED: + case StartRequestState::CANCELED: + LOG_ERROR("Invalid state, start stream already confirmed"); + return std::make_pair(currect_start_request_state, false); + } + }; + + if (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::HIDL) { + auto hidl_instance = hidl::le_audio::LeAudioSinkTransport::instance; + if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) { + hidl::le_audio::LeAudioSinkTransport::interface->StreamStarted( + hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED); + } + + return; + } + + auto aidl_instance = get_aidl_transport_instance(is_broadcaster_); + if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) { + get_aidl_client_interface(is_broadcaster_) + ->StreamStarted(aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED); + } +} + void LeAudioClientInterface::Sink::CancelStreamingRequest() { if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) { @@ -309,6 +349,55 @@ void LeAudioClientInterface::Sink::CancelStreamingRequest() { } } +void LeAudioClientInterface::Sink::CancelStreamingRequestV2() { + if (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::HIDL) { + auto hidl_instance = hidl::le_audio::LeAudioSinkTransport::instance; + auto start_request_state = hidl_instance->GetStartRequestState(); + switch (start_request_state) { + case StartRequestState::IDLE: + LOG_WARN(", no pending start stream request"); + return; + case StartRequestState::PENDING_BEFORE_RESUME: + LOG_INFO("Response before sending PENDING to audio HAL"); + hidl_instance->SetStartRequestState(StartRequestState::CANCELED); + return; + case StartRequestState::PENDING_AFTER_RESUME: + LOG_INFO("Response after sending PENDING to audio HAL"); + hidl_instance->ClearStartRequestState(); + hidl::le_audio::LeAudioSinkTransport::interface->StreamStarted( + hidl::BluetoothAudioCtrlAck::FAILURE); + return; + case StartRequestState::CONFIRMED: + case StartRequestState::CANCELED: + LOG_ERROR("Invalid state, start stream already confirmed"); + break; + } + } + + auto aidl_instance = get_aidl_transport_instance(is_broadcaster_); + auto start_request_state = aidl_instance->GetStartRequestState(); + switch (start_request_state) { + case StartRequestState::IDLE: + LOG_WARN(", no pending start stream request"); + return; + case StartRequestState::PENDING_BEFORE_RESUME: + LOG_INFO("Response before sending PENDING to audio HAL"); + aidl_instance->SetStartRequestState(StartRequestState::CANCELED); + return; + case StartRequestState::PENDING_AFTER_RESUME: + LOG_INFO("Response after sending PENDING to audio HAL"); + aidl_instance->ClearStartRequestState(); + get_aidl_client_interface(is_broadcaster_) + ->StreamStarted(aidl::BluetoothAudioCtrlAck::FAILURE); + return; + case StartRequestState::CONFIRMED: + case StartRequestState::CANCELED: + LOG_ERROR("Invalid state, start stream already confirmed"); + break; + } +} + void LeAudioClientInterface::Sink::StopSession() { LOG(INFO) << __func__ << " sink"; if (HalVersionManager::GetHalTransport() == @@ -547,6 +636,44 @@ void LeAudioClientInterface::Source::ConfirmStreamingRequest() { } } +void LeAudioClientInterface::Source::ConfirmStreamingRequestV2() { + auto lambda = [&](StartRequestState currect_start_request_state) + -> std::pair { + switch (currect_start_request_state) { + case StartRequestState::IDLE: + LOG_WARN(", no pending start stream request"); + return std::make_pair(StartRequestState::IDLE, false); + case StartRequestState::PENDING_BEFORE_RESUME: + LOG_INFO("Response before sending PENDING to audio HAL"); + return std::make_pair(StartRequestState::CONFIRMED, false); + case StartRequestState::PENDING_AFTER_RESUME: + LOG_INFO("Response after sending PENDING to audio HAL"); + return std::make_pair(StartRequestState::IDLE, true); + case StartRequestState::CONFIRMED: + case StartRequestState::CANCELED: + LOG_ERROR("Invalid state, start stream already confirmed"); + return std::make_pair(currect_start_request_state, false); + } + }; + + if (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::HIDL) { + auto hidl_instance = hidl::le_audio::LeAudioSourceTransport::instance; + + if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) { + hidl::le_audio::LeAudioSourceTransport::interface->StreamStarted( + hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED); + } + return; + } + + auto aidl_instance = aidl::le_audio::LeAudioSourceTransport::instance; + if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) { + aidl::le_audio::LeAudioSourceTransport::interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED); + } +} + void LeAudioClientInterface::Source::CancelStreamingRequest() { if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) { @@ -596,6 +723,43 @@ void LeAudioClientInterface::Source::CancelStreamingRequest() { } } +void LeAudioClientInterface::Source::CancelStreamingRequestV2() { + auto lambda = [&](StartRequestState currect_start_request_state) + -> std::pair { + switch (currect_start_request_state) { + case StartRequestState::IDLE: + LOG_WARN(", no pending start stream request"); + return std::make_pair(StartRequestState::IDLE, false); + case StartRequestState::PENDING_BEFORE_RESUME: + LOG_INFO("Response before sending PENDING to audio HAL"); + return std::make_pair(StartRequestState::CANCELED, false); + case StartRequestState::PENDING_AFTER_RESUME: + LOG_INFO("Response after sending PENDING to audio HAL"); + return std::make_pair(StartRequestState::IDLE, true); + case StartRequestState::CONFIRMED: + case StartRequestState::CANCELED: + LOG_ERROR("Invalid state, start stream already confirmed"); + return std::make_pair(currect_start_request_state, false); + } + }; + + if (HalVersionManager::GetHalTransport() == + BluetoothAudioHalTransport::HIDL) { + auto hidl_instance = hidl::le_audio::LeAudioSourceTransport::instance; + if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) { + hidl::le_audio::LeAudioSourceTransport::interface->StreamStarted( + hidl::BluetoothAudioCtrlAck::FAILURE); + } + return; + } + + auto aidl_instance = aidl::le_audio::LeAudioSourceTransport::instance; + if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) { + aidl::le_audio::LeAudioSourceTransport::interface->StreamStarted( + aidl::BluetoothAudioCtrlAck::FAILURE); + } +} + void LeAudioClientInterface::Source::StopSession() { LOG(INFO) << __func__ << " source"; if (HalVersionManager::GetHalTransport() == @@ -702,8 +866,7 @@ LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink( std::move(stream_cb)); aidl::le_audio::LeAudioSinkTransport::interface_unicast_ = new aidl::BluetoothAudioSinkClientInterface( - aidl::le_audio::LeAudioSinkTransport::instance_unicast_, - message_loop); + aidl::le_audio::LeAudioSinkTransport::instance_unicast_); if (!aidl::le_audio::LeAudioSinkTransport::interface_unicast_ ->IsValid()) { LOG(WARNING) << __func__ @@ -723,8 +886,7 @@ LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink( std::move(stream_cb)); aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ = new aidl::BluetoothAudioSinkClientInterface( - aidl::le_audio::LeAudioSinkTransport::instance_broadcast_, - message_loop); + aidl::le_audio::LeAudioSinkTransport::instance_broadcast_); if (!aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ ->IsValid()) { LOG(WARNING) << __func__ @@ -830,7 +992,7 @@ LeAudioClientInterface::Source* LeAudioClientInterface::GetSource( std::move(stream_cb)); aidl::le_audio::LeAudioSourceTransport::interface = new aidl::BluetoothAudioSourceClientInterface( - aidl::le_audio::LeAudioSourceTransport::instance, message_loop); + aidl::le_audio::LeAudioSourceTransport::instance); if (!aidl::le_audio::LeAudioSourceTransport::interface->IsValid()) { LOG(WARNING) << __func__ << ": BluetoothAudio HAL for Le Audio is invalid?!"; @@ -870,13 +1032,23 @@ bool LeAudioClientInterface::ReleaseSource( } void LeAudioClientInterface::SetAllowedDsaModes(DsaModes dsa_modes) { + if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + return; + } + if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL) { - std::vector latency_modes; + if (aidl::le_audio::LeAudioSinkTransport::interface_unicast_ == nullptr || + aidl::le_audio::LeAudioSinkTransport::instance_unicast_ == nullptr) { + LOG(WARNING) << __func__ << ": LeAudioSourceTransport::interface is null"; + return; + } + + std::vector latency_modes = {LatencyMode::FREE}; for (auto dsa_mode : dsa_modes) { switch (dsa_mode) { case DsaMode::DISABLED: - latency_modes.push_back(LatencyMode::FREE); + // Already added break; case DsaMode::ACL: latency_modes.push_back(LatencyMode::LOW_LATENCY); @@ -892,12 +1064,8 @@ void LeAudioClientInterface::SetAllowedDsaModes(DsaModes dsa_modes) { break; } } - if (aidl::le_audio::LeAudioSourceTransport::interface) { - aidl::le_audio::LeAudioSourceTransport::interface->SetAllowedLatencyModes( - latency_modes); - } else { - LOG(WARNING) << "LeAudioSourceTransport::interface is null"; - } + aidl::le_audio::LeAudioSinkTransport::interface_unicast_ + ->SetAllowedLatencyModes(latency_modes); } } diff --git a/system/audio_hal_interface/le_audio_software.h b/system/audio_hal_interface/le_audio_software.h index 4544387abb720a2e68ae90378fcd76790744ce54..56c6f75ad2c0e72dc8758e167e97e2c69b9068ed 100644 --- a/system/audio_hal_interface/le_audio_software.h +++ b/system/audio_hal_interface/le_audio_software.h @@ -22,6 +22,8 @@ #include #endif +#include + #include #include "bta/le_audio/codec_manager.h" @@ -87,6 +89,8 @@ class LeAudioClientInterface { virtual void StopSession() = 0; virtual void ConfirmStreamingRequest() = 0; virtual void CancelStreamingRequest() = 0; + virtual void ConfirmStreamingRequestV2() = 0; + virtual void CancelStreamingRequestV2() = 0; virtual void UpdateAudioConfigToHal( const ::le_audio::offload_config& config) = 0; virtual void SuspendedForReconfiguration() = 0; @@ -106,6 +110,8 @@ class LeAudioClientInterface { void StopSession() override; void ConfirmStreamingRequest() override; void CancelStreamingRequest() override; + void ConfirmStreamingRequestV2() override; + void CancelStreamingRequestV2() override; void UpdateAudioConfigToHal( const ::le_audio::offload_config& config) override; void UpdateBroadcastAudioConfigToHal( @@ -130,6 +136,8 @@ class LeAudioClientInterface { void StopSession() override; void ConfirmStreamingRequest() override; void CancelStreamingRequest() override; + void ConfirmStreamingRequestV2() override; + void CancelStreamingRequestV2() override; void UpdateAudioConfigToHal( const ::le_audio::offload_config& config) override; void SuspendedForReconfiguration() override; diff --git a/system/audio_hearing_aid_hw/Android.bp b/system/audio_hearing_aid_hw/Android.bp index 920bfa7a0b8f5d0a09067a8c92ef2a5ed9f50fb8..8c7c865c7498be58f8cefbb5d634adb4093189b8 100644 --- a/system/audio_hearing_aid_hw/Android.bp +++ b/system/audio_hearing_aid_hw/Android.bp @@ -34,7 +34,10 @@ cc_library { shared_libs: [ "liblog", ], - static_libs: ["libosi"], + static_libs: [ + "libbluetooth_log", + "libosi", + ], } // Audio A2DP library unit tests for target and host @@ -53,6 +56,7 @@ cc_test { ], static_libs: [ "audio.hearing_aid.default", + "libbluetooth_log", "libosi", ], min_sdk_version: "29", diff --git a/system/bta/Android.bp b/system/bta/Android.bp index b3c47939031a55b40120cb600f36f1556dd918c1..6919b1a9390ad0a3bb4da527fee5fe17fd9888f9 100644 --- a/system/bta/Android.bp +++ b/system/bta/Android.bp @@ -21,9 +21,7 @@ cc_defaults { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/btif/avrcp", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/btm", "packages/modules/Bluetooth/system/stack/include", "packages/modules/Bluetooth/system/udrv/include", @@ -32,7 +30,6 @@ cc_defaults { generated_headers: [ "BluetoothGeneratedDumpsysDataSchema_h", ], - cflags: ["-DBUILDCFG"], } filegroup { @@ -100,9 +97,7 @@ cc_library_static { "hh/bta_hh_le.cc", "hh/bta_hh_main.cc", "hh/bta_hh_utils.cc", - "le_audio/audio_hal_client/asrc_tables.cc", "le_audio/audio_hal_client/audio_sink_hal_client.cc", - "le_audio/audio_hal_client/audio_source_hal_asrc.cc", "le_audio/audio_hal_client/audio_source_hal_client.cc", "le_audio/broadcaster/broadcaster.cc", "le_audio/broadcaster/broadcaster_types.cc", @@ -136,19 +131,22 @@ cc_library_static { "-fvisibility=default", ], static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", "avrcp-target-service", + "bluetooth_flags_c_lib", "lib-bt-packets", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", + "libbt-audio-asrc", "libbt-bta-core", "libbt-platform-protos-lite", "libbt_shim_bridge", "libcom.android.sysprop.bluetooth.wrapped", "liblc3", ], - shared_libs: [ - "android.hardware.bluetooth.audio@2.1", - ], generated_headers: [ "LeAudioSetConfigSchemas_h", ], @@ -206,9 +204,13 @@ cc_library_static { "bluetooth_flags_c_lib", "lib-bt-packets", "libbase", + "libbluetooth_hci_pdl", + "libbluetooth_log", + "libbt-audio-hal-interface", "libbt-platform-protos-lite", "libbt_shim_bridge", "libcom.android.sysprop.bluetooth.wrapped", + "libflatbuffers-cpp", "server_configurable_flags", ], apex_available: [ @@ -222,6 +224,9 @@ cc_test { name: "net_test_bta", defaults: [ "fluoride_bta_defaults", + "latest_android_hardware_audio_common_ndk_static", + "latest_android_hardware_bluetooth_audio_ndk_static", + "latest_android_media_audio_common_types_ndk_static", "mts_defaults", ], test_suites: ["general-tests"], @@ -232,9 +237,11 @@ cc_test { ":TestCommonMockFunctions", ":TestCommonSyncMainHandler", ":TestFakeOsi", + ":TestMockAudioHalInterface", ":TestMockBtif", ":TestMockDevice", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackA2dp", ":TestMockStackAcl", ":TestMockStackAvct", @@ -267,20 +274,26 @@ cc_test { "BluetoothGeneratedDumpsysDataSchema_h", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", - "libbase", "libcrypto", "libcutils", + "libhidlbase", "liblog", + "libutils", "server_configurable_flags", ], static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", "bluetooth_flags_c_lib", + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", @@ -295,6 +308,7 @@ cc_test { "libcom.android.sysprop.bluetooth.wrapped", "libevent", "libflagtest", + "libfmq", "libgmock", "server_configurable_flags", ], @@ -304,7 +318,22 @@ cc_test { ":audio_set_scenarios_bfbs", ":audio_set_scenarios_json", ], - cflags: ["-Wno-unused-parameter"], + cflags: [ + "-Wno-macro-redefined", + "-Wno-unused-parameter", + ], + target: { + android: { + shared_libs: [ + "libbinder_ndk", + ], + }, + host: { + static_libs: [ + "libbinder_ndk", + ], + }, + }, } // bta GATT unit tests @@ -322,6 +351,7 @@ cc_test { ":TestMockBtif", ":TestMockDevice", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackBtm", ":TestMockStackL2cap", ":TestMockStackMetrics", @@ -333,14 +363,18 @@ cc_test { "BluetoothGeneratedDumpsysDataSchema_h", ], shared_libs: [ + "libbase", "libcrypto", "liblog", + "server_configurable_flags", ], static_libs: [ + "bluetooth_flags_c_lib", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", @@ -372,18 +406,20 @@ cc_test { "test/bta_hf_client_security_test.cc", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", + "libbase", "libcrypto", "libcutils", "liblog", "libprotobuf-cpp-lite", "libstatssocket", + "server_configurable_flags", ], static_libs: [ + "bluetooth_flags_c_lib", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", @@ -433,9 +469,12 @@ cc_test { "libcrypto", "libcutils", "liblog", + "server_configurable_flags", ], static_libs: [ + "bluetooth_flags_c_lib", "libbluetooth-types", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -454,7 +493,7 @@ cc_test { }, target: { android: { - whole_static_libs: [ + static_libs: [ "libPlatformProperties", ], }, @@ -476,7 +515,6 @@ cc_test { "packages/modules/Bluetooth/system/bta/groups", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/test/common", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/osi/include", ], srcs: [ @@ -503,6 +541,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -544,6 +583,7 @@ cc_test { "groups/groups_test.cc", ], shared_libs: [ + "libbase", "libcrypto", "liblog", ], @@ -551,6 +591,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -602,6 +643,7 @@ cc_test { "vc/vc_test.cc", ], shared_libs: [ + "libbase", "libcrypto", "liblog", ], @@ -609,6 +651,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -713,7 +756,7 @@ cc_test { sanitize: { misc_undefined: ["bounds"], }, - whole_static_libs: [ + static_libs: [ "libPlatformProperties", ], }, @@ -722,7 +765,6 @@ cc_test { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/test/common", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/stack/include", ], @@ -748,8 +790,6 @@ cc_test { "LeAudioSetConfigSchemas_h", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libcrypto", "libhidlbase", "liblog", // __android_log_print @@ -758,6 +798,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -790,7 +831,7 @@ cc_test { sanitize: { misc_undefined: ["bounds"], }, - whole_static_libs: [ + static_libs: [ "libPlatformProperties", ], }, @@ -799,7 +840,6 @@ cc_test { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/test/common", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/stack/include", ], @@ -807,11 +847,11 @@ cc_test { ":TestCommonMockFunctions", ":TestMockBtaLeAudioHalVerifier", ":TestMockMainShim", + ":TestMockMainShimEntry", + ":TestMockStackL2cap", ":TestStubOsi", - "le_audio/audio_hal_client/asrc_tables.cc", "le_audio/audio_hal_client/audio_hal_client_test.cc", "le_audio/audio_hal_client/audio_sink_hal_client.cc", - "le_audio/audio_hal_client/audio_source_hal_asrc.cc", "le_audio/audio_hal_client/audio_source_hal_client.cc", "le_audio/client_parser.cc", "le_audio/client_parser_test.cc", @@ -851,8 +891,6 @@ cc_test { "LeAudioSetConfigSchemas_h", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libcrypto", "libhidlbase", "liblog", // __android_log_print @@ -862,6 +900,8 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", + "libbt-audio-asrc", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -899,6 +939,8 @@ cc_test { ":TestCommonMockFunctions", ":TestMockBtaLeAudioHalVerifier", ":TestMockMainShim", + ":TestMockMainShimEntry", + ":TestMockStackL2cap", ":TestStubOsi", "gatt/database.cc", "gatt/database_builder.cc", @@ -930,12 +972,8 @@ cc_test { "test/common/mock_device_groups.cc", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libbase", - "libbinder_ndk", "libcrypto", - "libfmq", "libhidlbase", "liblog", "server_configurable_flags", @@ -944,6 +982,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-common", "libbt-platform-protos-lite", @@ -968,10 +1007,18 @@ cc_test { ], target: { android: { - whole_static_libs: [ + shared_libs: [ + "libbinder_ndk", + ], + static_libs: [ "libPlatformProperties", ], }, + host: { + static_libs: [ + "libbinder_ndk", + ], + }, }, sanitize: { cfi: true, @@ -1000,15 +1047,14 @@ cc_test { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/le_audio", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/stack/btm", "packages/modules/Bluetooth/system/stack/include", ], srcs: [ ":TestCommonMockFunctions", ":TestCommonStackConfig", + ":TestMockMainShim", "le_audio/broadcaster/broadcaster_types.cc", - "le_audio/broadcaster/mock_ble_advertising_manager.cc", "le_audio/broadcaster/state_machine.cc", "le_audio/broadcaster/state_machine_test.cc", "le_audio/le_audio_types.cc", @@ -1024,12 +1070,16 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", + "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", + "libflatbuffers-cpp", "libgmock", "liblc3", + "libosi", ], sanitize: { cfi: true, @@ -1057,7 +1107,6 @@ cc_test { "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/le_audio", "packages/modules/Bluetooth/system/bta/test/common", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/stack/btm", "packages/modules/Bluetooth/system/stack/include", ], @@ -1068,7 +1117,6 @@ cc_test { "le_audio/broadcaster/broadcaster.cc", "le_audio/broadcaster/broadcaster_test.cc", "le_audio/broadcaster/broadcaster_types.cc", - "le_audio/broadcaster/mock_ble_advertising_manager.cc", "le_audio/broadcaster/mock_state_machine.cc", "le_audio/content_control_id_keeper.cc", "le_audio/le_audio_types.cc", @@ -1080,8 +1128,6 @@ cc_test { "test/common/mock_controller.cc", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libbinder_ndk", "libcrypto", "libfmq", @@ -1090,6 +1136,7 @@ cc_test { ], static_libs: [ "libbluetooth-types", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-common", "libbt_shim_bridge", @@ -1148,6 +1195,7 @@ cc_test { "test/common/mock_csis_client.cc", ], shared_libs: [ + "libbase", "libcrypto", "liblog", ], @@ -1155,6 +1203,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -1195,11 +1244,13 @@ cc_test { ":TestCommonMainHandler", ":TestCommonMockFunctions", ":TestMockBtaGatt", + ":TestMockBtaLeAudio", ":TestMockBtaSdp", ":TestMockBtaSys", ":TestMockBtif", ":TestMockDevice", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockOsi", ":TestMockStack", "gatt/bta_gattc_queue.cc", @@ -1222,6 +1273,7 @@ cc_test { "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -1247,37 +1299,3 @@ cc_test { }, cflags: ["-Wno-unused-parameter"], } - -cc_library_host_shared { - name: "libasrc_resampler_test", - defaults: ["bluetooth_cflags"], - srcs: [ - "le_audio/audio_hal_client/asrc_resampler_test.cc", - "le_audio/audio_hal_client/asrc_tables.cc", - ], - static_libs: [ - "libchrome", - "libflatbuffers-cpp", - ], - stl: "libc++_static", - include_dirs: [ - "packages/modules/Bluetooth/system", - "packages/modules/Bluetooth/system/gd", - ], - generated_headers: [ - "BluetoothGeneratedDumpsysDataSchema_h", - ], -} - -python_test_host { - name: "asrc_resampler_test", - main: "le_audio/audio_hal_client/asrc_resampler_test.py", - srcs: ["le_audio/audio_hal_client/asrc_resampler_test.py"], - libs: ["mobly"], - data: [":libasrc_resampler_test"], - test_config: "le_audio/audio_hal_client/asrc_resampler_test.config", - test_suites: ["general-tests"], - test_options: { - unit_test: false, - }, -} diff --git a/system/bta/BUILD.gn b/system/bta/BUILD.gn index f2b16d3066932faa1292c5cb33a95c05f5bc1c47..18187047ff42233d50bab21779bf8a4dd17ec45d 100644 --- a/system/bta/BUILD.gn +++ b/system/bta/BUILD.gn @@ -89,9 +89,7 @@ static_library("bta") { "jv/bta_jv_act.cc", "jv/bta_jv_api.cc", "jv/bta_jv_cfg.cc", - "le_audio/audio_hal_client/asrc_tables.cc", "le_audio/audio_hal_client/audio_sink_hal_client.cc", - "le_audio/audio_hal_client/audio_source_hal_asrc.cc", "le_audio/audio_hal_client/audio_source_hal_client.cc", "le_audio/broadcaster/broadcaster.cc", "le_audio/broadcaster/broadcaster_types.cc", @@ -140,8 +138,6 @@ static_library("bta") { "//bt/system/linux_include", "//bt/system/bta", "//bt/system/gd", - "//bt/system/internal_include", - "//bt/system/internal_include", "//bt/system/stack/include", "//bt/system/stack/btm", "//bt/system/udrv/include", @@ -155,10 +151,12 @@ static_library("bta") { ] configs += [ - "//bt/system:target_defaults" + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", ] deps = [ + "//bt/system/audio:libbt-audio-asrc", "//bt/system/bta:LeAudioSetScenariosSchema_bfbs", "//bt/system/bta:LeAudioSetConfigsSchema_bfbs", "//bt/system/bta:install_audio_set_scenarios_json", @@ -225,7 +223,6 @@ if (use.test) { "include", "//bt/system/", "//bt/system/bta", - "//bt/system/internal_include", "//bt/system/stack/btm", ] diff --git a/system/bta/ag/bta_ag_act.cc b/system/bta/ag/bta_ag_act.cc index 40896c172c63565552b4d8a06d0460bbf1eee265..92310678c01fd43f366ad4a9ede2f1f085e0c26f 100644 --- a/system/bta/ag/bta_ag_act.cc +++ b/system/bta/ag/bta_ag_act.cc @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -32,6 +33,7 @@ #include "bta/include/bta_dm_api.h" #include "bta/include/bta_hfp_api.h" #include "bta_ag_swb_aptx.h" +#include "internal_include/bt_trace.h" #ifdef __ANDROID__ #include "bta/le_audio/devices.h" @@ -45,8 +47,10 @@ #include "stack/include/l2c_api.h" #include "stack/include/port_api.h" #include "stack/include/sdp_api.h" +#include "storage/config_keys.h" #include "types/raw_address.h" +using namespace bluetooth; using namespace bluetooth::legacy::stack::sdp; /***************************************************************************** @@ -224,7 +228,7 @@ void bta_ag_start_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { void bta_ag_disc_int_res(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { uint16_t event = BTA_AG_DISC_FAIL_EVT; - LOG_VERBOSE("bta_ag_disc_int_res: Status: %d", data.disc_result.status); + log::verbose("bta_ag_disc_int_res: Status: {}", data.disc_result.status); /* if found service */ if (data.disc_result.status == SDP_SUCCESS || @@ -333,7 +337,7 @@ void bta_ag_disc_fail(tBTA_AG_SCB* p_scb, ******************************************************************************/ void bta_ag_open_fail(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { /* call open cback w. failure */ - LOG_DEBUG("state [0x%02x]", p_scb->state); + log::debug("state [0x{:02x}]", p_scb->state); bta_ag_cback_open(p_scb, data.api_open.bd_addr, BTA_AG_FAIL_RESOURCES); } @@ -394,6 +398,7 @@ void bta_ag_rfc_close(tBTA_AG_SCB* p_scb, /* Clear these flags upon SLC teardown */ p_scb->codec_updated = false; p_scb->codec_fallback = false; + p_scb->retransmission_effort_retries = 0; p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; p_scb->codec_aptx_settings = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0; p_scb->is_aptx_swb_codec = false; @@ -484,15 +489,15 @@ void bta_ag_rfc_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { if (p_scb->conn_service == BTA_AG_HFP) { size_t version_value_size = sizeof(p_scb->peer_version); if (!btif_config_get_bin( - p_scb->peer_addr.ToString(), HFP_VERSION_CONFIG_KEY, + p_scb->peer_addr.ToString(), BTIF_STORAGE_KEY_HFP_VERSION, (uint8_t*)&p_scb->peer_version, &version_value_size)) { - LOG_WARN("%s: Failed read cached peer HFP version for %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); + log::warn("Failed read cached peer HFP version for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); p_scb->peer_version = HFP_HSP_VERSION_UNKNOWN; } size_t sdp_features_size = sizeof(p_scb->peer_sdp_features); if (btif_config_get_bin( - p_scb->peer_addr.ToString(), HFP_SDP_FEATURES_CONFIG_KEY, + p_scb->peer_addr.ToString(), BTIF_STORAGE_KEY_HFP_SDP_FEATURES, (uint8_t*)&p_scb->peer_sdp_features, &sdp_features_size)) { bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT; if (!p_scb->received_at_bac && sdp_wbs_support) { @@ -507,8 +512,8 @@ void bta_ag_rfc_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { p_scb->sco_codec = BTM_SCO_CODEC_LC3; } } else { - LOG_WARN("%s: Failed read cached peer HFP SDP features for %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); + log::warn("Failed read cached peer HFP SDP features for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); } } @@ -545,8 +550,8 @@ void bta_ag_rfc_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { * ******************************************************************************/ void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { - LOG_VERBOSE("%s: serv_handle0 = %d serv_handle = %d", __func__, - p_scb->serv_handle[0], p_scb->serv_handle[1]); + log::verbose("serv_handle0 = {} serv_handle = {}", p_scb->serv_handle[0], + p_scb->serv_handle[1]); /* set role */ p_scb->role = BTA_AG_ACP; @@ -556,7 +561,7 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { RawAddress dev_addr = RawAddress::kEmpty; int status = PORT_CheckConnection(data.rfc.port_handle, &dev_addr, &lcid); if (status != PORT_SUCCESS) { - LOG(ERROR) << __func__ << ", PORT_CheckConnection returned " << status; + log::error("PORT_CheckConnection returned {}", status); return; } @@ -564,8 +569,8 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { for (tBTA_AG_SCB& ag_scb : bta_ag_cb.scb) { // Cancel any pending collision timers if (ag_scb.in_use && alarm_is_scheduled(ag_scb.collision_timer)) { - VLOG(1) << __func__ << ": cancel collision alarm for " - << ag_scb.peer_addr; + log::verbose("cancel collision alarm for {}", + ADDRESS_TO_LOGGABLE_STR(ag_scb.peer_addr)); alarm_cancel(ag_scb.collision_timer); if (dev_addr != ag_scb.peer_addr && p_scb != &ag_scb) { // Resume outgoing connection if incoming is not on the same device @@ -573,33 +578,36 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { } } if (dev_addr == ag_scb.peer_addr && p_scb != &ag_scb) { - VLOG(1) << __func__ << ": fail outgoing connection before accepting " - << ag_scb.peer_addr; - // Fail the outgoing connection to clean up any upper layer states - bta_ag_rfc_fail(&ag_scb, tBTA_AG_DATA::kEmpty); + log::info( + "close outgoing connection before accepting {} with conn_handle={}", + ADDRESS_TO_LOGGABLE_STR(ag_scb.peer_addr), ag_scb.conn_handle); + if (!IS_FLAG_ENABLED(close_rfcomm_instead_of_reset)) { + // Fail the outgoing connection to clean up any upper layer states + bta_ag_rfc_fail(&ag_scb, tBTA_AG_DATA::kEmpty); + } // If client port is opened, close it if (ag_scb.conn_handle > 0) { status = RFCOMM_RemoveConnection(ag_scb.conn_handle); if (status != PORT_SUCCESS) { - LOG(WARNING) << __func__ << ": RFCOMM_RemoveConnection failed for " - << dev_addr << ", handle " - << std::to_string(ag_scb.conn_handle) << ", error " - << status; + log::warn( + "RFCOMM_RemoveConnection failed for {}, handle {}, error {}", + ADDRESS_TO_LOGGABLE_STR(dev_addr), ag_scb.conn_handle, status); } } } - VLOG(1) << __func__ << ": dev_addr=" << dev_addr - << ", peer_addr=" << ag_scb.peer_addr - << ", in_use=" << ag_scb.in_use - << ", index=" << bta_ag_scb_to_idx(p_scb); + log::info("dev_addr={}, peer_addr={}, in_use={}, index={}", + ADDRESS_TO_LOGGABLE_STR(dev_addr), + ADDRESS_TO_LOGGABLE_STR(ag_scb.peer_addr), ag_scb.in_use, + bta_ag_scb_to_idx(p_scb)); } p_scb->peer_addr = dev_addr; /* determine connected service from port handle */ for (uint8_t i = 0; i < BTA_AG_NUM_IDX; i++) { - LOG_VERBOSE("bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d", - i, p_scb->serv_handle[i], data.rfc.port_handle); + log::verbose( + "bta_ag_rfc_acp_open: i = {} serv_handle = {} port_handle = {}", i, + p_scb->serv_handle[i], data.rfc.port_handle); if (p_scb->serv_handle[i] == data.rfc.port_handle) { p_scb->conn_service = i; @@ -608,17 +616,17 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { } } - LOG_VERBOSE("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d", - p_scb->conn_service, p_scb->conn_handle); + log::verbose("bta_ag_rfc_acp_open: conn_service = {} conn_handle = {}", + p_scb->conn_service, p_scb->conn_handle); /* close any unopened server */ bta_ag_close_servers( p_scb, (p_scb->reg_services & ~bta_ag_svc_mask[p_scb->conn_service])); size_t version_value_size = sizeof(hfp_version); - bool get_version = - btif_config_get_bin(p_scb->peer_addr.ToString(), HFP_VERSION_CONFIG_KEY, - (uint8_t*)&hfp_version, &version_value_size); + bool get_version = btif_config_get_bin( + p_scb->peer_addr.ToString(), BTIF_STORAGE_KEY_HFP_VERSION, + (uint8_t*)&hfp_version, &version_value_size); if (p_scb->conn_service == BTA_AG_HFP && get_version) { DEVICE_IOT_CONFIG_ADDR_SET_HEX_IF_GREATER(p_scb->peer_addr, @@ -646,20 +654,21 @@ void bta_ag_rfc_data(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { uint16_t len; char buf[BTA_AG_RFC_READ_MAX] = ""; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* do the following */ for (;;) { /* read data from rfcomm; if bad status, we're done */ if (PORT_ReadData(p_scb->conn_handle, buf, BTA_AG_RFC_READ_MAX, &len) != PORT_SUCCESS) { - LOG(ERROR) << __func__ << ": failed to read data " << p_scb->peer_addr; + log::error("failed to read data {}", + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); break; } /* if no data, we're done */ if (len == 0) { - LOG(WARNING) << __func__ << ": no data for " << p_scb->peer_addr; + log::warn("no data for {}", ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); break; } @@ -668,7 +677,7 @@ void bta_ag_rfc_data(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { bta_ag_at_parse(&p_scb->at_cb, buf, len); if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) && bta_ag_sco_is_open(p_scb)) { - LOG_VERBOSE("%s change link policy for SCO", __func__); + log::verbose("change link policy for SCO"); bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); } else { bta_sys_idle(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); @@ -848,8 +857,8 @@ void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { tBTA_AG_VAL val = {}; const bool aptx_voice = is_hfp_aptx_voice_enabled() && (codec_type == BTA_AG_SCO_APTX_SWB_SETTINGS_Q0); - LOG_VERBOSE("aptx_voice=%s, codec_type=%#x", logbool(aptx_voice).c_str(), - codec_type); + log::verbose("aptx_voice={}, codec_type={:#x}", logbool(aptx_voice), + codec_type); val.hdr.handle = bta_ag_scb_to_idx(p_scb); @@ -860,7 +869,7 @@ void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { !aptx_voice) { val.num = codec_type; val.hdr.status = BTA_AG_FAIL_RESOURCES; - LOG_ERROR("bta_ag_setcodec error: unsupported codec type %d", codec_type); + log::error("bta_ag_setcodec error: unsupported codec type {}", codec_type); (*bta_ag_cb.p_cback)(BTA_AG_CODEC_EVT, (tBTA_AG*)&val); return; } @@ -871,11 +880,11 @@ void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { p_scb->codec_updated = true; val.num = codec_type; val.hdr.status = BTA_AG_SUCCESS; - LOG_VERBOSE("bta_ag_setcodec: Updated codec type %d", codec_type); + log::verbose("bta_ag_setcodec: Updated codec type {}", codec_type); } else { val.num = codec_type; val.hdr.status = BTA_AG_FAIL_RESOURCES; - LOG_ERROR("bta_ag_setcodec error: unsupported codec type %d", codec_type); + log::error("bta_ag_setcodec error: unsupported codec type {}", codec_type); } (*bta_ag_cb.p_cback)(BTA_AG_CODEC_EVT, (tBTA_AG*)&val); @@ -883,7 +892,7 @@ void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { static void bta_ag_collision_timer_cback(void* data) { if (data == nullptr) { - LOG(ERROR) << __func__ << ": data should never be null in a timer callback"; + log::error("data should never be null in a timer callback"); return; } /* If the peer haven't opened AG connection */ diff --git a/system/bta/ag/bta_ag_api.cc b/system/bta/ag/bta_ag_api.cc index 980e13bda4697a49f589e9829e86834ea3e582f0..7db4adf9a72846a0846f9b41ef1927ee17a7681a 100644 --- a/system/bta/ag/bta_ag_api.cc +++ b/system/bta/ag/bta_ag_api.cc @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -37,6 +38,8 @@ #include "stack/include/main_thread.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants ****************************************************************************/ @@ -61,7 +64,7 @@ tBTA_STATUS BTA_AgEnable(tBTA_AG_CBACK* p_cback) { /* Error if AG is already enabled, or AG is in the middle of disabling. */ for (const tBTA_AG_SCB& scb : bta_ag_cb.scb) { if (scb.in_use) { - LOG_ERROR("BTA_AgEnable: FAILED, AG already enabled."); + log::error("BTA_AgEnable: FAILED, AG already enabled."); return BTA_FAILURE; } } diff --git a/system/bta/ag/bta_ag_at.cc b/system/bta/ag/bta_ag_at.cc index a3ff49aa830a5560b515a0bb2e25410a9d52ade6..df7acbd1437ac764df756ee04d1e68b46b577150 100644 --- a/system/bta/ag/bta_ag_at.cc +++ b/system/bta/ag/bta_ag_at.cc @@ -23,15 +23,19 @@ ******************************************************************************/ #define LOG_TAG "bta_ag_at" -#include +#include "bta/ag/bta_ag_at.h" -#include "bt_target.h" // Must be first to define build configuration: +#include + +#include -#include "bta/ag/bta_ag_at.h" #include "bta/ag/bta_ag_int.h" #include "bta/include/utl.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" + +using namespace bluetooth; /***************************************************************************** * Constants @@ -138,7 +142,7 @@ void bta_ag_process_at(tBTA_AG_AT_CB* p_cb, char* p_end) { if (int_arg < (int16_t)p_cb->p_at_tbl[idx].min || int_arg > (int16_t)p_cb->p_at_tbl[idx].max) { /* arg out of range; error */ - LOG_WARN("arg out of range"); + log::warn("arg out of range"); (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, false, nullptr); } else { (*p_cb->p_cmd_cback)((tBTA_AG_SCB*)p_cb->p_user, @@ -152,13 +156,13 @@ void bta_ag_process_at(tBTA_AG_AT_CB* p_cb, char* p_end) { } } else { /* else error */ - LOG_WARN("Incoming arg type 0x%x does not match cmd arg type 0x%x", - arg_type, p_cb->p_at_tbl[idx].arg_type); + log::warn("Incoming arg type 0x{:x} does not match cmd arg type 0x{:x}", + arg_type, p_cb->p_at_tbl[idx].arg_type); (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, false, nullptr); } } else { /* else no match call error callback */ - LOG_WARN("Unmatched command index %d", idx); + log::warn("Unmatched command index {}", idx); (*p_cb->p_err_cback)((tBTA_AG_SCB*)p_cb->p_user, true, p_cb->p_cmd_buf); } } diff --git a/system/bta/ag/bta_ag_cfg.cc b/system/bta/ag/bta_ag_cfg.cc index 99e5faa9843746c718d4f27732a69f4112946254..446a07be5c95827cb3263027494107f96687fc77 100644 --- a/system/bta/ag/bta_ag_cfg.cc +++ b/system/bta/ag/bta_ag_cfg.cc @@ -41,13 +41,11 @@ #define BTA_AG_CONN_TIMEOUT 5000 #endif -#ifndef BTA_AG_SCO_PKT_TYPES /* S1 packet type setting from HFP 1.5 spec */ #define BTA_AG_SCO_PKT_TYPES /* BTM_SCO_LINK_ALL_PKT_MASK */ \ (BTM_SCO_LINK_ONLY_MASK | ESCO_PKT_TYPES_MASK_EV3 | \ ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 | \ ESCO_PKT_TYPES_MASK_NO_3_EV5) -#endif #ifndef BTA_AG_BIND_INFO #define BTA_AG_BIND_INFO "(1)" diff --git a/system/bta/ag/bta_ag_cmd.cc b/system/bta/ag/bta_ag_cmd.cc index 07308c958e3b70761e52ad05e2f9d78c6eed7600..cea6374049277f87353304fc1359821bc0529df2 100644 --- a/system/bta/ag/bta_ag_cmd.cc +++ b/system/bta/ag/bta_ag_cmd.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -27,6 +28,7 @@ #include "bta/ag/bta_ag_at.h" #include "bta/ag/bta_ag_int.h" #include "bta/include/bta_ag_api.h" +#include "bta/include/bta_hfp_api.h" #include "bta/include/utl.h" #include "bta_ag_swb_aptx.h" @@ -45,6 +47,8 @@ #include "stack/btm/btm_sco_hfp_hal.h" #include "stack/include/port_api.h" +using namespace bluetooth; + /***************************************************************************** * Constants ****************************************************************************/ @@ -226,7 +230,7 @@ static void bta_ag_send_result(tBTA_AG_SCB* p_scb, size_t code, const char* p_arg, int16_t int_arg) { const tBTA_AG_RESULT* result = bta_ag_result_by_code(code); if (result == nullptr) { - LOG_ERROR("%s Unable to lookup result for code %zu", __func__, code); + log::error("Unable to lookup result for code {}", code); return; } @@ -490,7 +494,7 @@ static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB* p_scb, char* p_s, retval |= BTM_SCO_CODEC_LC3; break; default: - LOG_ERROR("Unknown Codec UUID(%d) received", uuid_codec); + log::error("Unknown Codec UUID({}) received", uuid_codec); break; } @@ -602,8 +606,8 @@ void bta_ag_send_call_inds(tBTA_AG_SCB* p_scb, tBTA_AG_RES result) { void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t command_id, uint8_t arg_type, char* p_arg, char* p_end, int16_t int_arg) { - LOG_VERBOSE("AT cmd:%d arg_type:%d arg:%d arg:%s", command_id, arg_type, - int_arg, p_arg); + log::verbose("AT cmd:{} arg_type:{} arg:{} arg:{}", command_id, arg_type, + int_arg, p_arg); bta_ag_send_ok(p_scb); @@ -613,7 +617,7 @@ void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t command_id, val.num = (uint16_t)int_arg; if ((p_end - p_arg + 1) >= (long)sizeof(val.str)) { - LOG_ERROR("%s: p_arg is too long, send error and return", __func__); + log::error("p_arg is too long, send error and return"); bta_ag_send_error(p_scb, BTA_AG_ERR_TEXT_TOO_LONG); return; } @@ -621,7 +625,7 @@ void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t command_id, /* call callback with event */ if (command_id & 0xff00) { - LOG_WARN("Received value that exceeds data type - lost information"); + log::warn("Received value that exceeds data type - lost information"); } tBTA_AG_EVT event = static_cast(command_id); (*bta_ag_cb.p_cback)(event, (tBTA_AG*)&val); @@ -698,12 +702,12 @@ static bool bta_ag_parse_bind_set(tBTA_AG_SCB* p_scb, tBTA_AG_VAL val) { uint16_t rcv_ind_id = atoi(p_token); int index = bta_ag_find_empty_hf_ind(p_scb); if (index == -1) { - LOG_WARN("%s Can't save more indicators", __func__); + log::warn("Can't save more indicators"); return false; } p_scb->peer_hf_indicators[index].ind_id = rcv_ind_id; - LOG_VERBOSE("%s peer_hf_ind[%d] = %d", __func__, index, rcv_ind_id); + log::verbose("peer_hf_ind[{}] = {}", index, rcv_ind_id); p_token = strtok(nullptr, ","); } @@ -747,7 +751,7 @@ static void bta_ag_bind_response(tBTA_AG_SCB* p_scb, uint8_t arg_type) { /* bta_ag_local_hf_ind_cfg[0].ind_id is used as BTA_AG_NUM_LOCAL_HF_IND */ for (uint32_t i = 0; i < bta_ag_local_hf_ind_cfg[0].ind_id; i++) { if (i == BTA_AG_MAX_NUM_LOCAL_HF_IND) { - LOG_WARN("%s No space for more HF indicators", __func__); + log::warn("No space for more HF indicators"); break; } @@ -808,12 +812,11 @@ static bool bta_ag_parse_biev_response(tBTA_AG_SCB* p_scb, tBTA_AG_VAL* val) { if (p_token == nullptr) return false; uint16_t rcv_ind_val = atoi(p_token); - LOG_VERBOSE("%s BIEV indicator id %d, value %d", __func__, rcv_ind_id, - rcv_ind_val); + log::verbose("BIEV indicator id {}, value {}", rcv_ind_id, rcv_ind_val); /* Check whether indicator ID is valid or not */ if (rcv_ind_id > BTA_AG_NUM_LOCAL_HF_IND) { - LOG_WARN("%s received invalid indicator id %d", __func__, rcv_ind_id); + log::warn("received invalid indicator id {}", rcv_ind_id); return false; } @@ -823,15 +826,14 @@ static bool bta_ag_parse_biev_response(tBTA_AG_SCB* p_scb, tBTA_AG_VAL* val) { if (local_index == -1 || !p_scb->local_hf_indicators[local_index].is_supported || !p_scb->local_hf_indicators[local_index].is_enable) { - LOG_WARN("%s indicator id %d not supported or disabled", __func__, - rcv_ind_id); + log::warn("indicator id {} not supported or disabled", rcv_ind_id); return false; } /* For each indicator ID, check whether the indicator value is in range */ if (rcv_ind_val < bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_min_val || rcv_ind_val > bta_ag_local_hf_ind_cfg[rcv_ind_id].ind_max_val) { - LOG_WARN("%s invalid ind_val %d", __func__, rcv_ind_val); + log::warn("invalid ind_val {}", rcv_ind_val); return false; } @@ -873,13 +875,13 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, uint32_t i, ind_id; uint32_t bia_masked_out; if (p_arg == nullptr) { - LOG_WARN("p_arg is null for cmd 0x%x, send error and return", cmd); + log::warn("p_arg is null for cmd 0x{:x}, send error and return", cmd); bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_TSTR); return; } - LOG_VERBOSE("%s: AT command %d, arg_type %d, int_arg %d, arg %s", __func__, - cmd, arg_type, int_arg, p_arg); + log::verbose("AT command {}, arg_type {}, int_arg {}, arg {}", cmd, arg_type, + int_arg, p_arg); val.hdr.handle = bta_ag_scb_to_idx(p_scb); val.hdr.app_id = p_scb->app_id; @@ -888,7 +890,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, val.bd_addr = p_scb->peer_addr; if ((p_end - p_arg + 1) >= (long)sizeof(val.str)) { - LOG_ERROR("p_arg is too long for cmd 0x%x, send error and return", cmd); + log::error("p_arg is too long for cmd 0x{:x}, send error and return", cmd); bta_ag_send_error(p_scb, BTA_AG_ERR_TEXT_TOO_LONG); return; } @@ -1037,7 +1039,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, break; case BTA_AG_AT_BIND_EVT: - LOG_VERBOSE("%s BTA_AG_AT_BIND_EVT arg_type: %d", __func__, arg_type); + log::verbose("BTA_AG_AT_BIND_EVT arg_type: {}", arg_type); alarm_cancel(p_scb->bind_timer); if (arg_type == BTA_AG_AT_SET) { if (bta_ag_parse_bind_set(p_scb, val)) { @@ -1137,8 +1139,8 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, p_scb->masked_features &= HFP_1_6_FEAT_MASK; } - LOG_VERBOSE("%s BRSF HF: 0x%x, phone: 0x%x", __func__, - p_scb->peer_features, p_scb->masked_features); + log::verbose("BRSF HF: 0x{:x}, phone: 0x{:x}", p_scb->peer_features, + p_scb->masked_features); /* send BRSF, send OK */ bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_BRSF, nullptr, @@ -1150,6 +1152,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, case BTA_AG_AT_NREC_EVT: /* if feature send OK, else don't call callback, send ERROR */ if (p_scb->features & BTA_AG_FEAT_ECNR) { + p_scb->nrec_enabled = (val.num == 1); bta_ag_send_ok(p_scb); } else { event = BTA_AG_ENABLE_EVT; @@ -1260,23 +1263,22 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, bool swb_supported = hfp_hal_interface::get_swb_supported(); const bool aptx_voice = is_hfp_aptx_voice_enabled() && p_scb->is_aptx_swb_codec; - LOG_VERBOSE("BTA_AG_AT_BAC_EVT aptx_voice=%s", - logbool(aptx_voice).c_str()); + log::verbose("BTA_AG_AT_BAC_EVT aptx_voice={}", logbool(aptx_voice)); if (swb_supported && (p_scb->peer_codecs & BTM_SCO_CODEC_LC3) && !(p_scb->disabled_codecs & BTM_SCO_CODEC_LC3)) { p_scb->sco_codec = BTM_SCO_CODEC_LC3; - LOG_VERBOSE("Received AT+BAC, updating sco codec to LC3"); + log::verbose("Received AT+BAC, updating sco codec to LC3"); } else if (aptx_voice) { p_scb->sco_codec = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0; - LOG_VERBOSE("Received AT+BAC, updating sco codec to AptX Voice"); + log::verbose("Received AT+BAC, updating sco codec to AptX Voice"); } else if (wbs_supported && (p_scb->peer_codecs & BTM_SCO_CODEC_MSBC) && !(p_scb->disabled_codecs & BTM_SCO_CODEC_MSBC)) { p_scb->sco_codec = BTM_SCO_CODEC_MSBC; - LOG_VERBOSE("Received AT+BAC, updating sco codec to MSBC"); + log::verbose("Received AT+BAC, updating sco codec to MSBC"); } else { p_scb->sco_codec = BTM_SCO_CODEC_CVSD; - LOG_VERBOSE("Received AT+BAC, updating sco codec to CVSD"); + log::verbose("Received AT+BAC, updating sco codec to CVSD"); } /* The above logic sets the stack preferred codec based on local and peer codec @@ -1292,7 +1294,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, } } else { p_scb->peer_codecs = BTM_SCO_CODEC_CVSD; - LOG_ERROR("Unexpected CMD:AT+BAC, Codec Negotiation is not supported"); + log::error("Unexpected CMD:AT+BAC, Codec Negotiation is not supported"); } break; @@ -1312,7 +1314,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, codec_type = BTM_SCO_CODEC_LC3; break; default: - LOG_ERROR("Unknown codec_uuid %d", int_arg); + log::error("Unknown codec_uuid {}", int_arg); codec_type = 0xFFFF; break; } @@ -1330,10 +1332,9 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, } case BTA_AG_LOCAL_EVT_BCC: { if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) { - LOG_WARN( - "NOT opening SCO for EVT %s as %s is not the active HFP device", - "BTA_AG_LOCAL_EVT_BCC", - p_scb->peer_addr.ToStringForLogging().c_str()); + log::warn( + "NOT opening SCO for EVT {} as {} is not the active HFP device", + "BTA_AG_LOCAL_EVT_BCC", p_scb->peer_addr.ToStringForLogging()); bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_ALLOWED); break; } @@ -1391,7 +1392,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, ******************************************************************************/ void bta_ag_at_err_cback(tBTA_AG_SCB* p_scb, bool unknown, const char* p_arg) { if (unknown && (!strlen(p_arg))) { - LOG_VERBOSE("Empty AT cmd string received"); + log::verbose("Empty AT cmd string received"); bta_ag_send_ok(p_scb); return; } @@ -1422,7 +1423,7 @@ void bta_ag_at_err_cback(tBTA_AG_SCB* p_scb, bool unknown, const char* p_arg) { ******************************************************************************/ static void bta_ag_hsp_result(tBTA_AG_SCB* p_scb, const tBTA_AG_API_RESULT& result) { - LOG_VERBOSE("bta_ag_hsp_result : res = %d", result.result); + log::verbose("bta_ag_hsp_result : res = {}", result.result); switch (result.result) { case BTA_AG_SPK_RES: @@ -1494,7 +1495,7 @@ static void bta_ag_hsp_result(tBTA_AG_SCB* p_scb, case BTA_AG_INBAND_RING_RES: p_scb->inband_enabled = result.data.state; - LOG_VERBOSE("inband_enabled set to %d", p_scb->inband_enabled); + log::verbose("inband_enabled set to {}", p_scb->inband_enabled); break; case BTA_AG_UNAT_RES: @@ -1527,7 +1528,7 @@ static void bta_ag_hsp_result(tBTA_AG_SCB* p_scb, ******************************************************************************/ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, const tBTA_AG_API_RESULT& result) { - LOG_DEBUG("HFP connection result:%s", result.ToString().c_str()); + log::debug("HFP connection result:{}", result.ToString()); switch (result.result) { case BTA_AG_SPK_RES: @@ -1626,7 +1627,7 @@ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, case BTA_AG_MULTI_CALL_RES: /* open SCO at SLC for this three way call */ - LOG_VERBOSE("Headset Connected in three way call"); + log::verbose("Headset Connected in three way call"); if (!(p_scb->features & BTA_AG_FEAT_NOSCO)) { if (result.data.audio_handle == bta_ag_scb_to_idx(p_scb)) { if (!bta_ag_is_sco_open_allowed(p_scb, @@ -1685,7 +1686,7 @@ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, case BTA_AG_INBAND_RING_RES: p_scb->inband_enabled = result.data.state; - LOG_VERBOSE("inband_enabled set to %d", p_scb->inband_enabled); + log::verbose("inband_enabled set to {}", p_scb->inband_enabled); bta_ag_send_result(p_scb, result.result, nullptr, result.data.state); break; @@ -1698,8 +1699,8 @@ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, p_scb->roam_ind = result.data.str[8] - '0'; p_scb->battchg_ind = result.data.str[10] - '0'; p_scb->callheld_ind = result.data.str[12] - '0'; - LOG_VERBOSE("cind call:%d callsetup:%d", p_scb->call_ind, - p_scb->callsetup_ind); + log::verbose("cind call:{} callsetup:{}", p_scb->call_ind, + p_scb->callsetup_ind); bta_ag_send_result(p_scb, result.result, result.data.str, 0); bta_ag_send_ok(p_scb); @@ -1725,7 +1726,7 @@ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, if (result.data.str[0] != 0) { tBTA_AG_API_RESULT result_copy(result); bta_ag_process_unat_res(result_copy.data.str); - LOG_VERBOSE("BTA_AG_RES :%s", result_copy.data.str); + log::verbose("BTA_AG_RES :{}", result_copy.data.str); bta_ag_send_result(p_scb, result_copy.result, result_copy.data.str, 0); } @@ -1779,7 +1780,7 @@ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, BTA_AG_MAX_NUM_LOCAL_HF_IND, result.data.ind.id); if (local_index == -1) { - LOG_WARN("%s Invalid HF Indicator ID %d", __func__, result.data.ind.id); + log::warn("Invalid HF Indicator ID {}", result.data.ind.id); return; } @@ -1788,7 +1789,7 @@ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, BTA_AG_MAX_NUM_PEER_HF_IND, result.data.ind.id); if (peer_index == -1) { - LOG_WARN("%s Invalid HF Indicator ID %d", __func__, result.data.ind.id); + log::warn("Invalid HF Indicator ID {}", result.data.ind.id); return; } else { /* If the current state is different from the one upper layer request @@ -1806,9 +1807,8 @@ static void bta_ag_hfp_result(tBTA_AG_SCB* p_scb, bta_ag_send_result(p_scb, result.result, buffer, 0); } else { - LOG_VERBOSE("%s HF Indicator %d already %s", __func__, - result.data.ind.id, - (result.data.ind.on_demand) ? "Enabled" : "Disabled"); + log::verbose("HF Indicator {} already {}", result.data.ind.id, + (result.data.ind.on_demand) ? "Enabled" : "Disabled"); } } break; @@ -1865,15 +1865,15 @@ void bta_ag_send_bcs(tBTA_AG_SCB* p_scb) { codec_uuid = UUID_CODEC_LC3; break; default: - LOG_ERROR("bta_ag_send_bcs: unknown codec %d, use CVSD", - p_scb->sco_codec); + log::error("bta_ag_send_bcs: unknown codec {}, use CVSD", + p_scb->sco_codec); codec_uuid = UUID_CODEC_CVSD; break; } } /* send +BCS */ - LOG_VERBOSE("send +BCS codec is %d", codec_uuid); + log::verbose("send +BCS codec is {}", codec_uuid); bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_BCS, nullptr, codec_uuid); } @@ -1893,12 +1893,12 @@ bool bta_ag_is_sco_open_allowed(tBTA_AG_SCB* p_scb, const std::string event) { if (bluetooth::os::GetSystemPropertyBool( bluetooth::os::kIsDualModeAudioEnabledProperty, false)) { if (LeAudioClient::Get()->isDuplexPreferenceLeAudio(p_scb->peer_addr)) { - LOG_INFO("NOT opening SCO for EVT %s on dual mode device %s", - event.c_str(), p_scb->peer_addr.ToStringForLogging().c_str()); + log::info("NOT opening SCO for EVT {} on dual mode device {}", event, + p_scb->peer_addr.ToStringForLogging()); return false; } else { - LOG_INFO("Opening SCO for EVT %s on dual mode device %s", event.c_str(), - p_scb->peer_addr.ToStringForLogging().c_str()); + log::info("Opening SCO for EVT {} on dual mode device {}", event, + p_scb->peer_addr.ToStringForLogging()); } } #endif @@ -1919,9 +1919,8 @@ void bta_ag_send_ring(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { if ((p_scb->conn_service == BTA_AG_HFP) && p_scb->callsetup_ind != BTA_AG_CALLSETUP_INCOMING) { - LOG(WARNING) << __func__ << ": don't send RING, conn_service=" - << std::to_string(p_scb->conn_service) - << ", callsetup_ind=" << std::to_string(p_scb->callsetup_ind); + log::warn("don't send RING, conn_service={}, callsetup_ind={}", + p_scb->conn_service, p_scb->callsetup_ind); return; } /* send RING */ @@ -1958,7 +1957,7 @@ void bta_ag_send_qcs(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { codec_uuid = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0; } - LOG_VERBOSE("send +QCS codec is %d", codec_uuid); + log::verbose("send +QCS codec is {}", codec_uuid); bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_QCS, NULL, codec_uuid); } @@ -1972,7 +1971,7 @@ void bta_ag_send_qcs(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { * ******************************************************************************/ void bta_ag_send_qac(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data) { - LOG_VERBOSE("send +QAC codecs supported"); + log::verbose("send +QAC codecs supported"); bta_ag_send_result(p_scb, BTA_AG_LOCAL_RES_QAC, SWB_CODECS_SUPPORTED, 0); if (p_scb->sco_codec == BTA_AG_SCO_APTX_SWB_SETTINGS_Q0) { diff --git a/system/bta/ag/bta_ag_int.h b/system/bta/ag/bta_ag_int.h index 9f1f92b334d983f96e4314f5ba8a5327c82dade7..c2cd7882a64916d0d392bdf91af67eed1ae005ad 100644 --- a/system/bta/ag/bta_ag_int.h +++ b/system/bta/ag/bta_ag_int.h @@ -24,6 +24,8 @@ #ifndef BTA_AG_INT_H #define BTA_AG_INT_H +#include + #include #include "bta/ag/bta_ag_at.h" @@ -242,6 +244,7 @@ struct tBTA_AG_SCB { bool cmer_enabled; /* set to true if HF enables CMER reporting */ bool cmee_enabled; /* set to true if HF enables CME ERROR reporting */ bool inband_enabled; /* set to true if inband ring enabled */ + bool nrec_enabled; /* noise reduction & echo canceling */ bool svc_conn; /* set to true when service level connection up */ uint8_t state; /* state machine state */ uint8_t conn_service; /* connected service */ @@ -270,6 +273,8 @@ struct tBTA_AG_SCB { inuse_codec; /* codec being used for the current SCO connection */ bool codec_updated; /* set to true whenever the app updates codec type */ bool codec_fallback; /* If sco nego fails for mSBC, fallback to CVSD */ + uint8_t retransmission_effort_retries; /* Retry eSCO + with retransmission_effort value*/ tBTA_AG_SCO_MSBC_SETTINGS codec_msbc_settings; /* settings to be used for the impending eSCO on WB */ tBTA_AG_SCO_LC3_SETTINGS codec_lc3_settings; /* settings to be used for the @@ -288,10 +293,10 @@ struct tBTA_AG_SCB { std::string ToString() const { return base::StringPrintf( - "codec_updated=%d, codec_fallback=%d, " + "codec_updated=%d, codec_fallback=%d, nrec=%d" "sco_codec=%d, peer_codec=%d, msbc_settings=%d, lc3_settings=%d, " "device=%s", - codec_updated, codec_fallback, sco_codec, peer_codecs, + codec_updated, codec_fallback, nrec_enabled, sco_codec, peer_codecs, codec_msbc_settings, codec_lc3_settings, ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); } @@ -438,4 +443,12 @@ void bta_clear_active_device(); void bta_ag_send_qac(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data); void bta_ag_send_qcs(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data); +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* BTA_AG_INT_H */ diff --git a/system/bta/ag/bta_ag_main.cc b/system/bta/ag/bta_ag_main.cc index fbc4603f7b8c967c32517285fea15d022857e2a1..64f4c3769c763ba38cda28bf116270f51893f3a5 100644 --- a/system/bta/ag/bta_ag_main.cc +++ b/system/bta/ag/bta_ag_main.cc @@ -22,7 +22,9 @@ * ******************************************************************************/ +#include #include +#include #include #include @@ -38,6 +40,8 @@ #include "stack/include/btm_api.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants and types ****************************************************************************/ @@ -148,6 +152,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) { p_scb->received_at_bac = false; p_scb->codec_updated = false; p_scb->codec_fallback = false; + p_scb->retransmission_effort_retries = 0; p_scb->peer_codecs = BTM_SCO_CODEC_CVSD; p_scb->sco_codec = BTM_SCO_CODEC_CVSD; p_scb->peer_version = HFP_HSP_VERSION_UNKNOWN; @@ -164,7 +169,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) { /* set eSCO SWB setting to Q0 as the preferred */ p_scb->codec_aptx_settings = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0; p_scb->is_aptx_swb_codec = false; - LOG_VERBOSE("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb)); + log::verbose("bta_ag_scb_alloc {}", bta_ag_scb_to_idx(p_scb)); break; } } @@ -172,7 +177,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) { if (i == BTA_AG_MAX_NUM_CLIENTS) { /* out of scbs */ p_scb = nullptr; - LOG_WARN("Out of scbs"); + log::warn("Out of scbs"); } return p_scb; } @@ -191,7 +196,7 @@ void bta_ag_scb_dealloc(tBTA_AG_SCB* p_scb) { uint8_t idx; bool allocated = false; - LOG_VERBOSE("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb)); + log::verbose("bta_ag_scb_dealloc {}", bta_ag_scb_to_idx(p_scb)); /* stop and free timers */ alarm_free(p_scb->ring_timer); @@ -250,11 +255,11 @@ tBTA_AG_SCB* bta_ag_scb_by_idx(uint16_t idx) { p_scb = &bta_ag_cb.scb[idx - 1]; if (!p_scb->in_use) { p_scb = nullptr; - LOG_WARN("ag scb idx %d not allocated", idx); + log::warn("ag scb idx {} not allocated", idx); } } else { p_scb = nullptr; - LOG_VERBOSE("ag scb idx %d out of range", idx); + log::verbose("ag scb idx {} out of range", idx); } return p_scb; } @@ -298,7 +303,7 @@ uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr) { } /* no scb found */ - LOG_WARN("No ag scb for peer addr"); + log::warn("No ag scb for peer addr"); return 0; } @@ -321,7 +326,7 @@ bool bta_ag_other_scb_open(tBTA_AG_SCB* p_curr_scb) { } } /* no other scb found */ - LOG_DEBUG("No other ag scb open"); + log::debug("No other ag scb open"); return false; } @@ -359,14 +364,14 @@ void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, if (p_scb && (p_scb->state == BTA_AG_OPENING_ST)) { if (id == BTA_ID_SYS) { - LOG(WARNING) << __func__ << ": AG found collision (ACL) for handle " - << unsigned(handle) << " device " << peer_addr; + log::warn("AG found collision (ACL) for handle {} device {}", + unsigned(handle), ADDRESS_TO_LOGGABLE_STR(peer_addr)); } else if (id == BTA_ID_AG) { - LOG(WARNING) << __func__ << ": AG found collision (RFCOMM) for handle " - << unsigned(handle) << " device " << peer_addr; + log::warn("AG found collision (RFCOMM) for handle {} device {}", + unsigned(handle), ADDRESS_TO_LOGGABLE_STR(peer_addr)); } else { - LOG(WARNING) << __func__ << ": AG found collision (UNKNOWN) for handle " - << unsigned(handle) << " device " << peer_addr; + log::warn("AG found collision (UNKNOWN) for handle {} device {}", + unsigned(handle), ADDRESS_TO_LOGGABLE_STR(peer_addr)); } bta_ag_sm_execute(p_scb, BTA_AG_COLLISION_EVT, tBTA_AG_DATA::kEmpty); } @@ -384,13 +389,14 @@ void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, ******************************************************************************/ void bta_ag_resume_open(tBTA_AG_SCB* p_scb) { if (p_scb->state == BTA_AG_INIT_ST) { - LOG(INFO) << __func__ << ": Resume connection to " << p_scb->peer_addr - << ", handle" << bta_ag_scb_to_idx(p_scb); + log::info("Resume connection to {}, handle{}", + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr), + bta_ag_scb_to_idx(p_scb)); tBTA_AG_DATA open_data = {.api_open = {.bd_addr = p_scb->peer_addr}}; bta_ag_sm_execute(p_scb, BTA_AG_API_OPEN_EVT, open_data); } else { - VLOG(1) << __func__ << ": device " << p_scb->peer_addr - << " is already in state " << std::to_string(p_scb->state); + log::verbose("device {} is already in state {}", + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr), p_scb->state); } } @@ -406,7 +412,7 @@ void bta_ag_resume_open(tBTA_AG_SCB* p_scb) { ******************************************************************************/ void bta_ag_api_enable(tBTA_AG_CBACK* p_cback) { /* initialize control block */ - LOG_INFO("AG api enable"); + log::info("AG api enable"); for (tBTA_AG_SCB& scb : bta_ag_cb.scb) { alarm_free(scb.ring_timer); alarm_free(scb.codec_negotiation_timer); @@ -443,7 +449,7 @@ void bta_ag_api_disable() { int i; if (!bta_sys_is_register(BTA_ID_AG)) { - LOG_ERROR("BTA AG is already disabled, ignoring ..."); + log::error("BTA AG is already disabled, ignoring ..."); return; } @@ -457,6 +463,11 @@ void bta_ag_api_disable() { } } + if (IS_FLAG_ENABLED(is_sco_managed_by_audio)) { + // Stop session if not done + bta_clear_active_device(); + } + if (!do_dereg) { /* Done, send callback evt to app */ (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, nullptr); @@ -479,8 +490,8 @@ void bta_ag_api_register(tBTA_SERVICE_MASK services, tBTA_AG_FEAT features, const std::vector& service_names, uint8_t app_id) { tBTA_AG_SCB* p_scb = bta_ag_scb_alloc(); - LOG_DEBUG("bta_ag_api_register: p_scb allocation %s", - p_scb == nullptr ? "failed" : "success"); + log::debug("bta_ag_api_register: p_scb allocation {}", + p_scb == nullptr ? "failed" : "success"); if (p_scb) { tBTA_AG_DATA data = {}; data.api_register.features = features; @@ -521,14 +532,13 @@ void bta_ag_api_result(uint16_t handle, tBTA_AG_RES result, if (handle != BTA_AG_HANDLE_ALL) { p_scb = bta_ag_scb_by_idx(handle); if (p_scb) { - LOG_DEBUG("Audio gateway event for one client handle:%hu scb:%s", handle, - p_scb->ToString().c_str()); + log::debug("Audio gateway event for one client handle:{} scb:{}", handle, + p_scb->ToString()); bta_ag_sm_execute(p_scb, static_cast(BTA_AG_API_RESULT_EVT), event_data); } else { - LOG_WARN( - "Received audio gateway event for unknown AG control block " - "handle:%hu", + log::warn( + "Received audio gateway event for unknown AG control block handle:{}", handle); } } else { @@ -536,8 +546,8 @@ void bta_ag_api_result(uint16_t handle, tBTA_AG_RES result, for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) { if (p_scb->in_use && p_scb->svc_conn) { - LOG_DEBUG("Audio gateway event for all clients scb:%s", - p_scb->ToString().c_str()); + log::debug("Audio gateway event for all clients scb:{}", + p_scb->ToString()); bta_ag_sm_execute(p_scb, static_cast(BTA_AG_API_RESULT_EVT), event_data); } @@ -566,7 +576,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_sco_listen(p_scb, data); break; case BTA_AG_SCO_OPEN_EVT: - LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); + log::info("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); bta_ag_sco_conn_open(p_scb, data); break; case BTA_AG_SCO_CLOSE_EVT: @@ -576,7 +586,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_free_db(p_scb, data); break; default: - LOG_ERROR("unknown event %d at state %d", event, p_scb->state); + log::error("unknown event {} at state {}", event, p_scb->state); break; } break; @@ -604,7 +614,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_rfc_fail(p_scb, data); break; case BTA_AG_SCO_OPEN_EVT: - LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); + log::info("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); bta_ag_sco_conn_open(p_scb, data); break; case BTA_AG_SCO_CLOSE_EVT: @@ -625,7 +635,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_handle_collision(p_scb, data); break; default: - LOG_ERROR("unknown event %d at state %d", event, p_scb->state); + log::error("unknown event {} at state {}", event, p_scb->state); break; } break; @@ -663,7 +673,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_rfc_data(p_scb, data); break; case BTA_AG_SCO_OPEN_EVT: - LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); + log::info("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); bta_ag_sco_conn_open(p_scb, data); bta_ag_post_sco_open(p_scb, data); break; @@ -682,7 +692,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_start_close(p_scb, data); break; default: - LOG_ERROR("unknown event %d at state %d", event, p_scb->state); + log::error("unknown event {} at state {}", event, p_scb->state); break; } break; @@ -699,7 +709,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_rfc_close(p_scb, data); break; case BTA_AG_SCO_OPEN_EVT: - LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); + log::info("Opening sco for EVT BTA_AG_SCO_OPEN_EVT"); bta_ag_sco_conn_open(p_scb, data); break; case BTA_AG_SCO_CLOSE_EVT: @@ -714,7 +724,7 @@ static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_free_db(p_scb, data); break; default: - LOG_ERROR("unknown event %d at state %d", event, p_scb->state); + log::error("unknown event {} at state {}", event, p_scb->state); break; } break; @@ -736,9 +746,9 @@ void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event, uint16_t previous_event = event; uint8_t previous_state = p_scb->state; - LOG_DEBUG( - "Execute AG event handle:0x%04x bd_addr:%s state:%s[0x%02x]" - " event:%s[0x%04x] result:%s[0x%02x]", + log::debug( + "Execute AG event handle:0x{:04x} bd_addr:{} state:{}[0x{:02x}] " + "event:{}[0x{:04x}] result:{}[0x{:02x}]", bta_ag_scb_to_idx(p_scb), ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr), bta_ag_state_str(p_scb->state), p_scb->state, bta_ag_evt_str(event), event, bta_ag_res_str(data.api_result.result), data.api_result.result); @@ -746,10 +756,10 @@ void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event, bta_ag_better_state_machine(p_scb, event, data); if (p_scb->state != previous_state) { - LOG_DEBUG( - "State changed handle:0x%04x bd_addr:%s " - "state_change:%s[0x%02x]->%s[0x%02x]" - " event:%s[0x%04x] result:%s[0x%02x]", + log::debug( + "State changed handle:0x{:04x} bd_addr:{} " + "state_change:{}[0x{:02x}]->{}[0x{:02x}] event:{}[0x{:04x}] " + "result:{}[0x{:02x}]", bta_ag_scb_to_idx(p_scb), ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr), bta_ag_state_str(previous_state), previous_state, bta_ag_state_str(p_scb->state), p_scb->state, @@ -762,8 +772,8 @@ void bta_ag_sm_execute_by_handle(uint16_t handle, uint16_t event, const tBTA_AG_DATA& data) { tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle); if (p_scb) { - LOG_DEBUG("AG state machine event:%s[0x%04x] handle:0x%04x", - bta_ag_evt_str(event), event, handle); + log::debug("AG state machine event:{}[0x{:04x}] handle:0x{:04x}", + bta_ag_evt_str(event), event, handle); bta_ag_sm_execute(p_scb, event, data); } } @@ -783,8 +793,8 @@ bool bta_ag_hdl_event(const BT_HDR_RIGID* p_msg) { tBTA_AG_DATA::kEmpty); break; default: - LOG(FATAL) << __func__ << ": bad event " << p_msg->event - << " layer_specific=" << p_msg->layer_specific; + log::fatal("bad event {} layer_specific={}", p_msg->event, + p_msg->layer_specific); break; } return true; diff --git a/system/bta/ag/bta_ag_rfc.cc b/system/bta/ag/bta_ag_rfc.cc index 95696736adce0a45df25a770352e09341a4ecc60..62de05effc02eab0ae85fe4b1ba7fe70940b66ed 100644 --- a/system/bta/ag/bta_ag_rfc.cc +++ b/system/bta/ag/bta_ag_rfc.cc @@ -25,6 +25,7 @@ #include #include +#include #include "bta/ag/bta_ag_int.h" #include "bta/include/bta_sec_api.h" @@ -37,6 +38,8 @@ /* Event mask for RfCOMM port callback */ #define BTA_AG_PORT_EV_MASK PORT_EV_RXCHAR +using namespace bluetooth; + /* each scb has its own rfcomm callbacks */ void bta_ag_port_cback_1(uint32_t code, uint16_t port_handle); void bta_ag_port_cback_2(uint32_t code, uint16_t port_handle); @@ -77,15 +80,15 @@ static void bta_ag_port_cback(UNUSED_ATTR uint32_t code, uint16_t port_handle, if (p_scb != nullptr) { /* ignore port events for port handles other than connected handle */ if (port_handle != p_scb->conn_handle) { - LOG_ERROR( - "ag_port_cback ignoring handle:%d conn_handle = %d other handle = %d", + log::error( + "ag_port_cback ignoring handle:{} conn_handle = {} other handle = {}", port_handle, p_scb->conn_handle, handle); return; } if (!bta_ag_scb_open(p_scb)) { - LOG(ERROR) << __func__ << ": rfcomm data on an unopened control block " - << handle << " peer_addr " << p_scb->peer_addr << " state " - << std::to_string(p_scb->state); + log::error( + "rfcomm data on an unopened control block {} peer_addr {} state {}", + handle, ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr), p_scb->state); } do_in_main_thread( FROM_HERE, base::BindOnce(&bta_ag_sm_execute_by_handle, handle, @@ -106,17 +109,17 @@ static void bta_ag_port_cback(UNUSED_ATTR uint32_t code, uint16_t port_handle, static void bta_ag_mgmt_cback(uint32_t code, uint16_t port_handle, uint16_t handle) { tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle); - LOG_VERBOSE("%s: code=%d, port_handle=%d, scb_handle=%d, p_scb=0x%p", - __func__, code, port_handle, handle, p_scb); + log::verbose("code={}, port_handle={}, scb_handle={}, p_scb=0x{}", code, + port_handle, handle, fmt::ptr(p_scb)); if (p_scb == nullptr) { - LOG(WARNING) << __func__ << ": cannot find scb, code=" << code - << ", port_handle=" << port_handle << ", handle=" << handle; + log::warn("cannot find scb, code={}, port_handle={}, handle={}", code, + port_handle, handle); return; } /* ignore close event for port handles other than connected handle */ if ((code != PORT_SUCCESS) && (port_handle != p_scb->conn_handle)) { - LOG(WARNING) << __func__ << ": ignore open failure for unmatched " - << "port_handle " << port_handle << ", scb_handle=" << handle; + log::warn("ignore open failure for unmatched port_handle {}, scb_handle={}", + port_handle, handle); return; } uint16_t event; @@ -137,9 +140,10 @@ static void bta_ag_mgmt_cback(uint32_t code, uint16_t port_handle, } } if (!found_handle) { - LOG(ERROR) << __func__ << ": port opened successfully, but port_handle " - << port_handle << " is unknown" - << ", scb_handle=" << handle; + log::error( + "port opened successfully, but port_handle {} is unknown, " + "scb_handle={}", + port_handle, handle); return; } event = BTA_AG_RFC_OPEN_EVT; @@ -262,13 +266,14 @@ void bta_ag_start_servers(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK services) { bta_ag_setup_port(p_scb, p_scb->serv_handle[i]); } else { /* TODO: CR#137125 to handle to error properly */ - LOG(ERROR) << __func__ << ": RFCOMM_CreateConnectionWithSecurity ERROR " - << status << ", p_scb=" << p_scb - << ", services=" << loghex(services) - << ", mgmt_cback_index=" << management_callback_index; + log::error( + "RFCOMM_CreateConnectionWithSecurity ERROR {}, p_scb={}, " + "services={}, mgmt_cback_index={}", + status, fmt::ptr(p_scb), loghex(services), + management_callback_index); } - LOG_VERBOSE("%s: p_scb=0x%p, services=0x%04x, mgmt_cback_index=%d", - __func__, p_scb, services, management_callback_index); + log::verbose("p_scb=0x{}, services=0x{:04x}, mgmt_cback_index={}", + fmt::ptr(p_scb), services, management_callback_index); } } } @@ -332,16 +337,15 @@ void bta_ag_rfc_do_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { p_scb->peer_addr, &(p_scb->conn_handle), bta_ag_mgmt_cback_tbl[management_callback_index], BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); - LOG_VERBOSE( - "%s: p_scb=0x%p, conn_handle=%d, mgmt_cback_index=%d," - " status=%d", - __func__, p_scb, p_scb->conn_handle, management_callback_index, status); + log::verbose("p_scb=0x{}, conn_handle={}, mgmt_cback_index={}, status={}", + fmt::ptr(p_scb), p_scb->conn_handle, management_callback_index, + status); if (status == PORT_SUCCESS) { bta_ag_setup_port(p_scb, p_scb->conn_handle); } else { /* RFCOMM create connection failed; send ourselves RFCOMM close event */ - LOG(ERROR) << __func__ << ": RFCOMM_CreateConnection ERROR " << status - << " for " << p_scb->peer_addr; + log::error("RFCOMM_CreateConnection ERROR {} for {}", status, + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); bta_ag_sm_execute(p_scb, BTA_AG_RFC_CLOSE_EVT, data); } } @@ -358,7 +362,7 @@ void bta_ag_rfc_do_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) { ******************************************************************************/ void bta_ag_rfc_do_close(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { - LOG_INFO("p_scb->conn_handle: 0x%04x", p_scb->conn_handle); + log::info("p_scb->conn_handle: 0x{:04x}", p_scb->conn_handle); if (p_scb->conn_handle) { RFCOMM_RemoveConnection(p_scb->conn_handle); } else { diff --git a/system/bta/ag/bta_ag_sco.cc b/system/bta/ag/bta_ag_sco.cc index 5ecfdd5e00f5172a89fc7ac0e2560342c7122545..710545273f75c1168764ae226a2da90627382e2d 100644 --- a/system/bta/ag/bta_ag_sco.cc +++ b/system/bta/ag/bta_ag_sco.cc @@ -25,9 +25,11 @@ #include #include #include +#include #include +#include "audio_hal_interface/hfp_client_interface.h" #include "bta/ag/bta_ag_int.h" #include "bta_ag_swb_aptx.h" #include "common/init_flags.h" @@ -45,6 +47,9 @@ extern tBTM_CB btm_cb; +using HfpInterface = bluetooth::audio::hfp::HfpClientInterface; +using namespace bluetooth; + /* Codec negotiation timeout */ #ifndef BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS #define BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS (3 * 1000) /* 3 seconds */ @@ -60,6 +65,15 @@ extern tBTM_CB btm_cb; static bool sco_allowed = true; static RawAddress active_device_addr = {}; +static std::unique_ptr hfp_client_interface; +static std::unique_ptr hfp_offload_interface; +static std::unordered_map sco_config_map; +static std::unordered_map + codec_coding_format_map{ + {UUID_CODEC_LC3, ESCO_CODING_FORMAT_LC3}, + {UUID_CODEC_MSBC, ESCO_CODING_FORMAT_MSBC}, + {UUID_CODEC_CVSD, ESCO_CODING_FORMAT_CVSD}, + }; /* sco events */ enum { @@ -123,6 +137,9 @@ bool bta_ag_sco_is_active_device(const RawAddress& bd_addr) { return !active_device_addr.IsEmpty() && active_device_addr == bd_addr; } +void updateCodecParametersFromProviderInfo(tBTA_AG_PEER_CODEC esco_codec, + enh_esco_params_t& params); + /******************************************************************************* * * Function bta_ag_sco_conn_cback @@ -174,17 +191,14 @@ static void bta_ag_sco_conn_cback(uint16_t sco_idx) { static void bta_ag_sco_disc_cback(uint16_t sco_idx) { uint16_t handle = 0; - LOG_DEBUG( - "sco_idx: 0x%x sco.state:%s", sco_idx, - sco_state_text(static_cast(bta_ag_cb.sco.state)).c_str()); - LOG_DEBUG( - " scb[0] in_use:%s sco_idx: 0x%x sco state:%s", - logbool(bta_ag_cb.scb[0].in_use).c_str(), bta_ag_cb.scb[0].sco_idx, - sco_state_text(static_cast(bta_ag_cb.scb[0].state)).c_str()); - LOG_DEBUG( - " scb[1] in_use:%s sco_idx:0x%x sco state:%s", - logbool(bta_ag_cb.scb[1].in_use).c_str(), bta_ag_cb.scb[1].sco_idx, - sco_state_text(static_cast(bta_ag_cb.scb[1].state)).c_str()); + log::debug("sco_idx: 0x{:x} sco.state:{}", sco_idx, + sco_state_text(static_cast(bta_ag_cb.sco.state))); + log::debug("scb[0] in_use:{} sco_idx: 0x{:x} sco state:{}", + logbool(bta_ag_cb.scb[0].in_use), bta_ag_cb.scb[0].sco_idx, + sco_state_text(static_cast(bta_ag_cb.scb[0].state))); + log::debug("scb[1] in_use:{} sco_idx:0x{:x} sco state:{}", + logbool(bta_ag_cb.scb[1].in_use), bta_ag_cb.scb[1].sco_idx, + sco_state_text(static_cast(bta_ag_cb.scb[1].state))); /* match callback to scb */ if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use) { @@ -201,8 +215,8 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) { (bta_ag_cb.sco.p_curr_scb->is_aptx_swb_codec == true) && (bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_SCO_APTX_SWB_SETTINGS_Q0); - LOG_VERBOSE("aptx_voice=%s, inuse_codec=%#x", logbool(aptx_voice).c_str(), - bta_ag_cb.sco.p_curr_scb->inuse_codec); + log::verbose("aptx_voice={}, inuse_codec={:#x}", logbool(aptx_voice), + bta_ag_cb.sco.p_curr_scb->inuse_codec); /* Restore settings */ if (bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_MSBC || @@ -221,37 +235,42 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) { if (bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_LC3) { if (bta_ag_cb.sco.p_curr_scb->codec_lc3_settings == BTA_AG_SCO_LC3_SETTINGS_T2) { - LOG_WARN( - "%s: eSCO/SCO failed to open, falling back to LC3 T1 settings", - __func__); + log::warn( + "eSCO/SCO failed to open, falling back to LC3 T1 settings"); bta_ag_cb.sco.p_curr_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T1; } else { - LOG_WARN( - "%s: eSCO/SCO failed to open, falling back to CVSD settings", - __func__); + log::warn("eSCO/SCO failed to open, falling back to CVSD settings"); bta_ag_cb.sco.p_curr_scb->inuse_codec = UUID_CODEC_CVSD; bta_ag_cb.sco.p_curr_scb->codec_fallback = true; } } else { if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) { - LOG_WARN( - "%s: eSCO/SCO failed to open, falling back to mSBC T1 settings", - __func__); + log::warn( + "eSCO/SCO failed to open, falling back to mSBC T1 settings"); bta_ag_cb.sco.p_curr_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T1; } else { - LOG_WARN("%s: eSCO/SCO failed to open, falling back to CVSD", - __func__); + log::warn("eSCO/SCO failed to open, falling back to CVSD"); bta_ag_cb.sco.p_curr_scb->inuse_codec = UUID_CODEC_CVSD; bta_ag_cb.sco.p_curr_scb->codec_fallback = true; } } } } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) { - LOG_ERROR("%s: eSCO/SCO failed to open, no more fall back", __func__); + if (IS_FLAG_ENABLED(retry_esco_with_zero_retransmission_effort) && + bta_ag_cb.sco.p_curr_scb->retransmission_effort_retries == 0) { + bta_ag_cb.sco.p_curr_scb->retransmission_effort_retries++; + bta_ag_cb.sco.p_curr_scb->state = BTA_AG_SCO_CODEC_ST; + log::warn("eSCO/SCO failed to open, retry with retransmission_effort"); + } else { + log::error("eSCO/SCO failed to open, no more fall back"); + if (IS_FLAG_ENABLED(is_sco_managed_by_audio)) { + hfp_offload_interface->CancelStreamingRequest(); + } + } } bta_ag_cb.sco.p_curr_scb->inuse_codec = BTM_SCO_CODEC_NONE; @@ -261,7 +280,7 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) { BTA_AG_SCO_CLOSE_EVT, tBTA_AG_DATA::kEmpty)); } else { /* no match found */ - LOG_VERBOSE("no scb for ag_sco_disc_cback"); + log::verbose("no scb for ag_sco_disc_cback"); /* sco could be closed after scb dealloc'ed */ if (bta_ag_cb.sco.p_curr_scb != nullptr) { @@ -287,8 +306,8 @@ static bool bta_ag_remove_sco(tBTA_AG_SCB* p_scb, bool only_active) { if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) { if (!only_active || p_scb->sco_idx == bta_ag_cb.sco.cur_idx) { tBTM_STATUS status = BTM_RemoveSco(p_scb->sco_idx); - LOG_DEBUG("Removed SCO index:0x%04x status:%s", p_scb->sco_idx, - btm_status_text(status).c_str()); + log::debug("Removed SCO index:0x{:04x} status:{}", p_scb->sco_idx, + btm_status_text(status)); if (status == BTM_CMD_STARTED) { /* SCO is connected; set current control block */ bta_ag_cb.sco.p_curr_scb = p_scb; @@ -325,8 +344,7 @@ static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, /* If no other SCO active, allow this one */ if (!bta_ag_cb.sco.p_curr_scb) { - LOG_VERBOSE("%s: Accept Conn Request (sco_inx 0x%04x)", __func__, - sco_inx); + log::verbose("Accept Conn Request (sco_inx 0x{:04x})", sco_inx); bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt); bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST; @@ -334,15 +352,15 @@ static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, bta_ag_cb.sco.cur_idx = p_scb->sco_idx; } else { /* Begin a transfer: Close current SCO before responding */ - LOG_VERBOSE("bta_ag_esco_connreq_cback: Begin XFER"); + log::verbose("bta_ag_esco_connreq_cback: Begin XFER"); bta_ag_cb.sco.p_xfer_scb = p_scb; bta_ag_cb.sco.conn_data = p_data->conn_evt; bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST; if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, true)) { - LOG_ERROR( - "%s: Nothing to remove,so accept Conn Request(sco_inx 0x%04x)", - __func__, sco_inx); + log::error( + "Nothing to remove,so accept Conn Request(sco_inx 0x{:04x})", + sco_inx); bta_ag_cb.sco.p_xfer_scb = nullptr; bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST; @@ -350,11 +368,14 @@ static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, } } } else { - LOG(WARNING) << __func__ - << ": reject incoming SCO connection, remote_bda=" - << (remote_bda ? *remote_bda : RawAddress::kEmpty) - << ", active_bda=" << active_device_addr << ", current_bda=" - << (p_scb ? p_scb->peer_addr : RawAddress::kEmpty); + log::warn( + "reject incoming SCO connection, remote_bda={}, active_bda={}, " + "current_bda={}", + ADDRESS_TO_LOGGABLE_STR(remote_bda ? *remote_bda + : RawAddress::kEmpty), + ADDRESS_TO_LOGGABLE_STR(active_device_addr), + ADDRESS_TO_LOGGABLE_STR(p_scb ? p_scb->peer_addr + : RawAddress::kEmpty)); BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, (enh_esco_params_t*)nullptr); } @@ -391,12 +412,13 @@ static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, tBTA_AG_EVT event) { * ******************************************************************************/ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) { - LOG_DEBUG("BEFORE %s", p_scb->ToString().c_str()); + log::debug("BEFORE {}", p_scb->ToString()); tBTA_AG_PEER_CODEC esco_codec = UUID_CODEC_CVSD; if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) { - LOG(WARNING) << __func__ << ": device " << p_scb->peer_addr - << " is not active, active_device=" << active_device_addr; + log::warn("device {} is not active, active_device={}", + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr), + ADDRESS_TO_LOGGABLE_STR(active_device_addr)); if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use && p_scb == bta_ag_cb.sco.p_curr_scb) { do_in_main_thread(FROM_HERE, base::BindOnce(&bta_ag_sm_execute, p_scb, @@ -407,8 +429,8 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) { } /* Make sure this SCO handle is not already in use */ if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) { - LOG_ERROR("%s: device %s, index 0x%04x already in use!", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr), p_scb->sco_idx); + log::error("device {}, index 0x{:04x} already in use!", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr), p_scb->sco_idx); return; } @@ -450,7 +472,7 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) { * index is 0 for CVSD by initialization. * If eSCO codec is mSBC, index is T2 or T1. * If eSCO coedc is LC3, index is T2 or T1. */ - LOG_WARN("esco_codec: %d", (int)esco_codec); + log::warn("esco_codec: {}", (int)esco_codec); if (esco_codec == UUID_CODEC_LC3) { if (p_scb->codec_lc3_settings == BTA_AG_SCO_LC3_SETTINGS_T2) { params = esco_parameters_for_codec(ESCO_CODEC_LC3_T2, offload); @@ -485,6 +507,15 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) { } } + updateCodecParametersFromProviderInfo(esco_codec, params); + + if (IS_FLAG_ENABLED(retry_esco_with_zero_retransmission_effort) && + p_scb->retransmission_effort_retries == 1) { + log::info("change retransmission_effort to 0, retry"); + p_scb->retransmission_effort_retries++; + params.retransmission_effort = ESCO_RETRANSMISSION_OFF; + } + /* Configure input/output data path based on HAL settings. */ hfp_hal_interface::set_codec_datapath(esco_codec); hfp_hal_interface::update_esco_parameters(¶ms); @@ -503,8 +534,8 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) { /* Send pending commands to create SCO connection to peer */ bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local); - LOG_DEBUG("Initiating AG SCO inx 0x%04x, pkt types 0x%04x", p_scb->sco_idx, - params.packet_types); + log::debug("Initiating AG SCO inx 0x{:04x}, pkt types 0x{:04x}", + p_scb->sco_idx, params.packet_types); } else { /* Not initiating, go to listen mode */ tBTM_STATUS btm_status = BTM_CreateSco( @@ -513,11 +544,34 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) { if (btm_status == BTM_CMD_STARTED) { BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback); } - LOG_DEBUG("Listening AG SCO inx 0x%04x status:%s pkt types 0x%04x", - p_scb->sco_idx, btm_status_text(btm_status).c_str(), - params.packet_types); + log::debug("Listening AG SCO inx 0x{:04x} status:{} pkt types 0x{:04x}", + p_scb->sco_idx, btm_status_text(btm_status), + params.packet_types); + } + log::debug("AFTER {}", p_scb->ToString()); +} + +void updateCodecParametersFromProviderInfo(tBTA_AG_PEER_CODEC esco_codec, + enh_esco_params_t& params) { + if (IS_FLAG_ENABLED(is_sco_managed_by_audio) && !sco_config_map.empty()) { + auto sco_config_it = sco_config_map.find(esco_codec); + if (sco_config_it == sco_config_map.end()) { + log::error("cannot find sco config for esco_codec index={}", esco_codec); + return; + } + log::debug("use ProviderInfo to update (e)sco parameters"); + params.input_data_path = sco_config_it->second.inputDataPath; + params.output_data_path = sco_config_it->second.outputDataPath; + if (!sco_config_it->second.useControllerCodec) { + log::debug("use DSP Codec instead of controller codec"); + + esco_coding_format_t codingFormat = codec_coding_format_map[esco_codec]; + params.input_coding_format.coding_format = codingFormat; + params.output_coding_format.coding_format = codingFormat; + params.input_bandwidth = TXRX_64KBITS_RATE; + params.output_bandwidth = TXRX_64KBITS_RATE; + } } - LOG_DEBUG("AFTER %s", p_scb->ToString().c_str()); } /******************************************************************************* @@ -596,7 +650,7 @@ void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) { /* Configure input/output data. */ hfp_hal_interface::set_codec_datapath(esco_codec); } - LOG_VERBOSE("%s: initiated SCO connection", __func__); + log::verbose("initiated SCO connection"); } else { // Local device accepted SCO connection from peer(HF) // Because HF devices usually do not send AT+BAC and +BCS command, @@ -622,7 +676,7 @@ void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) { } BTM_EScoConnRsp(p_scb->sco_idx, HCI_SUCCESS, ¶ms); - LOG_VERBOSE("%s: listening for SCO connection", __func__); + log::verbose("listening for SCO connection"); } } @@ -637,7 +691,7 @@ void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) { * ******************************************************************************/ static void bta_ag_codec_negotiation_timer_cback(void* data) { - LOG_WARN("Codec negotiation timeout"); + log::warn("Codec negotiation timeout"); tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data; /* Announce that codec negotiation failed. */ @@ -663,7 +717,7 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) { bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT; if (p_rem_feat == nullptr) { - LOG_WARN("Skip codec negotiation, failed to read remote features"); + log::warn("Skip codec negotiation, failed to read remote features"); bta_ag_sco_codec_nego(p_scb, false); return; } @@ -679,23 +733,22 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) { // SCO setup fail by Firmware reject. if (!HCI_LMP_TRANSPNT_SUPPORTED(p_rem_feat) || !sdp_wbs_support || !(p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) { - LOG_INFO("Assume CVSD by default due to mask mismatch"); + log::info("Assume CVSD by default due to mask mismatch"); p_scb->sco_codec = UUID_CODEC_CVSD; } const bool aptx_voice = is_hfp_aptx_voice_enabled() && p_scb->is_aptx_swb_codec && (p_scb->peer_codecs & BTA_AG_SCO_APTX_SWB_SETTINGS_Q0_MASK); - LOG_VERBOSE("aptx_voice=%s, is_aptx_swb_codec=%s, Q0 codec supported=%s", - logbool(aptx_voice).c_str(), - logbool(p_scb->is_aptx_swb_codec).c_str(), - logbool(p_scb->peer_codecs & BTA_AG_SCO_APTX_SWB_SETTINGS_Q0_MASK) - .c_str()); + log::verbose( + "aptx_voice={}, is_aptx_swb_codec={}, Q0 codec supported={}", + logbool(aptx_voice), logbool(p_scb->is_aptx_swb_codec), + logbool(p_scb->peer_codecs & BTA_AG_SCO_APTX_SWB_SETTINGS_Q0_MASK)); if (((p_scb->codec_updated || p_scb->codec_fallback) && (p_scb->features & BTA_AG_FEAT_CODEC) && (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) || (aptx_voice)) { - LOG_INFO("Starting codec negotiation"); + log::info("Starting codec negotiation"); /* Change the power mode to Active until SCO open is completed. */ bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); @@ -704,8 +757,8 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) { p_scb->sco_codec = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0; p_scb->is_aptx_swb_codec = true; } - LOG_VERBOSE("Sending +QCS, sco_codec=%d, is_aptx_swb_codec=%s", - p_scb->sco_codec, logbool(p_scb->is_aptx_swb_codec).c_str()); + log::verbose("Sending +QCS, sco_codec={}, is_aptx_swb_codec={}", + p_scb->sco_codec, logbool(p_scb->is_aptx_swb_codec)); /* Send +QCS to the peer */ bta_ag_send_qcs(p_scb, NULL); } else { @@ -713,8 +766,8 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) { p_scb->sco_codec = BTM_SCO_CODEC_MSBC; p_scb->is_aptx_swb_codec = false; } - LOG_VERBOSE("Sending +BCS, sco_codec=%d, is_aptx_swb_codec=%s", - p_scb->sco_codec, logbool(p_scb->is_aptx_swb_codec).c_str()); + log::verbose("Sending +BCS, sco_codec={}, is_aptx_swb_codec={}", + p_scb->sco_codec, logbool(p_scb->is_aptx_swb_codec)); /* Send +BCS to the peer */ bta_ag_send_bcs(p_scb); } @@ -725,7 +778,7 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) { bta_ag_codec_negotiation_timer_cback, p_scb); } else { /* use same codec type as previous SCO connection, skip codec negotiation */ - LOG_INFO("Skip codec negotiation, using the same codec"); + log::info("Skip codec negotiation, using the same codec"); bta_ag_sco_codec_nego(p_scb, true); } } @@ -733,10 +786,10 @@ void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) { static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { tBTA_AG_SCO_CB* p_sco = &bta_ag_cb.sco; uint8_t previous_state = p_sco->state; - LOG_INFO("device:%s index:0x%04x state:%s[%d] event:%s[%d]", - ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr), p_scb->sco_idx, - bta_ag_sco_state_str(p_sco->state), p_sco->state, - bta_ag_sco_evt_str(event), event); + log::info("device:{} index:0x{:04x} state:{}[{}] event:{}[{}]", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr), p_scb->sco_idx, + bta_ag_sco_state_str(p_sco->state), p_sco->state, + bta_ag_sco_evt_str(event), event); switch (p_sco->state) { case BTA_AG_SCO_SHUTDOWN_ST: @@ -748,8 +801,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -790,8 +843,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { case BTA_AG_SCO_CLOSE_E: /* remove listening connection */ /* Ignore the event. Keep listening SCO for the active SLC */ - LOG_WARN("BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_LISTEN_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; case BTA_AG_SCO_CONN_CLOSE_E: @@ -801,8 +854,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_LISTEN_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -859,8 +912,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_CODEC_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_CODEC_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -914,8 +967,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_OPENING_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_OPENING_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -957,8 +1010,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_OPEN_CL_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -993,8 +1046,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -1043,8 +1096,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_OPEN_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_OPEN_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -1087,8 +1140,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_CLOSING_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_CLOSING_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -1117,8 +1170,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -1169,8 +1222,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { } default: - LOG_WARN(" BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -1227,8 +1280,8 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; default: - LOG_WARN("BTA_AG_SCO_SHUTTING_ST: Ignoring event %s[%d]", - bta_ag_sco_evt_str(event), event); + log::warn("BTA_AG_SCO_SHUTTING_ST: Ignoring event {}[{}]", + bta_ag_sco_evt_str(event), event); break; } break; @@ -1237,9 +1290,9 @@ static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) { break; } if (p_sco->state != previous_state) { - LOG_WARN( - "SCO_state_change: [%s(0x%02x)]->[%s(0x%02x)] " - "after event [%s(0x%02x)]", + log::warn( + "SCO_state_change: [{}(0x{:02x})]->[{}(0x{:02x})] after event " + "[{}(0x{:02x})]", bta_ag_sco_state_str(previous_state), previous_state, bta_ag_sco_state_str(p_sco->state), p_sco->state, bta_ag_sco_evt_str(event), event); @@ -1289,7 +1342,7 @@ bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb) { ******************************************************************************/ void bta_ag_sco_listen(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { - LOG(INFO) << __func__ << ": " << p_scb->peer_addr; + log::info("{}", ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E); } @@ -1305,13 +1358,13 @@ void bta_ag_sco_listen(tBTA_AG_SCB* p_scb, ******************************************************************************/ void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { if (!sco_allowed) { - LOG(INFO) << __func__ << ": not opening sco, by policy"; + log::info("not opening sco, by policy"); return; } p_scb->disabled_codecs = data.api_audio_open.disabled_codecs; - LOG(INFO) << __func__ << ": disabled_codecs = " << p_scb->disabled_codecs - << ", sco_codec = " << p_scb->sco_codec; + log::info("disabled_codecs = {}, sco_codec = {}", p_scb->disabled_codecs, + p_scb->sco_codec); if (p_scb->disabled_codecs & p_scb->sco_codec) { tBTA_AG_PEER_CODEC updated_codec = BTM_SCO_CODEC_NONE; @@ -1333,13 +1386,13 @@ void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { /* if another scb using sco, this is a transfer */ if (bta_ag_cb.sco.p_curr_scb && bta_ag_cb.sco.p_curr_scb != p_scb) { - LOG(INFO) << __func__ << ": transfer " - << bta_ag_cb.sco.p_curr_scb->peer_addr << " -> " - << p_scb->peer_addr; + log::info("transfer {} -> {}", + ADDRESS_TO_LOGGABLE_STR(bta_ag_cb.sco.p_curr_scb->peer_addr), + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); bta_ag_sco_event(p_scb, BTA_AG_SCO_XFER_E); } else { /* else it is an open */ - LOG(INFO) << __func__ << ": open " << p_scb->peer_addr; + log::info("open {}", ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); bta_ag_sco_event(p_scb, BTA_AG_SCO_OPEN_E); } } @@ -1361,7 +1414,7 @@ void bta_ag_sco_close(tBTA_AG_SCB* p_scb, * state. */ if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) || (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST)) { - LOG_VERBOSE("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx); + log::verbose("bta_ag_sco_close: sco_inx = {}", p_scb->sco_idx); bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E); } } @@ -1379,14 +1432,14 @@ void bta_ag_sco_close(tBTA_AG_SCB* p_scb, void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result) { if (result) { /* Subsequent SCO connection will skip codec negotiation */ - LOG_INFO("Succeeded for index 0x%04x, device %s", p_scb->sco_idx, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); + log::info("Succeeded for index 0x{:04x}, device {}", p_scb->sco_idx, + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); p_scb->codec_updated = false; bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E); } else { /* codec negotiation failed */ - LOG_INFO("Failed for index 0x%04x, device %s", p_scb->sco_idx, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); + log::info("Failed for index 0x{:04x}, device {}", p_scb->sco_idx, + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E); } } @@ -1419,12 +1472,35 @@ void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb, void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) { bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E); - bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); + if (IS_FLAG_ENABLED(is_sco_managed_by_audio)) { + // ConfirmStreamingRequest before sends callback to java layer + hfp_offload_interface->ConfirmStreamingRequest(); + + bool is_controller_codec = false; + if (sco_config_map.find(p_scb->inuse_codec) == sco_config_map.end()) { + log::error("sco_config_map does not have inuse_codec={}", + p_scb->inuse_codec); + } else { + is_controller_codec = + sco_config_map[p_scb->inuse_codec].useControllerCodec; + } + + hfp::offload_config config{ + .sco_codec = p_scb->inuse_codec, + .connection_handle = p_scb->conn_handle, + .is_controller_codec = is_controller_codec, + .is_nrec = p_scb->nrec_enabled, + }; + hfp_offload_interface->UpdateAudioConfigToHal(config); + } + /* call app callback */ bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT); + /* reset retransmission_effort_retries*/ + p_scb->retransmission_effort_retries = 0; /* reset to mSBC T2 settings as the preferred */ p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2; /* reset to LC3 T2 settings as the preferred */ @@ -1451,9 +1527,8 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb, const bool aptx_voice = is_hfp_aptx_voice_enabled() && p_scb->codec_fallback && (p_scb->sco_codec == BTA_AG_SCO_APTX_SWB_SETTINGS_Q0); - LOG_VERBOSE("aptx_voice=%s, codec_fallback=%#x, sco_codec=%#x", - logbool(aptx_voice).c_str(), p_scb->codec_fallback, - p_scb->sco_codec); + log::verbose("aptx_voice={}, codec_fallback={:#x}, sco_codec={:#x}", + logbool(aptx_voice), p_scb->codec_fallback, p_scb->sco_codec); /* codec_fallback is set when AG is initiator and connection failed for mSBC. * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings @@ -1464,6 +1539,8 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb, p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1) || (p_scb->sco_codec == BTM_SCO_CODEC_LC3 && p_scb->codec_lc3_settings == BTA_AG_SCO_LC3_SETTINGS_T1) || + (IS_FLAG_ENABLED(retry_esco_with_zero_retransmission_effort) && + p_scb->retransmission_effort_retries == 1) || aptx_voice)) { bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E); } else { @@ -1502,10 +1579,10 @@ void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA* p_data) { bta_ag_cb.sco.is_local = false; - LOG_VERBOSE("%s: eSCO %d, state %d", __func__, - controller_get_interface() - ->supports_enhanced_setup_synchronous_connection(), - bta_ag_cb.sco.state); + log::verbose("eSCO {}, state {}", + controller_get_interface() + ->supports_enhanced_setup_synchronous_connection(), + bta_ag_cb.sco.state); if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST || bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST || @@ -1531,20 +1608,50 @@ void bta_ag_set_sco_offload_enabled(bool value) { void bta_ag_set_sco_allowed(bool value) { sco_allowed = value; - LOG_VERBOSE("%s", sco_allowed ? "sco now allowed" : "sco now not allowed"); + log::verbose("{}", sco_allowed ? "sco now allowed" : "sco now not allowed"); } const RawAddress& bta_ag_get_active_device() { return active_device_addr; } void bta_clear_active_device() { - LOG_DEBUG("Set bta active device to null"); + log::debug("Set bta active device to null"); + if (IS_FLAG_ENABLED(is_sco_managed_by_audio)) { + if (hfp_offload_interface && !active_device_addr.IsEmpty()) { + hfp_offload_interface->StopSession(); + } + } active_device_addr = RawAddress::kEmpty; } void bta_ag_api_set_active_device(const RawAddress& new_active_device) { if (new_active_device.IsEmpty()) { - LOG_ERROR("%s: empty device", __func__); + log::error("empty device"); return; } + + if (IS_FLAG_ENABLED(is_sco_managed_by_audio)) { + if (!hfp_client_interface) { + hfp_client_interface = std::unique_ptr(HfpInterface::Get()); + if (!hfp_client_interface) { + log::error("could not acquire audio source interface"); + return; + } + } + + if (!hfp_offload_interface) { + hfp_offload_interface = std::unique_ptr( + hfp_client_interface->GetOffload(get_main_thread())); + sco_config_map = hfp_offload_interface->GetHfpScoConfig(); + if (!hfp_offload_interface) { + log::warn("could not get offload interface"); + } else { + // start audio session if there was no previous active device + // if there was an active device, java layer would call disconnectAudio + if (active_device_addr.IsEmpty()) { + hfp_offload_interface->StartSession(); + } + } + } + } active_device_addr = new_active_device; } diff --git a/system/bta/ag/bta_ag_sdp.cc b/system/bta/ag/bta_ag_sdp.cc index 1314cc4b9ac07bd78d4fdecf0f979a4e02153b37..c4b30d88ebae1dab12b4d17fc0ba28c9c787c6fc 100644 --- a/system/bta/ag/bta_ag_sdp.cc +++ b/system/bta/ag/bta_ag_sdp.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include "bta/ag/bta_ag_int.h" #include "bta/include/bta_hfp_api.h" @@ -43,9 +44,11 @@ #include "stack/include/bt_uuid16.h" #include "stack/include/main_thread.h" #include "stack/include/sdp_api.h" +#include "storage/config_keys.h" #include "types/bluetooth/uuid.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; using bluetooth::Uuid; /* Number of protocol elements in protocol element list. */ @@ -84,7 +87,7 @@ const tBTA_AG_SDP_CBACK bta_ag_sdp_cback_tbl[] = { * ******************************************************************************/ static void bta_ag_sdp_cback(uint16_t status, uint8_t idx) { - LOG_VERBOSE("%s status:0x%x", __func__, status); + log::verbose("status:0x{:x}", status); tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(idx); if (p_scb) { uint16_t event; @@ -163,8 +166,8 @@ bool bta_ag_add_record(uint16_t service_uuid, const char* p_service_name, bool codec_supported = false; uint8_t buf[2]; - LOG_VERBOSE("%s uuid: %x", __func__, service_uuid); - LOG_INFO("features: %d", features); + log::verbose("uuid: {:x}", service_uuid); + log::info("features: {}", features); for (auto& proto_element : proto_elem_list) { proto_element = {}; @@ -303,7 +306,7 @@ void bta_ag_del_records(tBTA_AG_SCB* p_scb) { /* if service registered for this scb and not registered for any other scb */ if (((services & 1) == 1) && ((others & 1) == 0)) { - LOG_VERBOSE("bta_ag_del_records %d", i); + log::verbose("bta_ag_del_records {}", i); if (bta_ag_cb.profile[i].sdp_handle != 0) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord( bta_ag_cb.profile[i].sdp_handle); @@ -380,8 +383,8 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { uint16_t peer_version = HFP_HSP_VERSION_UNKNOWN; if (!get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( p_rec, uuid, &peer_version)) { - LOG_WARN("%s: Get peer_version failed, using default 0x%04x", __func__, - p_scb->peer_version); + log::warn("Get peer_version failed, using default 0x{:04x}", + p_scb->peer_version); peer_version = p_scb->peer_version; } @@ -390,11 +393,11 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { if (peer_version != p_scb->peer_version) { p_scb->peer_version = peer_version; if (btif_config_set_bin( - p_scb->peer_addr.ToString(), HFP_VERSION_CONFIG_KEY, + p_scb->peer_addr.ToString(), BTIF_STORAGE_KEY_HFP_VERSION, (const uint8_t*)&peer_version, sizeof(peer_version))) { } else { - LOG_WARN("%s: Failed to store peer HFP version for %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); + log::warn("Failed to store peer HFP version for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); } } /* get features if HFP */ @@ -419,12 +422,13 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { } if (sdp_features != p_scb->peer_sdp_features) { p_scb->peer_sdp_features = sdp_features; - if (btif_config_set_bin( - p_scb->peer_addr.ToString(), HFP_SDP_FEATURES_CONFIG_KEY, - (const uint8_t*)&sdp_features, sizeof(sdp_features))) { + if (btif_config_set_bin(p_scb->peer_addr.ToString(), + BTIF_STORAGE_KEY_HFP_SDP_FEATURES, + (const uint8_t*)&sdp_features, + sizeof(sdp_features))) { } else { - LOG_WARN("%s: Failed to store peer HFP SDP Features for %s", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); + log::warn("Failed to store peer HFP SDP Features for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr)); } } if (p_scb->peer_features == 0) { @@ -531,7 +535,7 @@ void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { } if (p_scb->p_disc_db != nullptr) { - LOG_ERROR("Discovery already in progress... returning."); + log::error("Discovery already in progress... returning."); return; } @@ -546,12 +550,12 @@ void bta_ag_do_disc(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { bta_ag_sdp_cback_tbl[bta_ag_scb_to_idx(p_scb) - 1])) { return; } else { - LOG(ERROR) << __func__ << ": failed to start SDP discovery for " - << p_scb->peer_addr; + log::error("failed to start SDP discovery for {}", + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); } } else { - LOG(ERROR) << __func__ << ": failed to init SDP discovery database for " - << p_scb->peer_addr; + log::error("failed to init SDP discovery database for {}", + ADDRESS_TO_LOGGABLE_STR(p_scb->peer_addr)); } // Failure actions bta_ag_free_db(p_scb, tBTA_AG_DATA::kEmpty); diff --git a/system/bta/ag/bta_ag_swb_aptx.cc b/system/bta/ag/bta_ag_swb_aptx.cc index b24f5c8fc40be2ff8b8924e1b2def77db14dce2e..d0cfbe194f8531d4fbb2ab5224fa154de4fef7ca 100644 --- a/system/bta/ag/bta_ag_swb_aptx.cc +++ b/system/bta/ag/bta_ag_swb_aptx.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -25,6 +26,8 @@ #include "common/strings.h" #include "stack/include/btm_api_types.h" +using namespace bluetooth; + bool is_hfp_aptx_voice_enabled() { return IS_FLAG_ENABLED(hfp_codec_aptx_voice) && GET_SYSPROP(Hfp, codec_aptx_voice, false); @@ -34,7 +37,7 @@ void bta_ag_swb_handle_vs_at_events(tBTA_AG_SCB* p_scb, uint16_t cmd, int16_t int_arg, tBTA_AG_VAL* val) { switch (cmd) { case BTA_AG_AT_QAC_EVT: - LOG_VERBOSE("BTA_AG_AT_QAC_EVT"); + log::verbose("BTA_AG_AT_QAC_EVT"); p_scb->codec_updated = true; if (p_scb->peer_codecs & BTA_AG_SCO_APTX_SWB_SETTINGS_Q0_MASK) { p_scb->sco_codec = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0; @@ -42,15 +45,15 @@ void bta_ag_swb_handle_vs_at_events(tBTA_AG_SCB* p_scb, uint16_t cmd, p_scb->sco_codec = UUID_CODEC_MSBC; } bta_ag_send_qac(p_scb, NULL); - LOG_VERBOSE("Received AT+QAC, updating sco codec to SWB: %d", - p_scb->sco_codec); + log::verbose("Received AT+QAC, updating sco codec to SWB: {}", + p_scb->sco_codec); val->num = p_scb->peer_codecs; break; case BTA_AG_AT_QCS_EVT: { tBTA_AG_PEER_CODEC codec_type, codec_sent; alarm_cancel(p_scb->codec_negotiation_timer); - LOG_VERBOSE("BTA_AG_AT_QCS_EVT int_arg=%d", int_arg); + log::verbose("BTA_AG_AT_QCS_EVT int_arg={}", int_arg); switch (int_arg) { case BTA_AG_SCO_APTX_SWB_SETTINGS_Q0: codec_type = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0; @@ -65,7 +68,7 @@ void bta_ag_swb_handle_vs_at_events(tBTA_AG_SCB* p_scb, uint16_t cmd, codec_type = BTA_AG_SCO_APTX_SWB_SETTINGS_Q3; break; default: - LOG_ERROR("Unknown codec_uuid %d", int_arg); + log::error("Unknown codec_uuid {}", int_arg); p_scb->is_aptx_swb_codec = false; codec_type = BTM_SCO_CODEC_MSBC; p_scb->codec_fallback = true; @@ -113,7 +116,7 @@ tBTA_AG_PEER_CODEC bta_ag_parse_qac(char* p_s) { retval |= BTA_AG_SCO_APTX_SWB_SETTINGS_Q3_MASK; break; default: - LOG_VERBOSE("Unknown Codec UUID(%d) received\n", codec_mode); + log::verbose("Unknown Codec UUID({}) received", codec_mode); break; } } diff --git a/system/bta/ar/bta_ar.cc b/system/bta/ar/bta_ar.cc index 028fc8e62d113a17facbb5c67b9ab19a106bfc01..72fccae079e828f662d1485ae8b0556334a552fd 100644 --- a/system/bta/ar/bta_ar.cc +++ b/system/bta/ar/bta_ar.cc @@ -22,6 +22,8 @@ * ******************************************************************************/ +#include + #include #include "bta/ar/bta_ar_int.h" @@ -34,6 +36,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; /* AV control block */ tBTA_AR_CB bta_ar_cb; @@ -113,8 +116,8 @@ void bta_ar_reg_avdt(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback) { if (bta_ar_cb.avdt_registered == 0) { AVDT_Register(p_reg, bta_ar_avdt_cback); } else { - LOG_WARN("%s: doesn't register again (registered:%d)", __func__, - bta_ar_cb.avdt_registered); + log::warn("doesn't register again (registered:{})", + bta_ar_cb.avdt_registered); } bta_ar_cb.avdt_registered |= BTA_AR_AV_MASK; } @@ -330,7 +333,7 @@ void bta_ar_reg_avrc_for_src_sink_coexist( } else { /* If first reg 1,3 version, reg 1.6 must update class id */ if (bta_ar_cb.ct_ver < profile_version) { - LOG_VERBOSE("%s ver=0x%x", __FUNCTION__, profile_version); + log::verbose("ver=0x{:x}", profile_version); if (bta_ar_cb.ct_ver <= AVRC_REV_1_3 && profile_version > AVRC_REV_1_3) { bta_ar_cb.ct_ver = profile_version; diff --git a/system/bta/av/bta_av_aact.cc b/system/bta/av/bta_av_aact.cc index 46912d0bd03585356ff3a21ded197a79d85238ea..0be93e4b51ba4bcc6d156b163edcf03521f653fc 100644 --- a/system/bta/av/bta_av_aact.cc +++ b/system/bta/av/bta_av_aact.cc @@ -27,6 +27,7 @@ #define LOG_TAG "bt_bta_av" #include +#include #include #include @@ -42,10 +43,12 @@ #include "btif/include/btif_storage.h" #include "device/include/device_iot_config.h" #include "device/include/interop.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "osi/include/properties.h" +#include "stack/include/a2dp_ext.h" #include "stack/include/a2dp_sbc.h" #include "stack/include/acl_api.h" #include "stack/include/bt_hdr.h" @@ -55,9 +58,12 @@ #include "stack/include/btm_client_interface.h" #include "stack/include/btm_log_history.h" #include "stack/include/l2c_api.h" +#include "storage/config_keys.h" #include "types/hci_role.h" #include "types/raw_address.h" +using namespace bluetooth; + namespace { constexpr char kBtmLogTag[] = "A2DP"; @@ -183,7 +189,7 @@ static uint8_t bta_av_get_scb_handle(tBTA_AV_SCB* p_scb, uint8_t local_sep) { return (p_scb->seps[i].av_handle); } } - LOG_VERBOSE("%s: local sep_type %d not found", __func__, local_sep); + log::verbose("local sep_type {} not found", local_sep); return 0; /* return invalid handle */ } @@ -201,7 +207,7 @@ static uint8_t bta_av_get_scb_sep_type(tBTA_AV_SCB* p_scb, for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) { if (p_scb->seps[i].av_handle == tavdt_handle) return (p_scb->seps[i].tsep); } - LOG_VERBOSE("%s: avdt_handle %d not found", __func__, tavdt_handle); + log::verbose("avdt_handle {} not found", tavdt_handle); return AVDT_TSEP_INVALID; } @@ -216,13 +222,13 @@ static uint8_t bta_av_get_scb_sep_type(tBTA_AV_SCB* p_scb, * ******************************************************************************/ static void bta_av_save_addr(tBTA_AV_SCB* p_scb, const RawAddress& bd_addr) { - LOG_VERBOSE("%s: peer=%s recfg_sup:%d, suspend_sup:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p_scb->recfg_sup, - p_scb->suspend_sup); + log::verbose("peer={} recfg_sup:{}, suspend_sup:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p_scb->recfg_sup, + p_scb->suspend_sup); if (p_scb->PeerAddress() != bd_addr) { - LOG_INFO("%s: reset flags old_addr=%s new_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("reset flags old_addr={} new_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); /* a new addr, reset the supported flags */ p_scb->recfg_sup = true; p_scb->suspend_sup = true; @@ -244,9 +250,9 @@ static void bta_av_save_addr(tBTA_AV_SCB* p_scb, const RawAddress& bd_addr) { * ******************************************************************************/ static void notify_start_failed(tBTA_AV_SCB* p_scb) { - LOG_ERROR("%s: peer %s role:0x%x bta_channel:%d bta_handle:0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->role, - p_scb->chnl, p_scb->hndl); + log::error("peer {} role:0x{:x} bta_channel:{} bta_handle:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->role, + p_scb->chnl, p_scb->hndl); tBTA_AV bta_av_data = { .start = { @@ -276,8 +282,7 @@ static void notify_start_failed(tBTA_AV_SCB* p_scb) { * ******************************************************************************/ void bta_av_st_rc_timer(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: rc_handle:%d, use_rc: %d", __func__, p_scb->rc_handle, - p_scb->use_rc); + log::verbose("rc_handle:{}, use_rc: {}", p_scb->rc_handle, p_scb->use_rc); /* for outgoing RC connection as INT/CT */ if ((p_scb->rc_handle == BTA_AV_RC_HANDLE_NONE) && /* (bta_av_cb.features & BTA_AV_FEAT_RCCT) && */ @@ -331,8 +336,8 @@ static bool bta_av_next_getcap(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { /* if no streams available then stream open fails */ if (!sent_cmd) { - LOG_ERROR("%s: BTA_AV_STR_GETCAP_FAIL_EVT: peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("BTA_AV_STR_GETCAP_FAIL_EVT: peer_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); bta_av_ssm_execute(p_scb, BTA_AV_STR_GETCAP_FAIL_EVT, p_data); } @@ -355,10 +360,10 @@ void bta_av_proc_stream_evt(uint8_t handle, const RawAddress& bd_addr, tBTA_AV_SCB* p_scb = bta_av_cb.p_scb[scb_index]; uint16_t sec_len = 0; - LOG_VERBOSE( - "%s: peer_address: %s avdt_handle: %d event=0x%x scb_index=%d p_scb=%p", - __func__, ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle, event, scb_index, - p_scb); + log::verbose( + "peer_address: {} avdt_handle: {} event=0x{:x} scb_index={} p_scb={}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle, event, scb_index, + fmt::ptr(p_scb)); if (p_data) { if (event == AVDT_SECURITY_IND_EVT) { @@ -381,8 +386,8 @@ void bta_av_proc_stream_evt(uint8_t handle, const RawAddress& bd_addr, p_msg->bd_addr = bd_addr; p_msg->scb_index = scb_index; - LOG_VERBOSE("%s: stream event bd_addr: %s scb_index: %u", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_msg->bd_addr), scb_index); + log::verbose("stream event bd_addr: {} scb_index: {}", + ADDRESS_TO_LOGGABLE_CSTR(p_msg->bd_addr), scb_index); if (p_data != NULL) { memcpy(&p_msg->msg, p_data, sizeof(tAVDT_CTRL)); @@ -432,8 +437,7 @@ void bta_av_proc_stream_evt(uint8_t handle, const RawAddress& bd_addr, p_msg->initiator = false; if (event == AVDT_SUSPEND_CFM_EVT) p_msg->initiator = true; - LOG_VERBOSE("%s: bta_handle:0x%x avdt_handle:%d", __func__, p_scb->hndl, - handle); + log::verbose("bta_handle:0x{:x} avdt_handle:{}", p_scb->hndl, handle); p_msg->hdr.layer_specific = p_scb->hndl; p_msg->handle = handle; p_msg->avdt_event = event; @@ -443,7 +447,7 @@ void bta_av_proc_stream_evt(uint8_t handle, const RawAddress& bd_addr, if (p_data) { bta_av_conn_cback(handle, bd_addr, event, p_data, scb_index); } else { - LOG_ERROR("%s: p_data is null", __func__); + log::error("p_data is null"); } } @@ -460,10 +464,10 @@ void bta_av_sink_data_cback(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp, uint8_t m_pt) { int index = 0; tBTA_AV_SCB* p_scb; - LOG_VERBOSE( - "%s: avdt_handle: %d pkt_len=0x%x offset = 0x%x " - "number of frames 0x%x sequence number 0x%x", - __func__, handle, p_pkt->len, p_pkt->offset, + log::verbose( + "avdt_handle: {} pkt_len=0x{:x} offset = 0x{:x} number of frames 0x{:x} " + "sequence number 0x{:x}", + handle, p_pkt->len, p_pkt->offset, *((uint8_t*)(p_pkt + 1) + p_pkt->offset), p_pkt->layer_specific); /* Get SCB and correct sep type */ for (index = 0; index < BTA_AV_NUM_STRS; index++) { @@ -496,9 +500,8 @@ void bta_av_sink_data_cback(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp, ******************************************************************************/ static void bta_av_a2dp_sdp_cback(bool found, tA2DP_Service* p_service, const RawAddress& peer_address) { - LOG_VERBOSE("%s: peer %s : found=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - (found) ? "true" : "false"); + log::verbose("peer {} : found={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + (found) ? "true" : "false"); tBTA_AV_SCB* p_scb = NULL; if (peer_address != RawAddress::kEmpty) { @@ -508,22 +511,21 @@ static void bta_av_a2dp_sdp_cback(bool found, tA2DP_Service* p_service, p_scb = bta_av_hndl_to_scb(bta_av_cb.handle); } if (p_scb == NULL) { - LOG_ERROR("%s: no scb found for SDP handle(0x%x)", __func__, - bta_av_cb.handle); + log::error("no scb found for SDP handle(0x{:x})", bta_av_cb.handle); return; } if (bta_av_cb.handle != p_scb->hndl) { - LOG_WARN("%s: SDP bta_handle expected=0x%x processing=0x%x", __func__, - bta_av_cb.handle, p_scb->hndl); + log::warn("SDP bta_handle expected=0x{:x} processing=0x{:x}", + bta_av_cb.handle, p_scb->hndl); } if (!found) { - LOG_ERROR("%s: peer %s A2DP service discovery failed", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("peer {} A2DP service discovery failed", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); } - LOG_VERBOSE("%s: peer %s found=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - (found) ? "true" : "false"); + log::verbose("peer {} found={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + (found) ? "true" : "false"); tBTA_AV_SDP_RES* p_msg = (tBTA_AV_SDP_RES*)osi_malloc(sizeof(tBTA_AV_SDP_RES)); @@ -531,8 +533,8 @@ static void bta_av_a2dp_sdp_cback(bool found, tA2DP_Service* p_service, p_msg->hdr.event = BTA_AV_SDP_DISC_OK_EVT; } else { p_msg->hdr.event = BTA_AV_SDP_DISC_FAIL_EVT; - LOG_ERROR("%s: BTA_AV_SDP_DISC_FAIL_EVT: peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("BTA_AV_SDP_DISC_FAIL_EVT: peer_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); } if (found && (p_service != NULL)) { p_scb->SetAvdtpVersion(p_service->avdt_version); @@ -542,12 +544,12 @@ static void bta_av_a2dp_sdp_cback(bool found, tA2DP_Service* p_service, if (p_service->avdt_version != 0) { if (btif_config_set_bin(p_scb->PeerAddress().ToString(), - AVDTP_VERSION_CONFIG_KEY, + BTIF_STORAGE_KEY_AVDTP_VERSION, (const uint8_t*)&p_service->avdt_version, sizeof(p_service->avdt_version))) { } else { - LOG_WARN("%s: Failed to store peer AVDTP version for %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::warn("Failed to store peer AVDTP version for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); } } } else { @@ -568,11 +570,10 @@ static void bta_av_a2dp_sdp_cback(bool found, tA2DP_Service* p_service, * ******************************************************************************/ static void bta_av_adjust_seps_idx(tBTA_AV_SCB* p_scb, uint8_t avdt_handle) { - LOG_VERBOSE("%s: codec: %s", __func__, A2DP_CodecName(p_scb->cfg.codec_info)); + log::verbose("codec: {}", A2DP_CodecName(p_scb->cfg.codec_info)); for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) { - LOG_VERBOSE("%s: avdt_handle: %d codec: %s", __func__, - p_scb->seps[i].av_handle, - A2DP_CodecName(p_scb->seps[i].codec_info)); + log::verbose("avdt_handle: {} codec: {}", p_scb->seps[i].av_handle, + A2DP_CodecName(p_scb->seps[i].codec_info)); if (p_scb->seps[i].av_handle && (p_scb->seps[i].av_handle == avdt_handle) && A2DP_CodecTypeEquals(p_scb->seps[i].codec_info, p_scb->cfg.codec_info)) { @@ -597,8 +598,8 @@ void bta_av_switch_role(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { tBTA_AV_RS_RES switch_res = BTA_AV_RS_NONE; tBTA_AV_API_OPEN* p_buf = &p_scb->q_info.open; - LOG_VERBOSE("%s: peer %s wait:0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait); + log::verbose("peer {} wait:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait); if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_RES_START) p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RETRY; @@ -617,8 +618,8 @@ void bta_av_switch_role(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { } } else { /* report failure on OPEN */ - LOG_ERROR("%s: peer %s role switch failed (wait=0x%x)", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait); + log::error("peer {} role switch failed (wait=0x{:x})", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait); switch_res = BTA_AV_RS_FAIL; } @@ -646,9 +647,9 @@ void bta_av_switch_role(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { bool initiator = false; - LOG_VERBOSE("%s: peer %s q_tag:%d, wait:0x%x, role:0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->q_tag, - p_scb->wait, p_scb->role); + log::verbose("peer {} q_tag:{}, wait:0x{:x}, role:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->q_tag, + p_scb->wait, p_scb->role); if (p_scb->role & BTA_AV_ROLE_START_INT) initiator = true; if (p_scb->q_tag == BTA_AV_Q_TAG_START) { @@ -705,16 +706,16 @@ void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { bta_av_do_disc_a2dp(p_scb, (tBTA_AV_DATA*)&(p_scb->q_info.open)); } } else { - LOG_WARN( - "%s: peer %s unexpected role switch event: q_tag = %d wait = 0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - p_scb->q_tag, p_scb->wait); + log::warn( + "peer {} unexpected role switch event: q_tag = {} wait = 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->q_tag, + p_scb->wait); } } - LOG_VERBOSE("%s: peer %s wait:0x%x, role:0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait, - p_scb->role); + log::verbose("peer {} wait:0x{:x}, role:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait, + p_scb->role); } /******************************************************************************* @@ -728,9 +729,9 @@ void bta_av_role_res(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_delay_co(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: peer %s bta_handle:0x%x delay:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - p_data->str_msg.msg.delay_rpt_cmd.delay); + log::verbose("peer {} bta_handle:0x{:x} delay:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + p_data->str_msg.msg.delay_rpt_cmd.delay); p_scb->p_cos->delay(p_scb->hndl, p_scb->PeerAddress(), p_data->str_msg.msg.delay_rpt_cmd.delay); } @@ -752,10 +753,10 @@ void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { ATTR_ID_BT_PROFILE_DESC_LIST}; uint16_t sdp_uuid = 0; /* UUID for which SDP has to be done */ - LOG_VERBOSE("%s: peer_addr: %s use_rc: %d switch_res:%d, oc:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_data->api_open.bd_addr), - p_data->api_open.use_rc, p_data->api_open.switch_res, - bta_av_cb.audio_open_cnt); + log::verbose("peer_addr: {} use_rc: {} switch_res:{}, oc:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->api_open.bd_addr), + p_data->api_open.use_rc, p_data->api_open.switch_res, + bta_av_cb.audio_open_cnt); memcpy(&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN)); @@ -776,8 +777,8 @@ void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { case BTA_AV_RS_FAIL: /* report a new failure event */ p_scb->open_status = BTA_AV_FAIL_ROLE; - LOG_ERROR("%s: BTA_AV_SDP_DISC_FAIL_EVT: peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("BTA_AV_SDP_DISC_FAIL_EVT: peer_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); bta_av_ssm_execute(p_scb, BTA_AV_SDP_DISC_FAIL_EVT, NULL); break; @@ -796,8 +797,8 @@ void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { break; } - LOG_VERBOSE("%s: ok_continue: %d wait:0x%x, q_tag: %d", __func__, ok_continue, - p_scb->wait, p_scb->q_tag); + log::verbose("ok_continue: {} wait:0x{:x}, q_tag: {}", ok_continue, + p_scb->wait, p_scb->q_tag); if (!ok_continue) return; /* clear the role switch bits */ @@ -826,19 +827,18 @@ void bta_av_do_disc_a2dp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { else if (p_scb->uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) sdp_uuid = UUID_SERVCLASS_AUDIO_SINK; - LOG_VERBOSE( - "%s: Initiate SDP discovery for peer %s : uuid_int=0x%x " - "sdp_uuid=0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->uuid_int, + log::verbose( + "Initiate SDP discovery for peer {} : uuid_int=0x{:x} sdp_uuid=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->uuid_int, sdp_uuid); tA2DP_STATUS find_service_status = A2DP_FindService( sdp_uuid, p_scb->PeerAddress(), &db_params, bta_av_a2dp_sdp_cback); if (find_service_status != A2DP_SUCCESS) { - LOG_ERROR( - "%s: A2DP_FindService() failed for peer %s uuid_int=0x%x " - "sdp_uuid=0x%x : status=%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - p_scb->uuid_int, sdp_uuid, find_service_status); + log::error( + "A2DP_FindService() failed for peer {} uuid_int=0x{:x} sdp_uuid=0x{:x} " + ": status={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->uuid_int, + sdp_uuid, find_service_status); bta_av_a2dp_sdp_cback(false, nullptr, p_scb->PeerAddress()); } else { /* only one A2DP find service is active at a time */ @@ -859,8 +859,7 @@ void bta_av_cleanup(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { tBTA_AV_CONN_CHG msg; uint8_t role = BTA_AV_ROLE_AD_INT; - LOG_INFO("%s peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::info("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); /* free any buffers */ p_scb->sdp_discovery_started = false; @@ -945,11 +944,10 @@ void bta_av_config_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { local_sep = bta_av_get_scb_sep_type(p_scb, p_msg->handle); p_scb->avdt_label = p_data->str_msg.msg.hdr.label; - LOG_VERBOSE("%s: peer %s bta_handle:0x%x local_sep:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - local_sep); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_evt_cfg->codec_info).c_str()); + log::verbose("peer {} bta_handle:0x{:x} local_sep:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + local_sep); + log::verbose("codec: {}", A2DP_CodecInfoString(p_evt_cfg->codec_info)); memcpy(p_scb->cfg.codec_info, p_evt_cfg->codec_info, AVDT_CODEC_SIZE); bta_av_save_addr(p_scb, p_data->str_msg.bd_addr); @@ -995,8 +993,8 @@ void bta_av_config_ind(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { p_scb->num_seps = 1; p_scb->sep_info_idx = 0; - LOG_VERBOSE("%s: SEID: %d use_rc: %d cur_psc_mask:0x%x", __func__, - p_info->seid, p_scb->use_rc, p_scb->cur_psc_mask); + log::verbose("SEID: {} use_rc: {} cur_psc_mask:0x{:x}", p_info->seid, + p_scb->use_rc, p_scb->cur_psc_mask); /* in case of A2DP SINK this is the first time peer data is being sent to * co functions */ if (local_sep == AVDT_TSEP_SNK) { @@ -1026,8 +1024,8 @@ void bta_av_disconnect_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { tBTA_AV_RCB* p_rcb; - LOG_VERBOSE("%s: conn_lcb: 0x%x peer_addr: %s", __func__, bta_av_cb.conn_lcb, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::verbose("conn_lcb: 0x{:x} peer_addr: {}", bta_av_cb.conn_lcb, + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); alarm_cancel(p_scb->link_signalling_timer); alarm_cancel(p_scb->accept_signalling_timer); @@ -1042,8 +1040,8 @@ void bta_av_disconnect_req(tBTA_AV_SCB* p_scb, } AVDT_DisconnectReq(p_scb->PeerAddress(), &bta_av_proc_stream_evt); } else { - LOG_WARN("%s: conn_lcb=0x%x bta_handle=0x%x (hdi=%u) no link", __func__, - bta_av_cb.conn_lcb, p_scb->hndl, p_scb->hdi); + log::warn("conn_lcb=0x{:x} bta_handle=0x{:x} (hdi={}) no link", + bta_av_cb.conn_lcb, p_scb->hndl, p_scb->hdi); bta_av_ssm_execute(p_scb, BTA_AV_AVDT_DISCONNECT_EVT, NULL); } } @@ -1104,9 +1102,9 @@ void bta_av_setconfig_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { /* we like this codec_type. find the sep_idx */ local_sep = bta_av_get_scb_sep_type(p_scb, avdt_handle); bta_av_adjust_seps_idx(p_scb, avdt_handle); - LOG_INFO( - "%s: peer %s bta_handle=0x%x avdt_handle=%d sep_idx=%d cur_psc_mask:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + log::info( + "peer {} bta_handle=0x{:x} avdt_handle={} sep_idx={} cur_psc_mask:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, p_scb->avdt_handle, p_scb->sep_idx, p_scb->cur_psc_mask); if ((AVDT_TSEP_SNK == local_sep) && @@ -1128,8 +1126,8 @@ void bta_av_setconfig_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { p_scb->wait = BTA_AV_WAIT_ACP_CAPS_ON; if (p_data->ci_setconfig.recfg_needed) p_scb->role |= BTA_AV_ROLE_SUSPEND_OPT; - LOG_VERBOSE("%s: recfg_needed:%d role:0x%x num:%d", __func__, - p_data->ci_setconfig.recfg_needed, p_scb->role, num); + log::verbose("recfg_needed:{} role:0x{:x} num:{}", + p_data->ci_setconfig.recfg_needed, p_scb->role, num); /* callout module tells BTA the number of "good" SEPs and their SEIDs. * getcap on these SEID */ p_scb->num_seps = num; @@ -1156,7 +1154,7 @@ void bta_av_setconfig_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } for (i = 1; i < num; i++) { - LOG_VERBOSE("%s: sep_info[%d] SEID: %d", __func__, i, p_seid[i - 1]); + log::verbose("sep_info[{}] SEID: {}", i, p_seid[i - 1]); /* initialize the sep_info[] to get capabilities */ p_scb->sep_info[i].in_use = false; p_scb->sep_info[i].tsep = AVDT_TSEP_SNK; @@ -1201,8 +1199,8 @@ void bta_av_str_opened(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { char remote_name[BTM_MAX_REM_BD_NAME_LEN] = ""; uint8_t* p; - LOG_VERBOSE("%s: peer %s bta_handle: 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl); + log::verbose("peer {} bta_handle: 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl); msg.hdr.layer_specific = p_scb->hndl; msg.is_up = true; @@ -1216,16 +1214,15 @@ void bta_av_str_opened(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if (interop_match_name(INTEROP_DISABLE_AVDTP_SUSPEND, remote_name) || interop_match_addr(INTEROP_DISABLE_AVDTP_SUSPEND, &p_scb->PeerAddress())) { - LOG_INFO("%s: disable AVDTP SUSPEND: interop matched name %s address %s", - __func__, remote_name, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::info("disable AVDTP SUSPEND: interop matched name {} address {}", + remote_name, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); p_scb->suspend_sup = false; } p_scb->stream_mtu = p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE; - LOG_VERBOSE("%s: l2c_cid: 0x%x stream_mtu: %d", __func__, p_scb->l2c_cid, - p_scb->stream_mtu); + log::verbose("l2c_cid: 0x{:x} stream_mtu: {}", p_scb->l2c_cid, + p_scb->stream_mtu); /* Set the media channel as high priority */ L2CA_SetTxPriority(p_scb->l2c_cid, L2CAP_CHNL_PRIORITY_HIGH); @@ -1291,7 +1288,7 @@ void bta_av_str_opened(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { char value[PROPERTY_VALUE_MAX] = {0}; if ((osi_property_get("bluetooth.pts.force_a2dp_abort", value, "false")) && (!strcmp(value, "true"))) { - LOG_ERROR("%s: Calling AVDT_AbortReq", __func__); + log::error("Calling AVDT_AbortReq"); AVDT_AbortReq(p_scb->avdt_handle); } } @@ -1362,7 +1359,7 @@ void bta_av_security_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_do_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: p_scb->co_started=%d", __func__, p_scb->co_started); + log::verbose("p_scb->co_started={}", p_scb->co_started); /* stop stream if started */ if (p_scb->co_started) { @@ -1397,16 +1394,16 @@ void bta_av_do_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_connect_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: peer %s coll_mask=0x%02x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->coll_mask); + log::verbose("peer {} coll_mask=0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + p_scb->coll_mask); p_scb->sdp_discovery_started = false; if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) { /* SNK initiated L2C connection while SRC was doing SDP. */ /* Wait until timeout to check if SNK starts signalling. */ - LOG_WARN("%s: coll_mask=0x%02x incoming timer is up", __func__, - p_scb->coll_mask); + log::warn("coll_mask=0x{:02x} incoming timer is up", p_scb->coll_mask); p_scb->coll_mask |= BTA_AV_COLL_API_CALLED; - LOG_VERBOSE("%s: updated coll_mask=0x%02x", __func__, p_scb->coll_mask); + log::verbose("updated coll_mask=0x{:02x}", p_scb->coll_mask); return; } @@ -1423,8 +1420,9 @@ void bta_av_connect_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_sdp_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { - LOG_ERROR("%s: peer_addr=%s open_status=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->open_status); + log::error("peer_addr={} open_status={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + p_scb->open_status); if (p_scb->open_status == BTA_AV_SUCCESS) { p_scb->open_status = BTA_AV_FAIL_SDP; @@ -1450,9 +1448,9 @@ void bta_av_disc_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { /* our uuid in case we initiate connection */ uint16_t uuid_int = p_scb->uuid_int; - LOG_VERBOSE("%s: peer %s bta_handle: 0x%x initiator UUID 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - uuid_int); + log::verbose("peer {} bta_handle: 0x{:x} initiator UUID 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + uuid_int); /* store number of stream endpoints returned */ p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps; @@ -1467,19 +1465,19 @@ void bta_av_disc_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if (p_scb->sep_info[i].tsep == AVDT_TSEP_SRC) num_srcs++; } } - LOG_VERBOSE("both_enable=%d, uuid_int=0x%x, incoming=%d", - btif_av_both_enable(), uuid_int, p_scb->open_api.incoming); + log::verbose("both_enable={}, uuid_int=0x{:x}, incoming={}", + btif_av_both_enable(), uuid_int, p_scb->open_api.incoming); if (btif_av_both_enable() && p_scb->open_api.incoming) { if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE && num_snks == 0 && num_srcs > 0) { p_scb->uuid_int = UUID_SERVCLASS_AUDIO_SINK; - LOG_VERBOSE(" change UUID to 0x%x, num_snks=%u, num_srcs=%u", - p_scb->uuid_int, num_snks, num_srcs); + log::verbose("change UUID to 0x{:x}, num_snks={}, num_srcs={}", + p_scb->uuid_int, num_snks, num_srcs); } else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK && num_srcs == 0 && num_snks > 0) { p_scb->uuid_int = UUID_SERVCLASS_AUDIO_SOURCE; - LOG_VERBOSE(" change UUID to 0x%x, num_snks=%u, num_srcs=%u", - p_scb->uuid_int, num_snks, num_srcs); + log::verbose("change UUID to 0x{:x}, num_snks={}, num_srcs={}", + p_scb->uuid_int, num_snks, num_srcs); } uuid_int = p_scb->uuid_int; } @@ -1514,8 +1512,8 @@ void bta_av_disc_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } /* else we got discover response but with no streams; we're done */ else { - LOG_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("BTA_AV_STR_DISC_FAIL_EVT: peer_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data); } } @@ -1534,8 +1532,8 @@ void bta_av_disc_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { void bta_av_disc_res_as_acp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { uint8_t num_snks = 0, i; - LOG_VERBOSE("%s: peer %s bta_handle: 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl); + log::verbose("peer {} bta_handle: 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl); /* store number of stream endpoints returned */ p_scb->num_seps = p_data->str_msg.msg.discover_cfm.num_seps; @@ -1563,8 +1561,8 @@ void bta_av_disc_res_as_acp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } /* else we got discover response but with no streams; we're done */ else { - LOG_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("BTA_AV_STR_DISC_FAIL_EVT: peer_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, p_data); } } @@ -1584,12 +1582,11 @@ void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { uint8_t old_wait = p_scb->wait; bool getcap_done = false; - LOG_VERBOSE( - "%s: peer %s bta_handle:0x%x num_seps:%d sep_info_idx:%d wait:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + log::verbose( + "peer {} bta_handle:0x{:x} num_seps:{} sep_info_idx:{} wait:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, p_scb->num_seps, p_scb->sep_info_idx, p_scb->wait); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_scb->peer_cap.codec_info).c_str()); + log::verbose("codec: {}", A2DP_CodecInfoString(p_scb->peer_cap.codec_info)); cfg = p_scb->peer_cap; /* let application know the capability of the SNK */ @@ -1597,16 +1594,13 @@ void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { &p_scb->sep_info_idx, p_info->seid, &cfg.num_protect, cfg.protect_info) != A2DP_SUCCESS) { p_scb->sep_info_idx++; - LOG_VERBOSE("%s: result: next sep_info_idx:%d", __func__, - p_scb->sep_info_idx); + log::verbose("result: next sep_info_idx:{}", p_scb->sep_info_idx); } else { // All capabilities found getcap_done = true; - LOG_VERBOSE("%s: result: done sep_info_idx:%d", __func__, - p_scb->sep_info_idx); + log::verbose("result: done sep_info_idx:{}", p_scb->sep_info_idx); } - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(cfg.codec_info).c_str()); + log::verbose("codec: {}", A2DP_CodecInfoString(cfg.codec_info)); if (p_scb->num_seps > p_scb->sep_info_idx && !getcap_done) { /* Some devices have seps at the end of the discover list, which is not */ @@ -1619,8 +1613,8 @@ void bta_av_save_caps(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } if (getcap_done) { - LOG_VERBOSE("%s: getcap_done: num_seps:%d sep_info_idx:%d wait:0x%x", - __func__, p_scb->num_seps, p_scb->sep_info_idx, p_scb->wait); + log::verbose("getcap_done: num_seps:{} sep_info_idx:{} wait:0x{:x}", + p_scb->num_seps, p_scb->sep_info_idx, p_scb->wait); p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON | BTA_AV_WAIT_ACP_CAPS_STARTED); if (old_wait & BTA_AV_WAIT_ACP_CAPS_STARTED) { bta_av_start_ok(p_scb, NULL); @@ -1651,8 +1645,8 @@ void bta_av_set_use_rc(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_cco_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: peer %s bta_handle:0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl); + log::verbose("peer {} bta_handle:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl); p_scb->p_cos->close(p_scb->hndl, p_scb->PeerAddress()); } @@ -1670,8 +1664,7 @@ void bta_av_open_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tBTA_AV_SCB* p_opened_scb = NULL; uint8_t idx; - LOG_ERROR("%s: peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("peer_addr={}", ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); p_scb->open_status = BTA_AV_FAIL_STREAM; bta_av_cco_close(p_scb, p_data); @@ -1706,10 +1699,10 @@ void bta_av_open_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { bta_av_data.open.sep = AVDT_TSEP_SRC; } - LOG_ERROR( - "%s: there is already an active connection: peer_addr=%s chnl=%d " - "hndl=0x%x status=%d starting=%d edr=%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(bta_av_data.open.bd_addr), + log::error( + "there is already an active connection: peer_addr={} chnl={} " + "hndl=0x{:x} status={} starting={} edr={}", + ADDRESS_TO_LOGGABLE_CSTR(bta_av_data.open.bd_addr), bta_av_data.open.chnl, bta_av_data.open.hndl, bta_av_data.open.status, bta_av_data.open.starting, bta_av_data.open.edr); @@ -1740,13 +1733,11 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { memcpy(cfg.codec_info, p_scb->peer_cap.codec_info, AVDT_CODEC_SIZE); memcpy(cfg.protect_info, p_scb->peer_cap.protect_info, AVDT_PROTECT_SIZE); - LOG_VERBOSE("%s: peer %s bta_handle:0x%x num_codec:%d psc_mask=0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - p_scb->hndl, p_scb->peer_cap.num_codec, p_scb->cfg.psc_mask); - LOG_VERBOSE("%s: media type 0x%x, 0x%x", __func__, media_type, - p_scb->media_type); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str()); + log::verbose("peer {} bta_handle:0x{:x} num_codec:{} psc_mask=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + p_scb->peer_cap.num_codec, p_scb->cfg.psc_mask); + log::verbose("media type 0x{:x}, 0x{:x}", media_type, p_scb->media_type); + log::verbose("codec: {}", A2DP_CodecInfoString(p_scb->cfg.codec_info)); /* if codec present and we get a codec configuration */ if ((p_scb->peer_cap.num_codec != 0) && (media_type == p_scb->media_type) && @@ -1760,32 +1751,31 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { /* save copy of codec configuration */ p_scb->cfg = cfg; - LOG_VERBOSE("%s: result: sep_info_idx=%d", __func__, p_scb->sep_info_idx); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str()); + log::verbose("result: sep_info_idx={}", p_scb->sep_info_idx); + log::verbose("codec: {}", A2DP_CodecInfoString(p_scb->cfg.codec_info)); - LOG_VERBOSE("%s: initiator UUID = 0x%x", __func__, uuid_int); + log::verbose("initiator UUID = 0x{:x}", uuid_int); if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC)); else if (uuid_int == UUID_SERVCLASS_AUDIO_SINK) bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SNK)); - LOG_INFO("%s: sep_idx=%d avdt_handle=%d bta_handle=0x%x", __func__, - p_scb->sep_idx, p_scb->avdt_handle, p_scb->hndl); + log::info("sep_idx={} avdt_handle={} bta_handle=0x{:x}", p_scb->sep_idx, + p_scb->avdt_handle, p_scb->hndl); /* use only the services peer supports */ cfg.psc_mask &= p_scb->peer_cap.psc_mask; p_scb->cur_psc_mask = cfg.psc_mask; - LOG_VERBOSE( - "%s: peer %s bta_handle:0x%x sep_idx:%d sep_info_idx:%d " - "cur_psc_mask:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + log::verbose( + "peer {} bta_handle:0x{:x} sep_idx:{} sep_info_idx:{} " + "cur_psc_mask:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, p_scb->sep_idx, p_scb->sep_info_idx, p_scb->cur_psc_mask); if ((uuid_int == UUID_SERVCLASS_AUDIO_SINK) && (p_scb->seps[p_scb->sep_idx].p_app_sink_data_cback != NULL)) { - LOG_VERBOSE("%s: configure decoder for Sink connection", __func__); + log::verbose("configure decoder for Sink connection"); tBTA_AV_MEDIA av_sink_codec_info = { .avk_config = { @@ -1824,8 +1814,8 @@ void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { uint8_t avdt_handle = p_data->ci_setconfig.avdt_handle; bta_av_adjust_seps_idx(p_scb, avdt_handle); - LOG_INFO("%s: sep_idx=%d avdt_handle=%d bta_handle=0x%x", __func__, - p_scb->sep_idx, p_scb->avdt_handle, p_scb->hndl); + log::info("sep_idx={} avdt_handle={} bta_handle=0x{:x}", p_scb->sep_idx, + p_scb->avdt_handle, p_scb->hndl); AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0); tBTA_AV bta_av_data = { @@ -1865,8 +1855,9 @@ void bta_av_discover_req(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_conn_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { - LOG_ERROR("%s: peer_addr=%s open_status=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->open_status); + log::error("peer_addr={} open_status={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + p_scb->open_status); p_scb->open_status = BTA_AV_FAIL_STREAM; bta_av_str_closed(p_scb, p_data); @@ -1882,14 +1873,14 @@ void bta_av_conn_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { - LOG_INFO( - "A2dp stream start peer:%s sco_occupied:%s av_role:0x%x started:%s " - "wait:0x%x", + log::info( + "A2dp stream start peer:{} sco_occupied:{} av_role:0x{:x} started:{} " + "wait:0x{:x}", ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role, - logbool(p_scb->started).c_str(), p_scb->wait); + logbool(bta_av_cb.sco_occupied), p_scb->role, logbool(p_scb->started), + p_scb->wait); if (bta_av_cb.sco_occupied) { - LOG_WARN("A2dp stream start failed"); + log::warn("A2dp stream start failed"); bta_av_start_failed(p_scb, p_data); return; } @@ -1897,12 +1888,12 @@ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if (p_scb->started) { p_scb->role |= BTA_AV_ROLE_START_INT; if (p_scb->wait != 0) { - LOG_WARN( - "%s: peer %s start stream request ignored: " - "already waiting: sco_occupied:%s role:0x%x started:%s wait:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role, - logbool(p_scb->started).c_str(), p_scb->wait); + log::warn( + "peer {} start stream request ignored: already waiting: " + "sco_occupied:{} role:0x{:x} started:{} wait:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + logbool(bta_av_cb.sco_occupied), p_scb->role, logbool(p_scb->started), + p_scb->wait); return; } if (p_scb->role & BTA_AV_ROLE_SUSPEND) { @@ -1917,12 +1908,12 @@ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } if ((p_scb->role & BTA_AV_ROLE_START_INT) != 0) { - LOG_WARN( - "%s: peer %s start stream request ignored: " - "already initiated: sco_occupied:%s role:0x%x started:%s wait:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role, - logbool(p_scb->started).c_str(), p_scb->wait); + log::warn( + "peer {} start stream request ignored: already initiated: " + "sco_occupied:{} role:0x{:x} started:{} wait:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + logbool(bta_av_cb.sco_occupied), p_scb->role, logbool(p_scb->started), + p_scb->wait); return; } @@ -1942,18 +1933,18 @@ void bta_av_do_start(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { uint16_t result = AVDT_StartReq(&p_scb->avdt_handle, 1); if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: AVDT_StartReq failed for peer %s result:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), result); + log::error("AVDT_StartReq failed for peer {} result:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), result); bta_av_start_failed(p_scb, p_data); } else if (p_data) { bta_av_set_use_latency_mode(p_scb, p_data->do_start.use_latency_mode); } - LOG_INFO( - "%s: peer %s start requested: sco_occupied:%s role:0x%x " - "started:%s wait:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - logbool(bta_av_cb.sco_occupied).c_str(), p_scb->role, - logbool(p_scb->started).c_str(), p_scb->wait); + log::info( + "peer {} start requested: sco_occupied:{} role:0x{:x} started:{} " + "wait:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + logbool(bta_av_cb.sco_occupied), p_scb->role, logbool(p_scb->started), + p_scb->wait); } /******************************************************************************* @@ -1970,9 +1961,9 @@ void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { bool sus_evt = true; BT_HDR* p_buf; - LOG_INFO("peer %s bta_handle:0x%x audio_open_cnt:%d, p_data %p start:%d", - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - bta_av_cb.audio_open_cnt, p_data, start); + log::info("peer {} bta_handle:0x{:x} audio_open_cnt:{}, p_data {} start:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + bta_av_cb.audio_open_cnt, fmt::ptr(p_data), start); bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress()); BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress()); @@ -1982,7 +1973,7 @@ void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { bta_av_vendor_offload_stop(); bta_av_cb.offload_started_hndl = BTA_AV_INVALID_HANDLE; } else if (bta_av_cb.offload_start_pending_hndl == p_scb->hndl) { - LOG_WARN("%s: Stop pending offload start command", __func__); + log::warn("Stop pending offload start command"); bta_av_vendor_offload_stop(); bta_av_cb.offload_start_pending_hndl = BTA_AV_INVALID_HANDLE; } @@ -2011,9 +2002,9 @@ void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { suspend_rsp.hndl = p_scb->hndl; if (p_data && p_data->api_stop.suspend) { - LOG_VERBOSE("%s: peer %s suspending: %d, sup:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), start, - p_scb->suspend_sup); + log::verbose("peer {} suspending: {}, sup:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), start, + p_scb->suspend_sup); if ((start) && (p_scb->suspend_sup)) { sus_evt = false; p_scb->l2c_bufs = 0; @@ -2032,7 +2023,7 @@ void bta_av_str_stopped(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } else { suspend_rsp.status = BTA_AV_SUCCESS; suspend_rsp.initiator = true; - LOG_VERBOSE("%s: status %d", __func__, suspend_rsp.status); + log::verbose("status {}", suspend_rsp.status); // Send STOP_EVT event only if not in reconfiguring state. // However, we should send STOP_EVT if we are reconfiguring when taking @@ -2062,8 +2053,8 @@ void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tBTA_AV_API_STOP stop = {}; tBTA_AV_API_RCFG* p_rcfg = &p_data->api_reconfig; - LOG_VERBOSE("%s: r:%d, s:%d idx: %d (o:%d)", __func__, p_scb->recfg_sup, - p_scb->suspend_sup, p_scb->rcfg_idx, p_scb->sep_info_idx); + log::verbose("r:{}, s:{} idx: {} (o:{})", p_scb->recfg_sup, + p_scb->suspend_sup, p_scb->rcfg_idx, p_scb->sep_info_idx); p_scb->num_recfg = 0; /* store the new configuration in control block */ @@ -2071,14 +2062,13 @@ void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { alarm_cancel(p_scb->avrc_ct_timer); - LOG_DEBUG("p_scb->sep_info_idx=%d p_scb->rcfg_idx=%d p_rcfg->sep_info_idx=%d", - p_scb->sep_info_idx, p_scb->rcfg_idx, p_rcfg->sep_info_idx); - LOG_DEBUG("Peer capable codec: %s", - A2DP_CodecInfoString(p_scb->peer_cap.codec_info).c_str()); - LOG_DEBUG("Current codec: %s", - A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str()); - LOG_DEBUG("Reconfig codec: %s", - A2DP_CodecInfoString(p_rcfg->codec_info).c_str()); + log::debug( + "p_scb->sep_info_idx={} p_scb->rcfg_idx={} p_rcfg->sep_info_idx={}", + p_scb->sep_info_idx, p_scb->rcfg_idx, p_rcfg->sep_info_idx); + log::debug("Peer capable codec: {}", + A2DP_CodecInfoString(p_scb->peer_cap.codec_info)); + log::debug("Current codec: {}", A2DP_CodecInfoString(p_scb->cfg.codec_info)); + log::debug("Reconfig codec: {}", A2DP_CodecInfoString(p_rcfg->codec_info)); BTM_LogHistory( kBtmLogTag, p_scb->PeerAddress(), "Codec reconfig", @@ -2105,16 +2095,15 @@ void bta_av_reconfig(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { bta_av_str_stopped(p_scb, (tBTA_AV_DATA*)&stop); } else { // Reconfigure - LOG_VERBOSE("%s: reconfig", __func__); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str()); + log::verbose("reconfig"); + log::verbose("codec: {}", A2DP_CodecInfoString(p_scb->cfg.codec_info)); AVDT_ReconfigReq(p_scb->avdt_handle, &p_scb->cfg); p_scb->cfg.psc_mask = p_scb->cur_psc_mask; } } else { // Close the stream first, and then Configure it - LOG_VERBOSE("%s: Close/Open started: %d state: %d num_protect: %d", - __func__, p_scb->started, p_scb->state, p_cfg->num_protect); + log::verbose("Close/Open started: {} state: {} num_protect: {}", + p_scb->started, p_scb->state, p_cfg->num_protect); if (p_scb->started) { // Close->Configure->Open->Start if ((p_scb->rcfg_idx != p_scb->sep_info_idx) && p_scb->recfg_sup) { @@ -2281,9 +2270,9 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tHCI_ROLE cur_role; uint8_t local_tsep = p_scb->seps[p_scb->sep_idx].tsep; - LOG_INFO("%s: peer %s bta_handle:0x%x wait:0x%x role:0x%x local_tsep:%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - p_scb->hndl, p_scb->wait, p_scb->role, local_tsep); + log::info("peer {} bta_handle:0x{:x} wait:0x{:x} role:0x{:x} local_tsep:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + p_scb->wait, p_scb->role, local_tsep); p_scb->started = true; @@ -2305,22 +2294,22 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if ((p_scb->avdt_handle == p_scb->seps[p_scb->sep_idx].av_handle) && (local_tsep == AVDT_TSEP_SNK)) { p_scb->wait &= ~(BTA_AV_WAIT_ACP_CAPS_ON); - LOG_VERBOSE("%s: local SEP type is SNK new wait is 0x%x", __func__, - p_scb->wait); + log::verbose("local SEP type is SNK new wait is 0x{:x}", p_scb->wait); } if (p_scb->wait & BTA_AV_WAIT_ROLE_SW_FAILED) { /* role switch has failed */ - LOG_ERROR( - "%s: peer %s role switch failed: bta_handle:0x%x wait:0x%x, role:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + log::error( + "peer {} role switch failed: bta_handle:0x{:x} wait:0x{:x}, " + "role:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, p_scb->wait, p_scb->role); p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_FAILED; p_data = (tBTA_AV_DATA*)&hdr; hdr.offset = BTA_AV_RS_FAIL; } - LOG_VERBOSE("%s: peer %s wait:0x%x use_rtp_header_marker_bit:%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait, - (p_scb->use_rtp_header_marker_bit) ? "true" : "false"); + log::verbose("peer {} wait:0x{:x} use_rtp_header_marker_bit:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait, + (p_scb->use_rtp_header_marker_bit) ? "true" : "false"); if (p_data && (p_data->hdr.offset != BTA_AV_RS_NONE)) { p_scb->wait &= ~BTA_AV_WAIT_ROLE_SW_BITS; @@ -2360,9 +2349,9 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } if (p_scb->wait) { - LOG_ERROR("%s: peer %s wait:0x%x q_tag:%d not started", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait, - p_scb->q_tag); + log::error("peer {} wait:0x{:x} q_tag:{} not started", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->wait, + p_scb->q_tag); /* Clear first bit of p_scb->wait and not to return from this point else * HAL layer gets blocked. And if there is delay in Get Capability response * as @@ -2428,9 +2417,9 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { p_scb->cfg.codec_info, &p_scb->no_rtp_header); p_scb->co_started = true; - LOG_VERBOSE("%s: peer %s suspending: %d, role:0x%x, init %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), suspend, - p_scb->role, initiator); + log::verbose("peer {} suspending: {}, role:0x{:x}, init {}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), suspend, + p_scb->role, initiator); tBTA_AV bta_av_data = { .start = @@ -2471,11 +2460,10 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_start_failed(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_ERROR( - "%s: peer %s bta_handle:0x%x audio_open_cnt:%d started:%s co_started:%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - bta_av_cb.audio_open_cnt, logbool(p_scb->started).c_str(), - p_scb->co_started); + log::error( + "peer {} bta_handle:0x{:x} audio_open_cnt:{} started:{} co_started:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + bta_av_cb.audio_open_cnt, logbool(p_scb->started), p_scb->co_started); if (!p_scb->started && !p_scb->co_started) { bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->PeerAddress()); @@ -2499,9 +2487,9 @@ void bta_av_str_closed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tBTA_AV data = {}; tBTA_AV_EVT event = {}; - LOG_WARN("%s: peer %s bta_handle:0x%x open_status:%d chnl:%d co_started:%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - p_scb->hndl, p_scb->open_status, p_scb->chnl, p_scb->co_started); + log::warn("peer {} bta_handle:0x{:x} open_status:{} chnl:{} co_started:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + p_scb->open_status, p_scb->chnl, p_scb->co_started); BTM_unblock_role_switch_and_sniff_mode_for(p_scb->PeerAddress()); if (bta_av_cb.audio_open_cnt <= 1) { @@ -2557,7 +2545,7 @@ void bta_av_str_closed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_clr_cong(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (p_scb->co_started) { p_scb->cong = false; } @@ -2576,16 +2564,16 @@ void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tBTA_AV_SUSPEND suspend_rsp = {}; uint8_t err_code = p_data->str_msg.msg.hdr.err_code; - LOG_VERBOSE("%s: peer %s bta_handle:0x%x audio_open_cnt:%d err_code:%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - p_scb->hndl, bta_av_cb.audio_open_cnt, err_code); + log::verbose("peer {} bta_handle:0x{:x} audio_open_cnt:{} err_code:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + bta_av_cb.audio_open_cnt, err_code); if (!p_scb->started) { /* handle the condition where there is a collision of SUSPEND req from *either side ** Second SUSPEND req could be rejected. Do not treat this as a failure */ - LOG_WARN("%s: already suspended, ignore, err_code %d", __func__, err_code); + log::warn("already suspended, ignore, err_code {}", err_code); return; } @@ -2593,7 +2581,7 @@ void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if (err_code && (err_code != AVDT_ERR_BAD_STATE)) { suspend_rsp.status = BTA_AV_FAIL; - LOG_ERROR("%s: suspend failed, closing connection", __func__); + log::error("suspend failed, closing connection"); /* SUSPEND failed. Close connection. */ bta_av_ssm_execute(p_scb, BTA_AV_API_CLOSE_EVT, NULL); @@ -2616,7 +2604,7 @@ void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { bta_av_vendor_offload_stop(); bta_av_cb.offload_started_hndl = BTA_AV_INVALID_HANDLE; } else if (bta_av_cb.offload_start_pending_hndl == p_scb->hndl) { - LOG_WARN("%s: Stop pending offload start command", __func__); + log::warn("Stop pending offload start command"); bta_av_vendor_offload_stop(); bta_av_cb.offload_start_pending_hndl = BTA_AV_INVALID_HANDLE; } @@ -2649,16 +2637,16 @@ void bta_av_suspend_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { ******************************************************************************/ void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { p_scb->l2c_cid = AVDT_GetL2CapChannel(p_scb->avdt_handle); - LOG_VERBOSE("%s: peer %s bta_handle:0x%x l2c_cid:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - p_scb->l2c_cid); + log::verbose("peer {} bta_handle:0x{:x} l2c_cid:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + p_scb->l2c_cid); if (p_data != NULL) { // p_data could be NULL if the reconfig was triggered by the local device p_scb->stream_mtu = p_data->str_msg.msg.open_ind.peer_mtu - AVDT_MEDIA_HDR_SIZE; - LOG_VERBOSE("%s: l2c_cid: 0x%x stream_mtu: %d", __func__, p_scb->l2c_cid, - p_scb->stream_mtu); + log::verbose("l2c_cid: 0x{:x} stream_mtu: {}", p_scb->l2c_cid, + p_scb->stream_mtu); p_scb->p_cos->update_mtu(p_scb->hndl, p_scb->PeerAddress(), p_scb->stream_mtu); } @@ -2695,9 +2683,9 @@ void bta_av_rcfg_str_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_rcfg_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { - LOG_ERROR("%s: num_recfg=%d conn_lcb=0x%x peer_addr=%s", __func__, - p_scb->num_recfg, bta_av_cb.conn_lcb, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("num_recfg={} conn_lcb=0x{:x} peer_addr={}", p_scb->num_recfg, + bta_av_cb.conn_lcb, + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) { bta_av_cco_close(p_scb, p_data); @@ -2721,8 +2709,8 @@ void bta_av_rcfg_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if ((bta_av_cb.conn_lcb & (1 << p_scb->hdi)) != 0) { AVDT_DisconnectReq(p_scb->PeerAddress(), &bta_av_proc_stream_evt); } else { - LOG_WARN("%s: conn_lcb=0x%x bta_handle=0x%x (hdi=%u) no link", __func__, - bta_av_cb.conn_lcb, p_scb->hndl, p_scb->hdi); + log::warn("conn_lcb=0x{:x} bta_handle=0x{:x} (hdi={}) no link", + bta_av_cb.conn_lcb, p_scb->hndl, p_scb->hdi); bta_av_connect_req(p_scb, NULL); } } @@ -2738,11 +2726,11 @@ void bta_av_rcfg_failed(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_rcfg_connect(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); p_scb->cong = false; p_scb->num_recfg++; - LOG_VERBOSE("%s: num_recfg: %d", __func__, p_scb->num_recfg); + log::verbose("num_recfg: {}", p_scb->num_recfg); if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) { /* let bta_av_rcfg_failed report fail */ bta_av_rcfg_failed(p_scb, NULL); @@ -2761,9 +2749,9 @@ void bta_av_rcfg_connect(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_rcfg_discntd(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_ERROR("%s: num_recfg=%d conn_lcb=0x%x peer_addr=%s", __func__, - p_scb->num_recfg, bta_av_cb.conn_lcb, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("num_recfg={} conn_lcb=0x{:x} peer_addr={}", p_scb->num_recfg, + bta_av_cb.conn_lcb, + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); p_scb->num_recfg++; if (p_scb->num_recfg > BTA_AV_RECONFIG_RETRY) { @@ -2797,7 +2785,7 @@ void bta_av_rcfg_discntd(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { uint8_t err_code = p_data->str_msg.msg.hdr.err_code; - LOG_VERBOSE("%s: err_code=%d", __func__, err_code); + log::verbose("err_code={}", err_code); p_scb->started = false; p_scb->cong = false; @@ -2813,22 +2801,21 @@ void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { }, }; (*bta_av_cb.p_cback)(BTA_AV_RECONFIG_EVT, &bta_av_data); - LOG_ERROR("%s: BTA_AV_STR_DISC_FAIL_EVT: peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("BTA_AV_STR_DISC_FAIL_EVT: peer_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); bta_av_ssm_execute(p_scb, BTA_AV_STR_DISC_FAIL_EVT, NULL); } else { - LOG_ERROR("%s: suspend rejected, try close", __func__); + log::error("suspend rejected, try close"); /* drop the buffers queued in L2CAP */ L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL); AVDT_CloseReq(p_scb->avdt_handle); } } else { - LOG_VERBOSE("%s: calling AVDT_ReconfigReq", __func__); + log::verbose("calling AVDT_ReconfigReq"); /* reconfig the stream */ - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str()); + log::verbose("codec: {}", A2DP_CodecInfoString(p_scb->cfg.codec_info)); AVDT_ReconfigReq(p_scb->avdt_handle, &p_scb->cfg); p_scb->cfg.psc_mask = p_scb->cur_psc_mask; } @@ -2847,7 +2834,7 @@ void bta_av_suspend_cont(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { void bta_av_rcfg_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { uint8_t err_code = p_data->str_msg.msg.hdr.err_code; - LOG_VERBOSE("%s: err_code = %d", __func__, err_code); + log::verbose("err_code = {}", err_code); // Disable AVDTP RECONFIGURE for rejectlisted devices bool disable_avdtp_reconfigure = false; @@ -2858,18 +2845,16 @@ void bta_av_rcfg_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if (interop_match_name(INTEROP_DISABLE_AVDTP_RECONFIGURE, remote_name) || interop_match_addr(INTEROP_DISABLE_AVDTP_RECONFIGURE, (const RawAddress*)&p_scb->PeerAddress())) { - LOG_INFO( - "%s: disable AVDTP RECONFIGURE: interop matched " - "name %s address %s", - __func__, remote_name, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::info( + "disable AVDTP RECONFIGURE: interop matched name {} address {}", + remote_name, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); disable_avdtp_reconfigure = true; } } } if ((err_code != 0) || disable_avdtp_reconfigure) { - LOG_ERROR("%s: reconfig rejected, try close", __func__); + log::error("reconfig rejected, try close"); /* Disable reconfiguration feature only with explicit rejection(not with * timeout) */ if ((err_code != AVDT_ERR_TIMEOUT) || disable_avdtp_reconfigure) { @@ -2881,8 +2866,8 @@ void bta_av_rcfg_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { AVDT_CloseReq(p_scb->avdt_handle); } else { /* update the codec info after rcfg cfm */ - LOG_VERBOSE( - "%s: updating from codec %s to codec %s", __func__, + log::verbose( + "updating from codec {} to codec {}", A2DP_CodecName(p_scb->cfg.codec_info), A2DP_CodecName(p_data->str_msg.msg.reconfig_cfm.p_cfg->codec_info)); memcpy(p_scb->cfg.codec_info, @@ -2903,9 +2888,9 @@ void bta_av_rcfg_cfm(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_rcfg_open(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: peer %s bta_handle:0x%x num_disc_snks:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - p_scb->num_disc_snks); + log::verbose("peer {} bta_handle:0x{:x} num_disc_snks:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + p_scb->num_disc_snks); if (p_scb->num_disc_snks == 0) { /* Need to update call-out module so that it will be ready for discover */ @@ -2915,15 +2900,14 @@ void bta_av_rcfg_open(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { AVDT_DiscoverReq(p_scb->PeerAddress(), p_scb->hdi, p_scb->sep_info, BTA_AV_NUM_SEPS, &bta_av_proc_stream_evt); } else { - LOG_VERBOSE("%s: calling AVDT_OpenReq()", __func__); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_scb->cfg.codec_info).c_str()); + log::verbose("calling AVDT_OpenReq()"); + log::verbose("codec: {}", A2DP_CodecInfoString(p_scb->cfg.codec_info)); /* we may choose to use a different SEP at reconfig. * adjust the sep_idx now */ bta_av_adjust_seps_idx(p_scb, bta_av_get_scb_handle(p_scb, AVDT_TSEP_SRC)); - LOG_INFO("%s: sep_idx=%d avdt_handle=%d bta_handle=0x%x", __func__, - p_scb->sep_idx, p_scb->avdt_handle, p_scb->hndl); + log::info("sep_idx={} avdt_handle={} bta_handle=0x{:x}", p_scb->sep_idx, + p_scb->avdt_handle, p_scb->hndl); /* open the stream with the new config */ p_scb->sep_info_idx = p_scb->rcfg_idx; @@ -2959,10 +2943,10 @@ void bta_av_security_rej(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { ******************************************************************************/ void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { - LOG_INFO( - "%s: peer %s channel:%d bta_av_cb.audio_open_cnt:%d role:0x%x " - "features:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->chnl, + log::info( + "peer {} channel:{} bta_av_cb.audio_open_cnt:{} role:0x{:x} " + "features:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->chnl, bta_av_cb.audio_open_cnt, p_scb->role, bta_av_cb.features); if ((p_scb->chnl == BTA_AV_CHNL_AUDIO) && (bta_av_cb.audio_open_cnt >= 2) && @@ -2982,10 +2966,10 @@ void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb, if (!new_started) { // Start the new stream new_started = true; - LOG_INFO( - "%s: starting new stream for peer %s because peer %s " - "already started", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + log::info( + "starting new stream for peer {} because peer {} already " + "started", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), ADDRESS_TO_LOGGABLE_CSTR(p_scbi->PeerAddress())); bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL); } @@ -3009,14 +2993,13 @@ void bta_av_chk_2nd_start(tBTA_AV_SCB* p_scb, * ******************************************************************************/ void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: use_rc: %d, wait: 0x%x role: 0x%x", __func__, p_scb->use_rc, - p_scb->wait, p_scb->role); + log::verbose("use_rc: {}, wait: 0x{:x} role: 0x{:x}", p_scb->use_rc, + p_scb->wait, p_scb->role); if ((p_scb->wait & BTA_AV_WAIT_ROLE_SW_BITS) && (p_scb->q_tag == BTA_AV_Q_TAG_START)) { /* waiting for role switch for some reason & the timer expires */ if (!bta_av_link_role_ok(p_scb, A2DP_SET_ONE_BIT)) { - LOG_ERROR("%s: failed to start streaming for role management reasons!!", - __func__); + log::error("failed to start streaming for role management reasons!!"); alarm_cancel(p_scb->avrc_ct_timer); tBTA_AV bta_av_data = { @@ -3059,7 +3042,7 @@ void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { /* if peer is sink, it should run new avrcp */ if ((p_scb->seps[p_scb->sep_idx].tsep == AVDT_TSEP_SRC) && is_new_avrcp_enabled()) { - LOG_WARN("%s: local src Using the new AVRCP Profile", __func__); + log::warn("local src Using the new AVRCP Profile"); if (bluetooth::avrcp::AvrcpService::Get() != nullptr) { bluetooth::avrcp::AvrcpService::Get()->ConnectDevice( p_scb->PeerAddress()); @@ -3067,13 +3050,13 @@ void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { } } - LOG_WARN("%s: local sink Using the legacy AVRCP Profile", __func__); + log::warn("local sink Using the legacy AVRCP Profile"); bta_av_rc_disc((uint8_t)(p_scb->hdi + 1)); return; } if (btif_av_is_source_enabled() && is_new_avrcp_enabled()) { - LOG_WARN("%s: Using the new AVRCP Profile", __func__); + log::warn("Using the new AVRCP Profile"); bluetooth::avrcp::AvrcpService::Get()->ConnectDevice( p_scb->PeerAddress()); } else { @@ -3102,8 +3085,9 @@ void bta_av_open_rc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { void bta_av_open_at_inc(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { memcpy(&(p_scb->open_api), &(p_data->api_open), sizeof(tBTA_AV_API_OPEN)); - LOG_VERBOSE("%s: peer %s coll_mask=0x%02x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->coll_mask); + log::verbose("peer {} coll_mask=0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + p_scb->coll_mask); if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) { p_scb->coll_mask |= BTA_AV_COLL_API_CALLED; @@ -3127,24 +3111,27 @@ void offload_vendor_callback(tBTM_VSC_CMPL* param) { tBTA_AV value{0}; uint8_t sub_opcode = 0; if (param->param_len) { - LOG_VERBOSE("%s: param_len = %d status = %d", __func__, param->param_len, - param->p_param_buf[0]); + log::verbose("param_len = {} status = {}", param->param_len, + param->p_param_buf[0]); value.status = static_cast(param->p_param_buf[0]); } if (value.status == 0) { sub_opcode = param->p_param_buf[1]; - LOG_VERBOSE("%s: subopcode = %d", __func__, sub_opcode); + log::verbose("subopcode = {}", sub_opcode); switch (sub_opcode) { case VS_HCI_A2DP_OFFLOAD_STOP: - LOG_VERBOSE("%s: VS_HCI_STOP_A2DP_MEDIA successful", __func__); + case VS_HCI_A2DP_OFFLOAD_STOP_V2: + log::verbose("VS_HCI_STOP_A2DP_MEDIA successful"); break; case VS_HCI_A2DP_OFFLOAD_START: + case VS_HCI_A2DP_OFFLOAD_START_V2: if (bta_av_cb.offload_start_pending_hndl) { - LOG_VERBOSE("%s: VS_HCI_START_A2DP_MEDIA successful", __func__); + log::verbose("VS_HCI_START_A2DP_MEDIA successful"); bta_av_cb.offload_started_hndl = bta_av_cb.offload_start_pending_hndl; bta_av_cb.offload_start_pending_hndl = BTA_AV_INVALID_HANDLE; } else { - LOG_INFO("%s: No pending start command due to AVDTP suspend immediately", __func__); + log::info( + "No pending start command due to AVDTP suspend immediately"); } (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &value); break; @@ -3152,8 +3139,9 @@ void offload_vendor_callback(tBTM_VSC_CMPL* param) { break; } } else { - LOG_VERBOSE("%s: Offload failed for subopcode= %d", __func__, sub_opcode); - if (param->opcode != VS_HCI_A2DP_OFFLOAD_STOP) { + log::verbose("Offload failed for subopcode= {}", sub_opcode); + if (param->opcode != VS_HCI_A2DP_OFFLOAD_STOP && + param->opcode != VS_HCI_A2DP_OFFLOAD_STOP_V2) { bta_av_cb.offload_start_pending_hndl = BTA_AV_INVALID_HANDLE; (*bta_av_cb.p_cback)(BTA_AV_OFFLOAD_START_RSP_EVT, &value); } @@ -3163,7 +3151,7 @@ void offload_vendor_callback(tBTM_VSC_CMPL* param) { void bta_av_vendor_offload_start(tBTA_AV_SCB* p_scb, tBT_A2DP_OFFLOAD* offload_start) { uint8_t param[sizeof(tBT_A2DP_OFFLOAD)]; - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t* p_param = param; *p_param++ = VS_HCI_A2DP_OFFLOAD_START; @@ -3182,24 +3170,108 @@ void bta_av_vendor_offload_start(tBTA_AV_SCB* p_scb, ARRAY_TO_STREAM(p_param, offload_start->codec_info, (int8_t)sizeof(offload_start->codec_info)); bta_av_cb.offload_start_pending_hndl = p_scb->hndl; - LOG_INFO( - "codec: %#x, sample rate: %#x, bit depth: %#x, channel: %#x, bitrate: " - "%#x, ACL: %#x, L2CAP: %#x, MTU: %#x", + bta_av_cb.offload_start_v2 = false; + log::info( + "codec: {:#x}, sample rate: {:#x}, bit depth: {:#x}, channel: {:#x}, " + "bitrate: {:#x}, ACL: {:#x}, L2CAP: {:#x}, MTU: {:#x}", offload_start->codec_type, offload_start->sample_rate, offload_start->bits_per_sample, offload_start->ch_mode, offload_start->encoded_audio_bitrate, offload_start->acl_hdl, offload_start->l2c_rcid, offload_start->mtu); + BTM_VendorSpecificCommand(HCI_CONTROLLER_A2DP, p_param - param, param, + offload_vendor_callback); +} + +void bta_av_vendor_offload_start_v2(tBTA_AV_SCB* p_scb, + A2dpCodecConfigExt* offload_codec) { + log::verbose(""); + + uint16_t connection_handle = + get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle( + p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR); + btav_a2dp_scmst_info_t scmst_info = + p_scb->p_cos->get_scmst_info(p_scb->PeerAddress()); + uint16_t mtu = p_scb->stream_mtu; + uint16_t l2cap_channel_handle = 0; + + if (mtu > MAX_3MBPS_AVDTP_MTU) { + mtu = MAX_3MBPS_AVDTP_MTU; + } + if (L2CA_GetRemoteCid(p_scb->l2c_cid, &l2cap_channel_handle) == false) { + log::error("Failed to fetch l2c rcid"); + } + + uint8_t param[255]; + uint8_t* p_param = param; + *p_param++ = VS_HCI_A2DP_OFFLOAD_START_V2; + + // Connection_Handle: 2 bytes + UINT16_TO_STREAM(p_param, connection_handle); + // L2CAP_Channel_ID: 2 bytes + UINT16_TO_STREAM(p_param, l2cap_channel_handle); + // Data_Path_Direction: 1 byte + // TODO(b/305779580): Sink offload + UINT8_TO_STREAM(p_param, 0x0); + // Peer_MTU: 2 bytes + UINT16_TO_STREAM(p_param, mtu); + // CP_Enable_SCMS_T: 1 byte + UINT8_TO_STREAM(p_param, scmst_info.enable_status); + // CP_Header_SCMS_T: 1 byte + UINT8_TO_STREAM(p_param, scmst_info.cp_header); + // Vendor_Specific_Parameters_Len: 1 byte + // Vendor_Specific_Parameters: N bytes + auto const& vendor_specific_parameters = + offload_codec->getVendorCodecParameters(); + UINT8_TO_STREAM(p_param, + static_cast(vendor_specific_parameters.size())); + ARRAY_TO_STREAM(p_param, vendor_specific_parameters.data(), + static_cast(vendor_specific_parameters.size())); + + // Update the pending state. + bta_av_cb.offload_start_pending_hndl = p_scb->hndl; + bta_av_cb.offload_start_v2 = true; + BTM_VendorSpecificCommand(HCI_CONTROLLER_A2DP, p_param - param, param, offload_vendor_callback); } void bta_av_vendor_offload_stop() { - uint8_t param[sizeof(tBT_A2DP_OFFLOAD)]; - LOG_VERBOSE("%s", __func__); - param[0] = VS_HCI_A2DP_OFFLOAD_STOP; - BTM_VendorSpecificCommand(HCI_CONTROLLER_A2DP, 1, param, + uint8_t param[255]; + uint8_t* p_param = param; + + log::verbose(""); + + if (bta_av_cb.offload_start_v2) { + tBTA_AV_SCB* p_scb = + bta_av_hndl_to_scb(bta_av_cb.offload_start_pending_hndl); + if (p_scb == nullptr) { + return; + } + uint16_t connection_handle = + get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle( + p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR); + uint16_t l2cap_channel_handle = 0; + + if (L2CA_GetRemoteCid(p_scb->l2c_cid, &l2cap_channel_handle) == false) { + log::error("Failed to fetch l2c rcid"); + } + + *p_param++ = VS_HCI_A2DP_OFFLOAD_STOP_V2; + // Connection_Handle: 2 bytes + UINT16_TO_STREAM(p_param, connection_handle); + // L2CAP_Channel_ID: 2 bytes + UINT16_TO_STREAM(p_param, l2cap_channel_handle); + // Data_Path_Direction: 1 byte + // TODO(b/305779580): Sink offload + UINT8_TO_STREAM(p_param, 0x0); + } else { + *p_param++ = VS_HCI_A2DP_OFFLOAD_STOP; + } + + BTM_VendorSpecificCommand(HCI_CONTROLLER_A2DP, p_param - param, param, offload_vendor_callback); } + /******************************************************************************* * * Function bta_av_offload_req @@ -3214,16 +3286,25 @@ void bta_av_offload_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tBTA_AV_STATUS status = BTA_AV_FAIL_RESOURCES; tBT_A2DP_OFFLOAD offload_start; - LOG_VERBOSE("%s: stream %s, audio channels open %d", __func__, - p_scb->started ? "STARTED" : "STOPPED", bta_av_cb.audio_open_cnt); + log::verbose("stream {}, audio channels open {}", + p_scb->started ? "STARTED" : "STOPPED", + bta_av_cb.audio_open_cnt); + + A2dpCodecConfig* codec_config = bta_av_get_a2dp_current_codec(); + ASSERT(codec_config != nullptr); + /* Check if stream has already been started. */ /* Support offload if only one audio source stream is open. */ if (p_scb->started != true) { status = BTA_AV_FAIL_STREAM; } else if (bta_av_cb.offload_start_pending_hndl || bta_av_cb.offload_started_hndl) { - LOG_WARN("%s: offload already started, ignore request", __func__); + log::warn("offload already started, ignore request"); return; + } else if (::bluetooth::audio::a2dp::provider::supports_codec( + codec_config->codecIndex())) { + bta_av_vendor_offload_start_v2( + p_scb, static_cast(codec_config)); } else { bta_av_offload_codec_builder(p_scb, &offload_start); bta_av_vendor_offload_start(p_scb, &offload_start); @@ -3243,11 +3324,9 @@ void bta_av_offload_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { if (L2CA_GetConnectionConfig( p_scb->l2c_cid, &a2dp_offload_start.acl_data_size, &a2dp_offload_start.remote_cid, &a2dp_offload_start.lm_handle)) { - LOG_VERBOSE("%s: l2cmtu %d lcid 0x%02X rcid 0x%02X lm_handle - 0x%02X", - __func__, a2dp_offload_start.acl_data_size, - p_scb->l2c_cid, a2dp_offload_start.remote_cid, - a2dp_offload_start.lm_handle); + log::verbose("l2cmtu {} lcid 0x{:02X} rcid 0x{:02X} lm_handle 0x{:02X}", + a2dp_offload_start.acl_data_size, p_scb->l2c_cid, + a2dp_offload_start.remote_cid, a2dp_offload_start.lm_handle); a2dp_offload_start.bta_av_handle = p_scb->hndl; a2dp_offload_start.xmit_quota = BTA_AV_A2DP_OFFLOAD_XMIT_QUOTA; @@ -3284,9 +3363,8 @@ void bta_av_offload_req(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { void bta_av_offload_rsp(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tBTA_AV_STATUS status = p_data->api_status_rsp.status; - LOG_VERBOSE("%s: stream %s status %s", __func__, - p_scb->started ? "STARTED" : "STOPPED", - status ? "FAIL" : "SUCCESS"); + log::verbose("stream {} status {}", p_scb->started ? "STARTED" : "STOPPED", + status ? "FAIL" : "SUCCESS"); /* Check if stream has already been started. */ if (status == BTA_AV_SUCCESS && p_scb->started != true) { @@ -3306,13 +3384,13 @@ static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb, A2DP_SourceCodecIndex(p_scb->cfg.codec_info); uint32_t codec_type = 0; uint16_t mtu = p_scb->stream_mtu; - LOG_VERBOSE("%s:codec_index = %d", __func__, codec_index); + log::verbose("codec_index = {}", codec_index); switch (codec_index) { case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: codec_type = BTA_AV_CODEC_TYPE_SBC; if (A2DP_GetMaxBitpoolSbc(p_scb->cfg.codec_info) <= A2DP_SBC_BITPOOL_MIDDLE_QUALITY) { - LOG_WARN("%s: Restricting streaming MTU size for MQ Bitpool", __func__); + log::warn("Restricting streaming MTU size for MQ Bitpool"); mtu = MAX_2MBPS_AVDTP_MTU; } break; @@ -3332,7 +3410,7 @@ static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb, codec_type = BTA_AV_CODEC_TYPE_OPUS; break; default: - LOG_ERROR("%s: Unknown Codec type ", __func__); + log::error("Unknown Codec type"); return; } if (mtu > MAX_3MBPS_AVDTP_MTU) mtu = MAX_3MBPS_AVDTP_MTU; @@ -3346,10 +3424,9 @@ static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb, p_scb->p_cos->get_scmst_info(p_scb->PeerAddress()); p_a2dp_offload->scms_t_enable[0] = scmst_info.enable_status; p_a2dp_offload->scms_t_enable[1] = scmst_info.cp_header; - LOG_VERBOSE( - "%s: SCMS-T_enable status: %d, " - "SCMS-T header (if it's enabled): 0x%02x", - __func__, scmst_info.enable_status, scmst_info.cp_header); + log::verbose( + "SCMS-T_enable status: {}, SCMS-T header (if it's enabled): 0x{:02x}", + scmst_info.enable_status, scmst_info.cp_header); switch (A2DP_GetTrackSampleRate(p_scb->cfg.codec_info)) { case 44100: @@ -3366,7 +3443,7 @@ static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb, break; } if (L2CA_GetRemoteCid(p_scb->l2c_cid, &p_a2dp_offload->l2c_rcid) == false) { - LOG_ERROR("%s: Failed to fetch l2c rcid", __func__); + log::error("Failed to fetch l2c rcid"); return; } switch (CodecConfig->getAudioBitsPerSample()) { @@ -3383,27 +3460,27 @@ static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb, p_a2dp_offload->ch_mode = A2DP_GetTrackChannelCount(p_scb->cfg.codec_info); p_a2dp_offload->encoded_audio_bitrate = CodecConfig->getTrackBitRate(); if (!CodecConfig->getCodecSpecificConfig(p_a2dp_offload)) { - LOG_ERROR("%s: not a valid codec info", __func__); + log::error("not a valid codec info"); } } void bta_av_api_set_peer_sep(tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s, bd_addr=%s, sep:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_data->peer_sep.addr), - p_data->peer_sep.sep); + log::verbose("bd_addr={}, sep:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->peer_sep.addr), + p_data->peer_sep.sep); const tBTA_AV_SCB* p_scb = bta_av_addr_to_scb(p_data->peer_sep.addr); if (!p_scb) { - LOG_WARN("%s scb not found", __func__); + log::warn("scb not found"); return; } - LOG_VERBOSE("%s, rc_handle:%d", __func__, p_scb->rc_handle); + log::verbose("rc_handle:{}", p_scb->rc_handle); if (btif_av_both_enable()) { if (p_data->peer_sep.sep == AVDT_TSEP_SNK) { // src close legacy cback - LOG_WARN("%s: current dut is src", __func__); + log::warn("current dut is src"); AVRC_UpdateCcb(&p_data->peer_sep.addr, AVRC_CO_METADATA); } else if (p_data->peer_sep.sep == AVDT_TSEP_SRC) { // sink close new cback - LOG_WARN("%s: current dut is sink", __func__); + log::warn("current dut is sink"); AVRC_UpdateCcb(&p_data->peer_sep.addr, AVRC_CO_GOOGLE); } } diff --git a/system/bta/av/bta_av_act.cc b/system/bta/av/bta_av_act.cc index 3fac7a9b3eef4848c3dd907ae11348cf31db5ca4..831439f6964f80876aacfd9a5a396f4763a91a64 100644 --- a/system/bta/av/bta_av_act.cc +++ b/system/bta/av/bta_av_act.cc @@ -25,6 +25,8 @@ #define LOG_TAG "bt_bta_av" +#include + #include #include "bta/av/bta_av_int.h" @@ -46,6 +48,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; /***************************************************************************** * Constants @@ -119,8 +122,8 @@ void bta_av_del_rc(tBTA_AV_RCB* p_rcb) { p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1]; } if (p_scb) { - LOG_VERBOSE("%s: shdl:%d, srch:%d rc_handle:%d", __func__, p_rcb->shdl, - p_scb->rc_handle, p_rcb->handle); + log::verbose("shdl:{}, srch:{} rc_handle:{}", p_rcb->shdl, + p_scb->rc_handle, p_rcb->handle); if (p_scb->rc_handle == p_rcb->handle) p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE; /* just in case the RC timer is active @@ -130,9 +133,9 @@ void bta_av_del_rc(tBTA_AV_RCB* p_rcb) { } } - LOG_VERBOSE("%s: handle: %d status=0x%x, rc_acp_handle:%d, idx:%d", - __func__, p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, - bta_av_cb.rc_acp_idx); + log::verbose("handle: {} status=0x{:x}, rc_acp_handle:{}, idx:{}", + p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, + bta_av_cb.rc_acp_idx); rc_handle = p_rcb->handle; if (!(p_rcb->status & BTA_AV_RC_CONN_MASK) || ((p_rcb->status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT)) { @@ -145,10 +148,9 @@ void bta_av_del_rc(tBTA_AV_RCB* p_rcb) { AVRC_Close(rc_handle); if (rc_handle == bta_av_cb.rc_acp_handle) bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE; - LOG_VERBOSE( - "%s: end del_rc handle: %d status=0x%x, rc_acp_handle:%d, lidx:%d", - __func__, p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, - p_rcb->lidx); + log::verbose( + "end del_rc handle: {} status=0x{:x}, rc_acp_handle:{}, lidx:{}", + p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, p_rcb->lidx); } } @@ -219,10 +221,10 @@ static void bta_av_rc_ctrl_cback(uint8_t handle, uint8_t event, if (btif_av_both_enable() && peer_addr != NULL && btif_av_peer_is_connected_sink(*peer_addr)) { - LOG_WARN("%s: not cback legacy cback, and close the handle", __func__); + log::warn("not cback legacy cback, and close the handle"); if (event == AVRC_CLOSE_IND_EVT || event == AVRC_OPEN_IND_EVT) { - LOG_VERBOSE("%s: resend close event", __func__); + log::verbose("resend close event"); tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)osi_malloc(sizeof(tBTA_AV_RC_CONN_CHG)); p_msg->hdr.event = BTA_AV_AVRC_CLOSE_EVT; @@ -233,7 +235,7 @@ static void bta_av_rc_ctrl_cback(uint8_t handle, uint8_t event, return; } - LOG_VERBOSE("%s: handle: %d event=0x%x", __func__, handle, event); + log::verbose("handle: {} event=0x{:x}", handle, event); if (event == AVRC_OPEN_IND_EVT) { /* save handle of opened connection bta_av_cb.rc_handle = handle;*/ @@ -271,7 +273,7 @@ static void bta_av_rc_msg_cback(uint8_t handle, uint8_t label, uint8_t opcode, uint8_t* p_data_src = NULL; uint16_t data_len = 0; - LOG_VERBOSE("%s: handle: %u opcode=0x%x", __func__, handle, opcode); + log::verbose("handle: {} opcode=0x{:x}", handle, opcode); /* Copy avrc packet into BTA message buffer (for sending to BTA state machine) */ @@ -333,7 +335,7 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, (btif_av_src_sink_coexist_enabled() && !btif_av_is_sink_enabled() && btif_av_is_source_enabled())) && is_new_avrcp_enabled()) { - LOG_INFO("Skipping RC creation for the old AVRCP profile"); + log::info("Skipping RC creation for the old AVRCP profile"); return BTA_AV_RC_HANDLE_NONE; } @@ -347,9 +349,8 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, if (role == AVCT_INT) { // Can't grab a stream control block that doesn't have a valid handle if (!shdl) { - LOG_ERROR( - "%s: Can't grab stream control block for shdl = %d -> index = %d", - __func__, shdl, shdl - 1); + log::error("Can't grab stream control block for shdl = {} -> index = {}", + shdl, shdl - 1); return BTA_AV_RC_HANDLE_NONE; } tBTA_AV_SCB* p_scb = p_cb->p_scb[shdl - 1]; @@ -361,7 +362,7 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, } else { p_rcb = bta_av_get_rcb_by_shdl(shdl); if (p_rcb != NULL) { - LOG_ERROR("%s: ACP handle exist for shdl:%d", __func__, shdl); + log::error("ACP handle exist for shdl:{}", shdl); p_rcb->lidx = lidx; return p_rcb->handle; } @@ -385,7 +386,7 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, p_rcb = &p_cb->rcb[i]; if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) { - LOG_ERROR("%s: found duplicated handle:%d", __func__, rc_handle); + log::error("found duplicated handle:{}", rc_handle); } p_rcb->handle = rc_handle; @@ -400,12 +401,12 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, /* this LIDX is reserved for the AVRCP ACP connection */ p_cb->rc_acp_handle = p_rcb->handle; p_cb->rc_acp_idx = (i + 1); - LOG_VERBOSE("%s: rc_acp_handle:%d idx:%d", __func__, p_cb->rc_acp_handle, - p_cb->rc_acp_idx); + log::verbose("rc_acp_handle:{} idx:{}", p_cb->rc_acp_handle, + p_cb->rc_acp_idx); } - LOG_VERBOSE( - "%s: create %d, role: %d, shdl:%d, rc_handle:%d, lidx:%d, status:0x%x", - __func__, i, role, shdl, p_rcb->handle, lidx, p_rcb->status); + log::verbose( + "create {}, role: {}, shdl:{}, rc_handle:{}, lidx:{}, status:0x{:x}", i, + role, shdl, p_rcb->handle, lidx, p_rcb->status); return rc_handle; } @@ -491,15 +492,14 @@ tBTA_AV_LCB* bta_av_find_lcb(const RawAddress& addr, uint8_t op) { uint8_t mask; tBTA_AV_LCB* p_lcb = NULL; - LOG_VERBOSE("%s: address: %s op:%d", __func__, ADDRESS_TO_LOGGABLE_CSTR(addr), - op); + log::verbose("address: {} op:{}", ADDRESS_TO_LOGGABLE_CSTR(addr), op); for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) { mask = 1 << xx; /* the used mask for this lcb */ if ((mask & p_cb->conn_lcb) && p_cb->lcb[xx].addr == addr) { p_lcb = &p_cb->lcb[xx]; if (op == BTA_AV_LCB_FREE) { p_cb->conn_lcb &= ~mask; /* clear the connect mask */ - LOG_VERBOSE("%s: conn_lcb: 0x%x", __func__, p_cb->conn_lcb); + log::verbose("conn_lcb: 0x{:x}", p_cb->conn_lcb); } break; } @@ -531,10 +531,9 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { p_scb = p_cb->p_scb[i]; if (p_scb && p_scb->PeerAddress() == p_data->rc_conn_chg.peer_addr) { p_scb->rc_handle = p_data->rc_conn_chg.handle; - LOG_VERBOSE("%s: shdl:%d, srch %d", __func__, i + 1, p_scb->rc_handle); + log::verbose("shdl:{}, srch {}", i + 1, p_scb->rc_handle); shdl = i + 1; - LOG_INFO("%s: allow incoming AVRCP connections:%d", __func__, - p_scb->use_rc); + log::info("allow incoming AVRCP connections:{}", p_scb->use_rc); alarm_cancel(p_scb->avrc_ct_timer); disc = p_scb->hndl; break; @@ -543,12 +542,12 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { i = p_data->rc_conn_chg.handle; if (p_cb->rcb[i].handle == BTA_AV_RC_HANDLE_NONE) { - LOG_ERROR("%s: not a valid handle:%d any more", __func__, i); + log::error("not a valid handle:{} any more", i); return; } - LOG_VERBOSE("%s: local features %d peer features %d", __func__, - p_cb->features, p_cb->rcb[i].peer_features); + log::verbose("local features {} peer features {}", p_cb->features, + p_cb->rcb[i].peer_features); /* listen to browsing channel when the connection is open, * if peer initiated AVRCP connection and local device supports browsing @@ -566,15 +565,15 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { p_cb->rcb[i].lidx = tmp; p_cb->rc_acp_handle = p_rcb->handle; p_cb->rc_acp_idx = (p_rcb - p_cb->rcb) + 1; - LOG_VERBOSE("%s: switching RCB rc_acp_handle:%d idx:%d", __func__, - p_cb->rc_acp_handle, p_cb->rc_acp_idx); + log::verbose("switching RCB rc_acp_handle:{} idx:{}", p_cb->rc_acp_handle, + p_cb->rc_acp_idx); } } p_cb->rcb[i].shdl = shdl; rc_open.rc_handle = i; - LOG_ERROR("%s: rcb[%d] shdl:%d lidx:%d/%d", __func__, i, shdl, - p_cb->rcb[i].lidx, p_cb->lcb[BTA_AV_NUM_LINKS].lidx); + log::error("rcb[{}] shdl:{} lidx:{}/{}", i, shdl, p_cb->rcb[i].lidx, + p_cb->lcb[BTA_AV_NUM_LINKS].lidx); p_cb->rcb[i].status |= BTA_AV_RC_CONN_MASK; if (!shdl && 0 == p_cb->lcb[BTA_AV_NUM_LINKS].lidx) { @@ -585,9 +584,9 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { p_lcb->lidx = BTA_AV_NUM_LINKS + 1; p_cb->rcb[i].lidx = p_lcb->lidx; p_lcb->conn_msk = 1; - LOG_ERROR("%s: bd_addr: %s rcb[%d].lidx=%d, lcb.conn_msk=x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_lcb->addr), i, p_cb->rcb[i].lidx, - p_lcb->conn_msk); + log::error("bd_addr: {} rcb[{}].lidx={}, lcb.conn_msk=x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_lcb->addr), i, p_cb->rcb[i].lidx, + p_lcb->conn_msk); disc = p_data->rc_conn_chg.handle | BTA_AV_CHNL_MSK; } @@ -605,9 +604,9 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { rc_open.peer_tg_features = p_cb->rcb[i].peer_tg_features; } rc_open.status = BTA_AV_SUCCESS; - LOG_VERBOSE( - "local features:0x%x peer_features:0x%x, peer_ct_feature:0x%x, " - "peer_tg_feature:0x%x", + log::verbose( + "local features:0x{:x} peer_features:0x{:x}, peer_ct_feature:0x{:x}, " + "peer_tg_feature:0x{:x}", p_cb->features, rc_open.peer_features, rc_open.peer_ct_features, rc_open.peer_tg_features); if (rc_open.peer_features == 0 && rc_open.peer_ct_features == 0 && @@ -633,16 +632,16 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { ((rc_open.peer_ct_features & BTA_AV_FEAT_BROWSE) || (rc_open.peer_tg_features & BTA_AV_FEAT_BROWSE))) { if ((p_cb->rcb[i].status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT) { - LOG_VERBOSE("%s: opening AVRC Browse channel", __func__); + log::verbose("opening AVRC Browse channel"); AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_INT); } } return; } rc_open.status = BTA_AV_SUCCESS; - LOG_VERBOSE("%s: local features:x%x peer_features:x%x", __func__, - p_cb->features, rc_open.peer_features); - LOG_VERBOSE("%s: cover art psm:x%x", __func__, rc_open.cover_art_psm); + log::verbose("local features:x{:x} peer_features:x{:x}", p_cb->features, + rc_open.peer_features); + log::verbose("cover art psm:x{:x}", rc_open.cover_art_psm); if (rc_open.peer_features == 0) { /* we have not done SDP on peer RC capabilities. * peer must have initiated the RC connection */ @@ -664,7 +663,7 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { if ((p_cb->features & BTA_AV_FEAT_BROWSE) && (rc_open.peer_features & BTA_AV_FEAT_BROWSE) && ((p_cb->rcb[i].status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT)) { - LOG_VERBOSE("%s: opening AVRC Browse channel", __func__); + log::verbose("opening AVRC Browse channel"); AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_INT); } } @@ -849,7 +848,7 @@ void bta_av_proc_rsp(tAVRC_RESPONSE* p_rc_rsp) { p_rc_rsp->get_caps.count = p_src_cfg->num_evt_ids; memcpy(p_rc_rsp->get_caps.param.event_id, p_src_cfg->p_meta_evt_ids, p_src_cfg->num_evt_ids); - LOG_VERBOSE("%s: ver: 0x%x", __func__, rc_ver); + log::verbose("ver: 0x{:x}", rc_ver); /* if it's not 1.3, then there should be a absolute volume */ if (rc_ver != 0x103) { uint8_t evt_cnt = p_rc_rsp->get_caps.count; @@ -884,7 +883,7 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE* p_rc_rsp, if (p_vendor->vendor_len == 0) { p_rc_rsp->rsp.status = AVRC_STS_BAD_PARAM; - LOG_VERBOSE("%s: p_vendor->vendor_len == 0", __func__); + log::verbose("p_vendor->vendor_len == 0"); // the caller of this function assume 0 to be an invalid event return 0; } @@ -897,22 +896,20 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE* p_rc_rsp, if ((AVRC_MIN_META_CMD_LEN + p_vendor->vendor_len) > AVRC_META_CMD_BUF_SIZE) { /* reject it */ p_rc_rsp->rsp.status = AVRC_STS_BAD_PARAM; - LOG_ERROR("%s: Invalid meta-command length: %d", __func__, - p_vendor->vendor_len); + log::error("Invalid meta-command length: {}", p_vendor->vendor_len); return 0; } /* Metadata messages only use PANEL sub-unit type */ if (p_vendor->hdr.subunit_type != AVRC_SUB_PANEL) { - LOG_VERBOSE("%s: SUBUNIT must be PANEL", __func__); + log::verbose("SUBUNIT must be PANEL"); /* reject it */ evt = 0; p_vendor->hdr.ctype = AVRC_RSP_NOT_IMPL; p_vendor->vendor_len = 0; p_rc_rsp->rsp.status = AVRC_STS_BAD_PARAM; } else if (!AVRC_IsValidAvcType(pdu, p_vendor->hdr.ctype)) { - LOG_VERBOSE("%s: Invalid pdu/ctype: 0x%x, %d", __func__, pdu, - p_vendor->hdr.ctype); + log::verbose("Invalid pdu/ctype: 0x{:x}, {}", pdu, p_vendor->hdr.ctype); /* reject invalid message without reporting to app */ evt = 0; p_rc_rsp->rsp.status = AVRC_STS_BAD_CMD; @@ -949,7 +946,7 @@ tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE* p_rc_rsp, memcpy(p_rc_rsp->get_caps.param.event_id, p_bta_av_cfg->p_meta_evt_ids, p_bta_av_cfg->num_evt_ids); } else { - LOG_VERBOSE("%s: Invalid capability ID: 0x%x", __func__, u8); + log::verbose("Invalid capability ID: 0x{:x}", u8); /* reject - unknown capability ID */ p_rc_rsp->get_caps.status = AVRC_STS_BAD_PARAM; } @@ -989,12 +986,12 @@ void bta_av_rc_msg(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { rc_rsp.rsp.status = BTA_AV_STS_NO_RSP; if (NULL == p_data) { - LOG_ERROR("%s: Message from peer with no data", __func__); + log::error("Message from peer with no data"); return; } - LOG_VERBOSE("%s: opcode=%x, ctype=%x", __func__, p_data->rc_msg.opcode, - p_data->rc_msg.msg.hdr.ctype); + log::verbose("opcode={:x}, ctype={:x}", p_data->rc_msg.opcode, + p_data->rc_msg.msg.hdr.ctype); if (p_data->rc_msg.opcode == AVRC_OP_PASS_THRU) { /* if this is a pass thru command */ @@ -1020,7 +1017,7 @@ void bta_av_rc_msg(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { bta_av_op_supported(p_data->rc_msg.msg.pass.op_id, is_inquiry); } - LOG_VERBOSE("%s: ctype %d", __func__, p_data->rc_msg.msg.hdr.ctype); + log::verbose("ctype {}", p_data->rc_msg.msg.hdr.ctype); /* send response */ if (p_data->rc_msg.msg.hdr.ctype != AVRC_RSP_INTERIM) @@ -1056,8 +1053,8 @@ void bta_av_rc_msg(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { (p_data->rc_msg.msg.pass.pass_len > 0)) { av.remote_rsp.p_data = (uint8_t*)osi_malloc(p_data->rc_msg.msg.pass.pass_len); - LOG_VERBOSE("%s: Vendor Unique data len = %d", __func__, - p_data->rc_msg.msg.pass.pass_len); + log::verbose("Vendor Unique data len = {}", + p_data->rc_msg.msg.pass.pass_len); memcpy(av.remote_rsp.p_data, p_data->rc_msg.msg.pass.p_pass_data, p_data->rc_msg.msg.pass.pass_len); } @@ -1163,8 +1160,7 @@ void bta_av_rc_close(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { if (handle < BTA_AV_NUM_RCB) { p_rcb = &p_cb->rcb[handle]; - LOG_VERBOSE("%s: handle: %d, status=0x%x", __func__, p_rcb->handle, - p_rcb->status); + log::verbose("handle: {}, status=0x{:x}", p_rcb->handle, p_rcb->status); if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) { if (p_rcb->shdl) { p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1]; @@ -1191,7 +1187,7 @@ void bta_av_rc_close(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_rc_browse_close(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) { - LOG_WARN("%s: empty placeholder does nothing!", __func__); + log::warn("empty placeholder does nothing!"); } /******************************************************************************* @@ -1226,9 +1222,9 @@ static uint8_t bta_av_get_shdl(tBTA_AV_SCB* p_scb) { void bta_av_stream_chg(tBTA_AV_SCB* p_scb, bool started) { uint8_t started_msk = BTA_AV_HNDL_TO_MSK(p_scb->hdi); - LOG_VERBOSE("%s: peer %s started:%s started_msk:0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - logbool(started).c_str(), started_msk); + log::verbose("peer {} started:{} started_msk:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), logbool(started), + started_msk); if (started) { /* Let L2CAP know this channel is processed with high priority */ @@ -1278,10 +1274,9 @@ void bta_av_conn_chg(tBTA_AV_DATA* p_data) { for (i = 0; i < BTA_AV_NUM_RCB; i++) { if (bta_av_cb.rcb[i].lidx == p_lcb->lidx) { bta_av_cb.rcb[i].shdl = index + 1; - LOG_VERBOSE( - "%s: conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d", - __func__, i, bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, - bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx); + log::verbose("conn_chg up[{}]: {}, status=0x{:x}, shdl:{}, lidx:{}", + i, bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, + bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx); break; } } @@ -1294,20 +1289,20 @@ void bta_av_conn_chg(tBTA_AV_DATA* p_data) { bta_av_cb.audio_open_cnt++; } - LOG_VERBOSE("%s: rc_acp_handle:%d rc_acp_idx:%d", __func__, - p_cb->rc_acp_handle, p_cb->rc_acp_idx); + log::verbose("rc_acp_handle:{} rc_acp_idx:{}", p_cb->rc_acp_handle, + p_cb->rc_acp_idx); /* check if the AVRCP ACP channel is already connected */ if (p_lcb && p_cb->rc_acp_handle != BTA_AV_RC_HANDLE_NONE && p_cb->rc_acp_idx) { p_lcb_rc = &p_cb->lcb[BTA_AV_NUM_LINKS]; - LOG_VERBOSE( - "%s: rc_acp is connected && conn_chg on same addr " - "p_lcb_rc->conn_msk:x%x", - __func__, p_lcb_rc->conn_msk); + log::verbose( + "rc_acp is connected && conn_chg on same addr " + "p_lcb_rc->conn_msk:x{:x}", + p_lcb_rc->conn_msk); /* check if the RC is connected to the scb addr */ - LOG_INFO("%s: p_lcb_rc->addr: %s conn_chg.peer_addr: %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_lcb_rc->addr), - ADDRESS_TO_LOGGABLE_CSTR(p_data->conn_chg.peer_addr)); + log::info("p_lcb_rc->addr: {} conn_chg.peer_addr: {}", + ADDRESS_TO_LOGGABLE_CSTR(p_lcb_rc->addr), + ADDRESS_TO_LOGGABLE_CSTR(p_data->conn_chg.peer_addr)); if (p_lcb_rc->conn_msk && p_lcb_rc->addr == p_data->conn_chg.peer_addr) { @@ -1318,24 +1313,23 @@ void bta_av_conn_chg(tBTA_AV_DATA* p_data) { p_scb->rc_handle = p_cb->rc_acp_handle; p_rcb = &p_cb->rcb[p_cb->rc_acp_idx - 1]; p_rcb->shdl = bta_av_get_shdl(p_scb); - LOG_VERBOSE("%s: update rc_acp shdl:%d/%d srch:%d", __func__, - index + 1, p_rcb->shdl, p_scb->rc_handle); + log::verbose("update rc_acp shdl:{}/{} srch:{}", index + 1, + p_rcb->shdl, p_scb->rc_handle); p_rcb2 = bta_av_get_rcb_by_shdl(p_rcb->shdl); if (p_rcb2) { /* found the RCB that was created to associated with this SCB */ p_cb->rc_acp_handle = p_rcb2->handle; p_cb->rc_acp_idx = (p_rcb2 - p_cb->rcb) + 1; - LOG_VERBOSE("%s: new rc_acp_handle:%d, idx:%d", __func__, - p_cb->rc_acp_handle, p_cb->rc_acp_idx); + log::verbose("new rc_acp_handle:{}, idx:{}", p_cb->rc_acp_handle, + p_cb->rc_acp_idx); p_rcb2->lidx = (BTA_AV_NUM_LINKS + 1); - LOG_VERBOSE("%s: rc2 handle:%d lidx:%d/%d", __func__, - p_rcb2->handle, p_rcb2->lidx, - p_cb->lcb[p_rcb2->lidx - 1].lidx); + log::verbose("rc2 handle:{} lidx:{}/{}", p_rcb2->handle, + p_rcb2->lidx, p_cb->lcb[p_rcb2->lidx - 1].lidx); } p_rcb->lidx = p_lcb->lidx; - LOG_VERBOSE("%s: rc handle:%d lidx:%d/%d", __func__, p_rcb->handle, - p_rcb->lidx, p_cb->lcb[p_rcb->lidx - 1].lidx); + log::verbose("rc handle:{} lidx:{}/{}", p_rcb->handle, p_rcb->lidx, + p_cb->lcb[p_rcb->lidx - 1].lidx); } } } @@ -1364,11 +1358,11 @@ void bta_av_conn_chg(tBTA_AV_DATA* p_data) { } } - LOG_VERBOSE("%s: shdl:%d", __func__, index + 1); + log::verbose("shdl:{}", index + 1); for (i = 0; i < BTA_AV_NUM_RCB; i++) { - LOG_VERBOSE("%s: conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d", - __func__, i, bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, - bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx); + log::verbose("conn_chg dn[{}]: {}, status=0x{:x}, shdl:{}, lidx:{}", i, + bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status, + bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx); if (bta_av_cb.rcb[i].shdl == index + 1) { bta_av_del_rc(&bta_av_cb.rcb[i]); /* since the connection is already down and info was removed, clean @@ -1390,10 +1384,9 @@ void bta_av_conn_chg(tBTA_AV_DATA* p_data) { bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1); } - LOG_VERBOSE( - "%s: audio:%x up:%d conn_msk:0x%x chk_restore:%d " - "audio_open_cnt:%d", - __func__, p_cb->conn_audio, p_data->conn_chg.is_up, conn_msk, chk_restore, + log::verbose( + "audio:{:x} up:{} conn_msk:0x{:x} chk_restore:{} audio_open_cnt:{}", + p_cb->conn_audio, p_data->conn_chg.is_up, conn_msk, chk_restore, p_cb->audio_open_cnt); if (chk_restore) { @@ -1523,8 +1516,8 @@ void bta_av_api_set_latency(tBTA_AV_DATA* p_data) { */ static uint8_t bta_av_find_lcb_index_by_scb_and_address( const RawAddress& peer_address) { - LOG_VERBOSE("%s: peer_address: %s conn_lcb: 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_cb.conn_lcb); + log::verbose("peer_address: {} conn_lcb: 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_cb.conn_lcb); // Find the index if there is already SCB entry for the peer address for (uint8_t index = 0; index < BTA_AV_NUM_LINKS; index++) { @@ -1554,8 +1547,7 @@ static uint8_t bta_av_find_lcb_index_by_scb_and_address( if (!p_scb->IsAssigned()) { const RawAddress& btif_addr = btif_av_find_by_handle(p_scb->hndl); if (!btif_addr.IsEmpty() && btif_addr != peer_address) { - LOG_DEBUG("%s: btif_addr = %s, index=%d!", - __func__, btif_addr.ToString().c_str(), index); + log::debug("btif_addr = {}, index={}!", btif_addr.ToString(), index); continue; } return index; @@ -1581,10 +1573,10 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) { uint8_t mask; tBTA_AV_LCB* p_lcb = NULL; - LOG_VERBOSE("%s: event: %d", __func__, event); + log::verbose("event: {}", event); if (event == AVDT_CONNECT_IND_EVT) { - LOG_VERBOSE("%s: AVDT_CONNECT_IND_EVT: peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_data->str_msg.bd_addr)); + log::verbose("AVDT_CONNECT_IND_EVT: peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->str_msg.bd_addr)); p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FIND); if (!p_lcb) { @@ -1595,13 +1587,13 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) { if (xx >= BTA_AV_NUM_LINKS) { /* We do not have scb for this avdt connection. */ /* Silently close the connection. */ - LOG_ERROR("%s: av scb not available for avdt connection for %s", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_data->str_msg.bd_addr)); + log::error("av scb not available for avdt connection for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->str_msg.bd_addr)); AVDT_DisconnectReq(p_data->str_msg.bd_addr, NULL); return; } - LOG_INFO("%s: AVDT_CONNECT_IND_EVT: peer %s selected lcb_index %d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_data->str_msg.bd_addr), xx); + log::info("AVDT_CONNECT_IND_EVT: peer {} selected lcb_index {}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->str_msg.bd_addr), xx); tBTA_AV_SCB* p_scb = p_cb->p_scb[xx]; mask = 1 << xx; @@ -1615,10 +1607,9 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) { } /* this entry is not used yet. */ p_cb->conn_lcb |= mask; /* mark it as used */ - LOG_VERBOSE("%s: start sig timer %d", __func__, p_data->hdr.offset); + log::verbose("start sig timer {}", p_data->hdr.offset); if (p_data->hdr.offset == AVDT_ACP) { - LOG_VERBOSE("%s: Incoming L2CAP acquired, set state as incoming", - __func__); + log::verbose("Incoming L2CAP acquired, set state as incoming"); p_scb->OnConnected(p_data->str_msg.bd_addr); p_scb->use_rc = true; /* allowing RC for incoming connection */ bta_av_ssm_execute(p_scb, BTA_AV_ACP_CONNECT_EVT, p_data); @@ -1637,7 +1628,7 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) { hdr.layer_specific = p_scb->hndl; bta_av_signalling_timer((tBTA_AV_DATA*)&hdr); - LOG_VERBOSE("%s: Re-start timer for AVDTP service", __func__); + log::verbose("Re-start timer for AVDTP service"); bta_sys_conn_open(BTA_ID_AV, p_scb->app_id, p_scb->PeerAddress()); /* Possible collision : need to avoid outgoing processing while the * timer is running */ @@ -1657,11 +1648,11 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) { } else { /* disconnected. */ - LOG_VERBOSE("%s: bta_av_cb.conn_lcb=0x%x", __func__, bta_av_cb.conn_lcb); + log::verbose("bta_av_cb.conn_lcb=0x{:x}", bta_av_cb.conn_lcb); p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FREE); if (p_lcb && (p_lcb->conn_msk || bta_av_cb.conn_lcb)) { - LOG_VERBOSE("%s: conn_msk: 0x%x", __func__, p_lcb->conn_msk); + log::verbose("conn_msk: 0x{:x}", p_lcb->conn_msk); /* clean up ssm */ for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) { if (p_cb->p_scb[xx] && @@ -1672,7 +1663,7 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) { &(p_data->str_msg.bd_addr))) { continue; } - LOG_VERBOSE("%s: Closing timer for AVDTP service", __func__); + log::verbose("Closing timer for AVDTP service"); bta_sys_conn_close(BTA_ID_AV, p_cb->p_scb[xx]->app_id, p_cb->p_scb[xx]->PeerAddress()); } @@ -1680,15 +1671,14 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) { if (((mask & p_lcb->conn_msk) || bta_av_cb.conn_lcb) && p_cb->p_scb[xx] && p_cb->p_scb[xx]->PeerAddress() == p_data->str_msg.bd_addr) { - LOG_WARN("%s: Sending AVDT_DISCONNECT_EVT peer_addr=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_cb->p_scb[xx]->PeerAddress())); + log::warn("Sending AVDT_DISCONNECT_EVT peer_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->p_scb[xx]->PeerAddress())); bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_AVDT_DISCONNECT_EVT, NULL); } } } } - LOG_VERBOSE("%s: bta_av_cb.conn_lcb=0x%x after sig_chg", __func__, - p_cb->conn_lcb); + log::verbose("bta_av_cb.conn_lcb=0x{:x} after sig_chg", p_cb->conn_lcb); } /******************************************************************************* @@ -1712,18 +1702,17 @@ void bta_av_signalling_timer(UNUSED_ATTR tBTA_AV_DATA* p_data) { uint8_t mask; tBTA_AV_LCB* p_lcb = NULL; - LOG_VERBOSE("%s: conn_lcb=0x%x", __func__, p_cb->conn_lcb); + log::verbose("conn_lcb=0x{:x}", p_cb->conn_lcb); for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) { p_lcb = &p_cb->lcb[xx]; mask = 1 << xx; - LOG_VERBOSE("%s: index=%d conn_lcb=0x%x peer=%s conn_mask=0x%x lidx=%d", - __func__, xx, p_cb->conn_lcb, - ADDRESS_TO_LOGGABLE_CSTR(p_lcb->addr), p_lcb->conn_msk, - p_lcb->lidx); + log::verbose("index={} conn_lcb=0x{:x} peer={} conn_mask=0x{:x} lidx={}", + xx, p_cb->conn_lcb, ADDRESS_TO_LOGGABLE_CSTR(p_lcb->addr), + p_lcb->conn_msk, p_lcb->lidx); if (mask & p_cb->conn_lcb) { /* this entry is used. check if it is connected */ if (!p_lcb->conn_msk) { - LOG_VERBOSE("%s hndl 0x%x", __func__, p_scb->hndl); + log::verbose("hndl 0x{:x}", p_scb->hndl); bta_sys_start_timer(p_scb->link_signalling_timer, BTA_AV_SIGNALLING_TIMEOUT_MS, BTA_AV_SIGNALLING_TIMER_EVT, hndl); @@ -1731,10 +1720,10 @@ void bta_av_signalling_timer(UNUSED_ATTR tBTA_AV_DATA* p_data) { pend.bd_addr = p_lcb->addr; tBTA_AV bta_av_data; bta_av_data.pend = pend; - LOG_VERBOSE( - "%s: BTA_AV_PENDING_EVT for %s index=%d conn_mask=0x%x lidx=%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(pend.bd_addr), xx, - p_lcb->conn_msk, p_lcb->lidx); + log::verbose( + "BTA_AV_PENDING_EVT for {} index={} conn_mask=0x{:x} lidx={}", + ADDRESS_TO_LOGGABLE_CSTR(pend.bd_addr), xx, p_lcb->conn_msk, + p_lcb->lidx); (*p_cb->p_cback)(BTA_AV_PENDING_EVT, &bta_av_data); } } @@ -1759,14 +1748,14 @@ static void bta_av_accept_signalling_timer_cback(void* data) { p_scb = p_cb->p_scb[inx]; } if (p_scb) { - LOG_VERBOSE("%s: coll_mask=0x%02x", __func__, p_scb->coll_mask); + log::verbose("coll_mask=0x{:02x}", p_scb->coll_mask); if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) { p_scb->coll_mask &= ~BTA_AV_COLL_INC_TMR; if (bta_av_is_scb_opening(p_scb)) { - LOG_VERBOSE("%s: stream state opening: SDP started = %d", __func__, - p_scb->sdp_discovery_started); + log::verbose("stream state opening: SDP started = {}", + p_scb->sdp_discovery_started); if (p_scb->sdp_discovery_started) { /* We are still doing SDP. Run the timer again. */ p_scb->coll_mask |= BTA_AV_COLL_INC_TMR; @@ -1782,7 +1771,7 @@ static void bta_av_accept_signalling_timer_cback(void* data) { } else if (bta_av_is_scb_incoming(p_scb)) { /* Stay in incoming state if SNK does not start signalling */ - LOG_VERBOSE("%s: stream state incoming", __func__); + log::verbose("stream state incoming"); /* API open was called right after SNK opened L2C connection. */ if (p_scb->coll_mask & BTA_AV_COLL_API_CALLED) { p_scb->coll_mask &= ~BTA_AV_COLL_API_CALLED; @@ -1851,7 +1840,7 @@ tBTA_AV_FEAT bta_av_check_peer_features(uint16_t service_uuid) { uint16_t peer_rc_version = 0; uint16_t categories = 0; - LOG_VERBOSE("%s: service_uuid:x%x", __func__, service_uuid); + log::verbose("service_uuid:x{:x}", service_uuid); /* loop through all records we found */ while (true) { /* get next record; if none found, we're done */ @@ -1879,7 +1868,7 @@ tBTA_AV_FEAT bta_av_check_peer_features(uint16_t service_uuid) { /* get profile version (if failure, version parameter is not updated) */ get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version); - LOG_VERBOSE("%s: peer_rc_version 0x%x", __func__, peer_rc_version); + log::verbose("peer_rc_version 0x{:x}", peer_rc_version); if (peer_rc_version >= AVRC_REV_1_3) peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA); @@ -1900,7 +1889,7 @@ tBTA_AV_FEAT bta_av_check_peer_features(uint16_t service_uuid) { } } } - LOG_VERBOSE("%s: peer_features:x%x", __func__, peer_features); + log::verbose("peer_features:x{:x}", peer_features); return peer_features; } @@ -1918,13 +1907,13 @@ tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) { tBTA_AV_FEAT peer_features = 0; tBTA_AV_CB* p_cb = &bta_av_cb; - LOG_VERBOSE("%s: service_uuid:x%x", __func__, service_uuid); + log::verbose("service_uuid:x{:x}", service_uuid); /* loop through all records we found */ tSDP_DISC_REC* p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb( p_cb->p_disc_db, service_uuid, NULL); while (p_rec) { - LOG_VERBOSE("%s: found Service record for x%x", __func__, service_uuid); + log::verbose("found Service record for x{:x}", service_uuid); if ((get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) != NULL) { @@ -1945,8 +1934,8 @@ tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) { uint16_t peer_rc_version = 0; bool val = get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version); - LOG_VERBOSE("%s: peer_rc_version for TG 0x%x, profile_found %d", __func__, - peer_rc_version, val); + log::verbose("peer_rc_version for TG 0x{:x}, profile_found {}", + peer_rc_version, val); if (peer_rc_version >= AVRC_REV_1_3) peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA); @@ -1986,7 +1975,7 @@ tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) { p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb( p_cb->p_disc_db, service_uuid, p_rec); } - LOG_VERBOSE("%s: peer_features:x%x", __func__, peer_features); + log::verbose("peer_features:x{:x}", peer_features); return peer_features; } @@ -2002,7 +1991,7 @@ tBTA_AV_FEAT bta_avk_check_peer_features(uint16_t service_uuid) { * *****************************************************************************/ uint16_t bta_avk_get_cover_art_psm() { - LOG_VERBOSE("%s: searching for cover art psm", __func__); + log::verbose("searching for cover art psm"); /* Cover Art L2CAP PSM is only available on a target device */ tBTA_AV_CB* p_cb = &bta_av_cb; tSDP_DISC_REC* p_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb( @@ -2074,7 +2063,7 @@ uint16_t bta_avk_get_cover_art_psm() { } // If this protocol has l2cap and obex then we're found the BIP PSM if (protocol_has_l2cap && protocol_has_obex) { - LOG_VERBOSE("%s: found psm 0x%x", __func__, psm); + log::verbose("found psm 0x{:x}", psm); return psm; } p_protocol = p_protocol->p_next_attr; // next protocol element @@ -2088,7 +2077,7 @@ uint16_t bta_avk_get_cover_art_psm() { p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, p_rec); } /* L2CAP PSM range is 0x1000-0xFFFF so 0x0000 is safe default invalid */ - LOG_VERBOSE("%s: could not find a BIP psm", __func__); + log::verbose("could not find a BIP psm"); return 0x0000; } @@ -2101,7 +2090,7 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { tBTA_AV_FEAT peer_ct_features = 0; uint16_t cover_art_psm = 0x0000; - LOG_VERBOSE("%s: bta_av_rc_disc_done disc:x%x", __func__, p_cb->disc); + log::verbose("bta_av_rc_disc_done disc:x{:x}", p_cb->disc); if (!p_cb->disc) { return; } @@ -2109,12 +2098,11 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { if ((p_cb->disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) { /* this is the rc handle/index to tBTA_AV_RCB */ rc_handle = p_cb->disc & (~BTA_AV_CHNL_MSK); - LOG_ERROR("%s: WRONG MASK A2dp not connect", __func__); + log::error("WRONG MASK A2dp not connect"); } else { /* Validate array index*/ if (((p_cb->disc & BTA_AV_HNDL_MSK) - 1) < BTA_AV_NUM_STRS) { - LOG_VERBOSE("%s: wrong data bta_av_rc_disc_done disc:x%x", __func__, - p_cb->disc); + log::verbose("wrong data bta_av_rc_disc_done disc:x{:x}", p_cb->disc); p_scb = p_cb->p_scb[(p_cb->disc & BTA_AV_HNDL_MSK) - 1]; } if (p_scb) { @@ -2125,13 +2113,12 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { } } - LOG_VERBOSE("%s: rc_handle %d", __func__, rc_handle); + log::verbose("rc_handle {}", rc_handle); if (p_cb->sdp_a2dp_snk_handle) { /* This is Sink + CT + TG(Abs Vol) */ peer_tg_features = bta_avk_check_peer_features(UUID_SERVCLASS_AV_REM_CTRL_TARGET); - LOG_VERBOSE("%s: populating rem ctrl target features %d", __func__, - peer_tg_features); + log::verbose("populating rem ctrl target features {}", peer_tg_features); if (BTA_AV_FEAT_ADV_CTRL & bta_avk_check_peer_features(UUID_SERVCLASS_AV_REMOTE_CONTROL)) peer_tg_features |= (BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCCT); @@ -2139,8 +2126,7 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { if (peer_tg_features & BTA_AV_FEAT_COVER_ARTWORK) cover_art_psm = bta_avk_get_cover_art_psm(); - LOG_VERBOSE("%s: populating rem ctrl target bip psm 0x%x", __func__, - cover_art_psm); + log::verbose("populating rem ctrl target bip psm 0x{:x}", cover_art_psm); } else if (p_cb->sdp_a2dp_handle) { /* check peer version and whether support CT and TG role */ peer_ct_features = @@ -2166,8 +2152,7 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version); if (peer_rc_version <= AVRC_REV_1_3) { - LOG_VERBOSE("%s: Using AVRCP 1.3 Capabilities with remote device", - __func__); + log::verbose("Using AVRCP 1.3 Capabilities with remote device"); p_bta_av_cfg = &bta_av_cfg_compatibility; } } @@ -2180,8 +2165,9 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { p_cb->rc_feature.rc_handle = rc_handle; if (p_scb) p_cb->rc_feature.peer_addr = p_scb->PeerAddress(); - LOG_VERBOSE("peer_tg_features 0x%x, peer_ct_features 0x%x, features 0x%x", - peer_tg_features, peer_ct_features, p_cb->features); + log::verbose( + "peer_tg_features 0x{:x}, peer_ct_features 0x{:x}, features 0x{:x}", + peer_tg_features, peer_ct_features, p_cb->features); /* if we have no rc connection */ if (rc_handle == BTA_AV_RC_HANDLE_NONE) { @@ -2203,7 +2189,7 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { } else { /* cannot create valid rc_handle for current device. report failure */ - LOG_ERROR("%s: no link resources available", __func__); + log::error("no link resources available"); p_scb->use_rc = false; tBTA_AV bta_av_data = { .rc_open = @@ -2215,7 +2201,7 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data); } } else { - LOG_ERROR("%s: can not find LCB!!", __func__); + log::error("can not find LCB!!"); } } else if (p_scb->use_rc) { /* can not find AVRC on peer device. report failure */ @@ -2261,7 +2247,7 @@ void bta_av_rc_disc_done_all(UNUSED_ATTR tBTA_AV_DATA* p_data) { (*p_cb->p_cback)(BTA_AV_RC_FEAT_EVT, &bta_av_feat); // Send PSM data - LOG_VERBOSE("%s: Send PSM data. rc_psm = %#x", __func__, cover_art_psm); + log::verbose("Send PSM data. rc_psm = {:#x}", cover_art_psm); p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm; tBTA_AV bta_av_psm = { .rc_cover_art_psm = @@ -2298,7 +2284,7 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { return; } - LOG_VERBOSE("%s: bta_av_rc_disc_done disc:x%x", __func__, p_cb->disc); + log::verbose("bta_av_rc_disc_done disc:x{:x}", p_cb->disc); if (!p_cb->disc) { return; } @@ -2319,13 +2305,12 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { } } - LOG_VERBOSE("%s: rc_handle %d", __func__, rc_handle); + log::verbose("rc_handle {}", rc_handle); if (p_cb->sdp_a2dp_snk_handle) { /* This is Sink + CT + TG(Abs Vol) */ peer_features = bta_avk_check_peer_features(UUID_SERVCLASS_AV_REM_CTRL_TARGET); - LOG_VERBOSE("%s: populating rem ctrl target features %d", __func__, - peer_features); + log::verbose("populating rem ctrl target features {}", peer_features); if (BTA_AV_FEAT_ADV_CTRL & bta_avk_check_peer_features(UUID_SERVCLASS_AV_REMOTE_CONTROL)) peer_features |= (BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCCT); @@ -2333,8 +2318,7 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { if (peer_features & BTA_AV_FEAT_COVER_ARTWORK) cover_art_psm = bta_avk_get_cover_art_psm(); - LOG_VERBOSE("%s: populating rem ctrl target bip psm 0x%x", __func__, - cover_art_psm); + log::verbose("populating rem ctrl target bip psm 0x{:x}", cover_art_psm); } else if (p_cb->sdp_a2dp_handle) { /* check peer version and whether support CT and TG role */ peer_features = @@ -2360,8 +2344,7 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version); if (peer_rc_version <= AVRC_REV_1_3) { - LOG_VERBOSE("%s: Using AVRCP 1.3 Capabilities with remote device", - __func__); + log::verbose("Using AVRCP 1.3 Capabilities with remote device"); p_bta_av_cfg = &bta_av_cfg_compatibility; } } @@ -2372,8 +2355,8 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { p_cb->disc = 0; osi_free_and_reset((void**)&p_cb->p_disc_db); - LOG_VERBOSE("%s: peer_features 0x%x, features 0x%x", __func__, peer_features, - p_cb->features); + log::verbose("peer_features 0x{:x}, features 0x{:x}", peer_features, + p_cb->features); /* if we have no rc connection */ if (rc_handle == BTA_AV_RC_HANDLE_NONE) { @@ -2393,7 +2376,7 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { } else { /* cannot create valid rc_handle for current device. report failure */ - LOG_ERROR("%s: no link resources available", __func__); + log::error("no link resources available"); p_scb->use_rc = false; tBTA_AV_RC_OPEN rc_open; rc_open.peer_addr = p_scb->PeerAddress(); @@ -2405,7 +2388,7 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, &bta_av_data); } } else { - LOG_ERROR("%s: can not find LCB!!", __func__); + log::error("can not find LCB!!"); } } else if (p_scb->use_rc) { /* can not find AVRC on peer device. report failure */ @@ -2452,7 +2435,7 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { IOT_CONF_BYTE_NUM_2); // Send PSM data - LOG_VERBOSE("%s: Send PSM data", __func__); + log::verbose("Send PSM data"); tBTA_AV_RC_PSM rc_psm; p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm; rc_psm.rc_handle = rc_handle; @@ -2463,7 +2446,7 @@ void bta_av_rc_disc_done(UNUSED_ATTR tBTA_AV_DATA* p_data) { rc_psm.peer_addr = p_scb->PeerAddress(); } - LOG_VERBOSE("%s: rc_psm = 0x%x", __func__, rc_psm.cover_art_psm); + log::verbose("rc_psm = 0x{:x}", rc_psm.cover_art_psm); tBTA_AV bta_av_psm; bta_av_psm.rc_cover_art_psm = rc_psm; @@ -2493,20 +2476,19 @@ void bta_av_rc_closed(tBTA_AV_DATA* p_data) { rc_close.rc_handle = BTA_AV_RC_HANDLE_NONE; rc_close.peer_addr = RawAddress::kEmpty; p_scb = NULL; - LOG_VERBOSE("%s: rc_handle:%d, address:%s", __func__, p_msg->handle, - ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr)); + log::verbose("rc_handle:{}, address:{}", p_msg->handle, + ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr)); for (i = 0; i < BTA_AV_NUM_RCB; i++) { p_rcb = &p_cb->rcb[i]; - LOG_VERBOSE("%s: rcb[%d] rc_handle:%d, status=0x%x, shdl:%d, lidx:%d", - __func__, i, p_rcb->handle, p_rcb->status, p_rcb->shdl, - p_rcb->lidx); + log::verbose("rcb[{}] rc_handle:{}, status=0x{:x}, shdl:{}, lidx:{}", i, + p_rcb->handle, p_rcb->status, p_rcb->shdl, p_rcb->lidx); if (p_rcb->handle == p_msg->handle) { if (btif_av_src_sink_coexist_enabled() && p_rcb->shdl && (p_rcb->shdl - 1) < BTA_AV_NUM_STRS) { p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1]; if (p_scb && !(p_scb->PeerAddress() == p_msg->peer_addr)) { - LOG_VERBOSE("%s: handle%d %s error p_scb or addr", __func__, i, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::verbose("handle{} {} error p_scb or addr", i, + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); conn = true; continue; } @@ -2518,7 +2500,7 @@ void bta_av_rc_closed(tBTA_AV_DATA* p_data) { p_rcb->peer_ct_features = 0; p_rcb->peer_tg_features = 0; p_cb->rc_feature = {}; - LOG_VERBOSE("%s: shdl:%d, lidx:%d", __func__, p_rcb->shdl, p_rcb->lidx); + log::verbose("shdl:{}, lidx:{}", p_rcb->shdl, p_rcb->lidx); if (p_rcb->shdl) { if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) { p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1]; @@ -2527,16 +2509,15 @@ void bta_av_rc_closed(tBTA_AV_DATA* p_data) { rc_close.peer_addr = p_scb->PeerAddress(); if (p_scb->rc_handle == p_rcb->handle) p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE; - LOG_VERBOSE("%s: shdl:%d, srch:%d", __func__, p_rcb->shdl, - p_scb->rc_handle); + log::verbose("shdl:{}, srch:{}", p_rcb->shdl, p_scb->rc_handle); } p_rcb->shdl = 0; } else if (p_rcb->lidx == (BTA_AV_NUM_LINKS + 1)) { /* if the RCB uses the extra LCB, use the addr for event and clean it */ p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS]; rc_close.peer_addr = p_msg->peer_addr; - LOG_INFO("%s: rc_only closed bd_addr: %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr)); + log::info("rc_only closed bd_addr: {}", + ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr)); p_lcb->conn_msk = 0; p_lcb->lidx = 0; } @@ -2588,8 +2569,8 @@ void bta_av_rc_browse_opened(tBTA_AV_DATA* p_data) { tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)p_data; tBTA_AV_RC_BROWSE_OPEN rc_browse_open; - LOG_INFO("%s: peer_addr: %s rc_handle:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr), p_msg->handle); + log::info("peer_addr: {} rc_handle:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr), p_msg->handle); rc_browse_open.status = BTA_AV_SUCCESS; rc_browse_open.rc_handle = p_msg->handle; @@ -2614,8 +2595,8 @@ void bta_av_rc_browse_closed(tBTA_AV_DATA* p_data) { tBTA_AV_RC_CONN_CHG* p_msg = (tBTA_AV_RC_CONN_CHG*)p_data; tBTA_AV_RC_BROWSE_CLOSE rc_browse_close; - LOG_INFO("%s: peer_addr: %s rc_handle:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr), p_msg->handle); + log::info("peer_addr: {} rc_handle:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_msg->peer_addr), p_msg->handle); rc_browse_close.rc_handle = p_msg->handle; rc_browse_close.peer_addr = p_msg->peer_addr; @@ -2646,8 +2627,7 @@ void bta_av_rc_disc(uint8_t disc) { RawAddress peer_addr = RawAddress::kEmpty; uint8_t rc_handle; - LOG_VERBOSE("%s: disc: 0x%x, bta_av_cb.disc: 0x%x", __func__, disc, - bta_av_cb.disc); + log::verbose("disc: 0x{:x}, bta_av_cb.disc: 0x{:x}", disc, bta_av_cb.disc); if ((bta_av_cb.disc != 0) || (disc == 0)) return; if ((disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) { @@ -2661,7 +2641,7 @@ void bta_av_rc_disc(uint8_t disc) { p_scb = p_cb->p_scb[hdi]; if (p_scb) { - LOG_VERBOSE("%s: rc_handle %d", __func__, p_scb->rc_handle); + log::verbose("rc_handle {}", p_scb->rc_handle); peer_addr = p_scb->PeerAddress(); } } @@ -2682,7 +2662,7 @@ void bta_av_rc_disc(uint8_t disc) { &db_params, base::Bind(bta_av_avrc_sdp_cback)) == AVRC_SUCCESS) { p_cb->disc = disc; - LOG_VERBOSE("%s: disc 0x%x", __func__, p_cb->disc); + log::verbose("disc 0x{:x}", p_cb->disc); } } } @@ -2712,7 +2692,7 @@ void bta_av_dereg_comp(tBTA_AV_DATA* p_data) { p_scb = bta_av_hndl_to_scb(p_data->hdr.layer_specific); if (p_scb) { - LOG_VERBOSE("%s: deregistered %d(h%d)", __func__, p_scb->chnl, p_scb->hndl); + log::verbose("deregistered {}(h{})", p_scb->chnl, p_scb->hndl); mask = BTA_AV_HNDL_TO_MSK(p_scb->hdi); p_cb->reg_audio &= ~mask; if ((p_cb->conn_audio & mask) && p_cb->audio_open_cnt) { @@ -2734,12 +2714,11 @@ void bta_av_dereg_comp(tBTA_AV_DATA* p_data) { if (!p_cb->reg_audio) { /* Only remove the SDP record if we're the ones that created it */ if (is_new_avrcp_enabled()) { - LOG_VERBOSE( - "%s: newavrcp is the owner of the AVRCP Target SDP " - "record. Don't dereg the SDP record", - __func__); + log::verbose( + "newavrcp is the owner of the AVRCP Target SDP record. Don't dereg " + "the SDP record"); } else { - LOG_VERBOSE("%s: newavrcp is not enabled. Remove SDP record", __func__); + log::verbose("newavrcp is not enabled. Remove SDP record"); bta_ar_dereg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL); } @@ -2759,8 +2738,7 @@ void bta_av_dereg_comp(tBTA_AV_DATA* p_data) { bta_av_free_scb(p_scb); } - LOG_VERBOSE("%s: audio 0x%x, disable:%d", __func__, p_cb->reg_audio, - p_cb->disabling); + log::verbose("audio 0x{:x}, disable:{}", p_cb->reg_audio, p_cb->disabling); /* if no stream control block is active */ if (p_cb->reg_audio == 0) { /* deregister from AVDT */ diff --git a/system/bta/av/bta_av_api.cc b/system/bta/av/bta_av_api.cc index 8c99211c215cf108d8aa92aceb94676db48ab16a..f35ef990d632e4aac8e29a85cbffabaeb88c5913 100644 --- a/system/bta/av/bta_av_api.cc +++ b/system/bta/av/bta_av_api.cc @@ -26,9 +26,12 @@ #define LOG_TAG "bt_bta_av" -#include "bt_target.h" // Must be first to define build configuration +#include + #include "bta/av/bta_av_int.h" #include "btif/include/btif_av.h" +#include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" @@ -36,6 +39,8 @@ #include "stack/include/bt_uuid16.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants ****************************************************************************/ @@ -150,9 +155,9 @@ void BTA_AvDeregister(tBTA_AV_HNDL hndl) { ******************************************************************************/ void BTA_AvOpen(const RawAddress& bd_addr, tBTA_AV_HNDL handle, bool use_rc, uint16_t uuid) { - LOG_INFO("%s: peer %s bta_handle:0x%x use_rc=%s uuid=0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle, - (use_rc) ? "true" : "false", uuid); + log::info("peer {} bta_handle:0x{:x} use_rc={} uuid=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle, + (use_rc) ? "true" : "false", uuid); tBTA_AV_API_OPEN* p_buf = (tBTA_AV_API_OPEN*)osi_malloc(sizeof(tBTA_AV_API_OPEN)); @@ -188,7 +193,7 @@ void BTA_AvOpen(const RawAddress& bd_addr, tBTA_AV_HNDL handle, bool use_rc, * ******************************************************************************/ void BTA_AvClose(tBTA_AV_HNDL handle) { - LOG_INFO("%s: bta_handle:0x%x", __func__, handle); + log::info("bta_handle:0x{:x}", handle); BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID)); @@ -208,7 +213,7 @@ void BTA_AvClose(tBTA_AV_HNDL handle) { * ******************************************************************************/ void BTA_AvDisconnect(tBTA_AV_HNDL handle) { - LOG_INFO("%s: bta_handle=0x%x", __func__, handle); + log::info("bta_handle=0x{:x}", handle); tBTA_AV_API_DISCNT* p_buf = (tBTA_AV_API_DISCNT*)osi_malloc(sizeof(tBTA_AV_API_DISCNT)); @@ -229,9 +234,9 @@ void BTA_AvDisconnect(tBTA_AV_HNDL handle) { * ******************************************************************************/ void BTA_AvStart(tBTA_AV_HNDL handle, bool use_latency_mode) { - LOG_INFO( - "Starting audio/video stream data transfer bta_handle:%hhu, " - "use_latency_mode:%s", + log::info( + "Starting audio/video stream data transfer bta_handle:{}, " + "use_latency_mode:{}", handle, use_latency_mode ? "true" : "false"); tBTA_AV_DO_START* p_buf = @@ -253,7 +258,7 @@ void BTA_AvStart(tBTA_AV_HNDL handle, bool use_latency_mode) { * ******************************************************************************/ void BTA_AvOffloadStart(tBTA_AV_HNDL hndl) { - LOG_INFO("%s: bta_handle=0x%x", __func__, hndl); + log::info("bta_handle=0x{:x}", hndl); BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID)); @@ -295,8 +300,7 @@ void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status) { * ******************************************************************************/ void BTA_AvStop(tBTA_AV_HNDL handle, bool suspend) { - LOG_INFO("%s: bta_handle=0x%x suspend=%s", __func__, handle, - logbool(suspend).c_str()); + log::info("bta_handle=0x{:x} suspend={}", handle, logbool(suspend)); tBTA_AV_API_STOP* p_buf = (tBTA_AV_API_STOP*)osi_malloc(sizeof(tBTA_AV_API_STOP)); @@ -326,8 +330,8 @@ void BTA_AvStop(tBTA_AV_HNDL handle, bool suspend) { void BTA_AvReconfig(tBTA_AV_HNDL hndl, bool suspend, uint8_t sep_info_idx, uint8_t* p_codec_info, uint8_t num_protect, const uint8_t* p_protect_info) { - LOG_INFO("%s: bta_handle=0x%x suspend=%s sep_info_idx=%d", __func__, hndl, - logbool(suspend).c_str(), sep_info_idx); + log::info("bta_handle=0x{:x} suspend={} sep_info_idx={}", hndl, + logbool(suspend), sep_info_idx); tBTA_AV_API_RCFG* p_buf = (tBTA_AV_API_RCFG*)osi_malloc(sizeof(tBTA_AV_API_RCFG) + num_protect); @@ -641,8 +645,8 @@ void BTA_AvMetaCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_CMD cmd_code, * ******************************************************************************/ void BTA_AvSetLatency(tBTA_AV_HNDL handle, bool is_low_latency) { - LOG_INFO( - "Set audio/video stream low latency bta_handle:%hhu, is_low_latency:%s", + log::info( + "Set audio/video stream low latency bta_handle:{}, is_low_latency:{}", handle, is_low_latency ? "true" : "false"); tBTA_AV_API_SET_LATENCY* p_buf = diff --git a/system/bta/av/bta_av_cfg.cc b/system/bta/av/bta_av_cfg.cc index 077b8d17e42f429c58083d1ac8e1ba092cc26ff9..319e6294b40a442ced4b1dd18718042d8a643550 100644 --- a/system/bta/av/bta_av_cfg.cc +++ b/system/bta/av/bta_av_cfg.cc @@ -23,11 +23,12 @@ * ******************************************************************************/ -#include +#include -#include "bt_target.h" // Must be first to define build configuration +#include #include "bta/include/bta_av_api.h" +#include "internal_include/bt_target.h" #include "stack/include/avrc_api.h" #ifndef BTA_AV_RC_COMP_ID @@ -38,6 +39,8 @@ #define BTA_AV_RC_PASS_RSP_CODE AVRC_RSP_NOT_IMPL #endif +using namespace bluetooth; + const uint32_t bta_av_meta_caps_co_ids[] = {AVRC_CO_METADATA, AVRC_CO_BROADCOM}; /* AVRCP supported categories */ @@ -45,7 +48,6 @@ const uint32_t bta_av_meta_caps_co_ids[] = {AVRC_CO_METADATA, AVRC_CO_BROADCOM}; #define BTA_AVK_RC_SUPF_CT \ (AVRC_SUPF_CT_CAT1 | AVRC_SUPF_CT_BROWSE | \ AVRC_SUPF_CT_COVER_ART_GET_IMAGE_PROP | AVRC_SUPF_CT_COVER_ART_GET_IMAGE) -#define BTA_AVK_RC_SUPF_CT_V15 (AVRC_SUPF_CT_CAT1 | AVRC_SUPF_CT_BROWSE) #define BTA_AVK_RC_SUPF_TG (AVRC_SUPF_TG_CAT2) @@ -141,10 +143,10 @@ extern const tBTA_AV_CFG bta_av_cfg = { const tBTA_AV_CFG* get_bta_avk_cfg() { static const tBTA_AV_CFG bta_avk_cfg = { - AVRC_CO_METADATA, /* AVRCP Company ID */ - BTA_AVK_RC_SUPF_CT_V15, /* AVRCP controller categories */ - BTA_AVK_RC_SUPF_TG, /* AVRCP target categories */ - 6, /* AVDTP audio channel max data queue size */ + AVRC_CO_METADATA, /* AVRCP Company ID */ + BTA_AVK_RC_SUPF_CT, /* AVRCP controller categories */ + BTA_AVK_RC_SUPF_TG, /* AVRCP target categories */ + 6, /* AVDTP audio channel max data queue size */ false, /* true, to accept AVRC 1.3 group nevigation command */ 2, /* company id count in p_meta_co_ids */ (uint8_t)(avrcp_absolute_volume_is_enabled() diff --git a/system/bta/av/bta_av_ci.cc b/system/bta/av/bta_av_ci.cc index bfa4574734271cab8f66126706adf9005e0b9647..b43748a67ca00a6c5dbf00de9a6313461a1070ac 100644 --- a/system/bta/av/bta_av_ci.cc +++ b/system/bta/av/bta_av_ci.cc @@ -25,11 +25,15 @@ #define LOG_TAG "bt_bta_av" +#include + #include "bta/av/bta_av_int.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + /******************************************************************************* * * Function bta_av_ci_src_data_ready @@ -66,10 +70,10 @@ void bta_av_ci_src_data_ready(tBTA_AV_CHNL chnl) { void bta_av_ci_setconfig(tBTA_AV_HNDL bta_av_handle, uint8_t err_code, uint8_t category, uint8_t num_seid, uint8_t* p_seid, bool recfg_needed, uint8_t avdt_handle) { - LOG_INFO( - "%s: bta_av_handle=0x%x err_code=%d category=%d " - "num_seid=%d recfg_needed=%s avdt_handle=%d", - __func__, bta_av_handle, err_code, category, num_seid, + log::info( + "bta_av_handle=0x{:x} err_code={} category={} num_seid={} " + "recfg_needed={} avdt_handle={}", + bta_av_handle, err_code, category, num_seid, recfg_needed ? "true" : "false", avdt_handle); tBTA_AV_CI_SETCONFIG* p_buf = diff --git a/system/bta/av/bta_av_int.h b/system/bta/av/bta_av_int.h index 41637c4b0423b6134ecbb07c01b0cbbd8c82320a..90602aa425647d8c4951d79808a8e1e03a2b8c5d 100644 --- a/system/bta/av/bta_av_int.h +++ b/system/bta/av/bta_av_int.h @@ -24,6 +24,8 @@ #ifndef BTA_AV_INT_H #define BTA_AV_INT_H +#include + #include #include @@ -666,6 +668,9 @@ typedef struct { bool sco_occupied; /* true if SCO is being used or call is in progress */ uint16_t offload_start_pending_hndl; uint16_t offload_started_hndl; + /* Set to true if the new offload start vendor command + * was used to start the stream on the controller. */ + bool offload_start_v2; tBTA_AV_FEAT sink_features; /* sink features */ uint8_t reg_role; /* bit0-src, bit1-sink */ tBTA_AV_RC_FEAT rc_feature; /* save peer rc feature */ @@ -696,6 +701,9 @@ class tBT_A2DP_OFFLOAD { #define VS_HCI_A2DP_OFFLOAD_START 0x01 #define VS_HCI_A2DP_OFFLOAD_STOP 0x02 +#define VS_HCI_A2DP_OFFLOAD_START_V2 0x03 +#define VS_HCI_A2DP_OFFLOAD_STOP_V2 0x04 + /***************************************************************************** * Global data ****************************************************************************/ @@ -839,4 +847,9 @@ void bta_av_vendor_offload_stop(void); void bta_av_st_rc_timer(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data); void bta_av_api_set_peer_sep(tBTA_AV_DATA* p_data); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* BTA_AV_INT_H */ diff --git a/system/bta/av/bta_av_main.cc b/system/bta/av/bta_av_main.cc index 30dbbbde320c4b420acb4862d0fb792ab6a296ff..47abb2f79da7ceb9f130e801e238ef1e693314d4 100644 --- a/system/bta/av/bta_av_main.cc +++ b/system/bta/av/bta_av_main.cc @@ -25,6 +25,7 @@ #define LOG_TAG "bt_bta_av" #include +#include #include @@ -37,8 +38,8 @@ #include "btif/include/btif_av.h" #include "btif/include/btif_av_co.h" #include "btif/include/btif_config.h" -#include "gd/os/log.h" #include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "osi/include/properties.h" @@ -47,10 +48,12 @@ #include "stack/include/bt_uuid16.h" #include "stack/include/hci_error_code.h" #include "stack/include/sdp_api.h" +#include "storage/config_keys.h" #include "types/hci_role.h" #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; /***************************************************************************** * Constants and types @@ -153,18 +156,14 @@ static void bta_av_api_enable(tBTA_AV_DATA* p_data) { } if (bta_av_cb.disabling) { - LOG_WARN("%s: previous (reg_audio=%#x) is still disabling (attempts=%d)", - __func__, bta_av_cb.reg_audio, bta_av_cb.enabling_attempts); + log::warn("previous (reg_audio={:#x}) is still disabling (attempts={})", + bta_av_cb.reg_audio, bta_av_cb.enabling_attempts); if (++bta_av_cb.enabling_attempts <= kEnablingAttemptsCountMaximum) { tBTA_AV_API_ENABLE* p_buf = (tBTA_AV_API_ENABLE*)osi_malloc(sizeof(tBTA_AV_API_ENABLE)); memcpy(p_buf, &p_data->api_enable, sizeof(tBTA_AV_API_ENABLE)); -#if BASE_VER < 931007 - bta_sys_sendmsg_delayed(p_buf, base::TimeDelta::FromMilliseconds( -#else - bta_sys_sendmsg_delayed(p_buf, base::Milliseconds( -#endif - kEnablingAttemptsIntervalMs)); + bta_sys_sendmsg_delayed( + p_buf, std::chrono::milliseconds(kEnablingAttemptsIntervalMs)); return; } if (bta_av_cb.sdp_a2dp_handle) { @@ -253,8 +252,7 @@ int BTA_AvObtainPeerChannelIndex(const RawAddress& peer_address) { if (p_scb->PeerAddress().IsEmpty()) { const RawAddress& btif_addr = btif_av_find_by_handle(p_scb->hndl); if (!btif_addr.IsEmpty() && btif_addr != peer_address) { - LOG_VERBOSE("%s: btif_addr = %s, index=%d!", __func__, - btif_addr.ToString().c_str(), index); + log::verbose("btif_addr = {}, index={}!", btif_addr.ToString(), index); continue; } return p_scb->hdi; @@ -297,7 +295,7 @@ tBTA_AV_SCB* bta_av_hndl_to_scb(uint16_t handle) { ******************************************************************************/ static tBTA_AV_SCB* bta_av_alloc_scb(tBTA_AV_CHNL chnl) { if (chnl != BTA_AV_CHNL_AUDIO) { - LOG_ERROR("%s: bad channel: %d", __func__, chnl); + log::error("bad channel: {}", chnl); return nullptr; } @@ -322,7 +320,7 @@ static tBTA_AV_SCB* bta_av_alloc_scb(tBTA_AV_CHNL chnl) { static tBTA_AV_SCB* bta_av_find_scb(tBTA_AV_CHNL chnl, uint8_t app_id) { if (chnl != BTA_AV_CHNL_AUDIO) { - LOG_ERROR("%s: bad channel: %d", __func__, chnl); + log::error("bad channel: {}", chnl); return nullptr; } @@ -330,7 +328,7 @@ static tBTA_AV_SCB* bta_av_find_scb(tBTA_AV_CHNL chnl, uint8_t app_id) { if ((bta_av_cb.p_scb[xx] != nullptr) && (bta_av_cb.p_scb[xx]->chnl == chnl) && (bta_av_cb.p_scb[xx]->app_id == app_id)) { - LOG_VERBOSE("%s: found at: %d", __func__, xx); + log::verbose("found at: {}", xx); return bta_av_cb.p_scb[xx]; } } @@ -357,18 +355,19 @@ void tBTA_AV_SCB::OnConnected(const RawAddress& peer_address) { peer_address_ = peer_address; if (peer_address.IsEmpty()) { - LOG_ERROR("%s: Invalid peer address: %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("Invalid peer address: {}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } // Read and restore the AVDTP version from local storage uint16_t avdtp_version = 0; size_t version_value_size = sizeof(avdtp_version); - if (!btif_config_get_bin(peer_address_.ToString(), AVDTP_VERSION_CONFIG_KEY, + if (!btif_config_get_bin(peer_address_.ToString(), + BTIF_STORAGE_KEY_AVDTP_VERSION, (uint8_t*)&avdtp_version, &version_value_size)) { - LOG_WARN("%s: Failed to read cached peer AVDTP version for %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address_)); + log::warn("Failed to read cached peer AVDTP version for {}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address_)); } else { SetAvdtpVersion(avdtp_version); } @@ -381,8 +380,8 @@ void tBTA_AV_SCB::OnDisconnected() { void tBTA_AV_SCB::SetAvdtpVersion(uint16_t avdtp_version) { avdtp_version_ = avdtp_version; - LOG_INFO("%s: AVDTP version for %s set to 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address_), avdtp_version_); + log::info("AVDTP version for {} set to 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address_), avdtp_version_); } /******************************************************************************* @@ -399,7 +398,7 @@ void bta_av_conn_cback(UNUSED_ATTR uint8_t handle, const RawAddress& bd_addr, if (event == AVDT_DISCONNECT_IND_EVT) { p_scb = bta_av_addr_to_scb(bd_addr); } else if (event == AVDT_CONNECT_IND_EVT) { - LOG_VERBOSE("%s: CONN_IND is ACP:%d", __func__, p_data->hdr.err_param); + log::verbose("CONN_IND is ACP:{}", p_data->hdr.err_param); } tBTA_AV_STR_MSG* p_msg = @@ -410,11 +409,10 @@ void bta_av_conn_cback(UNUSED_ATTR uint8_t handle, const RawAddress& bd_addr, p_msg->bd_addr = bd_addr; p_msg->scb_index = scb_index; if (p_scb) { - LOG_VERBOSE("%s: bta_handle x%x, role x%x", __func__, p_scb->hndl, - p_scb->role); + log::verbose("bta_handle x{:x}, role x{:x}", p_scb->hndl, p_scb->role); } - LOG_INFO("%s: conn_cback bd_addr: %s, scb_index: %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), scb_index); + log::info("conn_cback bd_addr: {}, scb_index: {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), scb_index); bta_sys_sendmsg(p_msg); } } @@ -456,20 +454,15 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { uint8_t local_role = 0; if (bta_av_cb.disabling || (bta_av_cb.features == 0)) { - LOG_WARN( - "%s: AV instance (features=%#x, reg_audio=%#x) is not " - "ready for app_id %d", - __func__, bta_av_cb.features, bta_av_cb.reg_audio, - p_data->api_reg.app_id); + log::warn( + "AV instance (features={:#x}, reg_audio={:#x}) is not ready for app_id " + "{}", + bta_av_cb.features, bta_av_cb.reg_audio, p_data->api_reg.app_id); tBTA_AV_API_REG* p_buf = (tBTA_AV_API_REG*)osi_malloc(sizeof(tBTA_AV_API_REG)); memcpy(p_buf, &p_data->api_reg, sizeof(tBTA_AV_API_REG)); bta_sys_sendmsg_delayed( -#if BASE_VER < 931007 - p_buf, base::TimeDelta::FromMilliseconds(kEnablingAttemptsIntervalMs)); -#else - p_buf, base::Milliseconds(kEnablingAttemptsIntervalMs)); -#endif + p_buf, std::chrono::milliseconds(kEnablingAttemptsIntervalMs)); return; } @@ -487,7 +480,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { char avrcp_version[PROPERTY_VALUE_MAX] = {0}; osi_property_get(AVRCP_VERSION_PROPERTY, avrcp_version, AVRCP_DEFAULT_VERSION); - LOG_INFO("%s: AVRCP version used for sdp: \"%s\"", __func__, avrcp_version); + log::info("AVRCP version used for sdp: \"{}\"", avrcp_version); uint16_t profile_initialized = p_data->api_reg.service_uuid; if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) { @@ -496,14 +489,14 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { p_bta_av_cfg = &bta_av_cfg; if (!strncmp(AVRCP_1_3_STRING, avrcp_version, sizeof(AVRCP_1_3_STRING))) { - LOG_INFO("%s: AVRCP 1.3 capabilites used", __func__); + log::info("AVRCP 1.3 capabilites used"); p_bta_av_cfg = &bta_av_cfg_compatibility; } } - LOG_VERBOSE("%s: profile: 0x%x", __func__, profile_initialized); + log::verbose("profile: 0x{:x}", profile_initialized); if (p_bta_av_cfg == NULL) { - LOG_ERROR("%s: AV configuration is null!", __func__); + log::error("AV configuration is null!"); return; } @@ -516,7 +509,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { p_scb = bta_av_alloc_scb(reg_data.chnl); } if (p_scb == NULL) { - LOG_ERROR("%s: failed to alloc SCB", __func__); + log::error("failed to alloc SCB"); break; } @@ -548,13 +541,11 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { * absolute volume. */ if (is_new_avrcp_enabled()) { - LOG_VERBOSE( - "%s: newavrcp is the owner of the AVRCP Target SDP " - "record. Don't create the SDP record", - __func__); + log::verbose( + "newavrcp is the owner of the AVRCP Target SDP record. Don't " + "create the SDP record"); } else { - LOG_VERBOSE("%s: newavrcp is not enabled. Create SDP record", - __func__); + log::verbose("newavrcp is not enabled. Create SDP record"); uint16_t profile_version = AVRC_REV_1_0; if (!strncmp(AVRCP_1_6_STRING, avrcp_version, @@ -598,7 +589,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { if (!(bta_av_cb.features & BTA_AV_FEAT_PROTECT)) { avdtp_stream_config.nsc_mask |= AvdtpStreamConfig::AVDT_NSC_SECURITY; } - LOG_VERBOSE("%s: nsc_mask: 0x%x", __func__, avdtp_stream_config.nsc_mask); + log::verbose("nsc_mask: 0x{:x}", avdtp_stream_config.nsc_mask); if (p_data->api_reg.p_service_name[0] == 0) { p_service_name = NULL; @@ -662,9 +653,9 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { } if (AVDT_CreateStream(p_scb->app_id, &p_scb->seps[codec_index].av_handle, avdtp_stream_config) != AVDT_SUCCESS) { - LOG_WARN( - "%s: bta_handle=0x%x (app_id %d) failed to alloc an SEP index:%d", - __func__, p_scb->hndl, p_scb->app_id, codec_index); + log::warn( + "bta_handle=0x{:x} (app_id {}) failed to alloc an SEP index:{}", + p_scb->hndl, p_scb->app_id, codec_index); continue; } /* Save a copy of the codec */ @@ -745,7 +736,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { } } bta_av_cb.reg_audio |= BTA_AV_HNDL_TO_MSK(p_scb->hdi); - LOG_VERBOSE("%s: reg_audio: 0x%x", __func__, bta_av_cb.reg_audio); + log::verbose("reg_audio: 0x{:x}", bta_av_cb.reg_audio); } while (0); if (btif_av_src_sink_coexist_enabled()) { @@ -761,7 +752,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) { if (!strncmp(AVRCP_1_3_STRING, avrcp_version, sizeof(AVRCP_1_3_STRING))) { // ver if need - LOG_VERBOSE("%s: AVRCP 1.3 capabilites used", __func__); + log::verbose("AVRCP 1.3 capabilites used"); p_bta_av_cfg = &bta_av_cfg_compatibility; } } @@ -884,12 +875,12 @@ bool bta_av_chk_start(tBTA_AV_SCB* p_scb) { } } - LOG_INFO( - "%s: peer %s channel:%d bta_av_cb.audio_open_cnt:%d role:0x%x " - "features:0x%x start:%s", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->chnl, + log::info( + "peer {} channel:{} bta_av_cb.audio_open_cnt:{} role:0x{:x} " + "features:0x{:x} start:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->chnl, bta_av_cb.audio_open_cnt, p_scb->role, bta_av_cb.features, - logbool(start).c_str()); + logbool(start)); return start; } @@ -908,7 +899,7 @@ void bta_av_restore_switch(void) { int i; uint8_t mask; - LOG_VERBOSE("%s: reg_audio: 0x%x", __func__, bta_av_cb.reg_audio); + log::verbose("reg_audio: 0x{:x}", bta_av_cb.reg_audio); for (i = 0; i < BTA_AV_NUM_STRS; i++) { mask = BTA_AV_HNDL_TO_MSK(i); if (p_cb->conn_audio == mask) { @@ -937,9 +928,9 @@ static void bta_av_sys_rs_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, tHCI_ROLE cur_role; uint8_t peer_idx = 0; - LOG_VERBOSE("%s: peer %s new_role:%d hci_status:0x%x bta_av_cb.rs_idx:%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_addr), new_role, - hci_status, bta_av_cb.rs_idx); + log::verbose("peer {} new_role:{} hci_status:0x{:x} bta_av_cb.rs_idx:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), new_role, hci_status, + bta_av_cb.rs_idx); for (i = 0; i < BTA_AV_NUM_STRS; i++) { /* loop through all the SCBs to find matching peer addresses and report the @@ -949,9 +940,9 @@ static void bta_av_sys_rs_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, if (p_scb && p_scb->PeerAddress() == peer_addr) { tBTA_AV_ROLE_RES* p_buf = (tBTA_AV_ROLE_RES*)osi_malloc(sizeof(tBTA_AV_ROLE_RES)); - LOG_VERBOSE( - "%s: peer %s found: new_role:%d, hci_status:0x%x bta_handle:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_addr), new_role, hci_status, + log::verbose( + "peer {} found: new_role:{}, hci_status:0x{:x} bta_handle:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), new_role, hci_status, p_scb->hndl); p_buf->hdr.event = BTA_AV_ROLE_CHANGE_EVT; p_buf->hdr.layer_specific = p_scb->hndl; @@ -978,17 +969,17 @@ static void bta_av_sys_rs_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, p_scb = bta_av_cb.p_scb[bta_av_cb.rs_idx - 1]; } if (p_scb && p_scb->q_tag == BTA_AV_Q_TAG_OPEN) { - LOG_VERBOSE("%s: peer %s rs_idx:%d, bta_handle:0x%x q_tag:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - bta_av_cb.rs_idx, p_scb->hndl, p_scb->q_tag); + log::verbose("peer {} rs_idx:{}, bta_handle:0x{:x} q_tag:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + bta_av_cb.rs_idx, p_scb->hndl, p_scb->q_tag); if (HCI_SUCCESS == hci_status || HCI_ERR_NO_CONNECTION == hci_status) { p_scb->q_info.open.switch_res = BTA_AV_RS_OK; } else { - LOG_ERROR( - "%s: peer %s (p_scb peer %s) role switch failed: new_role:%d " - "hci_status:0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_addr), + log::error( + "peer {} (p_scb peer {}) role switch failed: new_role:{} " + "hci_status:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), new_role, hci_status); p_scb->q_info.open.switch_res = BTA_AV_RS_FAIL; @@ -1021,12 +1012,13 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, int i; tBTA_AV_API_STOP stop; - LOG(INFO) << __func__ << ": status=" << bta_sys_conn_status_text(status) - << ", num_links=" << +num_sco_links; + log::info("status={}, num_links={}", bta_sys_conn_status_text(status), + num_sco_links); if (num_sco_links) { bta_av_cb.sco_occupied = true; - LOG_DEBUG("SCO occupied peer:%s status:%s", ADDRESS_TO_LOGGABLE_CSTR(peer_addr), - bta_sys_conn_status_text(status).c_str()); + log::debug("SCO occupied peer:{} status:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), + bta_sys_conn_status_text(status)); if (bta_av_cb.features & BTA_AV_FEAT_NO_SCO_SSPD) { return; @@ -1037,7 +1029,7 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, p_scb = bta_av_cb.p_scb[i]; if (p_scb && p_scb->co_started && (!p_scb->sco_suspend)) { - VLOG(1) << __func__ << ": suspending scb:" << i; + log::verbose("suspending scb:{}", i); /* scb is used and started, not suspended automatically */ p_scb->sco_suspend = true; stop.flush = false; @@ -1048,8 +1040,9 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, } } else { bta_av_cb.sco_occupied = false; - LOG_DEBUG("SCO unoccupied peer:%s status:%s", ADDRESS_TO_LOGGABLE_CSTR(peer_addr), - bta_sys_conn_status_text(status).c_str()); + log::debug("SCO unoccupied peer:{} status:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), + bta_sys_conn_status_text(status)); if (bta_av_cb.features & BTA_AV_FEAT_NO_SCO_SSPD) { return; @@ -1060,7 +1053,7 @@ static void bta_av_sco_chg_cback(tBTA_SYS_CONN_STATUS status, if (p_scb && p_scb->sco_suspend) /* scb is used and suspended for SCO */ { - VLOG(1) << __func__ << ": starting scb:" << i; + log::verbose("starting scb:{}", i); bta_av_ssm_execute(p_scb, BTA_AV_AP_START_EVT, NULL); } } @@ -1133,17 +1126,17 @@ bool bta_av_switch_if_needed(tBTA_AV_SCB* p_scb) { bool bta_av_link_role_ok(tBTA_AV_SCB* p_scb, uint8_t bits) { tHCI_ROLE role; if (BTM_GetRole(p_scb->PeerAddress(), &role) != BTM_SUCCESS) { - LOG_WARN("Unable to find link role for device:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::warn("Unable to find link role for device:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); return true; } if (role != HCI_ROLE_CENTRAL && (A2DP_BitsSet(bta_av_cb.conn_audio) > bits)) { - LOG_INFO( - "Switch link role to central peer:%s bta_handle:0x%x current_role:%s" - " conn_audio:0x%x bits:%d features:0x%x", + log::info( + "Switch link role to central peer:{} bta_handle:0x{:x} current_role:{} " + "conn_audio:0x{:x} bits:{} features:0x{:x}", ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - RoleText(role).c_str(), bta_av_cb.conn_audio, bits, bta_av_cb.features); + RoleText(role), bta_av_cb.conn_audio, bits, bta_av_cb.features); const tBTM_STATUS status = BTM_SwitchRoleToCentral(p_scb->PeerAddress()); switch (status) { case BTM_CMD_STARTED: @@ -1153,15 +1146,15 @@ bool bta_av_link_role_ok(tBTA_AV_SCB* p_scb, uint8_t bits) { // Role switch can never happen, but indicate to caller // a result such that a timer will not start to repeatedly // try something not possible. - LOG_ERROR("Link can never role switch to central device:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); + log::error("Link can never role switch to central device:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress())); break; default: /* can not switch role on SCB - start the timer on SCB */ p_scb->wait |= BTA_AV_WAIT_ROLE_SW_RES_START; - LOG_ERROR("Unable to switch role to central device:%s error:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), - btm_status_text(status).c_str()); + log::error("Unable to switch role to central device:{} error:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), + btm_status_text(status)); return false; } } @@ -1323,8 +1316,9 @@ static void bta_av_better_state_machine(tBTA_AV_CB* p_cb, uint16_t event, } void bta_av_sm_execute(tBTA_AV_CB* p_cb, uint16_t event, tBTA_AV_DATA* p_data) { - LOG_VERBOSE("%s: AV event=0x%x(%s) state=%d(%s)", __func__, event, - bta_av_evt_code(event), p_cb->state, bta_av_st_code(p_cb->state)); + log::verbose("AV event=0x{:x}({}) state={}({})", event, + bta_av_evt_code(event), p_cb->state, + bta_av_st_code(p_cb->state)); bta_av_better_state_machine(p_cb, event, p_data); } @@ -1343,17 +1337,17 @@ bool bta_av_hdl_event(const BT_HDR_RIGID* p_msg) { return true; /* to free p_msg */ } if (p_msg->event >= BTA_AV_FIRST_NSM_EVT) { - LOG_VERBOSE("%s: AV nsm event=0x%x(%s)", __func__, p_msg->event, - bta_av_evt_code(p_msg->event)); + log::verbose("AV nsm event=0x{:x}({})", p_msg->event, + bta_av_evt_code(p_msg->event)); bta_av_non_state_machine_event(p_msg->event, (tBTA_AV_DATA*)p_msg); } else if (p_msg->event >= BTA_AV_FIRST_SM_EVT && p_msg->event <= BTA_AV_LAST_SM_EVT) { - LOG_VERBOSE("%s: AV sm event=0x%x(%s)", __func__, p_msg->event, - bta_av_evt_code(p_msg->event)); + log::verbose("AV sm event=0x{:x}({})", p_msg->event, + bta_av_evt_code(p_msg->event)); /* state machine events */ bta_av_sm_execute(&bta_av_cb, p_msg->event, (tBTA_AV_DATA*)p_msg); } else { - LOG_VERBOSE("%s: bta_handle=0x%x", __func__, p_msg->layer_specific); + log::verbose("bta_handle=0x{:x}", p_msg->layer_specific); /* stream state machine events */ bta_av_ssm_execute(bta_av_hndl_to_scb(p_msg->layer_specific), p_msg->event, (tBTA_AV_DATA*)p_msg); diff --git a/system/bta/av/bta_av_ssm.cc b/system/bta/av/bta_av_ssm.cc index 383591b54655af7ddc9a201a380e47363227181d..1aea2b3692cc74b887be20db8d20955949420e1b 100644 --- a/system/bta/av/bta_av_ssm.cc +++ b/system/bta/av/bta_av_ssm.cc @@ -22,12 +22,15 @@ * ******************************************************************************/ -#include "bt_target.h" // Must be first to define build configuration - #define LOG_TAG "bt_bta_av" +#include + #include "bta/av/bta_av_int.h" -#include "osi/include/log.h" +#include "internal_include/bt_target.h" +#include "os/log.h" + +using namespace bluetooth; /***************************************************************************** * Constants and types @@ -419,17 +422,18 @@ static void bta_av_better_stream_state_machine(tBTA_AV_SCB* p_scb, } if (previous_state != p_scb->state) { - LOG_INFO("peer %s p_scb=%#x(%p) AV event=0x%x(%s) state=%d(%s) -> %d(%s)", - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, p_scb, - event, bta_av_evt_code(event), previous_state, - bta_av_sst_code(previous_state), p_scb->state, - bta_av_sst_code(p_scb->state)); + log::info( + "peer {} p_scb={:#x}({}) AV event=0x{:x}({}) state={}({}) -> {}({})", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + fmt::ptr(p_scb), event, bta_av_evt_code(event), previous_state, + bta_av_sst_code(previous_state), p_scb->state, + bta_av_sst_code(p_scb->state)); } else { - LOG_VERBOSE("peer %s p_scb=%#x(%p) AV event=0x%x(%s) state=%d(%s)", - ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - p_scb, event, bta_av_evt_code(event), p_scb->state, - bta_av_sst_code(p_scb->state)); + log::verbose("peer {} p_scb={:#x}({}) AV event=0x{:x}({}) state={}({})", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, + fmt::ptr(p_scb), event, bta_av_evt_code(event), p_scb->state, + bta_av_sst_code(p_scb->state)); } if (event_handler1 != nullptr) { @@ -454,7 +458,7 @@ void bta_av_ssm_execute(tBTA_AV_SCB* p_scb, uint16_t event, tBTA_AV_DATA* p_data) { if (p_scb == NULL) { /* this stream is not registered */ - LOG_VERBOSE("%s: AV channel not registered", __func__); + log::verbose("AV channel not registered"); return; } @@ -518,11 +522,11 @@ void bta_av_set_scb_sst_init(tBTA_AV_SCB* p_scb) { uint8_t next_state = BTA_AV_INIT_SST; - LOG_VERBOSE( - "%s: peer %s AV (hndl=0x%x) state=%d(%s) next state=%d(%s) p_scb=%p", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, - p_scb->state, bta_av_sst_code(p_scb->state), next_state, - bta_av_sst_code(next_state), p_scb); + log::verbose( + "peer {} AV (hndl=0x{:x}) state={}({}) next state={}({}) p_scb={}", + ADDRESS_TO_LOGGABLE_CSTR(p_scb->PeerAddress()), p_scb->hndl, p_scb->state, + bta_av_sst_code(p_scb->state), next_state, bta_av_sst_code(next_state), + fmt::ptr(p_scb)); p_scb->state = next_state; } diff --git a/system/bta/csis/csis_client.cc b/system/bta/csis/csis_client.cc index 9083ef366ee517f63a7d8fbe5c6e516d4252b26a..090f34f1c8ba447a06fa2de0aeada81b0c49134a 100644 --- a/system/bta/csis/csis_client.cc +++ b/system/bta/csis/csis_client.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -35,13 +36,15 @@ #include "bta_groups.h" #include "bta_le_audio_uuids.h" #include "bta_sec_api.h" -#include "btif_storage.h" +#include "btif/include/btif_storage.h" +#include "common/init_flags.h" #include "crypto_toolbox/crypto_toolbox.h" #include "csis_types.h" #include "gap_api.h" #include "gatt_api.h" -#include "gd/common/init_flags.h" +#include "include/check.h" #include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "main/shim/le_scanning_manager.h" #include "osi/include/osi.h" #include "osi/include/stack_power_telemetry.h" @@ -70,6 +73,8 @@ using bluetooth::csis::kCsisSizeUuid; using bluetooth::groups::DeviceGroups; using bluetooth::groups::DeviceGroupsCallbacks; +using namespace bluetooth; + namespace { class CsisClientImpl; CsisClientImpl* instance; @@ -123,9 +128,9 @@ class CsisClientImpl : public CsisClient { base::Bind( [](Closure initCb, uint8_t client_id, uint8_t status) { if (status != GATT_SUCCESS) { - LOG_ERROR( - "Can't start Coordinated Set Service client " - "profile - no gatt clients left!"); + log::error( + "Can't start Coordinated Set Service client profile - no " + "gatt clients left!"); return; } instance->gatt_if_ = client_id; @@ -139,15 +144,15 @@ class CsisClientImpl : public CsisClient { BTA_DmSirkSecCbRegister([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { if (event != BTA_DM_SIRK_VERIFICATION_REQ_EVT) { - LOG_ERROR("Invalid event received by CSIP: %d", - static_cast(event)); + log::error("Invalid event received by CSIP: {}", + static_cast(event)); return; } instance->VerifySetMember(p_data->ble_req.bd_addr); }); - LOG_DEBUG(" Background scan enabled"); + log::debug("Background scan enabled"); CsisObserverSetBackground(true); } @@ -156,18 +161,18 @@ class CsisClientImpl : public CsisClient { std::shared_ptr AssignCsisGroup( const RawAddress& address, int group_id, bool create_group_if_non_existing, const bluetooth::Uuid& uuid) { - LOG_DEBUG("Device: %s, group_id: %d", ADDRESS_TO_LOGGABLE_CSTR(address), - group_id); + log::debug("Device: {}, group_id: {}", ADDRESS_TO_LOGGABLE_CSTR(address), + group_id); auto csis_group = FindCsisGroup(group_id); if (!csis_group) { if (create_group_if_non_existing) { /* Let's create a group */ - LOG_DEBUG(": Create a new group %d", group_id); + log::debug(": Create a new group {}", group_id); auto g = std::make_shared(group_id, uuid); csis_groups_.push_back(g); csis_group = FindCsisGroup(group_id); } else { - LOG_ERROR(": Missing group - that shall not happen"); + log::error(": Missing group - that shall not happen"); return nullptr; } } @@ -186,15 +191,14 @@ class CsisClientImpl : public CsisClient { void OnGroupAddedCb(const RawAddress& address, const bluetooth::Uuid& uuid, int group_id) { - LOG_DEBUG(" address: %s, uuid: %s, group_id: %d", - ADDRESS_TO_LOGGABLE_CSTR(address), uuid.ToString().c_str(), - group_id); + log::debug("address: {}, uuid: {}, group_id: {}", + ADDRESS_TO_LOGGABLE_CSTR(address), uuid.ToString(), group_id); AssignCsisGroup(address, group_id, true, uuid); } void OnGroupMemberAddedCb(const RawAddress& address, int group_id) { - LOG_DEBUG("%s, group_id: %d", ADDRESS_TO_LOGGABLE_CSTR(address), group_id); + log::debug("{}, group_id: {}", ADDRESS_TO_LOGGABLE_CSTR(address), group_id); AssignCsisGroup(address, group_id, false, Uuid::kEmpty); } @@ -204,7 +208,7 @@ class CsisClientImpl : public CsisClient { } void OnGroupMemberRemovedCb(const RawAddress& address, int group_id) { - LOG_DEBUG("%s, group_id: %d", ADDRESS_TO_LOGGABLE_CSTR(address), group_id); + log::debug("{}, group_id: {}", ADDRESS_TO_LOGGABLE_CSTR(address), group_id); auto device = FindDeviceByAddress(address); if (device) RemoveCsisDevice(device, group_id); @@ -217,13 +221,13 @@ class CsisClientImpl : public CsisClient { auto csis_group = FindCsisGroup(group_id); if (csis_group == nullptr) { - LOG_ERROR("the csis group (id: %d ) does not exist ", group_id); + log::error("the csis group (id: {} ) does not exist", group_id); return; } if (!csis_group->IsDeviceInTheGroup(device)) { - LOG_ERROR("the csis group (id: %d ) does contain the device: %s", - group_id, ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("the csis group (id: {} ) does contain the device: {}", + group_id, ADDRESS_TO_LOGGABLE_CSTR(address)); return; } @@ -231,20 +235,18 @@ class CsisClientImpl : public CsisClient { csis_group->SetUuid(uuid); } + int rank = bluetooth::csis::CSIS_RANK_INVALID; auto csis_instance = device->GetCsisInstanceByGroupId(group_id); - if (!csis_instance) { - LOG_ERROR(" device: %s, does not have the rank info for group (id: %d )", - ADDRESS_TO_LOGGABLE_CSTR(address), group_id); - return; + if (csis_instance) { + rank = csis_instance->GetRank(); } callbacks_->OnDeviceAvailable(device->addr, csis_group->GetGroupId(), - csis_group->GetDesiredSize(), - csis_instance->GetRank(), uuid); + csis_group->GetDesiredSize(), rank, uuid); } void Connect(const RawAddress& address) override { - LOG_DEBUG("%s ", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); auto device = FindDeviceByAddress(address); if (device == nullptr) { @@ -257,14 +259,12 @@ class CsisClientImpl : public CsisClient { } void Disconnect(const RawAddress& addr) override { - LOG_DEBUG("%s ", ADDRESS_TO_LOGGABLE_CSTR(addr)); - - btif_storage_set_csis_autoconnect(addr, false); + log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(addr)); auto device = FindDeviceByAddress(addr); if (device == nullptr) { - LOG_WARN("Device not connected to profile %s", - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::warn("Device not connected to profile {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); callbacks_->OnConnectionState(addr, ConnectionState::DISCONNECTED); return; } @@ -280,7 +280,7 @@ class CsisClientImpl : public CsisClient { } void RemoveDevice(const RawAddress& addr) override { - LOG_DEBUG("%s ", ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(addr)); auto device = FindDeviceByAddress(addr); if (!device) return; @@ -330,22 +330,22 @@ class CsisClientImpl : public CsisClient { uint16_t handle, void* data) { auto device = FindDeviceByConnId(conn_id); if (device == nullptr) { - LOG_ERROR(" Device not there for conn_id: 0x%04x", conn_id); + log::error("Device not there for conn_id: 0x{:04x}", conn_id); return; } int group_id = PTR_TO_UINT(data); auto csis_group = FindCsisGroup(group_id); if (csis_group == nullptr) { - LOG_ERROR(" There is no group: %d ", group_id); + log::error("There is no group: {}", group_id); return; } CsisLockState target_lock_state = csis_group->GetTargetLockState(); - LOG_DEBUG("Device %s, target lock: %d, status: 0x%02x", - ADDRESS_TO_LOGGABLE_CSTR(device->addr), (int)target_lock_state, - (int)status); + log::debug("Device {}, target lock: {}, status: 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr), (int)target_lock_state, + (int)status); if (target_lock_state == CsisLockState::CSIS_STATE_UNSET) return; if (status != GATT_SUCCESS && @@ -357,14 +357,14 @@ class CsisClientImpl : public CsisClient { } /* In case of GATT ERROR */ - LOG_ERROR("Incorrect write status=0x%02x", (int)(status)); + log::error("Incorrect write status=0x{:02x}", (int)(status)); /* Unlock previous devices */ HandleCsisLockProcedureError(csis_group, device); if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } return; @@ -376,7 +376,7 @@ class CsisClientImpl : public CsisClient { csis_instance->SetLockState(target_lock_state); if (csis_group->GetLockTransitionCnt() == 0) { - LOG_ERROR("Not expected lock state"); + log::error("Not expected lock state"); return; } @@ -421,9 +421,9 @@ class CsisClientImpl : public CsisClient { std::vector value = { (std::underlying_type::type)lock}; - LOG_INFO("%s, rank: %d, conn_id: 0x%04x, handle: 0x%04x", - ADDRESS_TO_LOGGABLE_CSTR(device->addr), csis_instance->GetRank(), - device->conn_id, csis_instance->svc_data.lock_handle.val_hdl); + log::info("{}, rank: {}, conn_id: 0x{:04x}, handle: 0x{:04x}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr), csis_instance->GetRank(), + device->conn_id, csis_instance->svc_data.lock_handle.val_hdl); BtaGattQueue::WriteCharacteristic( device->conn_id, csis_instance->svc_data.lock_handle.val_hdl, value, @@ -459,9 +459,9 @@ class CsisClientImpl : public CsisClient { void LockGroup(int group_id, bool lock, CsisLockCb cb) override { if (lock) { - LOG_DEBUG("Locking group: %d", group_id); + log::debug("Locking group: {}", group_id); } else { - LOG_DEBUG("Unlocking group: %d", group_id); + log::debug("Unlocking group: {}", group_id); } /* For now we try to lock only connected devices in the group @@ -470,7 +470,7 @@ class CsisClientImpl : public CsisClient { */ auto csis_group = FindCsisGroup(group_id); if (csis_group == nullptr) { - LOG_ERROR("Group not found: %d", group_id); + log::error("Group not found: {}", group_id); NotifyGroupStatus(group_id, false, CsisGroupLockStatus::FAILED_INVALID_GROUP, std::move(cb)); @@ -486,8 +486,8 @@ class CsisClientImpl : public CsisClient { if (csis_group->GetTargetLockState() != CsisLockState::CSIS_STATE_UNSET) { /* CSIS operation ongoing */ - LOG_DEBUG( - "Lock operation ongoing: group id: %d, target state %s", group_id, + log::debug( + "Lock operation ongoing: group id: {}, target state {}", group_id, (csis_group->GetTargetLockState() == CsisLockState::CSIS_STATE_LOCKED ? "lock" : "unlock")); @@ -498,7 +498,7 @@ class CsisClientImpl : public CsisClient { : CsisLockState::CSIS_STATE_UNLOCKED; if (csis_group->GetCurrentLockState() == new_lock_state) { - LOG_DEBUG("Nothing to do as requested lock is there"); + log::debug("Nothing to do as requested lock is there"); NotifyGroupStatus(group_id, lock, CsisGroupLockStatus::SUCCESS, std::move(cb)); return; @@ -506,7 +506,7 @@ class CsisClientImpl : public CsisClient { #if CSIP_UPPER_TESTER_FORCE_TO_SEND_LOCK == FALSE if (lock && !csis_group->IsAvailableForCsisLockOperation()) { - LOG_DEBUG("Group %d locked by other", group_id); + log::debug("Group {} locked by other", group_id); NotifyGroupStatus(group_id, false, CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER, std::move(cb)); @@ -551,7 +551,7 @@ class CsisClientImpl : public CsisClient { int GetDesiredSize(int group_id) override { auto csis_group = FindCsisGroup(group_id); if (!csis_group) { - LOG_INFO("Unknown group %d", group_id); + log::info("Unknown group {}", group_id); return -1; } @@ -561,18 +561,18 @@ class CsisClientImpl : public CsisClient { bool SerializeSets(const RawAddress& addr, std::vector& out) const { auto device = FindDeviceByAddress(addr); if (device == nullptr) { - LOG_WARN("Skipping unknown device addr= %s", - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::warn("Skipping unknown device addr= {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); return false; } if (device->GetNumberOfCsisInstances() == 0) { - LOG_WARN("No CSIS instances for addr= %s", - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::warn("No CSIS instances for addr= {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); return false; } - LOG_DEBUG(": device= %s", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::debug(": device= {}", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); auto num_sets = device->GetNumberOfCsisInstances(); if ((num_sets == 0) || (num_sets > std::numeric_limits::max())) @@ -591,7 +591,7 @@ class CsisClientImpl : public CsisClient { auto gid = csis_inst->GetGroupId(); auto csis_group = FindCsisGroup(gid); if (csis_group == nullptr) { - LOG_ERROR("SerializeSets: No matching group found!"); + log::error("SerializeSets: No matching group found!"); return; } @@ -623,7 +623,7 @@ class CsisClientImpl : public CsisClient { if (in.size() < CSIS_STORAGE_HEADER_SZ + (num_sets * CSIS_STORAGE_ENTRY_SZ)) { - LOG_ERROR("Invalid persistent storage data"); + log::error("Invalid persistent storage data"); return group_rank_map; } @@ -656,17 +656,26 @@ class CsisClientImpl : public CsisClient { return group_rank_map; } - void AddFromStorage(const RawAddress& addr, const std::vector& in, - bool autoconnect) { + void StartOpportunisticConnect(const RawAddress& address) { + /* Oportunistic works only for direct connect, + * but in fact this is background connect + */ + log::info(": {}", ADDRESS_TO_LOGGABLE_CSTR(address)); + BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, true); + } + + void AddFromStorage(const RawAddress& addr, const std::vector& in) { auto group_rank_map = DeserializeSets(addr, in); + log::debug("{}, number of groups {}", ADDRESS_TO_LOGGABLE_CSTR(addr), + static_cast(csis_groups_.size())); + auto device = FindDeviceByAddress(addr); if (device == nullptr) { device = std::make_shared(addr, false); devices_.push_back(device); } - bool is_le_audio_device = false; for (const auto& csis_group : csis_groups_) { if (!csis_group->IsDeviceInTheGroup(device)) continue; @@ -680,21 +689,11 @@ class CsisClientImpl : public CsisClient { callbacks_->OnDeviceAvailable(device->addr, group_id, csis_group->GetDesiredSize(), rank, csis_group->GetUuid()); - - if (csis_group->GetUuid() == - bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)) { - is_le_audio_device = true; - } } } - /* For now, if this is LeAudio device, CSIP is opportunistic profile. */ - bool is_opportunistic = is_le_audio_device; - - if (autoconnect) { - BTA_GATTC_Open(gatt_if_, addr, BTM_BLE_BKG_CONNECT_ALLOW_LIST, - is_opportunistic); - } + /* For bonded devices, CSIP can be always opportunistic service */ + StartOpportunisticConnect(addr); } void CleanUp() { @@ -783,7 +782,7 @@ class CsisClientImpl : public CsisClient { if (!csis_group) { /* This could happen when remove device is called when bonding is * removed */ - LOG_DEBUG("group not found %d", group_id); + log::debug("group not found {}", group_id); return; } @@ -844,7 +843,7 @@ class CsisClientImpl : public CsisClient { /* Handle encryption */ void OnEncrypted(std::shared_ptr& device) { - LOG_DEBUG("%s ", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); if (device->is_gatt_service_valid) { NotifyCsisDeviceValidAndStoreIfNeeded(device); @@ -866,7 +865,7 @@ class CsisClientImpl : public CsisClient { int group_id = csis_group->GetGroupId(); auto csis_instance = device->GetCsisInstanceByGroupId(group_id); - LOG_DEBUG("group id %d", group_id); + log::debug("group id {}", group_id); if (!csis_instance) { /* This can happen when some other user added device to group in the @@ -875,7 +874,7 @@ class CsisClientImpl : public CsisClient { * context. We will endup in having device in 2 groups. One in generic * context with valid csis_instance, and one in CAP context without csis * instance */ - LOG_INFO("csis_instance does not exist for group %d", group_id); + log::info("csis_instance does not exist for group {}", group_id); continue; } @@ -892,57 +891,60 @@ class CsisClientImpl : public CsisClient { if (notify_connected) { callbacks_->OnConnectionState(device->addr, ConnectionState::CONNECTED); - LOG_DEBUG("group_id %d", group_id_to_discover); + log::debug("group_id {}", group_id_to_discover); if (group_id_to_discover != bluetooth::groups::kGroupUnknown) { /* Start active search for the other device * b/281120322 */ auto g = FindCsisGroup(group_id_to_discover); - LOG_DEBUG("Group size %d target size %d", g->GetDesiredSize(), - g->GetCurrentSize()); - if (g->GetDesiredSize() > g->GetCurrentSize()) { + log::debug("Group size {} target size {}", g->GetDesiredSize(), + g->GetCurrentSize()); + + auto dev_waiting_for_bonding_cnt = + GetNumOfKnownExpectedDevicesWaitingForBonding(g->GetGroupId()); + log::debug("Group size: {}, desired size: {}, waiting for bonding: {}", + g->GetCurrentSize(), g->GetDesiredSize(), + dev_waiting_for_bonding_cnt); + + if (g->GetDesiredSize() > + g->GetCurrentSize() + dev_waiting_for_bonding_cnt) { CsisActiveDiscovery(g); } } } - - if (device->first_connection) { - device->first_connection = false; - btif_storage_set_csis_autoconnect(device->addr, true); - } } void OnGattWriteCcc(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, void* user_data) { auto device = FindDeviceByConnId(conn_id); if (device == nullptr) { - LOG_INFO("unknown conn_id= 0x%04x", conn_id); + log::info("unknown conn_id= 0x{:04x}", conn_id); BtaGattQueue::Clean(conn_id); return; } if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); return; } if (status == GATT_SUCCESS) { - LOG_INFO("Successfully registered on ccc: 0x%04x, device: %s", handle, - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Successfully registered on ccc: 0x{:04x}, device: {}", handle, + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); return; } - LOG_ERROR( - "Failed to register for indications: 0x%04x, device: %s, status: " - "0x%02x", + log::error( + "Failed to register for indications: 0x{:04x}, device: {}, status: " + "0x{:02x}", handle, ADDRESS_TO_LOGGABLE_CSTR(device->addr), status); auto val_handle = device->FindValueHandleByCccHandle(handle); if (!val_handle) { - LOG_ERROR("Unknown ccc handle: 0x%04x, device: %s", handle, - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::error("Unknown ccc handle: 0x{:04x}, device: {}", handle, + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); return; } @@ -955,14 +957,14 @@ class CsisClientImpl : public CsisClient { const uint8_t* value) { auto device = FindDeviceByConnId(conn_id); if (device == nullptr) { - LOG_WARN("Skipping unknown device, conn_id= 0x%04x", conn_id); + log::warn("Skipping unknown device, conn_id= 0x{:04x}", conn_id); return; } auto csis_instance = device->GetCsisInstanceByOwningHandle(handle); if (csis_instance == nullptr) { - LOG_ERROR("unknown notification handle: 0x%04x for conn_id: 0x%04x", - handle, conn_id); + log::error("unknown notification handle: 0x{:04x} for conn_id: 0x{:04x}", + handle, conn_id); return; } @@ -973,8 +975,8 @@ class CsisClientImpl : public CsisClient { } else if (handle == csis_instance->svc_data.size_handle.val_hdl) { OnCsisSizeValueUpdate(conn_id, GATT_SUCCESS, handle, len, value); } else { - LOG_WARN("unknown notification handle 0x%04x for conn_id= 0x%04x ", - handle, conn_id); + log::warn("unknown notification handle 0x{:04x} for conn_id= 0x{:04x}", + handle, conn_id); } } @@ -993,8 +995,8 @@ class CsisClientImpl : public CsisClient { void CsisLockCompleted(std::shared_ptr& csis_group, bool lock, CsisGroupLockStatus status) { - LOG_DEBUG("group id: %d, target state %s", csis_group->GetGroupId(), - (lock ? "lock" : "unlock")); + log::debug("group id: {}, target state {}", csis_group->GetGroupId(), + (lock ? "lock" : "unlock")); NotifyGroupStatus(csis_group->GetGroupId(), lock, status, std::move(csis_group->GetLockCb())); @@ -1005,14 +1007,14 @@ class CsisClientImpl : public CsisClient { std::shared_ptr& csis_instance, uint16_t len, const uint8_t* value) { if (len != 1) { - LOG_ERROR("invalid notification len: %d", len); + log::error("invalid notification len: {}", len); return; } CsisLockState new_lock = (CsisLockState)(value[0]); - LOG_DEBUG("New lock state: %d, device rank: %d", - static_cast(new_lock), csis_instance->GetRank()); + log::debug("New lock state: {}, device rank: {}", + static_cast(new_lock), csis_instance->GetRank()); csis_instance->SetLockState(new_lock); @@ -1061,40 +1063,41 @@ class CsisClientImpl : public CsisClient { auto device = FindDeviceByConnId(conn_id); if (device == nullptr) { - LOG_WARN("Skipping unknown device, conn_id=0x%04x", conn_id); + log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id); return; } - LOG_DEBUG("%s, status: 0x%02x", ADDRESS_TO_LOGGABLE_CSTR(device->addr), - status); + log::debug("{}, status: 0x{:02x}", ADDRESS_TO_LOGGABLE_CSTR(device->addr), + status); if (status != GATT_SUCCESS) { if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Could not read characteristic at handle=0x%04x", handle); + log::error("Could not read characteristic at handle=0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); } return; } if (len != 1) { - LOG_ERROR("Invalid size value length=%d at handle= 0x%04x", len, handle); + log::error("Invalid size value length={} at handle= 0x{:04x}", len, + handle); BTA_GATTC_Close(device->conn_id); return; } auto csis_instance = device->GetCsisInstanceByOwningHandle(handle); if (csis_instance == nullptr) { - LOG_ERROR("Unknown csis instance"); + log::error("Unknown csis instance"); BTA_GATTC_Close(device->conn_id); return; } auto csis_group = FindCsisGroup(csis_instance->GetGroupId()); if (!csis_group) { - LOG_ERROR("Unknown group id yet"); + log::error("Unknown group id yet"); return; } @@ -1109,34 +1112,35 @@ class CsisClientImpl : public CsisClient { bool notify_valid_services = false) { auto device = FindDeviceByConnId(conn_id); if (device == nullptr) { - LOG_WARN("Skipping unknown device, conn_id=0x%04x", conn_id); + log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id); return; } - LOG_INFO("%s, status 0x%02x", ADDRESS_TO_LOGGABLE_CSTR(device->addr), - status); + log::info("{}, status 0x{:02x}", ADDRESS_TO_LOGGABLE_CSTR(device->addr), + status); if (status != GATT_SUCCESS) { if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Could not read characteristic at handle=0x%04x", handle); + log::error("Could not read characteristic at handle=0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); } return; } if (len != 1) { - LOG_ERROR("Invalid lock value length=%d, at handle=0x%04x", len, handle); + log::error("Invalid lock value length={}, at handle=0x{:04x}", len, + handle); BTA_GATTC_Close(device->conn_id); return; } auto csis_instance = device->GetCsisInstanceByOwningHandle(handle); if (csis_instance == nullptr) { - LOG_ERROR("Unknown csis instance"); + log::error("Unknown csis instance"); BTA_GATTC_Close(device->conn_id); return; } @@ -1150,34 +1154,34 @@ class CsisClientImpl : public CsisClient { bool notify_valid_services) { auto device = FindDeviceByConnId(conn_id); if (device == nullptr) { - LOG_WARN("Skipping unknown device, conn_id= 0x%04x", conn_id); + log::warn("Skipping unknown device, conn_id= 0x{:04x}", conn_id); return; } - LOG_DEBUG("%s, status: 0x%02x, rank: %d", - ADDRESS_TO_LOGGABLE_CSTR(device->addr), status, value[0]); + log::debug("{}, status: 0x{:02x}, rank: {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr), status, value[0]); if (status != GATT_SUCCESS) { if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Could not read characteristic at handle=0x%04x", handle); + log::error("Could not read characteristic at handle=0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); } return; } if (len != 1) { - LOG_ERROR("Invalid rank value length= %d, at handle= 0x%04x", len, - handle); + log::error("Invalid rank value length= {}, at handle= 0x{:04x}", len, + handle); BTA_GATTC_Close(device->conn_id); return; } auto csis_instance = device->GetCsisInstanceByOwningHandle(handle); if (csis_instance == nullptr) { - LOG_ERROR("Unknown csis instance handle 0x%04x", handle); + log::error("Unknown csis instance handle 0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); return; } @@ -1185,7 +1189,7 @@ class CsisClientImpl : public CsisClient { csis_instance->SetRank((value[0])); auto csis_group = FindCsisGroup(csis_instance->GetGroupId()); if (!csis_group) { - LOG_ERROR("Unknown group id yet"); + log::error("Unknown group id yet"); return; } @@ -1195,10 +1199,10 @@ class CsisClientImpl : public CsisClient { } void OnCsisObserveCompleted(void) { - LOG_INFO("Group_id: %d", discovering_group_); + log::info("Group_id: {}", discovering_group_); if (discovering_group_ == bluetooth::groups::kGroupUnknown) { - LOG_ERROR("No ongoing CSIS discovery - disable scan"); + log::error("No ongoing CSIS discovery - disable scan"); return; } @@ -1206,7 +1210,7 @@ class CsisClientImpl : public CsisClient { discovering_group_ = bluetooth::groups::kGroupUnknown; if (!csis_group) { - LOG_WARN("Group_id %d is not existing", discovering_group_); + log::warn("Group_id {} is not existing", discovering_group_); discovering_group_ = bluetooth::groups::kGroupUnknown; return; } @@ -1228,14 +1232,14 @@ class CsisClientImpl : public CsisClient { Octet16& sirk) { auto pltk = BTM_BleGetPeerLTK(address); if (!pltk.has_value()) { - LOG_ERROR("No security for %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("No security for {}", ADDRESS_TO_LOGGABLE_CSTR(address)); return false; } #ifdef CSIS_DEBUG auto irk = BTM_BleGetPeerIRK(address); - LOG_INFO("LTK %s", (base::HexEncode(*pltk.data(), 16)).c_str()); - LOG_INFO("IRK %s", base::HexEncode(*irk.data(), 16).c_str()); + log::info("LTK {}", (base::HexEncode(*pltk.data(), 16))); + log::info("IRK {}", base::HexEncode(*irk.data(), 16)); #endif /* Calculate salt CSIS d1.0r05 4.3 */ @@ -1249,15 +1253,15 @@ class CsisClientImpl : public CsisClient { msg1.size()); #ifdef CSIS_DEBUG - LOG_INFO("s1 (le) %s", base::HexEncode(s1.data(), 16).c_str()); + log::info("s1 (le) {}", base::HexEncode(s1.data(), 16)); /* Create K = LTK */ - LOG_INFO("K (le) %s", base::HexEncode(*pltk.data(), 16).c_str()); + log::info("K (le) {}", base::HexEncode(*pltk.data(), 16)); #endif Octet16 T = crypto_toolbox::aes_cmac(s1, *pltk); #ifdef CSIS_DEBUG - LOG_INFO("T (le) %s", base::HexEncode(T.data(), 16).c_str()); + log::info("T (le) {}", base::HexEncode(T.data(), 16)); #endif std::string msg2 = "csis"; @@ -1266,13 +1270,13 @@ class CsisClientImpl : public CsisClient { Octet16 k1 = crypto_toolbox::aes_cmac(T, (uint8_t*)(msg2.c_str()), msg2.size()); #ifdef CSIS_DEBUG - LOG_INFO("K1 (le) %s", base::HexEncode(k1.data(), 16).c_str()); + log::info("K1 (le) {}", base::HexEncode(k1.data(), 16)); #endif for (int i = 0; i < 16; i++) sirk[i] = encrypted_sirk[i] ^ k1[i]; #ifdef CSIS_DEBUG - LOG_INFO("SIRK (le)%s", base::HexEncode(sirk.data(), 16).c_str()); + log::info("SIRK (le){}", base::HexEncode(sirk.data(), 16)); #endif return true; @@ -1302,6 +1306,14 @@ class CsisClientImpl : public CsisClient { return std::move(devices); } + int GetNumOfKnownExpectedDevicesWaitingForBonding(int group_id) { + return std::count_if( + devices_.begin(), devices_.end(), [group_id](const auto& device) { + return device->GetExpectedGroupIdMember() == group_id && + !device->GetCsisInstanceByGroupId(group_id); + }); + } + void CacheAndAdvertiseExpectedMember(const RawAddress& address, int group_id) { auto device = FindDeviceByAddress(address); @@ -1322,8 +1334,8 @@ class CsisClientImpl : public CsisClient { void OnActiveScanResult(const tBTA_DM_INQ_RES* result) { auto csis_device = FindDeviceByAddress(result->bd_addr); if (csis_device) { - LOG_DEBUG("Drop same device .. %s", - ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr)); + log::debug("Drop same device .. {}", + ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr)); return; } @@ -1331,10 +1343,10 @@ class CsisClientImpl : public CsisClient { * be a case for dual mode devices where */ if (BTM_BleIsLinkKeyKnown(result->bd_addr)) { - LOG_VERBOSE("Device %s already bonded. Identity address: %s", - ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr), - ADDRESS_TO_LOGGABLE_CSTR( - *BTM_BleGetIdentityAddress(result->bd_addr))); + log::verbose("Device {} already bonded. Identity address: {}", + ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr), + ADDRESS_TO_LOGGABLE_CSTR( + *BTM_BleGetIdentityAddress(result->bd_addr))); return; } @@ -1344,14 +1356,14 @@ class CsisClientImpl : public CsisClient { /* Notify only the actively searched group */ auto csis_group = FindCsisGroup(discovering_group_); if (csis_group == nullptr) { - LOG_ERROR("No ongoing CSIS discovery - disable scan"); + log::error("No ongoing CSIS discovery - disable scan"); CsisActiveObserverSet(false); return; } if (csis_group->GetDesiredSize() > 0 && (csis_group->GetDesiredSize() == csis_group->GetCurrentSize())) { - LOG_WARN("Group is already complete"); + log::warn("Group is already complete"); return; } @@ -1360,8 +1372,8 @@ class CsisClientImpl : public CsisClient { return csis_group->IsRsiMatching(rsi); }); if (discovered_group_rsi != all_rsi.cend()) { - LOG_DEBUG("Found set member %s", - ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr)); + log::debug("Found set member {}", + ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr)); CacheAndAdvertiseExpectedMember(result->bd_addr, csis_group->GetGroupId()); @@ -1378,8 +1390,8 @@ class CsisClientImpl : public CsisClient { bool is_ad_type_filter_supported = bluetooth::shim::is_ad_type_filter_supported(); - LOG_INFO("enable: %d, is_ad_type_filter_supported: %d", enable, - is_ad_type_filter_supported); + log::info("enable: {}, is_ad_type_filter_supported: {}", enable, + is_ad_type_filter_supported); if (is_ad_type_filter_supported) { bluetooth::shim::set_ad_type_rsi_filter(enable); @@ -1389,7 +1401,7 @@ class CsisClientImpl : public CsisClient { } void CsisActiveObserverSet(bool enable) { - LOG_INFO("Group_id %d: enable: %d", discovering_group_, enable); + log::info("Group_id {}: enable: {}", discovering_group_, enable); csis_ad_type_filter_set(enable); BTA_DmBleCsisObserve(enable, @@ -1402,8 +1414,8 @@ class CsisClientImpl : public CsisClient { if (event == BTA_DM_INQ_CMPL_EVT) { power_telemetry::GetInstance().LogBleScan( static_cast(p_data->inq_cmpl.num_resps)); - LOG_INFO("BLE observe complete. Num Resp: %d", - p_data->inq_cmpl.num_resps); + log::info("BLE observe complete. Num Resp: {}", + p_data->inq_cmpl.num_resps); csis_ad_type_filter_set(false); instance->OnCsisObserveCompleted(); instance->CsisObserverSetBackground(true); @@ -1411,7 +1423,7 @@ class CsisClientImpl : public CsisClient { } if (event != BTA_DM_INQ_RES_EVT) { - LOG_WARN("Unknown event: 0x%02x", event); + log::warn("Unknown event: 0x{:02x}", event); return; } @@ -1441,8 +1453,8 @@ class CsisClientImpl : public CsisClient { continue; } - LOG_INFO("Device %s from inquiry cache match to group id %d", - ADDRESS_TO_LOGGABLE_CSTR(address), csis_group->GetGroupId()); + log::info("Device {} from inquiry cache match to group id {}", + ADDRESS_TO_LOGGABLE_CSTR(address), csis_group->GetGroupId()); callbacks_->OnSetMemberAvailable(address, csis_group->GetGroupId()); break; } @@ -1455,9 +1467,9 @@ class CsisClientImpl : public CsisClient { if ((csis_group->GetDiscoveryState() != CsisDiscoveryState::CSIS_DISCOVERY_IDLE)) { - LOG_ERROR("Incorrect ase group: %d, state 0x%02x", - csis_group->GetGroupId(), - static_cast(csis_group->GetDiscoveryState())); + log::error("Incorrect ase group: {}, state 0x{:02x}", + csis_group->GetGroupId(), + static_cast(csis_group->GetDiscoveryState())); return; } @@ -1472,8 +1484,8 @@ class CsisClientImpl : public CsisClient { auto csis_device = FindDeviceByAddress(result->bd_addr); if (csis_device) { - LOG_DEBUG("Drop known device %s", - ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr)); + log::debug("Drop known device {}", + ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr)); return; } @@ -1481,10 +1493,10 @@ class CsisClientImpl : public CsisClient { * be a case for dual mode devices where */ if (BTM_BleIsLinkKeyKnown(result->bd_addr)) { - LOG_VERBOSE("Device %s already bonded. Identity address: %s", - ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr), - ADDRESS_TO_LOGGABLE_CSTR( - *BTM_BleGetIdentityAddress(result->bd_addr))); + log::verbose("Device {} already bonded. Identity address: {}", + ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr), + ADDRESS_TO_LOGGABLE_CSTR( + *BTM_BleGetIdentityAddress(result->bd_addr))); return; } @@ -1495,12 +1507,12 @@ class CsisClientImpl : public CsisClient { for (auto& group : csis_groups_) { for (auto& rsi : all_rsi) { if (group->IsRsiMatching(rsi)) { - LOG_INFO("Device %s match to group id %d", - ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr), - group->GetGroupId()); + log::info("Device {} match to group id {}", + ADDRESS_TO_LOGGABLE_CSTR(result->bd_addr), + group->GetGroupId()); if (group->GetDesiredSize() > 0 && (group->GetCurrentSize() == group->GetDesiredSize())) { - LOG_WARN( + log::warn( "Group is already completed. Some other device use same SIRK"); break; } @@ -1514,7 +1526,7 @@ class CsisClientImpl : public CsisClient { } void CsisObserverSetBackground(bool enable) { - LOG_DEBUG("CSIS Discovery background: %d", enable); + log::debug("CSIS Discovery background: {}", enable); BTA_DmBleCsisObserve(enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) { @@ -1526,13 +1538,13 @@ class CsisClientImpl : public CsisClient { if (event == BTA_DM_INQ_CMPL_EVT) { power_telemetry::GetInstance().LogBleScan( static_cast(p_data->inq_cmpl.num_resps)); - LOG_VERBOSE("BLE observe complete. Num Resp: %d", - p_data->inq_cmpl.num_resps); + log::verbose("BLE observe complete. Num Resp: {}", + p_data->inq_cmpl.num_resps); return; } if (event != BTA_DM_INQ_RES_EVT) { - LOG_WARN("Unknown event: 0x%02x", event); + log::warn("Unknown event: 0x{:02x}", event); return; } @@ -1546,12 +1558,12 @@ class CsisClientImpl : public CsisClient { bool notify_valid_services = true) { auto device = FindDeviceByConnId(conn_id); if (device == nullptr) { - LOG_WARN("Skipping unknown device, conn_id=0x%04x", conn_id); + log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id); return; } - LOG_DEBUG("%s, status: 0x%02x", ADDRESS_TO_LOGGABLE_CSTR(device->addr), - status); + log::debug("{}, status: 0x{:02x}", ADDRESS_TO_LOGGABLE_CSTR(device->addr), + status); if (status != GATT_SUCCESS) { /* TODO handle error codes: @@ -1559,37 +1571,38 @@ class CsisClientImpl : public CsisClient { * kCsisErrorCodeLockOobSirkOnly */ if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Could not read characteristic at handle=0x%04x", handle); + log::error("Could not read characteristic at handle=0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); } return; } if (len != bluetooth::csis::kCsisSirkCharLen) { - LOG_ERROR("Invalid sirk value length= %d at handle= 0x%04x", len, handle); + log::error("Invalid sirk value length= {} at handle= 0x{:04x}", len, + handle); BTA_GATTC_Close(device->conn_id); return; } auto csis_instance = device->GetCsisInstanceByOwningHandle(handle); if (csis_instance == nullptr) { - LOG_ERROR("Unknown csis instance: handle 0x%04x", handle); + log::error("Unknown csis instance: handle 0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); return; } uint8_t sirk_type = value[0]; - LOG_INFO("SIRK Type: 0x%02x", sirk_type); + log::info("SIRK Type: 0x{:02x}", sirk_type); /* Verify if sirk is not all zeros */ Octet16 zero{}; if (memcmp(zero.data(), value + 1, 16) == 0) { - LOG_ERROR("Received invalid zero SIRK conn_id: 0x%02x. Disconnecting ", - device->conn_id); + log::error("Received invalid zero SIRK conn_id: 0x{:02x}. Disconnecting", + device->conn_id); BTA_GATTC_Close(device->conn_id); return; } @@ -1646,13 +1659,12 @@ class CsisClientImpl : public CsisClient { if (notify_valid_services) NotifyCsisDeviceValidAndStoreIfNeeded(device); #ifdef CSIS_DEBUG - LOG_INFO("SIRK %s, address: %s", - base::HexEncode(received_sirk.data(), 16).c_str(), - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("SIRK {}, address: {}", base::HexEncode(received_sirk.data(), 16), + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); #endif - LOG_VERBOSE("Expected group size %d, actual group Size: %d", - csis_group->GetDesiredSize(), csis_group->GetCurrentSize()); + log::verbose("Expected group size {}, actual group Size: {}", + csis_group->GetDesiredSize(), csis_group->GetCurrentSize()); if (csis_group->GetDesiredSize() == csis_group->GetCurrentSize()) { auto iter = devices_.cbegin(); @@ -1687,7 +1699,7 @@ class CsisClientImpl : public CsisClient { } void DoDisconnectCleanUp(std::shared_ptr device) { - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); DeregisterNotifications(device); @@ -1701,9 +1713,8 @@ class CsisClientImpl : public CsisClient { const gatt::Service* service, const bluetooth::Uuid& context_uuid, bool is_last_instance) { - LOG_DEBUG("service handle: 0x%04x, end handle: 0x%04x, uuid: %s", - service->handle, service->end_handle, - context_uuid.ToString().c_str()); + log::debug("service handle: 0x{:04x}, end handle: 0x{:04x}, uuid: {}", + service->handle, service->end_handle, context_uuid.ToString()); auto csis_inst = std::make_shared( (uint16_t)service->handle, (uint16_t)service->end_handle, context_uuid); @@ -1722,7 +1733,7 @@ class CsisClientImpl : public CsisClient { uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle); if (ccc_handle == GAP_INVALID_HANDLE) { - LOG_ERROR("no HAS Active Preset CCC descriptor found!"); + log::error("no HAS Active Preset CCC descriptor found!"); device->RemoveCsisInstance(group_id); return false; } @@ -1732,17 +1743,18 @@ class CsisClientImpl : public CsisClient { SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle); - LOG_DEBUG( - "Lock UUID found handle: 0x%04x, ccc handle: 0x%04x, device: %s", + log::debug( + "Lock UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: " + "{}", csis_inst->svc_data.lock_handle.val_hdl, csis_inst->svc_data.lock_handle.ccc_hdl, ADDRESS_TO_LOGGABLE_CSTR(device->addr)); } else if (charac.uuid == kCsisRankUuid) { csis_inst->svc_data.rank_handle = charac.value_handle; - LOG_DEBUG("Rank UUID found handle: 0x%04x, device: %s", - csis_inst->svc_data.rank_handle, - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::debug("Rank UUID found handle: 0x{:04x}, device: {}", + csis_inst->svc_data.rank_handle, + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); } else if (charac.uuid == kCsisSirkUuid) { /* Find the optional CCC descriptor */ uint16_t ccc_handle = @@ -1754,8 +1766,9 @@ class CsisClientImpl : public CsisClient { SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle); - LOG_DEBUG( - "SIRK UUID found handle: 0x%04x, ccc handle: 0x%04x, device: %s", + log::debug( + "SIRK UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: " + "{}", csis_inst->svc_data.sirk_handle.val_hdl, csis_inst->svc_data.sirk_handle.ccc_hdl, ADDRESS_TO_LOGGABLE_CSTR(device->addr)); @@ -1770,8 +1783,9 @@ class CsisClientImpl : public CsisClient { SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle); - LOG_DEBUG( - "Size UUID found handle: 0x%04x, ccc handle: 0x%04x, device: %s", + log::debug( + "Size UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: " + "{}", csis_inst->svc_data.size_handle.val_hdl, csis_inst->svc_data.size_handle.ccc_hdl, ADDRESS_TO_LOGGABLE_CSTR(device->addr)); @@ -1783,7 +1797,7 @@ class CsisClientImpl : public CsisClient { */ if (csis_inst->svc_data.sirk_handle.val_hdl == GAP_INVALID_HANDLE) { /* We have some characteristics but all dependencies are not satisfied */ - LOG_ERROR("Service has a broken structure."); + log::error("Service has a broken structure."); device->RemoveCsisInstance(group_id); return false; } @@ -1863,7 +1877,7 @@ class CsisClientImpl : public CsisClient { /* These are all generic GATT event handlers calling HAS specific code. */ void GattcCallback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { - LOG_INFO("event = 0x%02x", event); + log::info("event = 0x{:02x}", event); /* This is in case Csis CleanUp is already done * while GATT is still up and could send events @@ -1914,29 +1928,29 @@ class CsisClientImpl : public CsisClient { } void OnGattConnected(const tBTA_GATTC_OPEN& evt) { - LOG_INFO("%s, conn_id=0x%04x, transport=%s, status=%s(0x%02x)", - ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda), evt.conn_id, - bt_transport_text(evt.transport).c_str(), - gatt_status_text(evt.status).c_str(), evt.status); + log::info("{}, conn_id=0x{:04x}, transport={}, status={}(0x{:02x})", + ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda), evt.conn_id, + bt_transport_text(evt.transport), gatt_status_text(evt.status), + evt.status); if (evt.transport != BT_TRANSPORT_LE) { - LOG_WARN("Only LE connection is allowed (transport %s)", - bt_transport_text(evt.transport).c_str()); + log::warn("Only LE connection is allowed (transport {})", + bt_transport_text(evt.transport)); BTA_GATTC_Close(evt.conn_id); return; } auto device = FindDeviceByAddress(evt.remote_bda); if (device == nullptr) { - LOG_DEBUG("Skipping unknown device, address= %s", - ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda)); + log::debug("Skipping unknown device, address= {}", + ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda)); BTA_GATTC_Close(evt.conn_id); return; } if (evt.status != GATT_SUCCESS) { - LOG_ERROR("Failed to connect to server device %s", - ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda)); + log::error("Failed to connect to server device {}", + ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda)); if (device->connecting_actively) callbacks_->OnConnectionState(evt.remote_bda, ConnectionState::DISCONNECTED); @@ -1964,12 +1978,12 @@ class CsisClientImpl : public CsisClient { int result = BTM_SetEncryption(device->addr, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT); - LOG_INFO("Encryption required for %s. Request result: 0x%02x", - ADDRESS_TO_LOGGABLE_CSTR(device->addr), result); + log::info("Encryption required for {}. Request result: 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr), result); if (result == BTM_ERR_KEY_MISSING) { - LOG_ERROR("Link key unknown for %s, disconnect profile", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::error("Link key unknown for {}, disconnect profile", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); BTA_GATTC_Close(device->conn_id); } } @@ -1977,12 +1991,12 @@ class CsisClientImpl : public CsisClient { void OnGattDisconnected(const tBTA_GATTC_CLOSE& evt) { auto device = FindDeviceByAddress(evt.remote_bda); if (device == nullptr) { - LOG_WARN("Skipping unknown device disconnect, conn_id= 0x%04x", - evt.conn_id); + log::warn("Skipping unknown device disconnect, conn_id= 0x{:04x}", + evt.conn_id); return; } - LOG_DEBUG("device=%s", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::debug("device={}", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); callbacks_->OnConnectionState(evt.remote_bda, ConnectionState::DISCONNECTED); @@ -2011,13 +2025,13 @@ class CsisClientImpl : public CsisClient { auto device = FindDeviceByConnId(evt.conn_id); if (device == nullptr) { - LOG_WARN("Skipping unknown device, conn_id= 0x%4x", evt.conn_id); + log::warn("Skipping unknown device, conn_id= 0x{:4x}", evt.conn_id); return; } /* verify encryption enabled */ if (!BTM_IsEncrypted(device->addr, BT_TRANSPORT_LE)) { - LOG_WARN("Device not yet bonded - waiting for encryption"); + log::warn("Device not yet bonded - waiting for encryption"); return; } @@ -2025,7 +2039,7 @@ class CsisClientImpl : public CsisClient { * else?) */ if (!device->is_gatt_service_valid) { if (evt.status != GATT_SUCCESS) { - LOG_ERROR("Service discovery failed"); + log::error("Service discovery failed"); BTA_GATTC_Close(device->conn_id); DoDisconnectCleanUp(device); return; @@ -2047,7 +2061,7 @@ class CsisClientImpl : public CsisClient { } if (all_csis_start_handles.size() == 0) { - LOG_DEBUG("No Csis instances found"); + log::debug("No Csis instances found"); BTA_GATTC_Close(device->conn_id); RemoveCsisDevice(device, bluetooth::groups::kGroupUnknown); return; @@ -2078,8 +2092,8 @@ class CsisClientImpl : public CsisClient { * As per spec, there can be only one service like this. */ if (all_csis_start_handles.size()) { - LOG_DEBUG("there is %d primary services without a context", - static_cast(all_csis_start_handles.size())); + log::debug("there is {} primary services without a context", + static_cast(all_csis_start_handles.size())); auto csis_svrc = BTA_GATTC_GetOwningService(device->conn_id, all_csis_start_handles[0]); instance->OnCsisServiceFound( @@ -2099,23 +2113,24 @@ class CsisClientImpl : public CsisClient { void OnGattNotification(const tBTA_GATTC_NOTIFY& evt) { /* Reject invalid lengths and indications as they are not supported */ if (!evt.is_notify || evt.len > GATT_MAX_ATTR_LEN) { - LOG_ERROR(": rejected BTA_GATTC_NOTIF_EVT. is_notify = %d, len= %d", - evt.is_notify, evt.len); + log::error(": rejected BTA_GATTC_NOTIF_EVT. is_notify = {}, len= {}", + evt.is_notify, evt.len); } OnCsisNotification(evt.conn_id, evt.handle, evt.len, evt.value); } void OnLeEncryptionComplete(const RawAddress& address, uint8_t status) { - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); auto device = FindDeviceByAddress(address); if (device == nullptr) { - LOG_WARN("Skipping unknown device %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } if (status != BTM_SUCCESS) { - LOG_ERROR("encryption failed. status: 0x%02x", status); + log::error("encryption failed. status: 0x{:02x}", status); BTA_GATTC_Close(device->conn_id); return; @@ -2124,22 +2139,20 @@ class CsisClientImpl : public CsisClient { if (device->is_gatt_service_valid) { instance->OnEncrypted(device); } else { - device->first_connection = true; BTA_GATTC_ServiceSearchRequest(device->conn_id, &kCsisServiceUuid); } } void ClearDeviceInformationAndStartSearch( std::shared_ptr device) { - LOG_INFO("%s ", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); if (device->is_gatt_service_valid == false) { - LOG_DEBUG("Device database already invalidated."); + log::debug("Device database already invalidated."); return; } /* Invalidate service discovery results */ BtaGattQueue::Clean(device->conn_id); - device->first_connection = true; DeregisterNotifications(device); device->ClearSvcData(); BTA_GATTC_ServiceSearchRequest(device->conn_id, &kCsisServiceUuid); @@ -2148,22 +2161,24 @@ class CsisClientImpl : public CsisClient { void OnGattServiceChangeEvent(const RawAddress& address) { auto device = FindDeviceByAddress(address); if (!device) { - LOG_WARN("Skipping unknown device %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); ClearDeviceInformationAndStartSearch(device); } void OnGattServiceDiscoveryDoneEvent(const RawAddress& address) { auto device = FindDeviceByAddress(address); if (!device) { - LOG_WARN("Skipping unknown device %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } - LOG_DEBUG("address=%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("address={}", ADDRESS_TO_LOGGABLE_CSTR(address)); if (!device->is_gatt_service_valid) BTA_GATTC_ServiceSearchRequest(device->conn_id, &kCsisServiceUuid); @@ -2173,7 +2188,7 @@ class CsisClientImpl : public CsisClient { const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(conn_id, char_handle); if (!p_char) { - LOG_WARN("No such characteristic: 0x%04x", char_handle); + log::warn("No such characteristic: 0x{:04x}", char_handle); return GAP_INVALID_HANDLE; } @@ -2190,10 +2205,10 @@ class CsisClientImpl : public CsisClient { if (value_handle != GAP_INVALID_HANDLE) { tGATT_STATUS register_status = BTA_GATTC_RegisterForNotifications(gatt_if_, address, value_handle); - LOG_DEBUG( - "BTA_GATTC_RegisterForNotifications, status=0x%02x, value=%s, " - "ccc=0x%04x", - register_status, loghex(value_handle).c_str(), ccc_handle); + log::debug( + "BTA_GATTC_RegisterForNotifications, status=0x{:02x}, value={}, " + "ccc=0x{:04x}", + register_status, loghex(value_handle), ccc_handle); if (register_status != GATT_SUCCESS) return; } @@ -2216,8 +2231,9 @@ class CsisClientImpl : public CsisClient { if (value_handle != GAP_INVALID_HANDLE) { tGATT_STATUS register_status = BTA_GATTC_DeregisterForNotifications(gatt_if_, address, value_handle); - LOG_DEBUG("DisableGattNotification, status=0x%02x, value_handle=0x%04x", - register_status, value_handle); + log::debug( + "DisableGattNotification, status=0x{:02x}, value_handle=0x{:04x}", + register_status, value_handle); if (register_status != GATT_SUCCESS) return; } @@ -2227,11 +2243,12 @@ class CsisClientImpl : public CsisClient { const RawAddress& address, uint8_t sirk_type, Octet16& received_sirk) { - LOG_INFO("%s, status: 0x%02x", ADDRESS_TO_LOGGABLE_CSTR(address), status); + log::info("{}, status: 0x{:02x}", ADDRESS_TO_LOGGABLE_CSTR(address), + status); auto device = FindDeviceByAddress(address); if (device == nullptr) { - LOG_ERROR("Unknown device %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("Unknown device {}", ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_DmSirkConfirmDeviceReply(address, false); return; } @@ -2244,15 +2261,15 @@ class CsisClientImpl : public CsisClient { */ auto csis_group = FindCsisGroup(group_id_to_join); if (!csis_group) { - LOG_ERROR("Group %d removed during paring a set member", - group_id_to_join); + log::error("Group {} removed during paring a set member", + group_id_to_join); RemoveDevice(address); BTA_DmSirkConfirmDeviceReply(address, false); return; } if (status != GATT_SUCCESS) { - LOG_INFO("Invalid member, can't read SIRK (status: 0x%02x)", status); + log::info("Invalid member, can't read SIRK (status: 0x{:02x})", status); BTA_DmSirkConfirmDeviceReply(address, false); return; } @@ -2260,8 +2277,8 @@ class CsisClientImpl : public CsisClient { /* Verify if sirk is not all zeros */ Octet16 zero{}; if (memcmp(zero.data(), received_sirk.data(), 16) == 0) { - LOG_ERROR("Received invalid zero SIRK address: %s ", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("Received invalid zero SIRK address: {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_DmSirkConfirmDeviceReply(address, false); return; } @@ -2279,14 +2296,14 @@ class CsisClientImpl : public CsisClient { * that its SIRK is different. Device connection was triggered by RSI * match for group. */ - LOG_ERROR("Joining device %s, does not match any existig group", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("Joining device {}, does not match any existig group", + ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_DmSirkConfirmDeviceReply(address, false); return; } - LOG_INFO("Device %s, verified successfully by SIRK", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Device {}, verified successfully by SIRK", + ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_DmSirkConfirmDeviceReply(address, true); /* It was temporary device and we can remove it. When upper layer @@ -2298,21 +2315,20 @@ class CsisClientImpl : public CsisClient { void VerifySetMember(const RawAddress& address) { auto device = FindDeviceByAddress(address); - LOG_INFO("Device: %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Device: {}", ADDRESS_TO_LOGGABLE_CSTR(address)); /* It's ok for device to not be a CSIS device at all */ if (!device) { - LOG_INFO("Valid - new member"); + log::info("Valid - new member"); BTA_DmSirkConfirmDeviceReply(address, true); return; } auto group_id_to_join = device->GetExpectedGroupIdMember(); if (group_id_to_join == bluetooth::groups::kGroupUnknown) { - LOG_WARN( - "Device %s (conn_id=0x%04x) is already known to CSIS (# of " - "instances=%d) but it is " - "not scheduled to join any group.", + log::warn( + "Device {} (conn_id=0x{:04x}) is already known to CSIS (# of " + "instances={}) but it is not scheduled to join any group.", ADDRESS_TO_LOGGABLE_CSTR(address), device->conn_id, device->GetNumberOfCsisInstances()); BTA_DmSirkConfirmDeviceReply(address, true); @@ -2323,7 +2339,8 @@ class CsisClientImpl : public CsisClient { address, base::BindOnce(&CsisClientImpl::SirkValueReadCompleteDuringPairing, weak_factory_.GetWeakPtr()))) { - LOG_ERROR("Could not read SIKR of %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("Could not read SIKR of {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_DmSirkConfirmDeviceReply(address, false); return; } @@ -2375,7 +2392,7 @@ void CsisClient::Initialize(bluetooth::csis::CsisClientCallbacks* callbacks, Closure initCb) { std::scoped_lock lock(instance_mutex); if (instance) { - LOG_INFO("Already initialized!"); + log::info("Already initialized!"); return; } @@ -2391,20 +2408,19 @@ CsisClient* CsisClient::Get(void) { } void CsisClient::AddFromStorage(const RawAddress& addr, - const std::vector& in, - bool autoconnect) { + const std::vector& in) { if (!instance) { - LOG_ERROR("Not initialized yet!"); + log::error("Not initialized yet!"); return; } - instance->AddFromStorage(addr, in, autoconnect); + instance->AddFromStorage(addr, in); } bool CsisClient::GetForStorage(const RawAddress& addr, std::vector& out) { if (!instance) { - LOG_ERROR("Not initialized yet!"); + log::error("Not initialized yet!"); return false; } diff --git a/system/bta/csis/csis_client_test.cc b/system/bta/csis/csis_client_test.cc index b2cd110d422a9f06c1713d2f12247d8af2c70fb2..0eb29a4f1d8896840595ba566de2bbc91c2484d2 100644 --- a/system/bta/csis/csis_client_test.cc +++ b/system/bta/csis/csis_client_test.cc @@ -16,16 +16,19 @@ */ #include +#include #include #include +#include + #include "bind_helpers.h" #include "bta_csis_api.h" #include "bta_dm_api_mock.h" #include "bta_gatt_api_mock.h" #include "bta_gatt_queue_mock.h" #include "bta_le_audio_uuids.h" -#include "btif_profile_storage.h" +#include "btif/include/btif_profile_storage.h" #include "btm_api_mock.h" #include "csis_types.h" #include "gatt/database_builder.h" @@ -411,7 +414,7 @@ class CsisClientTest : public ::testing::Test { value.assign(1, rank_2); break; default: - LOG(ERROR) << " Unknown handle? " << +handle; + log::error("Unknown handle? {}", handle); ASSERT_TRUE(false); return; } @@ -552,12 +555,8 @@ class CsisClientTest : public ::testing::Test { EXPECT_CALL(*callbacks, OnDeviceAvailable(address, _, _, _, _)) .Times(AtLeast(1)); - /* In testing only whe set info is empty, there is no CAP context. */ - bool is_opportunistic = (storage_buf.size() != 0); - EXPECT_CALL(gatt_interface, - Open(gatt_if, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, - is_opportunistic)) + Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, true)) .WillOnce(Invoke([this, conn_id](tGATT_IF client_if, const RawAddress& remote_bda, bool is_direct, bool opportunistic) { @@ -566,7 +565,7 @@ class CsisClientTest : public ::testing::Test { })); DeviceGroups::AddFromStorage(address, storage_group_buf); - CsisClient::AddFromStorage(address, storage_buf, true); + CsisClient::AddFromStorage(address, storage_buf); } void InjectEncryptionEvent(const RawAddress& test_address, uint16_t conn_id) { @@ -1087,6 +1086,100 @@ TEST_F(CsisClientTest, test_get_set_sirk) { ASSERT_EQ(g_1->GetSirk(), sirk); } +TEST_F(CsisClientTest, + test_not_open_duplicate_active_scan_while_bonding_set_member) { + uint16_t conn_id = 0x0001; + EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(1); + SetSampleDatabaseCsis(conn_id, 1, 1); + TestAppRegister(); + + // Here we handle background scan request + Mock::VerifyAndClearExpectations(&dm_interface); + + TestConnect(test_address); + InjectConnectedEvent(test_address, 1); + + auto ReadCharacteristicCbGenerator = []() { + return [](uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb, + void* cb_data) -> void { + std::vector value; + switch (handle) { + case 0x0003: + // device name + value.resize(20); + break; + case 0x0021: + // plain sirk + value.resize(17); + value.assign(17, 1); + break; + case 0x0024: + // size + value.resize(1); + value.assign(1, 2); + break; + case 0x0027: + // lock + value.resize(2); + break; + case 0x0030: + // rank + value.resize(1); + value.assign(1, 1); + break; + default: + FAIL(); + return; + } + if (cb) { + cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data); + } + }; + }; + + // We should read 4 times for sirk, rank, size, and lock characteristics + EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _)) + .Times(4) + .WillOnce(Invoke(ReadCharacteristicCbGenerator())) + .WillOnce(Invoke(ReadCharacteristicCbGenerator())) + .WillOnce(Invoke(ReadCharacteristicCbGenerator())) + .WillOnce(Invoke(ReadCharacteristicCbGenerator())); + + // Here is actual active scan request for the first device + tBTA_DM_SEARCH_CBACK* p_results_cb = nullptr; + EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)) + .Times(1) + .WillOnce(DoAll(SaveArg<1>(&p_results_cb))); + + GetSearchCompleteEvent(conn_id); + + Mock::VerifyAndClearExpectations(&dm_interface); + + // Simulate we find the set member + tBTA_DM_SEARCH result; + result.inq_res.include_rsi = true; + std::vector rsi = {0x07, 0x2e, 0x00, 0xed, 0x1a, 0x00, 0x00, 0x00}; + result.inq_res.p_eir = rsi.data(); + result.inq_res.eir_len = 8; + result.inq_res.bd_addr = test_address2; + + // CSIS client should process set member event to JNI + EXPECT_CALL(*callbacks, OnSetMemberAvailable(test_address2, 1)); + + p_results_cb(BTA_DM_INQ_RES_EVT, &result); + + Mock::VerifyAndClearExpectations(&dm_interface); + + EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(0); + + // Simulate getting duplicate response from remote for the first device + // At this momoment we should not open second active scan because the set + // member is already cached and waiting for bonding + GetSearchCompleteEvent(conn_id); + + Mock::VerifyAndClearExpectations(&dm_interface); +} + TEST_F(CsisClientTest, test_csis_member_not_found) { EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(1); SetSampleDatabaseDoubleCsis(0x001, 1, 2); @@ -1291,11 +1384,9 @@ TEST_F(CsisClientTest, test_storage_calls) { ASSERT_EQ(1, get_func_call_count("btif_storage_load_bonded_csis_devices")); ASSERT_EQ(0, get_func_call_count("btif_storage_update_csis_info")); - ASSERT_EQ(0, get_func_call_count("btif_storage_set_csis_autoconnect")); TestConnect(test_address); InjectConnectedEvent(test_address, 1); GetSearchCompleteEvent(1); - ASSERT_EQ(1, get_func_call_count("btif_storage_set_csis_autoconnect")); ASSERT_EQ(1, get_func_call_count("btif_storage_update_csis_info")); ASSERT_EQ(0, get_func_call_count("btif_storage_remove_csis_device")); diff --git a/system/bta/csis/csis_types.h b/system/bta/csis/csis_types.h index 25b43a60633210e92372c6e4cde651c869d80eb3..6c2e43ad6d027948accca3388b7821d4510988a3 100644 --- a/system/bta/csis/csis_types.h +++ b/system/bta/csis/csis_types.h @@ -18,6 +18,7 @@ #pragma once #include #include +#include #include #include @@ -26,7 +27,7 @@ #include "bta_csis_api.h" #include "bta_gatt_api.h" #include "bta_groups.h" -#include "btif_storage.h" +#include "btif/include/btif_storage.h" #include "common/init_flags.h" #include "common/strings.h" #include "crypto_toolbox/crypto_toolbox.h" @@ -89,12 +90,6 @@ enum class CsisDiscoveryState : uint8_t { class GattServiceDevice { public: RawAddress addr; - /* - * This is true only during first connection to profile, until we store the - * device. - */ - bool first_connection; - /* * We are making active attempt to connect to this device, 'direct connect'. */ @@ -105,7 +100,7 @@ class GattServiceDevice { bool is_gatt_service_valid = false; GattServiceDevice(const RawAddress& addr, bool first_connection) - : addr(addr), first_connection(first_connection) {} + : addr(addr) {} GattServiceDevice() : GattServiceDevice(RawAddress::kEmpty, false) {} @@ -174,21 +169,21 @@ class CsisInstance { } void SetLockState(CsisLockState state) { - LOG_DEBUG("current lock state: %d, new lock state: %d", - static_cast(lock_state_), static_cast(state)); + log::debug("current lock state: {}, new lock state: {}", + static_cast(lock_state_), static_cast(state)); lock_state_ = state; } CsisLockState GetLockState(void) const { return lock_state_; } uint8_t GetRank(void) const { return rank_; } void SetRank(uint8_t rank) { - LOG_DEBUG("current rank: %d, new rank: %d", static_cast(rank_), - static_cast(rank)); + log::debug("current rank: {}, new rank: {}", static_cast(rank_), + static_cast(rank)); rank_ = rank; } void SetGroupId(int group_id) { - LOG_INFO("set group id: %d, instance handle: 0x%04x", group_id, - svc_data.start_handle); + log::info("set group id: {}, instance handle: 0x{:04x}", group_id, + svc_data.start_handle); group_id_ = group_id; } @@ -251,7 +246,7 @@ class CsisDevice : public GattServiceDevice { if (handle >= inst->svc_data.start_handle && handle <= inst->svc_data.end_handle) { hdl = h; - LOG_VERBOSE("found 0x%04x", hdl); + log::verbose("found 0x{:04x}", hdl); break; } } @@ -272,14 +267,14 @@ class CsisDevice : public GattServiceDevice { void SetCsisInstance(uint16_t handle, std::shared_ptr csis_instance) { if (csis_instances_.count(handle)) { - LOG_DEBUG("instance is already here: %s", - csis_instance->GetUuid().ToString().c_str()); + log::debug("instance is already here: {}", + csis_instance->GetUuid().ToString()); return; } csis_instances_.insert({handle, csis_instance}); - LOG_DEBUG("instance added: 0x%04x, device %s", handle, - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::debug("instance added: 0x{:04x}, device {}", handle, + ADDRESS_TO_LOGGABLE_CSTR(addr)); } void RemoveCsisInstance(int group_id) { @@ -301,14 +296,14 @@ class CsisDevice : public GattServiceDevice { } void SetExpectedGroupIdMember(int group_id) { - LOG_INFO("Expected Group ID: %d, for member: %s is set", group_id, - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::info("Expected Group ID: {}, for member: {} is set", group_id, + ADDRESS_TO_LOGGABLE_CSTR(addr)); expected_group_id_member_ = group_id; } void SetPairingSirkReadFlag(bool flag) { - LOG_INFO("Pairing flag for Group ID: %d, member: %s is set to %d", - expected_group_id_member_, ADDRESS_TO_LOGGABLE_CSTR(addr), flag); + log::info("Pairing flag for Group ID: {}, member: {} is set to {}", + expected_group_id_member_, ADDRESS_TO_LOGGABLE_CSTR(addr), flag); pairing_sirk_read_flag_ = flag; } @@ -382,7 +377,7 @@ class CsisGroup { Octet16 GetSirk(void) const { return sirk_; } void SetSirk(Octet16& sirk) { if (sirk_available_) { - LOG_DEBUG("Updating SIRK"); + log::debug("Updating SIRK"); } sirk_available_ = true; sirk_ = sirk; @@ -397,9 +392,9 @@ class CsisGroup { return member_discovery_state_; } void SetDiscoveryState(CsisDiscoveryState state) { - LOG_DEBUG("current discovery state: %d, new discovery state: %d", - static_cast(member_discovery_state_), - static_cast(state)); + log::debug("current discovery state: {}, new discovery state: {}", + static_cast(member_discovery_state_), + static_cast(state)); member_discovery_state_ = state; } @@ -431,27 +426,27 @@ class CsisGroup { auto iter = std::find_if( devices_.begin(), devices_.end(), [id, &number_of_connected](auto& d) { if (!d->IsConnected()) { - LOG_DEBUG("Device %s is not connected in group %d", - ADDRESS_TO_LOGGABLE_CSTR(d->addr), id); + log::debug("Device {} is not connected in group {}", + ADDRESS_TO_LOGGABLE_CSTR(d->addr), id); return false; } auto inst = d->GetCsisInstanceByGroupId(id); if (!inst) { - LOG_DEBUG("Instance not available for group %d", id); + log::debug("Instance not available for group {}", id); return false; } number_of_connected++; - LOG_DEBUG("Device %s, lock state: %d", - ADDRESS_TO_LOGGABLE_CSTR(d->addr), - (int)inst->GetLockState()); + log::debug("Device {}, lock state: {}", + ADDRESS_TO_LOGGABLE_CSTR(d->addr), + (int)inst->GetLockState()); return inst->GetLockState() == CsisLockState::CSIS_STATE_LOCKED; }); - LOG_DEBUG("Locked set: %d, number of connected %d", iter != devices_.end(), - number_of_connected); + log::debug("Locked set: {}, number of connected {}", iter != devices_.end(), + number_of_connected); /* If there is no locked device, we are good to go */ if (iter != devices_.end()) { - LOG_WARN("Device %s is locked ", ADDRESS_TO_LOGGABLE_CSTR((*iter)->addr)); + log::warn("Device {} is locked", ADDRESS_TO_LOGGABLE_CSTR((*iter)->addr)); return false; } @@ -465,9 +460,9 @@ class CsisGroup { auto inst2 = dev2->GetCsisInstanceByGroupId(id); if (!inst1 || !inst2) { /* One of the device is not connected */ - LOG_DEBUG("Device %s is not connected.", - inst1 == nullptr ? ADDRESS_TO_LOGGABLE_CSTR(dev1->addr) - : ADDRESS_TO_LOGGABLE_CSTR(dev2->addr)); + log::debug("Device {} is not connected.", + inst1 == nullptr ? ADDRESS_TO_LOGGABLE_CSTR(dev1->addr) + : ADDRESS_TO_LOGGABLE_CSTR(dev2->addr)); return dev1->IsConnected(); } return (inst1->GetRank() < inst2->GetRank()); @@ -521,15 +516,15 @@ class CsisGroup { rand[1] = rsi.address[1]; rand[2] = rsi.address[0]; #ifdef CSIS_DEBUG - LOG_INFO("Prand %s", base::HexEncode(rand.data(), 3).c_str()); - LOG_INFO("SIRK %s", base::HexEncode(sirk.data(), 16).c_str()); + log::info("Prand {}", base::HexEncode(rand.data(), 3)); + log::info("SIRK {}", base::HexEncode(sirk.data(), 16)); #endif /* generate X = E irk(R0, R1, R2) and R is random address 3 LSO */ Octet16 x = crypto_toolbox::aes_128(sirk, rand); #ifdef CSIS_DEBUG - LOG_INFO("X %s", base::HexEncode(x.data(), 16).c_str()); + log::info("X {}", base::HexEncode(x.data(), 16)); #endif rand[0] = rsi.address[5]; @@ -537,7 +532,7 @@ class CsisGroup { rand[2] = rsi.address[3]; #ifdef CSIS_DEBUG - LOG_INFO("Hash %s", base::HexEncode(rand.data(), 3).c_str()); + log::info("Hash {}", base::HexEncode(rand.data(), 3)); #endif if (memcmp(x.data(), &rand[0], 3) == 0) { diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index a0b92321db2915bd2593e842c005185e24ef31d4..d66f68450c51c2d12282c810c34acb91a5f24b64 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -25,27 +25,34 @@ #define LOG_TAG "bt_bta_dm" +#include #include #include #include +#include #include +#include #include "bta/dm/bta_dm_disc.h" #include "bta/dm/bta_dm_gatt_client.h" #include "bta/dm/bta_dm_int.h" #include "bta/dm/bta_dm_sec_int.h" #include "bta/include/bta_api.h" +#include "bta/include/bta_le_audio_api.h" #include "bta/include/bta_sdp_api.h" #include "bta/include/bta_sec_api.h" #include "bta/sys/bta_sys.h" #include "btif/include/btif_dm.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "device/include/controller.h" +#include "hci/controller_interface.h" #include "include/bind_helpers.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "main/shim/acl_api.h" #include "main/shim/btm_api.h" +#include "main/shim/entry.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "osi/include/properties.h" @@ -62,6 +69,7 @@ #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; bool ble_vnd_is_included(); void BTIF_dm_disable(); @@ -84,6 +92,9 @@ static void bta_dm_adjust_roles(bool delay_role_switch); tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); static void bta_dm_ctrl_features_rd_cmpl_cback(tHCI_STATUS result); +static const char kPropertySniffOffloadEnabled[] = + "bluetooth.sniff_offload.enabled"; + #ifndef BTA_DM_BLE_ADV_CHNL_MAP #define BTA_DM_BLE_ADV_CHNL_MAP \ (BTM_BLE_ADV_CHNL_37 | BTM_BLE_ADV_CHNL_38 | BTM_BLE_ADV_CHNL_39) @@ -219,8 +230,6 @@ void BTA_dm_on_hw_off() { } void BTA_dm_on_hw_on() { - DEV_CLASS dev_class; - uint8_t key_mask = 0; tBTA_BLE_LOCAL_ID_KEYS id_key; @@ -233,9 +242,9 @@ void BTA_dm_on_hw_on() { memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs)); memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); - btif_dm_get_local_class_of_device(dev_class); - LOG_INFO("%s: Read default class of device {0x%x, 0x%x, 0x%x}", __func__, - dev_class[0], dev_class[1], dev_class[2]); + DEV_CLASS dev_class = btif_dm_get_local_class_of_device(); + log::info("Read default class of device [0x{:x}, 0x{:x}, 0x{:x}]", + dev_class[0], dev_class[1], dev_class[2]); get_btm_client_interface().local.BTM_SetDeviceClass(dev_class); @@ -244,11 +253,11 @@ void BTA_dm_on_hw_on() { btif_dm_get_ble_local_keys(&key_mask, &er, &id_key); if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) { - get_btm_client_interface().ble.BTM_BleLoadLocalKeys( + get_btm_client_interface().security.BTM_BleLoadLocalKeys( BTA_BLE_LOCAL_KEY_TYPE_ER, (tBTM_BLE_LOCAL_KEYS*)&er); } if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) { - get_btm_client_interface().ble.BTM_BleLoadLocalKeys( + get_btm_client_interface().security.BTM_BleLoadLocalKeys( BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS*)&id_key); } @@ -285,8 +294,13 @@ void BTA_dm_on_hw_on() { bta_sys_rm_register(bta_dm_rm_cback); - /* initialize bluetooth low power manager */ - bta_dm_init_pm(); + /* if sniff is offload, no need to handle it in the stack */ + if (IS_FLAG_ENABLED(enable_sniff_offload) && + osi_property_get_bool(kPropertySniffOffloadEnabled, false)) { + } else { + /* initialize bluetooth low power manager */ + bta_dm_init_pm(); + } bta_dm_disc_gattc_register(); } @@ -317,18 +331,18 @@ void bta_dm_disable() { const uint64_t disable_delay_ms = GET_SYSPROP(Bta, disable_delay, 200); switch (disable_delay_ms) { case 0: - LOG_DEBUG("Immediately disabling device manager"); + log::debug("Immediately disabling device manager"); bta_dm_disable_conn_down_timer_cback(nullptr); break; default: - LOG_DEBUG("Set timer to delay disable initiation:%lu ms", - static_cast(disable_delay_ms)); + log::debug("Set timer to delay disable initiation:{} ms", + static_cast(disable_delay_ms)); alarm_set_on_mloop(bta_dm_cb.disable_timer, disable_delay_ms, bta_dm_disable_conn_down_timer_cback, nullptr); } } else { - LOG_DEBUG("Set timer to wait for all ACL connections to close:%lu ms", - first_pass.TimeToWaitInMs()); + log::debug("Set timer to wait for all ACL connections to close:{} ms", + first_pass.TimeToWaitInMs()); alarm_set_on_mloop(bta_dm_cb.disable_timer, first_pass.time_to_wait_in_ms, bta_dm_wait_for_acl_to_drain_cback, first_pass.AlarmCallbackData()); @@ -364,16 +378,16 @@ static void bta_dm_wait_for_acl_to_drain_cback(void* data) { WaitForAllAclConnectionsToDrain::IsFirstPass(pass)) { /* DISABLE_EVT still need to be sent out to avoid java layer disable timeout */ - LOG_DEBUG( - "Set timer for second pass to wait for all ACL connections to " - "close:%lu ms ", + log::debug( + "Set timer for second pass to wait for all ACL connections to close:{} " + "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 to close were up or is second pass at ACL closure - LOG_INFO("Ensuring all ACL connections have been properly flushed"); + log::info("Ensuring all ACL connections have been properly flushed"); bluetooth::shim::ACL_Shutdown(); bta_dm_cb.disabling = false; @@ -458,7 +472,7 @@ void bta_dm_remove_device(const RawAddress& bd_addr) { tBT_TRANSPORT other_transport = BT_TRANSPORT_AUTO; if (is_bd_addr_connected) { - LOG_VERBOSE("%s: ACL Up count: %d", __func__, bta_dm_cb.device_list.count); + log::verbose("ACL Up count: {}", bta_dm_cb.device_list.count); /* Take the link down first, and mark the device for removal when * disconnected */ @@ -471,7 +485,7 @@ void bta_dm_remove_device(const RawAddress& bd_addr) { GATT_CancelConnect(0, bd_addr, false); btm_remove_acl(bd_addr, peer_device.transport); - LOG_VERBOSE("%s: transport: %d", __func__, peer_device.transport); + log::verbose("transport: {}", peer_device.transport); /* save the other transport to check if device is connected on * other_transport */ @@ -509,8 +523,8 @@ void bta_dm_remove_device(const RawAddress& bd_addr) { other_transport = connected_with_br_edr ? BT_TRANSPORT_BR_EDR : BT_TRANSPORT_LE; } - LOG_INFO("other_address %s with transport %d connected", - ADDRESS_TO_LOGGABLE_CSTR(other_address), other_transport); + log::info("other_address {} with transport {} connected", + ADDRESS_TO_LOGGABLE_CSTR(other_address), other_transport); /* Take the link down first, and mark the device for removal when * disconnected */ for (int i = 0; i < bta_dm_cb.device_list.count; i++) { @@ -518,7 +532,8 @@ void bta_dm_remove_device(const RawAddress& bd_addr) { if (peer_device.peer_bdaddr == other_address && peer_device.transport == other_transport) { peer_device.conn_state = BTA_DM_UNPAIRING; - LOG_INFO("Remove ACL of address %s", ADDRESS_TO_LOGGABLE_CSTR(other_address)); + log::info("Remove ACL of address {}", + ADDRESS_TO_LOGGABLE_CSTR(other_address)); /* Make sure device is not in acceptlist before we disconnect */ GATT_CancelConnect(0, bd_addr, false); @@ -546,7 +561,7 @@ void bta_dm_close_acl(const RawAddress& bd_addr, bool remove_dev, tBT_TRANSPORT transport) { uint8_t index; - LOG_VERBOSE("bta_dm_close_acl"); + log::verbose("bta_dm_close_acl"); if (BTM_IsAclConnectionUp(bd_addr, transport)) { for (index = 0; index < bta_dm_cb.device_list.count; index++) { @@ -555,12 +570,12 @@ void bta_dm_close_acl(const RawAddress& bd_addr, bool remove_dev, } if (index != bta_dm_cb.device_list.count) { if (remove_dev) { - LOG_INFO("Setting remove_dev_pending for %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Setting remove_dev_pending for {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); bta_dm_cb.device_list.peer_device[index].remove_dev_pending = true; } } else { - LOG_ERROR("unknown device, remove ACL failed"); + log::error("unknown device, remove ACL failed"); } /* Make sure device is not in acceptlist before we disconnect */ @@ -594,20 +609,19 @@ static void handle_role_change(const RawAddress& bd_addr, tHCI_ROLE new_role, tHCI_STATUS hci_status) { tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr); if (!p_dev) { - LOG_WARN( - "Unable to find device for role change peer:%s new_role:%s " - "hci_status:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), RoleText(new_role).c_str(), - hci_error_code_text(hci_status).c_str()); + log::warn( + "Unable to find device for role change peer:{} new_role:{} " + "hci_status:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), RoleText(new_role), + hci_error_code_text(hci_status)); return; } - LOG_INFO( - "Role change callback peer:%s info:%s new_role:%s dev count:%d " - "hci_status:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p_dev->info_text().c_str(), - RoleText(new_role).c_str(), bta_dm_cb.device_list.count, - hci_error_code_text(hci_status).c_str()); + log::info( + "Role change callback peer:{} info:{} new_role:{} dev count:{} " + "hci_status:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p_dev->info_text(), RoleText(new_role), + bta_dm_cb.device_list.count, hci_error_code_text(hci_status)); if (p_dev->is_av_active()) { bool need_policy_change = false; @@ -648,18 +662,19 @@ void BTA_dm_report_role_change(const RawAddress bd_addr, tHCI_ROLE new_role, void handle_remote_features_complete(const RawAddress& bd_addr) { tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr); if (!p_dev) { - LOG_WARN("Unable to find device peer:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Unable to find device peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } - if (controller_get_interface()->supports_sniff_subrating() && + if (bluetooth::shim::GetController()->SupportsSniffSubrating() && acl_peer_supports_sniff_subrating(bd_addr)) { - LOG_DEBUG("Device supports sniff subrating peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Device supports sniff subrating peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); p_dev->set_both_device_ssr_capable(); } else { - LOG_DEBUG("Device does NOT support sniff subrating peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Device does NOT support sniff subrating peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } @@ -694,18 +709,18 @@ void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport, uint16_t acl_handle) { auto device = allocate_device_for(bd_addr, transport); if (device == nullptr) { - LOG_WARN("Unable to allocate device resources for new connection"); + log::warn("Unable to allocate device resources for new connection"); return; } - LOG_INFO("Acl connected peer:%s transport:%s handle:%hu", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport).c_str(), acl_handle); + log::info("Acl connected peer:{} transport:{} handle:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport), + acl_handle); device->conn_state = BTA_DM_CONNECTED; device->pref_role = BTA_ANY_ROLE; device->reset_device_info(); device->transport = transport; - if (controller_get_interface()->supports_sniff_subrating() && + if (bluetooth::shim::GetController()->SupportsSniffSubrating() && acl_peer_supports_sniff_subrating(bd_addr)) { // NOTE: This callback assumes upon ACL connection that // the read remote features has completed and is valid. @@ -723,7 +738,7 @@ void bta_dm_acl_up(const RawAddress& bd_addr, tBT_TRANSPORT transport, conn.link_up.acl_handle = acl_handle; bta_dm_acl_cb.p_acl_cback(BTA_DM_LINK_UP_EVT, &conn); - LOG_DEBUG("Executed security callback for new connection available"); + log::debug("Executed security callback for new connection available"); } bta_dm_adjust_roles(true); } @@ -768,8 +783,7 @@ static void bta_dm_acl_down(const RawAddress& bd_addr, /* remove all cached GATT information */ get_gatt_interface().BTA_GATTC_Refresh(bd_addr); - LOG_VERBOSE("%s: Unpairing: issue unpair CB = %d ", __func__, - issue_unpair_cb); + log::verbose("Unpairing: issue unpair CB = {}", issue_unpair_cb); } remove_device = device->remove_dev_pending; @@ -808,8 +822,8 @@ static void bta_dm_acl_down(const RawAddress& bd_addr, } } if (remove_device) { - LOG_INFO("remove_dev_pending actually removing %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("remove_dev_pending actually removing {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); bta_dm_process_remove_device_no_callback(bd_addr); } @@ -851,11 +865,11 @@ static void bta_dm_check_av() { tBTA_DM_PEER_DEVICE* p_dev; if (bta_dm_cb.cur_av_count) { - LOG_INFO("av_count:%d", bta_dm_cb.cur_av_count); + log::info("av_count:{}", bta_dm_cb.cur_av_count); for (i = 0; i < bta_dm_cb.device_list.count; i++) { p_dev = &bta_dm_cb.device_list.peer_device[i]; - LOG_WARN("[%d]: state:%d, info:%s", i, p_dev->conn_state, - p_dev->info_text().c_str()); + log::warn("[{}]: state:{}, info:{}", i, p_dev->conn_state, + p_dev->info_text()); if ((p_dev->conn_state == BTA_DM_CONNECTED) && p_dev->is_av_active()) { /* make central and take away the role switch policy */ get_btm_client_interface().link_policy.BTM_SwitchRoleToCentral( @@ -884,7 +898,7 @@ static void bta_dm_disable_conn_down_timer_cback(UNUSED_ATTR void* data) { bta_dm_disable_pm(); bta_dm_cb.disabling = false; - LOG_INFO("Stack device manager shutdown completed"); + log::info("Stack device manager shutdown completed"); future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); } @@ -904,9 +918,9 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, tBTA_SYS_ID id, tBTA_PREF_ROLES role; tBTA_DM_PEER_DEVICE* p_dev; - LOG_DEBUG("BTA Role management callback count:%d status:%s peer:%s", - bta_dm_cb.cur_av_count, bta_sys_conn_status_text(status).c_str(), - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::debug("BTA Role management callback count:{} status:{} peer:{}", + bta_dm_cb.cur_av_count, bta_sys_conn_status_text(status), + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); p_dev = bta_dm_find_peer_device(peer_addr); if (status == BTA_SYS_CONN_OPEN) { @@ -966,7 +980,7 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, tBTA_SYS_ID id, * ******************************************************************************/ static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void* data) { - LOG_VERBOSE("%s: initiating Delayed RS", __func__); + log::verbose("initiating Delayed RS"); bta_dm_adjust_roles(false); } @@ -1078,7 +1092,7 @@ static void bta_dm_set_eir(char* local_name) { /* if local name is not provided, get it from controller */ if (local_name == NULL) { if (BTM_ReadLocalDeviceName((const char**)&local_name) != BTM_SUCCESS) { - LOG_ERROR("Fail to read local device name for EIR"); + log::error("Fail to read local device name for EIR"); } } #endif // BTA_EIR_CANNED_UUID_LIST @@ -1090,7 +1104,7 @@ static void bta_dm_set_eir(char* local_name) { memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN); - LOG_INFO("Generating extended inquiry response packet EIR"); + log::info("Generating extended inquiry response packet EIR"); if (local_name) local_name_len = strlen(local_name); @@ -1115,7 +1129,7 @@ static void bta_dm_set_eir(char* local_name) { if (local_name_len > (free_eir_length - 4 - num_uuid * Uuid::kNumBytes16)) { local_name_len = find_utf8_char_boundary( local_name, p_bta_dm_eir_cfg->bta_dm_eir_min_name_len); - LOG_WARN("%s local name is shortened (%d)", __func__, local_name_len); + log::warn("local name is shortened ({})", local_name_len); data_type = HCI_EIR_SHORTENED_LOCAL_NAME_TYPE; } else { data_type = HCI_EIR_COMPLETE_LOCAL_NAME_TYPE; @@ -1143,7 +1157,7 @@ static void bta_dm_set_eir(char* local_name) { data_type = HCI_EIR_COMPLETE_16BITS_UUID_TYPE; } else /* not enough room for all UUIDs */ { - LOG_WARN("BTA EIR: UUID 16-bit list is truncated"); + log::warn("BTA EIR: UUID 16-bit list is truncated"); num_uuid = free_eir_length / Uuid::kNumBytes16; data_type = HCI_EIR_MORE_16BITS_UUID_TYPE; } @@ -1167,7 +1181,7 @@ static void bta_dm_set_eir(char* local_name) { bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid); if (data_type == HCI_EIR_MORE_16BITS_UUID_TYPE) { - LOG_WARN("BTA EIR: UUID 16-bit list is truncated"); + log::warn("BTA EIR: UUID 16-bit list is truncated"); } #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) else { @@ -1181,7 +1195,7 @@ static void bta_dm_set_eir(char* local_name) { num_uuid++; } else { data_type = HCI_EIR_MORE_16BITS_UUID_TYPE; - LOG_WARN("BTA EIR: UUID 16-bit list is truncated"); + log::warn("BTA EIR: UUID 16-bit list is truncated"); break; } } @@ -1214,7 +1228,7 @@ static void bta_dm_set_eir(char* local_name) { num_uuid++; } else { data_type = HCI_EIR_MORE_32BITS_UUID_TYPE; - LOG_WARN("BTA EIR: UUID 32-bit list is truncated"); + log::warn("BTA EIR: UUID 32-bit list is truncated"); break; } } @@ -1243,7 +1257,7 @@ static void bta_dm_set_eir(char* local_name) { num_uuid++; } else { data_type = HCI_EIR_MORE_128BITS_UUID_TYPE; - LOG_WARN("BTA EIR: UUID 128-bit list is truncated"); + log::warn("BTA EIR: UUID 128-bit list is truncated"); break; } } @@ -1343,7 +1357,7 @@ static void bta_dm_update_cust_uuid(uint8_t c_uu_idx, const Uuid& uuid, uint32_t curr.custom_uuid.UpdateUuid(uuid); curr.handle = handle; } else { - LOG_ERROR("%s invalid uuid index %d", __func__, c_uu_idx); + log::error("invalid uuid index {}", c_uu_idx); } #endif } @@ -1358,7 +1372,7 @@ static void bta_dm_update_cust_uuid(uint8_t c_uu_idx, const Uuid& uuid, uint32_t * ******************************************************************************/ void bta_dm_eir_update_cust_uuid(const tBTA_CUSTOM_UUID& curr, bool adding) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) uint8_t c_uu_idx = 0; if (adding) { @@ -1390,12 +1404,14 @@ void bta_dm_eir_update_uuid(uint16_t uuid16, bool adding) { if (!BTM_HasEirService(p_bta_dm_eir_cfg->uuid_mask, uuid16)) return; if (adding) { - LOG_INFO("EIR Adding UUID=0x%04X into extended inquiry response", uuid16); + log::info("EIR Adding UUID=0x{:04X} into extended inquiry response", + uuid16); get_btm_client_interface().eir.BTM_AddEirService(bta_dm_cb.eir_uuid, uuid16); } else { - LOG_INFO("EIR Removing UUID=0x%04X from extended inquiry response", uuid16); + log::info("EIR Removing UUID=0x{:04X} from extended inquiry response", + uuid16); get_btm_client_interface().eir.BTM_RemoveEirService(bta_dm_cb.eir_uuid, uuid16); @@ -1416,14 +1432,14 @@ tBTA_DM_PEER_DEVICE* find_connected_device( } bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr) { - LOG_VERBOSE("%s: count(%d)", __func__, bta_dm_conn_srvcs.count); + log::verbose("count({})", bta_dm_conn_srvcs.count); for (uint8_t j = 0; j < bta_dm_conn_srvcs.count; j++) { // Check if profiles other than hid are connected if ((bta_dm_conn_srvcs.conn_srvc[j].id != BTA_ID_HD) && bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) { - LOG_VERBOSE("%s: Another profile (id=%d) is connected", __func__, - bta_dm_conn_srvcs.conn_srvc[j].id); + log::verbose("Another profile (id={}) is connected", + bta_dm_conn_srvcs.conn_srvc[j].id); return false; } } @@ -1453,7 +1469,7 @@ void bta_dm_ble_update_conn_params(const RawAddress& bd_addr, uint16_t min_int, if (!L2CA_UpdateBleConnParams(bd_addr, min_int, max_int, latency, timeout, min_ce_len, max_ce_len)) { - LOG_ERROR("Update connection parameters failed!"); + log::error("Update connection parameters failed!"); } } @@ -1463,8 +1479,68 @@ void bta_dm_ble_set_data_length(const RawAddress& bd_addr) { uint16_t max_len = controller->get_ble_maximum_tx_data_length(); if (BTM_SetBleDataLength(bd_addr, max_len) != BTM_SUCCESS) { - LOG_INFO("Unable to set ble data length:%hu", max_len); + log::info("Unable to set ble data length:{}", max_len); + } +} + +/** This function returns system context info */ +static tBTM_CONTRL_STATE bta_dm_obtain_system_context() { + uint32_t total_acl_num = bta_dm_cb.device_list.count; + uint32_t sniff_acl_num = BTM_PM_ReadSniffLinkCount(); + uint32_t le_acl_num = BTM_PM_ReadBleLinkCount(); + uint32_t active_acl_num = total_acl_num - sniff_acl_num - le_acl_num; + uint32_t le_adv_num = + bluetooth::shim::BTM_BleGetNumberOfAdvertisingInstancesInUse(); + uint32_t le_scan_duty_cycle = BTM_PM_ReadBleScanDutyCycle(); + bool is_inquiry_active = BTM_PM_DeviceInScanState(); + bool is_le_audio_active = LeAudioClient::IsLeAudioClientInStreaming(); + bool is_av_active = false; + bool is_sco_active = false; + + for (int i = 0; i < bta_dm_cb.device_list.count; i++) { + tBTA_DM_PEER_DEVICE* p_dev = &bta_dm_cb.device_list.peer_device[i]; + if (p_dev->conn_state == BTA_DM_CONNECTED && p_dev->is_av_active()) { + is_av_active = true; + break; + } + } + for (int j = 0; j < bta_dm_conn_srvcs.count; j++) { + /* check for SCO connected index */ + if (bta_dm_conn_srvcs.conn_srvc[j].id == BTA_ID_AG || + bta_dm_conn_srvcs.conn_srvc[j].id == BTA_ID_HS) { + if (bta_dm_conn_srvcs.conn_srvc[j].state == BTA_SYS_SCO_OPEN) { + is_sco_active = true; + break; + } + } + } + + tBTM_CONTRL_STATE ctrl_state = 0; + set_num_acl_active_to_ctrl_state(active_acl_num, ctrl_state); + set_num_acl_sniff_to_ctrl_state(sniff_acl_num, ctrl_state); + set_num_acl_le_to_ctrl_state(le_acl_num, ctrl_state); + set_num_le_adv_to_ctrl_state(le_adv_num, ctrl_state); + set_le_scan_mode_to_ctrl_state(le_scan_duty_cycle, ctrl_state); + + if (is_inquiry_active) { + ctrl_state |= BTM_CONTRL_INQUIRY; + } + if (is_sco_active) { + ctrl_state |= BTM_CONTRL_SCO; } + if (is_av_active) { + ctrl_state |= BTM_CONTRL_A2DP; + } + if (is_le_audio_active) { + ctrl_state |= BTM_CONTRL_LE_AUDIO; + } + log::debug( + "active_acl_num {} sniff_acl_num {} le_acl_num {} le_adv_num {} " + "le_scan_duty {} inquiry {} sco {} a2dp {} le_audio {} ctrl_state 0x{:x}", + active_acl_num, sniff_acl_num, le_acl_num, le_adv_num, le_scan_duty_cycle, + is_inquiry_active, is_sco_active, is_av_active, is_le_audio_active, + ctrl_state); + return ctrl_state; } /******************************************************************************* @@ -1485,7 +1561,11 @@ static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time, tBTA_STATUS st = (status == HCI_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE; tBTM_CONTRL_STATE ctrl_state = BTM_CONTRL_UNKNOWN; - if (BTA_SUCCESS == st) ctrl_state = bta_dm_pm_obtain_controller_state(); + if (BTA_SUCCESS == st) { + ctrl_state = IS_FLAG_ENABLED(bt_system_context_report) + ? bta_dm_obtain_system_context() + : bta_dm_pm_obtain_controller_state(); + } if (bta_dm_cb.p_energy_info_cback) bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, @@ -1512,7 +1592,7 @@ void bta_dm_ble_get_energy_info( * ******************************************************************************/ void bta_dm_clear_event_filter(void) { - VLOG(1) << "bta_dm_clear_event_filter in bta_dm_act"; + log::verbose("bta_dm_clear_event_filter in bta_dm_act"); bluetooth::shim::BTM_ClearEventFilter(); } @@ -1524,7 +1604,7 @@ void bta_dm_clear_event_filter(void) { * ******************************************************************************/ void bta_dm_clear_event_mask(void) { - VLOG(1) << "bta_dm_clear_event_mask in bta_dm_act"; + log::verbose("bta_dm_clear_event_mask in bta_dm_act"); bluetooth::shim::BTM_ClearEventMask(); } @@ -1536,7 +1616,7 @@ void bta_dm_clear_event_mask(void) { * ******************************************************************************/ void bta_dm_clear_filter_accept_list(void) { - VLOG(1) << "bta_dm_clear_filter_accept_list in bta_dm_act"; + log::verbose("bta_dm_clear_filter_accept_list in bta_dm_act"); bluetooth::shim::BTM_ClearFilterAcceptList(); } @@ -1548,7 +1628,7 @@ void bta_dm_clear_filter_accept_list(void) { * ******************************************************************************/ void bta_dm_disconnect_all_acls(void) { - VLOG(1) << "bta_dm_disconnect_all_acls in bta_dm_act"; + log::verbose("bta_dm_disconnect_all_acls in bta_dm_act"); bluetooth::shim::BTM_DisconnectAllAcls(); } @@ -1562,7 +1642,7 @@ void bta_dm_disconnect_all_acls(void) { * ******************************************************************************/ void bta_dm_le_rand(LeRandCallback cb) { - VLOG(1) << "bta_dm_le_rand in bta_dm_act"; + log::verbose("bta_dm_le_rand in bta_dm_act"); bluetooth::shim::BTM_LeRand(std::move(cb)); } @@ -1658,7 +1738,7 @@ void bta_dm_set_event_filter_inquiry_result_all_devices() { * ******************************************************************************/ void bta_dm_ble_reset_id(void) { - VLOG(1) << "bta_dm_ble_reset_id in bta_dm_act"; + log::verbose("bta_dm_ble_reset_id in bta_dm_act"); bluetooth::shim::BTM_BleResetId(); } @@ -1672,12 +1752,12 @@ void bta_dm_ble_reset_id(void) { * ******************************************************************************/ static void bta_dm_ctrl_features_rd_cmpl_cback(tHCI_STATUS result) { - LOG_VERBOSE("%s status = %d ", __func__, result); + log::verbose("status = {}", result); if (result == HCI_SUCCESS) { if (bta_dm_acl_cb.p_acl_cback) bta_dm_acl_cb.p_acl_cback(BTA_DM_LE_FEATURES_READ, NULL); } else { - LOG_ERROR("%s Ctrl BLE feature read failed: status :%d", __func__, result); + log::error("Ctrl BLE feature read failed: status :{}", result); } } @@ -1708,6 +1788,7 @@ tBTA_DM_PEER_DEVICE* allocate_device_for(const RawAddress& bd_addr, void bta_dm_init_cb() { ::bta_dm_init_cb(); } void bta_dm_deinit_cb() { ::bta_dm_deinit_cb(); } +void BTA_dm_on_hw_on() { ::BTA_dm_on_hw_on(); } } // namespace testing } // namespace legacy diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc index 44367bb9aef432816efa3fe325c987bc20f71319..3d2c9f4e7a287387df60b1e468bdc496b1f6cdc0 100644 --- a/system/bta/dm/bta_dm_api.cc +++ b/system/bta/dm/bta_dm_api.cc @@ -22,11 +22,12 @@ * ******************************************************************************/ +#include #include +#include #include -#include "android_bluetooth_flags.h" #include "bta/dm/bta_dm_disc.h" #include "bta/dm/bta_dm_int.h" #include "bta/dm/bta_dm_sec_int.h" @@ -40,6 +41,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; using bluetooth::Uuid; @@ -340,7 +342,7 @@ void BTA_DmCloseACL(const RawAddress& bd_addr, bool remove_dev, ******************************************************************************/ void BTA_DmBleObserve(bool start, uint8_t duration, tBTA_DM_SEARCH_CBACK* p_results_cb) { - LOG_VERBOSE("%s:start = %d ", __func__, start); + log::verbose("start = {}", start); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_ble_observe, start, duration, p_results_cb)); } @@ -362,7 +364,7 @@ void BTA_DmBleObserve(bool start, uint8_t duration, * ******************************************************************************/ void BTA_DmBleScan(bool start, uint8_t duration_sec, bool low_latency_scan) { - LOG_VERBOSE("%s:start = %d ", __func__, start); + log::verbose("start = {}", start); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_ble_scan, start, duration_sec, low_latency_scan)); } @@ -381,7 +383,7 @@ void BTA_DmBleScan(bool start, uint8_t duration_sec, bool low_latency_scan) { * ******************************************************************************/ void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) { - LOG_VERBOSE("%s:enable = %d ", __func__, observe); + log::verbose("enable = {}", observe); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_ble_csis_observe, observe, p_results_cb)); } @@ -395,7 +397,7 @@ void BTA_DmBleCsisObserve(bool observe, tBTA_DM_SEARCH_CBACK* p_results_cb) { * Returns void * ******************************************************************************/ -void BTA_VendorInit(void) { LOG_VERBOSE("BTA_VendorInit"); } +void BTA_VendorInit(void) { log::verbose("BTA_VendorInit"); } /******************************************************************************* * @@ -407,7 +409,7 @@ void BTA_VendorInit(void) { LOG_VERBOSE("BTA_VendorInit"); } * ******************************************************************************/ void BTA_DmClearEventFilter(void) { - LOG_VERBOSE("BTA_DmClearEventFilter"); + log::verbose("BTA_DmClearEventFilter"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_clear_event_filter)); } @@ -421,7 +423,7 @@ void BTA_DmClearEventFilter(void) { * ******************************************************************************/ void BTA_DmClearEventMask(void) { - LOG_VERBOSE("BTA_DmClearEventMask"); + log::verbose("BTA_DmClearEventMask"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_clear_event_mask)); } @@ -435,7 +437,7 @@ void BTA_DmClearEventMask(void) { * ******************************************************************************/ void BTA_DmClearFilterAcceptList(void) { - LOG_VERBOSE("BTA_DmClearFilterAcceptList"); + log::verbose("BTA_DmClearFilterAcceptList"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_clear_filter_accept_list)); } @@ -449,7 +451,7 @@ void BTA_DmClearFilterAcceptList(void) { * ******************************************************************************/ void BTA_DmLeRand(LeRandCallback cb) { - LOG_VERBOSE("BTA_DmLeRand"); + log::verbose("BTA_DmLeRand"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_le_rand, std::move(cb))); } @@ -463,12 +465,12 @@ void BTA_DmLeRand(LeRandCallback cb) { * ******************************************************************************/ void BTA_DmDisconnectAllAcls() { - LOG_VERBOSE("BTA_DmLeRand"); + log::verbose("BTA_DmLeRand"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_disconnect_all_acls)); } void BTA_DmSetEventFilterConnectionSetupAllDevices() { - LOG_VERBOSE("BTA_DmSetEventFilterConnectionSetupAllDevices"); + log::verbose("BTA_DmSetEventFilterConnectionSetupAllDevices"); do_in_main_thread( FROM_HERE, base::BindOnce(bta_dm_set_event_filter_connection_setup_all_devices)); @@ -477,7 +479,7 @@ void BTA_DmSetEventFilterConnectionSetupAllDevices() { void BTA_DmAllowWakeByHid( std::vector classic_hid_devices, std::vector> le_hid_devices) { - LOG_VERBOSE("BTA_DmAllowWakeByHid"); + log::verbose("BTA_DmAllowWakeByHid"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_allow_wake_by_hid, std::move(classic_hid_devices), std::move(le_hid_devices))); @@ -485,20 +487,20 @@ void BTA_DmAllowWakeByHid( void BTA_DmRestoreFilterAcceptList( std::vector> le_devices) { - LOG_VERBOSE("BTA_DmRestoreFilterAcceptList"); + log::verbose("BTA_DmRestoreFilterAcceptList"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_restore_filter_accept_list, std::move(le_devices))); } void BTA_DmSetDefaultEventMaskExcept(uint64_t mask, uint64_t le_mask) { - LOG_VERBOSE("BTA_DmSetDefaultEventMaskExcept"); + log::verbose("BTA_DmSetDefaultEventMaskExcept"); do_in_main_thread( FROM_HERE, base::BindOnce(bta_dm_set_default_event_mask_except, mask, le_mask)); } void BTA_DmSetEventFilterInquiryResultAllDevices() { - LOG_VERBOSE("BTA_DmSetEventFilterInquiryResultAllDevices"); + log::verbose("BTA_DmSetEventFilterInquiryResultAllDevices"); do_in_main_thread( FROM_HERE, base::BindOnce(bta_dm_set_event_filter_inquiry_result_all_devices)); @@ -514,7 +516,7 @@ void BTA_DmSetEventFilterInquiryResultAllDevices() { * ******************************************************************************/ void BTA_DmBleResetId(void) { - LOG_VERBOSE("BTA_DmBleResetId"); + log::verbose("BTA_DmBleResetId"); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_ble_reset_id)); } @@ -537,7 +539,7 @@ void BTA_DmBleResetId(void) { void BTA_DmBleSubrateRequest(const RawAddress& bd_addr, uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency, uint16_t cont_num, uint16_t timeout) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_ble_subrate_request, bd_addr, subrate_min, subrate_max, max_latency, cont_num, timeout)); @@ -550,7 +552,7 @@ bool BTA_DmCheckLeAudioCapable(const RawAddress& address) { if (inq_ent->results.remote_bd_addr != address) continue; if (inq_ent->results.ble_ad_is_le_audio_capable) { - LOG_INFO("Device is LE Audio capable based on AD content"); + log::info("Device is LE Audio capable based on AD content"); return true; } diff --git a/system/bta/dm/bta_dm_cfg.cc b/system/bta/dm/bta_dm_cfg.cc index ace7c25e6c0b3c0bdf6269b341d325be79baa7ab..509fe6f93506ef34e83c3d7e9551db4cb3e358c5 100644 --- a/system/bta/dm/bta_dm_cfg.cc +++ b/system/bta/dm/bta_dm_cfg.cc @@ -128,6 +128,13 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC* get_bta_dm_pm_spec() { static uint16_t hs_sniff_delay = uint16_t( osi_property_get_int32("bluetooth.bta_hs_sniff_delay_ms.config", 7000)); + static uint16_t fts_ops_idle_to_sniff_delay_ms = + uint16_t(osi_property_get_int32( + "bluetooth.bta_fts_ops_idle_to_sniff_delay_ms.config", + BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS)); + static uint16_t ftc_idle_to_sniff_delay_ms = uint16_t( + osi_property_get_int32("bluetooth.bta_ftc_idle_to_sniff_delay_ms.config", + BTA_FTC_IDLE_TO_SNIFF_DELAY_MS)); static tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = { @@ -307,7 +314,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC* get_bta_dm_pm_spec() { {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */ {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */ - {{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTC_IDLE_TO_SNIFF_DELAY_MS}, + {{BTA_DM_PM_SNIFF_A2DP_IDX, ftc_idle_to_sniff_delay_ms}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */ {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */ {{BTA_DM_PM_NO_ACTION, 0}, @@ -329,7 +336,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC* get_bta_dm_pm_spec() { {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */ {{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */ - {{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS}, + {{BTA_DM_PM_SNIFF_A2DP_IDX, fts_ops_idle_to_sniff_delay_ms}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */ {{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */ {{BTA_DM_PM_NO_ACTION, 0}, diff --git a/system/bta/dm/bta_dm_disc.cc b/system/bta/dm/bta_dm_disc.cc index 784c48396589505898b9d5f4cec02c89135308b1..5eb66c4e2de2449346d644c08b1ffce25edeaf41 100644 --- a/system/bta/dm/bta_dm_disc.cc +++ b/system/bta/dm/bta_dm_disc.cc @@ -18,13 +18,16 @@ #include "bta/dm/bta_dm_disc.h" +#include #include #include +#include #include #include +#include -#include "bta/dm/bta_dm_disc.h" +#include "android_bluetooth_flags.h" #include "bta/dm/bta_dm_disc_int.h" #include "bta/include/bta_gatt_api.h" #include "bta/include/bta_sdp_api.h" @@ -34,12 +37,13 @@ #include "common/strings.h" #include "device/include/interop.h" #include "include/bind_helpers.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/fixed_queue.h" -#include "osi/include/osi.h" // UNUSED_ATTR +#include "osi/include/osi.h" // UNUSED_ATTR #include "stack/btm/btm_int_types.h" // TimestampedStringCircularBuffer #include "stack/btm/neighbor_inquiry.h" #include "stack/include/avrc_api.h" @@ -54,6 +58,7 @@ #include "stack/include/hidh_api.h" #include "stack/include/sdp_status.h" #include "stack/sdp/sdpint.h" // is_sdp_pbap_pce_disabled +#include "storage/config_keys.h" #include "types/raw_address.h" #ifdef TARGET_FLOSS @@ -62,6 +67,7 @@ using bluetooth::Uuid; using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); @@ -194,9 +200,9 @@ void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr) { void bta_dm_disc_remove_device(const RawAddress& bd_addr) { if (bta_dm_search_cb.state == BTA_DM_DISCOVER_ACTIVE && bta_dm_search_cb.peer_bdaddr == bd_addr) { - LOG_INFO( - "Device removed while service discovery was pending, " - "conclude the service disvovery"); + log::info( + "Device removed while service discovery was pending, conclude the " + "service disvovery"); bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, (tGATT_STATUS)GATT_ERROR); } @@ -279,8 +285,8 @@ static void bta_dm_search_start(tBTA_DM_MSG* p_data) { // timer pops or is cancelled by the user break; default: - LOG_WARN("Unable to start device discovery search btm_status:%s", - btm_status_text(btm_status).c_str()); + log::warn("Unable to start device discovery search btm_status:{}", + btm_status_text(btm_status)); // Not started so completion callback is executed now bta_dm_inq_cmpl(0); break; @@ -307,7 +313,13 @@ static void bta_dm_search_cancel() { active */ else if (!bta_dm_search_cb.name_discover_done) { get_btm_client_interface().peer.BTM_CancelRemoteDeviceName(); - bta_dm_search_cmpl(); +#ifndef TARGET_FLOSS + /* bta_dm_search_cmpl is called when receiving the remote name cancel evt */ + if (!IS_FLAG_ENABLED( + bta_dm_defer_device_discovery_state_change_until_rnr_complete)) { + bta_dm_search_cmpl(); + } +#endif } else { bta_dm_inq_cmpl(0); } @@ -340,9 +352,10 @@ static void bta_dm_discover(tBTA_DM_MSG* p_data) { bta_dm_search_cb.name_discover_done = false; - LOG_INFO("bta_dm_discovery: starting service discovery to %s , transport: %s", - ADDRESS_TO_LOGGABLE_CSTR(p_data->discover.bd_addr), - bt_transport_text(p_data->discover.transport).c_str()); + log::info( + "bta_dm_discovery: starting service discovery to {} , transport: {}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->discover.bd_addr), + bt_transport_text(p_data->discover.transport)); bta_dm_discover_device(p_data->discover.bd_addr); } @@ -364,10 +377,10 @@ static void bta_dm_disable_search_and_disc(void) { case BTA_DM_SEARCH_CANCELLING: case BTA_DM_DISCOVER_ACTIVE: default: - LOG_DEBUG( + log::debug( "Search state machine is not idle so issuing search cancel current " - "state:%s", - bta_dm_state_text(bta_dm_search_get_state()).c_str()); + "state:{}", + bta_dm_state_text(bta_dm_search_get_state())); bta_dm_search_cancel(); } } @@ -385,7 +398,7 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, tBT_TRANSPORT transport) { tBTM_STATUS btm_status; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_dm_search_cb.peer_bdaddr = bd_addr; bta_dm_search_cb.peer_name[0] = 0; @@ -394,11 +407,11 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, bta_dm_search_cb.peer_bdaddr, bta_dm_remname_cback, transport); if (btm_status == BTM_CMD_STARTED) { - LOG_VERBOSE("%s: BTM_ReadRemoteDeviceName is started", __func__); + log::verbose("BTM_ReadRemoteDeviceName is started"); return (true); } else if (btm_status == BTM_BUSY) { - LOG_VERBOSE("%s: BTM_ReadRemoteDeviceName is busy", __func__); + log::verbose("BTM_ReadRemoteDeviceName is busy"); /* Remote name discovery is on going now so BTM cannot notify through * "bta_dm_remname_cback" */ @@ -409,8 +422,7 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, return (true); } else { - LOG_WARN("%s: BTM_ReadRemoteDeviceName returns 0x%02X", __func__, - btm_status); + log::warn("BTM_ReadRemoteDeviceName returns 0x{:02X}", btm_status); return (false); } @@ -438,7 +450,7 @@ static void bta_dm_inq_cmpl(uint8_t num) { tBTA_DM_SEARCH data; - LOG_VERBOSE("bta_dm_inq_cmpl"); + log::verbose("bta_dm_inq_cmpl"); data.inq_cmpl.num_resps = num; bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data); @@ -497,7 +509,7 @@ static void bta_dm_remote_name_cmpl(const tBTA_DM_MSG* p_data) { } bta_dm_search_cb.p_search_cback(BTA_DM_NAME_READ_EVT, &search_data); } else { - LOG_WARN("Received remote name complete without callback"); + log::warn("Received remote name complete without callback"); } switch (bta_dm_search_get_state()) { @@ -509,8 +521,8 @@ static void bta_dm_remote_name_cmpl(const tBTA_DM_MSG* p_data) { break; case BTA_DM_SEARCH_IDLE: case BTA_DM_SEARCH_CANCELLING: - LOG_WARN("Received remote name request in state:%s", - bta_dm_state_text(bta_dm_search_get_state()).c_str()); + log::warn("Received remote name request in state:{}", + bta_dm_state_text(bta_dm_search_get_state())); break; } } @@ -529,13 +541,13 @@ static void store_avrcp_profile_feature(tSDP_DISC_REC* sdp_rec) { } if (btif_config_set_bin(sdp_rec->remote_bd_addr.ToString().c_str(), - AV_REM_CTRL_FEATURES_CONFIG_KEY, + BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES, (const uint8_t*)&avrcp_features, sizeof(avrcp_features))) { - LOG_INFO("Saving avrcp_features: 0x%x", avrcp_features); + log::info("Saving avrcp_features: 0x{:x}", avrcp_features); } else { - LOG_INFO("Failed to store avrcp_features 0x%x for %s", avrcp_features, - ADDRESS_TO_LOGGABLE_CSTR(sdp_rec->remote_bd_addr)); + log::info("Failed to store avrcp_features 0x{:x} for {}", avrcp_features, + ADDRESS_TO_LOGGABLE_CSTR(sdp_rec->remote_bd_addr)); } } @@ -551,7 +563,7 @@ static void bta_dm_store_audio_profiles_version() { { .servclass_uuid = UUID_SERVCLASS_AV_REMOTE_CONTROL, .btprofile_uuid = UUID_SERVCLASS_AV_REMOTE_CONTROL, - .profile_key = AVRCP_CONTROLLER_VERSION_CONFIG_KEY, + .profile_key = BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION, .store_audio_profile_feature = store_avrcp_profile_feature, }, }}; @@ -575,8 +587,8 @@ static void bta_dm_store_audio_profiles_version() { (const uint8_t*)&profile_version, sizeof(profile_version))) { } else { - LOG_INFO("Failed to store peer profile version for %s", - ADDRESS_TO_LOGGABLE_CSTR(sdp_rec->remote_bd_addr)); + log::info("Failed to store peer profile version for {}", + ADDRESS_TO_LOGGABLE_CSTR(sdp_rec->remote_bd_addr)); } } audio_profile.store_audio_profile_feature(sdp_rec); @@ -606,7 +618,7 @@ static void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) || (p_data->sdp_event.sdp_result == SDP_DB_FULL)) { - LOG_VERBOSE("sdp_result::0x%x", p_data->sdp_event.sdp_result); + log::verbose("sdp_result::0x{:x}", p_data->sdp_event.sdp_result); do { p_sdp_rec = NULL; if (bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1)) { @@ -643,7 +655,7 @@ static void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { } while (p_sdp_rec); if (!gatt_uuids.empty()) { - LOG_INFO("GATT services discovered using SDP"); + log::info("GATT services discovered using SDP"); // send all result back to app tBTA_DM_SEARCH result; @@ -682,8 +694,7 @@ static void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID); - LOG_VERBOSE("%s services_found = %04x", __func__, - bta_dm_search_cb.services_found); + log::verbose("services_found = {:04x}", bta_dm_search_cb.services_found); /* Collect the 128-bit services here and put them into the list */ if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) { @@ -760,16 +771,16 @@ static void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { if (bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0 && bta_dm_search_cb.p_sdp_db->raw_data != NULL) { - LOG_VERBOSE("%s raw_data used = 0x%x raw_data_ptr = 0x%p", __func__, - bta_dm_search_cb.p_sdp_db->raw_used, - bta_dm_search_cb.p_sdp_db->raw_data); + log::verbose("raw_data used = 0x{:x} raw_data_ptr = 0x{}", + bta_dm_search_cb.p_sdp_db->raw_used, + fmt::ptr(bta_dm_search_cb.p_sdp_db->raw_data)); bta_dm_search_cb.p_sdp_db->raw_data = NULL; // no need to free this - it is a global assigned. bta_dm_search_cb.p_sdp_db->raw_used = 0; bta_dm_search_cb.p_sdp_db->raw_size = 0; } else { - LOG_VERBOSE("%s raw data size is 0 or raw_data is null!!", __func__); + log::verbose("raw data size is 0 or raw_data is null!!"); } /* Done with p_sdp_db. Free it */ bta_dm_free_sdp_db(); @@ -782,8 +793,8 @@ static void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { static_cast((3 + bta_dm_search_cb.peer_scn)); p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK; - LOG_VERBOSE(" Piggy back the SCN over result field SCN=%d", - bta_dm_search_cb.peer_scn); + log::verbose("Piggy back the SCN over result field SCN={}", + bta_dm_search_cb.peer_scn); } p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr; strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, @@ -795,7 +806,7 @@ static void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { BTM_LogHistory( kBtmLogTag, bta_dm_search_cb.peer_bdaddr, "Discovery failed", base::StringPrintf("Result:%s", sdp_result_text(sdp_result).c_str())); - LOG_ERROR("SDP connection failed %s", sdp_status_text(sdp_result).c_str()); + log::error("SDP connection failed {}", sdp_status_text(sdp_result)); if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED) bta_dm_search_cb.wait_disc = false; @@ -824,7 +835,7 @@ static void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { static void bta_dm_read_dis_cmpl(const RawAddress& addr, tDIS_VALUE* p_dis_value) { if (!p_dis_value) { - LOG_WARN("read DIS failed"); + log::warn("read DIS failed"); } else { tBTA_DM_SEARCH result; result.did_res.bd_addr = addr; @@ -869,11 +880,11 @@ static void bta_dm_search_cmpl() { /* no BLE connection, i.e. Classic service discovery end */ if (conn_id == GATT_INVALID_CONN_ID) { if (bta_dm_search_cb.gatt_disc_active) { - LOG_WARN( + log::warn( "GATT active but no BLE connection, likely disconnected midway " "through"); } else { - LOG_INFO("No BLE connection, processing classic results"); + log::info("No BLE connection, processing classic results"); } } else { btgatt_db_element_t* db = NULL; @@ -888,18 +899,18 @@ static void bta_dm_search_cmpl() { } } osi_free(db); - LOG_INFO( + log::info( "GATT services discovered using LE Transport, will always send to " "upper layer"); send_gatt_results = true; } else { - LOG_WARN("Empty GATT database - no BLE services discovered"); + log::warn("Empty GATT database - no BLE services discovered"); } } // send all result back to app if (send_gatt_results) { - LOG_INFO("Sending GATT results to upper layer"); + log::info("Sending GATT results to upper layer"); bta_dm_search_cb.p_search_cback(BTA_DM_GATT_OVER_LE_RES_EVT, &result); } @@ -928,7 +939,7 @@ static void bta_dm_search_cmpl() { * ******************************************************************************/ static void bta_dm_disc_result(tBTA_DM_MSG* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* disc_res.device_type is set only when GATT discovery is finished in * bta_dm_gatt_disc_complete */ @@ -958,9 +969,8 @@ static void bta_dm_disc_result(tBTA_DM_MSG* p_data) { * ******************************************************************************/ static void bta_dm_search_result(tBTA_DM_MSG* p_data) { - LOG_VERBOSE("%s searching:0x%04x, result:0x%04x", __func__, - bta_dm_search_cb.services, - p_data->disc_result.result.disc_res.services); + log::verbose("searching:0x{:04x}, result:0x{:04x}", bta_dm_search_cb.services, + p_data->disc_result.result.disc_res.services); /* call back if application wants name discovery or found services that * application is searching */ @@ -971,7 +981,7 @@ static void bta_dm_search_result(tBTA_DM_MSG* p_data) { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result); } else { - LOG_WARN("Received search result without valid callback"); + log::warn("Received search result without valid callback"); } } @@ -999,7 +1009,7 @@ static void bta_dm_search_result(tBTA_DM_MSG* p_data) { * ******************************************************************************/ static void bta_dm_search_timer_cback(UNUSED_ATTR void* data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_dm_search_cb.wait_disc = false; /* proceed with next device */ @@ -1030,13 +1040,13 @@ static void bta_dm_free_sdp_db() { ******************************************************************************/ static void bta_dm_queue_search(tBTA_DM_MSG* p_data) { if (bta_dm_search_cb.p_pending_search) { - LOG_WARN("Overwrote previous device discovery inquiry scan request"); + log::warn("Overwrote previous device discovery inquiry scan request"); } osi_free_and_reset((void**)&bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_SEARCH)); memcpy(bta_dm_search_cb.p_pending_search, p_data, sizeof(tBTA_DM_API_SEARCH)); - LOG_INFO("Queued device discovery inquiry scan request"); + log::info("Queued device discovery inquiry scan request"); } /******************************************************************************* @@ -1053,8 +1063,8 @@ static void bta_dm_queue_disc(tBTA_DM_MSG* p_data) { (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER)); memcpy(p_pending_discovery, p_data, sizeof(tBTA_DM_API_DISCOVER)); - LOG_INFO("bta_dm_discovery: queuing service discovery to %s", - ADDRESS_TO_LOGGABLE_CSTR(p_pending_discovery->discover.bd_addr)); + log::info("bta_dm_discovery: queuing service discovery to {}", + ADDRESS_TO_LOGGABLE_CSTR(p_pending_discovery->discover.bd_addr)); fixed_queue_enqueue(bta_dm_search_cb.pending_discovery_queue, p_pending_discovery); } @@ -1072,10 +1082,10 @@ static void bta_dm_execute_queued_request() { tBTA_DM_MSG* p_pending_discovery = (tBTA_DM_MSG*)fixed_queue_try_dequeue( bta_dm_search_cb.pending_discovery_queue); if (p_pending_discovery) { - LOG_INFO("%s Start pending discovery", __func__); + log::info("Start pending discovery"); bta_sys_sendmsg(p_pending_discovery); } else if (bta_dm_search_cb.p_pending_search) { - LOG_INFO("%s Start pending search", __func__); + log::info("Start pending search"); bta_sys_sendmsg(bta_dm_search_cb.p_pending_search); bta_dm_search_cb.p_pending_search = NULL; } @@ -1155,12 +1165,12 @@ static void bta_dm_find_services(const RawAddress& bd_addr) { bta_dm_search_cb.service_index))) { bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_DM_SDP_DB_SIZE); - LOG_VERBOSE("bta_dm_search_cb.services = %04x***********", - bta_dm_search_cb.services); + log::verbose("bta_dm_search_cb.services = {:04x}***********", + bta_dm_search_cb.services); /* try to search all services by search based on L2CAP UUID */ if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) { - LOG_INFO("%s services_to_search=%08x", __func__, - bta_dm_search_cb.services_to_search); + log::info("services_to_search={:08x}", + bta_dm_search_cb.services_to_search); if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) { uuid = Uuid::From16Bit(bta_service_id_to_uuid_lkup_tbl[0]); bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK; @@ -1185,7 +1195,7 @@ static void bta_dm_find_services(const RawAddress& bd_addr) { } } - LOG_INFO("%s search UUID = %s", __func__, uuid.ToString().c_str()); + log::info("search UUID = {}", uuid.ToString()); get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb( bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL); @@ -1207,7 +1217,7 @@ static void bta_dm_find_services(const RawAddress& bd_addr) { } else { if (uuid == Uuid::From16Bit(UUID_PROTOCOL_L2CAP)) { if (!is_sdp_pbap_pce_disabled(bd_addr)) { - LOG_DEBUG("SDP search for PBAP Client "); + log::debug("SDP search for PBAP Client"); BTA_SdpSearch(bd_addr, Uuid::From16Bit(UUID_SERVCLASS_PBAP_PCE)); } } @@ -1245,7 +1255,7 @@ static void bta_dm_find_services(const RawAddress& bd_addr) { * ******************************************************************************/ static void bta_dm_discover_next_device(void) { - LOG_VERBOSE("bta_dm_discover_next_device"); + log::verbose("bta_dm_discover_next_device"); /* searching next device on inquiry result */ bta_dm_search_cb.p_btm_inq_info = get_btm_client_interface().db.BTM_InqDbNext( @@ -1305,18 +1315,19 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { const tBT_TRANSPORT transport = bta_dm_determine_discovery_transport(remote_bd_addr); - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(remote_bd_addr); + log::verbose("BDA: {}", ADDRESS_TO_LOGGABLE_STR(remote_bd_addr)); bta_dm_search_cb.peer_bdaddr = remote_bd_addr; - LOG_VERBOSE( - "%s name_discover_done = %d p_btm_inq_info 0x%p state = %d, transport=%d", - __func__, bta_dm_search_cb.name_discover_done, - bta_dm_search_cb.p_btm_inq_info, bta_dm_search_get_state(), transport); + log::verbose( + "name_discover_done = {} p_btm_inq_info 0x{} state = {}, transport={}", + bta_dm_search_cb.name_discover_done, + fmt::ptr(bta_dm_search_cb.p_btm_inq_info), bta_dm_search_get_state(), + transport); if (bta_dm_search_cb.p_btm_inq_info) { - LOG_VERBOSE("%s appl_knows_rem_name %d", __func__, - bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name); + log::verbose("appl_knows_rem_name {}", + bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name); } if (((bta_dm_search_cb.p_btm_inq_info) && (bta_dm_search_cb.p_btm_inq_info->results.device_type == @@ -1331,8 +1342,9 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { // If we already have the name we can skip getting the name if (BTM_IsRemoteNameKnown(remote_bd_addr, transport) && bluetooth::common::init_flags::sdp_skip_rnr_if_known_is_enabled()) { - LOG_DEBUG("Security record already known skipping read remote name peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); + log::debug( + "Security record already known skipping read remote name peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); bta_dm_search_cb.name_discover_done = true; } @@ -1344,7 +1356,7 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport)) { if (bta_dm_search_get_state() != BTA_DM_DISCOVER_ACTIVE) { - LOG_DEBUG("Reset transport state for next discovery"); + log::debug("Reset transport state for next discovery"); bta_dm_search_cb.transport = BT_TRANSPORT_AUTO; } BTM_LogHistory(kBtmLogTag, bta_dm_search_cb.peer_bdaddr, @@ -1353,7 +1365,7 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { bt_transport_text(transport).c_str())); return; } else { - LOG_ERROR("Unable to start read remote device name"); + log::error("Unable to start read remote device name"); } /* starting name discovery failed */ @@ -1365,8 +1377,8 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { bool sdp_disable = HID_HostSDPDisable(remote_bd_addr); if (sdp_disable) - LOG_DEBUG("peer:%s with HIDSDPDisable attribute.", - ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); + log::debug("peer:{} with HIDSDPDisable attribute.", + ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); /* if application wants to discover service and HIDSDPDisable attribute is false. @@ -1396,18 +1408,18 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { bta_dm_search_cb.wait_disc = true; } if (bta_dm_search_cb.p_btm_inq_info) { - LOG_VERBOSE( - "%s p_btm_inq_info 0x%p results.device_type 0x%x " - "services_to_search 0x%x", - __func__, bta_dm_search_cb.p_btm_inq_info, + log::verbose( + "p_btm_inq_info 0x{} results.device_type 0x{:x} services_to_search " + "0x{:x}", + fmt::ptr(bta_dm_search_cb.p_btm_inq_info), bta_dm_search_cb.p_btm_inq_info->results.device_type, bta_dm_search_cb.services_to_search); } if (transport == BT_TRANSPORT_LE) { if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) { - LOG_INFO("bta_dm_discovery: starting GATT discovery on %s", - ADDRESS_TO_LOGGABLE_CSTR(bta_dm_search_cb.peer_bdaddr)); + log::info("bta_dm_discovery: starting GATT discovery on {}", + ADDRESS_TO_LOGGABLE_CSTR(bta_dm_search_cb.peer_bdaddr)); // set the raw data buffer here memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf)); /* start GATT for service discovery */ @@ -1415,8 +1427,8 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { return; } } else { - LOG_INFO("bta_dm_discovery: starting SDP discovery on %s", - ADDRESS_TO_LOGGABLE_CSTR(bta_dm_search_cb.peer_bdaddr)); + log::info("bta_dm_discovery: starting SDP discovery on {}", + ADDRESS_TO_LOGGABLE_CSTR(bta_dm_search_cb.peer_bdaddr)); bta_dm_search_cb.sdp_results = false; bta_dm_find_services(bta_dm_search_cb.peer_bdaddr); return; @@ -1478,7 +1490,7 @@ static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir, // Pass the original address to GattService#onScanResult result.inq_res.original_bda = p_inq->original_bda; - memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN); + result.inq_res.dev_class = p_inq->dev_class; BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class); result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false; @@ -1526,7 +1538,7 @@ static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir, * ******************************************************************************/ static void bta_dm_inq_cmpl_cb(void* p_result) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_dm_inq_cmpl(((tBTM_INQUIRY_CMPL*)p_result)->num_resp); } @@ -1546,7 +1558,7 @@ static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, tBTM_REMOTE_DEV_NAME rem_name = {}; tBTM_STATUS btm_status; - LOG_VERBOSE("%s name=<%s>", __func__, bd_name); + log::verbose("name=<{}>", reinterpret_cast(bd_name)); /* if this is what we are looking for */ if (bta_dm_search_cb.peer_bdaddr == bd_addr) { @@ -1566,11 +1578,10 @@ static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, BT_TRANSPORT_BR_EDR); if (btm_status == BTM_BUSY) { /* wait for next chance(notification of remote name discovery done) */ - LOG_VERBOSE("%s: BTM_ReadRemoteDeviceName is busy", __func__); + log::verbose("BTM_ReadRemoteDeviceName is busy"); } else if (btm_status != BTM_CMD_STARTED) { /* if failed to start getting remote name then continue */ - LOG_WARN("%s: BTM_ReadRemoteDeviceName returns 0x%02X", __func__, - btm_status); + log::warn("BTM_ReadRemoteDeviceName returns 0x{:02X}", btm_status); // needed so our response is not ignored, since this corresponds to the // actual peer_bdaddr @@ -1596,12 +1607,12 @@ static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, static void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p_remote_name) { CHECK(p_remote_name != nullptr); - LOG_INFO( - "Remote name request complete peer:%s btm_status:%s hci_status:%s " - "name[0]:%c length:%hu", + log::info( + "Remote name request complete peer:{} btm_status:{} hci_status:{} " + "name[0]:{:c} length:{}", ADDRESS_TO_LOGGABLE_CSTR(p_remote_name->bd_addr), - btm_status_text(p_remote_name->status).c_str(), - hci_error_code_text(p_remote_name->hci_status).c_str(), + btm_status_text(p_remote_name->status), + hci_error_code_text(p_remote_name->hci_status), p_remote_name->remote_bd_name[0], p_remote_name->length); if (bta_dm_search_cb.peer_bdaddr == p_remote_name->bd_addr) { @@ -1614,13 +1625,13 @@ static void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p_remote_name) { if (p_remote_name->hci_status == HCI_ERR_CONNECTION_EXISTS) { get_btm_client_interface().security.BTM_SecDeleteRmtNameNotifyCallback( &bta_dm_service_search_remname_cback); - LOG_INFO( - "Assume command failed due to disconnection hci_status:%s peer:%s", - hci_error_code_text(p_remote_name->hci_status).c_str(), + log::info( + "Assume command failed due to disconnection hci_status:{} peer:{}", + hci_error_code_text(p_remote_name->hci_status), ADDRESS_TO_LOGGABLE_CSTR(p_remote_name->bd_addr)); } else { - LOG_INFO( - "Ignored remote name response for the wrong address exp:%s act:%s", + log::info( + "Ignored remote name response for the wrong address exp:{} act:{}", ADDRESS_TO_LOGGABLE_CSTR(bta_dm_search_cb.peer_bdaddr), ADDRESS_TO_LOGGABLE_CSTR(p_remote_name->bd_addr)); return; @@ -1693,7 +1704,7 @@ static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir, uint16_t eir_len) { tBTA_DM_SEARCH result; tBTM_INQ_INFO* p_inq_info; - LOG_VERBOSE("bta_dm_observe_results_cb"); + log::verbose("bta_dm_observe_results_cb"); result.inq_res.bd_addr = p_inq->remote_bd_addr; result.inq_res.original_bda = p_inq->original_bda; @@ -1797,7 +1808,7 @@ static void bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS* p_inq, static void bta_dm_observe_cmpl_cb(void* p_result) { tBTA_DM_SEARCH data; - LOG_VERBOSE("bta_dm_observe_cmpl_cb"); + log::verbose("bta_dm_observe_cmpl_cb"); data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL*)p_result)->num_resp; if (bta_dm_search_cb.p_scan_cback) { @@ -1821,7 +1832,7 @@ static void bta_dm_start_scan(uint8_t duration_sec, .num_resps = 0, }, }; - LOG_WARN(" %s BTM_BleObserve failed. status %d", __func__, status); + log::warn("BTM_BleObserve failed. status {}", status); if (bta_dm_search_cb.p_scan_cback) { bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data); } @@ -1895,14 +1906,14 @@ static void bta_dm_gattc_register(void) { "%-32s client_id:%hu status:%s", "GATTC_RegisteredCallback", client_id, gatt_status_text(gatt_status).c_str())); if (static_cast(status) == GATT_SUCCESS) { - LOG_INFO( - "Registered device discovery search gatt client tGATT_IF:%hhu", + log::info( + "Registered device discovery search gatt client tGATT_IF:{}", client_id); bta_dm_search_cb.client_if = client_id; } else { - LOG_WARN( - "Failed to register device discovery search gatt client" - " gatt_status:%hhu previous tGATT_IF:%hhu", + log::warn( + "Failed to register device discovery search gatt client " + "gatt_status:{} previous tGATT_IF:{}", bta_dm_search_cb.client_if, status); bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF; } @@ -1920,7 +1931,7 @@ static void bta_dm_gattc_register(void) { * ******************************************************************************/ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) { - LOG_VERBOSE("%s conn_id = %d", __func__, conn_id); + log::verbose("conn_id = {}", conn_id); tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); @@ -1928,8 +1939,7 @@ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) { p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; p_msg->disc_result.result.disc_res.result = (status == GATT_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE; - LOG_VERBOSE("%s service found: 0x%08x", __func__, - bta_dm_search_cb.services_found); + log::verbose("service found: 0x{:08x}", bta_dm_search_cb.services_found); p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found; p_msg->disc_result.result.disc_res.num_uuids = 0; p_msg->disc_result.result.disc_res.p_uuid_list = NULL; @@ -1961,6 +1971,14 @@ static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) { bta_dm_clear_conn_id_on_client_close_is_enabled()) { bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID; } + + if (IS_FLAG_ENABLED(bta_dm_disc_stuck_in_cancelling_fix)) { + log::info( + "Discovery complete for invalid conn ID. Will pick up next job"); + bta_dm_search_set_state(BTA_DM_SEARCH_IDLE); + bta_dm_free_sdp_db(); + bta_dm_execute_queued_request(); + } } } @@ -2006,21 +2024,19 @@ static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) { } else { if (get_btm_client_interface().peer.BTM_IsAclConnectionUp( bd_addr, BT_TRANSPORT_LE)) { - LOG_DEBUG( - "Use existing gatt client connection for discovery peer:%s " - "transport:%s opportunistic:%c", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(BT_TRANSPORT_LE).c_str(), + log::debug( + "Use existing gatt client connection for discovery peer:{} " + "transport:{} opportunistic:{:c}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(BT_TRANSPORT_LE), (kUseOpportunistic) ? 'T' : 'F'); get_gatt_interface().BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, BTM_BLE_DIRECT_CONNECTION, kUseOpportunistic); } else { - LOG_DEBUG( - "Opening new gatt client connection for discovery peer:%s " - "transport:%s opportunistic:%c", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(BT_TRANSPORT_LE).c_str(), + log::debug( + "Opening new gatt client connection for discovery peer:{} " + "transport:{} opportunistic:{:c}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(BT_TRANSPORT_LE), (!kUseOpportunistic) ? 'T' : 'F'); get_gatt_interface().BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, BTM_BLE_DIRECT_CONNECTION, @@ -2039,12 +2055,13 @@ static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) { * ******************************************************************************/ static void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) { - VLOG(1) << "DM Search state= " << bta_dm_search_get_state() - << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr - << " connected_bda=" << p_data->remote_bda.address; + log::verbose("DM Search state= {} search_cb.peer_dbaddr:{} connected_bda={}", + bta_dm_search_get_state(), + ADDRESS_TO_LOGGABLE_STR(bta_dm_search_cb.peer_bdaddr), + ADDRESS_TO_LOGGABLE_STR(p_data->remote_bda)); - LOG_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d", - p_data->conn_id, p_data->client_if, p_data->status); + log::debug("BTA_GATTC_OPEN_EVT conn_id = {} client_if={} status = {}", + p_data->conn_id, p_data->client_if, p_data->status); disc_gatt_history_.Push(base::StringPrintf( "%-32s bd_addr:%s conn_id:%hu client_if:%hu event:%s", @@ -2062,37 +2079,6 @@ static void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) { } } -void bta_dm_proc_close_evt(const tBTA_GATTC_CLOSE& close) { - LOG_INFO("Gatt connection closed peer:%s reason:%s", - ADDRESS_TO_LOGGABLE_CSTR(close.remote_bda), - gatt_disconnection_reason_text(close.reason).c_str()); - - disc_gatt_history_.Push(base::StringPrintf( - "%-32s bd_addr:%s client_if:%hu status:%s event:%s", - "GATTC_EventCallback", ADDRESS_TO_LOGGABLE_CSTR(close.remote_bda), - close.client_if, gatt_status_text(close.status).c_str(), - gatt_client_event_text(BTA_GATTC_CLOSE_EVT).c_str())); - - if (close.remote_bda == bta_dm_search_cb.peer_bdaddr) { - if (bluetooth::common::init_flags:: - bta_dm_clear_conn_id_on_client_close_is_enabled()) { - LOG_DEBUG("Clearing connection id on client close"); - bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID; - } - } else { - LOG_WARN("Received close event for unknown peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(close.remote_bda)); - } - - /* in case of disconnect before search is completed */ - if ((bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) && - (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) && - close.remote_bda == bta_dm_search_cb.peer_bdaddr) { - bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, - (tGATT_STATUS)GATT_ERROR); - } -} - /******************************************************************************* * * Function bta_dm_gattc_callback @@ -2103,7 +2089,7 @@ void bta_dm_proc_close_evt(const tBTA_GATTC_CLOSE& close) { * ******************************************************************************/ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { - LOG_VERBOSE("bta_dm_gattc_callback event = %d", event); + log::verbose("bta_dm_gattc_callback event = {}", event); switch (event) { case BTA_GATTC_OPEN_EVT: @@ -2128,7 +2114,7 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { break; case BTA_GATTC_CLOSE_EVT: - LOG_INFO("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason); + log::info("BTA_GATTC_CLOSE_EVT reason = {}", p_data->close.reason); if (p_data->close.remote_bda == bta_dm_search_cb.peer_bdaddr) { if (bluetooth::common::init_flags:: @@ -2249,9 +2235,9 @@ void bta_dm_search_sm_disable() { bta_sys_deregister(BTA_ID_DM_SEARCH); } ******************************************************************************/ bool bta_dm_search_sm_execute(const BT_HDR_RIGID* p_msg) { const tBTA_DM_EVT event = static_cast(p_msg->event); - LOG_INFO("state:%s, event:%s[0x%x]", - bta_dm_state_text(bta_dm_search_get_state()).c_str(), - bta_dm_event_text(event).c_str(), event); + log::info("state:{}, event:{}[0x{:x}]", + bta_dm_state_text(bta_dm_search_get_state()), + bta_dm_event_text(event), event); search_state_history_.Push({ .state = bta_dm_search_get_state(), .event = event, @@ -2279,9 +2265,9 @@ bool bta_dm_search_sm_execute(const BT_HDR_RIGID* p_msg) { bta_dm_close_gatt_conn(message); break; default: - LOG_INFO("Received unexpected event %s[0x%x] in state %s", - bta_dm_event_text(event).c_str(), event, - bta_dm_state_text(bta_dm_search_get_state()).c_str()); + log::info("Received unexpected event {}[0x{:x}] in state {}", + bta_dm_event_text(event), event, + bta_dm_state_text(bta_dm_search_get_state())); } break; case BTA_DM_SEARCH_ACTIVE: @@ -2307,9 +2293,9 @@ bool bta_dm_search_sm_execute(const BT_HDR_RIGID* p_msg) { bta_dm_search_cancel(); break; default: - LOG_INFO("Received unexpected event %s[0x%x] in state %s", - bta_dm_event_text(event).c_str(), event, - bta_dm_state_text(bta_dm_search_get_state()).c_str()); + log::info("Received unexpected event {}[0x{:x}] in state {}", + bta_dm_event_text(event), event, + bta_dm_state_text(bta_dm_search_get_state())); } break; case BTA_DM_SEARCH_CANCELLING: @@ -2341,9 +2327,9 @@ bool bta_dm_search_sm_execute(const BT_HDR_RIGID* p_msg) { } [[fallthrough]]; default: - LOG_INFO("Received unexpected event %s[0x%x] in state %s", - bta_dm_event_text(event).c_str(), event, - bta_dm_state_text(bta_dm_search_get_state()).c_str()); + log::info("Received unexpected event {}[0x{:x}] in state {}", + bta_dm_event_text(event), event, + bta_dm_state_text(bta_dm_search_get_state())); } break; case BTA_DM_DISCOVER_ACTIVE: @@ -2379,9 +2365,9 @@ bool bta_dm_search_sm_execute(const BT_HDR_RIGID* p_msg) { } [[fallthrough]]; default: - LOG_INFO("Received unexpected event %s[0x%x] in state %s", - bta_dm_event_text(event).c_str(), event, - bta_dm_state_text(bta_dm_search_get_state()).c_str()); + log::info("Received unexpected event {}[0x{:x}] in state {}", + bta_dm_event_text(event), event, + bta_dm_state_text(bta_dm_search_get_state())); } break; } @@ -2419,7 +2405,7 @@ void bta_dm_disc_acl_down(const RawAddress& bd_addr, tBT_TRANSPORT transport) { bta_dm_search_cb.wait_disc = false; if (bta_dm_search_cb.sdp_results) { - LOG_VERBOSE(" timer stopped "); + log::verbose("timer stopped"); alarm_cancel(bta_dm_search_cb.search_timer); bta_dm_disc_discover_next_device(); } @@ -2467,9 +2453,9 @@ void bta_dm_disc_start_service_discovery(tBTA_DM_SEARCH_CBACK* p_cback, bta_sys_sendmsg(p_msg); } -void bta_dm_disc_stop_service_discovery(const RawAddress& bd_addr, - tBT_TRANSPORT transport) { - LOG_WARN("Stop service discovery not yet implemented for legacy module"); +void bta_dm_disc_stop_service_discovery(const RawAddress& /* bd_addr */, + tBT_TRANSPORT /* transport */) { + log::warn("Stop service discovery not yet implemented for legacy module"); } #define DUMPSYS_TAG "shim::legacy::bta::dm" diff --git a/system/bta/dm/bta_dm_disc_int.h b/system/bta/dm/bta_dm_disc_int.h index 7a5c8a47bb93ac39df764211b123dff77006b956..f24c97b7f7344c5b9e1eb2846626fa11c604367d 100644 --- a/system/bta/dm/bta_dm_disc_int.h +++ b/system/bta/dm/bta_dm_disc_int.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include @@ -185,3 +186,10 @@ typedef struct { extern const uint32_t bta_service_id_to_btm_srv_id_lkup_tbl[]; extern const uint16_t bta_service_id_to_uuid_lkup_tbl[]; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/bta/dm/bta_dm_gatt_client.cc b/system/bta/dm/bta_dm_gatt_client.cc index 29656ea0e0823bd62ef1cb8b840b6daee7fd5251..46462053c03c84e053d181c78a285e848606eac0 100644 --- a/system/bta/dm/bta_dm_gatt_client.cc +++ b/system/bta/dm/bta_dm_gatt_client.cc @@ -23,7 +23,7 @@ #include #include "bta/include/bta_gatt_api.h" -#include "gd/common/strings.h" +#include "common/strings.h" #include "main/shim/dumpsys.h" #include "stack/btm/btm_int_types.h" #include "types/bluetooth/uuid.h" diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h index dfeaee59a2e4f106d926391b55931d34630ff602..8fcb4ec0f6d05444b28640d4b48ebde79a511085 100644 --- a/system/bta/dm/bta_dm_int.h +++ b/system/bta/dm/bta_dm_int.h @@ -25,8 +25,10 @@ #define BTA_DM_INT_H #include +#include #include +#include #include "bta/include/bta_api.h" #include "bta/include/bta_sec_api.h" @@ -40,13 +42,6 @@ * Constants and data types ****************************************************************************/ -#define BTA_COPY_DEVICE_CLASS(coddst, codsrc) \ - { \ - ((uint8_t*)(coddst))[0] = ((uint8_t*)(codsrc))[0]; \ - ((uint8_t*)(coddst))[1] = ((uint8_t*)(codsrc))[1]; \ - ((uint8_t*)(coddst))[2] = ((uint8_t*)(codsrc))[2]; \ - } - #define BTA_DM_MSG_LEN 50 #define BTA_DM_NUM_PEER_DEVICE 7 @@ -364,4 +359,9 @@ void bta_dm_ble_subrate_request(const RawAddress& bd_addr, uint16_t subrate_min, uint16_t subrate_max, uint16_t max_latency, uint16_t cont_num, uint16_t timeout); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* BTA_DM_INT_H */ diff --git a/system/bta/dm/bta_dm_pm.cc b/system/bta/dm/bta_dm_pm.cc index 95020a50589806a4dfe69e390b98529ae9fda9c5..b296db43c6d10bde782bd4db95c40248e0a95a2c 100644 --- a/system/bta/dm/bta_dm_pm.cc +++ b/system/bta/dm/bta_dm_pm.cc @@ -24,6 +24,7 @@ ******************************************************************************/ #include +#include #include #include @@ -34,9 +35,10 @@ #include "bta/include/bta_dm_api.h" #include "bta/sys/bta_sys.h" #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" -#include "device/include/controller.h" +#include "btif/include/stack_manager_t.h" +#include "hci/controller_interface.h" #include "main/shim/dumpsys.h" +#include "main/shim/entry.h" #include "os/log.h" #include "osi/include/properties.h" #include "stack/include/acl_api.h" @@ -44,6 +46,8 @@ #include "stack/include/main_thread.h" #include "types/raw_address.h" +using namespace bluetooth; + static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, uint8_t app_id, const RawAddress& peer_addr); static void bta_dm_pm_set_mode(const RawAddress& peer_addr, @@ -55,6 +59,8 @@ static void bta_dm_pm_btm_cback(const RawAddress& bd_addr, tHCI_STATUS hci_status); static bool bta_dm_pm_park(const RawAddress& peer_addr); void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index); +static void bta_dm_sniff_cback(uint8_t id, uint8_t app_id, + const RawAddress& peer_addr); static int bta_dm_get_sco_index(); static void bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER* p_timer, uint8_t timer_idx); @@ -95,6 +101,7 @@ void bta_dm_init_pm(void) { /* if there are no power manger entries, so not register */ if (p_bta_dm_pm_cfg[0].app_id != 0) { bta_sys_pm_register(bta_dm_pm_cback); + bta_sys_sniff_register(bta_dm_sniff_cback); get_btm_client_interface().lifecycle.BTM_PmRegister( (BTM_PM_REG_SET), &bta_dm_cb.pm_id, bta_dm_pm_btm_cback); @@ -165,7 +172,7 @@ uint8_t bta_dm_get_av_count(void) { * ******************************************************************************/ static void bta_dm_pm_stop_timer(const RawAddress& peer_addr) { - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); for (int i = 0; i < BTA_DM_NUM_PM_TIMER; i++) { if (bta_dm_cb.pm_timer[i].in_use && @@ -334,6 +341,71 @@ static void bta_dm_pm_stop_timer_by_index(tBTA_PM_TIMER* p_timer, alarm_cancel(p_timer->timer[timer_idx]); } +/******************************************************************************* + * + * Function bta_dm_sniff_cback + * + * Description Restart sniff timer for a peer + * + * + * Returns void + * + ******************************************************************************/ +static void bta_dm_sniff_cback(uint8_t id, uint8_t app_id, + const RawAddress& peer_addr) { + int i = 0, j = 0; + uint64_t timeout_ms = 0; + + tBTA_DM_PEER_DEVICE* p_peer_device = bta_dm_find_peer_device(peer_addr); + if (p_peer_device == NULL) { + log::info("No peer device found: {}", ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + return; + } + + /* Search for sniff table for timeout value + p_bta_dm_pm_cfg[0].app_id is the number of entries */ + for (j = 1; j <= p_bta_dm_pm_cfg[0].app_id; j++) { + if ((p_bta_dm_pm_cfg[j].id == id) && + ((p_bta_dm_pm_cfg[j].app_id == BTA_ALL_APP_ID) || + (p_bta_dm_pm_cfg[j].app_id == app_id))) + break; + } + // Handle overflow access + if (j > p_bta_dm_pm_cfg[0].app_id) { + log::info("No configuration found for {}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + return; + } + const tBTA_DM_PM_CFG* p_pm_cfg = &p_bta_dm_pm_cfg[j]; + const tBTA_DM_PM_SPEC* p_pm_spec = &get_bta_dm_pm_spec()[p_pm_cfg->spec_idx]; + const tBTA_DM_PM_ACTN* p_act0 = &p_pm_spec->actn_tbl[BTA_SYS_CONN_IDLE][0]; + const tBTA_DM_PM_ACTN* p_act1 = &p_pm_spec->actn_tbl[BTA_SYS_CONN_IDLE][1]; + + tBTA_DM_PM_ACTION failed_pm = p_peer_device->pm_mode_failed; + /* first check if the first preference is ok */ + if (!(failed_pm & p_act0->power_mode)) { + timeout_ms = p_act0->timeout; + } + /* if first preference has already failed, try second preference */ + else if (!(failed_pm & p_act1->power_mode)) { + timeout_ms = p_act1->timeout; + } + + /* Refresh the sniff timer */ + for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) { + if (bta_dm_cb.pm_timer[i].in_use && + bta_dm_cb.pm_timer[i].peer_bdaddr == peer_addr) { + int timer_idx = bta_pm_action_to_timer_idx(BTA_DM_PM_SNIFF); + if (timer_idx != BTA_DM_PM_MODE_TIMER_MAX) { + /* Cancel and restart the timer */ + bta_dm_pm_stop_timer_by_index(&bta_dm_cb.pm_timer[i], timer_idx); + bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[i], timer_idx, timeout_ms, id, + BTA_DM_PM_SNIFF); + } + } + } +} + /******************************************************************************* * * Function bta_dm_pm_cback @@ -350,9 +422,9 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, tBTA_DM_PEER_DEVICE* p_dev; tBTA_DM_PM_REQ pm_req = BTA_DM_PM_NEW_REQ; - LOG_DEBUG("Power management callback status:%s[%hhu] id:%s[%hhu], app:%hhu", - bta_sys_conn_status_text(status).c_str(), status, - BtaIdSysText(id).c_str(), id, app_id); + log::debug("Power management callback status:{}[{}] id:{}[{}], app:{}", + bta_sys_conn_status_text(status), status, BtaIdSysText(id), id, + app_id); /* find if there is an power mode entry for the service */ for (i = 1; i <= p_bta_dm_pm_cfg[0].app_id; i++) { @@ -365,19 +437,20 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, /* if no entries are there for the app_id and subsystem in * get_bta_dm_pm_spec()*/ if (i > p_bta_dm_pm_cfg[0].app_id) { - LOG_DEBUG("Ignoring power management callback as no service entries exist"); + log::debug( + "Ignoring power management callback as no service entries exist"); return; } - LOG_DEBUG("Stopped all timers for service to device:%s id:%s[%hhu]", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), BtaIdSysText(id).c_str(), id); + log::debug("Stopped all timers for service to device:{} id:{}[{}]", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), BtaIdSysText(id), id); bta_dm_pm_stop_timer_by_srvc_id(peer_addr, static_cast(id)); p_dev = bta_dm_find_peer_device(peer_addr); if (p_dev) { - LOG_DEBUG("Device info:%s", p_dev->info_text().c_str()); + log::debug("Device info:{}", p_dev->info_text()); } else { - LOG_ERROR("Unable to find peer device...yet soldiering on..."); + log::error("Unable to find peer device...yet soldiering on..."); } /* set SSR parameters on SYS CONN OPEN */ @@ -425,13 +498,13 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, sizeof(bta_dm_conn_srvcs.conn_srvc[j])); } } else { - LOG_WARN("bta_dm_act no entry for connected service cbs"); + log::warn("bta_dm_act no entry for connected service cbs"); return; } } else if (j == bta_dm_conn_srvcs.count) { /* check if we have more connected service that cbs */ if (bta_dm_conn_srvcs.count == BTA_DM_NUM_CONN_SRVS) { - LOG_WARN("bta_dm_act no more connected service cbs"); + log::warn("bta_dm_act no more connected service cbs"); return; } @@ -441,8 +514,8 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, bta_dm_conn_srvcs.conn_srvc[j].new_request = true; bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr = peer_addr; - LOG_INFO("New connection service:%s[%hhu] app_id:%d", - BtaIdSysText(id).c_str(), id, app_id); + log::info("New connection service:{}[{}] app_id:{}", BtaIdSysText(id), id, + app_id); bta_dm_conn_srvcs.count++; bta_dm_conn_srvcs.conn_srvc[j].state = status; @@ -455,10 +528,10 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, bta_dm_pm_stop_timer(peer_addr); if (bta_dm_conn_srvcs.count > 0) { pm_req = BTA_DM_PM_RESTART; - LOG_VERBOSE( - "%s bta_dm_pm_stop_timer for current service, restart other " - "service timers: count = %d", - __func__, bta_dm_conn_srvcs.count); + log::verbose( + "bta_dm_pm_stop_timer for current service, restart other service " + "timers: count = {}", + bta_dm_conn_srvcs.count); } if (p_dev) { @@ -471,22 +544,21 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, const tBTA_SYS_ID id, if (id != BTA_ID_AV || status != BTA_SYS_CONN_BUSY) { bta_dm_pm_ssr(peer_addr, index); } else { - LOG_DEBUG("%s: Do not perform SSR when AVDTP start", __func__); + log::debug("Do not perform SSR when AVDTP start"); } } else { - const controller_t* controller = controller_get_interface(); uint8_t* p = NULL; - if (controller->supports_sniff_subrating() && + if (bluetooth::shim::GetController()->SupportsSniffSubrating() && ((NULL != (p = get_btm_client_interface().peer.BTM_ReadRemoteFeatures( peer_addr))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) && (index == BTA_DM_PM_SSR0)) { if (status == BTA_SYS_SCO_OPEN) { - LOG_VERBOSE("%s: SCO inactive, reset SSR to zero", __func__); + log::verbose("SCO inactive, reset SSR to zero"); get_btm_client_interface().link_policy.BTM_SetSsrParams(peer_addr, 0, 0, 0); } else if (status == BTA_SYS_SCO_CLOSE) { - LOG_VERBOSE("%s: SCO active, back to old SSR", __func__); + log::verbose("SCO active, back to old SSR"); bta_dm_pm_ssr(peer_addr, BTA_DM_PM_SSR0); } } @@ -526,7 +598,7 @@ static void bta_dm_pm_set_mode(const RawAddress& peer_addr, uint64_t remaining_ms = 0; if (!bta_dm_cb.device_list.count) { - LOG_INFO("Device list count is zero"); + log::info("Device list count is zero"); return; } @@ -534,7 +606,7 @@ static void bta_dm_pm_set_mode(const RawAddress& peer_addr, p_peer_device = bta_dm_find_peer_device(peer_addr); /* if no peer device found return */ if (p_peer_device == NULL) { - LOG_INFO("No peer device found"); + log::info("No peer device found"); return; } @@ -557,11 +629,10 @@ static void bta_dm_pm_set_mode(const RawAddress& peer_addr, p_act1 = &p_pm_spec->actn_tbl[p_srvcs->state][1]; allowed_modes |= p_pm_spec->allow_mask; - LOG_DEBUG( - "Service:%s[%hhu] state:%s[%hhu] allowed_modes:0x%02x " - "service_index:%hhu ", - BtaIdSysText(p_srvcs->id).c_str(), p_srvcs->id, - bta_sys_conn_status_text(p_srvcs->state).c_str(), p_srvcs->state, + log::debug( + "Service:{}[{}] state:{}[{}] allowed_modes:0x{:02x} service_index:{}", + BtaIdSysText(p_srvcs->id), p_srvcs->id, + bta_sys_conn_status_text(p_srvcs->state), p_srvcs->state, allowed_modes, j); /* PM actions are in the order of strictness */ @@ -645,7 +716,7 @@ static void bta_dm_pm_set_mode(const RawAddress& peer_addr, timer_started = true; } } else { - LOG_WARN("no more timers"); + log::warn("no more timers"); } } return; @@ -653,30 +724,28 @@ static void bta_dm_pm_set_mode(const RawAddress& peer_addr, /* if pending power mode timer expires, and currecnt link is in a lower power mode than current profile requirement, igonre it */ if (pm_req == BTA_DM_PM_EXECUTE && pm_request < pm_action) { - LOG_ERROR("Ignore the power mode request: %d", pm_request); + log::error("Ignore the power mode request: {}", pm_request); return; } if (pm_action == BTA_DM_PM_PARK) { p_peer_device->pm_mode_attempted = BTA_DM_PM_PARK; bta_dm_pm_park(peer_addr); - LOG_WARN("DEPRECATED Setting link to park mode peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::warn("DEPRECATED Setting link to park mode peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); } else if (pm_action & BTA_DM_PM_SNIFF) { /* dont initiate SNIFF, if link_policy has it disabled */ if (BTM_is_sniff_allowed_for(peer_addr)) { - LOG_DEBUG( - "Link policy allows sniff mode so setting mode " - "peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::debug("Link policy allows sniff mode so setting mode peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); p_peer_device->pm_mode_attempted = BTA_DM_PM_SNIFF; bta_dm_pm_sniff(p_peer_device, (uint8_t)(pm_action & 0x0F)); } else { - LOG_DEBUG("Link policy disallows sniff mode, ignore request peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::debug("Link policy disallows sniff mode, ignore request peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); } } else if (pm_action == BTA_DM_PM_ACTIVE) { - LOG_DEBUG("Setting link to active mode peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::debug("Setting link to active mode peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); bta_dm_pm_active(peer_addr); } } @@ -695,8 +764,8 @@ static bool bta_dm_pm_park(const RawAddress& peer_addr) { /* if not in park mode, switch to park */ if (!BTM_ReadPowerMode(peer_addr, &mode)) { - LOG_WARN("Unable to read power mode for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::warn("Unable to read power mode for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); } if (mode != BTM_PM_MD_PARK) { @@ -706,7 +775,7 @@ static bool bta_dm_pm_park(const RawAddress& peer_addr) { if (status == BTM_CMD_STORED || status == BTM_CMD_STARTED) { return true; } - LOG_WARN("Unable to set park power mode"); + log::warn("Unable to set park power mode"); } return true; } @@ -780,29 +849,28 @@ void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index) { tBTM_STATUS status; if (!BTM_ReadPowerMode(p_peer_dev->peer_bdaddr, &mode)) { - LOG_WARN("Unable to read power mode for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_peer_dev->peer_bdaddr)); + log::warn("Unable to read power mode for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer_dev->peer_bdaddr)); } tBTM_PM_STATUS mode_status = static_cast(mode); - LOG_DEBUG("Current power mode:%s[0x%x] peer_info:%s", - power_mode_status_text(mode_status).c_str(), mode_status, - p_peer_dev->info_text().c_str()); + log::debug("Current power mode:{}[0x{:x}] peer_info:{}", + power_mode_status_text(mode_status), mode_status, + p_peer_dev->info_text()); uint8_t* p_rem_feat = get_btm_client_interface().peer.BTM_ReadRemoteFeatures( p_peer_dev->peer_bdaddr); - const controller_t* controller = controller_get_interface(); if (mode != BTM_PM_MD_SNIFF || - (controller->supports_sniff_subrating() && p_rem_feat && - HCI_SNIFF_SUB_RATE_SUPPORTED(p_rem_feat) && + (bluetooth::shim::GetController()->SupportsSniffSubrating() && + p_rem_feat && HCI_SNIFF_SUB_RATE_SUPPORTED(p_rem_feat) && !(p_peer_dev->is_ssr_active()))) { /* Dont initiate Sniff if controller has alreay accepted * remote sniff params. This avoid sniff loop issue with * some agrresive headsets who use sniff latencies more than * DUT supported range of Sniff intervals.*/ if ((mode == BTM_PM_MD_SNIFF) && (p_peer_dev->is_remote_init_sniff())) { - LOG_DEBUG("Link already in sniff mode peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_peer_dev->peer_bdaddr)); + log::debug("Link already in sniff mode peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer_dev->peer_bdaddr)); return; } } @@ -811,7 +879,7 @@ void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index) { tBTM_PM_PWR_MD sniff_entry = get_sniff_entry(index); memcpy(&pwr_md, &sniff_entry, sizeof(tBTM_PM_PWR_MD)); if (p_peer_dev->is_local_init_sniff()) { - LOG_DEBUG("Trying to force power mode"); + log::debug("Trying to force power mode"); pwr_md.mode |= BTM_PM_MD_FORCE; } status = get_btm_client_interface().link_policy.BTM_SetPowerMode( @@ -820,12 +888,12 @@ void bta_dm_pm_sniff(tBTA_DM_PEER_DEVICE* p_peer_dev, uint8_t index) { p_peer_dev->reset_sniff_flags(); p_peer_dev->set_sniff_command_sent(); } else if (status == BTM_SUCCESS) { - LOG_VERBOSE("bta_dm_pm_sniff BTM_SetPowerMode() returns BTM_SUCCESS"); + log::verbose("bta_dm_pm_sniff BTM_SetPowerMode() returns BTM_SUCCESS"); p_peer_dev->reset_sniff_flags(); } else { - LOG_ERROR("Unable to set power mode peer:%s status:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_peer_dev->peer_bdaddr), - btm_status_text(status).c_str()); + log::error("Unable to set power mode peer:{} status:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer_dev->peer_bdaddr), + btm_status_text(status)); p_peer_dev->reset_sniff_flags(); } } @@ -842,8 +910,8 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, const int ssr) { int ssr_index = ssr; tBTA_DM_SSR_SPEC* p_spec = &p_bta_dm_ssr_spec[ssr]; - LOG_DEBUG("Request to put link to device:%s into power_mode:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), p_spec->name); + log::debug("Request to put link to device:{} into power_mode:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), p_spec->name); /* go through the connected services */ for (int i = 0; i < bta_dm_conn_srvcs.count; i++) { const tBTA_DM_SRVCS& service = bta_dm_conn_srvcs.conn_srvc[i]; @@ -858,10 +926,10 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, const int ssr) { current_ssr_index = get_bta_dm_pm_spec()[config.spec_idx].ssr; if ((config.id == service.id) && ((config.app_id == BTA_ALL_APP_ID) || (config.app_id == service.app_id))) { - LOG_INFO("Found connected service:%s app_id:%d peer:%s spec_name:%s", - BtaIdSysText(service.id).c_str(), service.app_id, - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), - p_bta_dm_ssr_spec[current_ssr_index].name); + log::info("Found connected service:{} app_id:{} peer:{} spec_name:{}", + BtaIdSysText(service.id), service.app_id, + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), + p_bta_dm_ssr_spec[current_ssr_index].name); break; } } @@ -870,19 +938,23 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, const int ssr) { /* HH has the per connection SSR preference, already read the SSR params * from BTA HH */ if (current_ssr_index == BTA_DM_PM_SSR_HH) { + tAclLinkSpec link_spec; + link_spec.addrt.bda = peer_addr; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_BR_EDR; if (GetInterfaceToProfiles()->profileSpecific_HACK->bta_hh_read_ssr_param( - peer_addr, &p_spec_cur->max_lat, &p_spec_cur->min_rmt_to) == + link_spec, &p_spec_cur->max_lat, &p_spec_cur->min_rmt_to) == BTA_HH_ERR) { continue; } } if (p_spec_cur->max_lat < p_spec->max_lat || (ssr_index == BTA_DM_PM_SSR0 && current_ssr_index != BTA_DM_PM_SSR0)) { - LOG_DEBUG( - "Changing sniff subrating specification for %s from %s[%d] ==> " - "%s[%d]", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), p_spec->name, ssr_index, p_spec_cur->name, - current_ssr_index); + log::debug( + "Changing sniff subrating specification for {} from {}[{}] ==> " + "{}[{}]", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), p_spec->name, ssr_index, + p_spec_cur->name, current_ssr_index); ssr_index = current_ssr_index; p_spec = &p_bta_dm_ssr_spec[ssr_index]; } @@ -893,14 +965,15 @@ static void bta_dm_pm_ssr(const RawAddress& peer_addr, const int ssr) { int idx = bta_dm_get_sco_index(); if (idx != -1) { if (bta_dm_conn_srvcs.conn_srvc[idx].peer_bdaddr == peer_addr) { - LOG_WARN("SCO is active on device, ignore SSR"); + log::warn("SCO is active on device, ignore SSR"); return; } } - LOG_DEBUG( - "Setting sniff subrating for device:%s spec_name:%s max_latency(s):%.2f" - " min_local_timeout(s):%.2f min_remote_timeout(s):%.2f", + log::debug( + "Setting sniff subrating for device:{} spec_name:{} " + "max_latency(s):{:.2f} min_local_timeout(s):{:.2f} " + "min_remote_timeout(s):{:.2f}", ADDRESS_TO_LOGGABLE_CSTR(peer_addr), p_spec->name, ticks_to_seconds(p_spec->max_lat), ticks_to_seconds(p_spec->min_loc_to), ticks_to_seconds(p_spec->min_rmt_to)); @@ -929,20 +1002,20 @@ void bta_dm_pm_active(const RawAddress& peer_addr) { bta_dm_cb.pm_id, peer_addr, &pm); switch (status) { case BTM_CMD_STORED: - LOG_DEBUG("Active power mode stored for execution later for remote:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::debug("Active power mode stored for execution later for remote:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); break; case BTM_CMD_STARTED: - LOG_DEBUG("Active power mode started for remote:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::debug("Active power mode started for remote:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); break; case BTM_SUCCESS: - LOG_DEBUG("Active power mode already set for device:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::debug("Active power mode already set for device:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); break; default: - LOG_WARN("Unable to set active power mode for device:%s status:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), btm_status_text(status).c_str()); + log::warn("Unable to set active power mode for device:{} status:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), btm_status_text(status)); break; } } @@ -971,13 +1044,13 @@ static void bta_dm_pm_timer_cback(void* data) { std::unique_lock state_lock(pm_timer_state_mutex); for (i = 0; i < BTA_DM_NUM_PM_TIMER; i++) { - LOG_VERBOSE("dm_pm_timer[%d] in use? %d", i, bta_dm_cb.pm_timer[i].in_use); + log::verbose("dm_pm_timer[{}] in use? {}", i, bta_dm_cb.pm_timer[i].in_use); if (bta_dm_cb.pm_timer[i].in_use) { for (j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) { if (bta_dm_cb.pm_timer[i].timer[j] == alarm) { bta_dm_cb.pm_timer[i].active--; bta_dm_cb.pm_timer[i].srvc_id[j] = BTA_ID_MAX; - LOG_VERBOSE("dm_pm_timer[%d] expires, timer_idx=%d", i, j); + log::verbose("dm_pm_timer[{}] expires, timer_idx={}", i, j); break; } } @@ -1000,16 +1073,16 @@ static void bta_dm_pm_timer_cback(void* data) { /** Process pm status event from btm */ void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status, uint16_t interval, tHCI_STATUS hci_status) { - LOG_DEBUG( - "Power mode notification event status:%s peer:%s interval:%hu " - "hci_status:%s", - power_mode_status_text(status).c_str(), ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - interval, hci_error_code_text(hci_status).c_str()); + log::debug( + "Power mode notification event status:{} peer:{} interval:{} " + "hci_status:{}", + power_mode_status_text(status), ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + interval, hci_error_code_text(hci_status)); tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr); if (p_dev == nullptr) { - LOG_INFO("Unable to process power event for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Unable to process power event for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } @@ -1019,7 +1092,7 @@ void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status, /* if our sniff or park attempt failed we should not try it again*/ if (hci_status != 0) { - LOG_ERROR("%s hci_status=%d", __func__, hci_status); + log::error("hci_status={}", hci_status); p_dev->reset_sniff_flags(); if (p_dev->pm_mode_attempted & (BTA_DM_PM_PARK | BTA_DM_PM_SNIFF)) { @@ -1051,16 +1124,16 @@ void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status, case BTM_PM_STS_SSR: if (hci_status != 0) { - LOG_WARN("Received error when attempting to set sniff subrating mode"); + log::warn("Received error when attempting to set sniff subrating mode"); } if (interval) { p_dev->set_ssr_active(); - LOG_DEBUG("Enabling sniff subrating mode for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Enabling sniff subrating mode for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } else { p_dev->reset_ssr_active(); - LOG_DEBUG("Disabling sniff subrating mode for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Disabling sniff subrating mode for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } break; case BTM_PM_STS_SNIFF: @@ -1087,14 +1160,14 @@ void bta_dm_pm_btm_status(const RawAddress& bd_addr, tBTM_PM_STATUS status, break; default: - LOG_ERROR("Received unknown power mode status event:%hhu", status); + log::error("Received unknown power mode status event:{}", status); break; } } /** Process pm timer event from btm */ void bta_dm_pm_timer(const RawAddress& bd_addr, tBTA_DM_PM_ACTION pm_request) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_dm_pm_set_mode(bd_addr, pm_request, BTA_DM_PM_EXECUTE); } @@ -1157,6 +1230,6 @@ tBTM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void) { tBTM_CONTRL_STATE cur_state = BTM_CONTRL_UNKNOWN; cur_state = BTM_PM_ReadControllerState(); - LOG_VERBOSE("bta_dm_pm_obtain_controller_state: %d", cur_state); + log::verbose("bta_dm_pm_obtain_controller_state: {}", cur_state); return cur_state; } diff --git a/system/bta/dm/bta_dm_sec.cc b/system/bta/dm/bta_dm_sec.cc index efca3e6996bf2f3ec846b7f5f4aa3dc39c9728cf..6554583da2f91f631378a2d622fa1564d43800da 100644 --- a/system/bta/dm/bta_dm_sec.cc +++ b/system/bta/dm/bta_dm_sec.cc @@ -16,7 +16,7 @@ #define LOG_TAG "bt_bta_dm_sec" -#include +#include #include @@ -30,13 +30,17 @@ #include "internal_include/bt_target.h" #include "osi/include/compat.h" // strlcpy #include "osi/include/osi.h" // UNUSED_ATTR +#include "stack/include/bt_dev_class.h" #include "stack/include/btm_ble_sec_api_types.h" #include "stack/include/btm_client_interface.h" #include "stack/include/btm_sec_api.h" #include "stack/include/gatt_api.h" #include "stack/include/security_client_callbacks.h" +#include "types/bt_transport.h" #include "types/raw_address.h" +using namespace bluetooth; + static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data); static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda, tBTM_LE_EVT_DATA* p_data); @@ -81,13 +85,12 @@ void btm_sec_on_hw_on() { void bta_dm_ble_sirk_sec_cb_register(tBTA_DM_SEC_CBACK* p_cback) { /* Save the callback to be called when a request of member validation will be * needed. */ - LOG_DEBUG(""); bta_dm_sec_cb.p_sec_sirk_cback = p_cback; } void bta_dm_ble_sirk_confirm_device_reply(const RawAddress& bd_addr, bool accept) { - LOG_DEBUG(""); + log::debug("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); get_btm_client_interface().security.BTM_BleSirkConfirmDeviceReply( bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED); } @@ -97,9 +100,9 @@ void bta_dm_consolidate(const RawAddress& identity_addr, for (auto i = 0; i < bta_dm_cb.device_list.count; i++) { if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr != rpa) continue; - LOG_INFO("consolidating bda_dm_cb record %s -> %s", - ADDRESS_TO_LOGGABLE_CSTR(rpa), - ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); + log::info("consolidating bda_dm_cb record {} -> {}", + ADDRESS_TO_LOGGABLE_CSTR(rpa), + ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); bta_dm_cb.device_list.peer_device[i].peer_bdaddr = identity_addr; } } @@ -118,6 +121,14 @@ void bta_dm_sec_enable(tBTA_DM_SEC_CBACK* p_sec_cback) { btm_local_io_caps = btif_storage_get_local_io_caps(); } +void bta_dm_remote_key_missing(const RawAddress bd_addr) { + if (bta_dm_sec_cb.p_sec_cback) { + tBTA_DM_SEC sec_event; + sec_event.key_missing.bd_addr = bd_addr; + bta_dm_sec_cb.p_sec_cback(BTA_DM_KEY_MISSING_EVT, &sec_event); + } +} + /******************************************************************************* * * Function bta_dm_add_device @@ -127,31 +138,29 @@ void bta_dm_sec_enable(tBTA_DM_SEC_CBACK* p_sec_cback) { * required information stored in the NVRAM. ******************************************************************************/ void bta_dm_add_device(std::unique_ptr msg) { - uint8_t* p_dc = NULL; + DEV_CLASS dc = kDevClassEmpty; LinkKey* p_lc = NULL; /* If not all zeros, the device class has been specified */ - if (msg->dc_known) p_dc = (uint8_t*)msg->dc; + if (msg->dc_known) dc = msg->dc; if (msg->link_key_known) p_lc = &msg->link_key; auto add_result = get_btm_client_interface().security.BTM_SecAddDevice( - msg->bd_addr, p_dc, msg->bd_name, nullptr, p_lc, msg->key_type, + msg->bd_addr, dc, msg->bd_name, nullptr, p_lc, msg->key_type, msg->pin_length); if (!add_result) { - LOG(ERROR) << "BTA_DM: Error adding device " - << ADDRESS_TO_LOGGABLE_STR(msg->bd_addr); + log::error("Error adding device:{}", + ADDRESS_TO_LOGGABLE_CSTR(msg->bd_addr)); } } /** Bonds with peer device */ void bta_dm_bond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, tBT_TRANSPORT transport, tBT_DEVICE_TYPE device_type) { - LOG_DEBUG("Bonding with peer device:%s type:%s transport:%s type:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - AddressTypeText(addr_type).c_str(), - bt_transport_text(transport).c_str(), - DeviceTypeText(device_type).c_str()); + log::debug("Bonding with peer device:{} type:{} transport:{} type:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), AddressTypeText(addr_type), + bt_transport_text(transport), DeviceTypeText(device_type)); tBTA_DM_SEC sec_event; const char* p_name; @@ -188,7 +197,7 @@ void bta_dm_bond_cancel(const RawAddress& bd_addr) { tBTM_STATUS status; tBTA_DM_SEC sec_event; - LOG_VERBOSE(" bta_dm_bond_cancel "); + log::debug("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); status = get_btm_client_interface().security.BTM_SecBondCancel(bd_addr); @@ -213,8 +222,8 @@ void bta_dm_pin_reply(std::unique_ptr msg) { /** Send the user confirm request reply in response to a request from BTM */ void bta_dm_confirm(const RawAddress& bd_addr, bool accept) { - get_btm_client_interface().security.BTM_ConfirmReqReply( - accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, bd_addr); + get_btm_client_interface().security.BTM_SecConfirmReqReply( + accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, BT_TRANSPORT_BR_EDR, bd_addr); } /** respond to the OOB data request for the remote device from BTM */ @@ -242,7 +251,7 @@ static void bta_dm_pinname_cback(const tBTM_REMOTE_DEV_NAME* p_data) { if (BTA_DM_SP_CFM_REQ_EVT == event) { /* Retrieved saved device class and bd_addr */ sec_event.cfm_req.bd_addr = bta_dm_sec_cb.pin_bd_addr; - BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_sec_cb.pin_dev_class); + sec_event.cfm_req.dev_class = bta_dm_sec_cb.pin_dev_class; if (p_result && p_result->status == BTM_SUCCESS) { bytes_to_copy = @@ -267,7 +276,7 @@ static void bta_dm_pinname_cback(const tBTM_REMOTE_DEV_NAME* p_data) { } else { /* Retrieved saved device class and bd_addr */ sec_event.pin_req.bd_addr = bta_dm_sec_cb.pin_bd_addr; - BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_sec_cb.pin_dev_class); + sec_event.pin_req.dev_class = bta_dm_sec_cb.pin_dev_class; if (p_result && p_result->status == BTM_SUCCESS) { bytes_to_copy = (p_result->length < BD_NAME_LEN) ? p_result->length @@ -304,21 +313,23 @@ static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class, if (bd_name[0] == 0) { bta_dm_sec_cb.pin_evt = BTA_DM_PIN_REQ_EVT; bta_dm_sec_cb.pin_bd_addr = bd_addr; - BTA_COPY_DEVICE_CLASS(bta_dm_sec_cb.pin_dev_class, dev_class); + bta_dm_sec_cb.pin_dev_class = dev_class; if ((get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) return BTM_CMD_STARTED; - LOG_WARN(" bta_dm_pin_cback() -> Failed to start Remote Name Request "); + log::warn("Failed to start Remote Name Request, addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } tBTA_DM_SEC sec_event = {.pin_req = { .bd_addr = bd_addr, + .dev_class = dev_class, + .bd_name = "", + .min_16_digit = min_16_digit, }}; - BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class); strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN + 1); - sec_event.pin_req.min_16_digit = min_16_digit; bta_dm_sec_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event); return BTM_CMD_STARTED; @@ -411,11 +422,9 @@ static void bta_dm_authentication_complete_cback( case HCI_ERR_KEY_MISSING: case HCI_ERR_HOST_REJECT_SECURITY: case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE: - LOG_WARN( - "Deleting device record as authentication failed entry:%s " - "reason:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - hci_reason_code_text(reason).c_str()); + log::warn("authentication failed entry:{}, reason:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + hci_reason_code_text(reason)); break; default: @@ -439,7 +448,7 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTA_DM_SEC sec_event = {}; tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT; - LOG_VERBOSE("bta_dm_sp_cback: %d", event); + log::verbose("event:{}", sp_evt_to_text(event)); if (!bta_dm_sec_cb.p_sec_cback) return BTM_NOT_AUTHORIZED; bool sp_rmt_result = false; @@ -451,8 +460,8 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, btif_dm_set_oob_for_io_req(&p_data->io_req.oob_data); btif_dm_proc_io_req(&p_data->io_req.auth_req, p_data->io_req.is_orig); } - LOG_VERBOSE("io mitm: %d oob_data:%d", p_data->io_req.auth_req, - p_data->io_req.oob_data); + log::verbose("io mitm: {} oob_data:{}", p_data->io_req.auth_req, + p_data->io_req.oob_data); break; case BTM_SP_IO_RSP_EVT: if (btm_local_io_caps != BTM_IO_CAP_NONE) { @@ -491,8 +500,7 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, BTM_SP_KEY_NOTIF_EVT, copy these values into key_notif from cfm_req */ sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr; - dev_class_copy(sec_event.key_notif.dev_class, - p_data->cfm_req.dev_class); + sec_event.key_notif.dev_class = p_data->cfm_req.dev_class; bd_name_copy(sec_event.key_notif.bd_name, p_data->cfm_req.bd_name); /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT, call remote name request using values from cfm_req */ @@ -504,7 +512,7 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, bta_dm_sec_cb.rmt_auth_req = sec_event.cfm_req.rmt_auth_req; bta_dm_sec_cb.loc_auth_req = sec_event.cfm_req.loc_auth_req; - dev_class_copy(bta_dm_sec_cb.pin_dev_class, p_data->cfm_req.dev_class); + bta_dm_sec_cb.pin_dev_class = p_data->cfm_req.dev_class; { const tBTM_STATUS btm_status = get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( @@ -515,8 +523,8 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, return btm_status; default: // NOTE: This will issue callback on this failure path - LOG_WARN("Failed to start Remote Name Request btm_status:%s", - btm_status_text(btm_status).c_str()); + log::warn("Failed to start Remote Name Request btm_status:{}", + btm_status_text(btm_status)); }; } } @@ -528,18 +536,16 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, if (p_data->key_notif.bd_name[0] == 0) { bta_dm_sec_cb.pin_evt = pin_evt; bta_dm_sec_cb.pin_bd_addr = p_data->key_notif.bd_addr; - BTA_COPY_DEVICE_CLASS(bta_dm_sec_cb.pin_dev_class, - p_data->key_notif.dev_class); + bta_dm_sec_cb.pin_dev_class = p_data->key_notif.dev_class; if ((get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( p_data->key_notif.bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) return BTM_CMD_STARTED; - LOG_WARN( - " bta_dm_sp_cback() -> Failed to start Remote Name Request "); + log::warn("Failed to start Remote Name Request, addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->key_notif.bd_addr)); } else { sec_event.key_notif.bd_addr = p_data->key_notif.bd_addr; - BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, - p_data->key_notif.dev_class); + sec_event.key_notif.dev_class = p_data->key_notif.dev_class; strlcpy((char*)sec_event.key_notif.bd_name, (char*)p_data->key_notif.bd_name, BD_NAME_LEN + 1); sec_event.key_notif.bd_name[BD_NAME_LEN] = 0; @@ -551,21 +557,17 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, break; case BTM_SP_LOC_OOB_EVT: -#ifdef BTIF_DM_OOB_TEST btif_dm_proc_loc_oob(BT_TRANSPORT_BR_EDR, (bool)(p_data->loc_oob.status == BTM_SUCCESS), p_data->loc_oob.c, p_data->loc_oob.r); -#endif break; case BTM_SP_RMT_OOB_EVT: { Octet16 c; Octet16 r; sp_rmt_result = false; -#ifdef BTIF_DM_OOB_TEST sp_rmt_result = btif_dm_proc_rmt_oob(p_data->rmt_oob.bd_addr, &c, &r); -#endif - LOG_VERBOSE("bta_dm_ci_rmt_oob: result=%d", sp_rmt_result); + log::verbose("result={}", sp_rmt_result); bta_dm_ci_rmt_oob(sp_rmt_result, p_data->rmt_oob.bd_addr, c, r); break; } @@ -574,7 +576,7 @@ static tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, status = BTM_NOT_AUTHORIZED; break; } - LOG_VERBOSE("dm status: %d", status); + log::verbose("dm status:{}", status); return status; } @@ -594,8 +596,8 @@ static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr) { auto& dev = bta_dm_cb.device_list.peer_device[i]; if (dev.peer_bdaddr == remote_bd_addr) { if (dev.remove_dev_pending) { - LOG_INFO("Clearing remove_dev_pending for %s", - ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr)); + log::info("Clearing remove_dev_pending for {}", + ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr)); dev.remove_dev_pending = false; } return; @@ -621,15 +623,15 @@ static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) { BT_TRANSPORT_LE) || get_btm_client_interface().peer.BTM_IsAclConnectionUp( remote_bd_addr, BT_TRANSPORT_BR_EDR)) { - LOG_VERBOSE("%s ACL is not down. Schedule for Dev Removal when ACL closes", - __func__); + log::debug("ACL is not down. Schedule for Dev Removal when ACL closes:{}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); get_btm_client_interface().security.BTM_SecClearSecurityFlags( remote_bd_addr); for (int i = 0; i < bta_dm_cb.device_list.count; i++) { auto& dev = bta_dm_cb.device_list.peer_device[i]; if (dev.peer_bdaddr == remote_bd_addr) { - LOG_INFO("Setting remove_dev_pending for %s", - ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr)); + log::info("Setting remove_dev_pending for {}", + ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr)); dev.remove_dev_pending = TRUE; break; } @@ -719,6 +721,9 @@ static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda, tBTA_DM_SEC sec_event; const char* p_name = NULL; + log::debug("addr:{},event:{}", ADDRESS_TO_LOGGABLE_CSTR(bda), + ble_evt_to_text(event)); + if (!bta_dm_sec_cb.p_sec_cback) return BTM_NOT_AUTHORIZED; memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); @@ -727,8 +732,8 @@ static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda, ble_io_req(bda, &p_data->io_req.io_cap, &p_data->io_req.oob_data, &p_data->io_req.auth_req, &p_data->io_req.max_key_size, &p_data->io_req.init_keys, &p_data->io_req.resp_keys); - LOG_VERBOSE("io mitm: %d oob_data:%d", p_data->io_req.auth_req, - p_data->io_req.oob_data); + log::info("io mitm:{} oob_data:{}", p_data->io_req.auth_req, + p_data->io_req.oob_data); break; case BTM_LE_CONSENT_REQ_EVT: @@ -823,9 +828,9 @@ static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda, // Bonded device failed to encrypt - to test this remove battery from // HID device right after connection, but before encryption is // established - LOG(INFO) << __func__ - << ": bonded device disconnected when encrypting - no " - "reason to unbond"; + log::warn( + "bonded device disconnected when encrypting - no reason to " + "unbond"); } else { /* delete this device entry from Sec Dev DB */ bta_dm_remove_sec_dev_entry(bda); @@ -874,47 +879,29 @@ void bta_dm_encrypt_cback(const RawAddress* bd_addr, tBT_TRANSPORT transport, device->p_encrypt_cback = nullptr; } + log::debug("Encrypted:{:c}, peer:{} transport:{} status:{} callback:{:c}", + result == BTM_SUCCESS ? 'T' : 'F', + ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), bt_transport_text(transport), + btm_status_text(result), (p_callback) ? 'T' : 'F'); + tBTA_STATUS bta_status = BTA_SUCCESS; switch (result) { case BTM_SUCCESS: - LOG_WARN("Encrypted link peer:%s transport:%s status:%s callback:%c", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), - bt_transport_text(transport).c_str(), - btm_status_text(result).c_str(), (p_callback) ? 'T' : 'F'); break; case BTM_WRONG_MODE: - LOG_WARN( - "Unable to encrypt link peer:%s transport:%s status:%s callback:%c", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), - bt_transport_text(transport).c_str(), btm_status_text(result).c_str(), - (p_callback) ? 'T' : 'F'); bta_status = BTA_WRONG_MODE; break; case BTM_NO_RESOURCES: - LOG_WARN( - "Unable to encrypt link peer:%s transport:%s status:%s callback:%c", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), - bt_transport_text(transport).c_str(), btm_status_text(result).c_str(), - (p_callback) ? 'T' : 'F'); bta_status = BTA_NO_RESOURCES; break; case BTM_BUSY: - LOG_WARN( - "Unable to encrypt link peer:%s transport:%s status:%s callback:%c", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), - bt_transport_text(transport).c_str(), btm_status_text(result).c_str(), - (p_callback) ? 'T' : 'F'); bta_status = BTA_BUSY; break; default: - LOG_ERROR( - "Failed to encrypt link peer:%s transport:%s status:%s callback:%c", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), - bt_transport_text(transport).c_str(), btm_status_text(result).c_str(), - (p_callback) ? 'T' : 'F'); bta_status = BTA_FAILURE; break; } + if (p_callback) { (*p_callback)(*bd_addr, transport, bta_status); } @@ -925,24 +912,23 @@ void bta_dm_set_encryption(const RawAddress& bd_addr, tBT_TRANSPORT transport, tBTA_DM_ENCRYPT_CBACK* p_callback, tBTM_BLE_SEC_ACT sec_act) { if (p_callback == nullptr) { - LOG_ERROR("bta_dm_set_encryption callback is not provided"); + log::error("callback is not provided,addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } tBTA_DM_PEER_DEVICE* device = find_connected_device(bd_addr, transport); if (device == nullptr) { - LOG_ERROR("Unable to find active ACL connection device:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport).c_str()); + log::error("Unable to find active ACL connection device:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport)); return; } if (device->p_encrypt_cback) { - LOG_ERROR( - "Unable to start encryption as already in progress peer:%s " - "transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport).c_str()); + log::error( + "Unable to start encryption as already in progress peer:{} " + "transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport)); (*p_callback)(bd_addr, transport, BTA_BUSY); return; } @@ -951,13 +937,11 @@ void bta_dm_set_encryption(const RawAddress& bd_addr, tBT_TRANSPORT transport, bd_addr, transport, bta_dm_encrypt_cback, NULL, sec_act) == BTM_CMD_STARTED) { device->p_encrypt_cback = p_callback; - LOG_DEBUG("Started encryption peer:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport).c_str()); + log::debug("Started encryption peer:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport)); } else { - LOG_ERROR("Unable to start encryption process peer:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport).c_str()); + log::error("Unable to start encryption process peer:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport)); } } @@ -990,7 +974,7 @@ static void bta_dm_ble_id_key_cback(uint8_t key_type, break; default: - LOG_VERBOSE("Unknown key type %d", key_type); + log::verbose("Unknown key type {}", key_type); break; } return; @@ -1011,12 +995,12 @@ static uint8_t bta_dm_sirk_verifiction_cback(const RawAddress& bd_addr) { }}; if (bta_dm_sec_cb.p_sec_sirk_cback) { - LOG_DEBUG("callback called"); + log::debug("callback called"); bta_dm_sec_cb.p_sec_sirk_cback(BTA_DM_SIRK_VERIFICATION_REQ_EVT, &sec_event); return BTM_CMD_STARTED; } - LOG_DEBUG("no callback registered"); + log::debug("no callback registered"); return BTM_SUCCESS_NO_SECURITY; } @@ -1072,15 +1056,15 @@ void bta_dm_add_ble_device(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, ******************************************************************************/ void bta_dm_ble_passkey_reply(const RawAddress& bd_addr, bool accept, uint32_t passkey) { - get_btm_client_interface().ble.BTM_BlePasskeyReply( + get_btm_client_interface().security.BTM_BlePasskeyReply( bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, passkey); } /** This is response to SM numeric comparison request submitted to application. */ void bta_dm_ble_confirm_reply(const RawAddress& bd_addr, bool accept) { - get_btm_client_interface().ble.BTM_BleConfirmReply( - bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED); + get_btm_client_interface().security.BTM_SecConfirmReqReply( + accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, BT_TRANSPORT_LE, bd_addr); } /** This function set the local device LE privacy settings. */ diff --git a/system/bta/dm/bta_dm_sec_api.cc b/system/bta/dm/bta_dm_sec_api.cc index 969586853628c8da03c84c3b63a3c2b8513a5912..bf346aed24152dfb968ee3c72b62ef9f92c0dc37 100644 --- a/system/bta/dm/bta_dm_sec_api.cc +++ b/system/bta/dm/bta_dm_sec_api.cc @@ -22,9 +22,10 @@ * ******************************************************************************/ +#include #include +#include -#include "android_bluetooth_flags.h" #include "bta/dm/bta_dm_sec_int.h" #include "stack/btm/btm_sec.h" #include "stack/include/bt_octets.h" @@ -32,6 +33,8 @@ #include "stack/include/main_thread.h" #include "types/raw_address.h" +using namespace bluetooth; + /** This function initiates a bonding procedure with a peer device */ void BTA_DmBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, tBT_TRANSPORT transport, tBT_DEVICE_TYPE device_type) { @@ -147,9 +150,9 @@ void BTA_DmAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class, msg->link_key = link_key; /* Load device class if specified */ - if (dev_class) { + if (dev_class != kDevClassEmpty) { msg->dc_known = true; - memcpy(msg->dc, dev_class, DEV_CLASS_LEN); + msg->dc = dev_class; } memset(msg->bd_name, 0, BD_NAME_LEN + 1); @@ -319,7 +322,7 @@ void BTA_DmBleSecurityGrant(const RawAddress& bd_addr, void BTA_DmSetEncryption(const RawAddress& bd_addr, tBT_TRANSPORT transport, tBTA_DM_ENCRYPT_CBACK* p_callback, tBTM_BLE_SEC_ACT sec_act) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (IS_FLAG_ENABLED(synchronous_bta_sec)) { bta_dm_set_encryption(bd_addr, transport, p_callback, sec_act); } else { @@ -342,7 +345,7 @@ void BTA_DmSetEncryption(const RawAddress& bd_addr, tBT_TRANSPORT transport, * ******************************************************************************/ void BTA_DmSirkSecCbRegister(tBTA_DM_SEC_CBACK* p_cback) { - LOG_DEBUG(""); + log::debug(""); if (IS_FLAG_ENABLED(synchronous_bta_sec)) { bta_dm_ble_sirk_sec_cb_register(p_cback); } else { @@ -365,7 +368,7 @@ void BTA_DmSirkSecCbRegister(tBTA_DM_SEC_CBACK* p_cback) { * ******************************************************************************/ void BTA_DmSirkConfirmDeviceReply(const RawAddress& bd_addr, bool accept) { - LOG_DEBUG(""); + log::debug(""); if (IS_FLAG_ENABLED(synchronous_bta_sec)) { bta_dm_ble_sirk_confirm_device_reply(bd_addr, accept); } else { diff --git a/system/bta/gatt/bta_gattc_act.cc b/system/bta/gatt/bta_gattc_act.cc index c925eacde5a2766d3d4af0c5388c9baedc17e85a..f4133c8c090fdc016c3e431992381670676c17d3 100644 --- a/system/bta/gatt/bta_gattc_act.cc +++ b/system/bta/gatt/bta_gattc_act.cc @@ -25,15 +25,19 @@ #define LOG_TAG "bt_bta_gattc" +#include #include #include #include +#include #include "bta/gatt/bta_gattc_int.h" #include "bta/include/bta_api.h" #include "btif/include/btif_debug_conn.h" #include "device/include/controller.h" #include "hardware/bt_gatt_types.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR @@ -48,6 +52,7 @@ using base::StringPrintf; using bluetooth::Uuid; +using namespace bluetooth; /***************************************************************************** * Constants @@ -118,14 +123,14 @@ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status); /** Enables GATTC module */ static void bta_gattc_enable() { - VLOG(1) << __func__; + log::verbose(""); if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) { /* initialize control block */ bta_gattc_cb = tBTA_GATTC_CB(); bta_gattc_cb.state = BTA_GATTC_STATE_ENABLED; } else { - VLOG(1) << "GATTC is already enabled"; + log::verbose("GATTC is already enabled"); } } @@ -134,10 +139,10 @@ static void bta_gattc_enable() { void bta_gattc_disable() { uint8_t i; - VLOG(1) << __func__; + log::verbose(""); if (bta_gattc_cb.state != BTA_GATTC_STATE_ENABLED) { - LOG(ERROR) << "not enabled, or disabled in progress"; + log::error("not enabled, or disabled in progress"); return; } @@ -157,9 +162,9 @@ void bta_gattc_disable() { /** start an application interface */ static void bta_gattc_start_if(uint8_t client_if) { - LOG_DEBUG("client_if=%d", +client_if); + log::debug("client_if={}", client_if); if (!bta_gattc_cl_get_regcb(client_if)) { - LOG_ERROR("Unable to start app.: Unknown client_if=%d", +client_if); + log::error("Unable to start app.: Unknown client_if={}", client_if); return; } @@ -171,12 +176,11 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, BtaAppRegisterCallback cb, bool eatt_support) { tGATT_STATUS status = GATT_NO_RESOURCES; uint8_t client_if = 0; - LOG_DEBUG("state: %d, uuid=%s", +bta_gattc_cb.state, - app_uuid.ToString().c_str()); + log::debug("state: {}, uuid={}", bta_gattc_cb.state, app_uuid.ToString()); /* check if GATTC module is already enabled . Else enable */ if (bta_gattc_cb.state == BTA_GATTC_STATE_DISABLED) { - LOG_DEBUG("GATTC module not enabled, enabling it"); + log::debug("GATTC module not enabled, enabling it"); bta_gattc_enable(); } /* todo need to check duplicate uuid */ @@ -185,9 +189,9 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, bta_gattc_cb.cl_rcb[i].client_if = GATT_Register( app_uuid, "GattClient", &bta_gattc_cl_cback, eatt_support); if (bta_gattc_cb.cl_rcb[i].client_if == 0) { - LOG_ERROR( - "Register with GATT stack failed with index %d, trying next index", - +i); + log::error( + "Register with GATT stack failed with index {}, trying next index", + i); status = GATT_ERROR; } else { bta_gattc_cb.cl_rcb[i].in_use = true; @@ -197,10 +201,10 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, /* BTA use the same client interface as BTE GATT statck */ client_if = bta_gattc_cb.cl_rcb[i].client_if; - LOG_DEBUG( - "Registered GATT client interface %d with uuid=%s, starting it on " + log::debug( + "Registered GATT client interface {} with uuid={}, starting it on " "main thread", - +client_if, app_uuid.ToString().c_str()); + client_if, app_uuid.ToString()); do_in_main_thread(FROM_HERE, base::BindOnce(&bta_gattc_start_if, client_if)); @@ -214,15 +218,15 @@ void bta_gattc_register(const Uuid& app_uuid, tBTA_GATTC_CBACK* p_cback, if (!cb.is_null()) { cb.Run(client_if, status); } else { - LOG_WARN("No GATT callback available, client_if=%d, status=%d", +client_if, - +status); + log::warn("No GATT callback available, client_if={}, status={}", client_if, + status); } } /** De-Register a GATT client application with BTA */ void bta_gattc_deregister(tBTA_GATTC_RCB* p_clreg) { uint8_t accept_list_size = 0; - if (controller_get_interface()->supports_ble()) { + if (controller_get_interface()->SupportsBle()) { accept_list_size = controller_get_interface()->get_ble_acceptlist_size(); } @@ -263,7 +267,7 @@ void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg) { tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(p_msg->api_conn.client_if); if (!p_clreg) { - LOG_ERROR("Failed, unknown client_if=%d", +p_msg->api_conn.client_if); + log::error("Failed, unknown client_if={}", p_msg->api_conn.client_if); return; } @@ -278,7 +282,7 @@ void bta_gattc_process_api_open(const tBTA_GATTC_DATA* p_msg) { if (p_clcb != nullptr) { bta_gattc_sm_execute(p_clcb, event, p_msg); } else { - LOG_ERROR("No resources to open a new connection."); + log::error("No resources to open a new connection."); bta_gattc_send_open_cback(p_clreg, GATT_NO_RESOURCES, p_msg->api_conn.remote_bda, GATT_INVALID_CONN_ID, @@ -293,11 +297,11 @@ void bta_gattc_process_api_open_cancel(const tBTA_GATTC_DATA* p_msg) { uint16_t event = ((BT_HDR_RIGID*)p_msg)->event; if (!p_msg->api_cancel_conn.is_direct) { - LOG_DEBUG("Cancel GATT client background connection"); + log::debug("Cancel GATT client background connection"); bta_gattc_cancel_bk_conn(&p_msg->api_cancel_conn); return; } - LOG_DEBUG("Cancel GATT client direct connection"); + log::debug("Cancel GATT client direct connection"); tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_cif( p_msg->api_cancel_conn.client_if, p_msg->api_cancel_conn.remote_bda, @@ -307,7 +311,7 @@ void bta_gattc_process_api_open_cancel(const tBTA_GATTC_DATA* p_msg) { return; } - LOG(ERROR) << "No such connection need to be cancelled"; + log::error("No such connection need to be cancelled"); tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(p_msg->api_cancel_conn.client_if); @@ -347,7 +351,7 @@ void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB* p_clcb, void bta_gattc_open_error(tBTA_GATTC_CLCB* p_clcb, UNUSED_ATTR const tBTA_GATTC_DATA* p_data) { - LOG(ERROR) << "Connection already opened. wrong state"; + log::error("Connection already opened. wrong state"); bta_gattc_send_open_cback(p_clcb->p_rcb, GATT_SUCCESS, p_clcb->bda, p_clcb->bta_conn_id, p_clcb->transport, 0); @@ -355,12 +359,22 @@ void bta_gattc_open_error(tBTA_GATTC_CLCB* p_clcb, void bta_gattc_open_fail(tBTA_GATTC_CLCB* p_clcb, UNUSED_ATTR const tBTA_GATTC_DATA* p_data) { - LOG(WARNING) << __func__ << ": Cannot establish Connection. conn_id=" - << loghex(p_clcb->bta_conn_id) << ". Return GATT_ERROR(" - << +GATT_ERROR << ")"; + if (IS_FLAG_ENABLED(enumerate_gatt_errors) && + p_data->int_conn.reason == GATT_CONN_TIMEOUT) { + log::warn( + "Connection timed out after 30 seconds. conn_id={}. Return " + "GATT_CONNECTION_TIMEOUT({})", + loghex(p_clcb->bta_conn_id), GATT_CONNECTION_TIMEOUT); + bta_gattc_send_open_cback(p_clcb->p_rcb, GATT_CONNECTION_TIMEOUT, + p_clcb->bda, p_clcb->bta_conn_id, + p_clcb->transport, 0); + } else { + log::warn("Cannot establish Connection. conn_id={}. Return GATT_ERROR({})", + loghex(p_clcb->bta_conn_id), GATT_ERROR); + bta_gattc_send_open_cback(p_clcb->p_rcb, GATT_ERROR, p_clcb->bda, + p_clcb->bta_conn_id, p_clcb->transport, 0); + } - bta_gattc_send_open_cback(p_clcb->p_rcb, GATT_ERROR, p_clcb->bda, - p_clcb->bta_conn_id, p_clcb->transport, 0); /* open failure, remove clcb */ bta_gattc_clcb_dealloc(p_clcb); } @@ -375,7 +389,7 @@ void bta_gattc_open(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { BTM_BLE_DIRECT_CONNECTION, p_data->api_conn.transport, p_data->api_conn.opportunistic, p_data->api_conn.initiating_phys)) { - LOG(ERROR) << "Connection open failure"; + log::error("Connection open failure"); bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_OPEN_FAIL_EVT, p_data); return; } @@ -405,7 +419,7 @@ void bta_gattc_open(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data, tBTA_GATTC_RCB* p_clreg) { if (!bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, true)) { - LOG_WARN("Unable to find space for accept list connection mask"); + log::warn("Unable to find space for accept list connection mask"); bta_gattc_send_open_cback(p_clreg, GATT_NO_RESOURCES, p_data->remote_bda, GATT_INVALID_CONN_ID, BT_TRANSPORT_LE, 0); return; @@ -414,8 +428,8 @@ static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data, /* always call open to hold a connection */ if (!GATT_Connect(p_data->client_if, p_data->remote_bda, p_data->connection_type, p_data->transport, false)) { - LOG_ERROR("Unable to connect to remote bd_addr=%s", - ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda)); + log::error("Unable to connect to remote bd_addr={}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda)); bta_gattc_send_open_cback(p_clreg, GATT_ILLEGAL_PARAMETER, p_data->remote_bda, GATT_INVALID_CONN_ID, BT_TRANSPORT_LE, 0); @@ -425,15 +439,15 @@ static void bta_gattc_init_bk_conn(const tBTA_GATTC_API_OPEN* p_data, uint16_t conn_id; if (!GATT_GetConnIdIfConnected(p_data->client_if, p_data->remote_bda, &conn_id, p_data->transport)) { - LOG_INFO("Not a connected remote device yet"); + log::info("Not a connected remote device yet"); return; } tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_alloc_clcb( p_data->client_if, p_data->remote_bda, BT_TRANSPORT_LE); if (!p_clcb) { - LOG_WARN("Unable to find connection link for device:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda)); + log::warn("Unable to find connection link for device:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda)); return; } @@ -461,9 +475,9 @@ void bta_gattc_cancel_bk_conn(const tBTA_GATTC_API_CANCEL_OPEN* p_data) { if (GATT_CancelConnect(p_data->client_if, p_data->remote_bda, false)) { cb_data.status = GATT_SUCCESS; } else { - LOG_ERROR("failed for client_if=%d, remote_bda=%s, is_direct=false", - static_cast(p_data->client_if), - ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda)); + log::error("failed for client_if={}, remote_bda={}, is_direct=false", + static_cast(p_data->client_if), + ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda)); } } p_clreg = bta_gattc_cl_get_regcb(p_data->client_if); @@ -503,10 +517,10 @@ void bta_gattc_cancel_open(tBTA_GATTC_CLCB* p_clcb, /** receive connection callback from stack */ void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { tGATT_IF gatt_if; - VLOG(1) << __func__ << ": server cache state=" << +p_clcb->p_srcb->state; + log::verbose("server cache state={}", p_clcb->p_srcb->state); if (p_data != NULL) { - VLOG(1) << __func__ << ": conn_id=" << loghex(p_data->hdr.layer_specific); + log::verbose("conn_id={}", loghex(p_data->hdr.layer_specific)); p_clcb->bta_conn_id = p_data->int_conn.hdr.layer_specific; GATT_GetConnectionInfor(p_data->hdr.layer_specific, &gatt_if, p_clcb->bda, @@ -543,9 +557,9 @@ void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { ? bta_gattc_cache_load(p_clcb->p_srcb->server_bda) : gatt::Database(); auto robust_caching_support = GetRobustCachingSupport(p_clcb, db); - LOG_INFO("Connected to %s, robust caching support is %d", - p_clcb->bda.ToRedactedStringForLogging().c_str(), - robust_caching_support); + log::info("Connected to {}, robust caching support is {}", + p_clcb->bda.ToRedactedStringForLogging(), + robust_caching_support); if (!db.IsEmpty()) p_clcb->p_srcb->gatt_database = db; @@ -611,8 +625,8 @@ void bta_gattc_close_fail(tBTA_GATTC_CLCB* p_clcb, cb_data.close.reason = BTA_GATT_CONN_NONE; cb_data.close.status = GATT_ERROR; - LOG(WARNING) << __func__ << ": conn_id=" << loghex(cb_data.close.conn_id) - << ". Returns GATT_ERROR(" << +GATT_ERROR << ")."; + log::warn("conn_id={}. Returns GATT_ERROR({}).", + loghex(cb_data.close.conn_id), GATT_ERROR); (*p_clcb->p_rcb->p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data); } @@ -662,19 +676,17 @@ void bta_gattc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (p_data->hdr.event == BTA_GATTC_API_CLOSE_EVT) { cb_data.close.status = GATT_Disconnect(p_data->hdr.layer_specific); cb_data.close.reason = GATT_CONN_TERMINATE_LOCAL_HOST; - LOG_DEBUG("Local close event client_if:%hu conn_id:%hu reason:%s", - cb_data.close.client_if, cb_data.close.conn_id, - gatt_disconnection_reason_text( - static_cast(cb_data.close.reason)) - .c_str()); + log::debug("Local close event client_if:{} conn_id:{} reason:{}", + cb_data.close.client_if, cb_data.close.conn_id, + gatt_disconnection_reason_text( + static_cast(cb_data.close.reason))); } else if (p_data->hdr.event == BTA_GATTC_INT_DISCONN_EVT) { cb_data.close.status = static_cast(p_data->int_conn.reason); cb_data.close.reason = p_data->int_conn.reason; - LOG_DEBUG("Peer close disconnect event client_if:%hu conn_id:%hu reason:%s", - cb_data.close.client_if, cb_data.close.conn_id, - gatt_disconnection_reason_text( - static_cast(cb_data.close.reason)) - .c_str()); + log::debug("Peer close disconnect event client_if:{} conn_id:{} reason:{}", + cb_data.close.client_if, cb_data.close.conn_id, + gatt_disconnection_reason_text( + static_cast(cb_data.close.reason))); } if (p_cback) (*p_cback)(BTA_GATTC_CLOSE_EVT, &cb_data); @@ -698,8 +710,7 @@ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV* p_srcb, tGATT_STATUS status) { /** close a GATTC connection while in discovery state */ void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { - VLOG(1) << __func__ - << ": Discovery cancel conn_id=" << loghex(p_clcb->bta_conn_id); + log::verbose("Discovery cancel conn_id={}", loghex(p_clcb->bta_conn_id)); if (p_clcb->disc_active) bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR); @@ -710,7 +721,8 @@ void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb, // while in the BTA_GATTC_DISCOVER_ST state. Once the state changes, the // connection itself still needs to be closed to resolve the original event. if (p_clcb->state == BTA_GATTC_CONN_ST) { - VLOG(1) << "State is back to BTA_GATTC_CONN_ST. Trigger connection close"; + log::verbose( + "State is back to BTA_GATTC_CONN_ST. Trigger connection close"); bta_gattc_close(p_clcb, p_data); } } @@ -745,14 +757,15 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { p_clcb->bta_conn_id, ¤t_mtu); switch (result) { case MTU_EXCHANGE_DEVICE_DISCONNECTED: - LOG_INFO("Device %s disconnected", ADDRESS_TO_LOGGABLE_CSTR(p_clcb->bda)); + log::info("Device {} disconnected", + ADDRESS_TO_LOGGABLE_CSTR(p_clcb->bda)); bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, GATT_NO_RESOURCES, NULL); bta_gattc_continue(p_clcb); return; case MTU_EXCHANGE_NOT_ALLOWED: - LOG_INFO("Not allowed for BR/EDR devices %s", - ADDRESS_TO_LOGGABLE_CSTR(p_clcb->bda)); + log::info("Not allowed for BR/EDR devices {}", + ADDRESS_TO_LOGGABLE_CSTR(p_clcb->bda)); bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_CONFIG, GATT_ERR_UNLIKELY, NULL); bta_gattc_continue(p_clcb); @@ -766,8 +779,8 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { bta_gattc_send_mtu_response(p_clcb, p_data, current_mtu); return; case MTU_EXCHANGE_IN_PROGRESS: - LOG_INFO("Enqueue MTU Request - waiting for response on p_clcb %p", - p_clcb); + log::info("Enqueue MTU Request - waiting for response on p_clcb {}", + fmt::ptr(p_clcb)); /* MTU request is in progress and this one will not be sent to remote * device. Just push back on the queue and response will be sent up to * the upper layer when MTU Exchange will be completed. @@ -798,13 +811,13 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { void bta_gattc_start_discover_internal(tBTA_GATTC_CLCB* p_clcb) { if (p_clcb->transport == BT_TRANSPORT_LE) - L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, false); + L2CA_LockBleConnParamsForServiceDiscovery(p_clcb->p_srcb->server_bda, true); bta_gattc_init_cache(p_clcb->p_srcb); p_clcb->status = bta_gattc_discover_pri_service( p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL); if (p_clcb->status != GATT_SUCCESS) { - LOG(ERROR) << "discovery on server failed"; + log::error("discovery on server failed"); bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status); } else p_clcb->disc_active = true; @@ -817,8 +830,8 @@ static void bta_gattc_continue_with_version_and_cache_known( /** Start a discovery on server */ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, UNUSED_ATTR const tBTA_GATTC_DATA* p_data) { - VLOG(1) << __func__ << ": conn_id:" << loghex(p_clcb->bta_conn_id) - << " p_clcb->p_srcb->state:" << +p_clcb->p_srcb->state; + log::verbose("conn_id:{} p_clcb->p_srcb->state:{}", + loghex(p_clcb->bta_conn_id), p_clcb->p_srcb->state); if (((p_clcb->p_q_cmd == NULL || p_clcb->auto_update == BTA_GATTC_REQ_WAITING) && @@ -829,7 +842,7 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE; if (p_clcb->p_srcb == NULL) { - LOG(ERROR) << "unknown device, can not start discovery"; + log::error("unknown device, can not start discovery"); return; } @@ -850,8 +863,8 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb, auto cache_support = GetRobustCachingSupport(p_clcb, p_clcb->p_srcb->gatt_database); if (cache_support == RobustCachingSupport::W4_REMOTE_VERSION) { - LOG_INFO( - "Pausing service discovery till remote version is read conn_id:%d", + log::info( + "Pausing service discovery till remote version is read conn_id:{}", p_clcb->bta_conn_id); p_clcb->p_srcb->disc_blocked_waiting_on_version = true; p_clcb->p_srcb->blocked_conn_id = p_clcb->bta_conn_id; @@ -882,13 +895,13 @@ void bta_gattc_continue_discovery_if_needed(const RawAddress& bd_addr, p_srcb->disc_blocked_waiting_on_version = false; p_srcb->blocked_conn_id = 0; - LOG_INFO("Received remote version, continue service discovery for %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Received remote version, continue service discovery for {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (!p_clcb) { - LOG_ERROR("Can't find CLCB to continue service discovery, id:%d", conn_id); + log::error("Can't find CLCB to continue service discovery, id:{}", conn_id); return; } @@ -903,8 +916,11 @@ void bta_gattc_continue_discovery_if_needed(const RawAddress& bd_addr, void bta_gattc_continue_with_version_and_cache_known( tBTA_GATTC_CLCB* p_clcb, RobustCachingSupport cache_support, bool is_svc_chg) { - if (cache_support == RobustCachingSupport::UNSUPPORTED) { - // Skip initial DB hash read if we have strong reason (due to interop, + if (cache_support == RobustCachingSupport::UNSUPPORTED || + (IS_FLAG_ENABLED(skip_unknown_robust_caching) && + cache_support == RobustCachingSupport::UNKNOWN)) { + // Skip initial DB hash read if no DB hash is known, or if + // we have strong reason (due to interop, // or a prior discovery) to believe that it is unsupported. p_clcb->p_srcb->srvc_hdl_db_hash = false; } @@ -913,9 +929,8 @@ void bta_gattc_continue_with_version_and_cache_known( if (bta_gattc_is_robust_caching_enabled() && p_clcb->p_srcb->srvc_hdl_db_hash && bta_gattc_read_db_hash(p_clcb, is_svc_chg)) { - LOG(INFO) << __func__ - << ": pending service discovery, read db hash first conn_id:" - << loghex(p_clcb->bta_conn_id); + log::info("pending service discovery, read db hash first conn_id:{}", + loghex(p_clcb->bta_conn_id)); p_clcb->p_srcb->srvc_hdl_db_hash = false; return; } @@ -927,10 +942,12 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, UNUSED_ATTR const tBTA_GATTC_DATA* p_data) { const tBTA_GATTC_DATA* p_q_cmd = p_clcb->p_q_cmd; - VLOG(1) << __func__ << ": conn_id=" << loghex(p_clcb->bta_conn_id); + log::verbose("conn_id={}", loghex(p_clcb->bta_conn_id)); - if (p_clcb->transport == BT_TRANSPORT_LE) - L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, true); + if (p_clcb->transport == BT_TRANSPORT_LE) { + L2CA_LockBleConnParamsForServiceDiscovery(p_clcb->p_srcb->server_bda, + false); + } p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; p_clcb->disc_active = false; @@ -964,7 +981,9 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb, * want to free the underlying buffer that's being * referenced by p_clcb->p_q_cmd */ - if (p_q_cmd != p_clcb->p_q_cmd) osi_free_and_reset((void**)&p_q_cmd); + if (!bta_gattc_is_data_queued(p_clcb, p_q_cmd)) { + osi_free_and_reset((void**)&p_q_cmd); + } } else { bta_gattc_continue(p_clcb); } @@ -1015,7 +1034,7 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB* p_clcb, if (bta_gattc_enqueue(p_clcb, p_data) == ENQUEUED_FOR_LATER) return; if (p_data->api_read_multi.handles.num_attr > GATT_MAX_READ_MULTI_HANDLES) { - LOG(ERROR) << "api_read_multi.num_attr > GATT_MAX_READ_MULTI_HANDLES"; + log::error("api_read_multi.num_attr > GATT_MAX_READ_MULTI_HANDLES"); return; } @@ -1102,7 +1121,7 @@ void bta_gattc_confirm(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (GATTC_SendHandleValueConfirm(p_data->api_confirm.hdr.layer_specific, cid) != GATT_SUCCESS) { - LOG(ERROR) << __func__ << ": to cid=" << loghex(cid) << " failed"; + log::error("to cid={} failed", loghex(cid)); } else { /* if over BR_EDR, inform PM for mode change */ if (p_clcb->transport == BT_TRANSPORT_BR_EDR) { @@ -1158,17 +1177,17 @@ static void bta_gattc_write_cmpl(tBTA_GATTC_CLCB* p_clcb, if (cb) { if (p_data->status == 0 && p_clcb->p_q_cmd->api_write.write_type == BTA_GATTC_WRITE_PREPARE) { - LOG_DEBUG("Handling prepare write success response: handle 0x%04x", - p_data->p_cmpl->att_value.handle); + log::debug("Handling prepare write success response: handle 0x{:04x}", + p_data->p_cmpl->att_value.handle); /* If this is successful Prepare write, lets provide to the callback the * data provided by server */ cb(p_clcb->bta_conn_id, p_data->status, p_data->p_cmpl->att_value.handle, p_data->p_cmpl->att_value.len, p_data->p_cmpl->att_value.value, my_cb_data); } else { - LOG_DEBUG("Handling write response type: %d: handle 0x%04x", - p_clcb->p_q_cmd->api_write.write_type, - p_data->p_cmpl->att_value.handle); + log::debug("Handling write response type: {}: handle 0x{:04x}", + p_clcb->p_q_cmd->api_write.write_type, + p_data->p_cmpl->att_value.handle); /* Otherwise, provide data which were intended to write. */ cb(p_clcb->bta_conn_id, p_data->status, p_data->p_cmpl->att_value.handle, p_clcb->p_q_cmd->api_write.len, p_clcb->p_q_cmd->api_write.p_value, @@ -1222,7 +1241,7 @@ static void bta_gattc_cfg_mtu_cmpl(tBTA_GATTC_CLCB* p_clcb, /** operation completed */ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (p_clcb->p_q_cmd == NULL) { - LOG_ERROR("No pending command gatt client command"); + log::error("No pending command gatt client command"); return; } @@ -1239,7 +1258,7 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { case GATTC_OPTYPE_NOTIFICATION: case GATTC_OPTYPE_INDICATION: default: - LOG(ERROR) << "unexpected operation, ignored"; + log::error("unexpected operation, ignored"); return; } @@ -1252,10 +1271,9 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { if (mapped_op > GATTC_OPTYPE_INDICATION) mapped_op = 0; - LOG(ERROR) << StringPrintf( - "expect op:(%s :0x%04x), receive unexpected operation (%s).", - bta_gattc_op_code_name[mapped_op], p_clcb->p_q_cmd->hdr.event, - bta_gattc_op_code_name[op]); + log::error("expect op:({} :0x{:04x}), receive unexpected operation ({}).", + bta_gattc_op_code_name[mapped_op], p_clcb->p_q_cmd->hdr.event, + bta_gattc_op_code_name[op]); return; } @@ -1264,8 +1282,8 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { */ if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING && p_clcb->p_srcb->srvc_hdl_chg && op != GATTC_OPTYPE_CONFIG) { - VLOG(1) << "Discard all responses when service change indication is " - "received."; + log::verbose( + "Discard all responses when service change indication is received."); // TODO Fix constness const_cast(p_data)->op_cmpl.status = GATT_ERROR; } @@ -1288,9 +1306,9 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { GATTC_GetAndRemoveListOfConnIdsWaitingForMtuRequest(p_clcb->bda); for (auto conn_id : outstanding_conn_ids) { tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); - LOG_DEBUG("Continue MTU request clcb %p", p_clcb); + log::debug("Continue MTU request clcb {}", fmt::ptr(p_clcb)); if (p_clcb) { - LOG_DEBUG("Continue MTU request for client conn_id=0x%04x", conn_id); + log::debug("Continue MTU request for client conn_id=0x{:04x}", conn_id); bta_gattc_continue(p_clcb); } } @@ -1300,7 +1318,7 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { // discovery immediately if (bta_gattc_is_robust_caching_enabled() && p_data->op_cmpl.status == GATT_DATABASE_OUT_OF_SYNC) { - LOG(INFO) << __func__ << ": DATABASE_OUT_OF_SYNC, re-discover service"; + log::info("DATABASE_OUT_OF_SYNC, re-discover service"); p_clcb->auto_update = BTA_GATTC_REQ_WAITING; /* request read db hash first */ p_clcb->p_srcb->srvc_hdl_db_hash = true; @@ -1327,7 +1345,7 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { void bta_gattc_search(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { tGATT_STATUS status = GATT_INTERNAL_ERROR; tBTA_GATTC cb_data; - VLOG(1) << __func__ << ": conn_id=" << loghex(p_clcb->bta_conn_id); + log::verbose("conn_id={}", loghex(p_clcb->bta_conn_id)); if (p_clcb->p_srcb && !p_clcb->p_srcb->gatt_database.IsEmpty()) { status = GATT_SUCCESS; /* search the local cache of a server device */ @@ -1350,7 +1368,7 @@ void bta_gattc_q_cmd(tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_DATA* p_data) { void bta_gattc_fail(tBTA_GATTC_CLCB* p_clcb, UNUSED_ATTR const tBTA_GATTC_DATA* p_data) { if (p_clcb->status == GATT_SUCCESS) { - LOG(ERROR) << "operation not supported at current state " << +p_clcb->state; + log::error("operation not supported at current state {}", p_clcb->state); } } @@ -1383,16 +1401,16 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, const RawAddress& bdaddr, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport) { if (connected) { - LOG_INFO("Connected client_if:%hhu addr:%s, transport:%s reason:%s", - gattc_if, ADDRESS_TO_LOGGABLE_CSTR(bdaddr), - bt_transport_text(transport).c_str(), - gatt_disconnection_reason_text(reason).c_str()); + log::info("Connected client_if:{} addr:{}, transport:{} reason:{}", + gattc_if, ADDRESS_TO_LOGGABLE_CSTR(bdaddr), + bt_transport_text(transport), + gatt_disconnection_reason_text(reason)); btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_OK); } else { - LOG_INFO("Disconnected att_id:%hhu addr:%s, transport:%s reason:%s", - gattc_if, ADDRESS_TO_LOGGABLE_CSTR(bdaddr), - bt_transport_text(transport).c_str(), - gatt_disconnection_reason_text(reason).c_str()); + log::info("Disconnected att_id:{} addr:{}, transport:{} reason:{}", + gattc_if, ADDRESS_TO_LOGGABLE_CSTR(bdaddr), + bt_transport_text(transport), + gatt_disconnection_reason_text(reason)); btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, GATT_CONN_OK); } @@ -1417,7 +1435,7 @@ static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, const RawAddress& bda) { if (p_clcb == NULL) return; - VLOG(1) << __func__ << ": cif:" << +gattc_if; + log::verbose("cif:{}", gattc_if); do_in_main_thread(FROM_HERE, base::BindOnce(&bta_gattc_process_enc_cmpl, gattc_if, bda)); @@ -1479,8 +1497,7 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, } if (att_value->len != BTA_GATTC_SERVICE_CHANGED_LEN) { - LOG(ERROR) << __func__ - << ": received malformed service changed indication, skipping"; + log::error("received malformed service changed indication, skipping"); return false; } @@ -1488,8 +1505,8 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, uint16_t s_handle = ((uint16_t)(*(p)) + (((uint16_t)(*(p + 1))) << 8)); uint16_t e_handle = ((uint16_t)(*(p + 2)) + (((uint16_t)(*(p + 3))) << 8)); - LOG(ERROR) << __func__ << ": service changed s_handle=" << loghex(s_handle) - << ", e_handle=" << loghex(e_handle); + log::error("service changed s_handle={}, e_handle={}", loghex(s_handle), + loghex(e_handle)); /* mark service handle change pending */ p_srcb->srvc_hdl_chg = true; @@ -1537,11 +1554,9 @@ static bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, static void bta_gattc_proc_other_indication(tBTA_GATTC_CLCB* p_clcb, uint8_t op, tGATT_CL_COMPLETE* p_data, tBTA_GATTC_NOTIFY* p_notify) { - VLOG(1) << __func__ - << StringPrintf( - ": check p_data->att_value.handle=%d p_data->handle=%d", - p_data->att_value.handle, p_data->handle); - VLOG(1) << "is_notify " << p_notify->is_notify; + log::verbose("check p_data->att_value.handle={} p_data->handle={}", + p_data->att_value.handle, p_data->handle); + log::verbose("is_notify {}", p_notify->is_notify); p_notify->is_notify = (op == GATTC_OPTYPE_INDICATION) ? false : true; p_notify->len = p_data->att_value.len; @@ -1566,7 +1581,7 @@ static void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op, tBT_TRANSPORT transport; if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) { - LOG(ERROR) << __func__ << ": indication/notif for unknown app"; + log::error("indication/notif for unknown app"); if (op == GATTC_OPTYPE_INDICATION) GATTC_SendHandleValueConfirm(conn_id, p_data->cid); return; @@ -1574,7 +1589,7 @@ static void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op, tBTA_GATTC_RCB* p_clrcb = bta_gattc_cl_get_regcb(gatt_if); if (p_clrcb == NULL) { - LOG(ERROR) << __func__ << ": indication/notif for unregistered app"; + log::error("indication/notif for unregistered app"); if (op == GATTC_OPTYPE_INDICATION) GATTC_SendHandleValueConfirm(conn_id, p_data->cid); return; @@ -1582,7 +1597,7 @@ static void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op, tBTA_GATTC_SERV* p_srcb = bta_gattc_find_srcb(remote_bda); if (p_srcb == NULL) { - LOG(ERROR) << __func__ << ": indication/notif for unknown device, ignore"; + log::error("indication/notif for unknown device, ignore"); if (op == GATTC_OPTYPE_INDICATION) GATTC_SendHandleValueConfirm(conn_id, p_data->cid); return; @@ -1605,7 +1620,7 @@ static void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op, p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport); if (p_clcb == NULL) { - LOG(ERROR) << "No resources"; + log::error("No resources"); return; } @@ -1620,7 +1635,7 @@ static void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op, } /* no one intersted and need ack? */ else if (op == GATTC_OPTYPE_INDICATION) { - VLOG(1) << __func__ << " no one interested, ack now"; + log::verbose("no one interested, ack now"); GATTC_SendHandleValueConfirm(conn_id, p_data->cid); } } @@ -1629,8 +1644,7 @@ static void bta_gattc_process_indicate(uint16_t conn_id, tGATTC_OPTYPE op, static void bta_gattc_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE* p_data) { - VLOG(1) << __func__ << ": conn_id:" << +conn_id << " op:" << +op - << " status:" << +status; + log::verbose("conn_id:{} op:{} status:{}", conn_id, op, status); /* notification and indication processed right away */ if (op == GATTC_OPTYPE_NOTIFICATION || op == GATTC_OPTYPE_INDICATION) { @@ -1640,8 +1654,7 @@ static void bta_gattc_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, /* for all other operation, not expected if w/o connection */ tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (!p_clcb) { - LOG(ERROR) << __func__ << ": unknown conn_id=" << loghex(conn_id) - << " ignore data"; + log::error("unknown conn_id={} ignore data", loghex(conn_id)); return; } @@ -1691,7 +1704,7 @@ static void bta_gattc_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id, tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(gatt_if); if (!p_clreg || !p_clreg->p_cback) { - LOG(ERROR) << __func__ << ": client_if=" << +gatt_if << " not found"; + log::error("client_if={} not found", gatt_if); return; } @@ -1710,7 +1723,7 @@ static void bta_gattc_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id, tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(gatt_if); if (!p_clreg || !p_clreg->p_cback) { - LOG(ERROR) << __func__ << ": client_if=" << gatt_if << " not found"; + log::error("client_if={} not found", gatt_if); return; } @@ -1730,7 +1743,7 @@ static void bta_gattc_subrate_chg_cback(tGATT_IF gatt_if, uint16_t conn_id, tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(gatt_if); if (!p_clreg || !p_clreg->p_cback) { - LOG(ERROR) << __func__ << ": client_if=" << gatt_if << " not found"; + log::error("client_if={} not found", gatt_if); return; } diff --git a/system/bta/gatt/bta_gattc_api.cc b/system/bta/gatt/bta_gattc_api.cc index 26797ac03cc5a22c080db455c4d3a5cc57b3efaa..ea5d42d61acb349f414a24dba060fa832b7534f8 100644 --- a/system/bta/gatt/bta_gattc_api.cc +++ b/system/bta/gatt/bta_gattc_api.cc @@ -26,17 +26,17 @@ #include #include +#include #include #include -#include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/gatt/bta_gattc_int.h" #include "device/include/controller.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "stack/include/bt_hdr.h" #include "stack/include/main_thread.h" #include "types/bluetooth/uuid.h" @@ -44,6 +44,7 @@ #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; /***************************************************************************** * Constants @@ -65,7 +66,7 @@ static const tBTA_SYS_REG bta_gattc_reg = {bta_gattc_hdl_event, ******************************************************************************/ void BTA_GATTC_Disable(void) { if (!bta_sys_is_register(BTA_ID_GATTC)) { - LOG(WARNING) << "GATTC Module not enabled/already disabled"; + log::warn("GATTC Module not enabled/already disabled"); return; } @@ -80,9 +81,9 @@ void BTA_GATTC_Disable(void) { */ void BTA_GATTC_AppRegister(tBTA_GATTC_CBACK* p_client_cb, BtaAppRegisterCallback cb, bool eatt_support) { - LOG_DEBUG("eatt_support=%d", eatt_support); + log::debug("eatt_support={}", eatt_support); if (!bta_sys_is_register(BTA_ID_GATTC)) { - LOG_DEBUG("BTA_ID_GATTC not registered in BTA, registering it"); + log::debug("BTA_ID_GATTC not registered in BTA, registering it"); bta_sys_register(BTA_ID_GATTC, &bta_gattc_reg); } @@ -97,7 +98,7 @@ static void app_deregister_impl(tGATT_IF client_if) { if (p_clreg != nullptr) { bta_gattc_deregister(p_clreg); } else { - LOG_ERROR("Unknown GATT ID: %d, state: %d", client_if, bta_gattc_cb.state); + log::error("Unknown GATT ID: {}, state: {}", client_if, bta_gattc_cb.state); } } /******************************************************************************* @@ -650,8 +651,7 @@ void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t cid) { tBTA_GATTC_API_CONFIRM* p_buf = (tBTA_GATTC_API_CONFIRM*)osi_calloc(sizeof(tBTA_GATTC_API_CONFIRM)); - VLOG(1) << __func__ << ": conn_id=" << +conn_id << " cid=0x" << std::hex - << +cid; + log::verbose("conn_id={} cid=0x{:x}", conn_id, cid); p_buf->hdr.event = BTA_GATTC_API_CONFIRM_EVT; p_buf->hdr.layer_specific = conn_id; @@ -682,7 +682,7 @@ tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF client_if, uint8_t i; if (!handle) { - LOG(ERROR) << __func__ << ": registration failed, handle is 0"; + log::error("registration failed, handle is 0"); return status; } @@ -692,7 +692,7 @@ tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF client_if, if (p_clreg->notif_reg[i].in_use && p_clreg->notif_reg[i].remote_bda == bda && p_clreg->notif_reg[i].handle == handle) { - LOG(WARNING) << "notification already registered"; + log::warn("notification already registered"); status = GATT_SUCCESS; break; } @@ -713,11 +713,11 @@ tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF client_if, } if (i == BTA_GATTC_NOTIF_REG_MAX) { status = GATT_NO_RESOURCES; - LOG(ERROR) << "Max Notification Reached, registration failed."; + log::error("Max Notification Reached, registration failed."); } } } else { - LOG(ERROR) << "client_if=" << +client_if << " Not Registered"; + log::error("client_if={} Not Registered", client_if); } return status; @@ -741,14 +741,14 @@ tGATT_STATUS BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if, const RawAddress& bda, uint16_t handle) { if (!handle) { - LOG(ERROR) << __func__ << ": deregistration failed, handle is 0"; + log::error("deregistration failed, handle is 0"); return GATT_ILLEGAL_PARAMETER; } tBTA_GATTC_RCB* p_clreg = bta_gattc_cl_get_regcb(client_if); if (p_clreg == NULL) { - LOG(ERROR) << __func__ << " client_if=" << +client_if - << " not registered bd_addr=" << ADDRESS_TO_LOGGABLE_STR(bda); + log::error("client_if={} not registered bd_addr={}", client_if, + ADDRESS_TO_LOGGABLE_STR(bda)); return GATT_ILLEGAL_PARAMETER; } @@ -756,15 +756,13 @@ tGATT_STATUS BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if, if (p_clreg->notif_reg[i].in_use && p_clreg->notif_reg[i].remote_bda == bda && p_clreg->notif_reg[i].handle == handle) { - VLOG(1) << __func__ << " deregistered bd_addr=" - << ADDRESS_TO_LOGGABLE_STR(bda); + log::verbose("deregistered bd_addr={}", ADDRESS_TO_LOGGABLE_STR(bda)); memset(&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG)); return GATT_SUCCESS; } } - LOG(ERROR) << __func__ << " registration not found bd_addr=" - << ADDRESS_TO_LOGGABLE_STR(bda); + log::error("registration not found bd_addr={}", ADDRESS_TO_LOGGABLE_STR(bda)); return GATT_ERROR; } diff --git a/system/bta/gatt/bta_gattc_cache.cc b/system/bta/gatt/bta_gattc_cache.cc index d337fa795f9a8bb0cef52711a9054c68c7899911..b5059597da05109f58be0bc48d507d915f7df013 100644 --- a/system/bta/gatt/bta_gattc_cache.cc +++ b/system/bta/gatt/bta_gattc_cache.cc @@ -28,15 +28,18 @@ #include #include #include +#include #include #include +#include -#include "bt_target.h" // Must be first to define build configuration #include "bta/gatt/bta_gattc_int.h" #include "bta/gatt/database.h" #include "common/init_flags.h" #include "device/include/interop.h" +#include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR @@ -49,6 +52,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; using base::StringPrintf; using bluetooth::Uuid; @@ -94,22 +98,22 @@ typedef struct { /* debug function to display the server cache */ static void bta_gattc_display_cache_server(const Database& database) { - LOG(INFO) << "<=--------------=Start Server Cache =-----------=>"; + log::info("<=--------------=Start Server Cache =-----------=>"); std::istringstream iss(database.ToString()); for (std::string line; std::getline(iss, line);) { - LOG(INFO) << line; + log::info("{}", line); } - LOG(INFO) << "<=--------------=End Server Cache =-----------=>"; + log::info("<=--------------=End Server Cache =-----------=>"); } /** debug function to display the exploration list */ static void bta_gattc_display_explore_record(const DatabaseBuilder& database) { - LOG(INFO) << "<=--------------=Start Explore Queue =-----------=>"; + log::info("<=--------------=Start Explore Queue =-----------=>"); std::istringstream iss(database.ToString()); for (std::string line; std::getline(iss, line);) { - LOG(INFO) << line; + log::info("{}", line); } - LOG(INFO) << "<=--------------= End Explore Queue =-----------=>"; + log::info("<=--------------= End Explore Queue =-----------=>"); } #endif /* BTA_GATT_DEBUG == TRUE */ @@ -132,12 +136,12 @@ const Service* bta_gattc_find_matching_service( /// Whether the peer device uses robust caching RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, const gatt::Database& db) { - LOG_DEBUG("GetRobustCachingSupport %s", - p_clcb->bda.ToRedactedStringForLogging().c_str()); + log::debug("GetRobustCachingSupport {}", + p_clcb->bda.ToRedactedStringForLogging()); // If the feature is disabled, then we never support it if (!bta_gattc_is_robust_caching_enabled()) { - LOG_DEBUG("robust caching is disabled, so UNSUPPORTED"); + log::debug("robust caching is disabled, so UNSUPPORTED"); return RobustCachingSupport::UNSUPPORTED; } @@ -152,7 +156,7 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, for (const auto& characteristic : service.characteristics) { if (characteristic.uuid.As16Bit() == GATT_UUID_DATABASE_HASH) { // the hash was found, so we should read it - LOG_DEBUG("database hash characteristic found, so SUPPORTED"); + log::debug("database hash characteristic found, so SUPPORTED"); return RobustCachingSupport::SUPPORTED; } } @@ -162,13 +166,13 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, // searching for it. Even if the hash was previously not present but is now, // we will still get the service changed indication, so there's no need to // speculatively check for the hash every time. - LOG_DEBUG("database hash characteristic not found, so UNSUPPORTED"); + log::debug("database hash characteristic not found, so UNSUPPORTED"); return RobustCachingSupport::UNSUPPORTED; } if (p_clcb->transport == BT_TRANSPORT_LE && !BTM_IsRemoteVersionReceived(p_clcb->bda)) { - LOG_INFO("version info is not ready yet"); + log::info("version info is not ready yet"); return RobustCachingSupport::W4_REMOTE_VERSION; } @@ -179,13 +183,13 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, // support GATT Caching. uint8_t lmp_version = 0; if (!BTM_ReadRemoteVersion(p_clcb->bda, &lmp_version, nullptr, nullptr)) { - LOG_WARN("Could not read remote version for %s", - ADDRESS_TO_LOGGABLE_CSTR(p_clcb->bda)); + log::warn("Could not read remote version for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_clcb->bda)); } if (lmp_version < 0x0a) { - LOG_WARN( - " Device LMP version 0x%02x < Bluetooth 5.1. Ignore database cache " + log::warn( + "Device LMP version 0x{:02x} < Bluetooth 5.1. Ignore database cache " "read.", lmp_version); return RobustCachingSupport::UNSUPPORTED; @@ -196,16 +200,16 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, // version and OUI prefix. if (lmp_version < 0x0c && interop_match_addr(INTEROP_DISABLE_ROBUST_CACHING, &p_clcb->bda)) { - LOG_WARN( - "Device LMP version 0x%02x <= Bluetooth 5.2 and MAC addr on " - "interop list, skipping robust caching", + log::warn( + "Device LMP version 0x{:02x} <= Bluetooth 5.2 and MAC addr on interop " + "list, skipping robust caching", lmp_version); return RobustCachingSupport::UNSUPPORTED; } // If we have no cached database and no interop considerations, // it is unknown whether or not robust caching is supported - LOG_DEBUG("database hash support is UNKNOWN"); + log::debug("database hash support is UNKNOWN"); return RobustCachingSupport::UNKNOWN; } @@ -230,14 +234,14 @@ static void bta_gattc_explore_next_service(uint16_t conn_id, tBTA_GATTC_SERV* p_srvc_cb) { tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (!p_clcb) { - LOG(ERROR) << "unknown conn_id=" << loghex(conn_id); + log::error("unknown conn_id={}", loghex(conn_id)); return; } if (p_srvc_cb->pending_discovery.StartNextServiceExploration()) { const auto& service = p_srvc_cb->pending_discovery.CurrentlyExploredService(); - VLOG(1) << "Start service discovery"; + log::verbose("Start service discovery"); /* start discovering included services */ GATTC_Discover(conn_id, GATT_DISC_INC_SRVC, service.first, service.second); @@ -289,12 +293,12 @@ static void bta_gattc_explore_srvc_finished(uint16_t conn_id, tBTA_GATTC_SERV* p_srvc_cb) { tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (!p_clcb) { - LOG(ERROR) << "unknown conn_id=" << loghex(conn_id); + log::error("unknown conn_id={}", loghex(conn_id)); return; } /* no service found at all, the end of server discovery*/ - LOG(INFO) << __func__ << ": service discovery finished"; + log::info("service discovery finished"); p_srvc_cb->gatt_database = p_srvc_cb->pending_discovery.Build(); @@ -317,15 +321,15 @@ static void bta_gattc_explore_srvc_finished(uint16_t conn_id, // If the device is trusted, link the addr file to hash file if (success && btm_sec_is_a_bonded_dev(p_srvc_cb->server_bda)) { - LOG_DEBUG( - "Linking db hash to address %s", - p_clcb->p_srcb->server_bda.ToRedactedStringForLogging().c_str()); + log::debug("Linking db hash to address {}", + p_clcb->p_srcb->server_bda.ToRedactedStringForLogging()); bta_gattc_cache_link(p_clcb->p_srcb->server_bda, hash); } // After success, reset the count. - LOG_DEBUG("service discovery succeed, reset count to zero, conn_id=0x%04x", - conn_id); + log::debug( + "service discovery succeed, reset count to zero, conn_id=0x{:04x}", + conn_id); p_srvc_cb->srvc_disc_count = 0; } @@ -335,7 +339,7 @@ static void bta_gattc_explore_srvc_finished(uint16_t conn_id, /** Start discovery for characteristic descriptor */ void bta_gattc_start_disc_char_dscp(uint16_t conn_id, tBTA_GATTC_SERV* p_srvc_cb) { - VLOG(1) << "starting discover characteristics descriptor"; + log::verbose("starting discover characteristics descriptor"); std::pair range = p_srvc_cb->pending_discovery.NextDescriptorRangeToExplore(); @@ -362,7 +366,7 @@ void bta_gattc_sdp_callback(UNUSED_ATTR const RawAddress& bd_addr, tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_scb_by_cid(cb_data->sdp_conn_id); if (p_srvc_cb == nullptr) { - LOG(ERROR) << "GATT service discovery is done on unknown connection"; + log::error("GATT service discovery is done on unknown connection"); /* allocated in bta_gattc_sdp_service_disc */ osi_free(cb_data); return; @@ -396,15 +400,14 @@ void bta_gattc_sdp_callback(UNUSED_ATTR const RawAddress& bd_addr, uint16_t end_handle = (uint16_t)pe.params[1]; #if (BTA_GATT_DEBUG == TRUE) - VLOG(1) << "Found ATT service uuid=" << service_uuid - << ", s_handle=" << loghex(start_handle) - << ", e_handle=" << loghex(end_handle); + log::verbose("Found ATT service uuid={}, s_handle={}, e_handle={}", + service_uuid, loghex(start_handle), loghex(end_handle)); #endif if (!GATT_HANDLE_IS_VALID(start_handle) || !GATT_HANDLE_IS_VALID(end_handle)) { - LOG(ERROR) << "invalid start_handle=" << loghex(start_handle) - << ", end_handle=" << loghex(end_handle); + log::error("invalid start_handle={}, end_handle={}", loghex(start_handle), + loghex(end_handle)); p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb( cb_data->p_sdp_db, 0, p_sdp_rec); continue; @@ -524,7 +527,7 @@ void bta_gattc_disc_res_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, case GATT_DISC_MAX: default: - LOG_ERROR("Received illegal discovery item"); + log::error("Received illegal discovery item"); break; } } @@ -545,9 +548,8 @@ void bta_gattc_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, p_srvc_cb->srvc_disc_count++; p_clcb->auto_update = BTA_GATTC_DISC_WAITING; } else { - LOG(ERROR) << __func__ - << ": retry limit exceeds for db out of sync, conn_id=" - << conn_id; + log::error("retry limit exceeds for db out of sync, conn_id={}", + conn_id); } } @@ -590,7 +592,7 @@ void bta_gattc_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, case GATT_DISC_MAX: default: - LOG_ERROR("Received illegal discovery item"); + log::error("Received illegal discovery item"); break; } } @@ -601,8 +603,7 @@ void bta_gattc_search_service(tBTA_GATTC_CLCB* p_clcb, Uuid* p_uuid) { if (p_uuid && *p_uuid != service.uuid) continue; #if (BTA_GATT_DEBUG == TRUE) - VLOG(1) << __func__ << "found service " << service.uuid - << " handle:" << +service.handle; + log::verbose("found service {} handle:{}", service.uuid, service.handle); #endif if (!p_clcb->p_rcb->p_cback) continue; @@ -752,7 +753,7 @@ static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb, bool is_svc_chg) { uint8_t op = (uint8_t)p_data->op_code; if (op != GATTC_OPTYPE_READ) { - VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific; + log::verbose("op = {}", p_data->hdr.layer_specific); return; } p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE; @@ -772,11 +773,10 @@ static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb, Octet16 local_hash = p_clcb->p_srcb->gatt_database.Hash(); matched = (local_hash == remote_hash); - LOG_DEBUG("lhash=%s", - base::HexEncode(local_hash.data(), local_hash.size()).c_str()); - LOG_DEBUG( - "rhash=%s", - base::HexEncode(remote_hash.data(), remote_hash.size()).c_str()); + log::debug("lhash={}", + base::HexEncode(local_hash.data(), local_hash.size())); + log::debug("rhash={}", + base::HexEncode(remote_hash.data(), remote_hash.size())); if (!matched) { gatt::Database db = bta_gattc_hash_load(remote_hash); @@ -800,20 +800,20 @@ static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb, p_clcb->p_srcb->gatt_database = db; found = true; } - LOG_DEBUG("load cache directly, result=%d", found); + log::debug("load cache directly, result={}", found); } else { - LOG_DEBUG("skip read cache, is_svc_chg=%d, is_a_bonded_dev=%d", - is_svc_chg, is_a_bonded_dev); + log::debug("skip read cache, is_svc_chg={}, is_a_bonded_dev={}", + is_svc_chg, is_a_bonded_dev); } } if (matched) { - LOG_DEBUG("hash is the same, skip service discovery"); + log::debug("hash is the same, skip service discovery"); p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS); } else { if (found) { - LOG_DEBUG("hash found in cache, skip service discovery"); + log::debug("hash found in cache, skip service discovery"); #if (BTA_GATT_DEBUG == TRUE) bta_gattc_display_cache_server(p_clcb->p_srcb->gatt_database); @@ -822,7 +822,7 @@ static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb, p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE; bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS); } else { - LOG_DEBUG("hash is not the same, start service discovery"); + log::debug("hash is not the same, start service discovery"); bta_gattc_start_discover_internal(p_clcb); } } @@ -833,12 +833,12 @@ static void bta_gattc_read_ext_prop_desc_cmpl( tBTA_GATTC_CLCB* p_clcb, const tBTA_GATTC_OP_CMPL* p_data) { uint8_t op = (uint8_t)p_data->op_code; if (op != GATTC_OPTYPE_READ) { - VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific; + log::verbose("op = {}", p_data->hdr.layer_specific); return; } if (!p_clcb->disc_active) { - VLOG(1) << __func__ << ": not active in discover state"; + log::verbose("not active in discover state"); return; } p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE; @@ -855,7 +855,7 @@ static void bta_gattc_read_ext_prop_desc_cmpl( } if (status != GATT_SUCCESS) { - LOG(WARNING) << "Discovery on server failed: " << loghex(status); + log::warn("Discovery on server failed: {}", loghex(status)); bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR); return; } @@ -864,8 +864,8 @@ static void bta_gattc_read_ext_prop_desc_cmpl( if (p_srvc_cb->read_multiple_not_supported && att_value.len != 2) { // Just one Characteristic Extended Properties value at a time in Read // Response - LOG(WARNING) << __func__ << " Read Response should be just 2 bytes!"; - bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR); + log::warn("Read Response should be just 2 bytes!"); + bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_INVALID_PDU); return; } @@ -881,8 +881,7 @@ static void bta_gattc_read_ext_prop_desc_cmpl( bool ret = p_srvc_cb->pending_discovery.SetValueOfDescriptors(value_of_descriptors); if (!ret) { - LOG(WARNING) << __func__ - << " Problem setting Extended Properties descriptors values"; + log::warn("Problem setting Extended Properties descriptors values"); bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR); return; } @@ -966,9 +965,8 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV* p_srvc_cb, uint16_t start_handle, uint16_t end_handle, btgatt_db_element_t** db, int* count) { - VLOG(1) << __func__ - << StringPrintf(": start_handle 0x%04x, end_handle 0x%04x", - start_handle, end_handle); + log::verbose("start_handle 0x{:04x}, end_handle 0x{:04x}", start_handle, + end_handle); if (p_srvc_cb->gatt_database.IsEmpty()) { *count = 0; @@ -1048,20 +1046,20 @@ void bta_gattc_get_gatt_db(uint16_t conn_id, uint16_t start_handle, int* count) { tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); - LOG_INFO("%s", __func__); + log::info(""); if (p_clcb == NULL) { - LOG(ERROR) << "Unknown conn_id=" << loghex(conn_id); + log::error("Unknown conn_id={}", loghex(conn_id)); return; } if (p_clcb->state != BTA_GATTC_CONN_ST) { - LOG(ERROR) << "server cache not available, CLCB state=" << +p_clcb->state; + log::error("server cache not available, CLCB state={}", p_clcb->state); return; } if (!p_clcb->p_srcb || p_clcb->p_srcb->pending_discovery.InProgress() || p_clcb->p_srcb->gatt_database.IsEmpty()) { - LOG(ERROR) << "No server cache available"; + log::error("No server cache available"); return; } diff --git a/system/bta/gatt/bta_gattc_db_storage.cc b/system/bta/gatt/bta_gattc_db_storage.cc index 9a862c8671d413287f1a15468fda84d9112a22da..08c3ac107b0df01e522bbbf07cb31c72b147dc13 100644 --- a/system/bta/gatt/bta_gattc_db_storage.cc +++ b/system/bta/gatt/bta_gattc_db_storage.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -32,6 +33,8 @@ #include "stack/include/gattdefs.h" #include "types/bluetooth/uuid.h" +using namespace bluetooth; + using gatt::StoredAttribute; using std::string; using std::vector; @@ -89,8 +92,8 @@ static gatt::Database EMPTY_DB; static gatt::Database bta_gattc_load_db(const char* fname) { FILE* fd = fopen(fname, "rb"); if (!fd) { - LOG(ERROR) << __func__ << ": can't open GATT cache file " << fname - << " for reading, error: " << strerror(errno); + log::error("can't open GATT cache file {} for reading, error: {}", fname, + strerror(errno)); return EMPTY_DB; } @@ -98,18 +101,17 @@ static gatt::Database bta_gattc_load_db(const char* fname) { uint16_t num_attr = 0; if (fread(&cache_ver, sizeof(uint16_t), 1, fd) != 1) { - LOG(ERROR) << __func__ << ": can't read GATT cache version from: " << fname; + log::error("can't read GATT cache version from: {}", fname); goto done; } if (cache_ver != GATT_CACHE_VERSION) { - LOG(ERROR) << __func__ << ": wrong GATT cache version: " << fname; + log::error("wrong GATT cache version: {}", fname); goto done; } if (fread(&num_attr, sizeof(uint16_t), 1, fd) != 1) { - LOG(ERROR) << __func__ - << ": can't read number of GATT attributes: " << fname; + log::error("can't read number of GATT attributes: {}", fname); goto done; } @@ -117,7 +119,7 @@ static gatt::Database bta_gattc_load_db(const char* fname) { std::vector attr(num_attr); if (fread(attr.data(), sizeof(StoredAttribute), num_attr, fd) != num_attr) { - LOG(ERROR) << __func__ << ": can't read GATT attributes: " << fname; + log::error("can't read GATT attributes: {}", fname); goto done; } fclose(fd); @@ -212,7 +214,7 @@ void StoredAttribute::SerializeStoredAttribute(const StoredAttribute& attr, bytes.push_back(attr.value.characteristic_extended_properties >> 8); break; default: - // LOG_VERBOSE("Unhandled type UUID 0x%04x", attr.type.As16Bit()); + // log::verbose("Unhandled type UUID 0x{:04x}", attr.type.As16Bit()); break; } } @@ -239,22 +241,20 @@ static bool bta_gattc_store_db(const char* fname, const std::vector& attr) { FILE* fd = fopen(fname, "wb"); if (!fd) { - LOG(ERROR) << __func__ - << ": can't open GATT cache file for writing: " << fname; + log::error("can't open GATT cache file for writing: {}", fname); return false; } uint16_t cache_ver = GATT_CACHE_VERSION; if (fwrite(&cache_ver, sizeof(uint16_t), 1, fd) != 1) { - LOG(ERROR) << __func__ << ": can't write GATT cache version: " << fname; + log::error("can't write GATT cache version: {}", fname); fclose(fd); return false; } uint16_t num_attr = attr.size(); if (fwrite(&num_attr, sizeof(uint16_t), 1, fd) != 1) { - LOG(ERROR) << __func__ - << ": can't write GATT cache attribute count: " << fname; + log::error("can't write GATT cache attribute count: {}", fname); fclose(fd); return false; } @@ -267,7 +267,7 @@ static bool bta_gattc_store_db(const char* fname, if (fwrite(db_bytes.data(), sizeof(uint8_t), db_bytes.size(), fd) != db_bytes.size()) { - LOG(ERROR) << __func__ << ": can't write GATT cache attributes: " << fname; + log::error("can't write GATT cache attributes: {}", fname); fclose(fd); return false; } @@ -325,7 +325,7 @@ void bta_gattc_cache_link(const RawAddress& server_bda, const Octet16& hash) { unlink(addr_file); // remove addr file first if the file exists if (link(hash_file, addr_file) == -1) { - LOG_ERROR("link %s to %s, errno=%d", addr_file, hash_file, errno); + log::error("link {} to {}, errno={}", addr_file, hash_file, errno); } } @@ -362,7 +362,7 @@ bool bta_gattc_hash_write(const Octet16& hash, const gatt::Database& database) { * ******************************************************************************/ void bta_gattc_cache_reset(const RawAddress& server_bda) { - VLOG(1) << __func__; + log::verbose(""); char fname[255] = {0}; bta_gattc_generate_cache_file_name(fname, sizeof(fname), server_bda); unlink(fname); @@ -384,7 +384,7 @@ static void bta_gattc_hash_remove_least_recently_used_if_possible() { std::unique_ptr dirp(opendir(GATT_HASH_PATH), &closedir); if (dirp == nullptr) { - LOG_ERROR("open dir error, dir=%s", GATT_HASH_PATH); + log::error("open dir error, dir={}", GATT_HASH_PATH); return; } @@ -394,7 +394,7 @@ static void bta_gattc_hash_remove_least_recently_used_if_possible() { string candidate_item; vector expired_items; - LOG_DEBUG("<-----------Start Local Hash Cache---------->"); + log::debug("<-----------Start Local Hash Cache---------->"); dirent* dp; while ((dp = readdir(dirp.get())) != nullptr) { if (strncmp(".", dp->d_name, 1) == 0 || strncmp("..", dp->d_name, 2) == 0) { @@ -423,8 +423,8 @@ static void bta_gattc_hash_remove_least_recently_used_if_possible() { struct stat buf; int result = lstat(tmp, &buf); - LOG_DEBUG("name=%s, result=%d, linknum=%lu, mtime=%lu", dp->d_name, result, - (unsigned long)buf.st_nlink, (unsigned long)buf.st_mtime); + log::debug("name={}, result={}, linknum={}, mtime={}", dp->d_name, result, + (unsigned long)buf.st_nlink, (unsigned long)buf.st_mtime); // if hard link count of the file is 1, it means no trusted device links to // the inode. It is safe to be a candidate to be removed @@ -441,17 +441,17 @@ static void bta_gattc_hash_remove_least_recently_used_if_possible() { } } } - LOG_DEBUG("<-----------End Local Hash Cache------------>"); + log::debug("<-----------End Local Hash Cache------------>"); // if the number of hash files exceeds the limit, remove the cadidate item. if (count > GATT_HASH_MAX_SIZE && !candidate_item.empty()) { unlink(candidate_item.c_str()); - LOG_DEBUG("delete hash file (size), name=%s", candidate_item.c_str()); + log::debug("delete hash file (size), name={}", candidate_item); } // If there is any file expired, also delete it. for (string expired_item : expired_items) { unlink(expired_item.c_str()); - LOG_DEBUG("delete hash file (expired), name=%s", expired_item.c_str()); + log::debug("delete hash file (expired), name={}", expired_item); } } diff --git a/system/bta/gatt/bta_gattc_int.h b/system/bta/gatt/bta_gattc_int.h index 7582e769a452c4869e2733ab904dd6b6602c1893..61986104b65981bb5a77437e2852042d72b77d9b 100644 --- a/system/bta/gatt/bta_gattc_int.h +++ b/system/bta/gatt/bta_gattc_int.h @@ -24,6 +24,8 @@ #ifndef BTA_GATTC_INT_H #define BTA_GATTC_INT_H +#include + #include #include @@ -521,4 +523,10 @@ void bta_gattc_cache_write(const RawAddress& server_bda, void bta_gattc_cache_link(const RawAddress& server_bda, const Octet16& hash); void bta_gattc_cache_reset(const RawAddress& server_bda); +namespace fmt { +template <> +struct formatter : enum_formatter { +}; +} // namespace fmt + #endif /* BTA_GATTC_INT_H */ diff --git a/system/bta/gatt/bta_gattc_main.cc b/system/bta/gatt/bta_gattc_main.cc index 643fb72e55167db2c63a6261362fd8d2fd457805..55efc0215f9bfadb8cc838a79cb5ccf464890006 100644 --- a/system/bta/gatt/bta_gattc_main.cc +++ b/system/bta/gatt/bta_gattc_main.cc @@ -25,13 +25,15 @@ #include #include +#include -#include "bt_target.h" // Must be first to define build configuration" #include "bta/gatt/bta_gattc_int.h" -#include "osi/include/log.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "stack/include/bt_hdr.h" using base::StringPrintf; +using namespace bluetooth; /***************************************************************************** * Constants and types @@ -307,12 +309,10 @@ bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event, tBTA_GATTC_STATE in_state = p_clcb->state; uint16_t in_event = event; #if (BTA_GATT_DEBUG == TRUE) - VLOG(1) << StringPrintf("%s: State 0x%02x [%s], Event 0x%x[%s]", __func__, - in_state, gattc_state_code(in_state), in_event, - gattc_evt_code(in_event)); + log::verbose("State 0x{:02x} [{}], Event 0x{:x}[{}]", in_state, + gattc_state_code(in_state), in_event, gattc_evt_code(in_event)); #else - VLOG(1) << StringPrintf("%s: State 0x%02x, Event 0x%x", __func__, in_state, - in_event); + log::verbose("State 0x{:02x}, Event 0x{:x}", in_state, in_event); #endif /* look up the state table for the current state */ @@ -341,15 +341,13 @@ bool bta_gattc_sm_execute(tBTA_GATTC_CLCB* p_clcb, uint16_t event, #if (BTA_GATT_DEBUG == TRUE) if (in_state != p_clcb->state) { - VLOG(1) << StringPrintf("GATTC State Change: [%s] -> [%s] after Event [%s]", - gattc_state_code(in_state), - gattc_state_code(p_clcb->state), - gattc_evt_code(in_event)); + log::verbose("GATTC State Change: [{}] -> [{}] after Event [{}]", + gattc_state_code(in_state), gattc_state_code(p_clcb->state), + gattc_evt_code(in_event)); } #else - VLOG(1) << StringPrintf( - "%s: GATTC State Change: 0x%02x -> 0x%02x after Event 0x%x", __func__, - in_state, p_clcb->state, in_event); + log::verbose("GATTC State Change: 0x{:02x} -> 0x{:02x} after Event 0x{:x}", + in_state, p_clcb->state, in_event); #endif return rt; } @@ -368,7 +366,7 @@ bool bta_gattc_hdl_event(const BT_HDR_RIGID* p_msg) { tBTA_GATTC_CLCB* p_clcb = NULL; bool rt = true; #if (BTA_GATT_DEBUG == TRUE) - VLOG(1) << __func__ << ": Event:" << gattc_evt_code(p_msg->event); + log::verbose("Event:{}", gattc_evt_code(p_msg->event)); #endif switch (p_msg->event) { @@ -392,7 +390,7 @@ bool bta_gattc_hdl_event(const BT_HDR_RIGID* p_msg) { rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (const tBTA_GATTC_DATA*)p_msg); } else { - LOG_ERROR("Ignore unknown conn ID: %d", +p_msg->layer_specific); + log::error("Ignore unknown conn ID: {}", p_msg->layer_specific); } break; diff --git a/system/bta/gatt/bta_gattc_queue.cc b/system/bta/gatt/bta_gattc_queue.cc index 982d67b81f3d0f0d7458a091cba18bbcb33df555..7531323a301e0728cd214b5faee5d891eb26f5a0 100644 --- a/system/bta/gatt/bta_gattc_queue.cc +++ b/system/bta/gatt/bta_gattc_queue.cc @@ -16,18 +16,20 @@ #define LOG_TAG "gatt" -#include "bta_gatt_queue.h" +#include +#include #include #include #include +#include +#include "bta_gatt_queue.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" - -#include using gatt_operation = BtaGattQueue::gatt_operation; +using namespace bluetooth; constexpr uint8_t GATT_READ_CHAR = 1; constexpr uint8_t GATT_READ_DESC = 2; @@ -139,21 +141,20 @@ void BtaGattQueue::gatt_read_multi_op_finished(uint16_t conn_id, } void BtaGattQueue::gatt_execute_next_op(uint16_t conn_id) { - LOG_VERBOSE("%s: conn_id=0x%x", __func__, conn_id); + log::verbose("conn_id=0x{:x}", conn_id); if (gatt_op_queue.empty()) { - LOG_VERBOSE("%s: op queue is empty", __func__); + log::verbose("op queue is empty"); return; } auto map_ptr = gatt_op_queue.find(conn_id); if (map_ptr == gatt_op_queue.end() || map_ptr->second.empty()) { - LOG_VERBOSE("%s: no more operations queued for conn_id %d", __func__, - conn_id); + log::verbose("no more operations queued for conn_id {}", conn_id); return; } if (gatt_op_queue_executing.count(conn_id)) { - LOG_VERBOSE("%s: can't enqueue next op, already executing", __func__); + log::verbose("can't enqueue next op, already executing"); return; } @@ -266,7 +267,7 @@ void BtaGattQueue::WriteDescriptor(uint16_t conn_id, uint16_t handle, } void BtaGattQueue::ConfigureMtu(uint16_t conn_id, uint16_t mtu) { - LOG(INFO) << __func__ << ", mtu: " << static_cast(mtu); + log::info("mtu: {}", static_cast(mtu)); std::vector value = {static_cast(mtu & 0xff), static_cast(mtu >> 8)}; gatt_op_queue[conn_id].push_back({.type = GATT_CONFIG_MTU, @@ -285,4 +286,4 @@ void BtaGattQueue::ReadMultiCharacteristic(uint16_t conn_id, .read_multi_cb = cb, .read_cb_data = cb_data}); gatt_execute_next_op(conn_id); -} \ No newline at end of file +} diff --git a/system/bta/gatt/bta_gattc_utils.cc b/system/bta/gatt/bta_gattc_utils.cc index aed8721085efd964e520c9ad084f0b75b5fb0b93..22c9b575f72e4a0c10da339bd0772dbcf313495b 100644 --- a/system/bta/gatt/bta_gattc_utils.cc +++ b/system/bta/gatt/bta_gattc_utils.cc @@ -25,6 +25,7 @@ #define LOG_TAG "bt_bta_gattc" #include +#include #include @@ -38,9 +39,11 @@ #include "types/hci_role.h" #include "types/raw_address.h" +using namespace bluetooth; + static uint8_t ble_acceptlist_size() { const controller_t* controller = controller_get_interface(); - if (!controller->supports_ble()) { + if (!controller->SupportsBle()) { return 0; } return controller->get_ble_acceptlist_size(); @@ -140,7 +143,7 @@ tBTA_GATTC_CLCB* bta_gattc_clcb_alloc(tGATT_IF client_if, for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) { if (!bta_gattc_cb.clcb[i_clcb].in_use) { #if (BTA_GATT_DEBUG == TRUE) - VLOG(1) << __func__ << ": found clcb:" << +i_clcb << " available"; + log::verbose("found clcb:{} available", i_clcb); #endif p_clcb = &bta_gattc_cb.clcb[i_clcb]; p_clcb->in_use = true; @@ -220,7 +223,7 @@ void bta_gattc_server_disconnected(tBTA_GATTC_SERV* p_srcb) { ******************************************************************************/ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB* p_clcb) { if (!p_clcb) { - LOG(ERROR) << __func__ << " p_clcb=NULL"; + log::error("p_clcb=NULL"); return; } @@ -382,8 +385,8 @@ void bta_gattc_send_mtu_response(tBTA_GATTC_CLCB* p_clcb, void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb) { if (p_clcb->p_q_cmd != NULL) { - LOG_INFO("Already scheduled another request for conn_id = 0x%04x", - p_clcb->bta_conn_id); + log::info("Already scheduled another request for conn_id = 0x{:04x}", + p_clcb->bta_conn_id); return; } @@ -415,7 +418,7 @@ void bta_gattc_continue(tBTA_GATTC_CLCB* p_clcb) { /* Handled, free command below and continue with a p_q_cmd_queue */ break; case MTU_EXCHANGE_IN_PROGRESS: - LOG_WARN("Waiting p_clcb %p", p_clcb); + log::warn("Waiting p_clcb {}", fmt::ptr(p_clcb)); return; case MTU_EXCHANGE_NOT_DONE_YET: p_clcb->p_q_cmd_queue.pop_front(); @@ -458,9 +461,9 @@ BtaEnqueuedResult_t bta_gattc_enqueue(tBTA_GATTC_CLCB* p_clcb, return ENQUEUED_READY_TO_SEND; } - LOG_INFO( - "Already has a pending command to executer. Queuing for later %s conn " - "id=0x%04x", + log::info( + "Already has a pending command to executer. Queuing for later {} conn " + "id=0x{:04x}", ADDRESS_TO_LOGGABLE_CSTR(p_clcb->bda), p_clcb->bta_conn_id); p_clcb->p_q_cmd_queue.push_back(p_data); @@ -486,7 +489,7 @@ bool bta_gattc_check_notif_registry(tBTA_GATTC_RCB* p_clreg, p_clreg->notif_reg[i].remote_bda == p_srcb->server_bda && p_clreg->notif_reg[i].handle == p_notify->handle && !p_clreg->notif_reg[i].app_disconnected) { - VLOG(1) << "Notification registered!"; + log::verbose("Notification registered!"); return true; } } @@ -531,7 +534,7 @@ void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb, } } } else { - LOG(ERROR) << "can not clear indication/notif registration for unknown app"; + log::error("can not clear indication/notif registration for unknown app"); } return; } @@ -573,9 +576,8 @@ bool bta_gattc_mark_bg_conn(tGATT_IF client_if, } } if (!add) { - LOG(ERROR) << __func__ - << " unable to find the bg connection mask for bd_addr=" - << ADDRESS_TO_LOGGABLE_STR(remote_bda_ptr); + log::error("unable to find the bg connection mask for bd_addr={}", + ADDRESS_TO_LOGGABLE_STR(remote_bda_ptr)); return false; } else /* adding a new device mask */ { @@ -591,7 +593,7 @@ bool bta_gattc_mark_bg_conn(tGATT_IF client_if, return true; } } - LOG(ERROR) << "no available space to mark the bg connection status"; + log::error("no available space to mark the bg connection status"); return false; } } @@ -664,7 +666,7 @@ tBTA_GATTC_CONN* bta_gattc_conn_alloc(const RawAddress& remote_bda) { for (i_conn = 0; i_conn < GATT_MAX_PHY_CHANNEL; i_conn++, p_conn++) { if (!p_conn->in_use) { #if (BTA_GATT_DEBUG == TRUE) - VLOG(1) << __func__ << ": found conn_track:" << +i_conn << " available"; + log::verbose("found conn_track:{} available", i_conn); #endif p_conn->in_use = true; p_conn->remote_bda = remote_bda; @@ -690,7 +692,7 @@ tBTA_GATTC_CONN* bta_gattc_conn_find(const RawAddress& remote_bda) { for (i_conn = 0; i_conn < GATT_MAX_PHY_CHANNEL; i_conn++, p_conn++) { if (p_conn->in_use && remote_bda == p_conn->remote_bda) { #if (BTA_GATT_DEBUG == TRUE) - VLOG(1) << __func__ << ": found conn_track:" << +i_conn << " matched"; + log::verbose("found conn_track:{} matched", i_conn); #endif return p_conn; } @@ -793,8 +795,8 @@ tBTA_GATTC_CLCB* bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA* p_msg) { p_msg->int_conn.transport); } if (p_clcb == NULL) { - VLOG(1) << " disconnection ID:" << +p_msg->int_conn.hdr.layer_specific - << " not used by BTA"; + log::verbose("disconnection ID:{} not used by BTA", + p_msg->int_conn.hdr.layer_specific); } return p_clcb; } diff --git a/system/bta/gatt/bta_gatts_act.cc b/system/bta/gatt/bta_gatts_act.cc index 4d5cfa5f5e334252c58d14bf2f2d9a0027f035c5..cf5b6c0fbbf662a994ea4a752230b1cf02105c59 100644 --- a/system/bta/gatt/bta_gatts_act.cc +++ b/system/bta/gatt/bta_gatts_act.cc @@ -23,18 +23,22 @@ * ******************************************************************************/ +#include +#include + #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/gatt/bta_gatts_int.h" #include "bta/include/bta_api.h" #include "btif/include/btif_debug_conn.h" +#include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "stack/include/gatt_api.h" #include "types/raw_address.h" -#include +using namespace bluetooth; static void bta_gatts_nv_save_cback(bool is_saved, tGATTS_HNDL_RANGE* p_hndl_range); @@ -119,7 +123,7 @@ static bool bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, ******************************************************************************/ void bta_gatts_enable(tBTA_GATTS_CB* p_cb) { if (p_cb->enabled) { - VLOG(1) << "GATTS already enabled."; + log::verbose("GATTS already enabled."); } else { memset(p_cb, 0, sizeof(tBTA_GATTS_CB)); @@ -128,7 +132,7 @@ void bta_gatts_enable(tBTA_GATTS_CB* p_cb) { gatt_load_bonded(); if (!GATTS_NVRegister(&bta_gatts_nv_cback)) { - LOG(ERROR) << "BTA GATTS NV register failed."; + log::error("BTA GATTS NV register failed."); } } } @@ -153,7 +157,7 @@ void bta_gatts_api_disable(tBTA_GATTS_CB* p_cb) { } memset(p_cb, 0, sizeof(tBTA_GATTS_CB)); } else { - LOG(ERROR) << "GATTS not enabled"; + log::error("GATTS not enabled"); } } @@ -178,7 +182,7 @@ void bta_gatts_register(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i++) { if (p_cb->rcb[i].in_use) { if (p_cb->rcb[i].app_uuid == p_msg->api_reg.app_uuid) { - LOG(ERROR) << "application already registered."; + log::error("application already registered."); status = GATT_DUP_REG; break; } @@ -196,7 +200,7 @@ void bta_gatts_register(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF; cb_data.reg_oper.uuid = p_msg->api_reg.app_uuid; if (first_unuse != 0xff) { - LOG(INFO) << "register application first_unuse rcb_idx=" << +first_unuse; + log::info("register application first_unuse rcb_idx={}", first_unuse); p_cb->rcb[first_unuse].in_use = true; p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback; @@ -237,8 +241,8 @@ void bta_gatts_start_if(UNUSED_ATTR tBTA_GATTS_CB* p_cb, if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if)) { GATT_StartIf(p_msg->int_start_if.server_if); } else { - LOG(ERROR) << "Unable to start app.: Unknown interface=" - << +p_msg->int_start_if.server_if; + log::error("Unable to start app.: Unknown interface={}", + p_msg->int_start_if.server_if); } } /******************************************************************************* @@ -278,7 +282,7 @@ void bta_gatts_deregister(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { if (p_cback) { (*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data); } else { - LOG(ERROR) << "application not registered."; + log::error("application not registered."); } } @@ -328,7 +332,7 @@ void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB* p_srvc_cb, cb_data.srvc_oper.server_if = p_rcb->gatt_if; cb_data.srvc_oper.service_id = p_srvc_cb->service_id; cb_data.srvc_oper.status = GATT_SUCCESS; - LOG(ERROR) << __func__ << " service_id=" << +p_srvc_cb->service_id; + log::error("service_id={}", p_srvc_cb->service_id); if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data); } @@ -346,7 +350,7 @@ void bta_gatts_send_rsp(UNUSED_ATTR tBTA_GATTS_CB* p_cb, if (GATTS_SendRsp(p_msg->api_rsp.hdr.layer_specific, p_msg->api_rsp.trans_id, p_msg->api_rsp.status, (tGATTS_RSP*)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) { - LOG(ERROR) << "Sending response failed"; + log::error("Sending response failed"); } } /******************************************************************************* @@ -391,9 +395,8 @@ void bta_gatts_indicate_handle(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda); } } else { - LOG(ERROR) << "Unknown connection_id=" - << loghex(p_msg->api_indicate.hdr.layer_specific) - << " fail sending notification"; + log::error("Unknown connection_id={} fail sending notification", + loghex(p_msg->api_indicate.hdr.layer_specific)); } if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) && @@ -404,8 +407,8 @@ void bta_gatts_indicate_handle(tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { (*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data); } } else { - LOG(ERROR) << "Not an registered servce attribute ID: " - << loghex(p_msg->api_indicate.attr_id); + log::error("Not an registered servce attribute ID: {}", + loghex(p_msg->api_indicate.attr_id)); } } @@ -437,7 +440,7 @@ void bta_gatts_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { } } } else { - LOG(ERROR) << "Inavlid server_if=" << p_msg->api_open.server_if; + log::error("Inavlid server_if={}", p_msg->api_open.server_if); } if (p_rcb && p_rcb->p_cback) { @@ -464,12 +467,12 @@ void bta_gatts_cancel_open(UNUSED_ATTR tBTA_GATTS_CB* p_cb, if (p_rcb != NULL) { if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, p_msg->api_cancel_open.is_direct)) { - LOG(ERROR) << __func__ << ": failed for open request"; + log::error("failed for open request"); } else { status = GATT_SUCCESS; } } else { - LOG(ERROR) << "Inavlid server_if=" << +p_msg->api_cancel_open.server_if; + log::error("Inavlid server_if={}", p_msg->api_cancel_open.server_if); } if (p_rcb && p_rcb->p_cback) { @@ -496,11 +499,11 @@ void bta_gatts_close(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport)) { - LOG_DEBUG("Disconnecting gatt_if=%d, remote_bda=%s, transport=%d", +gatt_if, - remote_bda.ToString().c_str(), transport); + log::debug("Disconnecting gatt_if={}, remote_bda={}, transport={}", gatt_if, + remote_bda.ToString(), transport); status = GATT_Disconnect(p_msg->hdr.layer_specific); if (status != GATT_SUCCESS) { - LOG_ERROR("fail conn_id=%d", +p_msg->hdr.layer_specific); + log::error("fail conn_id={}", p_msg->hdr.layer_specific); status = GATT_ERROR; } @@ -516,7 +519,7 @@ void bta_gatts_close(UNUSED_ATTR tBTA_GATTS_CB* p_cb, tBTA_GATTS_DATA* p_msg) { (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, &bta_gatts); } } else { - LOG(ERROR) << "Unknown connection_id=" << loghex(p_msg->hdr.layer_specific); + log::error("Unknown connection_id={}", loghex(p_msg->hdr.layer_specific)); } } @@ -543,8 +546,8 @@ static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id, &transport)) { p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if); - VLOG(1) << __func__ << ": conn_id=" << loghex(conn_id) - << ", trans_id=" << +trans_id << ", req_type=" << +req_type; + log::verbose("conn_id={}, trans_id={}, req_type={}", loghex(conn_id), + trans_id, req_type); if (p_rcb && p_rcb->p_cback) { /* if over BR_EDR, inform PM for mode change */ @@ -559,11 +562,10 @@ static void bta_gatts_send_request_cback(uint16_t conn_id, uint32_t trans_id, (*p_rcb->p_cback)(req_type, &cb_data); } else { - LOG(ERROR) << "connection request on gatt_if=" << +gatt_if - << " is not interested"; + log::error("connection request on gatt_if={} is not interested", gatt_if); } } else { - LOG(ERROR) << "request received on unknown conn_id=" << loghex(conn_id); + log::error("request received on unknown conn_id={}", loghex(conn_id)); } } @@ -584,8 +586,9 @@ static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bdaddr, uint8_t evt = connected ? BTA_GATTS_CONNECT_EVT : BTA_GATTS_DISCONNECT_EVT; tBTA_GATTS_RCB* p_reg; - VLOG(1) << __func__ << " bda=" << bdaddr << " gatt_if= " << gatt_if - << ", conn_id=" << loghex(conn_id) << " connected=" << connected; + log::verbose("bda={} gatt_if= {}, conn_id={} connected={}", + ADDRESS_TO_LOGGABLE_STR(bdaddr), gatt_if, loghex(conn_id), + connected); if (connected) btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_OK); @@ -609,7 +612,7 @@ static void bta_gatts_conn_cback(tGATT_IF gatt_if, const RawAddress& bdaddr, cb_data.conn.remote_bda = bdaddr; (*p_reg->p_cback)(evt, &cb_data); } else { - LOG(ERROR) << __func__ << " server_if=" << +gatt_if << " not found"; + log::error("server_if={} not found", gatt_if); } } @@ -618,7 +621,7 @@ static void bta_gatts_phy_update_cback(tGATT_IF gatt_if, uint16_t conn_id, tGATT_STATUS status) { tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); if (!p_reg || !p_reg->p_cback) { - LOG(ERROR) << __func__ << ": server_if=" << +gatt_if << " not found"; + log::error("server_if={} not found", gatt_if); return; } @@ -636,7 +639,7 @@ static void bta_gatts_conn_update_cback(tGATT_IF gatt_if, uint16_t conn_id, uint16_t timeout, tGATT_STATUS status) { tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); if (!p_reg || !p_reg->p_cback) { - LOG(ERROR) << __func__ << ": server_if=" << +gatt_if << " not found"; + log::error("server_if={} not found", gatt_if); return; } @@ -656,7 +659,7 @@ static void bta_gatts_subrate_chg_cback(tGATT_IF gatt_if, uint16_t conn_id, uint16_t timeout, tGATT_STATUS status) { tBTA_GATTS_RCB* p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if); if (!p_reg || !p_reg->p_cback) { - LOG(ERROR) << __func__ << ": server_if=" << +gatt_if << " not found"; + log::error("server_if={} not found", gatt_if); return; } diff --git a/system/bta/gatt/bta_gatts_api.cc b/system/bta/gatt/bta_gatts_api.cc index 19bc234abc559d780436e1dc3f9c30372c05496c..0362f0d991449bc0172ac6f3712be09c4e1c6634 100644 --- a/system/bta/gatt/bta_gatts_api.cc +++ b/system/bta/gatt/bta_gatts_api.cc @@ -25,13 +25,14 @@ #include #include #include +#include #include #include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/gatt/bta_gatts_int.h" +#include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" #include "stack/include/main_thread.h" @@ -39,6 +40,8 @@ #include "types/bt_transport.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants ****************************************************************************/ @@ -59,7 +62,7 @@ static const tBTA_SYS_REG bta_gatts_reg = {bta_gatts_hdl_event, ******************************************************************************/ void BTA_GATTS_Disable(void) { if (!bta_sys_is_register(BTA_ID_GATTS)) { - LOG(WARNING) << "GATTS Module not enabled/already disabled"; + log::warn("GATTS Module not enabled/already disabled"); return; } @@ -126,7 +129,7 @@ void bta_gatts_add_service_impl(tGATT_IF server_if, uint8_t rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(&bta_gatts_cb, server_if); - LOG(INFO) << __func__ << ": rcb_idx=" << +rcb_idx; + log::info("rcb_idx={}", rcb_idx); if (rcb_idx == BTA_GATTS_INVALID_APP) { cb.Run(GATT_ERROR, server_if, std::move(service)); @@ -143,7 +146,7 @@ void bta_gatts_add_service_impl(tGATT_IF server_if, GATTS_AddService(server_if, service.data(), service.size()); if (status != GATT_SERVICE_STARTED) { memset(&bta_gatts_cb.srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB)); - LOG(ERROR) << __func__ << ": service creation failed."; + log::error("service creation failed."); cb.Run(GATT_ERROR, server_if, std::move(service)); return; } @@ -244,7 +247,7 @@ void BTA_GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_id, bool need_confirm) { if (value.size() > sizeof(tBTA_GATTS_API_INDICATION::value)) { - LOG(ERROR) << __func__ << "data to indicate is too long"; + log::error("data to indicate is too long"); return; } @@ -376,7 +379,7 @@ void BTA_GATTS_Close(uint16_t conn_id) { } void BTA_GATTS_InitBonded(void) { - LOG(INFO) << __func__; + log::info(""); BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID)); p_buf->event = BTA_GATTS_API_INIT_BONDED_EVT; diff --git a/system/bta/gatt/bta_gatts_main.cc b/system/bta/gatt/bta_gatts_main.cc index 459961cb331d50b2f63cc021e0ad3117be5e6f1a..49eb718402feb3313bcb39c8ca3ecb05f29e720a 100644 --- a/system/bta/gatt/bta_gatts_main.cc +++ b/system/bta/gatt/bta_gatts_main.cc @@ -22,11 +22,14 @@ * ******************************************************************************/ -#include "bt_target.h" // Must be first to define build configuration +#include +#include + #include "bta/gatt/bta_gatts_int.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" -#include +using namespace bluetooth; /* GATTS control block */ tBTA_GATTS_CB bta_gatts_cb; @@ -88,7 +91,7 @@ bool bta_gatts_hdl_event(const BT_HDR_RIGID* p_msg) { if (p_srvc_cb != NULL) bta_gatts_delete_service(p_srvc_cb, (tBTA_GATTS_DATA*)p_msg); else - LOG(ERROR) << __func__ << ": can't delete service - no srvc_cb found"; + log::error("can't delete service - no srvc_cb found"); break; } @@ -100,7 +103,7 @@ bool bta_gatts_hdl_event(const BT_HDR_RIGID* p_msg) { if (p_srvc_cb != NULL) bta_gatts_stop_service(p_srvc_cb, (tBTA_GATTS_DATA*)p_msg); else - LOG(ERROR) << __func__ << ": can't stop service - no srvc_cb found"; + log::error("can't stop service - no srvc_cb found"); break; } diff --git a/system/bta/gatt/bta_gatts_queue.cc b/system/bta/gatt/bta_gatts_queue.cc index 33317c697fadab48ed983baffd188bee1d3acfb3..525e7eb14d706a5f1747d172ed00fe37c1cbca2f 100644 --- a/system/bta/gatt/bta_gatts_queue.cc +++ b/system/bta/gatt/bta_gatts_queue.cc @@ -16,15 +16,18 @@ #define LOG_TAG "gatt" +#include + #include #include #include #include "bta_gatt_server_queue.h" -#include "osi/include/log.h" +#include "os/log.h" using gatts_operation = BtaGattServerQueue::gatts_operation; using bluetooth::Uuid; +using namespace bluetooth; constexpr uint8_t GATT_NOTIFY = 1; @@ -38,10 +41,10 @@ void BtaGattServerQueue::mark_as_not_executing(uint16_t conn_id) { } void BtaGattServerQueue::gatts_execute_next_op(uint16_t conn_id) { - LOG_VERBOSE("%s: conn_id=0x%x", __func__, conn_id); + log::verbose("conn_id=0x{:x}", conn_id); if (gatts_op_queue.empty()) { - LOG_VERBOSE("%s: op queue is empty", __func__); + log::verbose("op queue is empty"); return; } @@ -49,10 +52,10 @@ void BtaGattServerQueue::gatts_execute_next_op(uint16_t conn_id) { if (ptr != congestion_queue.end()) { bool is_congested = ptr->second; - LOG_VERBOSE("%s: congestion queue exist, conn_id: %d, is_congested: %d", - __func__, conn_id, is_congested); + log::verbose("congestion queue exist, conn_id: {}, is_congested: {}", + conn_id, is_congested); if (is_congested) { - LOG_VERBOSE("%s: lower layer is congested", __func__); + log::verbose("lower layer is congested"); return; } } @@ -60,22 +63,22 @@ void BtaGattServerQueue::gatts_execute_next_op(uint16_t conn_id) { auto map_ptr = gatts_op_queue.find(conn_id); if (map_ptr == gatts_op_queue.end()) { - LOG_VERBOSE("%s: Queue is null", __func__); + log::verbose("Queue is null"); return; } if (map_ptr->second.empty()) { - LOG_VERBOSE("%s: queue is empty for conn_id: %d", __func__, conn_id); + log::verbose("queue is empty for conn_id: {}", conn_id); return; } if (gatts_op_queue_executing.count(conn_id)) { - LOG_VERBOSE("%s: can't enqueue next op, already executing", __func__); + log::verbose("can't enqueue next op, already executing"); return; } gatts_operation op = map_ptr->second.front(); - LOG_VERBOSE("%s: op.type=%d, attr_id=%d", __func__, op.type, op.attr_id); + log::verbose("op.type={}, attr_id={}", op.type, op.attr_id); if (op.type == GATT_NOTIFY) { BTA_GATTS_HandleValueIndication(conn_id, op.attr_id, op.value, @@ -85,7 +88,7 @@ void BtaGattServerQueue::gatts_execute_next_op(uint16_t conn_id) { } void BtaGattServerQueue::Clean(uint16_t conn_id) { - LOG_VERBOSE("%s: conn_id=0x%x", __func__, conn_id); + log::verbose("conn_id=0x{:x}", conn_id); gatts_op_queue.erase(conn_id); gatts_op_queue_executing.erase(conn_id); @@ -105,8 +108,7 @@ void BtaGattServerQueue::SendNotification(uint16_t conn_id, uint16_t handle, void BtaGattServerQueue::NotificationCallback(uint16_t conn_id) { auto map_ptr = gatts_op_queue.find(conn_id); if (map_ptr == gatts_op_queue.end() || map_ptr->second.empty()) { - LOG_VERBOSE("%s: no more operations queued for conn_id %d", __func__, - conn_id); + log::verbose("no more operations queued for conn_id {}", conn_id); return; } @@ -117,7 +119,7 @@ void BtaGattServerQueue::NotificationCallback(uint16_t conn_id) { } void BtaGattServerQueue::CongestionCallback(uint16_t conn_id, bool congested) { - LOG_VERBOSE("%s: conn_id: %d, congested: %d", __func__, conn_id, congested); + log::verbose("conn_id: {}, congested: {}", conn_id, congested); congestion_queue[conn_id] = congested; if (!congested) { diff --git a/system/bta/gatt/bta_gatts_utils.cc b/system/bta/gatt/bta_gatts_utils.cc index 966dd232fcc6efbc052ce48643041af8b2bd77e7..2f996470c478cf3e0bf25e4ae3c3f59ca962b3ab 100644 --- a/system/bta/gatt/bta_gatts_utils.cc +++ b/system/bta/gatt/bta_gatts_utils.cc @@ -22,13 +22,15 @@ * ******************************************************************************/ -#include +#include +#include -#include "bt_target.h" // Must be first to define build configuration +#include #include "bta/gatt/bta_gatts_int.h" +#include "internal_include/bt_target.h" -#include +using namespace bluetooth; /******************************************************************************* * @@ -104,10 +106,10 @@ uint8_t bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB* p_cb, tBTA_GATTS_SRVC_CB* bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB* p_cb, uint16_t service_id) { uint8_t i; - VLOG(1) << __func__ << ": service_id=" << +service_id; + log::verbose("service_id={}", service_id); for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i++) { if (p_cb->srvc_cb[i].in_use && p_cb->srvc_cb[i].service_id == service_id) { - VLOG(1) << __func__ << ": found service cb index=" << +i; + log::verbose("found service cb index={}", i); return &p_cb->srvc_cb[i]; } } diff --git a/system/bta/gatt/database.cc b/system/bta/gatt/database.cc index c5bef7632479ebe48cd14540f66ba0e89576cf0f..b1596b9cbd8ed1b397daad84312fc1b724b3cc65 100644 --- a/system/bta/gatt/database.cc +++ b/system/bta/gatt/database.cc @@ -19,6 +19,7 @@ #include "database.h" #include +#include #include #include @@ -31,6 +32,7 @@ #include "types/bluetooth/uuid.h" using bluetooth::Uuid; +using namespace bluetooth; namespace gatt { @@ -169,8 +171,8 @@ Database Database::Deserialize(const std::vector& nv_attr, if (current_service_it == result.services.end() || !HandleInRange(*current_service_it, attr.handle)) { - LOG(ERROR) << "Can't find service for attribute with handle: " - << loghex(attr.handle); + log::error("Can't find service for attribute with handle: {}", + loghex(attr.handle)); *success = false; return result; } @@ -179,7 +181,7 @@ Database Database::Deserialize(const std::vector& nv_attr, Service* included_service = FindService(result.services, attr.value.included_service.handle); if (!included_service) { - LOG(ERROR) << __func__ << ": Non-existing included service!"; + log::error("Non-existing included service!"); *success = false; return result; } diff --git a/system/bta/gatt/database_builder.cc b/system/bta/gatt/database_builder.cc index 27c919136ac20d2212039eecde294c75d2764ee7..34e63056179f653b5484eae21c7b988ddf33dfc6 100644 --- a/system/bta/gatt/database_builder.cc +++ b/system/bta/gatt/database_builder.cc @@ -16,6 +16,11 @@ * ******************************************************************************/ +#include "bta/gatt/database_builder.h" + +#include +#include + #include #include #include @@ -23,16 +28,14 @@ #include #include -#include "bt_target.h" // Must be first to define build configuration - #include "bta/gatt/database.h" -#include "bta/gatt/database_builder.h" +#include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "stack/include/gattdefs.h" #include "types/bluetooth/uuid.h" -#include - using bluetooth::Uuid; +using namespace bluetooth; namespace gatt { @@ -72,7 +75,7 @@ void DatabaseBuilder::AddIncludedService(uint16_t handle, const Uuid& uuid, uint16_t end_handle) { Service* service = FindService(database.services, handle); if (!service) { - LOG(ERROR) << "Illegal action to add to non-existing service!"; + log::error("Illegal action to add to non-existing service!"); return; } @@ -94,14 +97,15 @@ void DatabaseBuilder::AddCharacteristic(uint16_t handle, uint16_t value_handle, const Uuid& uuid, uint8_t properties) { Service* service = FindService(database.services, handle); if (!service) { - LOG(ERROR) << "Illegal action to add to non-existing service!"; + log::error("Illegal action to add to non-existing service!"); return; } if (service->end_handle < value_handle) - LOG(WARNING) << "Remote device violates spec: value_handle=" - << loghex(value_handle) << " is after service end_handle=" - << loghex(service->end_handle); + log::warn( + "Remote device violates spec: value_handle={} is after service " + "end_handle={}", + loghex(value_handle), loghex(service->end_handle)); service->characteristics.emplace_back(Characteristic{ .declaration_handle = handle, @@ -115,13 +119,12 @@ void DatabaseBuilder::AddCharacteristic(uint16_t handle, uint16_t value_handle, void DatabaseBuilder::AddDescriptor(uint16_t handle, const Uuid& uuid) { Service* service = FindService(database.services, handle); if (!service) { - LOG(ERROR) << "Illegal action to add to non-existing service!"; + log::error("Illegal action to add to non-existing service!"); return; } if (service->characteristics.empty()) { - LOG(ERROR) << __func__ - << ": Illegal action to add to non-existing characteristic!"; + log::error("Illegal action to add to non-existing characteristic!"); return; } @@ -216,7 +219,7 @@ Descriptor* FindDescriptorByHandle(std::list& services, bool DatabaseBuilder::SetValueOfDescriptors( const std::vector& values) { if (values.size() > descriptor_handles_to_read.size()) { - LOG(ERROR) << "values.size() <= descriptors.size() expected"; + log::error("values.size() <= descriptors.size() expected"); descriptor_handles_to_read.clear(); return false; } @@ -225,7 +228,7 @@ bool DatabaseBuilder::SetValueOfDescriptors( Descriptor* d = FindDescriptorByHandle(database.services, descriptor_handles_to_read[i]); if (!d) { - LOG(ERROR) << __func__ << "non-existing descriptor!"; + log::error("non-existing descriptor!"); descriptor_handles_to_read.clear(); return false; } diff --git a/system/bta/gatt/database_builder.h b/system/bta/gatt/database_builder.h index 0c8830eb53e6bc0d069e3e0eccc44400ace91375..5149fa0e68e5ac3e84ccf39019940f662fc61c2f 100644 --- a/system/bta/gatt/database_builder.h +++ b/system/bta/gatt/database_builder.h @@ -20,6 +20,7 @@ #include #include +#include #include "bta/gatt/database.h" #include "types/bluetooth/uuid.h" diff --git a/system/bta/groups/groups.cc b/system/bta/groups/groups.cc index f8337c4cb8b5c33792864c949449e7bbfa42da24..a2644998a0408623e209c8ac2c9ce1ef06c376c4 100644 --- a/system/bta/groups/groups.cc +++ b/system/bta/groups/groups.cc @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -24,7 +25,8 @@ #include #include "bta_groups.h" -#include "btif_profile_storage.h" +#include "btif/include/btif_profile_storage.h" +#include "os/logging/log_adapter.h" #include "stack/include/bt_types.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -119,8 +121,8 @@ class DeviceGroupsImpl : public DeviceGroups { LOG_ASSERT(group); if (group->Contains(addr)) { - LOG(ERROR) << __func__ << " device " << ADDRESS_TO_LOGGABLE_STR(addr) - << " already in the group: " << group_id; + log::error("device {} already in the group: {}", + ADDRESS_TO_LOGGABLE_STR(addr), group_id); return group->GetGroupId(); } @@ -216,7 +218,7 @@ class DeviceGroupsImpl : public DeviceGroups { if (in.size() < GROUP_STORAGE_HEADER_SZ + (num_groups * GROUP_STORAGE_ENTRY_SZ)) { - LOG(ERROR) << "Invalid persistent storage data"; + log::error("Invalid persistent storage data"); return; } @@ -287,13 +289,13 @@ class DeviceGroupsImpl : public DeviceGroups { auto group = find_device_group(group_id); if (group) { if (group->GetUuid() != uuid) { - LOG(ERROR) << __func__ << " group " << group_id - << " exists but for different uuid: " << group->GetUuid() - << ", user request uuid: " << uuid; + log::error( + "group {} exists but for different uuid: {}, user request uuid: {}", + group_id, group->GetUuid(), uuid); return nullptr; } - LOG(INFO) << __func__ << " group already exists: " << group_id; + log::info("group already exists: {}", group_id); return group; } @@ -316,7 +318,7 @@ class DeviceGroupsImpl : public DeviceGroups { } if (group_id < 0) { - LOG(ERROR) << __func__ << " too many groups"; + log::error("too many groups"); return nullptr; } @@ -343,7 +345,7 @@ void DeviceGroups::Initialize(DeviceGroupsCallbacks* callbacks) { void DeviceGroups::AddFromStorage(const RawAddress& addr, const std::vector& in) { if (!instance) { - LOG(ERROR) << __func__ << ": Not initialized yet"; + log::error("Not initialized yet"); return; } @@ -353,7 +355,7 @@ void DeviceGroups::AddFromStorage(const RawAddress& addr, bool DeviceGroups::GetForStorage(const RawAddress& addr, std::vector& out) { if (!instance) { - LOG(ERROR) << __func__ << ": Not initialized yet"; + log::error("Not initialized yet"); return false; } diff --git a/system/bta/has/has_client.cc b/system/bta/has/has_client.cc index 71beba452f709f36edc86efd0c618eaa5e3042a3..10c2c4b071a6b3fafa4f7c9464317fc895db4fc6 100644 --- a/system/bta/has/has_client.cc +++ b/system/bta/has/has_client.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,8 @@ #include "gap_api.h" #include "gatt_api.h" #include "has_types.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/properties.h" #include "stack/include/bt_types.h" @@ -66,6 +69,7 @@ using le_audio::has::kUuidHearingAidFeatures; using le_audio::has::kUuidHearingAidPresetControlPoint; using le_audio::has::PresetCtpChangeId; using le_audio::has::PresetCtpOpcode; +using namespace bluetooth; void btif_storage_add_leaudio_has_device(const RawAddress& address, std::vector presets_bin, @@ -131,8 +135,9 @@ class HasClientImpl : public HasClient { base::Bind( [](base::Closure initCb, uint8_t client_id, uint8_t status) { if (status != GATT_SUCCESS) { - LOG(ERROR) << "Can't start Hearing Aid Service client " - "profile - no gatt clients left!"; + log::error( + "Can't start Hearing Aid Service client profile - no gatt " + "clients left!"); return; } instance->gatt_if_ = client_id; @@ -157,8 +162,7 @@ class HasClientImpl : public HasClient { } if (addresses.empty()) { - LOG(WARNING) << __func__ << ": " << ADDRESS_TO_LOGGABLE_STR(address) - << " is not part of any set"; + log::warn("{} is not part of any set", ADDRESS_TO_LOGGABLE_STR(address)); addresses = {address}; } @@ -209,8 +213,7 @@ class HasClientImpl : public HasClient { } if (addresses.empty()) { - LOG(WARNING) << __func__ << ": " << ADDRESS_TO_LOGGABLE_STR(address) - << " is not part of any set"; + log::warn("{} is not part of any set", ADDRESS_TO_LOGGABLE_STR(address)); addresses = {address}; } @@ -218,8 +221,8 @@ class HasClientImpl : public HasClient { auto device = std::find_if(devices_.begin(), devices_.end(), HasDevice::MatchAddress(addr)); if (device == devices_.end()) { - LOG(WARNING) << "Device not connected to profile" - << ADDRESS_TO_LOGGABLE_STR(addr); + log::warn("Device not connected to profile{}", + ADDRESS_TO_LOGGABLE_STR(addr)); return; } @@ -256,14 +259,14 @@ class HasClientImpl : public HasClient { }); if (journal_entry == device.has_journal_.end()) { - LOG(WARNING) << "Journaling error or journal length limit was set to " - "low. Unable to log the operation outcome."; + log::warn( + "Journaling error or journal length limit was set to low. Unable to " + "log the operation outcome."); return; } if (journal_entry == device.has_journal_.end()) { - LOG(ERROR) << __func__ - << " Unable to find operation context in the journal!"; + log::error("Unable to find operation context in the journal!"); return; } @@ -292,7 +295,7 @@ class HasClientImpl : public HasClient { auto device = GetDevice(conn_id); if (!device) { - LOG(WARNING) << "Device not connected to profile, conn_id=" << +conn_id; + log::warn("Device not connected to profile, conn_id={}", conn_id); return; } @@ -309,7 +312,7 @@ class HasClientImpl : public HasClient { /* Error handling */ if (!op_opt.has_value()) { - LOG(ERROR) << __func__ << " Unknown operation error"; + log::error("Unknown operation error"); return; } auto op = op_opt.value(); @@ -317,8 +320,8 @@ class HasClientImpl : public HasClient { GattStatus2SvcErrorCode(status)); if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } } @@ -327,7 +330,7 @@ class HasClientImpl : public HasClient { void* user_data) { auto device = GetDevice(conn_id); if (!device) { - LOG(WARNING) << "Device not connected to profile, conn_id=" << +conn_id; + log::warn("Device not connected to profile, conn_id={}", conn_id); return; } @@ -345,15 +348,15 @@ class HasClientImpl : public HasClient { /* Error handling */ if (!op_opt.has_value()) { - LOG(ERROR) << __func__ << " Unknown operation error"; + log::error("Unknown operation error"); return; } auto op = op_opt.value(); callbacks_->OnSetPresetNameError(device->addr, op.index, GattStatus2SvcErrorCode(status)); if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } } @@ -362,7 +365,7 @@ class HasClientImpl : public HasClient { void* user_data) { auto device = GetDevice(conn_id); if (!device) { - LOG(WARNING) << "Device not connected to profile, conn_id=" << +conn_id; + log::warn("Device not connected to profile, conn_id={}", conn_id); return; } @@ -377,7 +380,7 @@ class HasClientImpl : public HasClient { /* Error handling */ if (!op_opt.has_value()) { - LOG(ERROR) << __func__ << " Unknown operation error"; + log::error("Unknown operation error"); return; } auto op = op_opt.value(); @@ -385,12 +388,12 @@ class HasClientImpl : public HasClient { GattStatus2SvcErrorCode(status)); if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Devices %s: Control point not usable. Disconnecting!", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::error("Devices {}: Control point not usable. Disconnecting!", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); BTA_GATTC_Close(device->conn_id); } } @@ -401,7 +404,7 @@ class HasClientImpl : public HasClient { auto device = GetDevice(conn_id); if (!device) { - LOG(WARNING) << "Device not connected to profile, conn_id=" << +conn_id; + log::warn("Device not connected to profile, conn_id={}", conn_id); return; } @@ -419,7 +422,7 @@ class HasClientImpl : public HasClient { /* Error handling */ if (!op_opt.has_value()) { - LOG(ERROR) << __func__ << " Unknown operation error"; + log::error("Unknown operation error"); return; } @@ -434,12 +437,12 @@ class HasClientImpl : public HasClient { } if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Devices %s: Control point not usable. Disconnecting!", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::error("Devices {}: Control point not usable. Disconnecting!", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); BTA_GATTC_Close(device->conn_id); } } @@ -448,8 +451,7 @@ class HasClientImpl : public HasClient { DLOG(INFO) << __func__ << " Operation: " << operation; if (std::holds_alternative(operation.addr_or_group)) { - LOG(ERROR) << __func__ - << " Read all presets on the entire group not supported."; + log::error("Read all presets on the entire group not supported."); callbacks_->OnPresetInfoError(operation.addr_or_group, operation.index, ErrorCode::OPERATION_NOT_POSSIBLE); return; @@ -459,8 +461,9 @@ class HasClientImpl : public HasClient { devices_.begin(), devices_.end(), HasDevice::MatchAddress(std::get(operation.addr_or_group))); if (device == devices_.end()) { - LOG(WARNING) << __func__ << " Device not connected to profile addr: " - << ADDRESS_TO_LOGGABLE_STR(std::get(operation.addr_or_group)); + log::warn("Device not connected to profile addr: {}", + ADDRESS_TO_LOGGABLE_STR( + std::get(operation.addr_or_group))); callbacks_->OnPresetInfoError(device->addr, operation.index, ErrorCode::OPERATION_NOT_POSSIBLE); return; @@ -616,7 +619,7 @@ class HasClientImpl : public HasClient { } void CpPresetIndexOperation(HasCtpOp operation) { - LOG(INFO) << __func__ << " Operation: " << operation; + log::info("Operation: {}", operation); auto status = CpPresetOperationCaller( operation, [](HasDevice& device, HasCtpOp operation) -> ErrorCode { @@ -768,8 +771,7 @@ class HasClientImpl : public HasClient { if (device != devices_.end()) { status = CpWritePresetNameOperationWriteReq(*device, operation); if (status != ErrorCode::NO_ERROR) { - LOG(ERROR) << __func__ - << " Control point write error: " << (int)status; + log::error("Control point write error: {}", (int)status); break; } } @@ -849,8 +851,8 @@ class HasClientImpl : public HasClient { auto device = std::find_if(devices_.begin(), devices_.end(), HasDevice::MatchAddress(address)); if (device == devices_.end()) { - LOG(WARNING) << "Device not connected to profile" - << ADDRESS_TO_LOGGABLE_STR(address); + log::warn("Device not connected to profile{}", + ADDRESS_TO_LOGGABLE_STR(address)); return; } @@ -864,8 +866,8 @@ class HasClientImpl : public HasClient { true)) { auto* preset = device->GetPreset(preset_index); if (preset == nullptr) { - LOG(ERROR) << __func__ << "Invalid preset request" - << ADDRESS_TO_LOGGABLE_STR(address); + log::error("Invalid preset request{}", + ADDRESS_TO_LOGGABLE_STR(address)); callbacks_->OnPresetInfoError(address, preset_index, ErrorCode::INVALID_PRESET_INDEX); return; @@ -923,8 +925,9 @@ class HasClientImpl : public HasClient { } void OnGroupOpCoordinatorTimeout(void* p) { - LOG(ERROR) << __func__ << ": Coordinated operation timeout: " - << " not all the devices notified their state change on time."; + log::error( + "Coordinated operation timeout: not all the devices notified their " + "state change on time."); /* Clear pending group operations */ pending_group_operation_timeouts_.clear(); @@ -934,13 +937,13 @@ class HasClientImpl : public HasClient { private: void WriteAllNeededCcc(const HasDevice& device) { if (device.conn_id == GATT_INVALID_CONN_ID) { - LOG_ERROR("Device %s is not connected", - ADDRESS_TO_LOGGABLE_CSTR(device.addr)); + log::error("Device {} is not connected", + ADDRESS_TO_LOGGABLE_CSTR(device.addr)); return; } /* Write CCC values even remote should have it */ - LOG_INFO("Subscribing for notification/indications"); + log::info("Subscribing for notification/indications"); if (device.SupportsFeaturesNotification()) { SubscribeForNotifications(device.conn_id, device.addr, device.features_handle, @@ -1017,14 +1020,14 @@ class HasClientImpl : public HasClient { auto device = GetDevice(conn_id); if (!device) { - LOG(ERROR) << __func__ << ": unknown conn_id=" << loghex(conn_id); + log::error("unknown conn_id={}", loghex(conn_id)); BtaGattQueue::Clean(conn_id); return; } if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); return; } @@ -1041,9 +1044,8 @@ class HasClientImpl : public HasClient { (handle == device->cp_ccc_handle)) { /* Both of these CCC are mandatory */ if (enabling_ntf && (status != GATT_SUCCESS)) { - LOG(ERROR) << __func__ - << ": Failed to register for notifications on handle=" - << loghex(handle); + log::error("Failed to register for notifications on handle={}", + loghex(handle)); BTA_GATTC_Close(conn_id); return; } @@ -1054,7 +1056,7 @@ class HasClientImpl : public HasClient { const uint8_t* value) { auto device = GetDevice(conn_id); if (!device) { - LOG(WARNING) << "Skipping unknown device, conn_id=" << loghex(conn_id); + log::warn("Skipping unknown device, conn_id={}", loghex(conn_id)); return; } @@ -1094,25 +1096,25 @@ class HasClientImpl : public HasClient { auto device = GetDevice(conn_id_device_variant); if (!device) { - LOG(ERROR) << __func__ << ": Unknown device!"; + log::error("Unknown device!"); return; } if (status != GATT_SUCCESS) { if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Could not read characteristic at handle=0x%04x", handle); + log::error("Could not read characteristic at handle=0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); } return; } if (len != 1) { - LOG(ERROR) << "Invalid features value length=" << +len - << " at handle=" << loghex(handle); + log::error("Invalid features value length={} at handle={}", len, + loghex(handle)); BTA_GATTC_Close(device->conn_id); return; } @@ -1437,7 +1439,7 @@ class HasClientImpl : public HasClient { OnHasPresetDeleted(device); break; default: - LOG(ERROR) << __func__ << " Invalid notification: " << ntf; + log::error("Invalid notification: {}", ntf); break; } @@ -1445,7 +1447,7 @@ class HasClientImpl : public HasClient { OnHasPresetReadResponseNotification(device); } else { - LOG(ERROR) << __func__ << " Unsupported preset notification: " << ntf; + log::error("Unsupported preset notification: {}", ntf); } } } @@ -1454,8 +1456,7 @@ class HasClientImpl : public HasClient { const uint8_t* value) { auto ntf_opt = HasCtpNtf::FromCharacteristicValue(len, value); if (!ntf_opt.has_value()) { - LOG(ERROR) << __func__ - << " Unhandled notification for device: " << *device; + log::error("Unhandled notification for device: {}", *device); BTA_GATTC_Close(device->conn_id); return; } @@ -1475,24 +1476,24 @@ class HasClientImpl : public HasClient { auto device = GetDevice(conn_id_device_variant); if (!device) { - LOG(ERROR) << "Skipping unknown device!"; + log::error("Skipping unknown device!"); return; } if (status != GATT_SUCCESS) { if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Could not read characteristic at handle=0x%04x", handle); + log::error("Could not read characteristic at handle=0x{:04x}", handle); BTA_GATTC_Close(device->conn_id); } } if (len != 1) { - LOG(ERROR) << "Invalid preset value length=" << +len - << " at handle=" << loghex(handle); + log::error("Invalid preset value length={} at handle={}", len, + loghex(handle)); BTA_GATTC_Close(device->conn_id); return; } @@ -1580,7 +1581,7 @@ class HasClientImpl : public HasClient { /* Cleans up after the device disconnection */ void DoDisconnectCleanUp(HasDevice& device, bool invalidate_gatt_service = true) { - LOG_DEBUG(": device=%s", ADDRESS_TO_LOGGABLE_CSTR(device.addr)); + log::debug(": device={}", ADDRESS_TO_LOGGABLE_CSTR(device.addr)); DeregisterNotifications(device); @@ -1616,8 +1617,7 @@ class HasClientImpl : public HasClient { uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle); if (ccc_handle == GAP_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": no HAS Active Preset CCC descriptor found!"; + log::error("no HAS Active Preset CCC descriptor found!"); return false; } device->active_preset_ccc_handle = ccc_handle; @@ -1628,8 +1628,7 @@ class HasClientImpl : public HasClient { uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle); if (ccc_handle == GAP_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": no HAS Control Point CCC descriptor found!"; + log::error("no HAS Control Point CCC descriptor found!"); return false; } uint8_t ccc_val = 0; @@ -1640,8 +1639,8 @@ class HasClientImpl : public HasClient { ccc_val |= GATT_CHAR_CLIENT_CONFIG_INDICTION; if (ccc_val == 0) { - LOG_ERROR("Invalid properties for the control point 0x%02x", - charac.properties); + log::error("Invalid properties for the control point 0x{:02x}", + charac.properties); return false; } @@ -1674,7 +1673,7 @@ class HasClientImpl : public HasClient { *device)) return false; - VLOG(1) << "Loading HAS service details from storage."; + log::verbose("Loading HAS service details from storage."); device->currently_active_preset = active_preset; @@ -1695,7 +1694,7 @@ class HasClientImpl : public HasClient { if (device->conn_id == GATT_INVALID_CONN_ID) return true; /* Be mistrustful here: write CCC values even remote should have it */ - LOG_INFO("Subscribing for notification/indications"); + log::info("Subscribing for notification/indications"); WriteAllNeededCcc(*device); return true; @@ -1706,7 +1705,7 @@ class HasClientImpl : public HasClient { // Validate service structure if (device->features_handle == GAP_INVALID_HANDLE) { /* Missing key characteristic */ - LOG(ERROR) << __func__ << ": Service has broken structure"; + log::error("Service has broken structure"); return false; } @@ -1735,8 +1734,7 @@ class HasClientImpl : public HasClient { device->features_handle, device->features_ccc_handle); } else { - LOG(WARNING) << __func__ - << ": server does not support features notification"; + log::warn("server does not support features notification"); } /* If Presets are supported we should read them all and subscribe for the @@ -1768,9 +1766,9 @@ class HasClientImpl : public HasClient { }, nullptr); } else { - LOG(WARNING) << __func__ - << ": server can only report HAS features, other " - "functionality is disabled"; + log::warn( + "server can only report HAS features, other functionality is " + "disabled"); } return true; @@ -1834,14 +1832,14 @@ class HasClientImpl : public HasClient { } void OnGattConnected(const tBTA_GATTC_OPEN& evt) { - LOG_INFO("%s, conn_id=0x%04x, transport=%s, status=%s(0x%02x)", - ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda), evt.conn_id, - bt_transport_text(evt.transport).c_str(), - gatt_status_text(evt.status).c_str(), evt.status); + log::info("{}, conn_id=0x{:04x}, transport={}, status={}(0x{:02x})", + ADDRESS_TO_LOGGABLE_CSTR(evt.remote_bda), evt.conn_id, + bt_transport_text(evt.transport), gatt_status_text(evt.status), + evt.status); if (evt.transport != BT_TRANSPORT_LE) { - LOG_WARN("Only LE connection is allowed (transport %s)", - bt_transport_text(evt.transport).c_str()); + log::warn("Only LE connection is allowed (transport {})", + bt_transport_text(evt.transport)); BTA_GATTC_Close(evt.conn_id); return; } @@ -1849,8 +1847,8 @@ class HasClientImpl : public HasClient { auto device = std::find_if(devices_.begin(), devices_.end(), HasDevice::MatchAddress(evt.remote_bda)); if (device == devices_.end()) { - LOG(WARNING) << "Skipping unknown device, address=" - << ADDRESS_TO_LOGGABLE_STR(evt.remote_bda); + log::warn("Skipping unknown device, address={}", + ADDRESS_TO_LOGGABLE_STR(evt.remote_bda)); BTA_GATTC_Close(evt.conn_id); return; } @@ -1861,7 +1859,7 @@ class HasClientImpl : public HasClient { return; } - LOG(WARNING) << "Failed to connect to server device"; + log::warn("Failed to connect to server device"); devices_.erase(device); callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, evt.remote_bda); @@ -1887,12 +1885,12 @@ class HasClientImpl : public HasClient { int result = BTM_SetEncryption(device->addr, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT); - LOG_INFO("Encryption required for %s. Request result: 0x%02x", - ADDRESS_TO_LOGGABLE_CSTR(device->addr), result); + log::info("Encryption required for {}. Request result: 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(device->addr), result); if (result == BTM_ERR_KEY_MISSING) { - LOG_ERROR("Link key unknown for %s, disconnect profile", - ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::error("Link key unknown for {}, disconnect profile", + ADDRESS_TO_LOGGABLE_CSTR(device->addr)); BTA_GATTC_Close(device->conn_id); } } @@ -1901,8 +1899,8 @@ class HasClientImpl : public HasClient { auto device = std::find_if(devices_.begin(), devices_.end(), HasDevice::MatchAddress(evt.remote_bda)); if (device == devices_.end()) { - LOG(WARNING) << "Skipping unknown device disconnect, conn_id=" - << loghex(evt.conn_id); + log::warn("Skipping unknown device disconnect, conn_id={}", + loghex(evt.conn_id)); return; } DLOG(INFO) << __func__ << ": device=" @@ -1927,8 +1925,7 @@ class HasClientImpl : public HasClient { void OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL& evt) { auto device = GetDevice(evt.conn_id); if (!device) { - LOG(WARNING) << "Skipping unknown device, conn_id=" - << loghex(evt.conn_id); + log::warn("Skipping unknown device, conn_id={}", loghex(evt.conn_id)); return; } @@ -1936,7 +1933,7 @@ class HasClientImpl : public HasClient { /* verify link is encrypted */ if (!BTM_IsEncrypted(device->addr, BT_TRANSPORT_LE)) { - LOG_WARN("Device not yet bonded - waiting for encryption"); + log::warn("Device not yet bonded - waiting for encryption"); return; } @@ -1945,7 +1942,7 @@ class HasClientImpl : public HasClient { */ if (!device->isGattServiceValid()) { if (evt.status != GATT_SUCCESS) { - LOG(ERROR) << __func__ << ": Service discovery failed"; + log::error("Service discovery failed"); BTA_GATTC_Close(device->conn_id); return; } @@ -1959,14 +1956,14 @@ class HasClientImpl : public HasClient { return svc.uuid == kUuidHearingAccessService; }); if (service == all_services->end()) { - LOG(ERROR) << "No service found"; + log::error("No service found"); BTA_GATTC_Close(device->conn_id); return; } /* Call the service specific verifier callback */ if (!instance->OnHasServiceFound(*service, &(*device))) { - LOG(ERROR) << "Not a valid service!"; + log::error("Not a valid service!"); BTA_GATTC_Close(device->conn_id); return; } @@ -1976,8 +1973,8 @@ class HasClientImpl : public HasClient { void OnGattNotification(const tBTA_GATTC_NOTIFY& evt) { /* Reject invalid lengths */ if (evt.len > GATT_MAX_ATTR_LEN) { - LOG(ERROR) << __func__ << ": rejected BTA_GATTC_NOTIF_EVT. is_notify = " - << evt.is_notify << ", len=" << static_cast(evt.len); + log::error("rejected BTA_GATTC_NOTIF_EVT. is_notify = {}, len={}", + evt.is_notify, static_cast(evt.len)); } if (!evt.is_notify) BTA_GATTC_SendIndConfirm(evt.conn_id, evt.cid); @@ -1990,14 +1987,13 @@ class HasClientImpl : public HasClient { auto device = std::find_if(devices_.begin(), devices_.end(), HasDevice::MatchAddress(address)); if (device == devices_.end()) { - LOG(WARNING) << "Skipping unknown device" - << ADDRESS_TO_LOGGABLE_STR(address); + log::warn("Skipping unknown device{}", ADDRESS_TO_LOGGABLE_STR(address)); return; } if (!success) { - LOG(ERROR) << "Encryption failed for device " - << ADDRESS_TO_LOGGABLE_STR(address); + log::error("Encryption failed for device {}", + ADDRESS_TO_LOGGABLE_STR(address)); BTA_GATTC_Close(device->conn_id); return; @@ -2013,14 +2009,14 @@ class HasClientImpl : public HasClient { void ClearDeviceInformationAndStartSearch(HasDevice* device) { if (!device) { - LOG_ERROR("Device is null"); + log::error("Device is null"); return; } - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(device->addr)); if (!device->isGattServiceValid()) { - LOG_INFO("Service already invalidated"); + log::info("Service already invalidated"); return; } @@ -2036,10 +2032,11 @@ class HasClientImpl : public HasClient { auto device = std::find_if(devices_.begin(), devices_.end(), HasDevice::MatchAddress(address)); if (device == devices_.end()) { - LOG(WARNING) << "Skipping unknown device" << address; + log::warn("Skipping unknown device: {}", + ADDRESS_TO_LOGGABLE_STR(address)); return; } - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); ClearDeviceInformationAndStartSearch(&(*device)); } @@ -2047,8 +2044,8 @@ class HasClientImpl : public HasClient { auto device = std::find_if(devices_.begin(), devices_.end(), HasDevice::MatchAddress(address)); if (device == devices_.end()) { - LOG(WARNING) << "Skipping unknown device" - << ADDRESS_TO_LOGGABLE_STR(address); + log::warn("Skipping unknown device: {}", + ADDRESS_TO_LOGGABLE_STR(address)); return; } @@ -2064,7 +2061,7 @@ class HasClientImpl : public HasClient { const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(conn_id, char_handle); if (!p_char) { - LOG(WARNING) << __func__ << ": No such characteristic: " << char_handle; + log::warn("No such characteristic: {}", char_handle); return GAP_INVALID_HANDLE; } @@ -2124,7 +2121,7 @@ void HasClient::Initialize(bluetooth::has::HasClientCallbacks* callbacks, base::Closure initCb) { std::scoped_lock lock(instance_mutex); if (instance) { - LOG(ERROR) << "Already initialized!"; + log::error("Already initialized!"); return; } @@ -2144,7 +2141,7 @@ HasClient* HasClient::Get(void) { void HasClient::AddFromStorage(const RawAddress& addr, uint8_t features, uint16_t is_acceptlisted) { if (!instance) { - LOG(ERROR) << "Not initialized yet"; + log::error("Not initialized yet"); } instance->AddFromStorage(addr, features, is_acceptlisted); diff --git a/system/bta/has/has_client_test.cc b/system/bta/has/has_client_test.cc index 74daaf3cba5e9c7600faafaebc7daf51d7e9df7c..02ea49fc8180203085a04e4e05b51ff0e67d7ba3 100644 --- a/system/bta/has/has_client_test.cc +++ b/system/bta/has/has_client_test.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -2945,7 +2946,7 @@ bool SimpleJsonValidator(int fd, int* dumpsys_byte_cnt) { } ss << buf; } - LOG(ERROR) << __func__ << ": " << ss.str(); + log::error("{}", ss.str()); return (left_bracket == right_bracket) && (left_sq_bracket == right_sq_bracket); } @@ -3214,7 +3215,7 @@ TEST_F(HasTypesTest, test_group_op_coordinator_copy) { TEST_F(HasTypesTest, test_group_op_coordinator_completion) { HasCtpGroupOpCoordinator::Initialize([](void*) { /* Do nothing */ - LOG(INFO) << __func__ << " callback call"; + log::info("callback call"); }); ASSERT_EQ(0u, HasCtpGroupOpCoordinator::ref_cnt); auto address1 = GetTestAddress(1); diff --git a/system/bta/has/has_ctp.cc b/system/bta/has/has_ctp.cc index a2beffea84e2292e4df7f1eef6aebba42d1b37dd..325141d9b57743dd889e6dc1569301eb1fee068f 100644 --- a/system/bta/has/has_ctp.cc +++ b/system/bta/has/has_ctp.cc @@ -17,17 +17,20 @@ #include "has_ctp.h" +#include + #include "os/log.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + namespace le_audio { namespace has { static bool ParsePresetGenericUpdate(uint16_t& len, const uint8_t* value, HasCtpNtf& ntf) { if (len < sizeof(ntf.prev_index) + HasPreset::kCharValueMinSize) { - LOG(ERROR) << "Invalid preset value length=" << +len - << " for generic update."; + log::error("Invalid preset value length={} for generic update.", len); return false; } @@ -41,8 +44,7 @@ static bool ParsePresetGenericUpdate(uint16_t& len, const uint8_t* value, static bool ParsePresetIndex(uint16_t& len, const uint8_t* value, HasCtpNtf& ntf) { if (len < sizeof(ntf.index)) { - LOG(ERROR) << __func__ << "Invalid preset value length=" << +len - << " for generic update."; + log::error("Invalid preset value length={} for generic update.", len); return false; } @@ -54,7 +56,7 @@ static bool ParsePresetIndex(uint16_t& len, const uint8_t* value, static bool ParsePresetReadResponse(uint16_t& len, const uint8_t* value, HasCtpNtf& ntf) { if (len < sizeof(ntf.is_last) + HasPreset::kCharValueMinSize) { - LOG(ERROR) << "Invalid preset value length=" << +len; + log::error("Invalid preset value length={}", len); return false; } @@ -68,7 +70,7 @@ static bool ParsePresetReadResponse(uint16_t& len, const uint8_t* value, static bool ParsePresetChanged(uint16_t len, const uint8_t* value, HasCtpNtf& ntf) { if (len < sizeof(ntf.is_last) + sizeof(ntf.change_id)) { - LOG(ERROR) << __func__ << "Invalid preset value length=" << +len; + log::error("Invalid preset value length={}", len); return false; } @@ -77,7 +79,7 @@ static bool ParsePresetChanged(uint16_t len, const uint8_t* value, len -= 1; if (change_id > static_cast>( PresetCtpChangeId::CHANGE_ID_MAX_)) { - LOG(ERROR) << __func__ << "Invalid preset chenge_id=" << change_id; + log::error("Invalid preset chenge_id={}", change_id); return false; } ntf.change_id = PresetCtpChangeId(change_id); @@ -103,7 +105,7 @@ static bool ParsePresetChanged(uint16_t len, const uint8_t* value, std::optional HasCtpNtf::FromCharacteristicValue( uint16_t len, const uint8_t* value) { if (len < 3) { - LOG(ERROR) << __func__ << " Invalid Cp notification."; + log::error("Invalid Cp notification."); return std::nullopt; } @@ -115,9 +117,7 @@ std::optional HasCtpNtf::FromCharacteristicValue( PresetCtpOpcode::READ_PRESET_RESPONSE)) && (op != static_cast>( PresetCtpOpcode::PRESET_CHANGED))) { - LOG(ERROR) << __func__ - << ": Received invalid opcode in control point notification: " - << ++op; + log::error("Received invalid opcode in control point notification: {}", op); return std::nullopt; } diff --git a/system/bta/has/has_ctp.h b/system/bta/has/has_ctp.h index ff58748e66b2103bcfec93a2c3aa559c0e0b1ba7..f5a6d68bfd2273766b6ce9aad391277241856856 100644 --- a/system/bta/has/has_ctp.h +++ b/system/bta/has/has_ctp.h @@ -18,9 +18,11 @@ #pragma once #include +#include #include #include +#include #include "hardware/bt_has.h" #include "has_preset.h" @@ -261,3 +263,10 @@ struct HasCtpGroupOpCoordinator { } // namespace has } // namespace le_audio + +namespace fmt { +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +} // namespace fmt diff --git a/system/bta/has/has_preset.cc b/system/bta/has/has_preset.cc index ab8c97b8840f0f5a50cb1f6e33433b1692966828..efe3b97e1cb725d4bbfd14e5c23abc6c548a64fe 100644 --- a/system/bta/has/has_preset.cc +++ b/system/bta/has/has_preset.cc @@ -17,8 +17,12 @@ #include "has_preset.h" +#include + #include "stack/include/bt_types.h" +using namespace bluetooth; + namespace le_audio { namespace has { @@ -26,7 +30,7 @@ std::optional HasPreset::FromCharacteristicValue( uint16_t& len, const uint8_t* value) { if ((len < kCharValueMinSize) || (len > kCharValueMinSize + kPresetNameLengthLimit)) { - LOG(ERROR) << __func__ << " Preset record to long: " << len; + log::error("Preset record to long: {}", len); return std::nullopt; } @@ -53,14 +57,13 @@ void HasPreset::ToCharacteristicValue(std::vector& value) const { uint8_t* HasPreset::Serialize(uint8_t* p_out, size_t buffer_size) const { if (buffer_size < SerializedSize()) { - LOG(ERROR) << "Invalid output buffer size!"; + log::error("Invalid output buffer size!"); return p_out; } uint8_t name_len = name_.length(); if (name_len > kPresetNameLengthLimit) { - LOG(ERROR) << __func__ - << " Invalid preset name length. Cannot be serialized!"; + log::error("Invalid preset name length. Cannot be serialized!"); return p_out; } @@ -79,22 +82,21 @@ const uint8_t* HasPreset::Deserialize(const uint8_t* p_in, size_t len, auto* p_curr = p_in; if (len < nonamed_size) { - LOG(ERROR) << "Invalid buffer size " << +len << ". Cannot deserialize."; + log::error("Invalid buffer size {}. Cannot deserialize.", len); return p_in; } uint8_t serialized_data_len; STREAM_TO_UINT8(serialized_data_len, p_curr); if (serialized_data_len < 2) { - LOG(ERROR) << __func__ << " Invalid data size. Cannot be deserialized!"; + log::error("Invalid data size. Cannot be deserialized!"); return p_in; } auto name_len = serialized_data_len - 2; if ((name_len > kPresetNameLengthLimit) || ((size_t)nonamed_size + name_len > len)) { - LOG(ERROR) << __func__ - << " Invalid preset name length. Cannot be deserialized!"; + log::error("Invalid preset name length. Cannot be deserialized!"); return p_in; } diff --git a/system/bta/has/has_types.h b/system/bta/has/has_types.h index 5b1fe54b920c3e4263d2e6818bd5f8ba75725ecb..f9d9ef71dae369eaa975b80b77c932e3559874df 100644 --- a/system/bta/has/has_types.h +++ b/system/bta/has/has_types.h @@ -17,6 +17,8 @@ #pragma once +#include + #include #include #include @@ -315,7 +317,7 @@ class HasDevice : public GattServiceDevice { auto* const p_end = p_out + buffer_size; for (auto& preset : has_presets) { if (p_out + preset.SerializedSize() >= p_end) { - LOG(ERROR) << "Serialization error."; + bluetooth::log::error("Serialization error."); return false; } p_out = preset.Serialize(p_out, p_end - p_out); @@ -331,7 +333,8 @@ class HasDevice : public GattServiceDevice { HasDevice& device) { HasPreset preset; if (len < 2 + preset.SerializedSize()) { - LOG(ERROR) << "Deserialization error. Invalid input buffer size length."; + bluetooth::log::error( + "Deserialization error. Invalid input buffer size length."); return false; } auto* p_end = p_in + len; @@ -339,7 +342,7 @@ class HasDevice : public GattServiceDevice { uint8_t hdr; STREAM_TO_UINT8(hdr, p_in); if (hdr != kHasDeviceBinaryBlobHdr) { - LOG(ERROR) << __func__ << " Deserialization error. Bad header."; + bluetooth::log::error("Deserialization error. Bad header."); return false; } @@ -350,7 +353,7 @@ class HasDevice : public GattServiceDevice { while (p_in < p_end) { auto* p_new = HasPreset::Deserialize(p_in, p_end - p_in, preset); if (p_new <= p_in) { - LOG(ERROR) << "Deserialization error. Invalid preset found."; + bluetooth::log::error("Deserialization error. Invalid preset found."); device.has_presets.clear(); return false; } @@ -420,3 +423,8 @@ class HasDevice : public GattServiceDevice { } // namespace has } // namespace le_audio + +namespace fmt { +template <> +struct formatter : ostream_formatter {}; +} // namespace fmt diff --git a/system/bta/hd/bta_hd_act.cc b/system/bta/hd/bta_hd_act.cc index 766be520765cc94abd14515de52746264e422eaa..c5ed49e69c9f1688b55735e01f2adce84bb5b172 100644 --- a/system/bta/hd/bta_hd_act.cc +++ b/system/bta/hd/bta_hd_act.cc @@ -29,6 +29,8 @@ #include "internal_include/bt_target.h" #if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE) +#include + #include "bta/hd/bta_hd_int.h" #include "include/hardware/bt_hd.h" #include "main/shim/metrics_api.h" @@ -40,6 +42,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event, uint32_t data, BT_HDR* pdata); @@ -87,7 +90,7 @@ void bta_hd_api_enable(tBTA_HD_DATA* p_data) { tBTA_HD_STATUS status = BTA_HD_ERROR; tHID_STATUS ret; - LOG_VERBOSE("%s", __func__); + log::verbose(""); HID_DevInit(); @@ -100,7 +103,7 @@ void bta_hd_api_enable(tBTA_HD_DATA* p_data) { if (ret == HID_SUCCESS) { status = BTA_HD_OK; } else { - LOG_ERROR("%s: Failed to register HID device (%d)", __func__, ret); + log::error("Failed to register HID device ({})", ret); } /* signal BTA call back event */ @@ -122,7 +125,7 @@ void bta_hd_api_disable(void) { tBTA_HD_STATUS status = BTA_HD_ERROR; tHID_STATUS ret; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* service is not enabled */ if (bta_hd_cb.p_cback == NULL) return; @@ -138,8 +141,7 @@ void bta_hd_api_disable(void) { if (ret == HID_SUCCESS) { status = BTA_HD_OK; } else { - LOG_ERROR("%s: Failed to deregister HID device (%s)", __func__, - hid_status_text(ret).c_str()); + log::error("Failed to deregister HID device ({})", hid_status_text(ret)); } tBTA_HD bta_hd; @@ -163,7 +165,7 @@ void bta_hd_register_act(tBTA_HD_DATA* p_data) { tBTA_HD_REGISTER_APP* p_app_data = (tBTA_HD_REGISTER_APP*)p_data; bool use_report_id = FALSE; - LOG_VERBOSE("%s", __func__); + log::verbose(""); ret.reg_status.in_use = FALSE; @@ -173,7 +175,7 @@ void bta_hd_register_act(tBTA_HD_DATA* p_data) { if (p_app_data->d_len > BTA_HD_APP_DESCRIPTOR_LEN || !check_descriptor(p_app_data->d_data, p_app_data->d_len, &use_report_id)) { - LOG_ERROR("%s: Descriptor is too long or malformed", __func__); + log::error("Descriptor is too long or malformed"); ret.reg_status.status = BTA_HD_ERROR; (*bta_hd_cb.p_cback)(BTA_HD_REGISTER_APP_EVT, &ret); bluetooth::shim::CountCounterMetrics( @@ -229,7 +231,7 @@ void bta_hd_register_act(tBTA_HD_DATA* p_data) { void bta_hd_unregister_act() { tBTA_HD_STATUS status = BTA_HD_OK; - LOG_VERBOSE("%s", __func__); + log::verbose(""); // application is no longer registered so we do not want incoming connections HID_DevSetIncomingPolicy(FALSE); @@ -256,7 +258,7 @@ void bta_hd_unregister_act() { * ******************************************************************************/ void bta_hd_unregister2_act(tBTA_HD_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); // close first bta_hd_close_act(p_data); @@ -283,17 +285,17 @@ void bta_hd_connect_act(tBTA_HD_DATA* p_data) { tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data; tBTA_HD cback_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); ret = HID_DevPlugDevice(p_ctrl->addr); if (ret != HID_SUCCESS) { - LOG_WARN("%s: HID_DevPlugDevice returned %d", __func__, ret); + log::warn("HID_DevPlugDevice returned {}", ret); return; } ret = HID_DevConnect(); if (ret != HID_SUCCESS) { - LOG_WARN("%s: HID_DevConnect returned %d", __func__, ret); + log::warn("HID_DevConnect returned {}", ret); return; } @@ -316,12 +318,12 @@ void bta_hd_disconnect_act() { tHID_STATUS ret; tBTA_HD cback_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); ret = HID_DevDisconnect(); if (ret != HID_SUCCESS) { - LOG_WARN("%s: HID_DevDisconnect returned %d", __func__, ret); + log::warn("HID_DevDisconnect returned {}", ret); return; } @@ -343,7 +345,7 @@ void bta_hd_disconnect_act() { void bta_hd_add_device_act(tBTA_HD_DATA* p_data) { tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); HID_DevPlugDevice(p_ctrl->addr); } @@ -360,7 +362,7 @@ void bta_hd_add_device_act(tBTA_HD_DATA* p_data) { void bta_hd_remove_device_act(tBTA_HD_DATA* p_data) { tBTA_HD_DEVICE_CTRL* p_ctrl = (tBTA_HD_DEVICE_CTRL*)p_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); HID_DevUnplugDevice(p_ctrl->addr); } @@ -379,7 +381,7 @@ void bta_hd_send_report_act(tBTA_HD_DATA* p_data) { uint8_t channel; uint8_t report_id; - LOG_VERBOSE("%s", __func__); + log::verbose(""); channel = p_report->use_intr ? HID_CHANNEL_INTR : HID_CHANNEL_CTRL; report_id = @@ -406,12 +408,12 @@ void bta_hd_report_error_act(tBTA_HD_DATA* p_data) { tBTA_HD_REPORT_ERR* p_report = (tBTA_HD_REPORT_ERR*)p_data; tHID_STATUS ret; - LOG_VERBOSE("%s: error = %d", __func__, p_report->error); + log::verbose("error = {}", p_report->error); ret = HID_DevReportError(p_report->error); if (ret != HID_SUCCESS) { - LOG_WARN("%s: HID_DevReportError returned %d", __func__, ret); + log::warn("HID_DevReportError returned {}", ret); } } @@ -427,14 +429,14 @@ void bta_hd_report_error_act(tBTA_HD_DATA* p_data) { void bta_hd_vc_unplug_act() { tHID_STATUS ret; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_hd_cb.vc_unplug = TRUE; ret = HID_DevVirtualCableUnplug(); if (ret != HID_SUCCESS) { - LOG_WARN("%s: HID_DevVirtualCableUnplug returned %d", __func__, ret); + log::warn("HID_DevVirtualCableUnplug returned {}", ret); } /* trigger PM */ @@ -455,7 +457,7 @@ void bta_hd_open_act(tBTA_HD_DATA* p_data) { tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data; tBTA_HD cback_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); HID_DevPlugDevice(p_cback->addr); bta_sys_conn_open(BTA_ID_HD, 1, p_cback->addr); @@ -480,7 +482,7 @@ void bta_hd_close_act(tBTA_HD_DATA* p_data) { tBTA_HD cback_data; tBTA_HD_EVT cback_event = BTA_HD_CLOSE_EVT; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr); @@ -512,7 +514,7 @@ void bta_hd_intr_data_act(tBTA_HD_DATA* p_data) { uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset; tBTA_HD_INTR_DATA ret; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (bta_hd_cb.use_report_id || bta_hd_cb.boot_mode) { if (len < 1) { @@ -550,7 +552,7 @@ void bta_hd_get_report_act(tBTA_HD_DATA* p_data) { uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset; tBTA_HD_GET_REPORT ret = {0, 0, 0}; - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint16_t remaining_len = p_msg->len; if (remaining_len < 1) { @@ -598,7 +600,7 @@ void bta_hd_set_report_act(tBTA_HD_DATA* p_data) { uint8_t* p_buf = (uint8_t*)(p_msg + 1) + p_msg->offset; tBTA_HD_SET_REPORT ret = {0, 0, 0, NULL}; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (len < 1) { return; @@ -640,7 +642,7 @@ void bta_hd_set_protocol_act(tBTA_HD_DATA* p_data) { tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data; tBTA_HD cback_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_hd_cb.boot_mode = (p_cback->data == HID_PAR_PROTOCOL_BOOT_MODE); cback_data.set_protocol = p_cback->data; @@ -661,7 +663,7 @@ void bta_hd_vc_unplug_done_act(tBTA_HD_DATA* p_data) { tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data; tBTA_HD cback_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_sys_conn_close(BTA_ID_HD, 1, p_cback->addr); @@ -685,7 +687,7 @@ void bta_hd_vc_unplug_done_act(tBTA_HD_DATA* p_data) { void bta_hd_suspend_act(tBTA_HD_DATA* p_data) { tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_sys_idle(BTA_ID_HD, 1, p_cback->addr); } @@ -702,7 +704,7 @@ void bta_hd_suspend_act(tBTA_HD_DATA* p_data) { void bta_hd_exit_suspend_act(tBTA_HD_DATA* p_data) { tBTA_HD_CBACK_DATA* p_cback = (tBTA_HD_CBACK_DATA*)p_data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_sys_busy(BTA_ID_HD, 1, p_cback->addr); bta_sys_idle(BTA_ID_HD, 1, p_cback->addr); @@ -722,7 +724,7 @@ static void bta_hd_cback(const RawAddress& bd_addr, uint8_t event, tBTA_HD_CBACK_DATA* p_buf = NULL; uint16_t sm_event = BTA_HD_INVALID_EVT; - LOG_VERBOSE("%s: event=%d", __func__, event); + log::verbose("event={}", event); switch (event) { case HID_DHOST_EVT_OPEN: diff --git a/system/bta/hd/bta_hd_api.cc b/system/bta/hd/bta_hd_api.cc index b6aa6b9355e32829d40e39941467b074f9b92c0d..f392f6dd6a1a6100d8f4bbb569d0ce845eb4f4b4 100644 --- a/system/bta/hd/bta_hd_api.cc +++ b/system/bta/hd/bta_hd_api.cc @@ -26,16 +26,21 @@ #define LOG_TAG "bluetooth" // BTA_HD_INCLUDED -#include "bt_target.h" // Must be first to define build configuration +#include "internal_include/bt_target.h" #if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE) +#include + #include "bta/hd/bta_hd_int.h" +#include "common/init_flags.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" -#include "osi/include/log.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants ****************************************************************************/ @@ -52,7 +57,7 @@ static const tBTA_SYS_REG bta_hd_reg = {bta_hd_hdl_event, BTA_HdDisable}; * ******************************************************************************/ void BTA_HdEnable(tBTA_HD_CBACK* p_cback) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_sys_register(BTA_ID_HD, &bta_hd_reg); @@ -77,7 +82,7 @@ void BTA_HdEnable(tBTA_HD_CBACK* p_cback) { * ******************************************************************************/ void BTA_HdDisable(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!bluetooth::common::init_flags:: delay_hidh_cleanup_until_hidh_ready_start_is_enabled()) { @@ -101,7 +106,7 @@ void BTA_HdDisable(void) { ******************************************************************************/ void BTA_HdRegisterApp(tBTA_HD_APP_INFO* p_app_info, tBTA_HD_QOS_INFO* p_in_qos, tBTA_HD_QOS_INFO* p_out_qos) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HD_REGISTER_APP* p_buf = (tBTA_HD_REGISTER_APP*)osi_malloc(sizeof(tBTA_HD_REGISTER_APP)); @@ -153,7 +158,7 @@ void BTA_HdRegisterApp(tBTA_HD_APP_INFO* p_app_info, tBTA_HD_QOS_INFO* p_in_qos, * ******************************************************************************/ void BTA_HdUnregisterApp(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID)); p_buf->event = BTA_HD_API_UNREGISTER_APP_EVT; @@ -171,13 +176,13 @@ void BTA_HdUnregisterApp(void) { * ******************************************************************************/ void BTA_HdSendReport(tBTA_HD_REPORT* p_report) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (p_report->len > BTA_HD_REPORT_LEN) { - LOG_WARN( - "%s, report len (%d) > MTU len (%d), can't send report." - " Increase value of HID_DEV_MTU_SIZE to send larger reports", - __func__, p_report->len, BTA_HD_REPORT_LEN); + log::warn( + "report len ({}) > MTU len ({}), can't send report. Increase value of " + "HID_DEV_MTU_SIZE to send larger reports", + p_report->len, BTA_HD_REPORT_LEN); return; } @@ -204,7 +209,7 @@ void BTA_HdSendReport(tBTA_HD_REPORT* p_report) { * ******************************************************************************/ void BTA_HdVirtualCableUnplug(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID)); p_buf->event = BTA_HD_API_VC_UNPLUG_EVT; @@ -223,7 +228,7 @@ void BTA_HdVirtualCableUnplug(void) { * ******************************************************************************/ void BTA_HdConnect(const RawAddress& addr) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HD_DEVICE_CTRL* p_buf = (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL)); @@ -244,7 +249,7 @@ void BTA_HdConnect(const RawAddress& addr) { * ******************************************************************************/ void BTA_HdDisconnect(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); BT_HDR_RIGID* p_buf = (BT_HDR_RIGID*)osi_malloc(sizeof(BT_HDR_RIGID)); p_buf->event = BTA_HD_API_DISCONNECT_EVT; @@ -261,7 +266,7 @@ void BTA_HdDisconnect(void) { * ******************************************************************************/ void BTA_HdAddDevice(const RawAddress& addr) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HD_DEVICE_CTRL* p_buf = (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL)); p_buf->hdr.event = BTA_HD_API_ADD_DEVICE_EVT; @@ -281,7 +286,7 @@ void BTA_HdAddDevice(const RawAddress& addr) { * ******************************************************************************/ void BTA_HdRemoveDevice(const RawAddress& addr) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HD_DEVICE_CTRL* p_buf = (tBTA_HD_DEVICE_CTRL*)osi_malloc(sizeof(tBTA_HD_DEVICE_CTRL)); p_buf->hdr.event = BTA_HD_API_REMOVE_DEVICE_EVT; @@ -301,7 +306,7 @@ void BTA_HdRemoveDevice(const RawAddress& addr) { * ******************************************************************************/ void BTA_HdReportError(uint8_t error) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HD_REPORT_ERR* p_buf = (tBTA_HD_REPORT_ERR*)osi_malloc(sizeof(tBTA_HD_REPORT_ERR)); p_buf->hdr.event = BTA_HD_API_REPORT_ERROR_EVT; diff --git a/system/bta/hd/bta_hd_main.cc b/system/bta/hd/bta_hd_main.cc index 79799ed2c92ba79e39dbf84fce314e16f14b6927..12e17d3018a05368784e6cfa426333fec92138b7 100644 --- a/system/bta/hd/bta_hd_main.cc +++ b/system/bta/hd/bta_hd_main.cc @@ -28,9 +28,13 @@ #include "internal_include/bt_target.h" #if defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE) +#include + #include "bta/hd/bta_hd_int.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + /***************************************************************************** * Constants and types ****************************************************************************/ @@ -177,7 +181,7 @@ static void bta_hd_better_state_machine(uint16_t event, tBTA_HD_DATA* p_data) { * ******************************************************************************/ bool bta_hd_hdl_event(const BT_HDR_RIGID* p_msg) { - LOG_VERBOSE("%s: p_msg->event=%d", __func__, p_msg->event); + log::verbose("p_msg->event={}", p_msg->event); switch (p_msg->event) { case BTA_HD_API_ENABLE_EVT: @@ -186,7 +190,7 @@ bool bta_hd_hdl_event(const BT_HDR_RIGID* p_msg) { case BTA_HD_API_DISABLE_EVT: if (bta_hd_cb.state == BTA_HD_CONN_ST) { - LOG_WARN("%s: host connected, disconnect before disabling", __func__); + log::warn("host connected, disconnect before disabling"); // unregister (and disconnect) bta_hd_cb.disable_w4_close = TRUE; diff --git a/system/bta/hearing_aid/hearing_aid.cc b/system/bta/hearing_aid/hearing_aid.cc index 5530abbabb3f3acd86d9b0002613aded4c8166e1..3b28bdfc57c31d298e18e8129ba120849458bd1f 100644 --- a/system/bta/hearing_aid/hearing_aid.cc +++ b/system/bta/hearing_aid/hearing_aid.cc @@ -25,19 +25,24 @@ #include #include #include // HexEncode +#include #include #include #include #include +#include "audio/asrc/asrc_resampler.h" #include "bta/include/bta_gatt_api.h" #include "bta/include/bta_gatt_queue.h" #include "bta/include/bta_hearing_aid_api.h" #include "btm_iso_api.h" #include "device/include/controller.h" #include "embdrv/g722/g722_enc_dec.h" +#include "hal/link_clocker.h" #include "hardware/bt_gatt_types.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/properties.h" @@ -56,6 +61,7 @@ using base::Closure; using bluetooth::Uuid; using bluetooth::hci::IsoManager; using bluetooth::hearing_aid::ConnectionState; +using namespace bluetooth; // The MIN_CE_LEN parameter for Connection Parameters based on the current // Connection Interval @@ -194,8 +200,8 @@ class HearingDevices { int read_rssi_start_interval_count = 0; for (auto& d : devices) { - LOG_DEBUG("device=%s, read_rssi_count=%d", - ADDRESS_TO_LOGGABLE_CSTR(d.address), d.read_rssi_count); + log::debug("device={}, read_rssi_count={}", + ADDRESS_TO_LOGGABLE_CSTR(d.address), d.read_rssi_count); // Reset the count if (d.read_rssi_count <= 0) { @@ -224,8 +230,8 @@ static void write_rpt_ctl_cfg_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, const uint8_t* value, void* data) { if (status != GATT_SUCCESS) { - LOG_ERROR("handle= %hu, conn_id=%hu, status= %s, length=%u", handle, - conn_id, loghex(static_cast(status)).c_str(), len); + log::error("handle= {}, conn_id={}, status= {}, length={}", handle, conn_id, + loghex(static_cast(status)), len); } } @@ -234,7 +240,7 @@ g722_encode_state_t* encoder_state_right = nullptr; inline void encoder_state_init() { if (encoder_state_left != nullptr) { - LOG_WARN("encoder already initialized"); + log::warn("encoder already initialized"); return; } encoder_state_left = g722_encode_init(nullptr, 64000, G722_PACKED); @@ -271,6 +277,13 @@ class HearingAidImpl : public HearingAid { const int DROP_FREQUENCY_THRESHOLD = bluetooth::common::init_flags::get_asha_packet_drop_frequency_threshold(); + // Resampler context for audio stream. + // Clock recovery uses L2CAP Flow Control Credit Ind acknowledgments + // from either the left or right connection, whichever is first + // connected. + std::shared_ptr asrc_clock_source; + std::unique_ptr asrc; + public: ~HearingAidImpl() override = default; @@ -288,21 +301,21 @@ class HearingAidImpl : public HearingAid { "persist.bluetooth.hearingaid.interval", (int32_t)HA_INTERVAL_20_MS); if ((default_data_interval_ms != HA_INTERVAL_10_MS) && (default_data_interval_ms != HA_INTERVAL_20_MS)) { - LOG_ERROR("invalid interval= %ums. Overwrriting back to default", - default_data_interval_ms); + log::error("invalid interval= {}ms. Overwrriting back to default", + default_data_interval_ms); default_data_interval_ms = HA_INTERVAL_20_MS; } - LOG_DEBUG("default_data_interval_ms=%u", default_data_interval_ms); + log::debug("default_data_interval_ms={}", default_data_interval_ms); overwrite_min_ce_len = (int16_t)osi_property_get_int32(PERSIST_MIN_CE_LEN_NAME.c_str(), -1); if (overwrite_min_ce_len != -1) { - LOG_INFO("Overwrites MIN_CE_LEN=%d", overwrite_min_ce_len); + log::info("Overwrites MIN_CE_LEN={}", overwrite_min_ce_len); } overwrite_max_ce_len = (int16_t)osi_property_get_int32(PERSIST_MAX_CE_LEN_NAME.c_str(), -1); if (overwrite_max_ce_len != -1) { - LOG_INFO("Overwrites MAX_CE_LEN=%d", overwrite_max_ce_len); + log::info("Overwrites MAX_CE_LEN={}", overwrite_max_ce_len); } BTA_GATTC_AppRegister( @@ -310,7 +323,7 @@ class HearingAidImpl : public HearingAid { base::Bind( [](Closure initCb, uint8_t client_id, uint8_t status) { if (status != GATT_SUCCESS) { - LOG_ERROR( + log::error( "Can't start Hearing Aid profile - no gatt clients left!"); return; } @@ -337,8 +350,8 @@ class HearingAidImpl : public HearingAid { } else { is_iso_running = false; } - LOG_INFO("is_iso_running: %d, needs_parameter_update: %d", is_iso_running, - needs_parameter_update); + log::info("is_iso_running: {}, needs_parameter_update: {}", is_iso_running, + needs_parameter_update); if (needs_parameter_update) { for (auto& device : hearingDevices.devices) { if (device.conn_id != 0) { @@ -350,6 +363,51 @@ class HearingAidImpl : public HearingAid { } } + // Reset and configure the ASHA resampling context using the input device + // devices as reference for the BT clock estimation. + void ConfigureAsrc() { + if (!IS_FLAG_ENABLED(asha_asrc)) { + log::info("Asha resampling disabled: feature flag off"); + return; + } + + // Create a new ASRC context if required. + if (asrc == nullptr) { + asrc_clock_source = + std::make_shared(); + asrc = std::make_unique( + asrc_clock_source, /*channels*/ 2, + /*sample_rate*/ codec_in_use == CODEC_G722_24KHZ ? 24000 : 16000, + /*bit_depth*/ 16, + /*interval_us*/ default_data_interval_ms * 1000, + /*num_burst_buffers*/ 0, + /*burst_delay*/ 0); + } + + for (auto& device : hearingDevices.devices) { + if (!device.accepting_audio) { + continue; + } + + uint16_t lcid = GAP_ConnGetL2CAPCid(device.gap_handle); + uint16_t rcid = 0; + L2CA_GetRemoteCid(lcid, &rcid); + + auto conn = btm_acl_for_bda(device.address, BT_TRANSPORT_LE); + log::info("Updating ASRC context for handle=0x{:x}, cid=0x{:x}", + conn->Handle(), rcid); + + asrc_clock_source->Update(device.isLeft(), conn->Handle(), rcid); + } + } + + // Reset the ASHA resampling context. + void ResetAsrc() { + log::info("Resetting the Asha resampling context"); + asrc_clock_source = nullptr; + asrc = nullptr; + } + uint16_t UpdateBleConnParams(const RawAddress& address) { /* List of parameters that depends on the chosen Connection Interval */ uint16_t min_ce_len = MIN_CE_LEN_20MS_CI; @@ -362,7 +420,7 @@ class HearingAidImpl : public HearingAid { connection_interval = CONNECTION_INTERVAL_10MS_PARAM; break; case HA_INTERVAL_20_MS: - LOG_INFO("is_iso_running %d", is_iso_running); + log::info("is_iso_running {}", is_iso_running); // Because when ISO is connected, controller might not be able to // update connection event length successfully. @@ -380,26 +438,25 @@ class HearingAidImpl : public HearingAid { connection_interval = CONNECTION_INTERVAL_20MS_PARAM; break; default: - LOG_ERROR("invalid default_data_interval_ms=%u", - default_data_interval_ms); + log::error("invalid default_data_interval_ms={}", + default_data_interval_ms); min_ce_len = MIN_CE_LEN_10MS_CI; connection_interval = CONNECTION_INTERVAL_10MS_PARAM; } if (overwrite_min_ce_len != -1) { - LOG_WARN("min_ce_len=%u for device %s is overwritten to %d", min_ce_len, - ADDRESS_TO_LOGGABLE_CSTR(address), overwrite_min_ce_len); + log::warn("min_ce_len={} for device {} is overwritten to {}", min_ce_len, + ADDRESS_TO_LOGGABLE_CSTR(address), overwrite_min_ce_len); min_ce_len = overwrite_min_ce_len; } if (overwrite_max_ce_len != -1) { - LOG_WARN("max_ce_len=%u for device %s is overwritten to %d", max_ce_len, - ADDRESS_TO_LOGGABLE_CSTR(address), overwrite_max_ce_len); + log::warn("max_ce_len={} for device {} is overwritten to {}", max_ce_len, + ADDRESS_TO_LOGGABLE_CSTR(address), overwrite_max_ce_len); max_ce_len = overwrite_max_ce_len; } - LOG_INFO( - "L2CA_UpdateBleConnParams for device %s min_ce_len:%u " - "max_ce_len:%u", + log::info( + "L2CA_UpdateBleConnParams for device {} min_ce_len:{} max_ce_len:{}", ADDRESS_TO_LOGGABLE_CSTR(address), min_ce_len, max_ce_len); L2CA_UpdateBleConnParams(address, connection_interval, connection_interval, 0x000A, 0x0064 /*1s*/, min_ce_len, max_ce_len); @@ -412,26 +469,26 @@ class HearingAidImpl : public HearingAid { bool droppable = std::chrono::duration_cast(duration).count() >= DROP_FREQUENCY_THRESHOLD; - LOG_INFO("IsBelowDropFrequency %s", droppable ? "true" : "false"); + log::info("IsBelowDropFrequency {}", droppable ? "true" : "false"); return droppable; } void Connect(const RawAddress& address) { - LOG_DEBUG("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); hearingDevices.Add(HearingDevice(address, true)); BTA_GATTC_Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, false); } void AddToAcceptlist(const RawAddress& address) { - LOG_DEBUG("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); hearingDevices.Add(HearingDevice(address, true)); BTA_GATTC_Open(gatt_if, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false); } void AddFromStorage(const HearingDevice& dev_info, bool is_acceptlisted) { - LOG_DEBUG("%s, hiSyncId=%s, isAcceptlisted=%u", - ADDRESS_TO_LOGGABLE_CSTR(dev_info.address), - loghex(dev_info.hi_sync_id).c_str(), is_acceptlisted); + log::debug("{}, hiSyncId={}, isAcceptlisted={}", + ADDRESS_TO_LOGGABLE_CSTR(dev_info.address), + loghex(dev_info.hi_sync_id), is_acceptlisted); if (is_acceptlisted) { hearingDevices.Add(dev_info); @@ -457,14 +514,14 @@ class HearingAidImpl : public HearingAid { if (!hearingDevice) { /* When Hearing Aid is quickly disabled and enabled in settings, this case * might happen */ - LOG_WARN("Closing connection to non hearing-aid device, address=%s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Closing connection to non hearing-aid device, address={}", + ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_GATTC_Close(conn_id); return; } - LOG_INFO("address=%s, conn_id=%u", ADDRESS_TO_LOGGABLE_CSTR(address), - conn_id); + log::info("address={}, conn_id={}", ADDRESS_TO_LOGGABLE_CSTR(address), + conn_id); if (status != GATT_SUCCESS) { if (!hearingDevice->connecting_actively) { @@ -477,8 +534,8 @@ class HearingAidImpl : public HearingAid { hearingDevice->switch_to_background_connection_after_failure = false; BTA_GATTC_Open(gatt_if, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false); } else { - LOG_INFO("Failed to connect to Hearing Aid device, bda=%s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Failed to connect to Hearing Aid device, bda={}", + ADDRESS_TO_LOGGABLE_CSTR(address)); hearingDevices.Remove(address); callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address); @@ -496,9 +553,9 @@ class HearingAidImpl : public HearingAid { for (auto& device : hearingDevices.devices) { if (device.hi_sync_id == hi_sync_id && device.conn_id == 0 && !device.connecting_actively) { - LOG_INFO( - "Promoting device from the set from background to direct" - "connection, bda=%s", + log::info( + "Promoting device from the set from background to " + "direct connection, bda={}", ADDRESS_TO_LOGGABLE_CSTR(device.address)); device.connecting_actively = true; device.switch_to_background_connection_after_failure = true; @@ -511,8 +568,8 @@ class HearingAidImpl : public HearingAid { hearingDevice->connection_update_status = STARTED; hearingDevice->requested_connection_interval = UpdateBleConnParams(address); - if (controller_get_interface()->supports_ble_2m_phy()) { - LOG_INFO("%s set preferred 2M PHY", ADDRESS_TO_LOGGABLE_CSTR(address)); + if (controller_get_interface()->SupportsBle2mPhy()) { + log::info("{} set preferred 2M PHY", ADDRESS_TO_LOGGABLE_CSTR(address)); BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0); } @@ -547,7 +604,7 @@ class HearingAidImpl : public HearingAid { void OnConnectionUpdateComplete(uint16_t conn_id, tBTA_GATTC* p_data) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device, conn_id=%s", loghex(conn_id).c_str()); + log::debug("Skipping unknown device, conn_id={}", loghex(conn_id)); return; } @@ -560,9 +617,9 @@ class HearingAidImpl : public HearingAid { switch (hearingDevice->connection_update_status) { case COMPLETED: if (!same_conn_interval) { - LOG_WARN( - "Unexpected change. Redo. connection interval=%u, " - "expected=%u, conn_id=%u, connection_update_status=%u", + log::warn( + "Unexpected change. Redo. connection interval={}, " + "expected={}, conn_id={}, connection_update_status={}", p_data->conn_update.interval, hearingDevice->requested_connection_interval, conn_id, hearingDevice->connection_update_status); @@ -572,14 +629,14 @@ class HearingAidImpl : public HearingAid { break; case STARTED: if (same_conn_interval) { - LOG_INFO("Connection update completed. conn_id=%u, device=%s", - conn_id, - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); + log::info("Connection update completed. conn_id={}, device={}", + conn_id, + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); hearingDevice->connection_update_status = COMPLETED; } else { - LOG_WARN( - "Ignored. Different connection interval=%u, expected=%u, " - "conn_id=%u, connection_update_status=%u", + log::warn( + "Ignored. Different connection interval={}, expected={}, " + "conn_id={}, connection_update_status={}", p_data->conn_update.interval, hearingDevice->requested_connection_interval, conn_id, hearingDevice->connection_update_status); @@ -600,15 +657,15 @@ class HearingAidImpl : public HearingAid { send_state_change_to_other_side(hearingDevice, conn_update); send_state_change(hearingDevice, conn_update); } else { - LOG_INFO( - "error status=%s, conn_id=%u,device=%s, " - "connection_update_status=%u", - loghex(static_cast(p_data->conn_update.status)).c_str(), - conn_id, ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), + log::info( + "error status={}, conn_id={},device={}, " + "connection_update_status={}", + loghex(static_cast(p_data->conn_update.status)), conn_id, + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), hearingDevice->connection_update_status); if (hearingDevice->connection_update_status == STARTED) { // Redo this connection interval change. - LOG_ERROR("Redo Connection Interval change"); + log::error("Redo Connection Interval change"); hearingDevice->connection_update_status = AWAITING; } } @@ -636,18 +693,18 @@ class HearingAidImpl : public HearingAid { void OnReadRssiComplete(const RawAddress& address, int8_t rssi_value) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { - LOG_INFO("Skipping unknown device %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } - LOG_DEBUG("device=%s, rss=%d", ADDRESS_TO_LOGGABLE_CSTR(address), - (int)rssi_value); + log::debug("device={}, rssi={}", ADDRESS_TO_LOGGABLE_CSTR(address), + (int)rssi_value); if (hearingDevice->read_rssi_count <= 0) { - LOG_ERROR(" device=%s, invalid read_rssi_count=%d", - ADDRESS_TO_LOGGABLE_CSTR(address), - hearingDevice->read_rssi_count); + log::error("device={}, invalid read_rssi_count={}", + ADDRESS_TO_LOGGABLE_CSTR(address), + hearingDevice->read_rssi_count); return; } @@ -656,8 +713,8 @@ class HearingAidImpl : public HearingAid { if (hearingDevice->read_rssi_count == READ_RSSI_NUM_TRIES) { // Store the timestamp only for the first one after packet flush clock_gettime(CLOCK_REALTIME, &last_log_set.timestamp); - LOG_INFO("store time, device=%s, rssi=%d", - ADDRESS_TO_LOGGABLE_CSTR(address), (int)rssi_value); + log::info("store time, device={}, rssi={}", + ADDRESS_TO_LOGGABLE_CSTR(address), (int)rssi_value); } last_log_set.rssi.emplace_back(rssi_value); @@ -667,13 +724,13 @@ class HearingAidImpl : public HearingAid { void OnEncryptionComplete(const RawAddress& address, bool success) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } if (!success) { - LOG_ERROR("encryption failed"); + log::error("encryption failed"); BTA_GATTC_Close(hearingDevice->conn_id); if (hearingDevice->first_connection) { callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address); @@ -681,7 +738,7 @@ class HearingAidImpl : public HearingAid { return; } - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); if (hearingDevice->audio_control_point_handle && hearingDevice->audio_status_handle && @@ -690,8 +747,8 @@ class HearingAidImpl : public HearingAid { // Use cached data, jump to read PSM ReadPSM(hearingDevice); } else { - LOG_INFO("%s: do BTA_GATTC_ServiceSearchRequest", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}: do BTA_GATTC_ServiceSearchRequest", + ADDRESS_TO_LOGGABLE_CSTR(address)); hearingDevice->first_connection = true; BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID); } @@ -702,41 +759,41 @@ class HearingAidImpl : public HearingAid { tGATT_STATUS status) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device, conn_id=%s", loghex(conn_id).c_str()); + log::debug("Skipping unknown device, conn_id={}", loghex(conn_id)); return; } if (status != GATT_SUCCESS) { - LOG_WARN("%s phy update fail with status: %hu", - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), status); + log::warn("{} phy update fail with status: {}", + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), status); return; } if (tx_phys == PHY_LE_2M && rx_phys == PHY_LE_2M) { - LOG_INFO("%s phy update to 2M successful", - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); + log::info("{} phy update to 2M successful", + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); hearingDevice->phy_update_retry_remain = PHY_UPDATE_RETRY_LIMIT; return; } if (hearingDevice->phy_update_retry_remain > 0) { - LOG_INFO( - "%s phy update successful but not target phy, try again. tx_phys: " - "%u,rx_phys: %u", + log::info( + "{} phy update successful but not target phy, try again. tx_phys: " + "{},rx_phys: {}", ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), tx_phys, rx_phys); BTM_BleSetPhy(hearingDevice->address, PHY_LE_2M, PHY_LE_2M, 0); hearingDevice->phy_update_retry_remain--; } else { - LOG_INFO("no more phy update after %d retry", PHY_UPDATE_RETRY_LIMIT); + log::info("no more phy update after {} retry", PHY_UPDATE_RETRY_LIMIT); } } void OnServiceChangeEvent(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } - LOG_INFO("address=%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("address={}", ADDRESS_TO_LOGGABLE_CSTR(address)); hearingDevice->first_connection = true; hearingDevice->service_changed_rcvd = true; BtaGattQueue::Clean(hearingDevice->conn_id); @@ -749,18 +806,18 @@ class HearingAidImpl : public HearingAid { void OnServiceDiscDoneEvent(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); if (hearingDevice->service_changed_rcvd || !(hearingDevice->audio_control_point_handle && hearingDevice->audio_status_handle && hearingDevice->audio_status_ccc_handle && hearingDevice->volume_handle && hearingDevice->read_psm_handle)) { - LOG_INFO("%s: do BTA_GATTC_ServiceSearchRequest", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}: do BTA_GATTC_ServiceSearchRequest", + ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID); } } @@ -768,7 +825,7 @@ class HearingAidImpl : public HearingAid { void OnServiceSearchComplete(uint16_t conn_id, tGATT_STATUS status) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device, conn_id=%s", loghex(conn_id).c_str()); + log::debug("Skipping unknown device, conn_id={}", loghex(conn_id)); return; } @@ -777,7 +834,7 @@ class HearingAidImpl : public HearingAid { if (status != GATT_SUCCESS) { /* close connection and report service discovery complete with error */ - LOG_ERROR("Service discovery failed"); + log::error("Service discovery failed"); if (hearingDevice->first_connection) { callbacks->OnConnectionState(ConnectionState::DISCONNECTED, hearingDevice->address); @@ -790,19 +847,18 @@ class HearingAidImpl : public HearingAid { const gatt::Service* service = nullptr; for (const gatt::Service& tmp : *services) { if (tmp.uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) { - LOG_INFO("Found UUID_SERVCLASS_GATT_SERVER, handle=%s", - loghex(tmp.handle).c_str()); + log::info("Found UUID_SERVCLASS_GATT_SERVER, handle={}", + loghex(tmp.handle)); const gatt::Service* service_changed_service = &tmp; find_server_changed_ccc_handle(conn_id, service_changed_service); } else if (tmp.uuid == HEARING_AID_UUID) { - LOG_INFO("Found Hearing Aid service, handle=%s", - loghex(tmp.handle).c_str()); + log::info("Found Hearing Aid service, handle={}", loghex(tmp.handle)); service = &tmp; } } if (!service) { - LOG_ERROR("No Hearing Aid service found"); + log::error("No Hearing Aid service found"); callbacks->OnConnectionState(ConnectionState::DISCONNECTED, hearingDevice->address); return; @@ -814,8 +870,8 @@ class HearingAidImpl : public HearingAid { hearingDevice->address, &hearingDevice->capabilities, &hearingDevice->hi_sync_id, &hearingDevice->render_delay, &hearingDevice->preparation_delay, &hearingDevice->codecs)) { - LOG_DEBUG("Reading read only properties %s", - loghex(charac.value_handle).c_str()); + log::debug("Reading read only properties {}", + loghex(charac.value_handle)); BtaGattQueue::ReadCharacteristic( conn_id, charac.value_handle, HearingAidImpl::OnReadOnlyPropertiesReadStatic, nullptr); @@ -829,20 +885,18 @@ class HearingAidImpl : public HearingAid { hearingDevice->audio_status_ccc_handle = find_ccc_handle(conn_id, charac.value_handle); if (!hearingDevice->audio_status_ccc_handle) { - LOG_ERROR("cannot find Audio Status CCC descriptor"); + log::error("cannot find Audio Status CCC descriptor"); continue; } - LOG_INFO("audio_status_handle=%s, ccc=%s", - loghex(charac.value_handle).c_str(), - loghex(hearingDevice->audio_status_ccc_handle).c_str()); + log::info("audio_status_handle={}, ccc={}", loghex(charac.value_handle), + loghex(hearingDevice->audio_status_ccc_handle)); } else if (charac.uuid == VOLUME_UUID) { hearingDevice->volume_handle = charac.value_handle; } else if (charac.uuid == LE_PSM_UUID) { hearingDevice->read_psm_handle = charac.value_handle; } else { - LOG_WARN("Unknown characteristic found:%s", - charac.uuid.ToString().c_str()); + log::warn("Unknown characteristic found:{}", charac.uuid.ToString()); } } @@ -855,9 +909,9 @@ class HearingAidImpl : public HearingAid { void ReadPSM(HearingDevice* hearingDevice) { if (hearingDevice->read_psm_handle) { - LOG_INFO("Reading PSM %s, device=%s", - loghex(hearingDevice->read_psm_handle).c_str(), - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); + log::info("Reading PSM {}, device={}", + loghex(hearingDevice->read_psm_handle), + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); BtaGattQueue::ReadCharacteristic( hearingDevice->conn_id, hearingDevice->read_psm_handle, HearingAidImpl::OnPsmReadStatic, nullptr); @@ -868,29 +922,28 @@ class HearingAidImpl : public HearingAid { uint8_t* value) { HearingDevice* device = hearingDevices.FindByConnId(conn_id); if (!device) { - LOG_INFO("Skipping unknown device, conn_id=%s", loghex(conn_id).c_str()); + log::info("Skipping unknown device, conn_id={}", loghex(conn_id)); return; } if (device->audio_status_handle != handle) { - LOG_INFO("Mismatched handle, %s!=%s", - loghex(device->audio_status_handle).c_str(), - loghex(handle).c_str()); + log::info("Mismatched handle, {}!={}", + loghex(device->audio_status_handle), loghex(handle)); return; } if (len < 1) { - LOG_ERROR("Data Length too small, len=%u, expecting at least 1", len); + log::error("Data Length too small, len={}, expecting at least 1", len); return; } if (value[0] != 0) { - LOG_INFO("Invalid returned status. data=%s", loghex(value[0]).c_str()); + log::info("Invalid returned status. data={}", loghex(value[0])); return; } - LOG_INFO("audio status success notification. command_acked=%u", - device->command_acked); + log::info("audio status success notification. command_acked={}", + device->command_acked); device->command_acked = true; } @@ -899,11 +952,11 @@ class HearingAidImpl : public HearingAid { void* data) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_DEBUG("unknown conn_id=%s", loghex(conn_id).c_str()); + log::debug("unknown conn_id={}", loghex(conn_id)); return; } - LOG_DEBUG("%s", base::HexEncode(value, len).c_str()); + log::debug("{}", base::HexEncode(value, len)); uint8_t* p = value; @@ -911,13 +964,13 @@ class HearingAidImpl : public HearingAid { STREAM_TO_UINT8(version, p); if (version != 0x01) { - LOG_WARN("Unknown version: %s", loghex(version).c_str()); + log::warn("Unknown version: {}", loghex(version)); return; } // version 0x01 of read only properties: if (len < 17) { - LOG_WARN("Read only properties too short: %s", loghex(len).c_str()); + log::warn("Read only properties too short: {}", loghex(len)); return; } uint8_t capabilities; @@ -926,35 +979,35 @@ class HearingAidImpl : public HearingAid { bool side = capabilities & CAPABILITY_SIDE; bool standalone = capabilities & CAPABILITY_BINAURAL; bool csis_capable = capabilities & CAPABILITY_CSIS; - LOG_DEBUG("capabilities: %s, %s, CSIS %s", (side ? "right" : "left"), - (standalone ? "binaural" : "monaural"), - (csis_capable ? "capable" : "not capable")); + log::debug("capabilities: {}, {}, CSIS {}", (side ? "right" : "left"), + (standalone ? "binaural" : "monaural"), + (csis_capable ? "capable" : "not capable")); if (capabilities & CAPABILITY_RESERVED) { - LOG_WARN("reserved capabilities are set"); + log::warn("reserved capabilities are set"); } STREAM_TO_UINT64(hearingDevice->hi_sync_id, p); - LOG_DEBUG("hiSyncId: %s", loghex(hearingDevice->hi_sync_id).c_str()); + log::debug("hiSyncId: {}", loghex(hearingDevice->hi_sync_id)); uint8_t feature_map; STREAM_TO_UINT8(feature_map, p); STREAM_TO_UINT16(hearingDevice->render_delay, p); - LOG_DEBUG("render delay: %s", loghex(hearingDevice->render_delay).c_str()); + log::debug("render delay: {}", loghex(hearingDevice->render_delay)); STREAM_TO_UINT16(hearingDevice->preparation_delay, p); - LOG_DEBUG("preparation delay: %s", - loghex(hearingDevice->preparation_delay).c_str()); + log::debug("preparation delay: {}", + loghex(hearingDevice->preparation_delay)); uint16_t codecs; STREAM_TO_UINT16(codecs, p); hearingDevice->codecs = codecs; - LOG_DEBUG("supported codecs: %s", loghex(codecs).c_str()); - if (codecs & (1 << CODEC_G722_16KHZ)) LOG_INFO("%s\tG722@16kHz", __func__); - if (codecs & (1 << CODEC_G722_24KHZ)) LOG_INFO("%s\tG722@24kHz", __func__); + log::debug("supported codecs: {}", loghex(codecs)); + if (codecs & (1 << CODEC_G722_16KHZ)) log::info("\tG722@16kHz"); + if (codecs & (1 << CODEC_G722_24KHZ)) log::info("\tG722@24kHz"); if (!(codecs & (1 << CODEC_G722_16KHZ))) { - LOG_WARN("Mandatory codec, G722@16kHz not supported"); + log::warn("Mandatory codec, G722@16kHz not supported"); } } @@ -993,7 +1046,7 @@ class HearingAidImpl : public HearingAid { } if ((codecs & (1 << CODEC_G722_24KHZ)) && - controller_get_interface()->supports_ble_2m_phy() && + controller_get_interface()->SupportsBle2mPhy() && default_data_interval_ms == HA_INTERVAL_10_MS) { codec_in_use = CODEC_G722_24KHZ; } else if (codecs & (1 << CODEC_G722_16KHZ)) { @@ -1003,31 +1056,30 @@ class HearingAidImpl : public HearingAid { void OnAudioStatus(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value, void* data) { - LOG_INFO("%s", base::HexEncode(value, len).c_str()); + log::info("{}", base::HexEncode(value, len)); } void OnPsmRead(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value, void* data) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown read event, conn_id=%s", - loghex(conn_id).c_str()); + log::debug("Skipping unknown read event, conn_id={}", loghex(conn_id)); return; } if (status != GATT_SUCCESS) { - LOG_ERROR("Error reading PSM for device %s", - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); + log::error("Error reading PSM for device {}", + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); return; } if (len > 2) { - LOG_ERROR("Bad PSM Lengh"); + log::error("Bad PSM Lengh"); return; } uint16_t psm = *((uint16_t*)value); - LOG_DEBUG("read psm:%s", loghex(psm).c_str()); + log::debug("read psm:{}", loghex(psm)); if (hearingDevice->gap_handle == GAP_INVALID_HANDLE && BTM_IsEncrypted(hearingDevice->address, BT_TRANSPORT_LE)) { @@ -1048,12 +1100,12 @@ class HearingAidImpl : public HearingAid { &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */, HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE); if (gap_handle == GAP_INVALID_HANDLE) { - LOG_ERROR("UNABLE TO GET gap_handle"); + log::error("UNABLE TO GET gap_handle"); return; } hearingDevice->gap_handle = gap_handle; - LOG_INFO("Successfully sent GAP connect request"); + log::info("Successfully sent GAP connect request"); } static void OnReadOnlyPropertiesReadStatic(uint16_t conn_id, @@ -1082,8 +1134,8 @@ class HearingAidImpl : public HearingAid { void OnDeviceReady(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { - LOG_INFO("Device not connected to profile %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Device not connected to profile {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } @@ -1093,17 +1145,17 @@ class HearingAidImpl : public HearingAid { hearingDevice->first_connection = false; } - LOG_INFO("audio_status_handle=%s, audio_status_ccc_handle=%s", - loghex(hearingDevice->audio_status_handle).c_str(), - loghex(hearingDevice->audio_status_ccc_handle).c_str()); + log::info("audio_status_handle={}, audio_status_ccc_handle={}", + loghex(hearingDevice->audio_status_handle), + loghex(hearingDevice->audio_status_ccc_handle)); /* Register and enable the Audio Status Notification */ tGATT_STATUS register_status; register_status = BTA_GATTC_RegisterForNotifications( gatt_if, address, hearingDevice->audio_status_handle); if (register_status != GATT_SUCCESS) { - LOG_ERROR("BTA_GATTC_RegisterForNotifications failed, status=%s", - loghex(static_cast(register_status)).c_str()); + log::error("BTA_GATTC_RegisterForNotifications failed, status={}", + loghex(static_cast(register_status))); return; } std::vector value(2); @@ -1126,10 +1178,10 @@ class HearingAidImpl : public HearingAid { hearingDevice->connecting_actively = false; hearingDevice->accepting_audio = true; - LOG_INFO("address=%s, hi_sync_id=%s, codec_in_use=%s, audio_running=%i", - ADDRESS_TO_LOGGABLE_CSTR(address), - loghex(hearingDevice->hi_sync_id).c_str(), - loghex(codec_in_use).c_str(), audio_running); + log::info("address={}, hi_sync_id={}, codec_in_use={}, audio_running={}", + ADDRESS_TO_LOGGABLE_CSTR(address), + loghex(hearingDevice->hi_sync_id), loghex(codec_in_use), + audio_running); StartSendingAudio(*hearingDevice); @@ -1139,7 +1191,7 @@ class HearingAidImpl : public HearingAid { } void StartSendingAudio(const HearingDevice& hearingDevice) { - LOG_DEBUG("device=%s", ADDRESS_TO_LOGGABLE_CSTR(hearingDevice.address)); + log::debug("device={}", ADDRESS_TO_LOGGABLE_CSTR(hearingDevice.address)); if (encoder_state_left == nullptr) { encoder_state_init(); @@ -1169,10 +1221,14 @@ class HearingAidImpl : public HearingAid { CHECK(stop_audio_ticks) << "stop_audio_ticks is empty"; if (!audio_running) { - LOG_WARN("Unexpected audio suspend"); + log::warn("Unexpected audio suspend"); } else { - LOG_INFO("audio_running=%i", audio_running); + log::info("audio_running={}", audio_running); } + + // Close the ASRC context. + ResetAsrc(); + audio_running = false; stop_audio_ticks(); @@ -1181,11 +1237,11 @@ class HearingAidImpl : public HearingAid { if (!device.accepting_audio) continue; if (!device.playback_started) { - LOG_WARN("Playback not started, skip send Stop cmd, device=%s", - ADDRESS_TO_LOGGABLE_CSTR(device.address)); + log::warn("Playback not started, skip send Stop cmd, device={}", + ADDRESS_TO_LOGGABLE_CSTR(device.address)); } else { - LOG_INFO("send Stop cmd, device=%s", - ADDRESS_TO_LOGGABLE_CSTR(device.address)); + log::info("send Stop cmd, device={}", + ADDRESS_TO_LOGGABLE_CSTR(device.address)); device.playback_started = false; device.command_acked = false; BtaGattQueue::WriteCharacteristic(device.conn_id, @@ -1199,9 +1255,9 @@ class HearingAidImpl : public HearingAid { CHECK(start_audio_ticks) << "start_audio_ticks is empty"; if (audio_running) { - LOG_ERROR("Unexpected Audio Resume"); + log::error("Unexpected Audio Resume"); } else { - LOG_INFO("audio_running=%i", audio_running); + log::info("audio_running={}", audio_running); } for (auto& device : hearingDevices.devices) { @@ -1211,10 +1267,13 @@ class HearingAidImpl : public HearingAid { } if (!audio_running) { - LOG_INFO("No device (0/%d) ready to start", GetDeviceCount()); + log::info("No device (0/{}) ready to start", GetDeviceCount()); return; } + // Open the ASRC context. + ConfigureAsrc(); + // TODO: shall we also reset the encoder ? encoder_state_release(); encoder_state_init(); @@ -1239,8 +1298,8 @@ class HearingAidImpl : public HearingAid { } void SendEnableServiceChangedInd(HearingDevice* device) { - LOG_DEBUG("Enable service changed ind.%s", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::debug("Enable service changed ind.{}", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); std::vector value(2); uint8_t* ptr = value.data(); UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION); @@ -1256,11 +1315,11 @@ class HearingAidImpl : public HearingAid { if (!audio_running) { if (!device->playback_started) { - LOG_INFO("Skip Send Start since audio is not running, device=%s", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); - } else { - LOG_ERROR("Audio not running but Playback has started, device=%s", + log::info("Skip Send Start since audio is not running, device={}", ADDRESS_TO_LOGGABLE_CSTR(device->address)); + } else { + log::error("Audio not running but Playback has started, device={}", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); } return; } @@ -1268,16 +1327,15 @@ class HearingAidImpl : public HearingAid { if (current_volume == VOLUME_UNKNOWN) start[3] = (uint8_t)VOLUME_MIN; if (device->playback_started) { - LOG_ERROR("Playback already started, skip send Start cmd, device=%s", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::error("Playback already started, skip send Start cmd, device={}", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); } else { start[4] = GetOtherSideStreamStatus(device); - LOG_INFO( - "send Start cmd, volume=%s, audio type=%s, device=%s, other side " - "streaming=%s", - loghex(start[3]).c_str(), loghex(start[2]).c_str(), - ADDRESS_TO_LOGGABLE_CSTR(device->address), - loghex(start[4]).c_str()); + log::info( + "send Start cmd, volume={}, audio type={}, device={}, other side " + "streaming={}", + loghex(start[3]), loghex(start[2]), + ADDRESS_TO_LOGGABLE_CSTR(device->address), loghex(start[4])); device->command_acked = false; BtaGattQueue::WriteCharacteristic( device->conn_id, device->audio_control_point_handle, start, @@ -1290,12 +1348,12 @@ class HearingAidImpl : public HearingAid { uint16_t len, const uint8_t* value, void* data) { if (status != GATT_SUCCESS) { - LOG_ERROR("handle=%u, conn_id=%u, status=%s", handle, conn_id, - loghex(static_cast(status)).c_str()); + log::error("handle={}, conn_id={}, status={}", handle, conn_id, + loghex(static_cast(status))); return; } if (!instance) { - LOG_ERROR("instance is null"); + log::error("instance is null"); return; } instance->StartAudioCtrlCallback(conn_id); @@ -1304,10 +1362,10 @@ class HearingAidImpl : public HearingAid { void StartAudioCtrlCallback(uint16_t conn_id) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_ERROR("Skipping unknown device, conn_id=%s", loghex(conn_id).c_str()); + log::error("Skipping unknown device, conn_id={}", loghex(conn_id)); return; } - LOG_INFO("device: %s", ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); + log::info("device: {}", ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); hearingDevice->playback_started = true; } @@ -1322,7 +1380,7 @@ class HearingAidImpl : public HearingAid { bool NeedToDropPacket(HearingDevice* target_side, HearingDevice* other_side) { // Just drop packet if the other side does not exist. if (!other_side) { - LOG_DEBUG("other side not connected to profile"); + log::debug("other side not connected to profile"); return true; } @@ -1331,14 +1389,14 @@ class HearingAidImpl : public HearingAid { uint16_t target_current_credit = L2CA_GetPeerLECocCredit( target_side->address, GAP_ConnGetL2CAPCid(target_side->gap_handle)); if (target_current_credit == L2CAP_LE_CREDIT_MAX) { - LOG_ERROR("Get target side credit value fail."); + log::error("Get target side credit value fail."); return true; } uint16_t other_current_credit = L2CA_GetPeerLECocCredit( other_side->address, GAP_ConnGetL2CAPCid(other_side->gap_handle)); if (other_current_credit == L2CAP_LE_CREDIT_MAX) { - LOG_ERROR("Get other side credit value fail."); + log::error("Get other side credit value fail."); return true; } @@ -1347,14 +1405,24 @@ class HearingAidImpl : public HearingAid { } else { diff_credit = other_current_credit - target_current_credit; } - LOG_DEBUG("Target(%s) Credit: %u, Other(%s) Credit: %u, Init Credit: %u", - ADDRESS_TO_LOGGABLE_CSTR(target_side->address), - target_current_credit, - ADDRESS_TO_LOGGABLE_CSTR(other_side->address), - other_current_credit, init_credit); + log::debug("Target({}) Credit: {}, Other({}) Credit: {}, Init Credit: {}", + ADDRESS_TO_LOGGABLE_CSTR(target_side->address), + target_current_credit, + ADDRESS_TO_LOGGABLE_CSTR(other_side->address), + other_current_credit, init_credit); return diff_credit < (init_credit / 2 - 1); } + void OnAudioDataReadyResample(const std::vector& data) { + if (asrc == nullptr) { + return OnAudioDataReady(data); + } + + for (auto const resampled_data : asrc->Run(data)) { + OnAudioDataReady(*resampled_data); + } + } + void OnAudioDataReady(const std::vector& data) { /* For now we assume data comes in as 16bit per sample 16kHz PCM stereo */ bool need_drop = false; @@ -1363,7 +1431,7 @@ class HearingAidImpl : public HearingAid { // The G.722 codec accept only even number of samples for encoding if (num_samples % 2 != 0) - LOG_ALWAYS_FATAL("num_samples is not even: %d", num_samples); + log::fatal("num_samples is not even: {}", num_samples); // TODO: we should cache left/right and current state, instad of recomputing // it for each packet, 100 times a second. @@ -1379,7 +1447,7 @@ class HearingAidImpl : public HearingAid { } if (left == nullptr && right == nullptr) { - LOG_WARN("No more (0/%d) devices ready", GetDeviceCount()); + log::warn("No more (0/{}) devices ready", GetDeviceCount()); DoDisconnectAudioStop(); return; } @@ -1417,6 +1485,18 @@ class HearingAidImpl : public HearingAid { l2cap_flush_threshold = 1; } + // Skipping packets completely messes up the resampler context. + // The condition for skipping packets seems to be easily triggered, + // causing dropouts that could have been avoided. + // + // When the resampler is enabled, the flush threshold is set + // to the number of credits specified for the ASHA l2cap streaming + // channel. This will ensure it is only triggered in case of + // critical failure. + if (IS_FLAG_ENABLED(asha_asrc)) { + l2cap_flush_threshold = 8; + } + // TODO: monural, binarual check // divide encoded data into packets, add header, send. @@ -1441,15 +1521,13 @@ class HearingAidImpl : public HearingAid { // Compare the two sides LE CoC credit value to confirm need to drop or // skip audio packet. if (NeedToDropPacket(left, right) && IsBelowDropFrequency(time_point)) { - LOG_INFO("%s triggers dropping, %u packets in channel", - ADDRESS_TO_LOGGABLE_CSTR(left->address), - packets_in_chans); + log::info("{} triggers dropping, {} packets in channel", + ADDRESS_TO_LOGGABLE_CSTR(left->address), packets_in_chans); need_drop = true; left->audio_stats.trigger_drop_count++; } else { - LOG_INFO("%s skipping %u packets", - ADDRESS_TO_LOGGABLE_CSTR(left->address), - packets_in_chans); + log::info("{} skipping {} packets", + ADDRESS_TO_LOGGABLE_CSTR(left->address), packets_in_chans); left->audio_stats.packet_flush_count += packets_in_chans; left->audio_stats.frame_flush_count++; L2CA_FlushChannel(cid, 0xffff); @@ -1475,15 +1553,13 @@ class HearingAidImpl : public HearingAid { // Compare the two sides LE CoC credit value to confirm need to drop or // skip audio packet. if (NeedToDropPacket(right, left) && IsBelowDropFrequency(time_point)) { - LOG_INFO("%s triggers dropping, %u packets in channel", - ADDRESS_TO_LOGGABLE_CSTR(right->address), - packets_in_chans); + log::info("{} triggers dropping, {} packets in channel", + ADDRESS_TO_LOGGABLE_CSTR(right->address), packets_in_chans); need_drop = true; right->audio_stats.trigger_drop_count++; } else { - LOG_INFO("%s skipping %u packets", - ADDRESS_TO_LOGGABLE_CSTR(right->address), - packets_in_chans); + log::info("{} skipping {} packets", + ADDRESS_TO_LOGGABLE_CSTR(right->address), packets_in_chans); right->audio_stats.packet_flush_count += packets_in_chans; right->audio_stats.frame_flush_count++; L2CA_FlushChannel(cid, 0xffff); @@ -1528,9 +1604,9 @@ class HearingAidImpl : public HearingAid { void SendAudio(uint8_t* encoded_data, uint16_t packet_size, HearingDevice* hearingAid) { if (!hearingAid->playback_started || !hearingAid->command_acked) { - LOG_DEBUG("Playback stalled, device=%s,cmd send=%i, cmd acked=%i", - ADDRESS_TO_LOGGABLE_CSTR(hearingAid->address), - hearingAid->playback_started, hearingAid->command_acked); + log::debug("Playback stalled, device={},cmd send={}, cmd acked={}", + ADDRESS_TO_LOGGABLE_CSTR(hearingAid->address), + hearingAid->playback_started, hearingAid->command_acked); return; } @@ -1540,20 +1616,20 @@ class HearingAidImpl : public HearingAid { p++; memcpy(p, encoded_data, packet_size); - LOG_DEBUG("%s : %s", ADDRESS_TO_LOGGABLE_CSTR(hearingAid->address), - base::HexEncode(p, packet_size).c_str()); + log::debug("{} : {}", ADDRESS_TO_LOGGABLE_CSTR(hearingAid->address), + base::HexEncode(p, packet_size)); uint16_t result = GAP_ConnWriteData(hearingAid->gap_handle, audio_packet); if (result != BT_PASS) { - LOG_ERROR("Error sending data: %s", loghex(result).c_str()); + log::error("Error sending data: {}", loghex(result)); } } void GapCallback(uint16_t gap_handle, uint16_t event, tGAP_CB_DATA* data) { HearingDevice* hearingDevice = hearingDevices.FindByGapHandle(gap_handle); if (!hearingDevice) { - LOG_INFO("Skipping unknown device, gap_handle=%u", gap_handle); + log::info("Skipping unknown device, gap_handle={}", gap_handle); return; } @@ -1565,13 +1641,13 @@ class HearingAidImpl : public HearingAid { init_credit = L2CA_GetPeerLECocCredit(address, GAP_ConnGetL2CAPCid(gap_handle)); - LOG_INFO("GAP_EVT_CONN_OPENED %s, tx_mtu=%u, init_credit=%u", - ADDRESS_TO_LOGGABLE_CSTR(address), tx_mtu, init_credit); + log::info("GAP_EVT_CONN_OPENED {}, tx_mtu={}, init_credit={}", + ADDRESS_TO_LOGGABLE_CSTR(address), tx_mtu, init_credit); HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { - LOG_INFO("Skipping unknown device %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } hearingDevice->gap_opened = true; @@ -1582,9 +1658,8 @@ class HearingAidImpl : public HearingAid { } case GAP_EVT_CONN_CLOSED: - LOG_INFO( - "GAP_EVT_CONN_CLOSED: %s, playback_started=%i, " - "accepting_audio=%i", + log::info( + "GAP_EVT_CONN_CLOSED: {}, playback_started={}, accepting_audio={}", ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), hearingDevice->playback_started, hearingDevice->accepting_audio); if (!hearingDevice->accepting_audio) { @@ -1601,7 +1676,7 @@ class HearingAidImpl : public HearingAid { } break; case GAP_EVT_CONN_DATA_AVAIL: { - LOG_DEBUG("GAP_EVT_CONN_DATA_AVAIL"); + log::debug("GAP_EVT_CONN_DATA_AVAIL"); // only data we receive back from hearing aids are some stats, not // really important, but useful now for debugging. @@ -1614,28 +1689,28 @@ class HearingAidImpl : public HearingAid { GAP_ConnReadData(gap_handle, buffer.data(), buffer.size(), &bytes_read); if (bytes_read < 4) { - LOG_WARN("Wrong data length"); + log::warn("Wrong data length"); return; } uint8_t* p = buffer.data(); - LOG_DEBUG("stats from the hearing aid:"); + log::debug("stats from the hearing aid:"); for (size_t i = 0; i + 4 <= buffer.size(); i += 4) { uint16_t event_counter, frame_index; STREAM_TO_UINT16(event_counter, p); STREAM_TO_UINT16(frame_index, p); - LOG_DEBUG("event_counter=%u frame_index: %u", event_counter, - frame_index); + log::debug("event_counter={} frame_index: {}", event_counter, + frame_index); } break; } case GAP_EVT_TX_EMPTY: - LOG_DEBUG("GAP_EVT_TX_EMPTY"); + log::debug("GAP_EVT_TX_EMPTY"); break; case GAP_EVT_CONN_CONGESTED: - LOG_DEBUG("GAP_EVT_CONN_CONGESTED"); + log::debug("GAP_EVT_CONN_CONGESTED"); // TODO: make it into function HearingAidAudioSource::Stop(); @@ -1645,7 +1720,7 @@ class HearingAidImpl : public HearingAid { // encoder_state_right = nulllptr; break; case GAP_EVT_CONN_UNCONGESTED: - LOG_DEBUG("GAP_EVT_CONN_UNCONGESTED"); + log::debug("GAP_EVT_CONN_UNCONGESTED"); break; } } @@ -1676,8 +1751,8 @@ class HearingAidImpl : public HearingAid { char temptime[20]; struct tm* tstamp = localtime(&rssi_logs.timestamp.tv_sec); if (!strftime(temptime, sizeof(temptime), "%H:%M:%S", tstamp)) { - LOG_ERROR("strftime fails. tm_sec=%d, tm_min=%d, tm_hour=%d", - tstamp->tm_sec, tstamp->tm_min, tstamp->tm_hour); + log::error("strftime fails. tm_sec={}, tm_min={}, tm_hour={}", + tstamp->tm_sec, tstamp->tm_min, tstamp->tm_hour); strlcpy(temptime, "UNKNOWN TIME", sizeof(temptime)); } snprintf(eventtime, sizeof(eventtime), "%s.%03ld", temptime, rssi_logs.timestamp.tv_nsec / 1000000); @@ -1721,19 +1796,19 @@ class HearingAidImpl : public HearingAid { void Disconnect(const RawAddress& address) { HearingDevice* hearingDevice = hearingDevices.FindByAddress(address); if (!hearingDevice) { - LOG_INFO("Device not connected to profile %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Device not connected to profile {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return; } - LOG_DEBUG("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); bool connected = hearingDevice->accepting_audio; bool connecting_by_user = hearingDevice->connecting_actively; - LOG_INFO("%s, playback_started=%i, accepting_audio=%i", - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), - hearingDevice->playback_started, hearingDevice->accepting_audio); + log::info("{}, playback_started={}, accepting_audio={}", + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), + hearingDevice->playback_started, hearingDevice->accepting_audio); if (hearingDevice->connecting_actively) { // cancel pending direct connect @@ -1766,7 +1841,7 @@ class HearingAidImpl : public HearingAid { for (const auto& device : hearingDevices.devices) { if (device.accepting_audio) return; } - LOG_INFO("No more (0/%d) devices ready", GetDeviceCount()); + log::info("No more (0/{}) devices ready", GetDeviceCount()); DoDisconnectAudioStop(); } @@ -1774,12 +1849,12 @@ class HearingAidImpl : public HearingAid { RawAddress remote_bda) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device disconnect, conn_id=%s", - loghex(conn_id).c_str()); + log::debug("Skipping unknown device disconnect, conn_id={}", + loghex(conn_id)); return; } - LOG_DEBUG("conn_id=%s, remote_bda=%s", loghex(conn_id).c_str(), - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::debug("conn_id={}, remote_bda={}", loghex(conn_id), + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); // Inform the other side (if any) of this disconnection std::vector inform_disconn_state( @@ -1792,9 +1867,9 @@ class HearingAidImpl : public HearingAid { hearingDevices.FindOtherConnectedDeviceFromSet(*hearingDevice); if (other_connected_device_from_set != nullptr) { - LOG_INFO( + log::info( "Another device from the set is still connected, issuing a direct " - "connection, other_device_bda=%s", + "connection, other_device_bda={}", ADDRESS_TO_LOGGABLE_CSTR(other_connected_device_from_set->address)); } @@ -1819,15 +1894,15 @@ class HearingAidImpl : public HearingAid { for (const auto& device : hearingDevices.devices) { if (device.accepting_audio) return; } - LOG_INFO("No more (0/%d) devices ready", GetDeviceCount()); + log::info("No more (0/{}) devices ready", GetDeviceCount()); DoDisconnectAudioStop(); } void DoDisconnectCleanUp(HearingDevice* hearingDevice) { if (hearingDevice->connection_update_status != COMPLETED) { - LOG_INFO("connection update not completed. Current=%u, device=%s", - hearingDevice->connection_update_status, - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); + log::info("connection update not completed. Current={}, device={}", + hearingDevice->connection_update_status, + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address)); if (hearingDevice->connection_update_status == STARTED) { OnConnectionUpdateComplete(hearingDevice->conn_id, NULL); @@ -1848,9 +1923,9 @@ class HearingAidImpl : public HearingAid { } hearingDevice->accepting_audio = false; - LOG_INFO("device=%s, playback_started=%i", - ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), - hearingDevice->playback_started); + log::info("device={}, playback_started={}", + ADDRESS_TO_LOGGABLE_CSTR(hearingDevice->address), + hearingDevice->playback_started); hearingDevice->playback_started = false; hearingDevice->command_acked = false; } @@ -1863,7 +1938,7 @@ class HearingAidImpl : public HearingAid { } void SetVolume(int8_t volume) { - LOG_DEBUG("%d", volume); + log::debug("{}", volume); current_volume = volume; for (HearingDevice& device : hearingDevices.devices) { if (!device.accepting_audio) continue; @@ -1906,7 +1981,7 @@ class HearingAidImpl : public HearingAid { const gatt::Service* service) { HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id); if (!hearingDevice) { - LOG_DEBUG("Skipping unknown device, conn_id=%s", loghex(conn_id).c_str()); + log::debug("Skipping unknown device, conn_id={}", loghex(conn_id)); return; } for (const gatt::Characteristic& charac : service->characteristics) { @@ -1914,11 +1989,11 @@ class HearingAidImpl : public HearingAid { hearingDevice->service_changed_ccc_handle = find_ccc_handle(conn_id, charac.value_handle); if (!hearingDevice->service_changed_ccc_handle) { - LOG_ERROR("cannot find service changed CCC descriptor"); + log::error("cannot find service changed CCC descriptor"); continue; } - LOG_INFO("service_changed_ccc=%s", - loghex(hearingDevice->service_changed_ccc_handle).c_str()); + log::info("service_changed_ccc={}", + loghex(hearingDevice->service_changed_ccc_handle)); break; } } @@ -1931,7 +2006,7 @@ class HearingAidImpl : public HearingAid { BTA_GATTC_GetCharacteristic(conn_id, char_handle); if (!p_char) { - LOG_WARN("No such characteristic: %u", char_handle); + log::warn("No such characteristic: {}", char_handle); return 0; } @@ -1946,14 +2021,13 @@ class HearingAidImpl : public HearingAid { void send_state_change(HearingDevice* device, std::vector payload) { if (device->conn_id != 0) { if (device->service_changed_rcvd) { - LOG_INFO( + log::info( "service discover is in progress, skip send State Change cmd."); return; } // Send the data packet - LOG_INFO("Send State Change. device=%s, status=%s", - ADDRESS_TO_LOGGABLE_CSTR(device->address), - loghex(payload[1]).c_str()); + log::info("Send State Change. device={}, status={}", + ADDRESS_TO_LOGGABLE_CSTR(device->address), loghex(payload[1])); BtaGattQueue::WriteCharacteristic( device->conn_id, device->audio_control_point_handle, payload, GATT_WRITE_NO_RSP, nullptr, nullptr); @@ -1976,7 +2050,7 @@ class HearingAidImpl : public HearingAid { device->num_intervals_since_last_rssi_read++; if (device->num_intervals_since_last_rssi_read >= PERIOD_TO_READ_RSSI_IN_INTERVALS) { device->num_intervals_since_last_rssi_read = 0; - LOG_DEBUG("device=%s", ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::debug("device={}", ADDRESS_TO_LOGGABLE_CSTR(device->address)); BTM_ReadRSSI(device->address, read_rssi_cb); } } @@ -1994,7 +2068,7 @@ void read_rssi_cb(void* p_void) { } void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { - LOG_DEBUG("event = %u", event); + log::debug("event = {}", event); if (p_data == nullptr) return; @@ -2025,8 +2099,8 @@ void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { case BTA_GATTC_NOTIF_EVT: if (!instance) return; if (!p_data->notify.is_notify || p_data->notify.len > GATT_MAX_ATTR_LEN) { - LOG_ERROR("rejected BTA_GATTC_NOTIF_EVT. is_notify=%i, len=%u", - p_data->notify.is_notify, p_data->notify.len); + log::error("rejected BTA_GATTC_NOTIF_EVT. is_notify={}, len={}", + p_data->notify.is_notify, p_data->notify.len); break; } instance->OnNotificationEvent(p_data->notify.conn_id, @@ -2078,7 +2152,7 @@ void encryption_callback(const RawAddress* address, tBT_TRANSPORT, void*, class HearingAidAudioReceiverImpl : public HearingAidAudioReceiver { public: void OnAudioDataReady(const std::vector& data) override { - if (instance) instance->OnAudioDataReady(data); + if (instance) instance->OnAudioDataReadyResample(data); } void OnAudioSuspend(const std::function& stop_audio_ticks) override { if (instance) instance->OnAudioSuspend(stop_audio_ticks); @@ -2096,7 +2170,7 @@ void HearingAid::Initialize( bluetooth::hearing_aid::HearingAidCallbacks* callbacks, Closure initCb) { std::scoped_lock lock(instance_mutex); if (instance) { - LOG_ERROR("Already initialized!"); + log::error("Already initialized!"); return; } @@ -2109,7 +2183,7 @@ bool HearingAid::IsHearingAidRunning() { return instance; } void HearingAid::Connect(const RawAddress& address) { if (!instance) { - LOG_ERROR("Hearing Aid instance is not available"); + log::error("Hearing Aid instance is not available"); return; } instance->Connect(address); @@ -2117,7 +2191,7 @@ void HearingAid::Connect(const RawAddress& address) { void HearingAid::Disconnect(const RawAddress& address) { if (!instance) { - LOG_ERROR("Hearing Aid instance is not available"); + log::error("Hearing Aid instance is not available"); return; } instance->Disconnect(address); @@ -2125,7 +2199,7 @@ void HearingAid::Disconnect(const RawAddress& address) { void HearingAid::AddToAcceptlist(const RawAddress& address) { if (!instance) { - LOG_ERROR("Hearing Aid instance is not available"); + log::error("Hearing Aid instance is not available"); return; } instance->AddToAcceptlist(address); @@ -2133,7 +2207,7 @@ void HearingAid::AddToAcceptlist(const RawAddress& address) { void HearingAid::SetVolume(int8_t volume) { if (!instance) { - LOG_ERROR("Hearing Aid instance is not available"); + log::error("Hearing Aid instance is not available"); return; } instance->SetVolume(volume); @@ -2142,7 +2216,7 @@ void HearingAid::SetVolume(int8_t volume) { void HearingAid::AddFromStorage(const HearingDevice& dev_info, bool is_acceptlisted) { if (!instance) { - LOG_ERROR("Not initialized yet"); + log::error("Not initialized yet"); } instance->AddFromStorage(dev_info, is_acceptlisted); @@ -2150,7 +2224,7 @@ void HearingAid::AddFromStorage(const HearingDevice& dev_info, int HearingAid::GetDeviceCount() { if (!instance) { - LOG_INFO("Not initialized yet"); + log::info("Not initialized yet"); return 0; } diff --git a/system/bta/hearing_aid/hearing_aid_audio_source.cc b/system/bta/hearing_aid/hearing_aid_audio_source.cc index 7a284e97ccfa72e67643ed60acd8155c30fcc236..3c1b038934c424b6b4fbafad8b2027924ba077a4 100644 --- a/system/bta/hearing_aid/hearing_aid_audio_source.cc +++ b/system/bta/hearing_aid/hearing_aid_audio_source.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -29,12 +30,24 @@ #include "bta/include/bta_hearing_aid_api.h" #include "common/repeating_timer.h" #include "common/time_util.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/wakelock.h" #include "stack/include/main_thread.h" #include "udrv/include/uipc.h" using base::FilePath; +using namespace bluetooth; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt namespace { #define CASE_RETURN_STR(const) \ @@ -100,7 +113,7 @@ void send_audio_data() { bytes_per_tick); } - LOG_DEBUG("bytes_read: %u", bytes_read); + log::debug("bytes_read: {}", bytes_read); if (bytes_read < bytes_per_tick) { stats.media_read_total_underflow_bytes += bytes_per_tick - bytes_read; stats.media_read_total_underflow_count++; @@ -117,38 +130,34 @@ void send_audio_data() { void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) { uint8_t ack = status; - LOG_DEBUG("Hearing Aid audio ctrl ack: %u", status); + log::debug("Hearing Aid audio ctrl ack: {}", status); UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack)); } void start_audio_ticks() { if (data_interval_ms != HA_INTERVAL_10_MS && data_interval_ms != HA_INTERVAL_20_MS) { - LOG_ALWAYS_FATAL("Unsupported data interval: %d", data_interval_ms); + log::fatal("Unsupported data interval: {}", data_interval_ms); } wakelock_acquire(); - audio_timer.SchedulePeriodic( - get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(data_interval_ms)); -#else - base::Milliseconds(data_interval_ms)); -#endif - LOG_INFO("running with data interval: %d", data_interval_ms); + audio_timer.SchedulePeriodic(get_main_thread()->GetWeakPtr(), FROM_HERE, + base::BindRepeating(&send_audio_data), + std::chrono::milliseconds(data_interval_ms)); + log::info("running with data interval: {}", data_interval_ms); } void stop_audio_ticks() { - LOG_INFO("stopped"); + log::info("stopped"); audio_timer.CancelAndWait(); wakelock_release(); } void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) { - LOG_DEBUG("Hearing Aid audio data event: %u", event); + log::debug("Hearing Aid audio data event: {}", event); switch (event) { case UIPC_OPEN_EVT: - LOG_INFO("UIPC_OPEN_EVT"); + log::info("UIPC_OPEN_EVT"); /* * Read directly from media task from here on (keep callback for * connection events. @@ -161,12 +170,12 @@ void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) { do_in_main_thread(FROM_HERE, base::BindOnce(start_audio_ticks)); break; case UIPC_CLOSE_EVT: - LOG_INFO("UIPC_CLOSE_EVT"); + log::info("UIPC_CLOSE_EVT"); hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); do_in_main_thread(FROM_HERE, base::BindOnce(stop_audio_ticks)); break; default: - LOG_ERROR("Hearing Aid audio data event not recognized: %u", event); + log::error("Hearing Aid audio data event not recognized: {}", event); } } @@ -180,12 +189,12 @@ void hearing_aid_recv_ctrl_data() { /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { - LOG_WARN("CTRL CH DETACHED"); + log::warn("CTRL CH DETACHED"); UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL); return; } - LOG_INFO("%s", audio_ha_hw_dump_ctrl_event(cmd)); + log::info("{}", audio_ha_hw_dump_ctrl_event(cmd)); // a2dp_cmd_pending = cmd; tHEARING_AID_CTRL_ACK ctrl_ack_status; @@ -209,7 +218,7 @@ void hearing_aid_recv_ctrl_data() { case HEARING_AID_CTRL_CMD_STOP: if (!hearing_aid_on_suspend_req()) { - LOG_INFO( + log::info( "HEARING_AID_CTRL_CMD_STOP: hearing_aid_on_suspend_req() errs, but " "ignored."); } @@ -234,7 +243,7 @@ void hearing_aid_recv_ctrl_data() { codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000; codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000; } else { - LOG_ALWAYS_FATAL("unsupported sample rate: %d", sample_rate); + log::fatal("unsupported sample rate: {}", sample_rate); } codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16; @@ -282,14 +291,14 @@ void hearing_aid_recv_ctrl_data() { reinterpret_cast(&codec_config.sample_rate), sizeof(btav_a2dp_codec_sample_rate_t)) != sizeof(btav_a2dp_codec_sample_rate_t)) { - LOG_ERROR("Error reading sample rate from audio HAL"); + log::error("Error reading sample rate from audio HAL"); break; } if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, reinterpret_cast(&codec_config.bits_per_sample), sizeof(btav_a2dp_codec_bits_per_sample_t)) != sizeof(btav_a2dp_codec_bits_per_sample_t)) { - LOG_ERROR("Error reading bits per sample from audio HAL"); + log::error("Error reading bits per sample from audio HAL"); break; } @@ -297,28 +306,28 @@ void hearing_aid_recv_ctrl_data() { reinterpret_cast(&codec_config.channel_mode), sizeof(btav_a2dp_codec_channel_mode_t)) != sizeof(btav_a2dp_codec_channel_mode_t)) { - LOG_ERROR("Error reading channel mode from audio HAL"); + log::error("Error reading channel mode from audio HAL"); break; } - LOG_INFO( - "HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: sample_rate=%u, " - "bits_per_sample=%u,channel_mode=%u", + log::info( + "HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: sample_rate={}, " + "bits_per_sample={},channel_mode={}", codec_config.sample_rate, codec_config.bits_per_sample, codec_config.channel_mode); break; } default: - LOG_ERROR("UNSUPPORTED CMD: %u", cmd); + log::error("UNSUPPORTED CMD: {}", cmd); hearing_aid_send_ack(HEARING_AID_CTRL_ACK_FAILURE); break; } - LOG_INFO("a2dp-ctrl-cmd : %s DONE", audio_ha_hw_dump_ctrl_event(cmd)); + log::info("a2dp-ctrl-cmd : {} DONE", audio_ha_hw_dump_ctrl_event(cmd)); } void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) { - LOG_DEBUG("Hearing Aid audio ctrl event: %u", event); + log::debug("Hearing Aid audio ctrl event: {}", event); switch (event) { case UIPC_OPEN_EVT: break; @@ -333,13 +342,13 @@ void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) { hearing_aid_recv_ctrl_data(); break; default: - LOG_ERROR("Hearing Aid audio ctrl unrecognized event: %u", event); + log::error("Hearing Aid audio ctrl unrecognized event: {}", event); } } bool hearing_aid_on_resume_req(bool start_media_task) { if (localAudioReceiver == nullptr) { - LOG_ERROR("HEARING_AID_CTRL_CMD_START: audio receiver not started"); + log::error("HEARING_AID_CTRL_CMD_START: audio receiver not started"); return false; } bt_status_t status; @@ -350,7 +359,7 @@ bool hearing_aid_on_resume_req(bool start_media_task) { start_audio_ticks)); } else { auto start_dummy_ticks = []() { - LOG_INFO("start_audio_ticks: waiting for data path opened"); + log::info("start_audio_ticks: waiting for data path opened"); }; status = do_in_main_thread( FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume, @@ -358,7 +367,7 @@ bool hearing_aid_on_resume_req(bool start_media_task) { start_dummy_ticks)); } if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("HEARING_AID_CTRL_CMD_START: do_in_main_thread err=%u", status); + log::error("HEARING_AID_CTRL_CMD_START: do_in_main_thread err={}", status); return false; } return true; @@ -366,7 +375,7 @@ bool hearing_aid_on_resume_req(bool start_media_task) { bool hearing_aid_on_suspend_req() { if (localAudioReceiver == nullptr) { - LOG_ERROR("HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started"); + log::error("HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started"); return false; } bt_status_t status = do_in_main_thread( @@ -374,7 +383,8 @@ bool hearing_aid_on_suspend_req() { base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend, base::Unretained(localAudioReceiver), stop_audio_ticks)); if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err=%u", status); + log::error("HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err={}", + status); return false; } return true; @@ -384,7 +394,7 @@ bool hearing_aid_on_suspend_req() { void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration, HearingAidAudioReceiver* audioReceiver, uint16_t remote_delay_ms) { - LOG_INFO("Hearing Aid Source Open"); + log::info("Hearing Aid Source Open"); bit_rate = codecConfiguration.bit_rate; sample_rate = codecConfiguration.sample_rate; @@ -400,7 +410,7 @@ void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration, } void HearingAidAudioSource::Stop() { - LOG_INFO("Hearing Aid Source Close"); + log::info("Hearing Aid Source Close"); localAudioReceiver = nullptr; if (bluetooth::audio::hearing_aid::is_hal_enabled()) { @@ -416,7 +426,7 @@ void HearingAidAudioSource::Initialize() { .on_suspend_ = hearing_aid_on_suspend_req, }; if (!bluetooth::audio::hearing_aid::init(stream_cb, get_main_thread())) { - LOG_WARN("Using legacy HAL"); + log::warn("Using legacy HAL"); uipc_hearing_aid = UIPC_Init(); UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, HEARING_AID_CTRL_PATH); } diff --git a/system/bta/hf_client/bta_hf_client_act.cc b/system/bta/hf_client/bta_hf_client_act.cc index 2bd622cea3a368b09784996f0d0580befb40d09d..f6f44aba3e79b3b9f43248b67266394368afc57e 100644 --- a/system/bta/hf_client/bta_hf_client_act.cc +++ b/system/bta/hf_client/bta_hf_client_act.cc @@ -23,6 +23,8 @@ * ******************************************************************************/ +#include + #include "bta/hf_client/bta_hf_client_int.h" #include "bta/include/bta_dm_api.h" #include "os/log.h" @@ -31,6 +33,8 @@ #include "stack/include/sdp_status.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants ****************************************************************************/ @@ -52,8 +56,7 @@ void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, - p_data->hdr.layer_specific); + log::error("wrong handle to control block {}", p_data->hdr.layer_specific); return; } @@ -86,8 +89,7 @@ void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, - p_data->hdr.layer_specific); + log::error("wrong handle to control block {}", p_data->hdr.layer_specific); return; } @@ -125,12 +127,11 @@ void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) { * ******************************************************************************/ void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -151,25 +152,24 @@ void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) { * ******************************************************************************/ void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } /* set role */ client_cb->role = BTA_HF_CLIENT_ACP; - LOG_VERBOSE("%s: conn_handle %d", __func__, client_cb->conn_handle); + log::verbose("conn_handle {}", client_cb->conn_handle); /* get bd addr of peer */ uint16_t lcid = 0; RawAddress dev_addr = RawAddress::kEmpty; int status = PORT_CheckConnection(client_cb->conn_handle, &dev_addr, &lcid); if (status != PORT_SUCCESS) { - LOG_ERROR("PORT_CheckConnection returned status:%d", status); + log::error("PORT_CheckConnection returned status:{}", status); } /* Collision Handling */ @@ -209,8 +209,7 @@ void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -239,8 +238,7 @@ void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } } @@ -259,8 +257,7 @@ void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } } @@ -279,8 +276,7 @@ void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -322,12 +318,11 @@ void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) { void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) { uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT; - LOG_VERBOSE("%s: Status: %d", __func__, p_data->disc_result.status); + log::verbose("Status: {}", p_data->disc_result.status); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -361,8 +356,7 @@ void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -391,8 +385,7 @@ void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -427,12 +420,11 @@ void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) { * ******************************************************************************/ void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } diff --git a/system/bta/hf_client/bta_hf_client_api.cc b/system/bta/hf_client/bta_hf_client_api.cc index 62092bd0f159b9de98e0b11f84ee7e0c87a0163c..4110fe79d0770d8f0166ef64d2744328feb761ad 100644 --- a/system/bta/hf_client/bta_hf_client_api.cc +++ b/system/bta/hf_client/bta_hf_client_api.cc @@ -27,6 +27,7 @@ #include "bta/include/bta_hf_client_api.h" #include +#include #include @@ -38,6 +39,8 @@ #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * External Function Declarations ****************************************************************************/ @@ -85,12 +88,12 @@ void BTA_HfClientDisable(void) { bta_hf_client_api_disable(); } * ******************************************************************************/ bt_status_t BTA_HfClientOpen(const RawAddress& bd_addr, uint16_t* p_handle) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_API_OPEN* p_buf = (tBTA_HF_CLIENT_API_OPEN*)osi_malloc(sizeof(tBTA_HF_CLIENT_API_OPEN)); if (!bta_hf_client_allocate_handle(bd_addr, p_handle)) { - LOG_ERROR("%s: could not allocate handle", __func__); + log::error("could not allocate handle"); return BT_STATUS_FAIL; } diff --git a/system/bta/hf_client/bta_hf_client_at.cc b/system/bta/hf_client/bta_hf_client_at.cc index 64bc1ed18b7df052291097c3443c24c2c48adea7..f8730ca668003ac7a70e014a2e8f00f72db28772 100644 --- a/system/bta/hf_client/bta_hf_client_at.cc +++ b/system/bta/hf_client/bta_hf_client_at.cc @@ -19,11 +19,13 @@ #define LOG_TAG "bt_hf_client" +#include + #include "bta/hf_client/bta_hf_client_int.h" #include "internal_include/bt_trace.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" -#include "osi/include/log.h" #include "osi/include/properties.h" #include "stack/include/acl_api.h" #include "stack/include/port_api.h" @@ -40,6 +42,8 @@ /* timeout (in milliseconds) for AT hold timer */ #define BTA_HF_CLIENT_AT_HOLD_TIMEOUT 41 +using namespace bluetooth; + static constexpr char kPropertyEnhancedDrivingIndicatorEnabled[] = "bluetooth.headset_client.indicator.enhanced_driver_safety.enabled"; @@ -128,7 +132,7 @@ static void bta_hf_client_queue_at(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_AT_QCMD* new_cmd = (tBTA_HF_CLIENT_AT_QCMD*)osi_malloc(sizeof(tBTA_HF_CLIENT_AT_QCMD)); - LOG_VERBOSE("%s: cmd:%d", __func__, (int)cmd); + log::verbose("cmd:{}", (int)cmd); new_cmd->cmd = cmd; new_cmd->buf_len = buf_len; @@ -149,11 +153,10 @@ static void bta_hf_client_queue_at(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_at_resp_timer_cback(void* data) { tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data; if (client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_CNUM) { - LOG_INFO("%s: timed out waiting for AT+CNUM response; spoofing OK.", - __func__); + log::info("timed out waiting for AT+CNUM response; spoofing OK."); bta_hf_client_handle_ok(client_cb); } else { - LOG_ERROR("HFPClient: AT response timeout, disconnecting"); + log::error("HFPClient: AT response timeout, disconnecting"); tBTA_HF_CLIENT_DATA msg = {}; msg.hdr.layer_specific = client_cb->handle; @@ -173,27 +176,26 @@ static void bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) { static void bta_hf_client_send_at(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_AT_CMD cmd, const char* buf, uint16_t buf_len) { - LOG_VERBOSE("%s %d", __func__, cmd); + log::verbose("{}", cmd); if ((client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_NONE || !client_cb->svc_conn) && !alarm_is_scheduled(client_cb->at_cb.hold_timer)) { uint16_t len; #ifdef BTA_HF_CLIENT_AT_DUMP - LOG_VERBOSE("%s: %.*s", __func__, buf_len - 1, buf); + log::verbose("{:.{}}", buf, buf_len - 1); #endif client_cb->at_cb.current_cmd = cmd; /* Generate fake responses for these because they won't reliably work */ if (!service_availability && (cmd == BTA_HF_CLIENT_AT_CNUM || cmd == BTA_HF_CLIENT_AT_COPS)) { - LOG_WARN("%s: No service, skipping %d command", __func__, cmd); + log::warn("No service, skipping {} command", cmd); bta_hf_client_handle_ok(client_cb); return; } - LOG_VERBOSE("%s: writing port data to %d", __func__, - client_cb->conn_handle); + log::verbose("writing port data to {}", client_cb->conn_handle); PORT_WriteData(client_cb->conn_handle, buf, buf_len, &len); bta_hf_client_start_at_resp_timer(client_cb); @@ -201,14 +203,14 @@ static void bta_hf_client_send_at(tBTA_HF_CLIENT_CB* client_cb, return; } - LOG_VERBOSE("%s: busy! queued: %d", __func__, cmd); + log::verbose("busy! queued: {}", cmd); bta_hf_client_queue_at(client_cb, cmd, buf, buf_len); } static void bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB* client_cb) { tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (cur != NULL) { client_cb->at_cb.queued_cmd = cur->next; @@ -221,17 +223,17 @@ static void bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB* client_cb) { static void bta_hf_client_at_hold_timer_cback(void* data) { tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_hf_client_send_queued_at(client_cb); } static void bta_hf_client_stop_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); alarm_cancel(client_cb->at_cb.hold_timer); } static void bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); alarm_set_on_mloop(client_cb->at_cb.hold_timer, BTA_HF_CLIENT_AT_HOLD_TIMEOUT, bta_hf_client_at_hold_timer_cback, (void*)client_cb); } @@ -245,7 +247,7 @@ static void bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) { ******************************************************************************/ static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb) { - LOG_VERBOSE("%s: current_cmd:%d", __func__, client_cb->at_cb.current_cmd); + log::verbose("current_cmd:{}", client_cb->at_cb.current_cmd); bta_hf_client_stop_at_resp_timer(client_cb); @@ -289,8 +291,8 @@ static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb) { static void bta_hf_client_handle_error(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_AT_RESULT_TYPE type, uint16_t cme) { - LOG_VERBOSE("%s: type:%u cme:%u current_cmd:%d", __func__, type, cme, - client_cb->at_cb.current_cmd); + log::verbose("type:{} cme:{} current_cmd:{}", type, cme, + client_cb->at_cb.current_cmd); bta_hf_client_stop_at_resp_timer(client_cb); @@ -327,7 +329,7 @@ static void bta_hf_client_handle_error(tBTA_HF_CLIENT_CB* client_cb, } static void bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB* client_cb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); const bool exit_sniff_while_ring = osi_property_get_bool( "bluetooth.headset_client.exit_sniff_while_ring", false); @@ -346,7 +348,7 @@ static void bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB* client_cb) { static void bta_hf_client_handle_brsf(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) { - LOG_VERBOSE("%s: 0x%x", __func__, value); + log::verbose("0x{:x}", value); client_cb->peer_features = value; } @@ -357,8 +359,7 @@ static void bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB* client_cb, uint32_t max, uint32_t index) { uint8_t i = 0; - LOG_VERBOSE("%s: %" PRIu32 ".%s <%" PRIu32 ":%" PRIu32 ">", __func__, index, - name, min, max); + log::verbose("{} .{} <{}:{}>", index, name, min, max); if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) { return; @@ -389,7 +390,7 @@ static void bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB* client_cb, uint32_t index, uint32_t value) { - LOG_VERBOSE("%s: index: %u value: %u", __func__, index, value); + log::verbose("index: {} value: {}", index, value); if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) { return; @@ -421,21 +422,21 @@ static void bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB* client_cb, uint32_t mask) { - LOG_VERBOSE("%s: 0x%x", __func__, mask); + log::verbose("0x{:x}", mask); client_cb->chld_features |= mask; } static void bta_hf_client_handle_bind_read_supported_ind( tBTA_HF_CLIENT_CB* client_cb, int indicator_id) { - LOG_VERBOSE("%s: %d", __func__, indicator_id); + log::verbose("{}", indicator_id); client_cb->peer_hf_indicators.insert(indicator_id); } static void bta_hf_client_handle_bind_read_enabled_ind( tBTA_HF_CLIENT_CB* client_cb, int indicator_id, bool enable) { - LOG_VERBOSE("%s: %d", __func__, indicator_id); + log::verbose("{}", indicator_id); if (enable) { client_cb->enabled_hf_indicators.insert(indicator_id); @@ -448,7 +449,7 @@ static void bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB* client_cb, uint32_t index, uint32_t value) { int8_t realind = -1; - LOG_VERBOSE("%s: index: %u value: %u", __func__, index, value); + log::verbose("index: {} value: {}", index, value); if (index == 0 || index > BTA_HF_CLIENT_AT_INDICATOR_COUNT) { return; @@ -484,8 +485,7 @@ static void bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) { - LOG_VERBOSE("%s: codec: %u sco listen state: %d", __func__, codec, - client_cb->sco_state); + log::verbose("codec: {} sco listen state: {}", codec, client_cb->sco_state); if (codec == UUID_CODEC_CVSD || codec == UUID_CODEC_MSBC || (bta_hf_client_cb_arr.is_support_lc3 && codec == UUID_CODEC_LC3)) { switch (codec) { @@ -511,7 +511,7 @@ static void bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_bsir(tBTA_HF_CLIENT_CB* client_cb, uint32_t provided) { - LOG_VERBOSE("%s: %" PRIu32, __func__, provided); + log::verbose("{}", provided); bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BSIR_EVT, provided); } @@ -523,7 +523,7 @@ static void bta_hf_client_handle_cmeerror(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) { - LOG_VERBOSE("%s: %" PRIu32, __func__, value); + log::verbose("{}", value); if (value <= BTA_HF_CLIENT_VGM_MAX) { bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_MIC_EVT, value); @@ -532,7 +532,7 @@ static void bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) { - LOG_VERBOSE("%s: %" PRIu32, __func__, value); + log::verbose("{}", value); if (value <= BTA_HF_CLIENT_VGS_MAX) { bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_SPK_EVT, value); @@ -541,7 +541,7 @@ static void bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) { - LOG_VERBOSE("%s: %" PRIu32, __func__, value); + log::verbose("{}", value); if (value > 1) { return; @@ -552,28 +552,31 @@ static void bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_clip(tBTA_HF_CLIENT_CB* client_cb, char* numstr, uint32_t type) { - LOG_VERBOSE("%s: %u %s", __func__, type, numstr); + std::string cell_number(numstr); + log::verbose("{} {}", type, PRIVATE_CELL(cell_number)); bta_hf_client_clip(client_cb, numstr); } static void bta_hf_client_handle_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* numstr, uint32_t type) { - LOG_VERBOSE("%s: %u %s", __func__, type, numstr); + std::string cell_number(numstr); + log::verbose("{} {}", type, PRIVATE_CELL(cell_number)); bta_hf_client_ccwa(client_cb, numstr); } static void bta_hf_client_handle_cops(tBTA_HF_CLIENT_CB* client_cb, char* opstr, uint32_t mode) { - LOG_VERBOSE("%s: %u %s", __func__, mode, opstr); + log::verbose("{} {}", mode, opstr); bta_hf_client_operator_name(client_cb, opstr); } static void bta_hf_client_handle_binp(tBTA_HF_CLIENT_CB* client_cb, char* numstr) { - LOG_VERBOSE("%s: %s", __func__, numstr); + std::string cell_number(numstr); + log::verbose("{}", PRIVATE_CELL(cell_number)); bta_hf_client_binp(client_cb, numstr); } @@ -583,11 +586,12 @@ static void bta_hf_client_handle_clcc(tBTA_HF_CLIENT_CB* client_cb, uint16_t status, uint16_t mode, uint16_t mpty, char* numstr, uint16_t type) { - LOG_VERBOSE("%s: idx: %u dir: %u status: %u mode: %u mpty: %u", __func__, idx, - dir, status, mode, mpty); + log::verbose("idx: {} dir: {} status: {} mode: {} mpty: {}", idx, dir, status, + mode, mpty); if (numstr) { - LOG_VERBOSE("%s: number: %s type: %u", __func__, numstr, type); + std::string cell_number(numstr); + log::verbose("number: {} type: {}", PRIVATE_CELL(cell_number), type); } bta_hf_client_clcc(client_cb, idx, dir, status, mpty, numstr); @@ -596,8 +600,9 @@ static void bta_hf_client_handle_clcc(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB* client_cb, char* numstr, uint16_t type, uint16_t service) { - LOG_VERBOSE("%s: number: %s type: %u service: %u", __func__, numstr, type, - service); + std::string cell_number(numstr); + log::verbose("number: {} type: {} service: {}", PRIVATE_CELL(cell_number), + type, service); /* TODO: should number be modified according to type? */ bta_hf_client_cnum(client_cb, numstr, service); @@ -605,7 +610,7 @@ static void bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB* client_cb, static void bta_hf_client_handle_btrh(tBTA_HF_CLIENT_CB* client_cb, uint16_t code) { - LOG_VERBOSE("%s: %" PRIu32, __func__, code); + log::verbose("{}", code); bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BTRH_EVT, code); } @@ -850,7 +855,7 @@ void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number) { #define AT_CHECK_RN(buf) \ do { \ if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) { \ - LOG_VERBOSE("%s: missing end ", __func__); \ + log::verbose("missing end "); \ return NULL; \ } \ (buf) += sizeof("\r\n") - 1; \ @@ -965,7 +970,7 @@ static char* bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB* client_cb, &max, &offset)) > 2) { bta_hf_client_handle_cind_list_item(client_cb, name, min, max, index); if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1087,6 +1092,8 @@ static char* bta_hf_client_parse_bind(tBTA_HF_CLIENT_CB* client_cb, buffer++; } + AT_CHECK_RN(buffer); + return buffer; } @@ -1104,7 +1111,7 @@ static char* bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB* client_cb, } if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1197,7 +1204,7 @@ static char* bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB* client_cb, } if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1229,7 +1236,7 @@ static char* bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB* client_cb, } if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1261,7 +1268,7 @@ static char* bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB* client_cb, } /* Abort in case offset not set because of format error */ if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1298,7 +1305,7 @@ static char* bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB* client_cb, /* Abort in case offset not set because of format error */ if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1338,7 +1345,7 @@ static char* bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB* client_cb, /* Abort in case offset not set because of format error */ if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1363,7 +1370,7 @@ static char* bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB* client_cb, res += res2; /* Abort in case offset not set because of format error */ if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1426,7 +1433,7 @@ static char* bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB* client_cb, /* Abort in case offset not set because of format error */ if (offset == 0) { - LOG_ERROR("%s: Format Error %s", __func__, buffer); + log::error("Format Error {}", buffer); return NULL; } @@ -1546,7 +1553,7 @@ static char* bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB* client_cb, buffer = tmp + 2; - LOG_VERBOSE("%s: %.*s", __func__, (int)(buffer - start - 2), start); + log::verbose("{:.{}}", start, (int)(buffer - start - 2)); return buffer; } @@ -1572,11 +1579,11 @@ static char* bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB* client_cb, bta_hf_client_unknown_response(client_cb, tmp_buf); AT_CHECK_RN(end); } else { - LOG_ERROR("%s: exceed event buffer size. (%d, %d)", __func__, evt_size, - BTA_HF_CLIENT_UNKNOWN_EVENT_LEN); + log::error("exceed event buffer size. ({}, {})", evt_size, + BTA_HF_CLIENT_UNKNOWN_EVENT_LEN); } - LOG_VERBOSE("%s: %s", __func__, buffer); + log::verbose("{}", buffer); return end; } @@ -1623,10 +1630,10 @@ static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) { while (*p1 != '\0') { if (*p1 == '\r') { - strlcpy(p2, "", 4); + strncpy(p2, "", 4); p2 += 4; } else if (*p1 == '\n') { - strlcpy(p2, "", 4); + strncpy(p2, "", 4); p2 += 4; } else { *p2 = *p1; @@ -1637,14 +1644,14 @@ static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) { *p2 = '\0'; - LOG_VERBOSE("%s: %s", __func__, dump); + log::verbose("{}", dump); } #endif static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) { char* buf = client_cb->at_cb.buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); #ifdef BTA_HF_CLIENT_AT_DUMP bta_hf_client_dump_at(client_cb); @@ -1657,7 +1664,7 @@ static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) { for (i = 0; i < bta_hf_client_parser_cb_count; i++) { tmp = bta_hf_client_parser_cb[i](client_cb, buf); if (tmp == NULL) { - LOG_ERROR("HFPCient: AT event/reply parsing failed, skipping"); + log::error("HFPCient: AT event/reply parsing failed, skipping"); tmp = bta_hf_client_skip_unknown(client_cb, buf); break; } @@ -1672,7 +1679,7 @@ static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) { /* could not skip unknown (received garbage?)... disconnect */ if (tmp == NULL) { - LOG_ERROR("HFPCient: could not skip unknown AT event, disconnecting"); + log::error("HFPCient: could not skip unknown AT event, disconnecting"); bta_hf_client_at_reset(client_cb); tBTA_HF_CLIENT_DATA msg = {}; @@ -1696,7 +1703,7 @@ static bool bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB* client_cb) { } } - LOG_VERBOSE("%s: %d", __func__, ret); + log::verbose("{}", ret); return ret; } @@ -1714,7 +1721,7 @@ static void bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB* client_cb) { ******************************************************************************/ void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf, unsigned int len) { - LOG_VERBOSE("%s: offset: %u len: %u", __func__, client_cb->at_cb.offset, len); + log::verbose("offset: {} len: {}", client_cb->at_cb.offset, len); if (len + client_cb->at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) { char tmp_buff[BTA_HF_CLIENT_AT_PARSER_MAX_LEN]; @@ -1722,7 +1729,7 @@ void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf, unsigned int space_left = BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset; - LOG_VERBOSE("%s: overrun, trying to recover", __func__); + log::verbose("overrun, trying to recover"); /* fill up parser buffer */ memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, space_left); @@ -1733,7 +1740,7 @@ void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf, /* find end of last complete command before proceeding */ while (!bta_hf_client_check_at_complete(client_cb)) { if (client_cb->at_cb.offset == 0) { - LOG_ERROR("HFPClient: AT parser buffer overrun, disconnecting"); + log::error("HFPClient: AT parser buffer overrun, disconnecting"); bta_hf_client_at_reset(client_cb); @@ -1781,11 +1788,11 @@ void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb, char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", features); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -1795,7 +1802,7 @@ void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb, void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (bta_hf_client_cb_arr.is_support_lc3) { buf = "AT+BAC=1,2,3\r"; @@ -1810,11 +1817,11 @@ void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) { char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -1825,7 +1832,7 @@ void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) { const char* buf; tBTA_HF_CLIENT_AT_CMD cmd; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (status) { buf = "AT+CIND?\r"; @@ -1841,7 +1848,7 @@ void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) { void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb, bool activate) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (activate) buf = "AT+CMER=3,0,0,1\r"; @@ -1856,7 +1863,7 @@ void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd, char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (idx > 0) at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%u\r", cmd, idx); @@ -1864,7 +1871,7 @@ void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd, at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -1875,7 +1882,7 @@ void bta_hf_client_send_at_bind(tBTA_HF_CLIENT_CB* client_cb, int step) { std::string buf; tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIND_SET_IND; - LOG_VERBOSE("%s", __func__); + log::verbose(""); switch (step) { case 0: // List HF supported indicators @@ -1907,16 +1914,16 @@ void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int indicator_id, tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIEV; if ((client_cb->peer_features & BTA_HF_CLIENT_FEAT_HF_IND) == 0) { - LOG_ERROR("%s peer does not support HF Indicators", __func__); + log::error("peer does not support HF Indicators"); return; } if (client_cb->enabled_hf_indicators.count(indicator_id) <= 0) { - LOG_ERROR("%s HF indicators %d is disabled", __func__, indicator_id); + log::error("HF indicators {} is disabled", indicator_id); return; } - LOG_VERBOSE("%s", __func__); + log::verbose(""); int len = sprintf(buf, "AT+BIEV=%d,%d\r", indicator_id, indicator_value); @@ -1926,7 +1933,7 @@ void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int indicator_id, void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (activate) buf = "AT+CLIP=1\r"; @@ -1939,7 +1946,7 @@ void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) { void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (activate) buf = "AT+CCWA=1\r"; @@ -1952,7 +1959,7 @@ void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) { void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (activate) buf = "AT+CMEE=1\r"; @@ -1965,7 +1972,7 @@ void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) { void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (query) buf = "AT+COPS?\r"; @@ -1978,7 +1985,7 @@ void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) { void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); buf = "AT+CLCC\r"; @@ -1988,7 +1995,7 @@ void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) { void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb, bool enable) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (enable) buf = "AT+BVRA=1\r"; @@ -2002,11 +2009,11 @@ void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) { char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2017,11 +2024,11 @@ void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) { char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2033,7 +2040,7 @@ void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number, char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (number[0] != '\0') { at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number); @@ -2042,14 +2049,14 @@ void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number, } if (at_len < 0) { - LOG_ERROR("%s: error preparing ATD command", __func__); + log::error("error preparing ATD command"); return; } at_len = MIN((size_t)at_len, sizeof(buf)); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATD, buf, at_len); @@ -2058,7 +2065,7 @@ void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number, void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); buf = "AT+BLDN\r"; @@ -2068,7 +2075,7 @@ void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) { void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); buf = "ATA\r"; @@ -2078,7 +2085,7 @@ void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) { void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); buf = "AT+CHUP\r"; @@ -2090,7 +2097,7 @@ void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query, char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (query) { at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r"); @@ -2099,7 +2106,7 @@ void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query, } if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2110,12 +2117,12 @@ void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) { char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2125,7 +2132,7 @@ void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) { void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); buf = "AT+BCC\r"; @@ -2135,7 +2142,7 @@ void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) { void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); buf = "AT+CNUM\r"; @@ -2145,10 +2152,10 @@ void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) { void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb) { const char* buf; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!(client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_ECNR)) { - LOG_ERROR("%s: Remote does not support NREC.", __func__); + log::error("Remote does not support NREC."); return; } @@ -2161,12 +2168,12 @@ void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb, uint32_t action) { char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2178,9 +2185,9 @@ void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) { int at_len; int i; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (client_cb->peer_version < HFP_VERSION_1_6) { - LOG_VERBOSE("Remote does not Support AT+BIA"); + log::verbose("Remote does not Support AT+BIA"); return; } @@ -2206,7 +2213,7 @@ void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) { buf[at_len - 1] = '\r'; if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2217,12 +2224,12 @@ void bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB* client_cb, const char* str) { char buf[BTA_HF_CLIENT_AT_MAX_LEN]; - LOG_VERBOSE("%s", __func__); + log::verbose(""); int at_len = snprintf(buf, sizeof(buf), "AT%s", str); if (at_len < 1) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2237,11 +2244,11 @@ void bta_hf_client_send_at_android(tBTA_HF_CLIENT_CB* client_cb, char buf[BTA_HF_CLIENT_AT_MAX_LEN]; int at_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); at_len = snprintf(buf, sizeof(buf), "AT%s\r", str); if (at_len < 0) { - LOG_ERROR("%s: AT command Framing error", __func__); + log::error("AT command Framing error"); return; } @@ -2278,15 +2285,14 @@ void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (!client_cb) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } tBTA_HF_CLIENT_DATA_VAL* p_val = (tBTA_HF_CLIENT_DATA_VAL*)p_data; char buf[BTA_HF_CLIENT_AT_MAX_LEN]; - LOG_VERBOSE("%s: at cmd: %d", __func__, p_val->uint8_val); + log::verbose("at cmd: {}", p_val->uint8_val); switch (p_val->uint8_val) { case BTA_HF_CLIENT_AT_CMD_VTS: bta_hf_client_send_at_vts(client_cb, (char)p_val->uint32_val1); @@ -2351,11 +2357,11 @@ void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) { bta_hf_client_send_at_android(client_cb, p_val->str); break; default: - LOG_ERROR("Default case"); + log::error("Default case"); snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN, "Cmd %d 1st arg %u 2nd arg %u string arg %s", p_val->uint8_val, p_val->uint32_val1, p_val->uint32_val2, p_val->str); - LOG_ERROR("%s: AT buffer: %s ", __func__, buf); + log::error("AT buffer: {}", buf); break; } } diff --git a/system/bta/hf_client/bta_hf_client_main.cc b/system/bta/hf_client/bta_hf_client_main.cc index ad6f241e4e36bcb2115916cc67e2e0c01f1e4d7a..3f0fde6f079ff775c2c1efae444becf403c11b73 100644 --- a/system/bta/hf_client/bta_hf_client_main.cc +++ b/system/bta/hf_client/bta_hf_client_main.cc @@ -18,6 +18,7 @@ ******************************************************************************/ #include +#include #include #include @@ -33,6 +34,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; static const char* bta_hf_client_evt_str(uint16_t event); static const char* bta_hf_client_state_str(uint8_t state); @@ -300,7 +302,7 @@ void bta_hf_client_cb_arr_init() { * ******************************************************************************/ void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); // Free any memory we need to explicity release alarm_free(client_cb->collision_timer); @@ -330,7 +332,7 @@ void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) { * ******************************************************************************/ void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* resume opening process. */ if (client_cb->state == BTA_HF_CLIENT_INIT_ST) { @@ -353,7 +355,7 @@ void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) { * ******************************************************************************/ static void bta_hf_client_collision_timer_cback(void* data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data; /* If the peer haven't opened connection, restart opening process */ @@ -377,12 +379,12 @@ void bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) { if (id == BTA_ID_SYS) /* ACL collision */ { - LOG_WARN("HF Client found collision (ACL) ..."); + log::warn("HF Client found collision (ACL) ..."); } else if (id == BTA_ID_HS) /* RFCOMM collision */ { - LOG_WARN("HF Client found collision (RFCOMM) ..."); + log::warn("HF Client found collision (RFCOMM) ..."); } else { - LOG_WARN("HF Client found collision (\?\?\?) ..."); + log::warn("HF Client found collision (\?\?\?) ..."); } client_cb->state = BTA_HF_CLIENT_INIT_ST; @@ -420,7 +422,7 @@ tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback, const char* p_service_name) { /* If already registered then return error */ if (bta_sys_is_register(BTA_ID_HS)) { - LOG_ERROR("BTA HF Client is already enabled, ignoring ..."); + log::error("BTA HF Client is already enabled, ignoring ..."); return BTA_FAILURE; } @@ -472,8 +474,8 @@ tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback, tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) { // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) { - LOG_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1, - HF_CLIENT_MAX_DEVICES, handle); + log::error("handle out of range ({}, {}) {}", 1, HF_CLIENT_MAX_DEVICES, + handle); return NULL; } @@ -481,7 +483,7 @@ tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) { if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated) return &(bta_hf_client_cb_arr.cb[handle - 1]); - LOG_ERROR("%s: block not found for handle %d", __func__, handle); + log::error("block not found for handle {}", handle); return NULL; } @@ -506,11 +508,11 @@ tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const RawAddress& peer_addr) { if (client_cb->is_allocated && peer_addr == client_cb->peer_addr) { return client_cb; } else { - LOG_WARN("%s: bdaddr mismatch for handle %d alloc %d", __func__, i, - client_cb->is_allocated); + log::warn("bdaddr mismatch for handle {} alloc {}", i, + client_cb->is_allocated); } } - LOG_ERROR("%s: block not found", __func__); + log::error("block not found"); return NULL; } @@ -533,18 +535,18 @@ tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) { bool is_allocated = client_cb->is_allocated; uint16_t conn_handle = client_cb->conn_handle; - LOG_VERBOSE("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__, - handle, is_allocated, conn_handle); + log::verbose("cb rfc_handle {} alloc {} conn_handle {}", handle, + is_allocated, conn_handle); if (is_allocated && conn_handle == handle) { return client_cb; } - LOG_WARN("%s: no cb yet %d alloc %d conn_handle %d", __func__, handle, - is_allocated, conn_handle); + log::warn("no cb yet {} alloc {} conn_handle {}", handle, is_allocated, + conn_handle); } - LOG_ERROR("%s: no cb found for rfc handle %d", __func__, handle); + log::error("no cb found for rfc handle {}", handle); return NULL; } @@ -568,7 +570,7 @@ tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) { return client_cb; } } - LOG_ERROR("%s: block not found for handle %d", __func__, handle); + log::error("block not found for handle {}", handle); return NULL; } @@ -593,8 +595,7 @@ bool bta_hf_client_allocate_handle(const RawAddress& bd_addr, uint16_t* p_handle) { tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr); if (existing_cb != NULL) { - LOG_ERROR("%s: cannot allocate handle since BDADDR already exists", - __func__); + log::error("cannot allocate handle since BDADDR already exists"); return false; } /* Check that we do not have a request to for same device in the control @@ -602,7 +603,7 @@ bool bta_hf_client_allocate_handle(const RawAddress& bd_addr, for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i]; if (client_cb->is_allocated) { - LOG_WARN("%s: control block already used index %d", __func__, i); + log::warn("control block already used index {}", i); continue; } @@ -610,8 +611,7 @@ bool bta_hf_client_allocate_handle(const RawAddress& bd_addr, bta_hf_client_cb_init(client_cb, client_cb->handle); *p_handle = client_cb->handle; - LOG_VERBOSE("%s: marking CB handle %d to true", __func__, - client_cb->handle); + log::verbose("marking CB handle {} to true", client_cb->handle); client_cb->is_allocated = true; client_cb->peer_addr = bd_addr; @@ -620,7 +620,7 @@ bool bta_hf_client_allocate_handle(const RawAddress& bd_addr, } return false; - LOG_ERROR("%s: all control blocks in use!", __func__); + log::error("all control blocks in use!"); } /******************************************************************************* @@ -651,7 +651,7 @@ void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) { ******************************************************************************/ void bta_hf_client_api_disable() { if (!bta_sys_is_register(BTA_ID_HS)) { - LOG_WARN("BTA HF Client is already disabled, ignoring ..."); + log::warn("BTA HF Client is already disabled, ignoring ..."); return; } @@ -688,8 +688,8 @@ void bta_hf_client_api_disable() { * ******************************************************************************/ bool bta_hf_client_hdl_event(const BT_HDR_RIGID* p_msg) { - LOG_VERBOSE("%s: %s (0x%x)", __func__, bta_hf_client_evt_str(p_msg->event), - p_msg->event); + log::verbose("{} (0x{:x})", bta_hf_client_evt_str(p_msg->event), + p_msg->event); bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg); return true; } @@ -708,8 +708,7 @@ void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -723,14 +722,14 @@ void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) { /* Ignore displaying of AT results when not connected (Ignored in state * machine) */ if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) { - LOG_VERBOSE("HF Client evt : State %d (%s), Event 0x%04x (%s)", - client_cb->state, bta_hf_client_state_str(client_cb->state), - event, bta_hf_client_evt_str(event)); + log::verbose("HF Client evt : State {} ({}), Event 0x{:04x} ({})", + client_cb->state, bta_hf_client_state_str(client_cb->state), + event, bta_hf_client_evt_str(event)); } event &= 0x00FF; if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) { - LOG_ERROR("HF Client evt out of range, ignoring..."); + log::error("HF Client evt out of range, ignoring..."); return; } @@ -752,15 +751,15 @@ void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) { /* If the state has changed then notify the app of the corresponding change */ if (in_state != client_cb->state) { - VLOG(1) << __func__ << ": notifying state change to " << in_state << " -> " - << client_cb->state << " device " << client_cb->peer_addr; + log::verbose("notifying state change to {} -> {} device {}", in_state, + client_cb->state, + ADDRESS_TO_LOGGABLE_STR(client_cb->peer_addr)); tBTA_HF_CLIENT evt; memset(&evt, 0, sizeof(evt)); evt.bd_addr = client_cb->peer_addr; if (client_cb->state == BTA_HF_CLIENT_INIT_ST) { bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt); - LOG_VERBOSE("%s: marking CB handle %d to false", __func__, - client_cb->handle); + log::verbose("marking CB handle {} to false", client_cb->handle); client_cb->is_allocated = false; } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) { evt.open.handle = client_cb->handle; @@ -768,10 +767,11 @@ void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) { } } - VLOG(2) << __func__ << ": device " << client_cb->peer_addr - << "state change: [" << bta_hf_client_state_str(in_state) << "] -> [" - << bta_hf_client_state_str(client_cb->state) << "] after Event [" - << bta_hf_client_evt_str(in_event) << "]"; + log::verbose("device {} state change: [{}] -> [{}] after Event [{}]", + ADDRESS_TO_LOGGABLE_STR(client_cb->peer_addr), + bta_hf_client_state_str(in_state), + bta_hf_client_state_str(client_cb->state), + bta_hf_client_evt_str(in_event)); } static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) { @@ -799,12 +799,12 @@ static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) { * ******************************************************************************/ void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) { - LOG_VERBOSE("bta_hf_client_slc_seq cmd: %u", client_cb->at_cb.current_cmd); + log::verbose("bta_hf_client_slc_seq cmd: {}", client_cb->at_cb.current_cmd); if (error) { /* SLC establishment error, sent close rfcomm event */ - LOG_ERROR( - "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)", + log::error( + "HFPClient: Failed to create SLC due to AT error, disconnecting ({})", client_cb->at_cb.current_cmd); tBTA_HF_CLIENT_DATA msg; @@ -814,8 +814,7 @@ void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) { } if (client_cb->svc_conn) { - LOG_WARN("%s: SLC already connected for CB handle %d", __func__, - client_cb->handle); + log::warn("SLC already connected for CB handle {}", client_cb->handle); return; } @@ -890,9 +889,9 @@ void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) { default: { /* If happen there is a bug in SLC creation procedure... */ - LOG_ERROR( + log::error( "HFPClient: Failed to create SLCdue to unexpected AT command, " - "disconnecting (%u)", + "disconnecting ({})", client_cb->at_cb.current_cmd); tBTA_HF_CLIENT_DATA msg; diff --git a/system/bta/hf_client/bta_hf_client_rfc.cc b/system/bta/hf_client/bta_hf_client_rfc.cc index 1ead6ba3bf3086da488b7276019623e6f04ef187..b61ebb48e1a3fe4deeae025bd5cc979ef99ee1ce 100644 --- a/system/bta/hf_client/bta_hf_client_rfc.cc +++ b/system/bta/hf_client/bta_hf_client_rfc.cc @@ -25,6 +25,7 @@ ******************************************************************************/ #include +#include #include @@ -38,6 +39,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; /******************************************************************************* * @@ -56,7 +58,7 @@ static void bta_hf_client_port_cback(UNUSED_ATTR uint32_t code, tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_rfc_handle(port_handle); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, port_handle); + log::error("cb not found for handle {}", port_handle); return; } @@ -81,13 +83,13 @@ static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_rfc_handle(port_handle); - LOG_VERBOSE("%s: code = %d, port_handle = %d serv = %d", __func__, code, - port_handle, bta_hf_client_cb_arr.serv_handle); + log::verbose("code = {}, port_handle = {} serv = {}", code, port_handle, + bta_hf_client_cb_arr.serv_handle); /* ignore close event for port handles other than connected handle */ if (code != PORT_SUCCESS && client_cb != NULL && port_handle != client_cb->conn_handle) { - LOG_VERBOSE("bta_hf_client_mgmt_cback ignoring handle:%d", port_handle); + log::verbose("bta_hf_client_mgmt_cback ignoring handle:{}", port_handle); return; } @@ -100,13 +102,13 @@ static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) { } else if (port_handle == bta_hf_client_cb_arr.serv_handle) { p_buf->hdr.event = BTA_HF_CLIENT_RFC_OPEN_EVT; - LOG_VERBOSE("%s: allocating a new CB for incoming connection", __func__); + log::verbose("allocating a new CB for incoming connection"); // Find the BDADDR of the peer device RawAddress peer_addr = RawAddress::kEmpty; uint16_t lcid = 0; int status = PORT_CheckConnection(port_handle, &peer_addr, &lcid); if (status != PORT_SUCCESS) { - LOG(ERROR) << __func__ << ": PORT_CheckConnection returned " << status; + log::error("PORT_CheckConnection returned {}", status); } // Since we accepted a remote request we should allocate a handle first. @@ -116,7 +118,7 @@ static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) { // If allocation fails then we abort. if (client_cb == NULL) { - LOG_ERROR("%s: error allocating a new handle", __func__); + log::error("error allocating a new handle"); p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT; RFCOMM_RemoveConnection(port_handle); } else { @@ -130,15 +132,14 @@ static void bta_hf_client_mgmt_cback(uint32_t code, uint16_t port_handle) { bta_hf_client_start_server(); } } else { - LOG_ERROR("%s: PORT_SUCCESS, ignoring handle = %d", __func__, - port_handle); + log::error("PORT_SUCCESS, ignoring handle = {}", port_handle); osi_free(p_buf); return; } } else if (client_cb != NULL && port_handle == client_cb->conn_handle) { /* code != PORT_SUC */ - LOG(ERROR) << __func__ << ": closing port handle " << port_handle << "dev " - << client_cb->peer_addr; + log::error("closing port handle {} dev {}", port_handle, + ADDRESS_TO_LOGGABLE_STR(client_cb->peer_addr)); RFCOMM_RemoveServer(port_handle); p_buf->hdr.event = BTA_HF_CLIENT_RFC_CLOSE_EVT; @@ -181,8 +182,8 @@ void bta_hf_client_start_server() { int port_status; if (bta_hf_client_cb_arr.serv_handle > 0) { - LOG_VERBOSE("%s: already started, handle: %d", __func__, - bta_hf_client_cb_arr.serv_handle); + log::verbose("already started, handle: {}", + bta_hf_client_cb_arr.serv_handle); return; } @@ -191,14 +192,13 @@ void bta_hf_client_start_server() { BTA_HF_CLIENT_MTU, RawAddress::kAny, &(bta_hf_client_cb_arr.serv_handle), bta_hf_client_mgmt_cback, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); - LOG_VERBOSE("%s: started rfcomm server with handle %d", __func__, - bta_hf_client_cb_arr.serv_handle); + log::verbose("started rfcomm server with handle {}", + bta_hf_client_cb_arr.serv_handle); if (port_status == PORT_SUCCESS) { bta_hf_client_setup_port(bta_hf_client_cb_arr.serv_handle); } else { - LOG_VERBOSE("%s: RFCOMM_CreateConnection returned error:%d", __func__, - port_status); + log::verbose("RFCOMM_CreateConnection returned error:{}", port_status); } } @@ -213,10 +213,10 @@ void bta_hf_client_start_server() { * ******************************************************************************/ void bta_hf_client_close_server() { - LOG_VERBOSE("%s: %d", __func__, bta_hf_client_cb_arr.serv_handle); + log::verbose("{}", bta_hf_client_cb_arr.serv_handle); if (bta_hf_client_cb_arr.serv_handle == 0) { - LOG_VERBOSE("%s: already stopped", __func__); + log::verbose("already stopped"); return; } @@ -238,8 +238,7 @@ void bta_hf_client_rfc_do_open(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } @@ -249,8 +248,8 @@ void bta_hf_client_rfc_do_open(tBTA_HF_CLIENT_DATA* p_data) { bta_hf_client_mgmt_cback, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT) == PORT_SUCCESS) { bta_hf_client_setup_port(client_cb->conn_handle); - LOG_VERBOSE("bta_hf_client_rfc_do_open : conn_handle = %d", - client_cb->conn_handle); + log::verbose("bta_hf_client_rfc_do_open : conn_handle = {}", + client_cb->conn_handle); } /* RFCOMM create connection failed; send ourselves RFCOMM close event */ else { @@ -272,8 +271,7 @@ void bta_hf_client_rfc_do_close(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } diff --git a/system/bta/hf_client/bta_hf_client_sco.cc b/system/bta/hf_client/bta_hf_client_sco.cc index e7d7ec3b64c8548195abc3cb9dacd004cd087a23..a7439e4b16b041c74aa9b5eb69078b784da85119 100644 --- a/system/bta/hf_client/bta_hf_client_sco.cc +++ b/system/bta/hf_client/bta_hf_client_sco.cc @@ -17,6 +17,8 @@ * ******************************************************************************/ +#include + #include #include "bta/hf_client/bta_hf_client_int.h" @@ -29,6 +31,8 @@ (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \ ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5) +using namespace bluetooth; + enum { BTA_HF_CLIENT_SCO_LISTEN_E, BTA_HF_CLIENT_SCO_OPEN_E, /* open request */ @@ -51,13 +55,12 @@ static bool bta_hf_client_sco_remove(tBTA_HF_CLIENT_CB* client_cb) { bool removed_started = false; tBTM_STATUS status; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (client_cb->sco_idx != BTM_INVALID_SCO_INDEX) { status = BTM_RemoveSco(client_cb->sco_idx); - LOG_VERBOSE("%s: idx 0x%04x, status:0x%x", __func__, client_cb->sco_idx, - status); + log::verbose("idx 0x{:04x}, status:0x{:x}", client_cb->sco_idx, status); if (status == BTM_CMD_STARTED) { removed_started = true; @@ -105,7 +108,7 @@ static void bta_hf_client_sco_conn_rsp(tBTA_HF_CLIENT_CB* client_cb, enh_esco_params_t resp; uint8_t hci_status = HCI_SUCCESS; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (client_cb->sco_state == BTA_HF_CLIENT_SCO_LISTEN_ST) { if (p_data->link_type == BTM_LINK_TYPE_SCO) { @@ -146,13 +149,13 @@ static void bta_hf_client_sco_conn_rsp(tBTA_HF_CLIENT_CB* client_cb, ******************************************************************************/ static void bta_hf_client_esco_connreq_cback(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA* p_data) { - LOG_VERBOSE("%s: %d", __func__, event); + log::verbose("{}", event); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_sco_handle(p_data->conn_evt.sco_inx); if (client_cb == NULL) { - LOG_ERROR("%s: wrong SCO handle to control block %d", __func__, - p_data->conn_evt.sco_inx); + log::error("wrong SCO handle to control block {}", + p_data->conn_evt.sco_inx); return; } @@ -176,11 +179,11 @@ static void bta_hf_client_esco_connreq_cback(tBTM_ESCO_EVT event, * ******************************************************************************/ static void bta_hf_client_sco_conn_cback(uint16_t sco_idx) { - LOG_VERBOSE("%s: %d", __func__, sco_idx); + log::verbose("{}", sco_idx); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_sco_handle(sco_idx); if (client_cb == NULL) { - LOG_ERROR("%s: wrong SCO handle to control block %d", __func__, sco_idx); + log::error("wrong SCO handle to control block {}", sco_idx); return; } @@ -201,11 +204,11 @@ static void bta_hf_client_sco_conn_cback(uint16_t sco_idx) { * ******************************************************************************/ static void bta_hf_client_sco_disc_cback(uint16_t sco_idx) { - LOG_VERBOSE("%s: sco_idx %d", __func__, sco_idx); + log::verbose("sco_idx {}", sco_idx); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_sco_handle(sco_idx); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, sco_idx); + log::error("wrong handle to control block {}", sco_idx); return; } @@ -229,11 +232,11 @@ static void bta_hf_client_sco_create(tBTA_HF_CLIENT_CB* client_cb, bool is_orig) { tBTM_STATUS status; - LOG_VERBOSE("%s: %d", __func__, is_orig); + log::verbose("{}", is_orig); /* Make sure this SCO handle is not already in use */ if (client_cb->sco_idx != BTM_INVALID_SCO_INDEX) { - LOG_WARN("%s: Index 0x%04x already in use", __func__, client_cb->sco_idx); + log::warn("Index 0x{:04x} already in use", client_cb->sco_idx); return; } @@ -264,12 +267,11 @@ static void bta_hf_client_sco_create(tBTA_HF_CLIENT_CB* client_cb, if (status == BTM_CMD_STARTED && !is_orig) { if (!BTM_RegForEScoEvts(client_cb->sco_idx, bta_hf_client_esco_connreq_cback)) - LOG_VERBOSE("%s: SCO registration success", __func__); + log::verbose("SCO registration success"); } - LOG_VERBOSE("%s: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x", - __func__, is_orig, client_cb->sco_idx, status, - params.packet_types); + log::verbose("orig {}, inx 0x{:04x}, status 0x{:x}, pkt types 0x{:04x}", + is_orig, client_cb->sco_idx, status, params.packet_types); } /******************************************************************************* @@ -284,8 +286,7 @@ static void bta_hf_client_sco_create(tBTA_HF_CLIENT_CB* client_cb, ******************************************************************************/ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, uint8_t event) { - LOG_VERBOSE("%s: before state: %d event: %d", __func__, client_cb->sco_state, - event); + log::verbose("before state: {} event: {}", client_cb->sco_state, event); switch (client_cb->sco_state) { case BTA_HF_CLIENT_SCO_SHUTDOWN_ST: @@ -310,7 +311,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("BTA_HF_CLIENT_SCO_SHUTDOWN_ST: Ignoring event %d", event); + log::warn("BTA_HF_CLIENT_SCO_SHUTDOWN_ST: Ignoring event {}", event); break; } break; @@ -345,8 +346,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("%s: BTA_HF_CLIENT_SCO_LISTEN_ST: Ignoring event %d", - __func__, event); + log::warn("BTA_HF_CLIENT_SCO_LISTEN_ST: Ignoring event {}", event); break; } break; @@ -372,7 +372,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("BTA_HF_CLIENT_SCO_OPENING_ST: Ignoring event %d", event); + log::warn("BTA_HF_CLIENT_SCO_OPENING_ST: Ignoring event {}", event); break; } break; @@ -401,7 +401,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("BTA_HF_CLIENT_SCO_OPEN_CL_ST: Ignoring event %d", event); + log::warn("BTA_HF_CLIENT_SCO_OPEN_CL_ST: Ignoring event {}", event); break; } break; @@ -428,7 +428,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("BTA_HF_CLIENT_SCO_OPEN_ST: Ignoring event %d", event); + log::warn("BTA_HF_CLIENT_SCO_OPEN_ST: Ignoring event {}", event); break; } break; @@ -450,7 +450,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("BTA_HF_CLIENT_SCO_CLOSING_ST: Ignoring event %d", event); + log::warn("BTA_HF_CLIENT_SCO_CLOSING_ST: Ignoring event {}", event); break; } break; @@ -472,7 +472,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("BTA_HF_CLIENT_SCO_CLOSE_OP_ST: Ignoring event %d", event); + log::warn("BTA_HF_CLIENT_SCO_CLOSE_OP_ST: Ignoring event {}", event); break; } break; @@ -493,7 +493,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; default: - LOG_WARN("BTA_HF_CLIENT_SCO_SHUTTING_ST: Ignoring event %d", event); + log::warn("BTA_HF_CLIENT_SCO_SHUTTING_ST: Ignoring event {}", event); break; } break; @@ -502,7 +502,7 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, break; } - LOG_VERBOSE("%s: after state: %d", __func__, client_cb->sco_state); + log::verbose("after state: {}", client_cb->sco_state); } /******************************************************************************* @@ -516,13 +516,12 @@ static void bta_hf_client_sco_event(tBTA_HF_CLIENT_CB* client_cb, * ******************************************************************************/ void bta_hf_client_sco_listen(tBTA_HF_CLIENT_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, - p_data->hdr.layer_specific); + log::error("wrong handle to control block {}", p_data->hdr.layer_specific); return; } @@ -540,7 +539,7 @@ void bta_hf_client_sco_listen(tBTA_HF_CLIENT_DATA* p_data) { * ******************************************************************************/ void bta_hf_client_sco_shutdown(tBTA_HF_CLIENT_CB* client_cb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_SHUTDOWN_E); } @@ -556,13 +555,12 @@ void bta_hf_client_sco_shutdown(tBTA_HF_CLIENT_CB* client_cb) { * ******************************************************************************/ void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, - p_data->hdr.layer_specific); + log::error("wrong handle to control block {}", p_data->hdr.layer_specific); return; } @@ -590,13 +588,12 @@ void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA* p_data) { * ******************************************************************************/ void bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, - p_data->hdr.layer_specific); + log::error("wrong handle to control block {}", p_data->hdr.layer_specific); return; } @@ -629,13 +626,12 @@ void bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA* p_data) { * ******************************************************************************/ void bta_hf_client_sco_open(tBTA_HF_CLIENT_DATA* p_data) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, - p_data->hdr.layer_specific); + log::error("wrong handle to control block {}", p_data->hdr.layer_specific); return; } @@ -656,12 +652,11 @@ void bta_hf_client_sco_close(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: wrong handle to control block %d", __func__, - p_data->hdr.layer_specific); + log::error("wrong handle to control block {}", p_data->hdr.layer_specific); return; } - LOG_VERBOSE("%s: sco_idx 0x%x", __func__, client_cb->sco_idx); + log::verbose("sco_idx 0x{:x}", client_cb->sco_idx); if (client_cb->sco_idx != BTM_INVALID_SCO_INDEX) { bta_hf_client_sco_event(client_cb, BTA_HF_CLIENT_SCO_CLOSE_E); diff --git a/system/bta/hf_client/bta_hf_client_sdp.cc b/system/bta/hf_client/bta_hf_client_sdp.cc index 2abd0f60c748d4ddf3b9561938f1fe7688585a2d..91077f08af6dda8cfc28714cdc0a12c1ce56b92d 100644 --- a/system/bta/hf_client/bta_hf_client_sdp.cc +++ b/system/bta/hf_client/bta_hf_client_sdp.cc @@ -24,12 +24,15 @@ * ******************************************************************************/ +#include + #include #include "bta/hf_client/bta_hf_client_int.h" #include "bta/include/bta_hf_client_api.h" #include "bta/include/bta_rfcomm_scn.h" #include "bta/sys/bta_sys.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -42,6 +45,7 @@ using bluetooth::Uuid; using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; /* Number of protocol elements in protocol element list. */ #define BTA_HF_CLIENT_NUM_PROTO_ELEMS 2 @@ -65,7 +69,7 @@ static void bta_hf_client_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, tBTA_HF_CLIENT_DISC_RESULT* p_buf = (tBTA_HF_CLIENT_DISC_RESULT*)osi_malloc( sizeof(tBTA_HF_CLIENT_DISC_RESULT)); - LOG_VERBOSE("bta_hf_client_sdp_cback status:0x%x", status); + log::verbose("bta_hf_client_sdp_cback status:0x{:x}", status); tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data; /* set event according to int/acp */ @@ -107,8 +111,8 @@ bool bta_hf_client_add_record(const char* p_service_name, uint8_t scn, uint8_t buf[2]; uint16_t sdp_features = 0; - LOG_VERBOSE("bta_hf_client_add_record"); - LOG_INFO("features: %d", features); + log::verbose("bta_hf_client_add_record"); + log::info("features: {}", features); memset(proto_elem_list, 0, BTA_HF_CLIENT_NUM_PROTO_ELEMS * sizeof(tSDP_PROTOCOL_ELEM)); @@ -211,7 +215,7 @@ void bta_hf_client_create_record(tBTA_HF_CLIENT_CB_ARR* client_cb_arr, * ******************************************************************************/ void bta_hf_client_del_record(tBTA_HF_CLIENT_CB_ARR* client_cb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (client_cb->sdp_handle != 0) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(client_cb->sdp_handle); @@ -298,8 +302,8 @@ bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) { break; } - LOG_VERBOSE("%s: peer_version=0x%x peer_features=0x%x", __func__, - client_cb->peer_version, client_cb->peer_features); + log::verbose("peer_version=0x{:x} peer_features=0x{:x}", + client_cb->peer_version, client_cb->peer_features); return result; } @@ -380,8 +384,7 @@ void bta_hf_client_free_db(tBTA_HF_CLIENT_DATA* p_data) { tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific); if (client_cb == NULL) { - LOG_ERROR("%s: cb not found for handle %d", __func__, - p_data->hdr.layer_specific); + log::error("cb not found for handle {}", p_data->hdr.layer_specific); return; } diff --git a/system/bta/hh/bta_hh_act.cc b/system/bta/hh/bta_hh_act.cc index 61afe29ec1e029b9d7671c8f113f1060574c3374..5eb496c7f3de69cc86ed74966d51805c822ce1b4 100644 --- a/system/bta/hh/bta_hh_act.cc +++ b/system/bta/hh/bta_hh_act.cc @@ -22,7 +22,9 @@ * ******************************************************************************/ -#define LOG_TAG "bluetooth" +#define LOG_TAG "bt_bta_hh" + +#include #include #include @@ -32,6 +34,7 @@ #include "bta/include/bta_hh_co.h" #include "bta/sys/bta_sys.h" #include "btif/include/btif_storage.h" +#include "include/check.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR @@ -46,6 +49,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; /***************************************************************************** * Constants @@ -117,7 +121,7 @@ void bta_hh_api_enable(tBTA_HH_CBACK* p_cback, bool enable_hid, bool enable_hogp tBTA_HH bta_hh; bta_hh.status = status; if (status != BTA_HH_OK) { - LOG_ERROR("Failed to register, status: %d", status); + log::error("Failed to register, status:{}", status); } if (bta_hh_cb.p_cback) { (*bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, &bta_hh); @@ -170,14 +174,14 @@ void bta_hh_api_disable(void) { * ******************************************************************************/ void bta_hh_disc_cmpl(void) { - LOG_DEBUG("Disconnect complete"); + log::debug("Disconnect complete"); tBTA_HH_STATUS status = BTA_HH_OK; /* Deregister with lower layer */ if (HID_HostDeregister() != HID_SUCCESS) status = BTA_HH_ERR; if (bta_hh_cb.gatt_if != BTA_GATTS_INVALID_IF) { - LOG_DEBUG("Deregister HOGP host before cleanup"); + log::debug("Deregister HOGP host before cleanup"); bta_hh_le_deregister(); } else { bta_hh_cleanup_disable(status); @@ -204,8 +208,8 @@ static void bta_hh_sdp_cback(uint16_t result, uint16_t attr_mask, /* security is required for the connection, add attr_mask bit*/ attr_mask |= HID_SEC_REQUIRED; - LOG_VERBOSE("%s: p_cb: %p result 0x%02x, attr_mask 0x%02x, handle %x", - __func__, p_cb, result, attr_mask, p_cb->hid_handle); + log::verbose("p_cb:{} result:0x{:02x}, attr_mask:0x{:02x}, handle:0x{:x}", + fmt::ptr(p_cb), result, attr_mask, p_cb->hid_handle); /* check to see type of device is supported , and should not been added * before */ @@ -213,7 +217,8 @@ static void bta_hh_sdp_cback(uint16_t result, uint16_t attr_mask, /* if not added before */ if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { /* add device/update attr_mask information */ - if (HID_HostAddDev(p_cb->addr, attr_mask, &hdl) == HID_SUCCESS) { + if (HID_HostAddDev(p_cb->link_spec.addrt.bda, attr_mask, &hdl) == + HID_SUCCESS) { status = BTA_HH_OK; /* update cb_index[] map */ bta_hh_cb.cb_index[hdl] = p_cb->index; @@ -266,7 +271,7 @@ static void bta_hh_di_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, tBTA_HH_STATUS status = BTA_HH_ERR_SDP; tSDP_DI_GET_RECORD di_rec; tHID_STATUS ret; - LOG_VERBOSE("%s: p_cb: %p result 0x%02x", __func__, p_cb, result); + log::verbose("p_cb:{} result:0x{:02x}", fmt::ptr(p_cb), result); /* if DI record does not exist on remote device, vendor_id in * tBTA_HH_DEV_DSCP_INFO will be set to 0xffff and we will allow the @@ -291,13 +296,12 @@ static void bta_hh_di_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0, 0); } - ret = HID_HostGetSDPRecord(p_cb->addr, bta_hh_cb.p_disc_db, + ret = HID_HostGetSDPRecord(p_cb->link_spec.addrt.bda, bta_hh_cb.p_disc_db, p_bta_hh_cfg->sdp_db_size, bta_hh_sdp_cback); if (ret == HID_SUCCESS) { status = BTA_HH_OK; } else { - LOG_VERBOSE("%s: HID_HostGetSDPRecord failed: Status 0x%2x", __func__, - ret); + log::verbose("failure Status 0x{:2x}", ret); } } @@ -330,13 +334,13 @@ static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { /* Do DI discovery first */ if (get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover( - p_data->api_conn.bd_addr, bta_hh_cb.p_disc_db, + p_data->api_conn.link_spec.addrt.bda, bta_hh_cb.p_disc_db, p_bta_hh_cfg->sdp_db_size, bta_hh_di_sdp_cback) == SDP_SUCCESS) { /* SDP search started successfully * Connection will be triggered at the end of successful SDP search */ } else { - LOG_ERROR("SDP_DiDiscover failed"); + log::error("SDP_DiDiscover failed"); osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); @@ -351,7 +355,7 @@ static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { * doing SDP. In such case, just do nothing and the ongoing SDP completion * or failure will handle this case. */ - LOG_WARN("Ignoring as SDP already in progress"); + log::warn("Ignoring as SDP already in progress"); } } @@ -372,12 +376,12 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { tBTA_HH_CONN conn_dat; tBTA_HH_STATUS status = p_data->status; - LOG_VERBOSE("%s: status 0x%2X", __func__, p_data->status); + log::verbose("status 0x{:2X}", p_data->status); /* initialize call back data */ memset((void*)&conn_dat, 0, sizeof(tBTA_HH_CONN)); conn_dat.handle = p_cb->hid_handle; - conn_dat.bda = p_cb->addr; + conn_dat.link_spec = p_cb->link_spec; /* if SDP compl success */ if (status == BTA_HH_OK) { @@ -387,17 +391,17 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { /* open HID connection */ ret = HID_HostOpenDev(p_cb->hid_handle); - LOG_VERBOSE("%s: HID_HostOpenDev returned=%d", __func__, ret); + log::verbose("HID_HostOpenDev returned={}", ret); if (ret == HID_SUCCESS || ret == HID_ERR_ALREADY_CONN) { status = BTA_HH_OK; } else if (ret == HID_ERR_CONN_IN_PROCESS) { /* Connection already in progress, return from here, SDP * will be performed after connection is completed. */ - LOG_VERBOSE("%s: connection already in progress", __func__); + log::verbose("connection already in progress"); return; } else { - LOG_VERBOSE("%s: HID_HostOpenDev failed: Status 0x%2X", __func__, ret); + log::verbose("HID_HostOpenDev failed: Status 0x{:2X}", ret); /* open fail, remove device from management device list */ HID_HostRemoveDev(p_cb->hid_handle); status = BTA_HH_ERR; @@ -416,8 +420,8 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { */ if ((status == BTA_HH_ERR_SDP) && (p_cb->incoming_conn) && (p_cb->app_id == 0)) { - LOG_ERROR("%s: SDP failed for incoming conn hndl: %d", __func__, - p_cb->incoming_hid_handle); + log::error("SDP failed for incoming conn hndl:{}", + p_cb->incoming_hid_handle); HID_HostRemoveDev(p_cb->incoming_hid_handle); } conn_dat.status = status; @@ -457,11 +461,12 @@ static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) tBTA_HH_DATA bta_hh_data; bta_hh_data.status = BTA_HH_OK; - LOG_VERBOSE("%s: skip SDP for known devices", __func__); + log::verbose("skip SDP for known devices"); if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { uint8_t hdl; - if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) { + if (HID_HostAddDev(p_cb->link_spec.addrt.bda, p_cb->attr_mask, &hdl) == + HID_SUCCESS) { /* update device CB with newly register device handle */ bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL, p_cb->sub_class, @@ -496,7 +501,7 @@ void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { bluetooth::Uuid remote_uuids[BT_MAX_NUM_UUIDS] = {}; bt_property_t remote_properties = {BT_PROPERTY_UUIDS, sizeof(remote_uuids), &remote_uuids}; - const RawAddress& bd_addr = p_data->api_conn.bd_addr; + const RawAddress& bd_addr = p_data->api_conn.link_spec.addrt.bda; // Find the device type tBT_DEVICE_TYPE dev_type; @@ -543,16 +548,18 @@ void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { p_cb->is_le_device = false; } - LOG_DEBUG("bd_addr:%s, bredr:%d, hid_available:%d, le_acl:%d, hogp_available:%d, " - "dev_type:%d, is_le_device:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bredr, - hid_available, le_acl, hogp_available, dev_type, p_cb->is_le_device); + log::debug( + "bd_addr:{}, bredr:{}, hid_available:{}, le_acl:{}, hogp_available:{}, " + "dev_type:{}, is_le_device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bredr, hid_available, le_acl, + hogp_available, dev_type, p_cb->is_le_device); p_cb->mode = p_data->api_conn.mode; bta_hh_cb.p_cur = p_cb; // Initiate HID host connection if (p_cb->is_le_device) { - bta_hh_le_open_conn(p_cb, bd_addr); + bta_hh_le_open_conn(p_cb, p_data->api_conn.link_spec); } else { bta_hh_bredr_conn(p_cb, p_data); } @@ -568,13 +575,13 @@ void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { * Returns void * ******************************************************************************/ -void btif_hh_remove_device(RawAddress bd_addr); +void btif_hh_remove_device(tAclLinkSpec link_spec); void bta_hh_api_disc_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { CHECK(p_cb != nullptr); if (p_cb->is_le_device) { - LOG_DEBUG("Host initiating close to le device:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->addr)); + log::debug("Host initiating close to le device:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec)); bta_hh_le_api_disc_act(p_cb); @@ -584,11 +591,12 @@ void bta_hh_api_disc_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { : p_cb->hid_handle; tHID_STATUS status = HID_HostCloseDev(hid_handle); if (status != HID_SUCCESS) { - LOG_WARN("Failed closing classic device:%s status:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->addr), hid_status_text(status).c_str()); + log::warn("Failed closing classic device:{} status:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec), + hid_status_text(status)); } else { - LOG_DEBUG("Host initiated close to classic device:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->addr)); + log::debug("Host initiated close to classic device:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec)); } tBTA_HH bta_hh = { .dev_status = {.status = @@ -616,7 +624,7 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { memset((void*)&conn, 0, sizeof(tBTA_HH_CONN)); conn.handle = dev_handle; - conn.bda = p_cb->addr; + conn.link_spec = p_cb->link_spec; /* increase connection number */ bta_hh_cb.cnt_num++; @@ -628,7 +636,7 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { conn.attr_mask = p_cb->attr_mask; conn.app_id = p_cb->app_id; - BTM_LogHistory(kBtmLogTag, p_cb->addr, "Opened", + BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Opened", base::StringPrintf( "%s initiator:%s", (p_cb->is_le_device) ? "le" : "classic", (p_cb->incoming_conn) ? "remote" : "local")); @@ -636,7 +644,7 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { if (!p_cb->is_le_device) { /* inform role manager */ - bta_sys_conn_open(BTA_ID_HH, p_cb->app_id, p_cb->addr); + bta_sys_conn_open(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); /* set protocol mode when not default report mode */ if (p_cb->mode != BTA_HH_PROTO_RPT_MODE) { @@ -673,7 +681,7 @@ void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { uint8_t dev_handle = p_data ? (uint8_t)p_data->hid_cback.hdr.layer_specific : p_cb->hid_handle; - LOG_VERBOSE("%s: Device[%d] connected", __func__, dev_handle); + log::verbose("Device[{}] connected", dev_handle); /* SDP has been done */ if (p_cb->app_id != 0) { @@ -688,7 +696,7 @@ void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { p_cb->incoming_hid_handle = dev_handle; memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN)); - conn_data.bd_addr = p_cb->addr; + conn_data.link_spec = p_cb->link_spec; bta_hh_cb.p_cur = p_cb; bta_hh_bredr_conn(p_cb, (tBTA_HH_DATA*)&conn_data); } @@ -712,7 +720,7 @@ void bta_hh_data_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { bta_hh_co_data((uint8_t)p_data->hid_cback.hdr.layer_specific, p_rpt, pdata->len, p_cb->mode, p_cb->sub_class, - p_cb->dscp_info.ctry_code, p_cb->addr, p_cb->app_id); + p_cb->dscp_info.ctry_code, p_cb->link_spec, p_cb->app_id); osi_free_and_reset((void**)&pdata); } @@ -728,8 +736,8 @@ void bta_hh_data_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { * ******************************************************************************/ void bta_hh_handsk_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { - LOG_VERBOSE("HANDSHAKE received for: event = %s data= %d", - bta_hh_get_w4_event(p_cb->w4_evt), p_data->hid_cback.data); + log::verbose("HANDSHAKE received for: event={} data={}", + bta_hh_get_w4_event(p_cb->w4_evt), p_data->hid_cback.data); tBTA_HH bta_hh; memset(&bta_hh, 0, sizeof(tBTA_HH)); @@ -766,7 +774,7 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { bta_hh.conn.status = p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK; bta_hh.conn.handle = p_cb->hid_handle; - bta_hh.conn.bda = p_cb->addr; + bta_hh.conn.link_spec = p_cb->link_spec; (*bta_hh_cb.p_cback)(p_cb->w4_evt, &bta_hh); bta_hh_trace_dev_db(); p_cb->w4_evt = 0; @@ -774,12 +782,12 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { default: /* unknow transaction handshake response */ - LOG_VERBOSE("unknown transaction type"); + log::verbose("unknown transaction type"); break; } /* transaction achknoledgement received, inform PM for mode change */ - bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr); + bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); return; } /******************************************************************************* @@ -797,8 +805,8 @@ void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { uint8_t* data = (uint8_t*)(pdata + 1) + pdata->offset; tBTA_HH_HSDATA hs_data; - LOG_VERBOSE("Ctrl DATA received w4: event[%s]", - bta_hh_get_w4_event(p_cb->w4_evt)); + log::verbose("Ctrl DATA received w4: event[{}]", + bta_hh_get_w4_event(p_cb->w4_evt)); if (pdata->len == 0) { p_cb->w4_evt = 0; osi_free_and_reset((void**)&pdata); @@ -819,10 +827,10 @@ void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { hs_data.rsp_data.proto_mode = ((*data) == HID_PAR_PROTOCOL_REPORT) ? BTA_HH_PROTO_RPT_MODE : BTA_HH_PROTO_BOOT_MODE; - LOG_VERBOSE("GET_PROTOCOL Mode = [%s]", - (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) - ? "Report" - : "Boot"); + log::verbose("GET_PROTOCOL Mode = [{}]", + (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) + ? "Report" + : "Boot"); break; /* should not expect control DATA for SET_ transaction */ case BTA_HH_SET_PROTO_EVT: @@ -832,14 +840,14 @@ void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { case BTA_HH_SET_IDLE_EVT: FALLTHROUGH_INTENDED; /* FALLTHROUGH */ default: - LOG_VERBOSE("invalid transaction type for DATA payload: 4_evt[%s]", - bta_hh_get_w4_event(p_cb->w4_evt)); + log::verbose("invalid transaction type for DATA payload:4_evt[{}]", + bta_hh_get_w4_event(p_cb->w4_evt)); break; } /* inform PM for mode change */ - bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr); - bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr); + bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); + bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); (*bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH*)&hs_data); @@ -866,7 +874,7 @@ void bta_hh_open_failure(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { conn_dat.handle = p_cb->hid_handle; conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR; - conn_dat.bda = p_cb->addr; + conn_dat.link_spec = p_cb->link_spec; HID_HostCloseDev(p_cb->hid_handle); /* Report OPEN fail event */ @@ -916,14 +924,14 @@ void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { base::StringPrintf("%s %s %s", (l2cap_conn_fail) ? "l2cap_conn_fail" : "", (l2cap_req_fail) ? "l2cap_req_fail" : "", (l2cap_cfg_fail) ? "l2cap_cfg_fail" : ""); - BTM_LogHistory(kBtmLogTag, p_cb->addr, "Closed", + BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Closed", base::StringPrintf("%s reason %s %s", (p_cb->is_le_device) ? "le" : "classic", hid_status_text(hid_status).c_str(), overlay_fail.c_str())); /* inform role manager */ - bta_sys_conn_close(BTA_ID_HH, p_cb->app_id, p_cb->addr); + bta_sys_conn_close(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); /* update total conn number */ bta_hh_cb.cnt_num--; @@ -994,17 +1002,18 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { switch (p_dev_info->sub_event) { case BTA_HH_ADD_DEV_EVT: /* add a device */ - dev_info.bda = p_dev_info->bda; + dev_info.link_spec = p_dev_info->link_spec; /* initialize callback data */ if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { - if (BTM_UseLeLink(p_data->api_conn.bd_addr)) { + if (BTM_UseLeLink(p_data->api_conn.link_spec.addrt.bda)) { p_cb->is_le_device = true; dev_info.handle = bta_hh_le_add_device(p_cb, p_dev_info); if (dev_info.handle != BTA_HH_INVALID_HANDLE) dev_info.status = BTA_HH_OK; } else - if (HID_HostAddDev(p_dev_info->bda, p_dev_info->attr_mask, + if (HID_HostAddDev(p_dev_info->link_spec.addrt.bda, + p_dev_info->attr_mask, &dev_handle) == HID_SUCCESS) { dev_info.handle = dev_handle; dev_info.status = BTA_HH_OK; @@ -1034,7 +1043,7 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { break; case BTA_HH_RMV_DEV_EVT: /* remove device */ dev_info.handle = (uint8_t)p_dev_info->hdr.layer_specific; - dev_info.bda = p_cb->addr; + dev_info.link_spec = p_cb->link_spec; if (p_cb->is_le_device) { bta_hh_le_remove_dev_bg_conn(p_cb); @@ -1052,7 +1061,7 @@ void bta_hh_maint_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { break; default: - LOG_VERBOSE("invalid command"); + log::verbose("invalid command"); break; } @@ -1095,7 +1104,7 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { p_data->api_sndcmd.rpt_id, p_data->api_sndcmd.p_data); if (status != HID_SUCCESS) { - LOG_ERROR("HID_HostWriteDev Error, status: %d", status); + log::error("HID_HostWriteDev Error, status:{}", status); if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL && p_data->api_sndcmd.t_type != HID_TRANS_DATA) { @@ -1124,9 +1133,10 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { }; (*bta_hh_cb.p_cback)(BTA_HH_VC_UNPLUG_EVT, &cbdata); } else { - LOG_ERROR("skipped executing callback in hid host error handling. " - "command type: %d, param: %d", p_data->api_sndcmd.t_type, - p_data->api_sndcmd.param); + log::error( + "skipped executing callback in hid host error handling. command " + "type:{}, param:{}", + p_data->api_sndcmd.t_type, p_data->api_sndcmd.param); } } else { switch (p_data->api_sndcmd.t_type) { @@ -1156,19 +1166,19 @@ void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { /* currently not expected */ case HID_TRANS_DATAC: default: - LOG_VERBOSE("%s: cmd type = %d", __func__, p_data->api_sndcmd.t_type); + log::verbose("cmd type={}", p_data->api_sndcmd.t_type); break; } /* if not control type transaction, notify PM for energy control */ if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) { /* inform PM for mode change */ - bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr); - bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr); + bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); + bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); } else if (api_sndcmd_param == BTA_HH_CTRL_SUSPEND) { - bta_sys_sco_close(BTA_ID_HH, p_cb->app_id, p_cb->addr); + bta_sys_sco_close(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); } else if (api_sndcmd_param == BTA_HH_CTRL_EXIT_SUSPEND) { - bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr); + bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->link_spec.addrt.bda); } } } @@ -1193,7 +1203,7 @@ static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr, uint16_t sm_event = BTA_HH_INVALID_EVT; uint8_t xx = 0; - LOG_VERBOSE("%s::HID_event [%s]", __func__, bta_hh_hid_event_name(event)); + log::verbose("HID_event [{}]", bta_hh_hid_event_name(event)); switch (event) { case HID_HDEV_EVT_OPEN: @@ -1234,7 +1244,9 @@ static void bta_hh_cback(uint8_t dev_handle, const RawAddress& addr, p_buf->hdr.event = sm_event; p_buf->hdr.layer_specific = (uint16_t)dev_handle; p_buf->data = data; - p_buf->addr = addr; + p_buf->link_spec.addrt.bda = addr; + p_buf->link_spec.addrt.type = BLE_ADDR_PUBLIC; + p_buf->link_spec.transport = BT_TRANSPORT_BR_EDR; p_buf->p_data = pdata; bta_sys_sendmsg(p_buf); diff --git a/system/bta/hh/bta_hh_api.cc b/system/bta/hh/bta_hh_api.cc index 660aca11ae0ab57c68f38b40c041a2952af19a91..7d2d45fcc9f1394baf9b561dc41cb36cc20caf30 100644 --- a/system/bta/hh/bta_hh_api.cc +++ b/system/bta/hh/bta_hh_api.cc @@ -24,17 +24,21 @@ #define LOG_TAG "bt_bta_hh" +#include + #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/hh/bta_hh_int.h" #include "bta/sys/bta_sys.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/bt_hdr.h" #include "stack/include/main_thread.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants ****************************************************************************/ @@ -107,7 +111,7 @@ void BTA_HhClose(uint8_t dev_handle) { * Returns void * ******************************************************************************/ -void BTA_HhOpen(const RawAddress& dev_bda) { +void BTA_HhOpen(const tAclLinkSpec& link_spec) { tBTA_HH_API_CONN* p_buf = (tBTA_HH_API_CONN*)osi_calloc(sizeof(tBTA_HH_API_CONN)); tBTA_HH_PROTO_MODE mode = BTA_HH_PROTO_RPT_MODE; @@ -115,7 +119,7 @@ void BTA_HhOpen(const RawAddress& dev_bda) { p_buf->hdr.event = BTA_HH_API_OPEN_EVT; p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE; p_buf->mode = mode; - p_buf->bd_addr = dev_bda; + p_buf->link_spec = link_spec; bta_sys_sendmsg((void*)p_buf); } @@ -244,7 +248,7 @@ void BTA_HhSendCtrl(uint8_t dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type) { * Description This function send DATA transaction to HID device. * * Parameter dev_handle: device handle - * dev_bda: remote device address + * link_spec : remote device acl link specification * p_data: data to be sent in the DATA transaction; or * the data to be write into the Output Report of a LE * HID device. The report is identified the report ID @@ -256,10 +260,10 @@ void BTA_HhSendCtrl(uint8_t dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type) { * Returns void * ******************************************************************************/ -void BTA_HhSendData(uint8_t dev_handle, UNUSED_ATTR const RawAddress& dev_bda, - BT_HDR* p_data) { +void BTA_HhSendData(uint8_t dev_handle, + UNUSED_ATTR const tAclLinkSpec& link_spec, BT_HDR* p_data) { if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT) { - LOG_ERROR( + log::error( "ERROR! Wrong report type! Write Command only valid for output " "report!"); return; @@ -298,7 +302,7 @@ void BTA_HhGetDscpInfo(uint8_t dev_handle) { * Returns void * ******************************************************************************/ -void BTA_HhAddDev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask, +void BTA_HhAddDev(const tAclLinkSpec& link_spec, tBTA_HH_ATTR_MASK attr_mask, uint8_t sub_class, uint8_t app_id, tBTA_HH_DEV_DSCP_INFO dscp_info) { size_t len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len; @@ -311,7 +315,7 @@ void BTA_HhAddDev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask, p_buf->attr_mask = (uint16_t)attr_mask; p_buf->sub_class = sub_class; p_buf->app_id = app_id; - p_buf->bda = bda; + p_buf->link_spec = link_spec; memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO)); if (dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list) { diff --git a/system/bta/hh/bta_hh_int.h b/system/bta/hh/bta_hh_int.h index de9f3cf2157a77554db952f1e3e64255c6be5b76..d769a4e4556ee1ba37369b78b0da80e2a8e31d52 100644 --- a/system/bta/hh/bta_hh_int.h +++ b/system/bta/hh/bta_hh_int.h @@ -25,6 +25,8 @@ #ifndef BTA_HH_INT_H #define BTA_HH_INT_H +#include + #include #include "bta/include/bta_api.h" @@ -82,21 +84,21 @@ typedef struct { typedef struct { BT_HDR_RIGID hdr; - RawAddress bd_addr; + tAclLinkSpec link_spec; tBTA_HH_PROTO_MODE mode; } tBTA_HH_API_CONN; /* internal event data from BTE HID callback */ typedef struct { BT_HDR_RIGID hdr; - RawAddress addr; + tAclLinkSpec link_spec; uint32_t data; BT_HDR* p_data; } tBTA_HH_CBACK_DATA; typedef struct { BT_HDR_RIGID hdr; - RawAddress bda; + tAclLinkSpec link_spec; uint16_t attr_mask; uint16_t sub_event; uint8_t sub_class; @@ -181,7 +183,7 @@ typedef struct { /* device control block */ typedef struct { tBTA_HH_DEV_DSCP_INFO dscp_info; /* report descriptor and DI information */ - RawAddress addr; /* BD-Addr of the HID device */ + tAclLinkSpec link_spec; /* ACL link specification of the HID device */ uint16_t attr_mask; /* attribute mask */ uint16_t w4_evt; /* W4_handshake event name */ uint8_t index; /* index number referenced to handle index */ @@ -266,8 +268,8 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); void bta_hh_open_failure(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); /* utility functions */ -uint8_t bta_hh_find_cb(const RawAddress& bda); -tBTA_HH_DEV_CB* bta_hh_get_cb(const RawAddress& bda); +uint8_t bta_hh_find_cb(const tAclLinkSpec& link_spec); +tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec); bool bta_hh_tod_spt(tBTA_HH_DEV_CB* p_cb, uint8_t sub_class); void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB* p_cb); @@ -289,14 +291,14 @@ void bta_hh_api_enable(tBTA_HH_CBACK* p_cback, bool enable_hid, void bta_hh_api_disable(void); void bta_hh_disc_cmpl(void); -tBTA_HH_STATUS bta_hh_read_ssr_param(const RawAddress& bd_addr, +tBTA_HH_STATUS bta_hh_read_ssr_param(const tAclLinkSpec& link_spec, uint16_t* p_max_ssr_lat, uint16_t* p_min_ssr_tout); /* functions for LE HID */ void bta_hh_le_enable(void); void bta_hh_le_deregister(void); -void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda); +void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const tAclLinkSpec& link_spec); void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB* p_cb); void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb); void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); @@ -317,4 +319,10 @@ void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB* p_cb, void bta_hh_trace_dev_db(void); #endif +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/bta/hh/bta_hh_le.cc b/system/bta/hh/bta_hh_le.cc index 9acf55cce7a82558260bf36622f9b39ad8eff03e..88f6a2d9da6fe517d7769dfdb8e51c5ec71f8031 100644 --- a/system/bta/hh/bta_hh_le.cc +++ b/system/bta/hh/bta_hh_le.cc @@ -16,10 +16,12 @@ * ******************************************************************************/ -#define LOG_TAG "bt_bta_hh" +#define LOG_TAG "ble_bta_hh" +#include #include #include +#include #include #include @@ -27,7 +29,9 @@ #include "bta/hh/bta_hh_int.h" #include "bta/include/bta_gatt_queue.h" #include "bta/include/bta_hh_co.h" +#include "bta/include/bta_le_audio_api.h" #include "device/include/interop.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // ARRAY_SIZE #include "stack/btm/btm_sec.h" // BTM_ @@ -43,6 +47,7 @@ using bluetooth::Uuid; using std::vector; +using namespace bluetooth; namespace { @@ -63,8 +68,7 @@ constexpr bool kBTA_HH_LE_RECONN = false; namespace { -constexpr char kBtmLogTag[] = "HIDH"; - +constexpr char kBtmLogTag[] = "LE HIDH"; } static const uint16_t bta_hh_uuid_to_rtp_type[BTA_LE_HID_RTP_UUID_MAX][2] = { @@ -79,6 +83,9 @@ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb); static void bta_hh_process_cache_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache, uint8_t num_rpt); +static bool bta_hh_le_iso_data_callback(const RawAddress& addr, + uint16_t cis_conn_hdl, uint8_t* data, + uint16_t size, uint32_t timestamp); static const char* bta_hh_le_rpt_name[4] = {"UNKNOWN", "INPUT", "OUTPUT", "FEATURE"}; @@ -94,7 +101,7 @@ static const char* bta_hh_le_rpt_name[4] = {"UNKNOWN", "INPUT", "OUTPUT", * ******************************************************************************/ static void bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB* p_cb) { - LOG_VERBOSE("%s: HID Report DB", __func__); + log::verbose("HID Report DB"); if (p_cb->hid_srvc.state < BTA_HH_SERVICE_DISCOVERED) return; @@ -110,9 +117,9 @@ static void bta_hh_le_hid_report_dbg(tBTA_HH_DEV_CB* p_cb) { if (p_rpt->uuid == GATT_UUID_HID_BT_KB_OUTPUT) rpt_name = "Boot KB Output"; if (p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) rpt_name = "Boot MI Input"; - LOG_VERBOSE( - "\t\t [%s- 0x%04x] [Type: %s], [ReportID: %d] [srvc_inst_id: %d] " - "[char_inst_id: %d] [Clt_cfg: %d]", + log::verbose( + "\t\t[{}-0x{:04x}] [Type:{}], [ReportID:{}] [srvc_inst_id:{}] " + "[char_inst_id:{}] [Clt_cfg:{}]", rpt_name, p_rpt->uuid, ((p_rpt->rpt_type < 4) ? bta_hh_le_rpt_name[p_rpt->rpt_type] : "UNKNOWN"), @@ -196,6 +203,10 @@ void bta_hh_le_enable(void) { (*bta_hh_cb.p_cback)(BTA_HH_ENABLE_EVT, &bta_hh); } }), false); + + if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + LeAudioClient::RegisterIsoDataConsumer(bta_hh_le_iso_data_callback); + } } /******************************************************************************* @@ -241,7 +252,7 @@ static uint8_t bta_hh_le_get_le_dev_hdl(uint8_t cb_index) { * Parameters: * ******************************************************************************/ -void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) { +void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const tAclLinkSpec& link_spec) { tBTA_HH_STATUS status = BTA_HH_ERR_NO_RES; /* update cb_index[] map */ @@ -251,12 +262,12 @@ void bta_hh_le_open_conn(tBTA_HH_DEV_CB* p_cb, const RawAddress& remote_bda) { return; } - p_cb->addr = remote_bda; + p_cb->link_spec = link_spec; bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index; p_cb->in_use = true; - BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, BTM_BLE_DIRECT_CONNECTION, - false); + BTA_GATTC_Open(bta_hh_cb.gatt_if, link_spec.addrt.bda, + BTM_BLE_DIRECT_CONNECTION, false); } /******************************************************************************* @@ -284,12 +295,15 @@ static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_conn_id(uint16_t conn_id) { * Description Utility function find a device control block by BD address. * ******************************************************************************/ -static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda(const RawAddress& bda) { +static tBTA_HH_DEV_CB* bta_hh_le_find_dev_cb_by_bda( + const tAclLinkSpec& link_spec) { uint8_t i; tBTA_HH_DEV_CB* p_dev_cb = &bta_hh_cb.kdev[0]; for (i = 0; i < BTA_HH_MAX_DEVICE; i++, p_dev_cb++) { - if (p_dev_cb->in_use && p_dev_cb->addr == bda) return p_dev_cb; + if (p_dev_cb->in_use && + p_dev_cb->link_spec.addrt.bda == link_spec.addrt.bda) + return p_dev_cb; } return NULL; } @@ -359,8 +373,7 @@ static tBTA_HH_LE_RPT* bta_hh_le_find_rpt_by_idtype(tBTA_HH_LE_RPT* p_head, tBTA_HH_LE_RPT* p_rpt = p_head; uint8_t i; - LOG_VERBOSE("bta_hh_le_find_rpt_by_idtype: r_type: %d rpt_id: %d", r_type, - rpt_id); + log::verbose("r_type:{} rpt_id:{}", r_type, rpt_id); for (i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) { if (p_rpt->in_use && p_rpt->rpt_id == rpt_id && r_type == p_rpt->rpt_type) { @@ -441,7 +454,7 @@ static const gatt::Descriptor* find_descriptor_by_short_uuid( BTA_GATTC_GetCharacteristic(conn_id, char_handle); if (!p_char) { - LOG_WARN("%s No such characteristic: %d", __func__, char_handle); + log::warn("No such characteristic:{}", char_handle); return NULL; } @@ -503,7 +516,7 @@ static void bta_hh_le_save_report_ref(tBTA_HH_DEV_CB* p_dev_cb, if (p_rpt->rpt_type > BTA_HH_RPTT_FEATURE) /* invalid report type */ p_rpt->rpt_type = BTA_HH_RPTT_RESRV; - LOG_VERBOSE("%s: report ID: %d", __func__, p_rpt->rpt_id); + log::verbose("report ID:{}", p_rpt->rpt_id); tBTA_HH_RPT_CACHE_ENTRY rpt_entry; rpt_entry.rpt_id = p_rpt->rpt_id; rpt_entry.rpt_type = p_rpt->rpt_type; @@ -511,7 +524,7 @@ static void bta_hh_le_save_report_ref(tBTA_HH_DEV_CB* p_dev_cb, rpt_entry.srvc_inst_id = p_rpt->srvc_inst_id; rpt_entry.char_inst_id = p_rpt->char_inst_id; - bta_hh_le_co_rpt_info(p_dev_cb->addr, &rpt_entry, p_dev_cb->app_id); + bta_hh_le_co_rpt_info(p_dev_cb->link_spec, &rpt_entry, p_dev_cb->app_id); } if (p_rpt->index < BTA_HH_LE_RPT_MAX - 1) @@ -535,45 +548,45 @@ static void bta_hh_le_register_input_notif(tBTA_HH_DEV_CB* p_dev_cb, bool register_ba) { tBTA_HH_LE_RPT* p_rpt = &p_dev_cb->hid_srvc.report[0]; - LOG_VERBOSE("%s: bta_hh_le_register_input_notif mode: %d", __func__, - proto_mode); + log::verbose("mode:{}", proto_mode); for (int i = 0; i < BTA_HH_LE_RPT_MAX; i++, p_rpt++) { if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) { if (register_ba && p_rpt->uuid == GATT_UUID_BATTERY_LEVEL) { - BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, + BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, + p_dev_cb->link_spec.addrt.bda, p_rpt->char_inst_id); } /* boot mode, deregister report input notification */ else if (proto_mode == BTA_HH_PROTO_BOOT_MODE) { if (p_rpt->uuid == GATT_UUID_HID_REPORT && p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { - LOG_VERBOSE("%s ---> Deregister Report ID: %d", __func__, - p_rpt->rpt_id); - BTA_GATTC_DeregisterForNotifications( - bta_hh_cb.gatt_if, p_dev_cb->addr, p_rpt->char_inst_id); + log::verbose("---> Deregister Report ID:{}", p_rpt->rpt_id); + BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, + p_dev_cb->link_spec.addrt.bda, + p_rpt->char_inst_id); } /* register boot reports notification */ else if (p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) { - LOG_VERBOSE("%s <--- Register Boot Report ID: %d", __func__, - p_rpt->rpt_id); - BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, + log::verbose("<--- Register Boot Report ID:{}", p_rpt->rpt_id); + BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, + p_dev_cb->link_spec.addrt.bda, p_rpt->char_inst_id); } } else if (proto_mode == BTA_HH_PROTO_RPT_MODE) { if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) && p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { - LOG_VERBOSE("%s ---> Deregister Boot Report ID: %d", __func__, - p_rpt->rpt_id); - BTA_GATTC_DeregisterForNotifications( - bta_hh_cb.gatt_if, p_dev_cb->addr, p_rpt->char_inst_id); + log::verbose("--> Deregister Boot Report ID:{}", p_rpt->rpt_id); + BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, + p_dev_cb->link_spec.addrt.bda, + p_rpt->char_inst_id); } else if (p_rpt->uuid == GATT_UUID_HID_REPORT && p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { - LOG_VERBOSE("%s <--- Register Report ID: %d", __func__, - p_rpt->rpt_id); - BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, + log::verbose("<--- Register Report ID:{}", p_rpt->rpt_id); + BTA_GATTC_RegisterForNotifications(bta_hh_cb.gatt_if, + p_dev_cb->link_spec.addrt.bda, p_rpt->char_inst_id); } } @@ -597,16 +610,16 @@ static void bta_hh_le_deregister_input_notif(tBTA_HH_DEV_CB* p_dev_cb) { if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT) { if (p_rpt->uuid == GATT_UUID_HID_REPORT && p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { - LOG_VERBOSE("%s ---> Deregister Report ID: %d", __func__, - p_rpt->rpt_id); - BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, + log::verbose("---> Deregister Report ID:{}", p_rpt->rpt_id); + BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, + p_dev_cb->link_spec.addrt.bda, p_rpt->char_inst_id); } else if ((p_rpt->uuid == GATT_UUID_HID_BT_KB_INPUT || p_rpt->uuid == GATT_UUID_HID_BT_MOUSE_INPUT) && p_rpt->client_cfg_value == GATT_CLT_CONFIG_NOTIFICATION) { - LOG_VERBOSE("%s ---> Deregister Boot Report ID: %d", __func__, - p_rpt->rpt_id); - BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, p_dev_cb->addr, + log::verbose("---> Deregister Boot Report ID:{}", p_rpt->rpt_id); + BTA_GATTC_DeregisterForNotifications(bta_hh_cb.gatt_if, + p_dev_cb->link_spec.addrt.bda, p_rpt->char_inst_id); } } @@ -684,7 +697,7 @@ static void write_rpt_ctl_cfg_cb(uint16_t conn_id, tGATT_STATUS status, break; default: - LOG_ERROR("Unknown char ID clt cfg: 0x%04x", char_uuid); + log::error("Unknown char ID clt cfg:0x{:04x}", char_uuid); } } /******************************************************************************* @@ -762,8 +775,8 @@ static bool bta_hh_le_set_protocol_mode(tBTA_HH_DEV_CB* p_cb, tBTA_HH_PROTO_MODE mode) { tBTA_HH_CBDATA cback_data; - LOG_VERBOSE("%s attempt mode: %s", __func__, - (mode == BTA_HH_PROTO_RPT_MODE) ? "Report" : "Boot"); + log::verbose("attempt mode:{}", + (mode == BTA_HH_PROTO_RPT_MODE) ? "Report" : "Boot"); cback_data.handle = p_cb->hid_handle; /* boot mode is not supported in the remote device */ @@ -771,7 +784,7 @@ static bool bta_hh_le_set_protocol_mode(tBTA_HH_DEV_CB* p_cb, p_cb->mode = BTA_HH_PROTO_RPT_MODE; if (mode == BTA_HH_PROTO_BOOT_MODE) { - LOG_ERROR("Set Boot Mode failed!! No PROTO_MODE Char!"); + log::error("Set Boot Mode failed!! No PROTO_MODE Char!"); cback_data.status = BTA_HH_ERR; } else { /* if set to report mode, need to de-register all input report @@ -829,9 +842,9 @@ static void get_protocol_mode_cb(uint16_t conn_id, tGATT_STATUS status, p_dev_cb->mode = hs_data.rsp_data.proto_mode; } - LOG_VERBOSE("LE GET_PROTOCOL Mode = [%s]", - (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) ? "Report" - : "Boot"); + log::verbose("LE GET_PROTOCOL Mode=[{}]", + (hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) ? "Report" + : "Boot"); p_dev_cb->w4_evt = 0; (*bta_hh_cb.p_cback)(BTA_HH_GET_PROTO_EVT, (tBTA_HH*)&hs_data); @@ -875,28 +888,32 @@ static void bta_hh_le_get_protocol_mode(tBTA_HH_DEV_CB* p_cb) { ******************************************************************************/ static void bta_hh_le_dis_cback(const RawAddress& addr, tDIS_VALUE* p_dis_value) { - tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(addr); + tAclLinkSpec link_spec; + link_spec.addrt.bda = addr; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_LE; + tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(link_spec); if (p_cb == nullptr) { - LOG_WARN("Unknown address"); + log::warn("Unknown address"); return; } if (p_cb->status == BTA_HH_ERR_SDP) { - LOG_WARN("HID service was not found"); + log::warn("HID service was not found"); return; } if (p_dis_value == nullptr) { - LOG_WARN("Invalid value"); + log::warn("Invalid value"); return; } p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS; /* plug in the PnP info for this device */ if (p_dis_value->attr_mask & DIS_ATTR_PNP_ID_BIT) { - LOG_VERBOSE( - "Plug in PnP info: product_id = %02x, vendor_id = %04x, version = %04x", + log::verbose( + "Plug in PnP info: product_id={:02x}, vendor_id={:04x}, version={:04x}", p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.vendor_id, p_dis_value->pnp_id.product_version); p_cb->dscp_info.product_id = p_dis_value->pnp_id.product_id; @@ -917,13 +934,14 @@ static void bta_hh_le_dis_cback(const RawAddress& addr, * ******************************************************************************/ static void bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB* p_cb) { - bta_hh_le_co_reset_rpt_cache(p_cb->addr, p_cb->app_id); + bta_hh_le_co_reset_rpt_cache(p_cb->link_spec, p_cb->app_id); p_cb->disc_active |= (BTA_HH_LE_DISC_HIDS | BTA_HH_LE_DISC_DIS); /* read DIS info */ - if (!DIS_ReadDISInfo(p_cb->addr, bta_hh_le_dis_cback, DIS_ATTR_PNP_ID_BIT)) { - LOG_ERROR("read DIS failed"); + if (!DIS_ReadDISInfo(p_cb->link_spec.addrt.bda, bta_hh_le_dis_cback, + DIS_ATTR_PNP_ID_BIT)) { + log::error("read DIS failed"); p_cb->disc_active &= ~BTA_HH_LE_DISC_DIS; } @@ -947,9 +965,14 @@ static void bta_hh_le_encrypt_cback(const RawAddress* bd_addr, UNUSED_ATTR tBT_TRANSPORT transport, UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) { - tBTA_HH_DEV_CB* p_dev_cb = bta_hh_get_cb(*bd_addr); + tAclLinkSpec link_spec; + link_spec.addrt.bda = *bd_addr; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = transport; + + tBTA_HH_DEV_CB* p_dev_cb = bta_hh_get_cb(link_spec); if (p_dev_cb == nullptr) { - LOG_ERROR("unexpected encryption callback, ignore"); + log::error("unexpected encryption callback, ignore"); return; } @@ -973,17 +996,18 @@ static void bta_hh_le_encrypt_cback(const RawAddress* bd_addr, ******************************************************************************/ void bta_hh_security_cmpl(tBTA_HH_DEV_CB* p_cb, UNUSED_ATTR const tBTA_HH_DATA* p_buf) { - LOG_VERBOSE("%s", __func__); + log::verbose("addr:{}, status:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec), + p_cb->status); if (p_cb->status == BTA_HH_OK) { if (p_cb->hid_srvc.state < BTA_HH_SERVICE_DISCOVERED) { - LOG_DEBUG("No reports loaded, try to load"); + log::debug("No reports loaded, try to load"); /* start loading the cache if not in stack */ tBTA_HH_RPT_CACHE_ENTRY* p_rpt_cache; uint8_t num_rpt = 0; - if ((p_rpt_cache = bta_hh_le_co_cache_load(p_cb->addr, &num_rpt, + if ((p_rpt_cache = bta_hh_le_co_cache_load(p_cb->link_spec, &num_rpt, p_cb->app_id)) != NULL) { - LOG_DEBUG("Cache found, no need to perform service discovery"); + log::debug("Cache found, no need to perform service discovery"); bta_hh_process_cache_rpt(p_cb, p_rpt_cache, num_rpt); } } @@ -991,7 +1015,7 @@ void bta_hh_security_cmpl(tBTA_HH_DEV_CB* p_cb, /* discovery has been done for HID service */ if (p_cb->app_id != 0 && p_cb->hid_srvc.state >= BTA_HH_SERVICE_DISCOVERED) { - LOG_VERBOSE("%s: discovery has been done for HID service", __func__); + log::verbose("discovery has been done for HID service"); /* configure protocol mode */ if (!bta_hh_le_set_protocol_mode(p_cb, p_cb->mode)) { bta_hh_le_open_cmpl(p_cb); @@ -999,19 +1023,19 @@ void bta_hh_security_cmpl(tBTA_HH_DEV_CB* p_cb, } /* start primary service discovery for HID service */ else { - LOG_VERBOSE("%s: Starting service discovery", __func__); + log::verbose("Starting service discovery"); bta_hh_le_pri_service_discovery(p_cb); } } else if(p_cb->btm_status == BTM_ERR_KEY_MISSING) { - LOG_ERROR("Received encryption failed status:%s btm_status:%s", - bta_hh_status_text(p_cb->status).c_str(), - btm_status_text(p_cb->btm_status).c_str()); + log::error("Received encryption failed status:{} btm_status:{}", + bta_hh_status_text(p_cb->status), + btm_status_text(p_cb->btm_status)); bta_hh_le_api_disc_act(p_cb); } else { - LOG_ERROR("Encryption failed status:%s btm_status:%s", - bta_hh_status_text(p_cb->status).c_str(), - btm_status_text(p_cb->btm_status).c_str()); + log::error("Encryption failed status:{} btm_status:{}", + bta_hh_status_text(p_cb->status), + btm_status_text(p_cb->btm_status)); if (!(p_cb->status == BTA_HH_ERR_SEC && (p_cb->btm_status == BTM_ERR_PROCESSING || p_cb->btm_status == BTM_FAILED_ON_SECURITY || @@ -1070,29 +1094,37 @@ static void bta_hh_clear_service_cache(tBTA_HH_DEV_CB* p_cb) { ******************************************************************************/ void bta_hh_start_security(tBTA_HH_DEV_CB* p_cb, UNUSED_ATTR const tBTA_HH_DATA* p_buf) { - if (BTM_SecIsSecurityPending(p_cb->addr)) { + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec.addrt.bda)); + if (BTM_SecIsSecurityPending(p_cb->link_spec.addrt.bda)) { /* if security collision happened, wait for encryption done */ p_cb->security_pending = true; return; } /* if link has been encrypted */ - if (BTM_IsEncrypted(p_cb->addr, BT_TRANSPORT_LE)) { + if (BTM_IsEncrypted(p_cb->link_spec.addrt.bda, BT_TRANSPORT_LE)) { + log::debug("addr:{} already encrypted", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec.addrt.bda)); p_cb->status = BTA_HH_OK; bta_hh_sm_execute(p_cb, BTA_HH_ENC_CMPL_EVT, NULL); } /* if bonded and link not encrypted */ - else if (BTM_IsLinkKeyKnown(p_cb->addr, BT_TRANSPORT_LE)) { + else if (BTM_IsLinkKeyKnown(p_cb->link_spec.addrt.bda, BT_TRANSPORT_LE)) { + log::debug("addr:{} bonded, not encrypted", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec.addrt.bda)); p_cb->status = BTA_HH_ERR_AUTH_FAILED; - BTM_SetEncryption(p_cb->addr, BT_TRANSPORT_LE, bta_hh_le_encrypt_cback, - NULL, BTM_BLE_SEC_ENCRYPT); + BTM_SetEncryption(p_cb->link_spec.addrt.bda, BT_TRANSPORT_LE, + bta_hh_le_encrypt_cback, NULL, BTM_BLE_SEC_ENCRYPT); } /* unbonded device, report security error here */ else { + log::debug("addr:{} not bonded", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec.addrt.bda)); p_cb->status = BTA_HH_ERR_AUTH_FAILED; bta_hh_clear_service_cache(p_cb); - BTM_SetEncryption(p_cb->addr, BT_TRANSPORT_LE, bta_hh_le_encrypt_cback, - NULL, BTM_BLE_SEC_ENCRYPT_NO_MITM); + BTM_SetEncryption(p_cb->link_spec.addrt.bda, BT_TRANSPORT_LE, + bta_hh_le_encrypt_cback, NULL, + BTM_BLE_SEC_ENCRYPT_NO_MITM); } } @@ -1107,16 +1139,12 @@ void bta_hh_start_security(tBTA_HH_DEV_CB* p_cb, ******************************************************************************/ void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_buf) { const tBTA_GATTC_OPEN* p_data = &p_buf->le_open; - const uint8_t* p2; /* if received invalid callback data , ignore it */ if (p_cb == NULL || p_data == NULL) return; - p2 = p_data->remote_bda.address; - - LOG_VERBOSE("bta_hh_gatt_open BTA_GATTC_OPEN_EVT bda= [%08x%04x] status =%d", - ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]), - ((p2[4]) << 8) + p2[5], p_data->status); + log::verbose("BTA_GATTC_OPEN_EVT bda={} status={}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda), p_data->status); if (p_data->status == GATT_SUCCESS) { p_cb->hid_handle = bta_hh_le_get_le_dev_hdl(p_cb->index); @@ -1133,8 +1161,8 @@ void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_buf) { BtaGattQueue::Clean(p_cb->conn_id); - LOG_VERBOSE("hid_handle = %2x conn_id = %04x cb_index = %d", - p_cb->hid_handle, p_cb->conn_id, p_cb->index); + log::verbose("hid_handle=0x{:2x} conn_id=0x{:04x} cb_index={}", + p_cb->hid_handle, p_cb->conn_id, p_cb->index); bta_hh_sm_execute(p_cb, BTA_HH_START_ENC_EVT, NULL); @@ -1155,17 +1183,22 @@ void bta_hh_gatt_open(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_buf) { * ******************************************************************************/ static void bta_hh_le_close(const tBTA_GATTC_CLOSE& gattc_data) { - tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(gattc_data.remote_bda); + tAclLinkSpec link_spec; + link_spec.addrt.bda = gattc_data.remote_bda; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_LE; + + tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(link_spec); if (p_cb == nullptr) { - LOG_WARN("Received close event with unknown device:%s", - ADDRESS_TO_LOGGABLE_CSTR(gattc_data.remote_bda)); + log::warn("unknown device:{}", + ADDRESS_TO_LOGGABLE_CSTR(gattc_data.remote_bda)); return; } if (p_cb->hid_srvc.state == BTA_HH_SERVICE_CHANGED) { /* Service change would have already prompted a local disconnection */ - LOG_WARN("Disconnected after service changed indication:%s", - ADDRESS_TO_LOGGABLE_CSTR(gattc_data.remote_bda)); + log::warn("Disconnected after service changed indication:{}", + ADDRESS_TO_LOGGABLE_CSTR(gattc_data.remote_bda)); return; } @@ -1201,7 +1234,7 @@ static void bta_hh_le_close(const tBTA_GATTC_CLOSE& gattc_data) { ******************************************************************************/ static void bta_hh_le_gatt_disc_cmpl(tBTA_HH_DEV_CB* p_cb, tBTA_HH_STATUS status) { - LOG_VERBOSE("bta_hh_le_gatt_disc_cmpl "); + log::verbose("status:{}", status); /* if open sucessful or protocol mode not desired, keep the connection open * but inform app */ @@ -1223,12 +1256,12 @@ static void read_hid_info_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value, void* data) { if (status != GATT_SUCCESS) { - LOG_ERROR("%s: error: %d", __func__, status); + log::error("error:{}", status); return; } if (len != 4) { - LOG_ERROR("%s: wrong length: %d", __func__, len); + log::error("wrong length:{}", len); return; } @@ -1244,7 +1277,7 @@ static void read_hid_report_map_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value, void* data) { if (status != GATT_SUCCESS) { - LOG_ERROR("%s: error reading characteristic: %d", __func__, status); + log::error("error reading characteristic:{}", status); return; } @@ -1267,14 +1300,14 @@ static void read_ext_rpt_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value, void* data) { if (status != GATT_SUCCESS) { - LOG_ERROR("%s: error: %d", __func__, status); + log::error("error:{}", status); return; } /* if the length of the descriptor value is right, parse it assume it's a 16 * bits UUID */ if (len != Uuid::kNumBytes16) { - LOG_ERROR("%s: we support only 16bit UUID: %d", __func__, len); + log::error("we support only 16bit UUID {}", len); return; } @@ -1283,15 +1316,15 @@ static void read_ext_rpt_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status, STREAM_TO_UINT16(p_dev_cb->hid_srvc.ext_rpt_ref, pp); - LOG_VERBOSE("%s: External Report Reference UUID 0x%04x", __func__, - p_dev_cb->hid_srvc.ext_rpt_ref); + log::verbose("External Report Reference UUID 0x{:04x}", + p_dev_cb->hid_srvc.ext_rpt_ref); } static void read_report_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value, void* data) { if (status != GATT_SUCCESS) { - LOG_ERROR("%s: error: %d", __func__, status); + log::error("error:{}", status); return; } @@ -1299,7 +1332,7 @@ static void read_report_ref_desc_cb(uint16_t conn_id, tGATT_STATUS status, const gatt::Descriptor* p_desc = BTA_GATTC_GetDescriptor(conn_id, handle); if (!p_desc) { - LOG_ERROR("%s: error: descriptor is null!", __func__); + log::error("error: descriptor is null!"); return; } @@ -1319,12 +1352,12 @@ static void read_pref_conn_params_cb(uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value, void* data) { if (status != GATT_SUCCESS) { - LOG_ERROR("%s: error: %d", __func__, status); + log::error("error:{}", status); return; } if (len != 8) { - LOG_ERROR("%s: we support only 16bit UUID: %d", __func__, len); + log::error("we support only 16bit UUID:{}", len); return; } @@ -1352,24 +1385,23 @@ static void read_pref_conn_params_cb(uint16_t conn_id, tGATT_STATUS status, latency > BTM_BLE_CONN_LATENCY_MAX || timeout < BTM_BLE_CONN_SUP_TOUT_MIN || timeout > BTM_BLE_CONN_SUP_TOUT_MAX || max_interval < min_interval) { - LOG_ERROR( - "%s: Invalid connection parameters. min=%d, max=%d, latency=%d, " - "timeout=%d", - __func__, min_interval, max_interval, latency, timeout); + log::error( + "Invalid connection parameters. min={}, max={}, latency={}, timeout={}", + min_interval, max_interval, latency, timeout); return; } tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; if (interop_match_addr(INTEROP_HID_PREF_CONN_SUP_TIMEOUT_3S, - (RawAddress*)&p_dev_cb->addr)) { + (RawAddress*)&p_dev_cb->link_spec.addrt.bda)) { if (timeout < 300) timeout = 300; } - BTM_BleSetPrefConnParams(p_dev_cb->addr, min_interval, max_interval, latency, - timeout); - L2CA_UpdateBleConnParams(p_dev_cb->addr, min_interval, max_interval, latency, - timeout, 0, 0); + BTM_BleSetPrefConnParams(p_dev_cb->link_spec.addrt.bda, min_interval, + max_interval, latency, timeout); + L2CA_UpdateBleConnParams(p_dev_cb->link_spec.addrt.bda, min_interval, + max_interval, latency, timeout, 0, 0); } /******************************************************************************* @@ -1390,8 +1422,7 @@ static void bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB* p_dev_cb, if (!charac.uuid.Is16Bit()) continue; uint16_t uuid16 = charac.uuid.As16Bit(); - LOG_INFO("%s: %s %s", __func__, bta_hh_uuid_to_str(uuid16), - charac.uuid.ToString().c_str()); + log::info("{} {}", bta_hh_uuid_to_str(uuid16), charac.uuid.ToString()); switch (uuid16) { case GATT_UUID_HID_CONTROL_POINT: @@ -1417,7 +1448,7 @@ static void bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB* p_dev_cb, p_dev_cb, p_dev_cb->hid_srvc.srvc_inst_id, GATT_UUID_HID_REPORT, charac.value_handle); if (p_rpt == NULL) { - LOG_ERROR("%s: Add report entry failed !!!", __func__); + log::error("Add report entry failed !!!"); break; } @@ -1434,13 +1465,13 @@ static void bta_hh_le_search_hid_chars(tBTA_HH_DEV_CB* p_dev_cb, case GATT_UUID_HID_BT_KB_INPUT: if (bta_hh_le_find_alloc_report_entry(p_dev_cb, service->handle, uuid16, charac.value_handle) == NULL) - LOG_ERROR("%s: Add report entry failed !!!", __func__); + log::error("Add report entry failed !!!"); break; default: - LOG_VERBOSE("%s: not processing %s 0x%04d", __func__, - bta_hh_uuid_to_str(uuid16), uuid16); + log::verbose("not processing {} 0x{:04d}", bta_hh_uuid_to_str(uuid16), + uuid16); } } @@ -1470,7 +1501,7 @@ static void bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL* p_data) { if (p_dev_cb == NULL) return; if (p_data->status != GATT_SUCCESS) { - LOG_ERROR("Service discovery failed %d", p_data->status); + log::error("Service discovery failed {}", p_data->status); p_dev_cb->status = BTA_HH_ERR_SDP; bta_hh_le_api_disc_act(p_dev_cb); return; @@ -1494,8 +1525,8 @@ static void bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL* p_data) { bta_hh_le_search_hid_chars(p_dev_cb, &service); - LOG_VERBOSE("%s: have HID service inst_id= %d", __func__, - p_dev_cb->hid_srvc.srvc_inst_id); + log::verbose("have HID service inst_id={}", + p_dev_cb->hid_srvc.srvc_inst_id); } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_SCAN_PARAM)) { scp_service = &service; } else if (service.uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) { @@ -1504,7 +1535,7 @@ static void bta_hh_le_srvc_search_cmpl(tBTA_GATTC_SEARCH_CMPL* p_data) { } if (!have_hid) { - LOG_ERROR("HID service not found"); + log::error("HID service not found"); p_dev_cb->status = BTA_HH_ERR_SDP; bta_hh_le_api_disc_act(p_dev_cb); return; @@ -1554,18 +1585,15 @@ static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) { tBTA_HH_LE_RPT* p_rpt; if (p_dev_cb == NULL) { - LOG_ERROR("%s: notification received from Unknown device, conn_id: 0x%04x", - __func__, p_data->conn_id); + log::error("Unknown device, conn_id: 0x{:04x}", p_data->conn_id); return; } const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(p_dev_cb->conn_id, p_data->handle); if (p_char == NULL) { - LOG_ERROR( - "%s: notification received for Unknown Characteristic, conn_id: " - "0x%04x, handle: 0x%04x", - __func__, p_dev_cb->conn_id, p_data->handle); + log::error("Unknown Characteristic, conn_id:0x{:04x}, handle:0x{:04x}", + p_dev_cb->conn_id, p_data->handle); return; } @@ -1577,10 +1605,8 @@ static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) { p_rpt = bta_hh_le_find_report_entry( p_dev_cb, p_svc->handle, p_char->uuid.As16Bit(), p_char->value_handle); if (p_rpt == NULL) { - LOG_ERROR( - "%s: notification received for Unknown Report, uuid: %s, handle: " - "0x%04x", - __func__, p_char->uuid.ToString().c_str(), p_char->value_handle); + log::error("Unknown Report, uuid:{}, handle:0x{:04x}", + p_char->uuid.ToString(), p_char->value_handle); return; } @@ -1589,7 +1615,7 @@ static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) { else if (p_char->uuid == Uuid::From16Bit(GATT_UUID_HID_BT_KB_INPUT)) app_id = BTA_HH_APP_ID_KB; - LOG_VERBOSE("Notification received on report ID: %d", p_rpt->rpt_id); + log::verbose("report ID: {}", p_rpt->rpt_id); /* need to append report ID to the head of data */ if (p_rpt->rpt_id != 0) { @@ -1604,7 +1630,7 @@ static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) { bta_hh_co_data((uint8_t)p_dev_cb->hid_handle, p_buf, p_data->len, p_dev_cb->mode, 0, /* no sub class*/ - p_dev_cb->dscp_info.ctry_code, p_dev_cb->addr, app_id); + p_dev_cb->dscp_info.ctry_code, p_dev_cb->link_spec, app_id); if (p_buf != p_data->value) osi_free(p_buf); } @@ -1621,11 +1647,12 @@ static void bta_hh_le_input_rpt_notify(tBTA_GATTC_NOTIFY* p_data) { void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { const tBTA_HH_LE_CLOSE* le_close = &p_data->le_close; - BTM_LogHistory(kBtmLogTag, p_cb->addr, "Open failed", + BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Open failed", base::StringPrintf( "%s reason %s", (p_cb->is_le_device) ? "le" : "classic", gatt_disconnection_reason_text(le_close->reason).c_str())); - LOG_WARN("Open failed for device:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->addr)); + log::warn("Open failed for device:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec.addrt.bda)); /* open failure in the middle of service discovery, clear all services */ if (p_cb->disc_active & BTA_HH_LE_DISC_HIDS) { @@ -1633,7 +1660,7 @@ void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { } if (p_cb->is_le_device && p_cb->status != BTA_HH_ERR_SDP) { - LOG_DEBUG("gd_acl: Re-adding HID device to acceptlist"); + log::debug("gd_acl: Re-adding HID device to acceptlist"); // gd removes from bg list after failed connection // Correct the cached state to allow re-add to acceptlist. bta_hh_le_add_dev_bg_conn(p_cb); @@ -1644,7 +1671,7 @@ void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { tBTA_HH data = { .conn = { - .bda = p_cb->addr, + .link_spec = p_cb->link_spec, .status = (le_close->reason != GATT_CONN_OK) ? BTA_HH_ERR : p_cb->status, .handle = p_cb->hid_handle, @@ -1670,7 +1697,7 @@ void bta_hh_le_open_fail(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { const tBTA_HH_LE_CLOSE* le_close = &p_data->le_close; - BTM_LogHistory(kBtmLogTag, p_cb->addr, "Closed", + BTM_LogHistory(kBtmLogTag, p_cb->link_spec.addrt.bda, "Closed", base::StringPrintf( "%s reason %s", (p_cb->is_le_device) ? "le" : "classic", gatt_disconnection_reason_text(le_close->reason).c_str())); @@ -1695,10 +1722,10 @@ void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { case GATT_CONN_FAILED_ESTABLISHMENT: case GATT_CONN_TERMINATE_PEER_USER: case GATT_CONN_TIMEOUT: - LOG_DEBUG( - "gd_acl: add into acceptlist for reconnection device:%s reason:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->addr), - gatt_disconnection_reason_text(le_close->reason).c_str()); + log::debug( + "gd_acl: add into acceptlist for reconnection device:{} reason:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec), + gatt_disconnection_reason_text(le_close->reason)); // gd removes from bg list after successful connection // Correct the cached state to allow re-add to acceptlist. bta_hh_le_add_dev_bg_conn(p_cb); @@ -1710,11 +1737,11 @@ void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { case GATT_CONN_OK: case GATT_CONN_TERMINATE_LOCAL_HOST: default: - LOG_DEBUG( - "gd_acl: SKIP add into acceptlist for reconnection device:%s " - "reason:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->addr), - gatt_disconnection_reason_text(le_close->reason).c_str()); + log::debug( + "gd_acl: SKIP add into acceptlist for reconnection device:{} " + "reason:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec), + gatt_disconnection_reason_text(le_close->reason)); break; } } @@ -1731,7 +1758,7 @@ void bta_hh_gatt_close(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { ******************************************************************************/ void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB* p_cb) { if (p_cb->conn_id == GATT_INVALID_CONN_ID) { - LOG_ERROR("Tried to disconnect HID device with invalid id"); + log::error("Tried to disconnect HID device with invalid id"); return; } @@ -1757,14 +1784,14 @@ static void read_report_cb(uint16_t conn_id, tGATT_STATUS status, void* data) { tBTA_HH_DEV_CB* p_dev_cb = (tBTA_HH_DEV_CB*)data; if (p_dev_cb->w4_evt != BTA_HH_GET_RPT_EVT) { - LOG_WARN("Unexpected Read response, w4_evt = %d", p_dev_cb->w4_evt); + log::warn("Unexpected Read response, w4_evt={}", p_dev_cb->w4_evt); return; } const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(conn_id, handle); if (p_char == nullptr) { - LOG_ERROR("Unknown handle"); + log::error("Unknown handle"); return; } @@ -1777,7 +1804,7 @@ static void read_report_cb(uint16_t conn_id, tGATT_STATUS status, case GATT_UUID_BATTERY_LEVEL: break; default: - LOG_ERROR("Unexpected Read UUID: 0x%04x", char_uuid); + log::error("Unexpected Read UUID: 0x{:04x}", char_uuid); return; } @@ -1829,7 +1856,7 @@ static void bta_hh_le_get_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type, p_cb->hid_srvc.report, p_cb->mode, r_type, rpt_id); if (p_rpt == NULL) { - LOG_ERROR("%s: no matching report", __func__); + log::error("no matching report"); return; } @@ -1847,7 +1874,7 @@ static void write_report_cb(uint16_t conn_id, tGATT_STATUS status, if (cb_evt == 0) return; - LOG_VERBOSE("bta_hh_le_write_cmpl w4_evt: %d", p_dev_cb->w4_evt); + log::verbose("w4_evt:{}", p_dev_cb->w4_evt); const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(conn_id, handle); @@ -1882,7 +1909,7 @@ static void bta_hh_le_write_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type, uint8_t rpt_id; if (p_buf == NULL || p_buf->len == 0) { - LOG_ERROR("%s: Illegal data", __func__); + log::error("Illegal data"); return; } @@ -1894,7 +1921,7 @@ static void bta_hh_le_write_rpt(tBTA_HH_DEV_CB* p_cb, tBTA_HH_RPT_TYPE r_type, p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc.report, p_cb->mode, r_type, rpt_id); if (p_rpt == NULL) { - LOG_ERROR("%s: no matching report", __func__); + log::error("no matching report"); osi_free(p_buf); return; } @@ -1978,8 +2005,8 @@ void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { break; default: - LOG_ERROR("%s unsupported transaction for BLE HID device: %d", __func__, - p_data->api_sndcmd.t_type); + log::error("unsupported transaction for BLE HID device:{}", + p_data->api_sndcmd.t_type); break; } } @@ -1999,7 +2026,7 @@ void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb) { p_cb->dscp_info.descriptor.dl_len = p_cb->hid_srvc.descriptor.dl_len; p_cb->dscp_info.descriptor.dsc_list = p_cb->hid_srvc.descriptor.dsc_list; } else { - LOG_WARN("hid_srvc.descriptor.dl_len is 0"); + log::warn("hid_srvc.descriptor.dl_len is 0"); } (*bta_hh_cb.p_cback)(BTA_HH_GET_DSCP_EVT, (tBTA_HH*)&p_cb->dscp_info); @@ -2018,7 +2045,7 @@ void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB* p_cb) { ******************************************************************************/ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB* p_cb) { /* Add device into BG connection to accept remote initiated connection */ - BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, + BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->link_spec.addrt.bda, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false); p_cb->in_bg_conn = true; } @@ -2070,27 +2097,28 @@ uint8_t bta_hh_le_add_device(tBTA_HH_DEV_CB* p_cb, ******************************************************************************/ void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB* p_dev_cb) { if (p_dev_cb->in_bg_conn) { - LOG_DEBUG("Removing from background connection device:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_cb->addr)); + log::debug("Removing from background connection device:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_cb->link_spec)); p_dev_cb->in_bg_conn = false; - BTA_GATTC_CancelOpen(bta_hh_cb.gatt_if, p_dev_cb->addr, false); + BTA_GATTC_CancelOpen(bta_hh_cb.gatt_if, p_dev_cb->link_spec.addrt.bda, + false); } /* deregister all notifications */ bta_hh_le_deregister_input_notif(p_dev_cb); } -static void bta_hh_le_service_changed(RawAddress remote_bda) { - tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(remote_bda); +static void bta_hh_le_service_changed(tAclLinkSpec link_spec) { + tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(link_spec); if (p_cb == nullptr) { - LOG_WARN("Received close event with unknown device:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn("Received close event with unknown device:{}", + ADDRESS_TO_LOGGABLE_CSTR(link_spec)); return; } /* Forget the cached reports */ - bta_hh_le_co_reset_rpt_cache(p_cb->addr, p_cb->app_id); + bta_hh_le_co_reset_rpt_cache(p_cb->link_spec, p_cb->app_id); p_cb->dscp_info.descriptor.dsc_list = NULL; osi_free_and_reset((void**)&p_cb->hid_srvc.rpt_map); p_cb->hid_srvc = {}; @@ -2114,11 +2142,10 @@ static void bta_hh_le_service_changed(RawAddress remote_bda) { bta_hh_sm_execute(p_cb, BTA_HH_GATT_CLOSE_EVT, &data); } -static void bta_hh_le_service_discovery_done(RawAddress remote_bda) { - tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(remote_bda); +static void bta_hh_le_service_discovery_done(tAclLinkSpec link_spec) { + tBTA_HH_DEV_CB* p_cb = bta_hh_le_find_dev_cb_by_bda(link_spec); if (p_cb == nullptr) { - LOG_WARN("Received service discovery done event for unknown device:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn("unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(link_spec)); return; } @@ -2130,13 +2157,13 @@ static void bta_hh_le_service_discovery_done(RawAddress remote_bda) { .status = GATT_SUCCESS, .conn_id = p_cb->conn_id, .client_if = bta_hh_cb.gatt_if, - .remote_bda = remote_bda, + .remote_bda = link_spec.addrt.bda, .transport = BT_TRANSPORT_LE, .mtu = 0, }; bta_hh_sm_execute(p_cb, BTA_HH_GATT_OPEN_EVT, (tBTA_HH_DATA*)&open); } else { - LOG_INFO("Discovery done, service state: %d", p_cb->hid_srvc.state); + log::info("Discovery done, service state:{}", p_cb->hid_srvc.state); } } @@ -2151,8 +2178,11 @@ static void bta_hh_le_service_discovery_done(RawAddress remote_bda) { ******************************************************************************/ static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { tBTA_HH_DEV_CB* p_dev_cb; - LOG_VERBOSE("bta_hh_gattc_callback event:%s", - gatt_client_event_text(event).c_str()); + tAclLinkSpec link_spec; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_LE; + + log::verbose("event:{}", gatt_client_event_text(event)); if (p_data == NULL) return; switch (event) { @@ -2162,7 +2192,9 @@ static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { break; case BTA_GATTC_OPEN_EVT: /* 2 */ - p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->open.remote_bda); + link_spec.addrt.bda = p_data->open.remote_bda; + link_spec.transport = p_data->open.transport; + p_dev_cb = bta_hh_le_find_dev_cb_by_bda(link_spec); if (p_dev_cb) { bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_OPEN_EVT, (tBTA_HH_DATA*)&p_data->open); @@ -2182,15 +2214,18 @@ static void bta_hh_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { break; case BTA_GATTC_SRVC_CHG_EVT: - bta_hh_le_service_changed(p_data->remote_bda); + link_spec.addrt.bda = p_data->remote_bda; + bta_hh_le_service_changed(link_spec); break; case BTA_GATTC_SRVC_DISC_DONE_EVT: - bta_hh_le_service_discovery_done(p_data->remote_bda); + link_spec.addrt.bda = p_data->remote_bda; + bta_hh_le_service_discovery_done(link_spec); break; case BTA_GATTC_ENC_CMPL_CB_EVT: /* 17 */ - p_dev_cb = bta_hh_le_find_dev_cb_by_bda(p_data->enc_cmpl.remote_bda); + link_spec.addrt.bda = p_data->enc_cmpl.remote_bda; + p_dev_cb = bta_hh_le_find_dev_cb_by_bda(link_spec); if (p_dev_cb) { bta_hh_sm_execute(p_dev_cb, BTA_HH_GATT_ENC_CMPL_EVT, (tBTA_HH_DATA*)&p_data->enc_cmpl); @@ -2229,7 +2264,7 @@ static void bta_hh_process_cache_rpt(tBTA_HH_DEV_CB* p_cb, if ((p_rpt = bta_hh_le_find_alloc_report_entry( p_cb, p_rpt_cache->srvc_inst_id, p_rpt_cache->rpt_uuid, p_rpt_cache->char_inst_id)) == NULL) { - LOG_ERROR("bta_hh_process_cache_rpt: allocation report entry failure"); + log::error("allocation report entry failure"); break; } else { p_rpt->rpt_type = p_rpt_cache->rpt_type; @@ -2245,3 +2280,27 @@ static void bta_hh_process_cache_rpt(tBTA_HH_DEV_CB* p_cb, } } } + +static bool bta_hh_le_iso_data_callback(const RawAddress& addr, + uint16_t cis_conn_hdl, uint8_t* data, + uint16_t size, uint32_t timestamp) { + if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + LOG_WARN("DSA not supported"); + return false; + } + + tAclLinkSpec link_spec{}; + link_spec.addrt.bda = addr; + link_spec.transport = BT_TRANSPORT_LE; + + tBTA_HH_DEV_CB* p_dev_cb = bta_hh_le_find_dev_cb_by_bda(link_spec); + if (p_dev_cb == nullptr) { + LOG_WARN("Device not connected: %s", ADDRESS_TO_LOGGABLE_CSTR(link_spec)); + return false; + } + + bta_hh_co_data(p_dev_cb->hid_handle, data, size, p_dev_cb->mode, 0, + p_dev_cb->dscp_info.ctry_code, p_dev_cb->link_spec, + BTA_HH_APP_ID_LE); + return true; +} diff --git a/system/bta/hh/bta_hh_main.cc b/system/bta/hh/bta_hh_main.cc index f28d6ba06429765db1ac583ae4a383d8d7398ca5..f734aa626829c2df83b09fb6710daed44ffcac88 100644 --- a/system/bta/hh/bta_hh_main.cc +++ b/system/bta/hh/bta_hh_main.cc @@ -22,15 +22,20 @@ * ******************************************************************************/ +#define LOG_TAG "bt_bta_hh" + +#include #include // memset #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/hh/bta_hh_int.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + /***************************************************************************** * Global data ****************************************************************************/ @@ -44,6 +49,8 @@ static const char* bta_hh_state_code(tBTA_HH_STATE state_code); static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event, const tBTA_HH_DATA* p_data) { + log::verbose("state:{}, event:{}", bta_hh_state_code(p_cb->state), + bta_hh_evt_code(static_cast(event))); switch (p_cb->state) { case BTA_HH_IDLE_ST: switch (event) { @@ -195,6 +202,8 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, /* handle exception, no valid control block was found */ if (!p_cb) { + log::verbose("Event:{}, bta_hh_cb.p_cback:{}", bta_hh_evt_code(debug_event), + fmt::ptr(bta_hh_cb.p_cback)); /* BTA HH enabled already? otherwise ignore the event although it's bad*/ if (bta_hh_cb.p_cback != NULL) { switch (event) { @@ -202,7 +211,7 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, case BTA_HH_API_OPEN_EVT: cback_event = BTA_HH_OPEN_EVT; /* build cback data */ - cback_data.conn.bda = ((tBTA_HH_API_CONN*)p_data)->bd_addr; + cback_data.conn.link_spec = ((tBTA_HH_API_CONN*)p_data)->link_spec; cback_data.conn.status = BTA_HH_ERR_DB_FULL; cback_data.conn.handle = BTA_HH_INVALID_HANDLE; break; @@ -211,7 +220,7 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, cback_event = p_data->api_maintdev.sub_event; if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) { - cback_data.dev_info.bda = p_data->api_maintdev.bda; + cback_data.dev_info.link_spec = p_data->api_maintdev.link_spec; cback_data.dev_info.status = BTA_HH_ERR_DB_FULL; cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE; } else { @@ -255,7 +264,7 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, default: /* invalid handle, call bad API event */ - LOG_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific); + log::error("wrong device handle:{}", p_data->hdr.layer_specific); /* Free the callback buffer now */ if (p_data != NULL) osi_free_and_reset((void**)&p_data->hid_cback.p_data); @@ -267,21 +276,20 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB* p_cb, uint16_t event, /* corresponding CB is found, go to state machine */ else { in_state = p_cb->state; - LOG_VERBOSE("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]", in_state, - bta_hh_state_code(in_state), bta_hh_evt_code(debug_event)); + log::verbose("State 0x{:02x} [{}], Event [{}]", in_state, + bta_hh_state_code(in_state), bta_hh_evt_code(debug_event)); if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST)) { - LOG_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d", - p_cb->state, event); + log::error("Invalid state State=0x{:x}, Event={}", p_cb->state, event); return; } bta_hh_better_state_machine(p_cb, event, p_data); if (in_state != p_cb->state) { - LOG_DEBUG("HHID State Change: [%s] -> [%s] after Event [%s]", - bta_hh_state_code(in_state), bta_hh_state_code(p_cb->state), - bta_hh_evt_code(debug_event)); + log::debug("HHID State Change: [{}] -> [{}] after Event [{}]", + bta_hh_state_code(in_state), bta_hh_state_code(p_cb->state), + bta_hh_evt_code(debug_event)); } } } @@ -303,11 +311,11 @@ bool bta_hh_hdl_event(const BT_HDR_RIGID* p_msg) { /* all events processed in state machine need to find corresponding CB before proceed */ if (p_msg->event == BTA_HH_API_OPEN_EVT) { - index = bta_hh_find_cb(((tBTA_HH_API_CONN*)p_msg)->bd_addr); + index = bta_hh_find_cb(((tBTA_HH_API_CONN*)p_msg)->link_spec); } else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) { /* if add device */ if (((tBTA_HH_MAINT_DEV*)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) { - index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV*)p_msg)->bda); + index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV*)p_msg)->link_spec); } else /* else remove device by handle */ { index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific); /* If BT disable is done while the HID device is connected and @@ -325,15 +333,14 @@ bool bta_hh_hdl_event(const BT_HDR_RIGID* p_msg) { } } } else if (p_msg->event == BTA_HH_INT_OPEN_EVT) { - index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA*)p_msg)->addr); + index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA*)p_msg)->link_spec); } else { index = bta_hh_dev_handle_to_cb_idx((uint8_t)p_msg->layer_specific); } if (index != BTA_HH_IDX_INVALID) p_cb = &bta_hh_cb.kdev[index]; - LOG_VERBOSE("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", - p_msg->layer_specific, index); + log::verbose("handle={} dev_cb[{}]", p_msg->layer_specific, index); bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA*)p_msg); return (true); diff --git a/system/bta/hh/bta_hh_utils.cc b/system/bta/hh/bta_hh_utils.cc index c0220b98aa49bb0124f1e079e05b945004bcbf1a..b7357462ef1ddedca7c25ee5882262c12a360768 100644 --- a/system/bta/hh/bta_hh_utils.cc +++ b/system/bta/hh/bta_hh_utils.cc @@ -15,6 +15,9 @@ * limitations under the License. * ******************************************************************************/ +#define LOG_TAG "bt_bta_hh" + +#include #include // memset #include @@ -23,12 +26,14 @@ #include "btif/include/btif_storage.h" #include "device/include/interop.h" #include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "stack/include/btm_client_interface.h" #include "stack/include/sdp_api.h" #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; /* if SSR max latency is not defined by remote device, set the default value as half of the link supervision timeout */ @@ -54,38 +59,38 @@ constexpr uint16_t kSsrMaxLatency = 18; /* slots * 0.625ms */ * Returns void * ******************************************************************************/ -uint8_t bta_hh_find_cb(const RawAddress& bda) { +uint8_t bta_hh_find_cb(const tAclLinkSpec& link_spec) { uint8_t xx; /* See how many active devices there are. */ for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) { /* check if any active/known devices is a match */ - if ((bda == bta_hh_cb.kdev[xx].addr && !bda.IsEmpty())) { + if ((link_spec.addrt.bda == bta_hh_cb.kdev[xx].link_spec.addrt.bda && + !link_spec.addrt.bda.IsEmpty())) { #if (BTA_HH_DEBUG == TRUE) - LOG_VERBOSE("found kdev_cb[%d] hid_handle = %d ", xx, - bta_hh_cb.kdev[xx].hid_handle); + log::verbose("found kdev_cb[{}] hid_handle={}", xx, + bta_hh_cb.kdev[xx].hid_handle); #endif return xx; } #if (BTA_HH_DEBUG == TRUE) else - LOG_VERBOSE("in_use ? [%d] kdev[%d].hid_handle = %d state = [%d]", - bta_hh_cb.kdev[xx].in_use, xx, bta_hh_cb.kdev[xx].hid_handle, - bta_hh_cb.kdev[xx].state); + log::verbose("in_use ? [{}] kdev[{}].hid_handle={} state=[{}]", + bta_hh_cb.kdev[xx].in_use, xx, bta_hh_cb.kdev[xx].hid_handle, + bta_hh_cb.kdev[xx].state); #endif } /* if no active device match, find a spot for it */ for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) { if (!bta_hh_cb.kdev[xx].in_use) { - bta_hh_cb.kdev[xx].addr = bda; + bta_hh_cb.kdev[xx].link_spec = link_spec; break; } } /* If device list full, report BTA_HH_IDX_INVALID */ #if (BTA_HH_DEBUG == TRUE) - LOG_VERBOSE("bta_hh_find_cb:: index = %d while max = %d", xx, - BTA_HH_MAX_DEVICE); + log::verbose("index={} while max={}", xx, BTA_HH_MAX_DEVICE); #endif if (xx == BTA_HH_MAX_DEVICE) xx = BTA_HH_IDX_INVALID; @@ -93,8 +98,8 @@ uint8_t bta_hh_find_cb(const RawAddress& bda) { return xx; } -tBTA_HH_DEV_CB* bta_hh_get_cb(const RawAddress& bda) { - uint8_t idx = bta_hh_find_cb(bda); +tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec) { + uint8_t idx = bta_hh_find_cb(link_spec); if (idx == BTA_HH_IDX_INVALID) { return nullptr; } @@ -117,13 +122,13 @@ void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB* p_cb) { if (p_cb->is_le_device) { uint8_t le_hid_handle = BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle); if (le_hid_handle >= BTA_HH_LE_MAX_KNOWN) { - LOG_WARN("Invalid LE hid_handle %d", p_cb->hid_handle); + log::warn("Invalid LE hid_handle {}", p_cb->hid_handle); } else { bta_hh_cb.le_cb_index[le_hid_handle] = BTA_HH_IDX_INVALID; } } else { if (p_cb->hid_handle >= BTA_HH_MAX_KNOWN) { - LOG_WARN("Invalid hid_handle %d", p_cb->hid_handle); + log::warn("Invalid hid_handle {}", p_cb->hid_handle); } else { bta_hh_cb.cb_index[p_cb->hid_handle] = BTA_HH_IDX_INVALID; } @@ -154,8 +159,8 @@ void bta_hh_update_di_info(tBTA_HH_DEV_CB* p_cb, uint16_t vendor_id, uint16_t product_id, uint16_t version, uint8_t flag, uint8_t ctry_code) { #if (BTA_HH_DEBUG == TRUE) - LOG_VERBOSE("vendor_id = 0x%2x product_id = 0x%2x version = 0x%2x", vendor_id, - product_id, version); + log::verbose("vendor_id=0x{:2x} product_id=0x{:2x} version=0x{:2x}", + vendor_id, product_id, version); #endif p_cb->dscp_info.vendor_id = vendor_id; p_cb->dscp_info.product_id = product_id; @@ -178,7 +183,7 @@ void bta_hh_add_device_to_list(tBTA_HH_DEV_CB* p_cb, uint8_t handle, uint8_t sub_class, uint16_t ssr_max_latency, uint16_t ssr_min_tout, uint8_t app_id) { #if (BTA_HH_DEBUG == TRUE) - LOG_VERBOSE("subclass = 0x%2x", sub_class); + log::verbose("subclass=0x{:2x}", sub_class); #endif p_cb->hid_handle = handle; @@ -222,13 +227,13 @@ bool bta_hh_tod_spt(tBTA_HH_DEV_CB* p_cb, uint8_t sub_class) { if (cod == (uint8_t)p_bta_hh_cfg->p_devt_list[xx].tod) { p_cb->app_id = p_bta_hh_cfg->p_devt_list[xx].app_id; #if (BTA_HH_DEBUG == TRUE) - LOG_VERBOSE("bta_hh_tod_spt sub_class:0x%x supported", sub_class); + log::verbose("sub_class:0x{:x} supported", sub_class); #endif return true; } } #if (BTA_HH_DEBUG == TRUE) - LOG_VERBOSE("bta_hh_tod_spt sub_class:0x%x NOT supported", sub_class); + log::verbose("sub_class:0x{:x} NOT supported", sub_class); #endif return false; } @@ -243,12 +248,12 @@ bool bta_hh_tod_spt(tBTA_HH_DEV_CB* p_cb, uint8_t sub_class) { * Returns tBTA_HH_STATUS operation status * ******************************************************************************/ -tBTA_HH_STATUS bta_hh_read_ssr_param(const RawAddress& bd_addr, +tBTA_HH_STATUS bta_hh_read_ssr_param(const tAclLinkSpec& link_spec, uint16_t* p_max_ssr_lat, uint16_t* p_min_ssr_tout) { - tBTA_HH_DEV_CB* p_cb = bta_hh_get_cb(bd_addr); + tBTA_HH_DEV_CB* p_cb = bta_hh_get_cb(link_spec); if (p_cb == nullptr) { - LOG_WARN("Unable to find device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Unable to find device:{}", ADDRESS_TO_LOGGABLE_CSTR(link_spec)); return BTA_HH_ERR; } @@ -259,9 +264,9 @@ tBTA_HH_STATUS bta_hh_read_ssr_param(const RawAddress& bd_addr, uint16_t ssr_max_latency; if (get_btm_client_interface().link_controller.BTM_GetLinkSuperTout( - p_cb->addr, &ssr_max_latency) != BTM_SUCCESS) { - LOG_WARN("Unable to get supervision timeout for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->addr)); + p_cb->link_spec.addrt.bda, &ssr_max_latency) != BTM_SUCCESS) { + log::warn("Unable to get supervision timeout for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->link_spec)); return BTA_HH_ERR; } ssr_max_latency = BTA_HH_GET_DEF_SSR_MAX_LAT(ssr_max_latency); @@ -273,7 +278,7 @@ tBTA_HH_STATUS bta_hh_read_ssr_param(const RawAddress& bd_addr, ssr_max_latency = BTA_HH_SSR_MAX_LATENCY_DEF; char remote_name[BTM_MAX_REM_BD_NAME_LEN] = ""; - if (btif_storage_get_stored_remote_name(bd_addr, remote_name)) { + if (btif_storage_get_stored_remote_name(link_spec.addrt.bda, remote_name)) { if (interop_match_name(INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL, remote_name)) { if (ssr_max_latency > kSsrMaxLatency /* slots * 0.625ms */) { @@ -347,8 +352,7 @@ uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle) { if (BTA_HH_IS_LE_DEV_HDL_VALID(dev_handle)) index = bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(dev_handle)]; #if (BTA_HH_DEBUG == TRUE) - LOG_VERBOSE("bta_hh_dev_handle_to_cb_idx dev_handle = %d index = %d", - dev_handle, index); + log::verbose("dev_handle={} index={}", dev_handle, index); #endif } else /* regular HID device checking */ @@ -370,16 +374,17 @@ uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle) { void bta_hh_trace_dev_db(void) { uint8_t xx; - LOG_VERBOSE("bta_hh_trace_dev_db:: Device DB list********************"); + log::verbose("bta_hh_trace_dev_db:: Device DB list********************"); for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) { - LOG_VERBOSE("kdev[%d] in_use[%d] handle[%d] ", xx, - bta_hh_cb.kdev[xx].in_use, bta_hh_cb.kdev[xx].hid_handle); + log::verbose("kdev[{}] in_use[{}] handle[{}]", xx, + bta_hh_cb.kdev[xx].in_use, bta_hh_cb.kdev[xx].hid_handle); - LOG_VERBOSE("\t\t\t attr_mask[%04x] state [%d] sub_class[%02x] index = %d", - bta_hh_cb.kdev[xx].attr_mask, bta_hh_cb.kdev[xx].state, - bta_hh_cb.kdev[xx].sub_class, bta_hh_cb.kdev[xx].index); + log::verbose( + "\t\t\t attr_mask[{:04x}] state [{}] sub_class[{:02x}] index = {}", + bta_hh_cb.kdev[xx].attr_mask, bta_hh_cb.kdev[xx].state, + bta_hh_cb.kdev[xx].sub_class, bta_hh_cb.kdev[xx].index); } - LOG_VERBOSE("*********************************************************"); + log::verbose("*********************************************************"); } #endif diff --git a/system/bta/include/bta_ag_api.h b/system/bta/include/bta_ag_api.h index 569e16aaf4ffd4d3bc3ab1b6e44882514d1b9837..92d91104f0437e5d93616895bdad005b2b5aade8 100644 --- a/system/bta/include/bta_ag_api.h +++ b/system/bta/include/bta_ag_api.h @@ -25,13 +25,14 @@ #ifndef BTA_AG_API_H #define BTA_AG_API_H +#include + #include #include -#include "bta/include/bta_ag_api.h" #include "bta/include/bta_api.h" #include "bta_api.h" -#include "bta_hfp_api.h" +#include "internal_include/bt_target.h" #include "macros.h" #include "types/raw_address.h" @@ -302,6 +303,12 @@ struct offload_config { bool is_nrec; }; +struct sco_config { + int inputDataPath; + int outputDataPath; + bool useControllerCodec; +}; + } // namespace hfp /* data associated with BTA_AG_IND_RES */ typedef struct { @@ -634,4 +641,9 @@ void BTA_AgSetScoAllowed(bool value); void BTA_AgSetActiveDevice(const RawAddress& active_device_addr); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* BTA_AG_API_H */ diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index 062fe11841aa2399f0678f951ce621739f1299e6..7abc86d780dc6b600e73afebbc0cff783259f148 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ #include "macros.h" #include "os/log.h" #include "stack/btm/power_mode.h" +#include "stack/include/bt_device_type.h" #include "stack/include/bt_name.h" #include "stack/include/btm_api_types.h" #include "stack/include/btm_ble_api_types.h" @@ -969,4 +971,11 @@ bool BTA_DmCheckLeAudioCapable(const RawAddress& address); void DumpsysBtaDm(int fd); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* BTA_API_H */ diff --git a/system/bta/include/bta_api_data_types.h b/system/bta/include/bta_api_data_types.h index 94c852d22ff19a9fd81e3277ac65bffa6dc6fb37..aa41dd397faa8395188def261d9f4389d117f50a 100644 --- a/system/bta/include/bta_api_data_types.h +++ b/system/bta/include/bta_api_data_types.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -58,3 +59,11 @@ typedef struct { RawAddress id_addr; } tBTA_DM_PROC_ID_ADDR; +typedef struct { + RawAddress bd_addr; +} tBTA_DM_KEY_MISSING; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/bta/include/bta_csis_api.h b/system/bta/include/bta_csis_api.h index 6ed5bb41e595eb2bbd03410bd8ab8cb155bde076..e56d5cc0f5b035897bf959d6424aa357c5e93370 100644 --- a/system/bta/include/bta_csis_api.h +++ b/system/bta/include/bta_csis_api.h @@ -16,6 +16,8 @@ */ #pragma once +#include + #include "base/functional/callback.h" #include "bind_helpers.h" #include "bta/include/bta_groups.h" @@ -33,7 +35,7 @@ class CsisClient { static void Initialize(bluetooth::csis::CsisClientCallbacks* callbacks, base::Closure initCb); static void AddFromStorage(const RawAddress& addr, - const std::vector& in, bool autoconnect); + const std::vector& in); static bool GetForStorage(const RawAddress& addr, std::vector& out); static void CleanUp(); static CsisClient* Get(); diff --git a/system/bta/include/bta_gatt_api.h b/system/bta/include/bta_gatt_api.h index 01d53fdf49ee11717d3399842f8e5aacfb1810f1..3e3f15ed9e23dbd1d2f75493ae1493530b72a280 100644 --- a/system/bta/include/bta_gatt_api.h +++ b/system/bta/include/bta_gatt_api.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -1030,4 +1031,9 @@ void BTA_GATTS_Close(uint16_t conn_id); // Adds bonded device for GATT server tracking service changes void BTA_GATTS_InitBonded(void); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* BTA_GATT_API_H */ diff --git a/system/bta/include/bta_hearing_aid_api.h b/system/bta/include/bta_hearing_aid_api.h index c220631e87cc518073c395ff2e9ebd89184a4907..16aef09dfe457e34074f776c6ffe522395516578 100644 --- a/system/bta/include/bta_hearing_aid_api.h +++ b/system/bta/include/bta_hearing_aid_api.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -286,3 +287,9 @@ class HearingAidAudioSource { static void CleanUp(); static void DebugDump(int fd); }; + +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt diff --git a/system/bta/include/bta_hfp_api.h b/system/bta/include/bta_hfp_api.h index 22ea4a39272d045b289c20f45d3ecfc8f5a38cd7..fe86e2de47f9828a4a013c549a409f081de22a1e 100644 --- a/system/bta/include/bta_hfp_api.h +++ b/system/bta/include/bta_hfp_api.h @@ -30,9 +30,6 @@ #define HSP_VERSION_1_0 0x0100 #define HSP_VERSION_1_2 0x0102 -#define HFP_VERSION_CONFIG_KEY "HfpVersion" -#define HFP_SDP_FEATURES_CONFIG_KEY "HfpSdpFeatures" - int get_default_hfp_version(); #endif /* BTA_HFP_API_H */ diff --git a/system/bta/include/bta_hh_api.h b/system/bta/include/bta_hh_api.h index 1f62c9e1bbe06bad4b590874a3e2b690df3dc3d5..7f7335e4962e3deaace2f8da5a7fde0b30832340 100644 --- a/system/bta/include/bta_hh_api.h +++ b/system/bta/include/bta_hh_api.h @@ -19,15 +19,17 @@ #define BTA_HH_API_H #include +#include #include #include -#include "bta/include/bta_api.h" +#include "internal_include/bt_target.h" #include "macros.h" #include "stack/include/bt_hdr.h" #include "stack/include/hiddefs.h" -#include "types/raw_address.h" +#include "stack/include/l2c_api.h" +#include "types/ble_address_with_type.h" /***************************************************************************** * Constants and Type Definitions @@ -231,7 +233,7 @@ typedef struct { /* callback event data for BTA_HH_OPEN_EVT */ typedef struct { - RawAddress bda; /* HID device bd address */ + tAclLinkSpec link_spec; /* HID device ACL link specification */ tBTA_HH_STATUS status; /* operation status */ uint8_t handle; /* device handle */ bool le_hid; /* is LE devices? */ @@ -357,7 +359,7 @@ void BTA_HhDisable(void); * Returns void * ******************************************************************************/ -void BTA_HhOpen(const RawAddress& dev_bda); +void BTA_HhOpen(const tAclLinkSpec& link_spec); /******************************************************************************* * @@ -479,7 +481,7 @@ void BTA_HhGetIdle(uint8_t dev_handle); * Returns void * ******************************************************************************/ -void BTA_HhSendData(uint8_t dev_handle, const RawAddress& dev_bda, +void BTA_HhSendData(uint8_t dev_handle, const tAclLinkSpec& link_spec, BT_HDR* p_buf); /******************************************************************************* @@ -504,7 +506,7 @@ void BTA_HhGetDscpInfo(uint8_t dev_handle); * Returns void * ******************************************************************************/ -void BTA_HhAddDev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask, +void BTA_HhAddDev(const tAclLinkSpec& link_spec, tBTA_HH_ATTR_MASK attr_mask, uint8_t sub_class, uint8_t app_id, tBTA_HH_DEV_DSCP_INFO dscp_info); /******************************************************************************* @@ -518,4 +520,8 @@ void BTA_HhAddDev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask, ******************************************************************************/ void BTA_HhRemoveDev(uint8_t dev_handle); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt #endif /* BTA_HH_API_H */ diff --git a/system/bta/include/bta_hh_co.h b/system/bta/include/bta_hh_co.h index 2ddaf6831efa7f92c62737ccf83161afd531f3be..eb805b150ba889f763ed5a32f3ca6f5943ddc502 100644 --- a/system/bta/include/bta_hh_co.h +++ b/system/bta/include/bta_hh_co.h @@ -51,7 +51,7 @@ typedef struct { ******************************************************************************/ void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len, tBTA_HH_PROTO_MODE mode, uint8_t sub_class, - uint8_t ctry_code, const RawAddress& peer_addr, + uint8_t ctry_code, const tAclLinkSpec& link_spec, uint8_t app_id); /******************************************************************************* @@ -102,14 +102,14 @@ void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status, * information in NV if device is bonded and load it back when * stack reboot. * - * Parameters remote_bda - remote device address + * Parameters link_spec - acl link specification * p_entry - report entry pointer * app_id - application id * * Returns void. * ******************************************************************************/ -void bta_hh_le_co_rpt_info(const RawAddress& remote_bda, +void bta_hh_le_co_rpt_info(const tAclLinkSpec& link_spec, tBTA_HH_RPT_CACHE_ENTRY* p_entry, uint8_t app_id); /******************************************************************************* @@ -121,14 +121,14 @@ void bta_hh_le_co_rpt_info(const RawAddress& remote_bda, * is completed, bta_hh_le_ci_cache_load() is called by the * application. * - * Parameters remote_bda - remote device address + * Parameters link_spec - acl link specification * p_num_rpt: number of cached report * app_id - application id * * Returns the acched report array * ******************************************************************************/ -tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const RawAddress& remote_bda, +tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const tAclLinkSpec& link_spec, uint8_t* p_num_rpt, uint8_t app_id); @@ -138,11 +138,12 @@ tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const RawAddress& remote_bda, * * Description This callout function is to reset the HOGP device cache. * - * Parameters remote_bda - remote device address + * Parameters link_spec - acl link specification * * Returns none * ******************************************************************************/ -void bta_hh_le_co_reset_rpt_cache(const RawAddress& remote_bda, uint8_t app_id); +void bta_hh_le_co_reset_rpt_cache(const tAclLinkSpec& link_spec, + uint8_t app_id); #endif /* BTA_HH_CO_H */ diff --git a/system/bta/include/bta_jv_api.h b/system/bta/include/bta_jv_api.h index 604519d37b8c01f0f7031ac77400e6bc477c9780..6bb30d9f0a9b7ddc862c44bbb2a7f587be89a582 100644 --- a/system/bta/include/bta_jv_api.h +++ b/system/bta/include/bta_jv_api.h @@ -27,9 +27,9 @@ #include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/include/bta_api.h" #include "bta_sec_api.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" #include "stack/include/l2c_api.h" #include "types/bluetooth/uuid.h" diff --git a/system/bta/include/bta_le_audio_api.h b/system/bta/include/bta_le_audio_api.h index c5e4cef53d8afb200b9c00b352ab206a6b044ad0..eb9a4e49ffc6adc6604d14e1571a241ab3354831 100644 --- a/system/bta/include/bta_le_audio_api.h +++ b/system/bta/include/bta_le_audio_api.h @@ -32,6 +32,9 @@ class LeAudioHalVerifier { static bool SupportsStreamActiveApi(); }; +typedef bool(LeAudioIsoDataCallback)(const RawAddress& address, + uint16_t cis_conn_hdl, uint8_t* data, + uint16_t size, uint32_t timestamp); /* Interface class */ class LeAudioClient { public: @@ -67,6 +70,7 @@ class LeAudioClient { virtual void SetInVoipCall(bool in_call) = 0; virtual void SetUnicastMonitorMode(uint8_t direction, bool enable) = 0; virtual bool IsInVoipCall() = 0; + virtual bool IsInStreaming() = 0; virtual void SendAudioProfilePreferences( const int group_id, bool is_output_preference_le_audio, bool is_duplex_preference_le_audio) = 0; @@ -74,6 +78,9 @@ class LeAudioClient { virtual bool isOutputPreferenceLeAudio(const RawAddress& address) = 0; virtual bool isDuplexPreferenceLeAudio(const RawAddress& address) = 0; virtual std::vector GetGroupDevices(const int group_id) = 0; + + static bool RegisterIsoDataConsumer(LeAudioIsoDataCallback callback); + static void AddFromStorage(const RawAddress& addr, bool autoconnect, int sink_audio_location, int source_audio_location, int sink_supported_context_types, @@ -91,4 +98,5 @@ class LeAudioClient { static bool GetAsesForStorage(const RawAddress& addr, std::vector& out); static bool IsLeAudioClientRunning(); + static bool IsLeAudioClientInStreaming(); }; diff --git a/system/bta/include/bta_sec_api.h b/system/bta/include/bta_sec_api.h index 958ecfd5fbe40fb39af59bf4bf7c3a2e67496cb3..9b3ae1f8ae5841faf6c8ca3b7854e36760a6e38d 100644 --- a/system/bta/include/bta_sec_api.h +++ b/system/bta/include/bta_sec_api.h @@ -20,12 +20,13 @@ #include #include +#include #include -#include -#include "bt_target.h" // Must be first to define build configuration #include "bta_api_data_types.h" +#include "internal_include/bt_target.h" +#include "stack/include/bt_device_type.h" #include "stack/include/bt_name.h" #include "stack/include/bt_octets.h" #include "stack/include/btm_ble_sec_api_types.h" @@ -64,13 +65,14 @@ typedef enum : uint8_t { 23, /* Simple Pairing Remote OOB Extended Data request. */ BTA_DM_BLE_AUTH_CMPL_EVT = 24, /* BLE Auth complete */ BTA_DM_DEV_UNPAIRED_EVT = 25, - BTA_DM_ENER_INFO_READ = 28, /* Energy info read */ - BTA_DM_BLE_SC_OOB_REQ_EVT = 29, /* SMP SC OOB request event */ - BTA_DM_BLE_CONSENT_REQ_EVT = 30, /* SMP consent request event */ + BTA_DM_ENER_INFO_READ = 28, /* Energy info read */ + BTA_DM_BLE_SC_OOB_REQ_EVT = 29, /* SMP SC OOB request event */ + BTA_DM_BLE_CONSENT_REQ_EVT = 30, /* SMP consent request event */ BTA_DM_BLE_SC_CR_LOC_OOB_EVT = 31, /* SMP SC Create Local OOB request event */ BTA_DM_REPORT_BONDING_EVT = 32, /*handle for pin or key missing*/ BTA_DM_LE_ADDR_ASSOC_EVT = 33, /* identity address association event */ BTA_DM_SIRK_VERIFICATION_REQ_EVT = 35, + BTA_DM_KEY_MISSING_EVT = 36, } tBTA_DM_SEC_EVT; /* Structure associated with BTA_DM_PIN_REQ_EVT */ @@ -242,6 +244,7 @@ typedef union { tBTA_DM_LOC_OOB_DATA local_oob_data; /* Local OOB data generated by us */ tBTA_DM_RC_UNPAIR delete_key_RC_to_unpair; tBTA_DM_PROC_ID_ADDR proc_id_addr; /* Identity address event */ + tBTA_DM_KEY_MISSING key_missing; } tBTA_DM_SEC; /* Security callback */ @@ -493,3 +496,8 @@ void BTA_DmSirkSecCbRegister(tBTA_DM_SEC_CBACK* p_cback); * ******************************************************************************/ void BTA_DmSirkConfirmDeviceReply(const RawAddress& bd_addr, bool accept); + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/bta/jv/bta_jv_act.cc b/system/bta/jv/bta_jv_act.cc index 0f7748526081b83c30055d9700f5136a8ac6b68c..0fbba9d1926083a802a85affd7f09c05c088a27c 100644 --- a/system/bta/jv/bta_jv_act.cc +++ b/system/bta/jv/bta_jv_act.cc @@ -24,7 +24,9 @@ #define LOG_TAG "bluetooth" +#include #include +#include #include #include @@ -45,6 +47,7 @@ #include "stack/include/bt_psm_types.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" +#include "stack/include/btm_client_interface.h" #include "stack/include/gap_api.h" #include "stack/include/l2cdefs.h" #include "stack/include/port_api.h" @@ -53,6 +56,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; tBTA_JV_CB bta_jv_cb; std::unordered_set used_l2cap_classic_dynamic_psm; @@ -64,6 +68,7 @@ static void bta_jv_pm_conn_busy(tBTA_JV_PM_CB* p_cb); static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB* p_cb); static void bta_jv_pm_state_change(tBTA_JV_PM_CB* p_cb, const tBTA_JV_CONN_STATE state); +static void bta_jv_reset_sniff_timer(tBTA_JV_PM_CB* p_cb); #ifndef BTA_JV_SDP_DB_SIZE #define BTA_JV_SDP_DB_SIZE 4500 @@ -121,8 +126,7 @@ static int get_sec_id_used(void) { if (bta_jv_cb.sec_id[i]) used++; } if (used == BTA_JV_NUM_SERVICE_ID) - LOG(ERROR) << __func__ - << ": sec id exceeds the limit=" << BTA_JV_NUM_SERVICE_ID; + log::error("sec id exceeds the limit={}", BTA_JV_NUM_SERVICE_ID); return used; } static int get_rfc_cb_used(void) { @@ -132,8 +136,7 @@ static int get_rfc_cb_used(void) { if (bta_jv_cb.rfc_cb[i].handle) used++; } if (used == BTA_JV_MAX_RFC_CONN) - LOG(ERROR) << __func__ - << ": rfc ctrl block exceeds the limit=" << BTA_JV_MAX_RFC_CONN; + log::error("rfc ctrl block exceeds the limit={}", BTA_JV_MAX_RFC_CONN); return used; } @@ -226,8 +229,8 @@ tBTA_JV_RFC_CB* bta_jv_alloc_rfc_cb(uint16_t port_handle, p_cb->curr_sess = 1; for (j = 0; j < BTA_JV_MAX_RFC_SR_SESSION; j++) p_cb->rfc_hdl[j] = 0; p_cb->rfc_hdl[0] = port_handle; - VLOG(2) << __func__ << "port_handle=" << +port_handle - << ", handle=" << loghex(p_cb->handle); + log::verbose("port_handle={}, handle={}", port_handle, + loghex(p_cb->handle)); p_pcb = &bta_jv_cb.port_cb[port_handle - 1]; p_pcb->handle = p_cb->handle; @@ -238,7 +241,8 @@ tBTA_JV_RFC_CB* bta_jv_alloc_rfc_cb(uint16_t port_handle, } } if (p_cb == NULL) { - LOG(ERROR) << __func__ << "port_handle=" << port_handle << " ctrl block exceeds limit:" << BTA_JV_MAX_RFC_CONN; + log::error("port_handle={} ctrl block exceeds limit:{}", port_handle, + BTA_JV_MAX_RFC_CONN); } return p_cb; } @@ -285,8 +289,7 @@ tBTA_JV_RFC_CB* bta_jv_rfc_port_to_cb(uint16_t port_handle) { handle &= ~BTA_JV_RFCOMM_MASK; if (handle) p_cb = &bta_jv_cb.rfc_cb[handle - 1]; } else { - LOG(WARNING) << __func__ - << ": jv handle not found port_handle:" << port_handle; + log::warn("jv handle not found port_handle:{}", port_handle); } return p_cb; } @@ -298,48 +301,47 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB* p_cb, int close_pending = 0; if (!p_cb || !p_pcb) { - LOG(ERROR) << __func__ << " p_cb or p_pcb cannot be null"; + log::error("p_cb or p_pcb cannot be null"); return BTA_JV_FAILURE; } - VLOG(2) << __func__ << ": max_sess=" << p_cb->max_sess - << ", curr_sess=" << p_cb->curr_sess << ", p_pcb=" << p_pcb - << ", user=" << p_pcb->rfcomm_slot_id << ", state=" << p_pcb->state - << ", jv handle=" << loghex(p_pcb->handle); + log::verbose( + "max_sess={}, curr_sess={}, p_pcb={}, user={}, state={}, jv handle={}", + p_cb->max_sess, p_cb->curr_sess, fmt::ptr(p_pcb), p_pcb->rfcomm_slot_id, + p_pcb->state, loghex(p_pcb->handle)); if (p_cb->curr_sess <= 0) return BTA_JV_SUCCESS; switch (p_pcb->state) { case BTA_JV_ST_CL_CLOSING: case BTA_JV_ST_SR_CLOSING: - LOG(WARNING) << __func__ - << ": return on closing, port state=" << p_pcb->state - << ", scn=" << p_cb->scn << ", p_pcb=" << p_pcb - << ", user_data=" << p_pcb->rfcomm_slot_id; + log::warn( + "return on closing, port state={}, scn={}, p_pcb={}, user_data={}", + p_pcb->state, p_cb->scn, fmt::ptr(p_pcb), p_pcb->rfcomm_slot_id); status = BTA_JV_FAILURE; return status; case BTA_JV_ST_CL_OPEN: case BTA_JV_ST_CL_OPENING: - VLOG(2) << __func__ << ": state=" << p_pcb->state << ", scn=" << p_cb->scn - << ", user_data=" << p_pcb->rfcomm_slot_id; + log::verbose("state={}, scn={}, user_data={}", p_pcb->state, p_cb->scn, + p_pcb->rfcomm_slot_id); p_pcb->state = BTA_JV_ST_CL_CLOSING; break; case BTA_JV_ST_SR_LISTEN: p_pcb->state = BTA_JV_ST_SR_CLOSING; remove_server = true; - VLOG(2) << __func__ << ": state: BTA_JV_ST_SR_LISTEN, scn=" << p_cb->scn - << ", user_data=" << p_pcb->rfcomm_slot_id; + log::verbose("state: BTA_JV_ST_SR_LISTEN, scn={}, user_data={}", + p_cb->scn, p_pcb->rfcomm_slot_id); break; case BTA_JV_ST_SR_OPEN: p_pcb->state = BTA_JV_ST_SR_CLOSING; - VLOG(2) << ": state: BTA_JV_ST_SR_OPEN, scn=" << p_cb->scn - << " user_data=" << p_pcb->rfcomm_slot_id; + log::verbose(": state: BTA_JV_ST_SR_OPEN, scn={} user_data={}", p_cb->scn, + p_pcb->rfcomm_slot_id); break; default: - LOG(WARNING) << __func__ << ":failed, ignore port state= " << p_pcb->state - << ", scn=" << p_cb->scn << ", p_pcb= " << p_pcb - << ", jv handle=" << loghex(p_pcb->handle) - << ", port_handle=" << p_pcb->port_handle - << ", user_data=" << p_pcb->rfcomm_slot_id; + log::warn( + "failed, ignore port state= {}, scn={}, p_pcb= {}, jv handle={}, " + "port_handle={}, user_data={}", + p_pcb->state, p_cb->scn, fmt::ptr(p_pcb), loghex(p_pcb->handle), + p_pcb->port_handle, p_pcb->rfcomm_slot_id); status = BTA_JV_FAILURE; break; } @@ -352,11 +354,11 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB* p_cb, port_status = RFCOMM_RemoveServer(p_pcb->port_handle); if (port_status != PORT_SUCCESS) { status = BTA_JV_FAILURE; - LOG(WARNING) << __func__ << ": Remove jv handle=" << loghex(p_pcb->handle) - << ", state=" << p_pcb->state - << ", port_status=" << port_status - << ", port_handle=" << p_pcb->port_handle - << ", close_pending=" << close_pending; + log::warn( + "Remove jv handle={}, state={}, port_status={}, port_handle={}, " + "close_pending={}", + loghex(p_pcb->handle), p_pcb->state, port_status, p_pcb->port_handle, + close_pending); } } if (!close_pending) { @@ -459,10 +461,10 @@ static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(uint32_t jv_handle) { appid_counter++; } - VLOG(2) << __func__ << ": jv_handle=" << loghex(jv_handle) - << ", idx=" << i << "app_id=" << bta_jv_cb.pm_cb[i].app_id - << ", bd_counter=" << bd_counter - << ", appid_counter=" << appid_counter; + log::verbose( + "jv_handle={}, idx={}app_id={}, bd_counter={}, appid_counter={}", + loghex(jv_handle), i, bta_jv_cb.pm_cb[i].app_id, bd_counter, + appid_counter); if (bd_counter > 1) { bta_jv_pm_conn_idle(&bta_jv_cb.pm_cb[i]); } @@ -484,9 +486,8 @@ static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(uint32_t jv_handle) { bta_jv_rfc_port_to_pcb(bta_jv_cb.rfc_cb[hi].rfc_hdl[si]); if (p_pcb) { if (NULL == p_pcb->p_pm_cb) - LOG(WARNING) << __func__ << ": jv_handle=" << loghex(jv_handle) - << ", port_handle=" << p_pcb->port_handle - << ", i=" << i << ", no link to pm_cb?"; + log::warn("jv_handle={}, port_handle={}, i={}, no link to pm_cb?", + loghex(jv_handle), p_pcb->port_handle, i); p_cb = &p_pcb->p_pm_cb; } } @@ -494,8 +495,8 @@ static tBTA_JV_STATUS bta_jv_free_set_pm_profile_cb(uint32_t jv_handle) { if (jv_handle < BTA_JV_MAX_L2C_CONN) { tBTA_JV_L2C_CB* p_l2c_cb = &bta_jv_cb.l2c_cb[jv_handle]; if (NULL == p_l2c_cb->p_pm_cb) - LOG(WARNING) << __func__ << ": jv_handle=" << loghex(jv_handle) - << ", i=" << i << " no link to pm_cb?"; + log::warn("jv_handle={}, i={} no link to pm_cb?", loghex(jv_handle), + i); p_cb = &p_l2c_cb->p_pm_cb; } } @@ -555,10 +556,9 @@ static tBTA_JV_PM_CB* bta_jv_alloc_set_pm_profile_cb(uint32_t jv_handle, } } } - VLOG(2) << __func__ << ": handle=" << loghex(jv_handle) - << ", app_id=" << app_id << ", idx=" << i - << ", BTA_JV_PM_MAX_NUM=" << BTA_JV_PM_MAX_NUM - << ", pp_cb=" << pp_cb; + log::verbose( + "handle={}, app_id={}, idx={}, BTA_JV_PM_MAX_NUM={}, pp_cb={}", + loghex(jv_handle), app_id, i, BTA_JV_PM_MAX_NUM, fmt::ptr(pp_cb)); break; } } @@ -571,8 +571,7 @@ static tBTA_JV_PM_CB* bta_jv_alloc_set_pm_profile_cb(uint32_t jv_handle, bta_jv_cb.pm_cb[i].state = BTA_JV_PM_IDLE_ST; return &bta_jv_cb.pm_cb[i]; } - LOG(WARNING) << __func__ << ": handle=" << loghex(jv_handle) - << ", app_id=" << app_id << ", return NULL"; + log::warn("handle={}, app_id={}, return NULL", loghex(jv_handle), app_id); return NULL; } @@ -645,7 +644,7 @@ void bta_jv_enable(tBTA_JV_DM_CBACK* p_cback) { } /** Disables the BT device manager free the resources used by java */ -void bta_jv_disable() { LOG(INFO) << __func__; } +void bta_jv_disable() { log::info(""); } /** * We keep a list of PSM's that have been freed from JAVA, for reuse. @@ -659,7 +658,7 @@ static uint16_t bta_jv_get_free_psm() { for (int i = 0; i < cnt; i++) { uint16_t psm = bta_jv_cb.free_psm_list[i]; if (psm != 0) { - VLOG(2) << __func__ << ": Reusing PSM=" << loghex(psm); + log::verbose("Reusing PSM={}", loghex(psm)); bta_jv_cb.free_psm_list[i] = 0; return psm; } @@ -680,10 +679,9 @@ static void bta_jv_set_free_psm(uint16_t psm) { } if (free_index != -1) { bta_jv_cb.free_psm_list[free_index] = psm; - VLOG(2) << __func__ << ": Recycling PSM=" << loghex(psm); + log::verbose("Recycling PSM={}", loghex(psm)); } else { - LOG(ERROR) << __func__ << ": unable to free psm=" << loghex(psm) - << " no more free slots"; + log::error("unable to free psm={} no more free slots", loghex(psm)); } } @@ -726,12 +724,12 @@ void bta_jv_get_channel_id( if (BTA_TryAllocateSCN(channel)) { scn = static_cast(channel); } else { - LOG_ERROR("rfc channel %u already in use or invalid", channel); + log::error("rfc channel {} already in use or invalid", channel); } } else { scn = BTA_AllocateSCN(); if (scn == 0) { - LOG_ERROR("out of rfc channels"); + log::error("out of rfc channels"); } } if (bta_jv_cb.p_dm_cback) { @@ -745,13 +743,13 @@ void bta_jv_get_channel_id( psm = bta_jv_get_free_psm(); if (psm == 0) { psm = bta_jv_allocate_l2cap_classic_psm(); - VLOG(2) << __func__ << ": returned PSM=" << loghex(psm); + log::verbose("returned PSM={}", loghex(psm)); } break; case BTA_JV_CONN_TYPE_L2CAP_LE: psm = L2CA_AllocateLePSM(); if (psm == 0) { - LOG(ERROR) << __func__ << ": Error: No free LE PSM available"; + log::error("Error: No free LE PSM available"); } break; default: @@ -776,7 +774,7 @@ void bta_jv_free_scn(int32_t type /* One of BTA_JV_CONN_TYPE_ */, bta_jv_set_free_psm(scn); break; case BTA_JV_CONN_TYPE_L2CAP_LE: - VLOG(2) << __func__ << ": type=BTA_JV_CONN_TYPE_L2CAP_LE. psm=" << scn; + log::verbose("type=BTA_JV_CONN_TYPE_L2CAP_LE. psm={}", scn); L2CA_FreeLePSM(scn); break; default: @@ -800,7 +798,7 @@ static void bta_jv_start_discovery_cback(UNUSED_ATTR const RawAddress& bd_addr, uint32_t* p_rfcomm_slot_id = static_cast(const_cast(user_data)); - VLOG(2) << __func__ << ": res=" << loghex(static_cast(result)); + log::verbose("res={}", loghex(static_cast(result))); bta_jv_cb.sdp_active = BTA_JV_SDP_ACT_NONE; if (bta_jv_cb.p_dm_cback) { @@ -810,10 +808,10 @@ static void bta_jv_start_discovery_cback(UNUSED_ATTR const RawAddress& bd_addr, if (result == SDP_SUCCESS || result == SDP_DB_FULL) { tSDP_DISC_REC* p_sdp_rec = NULL; tSDP_PROTOCOL_ELEM pe; - VLOG(2) << __func__ << ": bta_jv_cb.uuid=" << bta_jv_cb.uuid; + log::verbose("bta_jv_cb.uuid={}", bta_jv_cb.uuid); p_sdp_rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb( p_bta_jv_cfg->p_sdp_db, bta_jv_cb.uuid, p_sdp_rec); - VLOG(2) << __func__ << ": p_sdp_rec=" << p_sdp_rec; + log::verbose("p_sdp_rec={}", fmt::ptr(p_sdp_rec)); if (p_sdp_rec && get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec( p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) { @@ -835,7 +833,7 @@ void bta_jv_start_discovery(const RawAddress& bd_addr, uint16_t num_uuid, bluetooth::Uuid* uuid_list, uint32_t rfcomm_slot_id) { tBTA_JV_STATUS status = BTA_JV_FAILURE; - VLOG(2) << __func__ << ": in, sdp_active=" << bta_jv_cb.sdp_active; + log::verbose("in, sdp_active={}", bta_jv_cb.sdp_active); if (bta_jv_cb.sdp_active != BTA_JV_SDP_ACT_NONE) { /* SDP is still in progress */ status = BTA_JV_BUSY; @@ -848,7 +846,7 @@ void bta_jv_start_discovery(const RawAddress& bd_addr, uint16_t num_uuid, } /* init the database/set up the filter */ - VLOG(2) << __func__ << ": call SDP_InitDiscoveryDb, num_uuid=" << num_uuid; + log::verbose("call SDP_InitDiscoveryDb, num_uuid={}", num_uuid); get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb( p_bta_jv_cfg->p_sdp_db, p_bta_jv_cfg->sdp_db_size, num_uuid, uuid_list, 0, NULL); @@ -917,8 +915,7 @@ static void bta_jv_l2cap_client_cback(uint16_t gap_handle, uint16_t event, if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) return; - VLOG(2) << __func__ << ": gap_handle=" << gap_handle - << ", evt=" << loghex(event); + log::verbose("gap_handle={}, evt={}", gap_handle, loghex(event)); evt_data.l2c_open.status = BTA_JV_SUCCESS; evt_data.l2c_open.handle = gap_handle; @@ -967,9 +964,9 @@ static void bta_jv_l2cap_client_cback(uint16_t gap_handle, uint16_t event, } /* makes an l2cap client connection */ -void bta_jv_l2cap_connect(int32_t type, tBTA_SEC sec_mask, tBTA_JV_ROLE role, - uint16_t remote_psm, uint16_t rx_mtu, - const RawAddress& peer_bd_addr, +void bta_jv_l2cap_connect(int32_t type, tBTA_SEC sec_mask, + tBTA_JV_ROLE /* role */, uint16_t remote_psm, + uint16_t rx_mtu, const RawAddress& peer_bd_addr, std::unique_ptr cfg_param, std::unique_ptr ertm_info, tBTA_JV_L2CAP_CBACK* p_cback, @@ -1055,7 +1052,7 @@ void bta_jv_l2cap_close(uint32_t handle, tBTA_JV_L2C_CB* p_cb) { * ******************************************************************************/ static void bta_jv_l2cap_server_cback(uint16_t gap_handle, uint16_t event, - tGAP_CB_DATA* data) { + tGAP_CB_DATA* /* data */) { tBTA_JV_L2C_CB* p_cb = &bta_jv_cb.l2c_cb[gap_handle]; tBTA_JV evt_data; tBTA_JV_L2CAP_CBACK* p_cback; @@ -1063,8 +1060,7 @@ static void bta_jv_l2cap_server_cback(uint16_t gap_handle, uint16_t event, if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) return; - VLOG(2) << __func__ << ": gap_handle=" << gap_handle - << ", evt=" << loghex(event); + log::verbose("gap_handle={}, evt={}", gap_handle, loghex(event)); evt_data.l2c_open.status = BTA_JV_SUCCESS; evt_data.l2c_open.handle = gap_handle; @@ -1112,7 +1108,7 @@ static void bta_jv_l2cap_server_cback(uint16_t gap_handle, uint16_t event, /** starts an L2CAP server */ void bta_jv_l2cap_start_server(int32_t type, tBTA_SEC sec_mask, - tBTA_JV_ROLE role, uint16_t local_psm, + tBTA_JV_ROLE /* role */, uint16_t local_psm, uint16_t rx_mtu, std::unique_ptr cfg_param, std::unique_ptr ertm_info, @@ -1168,7 +1164,8 @@ void bta_jv_l2cap_start_server(int32_t type, tBTA_SEC sec_mask, } /* stops an L2CAP server */ -void bta_jv_l2cap_stop_server(uint16_t local_psm, uint32_t l2cap_socket_id) { +void bta_jv_l2cap_stop_server(uint16_t /* local_psm */, + uint32_t l2cap_socket_id) { for (int i = 0; i < BTA_JV_MAX_L2C_CONN; i++) { if (bta_jv_cb.l2c_cb[i].l2cap_socket_id == l2cap_socket_id) { tBTA_JV_L2C_CB* p_cb = &bta_jv_cb.l2c_cb[i]; @@ -1209,7 +1206,7 @@ void bta_jv_l2cap_write(uint32_t handle, uint32_t req_id, BT_HDR* msg, /* As this pointer is checked in the API function, this occurs only when the * channel is disconnected after the API function is called, but before the * message is handled. */ - LOG(ERROR) << __func__ << ": p_cb->p_cback == NULL"; + log::error("p_cb->p_cback == NULL"); osi_free(msg); return; } @@ -1252,15 +1249,15 @@ static int bta_jv_port_data_co_cback(uint16_t port_handle, uint8_t* buf, uint16_t len, int type) { tBTA_JV_RFC_CB* p_cb = bta_jv_rfc_port_to_cb(port_handle); tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle); - VLOG(2) << __func__ << ": p_cb=" << p_cb << ", p_pcb=" << p_pcb - << ", len=" << len << ", type=" << type; + log::verbose("p_cb={}, p_pcb={}, len={}, type={}", fmt::ptr(p_cb), + fmt::ptr(p_pcb), len, type); if (p_pcb != NULL) { switch (type) { case DATA_CO_CALLBACK_TYPE_INCOMING: - // Exit sniff mode when receiving data by sysproxy + // Reset sniff timer when receiving data by sysproxy if (osi_property_get_bool("bluetooth.rfcomm.sysproxy.rx.exit_sniff", false)) { - bta_jv_pm_conn_busy(p_pcb->p_pm_cb); + bta_jv_reset_sniff_timer(p_pcb->p_pm_cb); } return bta_co_rfc_data_incoming(p_pcb->rfcomm_slot_id, (BT_HDR*)buf); case DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE: @@ -1268,7 +1265,7 @@ static int bta_jv_port_data_co_cback(uint16_t port_handle, uint8_t* buf, case DATA_CO_CALLBACK_TYPE_OUTGOING: return bta_co_rfc_data_outgoing(p_pcb->rfcomm_slot_id, buf, len); default: - LOG(ERROR) << __func__ << ": unknown callout type=" << type; + log::error("unknown callout type={}", type); break; } } @@ -1293,11 +1290,11 @@ static void bta_jv_port_mgmt_cl_cback(uint32_t code, uint16_t port_handle) { uint16_t lcid; tBTA_JV_RFCOMM_CBACK* p_cback; /* the callback function */ - VLOG(2) << __func__ << ": code=" << code << ", port_handle=" << port_handle; + log::verbose("code={}, port_handle={}", code, port_handle); if (NULL == p_cb || NULL == p_cb->p_cback) return; - VLOG(2) << __func__ << ": code=" << code << ", port_handle=" << port_handle - << ", handle=" << p_cb->handle; + log::verbose("code={}, port_handle={}, handle={}", code, port_handle, + p_cb->handle); PORT_CheckConnection(port_handle, &rem_bda, &lcid); @@ -1337,11 +1334,11 @@ static void bta_jv_port_event_cl_cback(uint32_t code, uint16_t port_handle) { tBTA_JV_PCB* p_pcb = bta_jv_rfc_port_to_pcb(port_handle); tBTA_JV evt_data; - VLOG(2) << __func__ << ": port_handle=" << port_handle; + log::verbose("port_handle={}", port_handle); if (NULL == p_cb || NULL == p_cb->p_cback) return; - VLOG(2) << __func__ << ": code=" << loghex(code) - << ", port_handle=" << port_handle << ", handle=" << p_cb->handle; + log::verbose("code={}, port_handle={}, handle={}", loghex(code), port_handle, + p_cb->handle); if (code & PORT_EV_RXCHAR) { evt_data.data_ind.handle = p_cb->handle; p_cb->p_cback(BTA_JV_RFCOMM_DATA_IND_EVT, &evt_data, p_pcb->rfcomm_slot_id); @@ -1372,12 +1369,27 @@ void bta_jv_rfcomm_connect(tBTA_SEC sec_mask, uint8_t remote_scn, tBTA_JV_RFCOMM_CL_INIT evt_data; memset(&evt_data, 0, sizeof(evt_data)); evt_data.status = BTA_JV_SUCCESS; + +#ifdef TARGET_FLOSS + if (true) +#else + if (IS_FLAG_ENABLED(rfcomm_always_use_mitm)) +#endif + { + // Update security service record for RFCOMM client so that + // secure RFCOMM connection will be authenticated with MTIM protection + // while creating the L2CAP connection. + get_btm_client_interface().security.BTM_SetSecurityLevel( + true, "RFC_MUX", BTM_SEC_SERVICE_RFC_MUX, sec_mask, BT_PSM_RFCOMM, + BTM_SEC_PROTO_RFCOMM, 0); + } + if (evt_data.status == BTA_JV_SUCCESS && RFCOMM_CreateConnectionWithSecurity( UUID_SERVCLASS_SERIAL_PORT, remote_scn, false, BTA_JV_DEF_RFC_MTU, peer_bd_addr, &handle, bta_jv_port_mgmt_cl_cback, sec_mask) != PORT_SUCCESS) { - LOG(ERROR) << __func__ << ": RFCOMM_CreateConnection failed"; + log::error("RFCOMM_CreateConnection failed"); evt_data.status = BTA_JV_FAILURE; } if (evt_data.status == BTA_JV_SUCCESS) { @@ -1403,7 +1415,7 @@ void bta_jv_rfcomm_connect(tBTA_SEC sec_mask, uint8_t remote_scn, evt_data.handle = p_cb->handle; } else { evt_data.status = BTA_JV_FAILURE; - LOG(ERROR) << __func__ << ": run out of rfc control block"; + log::error("run out of rfc control block"); } } tBTA_JV bta_jv; @@ -1425,26 +1437,26 @@ static int find_rfc_pcb(uint32_t rfcomm_slot_id, tBTA_JV_RFC_CB** cb, if (rfc_handle && bta_jv_cb.port_cb[i].rfcomm_slot_id == rfcomm_slot_id) { *pcb = &bta_jv_cb.port_cb[i]; *cb = &bta_jv_cb.rfc_cb[rfc_handle - 1]; - VLOG(2) << __func__ << ": FOUND rfc_cb_handle=" << loghex(rfc_handle) - << ", port.jv_handle=" << loghex((*pcb)->handle) - << ", state=" << (*pcb)->state - << ", rfc_cb->handle=" << loghex((*cb)->handle); + log::verbose( + "FOUND rfc_cb_handle={}, port.jv_handle={}, state={}, " + "rfc_cb->handle={}", + loghex(rfc_handle), loghex((*pcb)->handle), (*pcb)->state, + loghex((*cb)->handle)); return 1; } } - VLOG(2) << __func__ - << ": cannot find rfc_cb from user data:" << rfcomm_slot_id; + log::verbose("cannot find rfc_cb from user data:{}", rfcomm_slot_id); return 0; } /* Close an RFCOMM connection */ void bta_jv_rfcomm_close(uint32_t handle, uint32_t rfcomm_slot_id) { if (!handle) { - LOG(ERROR) << __func__ << ": rfc handle is null"; + log::error("rfc handle is null"); return; } - VLOG(2) << __func__ << ": rfc handle=" << handle; + log::verbose("rfc handle={}", handle); tBTA_JV_RFC_CB* p_cb = NULL; tBTA_JV_PCB* p_pcb = NULL; @@ -1469,24 +1481,25 @@ static void bta_jv_port_mgmt_sr_cback(uint32_t code, uint16_t port_handle) { tBTA_JV evt_data; RawAddress rem_bda = RawAddress::kEmpty; uint16_t lcid; - VLOG(2) << __func__ << ": code=" << code << ", port_handle=" << port_handle; + log::verbose("code={}, port_handle={}", code, port_handle); if (NULL == p_cb || NULL == p_cb->p_cback) { - LOG(ERROR) << __func__ << ": p_cb=" << p_cb - << ", p_cb->p_cback=" << (p_cb ? p_cb->p_cback : 0); + log::error("p_cb={}, p_cb->p_cback={}", fmt::ptr(p_cb), + fmt::ptr(p_cb ? p_cb->p_cback : nullptr)); return; } uint32_t rfcomm_slot_id = p_pcb->rfcomm_slot_id; - VLOG(2) << __func__ << ": code=" << code - << ", port_handle=" << loghex(port_handle) - << ", handle=" << loghex(p_cb->handle) << ", p_pcb" << p_pcb - << ", user=" << p_pcb->rfcomm_slot_id; + log::verbose("code={}, port_handle={}, handle={}, p_pcb{}, user={}", code, + loghex(port_handle), loghex(p_cb->handle), fmt::ptr(p_pcb), + p_pcb->rfcomm_slot_id); int status = PORT_CheckConnection(port_handle, &rem_bda, &lcid); int failed = true; if (code == PORT_SUCCESS) { if (status != PORT_SUCCESS) { - LOG(ERROR) << __func__ << ": PORT_CheckConnection returned " << status - << ", although port is supposed to be connected"; + log::error( + "PORT_CheckConnection returned {}, although port is supposed to be " + "connected", + status); } evt_data.rfc_srv_open.handle = p_pcb->handle; evt_data.rfc_srv_open.status = BTA_JV_SUCCESS; @@ -1497,15 +1510,14 @@ static void bta_jv_port_mgmt_sr_cback(uint32_t code, uint16_t port_handle) { p_pcb_new_listen->rfcomm_slot_id = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, rfcomm_slot_id); if (p_pcb_new_listen->rfcomm_slot_id == 0) { - LOG(ERROR) << __func__ << ": rfcomm_slot_id == " - << p_pcb_new_listen->rfcomm_slot_id; + log::error("rfcomm_slot_id == {}", p_pcb_new_listen->rfcomm_slot_id); } else { - VLOG(2) << __func__ << ": curr_sess=" << p_cb->curr_sess - << ", max_sess=" << p_cb->max_sess; + log::verbose("curr_sess={}, max_sess={}", p_cb->curr_sess, + p_cb->max_sess); failed = false; } } else - LOG(ERROR) << __func__ << ": failed to create new listen port"; + log::error("failed to create new listen port"); } if (failed) { evt_data.rfc_close.handle = p_cb->handle; @@ -1515,9 +1527,9 @@ static void bta_jv_port_mgmt_sr_cback(uint32_t code, uint16_t port_handle) { p_pcb->cong = false; tBTA_JV_RFCOMM_CBACK* p_cback = p_cb->p_cback; - VLOG(2) << __func__ - << ": PORT_CLOSED before BTA_JV_RFCOMM_CLOSE_EVT: curr_sess=" - << p_cb->curr_sess << ", max_sess=" << p_cb->max_sess; + log::verbose( + "PORT_CLOSED before BTA_JV_RFCOMM_CLOSE_EVT: curr_sess={}, max_sess={}", + p_cb->curr_sess, p_cb->max_sess); if (BTA_JV_ST_SR_CLOSING == p_pcb->state) { evt_data.rfc_close.async = false; evt_data.rfc_close.status = BTA_JV_SUCCESS; @@ -1526,9 +1538,9 @@ static void bta_jv_port_mgmt_sr_cback(uint32_t code, uint16_t port_handle) { p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, rfcomm_slot_id); // bta_jv_free_rfc_cb(p_cb, p_pcb); - VLOG(2) << __func__ - << ": PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess=" - << p_cb->curr_sess << ", max_sess=" << p_cb->max_sess; + log::verbose( + "PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess={}, max_sess={}", + p_cb->curr_sess, p_cb->max_sess); } } @@ -1547,13 +1559,13 @@ static void bta_jv_port_event_sr_cback(uint32_t code, uint16_t port_handle) { tBTA_JV evt_data; if (NULL == p_cb || NULL == p_cb->p_cback) { - LOG(ERROR) << __func__ << ": p_cb=" << p_cb - << ", p_cb->p_cback=" << (p_cb ? p_cb->p_cback : 0); + log::error("p_cb={}, p_cb->p_cback={}", fmt::ptr(p_cb), + fmt::ptr(p_cb ? p_cb->p_cback : nullptr)); return; } - VLOG(2) << __func__ << ": code=" << loghex(code) - << ", port_handle=" << port_handle << ", handle=" << p_cb->handle; + log::verbose("code={}, port_handle={}, handle={}", loghex(code), port_handle, + p_cb->handle); uint32_t user_data = p_pcb->rfcomm_slot_id; if (code & PORT_EV_RXCHAR) { @@ -1598,15 +1610,15 @@ static tBTA_JV_PCB* bta_jv_add_rfc_port(tBTA_JV_RFC_CB* p_cb, if (p_pcb->state == BTA_JV_ST_SR_LISTEN) { listen++; if (p_pcb_open == p_pcb) { - VLOG(2) << __func__ << ": port_handle=" << p_pcb->port_handle - << ", change the listen port to open state"; + log::verbose("port_handle={}, change the listen port to open state", + p_pcb->port_handle); p_pcb->state = BTA_JV_ST_SR_OPEN; } else { - LOG(ERROR) << __func__ - << ": open pcb not matching listen one, count=" << listen - << ", listen pcb handle=" << p_pcb->port_handle - << ", open pcb=" << p_pcb_open->handle; + log::error( + "open pcb not matching listen one, count={}, listen pcb " + "handle={}, open pcb={}", + listen, p_pcb->port_handle, p_pcb_open->handle); return NULL; } } @@ -1616,15 +1628,13 @@ static tBTA_JV_PCB* bta_jv_add_rfc_port(tBTA_JV_RFC_CB* p_cb, } } - VLOG(2) << __func__ << ": max_sess=" << p_cb->max_sess << ", used=" << used - << ", curr_sess=" << p_cb->curr_sess << ", listen=" << listen - << ", si=" << si; + log::verbose("max_sess={}, used={}, curr_sess={}, listen={}, si={}", + p_cb->max_sess, used, p_cb->curr_sess, listen, si); if (used < p_cb->max_sess && listen == 1 && si) { si--; if (PORT_GetSecurityMask(p_pcb_open->port_handle, &sec_mask) != PORT_SUCCESS) { - LOG(ERROR) << __func__ - << ": RFCOMM_CreateConnection failed: invalid port_handle"; + log::error("RFCOMM_CreateConnection failed: invalid port_handle"); } if (RFCOMM_CreateConnectionWithSecurity( @@ -1647,19 +1657,19 @@ static tBTA_JV_PCB* bta_jv_add_rfc_port(tBTA_JV_RFC_CB* p_cb, PORT_SetState(p_pcb->port_handle, &port_state); p_pcb->handle = BTA_JV_RFC_H_S_TO_HDL(p_cb->handle, si); - VLOG(2) << __func__ << ": p_pcb->handle=" << loghex(p_pcb->handle) - << ", curr_sess=" << p_cb->curr_sess; + log::verbose("p_pcb->handle={}, curr_sess={}", loghex(p_pcb->handle), + p_cb->curr_sess); } else { - LOG(ERROR) << __func__ << ": RFCOMM_CreateConnection failed"; + log::error("RFCOMM_CreateConnection failed"); return NULL; } } else { - LOG(ERROR) << __func__ << ": cannot create new rfc listen port"; + log::error("cannot create new rfc listen port"); return NULL; } } - VLOG(2) << __func__ << ": sec id in use=" << get_sec_id_used() - << ", rfc_cb in use=" << get_rfc_cb_used(); + log::verbose("sec id in use={}, rfc_cb in use={}", get_sec_id_used(), + get_rfc_cb_used()); return p_pcb; } @@ -1682,13 +1692,13 @@ void bta_jv_rfcomm_start_server(tBTA_SEC sec_mask, uint8_t local_scn, if (RFCOMM_CreateConnectionWithSecurity( 0, local_scn, true, BTA_JV_DEF_RFC_MTU, RawAddress::kAny, &handle, bta_jv_port_mgmt_sr_cback, sec_mask) != PORT_SUCCESS) { - LOG(ERROR) << __func__ << ": RFCOMM_CreateConnection failed"; + log::error("RFCOMM_CreateConnection failed"); break; } p_cb = bta_jv_alloc_rfc_cb(handle, &p_pcb); if (!p_cb) { - LOG(ERROR) << __func__ << ": run out of rfc control block"; + log::error("run out of rfc control block"); break; } @@ -1724,17 +1734,17 @@ void bta_jv_rfcomm_start_server(tBTA_SEC sec_mask, uint8_t local_scn, /* stops an RFCOMM server */ void bta_jv_rfcomm_stop_server(uint32_t handle, uint32_t rfcomm_slot_id) { if (!handle) { - LOG(ERROR) << __func__ << ": jv handle is null"; + log::error("jv handle is null"); return; } - VLOG(2) << __func__; + log::verbose(""); tBTA_JV_RFC_CB* p_cb = NULL; tBTA_JV_PCB* p_pcb = NULL; if (!find_rfc_pcb(rfcomm_slot_id, &p_cb, &p_pcb)) return; - VLOG(2) << __func__ << ": p_pcb=" << p_pcb - << ", p_pcb->port_handle=" << p_pcb->port_handle; + log::verbose("p_pcb={}, p_pcb->port_handle={}", fmt::ptr(p_pcb), + p_pcb->port_handle); bta_jv_free_rfc_cb(p_cb, p_pcb); } @@ -1742,7 +1752,7 @@ void bta_jv_rfcomm_stop_server(uint32_t handle, uint32_t rfcomm_slot_id) { void bta_jv_rfcomm_write(uint32_t handle, uint32_t req_id, tBTA_JV_RFC_CB* p_cb, tBTA_JV_PCB* p_pcb) { if (p_pcb->state == BTA_JV_ST_NONE) { - LOG(ERROR) << __func__ << ": in state BTA_JV_ST_NONE - cannot write"; + log::error("in state BTA_JV_ST_NONE - cannot write"); return; } @@ -1764,7 +1774,7 @@ void bta_jv_rfcomm_write(uint32_t handle, uint32_t req_id, tBTA_JV_RFC_CB* p_cb, evt_data.cong = p_pcb->cong; if (!p_cb->p_cback) { - LOG(ERROR) << __func__ << ": No JV callback set"; + log::error("No JV callback set"); return; } @@ -1779,15 +1789,15 @@ void bta_jv_set_pm_profile(uint32_t handle, tBTA_JV_PM_ID app_id, tBTA_JV_STATUS status; tBTA_JV_PM_CB* p_cb; - VLOG(2) << __func__ << " handle=" << loghex(handle) << ", app_id=" << app_id - << ", init_st=" << +init_st; + log::verbose("handle={}, app_id={}, init_st={}", loghex(handle), app_id, + init_st); /* clear PM control block */ if (app_id == BTA_JV_PM_ID_CLEAR) { status = bta_jv_free_set_pm_profile_cb(handle); if (status != BTA_JV_SUCCESS) { - LOG(WARNING) << __func__ << ": free pm cb failed: reason=" << +status; + log::warn("free pm cb failed: reason={}", status); } } else /* set PM control block */ { @@ -1796,7 +1806,7 @@ void bta_jv_set_pm_profile(uint32_t handle, tBTA_JV_PM_ID app_id, if (NULL != p_cb) bta_jv_pm_state_change(p_cb, init_st); else - LOG(WARNING) << __func__ << ": failed"; + log::warn("failed"); } } @@ -1845,10 +1855,9 @@ static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB* p_cb) { ******************************************************************************/ static void bta_jv_pm_state_change(tBTA_JV_PM_CB* p_cb, const tBTA_JV_CONN_STATE state) { - VLOG(2) << __func__ << ": p_cb=" << p_cb - << ", handle=" << loghex(p_cb->handle) - << ", busy/idle_state=" << p_cb->state << ", app_id=" << p_cb->app_id - << ", conn_state=" << state; + log::verbose( + "p_cb={}, handle={}, busy/idle_state={}, app_id={}, conn_state={}", + fmt::ptr(p_cb), loghex(p_cb->handle), p_cb->state, p_cb->app_id, state); switch (state) { case BTA_JV_CONN_OPEN: @@ -1886,8 +1895,26 @@ static void bta_jv_pm_state_change(tBTA_JV_PM_CB* p_cb, break; default: - LOG(WARNING) << __func__ << ": Invalid state=" << +state; + log::warn("Invalid state={}", state); break; } } + +/******************************************************************************* + * + * Function bta_jv_reset_sniff_timer + * + * Description reset pm sniff timer state (input param safe) + * + * Params p_cb: pm control block of jv connection + * + * Returns void + * + ******************************************************************************/ +static void bta_jv_reset_sniff_timer(tBTA_JV_PM_CB* p_cb) { + if (NULL != p_cb) { + p_cb->state = BTA_JV_PM_IDLE_ST; + bta_sys_reset_sniff(BTA_ID_JV, p_cb->app_id, p_cb->peer_bd_addr); + } +} /******************************************************************************/ diff --git a/system/bta/jv/bta_jv_api.cc b/system/bta/jv/bta_jv_api.cc index 4bae932f7e3e0964192d9cf1f5fab89fbcc26635..d8cc9dbb58c7159d9672db288211660370b7276a 100644 --- a/system/bta/jv/bta_jv_api.cc +++ b/system/bta/jv/bta_jv_api.cc @@ -26,12 +26,14 @@ #include #include #include +#include #include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/jv/bta_jv_int.h" +#include "include/check.h" +#include "internal_include/bt_target.h" #include "internal_include/bt_trace.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" @@ -42,6 +44,7 @@ using base::Bind; using bluetooth::Uuid; +using namespace bluetooth; namespace { bool bta_jv_enabled = false; @@ -62,13 +65,12 @@ bool bta_jv_enabled = false; * ******************************************************************************/ tBTA_JV_STATUS BTA_JvEnable(tBTA_JV_DM_CBACK* p_cback) { + log::verbose(""); if (!p_cback || bta_jv_enabled) { - LOG(ERROR) << __func__ << ": failure"; + log::error("failure"); return BTA_JV_FAILURE; } - VLOG(2) << __func__; - memset(&bta_jv_cb, 0, sizeof(tBTA_JV_CB)); /* set handle to invalid value by default */ for (int i = 0; i < BTA_JV_PM_MAX_NUM; i++) { @@ -85,7 +87,7 @@ tBTA_JV_STATUS BTA_JvEnable(tBTA_JV_DM_CBACK* p_cback) { /** Disable the Java I/F */ void BTA_JvDisable(void) { - VLOG(2) << __func__; + log::verbose(""); bta_jv_enabled = false; @@ -115,7 +117,7 @@ void BTA_JvDisable(void) { * ******************************************************************************/ void BTA_JvGetChannelId(int conn_type, uint32_t id, int32_t channel) { - VLOG(2) << __func__ << ": conn_type=" << conn_type; + log::verbose("conn_type:{}, id:{}, channel:{}", conn_type, id, channel); if (conn_type != BTA_JV_CONN_TYPE_RFCOMM && conn_type != BTA_JV_CONN_TYPE_L2CAP && @@ -142,7 +144,7 @@ void BTA_JvGetChannelId(int conn_type, uint32_t id, int32_t channel) { * ******************************************************************************/ tBTA_JV_STATUS BTA_JvFreeChannel(uint16_t channel, int conn_type) { - VLOG(2) << __func__; + log::verbose("channel:{}, conn_type:{}", channel, conn_type); do_in_main_thread(FROM_HERE, Bind(&bta_jv_free_scn, conn_type, channel)); return BTA_JV_SUCCESS; @@ -164,7 +166,8 @@ tBTA_JV_STATUS BTA_JvFreeChannel(uint16_t channel, int conn_type) { tBTA_JV_STATUS BTA_JvStartDiscovery(const RawAddress& bd_addr, uint16_t num_uuid, const Uuid* p_uuid_list, uint32_t rfcomm_slot_id) { - VLOG(2) << __func__; + log::verbose("bd_addr:{}, rfcomm_slot_id:{}, num_uuid:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), rfcomm_slot_id, num_uuid); Uuid* uuid_list_copy = new Uuid[num_uuid]; memcpy(uuid_list_copy, p_uuid_list, num_uuid * sizeof(Uuid)); @@ -188,7 +191,7 @@ tBTA_JV_STATUS BTA_JvStartDiscovery(const RawAddress& bd_addr, * ******************************************************************************/ tBTA_JV_STATUS BTA_JvCreateRecordByUser(uint32_t rfcomm_slot_id) { - VLOG(2) << __func__; + log::verbose("rfcomm_slot_id: {}", rfcomm_slot_id); do_in_main_thread(FROM_HERE, Bind(&bta_jv_create_record, rfcomm_slot_id)); return BTA_JV_SUCCESS; @@ -205,7 +208,7 @@ tBTA_JV_STATUS BTA_JvCreateRecordByUser(uint32_t rfcomm_slot_id) { * ******************************************************************************/ tBTA_JV_STATUS BTA_JvDeleteRecord(uint32_t handle) { - VLOG(2) << __func__; + log::verbose("handle:{}", handle); do_in_main_thread(FROM_HERE, Bind(&bta_jv_delete_record, handle)); return BTA_JV_SUCCESS; @@ -230,7 +233,11 @@ void BTA_JvL2capConnect(int conn_type, tBTA_SEC sec_mask, tBTA_JV_ROLE role, const RawAddress& peer_bd_addr, tBTA_JV_L2CAP_CBACK* p_cback, uint32_t l2cap_socket_id) { - VLOG(2) << __func__; + log::verbose( + "conn_type:{}, role:{}, remote_psm:{}, peer_bd_addr:{}, " + "l2cap_socket_id:{}", + conn_type, role, remote_psm, ADDRESS_TO_LOGGABLE_CSTR(peer_bd_addr), + l2cap_socket_id); CHECK(p_cback); do_in_main_thread(FROM_HERE, @@ -250,7 +257,7 @@ void BTA_JvL2capConnect(int conn_type, tBTA_SEC sec_mask, tBTA_JV_ROLE role, * ******************************************************************************/ tBTA_JV_STATUS BTA_JvL2capClose(uint32_t handle) { - VLOG(2) << __func__; + log::verbose("handle:{}", handle); if (handle >= BTA_JV_MAX_L2C_CONN || !bta_jv_cb.l2c_cb[handle].p_cback) return BTA_JV_FAILURE; @@ -280,7 +287,8 @@ void BTA_JvL2capStartServer(int conn_type, tBTA_SEC sec_mask, tBTA_JV_ROLE role, std::unique_ptr cfg, tBTA_JV_L2CAP_CBACK* p_cback, uint32_t l2cap_socket_id) { - VLOG(2) << __func__; + log::verbose("conn_type:{}, role:{}, local_psm:{}, l2cap_socket_id:{}", + conn_type, role, local_psm, l2cap_socket_id); CHECK(p_cback); do_in_main_thread(FROM_HERE, @@ -302,7 +310,7 @@ void BTA_JvL2capStartServer(int conn_type, tBTA_SEC sec_mask, tBTA_JV_ROLE role, ******************************************************************************/ tBTA_JV_STATUS BTA_JvL2capStopServer(uint16_t local_psm, uint32_t l2cap_socket_id) { - VLOG(2) << __func__; + log::verbose("local_psm:{}, l2cap_socket_id:{}", local_psm, l2cap_socket_id); do_in_main_thread( FROM_HERE, Bind(&bta_jv_l2cap_stop_server, local_psm, l2cap_socket_id)); @@ -323,7 +331,7 @@ tBTA_JV_STATUS BTA_JvL2capStopServer(uint16_t local_psm, ******************************************************************************/ tBTA_JV_STATUS BTA_JvL2capRead(uint32_t handle, uint32_t req_id, uint8_t* p_data, uint16_t len) { - VLOG(2) << __func__; + log::verbose("handle:{}, req_id:{}, len:{}", handle, req_id, len); if (handle >= BTA_JV_MAX_L2C_CONN || !bta_jv_cb.l2c_cb[handle].p_cback) return BTA_JV_FAILURE; @@ -358,7 +366,7 @@ tBTA_JV_STATUS BTA_JvL2capRead(uint32_t handle, uint32_t req_id, tBTA_JV_STATUS BTA_JvL2capReady(uint32_t handle, uint32_t* p_data_size) { tBTA_JV_STATUS status = BTA_JV_FAILURE; - VLOG(2) << __func__ << ": handle=" << handle; + log::verbose("handle:{}", handle); if (p_data_size && handle < BTA_JV_MAX_L2C_CONN && bta_jv_cb.l2c_cb[handle].p_cback) { *p_data_size = 0; @@ -387,7 +395,7 @@ tBTA_JV_STATUS BTA_JvL2capReady(uint32_t handle, uint32_t* p_data_size) { ******************************************************************************/ tBTA_JV_STATUS BTA_JvL2capWrite(uint32_t handle, uint32_t req_id, BT_HDR* msg, uint32_t user_id) { - VLOG(2) << __func__; + log::verbose("handle:{}, user_id:{}", handle, user_id); if (handle >= BTA_JV_MAX_L2C_CONN || !bta_jv_cb.l2c_cb[handle].p_cback) { osi_free(msg); @@ -420,7 +428,8 @@ tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask, tBTA_JV_ROLE role, const RawAddress& peer_bd_addr, tBTA_JV_RFCOMM_CBACK* p_cback, uint32_t rfcomm_slot_id) { - VLOG(2) << __func__; + log::verbose("remote_scn:{}, peer_bd_addr:{}, rfcomm_slot_id:{}", remote_scn, + ADDRESS_TO_LOGGABLE_CSTR(peer_bd_addr), rfcomm_slot_id); if (!p_cback) return BTA_JV_FAILURE; /* Nothing to do */ @@ -444,7 +453,7 @@ tBTA_JV_STATUS BTA_JvRfcommClose(uint32_t handle, uint32_t rfcomm_slot_id) { uint32_t hi = ((handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1; uint32_t si = BTA_JV_RFC_HDL_TO_SIDX(handle); - VLOG(2) << __func__; + log::verbose("handle:{}, rfcomm_slot_id:{}", handle, rfcomm_slot_id); if (hi >= BTA_JV_MAX_RFC_CONN || !bta_jv_cb.rfc_cb[hi].p_cback || si >= BTA_JV_MAX_RFC_SR_SESSION || !bta_jv_cb.rfc_cb[hi].rfc_hdl[si]) @@ -474,14 +483,13 @@ tBTA_JV_STATUS BTA_JvRfcommStartServer(tBTA_SEC sec_mask, tBTA_JV_ROLE role, uint8_t local_scn, uint8_t max_session, tBTA_JV_RFCOMM_CBACK* p_cback, uint32_t rfcomm_slot_id) { - VLOG(2) << __func__; + log::verbose("local_scn:{}, rfcomm_slot_id:{}", local_scn, rfcomm_slot_id); if (p_cback == NULL) return BTA_JV_FAILURE; /* Nothing to do */ if (max_session == 0) max_session = 1; if (max_session > BTA_JV_MAX_RFC_SR_SESSION) { - LOG(INFO) << __func__ << "max_session is too big. use max " - << BTA_JV_MAX_RFC_SR_SESSION; + log::info("max_session is too big. use max {}", BTA_JV_MAX_RFC_SR_SESSION); max_session = BTA_JV_MAX_RFC_SR_SESSION; } @@ -504,7 +512,7 @@ tBTA_JV_STATUS BTA_JvRfcommStartServer(tBTA_SEC sec_mask, tBTA_JV_ROLE role, ******************************************************************************/ tBTA_JV_STATUS BTA_JvRfcommStopServer(uint32_t handle, uint32_t rfcomm_slot_id) { - VLOG(2) << __func__; + log::verbose("handle:{}, rfcomm_slot_id:{}", handle, rfcomm_slot_id); do_in_main_thread(FROM_HERE, Bind(&bta_jv_rfcomm_stop_server, handle, rfcomm_slot_id)); @@ -515,10 +523,9 @@ tBTA_JV_STATUS BTA_JvRfcommStopServer(uint32_t handle, * * Function BTA_JvRfcommGetPortHdl * - * Description This function fetches the rfcomm port handle + * Description This function fetches the rfcomm port handle * - * Returns BTA_JV_SUCCESS, if the request is being processed. - * BTA_JV_FAILURE, otherwise. + * Returns * ******************************************************************************/ uint16_t BTA_JvRfcommGetPortHdl(uint32_t handle) { @@ -546,16 +553,13 @@ tBTA_JV_STATUS BTA_JvRfcommWrite(uint32_t handle, uint32_t req_id) { uint32_t hi = ((handle & BTA_JV_RFC_HDL_MASK) & ~BTA_JV_RFCOMM_MASK) - 1; uint32_t si = BTA_JV_RFC_HDL_TO_SIDX(handle); - VLOG(2) << __func__; - - VLOG(2) << __func__ << "handle=" << loghex(handle) << ", hi=" << hi - << ", si=" << si; + log::verbose("handle:{}, req_id:{}, hi:{}, si:{}", handle, req_id, hi, si); if (hi >= BTA_JV_MAX_RFC_CONN || !bta_jv_cb.rfc_cb[hi].p_cback || si >= BTA_JV_MAX_RFC_SR_SESSION || !bta_jv_cb.rfc_cb[hi].rfc_hdl[si]) { return BTA_JV_FAILURE; } - VLOG(2) << "write ok"; + log::verbose("write ok"); tBTA_JV_RFC_CB* p_cb = &bta_jv_cb.rfc_cb[hi]; do_in_main_thread(FROM_HERE, Bind(&bta_jv_rfcomm_write, handle, req_id, p_cb, @@ -588,7 +592,7 @@ tBTA_JV_STATUS BTA_JvRfcommWrite(uint32_t handle, uint32_t req_id) { ******************************************************************************/ tBTA_JV_STATUS BTA_JvSetPmProfile(uint32_t handle, tBTA_JV_PM_ID app_id, tBTA_JV_CONN_STATE init_st) { - VLOG(2) << __func__ << " handle=" << loghex(handle) << ", app_id:" << app_id; + log::verbose("handle:{}, app_id:{}, init_st:{}", handle, app_id, handle); do_in_main_thread(FROM_HERE, Bind(&bta_jv_set_pm_profile, handle, app_id, init_st)); diff --git a/system/bta/jv/bta_jv_cfg.cc b/system/bta/jv/bta_jv_cfg.cc index db1699c94efa32c0a00e41403b2ea5857f7b34ad..4a39a2067b7828668fe8ba84850d302b6101fe76 100644 --- a/system/bta/jv/bta_jv_cfg.cc +++ b/system/bta/jv/bta_jv_cfg.cc @@ -26,7 +26,6 @@ #include -#include "bt_target.h" // Must be first to define build configuration - #include "bta/include/bta_jv_api.h" +#include "internal_include/bt_target.h" #include "stack/include/sdp_api.h" diff --git a/system/bta/le_audio/audio_hal_client/audio_hal_client.h b/system/bta/le_audio/audio_hal_client/audio_hal_client.h index d13f662288dc410bdbc4ae1627c51f6159408433..41e9ded270e9ae7a1a5a069e60153e81f42c0c76 100644 --- a/system/bta/le_audio/audio_hal_client/audio_hal_client.h +++ b/system/bta/le_audio/audio_hal_client/audio_hal_client.h @@ -17,11 +17,10 @@ */ #pragma once -#include #include +#include #include "audio_hal_interface/le_audio_software.h" -#include "common/repeating_timer.h" namespace le_audio { /* Represents configuration of audio codec, as exchanged between le audio and diff --git a/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc b/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc index cd4914ab48140111502a83cf69fa8a74bacd3659..03967fbaaa4af5cee0d7a54199bb0c4f8151681a 100644 --- a/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc +++ b/system/bta/le_audio/audio_hal_client/audio_hal_client_test.cc @@ -177,6 +177,8 @@ void LeAudioClientInterface::Sink::StartSession() {} void LeAudioClientInterface::Sink::StopSession() {} void LeAudioClientInterface::Sink::ConfirmStreamingRequest(){}; void LeAudioClientInterface::Sink::CancelStreamingRequest(){}; +void LeAudioClientInterface::Sink::ConfirmStreamingRequestV2(){}; +void LeAudioClientInterface::Sink::CancelStreamingRequestV2(){}; void LeAudioClientInterface::Sink::UpdateAudioConfigToHal( const ::le_audio::offload_config& config){}; void LeAudioClientInterface::Sink::UpdateBroadcastAudioConfigToHal( @@ -192,6 +194,8 @@ void LeAudioClientInterface::Source::StartSession() {} void LeAudioClientInterface::Source::StopSession() {} void LeAudioClientInterface::Source::ConfirmStreamingRequest(){}; void LeAudioClientInterface::Source::CancelStreamingRequest(){}; +void LeAudioClientInterface::Source::ConfirmStreamingRequestV2(){}; +void LeAudioClientInterface::Source::CancelStreamingRequestV2(){}; void LeAudioClientInterface::Source::UpdateAudioConfigToHal( const ::le_audio::offload_config& config){}; void LeAudioClientInterface::Source::SuspendedForReconfiguration() {} diff --git a/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc b/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc index 7bb8cd7405168f5cfb9ff72da6afc7e20497bbe8..912326c3ceaf5785100506d9764298cf34dbf3e4 100644 --- a/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc +++ b/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc @@ -22,7 +22,7 @@ #include "audio_hal_interface/le_audio_software.h" #include "bta/le_audio/codec_manager.h" #include "common/time_util.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/wakelock.h" #include "stack/include/main_thread.h" @@ -261,7 +261,11 @@ void SinkImpl::ConfirmStreamingRequest() { } LOG_INFO(); - halSourceInterface_->ConfirmStreamingRequest(); + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + halSourceInterface_->ConfirmStreamingRequestV2(); + } else { + halSourceInterface_->ConfirmStreamingRequest(); + } } void SinkImpl::SuspendedForReconfiguration() { @@ -294,7 +298,11 @@ void SinkImpl::CancelStreamingRequest() { } LOG_INFO(); - halSourceInterface_->CancelStreamingRequest(); + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + halSourceInterface_->CancelStreamingRequestV2(); + } else { + halSourceInterface_->CancelStreamingRequest(); + } } void SinkImpl::UpdateRemoteDelay(uint16_t remote_delay_ms) { diff --git a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc index 1ef50f9f492c88564192fa86502a99572bc70f09..cf4b5bb761cb92a048dfd103539d1b715fecd97f 100644 --- a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc +++ b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc @@ -21,12 +21,14 @@ #include #include +#include "audio/asrc/asrc_resampler.h" #include "audio_hal_client.h" #include "audio_hal_interface/le_audio_software.h" -#include "audio_source_hal_asrc.h" #include "bta/le_audio/codec_manager.h" +#include "common/repeating_timer.h" #include "common/time_util.h" -#include "osi/include/log.h" +#include "gd/hal/link_clocker.h" +#include "os/log.h" #include "osi/include/wakelock.h" #include "stack/include/main_thread.h" @@ -100,7 +102,7 @@ class SourceImpl : public LeAudioSourceAudioHalClient { nullptr; LeAudioSourceAudioHalClient::Callbacks* audioSourceCallbacks_ = nullptr; std::mutex audioSourceCallbacksMutex_; - std::unique_ptr asrc_; + std::unique_ptr asrc_; }; bool SourceImpl::Acquire() { @@ -246,19 +248,16 @@ bool SourceImpl::InitAudioSinkThread() { void SourceImpl::StartAudioTicks() { wakelock_acquire(); if (IS_FLAG_ENABLED(leaudio_hal_client_asrc)) { - asrc_ = std::make_unique( + asrc_ = std::make_unique( + std::make_shared(), source_codec_config_.num_channels, source_codec_config_.sample_rate, source_codec_config_.bits_per_sample, source_codec_config_.data_interval_us); } audio_timer_.SchedulePeriodic( worker_thread_->GetWeakPtr(), FROM_HERE, - base::Bind(&SourceImpl::SendAudioData, base::Unretained(this)), -#if BASE_VER < 931007 - base::TimeDelta::FromMicroseconds(source_codec_config_.data_interval_us)); -#else - base::Microseconds(source_codec_config_.data_interval_us)); -#endif + base::BindRepeating(&SourceImpl::SendAudioData, base::Unretained(this)), + std::chrono::microseconds(source_codec_config_.data_interval_us)); } void SourceImpl::StopAudioTicks() { @@ -271,7 +270,13 @@ bool SourceImpl::OnSuspendReq() { std::lock_guard guard(audioSourceCallbacksMutex_); if (CodecManager::GetInstance()->GetCodecLocation() == types::CodecLocation::HOST) { - StopAudioTicks(); + if (IS_FLAG_ENABLED(run_ble_audio_ticks_in_worker_thread)) { + worker_thread_->DoInThread( + FROM_HERE, + base::BindOnce(&SourceImpl::StopAudioTicks, base::Unretained(this))); + } else { + StopAudioTicks(); + } } if (audioSourceCallbacks_ == nullptr) { @@ -373,7 +378,13 @@ void SourceImpl::Stop() { if (CodecManager::GetInstance()->GetCodecLocation() == types::CodecLocation::HOST) { - StopAudioTicks(); + if (IS_FLAG_ENABLED(run_ble_audio_ticks_in_worker_thread)) { + worker_thread_->DoInThread( + FROM_HERE, + base::BindOnce(&SourceImpl::StopAudioTicks, base::Unretained(this))); + } else { + StopAudioTicks(); + } } std::lock_guard guard(audioSourceCallbacksMutex_); @@ -388,12 +399,22 @@ void SourceImpl::ConfirmStreamingRequest() { } LOG_INFO(); - halSinkInterface_->ConfirmStreamingRequest(); + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + halSinkInterface_->ConfirmStreamingRequestV2(); + } else { + halSinkInterface_->ConfirmStreamingRequest(); + } if (CodecManager::GetInstance()->GetCodecLocation() != types::CodecLocation::HOST) return; - StartAudioTicks(); + if (IS_FLAG_ENABLED(run_ble_audio_ticks_in_worker_thread)) { + worker_thread_->DoInThread( + FROM_HERE, + base::BindOnce(&SourceImpl::StartAudioTicks, base::Unretained(this))); + } else { + StartAudioTicks(); + } } void SourceImpl::SuspendedForReconfiguration() { @@ -426,7 +447,11 @@ void SourceImpl::CancelStreamingRequest() { } LOG_INFO(); - halSinkInterface_->CancelStreamingRequest(); + if (IS_FLAG_ENABLED(leaudio_start_stream_race_fix)) { + halSinkInterface_->CancelStreamingRequestV2(); + } else { + halSinkInterface_->CancelStreamingRequest(); + } } void SourceImpl::UpdateRemoteDelay(uint16_t remote_delay_ms) { diff --git a/system/bta/le_audio/audio_set_configurations.json b/system/bta/le_audio/audio_set_configurations.json index aba4a0bf62b15fc449896bce515fac4d273aa019..719a8d49e652f695f4b9512163e306f24560060e 100644 --- a/system/bta/le_audio/audio_set_configurations.json +++ b/system/bta/le_audio/audio_set_configurations.json @@ -277,16 +277,6 @@ "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2", "qos_config_name": ["QoS_Config_16_2_2"] }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", - "qos_config_name": ["QoS_Config_Low_Latency"] - }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", - "qos_config_name": ["QoS_Config_16_1_1"] - }, { "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency", "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2", @@ -327,26 +317,6 @@ "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1", "qos_config_name": ["QoS_Config_16_1_1"] }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_2", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", - "qos_config_name": ["QoS_Config_16_1_2"] - }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", - "qos_config_name": ["QoS_Config_Low_Latency"] - }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", - "qos_config_name": ["QoS_Config_16_2_1"] - }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_2", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", - "qos_config_name": ["QoS_Config_16_2_2"] - }, { "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1", @@ -612,16 +582,6 @@ "codec_config_name": "SingleDev_OneChanStereoSnk_32_1", "qos_config_name": ["QoS_Config_Low_Latency"] }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2", - "qos_config_name": ["QoS_Config_Low_Latency"] - }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2", - "qos_config_name": ["QoS_Config_32_2_1"] - }, { "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2", @@ -962,21 +922,6 @@ "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2", "qos_config_name": ["QoS_Config_Balanced_Reliability"] }, - { - "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2", - "qos_config_name": ["QoS_Config_Balanced_Reliability"] - }, - { - "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2", - "qos_config_name": ["QoS_Config_Balanced_Reliability"] - }, - { - "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", - "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2", - "qos_config_name": ["QoS_Config_Balanced_Reliability"] - }, { "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability", "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2", @@ -2592,13 +2537,13 @@ ] }, { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2", "subconfigurations": [ { - "device_cnt": 2, - "ase_cnt": 4, + "device_cnt": 1, + "ase_cnt": 1, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -2610,7 +2555,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 6 ] } }, @@ -2628,7 +2573,7 @@ "type": 3, "compound_value": { "value": [ - 1, + 3, 0, 0, 0 @@ -2640,7 +2585,7 @@ "type": 4, "compound_value": { "value": [ - 40, + 80, 0 ] } @@ -2660,6 +2605,7 @@ "device_cnt": 1, "ase_cnt": 1, "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -2671,7 +2617,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 6 ] } }, @@ -2689,7 +2635,7 @@ "type": 3, "compound_value": { "value": [ - 1, + 3, 0, 0, 0 @@ -2701,7 +2647,7 @@ "type": 4, "compound_value": { "value": [ - 40, + 80, 0 ] } @@ -2720,13 +2666,13 @@ ] }, { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2", "subconfigurations": [ { - "device_cnt": 2, - "ase_cnt": 4, + "device_cnt": 1, + "ase_cnt": 1, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -2747,7 +2693,7 @@ "type": 2, "compound_value": { "value": [ - 0 + 1 ] } }, @@ -2756,7 +2702,7 @@ "type": 3, "compound_value": { "value": [ - 1, + 3, 0, 0, 0 @@ -2768,7 +2714,7 @@ "type": 4, "compound_value": { "value": [ - 30, + 40, 0 ] } @@ -2788,6 +2734,7 @@ "device_cnt": 1, "ase_cnt": 1, "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -2808,7 +2755,7 @@ "type": 2, "compound_value": { "value": [ - 0 + 1 ] } }, @@ -2817,7 +2764,7 @@ "type": 3, "compound_value": { "value": [ - 1, + 3, 0, 0, 0 @@ -2829,7 +2776,7 @@ "type": 4, "compound_value": { "value": [ - 30, + 40, 0 ] } @@ -2848,7 +2795,7 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2", + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1", "subconfigurations": [ { "device_cnt": 1, @@ -2866,7 +2813,7 @@ "type": 1, "compound_value": { "value": [ - 6 + 3 ] } }, @@ -2875,7 +2822,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -2896,7 +2843,7 @@ "type": 4, "compound_value": { "value": [ - 80, + 30, 0 ] } @@ -2928,7 +2875,7 @@ "type": 1, "compound_value": { "value": [ - 6 + 3 ] } }, @@ -2937,7 +2884,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -2958,7 +2905,7 @@ "type": 4, "compound_value": { "value": [ - 80, + 30, 0 ] } @@ -2977,7 +2924,7 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2", + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2", "subconfigurations": [ { "device_cnt": 1, @@ -3045,7 +2992,6 @@ "device_cnt": 1, "ase_cnt": 1, "direction": "SOURCE", - "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3075,7 +3021,7 @@ "type": 3, "compound_value": { "value": [ - 3, + 1, 0, 0, 0 @@ -3106,7 +3052,7 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1", + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1", "subconfigurations": [ { "device_cnt": 1, @@ -3174,7 +3120,6 @@ "device_cnt": 1, "ase_cnt": 1, "direction": "SOURCE", - "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3204,7 +3149,7 @@ "type": 3, "compound_value": { "value": [ - 3, + 1, 0, 0, 0 @@ -3235,13 +3180,13 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2", + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2", "subconfigurations": [ { "device_cnt": 1, - "ase_cnt": 1, + "ase_cnt": 2, "direction": "SINK", - "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3271,7 +3216,7 @@ "type": 3, "compound_value": { "value": [ - 3, + 1, 0, 0, 0 @@ -3363,13 +3308,13 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1", + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1", "subconfigurations": [ { "device_cnt": 1, - "ase_cnt": 1, + "ase_cnt": 2, "direction": "SINK", - "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3399,7 +3344,7 @@ "type": 3, "compound_value": { "value": [ - 3, + 1, 0, 0, 0 @@ -3491,13 +3436,12 @@ ] }, { - "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2", "subconfigurations": [ { "device_cnt": 1, - "ase_cnt": 2, + "ase_cnt": 1, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3619,13 +3563,12 @@ ] }, { - "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1", "subconfigurations": [ { "device_cnt": 1, - "ase_cnt": 2, + "ase_cnt": 1, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3747,12 +3690,12 @@ ] }, { - "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2", + "name": "DualDev_OneChanMonoSrc_16_2", "subconfigurations": [ { - "device_cnt": 1, - "ase_cnt": 1, - "direction": "SINK", + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3809,7 +3752,12 @@ } } ] - }, + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_4", + "subconfigurations": [ { "device_cnt": 1, "ase_cnt": 1, @@ -3825,7 +3773,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 8 ] } }, @@ -3855,7 +3803,7 @@ "type": 4, "compound_value": { "value": [ - 40, + 120, 0 ] } @@ -3874,12 +3822,12 @@ ] }, { - "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1", + "name": "SingleDev_OneChanMonoSrc_48_3", "subconfigurations": [ { "device_cnt": 1, "ase_cnt": 1, - "direction": "SINK", + "direction": "SOURCE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -3891,7 +3839,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 8 ] } }, @@ -3921,7 +3869,7 @@ "type": 4, "compound_value": { "value": [ - 30, + 90, 0 ] } @@ -3936,7 +3884,12 @@ } } ] - }, + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_2", + "subconfigurations": [ { "device_cnt": 1, "ase_cnt": 1, @@ -3952,7 +3905,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 8 ] } }, @@ -3961,7 +3914,7 @@ "type": 2, "compound_value": { "value": [ - 0 + 1 ] } }, @@ -3982,7 +3935,7 @@ "type": 4, "compound_value": { "value": [ - 30, + 100, 0 ] } @@ -4001,11 +3954,11 @@ ] }, { - "name": "DualDev_OneChanMonoSrc_16_2", + "name": "SingleDev_OneChanMonoSrc_48_1", "subconfigurations": [ { - "device_cnt": 2, - "ase_cnt": 2, + "device_cnt": 1, + "ase_cnt": 1, "direction": "SOURCE", "codec_id": { "coding_format": 6, @@ -4018,7 +3971,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 8 ] } }, @@ -4027,7 +3980,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -4048,7 +4001,7 @@ "type": 4, "compound_value": { "value": [ - 40, + 75, 0 ] } @@ -4067,7 +4020,7 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_48_4", + "name": "SingleDev_OneChanMonoSrc_32_2", "subconfigurations": [ { "device_cnt": 1, @@ -4084,7 +4037,7 @@ "type": 1, "compound_value": { "value": [ - 8 + 6 ] } }, @@ -4114,7 +4067,7 @@ "type": 4, "compound_value": { "value": [ - 120, + 80, 0 ] } @@ -4133,7 +4086,7 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_48_3", + "name": "SingleDev_OneChanMonoSrc_32_1", "subconfigurations": [ { "device_cnt": 1, @@ -4150,7 +4103,7 @@ "type": 1, "compound_value": { "value": [ - 8 + 6 ] } }, @@ -4180,7 +4133,7 @@ "type": 4, "compound_value": { "value": [ - 90, + 60, 0 ] } @@ -4199,7 +4152,7 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_48_2", + "name": "SingleDev_OneChanMonoSrc_24_2", "subconfigurations": [ { "device_cnt": 1, @@ -4216,7 +4169,7 @@ "type": 1, "compound_value": { "value": [ - 8 + 5 ] } }, @@ -4246,7 +4199,7 @@ "type": 4, "compound_value": { "value": [ - 100, + 60, 0 ] } @@ -4265,7 +4218,7 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_48_1", + "name": "SingleDev_OneChanMonoSrc_24_1", "subconfigurations": [ { "device_cnt": 1, @@ -4282,7 +4235,7 @@ "type": 1, "compound_value": { "value": [ - 8 + 5 ] } }, @@ -4312,7 +4265,7 @@ "type": 4, "compound_value": { "value": [ - 75, + 45, 0 ] } @@ -4331,7 +4284,7 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_32_2", + "name": "SingleDev_OneChanMonoSrc_16_2", "subconfigurations": [ { "device_cnt": 1, @@ -4348,7 +4301,7 @@ "type": 1, "compound_value": { "value": [ - 6 + 3 ] } }, @@ -4378,7 +4331,7 @@ "type": 4, "compound_value": { "value": [ - 80, + 40, 0 ] } @@ -4397,7 +4350,7 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_32_1", + "name": "SingleDev_OneChanMonoSrc_16_1", "subconfigurations": [ { "device_cnt": 1, @@ -4414,7 +4367,7 @@ "type": 1, "compound_value": { "value": [ - 6 + 3 ] } }, @@ -4444,7 +4397,7 @@ "type": 4, "compound_value": { "value": [ - 60, + 30, 0 ] } @@ -4463,12 +4416,13 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_24_2", + "name": "DualDev_OneChanStereoSnk_48_4", "subconfigurations": [ { - "device_cnt": 1, - "ase_cnt": 1, - "direction": "SOURCE", + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -4480,7 +4434,7 @@ "type": 1, "compound_value": { "value": [ - 5 + 8 ] } }, @@ -4510,7 +4464,7 @@ "type": 4, "compound_value": { "value": [ - 60, + 120, 0 ] } @@ -4529,12 +4483,13 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_24_1", + "name": "DualDev_OneChanStereoSnk_48_3", "subconfigurations": [ { - "device_cnt": 1, - "ase_cnt": 1, - "direction": "SOURCE", + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -4546,7 +4501,7 @@ "type": 1, "compound_value": { "value": [ - 5 + 8 ] } }, @@ -4555,7 +4510,7 @@ "type": 2, "compound_value": { "value": [ - 0 + 1 ] } }, @@ -4576,7 +4531,7 @@ "type": 4, "compound_value": { "value": [ - 45, + 90, 0 ] } @@ -4595,12 +4550,13 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_16_2", + "name": "DualDev_OneChanStereoSnk_48_2", "subconfigurations": [ { - "device_cnt": 1, - "ase_cnt": 1, - "direction": "SOURCE", + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -4612,7 +4568,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 8 ] } }, @@ -4642,7 +4598,7 @@ "type": 4, "compound_value": { "value": [ - 40, + 100, 0 ] } @@ -4661,73 +4617,7 @@ ] }, { - "name": "SingleDev_OneChanMonoSrc_16_1", - "subconfigurations": [ - { - "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", + "name": "DualDev_OneChanStereoSnk_48_1", "subconfigurations": [ { "device_cnt": 2, @@ -4754,77 +4644,10 @@ "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": "DualDev_OneChanStereoSnk_48_3", - "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, @@ -4842,7 +4665,7 @@ "type": 4, "compound_value": { "value": [ - 90, + 75, 0 ] } @@ -4861,13 +4684,13 @@ ] }, { - "name": "DualDev_OneChanStereoSnk_48_2", + "name": "SingleDev_OneChanStereoSnk_48_4", "subconfigurations": [ { - "device_cnt": 2, + "device_cnt": 1, "ase_cnt": 2, "direction": "SINK", - "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -4909,74 +4732,7 @@ "type": 4, "compound_value": { "value": [ - 100, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, - { - "name": "DualDev_OneChanStereoSnk_48_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": [ - 8 - ] - } - }, - { - "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": [ - 75, + 120, 0 ] } @@ -4995,7 +4751,7 @@ ] }, { - "name": "SingleDev_OneChanStereoSnk_48_4", + "name": "SingleDev_OneChanStereoSnk_48_3", "subconfigurations": [ { "device_cnt": 1, @@ -5043,7 +4799,7 @@ "type": 4, "compound_value": { "value": [ - 120, + 90, 0 ] } @@ -5062,7 +4818,7 @@ ] }, { - "name": "SingleDev_OneChanStereoSnk_48_3", + "name": "SingleDev_OneChanStereoSnk_48_2", "subconfigurations": [ { "device_cnt": 1, @@ -5110,7 +4866,7 @@ "type": 4, "compound_value": { "value": [ - 90, + 100, 0 ] } @@ -5129,7 +4885,7 @@ ] }, { - "name": "SingleDev_OneChanStereoSnk_48_2", + "name": "SingleDev_OneChanStereoSnk_48_1", "subconfigurations": [ { "device_cnt": 1, @@ -5156,7 +4912,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -5177,7 +4933,7 @@ "type": 4, "compound_value": { "value": [ - 100, + 75, 0 ] } @@ -5196,13 +4952,13 @@ ] }, { - "name": "SingleDev_OneChanStereoSnk_48_1", + "name": "SingleDev_TwoChanStereoSnk_48_4", "subconfigurations": [ { "device_cnt": 1, - "ase_cnt": 2, + "ase_cnt": 1, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -5223,7 +4979,7 @@ "type": 2, "compound_value": { "value": [ - 0 + 1 ] } }, @@ -5232,7 +4988,7 @@ "type": 3, "compound_value": { "value": [ - 1, + 3, 0, 0, 0 @@ -5244,7 +5000,7 @@ "type": 4, "compound_value": { "value": [ - 75, + 120, 0 ] } @@ -5263,7 +5019,7 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_48_4", + "name": "SingleDev_TwoChanStereoSnk_48_3", "subconfigurations": [ { "device_cnt": 1, @@ -5311,7 +5067,7 @@ "type": 4, "compound_value": { "value": [ - 120, + 90, 0 ] } @@ -5330,7 +5086,7 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_48_3", + "name": "SingleDev_TwoChanStereoSnk_48_2", "subconfigurations": [ { "device_cnt": 1, @@ -5378,7 +5134,7 @@ "type": 4, "compound_value": { "value": [ - 90, + 100, 0 ] } @@ -5397,7 +5153,7 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_48_2", + "name": "SingleDev_TwoChanStereoSnk_48_1", "subconfigurations": [ { "device_cnt": 1, @@ -5424,7 +5180,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -5445,7 +5201,7 @@ "type": 4, "compound_value": { "value": [ - 100, + 75, 0 ] } @@ -5464,74 +5220,7 @@ ] }, { - "name": "SingleDev_TwoChanStereoSnk_48_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": [ - 8 - ] - } - }, - { - "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": [ - 75, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, - { - "name": "SingleDev_OneChanMonoSnk_48_4", + "name": "SingleDev_OneChanMonoSnk_48_4", "subconfigurations": [ { "device_cnt": 1, @@ -5558,409 +5247,7 @@ "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_OneChanMonoSnk_48_3", - "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": [ - 90, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, - { - "name": "SingleDev_OneChanMonoSnk_48_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": [ - 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": [ - 100, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, - { - "name": "SingleDev_OneChanMonoSnk_48_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": [ - 8 - ] - } - }, - { - "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": [ - 75, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, - { - "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_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": [ - 8 - ] - } - }, - { - "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": [ - 100, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, - { - "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_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": [ - 8 - ] - } - }, - { - "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": [ - 100, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, - { - "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_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": [ - 8 - ] - } - }, - { - "name": "frame_duration", - "type": 2, - "compound_value": { - "value": [ - 0 + 1 ] } }, @@ -5981,7 +5268,7 @@ "type": 4, "compound_value": { "value": [ - 100, + 120, 0 ] } @@ -6000,13 +5287,13 @@ ] }, { - "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1", + "name": "SingleDev_OneChanMonoSnk_48_3", "subconfigurations": [ { "device_cnt": 1, "ase_cnt": 1, "direction": "SINK", - "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6027,7 +5314,7 @@ "type": 2, "compound_value": { "value": [ - 0 + 1 ] } }, @@ -6036,7 +5323,7 @@ "type": 3, "compound_value": { "value": [ - 3, + 1, 0, 0, 0 @@ -6048,7 +5335,7 @@ "type": 4, "compound_value": { "value": [ - 75, + 90, 0 ] } @@ -6067,12 +5354,13 @@ ] }, { - "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2", + "name": "SingleDev_OneChanMonoSnk_48_2", "subconfigurations": [ { - "device_cnt": 2, - "ase_cnt": 2, + "device_cnt": 1, + "ase_cnt": 1, "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6114,7 +5402,7 @@ "type": 4, "compound_value": { "value": [ - 120, + 100, 0 ] } @@ -6129,11 +5417,17 @@ } } ] - }, + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_1", + "subconfigurations": [ { - "device_cnt": 2, - "ase_cnt": 2, - "direction": "SOURCE", + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6145,7 +5439,7 @@ "type": 1, "compound_value": { "value": [ - 6 + 8 ] } }, @@ -6154,7 +5448,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -6175,7 +5469,7 @@ "type": 4, "compound_value": { "value": [ - 80, + 75, 0 ] } @@ -6194,12 +5488,13 @@ ] }, { - "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2", + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1", "subconfigurations": [ { - "device_cnt": 2, - "ase_cnt": 2, + "device_cnt": 1, + "ase_cnt": 1, "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6220,7 +5515,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -6229,7 +5524,7 @@ "type": 3, "compound_value": { "value": [ - 1, + 3, 0, 0, 0 @@ -6241,7 +5536,7 @@ "type": 4, "compound_value": { "value": [ - 120, + 100, 0 ] } @@ -6256,11 +5551,17 @@ } } ] - }, + } + ] + }, + { + "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1", + "subconfigurations": [ { "device_cnt": 2, "ase_cnt": 2, - "direction": "SOURCE", + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6272,7 +5573,7 @@ "type": 1, "compound_value": { "value": [ - 5 + 8 ] } }, @@ -6281,7 +5582,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -6302,7 +5603,7 @@ "type": 4, "compound_value": { "value": [ - 80, + 100, 0 ] } @@ -6321,12 +5622,13 @@ ] }, { - "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2", + "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1", "subconfigurations": [ { - "device_cnt": 2, + "device_cnt": 1, "ase_cnt": 2, "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6347,7 +5649,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -6368,7 +5670,7 @@ "type": 4, "compound_value": { "value": [ - 120, + 100, 0 ] } @@ -6383,11 +5685,17 @@ } } ] - }, + } + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1", + "subconfigurations": [ { - "device_cnt": 2, - "ase_cnt": 2, - "direction": "SOURCE", + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6399,7 +5707,7 @@ "type": 1, "compound_value": { "value": [ - 3 + 8 ] } }, @@ -6408,7 +5716,7 @@ "type": 2, "compound_value": { "value": [ - 1 + 0 ] } }, @@ -6417,7 +5725,7 @@ "type": 3, "compound_value": { "value": [ - 1, + 3, 0, 0, 0 @@ -6429,7 +5737,7 @@ "type": 4, "compound_value": { "value": [ - 80, + 75, 0 ] } @@ -6448,7 +5756,7 @@ ] }, { - "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2", + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2", "subconfigurations": [ { "device_cnt": 2, @@ -6512,8 +5820,8 @@ ] }, { - "device_cnt": 1, - "ase_cnt": 1, + "device_cnt": 2, + "ase_cnt": 2, "direction": "SOURCE", "codec_id": { "coding_format": 6, @@ -6575,7 +5883,7 @@ ] }, { - "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2", + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2", "subconfigurations": [ { "device_cnt": 2, @@ -6639,8 +5947,8 @@ ] }, { - "device_cnt": 1, - "ase_cnt": 1, + "device_cnt": 2, + "ase_cnt": 2, "direction": "SOURCE", "codec_id": { "coding_format": 6, @@ -6702,7 +6010,7 @@ ] }, { - "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2", + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2", "subconfigurations": [ { "device_cnt": 2, @@ -6766,8 +6074,8 @@ ] }, { - "device_cnt": 1, - "ase_cnt": 1, + "device_cnt": 2, + "ase_cnt": 2, "direction": "SOURCE", "codec_id": { "coding_format": 6, @@ -6829,13 +6137,12 @@ ] }, { - "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2", + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2", "subconfigurations": [ { "device_cnt": 2, - "ase_cnt": 4, + "ase_cnt": 2, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -6957,13 +6264,12 @@ ] }, { - "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2", + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2", "subconfigurations": [ { "device_cnt": 2, - "ase_cnt": 4, + "ase_cnt": 2, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -7085,13 +6391,12 @@ ] }, { - "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2", + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2", "subconfigurations": [ { "device_cnt": 2, - "ase_cnt": 4, + "ase_cnt": 2, "direction": "SINK", - "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", "codec_id": { "coding_format": 6, "vendor_company_id": 0, @@ -10053,134 +9358,6 @@ } ] }, - { - "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_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": [ - 6 - ] - } - }, - { - "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": [ - 80, - 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": [ - 6 - ] - } - }, - { - "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": [ - 80, - 0 - ] - } - }, - { - "name": "codec_frame_blocks_per_sdu", - "type": 5, - "compound_value": { - "value": [ - 1 - ] - } - } - ] - } - ] - }, { "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2", "subconfigurations": [ diff --git a/system/bta/le_audio/audio_set_scenarios.json b/system/bta/le_audio/audio_set_scenarios.json index 9fa3409e3d855419095bb3d7342f23595cba3ca1..b7788aa32848eda0ef5bef12021d063c3b3eb200 100644 --- a/system/bta/le_audio/audio_set_scenarios.json +++ b/system/bta/le_audio/audio_set_scenarios.json @@ -22,12 +22,6 @@ "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1", "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1", - "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1", - "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency", - "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency", - "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1", - "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency", - "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1", "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency", "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1", "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency", @@ -240,9 +234,6 @@ "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", - "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", - "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", - "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability", "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability", "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability", diff --git a/system/bta/le_audio/broadcaster/broadcaster.cc b/system/bta/le_audio/broadcaster/broadcaster.cc index 8680a1785c58c503a7169ac825e1ed0db8011780..86bc92946c8c0a13f3cc07a52294e5d8087df6e2 100644 --- a/system/bta/le_audio/broadcaster/broadcaster.cc +++ b/system/bta/le_audio/broadcaster/broadcaster.cc @@ -30,6 +30,7 @@ #include "bta/le_audio/metrics_collector.h" #include "common/strings.h" #include "device/include/controller.h" +#include "include/check.h" #include "internal_include/stack_config.h" #include "os/log.h" #include "osi/include/properties.h" @@ -126,6 +127,9 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { LOG_INFO("Broadcaster"); broadcasts_.clear(); callbacks_ = nullptr; + is_iso_running_ = false; + queued_start_broadcast_request_ = std::nullopt; + queued_create_broadcast_request_ = std::nullopt; if (le_audio_source_hal_client_) { le_audio_source_hal_client_->Stop(); @@ -374,15 +378,10 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { LeAudioLtvMap public_ltv; std::vector subgroup_ltvs; - if (queued_broadcast_.IsQueuedBroadcast()) { + if (queued_create_broadcast_request_) { LOG_ERROR("Not processed yet queued broadcast"); - return; - } - - if (!queued_broadcast_.CanCreateBroadcast()) { - queued_broadcast_.SetQueuedBroadcast(is_public, broadcast_name, - broadcast_code, public_metadata, - subgroup_quality, subgroup_metadata); + callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid, + false); return; } @@ -393,6 +392,8 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { public_metadata.data(), public_metadata.size(), is_metadata_valid); if (!is_metadata_valid) { LOG_ERROR("Invalid metadata provided."); + callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid, + false); return; } // Prepare public features byte @@ -434,6 +435,8 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { auto ltv = LeAudioLtvMap::Parse(metadata.data(), metadata.size(), is_metadata_valid); if (!is_metadata_valid) { LOG_ERROR("Invalid metadata provided."); + callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid, + false); return; } @@ -444,6 +447,8 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { if (stream_context_vec) { if (stream_context_vec.value().size() < 2) { LOG_ERROR("kLeAudioMetadataTypeStreamingAudioContext size < 2"); + callbacks_->OnBroadcastCreated( + bluetooth::le_audio::kBroadcastIdInvalid, false); return; } auto pp = stream_context_vec.value().data(); @@ -456,6 +461,8 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { if (stream_context_vec) { if (stream_context_vec.value().size() < 2) { LOG_ERROR("kLeAudioMetadataTypeStreamingAudioContext size < 2"); + callbacks_->OnBroadcastCreated( + bluetooth::le_audio::kBroadcastIdInvalid, false); return; } @@ -474,70 +481,79 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { subgroup_ltvs.push_back(ltv); } - if (CodecManager::GetInstance()->GetCodecLocation() == - CodecLocation::ADSP) { - auto offload_config = - CodecManager::GetInstance()->GetBroadcastOffloadConfig(); - if (offload_config == nullptr) { - LOG_ERROR("No valid broadcast offload config"); - return; - } - BroadcastCodecWrapper codec_config( - {.coding_format = le_audio::types::kLeAudioCodingFormatLC3, - .vendor_company_id = - le_audio::types::kLeAudioVendorCompanyIdUndefined, - .vendor_codec_id = le_audio::types::kLeAudioVendorCodecIdUndefined}, - {.num_channels = - static_cast(offload_config->stream_map.size()), - .sample_rate = offload_config->sampling_rate, - .bits_per_sample = offload_config->bits_per_sample, - .data_interval_us = offload_config->frame_duration}, - offload_config->octets_per_frame); - BroadcastQosConfig qos_config(offload_config->retransmission_number, - offload_config->max_transport_latency); - - BroadcastStateMachineConfig msg = { - .is_public = is_public, - .broadcast_id = broadcast_id, - .broadcast_name = broadcast_name, - .streaming_phy = GetStreamingPhy(), - .codec_wrapper = codec_config, - .qos_config = qos_config, - .announcement = prepareBasicAnnouncement(codec_config, subgroup_ltvs), - .broadcast_code = std::move(broadcast_code)}; - if (is_public) { - msg.public_announcement = - preparePublicAnnouncement(public_features, public_ltv); + auto codec_qos_pair = [](AudioContexts context_type) + -> std::optional< + std::pair> { + if (CodecManager::GetInstance()->GetCodecLocation() == + CodecLocation::ADSP) { + auto offload_config = + CodecManager::GetInstance()->GetBroadcastOffloadConfig(); + if (offload_config == nullptr) { + return std::nullopt; + } + return std::make_pair( + BroadcastCodecWrapper( + {.coding_format = le_audio::types::kLeAudioCodingFormatLC3, + .vendor_company_id = + le_audio::types::kLeAudioVendorCompanyIdUndefined, + .vendor_codec_id = + le_audio::types::kLeAudioVendorCodecIdUndefined}, + {.num_channels = + static_cast(offload_config->stream_map.size()), + .sample_rate = offload_config->sampling_rate, + .bits_per_sample = offload_config->bits_per_sample, + .data_interval_us = offload_config->frame_duration}, + offload_config->octets_per_frame), + BroadcastQosConfig(offload_config->retransmission_number, + offload_config->max_transport_latency)); + } else { + return le_audio::broadcaster::getStreamConfigForContext(context_type); } - pending_broadcasts_.push_back( - std::move(BroadcastStateMachine::CreateInstance(std::move(msg)))); - } else { - auto codec_qos_pair = - le_audio::broadcaster::getStreamConfigForContext(context_type); - BroadcastStateMachineConfig msg = { - .is_public = is_public, - .broadcast_id = broadcast_id, - .broadcast_name = broadcast_name, - .streaming_phy = GetStreamingPhy(), - .codec_wrapper = codec_qos_pair.first, - .qos_config = codec_qos_pair.second, - .announcement = - prepareBasicAnnouncement(codec_qos_pair.first, subgroup_ltvs), - .broadcast_code = std::move(broadcast_code)}; - if (is_public) { - msg.public_announcement = - preparePublicAnnouncement(public_features, public_ltv); + }(context_type); + + if (!codec_qos_pair) { + LOG_ERROR("No valid broadcast offload config"); + return; + } + + BroadcastStateMachineConfig msg = { + .is_public = is_public, + .broadcast_id = broadcast_id, + .broadcast_name = broadcast_name, + .streaming_phy = GetStreamingPhy(), + .codec_wrapper = codec_qos_pair->first, + .qos_config = codec_qos_pair->second, + .announcement = + prepareBasicAnnouncement(codec_qos_pair->first, subgroup_ltvs), + .broadcast_code = std::move(broadcast_code)}; + if (is_public) { + msg.public_announcement = + preparePublicAnnouncement(public_features, public_ltv); + } + + // If there is ongoing ISO traffic, it might be a unicast stream + if (is_iso_running_) { + LOG_INFO("Iso is still active. Queueing broadcast creation for later."); + if (queued_create_broadcast_request_) { + LOG_WARN( + "Already queued. Updating queued broadcast creation with the new " + "configuration."); } - /* Create the broadcaster instance - we'll receive it's init state in the - * async callback - */ - pending_broadcasts_.push_back( - std::move(BroadcastStateMachine::CreateInstance(std::move(msg)))); + queued_create_broadcast_request_ = std::move(msg); + return; } + InstantiateBroadcast(std::move(msg)); + } + + void InstantiateBroadcast(BroadcastStateMachineConfig msg) { LOG_INFO("CreateAudioBroadcast"); - // Notify the error instead just fail silently + /* Put the new broadcast on the initialization queue, notify the error and + * drop the pending broadcast data if init fails. + */ + pending_broadcasts_.push_back( + BroadcastStateMachine::CreateInstance(std::move(msg))); if (!pending_broadcasts_.back()->Initialize()) { pending_broadcasts_.pop_back(); callbacks_->OnBroadcastCreated(bluetooth::le_audio::kBroadcastIdInvalid, @@ -574,6 +590,16 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { void StartAudioBroadcast(uint32_t broadcast_id) override { LOG_INFO("Starting broadcast_id=%d", broadcast_id); + if (queued_start_broadcast_request_) { + LOG_ERROR("Not processed yet start broadcast request"); + return; + } + + if (is_iso_running_) { + queued_start_broadcast_request_ = broadcast_id; + return; + } + if (IsAnyoneStreaming()) { LOG_ERROR("Stop the other broadcast first!"); return; @@ -745,14 +771,23 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { } void IsoTrafficEventCb(bool is_active) { - if (is_active) { - queued_broadcast_.SetIsoTrafficFlag(); - } else { - queued_broadcast_.ResetIsoTrafficFlag(); - - if (!queued_broadcast_.IsQueuedBroadcast()) return; + is_iso_running_ = is_active; + LOG_INFO("is_iso_running: %d", is_iso_running_); + if (!is_iso_running_) { + if (queued_start_broadcast_request_) { + auto broadcast_id = *queued_start_broadcast_request_; + queued_start_broadcast_request_ = std::nullopt; + + LOG_INFO("Start queued broadcast."); + StartAudioBroadcast(broadcast_id); + } + if (queued_create_broadcast_request_) { + auto broadcast_msg = std::move(*queued_create_broadcast_request_); + queued_create_broadcast_request_ = std::nullopt; - queued_broadcast_.CreateAudioBroadcast(); + LOG_INFO("Create queued broadcast."); + InstantiateBroadcast(std::move(broadcast_msg)); + } } } @@ -1105,90 +1140,20 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { std::vector> sw_enc_; } audio_receiver_; - static class QueuedBroadcast { - public: - bool IsQueuedBroadcast() { - LOG_INFO(""); - - return is_queued_; - } - - void SetQueuedBroadcast( - bool is_public, const std::string& broadcast_name, - const std::optional& broadcast_code, - const std::vector& public_metadata, - const std::vector& subgroup_quality, - const std::vector>& subgroup_metadata) { - LOG_INFO(); - - is_public_ = is_public; - broadcast_name_ = broadcast_name; - broadcast_code_ = broadcast_code; - public_metadata_ = public_metadata; - subgroup_quality_ = subgroup_quality; - subgroup_metadata_ = subgroup_metadata; - - is_queued_ = true; - } - - void CreateAudioBroadcast() { - if (!instance || !CanCreateBroadcast()) return; - - LOG_INFO("Create queued broadcast"); - - is_queued_ = false; - - instance->CreateAudioBroadcast(is_public_, broadcast_name_, - broadcast_code_, public_metadata_, - subgroup_quality_, subgroup_metadata_); - } - - void ClearQueuedBroadcast() { - LOG_INFO(); - - is_queued_ = false; - } - - void SetIsoTrafficFlag() { - LOG_INFO(); - - is_iso_running_ = true; - } - - void ResetIsoTrafficFlag() { - LOG_INFO(); - - is_iso_running_ = false; - } - - bool CanCreateBroadcast() { - LOG_INFO("%d", is_iso_running_ == false); - - return is_iso_running_ == false; - } - - private: - /* Queued broadcast data */ - bool is_public_; - std::string broadcast_name_; - std::optional broadcast_code_; - std::vector public_metadata_; - std::vector subgroup_quality_; - std::vector> subgroup_metadata_; - - bool is_iso_running_; - bool is_queued_; - } queued_broadcast_; - bluetooth::le_audio::LeAudioBroadcasterCallbacks* callbacks_; std::map> broadcasts_; std::vector> pending_broadcasts_; + std::optional queued_create_broadcast_request_; + std::optional queued_start_broadcast_request_; /* Some BIG params are set globally */ uint8_t current_phy_; AudioDataPathState audio_data_path_state_; std::unique_ptr le_audio_source_hal_client_; std::vector available_broadcast_ids_; + + // Flag to track iso state + bool is_iso_running_ = false; }; /* Static members definitions */ @@ -1198,8 +1163,6 @@ LeAudioBroadcasterImpl::LeAudioSourceCallbacksImpl LeAudioBroadcasterImpl::audio_receiver_; LeAudioBroadcasterImpl::BroadcastAdvertisingCallbacks LeAudioBroadcasterImpl::state_machine_adv_callbacks_; -LeAudioBroadcasterImpl::QueuedBroadcast - LeAudioBroadcasterImpl::queued_broadcast_; } /* namespace */ void LeAudioBroadcaster::Initialize( @@ -1212,7 +1175,7 @@ void LeAudioBroadcaster::Initialize( return; } - if (!controller_get_interface()->supports_ble_isochronous_broadcaster() && + if (!controller_get_interface()->SupportsBleIsochronousBroadcaster() && !osi_property_get_bool("persist.bluetooth.fake_iso_support", false)) { LOG_WARN("Isochronous Broadcast not supported by the controller!"); return; @@ -1230,10 +1193,7 @@ void LeAudioBroadcaster::Initialize( /* Register for active traffic */ IsoManager::GetInstance()->RegisterOnIsoTrafficActiveCallback( [](bool is_active) { - if (!instance) { - return; - } - instance->IsoTrafficEventCb(is_active); + if (instance) instance->IsoTrafficEventCb(is_active); }); } diff --git a/system/bta/le_audio/broadcaster/broadcaster_test.cc b/system/bta/le_audio/broadcaster/broadcaster_test.cc index 8631b74699e137444e344d48ea2ffccd9c1f8f90..a3c0273265282dfa63ec9c23ab707b6564a8546e 100644 --- a/system/bta/le_audio/broadcaster/broadcaster_test.cc +++ b/system/bta/le_audio/broadcaster/broadcaster_test.cc @@ -253,6 +253,7 @@ class BroadcasterTest : public Test { ContentControlIdKeeper::GetInstance()->Stop(); iso_active_callback = nullptr; + delete mock_audio_source_; iso_manager_->Stop(); controller::SetMockControllerInterface(nullptr); diff --git a/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.cc b/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.cc deleted file mode 100644 index baeecc23c6f47a15fce90adb51eff588f995389c..0000000000000000000000000000000000000000 --- a/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2021 HIMSA II K/S - www.himsa.com. - * Represented by EHIMA - www.ehima.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "mock_ble_advertising_manager.h" - -#include - -#include "main/shim/le_advertising_manager.h" - -namespace { -MockBleAdvertisingManager* bt_le_advertiser_instance; -} // namespace - -void MockBleAdvertisingManager::Initialize() { - if (bt_le_advertiser_instance == nullptr) { - bt_le_advertiser_instance = new MockBleAdvertisingManager(); - } -} - -void MockBleAdvertisingManager::CleanUp() { - delete bt_le_advertiser_instance; - bt_le_advertiser_instance = nullptr; -} - -MockBleAdvertisingManager* MockBleAdvertisingManager::Get() { - return bt_le_advertiser_instance; -} - -BleAdvertiserInterface* bluetooth::shim::get_ble_advertiser_instance() { - return static_cast(bt_le_advertiser_instance); -} diff --git a/system/bta/le_audio/broadcaster/state_machine.cc b/system/bta/le_audio/broadcaster/state_machine.cc index 64effcbeb4b4ee26e454267f220a0ba14fce79ec..8decd18b94fb61c252fb6a36ccc282567fd77707 100644 --- a/system/bta/le_audio/broadcaster/state_machine.cc +++ b/system/bta/le_audio/broadcaster/state_machine.cc @@ -29,7 +29,7 @@ #include "bta/le_audio/le_audio_types.h" #include "common/strings.h" #include "hci/le_advertising_manager.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" #include "stack/include/btm_iso_api.h" diff --git a/system/bta/le_audio/broadcaster/state_machine.h b/system/bta/le_audio/broadcaster/state_machine.h index b3a40ce067d2e3e5c3d161c0f990720957a1d404..569e09034502707a265d156b05f2660ae2e48545 100644 --- a/system/bta/le_audio/broadcaster/state_machine.h +++ b/system/bta/le_audio/broadcaster/state_machine.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "base/functional/callback.h" #include "broadcaster_types.h" diff --git a/system/bta/le_audio/broadcaster/state_machine_test.cc b/system/bta/le_audio/broadcaster/state_machine_test.cc index 527c12b35e977d1436aece3d98987407f5117156..f02d3cce74a32a25eb96d2f82676bf167e077b5a 100644 --- a/system/bta/le_audio/broadcaster/state_machine_test.cc +++ b/system/bta/le_audio/broadcaster/state_machine_test.cc @@ -22,11 +22,11 @@ #include "../le_audio_types.h" #include "btm_iso_api.h" -#include "mock_ble_advertising_manager.h" #include "mock_iso_manager.h" #include "stack/include/btm_ble_api_types.h" #include "state_machine.h" #include "test/common/mock_functions.h" +#include "test/mock/mock_main_shim_le_advertising_manager.h" using namespace bluetooth::hci::iso_manager; diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc index 328e724bf7cb237b52fe76560e6c45bf6207e2c4..233d2c15683686b3902a7fd551d5309c64a2a22f 100644 --- a/system/bta/le_audio/client.cc +++ b/system/bta/le_audio/client.cc @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -31,16 +32,18 @@ #include "bta_gatt_queue.h" #include "bta_groups.h" #include "bta_le_audio_api.h" -#include "btif_profile_storage.h" +#include "btif/include/btif_profile_storage.h" #include "btm_iso_api.h" #include "client_parser.h" #include "codec_interface.h" #include "codec_manager.h" +#include "common/strings.h" #include "common/time_util.h" #include "content_control_id_keeper.h" #include "device/include/controller.h" #include "devices.h" -#include "gd/common/strings.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" #include "internal_include/stack_config.h" #include "le_audio_health_status.h" #include "le_audio_set_configuration_provider.h" @@ -177,6 +180,7 @@ LeAudioSinkAudioHalClient::Callbacks* audioSourceReceiver; CigCallbacks* stateMachineHciCallbacks; LeAudioGroupStateMachine::Callbacks* stateMachineCallbacks; DeviceGroupsCallbacks* device_group_callbacks; +LeAudioIsoDataCallback* iso_data_callback; /* * Coordinatet Set Identification Profile (CSIP) based on CSIP 1.0 @@ -234,6 +238,7 @@ class LeAudioClientImpl : public LeAudioClient { in_voip_call_(false), sink_monitor_mode_(false), sink_monitor_notified_status_(std::nullopt), + source_monitor_mode_(false), current_source_codec_config({0, 0, 0, 0}), current_sink_codec_config({0, 0, 0, 0}), le_audio_source_hal_client_(nullptr), @@ -291,6 +296,11 @@ class LeAudioClientImpl : public LeAudioClient { return; } + /* Reconfiguration to non requiring source scenario */ + if (sink_monitor_mode_) { + notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_SUSPENDED); + } + /* For sonification events we don't really need to reconfigure to HQ * configuration, but if the previous configuration was for HQ Media, * we might want to go back to that scenario. @@ -731,6 +741,7 @@ class LeAudioClientImpl : public LeAudioClient { ToString(group->cig.GetState()).c_str()); if (group->IsEmpty() && (group->cig.GetState() == le_audio::types::CigState::NONE)) { + lastNotifiedGroupStreamStatusMap_.erase(group->group_id_); aseGroups_.Remove(group->group_id_); } } @@ -909,6 +920,16 @@ class LeAudioClientImpl : public LeAudioClient { bluetooth::common::time_get_os_boottime_us(); } + /* If assistant have some connected delegators that needs to be informed + * when there would be request to stream unicast. + */ + if (IS_FLAG_ENABLED(leaudio_broadcast_audio_handover_policies) && + !sink_monitor_mode_ && source_monitor_mode_ && !group->IsStreaming()) { + callbacks_->OnUnicastMonitorModeStatus( + le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_REQUESTED); + } + bool result = groupStateMachine_->StartStream( group, configuration_context_type, remote_contexts, ccids); @@ -1024,6 +1045,11 @@ class LeAudioClientImpl : public LeAudioClient { bool IsInVoipCall() override { return in_voip_call_; } + bool IsInStreaming() override { + return audio_sender_state_ == AudioState::STARTED || + audio_receiver_state_ == AudioState::STARTED; + } + void SetUnicastMonitorMode(uint8_t direction, bool enable) override { if (!IS_FLAG_ENABLED(leaudio_broadcast_audio_handover_policies)) { LOG_WARN("Monitor mode is disabled, Set Unicast Monitor mode is ignored"); @@ -1044,6 +1070,32 @@ class LeAudioClientImpl : public LeAudioClient { LOG_DEBUG("enable: %d", enable); sink_monitor_mode_ = enable; + } else if (direction == le_audio::types::kLeAudioDirectionSource) { + LOG_DEBUG("enable: %d", enable); + source_monitor_mode_ = enable; + + if (!enable) { + return; + } + + LeAudioDeviceGroup* group = aseGroups_.FindById(active_group_id_); + if (!group) { + callbacks_->OnUnicastMonitorModeStatus( + le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_SUSPENDED); + + return; + } + + if (group->IsStreaming()) { + callbacks_->OnUnicastMonitorModeStatus( + le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING); + } else { + callbacks_->OnUnicastMonitorModeStatus( + le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_SUSPENDED); + } } else { LOG_ERROR("invalid direction: 0x%02x monitor mode set", direction); } @@ -1271,8 +1323,13 @@ class LeAudioClientImpl : public LeAudioClient { /* Reset sink listener notified status */ sink_monitor_notified_status_ = std::nullopt; - callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE); - SendAudioGroupSelectableCodecConfigChanged(group); + if (IS_FLAG_ENABLED(leaudio_codec_config_callback_order_fix)) { + SendAudioGroupSelectableCodecConfigChanged(group); + callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE); + } else { + callbacks_->OnGroupStatus(active_group_id_, GroupStatus::ACTIVE); + SendAudioGroupSelectableCodecConfigChanged(group); + } } void SetEnableState(const RawAddress& address, bool enabled) override { @@ -1993,7 +2050,7 @@ class LeAudioClientImpl : public LeAudioClient { BTA_GATTC_CancelOpen(gatt_if_, address, false); BTA_GATTC_Open(gatt_if_, address, reconnection_mode_, false); - if (controller_get_interface()->supports_ble_2m_phy()) { + if (controller_get_interface()->SupportsBle2mPhy()) { LOG(INFO) << ADDRESS_TO_LOGGABLE_STR(address) << " set preferred PHY to 2M"; BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0); @@ -2211,12 +2268,7 @@ class LeAudioClientImpl : public LeAudioClient { base::BindOnce( &LeAudioClientImpl::checkGroupConnectionStateAfterMemberDisconnect, weak_factory_.GetWeakPtr(), group_id), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(kGroupConnectedWatchDelayMs) -#else - base::Milliseconds(kDeviceAttachDelayMs) -#endif - ); + std::chrono::milliseconds(kGroupConnectedWatchDelayMs)); } void autoConnect(RawAddress address) { @@ -2236,12 +2288,7 @@ class LeAudioClientImpl : public LeAudioClient { FROM_HERE, base::BindOnce(&LeAudioClientImpl::autoConnect, weak_factory_.GetWeakPtr(), address), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(kAutoConnectAfterOwnDisconnectDelayMs) -#else - base::Milliseconds(kDeviceAttachDelayMs) -#endif - ); + std::chrono::milliseconds(kAutoConnectAfterOwnDisconnectDelayMs)); } void recoveryReconnect(RawAddress address) { @@ -2275,12 +2322,7 @@ class LeAudioClientImpl : public LeAudioClient { FROM_HERE, base::BindOnce(&LeAudioClientImpl::recoveryReconnect, weak_factory_.GetWeakPtr(), address), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(kRecoveryReconnectDelayMs) -#else - base::Milliseconds(kDeviceAttachDelayMs) -#endif - ); + std::chrono::milliseconds(kRecoveryReconnectDelayMs)); } void checkIfGroupMember(RawAddress address) { @@ -2316,12 +2358,7 @@ class LeAudioClientImpl : public LeAudioClient { FROM_HERE, base::BindOnce(&LeAudioClientImpl::checkIfGroupMember, weak_factory_.GetWeakPtr(), address), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(kCsisGroupMemberDelayMs) -#else - base::Milliseconds(kCsisGroupMemberDelayMs) -#endif - ); + std::chrono::milliseconds(kCsisGroupMemberDelayMs)); } void OnGattDisconnected(uint16_t conn_id, tGATT_IF client_if, @@ -3127,12 +3164,7 @@ class LeAudioClientImpl : public LeAudioClient { FROM_HERE, base::BindOnce(&LeAudioClientImpl::restartAttachToTheStream, weak_factory_.GetWeakPtr(), addr), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(kDeviceAttachDelayMs) -#else - base::Milliseconds(kDeviceAttachDelayMs) -#endif - ); + std::chrono::milliseconds(kDeviceAttachDelayMs)); } void SendAudioGroupSelectableCodecConfigChanged(LeAudioDeviceGroup* group) { @@ -3179,6 +3211,11 @@ class LeAudioClientImpl : public LeAudioClient { LOG_DEBUG("%s, %s", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), bluetooth::common::ToString(leAudioDevice->GetConnectionState()) .c_str()); + + if (IS_FLAG_ENABLED(le_audio_fast_bond_params)) { + L2CA_LockBleConnParamsForProfileConnection(leAudioDevice->address_, + false); + } callbacks_->OnConnectionState(ConnectionState::CONNECTED, leAudioDevice->address_); @@ -3405,6 +3442,10 @@ class LeAudioClientImpl : public LeAudioClient { return; } + if (DsaDataConsume(group, cis_conn_hdl, data, size, timestamp)) { + return; + } + uint16_t left_cis_handle = 0; uint16_t right_cis_handle = 0; for (auto [cis_handle, audio_location] : @@ -3780,6 +3821,8 @@ class LeAudioClientImpl : public LeAudioClient { dprintf(fd, " Local sink notified state: %d\n", sink_monitor_notified_status_.value()); } + dprintf(fd, " Source monitor mode: %s\n", + source_monitor_mode_ ? "true" : "false"); dprintf(fd, " Start time: "); for (auto t : stream_start_history_queue_) { dprintf(fd, ", %d ms", static_cast(t)); @@ -3814,6 +3857,7 @@ class LeAudioClientImpl : public LeAudioClient { } groupStateMachine_->Cleanup(); aseGroups_.Cleanup(); + lastNotifiedGroupStreamStatusMap_.clear(); leAudioDevices_.Cleanup(gatt_if_); if (gatt_if_) BTA_GATTC_AppDeregister(gatt_if_); @@ -3873,6 +3917,10 @@ class LeAudioClientImpl : public LeAudioClient { sink_cfg_available = false; } + if (DsaReconfigureNeeded(group, context_type)) { + reconfiguration_needed = true; + } + LOG_DEBUG( " Context: %s Reconfiguration_needed = %d, sink_cfg_available = %d, " "source_cfg_available = %d", @@ -4264,7 +4312,7 @@ class LeAudioClientImpl : public LeAudioClient { void notifyAudioLocalSink(UnicastMonitorModeStatus status) { if (sink_monitor_notified_status_ != status) { - LOG_INFO("Stram monitoring status changed to: %d", + LOG_INFO("Stream monitoring status changed to: %d", static_cast(status)); sink_monitor_notified_status_ = status; callbacks_->OnUnicastMonitorModeStatus( @@ -4286,7 +4334,8 @@ class LeAudioClientImpl : public LeAudioClient { if (sink_monitor_mode_ && active_group_id_ == bluetooth::groups::kGroupUnknown) { - if (!sink_monitor_notified_status_) { + if (sink_monitor_notified_status_ != + UnicastMonitorModeStatus::STREAMING_REQUESTED) { notifyAudioLocalSink(UnicastMonitorModeStatus::STREAMING_REQUESTED); } CancelLocalAudioSinkStreamingRequest(); @@ -4592,13 +4641,13 @@ class LeAudioClientImpl : public LeAudioClient { LOG_INFO( "group_id %d state=%s, target_state=%s, audio_receiver_state_: %s, " - "audio_sender_state_: %s", + "audio_sender_state_: %s, dsa_mode: %d", group->group_id_, ToString(group->GetState()).c_str(), ToString(group->GetTargetState()).c_str(), ToString(audio_receiver_state_).c_str(), - ToString(audio_sender_state_).c_str()); + ToString(audio_sender_state_).c_str(), static_cast(dsa_mode)); - group->dsa_mode_ = dsa_mode; + group->dsa_.mode = dsa_mode; /* Set the remote sink metadata context from the playback tracks metadata */ local_metadata_context_types_.source = @@ -5030,11 +5079,36 @@ class LeAudioClientImpl : public LeAudioClient { remote_metadata); } + bool DsaReconfigureNeeded(LeAudioDeviceGroup* group, + LeAudioContextType context) { + if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + return false; + } + + // Reconfigure if DSA mode changed for media streaming + if (context != le_audio::types::LeAudioContextType::MEDIA) { + return false; + } + + if (group->dsa_.mode != DsaMode::ISO_SW && + group->dsa_.mode != DsaMode::ISO_HW) { + return false; + } + + if (group->dsa_.active) { + return false; + } + + LOG_INFO("DSA mode %d requested but not active", group->dsa_.mode); + return true; + } + /* Return true if stream is started */ bool ReconfigureOrUpdateMetadata( LeAudioDeviceGroup* group, LeAudioContextType new_configuration_context, BidirectionalPair remote_contexts) { - if (new_configuration_context != configuration_context_type_) { + if (new_configuration_context != configuration_context_type_ || + DsaReconfigureNeeded(group, new_configuration_context)) { LOG_INFO("Checking whether to change configuration context from %s to %s", ToString(configuration_context_type_).c_str(), ToString(new_configuration_context).c_str()); @@ -5390,6 +5464,30 @@ class LeAudioClientImpl : public LeAudioClient { stream_setup_start_timestamp_ = 0; } + void notifyGroupStreamStatus(int group_id, + GroupStreamStatus groupStreamStatus) { + if (!IS_FLAG_ENABLED(leaudio_callback_on_group_stream_status)) { + return; + } + + GroupStreamStatus newGroupStreamStatus = GroupStreamStatus::IDLE; + if (groupStreamStatus == GroupStreamStatus::STREAMING) { + newGroupStreamStatus = GroupStreamStatus::STREAMING; + } + + auto it = lastNotifiedGroupStreamStatusMap_.find(group_id); + + if (it != lastNotifiedGroupStreamStatusMap_.end()) { + if (it->second != newGroupStreamStatus) { + callbacks_->OnGroupStreamStatus(group_id, newGroupStreamStatus); + it->second = newGroupStreamStatus; + } + } else { + callbacks_->OnGroupStreamStatus(group_id, newGroupStreamStatus); + lastNotifiedGroupStreamStatusMap_.emplace(group_id, newGroupStreamStatus); + } + } + void OnStateMachineStatusReportCb(int group_id, GroupStreamStatus status) { LOG_INFO( "status: %d , group_id: %d, audio_sender_state %s, " @@ -5398,6 +5496,9 @@ class LeAudioClientImpl : public LeAudioClient { bluetooth::common::ToString(audio_sender_state_).c_str(), bluetooth::common::ToString(audio_receiver_state_).c_str()); LeAudioDeviceGroup* group = aseGroups_.FindById(group_id); + + notifyGroupStreamStatus(group_id, status); + switch (status) { case GroupStreamStatus::STREAMING: { ASSERT_LOG(group_id == active_group_id_, "invalid group id %d!=%d", @@ -5513,6 +5614,14 @@ class LeAudioClientImpl : public LeAudioClient { kLeAudioContextAllRemoteSource.test(configuration_context_type_) ? le_audio::types::kLeAudioDirectionSource : le_audio::types::kLeAudioDirectionSink; + + /* Reconfiguration to non requiring source scenario */ + if (sink_monitor_mode_ && + (remote_direction == le_audio::types::kLeAudioDirectionSink)) { + notifyAudioLocalSink( + UnicastMonitorModeStatus::STREAMING_SUSPENDED); + } + auto remote_contexts = DirectionalRealignMetadataAudioContexts(group, remote_direction); ApplyRemoteMetadataAudioContextPolicy(group, remote_contexts, @@ -5527,8 +5636,13 @@ class LeAudioClientImpl : public LeAudioClient { group->ClearPendingConfiguration(); } else { if (sink_monitor_mode_) { + notifyAudioLocalSink( + UnicastMonitorModeStatus::STREAMING_SUSPENDED); + } + + if (source_monitor_mode_) { callbacks_->OnUnicastMonitorModeStatus( - le_audio::types::kLeAudioDirectionSink, + le_audio::types::kLeAudioDirectionSource, UnicastMonitorModeStatus::STREAMING_SUSPENDED); } } @@ -5609,6 +5723,8 @@ class LeAudioClientImpl : public LeAudioClient { bool sink_monitor_mode_; /* Status which has been notified to Service */ std::optional sink_monitor_notified_status_; + /* Listen for streaming status on Source stream */ + bool source_monitor_mode_; /* Reconnection mode */ tBTM_BLE_CONN_TYPE reconnection_mode_; @@ -5669,6 +5785,8 @@ class LeAudioClientImpl : public LeAudioClient { base::WeakPtrFactory weak_factory_{this}; + std::map lastNotifiedGroupStreamStatusMap_; + void ClientAudioInterfaceRelease() { if (le_audio_source_hal_client_) { le_audio_source_hal_client_->Stop(); @@ -5692,6 +5810,41 @@ class LeAudioClientImpl : public LeAudioClient { le_audio::MetricsCollector::Get()->OnStreamEnded(active_group_id_); } + + bool DsaDataConsume(LeAudioDeviceGroup* group, uint16_t cis_conn_hdl, + uint8_t* data, uint16_t size, uint32_t timestamp) { + if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + return false; + } + + if (iso_data_callback == nullptr || !group->dsa_.active || + group->dsa_.mode != DsaMode::ISO_SW) { + return false; + } + + // Find LE Audio device + LeAudioDevice* leAudioDevice = group->GetFirstDevice(); + while (leAudioDevice != nullptr) { + if (leAudioDevice->GetDsaCisHandle() == cis_conn_hdl && + leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURED) { + break; + } + leAudioDevice = group->GetNextDevice(leAudioDevice); + } + if (leAudioDevice == nullptr) { + LOG_WARN("No LE Audio device found for CIS handle: %d", cis_conn_hdl); + return false; + } + + bool consumed = iso_data_callback(leAudioDevice->address_, cis_conn_hdl, + data, size, timestamp); + if (consumed) { + return true; + } else { + LOG_VERBOSE("ISO data consumer not ready to accept data"); + return false; + } + } }; static void le_audio_health_status_callback(const RawAddress& addr, @@ -5950,6 +6103,13 @@ bool LeAudioClient::GetAsesForStorage(const RawAddress& addr, bool LeAudioClient::IsLeAudioClientRunning(void) { return instance != nullptr; } +bool LeAudioClient::IsLeAudioClientInStreaming(void) { + if (!instance) { + return false; + } + return instance->IsInStreaming(); +} + LeAudioClient* LeAudioClient::Get() { CHECK(instance); return instance; @@ -5968,9 +6128,9 @@ void LeAudioClient::Initialize( } if (!controller_get_interface() - ->supports_ble_connected_isochronous_stream_central() && + ->SupportsBleConnectedIsochronousStreamCentral() && !controller_get_interface() - ->supports_ble_connected_isochronous_stream_peripheral()) { + ->SupportsBleConnectedIsochronousStreamPeripheral()) { LOG(ERROR) << "Controller reports no ISO support." " LeAudioClient Init aborted."; return; @@ -6038,3 +6198,12 @@ void LeAudioClient::Cleanup(void) { IsoManager::GetInstance()->Stop(); le_audio::MetricsCollector::Get()->Flush(); } + +bool LeAudioClient::RegisterIsoDataConsumer(LeAudioIsoDataCallback callback) { + if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + return false; + } + + iso_data_callback = callback; + return true; +} diff --git a/system/bta/le_audio/client_linux.cc b/system/bta/le_audio/client_linux.cc index f905add422fab2d4c5212dbc89c8e180d99c982a..946deeda15c8eefe42b308455217f4021e0997f7 100644 --- a/system/bta/le_audio/client_linux.cc +++ b/system/bta/le_audio/client_linux.cc @@ -79,3 +79,4 @@ bool LeAudioClient::GetAsesForStorage(const RawAddress& addr, return false; } bool LeAudioClient::IsLeAudioClientRunning() { return false; } +bool LeAudioClient::IsLeAudioClientInStreaming() { return false; } diff --git a/system/bta/le_audio/client_parser.h b/system/bta/le_audio/client_parser.h index 38a7ec1b31c8f052a1c91f18a5c612c23d960b89..718c624b5d9399cece9b07b9d7330eea18035d58 100644 --- a/system/bta/le_audio/client_parser.h +++ b/system/bta/le_audio/client_parser.h @@ -22,6 +22,8 @@ #pragma once +#include + #include "le_audio_types.h" namespace le_audio { diff --git a/system/bta/le_audio/codec_interface.cc b/system/bta/le_audio/codec_interface.cc index 5a0baf3d5a30fcb88ed07962d85b37d4f7db2813..b4ede54b8ff70951b0753a612eb5a49585dc62fa 100644 --- a/system/bta/le_audio/codec_interface.cc +++ b/system/bta/le_audio/codec_interface.cc @@ -25,7 +25,7 @@ #include #include -#include "osi/include/log.h" +#include "os/log.h" namespace le_audio { diff --git a/system/bta/le_audio/codec_interface.h b/system/bta/le_audio/codec_interface.h index cd2cca98c604d30eff5d6a54f02f28930a691e2c..82a20c9bff99ede74d399e50c948dc642565fb14 100644 --- a/system/bta/le_audio/codec_interface.h +++ b/system/bta/le_audio/codec_interface.h @@ -20,6 +20,8 @@ #include +#include + #include "audio_hal_client/audio_hal_client.h" #include "le_audio_types.h" diff --git a/system/bta/le_audio/codec_manager.cc b/system/bta/le_audio/codec_manager.cc index ecd18aa6375a4f0a42510faf37105a1f600a62e7..c01d34a0b8ec5b6b4874b60e508389f23f82af27 100644 --- a/system/bta/le_audio/codec_manager.cc +++ b/system/bta/le_audio/codec_manager.cc @@ -21,7 +21,7 @@ #include "device/include/controller.h" #include "le_audio_set_configuration_provider.h" #include "le_audio_utils.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" #include "stack/include/hcimsgs.h" diff --git a/system/bta/le_audio/codec_manager.h b/system/bta/le_audio/codec_manager.h index 6d758bc3d5041667543133eccf591f1e16469597..7cd08d543f1d8feb4c59773ed4248c1031d3b9a1 100644 --- a/system/bta/le_audio/codec_manager.h +++ b/system/bta/le_audio/codec_manager.h @@ -16,6 +16,8 @@ #pragma once +#include + #include "hardware/bt_le_audio.h" #include "le_audio_types.h" diff --git a/system/bta/le_audio/codec_manager_test.cc b/system/bta/le_audio/codec_manager_test.cc index 45d12b46295227241916e4560a89db1c2435874b..cca0010f99ddc40bd26a501abe279c5eda06b630 100644 --- a/system/bta/le_audio/codec_manager_test.cc +++ b/system/bta/le_audio/codec_manager_test.cc @@ -19,7 +19,7 @@ #include #include -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "le_audio_set_configuration_provider.h" #include "mock_controller.h" #include "test/mock/mock_legacy_hci_interface.h" @@ -49,8 +49,9 @@ static const std::vector offload_capabilities_none(0); const std::vector* offload_capabilities = &offload_capabilities_none; -const char* test_flags[] = { +static const char* test_flags[] = { "INIT_default_log_level_str=LOG_VERBOSE", + nullptr, }; namespace bluetooth { diff --git a/system/bta/le_audio/content_control_id_keeper.cc b/system/bta/le_audio/content_control_id_keeper.cc index a1df761d8a7bfe51d3f0dfff0c92cd926889c279..75042b9881cc43d3d0cc02e1c90b41d28497f7a9 100644 --- a/system/bta/le_audio/content_control_id_keeper.cc +++ b/system/bta/le_audio/content_control_id_keeper.cc @@ -21,9 +21,9 @@ #include #include -#include "gd/common/strings.h" +#include "common/strings.h" #include "le_audio_types.h" -#include "osi/include/log.h" +#include "os/log.h" namespace { diff --git a/system/bta/le_audio/device_groups.cc b/system/bta/le_audio/device_groups.cc index 48ce4ad225593c63d643768c1f2c53654cff52dd..f64060c7289ccc22e12ab37acd503eeeeddf9dc3 100644 --- a/system/bta/le_audio/device_groups.cc +++ b/system/bta/le_audio/device_groups.cc @@ -18,11 +18,12 @@ #include "device_groups.h" +#include "bta/include/bta_gatt_api.h" #include "bta_csis_api.h" -#include "btif_storage.h" +#include "btif/include/btif_profile_storage.h" #include "btm_iso_api.h" #include "device/include/controller.h" -#include "dm/bta_dm_gatt_client.h" +#include "internal_include/bt_trace.h" #include "le_audio_set_configuration_provider.h" #include "metrics_collector.h" @@ -631,7 +632,7 @@ uint8_t LeAudioDeviceGroup::GetPhyBitmask(uint8_t direction) const { // local supported PHY's uint8_t phy_bitfield = bluetooth::hci::kIsoCigPhy1M; - if (controller_get_interface()->supports_ble_2m_phy()) + if (controller_get_interface()->SupportsBle2mPhy()) phy_bitfield |= bluetooth::hci::kIsoCigPhy2M; if (!leAudioDevice) { @@ -762,13 +763,14 @@ bool LeAudioDeviceGroup::UpdateAudioSetConfigurationCache( if (update_config) { context_to_configuration_cache_map[ctx_type] = std::pair(true, new_conf); - LOG_DEBUG("config: %s -> %s", ToHexString(ctx_type).c_str(), - (new_conf ? new_conf->name.c_str() : "(none)")); + LOG_INFO("config: %s -> %s", ToHexString(ctx_type).c_str(), + (new_conf ? new_conf->name.c_str() : "(none)")); } return update_config; } void LeAudioDeviceGroup::InvalidateCachedConfigurations(void) { + LOG_INFO(" Group id: %d", group_id_); context_to_configuration_cache_map.clear(); } @@ -831,9 +833,7 @@ bool LeAudioDeviceGroup::ReloadAudioDirections(void) { return true; } -bool LeAudioDeviceGroup::IsInTransition(void) const { - return target_state_ != current_state_; -} +bool LeAudioDeviceGroup::IsInTransition(void) const { return in_transition_; } bool LeAudioDeviceGroup::IsStreaming(void) const { return current_state_ == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING; @@ -934,9 +934,6 @@ void LeAudioDeviceGroup::CigConfiguration::GenerateCisIds( return; } - const set_configurations::AudioSetConfigurations* confs = - AudioSetConfigurationProvider::Get()->GetConfigurations(context_type); - uint8_t cis_count_bidir = 0; uint8_t cis_count_unidir_sink = 0; uint8_t cis_count_unidir_source = 0; @@ -950,11 +947,11 @@ void LeAudioDeviceGroup::CigConfiguration::GenerateCisIds( * If the last happen it means, group size is 1 */ int group_size = csis_group_size > 0 ? csis_group_size : 1; - get_cis_count(*confs, group_size, group_->GetGroupStrategy(group_size), - group_->GetAseCount(types::kLeAudioDirectionSink), - group_->GetAseCount(types::kLeAudioDirectionSource), - cis_count_bidir, cis_count_unidir_sink, - cis_count_unidir_source); + set_configurations::get_cis_count( + context_type, group_size, group_->GetGroupStrategy(group_size), + group_->GetAseCount(types::kLeAudioDirectionSink), + group_->GetAseCount(types::kLeAudioDirectionSource), cis_count_bidir, + cis_count_unidir_sink, cis_count_unidir_source); uint8_t idx = 0; while (cis_count_bidir > 0) { diff --git a/system/bta/le_audio/device_groups.h b/system/bta/le_audio/device_groups.h index 7bc4a257fd392398753bb844eed3249528ac09df..1c2be8a1a1d0498b6c3d4d6f03df6109e1afba81 100644 --- a/system/bta/le_audio/device_groups.h +++ b/system/bta/le_audio/device_groups.h @@ -84,7 +84,11 @@ class LeAudioDeviceGroup { /* Whether LE Audio is preferred for OUTPUT_ONLY and DUPLEX cases */ bool is_output_preference_le_audio; bool is_duplex_preference_le_audio; - DsaMode dsa_mode_; + + struct { + DsaMode mode; + bool active; + } dsa_; bool asymmetric_phy_for_unidirectional_cis_supported; explicit LeAudioDeviceGroup(const int group_id) @@ -93,7 +97,7 @@ class LeAudioDeviceGroup { stream_conf({}), notify_streaming_when_cises_are_ready_(false), audio_directions_(0), - dsa_mode_(DsaMode::DISABLED), + dsa_({DsaMode::DISABLED, false}), is_enabled_(true), transport_latency_mtos_us_(0), transport_latency_stom_us_(0), @@ -110,7 +114,8 @@ class LeAudioDeviceGroup { pending_group_available_contexts_change_( types::LeAudioContextType::UNINITIALIZED), target_state_(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE), - current_state_(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE) { + current_state_(types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE), + in_transition_(false) { #ifdef __ANDROID__ // 22 maps to BluetoothProfile#LE_AUDIO is_output_preference_le_audio = android::sysprop::BluetoothProperties:: @@ -227,13 +232,19 @@ class LeAudioDeviceGroup { inline types::AseState GetState(void) const { return current_state_; } void SetState(types::AseState state) { - LOG(INFO) << __func__ << " current state: " << current_state_ - << " new state: " << state; + LOG_INFO(" current state: %s, new state %s, in_transition_ %d", + bluetooth::common::ToString(current_state_).c_str(), + bluetooth::common::ToString(state).c_str(), in_transition_); LeAudioLogHistory::Get()->AddLogHistory( kLogStateMachineTag, group_id_, RawAddress::kEmpty, kLogStateChangedOp, bluetooth::common::ToString(current_state_) + "->" + bluetooth::common::ToString(state)); current_state_ = state; + + if (target_state_ == current_state_) { + in_transition_ = false; + LOG_INFO("In transition flag cleared"); + } } inline types::AseState GetTargetState(void) const { return target_state_; } @@ -244,14 +255,19 @@ class LeAudioDeviceGroup { return notify_streaming_when_cises_are_ready_; } void SetTargetState(types::AseState state) { - LOG(INFO) << __func__ << " target state: " << target_state_ - << " new target state: " << state; + LOG_INFO("target state: %s, new target state: %s, in_transition_ %d", + bluetooth::common::ToString(target_state_).c_str(), + bluetooth::common::ToString(state).c_str(), in_transition_); LeAudioLogHistory::Get()->AddLogHistory( kLogStateMachineTag, group_id_, RawAddress::kEmpty, kLogTargetStateChangedOp, bluetooth::common::ToString(target_state_) + "->" + bluetooth::common::ToString(state)); + target_state_ = state; + + in_transition_ = target_state_ != current_state_; + LOG_INFO("In transition flag = %d", in_transition_); } /* Returns context types for which support was recently added or removed */ @@ -315,14 +331,23 @@ class LeAudioDeviceGroup { int direction = types::kLeAudioDirectionBoth) const; DsaModes GetAllowedDsaModes() { - DsaModes dsa_modes = {}; + if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + return {DsaMode::DISABLED}; + } + + DsaModes dsa_modes{}; + std::set dsa_mode_set{}; + for (auto leAudioDevice : leAudioDevices_) { if (leAudioDevice.expired()) continue; - dsa_modes.insert(dsa_modes.end(), - leAudioDevice.lock()->GetDsaModes().begin(), - leAudioDevice.lock()->GetDsaModes().end()); + auto device_dsa_modes = leAudioDevice.lock()->GetDsaModes(); + + dsa_mode_set.insert(device_dsa_modes.begin(), device_dsa_modes.end()); } + + dsa_modes.assign(dsa_mode_set.begin(), dsa_mode_set.end()); + return dsa_modes; } @@ -396,6 +421,7 @@ class LeAudioDeviceGroup { types::AseState target_state_; types::AseState current_state_; + bool in_transition_; std::vector> leAudioDevices_; }; diff --git a/system/bta/le_audio/devices.cc b/system/bta/le_audio/devices.cc index 88b5060cc98a54fa7994dff815623e515954f7ac..c71b273c2bc346a0bc9510eeb6e811f1d18bddab 100644 --- a/system/bta/le_audio/devices.cc +++ b/system/bta/le_audio/devices.cc @@ -17,12 +17,13 @@ #include "devices.h" +#include #include #include "acl_api.h" -#include "android_bluetooth_flags.h" #include "bta_gatt_queue.h" -#include "btif_storage.h" +#include "btif/include/btif_storage.h" +#include "internal_include/bt_trace.h" using bluetooth::hci::kIsoCigPhy1M; using bluetooth::hci::kIsoCigPhy2M; @@ -355,7 +356,7 @@ void LeAudioDevice::RegisterPACs( pac_db->clear(); } - dsa_modes_ = {DsaMode::DISABLED}; + dsa_.modes = {DsaMode::DISABLED}; /* TODO wrap this logging part with debug flag */ for (const struct types::acs_ac_record& pac : *pac_recs) { @@ -372,8 +373,9 @@ void LeAudioDevice::RegisterPACs( if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { if (pac.codec_id == types::kLeAudioCodecHeadtracking) { + LOG(INFO) << __func__ << ": Headtracking supported"; /* Todo: Set DSA modes according to the codec configuration */ - dsa_modes_ = { + dsa_.modes = { DsaMode::DISABLED, DsaMode::ISO_SW, DsaMode::ISO_HW, @@ -1022,7 +1024,22 @@ void LeAudioDevice::UpdateDeviceAllowlistFlag(void) { } } } -DsaModes LeAudioDevice::GetDsaModes(void) { return dsa_modes_; } + +DsaModes LeAudioDevice::GetDsaModes(void) { return dsa_.modes; } + +types::DataPathState LeAudioDevice::GetDsaDataPathState(void) { + return dsa_.state; +} + +void LeAudioDevice::SetDsaDataPathState(types::DataPathState state) { + dsa_.state = state; +} + +uint16_t LeAudioDevice::GetDsaCisHandle(void) { return dsa_.cis_handle; } + +void LeAudioDevice::SetDsaCisHandle(uint16_t cis_handle) { + dsa_.cis_handle = cis_handle; +} /* LeAudioDevices Class methods implementation */ void LeAudioDevices::Add(const RawAddress& address, DeviceConnectState state, diff --git a/system/bta/le_audio/devices.h b/system/bta/le_audio/devices.h index 7d3f6f118d9beaa6631bb465cd61ac1d98e41c94..576e7c897b6bc90d518f0cb7729449a56cb21055 100644 --- a/system/bta/le_audio/devices.h +++ b/system/bta/le_audio/devices.h @@ -33,12 +33,12 @@ #include "audio_hal_client/audio_hal_client.h" #include "bta_groups.h" #include "btm_iso_api_types.h" +#include "common/strings.h" #include "gatt_api.h" -#include "gd/common/strings.h" #include "le_audio_log_history.h" #include "le_audio_types.h" +#include "os/log.h" #include "osi/include/alarm.h" -#include "osi/include/log.h" #include "osi/include/properties.h" #include "raw_address.h" @@ -141,7 +141,9 @@ class LeAudioDevice { model_name_(""), allowlist_flag_(false), link_quality_timer(nullptr), - dsa_modes_({DsaMode::DISABLED}) {} + dsa_({{DsaMode::DISABLED}, + types::DataPathState::IDLE, + GATT_INVALID_CONN_ID}) {} ~LeAudioDevice(void); void SetConnectionState(DeviceConnectState state); @@ -250,11 +252,20 @@ class LeAudioDevice { void GetDeviceModelName(void); void UpdateDeviceAllowlistFlag(void); DsaModes GetDsaModes(void); + types::DataPathState GetDsaDataPathState(void); + void SetDsaDataPathState(types::DataPathState state); + uint16_t GetDsaCisHandle(void); + void SetDsaCisHandle(uint16_t cis_handle); private: types::BidirectionalPair avail_contexts_; types::BidirectionalPair supp_contexts_; - DsaModes dsa_modes_; + struct { + DsaModes modes; + types::DataPathState state; + uint16_t cis_handle; + } dsa_; + static constexpr char kLeAudioDeviceAllowListProp[] = "persist.bluetooth.leaudio.allow_list"; diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc index 60418b39e308a62fe58c35b97790d0971a926dca..b71480c72240f301b5141cda49ea4ef30adec554 100644 --- a/system/bta/le_audio/le_audio_client_test.cc +++ b/system/bta/le_audio/le_audio_client_test.cc @@ -45,7 +45,7 @@ #include "mock_device_groups.h" #include "mock_iso_manager.h" #include "mock_state_machine.h" -#include "osi/include/log.h" +#include "os/log.h" #include "test/common/mock_functions.h" #define TEST_BT com::android::bluetooth::flags @@ -56,6 +56,7 @@ using testing::AtLeast; using testing::AtMost; using testing::DoAll; using testing::Expectation; +using testing::InSequence; using testing::Invoke; using testing::Matcher; using testing::Mock; @@ -94,16 +95,26 @@ constexpr le_audio::types::LeAudioContextType static constexpr char kNotifyUpperLayerAboutGroupBeingInIdleDuringCall[] = "persist.bluetooth.leaudio.notify.idle.during.call"; const char* test_flags[] = { - "INIT_logging_debug_enabled_for_all=true", + "INIT_default_log_level_str=LOG_VERBOSE", "INIT_leaudio_targeted_announcement_reconnection_mode=true", "INIT_leaudio_enable_health_based_actions=false", + "INIT_leaudio_broadcast_audio_handover_policies=false", nullptr, }; const char* test_flags_with_health_status[] = { - "INIT_logging_debug_enabled_for_all=true", + "INIT_default_log_level_str=LOG_VERBOSE", "INIT_leaudio_targeted_announcement_reconnection_mode=true", "INIT_leaudio_enable_health_based_actions=true", + "INIT_leaudio_broadcast_audio_handover_policies=false", + nullptr, +}; + +const char* test_flags_with_handover_mode[] = { + "INIT_default_log_level_str=LOG_VERBOSE", + "INIT_leaudio_targeted_announcement_reconnection_mode=true", + "INIT_leaudio_enable_health_based_actions=false", + "INIT_leaudio_broadcast_audio_handover_policies=true", nullptr, }; @@ -144,7 +155,7 @@ bt_status_t do_in_main_thread(const base::Location& from_here, bt_status_t do_in_main_thread_delayed(const base::Location& from_here, base::OnceClosure task, - const base::TimeDelta& delay) { + std::chrono::microseconds delay) { /* For testing purpose it is ok to just skip delay */ return do_in_main_thread(from_here, std::move(task)); } @@ -253,6 +264,9 @@ class MockAudioHalClientCallbacks (ConnectionState state, const RawAddress& address), (override)); MOCK_METHOD((void), OnGroupStatus, (int group_id, GroupStatus group_status), (override)); + MOCK_METHOD((void), OnGroupStreamStatus, + (int group_id, GroupStreamStatus group_stream_status), + (override)); MOCK_METHOD((void), OnGroupNodeStatus, (const RawAddress& bd_addr, int group_id, GroupNodeStatus node_status), @@ -336,11 +350,57 @@ class MockLeAudioSourceHalClient : public LeAudioSourceAudioHalClient { class UnicastTestNoInit : public Test { public: bool use_health_status = false; + bool use_handover_mode = false; protected: + void RegisterSourceHalClientMock() { + owned_mock_le_audio_source_hal_client_.reset( + new NiceMock()); + mock_le_audio_source_hal_client_ = + (MockLeAudioSourceHalClient*) + owned_mock_le_audio_source_hal_client_.get(); + + is_audio_unicast_source_acquired = false; + ON_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)) + .WillByDefault( + [this](const LeAudioCodecConfiguration& codec_configuration, + LeAudioSourceAudioHalClient::Callbacks* audioReceiver, + DsaModes dsa_modes) { + unicast_source_hal_cb_ = audioReceiver; + return true; + }); + ON_CALL(*mock_le_audio_source_hal_client_, OnDestroyed).WillByDefault([]() { + mock_le_audio_source_hal_client_ = nullptr; + is_audio_unicast_source_acquired = false; + }); + } + + void RegisterSinkHalClientMock() { + owned_mock_le_audio_sink_hal_client_.reset( + new NiceMock()); + mock_le_audio_sink_hal_client_ = + (MockLeAudioSinkHalClient*)owned_mock_le_audio_sink_hal_client_.get(); + + is_audio_unicast_sink_acquired = false; + ON_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)) + .WillByDefault( + [this](const LeAudioCodecConfiguration& codec_configuration, + LeAudioSinkAudioHalClient::Callbacks* audioReceiver, + DsaModes dsa_modes) { + unicast_sink_hal_cb_ = audioReceiver; + return true; + }); + ON_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed).WillByDefault([]() { + mock_le_audio_sink_hal_client_ = nullptr; + is_audio_unicast_sink_acquired = false; + }); + } + void SetUpMockAudioHal() { if (use_health_status) { bluetooth::common::InitFlags::Load(test_flags_with_health_status); + } else if (use_handover_mode) { + bluetooth::common::InitFlags::Load(test_flags_with_handover_mode); } else { bluetooth::common::InitFlags::Load(test_flags); } @@ -348,6 +408,7 @@ class UnicastTestNoInit : public Test { /* Since these are returned by the Acquire() methods as unique_ptrs, we * will not free them manually. */ + RegisterSourceHalClientMock(); owned_mock_le_audio_sink_hal_client_.reset( new NiceMock()); @@ -2764,6 +2825,23 @@ class UnicastTestHealthStatus : public UnicastTest { LeAudioDeviceGroup* group_ = nullptr; }; +class UnicastTestHandoverMode : public UnicastTest { + protected: + void SetUp() override { + use_handover_mode = true; + UnicastTest::SetUp(); + group_ = new LeAudioDeviceGroup(group_id_); + } + + void TearDown() override { + delete group_; + UnicastTest::TearDown(); + } + + const int group_id_ = 0; + LeAudioDeviceGroup* group_ = nullptr; +}; + RawAddress GetTestAddress(uint8_t index) { CHECK_LT(index, UINT8_MAX); RawAddress result = {{0xC0, 0xDE, 0xC0, 0xDE, 0x00, index}}; @@ -8625,4 +8703,944 @@ TEST_F(UnicastTest, DisconnectAclBeforeGettingReadResponses) { SyncOnMainLoop(); } +TEST_F_WITH_FLAGS(UnicastTest, GroupStreamStatus, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_callback_on_group_stream_status))) { + int group_id = bluetooth::groups::kGroupUnknown; + + InSequence s; + + /* Check if all states are properly notified */ + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::RELEASING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::SUSPENDING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::SUSPENDED); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb( + group_id, GroupStreamStatus::CONFIGURED_AUTONOMOUS); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb( + group_id, GroupStreamStatus::CONFIGURED_BY_USER); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::DESTROYED); + + /* Check if there are no resending of the same state */ + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::RELEASING); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::SUSPENDING); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::SUSPENDED); + state_machine_callbacks_->StatusReportCb( + group_id, GroupStreamStatus::CONFIGURED_AUTONOMOUS); + state_machine_callbacks_->StatusReportCb( + group_id, GroupStreamStatus::CONFIGURED_BY_USER); + state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE); + + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); +} + +TEST_F_WITH_FLAGS(UnicastTest, GroupStreamStatusManyGroups, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_callback_on_group_stream_status))) { + uint8_t group_size = 2; + int group_id_1 = 1; + int group_id_2 = 2; + + // Report working CSIS + ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) + .WillByDefault(Return(true)); + + ON_CALL(mock_csis_client_module_, GetDesiredSize(_)) + .WillByDefault(Return(group_size)); + + // First group - First earbud + const RawAddress test_address0 = GetTestAddress(0); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) + .Times(1); + ConnectCsisDevice(test_address0, 1 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontLeft, + codec_spec_conf::kLeAudioLocationFrontLeft, group_size, + group_id_1, 1 /* rank*/); + + // First group - Second earbud + const RawAddress test_address1 = GetTestAddress(1); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) + .Times(1); + ConnectCsisDevice(test_address1, 2 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontRight, + codec_spec_conf::kLeAudioLocationFrontRight, group_size, + group_id_1, 2 /* rank*/, true /*connect_through_csis*/); + + // Second group - First earbud + const RawAddress test_address2 = GetTestAddress(2); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address2, true)) + .Times(1); + ConnectCsisDevice(test_address2, 3 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontLeft, + codec_spec_conf::kLeAudioLocationFrontLeft, group_size, + group_id_2, 1 /* rank*/); + + // Second group - Second earbud + const RawAddress test_address3 = GetTestAddress(3); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address3, true)) + .Times(1); + ConnectCsisDevice(test_address3, 4 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontRight, + codec_spec_conf::kLeAudioLocationFrontRight, group_size, + group_id_2, 2 /* rank*/, true /*connect_through_csis*/); + + InSequence s; + + // Group 1 IDLE + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id_1, GroupStreamStatus::IDLE); + + // Group 2 IDLE + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id_2, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id_2, GroupStreamStatus::IDLE); + + // Group 1 active and start streaming + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id_1, GroupStreamStatus::STREAMING)) + .Times(1); + LeAudioClient::Get()->GroupSetActive(group_id_1); + SyncOnMainLoop(); + StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_1); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + + // Group 2 active + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id_1, GroupStreamStatus::IDLE)) + .Times(1); + LeAudioClient::Get()->GroupSetActive(group_id_2); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + + // Group 2 start streaming + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id_2, GroupStreamStatus::STREAMING)) + .Times(1); + StartStreaming(AUDIO_USAGE_MEDIA, AUDIO_CONTENT_TYPE_MUSIC, group_id_2); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); +} + +TEST_F_WITH_FLAGS(UnicastTest, GroupStreamStatusResendAfterRemove, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_callback_on_group_stream_status))) { + uint8_t group_size = 2; + int group_id = 1; + + // Report working CSIS + ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) + .WillByDefault(Return(true)); + + ON_CALL(mock_csis_client_module_, GetDesiredSize(_)) + .WillByDefault(Return(group_size)); + + // First earbud + const RawAddress test_address0 = GetTestAddress(0); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) + .Times(1); + ConnectCsisDevice(test_address0, 1 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontLeft, + codec_spec_conf::kLeAudioLocationFrontLeft, group_size, + group_id, 1 /* rank*/); + + // Second earbud + const RawAddress test_address1 = GetTestAddress(1); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) + .Times(1); + ConnectCsisDevice(test_address1, 2 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontRight, + codec_spec_conf::kLeAudioLocationFrontRight, group_size, + group_id, 2 /* rank*/, true /*connect_through_csis*/); + + Mock::VerifyAndClearExpectations(&mock_btif_storage_); + + InSequence s; + + // Activate group, start streaming and immediately stop + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::STREAMING)) + .Times(1); + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + LeAudioClient::Get()->GroupSetActive(group_id); + SyncOnMainLoop(); + state_machine_callbacks_->StatusReportCb(group_id, + GroupStreamStatus::STREAMING); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + + // No resend + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(0); + state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE); + + // No resend after removing only one device + /* + * StopStream will put calls on main_loop so to keep the correct order + * of operations and to avoid races we put the test command on main_loop as + * well. + */ + do_in_main_thread(FROM_HERE, base::BindOnce( + [](LeAudioClient* client, + const RawAddress& test_address0) { + client->RemoveDevice(test_address0); + }, + LeAudioClient::Get(), test_address0)); + SyncOnMainLoop(); + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(0); + state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + + // Resend after removing last device + /* + * StopStream will put calls on main_loop so to keep the correct order + * of operations and to avoid races we put the test command on main_loop as + * well. + */ + do_in_main_thread(FROM_HERE, base::BindOnce( + [](LeAudioClient* client, + const RawAddress& test_address1) { + client->RemoveDevice(test_address1); + }, + LeAudioClient::Get(), test_address1)); + SyncOnMainLoop(); + EXPECT_CALL(mock_audio_hal_client_callbacks_, + OnGroupStreamStatus(group_id, GroupStreamStatus::IDLE)) + .Times(1); + state_machine_callbacks_->StatusReportCb(group_id, GroupStreamStatus::IDLE); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); +} + +TEST_F_WITH_FLAGS(UnicastTestHandoverMode, + SetSinkMonitorModeWhileUnicastIsActive, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_broadcast_audio_handover_policies))) { + uint8_t group_size = 2; + int group_id = 2; + + // Report working CSIS + ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) + .WillByDefault(Return(true)); + + // First earbud + const RawAddress test_address0 = GetTestAddress(0); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) + .Times(1); + ConnectCsisDevice(test_address0, 1 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontLeft, + codec_spec_conf::kLeAudioLocationFrontLeft, group_size, + group_id, 1 /* rank*/); + + // Second earbud + const RawAddress test_address1 = GetTestAddress(1); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) + .Times(1); + ConnectCsisDevice(test_address1, 2 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontRight, + codec_spec_conf::kLeAudioLocationFrontRight, group_size, + group_id, 2 /* rank*/, true /*connect_through_csis*/); + + ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id)) + .WillByDefault(Invoke([&](int group_id) { return 2; })); + + // Start streaming + EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1); + LeAudioClient::Get()->GroupSetActive(group_id); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + + StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, + group_id); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + SyncOnMainLoop(); + + // Verify Data transfer on two peer sinks and one source + uint8_t cis_count_out = 2; + uint8_t cis_count_in = 2; + TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40); + + // Imitate activation of monitor mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + true /* enable */)); + + auto group = streaming_groups.at(group_id); + + // Stop streaming and expect Service to be informed about straming suspension + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSink, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(1); + + // Stop + StopStreaming(group_id, true); + + // Check if cache configuration is still present + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); + + // Release, Sink HAL client should remain in monitor mode + EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0); + LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + // Re-initialize mock for destroyed hal client + RegisterSourceHalClientMock(); + + // Setting group inactive, shall not change cached configuration + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); + + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSink, + UnicastMonitorModeStatus::STREAMING_REQUESTED)) + .Times(1); + + // Start streaming to trigger next group going to IDLE state + LocalAudioSinkResume(); + + EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1); + LeAudioClient::Get()->GroupSetActive(group_id); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + + StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, + group_id); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + + // Stop streaming and expect Service to be informed about straming suspension + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSink, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(1); + + // Stop + StopStreaming(group_id, true); + + // Release, Sink HAL client should remain in monitor mode + EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0); + LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + // De-activate monitoring mode + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1); + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + false /* enable */)); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); +} + +TEST_F_WITH_FLAGS(UnicastTestHandoverMode, + SetSinkMonitorModeWhileUnicastIsInactive, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_broadcast_audio_handover_policies))) { + uint8_t group_size = 2; + int group_id = 2; + + // Imitate activation of monitor mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + true /* enable */)); + + // Report working CSIS + ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) + .WillByDefault(Return(true)); + + // First earbud + const RawAddress test_address0 = GetTestAddress(0); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) + .Times(1); + ConnectCsisDevice(test_address0, 1 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontLeft, + codec_spec_conf::kLeAudioLocationFrontLeft, group_size, + group_id, 1 /* rank*/); + + // Second earbud + const RawAddress test_address1 = GetTestAddress(1); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) + .Times(1); + ConnectCsisDevice(test_address1, 2 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontRight, + codec_spec_conf::kLeAudioLocationFrontRight, group_size, + group_id, 2 /* rank*/, true /*connect_through_csis*/); + + ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id)) + .WillByDefault(Invoke([&](int group_id) { return 2; })); + + // Start streaming + EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1); + LeAudioClient::Get()->GroupSetActive(group_id); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + + // Expect no streaming request on stream resume when group is already active + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSink, + UnicastMonitorModeStatus::STREAMING_REQUESTED)) + .Times(0); + + StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, + group_id); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + SyncOnMainLoop(); + + // Verify Data transfer on two peer sinks and one source + uint8_t cis_count_out = 2; + uint8_t cis_count_in = 2; + TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40); + + auto group = streaming_groups.at(group_id); + + // Stop streaming and expect Service to be informed about straming suspension + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSink, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(1); + + // Stop + StopStreaming(group_id, true); + + // Check if cache configuration is still present + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); + + // Release, Sink HAL client should remain in monitor mode + EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(0); + LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + // Setting group inactive, shall not change cached configuration + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); +} + +TEST_F_WITH_FLAGS(UnicastTestHandoverMode, + ClearSinkMonitorModeWhileUnicastIsActive, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_broadcast_audio_handover_policies))) { + uint8_t group_size = 2; + int group_id = 2; + + // Imitate activation of monitor mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + true /* enable */)); + + // Report working CSIS + ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) + .WillByDefault(Return(true)); + + // First earbud + const RawAddress test_address0 = GetTestAddress(0); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) + .Times(1); + ConnectCsisDevice(test_address0, 1 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontLeft, + codec_spec_conf::kLeAudioLocationFrontLeft, group_size, + group_id, 1 /* rank*/); + + // Second earbud + const RawAddress test_address1 = GetTestAddress(1); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) + .Times(1); + ConnectCsisDevice(test_address1, 2 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontRight, + codec_spec_conf::kLeAudioLocationFrontRight, group_size, + group_id, 2 /* rank*/, true /*connect_through_csis*/); + + ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id)) + .WillByDefault(Invoke([&](int group_id) { return 2; })); + + // Start streaming + EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1); + LeAudioClient::Get()->GroupSetActive(group_id); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + + // Expect no streaming request on stream resume when group is already active + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSink, + UnicastMonitorModeStatus::STREAMING_REQUESTED)) + .Times(0); + + StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, + group_id); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + SyncOnMainLoop(); + + // Verify Data transfer on two peer sinks and one source + uint8_t cis_count_out = 2; + uint8_t cis_count_in = 2; + TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40); + + auto group = streaming_groups.at(group_id); + + // De-activate monitoring mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + false /* enable */)); + + // Stop + StopStreaming(group_id, true); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + + // Check if cache configuration is still present + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); + + // Release of sink and source hals due to de-activating monitor mode + EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1); + LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + // Setting group inactive, shall not change cached configuration + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); +} + +TEST_F_WITH_FLAGS(UnicastTestHandoverMode, + SetAndClearSinkMonitorModeWhileUnicastIsInactive, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_broadcast_audio_handover_policies))) { + EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(0); + EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(0); + EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(0); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(0); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1); + + // Imitate activation of monitor mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + true /* enable */)); + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + true /* enable */)); + + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + SyncOnMainLoop(); +} + +TEST_F_WITH_FLAGS(UnicastTestHandoverMode, + SetSourceMonitorModeWhileUnicastIsInactive, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_broadcast_audio_handover_policies))) { + /* Enabling monitor mode for source while group is not active should result in + * sending STREAMING_SUSPENDED notification. + */ + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(1); + + // Imitate activation of monitor mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSource, + true /* enable */)); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); +} + +TEST_F_WITH_FLAGS(UnicastTestHandoverMode, + SetSourceMonitorModeWhileUnicastIsNotStreaming, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_broadcast_audio_handover_policies))) { + int group_id = 2; + + LeAudioClient::Get()->GroupSetActive(group_id); + + /* Enabling monitor mode for source while group is not active should result in + * sending STREAMING_SUSPENDED notification. + */ + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(1); + + // Imitate activation of monitor mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSource, + true /* enable */)); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); +} + +TEST_F_WITH_FLAGS(UnicastTestHandoverMode, + SetSourceMonitorModeWhileUnicastIsActive, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + TEST_BT, leaudio_broadcast_audio_handover_policies))) { + uint8_t group_size = 2; + int group_id = 2; + + // Report working CSIS + ON_CALL(mock_csis_client_module_, IsCsisClientRunning()) + .WillByDefault(Return(true)); + + // First earbud + const RawAddress test_address0 = GetTestAddress(0); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address0, true)) + .Times(1); + ConnectCsisDevice(test_address0, 1 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontLeft, + codec_spec_conf::kLeAudioLocationFrontLeft, group_size, + group_id, 1 /* rank*/); + + // Second earbud + const RawAddress test_address1 = GetTestAddress(1); + EXPECT_CALL(mock_btif_storage_, AddLeaudioAutoconnect(test_address1, true)) + .Times(1); + ConnectCsisDevice(test_address1, 2 /*conn_id*/, + codec_spec_conf::kLeAudioLocationFrontRight, + codec_spec_conf::kLeAudioLocationFrontRight, group_size, + group_id, 2 /* rank*/, true /*connect_through_csis*/); + + ON_CALL(mock_csis_client_module_, GetDesiredSize(group_id)) + .WillByDefault(Invoke([&](int group_id) { return 2; })); + + // Start streaming + EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1); + LeAudioClient::Get()->GroupSetActive(group_id); + SyncOnMainLoop(); + + StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, + group_id); + + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + SyncOnMainLoop(); + + // Verify Data transfer on two peer sinks and one source + uint8_t cis_count_out = 2; + uint8_t cis_count_in = 2; + TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 40); + + /* Enabling monitor mode for source while stream is active should result in + * sending STREAMING notification. + */ + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING)) + .Times(1); + + // Imitate activation of monitor mode + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSource, + true /* enable */)); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + + auto group = streaming_groups.at(group_id); + + // Stop streaming and expect Service to be informed about straming suspension + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(1); + + // Stop + StopStreaming(group_id, true); + + // Check if cache configuration is still present + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); + + // Both Sink and Source HAL clients should be stopped + EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1); + LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + // Re-initialize mock for destroyed hal client + RegisterSourceHalClientMock(); + RegisterSinkHalClientMock(); + + // Setting group inactive, shall not change cached configuration + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSink) + .has_value()); + ASSERT_TRUE(group + ->GetCachedCodecConfigurationByDirection( + types::LeAudioContextType::CONVERSATIONAL, + le_audio::types::kLeAudioDirectionSource) + .has_value()); + + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_REQUESTED)) + .Times(1); + + EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1); + LeAudioClient::Get()->GroupSetActive(group_id); + + // Start streaming to trigger next group going to IDLE state + StartStreaming(AUDIO_USAGE_VOICE_COMMUNICATION, AUDIO_CONTENT_TYPE_SPEECH, + group_id); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + // Stop streaming and expect Service to be informed about straming suspension + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(1); + + // Stop + StopStreaming(group_id, true); + + // Both Sink and Source HAL clients should be stopped + EXPECT_CALL(*mock_le_audio_source_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_source_hal_client_, OnDestroyed()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, Stop()).Times(1); + EXPECT_CALL(*mock_le_audio_sink_hal_client_, OnDestroyed()).Times(1); + LeAudioClient::Get()->GroupSetActive(bluetooth::groups::kGroupUnknown); + SyncOnMainLoop(); + + Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); + Mock::VerifyAndClearExpectations(&mock_le_audio_source_hal_client_); + Mock::VerifyAndClearExpectations(&mock_le_audio_sink_hal_client_); + + // De-activate monitoring mode + EXPECT_CALL( + mock_audio_hal_client_callbacks_, + OnUnicastMonitorModeStatus(le_audio::types::kLeAudioDirectionSource, + UnicastMonitorModeStatus::STREAMING_SUSPENDED)) + .Times(0); + + do_in_main_thread(FROM_HERE, + base::BindOnce(&LeAudioClient::SetUnicastMonitorMode, + base::Unretained(LeAudioClient::Get()), + le_audio::types::kLeAudioDirectionSink, + false /* enable */)); +} } // namespace le_audio diff --git a/system/bta/le_audio/le_audio_health_status.cc b/system/bta/le_audio/le_audio_health_status.cc index 233a80e7c555e54c125c5ef2ec1260cad2cc50fd..5e548b01762741cd44316105de5ad73a4494decc 100644 --- a/system/bta/le_audio/le_audio_health_status.cc +++ b/system/bta/le_audio/le_audio_health_status.cc @@ -19,9 +19,9 @@ #include #include "bta/include/bta_groups.h" -#include "gd/common/strings.h" +#include "common/strings.h" #include "main/shim/metrics_api.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/properties.h" using bluetooth::common::ToString; diff --git a/system/bta/le_audio/le_audio_health_status_test.cc b/system/bta/le_audio/le_audio_health_status_test.cc index 48cfcde303f00b326b6c4b8970c0d4d49dd21c77..1f1d045467297a5473347eef3125067fe5378746 100644 --- a/system/bta/le_audio/le_audio_health_status_test.cc +++ b/system/bta/le_audio/le_audio_health_status_test.cc @@ -24,7 +24,7 @@ #include #include "bta/include/bta_groups.h" -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "test/common/mock_functions.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" diff --git a/system/bta/le_audio/le_audio_log_history.cc b/system/bta/le_audio/le_audio_log_history.cc index d4568cbaa09a1336fe5373607568edd01bfa45ee..fe9dafdc967119f3267acb4e66d61ad347ac6e11 100644 --- a/system/bta/le_audio/le_audio_log_history.cc +++ b/system/bta/le_audio/le_audio_log_history.cc @@ -23,10 +23,10 @@ #include #include -#include "gd/common/circular_buffer.h" -#include "gd/common/strings.h" +#include "common/circular_buffer.h" +#include "common/strings.h" #include "main/shim/dumpsys.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/osi.h" #include "osi/include/properties.h" 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 index d3338202809e0f8b9b3dfe61f9d0f48eba06d954..6d506c2df74983d1fbf44cdff3fb4b07a396bd76 100644 --- a/system/bta/le_audio/le_audio_set_configuration_provider_json.cc +++ b/system/bta/le_audio/le_audio_set_configuration_provider_json.cc @@ -28,7 +28,7 @@ #include "flatbuffers/idl.h" #include "flatbuffers/util.h" #include "le_audio_set_configuration_provider.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/osi.h" #include "osi/include/properties.h" diff --git a/system/bta/le_audio/le_audio_types.cc b/system/bta/le_audio/le_audio_types.cc index a3d2fbb6ee45a220213ca370ca431301c5d856cd..407ed3465170b5620dbf8304fa710a78b997e0d4 100644 --- a/system/bta/le_audio/le_audio_types.cc +++ b/system/bta/le_audio/le_audio_types.cc @@ -26,10 +26,8 @@ #include #include "audio_hal_client/audio_hal_client.h" -#include "bta_api.h" -#include "bta_le_audio_api.h" -#include "client_parser.h" -#include "gd/common/strings.h" +#include "common/strings.h" +#include "internal_include/bt_trace.h" #include "stack/include/bt_types.h" namespace le_audio { @@ -71,152 +69,72 @@ static uint8_t min_req_devices_cnt( return curr_min_req_devices_cnt; } -inline void get_cis_count(const AudioSetConfiguration& audio_set_conf, - int expected_device_cnt, - types::LeAudioConfigurationStrategy strategy, - int avail_group_sink_ase_count, - int avail_group_source_ase_count, - uint8_t& out_current_cis_count_bidir, - uint8_t& out_current_cis_count_unidir_sink, - uint8_t& out_current_cis_count_unidir_source) { - LOG_INFO("%s", audio_set_conf.name.c_str()); - - /* Sum up the requirements from all subconfigs. They usually have different - * directions. - */ - types::BidirectionalPair config_ase_count = {0, 0}; - int config_device_cnt = 0; - - for (auto ent : audio_set_conf.confs) { - if ((ent.direction == kLeAudioDirectionSink) && - (ent.strategy != strategy)) { - LOG_DEBUG("Strategy does not match (%d != %d)- skip this configuration", - static_cast(ent.strategy), static_cast(strategy)); - return; - } - - /* Sum up sink and source ases */ - if (ent.direction == kLeAudioDirectionSink) { - config_ase_count.sink += ent.ase_cnt; - } - if (ent.direction == kLeAudioDirectionSource) { - config_ase_count.source += ent.ase_cnt; - } - - /* Calculate the max device count */ - config_device_cnt = - std::max(static_cast(config_device_cnt), ent.device_cnt); - } - - LOG_DEBUG("Config sink ases: %d, source ases: %d, device count: %d", - config_ase_count.sink, config_ase_count.source, config_device_cnt); - - /* Reject configurations not matching our device count */ - if (expected_device_cnt != config_device_cnt) { - LOG_DEBUG(" Device cnt %d != %d", expected_device_cnt, config_device_cnt); - return; - } - - /* Reject configurations requiring sink ASES if our group has none */ - if ((avail_group_sink_ase_count == 0) && (config_ase_count.sink > 0)) { - LOG_DEBUG("Group does not have sink ASEs"); - return; - } - - /* Reject configurations requiring source ASES if our group has none */ - if ((avail_group_source_ase_count == 0) && (config_ase_count.source > 0)) { - LOG_DEBUG("Group does not have source ASEs"); - return; - } - - /* If expected group size is 1, then make sure device has enough ASEs */ - if (expected_device_cnt == 1) { - if ((config_ase_count.sink > avail_group_sink_ase_count) || - (config_ase_count.source > avail_group_source_ase_count)) { - LOG_DEBUG("Single device group with not enought sink/source ASEs"); - return; - } - } - - /* Configuration list is set in the prioritized order. - * it might happen that a higher prio configuration can be supported - * and is already taken into account (out_current_cis_count_* is non zero). - * Now let's try to ignore ortogonal configuration which would just - * increase our demant on number of CISes but will never happen - */ - if (config_ase_count.sink == 0 && (out_current_cis_count_unidir_sink > 0 || - out_current_cis_count_bidir > 0)) { - LOG_INFO( - "Higher prio configuration using sink ASEs has been taken into " - "account"); - return; - } - - if (config_ase_count.source == 0 && - (out_current_cis_count_unidir_source > 0 || - out_current_cis_count_bidir > 0)) { - LOG_INFO( - "Higher prio configuration using source ASEs has been taken into " - "account"); - return; - } - - /* Check how many bidirectional cises we can use */ - uint8_t config_bidir_cis_count = - std::min(config_ase_count.sink, config_ase_count.source); - /* Count the remaining unidirectional cises */ - uint8_t config_unidir_sink_cis_count = - config_ase_count.sink - config_bidir_cis_count; - uint8_t config_unidir_source_cis_count = - config_ase_count.source - config_bidir_cis_count; - - /* WARNING: Minipolicy which prioritizes bidirectional configs */ - if (config_bidir_cis_count > out_current_cis_count_bidir) { - /* Correct all counters to represent this single config */ - out_current_cis_count_bidir = config_bidir_cis_count; - out_current_cis_count_unidir_sink = config_unidir_sink_cis_count; - out_current_cis_count_unidir_source = config_unidir_source_cis_count; - - } else if (out_current_cis_count_bidir == 0) { - /* No bidirectionals possible yet. Calculate for unidirectional cises. */ - if ((out_current_cis_count_unidir_sink == 0) && - (out_current_cis_count_unidir_source == 0)) { - out_current_cis_count_unidir_sink = config_unidir_sink_cis_count; - out_current_cis_count_unidir_source = config_unidir_source_cis_count; - } - } -} - -void get_cis_count(const AudioSetConfigurations& audio_set_confs, - int expected_device_cnt, +void get_cis_count(LeAudioContextType context_type, int expected_device_cnt, types::LeAudioConfigurationStrategy strategy, int avail_group_ase_snk_cnt, int avail_group_ase_src_count, uint8_t& out_cis_count_bidir, uint8_t& out_cis_count_unidir_sink, uint8_t& out_cis_count_unidir_source) { LOG_INFO( - " strategy %d, group avail sink ases: %d, group avail source ases %d " + " %s strategy %d, group avail sink ases: %d, group avail source ases %d " "expected_device_count %d", + bluetooth::common::ToString(context_type).c_str(), static_cast(strategy), avail_group_ase_snk_cnt, avail_group_ase_src_count, expected_device_cnt); - /* Look for the most optimal configuration and store the needed cis counts */ - for (auto audio_set_conf : audio_set_confs) { - get_cis_count(*audio_set_conf, expected_device_cnt, strategy, - avail_group_ase_snk_cnt, avail_group_ase_src_count, - out_cis_count_bidir, out_cis_count_unidir_sink, - out_cis_count_unidir_source); - - LOG_DEBUG( - "Intermediate step: Bi-Directional: %d," - " Uni-Directional Sink: %d, Uni-Directional Source: %d ", - out_cis_count_bidir, out_cis_count_unidir_sink, - out_cis_count_unidir_source); + bool is_bidirectional = types::kLeAudioContextAllBidir.test(context_type); + + switch (strategy) { + case types::LeAudioConfigurationStrategy::MONO_ONE_CIS_PER_DEVICE: + /* This strategy is for the CSIS topology, e.g. two earbuds which are both + * connected with a Phone + */ + case types::LeAudioConfigurationStrategy::STEREO_ONE_CIS_PER_DEVICE: + /* This strategy is for e.g. the banded headphones */ + if (is_bidirectional) { + if ((avail_group_ase_snk_cnt > 0) && (avail_group_ase_src_count) > 0) { + /* Prepare CIG to enable all microphones */ + out_cis_count_bidir = expected_device_cnt; + } else { + if (avail_group_ase_snk_cnt > 0) { + out_cis_count_unidir_sink = expected_device_cnt; + } else if (avail_group_ase_src_count > 0) { + out_cis_count_unidir_source = expected_device_cnt; + } + } + } else { + out_cis_count_unidir_sink = expected_device_cnt; + } + + break; + case types::LeAudioConfigurationStrategy::STEREO_TWO_CISES_PER_DEVICE: + /* This strategy is for the old TWS topology. e.g. one earbud connected to + * the Phone but each channel is carried in separate CIS + */ + if (is_bidirectional) { + if ((avail_group_ase_snk_cnt > 0) && (avail_group_ase_src_count) > 0) { + /* Prepare CIG to enable all microphones per device */ + out_cis_count_bidir = expected_device_cnt; + out_cis_count_unidir_sink = expected_device_cnt; + } else { + if (avail_group_ase_snk_cnt > 0) { + out_cis_count_unidir_sink = 2 * expected_device_cnt; + } else if (avail_group_ase_src_count > 0) { + out_cis_count_unidir_source = 2 * expected_device_cnt; + } + } + } else { + out_cis_count_unidir_sink = 2 * expected_device_cnt; + } + break; + case types::LeAudioConfigurationStrategy::RFU: + LOG_ERROR("Should not happen;"); + break; } LOG_INFO( - " Maximum CIS count, Bi-Directional: %d," - " Uni-Directional Sink: %d, Uni-Directional Source: %d", + "Required cis count: Bi-Directional: %d, Uni-Directional Sink: %d, " + "Uni-Directional Source: %d", out_cis_count_bidir, out_cis_count_unidir_sink, out_cis_count_unidir_source); } diff --git a/system/bta/le_audio/le_audio_types.h b/system/bta/le_audio/le_audio_types.h index eea6b4403c3b4c09bd935a56c34b3129355a7b7f..89731fb7e02fc3b1d949c17a1c3c91aaf321ee44 100644 --- a/system/bta/le_audio/le_audio_types.h +++ b/system/bta/le_audio/le_audio_types.h @@ -1036,7 +1036,7 @@ static constexpr uint32_t kChannelAllocationStereo = codec_spec_conf::kLeAudioLocationFrontRight; /* Declarations */ -void get_cis_count(const AudioSetConfigurations& audio_set_configurations, +void get_cis_count(types::LeAudioContextType context_type, int expected_device_cnt, types::LeAudioConfigurationStrategy strategy, int group_ase_snk_cnt, int group_ase_src_count, diff --git a/system/bta/le_audio/le_audio_types_test.cc b/system/bta/le_audio/le_audio_types_test.cc index d39fecd3970cd1491061d8e6239a05b155dca030..fb3b86aaa8e6583276f02c11112e12558fc08caa 100644 --- a/system/bta/le_audio/le_audio_types_test.cc +++ b/system/bta/le_audio/le_audio_types_test.cc @@ -20,6 +20,8 @@ #include #include +#include + namespace le_audio { namespace types { diff --git a/system/bta/le_audio/le_audio_utils.cc b/system/bta/le_audio/le_audio_utils.cc index a028249cc3cfde9e53231ffeb8589d9e71e819ab..2fab56221101fec24e94a88da589e4d3e01447fe 100644 --- a/system/bta/le_audio/le_audio_utils.cc +++ b/system/bta/le_audio/le_audio_utils.cc @@ -17,9 +17,9 @@ #include "le_audio_utils.h" #include "bta/le_audio/content_control_id_keeper.h" -#include "gd/common/strings.h" +#include "common/strings.h" #include "le_audio_types.h" -#include "osi/include/log.h" +#include "os/log.h" using bluetooth::common::ToString; using le_audio::types::AudioContexts; @@ -45,10 +45,15 @@ LeAudioContextType AudioContentToLeAudioContext( case AUDIO_USAGE_CALL_ASSISTANT: return LeAudioContextType::CONVERSATIONAL; case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: - if (content_type == AUDIO_CONTENT_TYPE_SPEECH) + if (content_type == AUDIO_CONTENT_TYPE_SPEECH) { return LeAudioContextType::CONVERSATIONAL; - else - return LeAudioContextType::MEDIA; + } + + if (content_type == AUDIO_CONTENT_TYPE_SONIFICATION) { + return LeAudioContextType::RINGTONE; + } + + return LeAudioContextType::MEDIA; case AUDIO_USAGE_GAME: return LeAudioContextType::GAME; case AUDIO_USAGE_NOTIFICATION: diff --git a/system/bta/le_audio/mock_codec_interface.h b/system/bta/le_audio/mock_codec_interface.h index d2acda6f61e531fe3db74f13ca6f81d92fa1d0ff..de6037235b25748d260af4dab6cba92b5fafdfc9 100644 --- a/system/bta/le_audio/mock_codec_interface.h +++ b/system/bta/le_audio/mock_codec_interface.h @@ -18,6 +18,8 @@ #include +#include + #include "codec_interface.h" class MockCodecInterface { diff --git a/system/bta/le_audio/state_machine.cc b/system/bta/le_audio/state_machine.cc index 85443d777b613d1b18dd0c4e7ecae60dbac8f086..8dc4c44fa5ea11b98ec03a70f80e0d0c285631ed 100644 --- a/system/bta/le_audio/state_machine.cc +++ b/system/bta/le_audio/state_machine.cc @@ -26,10 +26,12 @@ #include "btm_iso_api.h" #include "client_parser.h" #include "codec_manager.h" +#include "common/strings.h" #include "devices.h" -#include "gd/common/strings.h" #include "hci/hci_packets.h" #include "hcimsgs.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" #include "le_audio_health_status.h" #include "le_audio_log_history.h" #include "le_audio_types.h" @@ -171,6 +173,11 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return false; } + /* Invalidate configuration to make sure it is chosen properly when new + * member connects + */ + group->InvalidateCachedConfigurations(); + if (!group->Configure(group->GetConfigurationContextType(), group->GetMetadataContexts(), ccids)) { LOG_ERROR(" failed to set ASE configuration"); @@ -400,6 +407,12 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { ParseAseStatusHeader(arh, len, value); + if (ase->id == 0x00) { + /* Initial state of Ase - update id */ + LOG_INFO(", discovered ase id: %d", arh.id); + ase->id = arh.id; + } + auto state = static_cast(arh.state); LOG_INFO(" %s , ASE id: %d, state changed %s -> %s ", @@ -596,6 +609,17 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return; } + if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + if (group->dsa_.active && + (group->dsa_.mode == DsaMode::ISO_SW || + group->dsa_.mode == DsaMode::ISO_HW) && + leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURING) { + LOG_INFO("Datapath configured for headtracking"); + leAudioDevice->SetDsaDataPathState(DataPathState::CONFIGURED); + return; + } + } + /* Update state for the given cis.*/ auto ase = leAudioDevice->GetFirstActiveAseByCisAndDataPathState( CisState::CONNECTED, DataPathState::CONFIGURING); @@ -673,6 +697,13 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { ases_pair.source->cis_state = CisState::DISCONNECTING; do_disconnect = true; } + } else if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + if (group->dsa_.active && + leAudioDevice->GetDsaDataPathState() == DataPathState::REMOVING) { + LOG_INFO("DSA data path removed"); + leAudioDevice->SetDsaDataPathState(DataPathState::IDLE); + leAudioDevice->SetDsaCisHandle(GATT_INVALID_CONN_ID); + } } if (do_disconnect) { @@ -834,6 +865,78 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { } } + void applyDsaDataPath(LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice, + uint16_t conn_hdl) { + if (!IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + return; + } + + if (!group->dsa_.active) { + LOG_INFO("DSA mode not used"); + return; + } + + DsaModes dsa_modes = leAudioDevice->GetDsaModes(); + if (dsa_modes.empty()) { + LOG_WARN("DSA mode not supported by this LE Audio device: %s", + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_)); + group->dsa_.active = false; + return; + } + + if (std::find(dsa_modes.begin(), dsa_modes.end(), DsaMode::ISO_SW) == + dsa_modes.end() && + std::find(dsa_modes.begin(), dsa_modes.end(), DsaMode::ISO_HW) == + dsa_modes.end()) { + LOG_WARN("DSA mode not supported by this LE Audio device: %s", + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_)); + group->dsa_.active = false; + return; + } + + uint8_t data_path_id = bluetooth::hci::iso_manager::kIsoDataPathHci; + LOG_INFO("DSA mode used: %d", static_cast(group->dsa_.mode)); + switch (group->dsa_.mode) { + case DsaMode::ISO_HW: + data_path_id = bluetooth::hci::iso_manager::kIsoDataPathPlatformDefault; + break; + case DsaMode::ISO_SW: + data_path_id = bluetooth::hci::iso_manager::kIsoDataPathHci; + break; + default: + LOG_WARN("Unexpected DsaMode: %d", static_cast(group->dsa_.mode)); + group->dsa_.active = false; + return; + } + + leAudioDevice->SetDsaDataPathState(DataPathState::CONFIGURING); + leAudioDevice->SetDsaCisHandle(conn_hdl); + + LOG_VERBOSE( + "DSA mode supported on this LE Audio device: %s, apply data path: %d", + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), data_path_id); + + LeAudioLogHistory::Get()->AddLogHistory( + kLogStateMachineTag, group->group_id_, RawAddress::kEmpty, + kLogSetDataPathOp + "cis_h:" + loghex(conn_hdl), + "direction: " + + loghex(bluetooth::hci::iso_manager::kIsoDataPathDirectionOut)); + + bluetooth::hci::iso_manager::iso_data_path_params param = { + .data_path_dir = bluetooth::hci::iso_manager::kIsoDataPathDirectionOut, + .data_path_id = data_path_id, + .codec_id_format = + le_audio::types::kLeAudioCodecHeadtracking.coding_format, + .codec_id_company = + le_audio::types::kLeAudioCodecHeadtracking.vendor_company_id, + .codec_id_vendor = + le_audio::types::kLeAudioCodecHeadtracking.vendor_codec_id, + .controller_delay = 0x00000000, + .codec_conf = std::vector(), + }; + IsoManager::GetInstance()->SetupIsoDataPath(conn_hdl, std::move(param)); + } + void ProcessHciNotifCisEstablished( LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice, const bluetooth::hci::iso_manager::cis_establish_cmpl_evt* event) @@ -910,6 +1013,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { if (ases_pair.source && (ases_pair.source->data_path_state == DataPathState::IDLE)) { PrepareDataPath(group->group_id_, ases_pair.source); + } else { + applyDsaDataPath(group, leAudioDevice, event->cis_conn_hdl); } if (osi_property_get_bool("persist.bluetooth.iso_link_quality_report", @@ -983,6 +1088,14 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { ases_pair.source->data_path_state == DataPathState::CONFIGURED) { value |= bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput; ases_pair.source->data_path_state = DataPathState::REMOVING; + } else { + if (IS_FLAG_ENABLED(leaudio_dynamic_spatial_audio)) { + if (leAudioDevice->GetDsaDataPathState() == DataPathState::CONFIGURED) { + value |= + bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionOutput; + leAudioDevice->SetDsaDataPathState(DataPathState::REMOVING); + } + } } if (value == 0) { @@ -1307,13 +1420,14 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return; } - LOG_INFO("DSA mode selected: %d", (int)group->dsa_mode_); + LOG_INFO("DSA mode selected: %d", (int)group->dsa_.mode); + group->dsa_.active = false; /* Unidirectional streaming */ - if (param.sdu_itv_stom != 0) { + if (param.sdu_itv_stom == 0) { LOG_INFO("Media streaming, apply DSA parameters"); - switch (group->dsa_mode_) { + switch (group->dsa_.mode) { case DsaMode::ISO_HW: case DsaMode::ISO_SW: { auto& cis_cfgs = param.cis_cfgs; @@ -1322,11 +1436,14 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { for (auto dsa_modes : group->GetAllowedDsaModesList()) { if (!dsa_modes.empty() && it != cis_cfgs.end()) { if (std::find(dsa_modes.begin(), dsa_modes.end(), - group->dsa_mode_) != dsa_modes.end()) { + group->dsa_.mode) != dsa_modes.end()) { LOG_INFO("Device found with support for selected DsaMode"); + group->dsa_.active = true; + + /* Todo: Replace literal values */ param.sdu_itv_stom = 20000; - param.max_trans_lat_stom = 10; + param.max_trans_lat_stom = 20; it->max_sdu_size_stom = 15; it->rtn_stom = 2; @@ -1642,13 +1759,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { switch (ase->state) { case AseState::BTA_LE_AUDIO_ASE_STATE_IDLE: case AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED: - case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED: - if (ase->id == 0x00) { - /* Initial state of Ase - update id */ - LOG(INFO) << __func__ - << ", discovered ase id: " << static_cast(arh.id); - ase->id = arh.id; - } break; case AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING: { SetAseState(leAudioDevice, ase, AseState::BTA_LE_AUDIO_ASE_STATE_IDLE); @@ -1702,10 +1812,25 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { break; } - default: - LOG(ERROR) << __func__ << ", invalid state transition, from: " - << static_cast(ase->state) << ", to: " - << static_cast(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE); + case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED: + case AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING: + LOG_ERROR( + "Ignore invalid attempt of state transition from %s to %s, %s, " + "ase_id: %d", + ToString(ase->state).c_str(), + ToString(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); + group->PrintDebugState(); + break; + case AseState::BTA_LE_AUDIO_ASE_STATE_ENABLING: + case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING: + LOG_ERROR( + "Invalid state transition from %s to %s, %s, ase_id: " + "%d. Stopping the stream.", + ToString(ase->state).c_str(), + ToString(AseState::BTA_LE_AUDIO_ASE_STATE_IDLE).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); + group->PrintDebugState(); StopStream(group); break; } @@ -1805,13 +1930,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { /* ase contain current ASE state. New state is in "arh" */ switch (ase->state) { case AseState::BTA_LE_AUDIO_ASE_STATE_IDLE: { - if (ase->id == 0x00) { - /* Initial state of Ase - update id */ - LOG(INFO) << __func__ - << ", discovered ase id: " << static_cast(arh.id); - ase->id = arh.id; - } - struct le_audio::client_parser::ascs::ase_codec_configured_state_params rsp; @@ -1869,6 +1987,10 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { /* This is autonomus change of the remote device */ LOG_DEBUG("Autonomus change for device %s, ase id %d. Just store it.", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); + + /* Since at least one ASE is in configured state, we should admit + * group is configured state */ + group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED); return; } @@ -2042,14 +2164,25 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return; } - LOG_ERROR(", Autonomouse change, from: %s to %s", - ToString(group->GetState()).c_str(), - ToString(group->GetTargetState()).c_str()); + LOG_INFO("Autonomous change, from: %s to %s", + ToString(group->GetState()).c_str(), + ToString(group->GetTargetState()).c_str()); break; } case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED: - /* TODO: Config Codec */ + SetAseState(leAudioDevice, ase, + AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED); + group->PrintDebugState(); + break; + case AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING: + LOG_ERROR( + "Ignore invalid attempt of state transition from %s to %s, %s, " + "ase_id: %d", + ToString(ase->state).c_str(), + ToString(AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); + group->PrintDebugState(); break; case AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING: SetAseState(leAudioDevice, ase, @@ -2107,11 +2240,15 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { state_machine_callbacks_->StatusReportCb( group->group_id_, GroupStreamStatus::CONFIGURED_AUTONOMOUS); break; - default: - LOG(ERROR) << __func__ << ", invalid state transition, from: " - << static_cast(ase->state) << ", to: " - << static_cast( - AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED); + case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING: + case AseState::BTA_LE_AUDIO_ASE_STATE_ENABLING: + LOG_ERROR( + "Invalid state transition from %s to %s, %s, ase_id: %d. Stopping " + "the stream", + ToString(ase->state).c_str(), + ToString(AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); + group->PrintDebugState(); StopStream(group); break; } @@ -2154,9 +2291,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { break; } - case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED: - /* TODO: Config Codec error/Config Qos/Config QoS error/Enable error */ - break; case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING: if (ase->direction == le_audio::types::kLeAudioDirectionSource) { /* Source ASE cannot go from Streaming to QoS Configured state */ @@ -2212,11 +2346,33 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { } break; } - default: - LOG(ERROR) << __func__ << ", invalid state transition, from: " - << static_cast(ase->state) << ", to: " - << static_cast( - AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED); + + case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED: + LOG_INFO( + "Unexpected state transition from %s to %s, %s, ase_id: %d", + ToString(ase->state).c_str(), + ToString(AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); + group->PrintDebugState(); + break; + case AseState::BTA_LE_AUDIO_ASE_STATE_IDLE: + case AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING: + // Do nothing here, just print an error message + LOG_ERROR( + "Ignore invalid attempt of state transition from %s to %s, %s, " + "ase_id: %d", + ToString(ase->state).c_str(), + ToString(AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); + group->PrintDebugState(); + break; + case AseState::BTA_LE_AUDIO_ASE_STATE_ENABLING: + LOG_ERROR( + "Invalid state transition from %s to %s, %s, ase_id: " + "%d. Stopping the stream.", + ToString(ase->state).c_str(), + ToString(AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), ase->id); StopStream(group); break; } @@ -2853,12 +3009,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { } switch (ase->state) { + case AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING: case AseState::BTA_LE_AUDIO_ASE_STATE_CODEC_CONFIGURED: - case AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING: { - SetAseState(leAudioDevice, ase, - AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING); - break; - } case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED: SetAseState(leAudioDevice, ase, AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING); @@ -2866,8 +3018,10 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { if (group->HaveAllActiveDevicesAsesTheSameState( AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)) { group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING); + } - /* At this point all of the active ASEs within group are released. */ + if (group->cig.GetState() == CigState::CREATED && + group->HaveAllCisesDisconnected()) { RemoveCigForGroup(group); } diff --git a/system/bta/le_audio/state_machine_test.cc b/system/bta/le_audio/state_machine_test.cc index e88c75c01b7ea56e05e77e67fa8ef7033e8d8428..331050744be4632ce1970cabdf2feb0c9b497f1d 100644 --- a/system/bta/le_audio/state_machine_test.cc +++ b/system/bta/le_audio/state_machine_test.cc @@ -27,8 +27,8 @@ #include "bta_gatt_queue_mock.h" #include "btm_api_mock.h" #include "client_parser.h" +#include "common/init_flags.h" #include "fake_osi.h" -#include "gd/common/init_flags.h" #include "le_audio_set_configuration_provider.h" #include "mock_codec_manager.h" #include "mock_controller.h" @@ -239,6 +239,13 @@ class StateMachineTestBase : public Test { ContentControlIdKeeper::GetInstance()->Start(); + ON_CALL(mock_callbacks_, StatusReportCb(_, _)) + .WillByDefault(Invoke( + [](int group_id, bluetooth::le_audio::GroupStreamStatus status) { + LOG_DEBUG(" [Testing] StatusReportCb: group id: %d, status: %d", + group_id, status); + })); + MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_); ON_CALL(mock_csis_client_module_, Get()) .WillByDefault(Return(&mock_csis_client_module_)); @@ -695,7 +702,9 @@ class StateMachineTestBase : public Test { auto* p = notif_value.data(); // Prepare header - UINT8_TO_STREAM(p, ase->id); + UINT8_TO_STREAM(p, ase->id == types::ase::kAseIdInvalid + ? ++ase_id_last_assigned + : ase->id); UINT8_TO_STREAM(p, new_state); UINT8_TO_STREAM(p, conf->cig_id); @@ -726,7 +735,10 @@ class StateMachineTestBase : public Test { auto* p = notif_value.data(); // Prepare header - UINT8_TO_STREAM(p, ase->id); + UINT8_TO_STREAM(p, ase->id == types::ase::kAseIdInvalid + ? ++ase_id_last_assigned + : ase->id); + UINT8_TO_STREAM(p, new_state); UINT8_TO_STREAM(p, group->group_id_); @@ -808,6 +820,47 @@ class StateMachineTestBase : public Test { } } + void InjectInitialIdleAndConfiguredNotification(LeAudioDeviceGroup* group) { + for (auto* device = group->GetFirstDevice(); device != nullptr; + device = group->GetNextDevice(device)) { + int i = 0; + for (auto& ase : device->ases_) { + if (i % 2 == 1) { + InjectAseStateNotification(&ase, device, group, ascs::kAseStateIdle, + nullptr); + } else { + client_parser::ascs::ase_codec_configured_state_params + codec_configured_state_params; + InjectAseStateNotification(&ase, device, group, + ascs::kAseStateCodecConfigured, + &codec_configured_state_params); + } + i++; + } + } + } + + void InjectInitialInvalidNotification(LeAudioDeviceGroup* group) { + for (auto* device = group->GetFirstDevice(); device != nullptr; + device = group->GetNextDevice(device)) { + int i = 0; + for (auto& ase : device->ases_) { + if (i % 2 == 1) { + client_parser::ascs::ase_qos_configured_state_params + qos_configured_state_params; + InjectAseStateNotification(&ase, device, group, + ascs::kAseStateQoSConfigured, + &qos_configured_state_params); + } else { + client_parser::ascs::ase_transient_state_params enable_params; + InjectAseStateNotification(&ase, device, group, + ascs::kAseStateEnabling, &enable_params); + } + i++; + } + } + } + void MultipleTestDevicePrepare(int leaudio_group_id, LeAudioContextType context_type, uint16_t device_cnt, @@ -1695,6 +1748,60 @@ TEST_F(StateMachineTest, testConfigureQosMultiple) { ASSERT_EQ(0, get_func_call_count("alarm_cancel")); } +TEST_F(StateMachineTest, testConfigureQosFailed) { + const auto context_type = kContextTypeMedia; + const auto leaudio_group_id = 3; + const auto num_devices = 2; + + // Check if CIG is properly cleared when QoS failed + + // Prepare multiple fake connected devices in a group + auto* group = + PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices); + ASSERT_EQ(group->Size(), num_devices); + + PrepareConfigureCodecHandler(group); + PrepareCtpNotificationError( + group, client_parser::ascs::kCtpOpcodeQosConfiguration, + client_parser::ascs::kCtpResponseCodeInvalidConfigurationParameterValue, + client_parser::ascs::kCtpResponsePhy); + PrepareReleaseHandler(group); + + auto* leAudioDevice = group->GetFirstDevice(); + auto expected_devices_written = 0; + while (leAudioDevice) { + EXPECT_CALL(gatt_queue, + WriteCharacteristic(leAudioDevice->conn_id_, + leAudioDevice->ctp_hdls_.val_hdl, _, + GATT_WRITE_NO_RSP, _, _)) + .Times(AtLeast(2)); + expected_devices_written++; + leAudioDevice = group->GetNextDevice(leAudioDevice); + } + ASSERT_EQ(expected_devices_written, num_devices); + + EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1); + EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(0); + EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(0); + EXPECT_CALL(*mock_iso_manager_, RemoveIsoDataPath(_, _)).Times(0); + EXPECT_CALL(*mock_iso_manager_, DisconnectCis(_, _)).Times(0); + EXPECT_CALL(*mock_iso_manager_, RemoveCig(_, _)).Times(1); + + InjectInitialIdleNotification(group); + + // Start the configuration and stream Media content + ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream( + group, context_type, + {.sink = types::AudioContexts(context_type), + .source = types::AudioContexts(context_type)})); + + // Check if group has transitioned to a proper state + ASSERT_EQ(group->GetState(), types::AseState::BTA_LE_AUDIO_ASE_STATE_IDLE); + ASSERT_EQ(2, get_func_call_count("alarm_cancel")); + + testing::Mock::VerifyAndClearExpectations(&mock_iso_manager_); +} + TEST_F(StateMachineTest, testStreamCreationError) { /* Device is banded headphones with 1x snk + 0x src ase * (1xunidirectional CIS) with channel count 2 (for stereo @@ -3843,6 +3950,135 @@ TEST_F(StateMachineTest, testAseAutonomousRelease2Devices) { } } +TEST_F(StateMachineTest, testHandlingAutonomousCodecConfigStateOnConnection) { + /* Scenario + * 1. After connection remote device has different ASE configurations + * 2. Try to start stream and make sure it is configured well. + */ + + const auto context_type = kContextTypeConversational; + const int leaudio_group_id = 4; + const int num_of_devices = 2; + + // Prepare fake connected device group + auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, + num_of_devices); + + auto* firstDevice = group->GetFirstDevice(); + auto* secondDevice = group->GetNextDevice(firstDevice); + + /* Since we prepared device with Conversional context in mind, Sink and Source + * ASEs should have been configured. + */ + PrepareConfigureCodecHandler(group, 0, true); + PrepareConfigureQosHandler(group); + PrepareEnableHandler(group); + PrepareDisableHandler(group); + PrepareReceiverStartReadyHandler(group); + PrepareReceiverStopReady(group); + + /* Number of control point calls + * 1. Codec Config + * 2. QoS Config + * 3. Enable + * 4. Receiver Start Ready + */ + EXPECT_CALL(gatt_queue, WriteCharacteristic(firstDevice->conn_id_, + firstDevice->ctp_hdls_.val_hdl, _, + GATT_WRITE_NO_RSP, _, _)) + .Times(4); + + EXPECT_CALL(gatt_queue, WriteCharacteristic(secondDevice->conn_id_, + secondDevice->ctp_hdls_.val_hdl, + _, GATT_WRITE_NO_RSP, _, _)) + .Times(4); + + InjectInitialIdleAndConfiguredNotification(group); + // Call it second time to make sure we get into state that current_state_ is + // different then target_state_ even group is not in transition. + InjectInitialIdleAndConfiguredNotification(group); + + ASSERT_TRUE(group->GetTargetState() != group->GetState()); + ASSERT_FALSE(group->IsInTransition()); + + // Validate initial GroupStreamStatus + EXPECT_CALL( + mock_callbacks_, + StatusReportCb(leaudio_group_id, + bluetooth::le_audio::GroupStreamStatus::STREAMING)); + + // Start the configuration and stream Media content + ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream( + group, context_type, + {.sink = types::AudioContexts(context_type), + .source = types::AudioContexts(context_type)})); + + testing::Mock::VerifyAndClearExpectations(&mock_callbacks_); +} + +TEST_F(StateMachineTest, testHandlingInvalidRemoteAseStateHandling) { + /* Scenario + * 1. After connection remote device has different ASE configurations + * 2. Try to start stream and make sure it is configured well. + */ + + const auto context_type = kContextTypeConversational; + const int leaudio_group_id = 4; + const int num_of_devices = 2; + + // Prepare fake connected device group + auto* group = PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, + num_of_devices); + + auto* firstDevice = group->GetFirstDevice(); + auto* secondDevice = group->GetNextDevice(firstDevice); + + /* Since we prepared device with Conversional context in mind, Sink and Source + * ASEs should have been configured. + */ + PrepareConfigureCodecHandler(group, 0, true); + PrepareConfigureQosHandler(group); + PrepareEnableHandler(group); + PrepareDisableHandler(group); + PrepareReceiverStartReadyHandler(group); + PrepareReceiverStopReady(group); + + /* Number of control point calls + * 1. Codec Config + * 2. QoS Config + * 3. Enable + * 4. Receiver Start Ready + */ + EXPECT_CALL(gatt_queue, WriteCharacteristic(firstDevice->conn_id_, + firstDevice->ctp_hdls_.val_hdl, _, + GATT_WRITE_NO_RSP, _, _)) + .Times(4); + + EXPECT_CALL(gatt_queue, WriteCharacteristic(secondDevice->conn_id_, + secondDevice->ctp_hdls_.val_hdl, + _, GATT_WRITE_NO_RSP, _, _)) + .Times(4); + + /* Inject invalid states*/ + InjectInitialInvalidNotification(group); + + ASSERT_FALSE(group->IsInTransition()); + + // Validate initial GroupStreamStatus + EXPECT_CALL( + mock_callbacks_, + StatusReportCb(leaudio_group_id, + bluetooth::le_audio::GroupStreamStatus::STREAMING)); + + // Start the configuration and stream Media content + ASSERT_TRUE(LeAudioGroupStateMachine::Get()->StartStream( + group, context_type, + {.sink = types::AudioContexts(context_type), + .source = types::AudioContexts(context_type)})); + + testing::Mock::VerifyAndClearExpectations(&mock_callbacks_); +} + TEST_F(StateMachineTest, testHandlingCachedCodecConfig2Devices) { const auto context_type = kContextTypeConversational; const int leaudio_group_id = 4; @@ -4291,6 +4527,127 @@ TEST_F(StateMachineTest, testAttachDeviceToTheStream) { ASSERT_NE(ase->retrans_nb, 0); } +TEST_F(StateMachineTest, testAttachDeviceToTheStreamV2) { + const auto context_type = kContextTypeMedia; + const auto leaudio_group_id = 6; + const auto num_devices = 2; + + /* Scenario + * 1. Both devices streaming + * 2. One device disconnects + * 3. Audio configuration resume and configuration cache is rebuilt + * 4. Device attached + */ + ContentControlIdKeeper::GetInstance()->SetCcid(media_context, media_ccid); + + // Prepare multiple fake connected devices in a group + auto* group = + PrepareSingleTestDeviceGroup(leaudio_group_id, context_type, num_devices); + ASSERT_EQ(group->Size(), num_devices); + + PrepareConfigureCodecHandler(group); + PrepareConfigureQosHandler(group); + PrepareEnableHandler(group); + PrepareDisableHandler(group); + PrepareReleaseHandler(group); + + auto* leAudioDevice = group->GetFirstDevice(); + LeAudioDevice* lastDevice; + LeAudioDevice* fistDevice = leAudioDevice; + + auto expected_devices_written = 0; + while (leAudioDevice) { + /* Three Writes: + * 1: Codec Config + * 2: Codec QoS + * 3: Enabling + */ + lastDevice = leAudioDevice; + EXPECT_CALL(gatt_queue, + WriteCharacteristic(leAudioDevice->conn_id_, + leAudioDevice->ctp_hdls_.val_hdl, _, + GATT_WRITE_NO_RSP, _, _)) + .Times(AtLeast(3)); + expected_devices_written++; + leAudioDevice = group->GetNextDevice(leAudioDevice); + } + ASSERT_EQ(expected_devices_written, num_devices); + + EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(1); + EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1); + EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(2); + + InjectInitialIdleNotification(group); + + // Start the configuration and stream Media content + LeAudioGroupStateMachine::Get()->StartStream( + group, context_type, + {.sink = types::AudioContexts(context_type), + .source = types::AudioContexts(context_type)}); + + // Check if group has transitioned to a proper state + ASSERT_EQ(group->GetState(), + types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING); + testing::Mock::VerifyAndClearExpectations(&mock_iso_manager_); + + // Inject CIS and ACL disconnection of first device + InjectCisDisconnected(group, lastDevice, HCI_ERR_CONNECTION_TOUT); + InjectAclDisconnected(group, lastDevice); + + /* Force update configuration which is what happens when stream stops + * and starts while streaming to single dev. This will rebuild cache, + * which is what we need in this test. + */ + group->UpdateAudioSetConfigurationCache(context_type); + + // Check if group keeps streaming + ASSERT_EQ(group->GetState(), + types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING); + + lastDevice->conn_id_ = 3; + lastDevice->SetConnectionState(DeviceConnectState::CONNECTED); + + // Make sure ASE with disconnected CIS are not left in STREAMING + ASSERT_EQ(lastDevice->GetFirstAseWithState( + ::le_audio::types::kLeAudioDirectionSink, + types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING), + nullptr); + ASSERT_EQ(lastDevice->GetFirstAseWithState( + ::le_audio::types::kLeAudioDirectionSource, + types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING), + nullptr); + + EXPECT_CALL(gatt_queue, WriteCharacteristic(lastDevice->conn_id_, + lastDevice->ctp_hdls_.val_hdl, _, + GATT_WRITE_NO_RSP, _, _)) + .Times(AtLeast(3)); + + EXPECT_CALL(*mock_iso_manager_, EstablishCis(_)).Times(1); + EXPECT_CALL(*mock_iso_manager_, SetupIsoDataPath(_, _)).Times(1); + LeAudioGroupStateMachine::Get()->AttachToStream( + group, lastDevice, {.sink = {media_ccid}, .source = {}}); + + // Check if group keeps streaming + ASSERT_EQ(group->GetState(), + types::AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING); + + // Verify that the joining device receives the right CCID list + auto lastMeta = lastDevice->GetFirstActiveAse()->metadata; + bool parsedOk = false; + auto ltv = le_audio::types::LeAudioLtvMap::Parse(lastMeta.data(), + lastMeta.size(), parsedOk); + ASSERT_TRUE(parsedOk); + + auto ccids = ltv.Find(le_audio::types::kLeAudioMetadataTypeCcidList); + ASSERT_TRUE(ccids.has_value()); + ASSERT_NE(std::find(ccids->begin(), ccids->end(), media_ccid), ccids->end()); + + /* Verify that ASE of first device are still good*/ + auto ase = fistDevice->GetFirstActiveAse(); + ASSERT_NE(ase->max_transport_latency, 0); + ASSERT_NE(ase->retrans_nb, 0); +} + TEST_F(StateMachineTest, testAttachDeviceToTheStreamDeviceNoAvailableContext) { const auto context_type = kContextTypeMedia; const auto leaudio_group_id = 6; @@ -5306,19 +5663,23 @@ TEST_F(StateMachineTest, StartStreamCachedConfigReconfigInvalidBehavior) { EXPECT_CALL(mock_callbacks_, StatusReportCb(leaudio_group_id, bluetooth::le_audio::GroupStreamStatus::RELEASING)) - .Times(1); + .Times(0); EXPECT_CALL(*mock_iso_manager_, CreateCig(_, _)).Times(0); - // Block the fallback Release which will happen when CreateCig will faile + // Block the fallback Release which will happen when CreateCig will fail stay_in_releasing_state_ = true; // Start the configuration and stream Live content - LeAudioGroupStateMachine::Get()->StartStream( + bool result = LeAudioGroupStateMachine::Get()->StartStream( group, kContextTypeLive, {.sink = types::AudioContexts(kContextTypeLive), .source = types::AudioContexts(kContextTypeLive)}); + // Group internally in releasing state. StartStrean should faile. + + ASSERT_FALSE(result); + testing::Mock::VerifyAndClearExpectations(&mock_callbacks_); testing::Mock::VerifyAndClearExpectations(&mock_iso_manager_); } diff --git a/system/bta/le_audio/storage_helper.cc b/system/bta/le_audio/storage_helper.cc index ccb25998a4f4a07149945962b8950526d844b050..92b9cbca27e54fb8851571df61af98aa8b3bb100 100644 --- a/system/bta/le_audio/storage_helper.cc +++ b/system/bta/le_audio/storage_helper.cc @@ -19,9 +19,9 @@ #include "storage_helper.h" #include "client_parser.h" -#include "gd/common/strings.h" +#include "common/strings.h" #include "le_audio_types.h" -#include "osi/include/log.h" +#include "os/log.h" #include "stack/include/bt_types.h" using le_audio::types::hdl_pair; diff --git a/system/bta/pan/bta_pan_act.cc b/system/bta/pan/bta_pan_act.cc index a47c284b7610e1367dbbf1c40eb0b9eb7520a765..4ad5bbcdb079d585c7bf4d52d91d27b3d6543f5f 100644 --- a/system/bta/pan/bta_pan_act.cc +++ b/system/bta/pan/bta_pan_act.cc @@ -24,6 +24,8 @@ #define LOG_TAG "bluetooth" +#include + #include #include "bta/include/bta_pan_co.h" @@ -37,6 +39,8 @@ #include "stack/include/pan_api.h" #include "types/raw_address.h" +using namespace bluetooth; + #if (PAN_INCLUDED == TRUE) void bta_pan_sm_execute(tBTA_PAN_SCB* p_scb, uint16_t event, tBTA_PAN_DATA* p_data); @@ -177,7 +181,7 @@ static void bta_pan_data_buf_ind_cback(uint16_t handle, const RawAddress& src, if (sizeof(BT_HDR) + sizeof(tBTA_PAN_DATA_PARAMS) + p_buf->len > PAN_BUF_SIZE) { - LOG_ERROR("%s: received buffer length too large: %d", __func__, p_buf->len); + log::error("received buffer length too large: {}", p_buf->len); return; } @@ -410,7 +414,7 @@ void bta_pan_open(tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { status = PAN_Connect(p_data->api_open.bd_addr, p_data->api_open.local_role, p_data->api_open.peer_role, &p_scb->handle); - LOG_VERBOSE("%s pan connect status: %d", __func__, status); + log::verbose("pan connect status: {}", status); if (status == PAN_SUCCESS) { p_scb->bd_addr = p_data->api_open.bd_addr; @@ -468,7 +472,7 @@ void bta_pan_api_close(tBTA_PAN_SCB* p_scb, UNUSED_ATTR tBTA_PAN_DATA* p_data) { void bta_pan_conn_open(tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { tBTA_PAN bta_pan; - LOG_VERBOSE("%s pan connection result: %d", __func__, p_data->conn.result); + log::verbose("pan connection result: {}", p_data->conn.result); bta_pan.open.bd_addr = p_scb->bd_addr; bta_pan.open.handle = p_scb->handle; diff --git a/system/bta/pan/bta_pan_api.cc b/system/bta/pan/bta_pan_api.cc index 1d338869e9a5a18efa9b1a894a960991a3f690c7..d3d16ebea000114f68d60b81228bc2b9af22ebfa 100644 --- a/system/bta/pan/bta_pan_api.cc +++ b/system/bta/pan/bta_pan_api.cc @@ -26,8 +26,8 @@ #include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/pan/bta_pan_int.h" +#include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "stack/include/bt_hdr.h" diff --git a/system/bta/pan/bta_pan_main.cc b/system/bta/pan/bta_pan_main.cc index 8e1f383b48988b8591570a28408891ce978c6efa..14a1587c32e8cf8394ebc64b33aa9d81233a2f34 100644 --- a/system/bta/pan/bta_pan_main.cc +++ b/system/bta/pan/bta_pan_main.cc @@ -21,14 +21,18 @@ * This file contains the PAN main functions and state machine. * ******************************************************************************/ -#include +#include -#include "bt_target.h" // Must be first to define build configuration +#include #include "bta/pan/bta_pan_int.h" +#include "include/check.h" +#include "internal_include/bt_target.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/bt_hdr.h" +using namespace bluetooth; + /***************************************************************************** * Constants and types ****************************************************************************/ @@ -134,7 +138,7 @@ tBTA_PAN_SCB* bta_pan_scb_alloc(void) { for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++) { if (!p_scb->in_use) { p_scb->in_use = true; - LOG_VERBOSE("bta_pan_scb_alloc %d", i); + log::verbose("bta_pan_scb_alloc {}", i); break; } } @@ -142,7 +146,7 @@ tBTA_PAN_SCB* bta_pan_scb_alloc(void) { if (i == BTA_PAN_NUM_CONN) { /* out of scbs */ p_scb = NULL; - LOG_WARN("Out of scbs"); + log::warn("Out of scbs"); } return p_scb; } @@ -163,8 +167,8 @@ void bta_pan_sm_execute(tBTA_PAN_SCB* p_scb, uint16_t event, uint8_t action; int i; - LOG_VERBOSE("PAN scb=%d event=0x%x state=%d", bta_pan_scb_to_idx(p_scb), - event, p_scb->state); + log::verbose("PAN scb={} event=0x{:x} state={}", bta_pan_scb_to_idx(p_scb), + event, p_scb->state); /* look up the state table for the current state */ state_table = bta_pan_st_tbl[p_scb->state]; @@ -251,7 +255,7 @@ void bta_pan_api_open(tBTA_PAN_DATA* p_data) { * ******************************************************************************/ void bta_pan_scb_dealloc(tBTA_PAN_SCB* p_scb) { - LOG_VERBOSE("bta_pan_scb_dealloc %d", bta_pan_scb_to_idx(p_scb)); + log::verbose("bta_pan_scb_dealloc {}", bta_pan_scb_to_idx(p_scb)); fixed_queue_free(p_scb->data_queue, NULL); memset(p_scb, 0, sizeof(tBTA_PAN_SCB)); } @@ -291,7 +295,7 @@ tBTA_PAN_SCB* bta_pan_scb_by_handle(uint16_t handle) { } } - LOG_WARN("No scb for handle %d", handle); + log::warn("No scb for handle {}", handle); return NULL; } diff --git a/system/bta/pb/bta_pbs_int.h b/system/bta/pb/bta_pbs_int.h index 546a5f906dc78fbfd22698ebe544a58694316607..524963a5db085e94f48e8e41f19eea83647b3c16 100644 --- a/system/bta/pb/bta_pbs_int.h +++ b/system/bta/pb/bta_pbs_int.h @@ -25,7 +25,8 @@ #define BTA_PBS_INT_H #include -#include "bt_target.h" // Must be first to define build configuration + +#include "internal_include/bt_target.h" /***************************************************************************** * Constants and data types diff --git a/system/bta/rfcomm/bta_rfcomm_scn.cc b/system/bta/rfcomm/bta_rfcomm_scn.cc index c303e79cba68c0bcfaf5b2851dab740e6ac50dcd..2a01d346dae9e12526599ffdd54f734154af521d 100644 --- a/system/bta/rfcomm/bta_rfcomm_scn.cc +++ b/system/bta/rfcomm/bta_rfcomm_scn.cc @@ -18,11 +18,15 @@ #define LOG_TAG "bta" +#include + #include #include "bta/jv/bta_jv_int.h" // tBTA_JV_CB #include "stack/include/rfcdefs.h" // RFCOMM_MAX_SCN +using namespace bluetooth; + extern tBTA_JV_CB bta_jv_cb; /******************************************************************************* @@ -41,7 +45,7 @@ uint8_t BTA_AllocateSCN(void) { if (!bta_jv_cb.scn_in_use[i]) { bta_jv_cb.scn_in_use[i] = true; bta_jv_cb.scn_search_index = (i + 1); - LOG_DEBUG("Allocating scn: %u", i + 1); + log::debug("Allocating scn: {}", i + 1); return (i + 1); // allocated scn is index + 1 } } @@ -57,11 +61,11 @@ uint8_t BTA_AllocateSCN(void) { if (!bta_jv_cb.scn_in_use[i]) { bta_jv_cb.scn_in_use[i] = true; bta_jv_cb.scn_search_index = (i + 1); - LOG_DEBUG("Allocating scn: %u", i + 1); + log::debug("Allocating scn: {}", i + 1); return (i + 1); // allocated scn is index + 1 } } - LOG_DEBUG("Unable to allocate an scn"); + log::debug("Unable to allocate an scn"); return (0); /* No free ports */ } @@ -84,10 +88,10 @@ bool BTA_TryAllocateSCN(uint8_t scn) { /* check if this scn is available */ if (!bta_jv_cb.scn_in_use[scn - 1]) { bta_jv_cb.scn_in_use[scn - 1] = true; - LOG_DEBUG("Allocating scn: %u", scn); + log::debug("Allocating scn: {}", scn); return true; } - LOG_DEBUG("Unable to allocate scn %u", scn); + log::debug("Unable to allocate scn {}", scn); return (false); /* scn was busy */ } @@ -106,10 +110,10 @@ bool BTA_FreeSCN(uint8_t scn) { */ if (scn < RFCOMM_MAX_SCN && scn > 1) { bta_jv_cb.scn_in_use[scn - 1] = false; - LOG_DEBUG("Freed SCN: %u", scn); + log::debug("Freed SCN: {}", scn); return (true); } else { - LOG_WARN("Invalid SCN: %u", scn); + log::warn("Invalid SCN: {}", scn); return (false); /* Illegal SCN passed in */ } } diff --git a/system/bta/sdp/bta_sdp_act.cc b/system/bta/sdp/bta_sdp_act.cc index 9c1d5bd62611613c6fe97d362c4912536bc015a6..936f8a5aa89c6ebada9e12701adf5412ebbe6fab 100644 --- a/system/bta/sdp/bta_sdp_act.cc +++ b/system/bta/sdp/bta_sdp_act.cc @@ -20,6 +20,7 @@ * This file contains action functions for SDP search. ******************************************************************************/ +#include #include #include @@ -41,6 +42,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) { @@ -62,10 +64,10 @@ static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) { record->mns.supported_features = p_attr->attr_value.v.u32; } else { - LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or size wrong!!"); + log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or size wrong!!"); } } else { - LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!"); + log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -76,10 +78,10 @@ static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type); record->mns.hdr.service_name = (char*)p_attr->attr_value.v.array; } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr type not TEXT_STR_DESC_TYPE!!"); + log::error("ATTR_ID_SERVICE_NAME attr type not TEXT_STR_DESC_TYPE!!"); } } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!"); + log::error("ATTR_ID_SERVICE_NAME attr not found!!"); } if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( @@ -99,10 +101,10 @@ static void bta_create_mns_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); } } @@ -129,10 +131,10 @@ static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) { record->mas.mas_instance_id = p_attr->attr_value.v.u8; } else { - LOG_ERROR("ATTR_ID_MAS_INSTANCE_ID attr type or len wrong!!"); + log::error("ATTR_ID_MAS_INSTANCE_ID attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_MAS_INSTANCE_ID attr not found!!"); + log::error("ATTR_ID_MAS_INSTANCE_ID attr not found!!"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -142,10 +144,10 @@ static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) { record->mas.supported_message_types = p_attr->attr_value.v.u8; } else { - LOG_ERROR("ATTR_ID_SUPPORTED_MSG_TYPE attr type or len wrong!!"); + log::error("ATTR_ID_SUPPORTED_MSG_TYPE attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_SUPPORTED_MSG_TYPE attr not found!!"); + log::error("ATTR_ID_SUPPORTED_MSG_TYPE attr not found!!"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -155,10 +157,10 @@ static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) { record->mas.supported_features = p_attr->attr_value.v.u32; } else { - LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or len wrong!!"); + log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!"); + log::error("ATTR_ID_MAP_SUPPORTED_FEATURES attr not found!!"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -169,10 +171,10 @@ static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type); record->mas.hdr.service_name = (char*)p_attr->attr_value.v.array; } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr type wrong!!"); + log::error("ATTR_ID_SERVICE_NAME attr type wrong!!"); } } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!"); + log::error("ATTR_ID_SERVICE_NAME attr not found!!"); } if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( @@ -192,10 +194,10 @@ static void bta_create_mas_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); } } @@ -221,10 +223,10 @@ static void bta_create_pse_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) { record->pse.supported_repositories = p_attr->attr_value.v.u8; } else { - LOG_ERROR("ATTR_ID_SUPPORTED_REPOSITORIES attr type or len wrong!!"); + log::error("ATTR_ID_SUPPORTED_REPOSITORIES attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_SUPPORTED_REPOSITORIES attr not found!!"); + log::error("ATTR_ID_SUPPORTED_REPOSITORIES attr not found!!"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES); @@ -233,10 +235,10 @@ static void bta_create_pse_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 4) { record->pse.supported_features = p_attr->attr_value.v.u32; } else { - LOG_ERROR("ATTR_ID_PBAP_SUPPORTED_FEATURES attr type or len wrong!!"); + log::error("ATTR_ID_PBAP_SUPPORTED_FEATURES attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_PBAP_SUPPORTED_FEATURES attr not found!!"); + log::error("ATTR_ID_PBAP_SUPPORTED_FEATURES attr not found!!"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -248,10 +250,10 @@ static void bta_create_pse_sdp_record(bluetooth_sdp_record* record, // TODO: validate the lifetime of this value record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array; } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!"); + log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!"); } } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!"); + log::error("ATTR_ID_SERVICE_NAME attr not found!!"); } if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( @@ -271,10 +273,10 @@ static void bta_create_pse_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); } } @@ -300,10 +302,10 @@ static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type); record->ops.hdr.service_name = (char*)p_attr->attr_value.v.array; } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!"); + log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!"); } } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!"); + log::error("ATTR_ID_SERVICE_NAME attr not found!!"); } if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( @@ -323,10 +325,10 @@ static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr type or len wrong!!"); } } else { - LOG_ERROR("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); + log::error("ATTR_ID_GOEP_L2CAP_PSM attr not found!!"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -335,10 +337,10 @@ static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, /* Safety check - each entry should itself be a sequence */ if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) { record->ops.supported_formats_list_len = 0; - LOG_ERROR( - "%s() - supported_formats_list - wrong attribute length/type:" - " 0x%02x - expected 0x06", - __func__, p_attr->attr_len_type); + log::error( + "supported_formats_list - wrong attribute length/type: 0x{:02x} - " + "expected 0x06", + p_attr->attr_len_type); } else { int count = 0; /* 1 byte for type/length 1 byte for value */ @@ -351,10 +353,9 @@ static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE) && (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) >= 1)) { if (count == sizeof(record->ops.supported_formats_list)) { - LOG_ERROR( - "%s() - supported_formats_list - count overflow - " - "too many sub attributes!!", - __func__); + log::error( + "supported_formats_list - count overflow - too many sub " + "attributes!!"); /* If you hit this, new formats have been added, * update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */ break; @@ -362,19 +363,19 @@ static void bta_create_ops_sdp_record(bluetooth_sdp_record* record, record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8; count++; } else { - LOG_ERROR( - "%s() - supported_formats_list - wrong sub attribute " - "length/type: 0x%02x - expected 0x80", - __func__, p_sattr->attr_len_type); + log::error( + "supported_formats_list - wrong sub attribute length/type: " + "0x{:02x} - expected 0x80", + p_sattr->attr_len_type); break; } } if (record->ops.supported_formats_list_len != count) { - LOG_WARN( - "%s() - supported_formats_list - Length of attribute different " - "from the actual number of sub-attributes in the sequence " - "att-length: %d - number of elements: %d", - __func__, record->ops.supported_formats_list_len, count); + log::warn( + "supported_formats_list - Length of attribute different from the " + "actual number of sub-attributes in the sequence att-length: {} - " + "number of elements: {}", + record->ops.supported_formats_list_len, count); } record->ops.supported_formats_list_len = count; } @@ -402,10 +403,10 @@ static void bta_create_sap_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type); record->sap.hdr.service_name = (char*)p_attr->attr_value.v.array; } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!"); + log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!"); } } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!"); + log::error("ATTR_ID_SERVICE_NAME attr not found!!"); } if (get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec( @@ -423,7 +424,7 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec) { tSDP_DISC_ATTR* p_attr; - LOG_VERBOSE("%s()", __func__); + log::verbose(""); /* hdr is redundancy in dip */ record->dip.hdr.type = SDP_TYPE_DIP; @@ -440,10 +441,10 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->dip.spec_id = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_SPECIFICATION_ID attr type or len wrong!!"); + log::error("ATTR_ID_SPECIFICATION_ID attr type or len wrong!!"); } } else { - LOG_ERROR("%s() ATTR_ID_SPECIFICATION_ID not found", __func__); + log::error("ATTR_ID_SPECIFICATION_ID not found"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -453,10 +454,10 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->dip.vendor = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_VENDOR_ID attr type or len wrong!!"); + log::error("ATTR_ID_VENDOR_ID attr type or len wrong!!"); } } else { - LOG_ERROR("%s() ATTR_ID_VENDOR_ID not found", __func__); + log::error("ATTR_ID_VENDOR_ID not found"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -466,10 +467,10 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->dip.vendor_id_source = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_VENDOR_ID_SOURCE attr type or len wrong!!"); + log::error("ATTR_ID_VENDOR_ID_SOURCE attr type or len wrong!!"); } } else { - LOG_ERROR("%s() ATTR_ID_VENDOR_ID_SOURCE not found", __func__); + log::error("ATTR_ID_VENDOR_ID_SOURCE not found"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -479,10 +480,10 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->dip.product = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_PRODUCT_ID attr type or len wrong!!"); + log::error("ATTR_ID_PRODUCT_ID attr type or len wrong!!"); } } else { - LOG_ERROR("%s() ATTR_ID_PRODUCT_ID not found", __func__); + log::error("ATTR_ID_PRODUCT_ID not found"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -492,10 +493,10 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { record->dip.version = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_PRODUCT_VERSION attr type or len wrong!!"); + log::error("ATTR_ID_PRODUCT_VERSION attr type or len wrong!!"); } } else { - LOG_ERROR("%s() ATTR_ID_PRODUCT_VERSION not found", __func__); + log::error("ATTR_ID_PRODUCT_VERSION not found"); } p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( @@ -505,10 +506,10 @@ static void bta_create_dip_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) { record->dip.primary_record = !(!p_attr->attr_value.v.u8); } else { - LOG_ERROR("ATTR_ID_PRIMARY_RECORD attr type or len wrong!!"); + log::error("ATTR_ID_PRIMARY_RECORD attr type or len wrong!!"); } } else { - LOG_ERROR("%s() ATTR_ID_PRIMARY_RECORD not found", __func__); + log::error("ATTR_ID_PRIMARY_RECORD not found"); } } @@ -533,10 +534,10 @@ static void bta_create_raw_sdp_record(bluetooth_sdp_record* record, SDP_DISC_ATTR_LEN(p_attr->attr_len_type); record->pse.hdr.service_name = (char*)p_attr->attr_value.v.array; } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr type NOT string!!"); + log::error("ATTR_ID_SERVICE_NAME attr type NOT string!!"); } } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!"); + log::error("ATTR_ID_SERVICE_NAME attr not found!!"); } /* Try to extract an RFCOMM channel */ @@ -553,7 +554,7 @@ static void bta_sdp_search_cback(UNUSED_ATTR const RawAddress& bd_addr, tSDP_RESULT result, const void* user_data) { tBTA_SDP_STATUS status = BTA_SDP_FAILURE; int count = 0; - LOG_VERBOSE("%s() - res: 0x%x", __func__, result); + log::verbose("res: 0x{:x}", result); bta_sdp_cb.sdp_active = false; @@ -573,28 +574,28 @@ static void bta_sdp_search_cback(UNUSED_ATTR const RawAddress& bd_addr, p_bta_sdp_cfg->p_sdp_db, uuid, p_rec); /* generate the matching record data pointer */ if (!p_rec) { - LOG_VERBOSE("%s() - UUID not found", __func__); + log::verbose("UUID not found"); continue; } status = BTA_SDP_SUCCESS; if (uuid == UUID_MAP_MAS) { - LOG_VERBOSE("%s() - found MAP (MAS) uuid", __func__); + log::verbose("found MAP (MAS) uuid"); bta_create_mas_sdp_record(&evt_data.records[count], p_rec); } else if (uuid == UUID_MAP_MNS) { - LOG_VERBOSE("%s() - found MAP (MNS) uuid", __func__); + log::verbose("found MAP (MNS) uuid"); bta_create_mns_sdp_record(&evt_data.records[count], p_rec); } else if (uuid == UUID_PBAP_PSE) { - LOG_VERBOSE("%s() - found PBAP (PSE) uuid", __func__); + log::verbose("found PBAP (PSE) uuid"); bta_create_pse_sdp_record(&evt_data.records[count], p_rec); } else if (uuid == UUID_OBEX_OBJECT_PUSH) { - LOG_VERBOSE("%s() - found Object Push Server (OPS) uuid", __func__); + log::verbose("found Object Push Server (OPS) uuid"); bta_create_ops_sdp_record(&evt_data.records[count], p_rec); } else if (uuid == UUID_SAP) { - LOG_VERBOSE("%s() - found SAP uuid", __func__); + log::verbose("found SAP uuid"); bta_create_sap_sdp_record(&evt_data.records[count], p_rec); } else if (uuid == UUID_PBAP_PCE) { - LOG_VERBOSE("%s() - found PBAP (PCE) uuid", __func__); + log::verbose("found PBAP (PCE) uuid"); if (p_rec != NULL) { uint16_t peer_pce_version = 0; @@ -605,14 +606,14 @@ static void bta_sdp_search_cback(UNUSED_ATTR const RawAddress& bd_addr, peer_pce_version); } } else { - LOG_VERBOSE("%s() - PCE Record is null", __func__); + log::verbose("PCE Record is null"); } } else if (uuid == UUID_DIP) { - LOG_VERBOSE("%s() - found DIP uuid", __func__); + log::verbose("found DIP uuid"); bta_create_dip_sdp_record(&evt_data.records[count], p_rec); } else { /* we do not have specific structure for this */ - LOG_VERBOSE("%s() - profile not identified. using raw data", __func__); + log::verbose("profile not identified. using raw data"); bta_create_raw_sdp_record(&evt_data.records[count], p_rec); p_rec = NULL; // Terminate loop /* For raw, we only extract the first entry, and then return the @@ -647,7 +648,7 @@ static void bta_sdp_search_cback(UNUSED_ATTR const RawAddress& bd_addr, * ******************************************************************************/ void bta_sdp_enable(tBTA_SDP_DM_CBACK* p_cback) { - LOG_VERBOSE("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active); + log::verbose("in, sdp_active:{}", bta_sdp_cb.sdp_active); tBTA_SDP_STATUS status = BTA_SDP_SUCCESS; bta_sdp_cb.p_dm_cback = p_cback; tBTA_SDP bta_sdp; @@ -667,7 +668,7 @@ void bta_sdp_enable(tBTA_SDP_DM_CBACK* p_cback) { void bta_sdp_search(const RawAddress bd_addr, const bluetooth::Uuid uuid) { tBTA_SDP_STATUS status = BTA_SDP_FAILURE; - LOG_VERBOSE("%s in, sdp_active:%d", __func__, bta_sdp_cb.sdp_active); + log::verbose("in, sdp_active:{}", bta_sdp_cb.sdp_active); if (bta_sdp_cb.sdp_active) { /* SDP is still in progress */ @@ -689,8 +690,7 @@ void bta_sdp_search(const RawAddress bd_addr, const bluetooth::Uuid uuid) { bta_sdp_cb.remote_addr = bd_addr; /* initialize the search for the uuid */ - LOG_VERBOSE("%s init discovery with UUID: %s", __func__, - uuid.ToString().c_str()); + log::verbose("init discovery with UUID: {}", uuid.ToString()); get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb( p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1, &uuid, 0, NULL); diff --git a/system/bta/sdp/bta_sdp_api.cc b/system/bta/sdp/bta_sdp_api.cc index c77a6efe9b192ca84de8bc540eaacb3564904cf7..d68c42d03d43515cd3cf70abb5c84a318ff27281 100644 --- a/system/bta/sdp/bta_sdp_api.cc +++ b/system/bta/sdp/bta_sdp_api.cc @@ -27,8 +27,8 @@ #include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/sdp/bta_sdp_int.h" +#include "internal_include/bt_target.h" #include "stack/include/main_thread.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" diff --git a/system/bta/sdp/bta_sdp_cfg.cc b/system/bta/sdp/bta_sdp_cfg.cc index 36e745d1926a9c1472aceb0e752da380e63b8a73..1f8eff67ba142405b66edc69e5c8f8d5a73a1c22 100644 --- a/system/bta/sdp/bta_sdp_cfg.cc +++ b/system/bta/sdp/bta_sdp_cfg.cc @@ -20,9 +20,8 @@ * This file contains compile-time configurable constants for SDP Search ******************************************************************************/ -#include "bt_target.h" // Must be first to define build configuration - #include "bta/include/bta_sdp_api.h" +#include "internal_include/bt_target.h" #include "stack/include/sdp_api.h" #ifndef BTA_SDP_DB_SIZE diff --git a/system/bta/sys/bta_sys.h b/system/bta/sys/bta_sys.h index 0e791a23d6a013ea564b9f455411011ee63ef990..1707cc9c435b51c2b1e88195c2ff41a809cb7bec 100644 --- a/system/bta/sys/bta_sys.h +++ b/system/bta/sys/bta_sys.h @@ -25,8 +25,9 @@ #define BTA_SYS_H #include -#include +#include +#include #include #include @@ -200,6 +201,9 @@ typedef void(tBTA_SYS_ROLE_SWITCH_CBACK)(tBTA_SYS_CONN_STATUS status, typedef void(tBTA_SYS_SSR_CFG_CBACK)(uint8_t id, uint8_t app_id, uint16_t latency, uint16_t tout); +typedef void(tBTA_SYS_SNIFF_CBACK)(uint8_t id, uint8_t app_id, + const RawAddress& peer_addr); + typedef struct { bluetooth::Uuid custom_uuid; uint32_t handle; @@ -226,22 +230,19 @@ typedef struct { /***************************************************************************** * Function declarations ****************************************************************************/ -void bta_set_forward_hw_failures(bool value); -void BTA_sys_signal_hw_error(); - void bta_sys_init(void); void bta_sys_register(uint8_t id, const tBTA_SYS_REG* p_reg); void bta_sys_deregister(uint8_t id); bool bta_sys_is_register(uint8_t id); void bta_sys_sendmsg(void* p_msg); -void bta_sys_sendmsg_delayed(void* p_msg, const base::TimeDelta& delay); +void bta_sys_sendmsg_delayed(void* p_msg, std::chrono::microseconds delay); void bta_sys_start_timer(alarm_t* alarm, uint64_t interval_ms, uint16_t event, uint16_t layer_specific); void bta_sys_disable(); void bta_sys_rm_register(tBTA_SYS_CONN_CBACK* p_cback); void bta_sys_pm_register(tBTA_SYS_CONN_CBACK* p_cback); - +void bta_sys_sniff_register(tBTA_SYS_SNIFF_CBACK* p_cback); void bta_sys_sco_register(tBTA_SYS_CONN_SCO_CBACK* p_cback); void bta_sys_conn_open(tBTA_SYS_ID id, uint8_t app_id, @@ -262,7 +263,8 @@ void bta_sys_sco_unuse(tBTA_SYS_ID id, uint8_t app_id, const RawAddress& peer_addr); void bta_sys_idle(tBTA_SYS_ID id, uint8_t app_id, const RawAddress& peer_addr); void bta_sys_busy(tBTA_SYS_ID id, uint8_t app_id, const RawAddress& peer_addr); - +void bta_sys_reset_sniff(uint8_t id, uint8_t app_id, + const RawAddress& peer_addr); void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK* p_cback); void bta_sys_chg_ssr_config(tBTA_SYS_ID id, uint8_t app_id, uint16_t max_latency, uint16_t min_tout); @@ -292,4 +294,12 @@ void bta_sys_remove_cust_uuid(const tBTA_CUSTOM_UUID& curr); #define bta_sys_remove_cust_uuid(ut) #endif +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter { +}; +} // namespace fmt + #endif /* BTA_SYS_H */ diff --git a/system/bta/sys/bta_sys_conn.cc b/system/bta/sys/bta_sys_conn.cc index 49422cc90c7bcd7a131640c1dccdade8d11f0c7a..850fce96b77ccb8816ff734d16fa37c30a37a1ed 100644 --- a/system/bta/sys/bta_sys_conn.cc +++ b/system/bta/sys/bta_sys_conn.cc @@ -22,18 +22,21 @@ * ******************************************************************************/ +#include + #include #include "bta/sys/bta_sys.h" #include "bta/sys/bta_sys_int.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/btm_api.h" #include "types/hci_role.h" #include "types/raw_address.h" +using namespace bluetooth; /******************************************************************************* * * Function bta_sys_rm_register @@ -87,9 +90,9 @@ void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK* p_cback) { ******************************************************************************/ void bta_sys_notify_role_chg(const RawAddress& peer_addr, tHCI_ROLE new_role, tHCI_STATUS hci_status) { - LOG_DEBUG("Role changed peer:%s new_role:%s hci_status:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), RoleText(new_role).c_str(), - hci_error_code_text(hci_status).c_str()); + log::debug("Role changed peer:{} new_role:{} hci_status:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), RoleText(new_role), + hci_error_code_text(hci_status)); if (bta_sys_cb.p_role_cb) { bta_sys_cb.p_role_cb(BTA_SYS_ROLE_CHANGE, new_role, hci_status, peer_addr); } @@ -169,6 +172,37 @@ void bta_sys_pm_register(tBTA_SYS_CONN_CBACK* p_cback) { bta_sys_cb.ppm_cb = p_cback; } +/******************************************************************************* + * + * Function bta_sys_sniff_register + * + * Description Called by BTA DM to register sniff callbacks + * + * + * Returns void + * + ******************************************************************************/ +void bta_sys_sniff_register(tBTA_SYS_SNIFF_CBACK* p_cback) { + bta_sys_cb.sniff_cb = p_cback; +} + +/******************************************************************************* + * + * Function bta_sys_reset_sniff + * + * Description Called by BTA subsystems to reset sniff timer + * + * + * Returns void + * + ******************************************************************************/ +void bta_sys_reset_sniff(uint8_t id, uint8_t app_id, + const RawAddress& peer_addr) { + if (bta_sys_cb.sniff_cb) { + bta_sys_cb.sniff_cb(id, app_id, peer_addr); + } +} + /******************************************************************************* * * Function bta_sys_conn_open @@ -401,14 +435,14 @@ void bta_sys_busy(tBTA_SYS_ID id, uint8_t app_id, const RawAddress& peer_addr) { ******************************************************************************/ void bta_sys_eir_register(tBTA_SYS_EIR_CBACK* p_cback) { if (bta_sys_cb.eir_cb != nullptr) { - LOG_WARN("Already registered extended inquiry result callback"); + log::warn("Already registered extended inquiry result callback"); } bta_sys_cb.eir_cb = p_cback; } void bta_sys_eir_unregister() { if (bta_sys_cb.eir_cb == nullptr) { - LOG_WARN("Already unregistered extended inquiry result callback"); + log::warn("Already unregistered extended inquiry result callback"); } bta_sys_cb.eir_cb = nullptr; } diff --git a/system/bta/sys/bta_sys_int.h b/system/bta/sys/bta_sys_int.h index 464fb72fddcb91a5f41caed8d81ab66eca956e12..eb0f7863e5f8b2e41e4164621bf5ec114b9a510d 100644 --- a/system/bta/sys/bta_sys_int.h +++ b/system/bta/sys/bta_sys_int.h @@ -48,12 +48,13 @@ typedef struct { typedef struct { tBTA_SYS_REG* reg[BTA_ID_MAX]; /* registration structures */ bool is_reg[BTA_ID_MAX]; /* registration structures */ - bool forward_hw_failures; uint16_t sys_features; /* Bitmask of sys features */ tBTA_SYS_CONN_CBACK* prm_cb; /* role management callback registered by DM */ tBTA_SYS_CONN_CBACK* ppm_cb; /* low power management callback registered by DM */ + tBTA_SYS_SNIFF_CBACK* + sniff_cb; /* low power management sniff callback registered by DM */ tBTA_SYS_CONN_SCO_CBACK* p_sco_cb; /* SCO connection change callback registered by AV */ tBTA_SYS_ROLE_SWITCH_CBACK* diff --git a/system/bta/sys/bta_sys_main.cc b/system/bta/sys/bta_sys_main.cc index 614deb3a4c5b06f89f7ca3b21d95761a4b94e008..bfcf5e9daecc914acf8d70c454c37d4041c52167 100644 --- a/system/bta/sys/bta_sys_main.cc +++ b/system/bta/sys/bta_sys_main.cc @@ -26,20 +26,21 @@ #include #include +#include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/sys/bta_sys.h" #include "bta/sys/bta_sys_int.h" #include "include/hardware/bluetooth.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "stack/include/bt_hdr.h" #include "stack/include/main_thread.h" -void BTIF_dm_on_hw_error(); +using namespace bluetooth; /* system manager control block definition */ tBTA_SYS_CB bta_sys_cb; @@ -58,16 +59,6 @@ void bta_sys_init(void) { memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB)); } -void bta_set_forward_hw_failures(bool value) { - bta_sys_cb.forward_hw_failures = value; -} - -void BTA_sys_signal_hw_error() { - if (bta_sys_cb.forward_hw_failures) { - BTIF_dm_on_hw_error(); - } -} - /******************************************************************************* * * Function bta_sys_event @@ -81,7 +72,7 @@ void BTA_sys_signal_hw_error() { static void bta_sys_event(BT_HDR_RIGID* p_msg) { bool freebuf = true; - LOG_VERBOSE("%s: Event 0x%x", __func__, p_msg->event); + log::verbose("Event 0x{:x}", p_msg->event); /* get subsystem id from event */ uint8_t id = (uint8_t)(p_msg->event >> 8); @@ -90,8 +81,8 @@ static void bta_sys_event(BT_HDR_RIGID* p_msg) { if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) { freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg); } else { - LOG_INFO("Ignoring receipt of unregistered event id:%s[%hhu]", - BtaIdSysText(static_cast(id)).c_str(), id); + log::info("Ignoring receipt of unregistered event id:{}[{}]", + BtaIdSysText(static_cast(id)), id); } if (freebuf) { @@ -161,16 +152,16 @@ void bta_sys_sendmsg(void* p_msg) { FROM_HERE, base::BindOnce(&bta_sys_event, static_cast(p_msg))) != BT_STATUS_SUCCESS) { - LOG(ERROR) << __func__ << ": do_in_main_thread failed"; + log::error("do_in_main_thread failed"); } } -void bta_sys_sendmsg_delayed(void* p_msg, const base::TimeDelta& delay) { +void bta_sys_sendmsg_delayed(void* p_msg, std::chrono::microseconds delay) { if (do_in_main_thread_delayed( FROM_HERE, base::Bind(&bta_sys_event, static_cast(p_msg)), delay) != BT_STATUS_SUCCESS) { - LOG(ERROR) << __func__ << ": do_in_main_thread_delayed failed"; + log::error("do_in_main_thread_delayed failed"); } } diff --git a/system/bta/sys/utl.cc b/system/bta/sys/utl.cc index e4d9034db0c8b41c9429790908a33e68c487daba..1b5c22c6a2fe2156a77de99558e79a96d51268c7 100644 --- a/system/bta/sys/utl.cc +++ b/system/bta/sys/utl.cc @@ -21,11 +21,11 @@ * This file contains utility functions. * ******************************************************************************/ -#include +#include "bta/include/utl.h" -#include "bt_target.h" // Must be first to define build configuration +#include -#include "bta/include/utl.h" +#include "internal_include/bt_target.h" #include "stack/include/btm_api.h" /******************************************************************************* @@ -158,15 +158,14 @@ uint8_t utl_itoa(uint16_t i, char* p_s) { * ******************************************************************************/ bool utl_set_device_class(tBTA_UTL_COD* p_cod, uint8_t cmd) { - uint8_t* dev; uint16_t service; uint8_t minor, major; - DEV_CLASS dev_class; + DEV_CLASS old_class; - dev = BTM_ReadDeviceClass(); - BTM_COD_SERVICE_CLASS(service, dev); - BTM_COD_MINOR_CLASS(minor, dev); - BTM_COD_MAJOR_CLASS(major, dev); + old_class = BTM_ReadDeviceClass(); + BTM_COD_SERVICE_CLASS(service, old_class); + BTM_COD_MINOR_CLASS(minor, old_class); + BTM_COD_MAJOR_CLASS(major, old_class); switch (cmd) { case BTA_UTL_SET_COD_MAJOR_MINOR: @@ -203,6 +202,7 @@ bool utl_set_device_class(tBTA_UTL_COD* p_cod, uint8_t cmd) { } /* convert the fields into the device class type */ + DEV_CLASS dev_class; FIELDS_TO_COD(dev_class, minor, major, service); if (BTM_SetDeviceClass(dev_class) == BTM_SUCCESS) return true; diff --git a/system/bta/test/bta_ag_sco_test.cc b/system/bta/test/bta_ag_sco_test.cc index 2ef8abb828c1ef36bb81497299f6d90bce5969f1..d3bdb93c9b3dfce080a5529a2d97210b2e74d703 100644 --- a/system/bta/test/bta_ag_sco_test.cc +++ b/system/bta/test/bta_ag_sco_test.cc @@ -27,6 +27,7 @@ bool btm_peer_supports_esco_ev3(const RawAddress& remote_bda) { return true; } tBTM_CB btm_cb; LeAudioClient* LeAudioClient::Get() { return nullptr; } +bool LeAudioClient::IsLeAudioClientInStreaming() { return false; } const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); diff --git a/system/bta/test/bta_ag_test.cc b/system/bta/test/bta_ag_test.cc index f405288346cf947bf2bfded9dd6036d5b42ff239..8b1f652c1044e7c5cd1f55292db8f3015a803ace 100644 --- a/system/bta/test/bta_ag_test.cc +++ b/system/bta/test/bta_ag_test.cc @@ -14,8 +14,11 @@ * limitations under the License. */ +#include +#include #include #include +#include #include #include #include @@ -32,7 +35,6 @@ #include "bta/include/bta_dm_api.h" #include "bta/include/bta_hf_client_api.h" #include "bta/include/bta_le_audio_api.h" -#include "btif/include/stack_manager.h" #include "common/message_loop_thread.h" #include "os/system_properties.h" #include "osi/include/compat.h" @@ -50,6 +52,8 @@ #define TEST_BT com::android::bluetooth::flags +using namespace bluetooth; + namespace { bool bta_ag_hdl_event(const BT_HDR_RIGID* p_msg) { return true; }; @@ -64,12 +68,7 @@ const std::string kBtCodecAptxVoiceEnabled = static bool enable_aptx_voice_property(bool enable) { const std::string value = enable ? "true" : "false"; - bool result = - bluetooth::os::SetSystemProperty(kBtCodecAptxVoiceEnabled, value); - auto codec_aptx_voice_enabled = - bluetooth::os::GetSystemProperty(kBtCodecAptxVoiceEnabled); - return result && codec_aptx_voice_enabled && - (codec_aptx_voice_enabled.value() == value); + return android::base::SetProperty(kBtCodecAptxVoiceEnabled, value); } class BtaAgTest : public testing::Test { @@ -79,7 +78,7 @@ class BtaAgTest : public testing::Test { fake_osi_ = std::make_unique(); main_thread_start_up(); - post_on_bt_main([]() { LOG_INFO("Main thread started up"); }); + post_on_bt_main([]() { log::info("Main thread started up"); }); bta_sys_register(BTA_ID_AG, &bta_ag_reg); @@ -94,7 +93,7 @@ class BtaAgTest : public testing::Test { void TearDown() override { test::mock::device_esco_parameters::esco_parameters_for_codec = {}; bta_sys_deregister(BTA_ID_AG); - post_on_bt_main([]() { LOG_INFO("Main thread shutting down"); }); + post_on_bt_main([]() { log::info("Main thread shutting down"); }); main_thread_shut_down(); } @@ -172,8 +171,6 @@ TEST_F_WITH_FLAGS(BtaAgActTest, set_codec_q0_success, bta_ag_setcodec(p_scb, data); ASSERT_EQ(p_scb->sco_codec, BTA_AG_SCO_APTX_SWB_SETTINGS_Q0); - ASSERT_TRUE( - bluetooth::os::SetSystemProperty(kBtCodecAptxVoiceEnabled, "false")); } TEST_F_WITH_FLAGS(BtaAgActTest, set_codec_q1_fail_unsupported, @@ -205,6 +202,28 @@ class BtaAgCmdTest : public BtaAgTest { void TearDown() override { BtaAgTest::TearDown(); } }; +TEST_F_WITH_FLAGS(BtaAgCmdTest, check_flag_disabling_guarding_with_prop, + REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, + hfp_codec_aptx_voice))) { + ASSERT_FALSE(IS_FLAG_ENABLED(hfp_codec_aptx_voice)); + ASSERT_TRUE(enable_aptx_voice_property(false)); + ASSERT_FALSE(is_hfp_aptx_voice_enabled()); + + ASSERT_TRUE(enable_aptx_voice_property(true)); + ASSERT_FALSE(is_hfp_aptx_voice_enabled()); +} + +TEST_F_WITH_FLAGS(BtaAgCmdTest, check_flag_guarding_with_prop, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, + hfp_codec_aptx_voice))) { + ASSERT_TRUE(IS_FLAG_ENABLED(hfp_codec_aptx_voice)); + ASSERT_TRUE(enable_aptx_voice_property(false)); + ASSERT_FALSE(is_hfp_aptx_voice_enabled()); + + ASSERT_TRUE(enable_aptx_voice_property(true)); + ASSERT_TRUE(is_hfp_aptx_voice_enabled()); +} + TEST_F_WITH_FLAGS(BtaAgCmdTest, at_hfp_cback__qac_ev_codec_disabled, REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, hfp_codec_aptx_voice))) { diff --git a/system/bta/test/bta_dip_test.cc b/system/bta/test/bta_dip_test.cc index 3ad0f1213b3500971b7f9eef9888a68f31fa5270..b9b4cfa65f9cf5337d4c009f4c59846068705ce7 100644 --- a/system/bta/test/bta_dip_test.cc +++ b/system/bta/test/bta_dip_test.cc @@ -194,6 +194,16 @@ TEST_F(BtaDipTest, test_invalid_size_checks) { ASSERT_EQ(record.dip.product, 0); ASSERT_EQ(record.dip.version, 0); ASSERT_EQ(record.dip.primary_record, true); + + // a size zero for boolean won't be accepted + g_attr_vendor_product_primary_record.attr_len_type = + (BOOLEAN_DESC_TYPE << 12) | 0; + + record = {}; + + g_attr_vendor_product_primary_record.attr_value.v.u8 = 1; + bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec); + ASSERT_EQ(record.dip.primary_record, false); } diff --git a/system/bta/test/bta_dm_test.cc b/system/bta/test/bta_dm_test.cc index 64453338ee2679ac2571b9c6de97b339f6e8d134..d41d59cd978464589ab645dfaf867eedbdac2a8f 100644 --- a/system/bta/test/bta_dm_test.cc +++ b/system/bta/test/bta_dm_test.cc @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include #include @@ -24,6 +27,7 @@ #include "bta/dm/bta_dm_disc.h" #include "bta/dm/bta_dm_disc_int.h" #include "bta/dm/bta_dm_int.h" +#include "bta/dm/bta_dm_pm.cc" #include "bta/dm/bta_dm_sec_int.h" #include "bta/hf_client/bta_hf_client_int.h" #include "bta/include/bta_api.h" @@ -35,10 +39,14 @@ #include "test/common/mock_functions.h" #include "test/mock/mock_osi_alarm.h" #include "test/mock/mock_osi_allocator.h" +#include "test/mock/mock_osi_properties.h" #include "test/mock/mock_stack_acl.h" #include "test/mock/mock_stack_btm_interface.h" +#define TEST_BT com::android::bluetooth::flags + using namespace std::chrono_literals; +using namespace bluetooth; namespace { constexpr uint8_t kUnusedTimer = BTA_ID_MAX; @@ -76,7 +84,7 @@ class BtaDmTest : public BtaBaseTest { void SetUp() override { BtaBaseTest::SetUp(); main_thread_start_up(); - post_on_bt_main([]() { LOG_INFO("Main thread started up"); }); + post_on_bt_main([]() { log::info("Main thread started up"); }); bta_sys_register(BTA_ID_DM_SEARCH, &bta_dm_search_reg); bluetooth::legacy::testing::bta_dm_init_cb(); @@ -90,7 +98,7 @@ class BtaDmTest : public BtaBaseTest { void TearDown() override { bta_sys_deregister(BTA_ID_DM_SEARCH); bluetooth::legacy::testing::bta_dm_deinit_cb(); - post_on_bt_main([]() { LOG_INFO("Main thread shutting down"); }); + post_on_bt_main([]() { log::info("Main thread shutting down"); }); main_thread_shut_down(); BtaBaseTest::TearDown(); } @@ -212,6 +220,8 @@ void btm_set_local_io_caps(uint8_t io_caps); tBTM_STATUS bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data); +void BTA_dm_on_hw_on(); + } // namespace testing } // namespace legacy } // namespace bluetooth @@ -579,3 +589,67 @@ TEST_F(BtaDmTest, bta_dm_disc_start__true) { bta_dm_disc_start(true); } TEST_F(BtaDmTest, bta_dm_disc_start__false) { bta_dm_disc_start(false); } TEST_F(BtaDmTest, bta_dm_disc_stop) { bta_dm_disc_stop(); } + +TEST_F(BtaDmCustomAlarmTest, bta_dm_sniff_cback) { + // Setup a connected device + const tBT_TRANSPORT transport{BT_TRANSPORT_BR_EDR}; + tBTA_DM_PEER_DEVICE* device = + bluetooth::legacy::testing::allocate_device_for(kRawAddress, transport); + ASSERT_TRUE(device != nullptr); + + // Trigger a sniff timer + bta_dm_pm_start_timer(&bta_dm_cb.pm_timer[0], + bta_pm_action_to_timer_idx(BTA_DM_PM_SNIFF), 10, 1, + BTA_DM_PM_SNIFF); + bta_dm_cb.pm_timer[0].peer_bdaddr = kRawAddress; + ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop")); + + // Trigger reset sniff + bta_dm_sniff_cback(BTA_ID_JV, 1, kRawAddress); + ASSERT_EQ(1, get_func_call_count("alarm_cancel")); + ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop")); +} + +TEST_F_WITH_FLAGS(BtaDmCustomAlarmTest, sniff_offload_feature__enable_flag, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, + enable_sniff_offload))) { + bool is_property_enabled = true; + test::mock::osi_properties::osi_property_get_bool.body = + [&](const char* key, bool default_value) -> int { + return is_property_enabled; + }; + + // Expect not to trigger bta_dm_init_pm due to both flag and prop are enabled + // and reset the value of .srvc_id. + is_property_enabled = true; + bluetooth::legacy::testing::BTA_dm_on_hw_on(); + ASSERT_EQ(0, bta_dm_cb.pm_timer[0].srvc_id[0]); + + // Expect to trigger bta_dm_init_pm and init the value of .srvc_id to + // BTA_ID_MAX. + is_property_enabled = false; + bluetooth::legacy::testing::BTA_dm_on_hw_on(); + ASSERT_EQ((uint8_t)BTA_ID_MAX, bta_dm_cb.pm_timer[0].srvc_id[0]); +} + +TEST_F_WITH_FLAGS(BtaDmCustomAlarmTest, sniff_offload_feature__disable_flag, + REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, + enable_sniff_offload))) { + bool is_property_enabled = true; + test::mock::osi_properties::osi_property_get_bool.body = + [&](const char* key, bool default_value) -> int { + return is_property_enabled; + }; + + // Expect to trigger bta_dm_init_pm and init the value of .srvc_id to + // BTA_ID_MAX. + is_property_enabled = true; + bluetooth::legacy::testing::BTA_dm_on_hw_on(); + ASSERT_EQ((uint8_t)BTA_ID_MAX, bta_dm_cb.pm_timer[0].srvc_id[0]); + + // Expect to trigger bta_dm_init_pm and init the value of .srvc_id to + // BTA_ID_MAX. + is_property_enabled = false; + bluetooth::legacy::testing::BTA_dm_on_hw_on(); + ASSERT_EQ((uint8_t)BTA_ID_MAX, bta_dm_cb.pm_timer[0].srvc_id[0]); +} diff --git a/system/bta/test/bta_gatt_client_test.cc b/system/bta/test/bta_gatt_client_test.cc index ef92ed70483966712e838032f0dad248d29c1b4a..5e629cce787f6eb7497e59197de09396dbc1acaa 100644 --- a/system/bta/test/bta_gatt_client_test.cc +++ b/system/bta/test/bta_gatt_client_test.cc @@ -22,8 +22,7 @@ #include #include "bta/dm/bta_dm_gatt_client.h" -#include "gd/common/circular_buffer.h" -#include "stack/btm/btm_int_types.h" +#include "common/circular_buffer.h" using namespace bluetooth::common; diff --git a/system/bta/test/bta_hh_test.cc b/system/bta/test/bta_hh_test.cc index b9b2b552c1c5055582c23c5c5190a2a7f58b478d..c97cbbb4644285b00f5dbd4b6e7fe8f791372ff6 100644 --- a/system/bta/test/bta_hh_test.cc +++ b/system/bta/test/bta_hh_test.cc @@ -21,6 +21,7 @@ #include "bta/dm/bta_dm_int.h" #include "bta/hh/bta_hh_int.h" #include "bta/include/bta_hh_api.h" +#include "bta/include/bta_le_audio_api.h" #include "osi/include/allocator.h" #include "test/common/mock_functions.h" #include "test/mock/mock_osi_allocator.h" @@ -77,7 +78,9 @@ TEST_F(BtaHhTest, bta_hh_ctrl_dat_act__BTA_HH_GET_RPT_EVT) { .offset = 0, .layer_specific = 0, }, - .addr = RawAddress::kEmpty, + .link_spec.addrt.bda = RawAddress::kEmpty, + .link_spec.addrt.type = BLE_ADDR_PUBLIC, + .link_spec.transport = BT_TRANSPORT_AUTO, .data = 32, .p_data = static_cast(osi_calloc(32 + sizeof(BT_HDR))), }, diff --git a/system/bta/test/bta_sec_test.cc b/system/bta/test/bta_sec_test.cc index 55ce9bb51ffc8e193ff5793b6b7f71e3a3f7ffbc..9df0cc41899359799c94825e86769ae5e4039003 100644 --- a/system/bta/test/bta_sec_test.cc +++ b/system/bta/test/bta_sec_test.cc @@ -85,7 +85,7 @@ TEST_F(BtaSecTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithName) { .rmt_io_caps = BTM_IO_CAP_NONE, }, }; - dev_class_copy(data.cfm_req.dev_class, kDeviceClass); + data.cfm_req.dev_class = kDeviceClass; bd_name_copy(data.cfm_req.bd_name, kRemoteName); ASSERT_EQ(btm_status_text(BTM_CMD_STARTED), @@ -136,7 +136,7 @@ TEST_F(BtaSecTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithoutName_RNRSuccess) { .rmt_io_caps = BTM_IO_CAP_NONE, }, }; - dev_class_copy(data.cfm_req.dev_class, kDeviceClass); + data.cfm_req.dev_class = kDeviceClass; ASSERT_EQ(btm_status_text(BTM_CMD_STARTED), btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback( @@ -177,7 +177,7 @@ TEST_F(BtaSecTest, bta_dm_sp_cback__BTM_SP_CFM_REQ_EVT_WithoutName_RNRFail) { .rmt_io_caps = BTM_IO_CAP_NONE, }, }; - dev_class_copy(data.cfm_req.dev_class, kDeviceClass); + data.cfm_req.dev_class = kDeviceClass; ASSERT_EQ(btm_status_text(BTM_CMD_STARTED), btm_status_text(bluetooth::legacy::testing::bta_dm_sp_cback( @@ -220,7 +220,7 @@ TEST_F(BtaSecTest, bta_dm_sp_cback__BTM_SP_KEY_NOTIF_EVT) { .passkey = kPassKey, }, }; - dev_class_copy(data.key_notif.dev_class, kDeviceClass); + data.key_notif.dev_class = kDeviceClass; bd_name_copy(data.key_notif.bd_name, kRemoteName); ASSERT_EQ(btm_status_text(BTM_CMD_STARTED), diff --git a/system/bta/test/common/mock_controller.cc b/system/bta/test/common/mock_controller.cc index 1aeb5527b21cce0b6d4e290f66442f427701f666..5a514f38cf1073c1c7e1bf1f6c108d0a52fc1b02 100644 --- a/system/bta/test/common/mock_controller.cc +++ b/system/bta/test/common/mock_controller.cc @@ -67,12 +67,12 @@ const controller_t* controller_get_interface() { controller_instance->get_iso_data_size = &get_iso_data_size; controller_instance->get_iso_buffer_count = &get_iso_buffer_count; - controller_instance->supports_ble_isochronous_broadcaster = + controller_instance->SupportsBleIsochronousBroadcaster = &supports_ble_isochronous_broadcaster; - controller_instance->supports_ble_2m_phy = &supports_ble_2m_phy; - controller_instance->supports_ble_connected_isochronous_stream_central = + controller_instance->SupportsBle2mPhy = &supports_ble_2m_phy; + controller_instance->SupportsBleConnectedIsochronousStreamCentral = &supports_ble_connected_isochronous_stream_central; - controller_instance->supports_ble_connected_isochronous_stream_peripheral = + controller_instance->SupportsBleConnectedIsochronousStreamPeripheral = &supports_ble_connected_isochronous_stream_peripheral; controller_instance->supports_configure_data_path = &supports_configure_data_path; diff --git a/system/bta/test/gatt/database_test.cc b/system/bta/test/gatt/database_test.cc index 16265f3ea5c708c4ae4bbad668240cd61655171d..7b0adeff3c30e7bcd323663d04201c0da40be388 100644 --- a/system/bta/test/gatt/database_test.cc +++ b/system/bta/test/gatt/database_test.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include "gatt/database_builder.h" @@ -27,6 +28,7 @@ #include "types/bluetooth/uuid.h" using bluetooth::Uuid; +using namespace bluetooth; namespace gatt { @@ -123,7 +125,7 @@ TEST(GattCacheTest, stored_attribute_to_binary_service_test) { // clang-format on // useful for debugging: - // LOG(ERROR) << " " << base::HexEncode(&attr, len); + // log::error("{}", base::HexEncode(&attr, len)); // Do not compare last 2 bytes which are padding as // x86 can use non-zero padding causing the test to fail @@ -160,7 +162,7 @@ TEST(GattCacheTest, stored_attribute_to_binary_included_service_test) { // clang-format on // useful for debugging: - // LOG(ERROR) << " " << base::HexEncode(&attr, len); + // log::error("{}", base::HexEncode(&attr, len)); EXPECT_EQ(memcmp(binary_form, &attr, len), 0); } @@ -193,7 +195,7 @@ TEST(GattCacheTest, stored_attribute_to_binary_characteristic_test) { // clang-format on // useful for debugging: - // LOG(ERROR) << " " << base::HexEncode(&attr, len); + // log::error("{}", base::HexEncode(&attr, len)); EXPECT_EQ(memcmp(binary_form, &attr, len), 0); } @@ -219,7 +221,7 @@ TEST(GattCacheTest, stored_attribute_to_binary_descriptor_test) { // clang-format on // useful for debugging: - // LOG(ERROR) << " " << base::HexEncode(&attr, len); + // log::error("{}", base::HexEncode(&attr, len)); EXPECT_EQ(memcmp(binary_form, &attr, len), 0); } @@ -287,7 +289,7 @@ TEST(GattCacheTest, // clang-format on // useful for debugging: - // LOG(ERROR) << " " << base::HexEncode(&attr, len); + // log::error("{}", base::HexEncode(&attr, len)); EXPECT_EQ(memcmp(binary_form.data(), &attr, len), 0); // Don't use memcmp, for better error messages. @@ -339,7 +341,7 @@ TEST(GattCacheTest, stored_attributes_serialized_to_binary_test) { attr = {.handle = 0x0003, .type = Uuid::FromString("2900"), .value.characteristic_extended_properties = 0x1234}; - LOG(ERROR) << " " << base::HexEncode(&attr, StoredAttribute::kSizeOnDisk); + log::error("{}", base::HexEncode(&attr, StoredAttribute::kSizeOnDisk)); */ memcpy( @@ -371,7 +373,7 @@ TEST(GattCacheTest, stored_attributes_serialized_to_binary_test) { .end_handle = 0x1203, }, }; - LOG(ERROR) << " " << base::HexEncode(&attr, StoredAttribute::kSizeOnDisk); + log::error("{}", base::HexEncode(&attr, StoredAttribute::kSizeOnDisk)); */ memcpy( attr_bytes, @@ -401,7 +403,7 @@ TEST(GattCacheTest, stored_attributes_serialized_to_binary_test) { }, }; - LOG(ERROR) << " " << base::HexEncode(&attr, StoredAttribute::kSizeOnDisk); + log::error("{}", base::HexEncode(&attr, StoredAttribute::kSizeOnDisk)); */ memcpy( attr_bytes, @@ -431,7 +433,7 @@ TEST(GattCacheTest, stored_attributes_serialized_to_binary_test) { .uuid = Uuid::FromString("3456"), }, }; - LOG(ERROR) << " " << base::HexEncode(&attr, StoredAttribute::kSizeOnDisk); + log::error("{}", base::HexEncode(&attr, StoredAttribute::kSizeOnDisk)); */ memcpy( @@ -459,7 +461,7 @@ TEST(GattCacheTest, stored_attributes_serialized_to_binary_test) { .value_handle = 0x302, .uuid = Uuid::FromString("3456")}, }; - LOG(ERROR) << " " << base::HexEncode(&attr, StoredAttribute::kSizeOnDisk); + log::error("{}", base::HexEncode(&attr, StoredAttribute::kSizeOnDisk)); */ memcpy( attr_bytes, @@ -485,7 +487,7 @@ TEST(GattCacheTest, stored_attributes_serialized_to_binary_test) { .type = Uuid::FromString("4444"), .value.characteristic = {}, }; - LOG(ERROR) << " " << base::HexEncode(&attr, StoredAttribute::kSizeOnDisk); + log::error("{}", base::HexEncode(&attr, StoredAttribute::kSizeOnDisk)); */ memcpy( attr_bytes, diff --git a/system/bta/vc/device.cc b/system/bta/vc/device.cc index 38611f9ec757325ccf52295ece3c44d3dff1596f..b9d47b91e313a8a2d04482c078b5bd6eab1ff3f5 100644 --- a/system/bta/vc/device.cc +++ b/system/bta/vc/device.cc @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -24,6 +25,7 @@ #include "bta_gatt_queue.h" #include "devices.h" #include "gatt_api.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "os/logging/log_adapter.h" #include "stack/btm/btm_sec.h" @@ -49,7 +51,7 @@ void VolumeControlDevice::DeregisterNotifications(tGATT_IF gatt_if) { } void VolumeControlDevice::Disconnect(tGATT_IF gatt_if) { - LOG(INFO) << __func__ << ": " << ADDRESS_TO_LOGGABLE_STR(address); + log::info("{}", ADDRESS_TO_LOGGABLE_STR(address)); if (IsConnected()) { DeregisterNotifications(gatt_if); @@ -70,7 +72,7 @@ uint16_t VolumeControlDevice::find_ccc_handle(uint16_t chrc_handle) { const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(connection_id, chrc_handle); if (!p_char) { - LOG(WARNING) << __func__ << ": no such handle=" << loghex(chrc_handle); + log::warn("no such handle={}", loghex(chrc_handle)); return 0; } @@ -97,7 +99,7 @@ bool VolumeControlDevice::set_volume_control_service_handles( flags_handle = chrc.value_handle; flags_ccc_handle = find_ccc_handle(chrc.value_handle); } else { - LOG(WARNING) << __func__ << ": unknown characteristic=" << chrc.uuid; + log::warn("unknown characteristic={}", chrc.uuid); } } @@ -143,7 +145,7 @@ void VolumeControlDevice::set_volume_offset_control_service_handles( chrc.properties & GATT_CHAR_PROP_BIT_WRITE_NR; } else { - LOG(WARNING) << __func__ << ": unknown characteristic=" << chrc.uuid; + log::warn("unknown characteristic={}", chrc.uuid); } } @@ -156,9 +158,9 @@ void VolumeControlDevice::set_volume_offset_control_service_handles( GATT_HANDLE_IS_VALID(offset.audio_descr_handle) /* audio_descr_ccc_handle is optional */) { audio_offsets.Add(offset); - LOG(INFO) << "Offset added id=" << loghex(offset.id); + log::info("Offset added id={}", loghex(offset.id)); } else { - LOG(WARNING) << "Ignoring offset handle=" << loghex(service.handle); + log::warn("Ignoring offset handle={}", loghex(service.handle)); } } @@ -169,13 +171,13 @@ bool VolumeControlDevice::UpdateHandles(void) { const std::list* services = BTA_GATTC_GetServices(connection_id); if (services == nullptr) { - LOG(ERROR) << "No services found"; + log::error("No services found"); return false; } for (auto const& service : *services) { if (service.uuid == kVolumeControlUuid) { - LOG(INFO) << "Found VCS, handle=" << loghex(service.handle); + log::info("Found VCS, handle={}", loghex(service.handle)); vcs_found = set_volume_control_service_handles(service); if (!vcs_found) break; @@ -186,11 +188,11 @@ bool VolumeControlDevice::UpdateHandles(void) { if (service == nullptr) continue; if (included.uuid == kVolumeOffsetUuid) { - LOG(INFO) << "Found VOCS, handle=" << loghex(service->handle); + log::info("Found VOCS, handle={}", loghex(service->handle)); set_volume_offset_control_service_handles(*service); } else { - LOG(WARNING) << __func__ << ": unknown service=" << service->uuid; + log::warn("unknown service={}", service->uuid); } } } @@ -234,7 +236,7 @@ bool VolumeControlDevice::subscribe_for_notifications(tGATT_IF gatt_if, tGATT_STATUS status = BTA_GATTC_RegisterForNotifications(gatt_if, address, handle); if (status != GATT_SUCCESS) { - LOG(ERROR) << __func__ << ": failed, status=" << loghex(+status); + log::error("failed, status={}", loghex(+status)); return false; } @@ -325,7 +327,7 @@ void VolumeControlDevice::GetExtAudioOutVolumeOffset(uint8_t ext_output_id, void* cb_data) { VolumeOffset* offset = audio_offsets.FindById(ext_output_id); if (!offset) { - LOG(ERROR) << __func__ << ": no such offset!"; + log::error("no such offset!"); return; } @@ -338,7 +340,7 @@ void VolumeControlDevice::GetExtAudioOutLocation(uint8_t ext_output_id, void* cb_data) { VolumeOffset* offset = audio_offsets.FindById(ext_output_id); if (!offset) { - LOG(ERROR) << __func__ << ": no such offset!"; + log::error("no such offset!"); return; } @@ -350,12 +352,12 @@ void VolumeControlDevice::SetExtAudioOutLocation(uint8_t ext_output_id, uint32_t location) { VolumeOffset* offset = audio_offsets.FindById(ext_output_id); if (!offset) { - LOG(ERROR) << __func__ << ": no such offset!"; + log::error("no such offset!"); return; } if (!offset->audio_location_writable) { - LOG(WARNING) << __func__ << ": not writable"; + log::warn("not writable"); return; } @@ -372,7 +374,7 @@ void VolumeControlDevice::GetExtAudioOutDescription(uint8_t ext_output_id, void* cb_data) { VolumeOffset* offset = audio_offsets.FindById(ext_output_id); if (!offset) { - LOG(ERROR) << __func__ << ": no such offset!"; + log::error("no such offset!"); return; } @@ -384,12 +386,12 @@ void VolumeControlDevice::SetExtAudioOutDescription(uint8_t ext_output_id, std::string& descr) { VolumeOffset* offset = audio_offsets.FindById(ext_output_id); if (!offset) { - LOG(ERROR) << __func__ << ": no such offset!"; + log::error("no such offset!"); return; } if (!offset->audio_descr_writable) { - LOG(WARNING) << __func__ << ": not writable"; + log::warn("not writable"); return; } @@ -403,7 +405,7 @@ void VolumeControlDevice::ExtAudioOutControlPointOperation( GATT_WRITE_OP_CB cb, void* cb_data) { VolumeOffset* offset = audio_offsets.FindById(ext_output_id); if (!offset) { - LOG(ERROR) << __func__ << ": no such offset!"; + log::error("no such offset!"); return; } @@ -422,7 +424,7 @@ bool VolumeControlDevice::IsEncryptionEnabled() { bool VolumeControlDevice::EnableEncryption() { int result = BTM_SetEncryption(address, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT); - LOG_INFO("%s: result=0x%02x", ADDRESS_TO_LOGGABLE_CSTR(address), result); + log::info("{}: result=0x{:02x}", ADDRESS_TO_LOGGABLE_CSTR(address), result); return result != BTM_ERR_KEY_MISSING; } diff --git a/system/bta/vc/devices.h b/system/bta/vc/devices.h index 7fe871b14ac86bf7037c082fdc68d17e9f4dc5c8..75ef13d8ec5a415b6f244845e51769922cc9aa08 100644 --- a/system/bta/vc/devices.h +++ b/system/bta/vc/devices.h @@ -25,7 +25,7 @@ #include "bta/include/bta_gatt_api.h" #include "bta/vc/types.h" #include "common/interfaces/ILoggable.h" -#include "include/hardware/bt_vc.h" +#include "os/logging/log_adapter.h" #include "types/raw_address.h" namespace bluetooth { diff --git a/system/bta/vc/vc.cc b/system/bta/vc/vc.cc index 5a112b1981d716a35dafea5cdf0fc9168c6b7071..ddbaabcdaa7764475a2c1e52f3f471799571d604 100644 --- a/system/bta/vc/vc.cc +++ b/system/bta/vc/vc.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,16 +27,15 @@ #include #include -#include "bind_helpers.h" #include "bta/le_audio/le_audio_types.h" #include "bta_csis_api.h" #include "bta_gatt_api.h" #include "bta_gatt_queue.h" #include "bta_vc_api.h" -#include "btif_storage.h" #include "devices.h" -#include "gd/common/strings.h" -#include "osi/include/log.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" +#include "os/log.h" #include "osi/include/osi.h" #include "stack/btm/btm_sec.h" #include "stack/include/bt_types.h" @@ -47,6 +47,7 @@ using bluetooth::Uuid; using bluetooth::csis::CsisClient; using bluetooth::vc::ConnectionState; using namespace bluetooth::vc::internal; +using namespace bluetooth; namespace { class VolumeControlImpl; @@ -91,8 +92,9 @@ class VolumeControlImpl : public VolumeControl { base::Bind( [](const base::Closure& initCb, uint8_t client_id, uint8_t status) { if (status != GATT_SUCCESS) { - LOG(ERROR) << "Can't start Volume Control profile - no gatt " - "clients left!"; + log::error( + "Can't start Volume Control profile - no gatt clients " + "left!"); return; } instance->gatt_if_ = client_id; @@ -106,12 +108,12 @@ class VolumeControlImpl : public VolumeControl { /* Oportunistic works only for direct connect, * but in fact this is background connect */ - LOG_INFO(": %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info(": {}", ADDRESS_TO_LOGGABLE_CSTR(address)); BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, true); } void Connect(const RawAddress& address) override { - LOG_INFO(": %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info(": {}", ADDRESS_TO_LOGGABLE_CSTR(address)); auto device = volume_control_devices_.FindByAddress(address); if (!device) { @@ -120,9 +122,8 @@ class VolumeControlImpl : public VolumeControl { device->connecting_actively = true; if (device->IsConnected()) { - LOG(WARNING) << __func__ << ": address=" << address - << ", connection_id=" << device->connection_id - << " already connected."; + log::warn("address={}, connection_id={} already connected.", + ADDRESS_TO_LOGGABLE_STR(address), device->connection_id); if (device->IsReady()) { callbacks_->OnConnectionState(ConnectionState::CONNECTED, @@ -139,7 +140,7 @@ class VolumeControlImpl : public VolumeControl { } void AddFromStorage(const RawAddress& address) { - LOG_INFO("%s ", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); volume_control_devices_.Add(address, false); StartOpportunisticConnect(address); } @@ -147,14 +148,13 @@ class VolumeControlImpl : public VolumeControl { void OnGattConnected(tGATT_STATUS status, uint16_t connection_id, tGATT_IF /*client_if*/, RawAddress address, tBT_TRANSPORT transport, uint16_t /*mtu*/) { - LOG_INFO("%s, conn_id=0x%04x, transport=%s, status=%s(0x%02x)", - ADDRESS_TO_LOGGABLE_CSTR(address), connection_id, - bt_transport_text(transport).c_str(), - gatt_status_text(status).c_str(), status); + log::info("{}, conn_id=0x{:04x}, transport={}, status={}(0x{:02x})", + ADDRESS_TO_LOGGABLE_CSTR(address), connection_id, + bt_transport_text(transport), gatt_status_text(status), status); if (transport != BT_TRANSPORT_LE) { - LOG_WARN("Only LE connection is allowed (transport %s)", - bt_transport_text(transport).c_str()); + log::warn("Only LE connection is allowed (transport {})", + bt_transport_text(transport)); BTA_GATTC_Close(connection_id); return; } @@ -162,13 +162,13 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << "Skipping unknown device, address=" - << ADDRESS_TO_LOGGABLE_STR(address); + log::error("Skipping unknown device, address={}", + ADDRESS_TO_LOGGABLE_STR(address)); return; } if (status != GATT_SUCCESS) { - LOG(INFO) << "Failed to connect to Volume Control device"; + log::info("Failed to connect to Volume Control device"); device_cleanup_helper(device, device->connecting_actively); return; } @@ -186,8 +186,8 @@ class VolumeControlImpl : public VolumeControl { } if (!device->EnableEncryption()) { - LOG_ERROR("Link key is not known for %s, disconnect profile", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("Link key is not known for {}, disconnect profile", + ADDRESS_TO_LOGGABLE_CSTR(address)); device->Disconnect(gatt_if_); } } @@ -196,14 +196,13 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << "Skipping unknown device " - << ADDRESS_TO_LOGGABLE_STR(address); + log::error("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_STR(address)); return; } if (success != BTM_SUCCESS) { - LOG(ERROR) << "encryption failed " - << "status: " << int{success}; + log::error("encryption failed status: {}", int{success}); // If the encryption failed, do not remove the device. // Disconnect only, since the Android will try to re-enable encryption // after disconnection @@ -211,8 +210,7 @@ class VolumeControlImpl : public VolumeControl { return; } - LOG(INFO) << __func__ << " " << ADDRESS_TO_LOGGABLE_STR(address) - << " status: " << +success; + log::info("{} status: {}", ADDRESS_TO_LOGGABLE_STR(address), success); if (device->HasHandles()) { device->EnqueueInitialRequests(gatt_if_, chrc_read_callback_static, @@ -226,13 +224,13 @@ class VolumeControlImpl : public VolumeControl { void ClearDeviceInformationAndStartSearch(VolumeControlDevice* device) { if (!device) { - LOG_ERROR("Device is null"); + log::error("Device is null"); return; } - LOG_INFO(": address=%s", ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("address={}", ADDRESS_TO_LOGGABLE_CSTR(device->address)); if (device->known_service_handles_ == false) { - LOG_INFO("Device already is waiting for new services"); + log::info("Device already is waiting for new services"); return; } @@ -249,8 +247,8 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << "Skipping unknown device " - << ADDRESS_TO_LOGGABLE_STR(address); + log::error("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_STR(address)); return; } @@ -261,8 +259,8 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << "Skipping unknown device " - << ADDRESS_TO_LOGGABLE_STR(address); + log::error("Skipping unknown device {}", + ADDRESS_TO_LOGGABLE_STR(address)); return; } @@ -276,8 +274,8 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByConnId(connection_id); if (!device) { - LOG(ERROR) << __func__ << "Skipping unknown device, connection_id=" - << loghex(connection_id); + log::error("Skipping unknown device, connection_id={}", + loghex(connection_id)); return; } @@ -286,19 +284,19 @@ class VolumeControlImpl : public VolumeControl { if (status != GATT_SUCCESS) { /* close connection and report service discovery complete with error */ - LOG(ERROR) << "Service discovery failed"; + log::error("Service discovery failed"); device_cleanup_helper(device, device->connecting_actively); return; } if (!device->IsEncryptionEnabled()) { - LOG_WARN("Device not yet bonded - waiting for encryption"); + log::warn("Device not yet bonded - waiting for encryption"); return; } bool success = device->UpdateHandles(); if (!success) { - LOG(ERROR) << "Incomplete service database"; + log::error("Incomplete service database"); device_cleanup_helper(device, device->connecting_actively); return; } @@ -313,15 +311,15 @@ class VolumeControlImpl : public VolumeControl { bool is_notification) { VolumeControlDevice* device = volume_control_devices_.FindByConnId(conn_id); if (!device) { - LOG(INFO) << __func__ << ": unknown conn_id=" << loghex(conn_id); + log::info("unknown conn_id={}", loghex(conn_id)); return; } if (status != GATT_SUCCESS) { - LOG_INFO(": status=0x%02x", static_cast(status)); + log::info("status=0x{:02x}", static_cast(status)); if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); ClearDeviceInformationAndStartSearch(device); } return; @@ -351,7 +349,7 @@ class VolumeControlImpl : public VolumeControl { } else if (handle == offset->audio_descr_handle) { OnOffsetOutputDescChanged(device, offset, len, value); } else { - LOG(ERROR) << __func__ << ": unknown offset handle=" << loghex(handle); + log::error("unknown offset handle={}", loghex(handle)); return; } @@ -359,12 +357,12 @@ class VolumeControlImpl : public VolumeControl { return; } - LOG(ERROR) << __func__ << ": unknown handle=" << loghex(handle); + log::error("unknown handle={}", loghex(handle)); } void OnNotificationEvent(uint16_t conn_id, uint16_t handle, uint16_t len, uint8_t* value) { - LOG(INFO) << __func__ << ": handle=" << loghex(handle); + log::info("handle={}", loghex(handle)); OnCharacteristicValueChanged(conn_id, GATT_SUCCESS, handle, len, value, nullptr, true); } @@ -381,8 +379,7 @@ class VolumeControlImpl : public VolumeControl { << " is mute change: " << is_mute_change; if (!is_volume_change && !is_mute_change) { - LOG(ERROR) << __func__ - << "Autonomous change but volume and mute did not changed."; + log::error("Autonomous change but volume and mute did not changed."); return; } @@ -415,7 +412,7 @@ class VolumeControlImpl : public VolumeControl { } if (devices.empty() && (is_volume_change || is_mute_change)) { - LOG_INFO("No more devices in the group right now"); + log::info("No more devices in the group right now"); callbacks_->OnGroupVolumeStateChanged(group_id, device->volume, device->mute, true); return; @@ -441,7 +438,7 @@ class VolumeControlImpl : public VolumeControl { uint16_t len, uint8_t* value, bool is_notification) { if (len != 3) { - LOG(INFO) << __func__ << ": malformed len=" << loghex(len); + log::info("malformed len={}", loghex(len)); return; } @@ -458,13 +455,12 @@ class VolumeControlImpl : public VolumeControl { bool is_mute_change = (device->mute != mute); device->mute = mute; - LOG(INFO) << __func__ << " volume " << loghex(device->volume) << " mute " - << loghex(device->mute) << " change_counter " - << loghex(device->change_counter); + log::info("volume {} mute {} change_counter {}", loghex(device->volume), + loghex(device->mute), loghex(device->change_counter)); if (!device->IsReady()) { - LOG_INFO("Device: %s is not ready yet.", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("Device: {} is not ready yet.", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); return; } @@ -520,14 +516,14 @@ class VolumeControlImpl : public VolumeControl { uint8_t* value) { device->flags = *value; - LOG(INFO) << __func__ << " flags " << loghex(device->flags); + log::info("flags {}", loghex(device->flags)); } void OnExtAudioOutStateChanged(VolumeControlDevice* device, VolumeOffset* offset, uint16_t len, uint8_t* value) { if (len != 3) { - LOG(INFO) << __func__ << ": malformed len=" << loghex(len); + log::info("malformed len={}", loghex(len)); return; } @@ -535,14 +531,13 @@ class VolumeControlImpl : public VolumeControl { STREAM_TO_UINT16(offset->offset, pp); STREAM_TO_UINT8(offset->change_counter, pp); - LOG(INFO) << __func__ << " " << base::HexEncode(value, len); - LOG(INFO) << __func__ << " id: " << loghex(offset->id) - << " offset: " << loghex(offset->offset) - << " counter: " << loghex(offset->change_counter); + log::info("{}", base::HexEncode(value, len)); + log::info("id: {} offset: {} counter: {}", loghex(offset->id), + loghex(offset->offset), loghex(offset->change_counter)); if (!device->IsReady()) { - LOG_INFO("Device: %s is not ready yet.", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("Device: {} is not ready yet.", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); return; } @@ -554,20 +549,19 @@ class VolumeControlImpl : public VolumeControl { VolumeOffset* offset, uint16_t len, uint8_t* value) { if (len != 4) { - LOG(INFO) << __func__ << ": malformed len=" << loghex(len); + log::info("malformed len={}", loghex(len)); return; } uint8_t* pp = value; STREAM_TO_UINT32(offset->location, pp); - LOG(INFO) << __func__ << " " << base::HexEncode(value, len); - LOG(INFO) << __func__ << "id " << loghex(offset->id) << "location " - << loghex(offset->location); + log::info("{}", base::HexEncode(value, len)); + log::info("id {}location {}", loghex(offset->id), loghex(offset->location)); if (!device->IsReady()) { - LOG_INFO("Device: %s is not ready yet.", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("Device: {} is not ready yet.", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); return; } @@ -580,14 +574,13 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByConnId(connection_id); if (!device) { - LOG(ERROR) << __func__ - << "Skipping unknown device disconnect, connection_id=" - << loghex(connection_id); + log::error("Skipping unknown device disconnect, connection_id={}", + loghex(connection_id)); return; } - LOG(INFO) << "Offset Control Point write response handle" << loghex(handle) - << " status: " << loghex((int)(status)); + log::info("Offset Control Point write response handle{} status: {}", + loghex(handle), loghex((int)(status))); /* TODO Design callback API to notify about changes */ } @@ -598,11 +591,11 @@ class VolumeControlImpl : public VolumeControl { std::string description = std::string(value, value + len); if (!base::IsStringUTF8(description)) description = ""; - LOG(INFO) << __func__ << " " << description; + log::info("{}", description); if (!device->IsReady()) { - LOG_INFO("Device: %s is not ready yet.", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("Device: {} is not ready yet.", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); return; } @@ -616,27 +609,27 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByConnId(connection_id); if (!device) { - LOG(INFO) << __func__ - << "unknown connection_id=" << loghex(connection_id); + log::info("unknown connection_id={}", loghex(connection_id)); BtaGattQueue::Clean(connection_id); return; } if (status != GATT_SUCCESS) { if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s, conn_id: 0x%04x", - ADDRESS_TO_LOGGABLE_CSTR(device->address), connection_id); + log::info("Database out of sync for {}, conn_id: 0x{:04x}", + ADDRESS_TO_LOGGABLE_CSTR(device->address), connection_id); ClearDeviceInformationAndStartSearch(device); } else { - LOG_ERROR("Failed to register for notification: 0x%04x, status 0x%02x", - handle, status); + log::error( + "Failed to register for notification: 0x{:04x}, status 0x{:02x}", + handle, status); device_cleanup_helper(device, true); } return; } - LOG_INFO("Successfully registered on ccc: 0x%04x, device: %s", handle, - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("Successfully registered on ccc: 0x{:04x}, device: {}", handle, + ADDRESS_TO_LOGGABLE_CSTR(device->address)); verify_device_ready(device, handle); } @@ -645,7 +638,7 @@ class VolumeControlImpl : public VolumeControl { uint16_t handle, uint16_t len, const uint8_t* value, void* data) { if (!instance) { - LOG(ERROR) << __func__ << "No instance=" << handle; + log::error("No instance={}", handle); return; } @@ -658,25 +651,25 @@ class VolumeControlImpl : public VolumeControl { } void Disconnect(const RawAddress& address) override { - LOG_INFO(": %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG_WARN("Device not connected to profile %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Device not connected to profile {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); callbacks_->OnConnectionState(ConnectionState::DISCONNECTED, address); return; } - LOG(INFO) << __func__ << " GAP_EVT_CONN_CLOSED: " - << ADDRESS_TO_LOGGABLE_STR(device->address); + log::info("GAP_EVT_CONN_CLOSED: {}", + ADDRESS_TO_LOGGABLE_STR(device->address)); device->connecting_actively = false; device_cleanup_helper(device, true); } void Remove(const RawAddress& address) override { - LOG_INFO(": %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(address)); /* Removes all registrations for connection. */ BTA_GATTC_CancelOpen(gatt_if_, address, false); @@ -689,17 +682,16 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByConnId(connection_id); if (!device) { - LOG(ERROR) << __func__ - << " Skipping unknown device disconnect, connection_id=" - << loghex(connection_id); + log::error("Skipping unknown device disconnect, connection_id={}", + loghex(connection_id)); return; } if (!device->IsConnected()) { - LOG(ERROR) << __func__ - << " Skipping disconnect of the already disconnected device, " - "connection_id=" - << loghex(connection_id); + log::error( + "Skipping disconnect of the already disconnected device, " + "connection_id={}", + loghex(connection_id)); return; } @@ -719,8 +711,7 @@ class VolumeControlImpl : public VolumeControl { }); if (op == ongoing_operations_.end()) { - LOG(ERROR) << __func__ - << " Could not find operation id: " << operation_id; + log::error("Could not find operation id: {}", operation_id); return; } @@ -771,14 +762,13 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByConnId(connection_id); if (!device) { - LOG(ERROR) << __func__ - << "Skipping unknown device disconnect, connection_id=" - << loghex(connection_id); + log::error("Skipping unknown device disconnect, connection_id={}", + loghex(connection_id)); return; } - LOG(INFO) << "Write response handle: " << loghex(handle) - << " status: " << loghex((int)(status)); + log::info("Write response handle: {} status: {}", loghex(handle), + loghex((int)(status))); if (status == GATT_SUCCESS) return; @@ -786,8 +776,8 @@ class VolumeControlImpl : public VolumeControl { RemoveDeviceFromOperationList(device->address, PTR_TO_INT(data)); if (status == GATT_DATABASE_OUT_OF_SYNC) { - LOG_INFO("Database out of sync for %s", - ADDRESS_TO_LOGGABLE_CSTR(device->address)); + log::info("Database out of sync for {}", + ADDRESS_TO_LOGGABLE_CSTR(device->address)); ClearDeviceInformationAndStartSearch(device); } } @@ -797,18 +787,17 @@ class VolumeControlImpl : public VolumeControl { } void StartQueueOperation(void) { - LOG(INFO) << __func__; + log::info(""); if (ongoing_operations_.empty()) { return; }; auto op = &ongoing_operations_.front(); - LOG(INFO) << __func__ << " operation_id: " << op->operation_id_; + log::info("operation_id: {}", op->operation_id_); if (op->IsStarted()) { - LOG(INFO) << __func__ << " wait until operation " << op->operation_id_ - << " is complete"; + log::info("wait until operation {} is complete", op->operation_id_); return; } @@ -822,15 +811,14 @@ class VolumeControlImpl : public VolumeControl { } void CancelVolumeOperation(int operation_id) { - LOG(INFO) << __func__ << " canceling operation_id: " << operation_id; + log::info("canceling operation_id: {}", operation_id); auto op = find_if( ongoing_operations_.begin(), ongoing_operations_.end(), [operation_id](auto& it) { return it.operation_id_ == operation_id; }); if (op == ongoing_operations_.end()) { - LOG(ERROR) << __func__ - << " Could not find operation_id: " << operation_id; + log::error("Could not find operation_id: {}", operation_id); return; } @@ -843,10 +831,10 @@ class VolumeControlImpl : public VolumeControl { int group_id, bool is_autonomous, uint8_t opcode, std::vector& arguments) { - LOG_DEBUG( - "num of devices: %zu, group_id: %d, is_autonomous: %s opcode: %d, arg " - "size: %zu", - devices.size(), group_id, is_autonomous ? "true" : "false", +opcode, + log::debug( + "num of devices: {}, group_id: {}, is_autonomous: {} opcode: {}, arg " + "size: {}", + devices.size(), group_id, is_autonomous ? "true" : "false", opcode, arguments.size()); if (std::find_if(ongoing_operations_.begin(), ongoing_operations_.end(), @@ -882,9 +870,9 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* dev = volume_control_devices_.FindByAddress( std::get(addr_or_group_id)); if (dev != nullptr) { - LOG_DEBUG("Address: %s: isReady: %s", - ADDRESS_TO_LOGGABLE_CSTR(dev->address), - dev->IsReady() ? "true" : "false"); + log::debug("Address: {}: isReady: {}", + ADDRESS_TO_LOGGABLE_CSTR(dev->address), + dev->IsReady() ? "true" : "false"); if (dev->IsReady() && (dev->mute != mute)) { std::vector devices = {dev->address}; PrepareVolumeControlOperation( @@ -894,16 +882,16 @@ class VolumeControlImpl : public VolumeControl { } else { /* Handle group change */ auto group_id = std::get(addr_or_group_id); - LOG_DEBUG("group: %d", group_id); + log::debug("group: {}", group_id); auto csis_api = CsisClient::Get(); if (!csis_api) { - LOG(ERROR) << __func__ << " Csis is not there"; + log::error("Csis is not there"); return; } auto devices = csis_api->GetDeviceList(group_id); if (devices.empty()) { - LOG_ERROR("group id: %d has no devices", group_id); + log::error("group id: {} has no devices", group_id); return; } @@ -928,9 +916,9 @@ class VolumeControlImpl : public VolumeControl { } if (devices.empty()) { - LOG_DEBUG( - "No need to update mute for group id: %d . muteNotChanged: %d, " - "deviceNotReady: %d", + log::debug( + "No need to update mute for group id: {} . muteNotChanged: {}, " + "deviceNotReady: {}", group_id, muteNotChanged, deviceNotReady); return; } @@ -959,14 +947,14 @@ class VolumeControlImpl : public VolumeControl { uint8_t opcode = kControlPointOpcodeSetAbsoluteVolume; if (std::holds_alternative(addr_or_group_id)) { - LOG_DEBUG("Address: %s: ", ADDRESS_TO_LOGGABLE_CSTR( + log::debug("Address: {}:", ADDRESS_TO_LOGGABLE_CSTR( std::get(addr_or_group_id))); VolumeControlDevice* dev = volume_control_devices_.FindByAddress( std::get(addr_or_group_id)); if (dev != nullptr) { - LOG_DEBUG("Address: %s: isReady: %s", - ADDRESS_TO_LOGGABLE_CSTR(dev->address), - dev->IsReady() ? "true" : "false"); + log::debug("Address: {}: isReady: {}", + ADDRESS_TO_LOGGABLE_CSTR(dev->address), + dev->IsReady() ? "true" : "false"); if (dev->IsReady() && (dev->volume != volume)) { std::vector devices = {dev->address}; RemovePendingVolumeControlOperations( @@ -981,13 +969,13 @@ class VolumeControlImpl : public VolumeControl { DLOG(INFO) << __func__ << " group: " << group_id; auto csis_api = CsisClient::Get(); if (!csis_api) { - LOG(ERROR) << __func__ << " Csis is not there"; + log::error("Csis is not there"); return; } auto devices = csis_api->GetDeviceList(group_id); if (devices.empty()) { - LOG_ERROR("group id: %d has no devices", group_id); + log::error("group id: {} has no devices", group_id); return; } @@ -1013,9 +1001,9 @@ class VolumeControlImpl : public VolumeControl { } if (devices.empty()) { - LOG_DEBUG( - "No need to update volume for group id: %d . volumeNotChanged: %d, " - "deviceNotReady: %d", + log::debug( + "No need to update volume for group id: {} . volumeNotChanged: {}, " + "deviceNotReady: {}", group_id, volumeNotChanged, deviceNotReady); return; } @@ -1033,7 +1021,7 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << ", no such device!"; + log::error("no such device!"); return; } @@ -1056,7 +1044,7 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << ", no such device!"; + log::error("no such device!"); return; } @@ -1069,7 +1057,7 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << ", no such device!"; + log::error("no such device!"); return; } @@ -1081,7 +1069,7 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << ", no such device!"; + log::error("no such device!"); return; } @@ -1095,7 +1083,7 @@ class VolumeControlImpl : public VolumeControl { VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << ", no such device!"; + log::error("no such device!"); return; } @@ -1103,7 +1091,7 @@ class VolumeControlImpl : public VolumeControl { } void CleanUp() { - LOG(INFO) << __func__; + log::info(""); volume_control_devices_.Disconnect(gatt_if_); volume_control_devices_.Clear(); ongoing_operations_.clear(); @@ -1125,7 +1113,7 @@ class VolumeControlImpl : public VolumeControl { // VerifyReady sets the device_ready flag if all remaining GATT operations // are completed if (device->VerifyReady(handle)) { - LOG(INFO) << __func__ << " Outstanding reads completed."; + log::info("Outstanding reads completed."); callbacks_->OnDeviceAvailable(device->address, device->audio_offsets.Size()); @@ -1171,12 +1159,12 @@ class VolumeControlImpl : public VolumeControl { void ext_audio_out_control_point_helper(const RawAddress& address, uint8_t ext_output_id, uint8_t opcode, const std::vector* arg) { - LOG(INFO) << __func__ << ": " << ADDRESS_TO_LOGGABLE_STR(address) - << " id=" << loghex(ext_output_id) << " op=" << loghex(opcode); + log::info("{} id={} op={}", ADDRESS_TO_LOGGABLE_STR(address), + loghex(ext_output_id), loghex(opcode)); VolumeControlDevice* device = volume_control_devices_.FindByAddress(address); if (!device) { - LOG(ERROR) << __func__ << ", no such device!"; + log::error("no such device!"); return; } device->ExtAudioOutControlPointOperation( @@ -1190,7 +1178,7 @@ class VolumeControlImpl : public VolumeControl { } void gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { - LOG(INFO) << __func__ << " event = " << static_cast(event); + log::info("event = {}", static_cast(event)); if (p_data == nullptr) return; @@ -1215,8 +1203,8 @@ class VolumeControlImpl : public VolumeControl { case BTA_GATTC_NOTIF_EVT: { tBTA_GATTC_NOTIFY& n = p_data->notify; if (!n.is_notify || n.len > GATT_MAX_ATTR_LEN) { - LOG(ERROR) << __func__ << ": rejected BTA_GATTC_NOTIF_EVT. is_notify=" - << n.is_notify << ", len=" << static_cast(n.len); + log::error("rejected BTA_GATTC_NOTIF_EVT. is_notify={}, len={}", + n.is_notify, static_cast(n.len)); break; } OnNotificationEvent(n.conn_id, n.handle, n.len, n.value); @@ -1263,7 +1251,7 @@ void VolumeControl::Initialize(bluetooth::vc::VolumeControlCallbacks* callbacks, const base::Closure& initCb) { std::scoped_lock lock(instance_mutex); if (instance) { - LOG(ERROR) << "Already initialized!"; + log::error("Already initialized!"); return; } @@ -1279,7 +1267,7 @@ VolumeControl* VolumeControl::Get(void) { void VolumeControl::AddFromStorage(const RawAddress& address) { if (!instance) { - LOG(ERROR) << "Not initialized yet"; + log::error("Not initialized yet"); return; } @@ -1289,7 +1277,7 @@ void VolumeControl::AddFromStorage(const RawAddress& address) { void VolumeControl::CleanUp() { std::scoped_lock lock(instance_mutex); if (!instance) { - LOG(ERROR) << "Not initialized!"; + log::error("Not initialized!"); return; } diff --git a/system/btcore/Android.bp b/system/btcore/Android.bp index 02e25de69e9643b98d17422630f51c538a2502a8..41ff38329d99154fcb9df6ad077cacfec85d9648 100644 --- a/system/btcore/Android.bp +++ b/system/btcore/Android.bp @@ -55,7 +55,10 @@ cc_library_static { cflags: ["-D_GNU_SOURCE"], }, }, - static_libs: ["libbt_shim_bridge"], + static_libs: [ + "libbluetooth_log", + "libbt_shim_bridge", + ], } cc_library_static { @@ -66,7 +69,10 @@ cc_library_static { ], defaults: ["libbtcore_defaults"], min_sdk_version: "Tiramisu", - static_libs: ["libbt_shim_bridge"], + static_libs: [ + "libbluetooth_log", + "libbt_shim_bridge", + ], } cc_library_headers { @@ -102,6 +108,7 @@ cc_test { ], static_libs: [ "libbluetooth-types", + "libbluetooth_log", "libbtcore", "libchrome", "libosi", diff --git a/system/btcore/BUILD.gn b/system/btcore/BUILD.gn index 56485846032061e512f7a02a25b519e10da5f43c..f7b86f2023cf1c55bdac1151d977c6eb20f3abe7 100644 --- a/system/btcore/BUILD.gn +++ b/system/btcore/BUILD.gn @@ -28,7 +28,10 @@ static_library("btcore") { "//bt/system", ] - configs += [ "//bt/system:target_defaults" ] + configs += [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd/rust/shim:init_flags_bridge_header", @@ -57,6 +60,7 @@ if (use.test) { configs += [ "//bt/system:external_gtest_main", "//bt/system:target_defaults", + "//bt/system/log:log_defaults", ] libs = [ diff --git a/system/btcore/fuzzer/Android.bp b/system/btcore/fuzzer/Android.bp index 34305eeb23406c2e11508c25b41a90621d736a93..746fdb9244f41f29b00da53fd28ae2daf6bb8727 100644 --- a/system/btcore/fuzzer/Android.bp +++ b/system/btcore/fuzzer/Android.bp @@ -26,9 +26,6 @@ package { cc_defaults { name: "btcore_fuzz_defaults", shared_libs: [ - "android.hardware.bluetooth.audio-V2-ndk", - "android.hardware.bluetooth@1.0", - "android.hardware.bluetooth@1.1", "libcrypto", "libstatslog_bt", ], @@ -37,6 +34,7 @@ cc_defaults { "libbluetooth-protos", "libbluetooth-types", "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbluetooth_rust_interop", "libbt-common", "libbt_shim_bridge", @@ -48,7 +46,6 @@ cc_defaults { "libmodpb64", "libosi", "libprotobuf-cpp-lite", - "libvndksupport", ], include_dirs: [ "packages/modules/Bluetooth/system", diff --git a/system/btcore/include/module.h b/system/btcore/include/module.h index a6f5fd2724d8898618904461312aebb6636d9faf..6ea11c163b1100d260af05a7ff749b57075b7ba7 100644 --- a/system/btcore/include/module.h +++ b/system/btcore/include/module.h @@ -20,9 +20,7 @@ #include -#include "common/message_loop_thread.h" #include "osi/include/future.h" -#include "osi/include/thread.h" typedef future_t* (*module_lifecycle_fn)(void); diff --git a/system/btcore/src/module.cc b/system/btcore/src/module.cc index 5c73fa5297c12d0705b00f314484b0d34183205e..b04434b3aa48c7e5cb328d653f4da8ad990fb8dd 100644 --- a/system/btcore/src/module.cc +++ b/system/btcore/src/module.cc @@ -21,6 +21,7 @@ #include "btcore/include/module.h" #include +#include #include #include @@ -28,9 +29,11 @@ #include #include "common/message_loop_thread.h" +#include "include/check.h" #include "os/log.h" using bluetooth::common::MessageLoopThread; +using namespace bluetooth; typedef enum { MODULE_STATE_NONE = 0, @@ -62,7 +65,7 @@ bool module_init(const module_t* module) { CHECK(get_module_state(module) == MODULE_STATE_NONE); if (!call_lifecycle_function(module->init)) { - LOG_ERROR("%s Failed to initialize module \"%s\"", __func__, module->name); + log::error("Failed to initialize module \"{}\"", module->name); return false; } @@ -80,12 +83,12 @@ bool module_start_up(const module_t* module) { CHECK(get_module_state(module) == MODULE_STATE_INITIALIZED || module->init == NULL); - LOG_INFO("%s Starting module \"%s\"", __func__, module->name); + log::info("Starting module \"{}\"", module->name); if (!call_lifecycle_function(module->start_up)) { - LOG_ERROR("%s Failed to start up module \"%s\"", __func__, module->name); + log::error("Failed to start up module \"{}\"", module->name); return false; } - LOG_INFO("%s Started module \"%s\"", __func__, module->name); + log::info("Started module \"{}\"", module->name); set_module_state(module, MODULE_STATE_STARTED); return true; @@ -99,12 +102,12 @@ void module_shut_down(const module_t* module) { // Only something to do if the module was actually started if (state < MODULE_STATE_STARTED) return; - LOG_INFO("%s Shutting down module \"%s\"", __func__, module->name); + log::info("Shutting down module \"{}\"", module->name); if (!call_lifecycle_function(module->shut_down)) { - LOG_ERROR("%s Failed to shutdown module \"%s\". Continuing anyway.", - __func__, module->name); + log::error("Failed to shutdown module \"{}\". Continuing anyway.", + module->name); } - LOG_INFO("%s Shutdown of module \"%s\" completed", __func__, module->name); + log::info("Shutdown of module \"{}\" completed", module->name); set_module_state(module, MODULE_STATE_INITIALIZED); } @@ -117,12 +120,12 @@ void module_clean_up(const module_t* module) { // Only something to do if the module was actually initialized if (state < MODULE_STATE_INITIALIZED) return; - LOG_INFO("%s Cleaning up module \"%s\"", __func__, module->name); + log::info("Cleaning up module \"{}\"", module->name); if (!call_lifecycle_function(module->clean_up)) { - LOG_ERROR("%s Failed to cleanup module \"%s\". Continuing anyway.", - __func__, module->name); + log::error("Failed to cleanup module \"{}\". Continuing anyway.", + module->name); } - LOG_INFO("%s Cleanup of module \"%s\" completed", __func__, module->name); + log::info("Cleanup of module \"{}\" completed", module->name); set_module_state(module, MODULE_STATE_NONE); } diff --git a/system/btcore/src/osi_module.cc b/system/btcore/src/osi_module.cc index 9481c87bab0805111dc7edd1a7ec4c26e9a5e8b1..6a9f939f18bdaba06a70fea7e694e9aff9bab391 100644 --- a/system/btcore/src/osi_module.cc +++ b/system/btcore/src/osi_module.cc @@ -19,10 +19,11 @@ #define LOG_TAG "bt_osi_module" #include "btcore/include/osi_module.h" + #include "btcore/include/module.h" +#include "os/log.h" #include "osi/include/alarm.h" #include "osi/include/future.h" -#include "osi/include/log.h" #include "osi/include/osi.h" #include "osi/include/wakelock.h" diff --git a/system/btif/Android.bp b/system/btif/Android.bp index 096ba480e65711d471b89f3ee5188bc13603aca8..263ca2048aea125453593b2d641994c6d28761aa 100644 --- a/system/btif/Android.bp +++ b/system/btif/Android.bp @@ -14,7 +14,6 @@ btifCommonIncludes = [ "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/include", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ] @@ -29,22 +28,16 @@ cc_library { "com.android.btservices", ], min_sdk_version: "30", + shared_libs: [ + "libstatssocket", + ], + export_shared_lib_headers: [ + "libstatssocket", + ], target: { - android: { - shared_libs: [ - "libstatssocket", - ], - export_shared_lib_headers: [ - "libstatssocket", - ], - }, host: { static_libs: [ "libbase", - "libstatssocket", - ], - export_static_lib_headers: [ - "libstatssocket", ], }, darwin: { @@ -66,6 +59,7 @@ cc_library_static { ], srcs: ["src/btif_jni_task.cc"], static_libs: [ + "libbluetooth_log", "libbt_shim_bridge", "libosi", ], @@ -105,6 +99,7 @@ cc_library_static { "avrcp/avrcp_service.cc", // Callouts "co/bta_av_co.cc", + "co/bta_av_co_peer.cc", "co/bta_hh_co.cc", "co/bta_pan_co.cc", // HAL layer @@ -154,23 +149,23 @@ cc_library_static { }, static_libs: [ "avrcp-target-service", + "bluetooth_flags_c_lib", "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", "libaudio-a2dp-hw-utils", "libbluetooth-types", + "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-platform-protos-lite", "libbt-stack", "libbt-stack-core", "libbt_shim_bridge", "libbtif-core", - ], - shared_libs: [ - "android.hardware.bluetooth.audio@2.1", + "libflatbuffers-cpp", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], apex_available: [ @@ -202,7 +197,6 @@ cc_library_static { "src/btif_gatt_test.cc", "src/btif_gatt_util.cc", "src/btif_iot_config.cc", - "src/btif_jni_task.cc", "src/btif_keystore.cc", "src/btif_metrics_logging.cc", "src/btif_profile_queue.cc", @@ -243,10 +237,14 @@ cc_library_static { "lib-bt-packets-base", "libaudio-a2dp-hw-utils", "libbluetooth_crypto_toolbox", + "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-audio-hal-interface", + "libbt-jni-thread", "libbt-platform-protos-lite", "libbt-stack-core", "libbt_shim_bridge", + "libflatbuffers-cpp", "libstatslog_bt", ], whole_static_libs: [ @@ -256,7 +254,6 @@ cc_library_static { "libcrypto", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", /* we export all classes, so change default visibility, instead of having EXPORT_SYMBOL on each class*/ "-fvisibility=default", @@ -282,34 +279,43 @@ cc_test { host_supported: true, include_dirs: btifCommonIncludes, srcs: [ + ":OsiCompatSources", + ":TestCommonMockFunctions", + ":TestFakeOsi", "test/btif_dm_test.cc", "test/btif_storage_test.cc", ], header_libs: ["libbluetooth_headers"], shared_libs: [ - "libbinder_ndk", + "libbase", "libcrypto", "libcutils", - "libfmq", "libhidlbase", "liblog", "libutils", "server_configurable_flags", ], static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", "libFraunhoferAAC", "libbase", "libbluetooth-dumpsys", "libbluetooth-for-tests", + "libbluetooth-gdx", "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_crypto_toolbox", + "libbluetooth_log", + "libbt-audio-asrc", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", "libbt-btu-main-thread", "libbt-common", "libbt-hci", + "libbt-jni-thread", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", @@ -322,12 +328,13 @@ cc_test { "libchrome", "libcom.android.sysprop.bluetooth.wrapped", "libevent", + "libflagtest", "libflatbuffers-cpp", + "libfmq", "libg722codec", "libgmock", "liblc3", "libopus", - "libosi", "libprotobuf-cpp-lite", "libstatslog_bt", "libudrv-uipc", @@ -335,8 +342,6 @@ cc_test { target: { android: { shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libPlatformProperties", "libbinder_ndk", "libstatssocket", @@ -347,12 +352,17 @@ cc_test { "android.hardware.bluetooth@1.1", "android.hardware.common-V2-ndk", "android.hardware.common.fmq-V1-ndk", + "android.system.suspend-V1-ndk", "android.system.suspend.control-V1-ndk", "libaaudio", ], }, + host: { + static_libs: [ + "libbinder_ndk", + ], + }, }, - cflags: ["-DBUILDCFG"], sanitize: { integer_overflow: true, }, @@ -378,16 +388,19 @@ cc_test { static_libs: [ "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", "libosi", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], - shared_libs: ["liblog"], + shared_libs: [ + "libbase", + "liblog", + ], } // btif avrcp audio track unit tests @@ -414,16 +427,17 @@ cc_test { ], static_libs: [ "libbluetooth-types", + "libbluetooth_log", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", "libosi", ], shared_libs: [ + "libbase", "liblog", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], } @@ -451,6 +465,7 @@ cc_test { ], header_libs: ["libbluetooth_headers"], shared_libs: [ + "libbase", "libcrypto", "libcutils", "liblog", @@ -459,6 +474,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -472,7 +488,6 @@ cc_test { }, }, cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], sanitize: { @@ -501,6 +516,7 @@ cc_test { ], header_libs: ["libbluetooth_headers"], shared_libs: [ + "libbase", "libbinder_ndk", "libcrypto", "libcutils", @@ -509,13 +525,13 @@ cc_test { static_libs: [ "libbluetooth-types", "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbt_shim_bridge", "libc++fs", "libchrome", "libgmock", "libosi", ], - cflags: ["-DBUILDCFG"], target: { android: { static_libs: [ @@ -542,11 +558,13 @@ cc_test { ], header_libs: ["libbluetooth_headers"], shared_libs: [ + "libbase", "libcutils", "liblog", ], static_libs: [ "libbluetooth-types", + "libbluetooth_log", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", @@ -554,7 +572,6 @@ cc_test { "libcom.android.sysprop.bluetooth.wrapped", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], } @@ -602,11 +619,14 @@ cc_test { ":TestMockBtu", ":TestMockHci", ":TestMockMainShim", + ":TestMockMainShimDumpsys", + ":TestMockMainShimEntry", ":TestMockStack", ":TestMockUdrv", "test/btif_hh_test.cc", ], generated_headers: [ + "BluetoothGeneratedBundlerSchema_h_bfbs", "BluetoothGeneratedDumpsysDataSchema_h", ], header_libs: ["libbluetooth_headers"], @@ -621,7 +641,10 @@ cc_test { "server_configurable_flags", ], static_libs: [ + "android.hardware.audio.common@5.0", "android.hardware.bluetooth.a2dp@1.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", "avrcp-target-service", "bluetooth_flags_c_lib", "lib-bt-packets", @@ -631,8 +654,10 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-common", + "libbt-jni-thread", "libbt-platform-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", @@ -653,7 +678,6 @@ cc_test { "libstatslog_bt", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], target: { @@ -663,8 +687,6 @@ cc_test { "android.hardware.common.fmq-V1-ndk", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libaaudio", "libbinder_ndk", "libstatssocket", @@ -723,11 +745,14 @@ cc_test { ":TestMockBtu", ":TestMockHci", ":TestMockMainShim", + ":TestMockMainShimDumpsys", + ":TestMockMainShimEntry", ":TestMockStack", ":TestMockUdrv", "test/btif_core_test.cc", ], generated_headers: [ + "BluetoothGeneratedBundlerSchema_h_bfbs", "BluetoothGeneratedDumpsysDataSchema_h", ], header_libs: ["libbluetooth_headers"], @@ -742,6 +767,9 @@ cc_test { "server_configurable_flags", ], static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", "avrcp-target-service", "bluetooth_flags_c_lib", "lib-bt-packets", @@ -751,8 +779,10 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-common", + "libbt-jni-thread", "libbt-platform-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", @@ -770,7 +800,6 @@ cc_test { "libstatslog_bt", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], target: { @@ -781,8 +810,6 @@ cc_test { "android.hardware.common.fmq-V1-ndk", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libbinder_ndk", "libstatssocket", ], diff --git a/system/btif/BUILD.gn b/system/btif/BUILD.gn index 466ef9476e9c0c5d086dde3149a880d09737b2d0..fbf05cde34b12d22f5543645bf27695a9d74fcea 100644 --- a/system/btif/BUILD.gn +++ b/system/btif/BUILD.gn @@ -22,9 +22,10 @@ static_library("btif") { # AVRCP Target Service "avrcp/avrcp_service.cc", - "co/bta_av_co.cc", # Callouts + "co/bta_av_co.cc", + "co/bta_av_co_peer.cc", "co/bta_dm_co.cc", "co/bta_gatts_co.cc", "co/bta_hh_co.cc", @@ -106,7 +107,6 @@ static_library("btif") { "//bt/system/stack/btm", "//bt/system/stack/l2cap", "//bt/system/stack/include", - "//bt/system/internal_include", "//bt/system/udrv/include", "//bt/system/vnd/include", "//bt/system/profile/avrcp", @@ -121,6 +121,7 @@ static_library("btif") { configs += [ "//bt/system:target_defaults", + "//bt/system/log:log_defaults", "//bt/system:external_tinyxml2", ] } diff --git a/system/btif/avrcp/avrcp_service.cc b/system/btif/avrcp/avrcp_service.cc index 9ec35a3779b753f587eeaefc4fb30e98ee22662d..aaa200b55d689ac39396a6c6bfbc00b07dceb652 100644 --- a/system/btif/avrcp/avrcp_service.cc +++ b/system/btif/avrcp/avrcp_service.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ #include "btif_av.h" #include "btif_common.h" #include "device.h" +#include "include/check.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_uuid16.h" #include "stack/include/main_thread.h" @@ -373,7 +375,7 @@ class PlayerSettingsInterfaceWrapper : public PlayerSettingsInterface { void AvrcpService::Init(MediaInterface* media_interface, VolumeInterface* volume_interface, PlayerSettingsInterface* player_settings_interface) { - LOG(INFO) << "AVRCP Target Service started"; + log::info("AVRCP Target Service started"); profile_version = avrcp_interface_.GetAvrcpVersion(); @@ -413,7 +415,8 @@ void AvrcpService::Init(MediaInterface* media_interface, player_settings_interface_ = wrapped_player_settings_interface; ConnectionHandler::Initialize( - base::Bind(&AvrcpService::DeviceCallback, base::Unretained(instance_)), + base::BindRepeating(&AvrcpService::DeviceCallback, + base::Unretained(instance_)), &avrcp_interface_, &sdp_interface_, wrapped_volume_interface); connection_handler_ = ConnectionHandler::Get(); } @@ -433,7 +436,7 @@ uint16_t AvrcpService::GetSupportedFeatures(uint16_t profile_version) { } void AvrcpService::Cleanup() { - LOG(INFO) << "AVRCP Target Service stopped"; + log::info("AVRCP Target Service stopped"); avrcp_interface_.RemoveRecord(sdp_record_handle); bta_sys_remove_uuid(UUID_SERVCLASS_AV_REM_CTRL_TARGET); @@ -454,8 +457,8 @@ void AvrcpService::Cleanup() { } void AvrcpService::RegisterBipServer(int psm) { - LOG(INFO) << "AVRCP Target Service has registered a BIP OBEX server, psm=" - << psm; + log::info("AVRCP Target Service has registered a BIP OBEX server, psm={}", + psm); avrcp_interface_.RemoveRecord(sdp_record_handle); uint16_t supported_features = GetSupportedFeatures(profile_version) | AVRC_SUPF_TG_PLAYER_COVER_ART; @@ -467,7 +470,7 @@ void AvrcpService::RegisterBipServer(int psm) { } void AvrcpService::UnregisterBipServer() { - LOG(INFO) << "AVRCP Target Service has unregistered a BIP OBEX server"; + log::info("AVRCP Target Service has unregistered a BIP OBEX server"); avrcp_interface_.RemoveRecord(sdp_record_handle); uint16_t supported_features = GetSupportedFeatures(profile_version); sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); @@ -491,32 +494,27 @@ ServiceInterface* AvrcpService::GetServiceInterface() { } void AvrcpService::ConnectDevice(const RawAddress& bdaddr) { - LOG(INFO) << __PRETTY_FUNCTION__ - << ": address=" << ADDRESS_TO_LOGGABLE_STR(bdaddr); + log::info("address={}", ADDRESS_TO_LOGGABLE_STR(bdaddr)); connection_handler_->ConnectDevice(bdaddr); } void AvrcpService::DisconnectDevice(const RawAddress& bdaddr) { - LOG(INFO) << __PRETTY_FUNCTION__ - << ": address=" << ADDRESS_TO_LOGGABLE_STR(bdaddr); + log::info("address={}", ADDRESS_TO_LOGGABLE_STR(bdaddr)); connection_handler_->DisconnectDevice(bdaddr); } void AvrcpService::SetBipClientStatus(const RawAddress& bdaddr, bool connected) { - LOG(INFO) << __PRETTY_FUNCTION__ - << ": address=" << ADDRESS_TO_LOGGABLE_STR(bdaddr) - << ", connected=" << connected; + log::info("address={}, connected={}", ADDRESS_TO_LOGGABLE_STR(bdaddr), + connected); connection_handler_->SetBipClientStatus(bdaddr, connected); } void AvrcpService::SendMediaUpdate(bool track_changed, bool play_state, bool queue) { - LOG(INFO) << __PRETTY_FUNCTION__ << " track_changed=" << track_changed - << " : " - << " play_state=" << play_state << " : " - << " queue=" << queue; + log::info("track_changed={} : play_state={} : queue={}", track_changed, + play_state, queue); // This function may be called on any thread, we need to make sure that the // device update happens on the main thread. @@ -530,10 +528,8 @@ void AvrcpService::SendMediaUpdate(bool track_changed, bool play_state, void AvrcpService::SendFolderUpdate(bool available_players, bool addressed_players, bool uids) { - LOG(INFO) << __PRETTY_FUNCTION__ << " available_players=" << available_players - << " : " - << " addressed_players=" << addressed_players << " : " - << " uids=" << uids; + log::info("available_players={} : addressed_players={} : uids={}", + available_players, addressed_players, uids); // Ensure that the update is posted to the correct thread for (const auto& device : @@ -552,7 +548,7 @@ void AvrcpService::SendActiveDeviceChanged(const RawAddress& address) { void AvrcpService::SendPlayerSettingsChanged( std::vector attributes, std::vector values) { - LOG(INFO) << __PRETTY_FUNCTION__; + log::info(""); std::stringstream ss; for (size_t i = 0; i < attributes.size(); i++) { ss << "attribute=" << attributes.at(i) << " : "; @@ -566,7 +562,7 @@ void AvrcpService::SendPlayerSettingsChanged( ss << std::endl; } - LOG(INFO) << ss.str(); + log::info("{}", ss.str()); // Ensure that the update is posted to the correct thread for (const auto& device : @@ -692,7 +688,7 @@ void AvrcpService::DebugDump(int fd) { /** when a2dp connected, btif will start register vol changed, so we need a * interface for it. */ void AvrcpService::RegisterVolChanged(const RawAddress& bdaddr) { - LOG(INFO) << ": address=" << ADDRESS_TO_LOGGABLE_STR(bdaddr); + log::info(": address={}", ADDRESS_TO_LOGGABLE_STR(bdaddr)); connection_handler_->RegisterVolChanged(bdaddr); } diff --git a/system/btif/co/bta_av_co.cc b/system/btif/co/bta_av_co.cc index 2a290cc10b048e20c1795b2d703f6553c55dd4d3..a567296a9e9b0cf380e3bda42cf6ee6a2f4c5d6c 100644 --- a/system/btif/co/bta_av_co.cc +++ b/system/btif/co/bta_av_co.cc @@ -23,754 +23,89 @@ * ******************************************************************************/ -#include +#include "btif/include/bta_av_co.h" + +#include #include +#include #include +#include "audio_hal_interface/a2dp_encoding.h" #include "bta/include/bta_av_api.h" #include "bta/include/bta_av_ci.h" +#include "btif/include/bta_av_co_peer.h" #include "btif/include/btif_a2dp_source.h" #include "btif/include/btif_av.h" #include "device/include/device_iot_config.h" +#include "include/check.h" #include "include/hardware/bt_av.h" #include "internal_include/bt_trace.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/a2dp_codec_api.h" #include "stack/include/a2dp_error_codes.h" +#include "stack/include/a2dp_ext.h" #include "stack/include/avdt_api.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "types/raw_address.h" -// Macro to retrieve the number of elements in a statically allocated array -#define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0])) - -// Macro to convert BTA AV audio handle to index and vice versa -#define BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle) \ - (((bta_av_handle) & (~BTA_AV_CHNL_MSK)) - 1) -#define BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(index) \ - (((index) + 1) | BTA_AV_CHNL_AUDIO) - -class BtaAvCoSep { - public: - BtaAvCoSep() - : sep_info_idx(0), seid(0), codec_caps{}, num_protect(0), protect_info{} { - Reset(); - } - - /** - * Reset the state. - */ - void Reset() { - sep_info_idx = 0; - seid = 0; - memset(codec_caps, 0, sizeof(codec_caps)); - num_protect = 0; - memset(protect_info, 0, sizeof(protect_info)); - } - - uint8_t sep_info_idx; // Local SEP index (in BTA tables) - uint8_t seid; // Peer SEP index (in peer tables) - uint8_t codec_caps[AVDT_CODEC_SIZE]; // Peer SEP codec capabilities - uint8_t num_protect; // Peer SEP number of CP elements - uint8_t protect_info[AVDT_CP_INFO_LEN]; // Peer SEP content protection info -}; - -class BtaAvCoPeer { - public: - BtaAvCoPeer() - : addr(RawAddress::kEmpty), - num_sinks(0), - num_sources(0), - num_seps(0), - num_rx_sinks(0), - num_rx_sources(0), - num_sup_sinks(0), - num_sup_sources(0), - p_sink(nullptr), - p_source(nullptr), - codec_config{}, - acceptor(false), - reconfig_needed(false), - opened(false), - mtu(0), - uuid_to_connect(0), - bta_av_handle_(0), - codecs_(nullptr), - content_protect_active_(false) { - Reset(0); - } - - /** - * Initialize the state. - * - * @param codec_priorities the codec priorities to use for the initialization - */ - void Init(const std::vector& codec_priorities); - - /** - * Reset the state. - * - * @param bta_av_handle the BTA AV handle to use - */ - void Reset(tBTA_AV_HNDL bta_av_handle); - - /** - * Get the BTA AV handle. - * - * @return the BTA AV handle - */ - tBTA_AV_HNDL BtaAvHandle() const { return bta_av_handle_; } - - /** - * Get the A2DP codecs. - * - * @return the A2DP codecs - */ - A2dpCodecs* GetCodecs() { return codecs_; } - - bool ContentProtectActive() const { return content_protect_active_; } - void SetContentProtectActive(bool cp_active) { - content_protect_active_ = cp_active; - } - - RawAddress addr; // Peer address - BtaAvCoSep sinks[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sinks - BtaAvCoSep sources[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sources - uint8_t num_sinks; // Total number of sinks at peer - uint8_t num_sources; // Total number of sources at peer - uint8_t num_seps; // Total number of SEPs at peer - uint8_t num_rx_sinks; // Number of received sinks - uint8_t num_rx_sources; // Number of received sources - uint8_t num_sup_sinks; // Number of supported sinks - uint8_t num_sup_sources; // Number of supported sources - const BtaAvCoSep* p_sink; // Currently selected sink - const BtaAvCoSep* p_source; // Currently selected source - uint8_t codec_config[AVDT_CODEC_SIZE]; // Current codec configuration - bool acceptor; // True if acceptor - bool reconfig_needed; // True if reconfiguration is needed - bool opened; // True if opened - uint16_t mtu; // Maximum Transmit Unit size - uint16_t uuid_to_connect; // UUID of peer device - - private: - tBTA_AV_HNDL bta_av_handle_; // BTA AV handle to use - A2dpCodecs* codecs_; // Locally supported codecs - bool content_protect_active_; // True if Content Protect is active -}; - -class BtaAvCo { - public: - BtaAvCo(bool content_protect_enabled) - : active_peer_(nullptr), - codec_config_{}, - content_protect_enabled_(content_protect_enabled), - content_protect_flag_(0) { - Reset(); - } - - /** - * Initialize the state. - * - * @param codec_priorities the codec priorities to use for the initialization - */ - void Init(const std::vector& codec_priorities); - - /** - * Checks whether a codec is supported. - * - * @param codec_index the index of the codec to check - * @return true if the codec is supported, otherwise false - */ - bool IsSupportedCodec(btav_a2dp_codec_index_t codec_index); - - /** - * Get the current codec configuration for the active peer. - * - * @return the current codec configuration if found, otherwise nullptr - */ - A2dpCodecConfig* GetActivePeerCurrentCodec(); - - /** - * Get the current codec configuration for a peer. - * - * @param peer_address the peer address - * @return the current codec configuration if found, otherwise nullptr - */ - A2dpCodecConfig* GetPeerCurrentCodec(const RawAddress& peer_address); - - /** - * Find the peer UUID for a given BTA AV handle. - * - * @param bta_av_handle the BTA AV handle to use - * @return the peer UUID if found, otherwise 0 - */ - uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle); - - /** - * Process the AVDTP discovery result: number of Stream End Points (SEP) - * found during the AVDTP stream discovery process. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param num_seps the number of discovered SEPs - * @param num_sinks number of discovered Sink SEPs - * @param num_sources number of discovered Source SEPs - * @param uuid_local local UUID - */ - void ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address, uint8_t num_seps, - uint8_t num_sinks, uint8_t num_sources, - uint16_t uuid_local); - - /** - * Process retrieved codec configuration and content protection from - * Peer Sink SEP. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param p_codec_info the peer sink capability filled-in by the caller. - * On success, it will contain the current codec configuration for the peer. - * @param p_sep_info_idx the peer SEP index for the corresponding peer - * sink capability filled-in by the caller. On success, it will contain - * the SEP index for the current codec configuration for the peer. - * @param seid the peer SEP index in peer tables - * @param p_num_protect the peer SEP number of content protection elements - * filled-in by the caller. On success, it will contain the SEP number of - * content protection elements for the current codec configuration for the - * peer. - * @param p_protect_info the peer SEP content protection info filled-in by - * the caller. On success, it will contain the SEP content protection info - * for the current codec configuration for the peer. - * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL - */ - tA2DP_STATUS ProcessSourceGetConfig(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address, - uint8_t* p_codec_info, - uint8_t* p_sep_info_idx, uint8_t seid, - uint8_t* p_num_protect, - uint8_t* p_protect_info); - - /** - * Process retrieved codec configuration and content protection from - * Peer Source SEP. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param p_codec_info the peer source capability filled-in by the caller. - * On success, it will contain the current codec configuration for the peer. - * @param p_sep_info_idx the peer SEP index for the corresponding peer - * source capability filled-in by the caller. On success, it will contain - * the SEP index for the current codec configuration for the peer. - * @param seid the peer SEP index in peer tables - * @param p_num_protect the peer SEP number of content protection elements - * filled-in by the caller. On success, it will contain the SEP number of - * content protection elements for the current codec configuration for the - * peer. - * @param p_protect_info the peer SEP content protection info filled-in by - * the caller. On success, it will contain the SEP content protection info - * for the current codec configuration for the peer. - * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL - */ - tA2DP_STATUS ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address, - uint8_t* p_codec_info, - uint8_t* p_sep_info_idx, uint8_t seid, - uint8_t* p_num_protect, - uint8_t* p_protect_info); - - /** - * Process AVDTP Set Config to set the codec and content protection - * configuration of the audio stream. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param p_codec_info the codec configuration to set - * @param seid stream endpoint ID of stream initiating the operation - * @param peer_address the peer address - * @param num_protect the peer SEP number of content protection elements - * @param p_protect_info the peer SEP conntent protection info - * @param t_local_sep the local SEP: AVDT_TSEP_SRC or AVDT_TSEP_SNK - * @param avdt_handle the AVDTP handle - */ - void ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address, - const uint8_t* p_codec_info, uint8_t seid, - uint8_t num_protect, const uint8_t* p_protect_info, - uint8_t t_local_sep, uint8_t avdt_handle); - - /** - * Process AVDTP Open when the stream connection is opened. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param mtu the MTU of the connection - */ - void ProcessOpen(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - uint16_t mtu); - - /** - * Process AVDTP Close when the stream connection is closed. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - */ - void ProcessClose(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); - - /** - * Process AVDTP Start when the audio data streaming is started. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param p_codec_info the codec configuration - * @param p_no_rtp_header on return, set to true if the audio data packets - * should not contain RTP header - */ - void ProcessStart(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - const uint8_t* p_codec_info, bool* p_no_rtp_header); - - /** - * Process AVDTP Stop when the audio data streaming is stopped. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - */ - void ProcessStop(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); - - /** - * Get the next encoded audio data packet to send. - * - * @param p_codec_info the codec configuration - * @param p_timestamp on return, set to the timestamp of the data packet - * @return the next encoded data packet or nullptr if no encoded data to send - */ - BT_HDR* GetNextSourceDataPacket(const uint8_t* p_codec_info, - uint32_t* p_timestamp); - - /** - * An audio packet has been dropped. - * This signal can be used by the encoder to reduce the encoder bit rate - * setting. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - */ - void DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address); - - /** - * Process AVDTP Audio Delay when the initial delay report is received by - * the Source. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param delay the reported delay in 1/10th of a millisecond - */ - void ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address, uint16_t delay); - - /** - * Update the MTU of the audio data connection. - * - * @param bta_av_handle the BTA AV handle to identify the peer - * @param peer_address the peer address - * @param mtu the new MTU of the audio data connection - */ - void UpdateMtu(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - uint16_t mtu); - - /** - * Set the active peer. - * - * @param peer_address the peer address - * @return true on success, otherwise false - */ - bool SetActivePeer(const RawAddress& peer_address); - - /** - * Save the reconfig codec - * - * @param new_codec_config the new codec config - */ - void SaveCodec(const uint8_t* new_codec_config); - - /** - * Get the encoder parameters for a peer. - * - * @param peer_address the peer address - * @param p_peer_params on return, set to the peer's encoder parameters - */ - void GetPeerEncoderParameters(const RawAddress& peer_address, - tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params); - - /** - * Get the Source encoder interface for the current codec. - * - * @return the Source encoder interface for the current codec - */ - const tA2DP_ENCODER_INTERFACE* GetSourceEncoderInterface(); - - /** - * Set the codec user configuration. - * - * @param peer_address the peer address - * @param codec_user_config the codec user configuration to set - * @param p_restart_output if there is a change in the encoder configuration - * that requires restarting of the A2DP connection, flag |p_restart_output| - * will be set to true. - * @return true on success, otherwise false - */ - bool SetCodecUserConfig(const RawAddress& peer_address, - const btav_a2dp_codec_config_t& codec_user_config, - bool* p_restart_output); - - /** - * Set the codec audio configuration. - * - * @param codec_audio_config the codec audio configuration to set - * @return true on success, otherwise false - */ - bool SetCodecAudioConfig(const btav_a2dp_codec_config_t& codec_audio_config); - - /** - * Get the Source encoder maximum frame size for the current codec. - * - * @return the effective frame size for the current codec - */ - int GetSourceEncoderEffectiveFrameSize(); - - /** - * Report the source codec state for a peer - * - * @param p_peer the peer to report - * @return true on success, otherwise false - */ - bool ReportSourceCodecState(BtaAvCoPeer* p_peer); - - /** - * Report the sink codec state for a peer - * - * @param p_peer the peer to report - * @return true on success, otherwise false - */ - bool ReportSinkCodecState(BtaAvCoPeer* p_peer); - - /** - * Get the content protection flag. - * - * @return the content protection flag. It should be one of the following: - * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE - */ - uint8_t ContentProtectFlag() const { return content_protect_flag_; } - - /** - * Set the content protection flag. - * - * @param cp_flag the content protection flag. It should be one of the - * following: - * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE - * NOTE: If Content Protection is not enabled on the system, then - * the only acceptable vailue is AVDT_CP_SCMS_COPY_FREE. - */ - void SetContentProtectFlag(uint8_t cp_flag) { - if (!ContentProtectEnabled() && (cp_flag != AVDT_CP_SCMS_COPY_FREE)) { - return; - } - content_protect_flag_ = cp_flag; - } - - /** - * Dump debug-related information. - * - * @param fd the file descritor to use for writing the ASCII formatted - * information - */ - void DebugDump(int fd); - - /** - * Find the peer entry for a given peer address. - * - * @param peer_address the peer address to use - * @return the peer entry if found, otherwise nullptr - */ - BtaAvCoPeer* FindPeer(const RawAddress& peer_address); - - /** - * Find the peer Sink SEP entry for a given codec index. - * - * @param p_peer the peer to use - * @param codec_index the codec index to use - * @return the peer Sink SEP for the codec index if found, otherwise nullptr - */ - BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer, - btav_a2dp_codec_index_t codec_index); - - /** - * Find the peer Source SEP entry for a given codec index. - * - * @param p_peer the peer to use - * @param codec_config the codec index to use - * @return the peer Source SEP for the codec index if found, otherwise nullptr - */ - BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer, - btav_a2dp_codec_index_t codec_index); - - private: - /** - * Reset the state. - */ - void Reset(); - - /** - * Find the peer entry for a given BTA AV handle. - * - * @param bta_av_handle the BTA AV handle to use - * @return the peer entry if found, otherwise nullptr - */ - BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle); - - /** - * Find the peer entry for a given BTA AV handle and update it with the - * peer address. - * - * @param bta_av_handle the BTA AV handle to use - * @param peer_address the peer address - * @return the peer entry if found, otherwise nullptr - */ - BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address); - - /** - * Select the Source codec configuration based on peer codec support. - * - * Furthermore, the local state for the remaining non-selected codecs is - * updated to reflect whether the codec is selectable. - * - * @param p_peer the peer to use - * @return a pointer to the corresponding SEP Sink entry on success, - * otherwise nullptr - */ - const BtaAvCoSep* SelectSourceCodec(BtaAvCoPeer* p_peer); - - /** - * Select the Sink codec configuration based on peer codec support. - * - * Furthermore, the local state for the remaining non-selected codecs is - * updated to reflect whether the codec is selectable. - * - * @param p_peer the peer to use - * @return a pointer to the corresponding SEP Source entry on success, - * otherwise nullptr - */ - const BtaAvCoSep* SelectSinkCodec(BtaAvCoPeer* p_peer); - - /** - * Save new codec configuration. - * - * @param p_peer the peer to use - * @param new_codec_config the new codec configuration to use - * @param num_protect the number of content protection elements - * @param p_protect_info the content protection info to use - */ - void SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, - uint8_t num_protect, const uint8_t* p_protect_info); - - /** - * Set the Over-The-Air preferred codec configuration. - * - * The OTA prefered codec configuration is ignored if the current - * codec configuration contains explicit user configuration, or if the - * codec configuration for the same codec contains explicit user - * configuration. - * - * @param p_peer is the peer device that sent the OTA codec configuration - * @param p_ota_codec_config contains the received OTA A2DP codec - * configuration from the remote peer. Note: this is not the peer codec - * capability, but the codec configuration that the peer would like to use. - * @param num_protect is the number of content protection methods to use - * @param p_protect_info contains the content protection information to use. - * @param p_restart_output if there is a change in the encoder configuration - * that requires restarting of the A2DP connection, flag |p_restart_output| - * is set to true. - * @return true on success, otherwise false - */ - bool SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config, - uint8_t num_protect, const uint8_t* p_protect_info, - bool* p_restart_output); - - /** - * Update all selectable Source codecs with the corresponding codec - * information from a Sink peer. - * - * @param p_peer the peer Sink SEP to use - * @return the number of codecs that have been updated - */ - size_t UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer); - - /** - * Update a selectable Source codec with the corresponding codec information - * from a Sink peer. - * - * @param codec_config the codec config info to identify the codec to update - * @param p_peer the peer Sink SEP to use - * @return true if the codec is updated, otherwise false - */ - bool UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config, - BtaAvCoPeer* p_peer); - - /** - * Update all selectable Sink codecs with the corresponding codec - * information from a Source peer. - * - * @param p_peer the peer Source SEP to use - * @return the number of codecs that have been updated - */ - size_t UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer); - - /** - * Update a selectable Sink codec with the corresponding codec information - * from a Source peer. - * - * @param codec_config the codec config info to identify the codec to update - * @param p_peer the peer Source SEP to use - * @return true if the codec is updated, otherwise false - */ - bool UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config, - BtaAvCoPeer* p_peer); - - /** - * Attempt to select Source codec configuration for a Sink peer. - * - * @param codec_config the codec configuration to use - * @param p_peer the Sink peer to use - * @return a pointer to the corresponding SEP Sink entry on success, - * otnerwise nullptr - */ - const BtaAvCoSep* AttemptSourceCodecSelection( - const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer); +using namespace bluetooth; - /** - * Attempt to select Sink codec configuration for a Source peer. - * - * @param codec_config the codec configuration to use - * @param p_peer the Source peer to use - * @return a pointer to the corresponding SEP Source entry on success, - * otnerwise nullptr - */ - const BtaAvCoSep* AttemptSinkCodecSelection( - const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer); +// SCMS-T protect info +const uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00}; - /** - * Check if a peer SEP has content protection enabled. - * - * @param p_sep the peer SEP to check - * @return true if the peer SEP has content protection enabled, - * otherwise false - */ - bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep); +// Control block instance +static const bool kContentProtectEnabled = false; +static BtaAvCo bta_av_co_cb(kContentProtectEnabled, new BtaAvCoPeerCache()); - /** - * Check if a content protection service is SCMS-T. - * - * @param p_orotect_info the content protection info to check - * @return true if the Contention Protection in @param p_protect_info - * is SCMS-T, otherwise false - */ - static bool ContentProtectIsScmst(const uint8_t* p_protect_info); +void BtaAvCoState::setActivePeer(BtaAvCoPeer* peer) { active_peer_ = peer; } - /** - * Check if audio protect info contains SCMS-T Content Protection. - * - * @param num_protect number of protect schemes - * @param p_protect_info the protect info to check - * @return true if @param p_protect_info contains SCMS-T, otherwise false - */ - static bool AudioProtectHasScmst(uint8_t num_protect, - const uint8_t* p_protect_info); +BtaAvCoPeer* BtaAvCoState::getActivePeer() const { return active_peer_; } - bool ContentProtectEnabled() const { return content_protect_enabled_; } +uint8_t* BtaAvCoState::getCodecConfig() { return codec_config_; } - std::recursive_mutex codec_lock_; // Protect access to the codec state - std::vector codec_priorities_; // Configured - BtaAvCoPeer peers_[BTA_AV_NUM_STRS]; // Connected peer information - BtaAvCoPeer* active_peer_; // The current active peer - uint8_t codec_config_[AVDT_CODEC_SIZE]; // Current codec configuration - const bool content_protect_enabled_; // True if Content Protect is enabled - uint8_t content_protect_flag_; // Content Protect flag -}; +void BtaAvCoState::setCodecConfig(const uint8_t* codec_config) { + memcpy(codec_config_, codec_config, AVDT_CODEC_SIZE); +} -// SCMS-T protect info -const uint8_t bta_av_co_cp_scmst[AVDT_CP_INFO_LEN] = {0x02, 0x02, 0x00}; +void BtaAvCoState::clearCodecConfig() { + memset(codec_config_, 0, AVDT_CODEC_SIZE); +} -// Control block instance -static const bool kContentProtectEnabled = false; -static BtaAvCo bta_av_co_cb(kContentProtectEnabled); - -void BtaAvCoPeer::Init( - const std::vector& codec_priorities) { - Reset(bta_av_handle_); - // Reset the current config - codecs_ = new A2dpCodecs(codec_priorities); - codecs_->init(); - A2DP_InitDefaultCodec(codec_config); -} - -void BtaAvCoPeer::Reset(tBTA_AV_HNDL bta_av_handle) { - addr = RawAddress::kEmpty; - for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sinks); i++) { - BtaAvCoSep& sink = sinks[i]; - sink.Reset(); - } - for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sources); i++) { - BtaAvCoSep& source = sources[i]; - source.Reset(); - } - num_sinks = 0; - num_sources = 0; - num_seps = 0; - num_rx_sinks = 0; - num_rx_sources = 0; - num_sup_sinks = 0; - num_sup_sources = 0; - p_sink = nullptr; - p_source = nullptr; - memset(codec_config, 0, sizeof(codec_config)); - acceptor = false; - reconfig_needed = false; - opened = false; - mtu = 0; - uuid_to_connect = 0; - - bta_av_handle_ = bta_av_handle; - delete codecs_; - codecs_ = nullptr; - content_protect_active_ = false; +void BtaAvCoState::Reset() { + active_peer_ = nullptr; + clearCodecConfig(); } void BtaAvCo::Init( - const std::vector& codec_priorities) { - LOG_VERBOSE("%s", __func__); + const std::vector& codec_priorities, + std::vector* supported_codecs) { + log::verbose(""); - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); // Reset the control block Reset(); - codec_priorities_ = codec_priorities; + peer_cache_->Init(codec_priorities, supported_codecs); - for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { - BtaAvCoPeer* p_peer = &peers_[i]; - p_peer->Init(codec_priorities); + // Gather the supported codecs from the first peer context; + // all contexes should be identical. + supported_codecs->clear(); + for (auto* codec_config : + peer_cache_->peers_[0].GetCodecs()->orderedSourceCodecs()) { + auto& codec_info = supported_codecs->emplace_back(); + codec_info.codec_type = codec_config->codecIndex(); + codec_info.codec_id = codec_config->codecId(); + codec_info.codec_name = codec_config->name(); } } void BtaAvCo::Reset() { - codec_priorities_.clear(); - active_peer_ = nullptr; + bta_av_legacy_state_.Reset(); content_protect_flag_ = 0; - memset(codec_config_, 0, sizeof(codec_config_)); if (ContentProtectEnabled()) { SetContentProtectFlag(AVDT_CP_SCMS_COPY_NEVER); @@ -778,119 +113,62 @@ void BtaAvCo::Reset() { SetContentProtectFlag(AVDT_CP_SCMS_COPY_FREE); } - // Reset the peers and initialize the handles - for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { - BtaAvCoPeer* p_peer = &peers_[i]; - p_peer->Reset(BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(i)); - } + peer_cache_->Reset(); } bool BtaAvCo::IsSupportedCodec(btav_a2dp_codec_index_t codec_index) { // All peer state is initialized with the same local codec config, // hence we check only the first peer. - A2dpCodecs* codecs = peers_[0].GetCodecs(); + A2dpCodecs* codecs = peer_cache_->peers_[0].GetCodecs(); if (codecs == nullptr) { - LOG_ERROR("Peer codecs is set to null"); + log::error("Peer codecs is set to null"); return false; } return codecs->isSupportedCodec(codec_index); } A2dpCodecConfig* BtaAvCo::GetActivePeerCurrentCodec() { - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); - if (active_peer_ == nullptr || active_peer_->GetCodecs() == nullptr) { + BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); + if (active_peer == nullptr || active_peer->GetCodecs() == nullptr) { return nullptr; } - return active_peer_->GetCodecs()->getCurrentCodecConfig(); + return active_peer->GetCodecs()->getCurrentCodecConfig(); } A2dpCodecConfig* BtaAvCo::GetPeerCurrentCodec(const RawAddress& peer_address) { - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); - BtaAvCoPeer* peer = FindPeer(peer_address); + BtaAvCoPeer* peer = peer_cache_->FindPeer(peer_address); if (peer == nullptr || peer->GetCodecs() == nullptr) { return nullptr; } return peer->GetCodecs()->getCurrentCodecConfig(); } -BtaAvCoPeer* BtaAvCo::FindPeer(const RawAddress& peer_address) { - for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { - BtaAvCoPeer* p_peer = &peers_[i]; - if (p_peer->addr == peer_address) { - return p_peer; - } - } - return nullptr; -} - -BtaAvCoPeer* BtaAvCo::FindPeer(tBTA_AV_HNDL bta_av_handle) { - uint8_t index; - - index = BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle); - - LOG_VERBOSE("%s: bta_av_handle = 0x%x index = %d", __func__, bta_av_handle, - index); - - // Sanity check - if (index >= BTA_AV_CO_NUM_ELEMENTS(peers_)) { - LOG_ERROR("%s: peer index %d for BTA AV handle 0x%x is out of bounds", - __func__, index, bta_av_handle); - return nullptr; - } - - return &peers_[index]; -} - -BtaAvCoPeer* BtaAvCo::FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle, - const RawAddress& peer_address) { - LOG_VERBOSE("%s: peer %s bta_av_handle = 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); - - BtaAvCoPeer* p_peer = FindPeer(bta_av_handle); - if (p_peer == nullptr) { - LOG_ERROR("%s: peer entry for BTA AV handle 0x%x peer %s not found", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); - return nullptr; - } - - LOG_VERBOSE("%s: peer %s bta_av_handle = 0x%x previous address %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); - p_peer->addr = peer_address; - return p_peer; -} - -uint16_t BtaAvCo::FindPeerUuid(tBTA_AV_HNDL bta_av_handle) { - BtaAvCoPeer* p_peer = FindPeer(bta_av_handle); - if (p_peer == nullptr) { - return 0; - } - return p_peer->uuid_to_connect; -} - void BtaAvCo::ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint8_t num_seps, uint8_t num_sinks, uint8_t num_sources, uint16_t uuid_local) { - LOG_VERBOSE( - "%s: peer %s bta_av_handle:0x%x num_seps:%d num_sinks:%d num_sources:%d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, num_seps, + log::verbose( + "peer {} bta_av_handle:0x{:x} num_seps:{} num_sinks:{} num_sources:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, num_seps, num_sinks, num_sources); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG_ERROR("%s: could not find peer entry for bta_av_handle 0x%x peer %s", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } /* Sanity check : this should never happen */ if (p_peer->opened) { - LOG_ERROR("%s: peer %s already opened", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("peer {} already opened", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); } /* Copy the discovery results */ @@ -910,42 +188,54 @@ void BtaAvCo::ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle, } static void bta_av_co_store_peer_codectype(const BtaAvCoPeer* p_peer); +static bool bta_av_co_should_select_hardware_codec( + const A2dpCodecConfig& software_config, + const ::bluetooth::audio::a2dp::provider::a2dp_configuration& + hardware_config); tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid, uint8_t* p_num_protect, uint8_t* p_protect_info) { - LOG_VERBOSE("%s: peer %s bta_av_handle:0x%x codec:%s seid:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, - A2DP_CodecName(p_codec_info), seid); - LOG_VERBOSE("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x", __func__, - *p_num_protect, p_protect_info[0], p_protect_info[1], - p_protect_info[2]); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_codec_info).c_str()); + log::verbose("peer {} bta_av_handle:0x{:x} codec:{} seid:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, + A2DP_CodecName(p_codec_info), seid); + log::verbose("num_protect:0x{:02x} protect_info:0x{:02x}{:02x}{:02x}", + *p_num_protect, p_protect_info[0], p_protect_info[1], + p_protect_info[2]); + log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info)); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG_ERROR("%s: could not find peer entry for bta_av_handle 0x%x peer %s", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return A2DP_FAIL; } - LOG_VERBOSE("%s: peer(o=%d, n_sinks=%d, n_rx_sinks=%d, n_sup_sinks=%d)", - __func__, p_peer->opened, p_peer->num_sinks, p_peer->num_rx_sinks, - p_peer->num_sup_sinks); + log::verbose("peer(o={}, n_sinks={}, n_rx_sinks={}, n_sup_sinks={})", + p_peer->opened, p_peer->num_sinks, p_peer->num_rx_sinks, + p_peer->num_sup_sinks); p_peer->num_rx_sinks++; + // Bypass the validation for codecs that are offloaded: + // the stack does not need to know about the peer capabilities, + // since the validation and selection will be performed by the + // bluetooth audio HAL for offloaded codecs. + auto codec_index = A2DP_SourceCodecIndex(p_codec_info); + bool is_offloaded_codec = + ::bluetooth::audio::a2dp::provider::supports_codec(codec_index); + // Check the peer's Sink codec - if (A2DP_IsPeerSinkCodecValid(p_codec_info)) { + if (is_offloaded_codec || A2DP_IsPeerSinkCodecValid(p_codec_info)) { // If there is room for a new one if (p_peer->num_sup_sinks < BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks)) { BtaAvCoSep* p_sink = &p_peer->sinks[p_peer->num_sup_sinks++]; - LOG_VERBOSE("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__, - p_codec_info[1], p_codec_info[2], p_codec_info[3], - p_codec_info[4], p_codec_info[5], p_codec_info[6]); + log::verbose("saved caps[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", p_codec_info[1], + p_codec_info[2], p_codec_info[3], p_codec_info[4], + p_codec_info[5], p_codec_info[6]); memcpy(p_sink->codec_caps, p_codec_info, AVDT_CODEC_SIZE); p_sink->sep_info_idx = *p_sep_info_idx; @@ -953,8 +243,8 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( p_sink->num_protect = *p_num_protect; memcpy(p_sink->protect_info, p_protect_info, AVDT_CP_INFO_LEN); } else { - LOG_ERROR("%s: peer %s : no more room for Sink info", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("peer {} : no more room for Sink info", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); } } @@ -964,9 +254,9 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { return A2DP_FAIL; } - LOG_VERBOSE("%s: last Sink codec reached for peer %s (local %s)", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), - p_peer->acceptor ? "acceptor" : "initiator"); + log::verbose("last Sink codec reached for peer {} (local {})", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), + p_peer->acceptor ? "acceptor" : "initiator"); bta_av_co_store_peer_codectype(p_peer); @@ -976,22 +266,24 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( UpdateAllSelectableSourceCodecs(p_peer); if (p_peer->p_sink == nullptr) { // Update the selected codec - p_peer->p_sink = - FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_peer->codec_config)); + p_peer->p_sink = peer_cache_->FindPeerSink( + p_peer, A2DP_SourceCodecIndex(p_peer->codec_config), + ContentProtectFlag()); } p_sink = p_peer->p_sink; if (p_sink == nullptr) { - LOG_ERROR("%s: cannot find the selected codec for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("cannot find the selected codec for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); return A2DP_FAIL; } } else { if (btif_av_peer_prefers_mandatory_codec(p_peer->addr)) { // Apply user preferred codec directly before first codec selected. - p_sink = FindPeerSink(p_peer, BTAV_A2DP_CODEC_INDEX_SOURCE_SBC); + p_sink = peer_cache_->FindPeerSink( + p_peer, BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, ContentProtectFlag()); if (p_sink != nullptr) { - LOG_VERBOSE("%s: mandatory codec preferred for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("mandatory codec preferred for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); btav_a2dp_codec_config_t high_priority_mandatory{ .codec_type = BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, .codec_priority = BTAV_A2DP_CODEC_PRIORITY_HIGHEST, @@ -1008,14 +300,14 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( result_codec_config, &restart_input, &restart_output, &config_updated); } else { - LOG_WARN("%s: mandatory codec not found for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::warn("mandatory codec not found for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); } } p_sink = SelectSourceCodec(p_peer); if (p_sink == nullptr) { - LOG_ERROR("%s: cannot set up codec for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("cannot set up codec for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); return A2DP_FAIL; } } @@ -1029,14 +321,14 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( // If acceptor -> reconfig otherwise reply for configuration *p_sep_info_idx = p_sink->sep_info_idx; - LOG_VERBOSE("%s: peer %s acceptor:%s reconfig_needed:%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), - (p_peer->acceptor) ? "true" : "false", - (p_peer->reconfig_needed) ? "true" : "false"); + log::verbose("peer {} acceptor:{} reconfig_needed:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), + (p_peer->acceptor) ? "true" : "false", + (p_peer->reconfig_needed) ? "true" : "false"); if (p_peer->acceptor) { if (p_peer->reconfig_needed) { - LOG_VERBOSE("%s: call BTA_AvReconfig(0x%x) for peer %s", __func__, - bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("call BTA_AvReconfig(0x{:x}) for peer {}", bta_av_handle, + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); BTA_AvReconfig(bta_av_handle, true, p_sink->sep_info_idx, p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst); } @@ -1045,8 +337,8 @@ tA2DP_STATUS BtaAvCo::ProcessSourceGetConfig( } // report this peer selectable codecs after retrieved all its capabilities. - LOG(INFO) << __func__ << ": retrieved " << +p_peer->num_rx_sinks - << " capabilities from peer " << p_peer->addr; + log::info("retrieved {} capabilities from peer {}", p_peer->num_rx_sinks, + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); ReportSourceCodecState(p_peer); return A2DP_SUCCESS; @@ -1058,28 +350,27 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, uint8_t* p_sep_info_idx, uint8_t seid, uint8_t* p_num_protect, uint8_t* p_protect_info) { - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); - LOG_VERBOSE("%s: peer %s bta_av_handle:0x%x codec:%s seid:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, - A2DP_CodecName(p_codec_info), seid); - LOG_VERBOSE("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x", __func__, - *p_num_protect, p_protect_info[0], p_protect_info[1], - p_protect_info[2]); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_codec_info).c_str()); + log::verbose("peer {} bta_av_handle:0x{:x} codec:{} seid:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, + A2DP_CodecName(p_codec_info), seid); + log::verbose("num_protect:0x{:02x} protect_info:0x{:02x}{:02x}{:02x}", + *p_num_protect, p_protect_info[0], p_protect_info[1], + p_protect_info[2]); + log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info)); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG_ERROR("%s: could not find peer entry for bta_av_handle 0x%x peer %s", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return A2DP_FAIL; } - LOG_VERBOSE( - "%s: peer %s found (o=%d, n_sources=%d, n_rx_sources=%d, " - "n_sup_sources=%d)", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), p_peer->opened, + log::verbose( + "peer {} found (o={}, n_sources={}, n_rx_sources={}, n_sup_sources={})", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), p_peer->opened, p_peer->num_sources, p_peer->num_rx_sources, p_peer->num_sup_sources); p_peer->num_rx_sources++; @@ -1090,9 +381,9 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, if (p_peer->num_sup_sources < BTA_AV_CO_NUM_ELEMENTS(p_peer->sources)) { BtaAvCoSep* p_source = &p_peer->sources[p_peer->num_sup_sources++]; - LOG_VERBOSE("%s: saved caps[%x:%x:%x:%x:%x:%x]", __func__, - p_codec_info[1], p_codec_info[2], p_codec_info[3], - p_codec_info[4], p_codec_info[5], p_codec_info[6]); + log::verbose("saved caps[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", p_codec_info[1], + p_codec_info[2], p_codec_info[3], p_codec_info[4], + p_codec_info[5], p_codec_info[6]); memcpy(p_source->codec_caps, p_codec_info, AVDT_CODEC_SIZE); p_source->sep_info_idx = *p_sep_info_idx; @@ -1100,8 +391,8 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, p_source->num_protect = *p_num_protect; memcpy(p_source->protect_info, p_protect_info, AVDT_CP_INFO_LEN); } else { - LOG_ERROR("%s: peer %s : no more room for Source info", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("peer {} : no more room for Source info", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); } } @@ -1111,8 +402,8 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, (p_peer->num_sup_sources != BTA_AV_CO_NUM_ELEMENTS(p_peer->sources))) { return A2DP_FAIL; } - LOG_VERBOSE("%s: last Source codec reached for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("last Source codec reached for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); // Select the Sink codec const BtaAvCoSep* p_source = nullptr; @@ -1120,20 +411,21 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, UpdateAllSelectableSinkCodecs(p_peer); if (p_peer->p_source == nullptr) { // Update the selected codec - p_peer->p_source = - FindPeerSource(p_peer, A2DP_SinkCodecIndex(p_peer->codec_config)); + p_peer->p_source = peer_cache_->FindPeerSource( + p_peer, A2DP_SinkCodecIndex(p_peer->codec_config), + ContentProtectFlag()); } p_source = p_peer->p_source; if (p_source == nullptr) { - LOG_ERROR("%s: cannot find the selected codec for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("cannot find the selected codec for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); return A2DP_FAIL; } } else { p_source = SelectSinkCodec(p_peer); if (p_source == nullptr) { - LOG_ERROR("%s: cannot set up codec for the peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("cannot set up codec for the peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); return A2DP_FAIL; } } @@ -1147,14 +439,14 @@ tA2DP_STATUS BtaAvCo::ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, // If acceptor -> reconfig otherwise reply for configuration *p_sep_info_idx = p_source->sep_info_idx; - LOG_VERBOSE("%s: peer %s acceptor:%s reconfig_needed:%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), - (p_peer->acceptor) ? "true" : "false", - (p_peer->reconfig_needed) ? "true" : "false"); + log::verbose("peer {} acceptor:{} reconfig_needed:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), + (p_peer->acceptor) ? "true" : "false", + (p_peer->reconfig_needed) ? "true" : "false"); if (p_peer->acceptor) { if (p_peer->reconfig_needed) { - LOG_VERBOSE("%s: call BTA_AvReconfig(0x%x) for peer %s", __func__, - bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("call BTA_AvReconfig(0x{:x}) for peer {}", bta_av_handle, + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); BTA_AvReconfig(bta_av_handle, true, p_source->sep_info_idx, p_peer->codec_config, *p_num_protect, bta_av_co_cp_scmst); } @@ -1175,56 +467,54 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, uint8_t category = A2DP_SUCCESS; bool reconfig_needed = false; - LOG_VERBOSE( - "%s: bta_av_handle=0x%x peer_address=%s seid=%d " - "num_protect=%d t_local_sep=%d avdt_handle=%d", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address), seid, - num_protect, t_local_sep, avdt_handle); - LOG_VERBOSE("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__, p_codec_info[1], - p_codec_info[2], p_codec_info[3], p_codec_info[4], - p_codec_info[5], p_codec_info[6]); - LOG_VERBOSE("%s: num_protect:0x%02x protect_info:0x%02x%02x%02x", __func__, - num_protect, p_protect_info[0], p_protect_info[1], - p_protect_info[2]); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_codec_info).c_str()); + log::verbose( + "bta_av_handle=0x{:x} peer_address={} seid={} num_protect={} " + "t_local_sep={} avdt_handle={}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address), seid, num_protect, + t_local_sep, avdt_handle); + log::verbose("p_codec_info[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", p_codec_info[1], + p_codec_info[2], p_codec_info[3], p_codec_info[4], + p_codec_info[5], p_codec_info[6]); + log::verbose("num_protect:0x{:02x} protect_info:0x{:02x}{:02x}{:02x}", + num_protect, p_protect_info[0], p_protect_info[1], + p_protect_info[2]); + log::verbose("codec: {}", A2DP_CodecInfoString(p_codec_info)); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG_ERROR("%s: could not find peer entry for bta_av_handle 0x%x peer %s", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); // Call call-in rejecting the configuration bta_av_ci_setconfig(bta_av_handle, A2DP_BUSY, AVDT_ASC_CODEC, 0, nullptr, false, avdt_handle); return; } - LOG_VERBOSE( - "%s: peer %s found (o=%d, n_sinks=%d, n_rx_sinks=%d, " - "n_sup_sinks=%d)", - __func__, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), p_peer->opened, - p_peer->num_sinks, p_peer->num_rx_sinks, p_peer->num_sup_sinks); + log::verbose( + "peer {} found (o={}, n_sinks={}, n_rx_sinks={}, n_sup_sinks={})", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), p_peer->opened, p_peer->num_sinks, + p_peer->num_rx_sinks, p_peer->num_sup_sinks); // Sanity check: should not be opened at this point if (p_peer->opened) { - LOG_ERROR("%s: peer %s already in use", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("peer {} already in use", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); } if (num_protect != 0) { if (ContentProtectEnabled()) { - if ((num_protect != 1) || - !BtaAvCo::ContentProtectIsScmst(p_protect_info)) { - LOG_ERROR("%s: wrong CP configuration for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + if ((num_protect != 1) || !ContentProtectIsScmst(p_protect_info)) { + log::error("wrong CP configuration for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); status = A2DP_BAD_CP_TYPE; category = AVDT_ASC_PROTECT; } } else { // Do not support content protection for the time being - LOG_ERROR("%s: wrong CP configuration for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("wrong CP configuration for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); status = A2DP_BAD_CP_TYPE; category = AVDT_ASC_PROTECT; } @@ -1234,8 +524,8 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, bool codec_config_supported = false; if (t_local_sep == AVDT_TSEP_SNK) { - LOG_VERBOSE("%s: peer %s is A2DP Source", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("peer {} is A2DP Source", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); codec_config_supported = A2DP_IsSinkCodecSupported(p_codec_info); if (codec_config_supported) { // If Peer is Source, and our config subset matches with what is @@ -1244,17 +534,17 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, } } if (t_local_sep == AVDT_TSEP_SRC) { - LOG_VERBOSE("%s: peer %s is A2DP SINK", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("peer {} is A2DP SINK", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); // Ignore the restart_output flag: accepting the remote device's // codec selection should not trigger codec reconfiguration. bool dummy_restart_output = false; if ((p_peer->GetCodecs() == nullptr) || !SetCodecOtaConfig(p_peer, p_codec_info, num_protect, p_protect_info, &dummy_restart_output)) { - LOG_ERROR("%s: cannot set source codec %s for peer %s", __func__, - A2DP_CodecName(p_codec_info), - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::error("cannot set source codec {} for peer {}", + A2DP_CodecName(p_codec_info), + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); } else { codec_config_supported = true; // Check if reconfiguration is needed @@ -1272,8 +562,8 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, } if (status != A2DP_SUCCESS) { - LOG_VERBOSE("%s: peer %s reject s=%d c=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), status, category); + log::verbose("peer {} reject s={} c={}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), status, category); // Call call-in rejecting the configuration bta_av_ci_setconfig(bta_av_handle, status, category, 0, nullptr, false, avdt_handle); @@ -1283,8 +573,8 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, // Mark that this is an acceptor peer p_peer->acceptor = true; p_peer->reconfig_needed = reconfig_needed; - LOG_VERBOSE("%s: peer %s accept reconf=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), reconfig_needed); + log::verbose("peer {} accept reconf={}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), reconfig_needed); // Call call-in accepting the configuration bta_av_ci_setconfig(bta_av_handle, A2DP_SUCCESS, A2DP_SUCCESS, 0, nullptr, reconfig_needed, avdt_handle); @@ -1292,72 +582,77 @@ void BtaAvCo::ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, void BtaAvCo::ProcessOpen(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t mtu) { - LOG_VERBOSE("%s: peer %s bta_av_handle: 0x%x mtu:%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, mtu); + log::verbose("peer {} bta_av_handle: 0x{:x} mtu:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, mtu); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG_ERROR("%s: could not find peer entry for bta_av_handle 0x%x peer %s", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } p_peer->opened = true; p_peer->mtu = mtu; // The first connected peer becomes the active peer - if (active_peer_ == nullptr) { - active_peer_ = p_peer; + BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); + if (active_peer == nullptr) { + bta_av_legacy_state_.setActivePeer(p_peer); } } void BtaAvCo::ProcessClose(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) { - LOG_VERBOSE("%s: peer %s bta_av_handle: 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); + log::verbose("peer {} bta_av_handle: 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); btif_av_reset_audio_delay(); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG_ERROR("%s: could not find peer entry for bta_av_handle 0x%x peer %s", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } // Reset the active peer - if (active_peer_ == p_peer) { - active_peer_ = nullptr; + BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); + if (active_peer == p_peer) { + bta_av_legacy_state_.setActivePeer(nullptr); } // Mark the peer closed and clean the peer info - p_peer->Init(codec_priorities_); + p_peer->Init(peer_cache_->codec_priorities_); } void BtaAvCo::ProcessStart(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, const uint8_t* p_codec_info, bool* p_no_rtp_header) { - LOG_VERBOSE("%s: peer %s bta_av_handle: 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); + log::verbose("peer {} bta_av_handle: 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG_ERROR("%s: could not find peer entry for bta_av_handle 0x%x peer %s", - __func__, bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("could not find peer entry for bta_av_handle 0x{:x} peer {}", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } bool add_rtp_header = A2DP_UsesRtpHeader(p_peer->ContentProtectActive(), p_codec_info); - LOG_VERBOSE("%s: bta_av_handle: 0x%x add_rtp_header: %s", __func__, - bta_av_handle, add_rtp_header ? "true" : "false"); + log::verbose("bta_av_handle: 0x{:x} add_rtp_header: {}", bta_av_handle, + add_rtp_header ? "true" : "false"); *p_no_rtp_header = !add_rtp_header; } void BtaAvCo::ProcessStop(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) { - LOG_VERBOSE("%s: peer %s bta_av_handle: 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); + log::verbose("peer {} bta_av_handle: 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); // Nothing to do } @@ -1365,14 +660,14 @@ BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info, uint32_t* p_timestamp) { BT_HDR* p_buf; - LOG_VERBOSE("%s: codec: %s", __func__, A2DP_CodecName(p_codec_info)); + log::verbose("codec: {}", A2DP_CodecName(p_codec_info)); p_buf = btif_a2dp_source_audio_readbuf(); if (p_buf == nullptr) return nullptr; if (p_buf->offset < 4) { osi_free(p_buf); - LOG_ERROR("No space for timestamp in packet, dropped"); + log::error("No space for timestamp in packet, dropped"); return nullptr; } /* @@ -1386,16 +681,16 @@ BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info, if (!A2DP_GetPacketTimestamp(p_codec_info, (const uint8_t*)(p_buf + 1), p_timestamp) || !A2DP_BuildCodecHeader(p_codec_info, p_buf, p_buf->layer_specific)) { - LOG_ERROR("%s: unsupported codec type (%d)", __func__, - A2DP_GetCodecType(p_codec_info)); + log::error("unsupported codec type ({})", A2DP_GetCodecType(p_codec_info)); osi_free(p_buf); return nullptr; } + BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); // if offset is 0, the decremental operation may result in // underflow and OOB access - if (ContentProtectEnabled() && (active_peer_ != nullptr) && - active_peer_->ContentProtectActive() && p_buf->offset > 0) { + if (ContentProtectEnabled() && (active_peer != nullptr) && + active_peer->ContentProtectActive() && p_buf->offset > 0) { p_buf->len++; p_buf->offset--; uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset; @@ -1407,64 +702,65 @@ BT_HDR* BtaAvCo::GetNextSourceDataPacket(const uint8_t* p_codec_info, void BtaAvCo::DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) { - LOG_ERROR("%s: peer %s dropped audio packet on handle 0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); + log::error("peer {} dropped audio packet on handle 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); } void BtaAvCo::ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t delay) { - LOG_VERBOSE("%s: peer %s bta_av_handle: 0x%x delay:0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, delay); + log::verbose("peer {} bta_av_handle: 0x{:x} delay:0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, delay); btif_av_set_audio_delay(peer_address, delay); } void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t mtu) { - LOG(INFO) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " bta_av_handle: " << loghex(bta_av_handle) << " mtu: " << mtu; + log::info("peer {} bta_av_handle: {} mtu: {}", + ADDRESS_TO_LOGGABLE_STR(peer_address), loghex(bta_av_handle), mtu); // Find the peer - BtaAvCoPeer* p_peer = FindPeerAndUpdate(bta_av_handle, peer_address); + BtaAvCoPeer* p_peer = + peer_cache_->FindPeerAndUpdate(bta_av_handle, peer_address); if (p_peer == nullptr) { - LOG(ERROR) << __func__ << ": could not find peer entry for bta_av_handle " - << loghex(bta_av_handle) << " peer " - << ADDRESS_TO_LOGGABLE_STR(peer_address); + log::error("could not find peer entry for bta_av_handle {} peer {}", + loghex(bta_av_handle), ADDRESS_TO_LOGGABLE_STR(peer_address)); return; } p_peer->mtu = mtu; } bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) { - LOG(INFO) << __func__ - << ": peer_address=" << ADDRESS_TO_LOGGABLE_STR(peer_address); + log::info("peer_address={}", ADDRESS_TO_LOGGABLE_STR(peer_address)); - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); + BtaAvCoState* reference_state = &bta_av_legacy_state_; if (peer_address.IsEmpty()) { // Reset the active peer; - active_peer_ = nullptr; - memset(codec_config_, 0, sizeof(codec_config_)); + reference_state->setActivePeer(nullptr); + reference_state->clearCodecConfig(); return true; } // Find the peer - BtaAvCoPeer* p_peer = FindPeer(peer_address); + BtaAvCoPeer* p_peer = peer_cache_->FindPeer(peer_address); if (p_peer == nullptr) { return false; } - active_peer_ = p_peer; - memcpy(codec_config_, active_peer_->codec_config, AVDT_CODEC_SIZE); - LOG(INFO) << __func__ << ": codec = " << A2DP_CodecInfoString(codec_config_); + reference_state->setActivePeer(p_peer); + reference_state->setCodecConfig(p_peer->codec_config); + log::info("codec = {}", + A2DP_CodecInfoString(reference_state->getCodecConfig())); // report the selected codec configuration of this new active peer. - ReportSourceCodecState(active_peer_); + ReportSourceCodecState(p_peer); return true; } void BtaAvCo::SaveCodec(const uint8_t* new_codec_config) { - memcpy(codec_config_, new_codec_config, sizeof(codec_config_)); + bta_av_legacy_state_.setCodecConfig(new_codec_config); } void BtaAvCo::GetPeerEncoderParameters( @@ -1474,11 +770,11 @@ void BtaAvCo::GetPeerEncoderParameters( CHECK(p_peer_params != nullptr) << "Peer address " << ADDRESS_TO_LOGGABLE_STR(peer_address); - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); // Compute the MTU - for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { - const BtaAvCoPeer* p_peer = &peers_[i]; + for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) { + const BtaAvCoPeer* p_peer = &peer_cache_->peers_[i]; if (!p_peer->opened) continue; if (p_peer->addr != peer_address) continue; if (p_peer->mtu < min_mtu) min_mtu = p_peer->mtu; @@ -1487,17 +783,17 @@ void BtaAvCo::GetPeerEncoderParameters( p_peer_params->is_peer_edr = btif_av_is_peer_edr(peer_address); p_peer_params->peer_supports_3mbps = btif_av_peer_supports_3mbps(peer_address); - LOG_VERBOSE( - "%s: peer_address=%s peer_mtu=%d is_peer_edr=%s peer_supports_3mbps=%s", - __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address), p_peer_params->peer_mtu, - logbool(p_peer_params->is_peer_edr).c_str(), - logbool(p_peer_params->peer_supports_3mbps).c_str()); + log::verbose( + "peer_address={} peer_mtu={} is_peer_edr={} peer_supports_3mbps={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), p_peer_params->peer_mtu, + logbool(p_peer_params->is_peer_edr), + logbool(p_peer_params->peer_supports_3mbps)); } const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() { - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); - return A2DP_GetEncoderInterface(codec_config_); + return A2DP_GetEncoderInterface(bta_av_legacy_state_.getCodecConfig()); } bool BtaAvCo::SetCodecUserConfig( @@ -1510,17 +806,16 @@ bool BtaAvCo::SetCodecUserConfig( bool config_updated = false; bool success = true; - VLOG(1) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " codec_user_config={" << codec_user_config.ToString() << "}"; + log::verbose("peer_address={} codec_user_config={{}}", + ADDRESS_TO_LOGGABLE_STR(peer_address), + codec_user_config.ToString()); *p_restart_output = false; - BtaAvCoPeer* p_peer = FindPeer(peer_address); + BtaAvCoPeer* p_peer = peer_cache_->FindPeer(peer_address); if (p_peer == nullptr) { - LOG(ERROR) << __func__ << ": cannot find peer " - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " to configure"; + log::error("cannot find peer {} to configure", + ADDRESS_TO_LOGGABLE_STR(peer_address)); success = false; goto done; } @@ -1528,24 +823,24 @@ bool BtaAvCo::SetCodecUserConfig( // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities if ((p_peer->num_rx_sinks != p_peer->num_sinks) && (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { - LOG(WARNING) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : not all peer's capabilities have been retrieved"; + log::warn("peer {} : not all peer's capabilities have been retrieved", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); success = false; goto done; } // Find the peer SEP codec to use if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) { - p_sink = FindPeerSink(p_peer, codec_user_config.codec_type); + p_sink = peer_cache_->FindPeerSink(p_peer, codec_user_config.codec_type, + ContentProtectFlag()); } else { // Use the current sink codec p_sink = p_peer->p_sink; } if (p_sink == nullptr) { - LOG(ERROR) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : cannot find peer SEP to configure for codec type " - << codec_user_config.codec_type; + log::error("peer {} : cannot find peer SEP to configure for codec type {}", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr), + codec_user_config.codec_type); success = false; goto done; } @@ -1568,16 +863,14 @@ bool BtaAvCo::SetCodecUserConfig( p_sink = SelectSourceCodec(p_peer); if (p_sink == nullptr) { - LOG(ERROR) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : cannot set up codec for the peer SINK"; + log::error("peer {} : cannot set up codec for the peer SINK", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); success = false; goto done; } p_peer->acceptor = false; - VLOG(1) << __func__ << ": call BTA_AvReconfig(" - << loghex(p_peer->BtaAvHandle()) << ")"; + log::verbose("call BTA_AvReconfig({})", loghex(p_peer->BtaAvHandle())); BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx, p_peer->codec_config, num_protect, bta_av_co_cp_scmst); *p_restart_output = true; @@ -1592,8 +885,11 @@ done: // would always know the result. // NOTE: Currently, the input is restarted by sending an upcall // and informing the Media Framework about the change. + + // Find the peer that is currently open + BtaAvCoPeer* active_peer = bta_av_legacy_state_.getActivePeer(); if (p_peer != nullptr && - (!restart_output || !success || p_peer != active_peer_)) { + (!restart_output || !success || p_peer != active_peer)) { return ReportSourceCodecState(p_peer); } @@ -1606,31 +902,28 @@ bool BtaAvCo::SetCodecAudioConfig( bool restart_output = false; bool config_updated = false; - VLOG(1) << __func__ - << ": codec_audio_config: " << codec_audio_config.ToString(); + log::verbose("codec_audio_config: {}", codec_audio_config.ToString()); // Find the peer that is currently open - BtaAvCoPeer* p_peer = active_peer_; + BtaAvCoPeer* p_peer = bta_av_legacy_state_.getActivePeer(); if (p_peer == nullptr) { - LOG(ERROR) << __func__ << ": no active peer to configure"; + log::error("no active peer to configure"); return false; } // Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities if ((p_peer->num_rx_sinks != p_peer->num_sinks) && (p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) { - LOG(WARNING) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : not all peer's capabilities have been retrieved"; + log::warn("peer {} : not all peer's capabilities have been retrieved", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); return false; } // Use the current sink codec const BtaAvCoSep* p_sink = p_peer->p_sink; if (p_sink == nullptr) { - LOG(ERROR) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : cannot find peer SEP to configure"; + log::error("peer {} : cannot find peer SEP to configure", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); return false; } @@ -1652,8 +945,7 @@ bool BtaAvCo::SetCodecAudioConfig( p_sink->protect_info); p_peer->acceptor = false; - VLOG(1) << __func__ << ": call BTA_AvReconfig(" - << loghex(p_peer->BtaAvHandle()) << ")"; + log::verbose("call BTA_AvReconfig({})", loghex(p_peer->BtaAvHandle())); BTA_AvReconfig(p_peer->BtaAvHandle(), true, p_sink->sep_info_idx, p_peer->codec_config, num_protect, bta_av_co_cp_scmst); } @@ -1668,9 +960,10 @@ bool BtaAvCo::SetCodecAudioConfig( } int BtaAvCo::GetSourceEncoderEffectiveFrameSize() { - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); - return A2DP_GetEecoderEffectiveFrameSize(codec_config_); + return A2DP_GetEecoderEffectiveFrameSize( + bta_av_legacy_state_.getCodecConfig()); } bool BtaAvCo::ReportSourceCodecState(BtaAvCoPeer* p_peer) { @@ -1688,25 +981,23 @@ bool BtaAvCo::ReportSourceCodecState(BtaAvCoPeer* p_peer) { std::vector codecs_local_capabilities; std::vector codecs_selectable_capabilities; - VLOG(1) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr); + log::verbose("peer_address={}", ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); A2dpCodecs* codecs = p_peer->GetCodecs(); if (codecs == nullptr) { - LOG_ERROR("Peer codecs is set to null"); + log::error("Peer codecs is set to null"); return false; } if (!codecs->getCodecConfigAndCapabilities(&codec_config, &codecs_local_capabilities, &codecs_selectable_capabilities)) { - LOG(WARNING) << __func__ << ": Peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : error reporting audio source codec state: cannot get " - "codec config and capabilities"; + log::warn( + "Peer {} : error reporting audio source codec state: cannot get codec " + "config and capabilities", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); return false; } - LOG(INFO) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) << " codec_config={" - << codec_config.ToString() << "}"; + log::info("peer {} codec_config={{}}", ADDRESS_TO_LOGGABLE_STR(p_peer->addr), + codec_config.ToString()); btif_av_report_source_codec_state(p_peer->addr, codec_config, codecs_local_capabilities, codecs_selectable_capabilities); @@ -1714,33 +1005,33 @@ bool BtaAvCo::ReportSourceCodecState(BtaAvCoPeer* p_peer) { } bool BtaAvCo::ReportSinkCodecState(BtaAvCoPeer* p_peer) { - LOG_VERBOSE("%s: peer_address=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("peer_address={}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); // Nothing to do (for now) return true; } void BtaAvCo::DebugDump(int fd) { - std::lock_guard lock(codec_lock_); + std::lock_guard lock(peer_cache_->codec_lock_); // // Active peer codec-specific stats // - if (active_peer_ != nullptr) { - A2dpCodecs* a2dp_codecs = active_peer_->GetCodecs(); + if (bta_av_legacy_state_.getActivePeer() != nullptr) { + A2dpCodecs* a2dp_codecs = bta_av_legacy_state_.getActivePeer()->GetCodecs(); if (a2dp_codecs != nullptr) { a2dp_codecs->debug_codec_dump(fd); } } dprintf(fd, "\nA2DP Peers State:\n"); - dprintf(fd, " Active peer: %s\n", - (active_peer_ != nullptr) - ? ADDRESS_TO_LOGGABLE_CSTR(active_peer_->addr) - : "null"); - - for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { - const BtaAvCoPeer& peer = peers_[i]; + dprintf( + fd, " Active peer: %s\n", + (bta_av_legacy_state_.getActivePeer() != nullptr) + ? ADDRESS_TO_LOGGABLE_CSTR(bta_av_legacy_state_.getActivePeer()->addr) + : "null"); + + for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peer_cache_->peers_); i++) { + const BtaAvCoPeer& peer = peer_cache_->peers_[i]; if (peer.addr.IsEmpty()) { continue; } @@ -1762,65 +1053,119 @@ void BtaAvCo::DebugDump(int fd) { } } -bool BtaAvCo::ContentProtectIsScmst(const uint8_t* p_protect_info) { - LOG_VERBOSE("%s", __func__); - - if (*p_protect_info >= AVDT_CP_LOSC) { - uint16_t cp_id; - p_protect_info++; - STREAM_TO_UINT16(cp_id, p_protect_info); - if (cp_id == AVDT_CP_SCMS_T_ID) { - LOG_VERBOSE("%s: SCMS-T found", __func__); - return true; - } - } - return false; -} - -bool BtaAvCo::AudioProtectHasScmst(uint8_t num_protect, - const uint8_t* p_protect_info) { - LOG_VERBOSE("%s", __func__); - while (num_protect--) { - if (BtaAvCo::ContentProtectIsScmst(p_protect_info)) return true; - // Move to the next Content Protect schema - p_protect_info += *p_protect_info + 1; - } - LOG_VERBOSE("%s: SCMS-T not found", __func__); - return false; -} - -bool BtaAvCo::AudioSepHasContentProtection(const BtaAvCoSep* p_sep) { - LOG_VERBOSE("%s", __func__); - - // Check if content protection is enabled for this stream - if (ContentProtectFlag() != AVDT_CP_SCMS_COPY_FREE) { - return BtaAvCo::AudioProtectHasScmst(p_sep->num_protect, - p_sep->protect_info); - } +std::optional<::bluetooth::audio::a2dp::provider::a2dp_configuration> +BtaAvCo::GetProviderCodecConfiguration(BtaAvCoPeer* p_peer) { + // Gather peer codec capabilities. + std::vector<::bluetooth::audio::a2dp::provider::a2dp_remote_capabilities> + a2dp_remote_caps; + for (size_t index = 0; index < p_peer->num_sup_sinks; index++) { + const BtaAvCoSep* p_sink = &p_peer->sinks[index]; + auto& capabilities = a2dp_remote_caps.emplace_back(); + capabilities.seid = p_sink->seid; + capabilities.capabilities = p_sink->codec_caps; + } + + // Get the configuration of the preferred codec as codec hint. + btav_a2dp_codec_config_t codec_config = + p_peer->GetCodecs()->orderedSourceCodecs().front()->getCodecUserConfig(); + + // Pass all gathered codec capabilities to the provider + return ::bluetooth::audio::a2dp::provider::get_a2dp_configuration( + p_peer->addr, a2dp_remote_caps, codec_config); +} + +BtaAvCoSep* BtaAvCo::SelectProviderCodecConfiguration( + BtaAvCoPeer* p_peer, + const ::bluetooth::audio::a2dp::provider::a2dp_configuration& + provider_codec_config) { + // Configure the selected offload codec for the active peer. + // This function _must_ have the same external behaviour as + // AttemptSourceCodecSelection, except the configuration + // is provided by the HAL rather than derived locally. + + log::info("Configuration={}", provider_codec_config.toString()); + + // Identify the selected sink. + auto* p_sink = peer_cache_->FindPeerSink( + p_peer, provider_codec_config.codec_parameters.codec_type, + ContentProtectFlag()); + ASSERT_LOG(p_sink != nullptr, "Unable to find the selected codec config"); + + // Identify the selected codec. + auto* codec_config = reinterpret_cast( + p_peer->GetCodecs()->findSourceCodecConfig( + provider_codec_config.codec_parameters.codec_type)); + ASSERT_LOG(codec_config != nullptr, + "Unable to find the selected codec config"); + + // Update the vendor codec parameters and codec configuration. + codec_config->setCodecConfig( + provider_codec_config.codec_parameters, + provider_codec_config.codec_config, + provider_codec_config.vendor_specific_parameters); + + // Select the codec config. + p_peer->GetCodecs()->setCurrentCodecConfig(codec_config); + p_peer->p_sink = p_sink; + SaveNewCodecConfig(p_peer, provider_codec_config.codec_config, + p_sink->num_protect, p_sink->protect_info); - LOG_VERBOSE("%s: not required", __func__); - return true; + return p_sink; } const BtaAvCoSep* BtaAvCo::SelectSourceCodec(BtaAvCoPeer* p_peer) { - const BtaAvCoSep* p_sink = nullptr; - // Update all selectable codecs. // This is needed to update the selectable parameters for each codec. // NOTE: The selectable codec info is used only for informational purpose. UpdateAllSelectableSourceCodecs(p_peer); - // Select the codec + // Query the preferred codec configuration for offloaded codecs. + auto provider_codec_config = GetProviderCodecConfiguration(p_peer); + + // Query the preferred codec configuration for software codecs. + A2dpCodecConfig* software_codec_config = nullptr; for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) { - VLOG(1) << __func__ << ": trying codec " << iter->name(); - p_sink = AttemptSourceCodecSelection(*iter, p_peer); - if (p_sink != nullptr) { - VLOG(1) << __func__ << ": selected codec " << iter->name(); + if (::bluetooth::audio::a2dp::provider::supports_codec( + iter->codecIndex())) { + continue; + } + + // Find the peer Sink for the codec + uint8_t new_codec_config[AVDT_CODEC_SIZE]; + const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink( + p_peer, iter->codecIndex(), ContentProtectFlag()); + + if (p_sink == nullptr) { + log::verbose("peer Sink for codec {} not found", iter->name()); + continue; + } + + if (!p_peer->GetCodecs()->setCodecConfig( + p_sink->codec_caps, true /* is_capability */, new_codec_config, + false /* select_current_codec */)) { + log::verbose("cannot set source codec {}", iter->name()); + } else { + log::verbose("feasible to set source codec {}", iter->name()); + software_codec_config = iter; break; } - VLOG(1) << __func__ << ": cannot use codec " << iter->name(); } - return p_sink; + + if (provider_codec_config.has_value() && + (software_codec_config == nullptr || + bta_av_co_should_select_hardware_codec(*software_codec_config, + provider_codec_config.value()))) { + // Select hardware offload codec configuration + return SelectProviderCodecConfiguration(p_peer, + provider_codec_config.value()); + } + + if (software_codec_config != nullptr) { + // Select software codec configuration + return AttemptSourceCodecSelection(*software_codec_config, p_peer); + } + + return nullptr; } const BtaAvCoSep* BtaAvCo::SelectSinkCodec(BtaAvCoPeer* p_peer) { @@ -1833,13 +1178,13 @@ const BtaAvCoSep* BtaAvCo::SelectSinkCodec(BtaAvCoPeer* p_peer) { // Select the codec for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) { - LOG_VERBOSE("%s: trying codec %s", __func__, iter->name().c_str()); + log::verbose("trying codec {}", iter->name()); p_source = AttemptSinkCodecSelection(*iter, p_peer); if (p_source != nullptr) { - LOG_VERBOSE("%s: selected codec %s", __func__, iter->name().c_str()); + log::verbose("selected codec {}", iter->name()); break; } - LOG_VERBOSE("%s: cannot use codec %s", __func__, iter->name().c_str()); + log::verbose("cannot use codec {}", iter->name()); } // NOTE: Unconditionally dispatch the event to make sure a callback with @@ -1849,80 +1194,23 @@ const BtaAvCoSep* BtaAvCo::SelectSinkCodec(BtaAvCoPeer* p_peer) { return p_source; } -BtaAvCoSep* BtaAvCo::FindPeerSink(BtaAvCoPeer* p_peer, - btav_a2dp_codec_index_t codec_index) { - if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) { - LOG_WARN("%s: invalid codec index for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); - return nullptr; - } - - // Find the peer Sink for the codec - for (size_t index = 0; index < p_peer->num_sup_sinks; index++) { - BtaAvCoSep* p_sink = &p_peer->sinks[index]; - btav_a2dp_codec_index_t peer_codec_index = - A2DP_SourceCodecIndex(p_sink->codec_caps); - if (peer_codec_index != codec_index) { - continue; - } - if (!AudioSepHasContentProtection(p_sink)) { - LOG_VERBOSE( - "%s: peer Sink for codec %s does not support " - "Content Protection", - __func__, A2DP_CodecIndexStr(codec_index)); - continue; - } - return p_sink; - } - return nullptr; -} - -BtaAvCoSep* BtaAvCo::FindPeerSource(BtaAvCoPeer* p_peer, - btav_a2dp_codec_index_t codec_index) { - if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) { - LOG_WARN("%s: invalid codec index for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); - return nullptr; - } - - // Find the peer Source for the codec - for (size_t index = 0; index < p_peer->num_sup_sources; index++) { - BtaAvCoSep* p_source = &p_peer->sources[index]; - btav_a2dp_codec_index_t peer_codec_index = - A2DP_SinkCodecIndex(p_source->codec_caps); - if (peer_codec_index != codec_index) { - continue; - } - if (!AudioSepHasContentProtection(p_source)) { - LOG_VERBOSE( - "%s: peer Source for codec %s does not support " - "Content Protection", - __func__, A2DP_CodecIndexStr(codec_index)); - continue; - } - return p_source; - } - return nullptr; -} - const BtaAvCoSep* BtaAvCo::AttemptSourceCodecSelection( const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) { uint8_t new_codec_config[AVDT_CODEC_SIZE]; - LOG_VERBOSE("%s", __func__); + log::verbose(""); // Find the peer Sink for the codec - BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex()); + BtaAvCoSep* p_sink = peer_cache_->FindPeerSink( + p_peer, codec_config.codecIndex(), ContentProtectFlag()); if (p_sink == nullptr) { - LOG_VERBOSE("%s: peer Sink for codec %s not found", __func__, - codec_config.name().c_str()); + log::verbose("peer Sink for codec {} not found", codec_config.name()); return nullptr; } if (!p_peer->GetCodecs()->setCodecConfig( p_sink->codec_caps, true /* is_capability */, new_codec_config, true /* select_current_codec */)) { - LOG_VERBOSE("%s: cannot set source codec %s", __func__, - codec_config.name().c_str()); + log::verbose("cannot set source codec {}", codec_config.name()); return nullptr; } p_peer->p_sink = p_sink; @@ -1937,20 +1225,19 @@ const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection( const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) { uint8_t new_codec_config[AVDT_CODEC_SIZE]; - LOG_VERBOSE("%s", __func__); + log::verbose(""); // Find the peer Source for the codec - BtaAvCoSep* p_source = FindPeerSource(p_peer, codec_config.codecIndex()); + BtaAvCoSep* p_source = peer_cache_->FindPeerSource( + p_peer, codec_config.codecIndex(), ContentProtectFlag()); if (p_source == nullptr) { - LOG_VERBOSE("%s: peer Source for codec %s not found", __func__, - codec_config.name().c_str()); + log::verbose("peer Source for codec {} not found", codec_config.name()); return nullptr; } if (!p_peer->GetCodecs()->setSinkCodecConfig( p_source->codec_caps, true /* is_capability */, new_codec_config, true /* select_current_codec */)) { - LOG_VERBOSE("%s: cannot set sink codec %s", __func__, - codec_config.name().c_str()); + log::verbose("cannot set sink codec {}", codec_config.name()); return nullptr; } p_peer->p_source = p_source; @@ -1962,12 +1249,11 @@ const BtaAvCoSep* BtaAvCo::AttemptSinkCodecSelection( } size_t BtaAvCo::UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer) { - LOG_VERBOSE("%s: peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); size_t updated_codecs = 0; for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) { - LOG_VERBOSE("%s: updating selectable codec %s", __func__, - iter->name().c_str()); + log::verbose("updating selectable codec {}", iter->name()); if (UpdateSelectableSourceCodec(*iter, p_peer)) { updated_codecs++; } @@ -1977,30 +1263,30 @@ size_t BtaAvCo::UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer) { bool BtaAvCo::UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) { - LOG_VERBOSE("%s: peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); // Find the peer Sink for the codec - const BtaAvCoSep* p_sink = FindPeerSink(p_peer, codec_config.codecIndex()); + const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink( + p_peer, codec_config.codecIndex(), ContentProtectFlag()); if (p_sink == nullptr) { // The peer Sink device does not support this codec return false; } if (!p_peer->GetCodecs()->setPeerSinkCodecCapabilities(p_sink->codec_caps)) { - LOG_WARN("%s: cannot update peer %s codec capabilities for %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), - A2DP_CodecName(p_sink->codec_caps)); + log::warn("cannot update peer {} codec capabilities for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), + A2DP_CodecName(p_sink->codec_caps)); return false; } return true; } size_t BtaAvCo::UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer) { - LOG_VERBOSE("%s: peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); size_t updated_codecs = 0; for (const auto& iter : p_peer->GetCodecs()->orderedSinkCodecs()) { - LOG_VERBOSE("%s: updating selectable codec %s", __func__, - iter->name().c_str()); + log::verbose("updating selectable codec {}", iter->name()); if (UpdateSelectableSinkCodec(*iter, p_peer)) { updated_codecs++; } @@ -2010,20 +1296,20 @@ size_t BtaAvCo::UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer) { bool BtaAvCo::UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer) { - LOG_VERBOSE("%s: peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); // Find the peer Source for the codec - const BtaAvCoSep* p_source = - FindPeerSource(p_peer, codec_config.codecIndex()); + const BtaAvCoSep* p_source = peer_cache_->FindPeerSource( + p_peer, codec_config.codecIndex(), ContentProtectFlag()); if (p_source == nullptr) { // The peer Source device does not support this codec return false; } if (!p_peer->GetCodecs()->setPeerSourceCodecCapabilities( p_source->codec_caps)) { - LOG_WARN("%s: cannot update peer %s codec capabilities for %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), - A2DP_CodecName(p_source->codec_caps)); + log::warn("cannot update peer {} codec capabilities for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr), + A2DP_CodecName(p_source->codec_caps)); return false; } return true; @@ -2033,18 +1319,16 @@ void BtaAvCo::SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, uint8_t num_protect, const uint8_t* p_protect_info) { - LOG_VERBOSE("%s: peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(new_codec_config).c_str()); - - std::lock_guard lock(codec_lock_); + log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + log::verbose("codec: {}", A2DP_CodecInfoString(new_codec_config)); - memcpy(codec_config_, new_codec_config, sizeof(codec_config_)); + std::lock_guard lock(peer_cache_->codec_lock_); + bta_av_legacy_state_.setCodecConfig(new_codec_config); memcpy(p_peer->codec_config, new_codec_config, AVDT_CODEC_SIZE); if (ContentProtectEnabled()) { // Check if this Sink supports SCMS - bool cp_active = BtaAvCo::AudioProtectHasScmst(num_protect, p_protect_info); + bool cp_active = AudioProtectHasScmst(num_protect, p_protect_info); p_peer->SetContentProtectActive(cp_active); } } @@ -2059,22 +1343,20 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer, bool restart_output = false; bool config_updated = false; - LOG(INFO) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << ", codec: " << A2DP_CodecInfoString(p_ota_codec_config); + log::info("peer_address={}, codec: {}", ADDRESS_TO_LOGGABLE_STR(p_peer->addr), + A2DP_CodecInfoString(p_ota_codec_config)); *p_restart_output = false; // Find the peer SEP codec to use - const BtaAvCoSep* p_sink = - FindPeerSink(p_peer, A2DP_SourceCodecIndex(p_ota_codec_config)); + const BtaAvCoSep* p_sink = peer_cache_->FindPeerSink( + p_peer, A2DP_SourceCodecIndex(p_ota_codec_config), ContentProtectFlag()); if ((p_peer->num_sup_sinks > 0) && (p_sink == nullptr)) { // There are no peer SEPs if we didn't do the discovery procedure yet. // We have all the information we need from the peer, so we can // proceed with the OTA codec configuration. - LOG(ERROR) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : cannot find peer SEP to configure"; + log::error("peer {} : cannot find peer SEP to configure", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); return false; } @@ -2083,15 +1365,14 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer, if (!p_peer->GetCodecs()->setCodecOtaConfig( p_ota_codec_config, &peer_params, result_codec_config, &restart_input, &restart_output, &config_updated)) { - LOG(ERROR) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(p_peer->addr) - << " : cannot set OTA config"; + log::error("peer {} : cannot set OTA config", + ADDRESS_TO_LOGGABLE_STR(p_peer->addr)); return false; } if (restart_output) { - VLOG(1) << __func__ << ": restart output for codec: " - << A2DP_CodecInfoString(result_codec_config); + log::verbose("restart output for codec: {}", + A2DP_CodecInfoString(result_codec_config)); *p_restart_output = true; p_peer->p_sink = p_sink; @@ -2109,8 +1390,9 @@ bool BtaAvCo::SetCodecOtaConfig(BtaAvCoPeer* p_peer, } void bta_av_co_init( - const std::vector& codec_priorities) { - bta_av_co_cb.Init(codec_priorities); + const std::vector& codec_priorities, + std::vector* supported_codecs) { + bta_av_co_cb.Init(codec_priorities, supported_codecs); } bool bta_av_co_is_supported_codec(btav_a2dp_codec_index_t codec_index) { @@ -2142,7 +1424,7 @@ void bta_av_co_audio_disc_res(tBTA_AV_HNDL bta_av_handle, static void bta_av_co_store_peer_codectype(const BtaAvCoPeer* p_peer) { int index, peer_codec_type = 0; const BtaAvCoSep* p_sink; - LOG_VERBOSE("%s", __func__); + log::verbose(""); for (index = 0; index < p_peer->num_sup_sinks; index++) { p_sink = &p_peer->sinks[index]; peer_codec_type |= A2DP_IotGetPeerSinkCodecType(p_sink->codec_caps); @@ -2152,16 +1434,69 @@ static void bta_av_co_store_peer_codectype(const BtaAvCoPeer* p_peer) { peer_codec_type, IOT_CONF_BYTE_NUM_1); } +static bool bta_av_co_should_select_hardware_codec( + const A2dpCodecConfig& software_config, + const ::bluetooth::audio::a2dp::provider::a2dp_configuration& + hardware_config) { + btav_a2dp_codec_index_t software_codec_index = software_config.codecIndex(); + btav_a2dp_codec_index_t hardware_offload_index = + hardware_config.codec_parameters.codec_type; + + // Prioritize any offload codec except SBC and AAC + if (A2DP_GetCodecType(hardware_config.codec_config) == + A2DP_MEDIA_CT_NON_A2DP) { + log::verbose("select hardware codec: {}", + A2DP_CodecIndexStr(hardware_offload_index)); + return true; + } + // Prioritize LDAC, AptX HD and AptX over AAC and SBC offload codecs + if (software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC || + software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD || + software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) { + log::verbose("select software codec: {}", + A2DP_CodecIndexStr(software_codec_index)); + return false; + } + // Prioritize AAC offload + if (hardware_offload_index == BTAV_A2DP_CODEC_INDEX_SOURCE_AAC) { + log::verbose("select hardware codec: {}", + A2DP_CodecIndexStr(hardware_offload_index)); + return true; + } + // Prioritize AAC software + if (software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_AAC) { + log::verbose("select software codec: {}", + A2DP_CodecIndexStr(software_codec_index)); + return false; + } + // Prioritize SBC offload + if (hardware_offload_index == BTAV_A2DP_CODEC_INDEX_SOURCE_SBC) { + log::verbose("select hardware codec: {}", + A2DP_CodecIndexStr(hardware_offload_index)); + return true; + } + // Prioritize SBC software + if (software_codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_SBC) { + log::verbose("select software codec: {}", + A2DP_CodecIndexStr(software_codec_index)); + return false; + } + log::error("select unknown software codec: {}", + A2DP_CodecIndexStr(software_codec_index)); + return false; +} + tA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid, uint8_t* p_num_protect, uint8_t* p_protect_info) { - uint16_t peer_uuid = bta_av_co_cb.FindPeerUuid(bta_av_handle); + uint16_t peer_uuid = bta_av_co_cb.peer_cache_->FindPeerUuid(bta_av_handle); - LOG_VERBOSE("%s: peer %s bta_av_handle=0x%x peer_uuid=0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, peer_uuid); + log::verbose("peer {} bta_av_handle=0x{:x} peer_uuid=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, + peer_uuid); switch (peer_uuid) { case UUID_SERVCLASS_AUDIO_SOURCE: @@ -2175,9 +1510,8 @@ tA2DP_STATUS bta_av_co_audio_getconfig(tBTA_AV_HNDL bta_av_handle, default: break; } - LOG_ERROR("%s: peer %s : Invalid peer UUID: 0x%x for bta_av_handle 0x%x", - __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address), peer_uuid, - bta_av_handle); + log::error("peer {} : Invalid peer UUID: 0x{:x} for bta_av_handle 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), peer_uuid, bta_av_handle); return A2DP_FAIL; } @@ -2269,7 +1603,7 @@ int bta_av_co_get_encoder_effective_frame_size() { btav_a2dp_scmst_info_t bta_av_co_get_scmst_info( const RawAddress& peer_address) { - BtaAvCoPeer* p_peer = bta_av_co_cb.FindPeer(peer_address); + BtaAvCoPeer* p_peer = bta_av_co_cb.peer_cache_->FindPeer(peer_address); CHECK(p_peer != nullptr); btav_a2dp_scmst_info_t scmst_info{}; scmst_info.enable_status = BTAV_A2DP_SCMST_DISABLED; diff --git a/system/btif/co/bta_av_co_peer.cc b/system/btif/co/bta_av_co_peer.cc new file mode 100644 index 0000000000000000000000000000000000000000..3cfbb3b1489adb09bf1d93bbb77df25282c79383 --- /dev/null +++ b/system/btif/co/bta_av_co_peer.cc @@ -0,0 +1,264 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "btif/include/bta_av_co_peer.h" + +#include + +#include "bta/include/bta_av_api.h" +#include "include/check.h" + +using namespace bluetooth; + +// Macro to convert BTA AV audio handle to index and vice versa +#define BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle) \ + (((bta_av_handle) & (~BTA_AV_CHNL_MSK)) - 1) +#define BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(index) \ + (((index) + 1) | BTA_AV_CHNL_AUDIO) + +BtaAvCoPeer::BtaAvCoPeer() + : addr(RawAddress::kEmpty), + num_sinks(0), + num_sources(0), + num_seps(0), + num_rx_sinks(0), + num_rx_sources(0), + num_sup_sinks(0), + num_sup_sources(0), + p_sink(nullptr), + p_source(nullptr), + codec_config{}, + acceptor(false), + reconfig_needed(false), + opened(false), + mtu(0), + uuid_to_connect(0), + bta_av_handle_(0), + codecs_(nullptr), + content_protect_active_(false) { + Reset(0); +} + +void BtaAvCoPeer::Init( + const std::vector& codec_priorities) { + Reset(bta_av_handle_); + // Reset the current config + codecs_ = new A2dpCodecs(codec_priorities); + codecs_->init(); + A2DP_InitDefaultCodec(codec_config); +} + +void BtaAvCoPeer::Reset(tBTA_AV_HNDL bta_av_handle) { + addr = RawAddress::kEmpty; + for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sinks); i++) { + BtaAvCoSep& sink = sinks[i]; + sink.Reset(); + } + for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(sources); i++) { + BtaAvCoSep& source = sources[i]; + source.Reset(); + } + num_sinks = 0; + num_sources = 0; + num_seps = 0; + num_rx_sinks = 0; + num_rx_sources = 0; + num_sup_sinks = 0; + num_sup_sources = 0; + p_sink = nullptr; + p_source = nullptr; + memset(codec_config, 0, sizeof(codec_config)); + acceptor = false; + reconfig_needed = false; + opened = false; + mtu = 0; + uuid_to_connect = 0; + + bta_av_handle_ = bta_av_handle; + delete codecs_; + codecs_ = nullptr; + content_protect_active_ = false; +} + +void BtaAvCoPeerCache::Init( + const std::vector& codec_priorities, + std::vector* supported_codecs) { + std::lock_guard lock(codec_lock_); + + codec_priorities_ = codec_priorities; + + for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { + BtaAvCoPeer* p_peer = &peers_[i]; + p_peer->Init(codec_priorities); + } +} + +void BtaAvCoPeerCache::Reset() { + codec_priorities_.clear(); + + // Reset the peers and initialize the handles + for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { + BtaAvCoPeer* p_peer = &peers_[i]; + p_peer->Reset(BTA_AV_CO_AUDIO_INDEX_TO_HANDLE(i)); + } +} + +BtaAvCoPeer* BtaAvCoPeerCache::FindPeer(const RawAddress& peer_address) { + for (size_t i = 0; i < BTA_AV_CO_NUM_ELEMENTS(peers_); i++) { + BtaAvCoPeer* p_peer = &peers_[i]; + if (p_peer->addr == peer_address) { + return p_peer; + } + } + return nullptr; +} + +BtaAvCoSep* BtaAvCoPeerCache::FindPeerSource( + BtaAvCoPeer* p_peer, btav_a2dp_codec_index_t codec_index, + const uint8_t content_protect_flag) { + if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) { + log::warn("invalid codec index for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + return nullptr; + } + + // Find the peer Source for the codec + for (size_t index = 0; index < p_peer->num_sup_sources; index++) { + BtaAvCoSep* p_source = &p_peer->sources[index]; + btav_a2dp_codec_index_t peer_codec_index = + A2DP_SinkCodecIndex(p_source->codec_caps); + if (peer_codec_index != codec_index) { + continue; + } + if (!AudioSepHasContentProtection(p_source, content_protect_flag)) { + log::verbose( + "peer Source for codec {} does not support Content Protection", + A2DP_CodecIndexStr(codec_index)); + continue; + } + return p_source; + } + return nullptr; +} + +BtaAvCoSep* BtaAvCoPeerCache::FindPeerSink(BtaAvCoPeer* p_peer, + btav_a2dp_codec_index_t codec_index, + const uint8_t content_protect_flag) { + if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) { + log::warn("invalid codec index for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + return nullptr; + } + + // Find the peer Sink for the codec + for (size_t index = 0; index < p_peer->num_sup_sinks; index++) { + BtaAvCoSep* p_sink = &p_peer->sinks[index]; + btav_a2dp_codec_index_t peer_codec_index = + A2DP_SourceCodecIndex(p_sink->codec_caps); + if (peer_codec_index != codec_index) { + continue; + } + if (!AudioSepHasContentProtection(p_sink, content_protect_flag)) { + log::warn("invalid codec index for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + continue; + } + return p_sink; + } + return nullptr; +} + +BtaAvCoPeer* BtaAvCoPeerCache::FindPeer(tBTA_AV_HNDL bta_av_handle) { + uint8_t index; + + index = BTA_AV_CO_AUDIO_HANDLE_TO_INDEX(bta_av_handle); + + log::verbose("bta_av_handle = 0x{:x} index = {}", bta_av_handle, index); + + // Sanity check + if (index >= BTA_AV_CO_NUM_ELEMENTS(peers_)) { + log::error("peer index {} for BTA AV handle 0x{:x} is out of bounds", index, + bta_av_handle); + return nullptr; + } + + return &peers_[index]; +} + +BtaAvCoPeer* BtaAvCoPeerCache::FindPeerAndUpdate( + tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) { + log::verbose("peer {} bta_av_handle = 0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle); + + BtaAvCoPeer* p_peer = FindPeer(bta_av_handle); + if (p_peer == nullptr) { + log::error("peer entry for BTA AV handle 0x{:x} peer {} not found", + bta_av_handle, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + return nullptr; + } + + log::verbose("peer {} bta_av_handle = 0x{:x} previous address {}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_av_handle, + ADDRESS_TO_LOGGABLE_CSTR(p_peer->addr)); + p_peer->addr = peer_address; + return p_peer; +} + +uint16_t BtaAvCoPeerCache::FindPeerUuid(tBTA_AV_HNDL bta_av_handle) { + BtaAvCoPeer* p_peer = FindPeer(bta_av_handle); + if (p_peer == nullptr) { + return 0; + } + return p_peer->uuid_to_connect; +} + +bool ContentProtectIsScmst(const uint8_t* p_protect_info) { + log::verbose(""); + + if (*p_protect_info >= AVDT_CP_LOSC) { + uint16_t cp_id; + p_protect_info++; + STREAM_TO_UINT16(cp_id, p_protect_info); + if (cp_id == AVDT_CP_SCMS_T_ID) { + log::verbose("SCMS-T found"); + return true; + } + } + return false; +} + +bool AudioProtectHasScmst(uint8_t num_protect, const uint8_t* p_protect_info) { + log::verbose(""); + while (num_protect--) { + if (ContentProtectIsScmst(p_protect_info)) return true; + // Move to the next Content Protect schema + p_protect_info += *p_protect_info + 1; + } + log::verbose("SCMS-T not found"); + return false; +} + +bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep, + const uint8_t content_protect_flag) { + log::verbose(""); + + // Check if content protection is enabled for this stream + if (content_protect_flag != AVDT_CP_SCMS_COPY_FREE) { + return AudioProtectHasScmst(p_sep->num_protect, p_sep->protect_info); + } + + log::verbose("not required"); + return true; +} diff --git a/system/btif/co/bta_hh_co.cc b/system/btif/co/bta_hh_co.cc index b8fc689e2a38ff4b38f04614d141480c9938aac6..7b6a6e1e8271ab8abd5d5581ddd246efa83596cf 100644 --- a/system/btif/co/bta_hh_co.cc +++ b/system/btif/co/bta_hh_co.cc @@ -30,13 +30,15 @@ #include -#include "bta_api.h" #include "bta_hh_api.h" #include "btif_hh.h" #include "device/include/controller.h" +#include "include/check.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "osi/include/osi.h" +#include "storage/config_keys.h" #include "types/raw_address.h" const char* dev_path = "/dev/uhid"; @@ -51,6 +53,8 @@ static tBTA_HH_RPT_CACHE_ENTRY sReportCache[BTA_HH_NV_LOAD_MAX]; /* Max number of polling interrupt allowed */ #define BTA_HH_UHID_INTERRUPT_COUNT_MAX 100 +using namespace bluetooth; + static const bthh_report_type_t map_rtype_uhid_hh[] = { BTHH_FEATURE_REPORT, BTHH_OUTPUT_REPORT, BTHH_INPUT_REPORT}; @@ -58,27 +62,25 @@ static void* btif_hh_poll_event_thread(void* arg); void uhid_set_non_blocking(int fd) { int opts = fcntl(fd, F_GETFL); - if (opts < 0) - LOG_ERROR("%s() Getting flags failed (%s)", __func__, strerror(errno)); + if (opts < 0) log::error("Getting flags failed ({})", strerror(errno)); opts |= O_NONBLOCK; if (fcntl(fd, F_SETFL, opts) < 0) - LOG_VERBOSE("%s() Setting non-blocking flag failed (%s)", __func__, - strerror(errno)); + log::verbose("Setting non-blocking flag failed ({})", strerror(errno)); } static bool uhid_feature_req_handler(btif_hh_device_t* p_dev, struct uhid_feature_req& req) { - LOG_DEBUG("Report type = %d, id = %d", req.rtype, req.rnum); + log::debug("Report type = {}, id = {}", req.rtype, req.rnum); if (req.rtype > UHID_INPUT_REPORT) { - LOG_ERROR("Invalid report type %d", req.rtype); + log::error("Invalid report type {}", req.rtype); return false; } if (p_dev->get_rpt_id_queue == nullptr) { - LOG_ERROR("Queue is not initialized"); + log::error("Queue is not initialized"); return false; } @@ -87,7 +89,7 @@ static bool uhid_feature_req_handler(btif_hh_device_t* p_dev, if (!fixed_queue_try_enqueue(p_dev->get_rpt_id_queue, (void*)context)) { osi_free(context); - LOG_ERROR("Queue is full, dropping event %d", req.id); + log::error("Queue is full, dropping event {}", req.id); return false; } @@ -98,15 +100,15 @@ static bool uhid_feature_req_handler(btif_hh_device_t* p_dev, #if ENABLE_UHID_SET_REPORT static bool uhid_set_report_req_handler(btif_hh_device_t* p_dev, struct uhid_set_report_req& req) { - LOG_DEBUG("Report type = %d, id = %d", req.rtype, req.rnum); + log::debug("Report type = {}, id = {}", req.rtype, req.rnum); if (req.rtype > UHID_INPUT_REPORT) { - LOG_ERROR("Invalid report type %d", req.rtype); + log::error("Invalid report type {}", req.rtype); return false; } if (p_dev->set_rpt_id_queue == nullptr) { - LOG_ERROR("Queue is not initialized"); + log::error("Queue is not initialized"); return false; } @@ -115,7 +117,7 @@ static bool uhid_set_report_req_handler(btif_hh_device_t* p_dev, if (!fixed_queue_try_enqueue(p_dev->set_rpt_id_queue, (void*)context)) { osi_free(context); - LOG_ERROR("Queue is full, dropping event %d", req.id); + log::error("Queue is full, dropping event {}", req.id); return false; } @@ -131,11 +133,10 @@ static int uhid_write(int fd, const struct uhid_event* ev) { if (ret < 0) { int rtn = -errno; - LOG_ERROR("%s: Cannot write to uhid:%s", __func__, strerror(errno)); + log::error("Cannot write to uhid:{}", strerror(errno)); return rtn; } else if (ret != (ssize_t)sizeof(*ev)) { - LOG_ERROR("%s: Wrong size written to uhid: %zd != %zu", __func__, ret, - sizeof(*ev)); + log::error("Wrong size written to uhid: {} != {}", ret, sizeof(*ev)); return -EFAULT; } @@ -153,39 +154,39 @@ static int uhid_read_event(btif_hh_device_t* p_dev) { OSI_NO_INTR(ret = read(p_dev->fd, &ev, sizeof(ev))); if (ret == 0) { - LOG_ERROR("%s: Read HUP on uhid-cdev %s", __func__, strerror(errno)); + log::error("Read HUP on uhid-cdev {}", strerror(errno)); return -EFAULT; } else if (ret < 0) { - LOG_ERROR("%s: Cannot read uhid-cdev: %s", __func__, strerror(errno)); + log::error("Cannot read uhid-cdev: {}", strerror(errno)); return -errno; } switch (ev.type) { case UHID_START: - LOG_VERBOSE("UHID_START from uhid-dev\n"); + log::verbose("UHID_START from uhid-dev\n"); p_dev->ready_for_data = true; break; case UHID_STOP: - LOG_VERBOSE("UHID_STOP from uhid-dev\n"); + log::verbose("UHID_STOP from uhid-dev\n"); p_dev->ready_for_data = false; break; case UHID_OPEN: - LOG_VERBOSE("UHID_OPEN from uhid-dev\n"); + log::verbose("UHID_OPEN from uhid-dev\n"); p_dev->ready_for_data = true; break; case UHID_CLOSE: - LOG_VERBOSE("UHID_CLOSE from uhid-dev\n"); + log::verbose("UHID_CLOSE from uhid-dev\n"); p_dev->ready_for_data = false; break; case UHID_OUTPUT: if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.output))) { - LOG_ERROR("%s: Invalid size read from uhid-dev: %zd < %zu", __func__, - ret, sizeof(ev.type) + sizeof(ev.u.output)); + log::error("Invalid size read from uhid-dev: {} < {}", ret, + sizeof(ev.type) + sizeof(ev.u.output)); return -EFAULT; } - LOG_VERBOSE("UHID_OUTPUT: Report type = %d, report_size = %d", - ev.u.output.rtype, ev.u.output.size); + log::verbose("UHID_OUTPUT: Report type = {}, report_size = {}", + ev.u.output.rtype, ev.u.output.size); // Send SET_REPORT with feature report if the report type in output event // is FEATURE if (ev.u.output.rtype == UHID_FEATURE_REPORT) @@ -194,22 +195,21 @@ static int uhid_read_event(btif_hh_device_t* p_dev) { else if (ev.u.output.rtype == UHID_OUTPUT_REPORT) btif_hh_senddata(p_dev, ev.u.output.size, ev.u.output.data); else - LOG_ERROR("%s: UHID_OUTPUT: Invalid report type = %d", __func__, - ev.u.output.rtype); + log::error("UHID_OUTPUT: Invalid report type = {}", ev.u.output.rtype); break; case UHID_OUTPUT_EV: if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.output_ev))) { - LOG_ERROR("%s: Invalid size read from uhid-dev: %zd < %zu", __func__, - ret, sizeof(ev.type) + sizeof(ev.u.output_ev)); + log::error("Invalid size read from uhid-dev: {} < {}", ret, + sizeof(ev.type) + sizeof(ev.u.output_ev)); return -EFAULT; } - LOG_VERBOSE("UHID_OUTPUT_EV from uhid-dev\n"); + log::verbose("UHID_OUTPUT_EV from uhid-dev\n"); break; case UHID_FEATURE: // UHID_GET_REPORT if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.feature))) { - LOG_ERROR("UHID_GET_REPORT: Invalid size read from uhid-dev: %zd < %zu", - ret, sizeof(ev.type) + sizeof(ev.u.feature)); + log::error("UHID_GET_REPORT: Invalid size read from uhid-dev: {} < {}", + ret, sizeof(ev.type) + sizeof(ev.u.feature)); return -EFAULT; } @@ -222,8 +222,8 @@ static int uhid_read_event(btif_hh_device_t* p_dev) { #if ENABLE_UHID_SET_REPORT case UHID_SET_REPORT: { if (ret < (ssize_t)(sizeof(ev.type) + sizeof(ev.u.set_report))) { - LOG_ERROR("UHID_SET_REPORT: Invalid size read from uhid-dev: %zd < %zu", - ret, sizeof(ev.type) + sizeof(ev.u.set_report)); + log::error("UHID_SET_REPORT: Invalid size read from uhid-dev: {} < {}", + ret, sizeof(ev.type) + sizeof(ev.u.set_report)); return -EFAULT; } @@ -235,7 +235,7 @@ static int uhid_read_event(btif_hh_device_t* p_dev) { #endif // ENABLE_UHID_SET_REPORT default: - LOG_ERROR("Invalid event from uhid-dev: %u\n", ev.type); + log::error("Invalid event from uhid-dev: {}\n", ev.type); } return 0; @@ -252,17 +252,17 @@ static int uhid_read_event(btif_hh_device_t* p_dev) { ******************************************************************************/ static inline pthread_t create_thread(void* (*start_routine)(void*), void* arg) { - LOG_VERBOSE("create_thread: entered"); + log::verbose("create_thread: entered"); pthread_attr_t thread_attr; pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); pthread_t thread_id = -1; if (pthread_create(&thread_id, &thread_attr, start_routine, arg) != 0) { - LOG_ERROR("pthread_create : %s", strerror(errno)); + log::error("pthread_create : {}", strerror(errno)); return -1; } - LOG_VERBOSE("create_thread: thread created successfully"); + log::verbose("create_thread: thread created successfully"); return thread_id; } @@ -272,8 +272,8 @@ static void uhid_fd_close(btif_hh_device_t* p_dev) { struct uhid_event ev = {}; ev.type = UHID_DESTROY; uhid_write(p_dev->fd, &ev); - LOG_DEBUG("Closing fd=%d, addr:%s", p_dev->fd, - ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr)); + log::debug("Closing fd={}, addr:{}", p_dev->fd, + ADDRESS_TO_LOGGABLE_CSTR(p_dev->link_spec)); close(p_dev->fd); p_dev->fd = -1; } @@ -284,7 +284,7 @@ static bool uhid_fd_open(btif_hh_device_t* p_dev) { if (p_dev->fd < 0) { p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC); if (p_dev->fd < 0) { - LOG_ERROR("Failed to open uhid, err:%s", strerror(errno)); + log::error("Failed to open uhid, err:{}", strerror(errno)); return false; } } @@ -315,7 +315,7 @@ static void* btif_hh_poll_event_thread(void* arg) { struct sched_param sched_params; sched_params.sched_priority = THREAD_NORMAL_PRIORITY; if (sched_setscheduler(pid, SCHED_OTHER, &sched_params)) { - LOG_ERROR("Failed to set thread priority to normal: %s", strerror(errno)); + log::error("Failed to set thread priority to normal: {}", strerror(errno)); p_dev->hh_poll_thread_id = -1; p_dev->hh_keep_polling = 0; uhid_fd_close(p_dev); @@ -323,8 +323,8 @@ static void* btif_hh_poll_event_thread(void* arg) { } pthread_setname_np(pthread_self(), BT_HH_THREAD); - LOG_DEBUG("Host hid polling thread created name:%s pid:%d fd:%d", - BT_HH_THREAD, pid, p_dev->fd); + log::debug("Host hid polling thread created name:{} pid:{} fd:{}", + BT_HH_THREAD, pid, p_dev->fd); pfds[0].fd = p_dev->fd; pfds[0].events = POLLIN; @@ -338,29 +338,29 @@ static void* btif_hh_poll_event_thread(void* arg) { do { if (counter++ > BTA_HH_UHID_INTERRUPT_COUNT_MAX) { - LOG_ERROR("Polling interrupted"); + log::error("Polling interrupted"); break; } ret = poll(pfds, 1, BTA_HH_UHID_POLL_PERIOD_MS); } while (ret == -1 && errno == EINTR); if (ret < 0) { - LOG_ERROR("Cannot poll for fds: %s\n", strerror(errno)); + log::error("Cannot poll for fds: {}\n", strerror(errno)); break; } if (pfds[0].revents & POLLIN) { - LOG_VERBOSE("%s: POLLIN", __func__); + log::verbose("POLLIN"); ret = uhid_read_event(p_dev); if (ret != 0) { - LOG_ERROR("Unhandled UHID event"); + log::error("Unhandled UHID event"); break; } } } /* Todo: Disconnect if loop exited due to a failure */ - LOG_INFO("Polling thread stopped for device %s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr)); + log::info("Polling thread stopped for device {}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev->link_spec)); p_dev->hh_poll_thread_id = -1; p_dev->hh_keep_polling = 0; uhid_fd_close(p_dev); @@ -368,14 +368,14 @@ static void* btif_hh_poll_event_thread(void* arg) { } int bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len) { - LOG_VERBOSE("%s: UHID write %d", __func__, len); + log::verbose("UHID write {}", len); struct uhid_event ev; memset(&ev, 0, sizeof(ev)); ev.type = UHID_INPUT; ev.u.input.size = len; if (len > sizeof(ev.u.input.data)) { - LOG_WARN("%s: Report size greater than allowed size", __func__); + log::warn("Report size greater than allowed size"); return -1; } memcpy(ev.u.input.data, rpt, len); @@ -398,7 +398,7 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, btif_hh_device_t* p_dev = NULL; if (dev_handle == BTA_HH_INVALID_HANDLE) { - LOG_WARN("dev_handle (%d) is invalid", dev_handle); + log::warn("dev_handle ({}) is invalid", dev_handle); return false; } @@ -407,10 +407,10 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->dev_handle == dev_handle) { // We found a device with the same handle. Must be a device reconnected. - LOG_INFO( - "Found an existing device with the same handle dev_status=%d, " - "address=%s, attr_mask=0x%04x, sub_class=0x%02x, app_id=%d", - p_dev->dev_status, ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr), + log::info( + "Found an existing device with the same handle dev_status={}, " + "address={}, attr_mask=0x{:04x}, sub_class=0x{:02x}, app_id={}", + p_dev->dev_status, ADDRESS_TO_LOGGABLE_CSTR(p_dev->link_spec), p_dev->attr_mask, p_dev->sub_class, p_dev->app_id); if (!uhid_fd_open(p_dev)) { @@ -447,7 +447,7 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, } if (p_dev == NULL) { - LOG_ERROR("Too many HID devices are connected"); + log::error("Too many HID devices are connected"); return false; } @@ -459,7 +459,7 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, CHECK(p_dev->set_rpt_id_queue); #endif // ENABLE_UHID_SET_REPORT - LOG_DEBUG("Return device status %d", p_dev->dev_status); + log::debug("Return device status {}", p_dev->dev_status); return true; } @@ -475,8 +475,9 @@ bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, * Returns void. ******************************************************************************/ void bta_hh_co_close(btif_hh_device_t* p_dev) { - LOG_INFO("Closing device handle=%d, status=%d, address=%s", p_dev->dev_handle, - p_dev->dev_status, ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr)); + log::info("Closing device handle={}, status={}, address={}", + p_dev->dev_handle, p_dev->dev_status, + ADDRESS_TO_LOGGABLE_CSTR(p_dev->link_spec)); /* Clear the queues */ fixed_queue_flush(p_dev->get_rpt_id_queue, osi_free); @@ -515,18 +516,18 @@ void bta_hh_co_close(btif_hh_device_t* p_dev) { ******************************************************************************/ void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len, tBTA_HH_PROTO_MODE mode, uint8_t sub_class, - uint8_t ctry_code, UNUSED_ATTR const RawAddress& peer_addr, - uint8_t app_id) { + uint8_t ctry_code, + UNUSED_ATTR const tAclLinkSpec& link_spec, uint8_t app_id) { btif_hh_device_t* p_dev; - LOG_VERBOSE( - "%s: dev_handle = %d, subclass = 0x%02X, mode = %d, " - "ctry_code = %d, app_id = %d", - __func__, dev_handle, sub_class, mode, ctry_code, app_id); + log::verbose( + "dev_handle = {}, subclass = 0x{:02X}, mode = {}, ctry_code = {}, app_id " + "= {}", + dev_handle, sub_class, mode, ctry_code, app_id); p_dev = btif_hh_find_connected_dev_by_handle(dev_handle); if (p_dev == NULL) { - LOG_WARN("%s: Error: unknown HID device handle %d", __func__, dev_handle); + log::warn("Error: unknown HID device handle {}", dev_handle); return; } @@ -544,8 +545,8 @@ void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len, if ((p_dev->fd >= 0) && p_dev->ready_for_data) { bta_hh_co_write(p_dev->fd, p_rpt, len); } else { - LOG_WARN("%s: Error: fd = %d, ready %d, len = %d", __func__, p_dev->fd, - p_dev->ready_for_data, len); + log::warn("Error: fd = {}, ready {}, len = {}", p_dev->fd, + p_dev->ready_for_data, len); } } @@ -570,17 +571,16 @@ void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name, struct uhid_event ev; if (p_dev->fd < 0) { - LOG_WARN("%s: Error: fd = %d, dscp_len = %d", __func__, p_dev->fd, - dscp_len); + log::warn("Error: fd = {}, dscp_len = {}", p_dev->fd, dscp_len); return; } - LOG_WARN("%s: fd = %d, name = [%s], dscp_len = %d", __func__, p_dev->fd, - dev_name, dscp_len); - LOG_WARN( - "%s: vendor_id = 0x%04x, product_id = 0x%04x, version= 0x%04x," - "ctry_code=0x%02x", - __func__, vendor_id, product_id, version, ctry_code); + log::warn("fd = {}, name = [{}], dscp_len = {}", p_dev->fd, dev_name, + dscp_len); + log::warn( + "vendor_id = 0x{:04x}, product_id = 0x{:04x}, version= " + "0x{:04x},ctry_code=0x{:02x}", + vendor_id, product_id, version, ctry_code); // Create and send hid descriptor to kernel memset(&ev, 0, sizeof(ev)); @@ -588,7 +588,7 @@ void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name, strlcpy((char*)ev.u.create.name, dev_name, sizeof(ev.u.create.name)); // TODO (b/258090765) fix: ToString -> ToColonSepHexString snprintf((char*)ev.u.create.uniq, sizeof(ev.u.create.uniq), "%s", - p_dev->bd_addr.ToString().c_str()); + p_dev->link_spec.addrt.bda.ToString().c_str()); // Write controller address to phys field to correlate the hid device with a // specific bluetooth controller. @@ -606,11 +606,11 @@ void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name, ev.u.create.country = ctry_code; result = uhid_write(p_dev->fd, &ev); - LOG_WARN("%s: wrote descriptor to fd = %d, dscp_len = %d, result = %d", - __func__, p_dev->fd, dscp_len, result); + log::warn("wrote descriptor to fd = {}, dscp_len = {}, result = {}", + p_dev->fd, dscp_len, result); if (result) { - LOG_WARN("%s: Error: failed to send DSCP, result = %d", __func__, result); + log::warn("Error: failed to send DSCP, result = {}", result); /* The HID report descriptor is corrupted. Close the driver. */ close(p_dev->fd); @@ -630,29 +630,29 @@ void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name, ******************************************************************************/ void bta_hh_co_set_rpt_rsp(uint8_t dev_handle, uint8_t status) { #if ENABLE_UHID_SET_REPORT - LOG_VERBOSE("dev_handle = %d", dev_handle); + log::verbose("dev_handle = {}", dev_handle); btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_handle(dev_handle); if (p_dev == nullptr) { - LOG_WARN("Unknown HID device handle %d", dev_handle); + log::warn("Unknown HID device handle {}", dev_handle); return; } if (!p_dev->set_rpt_id_queue) { - LOG_WARN("Missing UHID_SET_REPORT id queue"); + log::warn("Missing UHID_SET_REPORT id queue"); return; } // Send the HID set report reply to the kernel. if (p_dev->fd < 0) { - LOG_ERROR("Unexpected Set Report response"); + log::error("Unexpected Set Report response"); return; } uint32_t* context = (uint32_t*)fixed_queue_try_dequeue(p_dev->set_rpt_id_queue); if (context == nullptr) { - LOG_WARN("No pending UHID_SET_REPORT"); + log::warn("No pending UHID_SET_REPORT"); return; } @@ -669,7 +669,7 @@ void bta_hh_co_set_rpt_rsp(uint8_t dev_handle, uint8_t status) { osi_free(context); #else - LOG_ERROR("UHID_SET_REPORT_REPLY not supported"); + log::error("UHID_SET_REPORT_REPLY not supported"); #endif // ENABLE_UHID_SET_REPORT } @@ -687,34 +687,34 @@ void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status, const uint8_t* p_rpt, uint16_t len) { btif_hh_device_t* p_dev; - LOG_VERBOSE("dev_handle = %d, status = %d", dev_handle, status); + log::verbose("dev_handle = {}, status = {}", dev_handle, status); p_dev = btif_hh_find_connected_dev_by_handle(dev_handle); if (p_dev == nullptr) { - LOG_WARN("Unknown HID device handle %d", dev_handle); + log::warn("Unknown HID device handle {}", dev_handle); return; } if (!p_dev->get_rpt_id_queue) { - LOG_WARN("Missing UHID_GET_REPORT id queue"); + log::warn("Missing UHID_GET_REPORT id queue"); return; } // Send the HID report to the kernel. if (p_dev->fd < 0) { - LOG_WARN("Unexpected Get Report response"); + log::warn("Unexpected Get Report response"); return; } uint32_t* context = (uint32_t*)fixed_queue_try_dequeue(p_dev->get_rpt_id_queue); if (context == nullptr) { - LOG_WARN("No pending UHID_GET_REPORT"); + log::warn("No pending UHID_GET_REPORT"); return; } if (len == 0 || len > UHID_DATA_MAX) { - LOG_WARN("Invalid report size = %d", len); + log::warn("Invalid report size = {}", len); return; } @@ -750,27 +750,30 @@ void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status, * Returns void. * ******************************************************************************/ -void bta_hh_le_co_rpt_info(const RawAddress& remote_bda, +void bta_hh_le_co_rpt_info(const tAclLinkSpec& link_spec, tBTA_HH_RPT_CACHE_ENTRY* p_entry, UNUSED_ATTR uint8_t app_id) { unsigned idx = 0; - std::string addrstr = remote_bda.ToString(); + std::string addrstr = link_spec.addrt.ToString(); const char* bdstr = addrstr.c_str(); - size_t len = btif_config_get_bin_length(bdstr, "HidReport"); + size_t len = btif_config_get_bin_length(bdstr, BTIF_STORAGE_KEY_HID_REPORT); if (len >= sizeof(tBTA_HH_RPT_CACHE_ENTRY) && len <= sizeof(sReportCache)) { - btif_config_get_bin(bdstr, "HidReport", (uint8_t*)sReportCache, &len); + btif_config_get_bin(bdstr, BTIF_STORAGE_KEY_HID_REPORT, + (uint8_t*)sReportCache, &len); idx = len / sizeof(tBTA_HH_RPT_CACHE_ENTRY); } if (idx < BTA_HH_NV_LOAD_MAX) { memcpy(&sReportCache[idx++], p_entry, sizeof(tBTA_HH_RPT_CACHE_ENTRY)); - btif_config_set_bin(bdstr, "HidReport", (const uint8_t*)sReportCache, + btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_HID_REPORT, + (const uint8_t*)sReportCache, idx * sizeof(tBTA_HH_RPT_CACHE_ENTRY)); - btif_config_set_int(bdstr, "HidReportVersion", BTA_HH_CACHE_REPORT_VERSION); - LOG_VERBOSE("%s() - Saving report; dev=%s, idx=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(remote_bda), idx); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_REPORT_VERSION, + BTA_HH_CACHE_REPORT_VERSION); + log::verbose("Saving report; dev={}, idx={}", + ADDRESS_TO_LOGGABLE_CSTR(link_spec), idx); } } @@ -790,30 +793,32 @@ void bta_hh_le_co_rpt_info(const RawAddress& remote_bda, * Returns the cached report array * ******************************************************************************/ -tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const RawAddress& remote_bda, +tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const tAclLinkSpec& link_spec, uint8_t* p_num_rpt, UNUSED_ATTR uint8_t app_id) { - std::string addrstr = remote_bda.ToString(); + std::string addrstr = link_spec.addrt.ToString(); const char* bdstr = addrstr.c_str(); - size_t len = btif_config_get_bin_length(bdstr, "HidReport"); + size_t len = btif_config_get_bin_length(bdstr, BTIF_STORAGE_KEY_HID_REPORT); if (!p_num_rpt || len < sizeof(tBTA_HH_RPT_CACHE_ENTRY)) return NULL; if (len > sizeof(sReportCache)) len = sizeof(sReportCache); - btif_config_get_bin(bdstr, "HidReport", (uint8_t*)sReportCache, &len); + btif_config_get_bin(bdstr, BTIF_STORAGE_KEY_HID_REPORT, + (uint8_t*)sReportCache, &len); int cache_version = -1; - btif_config_get_int(bdstr, "HidReportVersion", &cache_version); + btif_config_get_int(bdstr, BTIF_STORAGE_KEY_HID_REPORT_VERSION, + &cache_version); if (cache_version != BTA_HH_CACHE_REPORT_VERSION) { - bta_hh_le_co_reset_rpt_cache(remote_bda, app_id); + bta_hh_le_co_reset_rpt_cache(link_spec, app_id); return NULL; } *p_num_rpt = len / sizeof(tBTA_HH_RPT_CACHE_ENTRY); - LOG_VERBOSE("%s() - Loaded %d reports; dev=%s", __func__, *p_num_rpt, - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::verbose("Loaded {} reports; dev={}", *p_num_rpt, + ADDRESS_TO_LOGGABLE_CSTR(link_spec)); return sReportCache; } @@ -829,13 +834,12 @@ tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const RawAddress& remote_bda, * Returns none * ******************************************************************************/ -void bta_hh_le_co_reset_rpt_cache(const RawAddress& remote_bda, +void bta_hh_le_co_reset_rpt_cache(const tAclLinkSpec& link_spec, UNUSED_ATTR uint8_t app_id) { - std::string addrstr = remote_bda.ToString(); + std::string addrstr = link_spec.addrt.ToString(); const char* bdstr = addrstr.c_str(); - btif_config_remove(bdstr, "HidReport"); - btif_config_remove(bdstr, "HidReportVersion"); - LOG_VERBOSE("%s() - Reset cache for bda %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_REPORT); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_REPORT_VERSION); + log::verbose("Reset cache for bda {}", ADDRESS_TO_LOGGABLE_CSTR(link_spec)); } diff --git a/system/btif/co/bta_pan_co.cc b/system/btif/co/bta_pan_co.cc index dd8a0b231b6217307da8ac4bcab40e75e6dcef46..5f5f2f55a527d9210b1c34bdac3dad13ea6377aa 100644 --- a/system/btif/co/bta_pan_co.cc +++ b/system/btif/co/bta_pan_co.cc @@ -31,19 +31,21 @@ #include #include -#include "os/log.h" #include "bta_api.h" #include "bta_pan_api.h" #include "bta_pan_ci.h" #include "btif_pan_internal.h" #include "btif_sock_thread.h" #include "btif_util.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "pan_api.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /******************************************************************************* * * Function bta_pan_co_init @@ -55,7 +57,7 @@ * ******************************************************************************/ uint8_t bta_pan_co_init(uint8_t* q_level) { - LOG_VERBOSE("bta_pan_co_init"); + log::verbose("bta_pan_co_init"); /* set the q_level to 30 buffers */ *q_level = 30; @@ -76,10 +78,10 @@ uint8_t bta_pan_co_init(uint8_t* q_level) { * ******************************************************************************/ void bta_pan_co_close(uint16_t handle, uint8_t app_id) { - LOG_VERBOSE("bta_pan_co_close:app_id:%d, handle:%d", app_id, handle); + log::verbose("bta_pan_co_close:app_id:{}, handle:{}", app_id, handle); btpan_conn_t* conn = btpan_find_conn_handle(handle); if (conn && conn->state == PAN_STATE_OPEN) { - LOG_VERBOSE("bta_pan_co_close"); + log::verbose("bta_pan_co_close"); // let bta close event reset this handle as it needs // the handle to find the connection upon CLOSE @@ -119,15 +121,15 @@ void bta_pan_co_tx_path(uint16_t handle, uint8_t app_id) { bool ext; bool forward; - LOG_VERBOSE("%s, handle:%d, app_id:%d", __func__, handle, app_id); + log::verbose("handle:{}, app_id:{}", handle, app_id); btpan_conn_t* conn = btpan_find_conn_handle(handle); if (!conn) { - LOG_ERROR("%s: cannot find pan connection", __func__); + log::error("cannot find pan connection"); return; } else if (conn->state != PAN_STATE_OPEN) { - LOG_ERROR("%s: conn is not opened, conn:%p, conn->state:%d", __func__, conn, - conn->state); + log::error("conn is not opened, conn:{}, conn->state:{}", fmt::ptr(conn), + conn->state); return; } @@ -135,14 +137,12 @@ void bta_pan_co_tx_path(uint16_t handle, uint8_t app_id) { /* read next data buffer from pan */ p_buf = bta_pan_ci_readbuf(handle, src, dst, &protocol, &ext, &forward); if (p_buf) { - LOG_VERBOSE( - "%s, calling btapp_tap_send, " - "p_buf->len:%d, offset:%d", - __func__, p_buf->len, p_buf->offset); + log::verbose("calling btapp_tap_send, p_buf->len:{}, offset:{}", + p_buf->len, p_buf->offset); if (is_empty_eth_addr(conn->eth_addr) && is_valid_bt_eth_addr(src)) { - VLOG(1) << __func__ << " pan bt peer addr: " - << ADDRESS_TO_LOGGABLE_STR(conn->peer) - << " update its ethernet addr: " << src; + log::verbose("pan bt peer addr: {} update its ethernet addr: {}", + ADDRESS_TO_LOGGABLE_STR(conn->peer), + ADDRESS_TO_LOGGABLE_STR(src)); conn->eth_addr = src; } btpan_tap_send(btpan_cb.tap_fd, src, dst, protocol, @@ -168,7 +168,7 @@ void bta_pan_co_tx_path(uint16_t handle, uint8_t app_id) { ******************************************************************************/ void bta_pan_co_rx_path(UNUSED_ATTR uint16_t handle, UNUSED_ATTR uint8_t app_id) { - LOG_VERBOSE("bta_pan_co_rx_path not used"); + log::verbose("bta_pan_co_rx_path not used"); } /******************************************************************************* @@ -187,7 +187,7 @@ void bta_pan_co_rx_path(UNUSED_ATTR uint16_t handle, ******************************************************************************/ void bta_pan_co_rx_flow(UNUSED_ATTR uint16_t handle, UNUSED_ATTR uint8_t app_id, UNUSED_ATTR bool enable) { - LOG_VERBOSE("bta_pan_co_rx_flow, enabled:%d, not used", enable); + log::verbose("bta_pan_co_rx_flow, enabled:{}, not used", enable); btpan_conn_t* conn = btpan_find_conn_handle(handle); if (!conn || conn->state != PAN_STATE_OPEN) return; btpan_set_flow_control(enable); @@ -207,7 +207,7 @@ void bta_pan_co_pfilt_ind(UNUSED_ATTR uint16_t handle, UNUSED_ATTR tBTA_PAN_STATUS result, UNUSED_ATTR uint16_t len, UNUSED_ATTR uint8_t* p_filters) { - LOG_VERBOSE("bta_pan_co_pfilt_ind"); + log::verbose("bta_pan_co_pfilt_ind"); } /******************************************************************************* @@ -224,5 +224,5 @@ void bta_pan_co_mfilt_ind(UNUSED_ATTR uint16_t handle, UNUSED_ATTR tBTA_PAN_STATUS result, UNUSED_ATTR uint16_t len, UNUSED_ATTR uint8_t* p_filters) { - LOG_VERBOSE("bta_pan_co_mfilt_ind"); + log::verbose("bta_pan_co_mfilt_ind"); } diff --git a/system/btif/include/bta_av_co.h b/system/btif/include/bta_av_co.h new file mode 100644 index 0000000000000000000000000000000000000000..fe7ca50f59e711b9f6e2d0db1c3f6d5639be964c --- /dev/null +++ b/system/btif/include/bta_av_co.h @@ -0,0 +1,548 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "btif/include/bta_av_co_peer.h" + +/** + * BTA AV codec callouts state. + */ +class BtaAvCoState { + public: + BtaAvCoState() = default; + + /** + * Set the active peer for the state. + * @param peer + */ + void setActivePeer(BtaAvCoPeer* peer); + + /** + * Gets the active peer for the state. + * @return pointer to the active peer. + */ + BtaAvCoPeer* getActivePeer() const; + + /** + * Gets the codec config for the state. + * @return the active codec config. + */ + uint8_t* getCodecConfig(); + + /** + * Updates the codec config + * @param codec_config codec config that needs to be updated. + */ + void setCodecConfig(const uint8_t* codec_config); + + /** + * Clears the codec config. + */ + void clearCodecConfig(); + + /** + * Resets the state. + */ + void Reset(); + virtual ~BtaAvCoState() = default; + + private: + // The current active peer + BtaAvCoPeer* active_peer_; + // Current codec configuration + uint8_t codec_config_[AVDT_CODEC_SIZE]; +}; + +class BtaAvCo { + public: + BtaAvCo(bool content_protect_enabled, BtaAvCoPeerCache* bta_av_co_peer_bank) + : peer_cache_(bta_av_co_peer_bank), + content_protect_enabled_(content_protect_enabled), + content_protect_flag_(0) { + Reset(); + } + + virtual ~BtaAvCo() = default; + + /** + * Initialize the state. + * + * @param codec_priorities the codec priorities to use for the initialization + * @param supported_codecs return the list of supported codecs + */ + void Init(const std::vector& codec_priorities, + std::vector* supported_codecs); + + /** + * Checks whether a codec is supported. + * + * @param codec_index the index of the codec to check + * @return true if the codec is supported, otherwise false + */ + bool IsSupportedCodec(btav_a2dp_codec_index_t codec_index); + + /** + * Get the current codec configuration for the active peer. + * + * @return the current codec configuration if found, otherwise nullptr + */ + A2dpCodecConfig* GetActivePeerCurrentCodec(); + + /** + * Get the current codec configuration for a peer. + * + * @param peer_address the peer address + * @return the current codec configuration if found, otherwise nullptr + */ + A2dpCodecConfig* GetPeerCurrentCodec(const RawAddress& peer_address); + + /** + * Process the AVDTP discovery result: number of Stream End Points (SEP) + * found during the AVDTP stream discovery process. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param num_seps the number of discovered SEPs + * @param num_sinks number of discovered Sink SEPs + * @param num_sources number of discovered Source SEPs + * @param uuid_local local UUID + */ + void ProcessDiscoveryResult(tBTA_AV_HNDL bta_av_handle, + const RawAddress& peer_address, uint8_t num_seps, + uint8_t num_sinks, uint8_t num_sources, + uint16_t uuid_local); + + /** + * Process retrieved codec configuration and content protection from + * Peer Sink SEP. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param p_codec_info the peer sink capability filled-in by the caller. + * On success, it will contain the current codec configuration for the peer. + * @param p_sep_info_idx the peer SEP index for the corresponding peer + * sink capability filled-in by the caller. On success, it will contain + * the SEP index for the current codec configuration for the peer. + * @param seid the peer SEP index in peer tables + * @param p_num_protect the peer SEP number of content protection elements + * filled-in by the caller. On success, it will contain the SEP number of + * content protection elements for the current codec configuration for the + * peer. + * @param p_protect_info the peer SEP content protection info filled-in by + * the caller. On success, it will contain the SEP content protection info + * for the current codec configuration for the peer. + * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL + */ + tA2DP_STATUS ProcessSourceGetConfig(tBTA_AV_HNDL bta_av_handle, + const RawAddress& peer_address, + uint8_t* p_codec_info, + uint8_t* p_sep_info_idx, uint8_t seid, + uint8_t* p_num_protect, + uint8_t* p_protect_info); + + /** + * Process retrieved codec configuration and content protection from + * Peer Source SEP. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param p_codec_info the peer source capability filled-in by the caller. + * On success, it will contain the current codec configuration for the peer. + * @param p_sep_info_idx the peer SEP index for the corresponding peer + * source capability filled-in by the caller. On success, it will contain + * the SEP index for the current codec configuration for the peer. + * @param seid the peer SEP index in peer tables + * @param p_num_protect the peer SEP number of content protection elements + * filled-in by the caller. On success, it will contain the SEP number of + * content protection elements for the current codec configuration for the + * peer. + * @param p_protect_info the peer SEP content protection info filled-in by + * the caller. On success, it will contain the SEP content protection info + * for the current codec configuration for the peer. + * @return A2DP_SUCCESS on success, otherwise A2DP_FAIL + */ + tA2DP_STATUS ProcessSinkGetConfig(tBTA_AV_HNDL bta_av_handle, + const RawAddress& peer_address, + uint8_t* p_codec_info, + uint8_t* p_sep_info_idx, uint8_t seid, + uint8_t* p_num_protect, + uint8_t* p_protect_info); + + /** + * Process AVDTP Set Config to set the codec and content protection + * configuration of the audio stream. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param p_codec_info the codec configuration to set + * @param seid stream endpoint ID of stream initiating the operation + * @param peer_address the peer address + * @param num_protect the peer SEP number of content protection elements + * @param p_protect_info the peer SEP content protection info + * @param t_local_sep the local SEP: AVDT_TSEP_SRC or AVDT_TSEP_SNK + * @param avdt_handle the AVDTP handle + */ + void ProcessSetConfig(tBTA_AV_HNDL bta_av_handle, + const RawAddress& peer_address, + const uint8_t* p_codec_info, uint8_t seid, + uint8_t num_protect, const uint8_t* p_protect_info, + uint8_t t_local_sep, uint8_t avdt_handle); + + /** + * Process AVDTP Open when the stream connection is opened. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param mtu the MTU of the connection + */ + void ProcessOpen(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, + uint16_t mtu); + + /** + * Process AVDTP Close when the stream connection is closed. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + */ + void ProcessClose(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); + + /** + * Process AVDTP Start when the audio data streaming is started. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param p_codec_info the codec configuration + * @param p_no_rtp_header on return, set to true if the audio data packets + * should not contain RTP header + */ + void ProcessStart(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, + const uint8_t* p_codec_info, bool* p_no_rtp_header); + + /** + * Process AVDTP Stop when the audio data streaming is stopped. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + */ + void ProcessStop(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address); + + /** + * Get the next encoded audio data packet to send. + * + * @param p_codec_info the codec configuration + * @param p_timestamp on return, set to the timestamp of the data packet + * @return the next encoded data packet or nullptr if no encoded data to send + */ + BT_HDR* GetNextSourceDataPacket(const uint8_t* p_codec_info, + uint32_t* p_timestamp); + + /** + * An audio packet has been dropped. + * This signal can be used by the encoder to reduce the encoder bit rate + * setting. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + */ + void DataPacketWasDropped(tBTA_AV_HNDL bta_av_handle, + const RawAddress& peer_address); + + /** + * Process AVDTP Audio Delay when the initial delay report is received by + * the Source. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param delay the reported delay in 1/10th of a millisecond + */ + void ProcessAudioDelay(tBTA_AV_HNDL bta_av_handle, + const RawAddress& peer_address, uint16_t delay); + + /** + * Update the MTU of the audio data connection. + * + * @param bta_av_handle the BTA AV handle to identify the peer + * @param peer_address the peer address + * @param mtu the new MTU of the audio data connection + */ + void UpdateMtu(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, + uint16_t mtu); + + /** + * Set the active peer. + * + * @param peer_address the peer address + * @return true on success, otherwise false + */ + bool SetActivePeer(const RawAddress& peer_address); + + /** + * Save the reconfig codec + * + * @param new_codec_config the new codec config + */ + void SaveCodec(const uint8_t* new_codec_config); + + /** + * Get the encoder parameters for a peer. + * + * @param peer_address the peer address + * @param p_peer_params on return, set to the peer's encoder parameters + */ + void GetPeerEncoderParameters(const RawAddress& peer_address, + tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params); + + /** + * Get the Source encoder interface for the current codec. + * + * @return the Source encoder interface for the current codec + */ + const tA2DP_ENCODER_INTERFACE* GetSourceEncoderInterface(); + + /** + * Set the codec user configuration. + * + * @param peer_address the peer address + * @param codec_user_config the codec user configuration to set + * @param p_restart_output if there is a change in the encoder configuration + * that requires restarting of the A2DP connection, flag |p_restart_output| + * will be set to true. + * @return true on success, otherwise false + */ + bool SetCodecUserConfig(const RawAddress& peer_address, + const btav_a2dp_codec_config_t& codec_user_config, + bool* p_restart_output); + + /** + * Set the codec audio configuration. + * + * @param codec_audio_config the codec audio configuration to set + * @return true on success, otherwise false + */ + bool SetCodecAudioConfig(const btav_a2dp_codec_config_t& codec_audio_config); + + /** + * Get the Source encoder maximum frame size for the current codec. + * + * @return the effective frame size for the current codec + */ + int GetSourceEncoderEffectiveFrameSize(); + + /** + * Report the source codec state for a peer + * + * @param p_peer the peer to report + * @return true on success, otherwise false + */ + bool ReportSourceCodecState(BtaAvCoPeer* p_peer); + + /** + * Report the sink codec state for a peer + * + * @param p_peer the peer to report + * @return true on success, otherwise false + */ + bool ReportSinkCodecState(BtaAvCoPeer* p_peer); + + /** + * Get the content protection flag. + * + * @return the content protection flag. It should be one of the following: + * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE + */ + uint8_t ContentProtectFlag() const { return content_protect_flag_; } + + /** + * Set the content protection flag. + * + * @param cp_flag the content protection flag. It should be one of the + * following: + * AVDT_CP_SCMS_COPY_NEVER, AVDT_CP_SCMS_COPY_ONCE, AVDT_CP_SCMS_COPY_FREE + * NOTE: If Content Protection is not enabled on the system, then + * the only acceptable vailue is AVDT_CP_SCMS_COPY_FREE. + */ + void SetContentProtectFlag(uint8_t cp_flag) { + if (!ContentProtectEnabled() && (cp_flag != AVDT_CP_SCMS_COPY_FREE)) { + return; + } + content_protect_flag_ = cp_flag; + } + + /** + * Dump debug-related information. + * + * @param fd the file descritor to use for writing the ASCII formatted + * information + */ + void DebugDump(int fd); + + /** + * Access peer data via cache. + */ + BtaAvCoPeerCache* peer_cache_; + + private: + /** + * Reset the state. + */ + void Reset(); + + /** + * Select the Source codec configuration based on peer codec support. + * + * Furthermore, the local state for the remaining non-selected codecs is + * updated to reflect whether the codec is selectable. + * + * @param p_peer the peer to use + * @return a pointer to the corresponding SEP Sink entry on success, + * otherwise nullptr + */ + const BtaAvCoSep* SelectSourceCodec(BtaAvCoPeer* p_peer); + + /** + * Select the Sink codec configuration based on peer codec support. + * + * Furthermore, the local state for the remaining non-selected codecs is + * updated to reflect whether the codec is selectable. + * + * @param p_peer the peer to use + * @return a pointer to the corresponding SEP Source entry on success, + * otherwise nullptr + */ + const BtaAvCoSep* SelectSinkCodec(BtaAvCoPeer* p_peer); + + /** + * Save new codec configuration. + * + * @param p_peer the peer to use + * @param new_codec_config the new codec configuration to use + * @param num_protect the number of content protection elements + * @param p_protect_info the content protection info to use + */ + void SaveNewCodecConfig(BtaAvCoPeer* p_peer, const uint8_t* new_codec_config, + uint8_t num_protect, const uint8_t* p_protect_info); + + /** + * Set the Over-The-Air preferred codec configuration. + * + * The OTA preferred codec configuration is ignored if the current + * codec configuration contains explicit user configuration, or if the + * codec configuration for the same codec contains explicit user + * configuration. + * + * @param p_peer is the peer device that sent the OTA codec configuration + * @param p_ota_codec_config contains the received OTA A2DP codec + * configuration from the remote peer. Note: this is not the peer codec + * capability, but the codec configuration that the peer would like to use. + * @param num_protect is the number of content protection methods to use + * @param p_protect_info contains the content protection information to use. + * @param p_restart_output if there is a change in the encoder configuration + * that requires restarting of the A2DP connection, flag |p_restart_output| + * is set to true. + * @return true on success, otherwise false + */ + bool SetCodecOtaConfig(BtaAvCoPeer* p_peer, const uint8_t* p_ota_codec_config, + uint8_t num_protect, const uint8_t* p_protect_info, + bool* p_restart_output); + + /** + * Update all selectable Source codecs with the corresponding codec + * information from a Sink peer. + * + * @param p_peer the peer Sink SEP to use + * @return the number of codecs that have been updated + */ + size_t UpdateAllSelectableSourceCodecs(BtaAvCoPeer* p_peer); + + /** + * Update a selectable Source codec with the corresponding codec information + * from a Sink peer. + * + * @param codec_config the codec config info to identify the codec to update + * @param p_peer the peer Sink SEP to use + * @return true if the codec is updated, otherwise false + */ + bool UpdateSelectableSourceCodec(const A2dpCodecConfig& codec_config, + BtaAvCoPeer* p_peer); + + /** + * Update all selectable Sink codecs with the corresponding codec + * information from a Source peer. + * + * @param p_peer the peer Source SEP to use + * @return the number of codecs that have been updated + */ + size_t UpdateAllSelectableSinkCodecs(BtaAvCoPeer* p_peer); + + /** + * Update a selectable Sink codec with the corresponding codec information + * from a Source peer. + * + * @param codec_config the codec config info to identify the codec to update + * @param p_peer the peer Source SEP to use + * @return true if the codec is updated, otherwise false + */ + bool UpdateSelectableSinkCodec(const A2dpCodecConfig& codec_config, + BtaAvCoPeer* p_peer); + + /** + * Attempt to select Source codec configuration for a Sink peer. + * + * @param codec_config the codec configuration to use + * @param p_peer the Sink peer to use + * @return a pointer to the corresponding SEP Sink entry on success, + * otnerwise nullptr + */ + const BtaAvCoSep* AttemptSourceCodecSelection( + const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer); + + /** + * Attempt to select Sink codec configuration for a Source peer. + * + * @param codec_config the codec configuration to use + * @param p_peer the Source peer to use + * @return a pointer to the corresponding SEP Source entry on success, + * otnerwise nullptr + */ + const BtaAvCoSep* AttemptSinkCodecSelection( + const A2dpCodecConfig& codec_config, BtaAvCoPeer* p_peer); + + /** + * Let the HAL offload provider select codec configuration. + * + * @param p_peer the peer to use + * @param configuration configuration from the offload provider + */ + std::optional<::bluetooth::audio::a2dp::provider::a2dp_configuration> + GetProviderCodecConfiguration(BtaAvCoPeer* p_peer); + + /** + * Select the HAL proposed configuration. + */ + BtaAvCoSep* SelectProviderCodecConfiguration( + BtaAvCoPeer* p_peer, + const ::bluetooth::audio::a2dp::provider::a2dp_configuration& + provider_codec_config); + + bool ContentProtectEnabled() const { return content_protect_enabled_; } + + const bool content_protect_enabled_; // True if Content Protect is enabled + uint8_t content_protect_flag_; // Content Protect flag + BtaAvCoState bta_av_legacy_state_; +}; diff --git a/system/btif/include/bta_av_co_peer.h b/system/btif/include/bta_av_co_peer.h new file mode 100644 index 0000000000000000000000000000000000000000..7703c3033b4f32f41e08769f7380d195063fc136 --- /dev/null +++ b/system/btif/include/bta_av_co_peer.h @@ -0,0 +1,226 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include "bta/include/bta_av_api.h" +#include "stack/include/a2dp_codec_api.h" +#include "stack/include/bt_types.h" +#include "types/raw_address.h" + +// Macro to retrieve the number of elements in a statically allocated array +#define BTA_AV_CO_NUM_ELEMENTS(__a) (sizeof(__a) / sizeof((__a)[0])) + +class BtaAvCoSep { + public: + BtaAvCoSep() + : sep_info_idx(0), seid(0), codec_caps{}, num_protect(0), protect_info{} { + Reset(); + } + + /** + * Reset the state. + */ + void Reset() { + sep_info_idx = 0; + seid = 0; + memset(codec_caps, 0, sizeof(codec_caps)); + num_protect = 0; + memset(protect_info, 0, sizeof(protect_info)); + } + + uint8_t sep_info_idx; // Local SEP index (in BTA tables) + uint8_t seid; // Peer SEP index (in peer tables) + uint8_t codec_caps[AVDT_CODEC_SIZE]; // Peer SEP codec capabilities + uint8_t num_protect; // Peer SEP number of CP elements + uint8_t protect_info[AVDT_CP_INFO_LEN]; // Peer SEP content protection info +}; + +class BtaAvCoPeer { + public: + /** + * Default constructor to initialize the state of the member variables. + */ + BtaAvCoPeer(); + + /** + * Initialize the state. + * + * @param codec_priorities the codec priorities to use for the initialization + */ + void Init(const std::vector& codec_priorities); + + /** + * Reset the state. + * + * @param bta_av_handle the BTA AV handle to use + */ + void Reset(tBTA_AV_HNDL bta_av_handle); + + /** + * Get the BTA AV handle. + * + * @return the BTA AV handle + */ + tBTA_AV_HNDL BtaAvHandle() const { return bta_av_handle_; } + + /** + * Get the A2DP codecs. + * + * @return the A2DP codecs + */ + A2dpCodecs* GetCodecs() const { return codecs_; } + + bool ContentProtectActive() const { return content_protect_active_; } + void SetContentProtectActive(bool cp_active) { + content_protect_active_ = cp_active; + } + + RawAddress addr; // Peer address + BtaAvCoSep sinks[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sinks + BtaAvCoSep sources[BTAV_A2DP_CODEC_INDEX_MAX]; // Supported sources + uint8_t num_sinks; // Total number of sinks at peer + uint8_t num_sources; // Total number of sources at peer + uint8_t num_seps; // Total number of SEPs at peer + uint8_t num_rx_sinks; // Number of received sinks + uint8_t num_rx_sources; // Number of received sources + uint8_t num_sup_sinks; // Number of supported sinks + uint8_t num_sup_sources; // Number of supported sources + const BtaAvCoSep* p_sink; // Currently selected sink + const BtaAvCoSep* p_source; // Currently selected source + uint8_t codec_config[AVDT_CODEC_SIZE]; // Current codec configuration + bool acceptor; // True if acceptor + bool reconfig_needed; // True if reconfiguration is needed + bool opened; // True if opened + uint16_t mtu; // Maximum Transmit Unit size + uint16_t uuid_to_connect; // UUID of peer device + + private: + tBTA_AV_HNDL bta_av_handle_; // BTA AV handle to use + A2dpCodecs* codecs_; // Locally supported codecs + bool content_protect_active_; // True if Content Protect is active +}; + +/** + * Cache to store all the peer and codec information. + * It provides different APIs to retrieve the peer and update the peer data. + */ +class BtaAvCoPeerCache { + public: + BtaAvCoPeerCache() = default; + std::recursive_mutex codec_lock_; // Protect access to the codec state + std::vector codec_priorities_; // Configured + BtaAvCoPeer peers_[BTA_AV_NUM_STRS]; // Connected peer information + + /** + * Inits the cache with the appropriate data. + * @param codec_priorities codec priorities. + * @param supported_codecs supported codecs by the stack. + */ + void Init(const std::vector& codec_priorities, + std::vector* supported_codecs); + + /** + * Resets the cache and the peer data. + */ + void Reset(); + + /** + * Find the peer entry for a given peer address. + * + * @param peer_address the peer address to use + * @return the peer entry if found, otherwise nullptr + */ + BtaAvCoPeer* FindPeer(const RawAddress& peer_address); + + /** + * Find the peer Source SEP entry for a given codec index. + * + * @param p_peer the peer to use + * @param codec_config the codec index to use + * @return the peer Source SEP for the codec index if found, otherwise nullptr + */ + BtaAvCoSep* FindPeerSource(BtaAvCoPeer* p_peer, + btav_a2dp_codec_index_t codec_index, + const uint8_t content_protect_flag); + + /** + * Find the peer Sink SEP entry for a given codec index. + * + * @param p_peer the peer to use + * @param codec_index the codec index to use + * @return the peer Sink SEP for the codec index if found, otherwise nullptr + */ + BtaAvCoSep* FindPeerSink(BtaAvCoPeer* p_peer, + btav_a2dp_codec_index_t codec_index, + const uint8_t content_protect_flag); + + /** + * Find the peer entry for a given BTA AV handle. + * + * @param bta_av_handle the BTA AV handle to use + * @return the peer entry if found, otherwise nullptr + */ + BtaAvCoPeer* FindPeer(tBTA_AV_HNDL bta_av_handle); + + /** + * Find the peer entry for a given BTA AV handle and update it with the + * peer address. + * + * @param bta_av_handle the BTA AV handle to use + * @param peer_address the peer address + * @return the peer entry if found, otherwise nullptr + */ + BtaAvCoPeer* FindPeerAndUpdate(tBTA_AV_HNDL bta_av_handle, + const RawAddress& peer_address); + + /** + * Find the peer UUID for a given BTA AV handle. + * + * @param bta_av_handle the BTA AV handle to use + * @return the peer UUID if found, otherwise 0 + */ + uint16_t FindPeerUuid(tBTA_AV_HNDL bta_av_handle); +}; + +/** + * Check if a content protection service is SCMS-T. + * + * @param p_orotect_info the content protection info to check + * @return true if the Contention Protection in @param p_protect_info + * is SCMS-T, otherwise false + */ +bool ContentProtectIsScmst(const uint8_t* p_protect_info); + +/** + * Check if audio protect info contains SCMS-T Content Protection. + * + * @param num_protect number of protect schemes + * @param p_protect_info the protect info to check + * @return true if @param p_protect_info contains SCMS-T, otherwise false + */ +bool AudioProtectHasScmst(uint8_t num_protect, const uint8_t* p_protect_info); + +/** + * Check if a peer SEP has content protection enabled. + * + * @param p_sep the peer SEP to check + * @param content_protect_flag flag to check if content protect is enabled or + * not. + * @return true if the peer SEP has content protection enabled, + * otherwise false + */ +bool AudioSepHasContentProtection(const BtaAvCoSep* p_sep, + const uint8_t content_protect_flag); diff --git a/system/btif/include/btif_a2dp_sink.h b/system/btif/include/btif_a2dp_sink.h index 8875eed850d84f9b7ca3a417f3d7243f7da3024e..72eca7665482ac442db4c601de0939c358ecd225 100644 --- a/system/btif/include/btif_a2dp_sink.h +++ b/system/btif/include/btif_a2dp_sink.h @@ -20,6 +20,8 @@ #ifndef BTIF_A2DP_SINK_H #define BTIF_A2DP_SINK_H +#include + #include #include @@ -141,4 +143,10 @@ void btif_a2dp_sink_set_audio_track_gain(float gain); // Get audio track handle void * btif_a2dp_sink_get_audio_track(void); +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt + #endif /* BTIF_A2DP_SINK_H */ diff --git a/system/btif/include/btif_acl.h b/system/btif/include/btif_acl.h index 0fa6d93bb4f7cff9c64388e427ebb2bbfe19fa4b..cab40b43f66b6b7821cc7deb54a26fcd8afd20ea 100644 --- a/system/btif/include/btif_acl.h +++ b/system/btif/include/btif_acl.h @@ -16,6 +16,6 @@ #pragma once -#include +#include "stack/include/acl_api_types.h" -void BTIF_dm_report_inquiry_status_change(uint8_t busy_level_flags); +void BTIF_dm_report_inquiry_status_change(tBTM_INQUIRY_STATE inquiry_state); diff --git a/system/btif/include/btif_api.h b/system/btif/include/btif_api.h index 2a7df05a7277bccaeb0c176562b2da59eb5d14bc..54106e041e010ebccd1e41e9e2b99196be09ecc2 100644 --- a/system/btif/include/btif_api.h +++ b/system/btif/include/btif_api.h @@ -266,13 +266,28 @@ void btif_dm_remove_bond(const RawAddress bd_addr); /******************************************************************************* * * Function btif_dm_get_connection_state - * - * Description Returns whether the remote device is currently connected - * - * Returns 0 if not connected + * btif_dm_get_connection_state_sync + * + * Description Returns bitmask on remote device connection state indicating + * connection and encryption. The `_sync` version properly + * synchronizes the state and is the preferred mechanism. + * NOTE: Currently no address resolution is attempted upon + * LE random addresses. + * + * Returns '000 (0x0000) if not connected + * '001 (0x0001) Connected with no encryption to remote + * device on BR/EDR or LE ACL + * '011 (0x0003) Connected with encryption to remote + * device on BR/EDR ACL + * '101 (0x0005) Connected with encruption to remote + * device on LE ACL + * '111 (0x0007) Connected with encruption to remote + * device on both BR/EDR and LE ACLs + * All other values are reserved * ******************************************************************************/ uint16_t btif_dm_get_connection_state(const RawAddress& bd_addr); +uint16_t btif_dm_get_connection_state_sync(const RawAddress& bd_addr); /******************************************************************************* * diff --git a/system/btif/include/btif_av.h b/system/btif/include/btif_av.h index f85656c063a7ae6b3c4dcb568986de53df0c32b7..3a44c293501c354a416ab474241bd7c9386f0f01 100644 --- a/system/btif/include/btif_av.h +++ b/system/btif/include/btif_av.h @@ -24,6 +24,7 @@ #define BTIF_AV_H #include +#include #include "include/hardware/bt_av.h" #include "types/raw_address.h" diff --git a/system/btif/include/btif_av_co.h b/system/btif/include/btif_av_co.h index 9b32b15f406ad95547e04909c3ead1b49257b4d9..ce9b873fe937eb18917ea2922dea567ac96c1b57 100644 --- a/system/btif/include/btif_av_co.h +++ b/system/btif/include/btif_av_co.h @@ -60,8 +60,10 @@ bool bta_av_co_set_codec_audio_config( // Initializes the control block. // |codec_priorities| contains the A2DP Source codec priorities to use. +// |supported_codecs| returns the list of supported A2DP Source codecs. void bta_av_co_init( - const std::vector& codec_priorities); + const std::vector& codec_priorities, + std::vector* supported_codecs); // Checks whether the codec for |codec_index| is supported. // Returns true if the codec is supported, otherwise false. diff --git a/system/btif/include/btif_bqr.h b/system/btif/include/btif_bqr.h index 374a387782e914b66a10ef572e6849a6d1b2c259..dd850c624186e5bf76df5ca4bed92b237b7b0952 100644 --- a/system/btif/include/btif_bqr.h +++ b/system/btif/include/btif_bqr.h @@ -17,6 +17,8 @@ #ifndef BTIF_BQR_H_ #define BTIF_BQR_H_ +#include + #include "btm_api_types.h" #include "common/leaky_bonded_queue.h" #include "include/hardware/bt_bqr.h" @@ -457,4 +459,12 @@ void DebugDump(int fd); } // namespace bqr } // namespace bluetooth +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter : ostream_formatter {}; +} // namespace fmt + #endif // BTIF_BQR_H_ diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h index 5f863e6d3603ed5eb99838ab607e8e112a08cc19..3a357ffdf48e874d9b3cabdee23e19f3e1170359 100644 --- a/system/btif/include/btif_common.h +++ b/system/btif/include/btif_common.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -29,7 +30,7 @@ #include "abstract_message_loop.h" #include "bta/include/bta_api.h" -#include "osi/include/log.h" +#include "os/log.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" @@ -38,21 +39,13 @@ * Constants & Macros ******************************************************************************/ -#define ASSERTC(cond, msg, val) \ - do { \ - if (!(cond)) { \ - LOG_ERROR("### ASSERT : %s %s line %d %s (%d) ###", __FILE__, __func__, \ - __LINE__, (msg), (val)); \ - } \ +#define ASSERTC(cond, msg, val) \ + do { \ + if (!(cond)) { \ + bluetooth::log::error("### ASSERT : {} ({}) ###", (msg), (val)); \ + } \ } while (0) -/* Calculate start of event enumeration; id is top 8 bits of event */ -#define BTIF_SIG_START(id) ((id) << 8) - -/* For upstream the MSB bit is always SET */ -#define BTIF_SIG_CB_BIT (0x8000) -#define BTIF_SIG_CB_START(id) (((id) << 8) | BTIF_SIG_CB_BIT) - /* * A memcpy(3) wrapper when copying memory that might not be aligned. * @@ -70,63 +63,16 @@ #define maybe_non_aligned_memcpy(_a, _b, _c) \ memcpy((void*)(_a), (void*)(_b), (_c)) -/* BTIF sub-systems */ -#define BTIF_CORE 0 -#define BTIF_DM 1 -#define BTIF_HFP 2 -#define BTIF_AV 3 -#define BTIF_PAN 4 -#define BTIF_HF_CLIENT 5 - -#define HAL_CBACK(P_CB, P_CBACK, ...) \ - do { \ - if ((P_CB) && (P_CB)->P_CBACK) { \ - LOG_VERBOSE("%s: HAL %s->%s", __func__, #P_CB, #P_CBACK); \ - (P_CB)->P_CBACK(__VA_ARGS__); \ - } else { \ - ASSERTC(0, "Callback is NULL", 0); \ - } \ +#define HAL_CBACK(P_CB, P_CBACK, ...) \ + do { \ + if ((P_CB) && (P_CB)->P_CBACK) { \ + bluetooth::log::verbose("HAL {}->{}", #P_CB, #P_CBACK); \ + (P_CB)->P_CBACK(__VA_ARGS__); \ + } else { \ + ASSERTC(0, "Callback is NULL", 0); \ + } \ } while (0) -/** - * BTIF events for requests that require context switch to btif task - * on downstreams path - */ -enum { - BTIF_DM_API_START = BTIF_SIG_START(BTIF_DM), - BTIF_DM_ENABLE_SERVICE, - BTIF_DM_DISABLE_SERVICE, - /* add here */ - - BTIF_HFP_API_START = BTIF_SIG_START(BTIF_HFP), - /* add here */ - - BTIF_AV_API_START = BTIF_SIG_START(BTIF_AV), - /* add here */ -}; - -/** - * BTIF events for callbacks that require context switch to btif task - * on upstream path - Typically these would be non-BTA events - * that are generated by the BTIF layer. - */ -enum { - BTIF_CORE_CB_START = BTIF_SIG_CB_START(BTIF_CORE), - /* add here */ - - BTIF_HFP_CB_START = BTIF_SIG_CB_START(BTIF_HFP), - BTIF_HFP_CB_AUDIO_CONNECTING, /* HF AUDIO connect has been sent to BTA - successfully */ - - BTIF_PAN_CB_START = BTIF_SIG_CB_START(BTIF_PAN), - BTIF_PAN_CB_DISCONNECTING, /* PAN Disconnect has been sent to BTA successfully - */ - - BTIF_HF_CLIENT_CLIENT_CB_START = BTIF_SIG_CB_START(BTIF_HF_CLIENT), - BTIF_HF_CLIENT_CB_AUDIO_CONNECTING, /* AUDIO connect has been sent to BTA - successfully */ -}; - /******************************************************************************* * Type definitions for callback functions ******************************************************************************/ @@ -236,5 +182,5 @@ void invoke_link_quality_report_cb( void invoke_switch_buffer_size_cb(bool is_low_latency_buffer_size); void invoke_switch_codec_cb(bool is_low_latency_buffer_size); - +void invoke_key_missing_cb(RawAddress bd_addr); #endif /* BTIF_COMMON_H */ diff --git a/system/btif/include/btif_config.h b/system/btif/include/btif_config.h index 7bb0659bbde54ed95f469a2593ecb4c8d082a855..f7e1cf462c95c0ffdbf33b1d4a8b21c54363783c 100644 --- a/system/btif/include/btif_config.h +++ b/system/btif/include/btif_config.h @@ -31,20 +31,6 @@ static const char BTIF_CONFIG_MODULE[] = "btif_config_module"; -static const std::string BT_CONFIG_KEY_SDP_DI_MANUFACTURER = - "SdpDiManufacturer"; -static const std::string BT_CONFIG_KEY_SDP_DI_MODEL = "SdpDiModel"; -static const std::string BT_CONFIG_KEY_SDP_DI_HW_VERSION = - "SdpDiHardwareVersion"; -static const std::string BT_CONFIG_KEY_SDP_DI_VENDOR_ID_SRC = - "SdpDiVendorIdSource"; - -static const std::string BT_CONFIG_KEY_REMOTE_VER_MFCT = "Manufacturer"; -static const std::string BT_CONFIG_KEY_REMOTE_VER_VER = "LmpVer"; -static const std::string BT_CONFIG_KEY_REMOTE_VER_SUBVER = "LmpSubVer"; -static const std::string BT_CONFIG_KEY_PBAP_PCE_VERSION = "PbapPceVersion"; -static const std::string BT_CONFIG_KEY_DIS_MODEL_NUM = "ModelName"; - bool btif_config_exist(const std::string& section, const std::string& key); bool btif_config_get_int(const std::string& section, const std::string& key, int* value); diff --git a/system/btif/include/btif_config_cache.h b/system/btif/include/btif_config_cache.h index 212d8298ea5a948d9eb1b68c0101c4eed96e1bae..8c10a87b2950606f5b72cd094b7a9f28f4f1903e 100644 --- a/system/btif/include/btif_config_cache.h +++ b/system/btif/include/btif_config_cache.h @@ -16,13 +16,10 @@ #pragma once -#include -#include +#include #include "common/lru.h" #include "osi/include/config.h" -#include "osi/include/log.h" -#include "raw_address.h" class BtifConfigCache { public: diff --git a/system/btif/include/btif_dm.h b/system/btif/include/btif_dm.h index 246d1445dbcfb2aaf8def00372c97fa1784f3e80..6df5e1c5d83d945e0c7ebe8911e0d7e819f9e943 100644 --- a/system/btif/include/btif_dm.h +++ b/system/btif/include/btif_dm.h @@ -81,7 +81,7 @@ void btif_dm_proc_io_rsp(const RawAddress& bd_addr, tBTM_IO_CAP io_cap, /** * Device Configuration Queries */ -void btif_dm_get_local_class_of_device(DEV_CLASS device_class); +DEV_CLASS btif_dm_get_local_class_of_device(); /** * Out-of-band functions @@ -90,14 +90,12 @@ void btif_dm_set_oob_for_io_req(tBTM_OOB_DATA* p_oob_data); void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, tBTM_OOB_DATA* p_oob_data, tBTM_LE_AUTH_REQ* p_auth_req); -#ifdef BTIF_DM_OOB_TEST void btif_dm_load_local_oob(void); void btif_dm_proc_loc_oob(tBT_TRANSPORT transport, bool is_valid, const Octet16& c, const Octet16& r); bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, Octet16* p_c, Octet16* p_r); void btif_dm_generate_local_oob_data(tBT_TRANSPORT transport); -#endif /* BTIF_DM_OOB_TEST */ void btif_dm_clear_event_filter(); diff --git a/system/btif/include/btif_hd.h b/system/btif/include/btif_hd.h index 337deefc7af591c1d722c6e596020e77b6b67d2a..ac29552cfb1e2a49048c752e607bd2eb9133ccf1 100644 --- a/system/btif/include/btif_hd.h +++ b/system/btif/include/btif_hd.h @@ -20,6 +20,7 @@ #ifndef BTIF_HD_H #define BTIF_HD_H +#include #include #include #include @@ -46,4 +47,9 @@ extern btif_hd_cb_t btif_hd_cb; void btif_hd_remove_device(RawAddress bd_addr); void btif_hd_service_registration(); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/btif/include/btif_hh.h b/system/btif/include/btif_hh.h index c69cc485b604f465347c673172fa213f91ecf3f8..7dd5aa1cdcf8d32151594901db1e418adf90d03b 100644 --- a/system/btif/include/btif_hh.h +++ b/system/btif/include/btif_hh.h @@ -20,6 +20,7 @@ #define BTIF_HH_H #include +#include #include #include #include @@ -29,6 +30,7 @@ #include "macros.h" #include "osi/include/alarm.h" #include "osi/include/fixed_queue.h" +#include "types/ble_address_with_type.h" #include "types/raw_address.h" /******************************************************************************* @@ -86,7 +88,7 @@ inline std::string btif_hh_status_text(const BTIF_HH_STATUS& status) { typedef struct { bthh_connection_state_t dev_status; uint8_t dev_handle; - RawAddress bd_addr; + tAclLinkSpec link_spec; tBTA_HH_ATTR_MASK attr_mask; uint8_t sub_class; uint8_t app_id; @@ -105,7 +107,7 @@ typedef struct { /* Control block to maintain properties of devices */ typedef struct { uint8_t dev_handle; - RawAddress bd_addr; + tAclLinkSpec link_spec; tBTA_HH_ATTR_MASK attr_mask; } btif_hh_added_device_t; @@ -119,7 +121,7 @@ typedef struct { uint32_t device_num; btif_hh_added_device_t added_devices[BTIF_HH_MAX_ADDED_DEV]; bool service_dereg_active; - RawAddress pending_conn_address; + tAclLinkSpec pending_link_spec; } btif_hh_cb_t; /******************************************************************************* @@ -129,10 +131,11 @@ typedef struct { extern btif_hh_cb_t btif_hh_cb; btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle); -void btif_hh_remove_device(RawAddress bd_addr); -bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask); -bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr); -void btif_hh_disconnect(RawAddress* bd_addr); +void btif_hh_remove_device(const tAclLinkSpec& link_spec); +bool btif_hh_add_added_dev(const tAclLinkSpec& link_spec, + tBTA_HH_ATTR_MASK attr_mask); +bt_status_t btif_hh_virtual_unplug(const tAclLinkSpec* link_spec); +void btif_hh_disconnect(const tAclLinkSpec* link_spec); void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type, uint16_t size, uint8_t* report); void btif_hh_senddata(btif_hh_device_t* p_dev, uint16_t size, uint8_t* report); @@ -142,4 +145,9 @@ void btif_hh_service_registration(bool enable); void DumpsysHid(int fd); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/btif/include/btif_metrics_logging.h b/system/btif/include/btif_metrics_logging.h index 632062eab7ef5d93ab87eb3e3a3e6c470fab00d0..6226060423e807c18fe765dc50df2b4ab43ed96d 100644 --- a/system/btif/include/btif_metrics_logging.h +++ b/system/btif/include/btif_metrics_logging.h @@ -35,6 +35,13 @@ void log_a2dp_audio_overrun_event(const RawAddress& address, void log_a2dp_playback_event(const RawAddress& address, int playback_state, int audio_coding_mode); +void log_a2dp_session_metrics_event( + const RawAddress& address, int64_t audio_duration_ms, + int media_timer_min_ms, int media_timer_max_ms, int media_timer_avg_ms, + int total_scheduling_count, int buffer_overruns_max_count, + int buffer_overruns_total, float buffer_underruns_average, + int buffer_underruns_count, int64_t codec_index, bool is_a2dp_offload); + void log_read_rssi_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status, int8_t rssi); diff --git a/system/btif/include/btif_profile_storage.h b/system/btif/include/btif_profile_storage.h index 55d6c27874f91051ee93ff5028bc174672a25add..7ba41e41522171f3e9f8ab62a6ad419dd7198974 100644 --- a/system/btif/include/btif_profile_storage.h +++ b/system/btif/include/btif_profile_storage.h @@ -21,12 +21,8 @@ #include #include -#include "bt_target.h" -#include "btif_storage.h" -#include "stack/include/btm_sec_api_types.h" -#include "stack/include/bt_device_type.h" -#include "stack/include/bt_octets.h" -#include "types/ble_address_with_type.h" +#include + #include "types/raw_address.h" /******************************************************************************* diff --git a/system/btif/include/btif_storage.h b/system/btif/include/btif_storage.h index dbf8d26488f11ff551fa6b64bcfe110e848b7834..394cd5b5b7da4f58ecc414548d2feefb8c1555b4 100644 --- a/system/btif/include/btif_storage.h +++ b/system/btif/include/btif_storage.h @@ -39,8 +39,6 @@ (p_prop)->val = (p_v); \ } while (0) -#define BTIF_STORAGE_PATH_REMOTE_SERVICE "Service" - #define STORAGE_BDADDR_STRING_SZ (18) /* 00:11:22:33:44:55 */ #define STORAGE_UUID_STRING_SIZE \ (36 + 1) /* 00001200-0000-1000-8000-00805f9b34fb; */ @@ -393,8 +391,6 @@ void btif_storage_add_groups(const RawAddress& addr); void btif_storage_load_bonded_groups(void); void btif_storage_remove_groups(const RawAddress& address); -void btif_storage_set_csis_autoconnect(const RawAddress& addr, - bool autoconnect); void btif_storage_update_csis_info(const RawAddress& addr); void btif_storage_load_bonded_csis_devices(); void btif_storage_remove_csis_device(const RawAddress& address); diff --git a/system/btif/include/btif_util.h b/system/btif/include/btif_util.h index c488da7fbfbb49071ced87b2673e50d31aceca85..48d751b1a4ae63592b082ac5575fd0f85b10563b 100644 --- a/system/btif/include/btif_util.h +++ b/system/btif/include/btif_util.h @@ -59,8 +59,8 @@ const char* dump_rc_event(uint8_t event); const char* dump_rc_notification_event_id(uint8_t event_id); const char* dump_rc_pdu(uint8_t pdu); -uint32_t devclass2uint(DEV_CLASS dev_class); -void uint2devclass(uint32_t dev, DEV_CLASS dev_class); +uint32_t devclass2uint(const DEV_CLASS dev_class); +DEV_CLASS uint2devclass(uint32_t dev); int ascii_2_hex(const char* p_ascii, int len, uint8_t* p_hex); diff --git a/system/btif/include/core_callbacks.h b/system/btif/include/core_callbacks.h index d212f9c2ac0cae60ca27b1a3b37e26e32bc75151..421211b58a031d6f91cc6a7143436ebc8d11a29f 100644 --- a/system/btif/include/core_callbacks.h +++ b/system/btif/include/core_callbacks.h @@ -66,6 +66,7 @@ struct EventCallbacks { int retransmission_count, int packets_not_receive_count, int negative_acknowledgement_count); + void (*invoke_key_missing_cb)(RawAddress bd_addr); EventCallbacks& operator=(const EventCallbacks&) = delete; }; @@ -106,9 +107,9 @@ struct CodecInterface { // that profiles can register themselves to. struct HACK_ProfileInterface { // HID hacks - bt_status_t (*btif_hh_connect)(const RawAddress* bd_addr); - bt_status_t (*btif_hh_virtual_unplug)(const RawAddress* bd_addr); - tBTA_HH_STATUS (*bta_hh_read_ssr_param)(const RawAddress& bd_addr, + bt_status_t (*btif_hh_connect)(const tAclLinkSpec* link_spec); + bt_status_t (*btif_hh_virtual_unplug)(const tAclLinkSpec* link_spec); + tBTA_HH_STATUS (*bta_hh_read_ssr_param)(const tAclLinkSpec& link_spec, uint16_t* p_max_ssr_lat, uint16_t* p_min_ssr_tout); diff --git a/system/btif/include/mock_core_callbacks.h b/system/btif/include/mock_core_callbacks.h index 5e88fe3b3190fb558998f5d3596804d40e57a615..5e154c0bd7fff1eb44fca856c394c367373913d2 100644 --- a/system/btif/include/mock_core_callbacks.h +++ b/system/btif/include/mock_core_callbacks.h @@ -96,13 +96,13 @@ MockCodecInterface mock_codec_msbcCodec; MockCodecInterface mock_codec_lc3Codec; HACK_ProfileInterface mock_HACK_profile_interface = { - .btif_hh_connect = [](const RawAddress* /* bd_addr */) -> bt_status_t { + .btif_hh_connect = [](const tAclLinkSpec* /* link_spec */) -> bt_status_t { return BT_STATUS_SUCCESS; }, - .btif_hh_virtual_unplug = [](const RawAddress* /* bd_addr */) + .btif_hh_virtual_unplug = [](const tAclLinkSpec* /* link_spec */) -> bt_status_t { return BT_STATUS_SUCCESS; }, .bta_hh_read_ssr_param = - [](const RawAddress& /* bd_addr */, uint16_t* /* p_max_ssr_lat */, + [](const tAclLinkSpec& /* link_spec */, uint16_t* /* p_max_ssr_lat */, uint16_t* /* p_min_ssr_tout */) -> tBTA_HH_STATUS { return BTA_HH_OK; }, diff --git a/system/btif/include/stack_manager.h b/system/btif/include/stack_manager_t.h similarity index 100% rename from system/btif/include/stack_manager.h rename to system/btif/include/stack_manager_t.h diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index a0905c04f2a7f7476321f97a42da5b2546867697..1bdc3de9a5ca76612fc3ece439b4c4ae10505a5e 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -27,7 +27,9 @@ #define LOG_TAG "bt_btif" +#include #include +#include #include #include #include @@ -63,7 +65,7 @@ #include "btif/avrcp/avrcp_service.h" #include "btif/include/btif_sock.h" #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "btif_a2dp.h" #include "btif_api.h" #include "btif_av.h" @@ -82,16 +84,18 @@ #include "btif_sock.h" #include "btif_storage.h" #include "common/address_obfuscator.h" +#include "common/init_flags.h" #include "common/metrics.h" #include "common/os_utils.h" #include "device/include/device_iot_config.h" +#include "device/include/esco_parameters.h" #include "device/include/interop.h" #include "device/include/interop_config.h" -#include "gd/common/init_flags.h" -#include "gd/os/parameter_provider.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" #include "os/log.h" +#include "os/parameter_provider.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "osi/include/stack_power_telemetry.h" @@ -108,6 +112,7 @@ #include "stack/include/hidh_api.h" #include "stack/include/main_thread.h" #include "stack/include/pan_api.h" +#include "storage/config_keys.h" #include "types/raw_address.h" using bluetooth::csis::CsisClientInterface; @@ -116,6 +121,7 @@ using bluetooth::hearing_aid::HearingAidInterface; using bluetooth::le_audio::LeAudioBroadcasterInterface; using bluetooth::le_audio::LeAudioClientInterface; using bluetooth::vc::VolumeControlInterface; +using namespace bluetooth; /******************************************************************************* * Static variables @@ -172,9 +178,11 @@ bt_status_t btif_av_sink_execute_service(bool b_enable); bt_status_t btif_hh_execute_service(bool b_enable); bt_status_t btif_hf_client_execute_service(bool b_enable); bt_status_t btif_sdp_execute_service(bool b_enable); -bt_status_t btif_hh_connect(const RawAddress* bd_addr); +bt_status_t btif_hh_connect(const tAclLinkSpec* link_spec); bt_status_t btif_hd_execute_service(bool b_enable); +extern void gatt_tcb_dump(int fd); + /******************************************************************************* * Callbacks from bluetooth::core (see go/invisalign-bt) ******************************************************************************/ @@ -193,7 +201,7 @@ struct ConfigInterfaceImpl : bluetooth::core::ConfigInterface { "false"); auto a2dp_offload_enabled = (strcmp(value_sup, "true") == 0) && (strcmp(value_dis, "false") == 0); - LOG_VERBOSE("a2dp_offload.enable = %d", a2dp_offload_enabled); + log::verbose("a2dp_offload.enable = {}", a2dp_offload_enabled); return a2dp_offload_enabled; } @@ -291,8 +299,8 @@ struct CoreInterfaceImpl : bluetooth::core::CoreInterface { */ } break; default: - LOG_ERROR("%s: Unknown service %d being %s", __func__, service_id, - (enable) ? "enabled" : "disabled"); + log::error("Unknown service {} being {}", service_id, + (enable) ? "enabled" : "disabled"); return BT_STATUS_FAIL; } return BT_STATUS_SUCCESS; @@ -301,7 +309,12 @@ struct CoreInterfaceImpl : bluetooth::core::CoreInterface { void removeDeviceFromProfiles(const RawAddress& bd_addr) override { /*special handling for HID devices */ #if (defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)) - btif_hh_remove_device(bd_addr); + tAclLinkSpec link_spec; + link_spec.addrt.bda = bd_addr; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; + + btif_hh_remove_device(link_spec); #endif #if (defined(BTA_HD_INCLUDED) && (BTA_HD_INCLUDED == TRUE)) btif_hd_remove_device(bd_addr); @@ -342,6 +355,7 @@ static bluetooth::core::CoreInterface* CreateInterfaceToProfiles() { .invoke_le_test_mode_cb = invoke_le_test_mode_cb, .invoke_energy_info_cb = invoke_energy_info_cb, .invoke_link_quality_report_cb = invoke_link_quality_report_cb, + .invoke_key_missing_cb = invoke_key_missing_cb, }; static bluetooth::core::HACK_ProfileInterface profileInterface{ // HID @@ -397,11 +411,10 @@ static int init(bt_callbacks_t* callbacks, bool start_restricted, const char** init_flags, bool is_atv, const char* user_data_directory) { (void)user_data_directory; - LOG_INFO( - "%s: start restricted = %d ; common criteria mode = %d, config compare " - "result = %d", - __func__, start_restricted, is_common_criteria_mode, - config_compare_result); + log::info( + "start restricted = {} ; common criteria mode = {}, config compare " + "result = {}", + start_restricted, is_common_criteria_mode, config_compare_result); bluetooth::common::InitFlags::Load(init_flags); @@ -478,6 +491,10 @@ static bool get_swb_supported() { return hfp_hal_interface::get_swb_supported(); } +static bool is_coding_format_supported(esco_coding_format_t coding_format) { + return hfp_hal_interface::is_coding_format_supported(coding_format); +} + bool is_common_criteria_mode() { return is_bluetooth_uid() && common_criteria_mode; } @@ -614,7 +631,7 @@ static int create_bond_out_of_band(const RawAddress* bd_addr, int transport, } static int generate_local_oob_data(tBT_TRANSPORT transport) { - LOG_INFO("%s", __func__); + log::info(""); if (!interface_ready()) return BT_STATUS_NOT_READY; return do_in_main_thread( @@ -630,8 +647,8 @@ static int cancel_bond(const RawAddress* bd_addr) { static int remove_bond(const RawAddress* bd_addr) { if (is_restricted_mode() && !btif_storage_is_restricted_device(bd_addr)) { - LOG_INFO("%s cannot be removed in restricted mode", - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::info("{} cannot be removed in restricted mode", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_SUCCESS; } @@ -641,12 +658,22 @@ static int remove_bond(const RawAddress* bd_addr) { return BT_STATUS_SUCCESS; } +static bool pairing_is_busy() { + if (btif_dm_pairing_is_busy()) return true; + + return false; +} + static int get_connection_state(const RawAddress* bd_addr) { if (!interface_ready()) return 0; if (bd_addr == nullptr) return 0; - return btif_dm_get_connection_state(*bd_addr); + if (IS_FLAG_ENABLED(api_get_connection_state_sync_on_main)) { + return btif_dm_get_connection_state_sync(*bd_addr); + } else { + return btif_dm_get_connection_state(*bd_addr); + } } static int pin_reply(const RawAddress* bd_addr, uint8_t accept, uint8_t pin_len, @@ -663,7 +690,7 @@ static int pin_reply(const RawAddress* bd_addr, uint8_t accept, uint8_t pin_len, } static int ssp_reply(const RawAddress* bd_addr, bt_ssp_variant_t variant, - uint8_t accept, uint32_t passkey) { + uint8_t accept, uint32_t /* passkey */) { if (!interface_ready()) return BT_STATUS_NOT_READY; if (variant == BT_SSP_VARIANT_PASSKEY_ENTRY) return BT_STATUS_FAIL; @@ -680,7 +707,7 @@ static int read_energy_info() { } static int clear_event_filter() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!interface_ready()) return BT_STATUS_NOT_READY; do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_clear_event_filter)); @@ -688,7 +715,7 @@ static int clear_event_filter() { } static int clear_event_mask() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!interface_ready()) return BT_STATUS_NOT_READY; do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_clear_event_mask)); @@ -696,7 +723,7 @@ static int clear_event_mask() { } static int clear_filter_accept_list() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!interface_ready()) return BT_STATUS_NOT_READY; do_in_main_thread(FROM_HERE, @@ -705,7 +732,7 @@ static int clear_filter_accept_list() { } static int disconnect_all_acls() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!interface_ready()) return BT_STATUS_NOT_READY; do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_disconnect_all_acls)); @@ -713,7 +740,7 @@ static int disconnect_all_acls() { } static void le_rand_btif_cb(uint64_t random_number) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); do_in_jni_thread( FROM_HERE, base::BindOnce( @@ -722,7 +749,7 @@ static void le_rand_btif_cb(uint64_t random_number) { } static int le_rand() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!interface_ready()) return BT_STATUS_NOT_READY; do_in_main_thread( @@ -791,12 +818,13 @@ static void dump(int fd, const char** arguments) { btif_sock_dump(fd); bluetooth::avrcp::AvrcpService::DebugDump(fd); btif_debug_config_dump(fd); + gatt_tcb_dump(fd); device_debug_iot_config_dump(fd); BTA_HfClientDumpStatistics(fd); wakelock_debug_dump(fd); alarm_debug_dump(fd); bluetooth::csis::CsisClient::DebugDump(fd); - le_audio::has::HasClient::DebugDump(fd); + ::le_audio::has::HasClient::DebugDump(fd); HearingAid::DebugDump(fd); LeAudioClient::DebugDump(fd); LeAudioBroadcaster::DebugDump(fd); @@ -818,10 +846,11 @@ static int get_remote_pbap_pce_version(const RawAddress* bd_addr) { // Read and restore the PCE version from local storage uint16_t pce_version = 0; size_t version_value_size = sizeof(pce_version); - if (!btif_config_get_bin(bd_addr->ToString(), BT_CONFIG_KEY_PBAP_PCE_VERSION, + if (!btif_config_get_bin(bd_addr->ToString(), + BTIF_STORAGE_KEY_PBAP_PCE_VERSION, (uint8_t*)&pce_version, &version_value_size)) { - LOG_WARN("Failed to read cached peer PCE version for %s", - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::warn("Failed to read cached peer PCE version for {}", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); } return pce_version; } @@ -831,12 +860,12 @@ static bool pbap_pse_dynamic_version_upgrade_is_enabled() { pbap_pse_dynamic_version_upgrade_is_enabled()) { return true; } - LOG_WARN("PBAP PSE dynamic version upgrade is not enabled"); + log::warn("PBAP PSE dynamic version upgrade is not enabled"); return false; } static const void* get_profile_interface(const char* profile_id) { - LOG_INFO("%s: id = %s", __func__, profile_id); + log::info("id = {}", profile_id); /* sanity check */ if (!interface_ready()) return NULL; @@ -989,15 +1018,15 @@ static int set_os_callouts(bt_os_callouts_t* callouts) { } static int config_clear(void) { - LOG_INFO("%s", __func__); + log::info(""); int ret = BT_STATUS_SUCCESS; if (!btif_config_clear()) { - LOG_ERROR("Failed to clear btif config"); + log::error("Failed to clear btif config"); ret = BT_STATUS_FAIL; } if (!device_iot_config_clear()) { - LOG_ERROR("Failed to clear device iot config"); + log::error("Failed to clear device iot config"); ret = BT_STATUS_FAIL; } @@ -1021,8 +1050,9 @@ static int set_dynamic_audio_buffer_size(int codec, int size) { return btif_set_dynamic_audio_buffer_size(codec, size); } -static bool allow_low_latency_audio(bool allowed, const RawAddress& address) { - LOG_INFO("%s %s", __func__, allowed ? "true" : "false"); +static bool allow_low_latency_audio(bool allowed, + const RawAddress& /* address */) { + log::info("{}", allowed); bluetooth::audio::a2dp::set_audio_low_latency_mode_allowed(allowed); return true; } @@ -1030,7 +1060,7 @@ static bool allow_low_latency_audio(bool allowed, const RawAddress& address) { static void metadata_changed(const RawAddress& remote_bd_addr, int key, std::vector value) { if (!interface_ready()) { - LOG_ERROR("Interface not ready!"); + log::error("Interface not ready!"); return; } @@ -1047,7 +1077,7 @@ static bool interop_match_addr(const char* feature_name, int feature = interop_feature_name_to_feature_id(feature_name); if (feature == -1) { - LOG_ERROR("%s: feature doesn't exist: %s", __func__, feature_name); + log::error("feature doesn't exist: {}", feature_name); return false; } @@ -1061,7 +1091,7 @@ static bool interop_match_name(const char* feature_name, const char* name) { int feature = interop_feature_name_to_feature_id(feature_name); if (feature == -1) { - LOG_ERROR("%s: feature doesn't exist: %s", __func__, feature_name); + log::error("feature doesn't exist: {}", feature_name); return false; } @@ -1076,7 +1106,7 @@ static bool interop_match_addr_or_name(const char* feature_name, int feature = interop_feature_name_to_feature_id(feature_name); if (feature == -1) { - LOG_ERROR("%s: feature doesn't exist: %s", __func__, feature_name); + log::error("feature doesn't exist: {}", feature_name); return false; } @@ -1094,7 +1124,7 @@ static void interop_database_add_remove_addr(bool do_add, int feature = interop_feature_name_to_feature_id(feature_name); if (feature == -1) { - LOG_ERROR("%s: feature doesn't exist: %s", __func__, feature_name); + log::error("feature doesn't exist: {}", feature_name); return; } @@ -1114,7 +1144,7 @@ static void interop_database_add_remove_name(bool do_add, int feature = interop_feature_name_to_feature_id(feature_name); if (feature == -1) { - LOG_ERROR("%s: feature doesn't exist: %s", __func__, feature_name); + log::error("feature doesn't exist: {}", feature_name); return; } @@ -1146,6 +1176,7 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = { .create_bond_out_of_band = create_bond_out_of_band, .remove_bond = remove_bond, .cancel_bond = cancel_bond, + .pairing_is_busy = pairing_is_busy, .get_connection_state = get_connection_state, .pin_reply = pin_reply, .ssp_reply = ssp_reply, @@ -1180,6 +1211,7 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = { set_event_filter_connection_setup_all_devices, .get_wbs_supported = get_wbs_supported, .get_swb_supported = get_swb_supported, + .is_coding_format_supported = is_coding_format_supported, .metadata_changed = metadata_changed, .interop_match_addr = interop_match_addr, .interop_match_name = interop_match_name, @@ -1319,7 +1351,7 @@ void invoke_ssp_request_cb(RawAddress bd_addr, bt_bdname_t bd_name, void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c, Octet16 r, RawAddress raw_address, uint8_t address_type) { - LOG_INFO("%s", __func__); + log::info(""); bt_oob_data_t oob_data = {}; const char* local_name; BTM_ReadLocalDeviceName(&local_name); @@ -1357,7 +1389,7 @@ void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c, }, t, oob_data)); if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("%s: Failed to call callback!", __func__); + log::error("Failed to call callback!"); } } @@ -1484,3 +1516,12 @@ void invoke_switch_codec_cb(bool is_low_latency_buffer_size) { }, is_low_latency_buffer_size)); } + +void invoke_key_missing_cb(RawAddress bd_addr) { + do_in_jni_thread(FROM_HERE, base::BindOnce( + [](RawAddress bd_addr) { + HAL_CBACK(bt_hal_cbacks, key_missing_cb, + bd_addr); + }, + bd_addr)); +} diff --git a/system/btif/src/btif_a2dp.cc b/system/btif/src/btif_a2dp.cc index 58076fa8d9490a2fdd282f64f57979e70d7a7598..c11281a236d5125fc7e537e38ac838ae9afe7897 100644 --- a/system/btif/src/btif_a2dp.cc +++ b/system/btif/src/btif_a2dp.cc @@ -21,6 +21,8 @@ #include "btif_a2dp.h" +#include +#include #include #include "audio_a2dp_hw/include/audio_a2dp_hw.h" @@ -33,18 +35,19 @@ #include "btif_av_co.h" #include "btif_hf.h" #include "btif_util.h" -#include "osi/include/log.h" +#include "internal_include/bt_trace.h" +#include "os/log.h" #include "types/raw_address.h" -#include +using namespace bluetooth; void btif_a2dp_on_idle(const RawAddress& peer_addr) { - LOG_VERBOSE("Peer stream endpoint type:%s", - peer_stream_endpoint_text(btif_av_get_peer_sep()).c_str()); + log::verbose("Peer stream endpoint type:{}", + peer_stream_endpoint_text(btif_av_get_peer_sep())); if (btif_av_src_sink_coexist_enabled()) { bool is_sink = btif_av_peer_is_sink(peer_addr); bool is_source = btif_av_peer_is_source(peer_addr); - LOG_INFO("## ON A2DP IDLE ## is_sink:%d is_source:%d", is_sink, is_source); + log::info("## ON A2DP IDLE ## is_sink:{} is_source:{}", is_sink, is_source); if (is_sink) { btif_a2dp_source_on_idle(); } else if (is_source) { @@ -61,15 +64,14 @@ void btif_a2dp_on_idle(const RawAddress& peer_addr) { } bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start) { - LOG(INFO) << __func__ << ": ## ON A2DP STARTED ## peer " - << ADDRESS_TO_LOGGABLE_STR(peer_addr) << " p_av_start:" - << p_av_start; + log::info("## ON A2DP STARTED ## peer {} p_av_start:{}", + ADDRESS_TO_LOGGABLE_STR(peer_addr), fmt::ptr(p_av_start)); if (p_av_start == NULL) { tA2DP_CTRL_ACK status = A2DP_CTRL_ACK_SUCCESS; if (!bluetooth::headset::IsCallIdle()) { - LOG(ERROR) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(peer_addr) - << " call in progress, do not start A2DP stream"; + log::error("peer {} call in progress, do not start A2DP stream", + ADDRESS_TO_LOGGABLE_STR(peer_addr)); status = A2DP_CTRL_ACK_INCALL_FAILURE; } /* just ack back a local start request, do not start the media encoder since @@ -82,15 +84,14 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start return true; } - LOG(INFO) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(peer_addr) - << " status:" << +p_av_start->status - << " suspending:" << logbool(p_av_start->suspending) << " initiator:" << logbool(p_av_start->initiator); + log::info("peer {} status:{} suspending:{} initiator:{}", + ADDRESS_TO_LOGGABLE_STR(peer_addr), p_av_start->status, + logbool(p_av_start->suspending), logbool(p_av_start->initiator)); if (p_av_start->status == BTA_AV_SUCCESS) { if (p_av_start->suspending) { - LOG(WARNING) << __func__ << ": peer " - << ADDRESS_TO_LOGGABLE_STR(peer_addr) - << " A2DP is suspending and ignores the started event"; + log::warn("peer {} A2DP is suspending and ignores the started event", + ADDRESS_TO_LOGGABLE_STR(peer_addr)); return false; } if (btif_av_is_a2dp_offload_running()) { @@ -112,8 +113,8 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start /* media task is auto-started upon UIPC connection of a2dp audiopath */ } } else if (p_av_start->initiator) { - LOG(ERROR) << __func__ << ": peer " << ADDRESS_TO_LOGGABLE_STR(peer_addr) - << " A2DP start request failed: status = " << +p_av_start->status; + log::error("peer {} A2DP start request failed: status = {}", + ADDRESS_TO_LOGGABLE_STR(peer_addr), p_av_start->status); if (bluetooth::audio::a2dp::is_hal_enabled()) { bluetooth::audio::a2dp::ack_stream_started(A2DP_CTRL_ACK_FAILURE); } else { @@ -125,7 +126,7 @@ bool btif_a2dp_on_started(const RawAddress& peer_addr, tBTA_AV_START* p_av_start } void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) { - LOG_INFO("%s: ## ON A2DP STOPPED ## p_av_suspend=%p", __func__, p_av_suspend); + log::info("## ON A2DP STOPPED ## p_av_suspend={}", fmt::ptr(p_av_suspend)); if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) { btif_a2dp_sink_on_stopped(p_av_suspend); @@ -138,8 +139,7 @@ void btif_a2dp_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) { } void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) { - LOG_INFO("%s: ## ON A2DP SUSPENDED ## p_av_suspend=%p", __func__, - p_av_suspend); + log::info("## ON A2DP SUSPENDED ## p_av_suspend={}", fmt::ptr(p_av_suspend)); if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) { btif_a2dp_sink_on_suspended(p_av_suspend); return; @@ -153,21 +153,20 @@ void btif_a2dp_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) { void btif_a2dp_on_offload_started(const RawAddress& peer_addr, tBTA_AV_STATUS status) { tA2DP_CTRL_ACK ack; - LOG_INFO("%s: peer %s status %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), status); + log::info("peer {} status {}", ADDRESS_TO_LOGGABLE_CSTR(peer_addr), status); switch (status) { case BTA_AV_SUCCESS: ack = A2DP_CTRL_ACK_SUCCESS; break; case BTA_AV_FAIL_RESOURCES: - LOG_ERROR("%s: peer %s FAILED UNSUPPORTED", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::error("peer {} FAILED UNSUPPORTED", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); ack = A2DP_CTRL_ACK_UNSUPPORTED; break; default: - LOG_ERROR("%s: peer %s FAILED: status = %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_addr), status); + log::error("peer {} FAILED: status = {}", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr), status); ack = A2DP_CTRL_ACK_FAILURE; break; } @@ -176,8 +175,8 @@ void btif_a2dp_on_offload_started(const RawAddress& peer_addr, // Offload request will return with failure from btif_av sm if // suspend is triggered for remote start. Disconnect only if SoC // returned failure for offload VSC - LOG_ERROR("%s: peer %s offload start failed", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); + log::error("peer {} offload start failed", + ADDRESS_TO_LOGGABLE_CSTR(peer_addr)); btif_av_src_disconnect_sink(peer_addr); } } diff --git a/system/btif/src/btif_a2dp_control.cc b/system/btif/src/btif_a2dp_control.cc index 0707135259f0919d184eb305e0f60ccdaa2bc68d..d6834a95001317f498c83df86bb4a3d86e025b15 100644 --- a/system/btif/src/btif_a2dp_control.cc +++ b/system/btif/src/btif_a2dp_control.cc @@ -22,22 +22,32 @@ #include "btif_a2dp_control.h" #include +#include #include #include #include "audio_a2dp_hw/include/audio_a2dp_hw.h" -#include "btif_a2dp.h" #include "btif_a2dp_sink.h" #include "btif_a2dp_source.h" #include "btif_av.h" #include "btif_av_co.h" #include "btif_hf.h" -#include "osi/include/osi.h" #include "types/raw_address.h" #include "udrv/include/uipc.h" #define A2DP_DATA_READ_POLL_MS 10 +using namespace bluetooth; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + struct { uint64_t total_bytes_read = 0; uint16_t audio_delay = 0; @@ -65,8 +75,7 @@ void btif_a2dp_control_cleanup(void) { static tA2DP_CTRL_ACK btif_a2dp_control_on_check_ready() { if (btif_a2dp_source_media_task_is_shutting_down()) { - LOG_WARN("%s: A2DP command check ready while media task shutting down", - __func__); + log::warn("A2DP command check ready while media task shutting down"); return A2DP_CTRL_ACK_FAILURE; } @@ -74,8 +83,7 @@ static tA2DP_CTRL_ACK btif_a2dp_control_on_check_ready() { if (btif_av_stream_ready() || btif_av_stream_started_ready()) { return A2DP_CTRL_ACK_SUCCESS; } else { - LOG_WARN("%s: A2DP command check ready while AV stream is not ready", - __func__); + log::warn("A2DP command check ready while AV stream is not ready"); return A2DP_CTRL_ACK_FAILURE; } } @@ -87,7 +95,7 @@ static tA2DP_CTRL_ACK btif_a2dp_control_on_start() { * while in a call, and respond with BAD_STATE. */ if (!bluetooth::headset::IsCallIdle()) { - LOG_WARN("%s: A2DP command start while call state is busy", __func__); + log::warn("A2DP command start while call state is busy"); return A2DP_CTRL_ACK_INCALL_FAILURE; } @@ -114,7 +122,7 @@ static tA2DP_CTRL_ACK btif_a2dp_control_on_start() { A2DP_DATA_PATH); return A2DP_CTRL_ACK_SUCCESS; } - LOG_WARN("%s: A2DP command start while AV stream is not ready", __func__); + log::warn("A2DP command start while AV stream is not ready"); return A2DP_CTRL_ACK_FAILURE; } @@ -200,28 +208,27 @@ static void btif_a2dp_control_on_set_output_audio_config() { reinterpret_cast(&codec_config.sample_rate), sizeof(btav_a2dp_codec_sample_rate_t)) != sizeof(btav_a2dp_codec_sample_rate_t)) { - LOG_ERROR("%s: Error reading sample rate from audio HAL", __func__); + log::error("Error reading sample rate from audio HAL"); return; } if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, reinterpret_cast(&codec_config.bits_per_sample), sizeof(btav_a2dp_codec_bits_per_sample_t)) != sizeof(btav_a2dp_codec_bits_per_sample_t)) { - LOG_ERROR("%s: Error reading bits per sample from audio HAL", __func__); + log::error("Error reading bits per sample from audio HAL"); return; } if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, reinterpret_cast(&codec_config.channel_mode), sizeof(btav_a2dp_codec_channel_mode_t)) != sizeof(btav_a2dp_codec_channel_mode_t)) { - LOG_ERROR("%s: Error reading channel mode from audio HAL", __func__); + log::error("Error reading channel mode from audio HAL"); return; } - LOG_VERBOSE( - "%s: A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: " - "sample_rate=0x%x bits_per_sample=0x%x " - "channel_mode=0x%x", - __func__, codec_config.sample_rate, codec_config.bits_per_sample, + log::verbose( + "A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: sample_rate=0x{:x} " + "bits_per_sample=0x{:x} channel_mode=0x{:x}", + codec_config.sample_rate, codec_config.bits_per_sample, codec_config.channel_mode); btif_a2dp_source_feeding_update_req(codec_config); } @@ -252,7 +259,7 @@ static void btif_a2dp_recv_ctrl_data(void) { /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { - LOG_WARN("%s: CTRL CH DETACHED", __func__); + log::warn("CTRL CH DETACHED"); UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_CTRL); return; } @@ -260,11 +267,9 @@ static void btif_a2dp_recv_ctrl_data(void) { // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it // could be very chatty when audio is streaming. if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) { - LOG_VERBOSE("%s: a2dp-ctrl-cmd : %s", __func__, - audio_a2dp_hw_dump_ctrl_event(cmd)); + log::verbose("a2dp-ctrl-cmd : {}", audio_a2dp_hw_dump_ctrl_event(cmd)); } else { - LOG_WARN("%s: a2dp-ctrl-cmd : %s", __func__, - audio_a2dp_hw_dump_ctrl_event(cmd)); + log::warn("a2dp-ctrl-cmd : {}", audio_a2dp_hw_dump_ctrl_event(cmd)); } a2dp_cmd_pending = cmd; @@ -302,7 +307,7 @@ static void btif_a2dp_recv_ctrl_data(void) { break; default: - LOG_ERROR("%s: UNSUPPORTED CMD (%d)", __func__, cmd); + log::error("UNSUPPORTED CMD ({})", cmd); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); break; } @@ -310,24 +315,19 @@ static void btif_a2dp_recv_ctrl_data(void) { // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it // could be very chatty when audio is streaming. if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) { - LOG_VERBOSE("%s: a2dp-ctrl-cmd : %s DONE", __func__, - audio_a2dp_hw_dump_ctrl_event(cmd)); + log::verbose("a2dp-ctrl-cmd : {} DONE", audio_a2dp_hw_dump_ctrl_event(cmd)); } else { - LOG_WARN("%s: a2dp-ctrl-cmd : %s DONE", __func__, - audio_a2dp_hw_dump_ctrl_event(cmd)); + log::warn("a2dp-ctrl-cmd : {} DONE", audio_a2dp_hw_dump_ctrl_event(cmd)); } } -static void btif_a2dp_ctrl_cb(UNUSED_ATTR tUIPC_CH_ID ch_id, - tUIPC_EVENT event) { +static void btif_a2dp_ctrl_cb(tUIPC_CH_ID /* ch_id */, tUIPC_EVENT event) { // Don't log UIPC_RX_DATA_READY_EVT by default, because it // could be very chatty when audio is streaming. if (event == UIPC_RX_DATA_READY_EVT) { - LOG_VERBOSE("%s: A2DP-CTRL-CHANNEL EVENT %s", __func__, - dump_uipc_event(event)); + log::verbose("A2DP-CTRL-CHANNEL EVENT {}", dump_uipc_event(event)); } else { - LOG_WARN("%s: A2DP-CTRL-CHANNEL EVENT %s", __func__, - dump_uipc_event(event)); + log::warn("A2DP-CTRL-CHANNEL EVENT {}", dump_uipc_event(event)); } switch (event) { @@ -346,16 +346,13 @@ static void btif_a2dp_ctrl_cb(UNUSED_ATTR tUIPC_CH_ID ch_id, break; default: - LOG_ERROR("%s: ### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###", __func__, - event); + log::error("### A2DP-CTRL-CHANNEL EVENT {} NOT HANDLED ###", event); break; } } -static void btif_a2dp_data_cb(UNUSED_ATTR tUIPC_CH_ID ch_id, - tUIPC_EVENT event) { - LOG_WARN("%s: BTIF MEDIA (A2DP-DATA) EVENT %s", __func__, - dump_uipc_event(event)); +static void btif_a2dp_data_cb(tUIPC_CH_ID /* ch_id */, tUIPC_EVENT event) { + log::warn("BTIF MEDIA (A2DP-DATA) EVENT {}", dump_uipc_event(event)); switch (event) { case UIPC_OPEN_EVT: @@ -377,14 +374,14 @@ static void btif_a2dp_data_cb(UNUSED_ATTR tUIPC_CH_ID ch_id, break; case UIPC_CLOSE_EVT: - LOG_VERBOSE("%s: ## AUDIO PATH DETACHED ##", __func__); + log::verbose("## AUDIO PATH DETACHED ##"); btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); /* Post stop event and wait for audio path to stop */ btif_av_stream_stop(RawAddress::kEmpty); break; default: - LOG_ERROR("%s: ### A2DP-DATA EVENT %d NOT HANDLED ###", __func__, event); + log::error("### A2DP-DATA EVENT {} NOT HANDLED ###", event); break; } } @@ -395,16 +392,16 @@ void btif_a2dp_command_ack(tA2DP_CTRL_ACK status) { // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it // could be very chatty when audio is streaming. if (a2dp_cmd_pending == A2DP_CTRL_GET_PRESENTATION_POSITION) { - LOG_VERBOSE("%s: ## a2dp ack : %s, status %d ##", __func__, - audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status); + log::verbose("## a2dp ack : {}, status {} ##", + audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status); } else { - LOG_WARN("%s: ## a2dp ack : %s, status %d ##", __func__, - audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status); + log::warn("## a2dp ack : {}, status {} ##", + audio_a2dp_hw_dump_ctrl_event(a2dp_cmd_pending), status); } /* Sanity check */ if (a2dp_cmd_pending == A2DP_CTRL_CMD_NONE) { - LOG_ERROR("%s: warning : no command pending, ignore ack", __func__); + log::error("warning : no command pending, ignore ack"); return; } @@ -423,12 +420,12 @@ void btif_a2dp_control_log_bytes_read(uint32_t bytes_read) { } void btif_a2dp_control_set_audio_delay(uint16_t delay) { - LOG_VERBOSE("%s: DELAY: %.1f ms", __func__, (float)delay / 10); + log::verbose("DELAY: {:.1f} ms", (float)delay / 10); delay_report_stats.audio_delay = delay; } void btif_a2dp_control_reset_audio_delay(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); delay_report_stats.audio_delay = 0; delay_report_stats.total_bytes_read = 0; delay_report_stats.timestamp = {}; diff --git a/system/btif/src/btif_a2dp_sink.cc b/system/btif/src/btif_a2dp_sink.cc index be2098788ec494c616a340661c128972965bb749..8e0083b014a5dfc598bf1842633f3a2f456f119e 100644 --- a/system/btif/src/btif_a2dp_sink.cc +++ b/system/btif/src/btif_a2dp_sink.cc @@ -23,27 +23,28 @@ #include #include +#include #include #include #include -#include "bt_target.h" // Must be first to define build configuration #include "btif/include/btif_av.h" #include "btif/include/btif_av_co.h" #include "btif/include/btif_avrcp_audio_track.h" #include "btif/include/btif_util.h" // CASE_RETURN_STR #include "common/message_loop_thread.h" +#include "include/check.h" +#include "os/log.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "osi/include/fixed_queue.h" -#include "osi/include/log.h" -#include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/bt_hdr.h" #include "types/raw_address.h" using bluetooth::common::MessageLoopThread; using LockGuard = std::lock_guard; +using namespace bluetooth; /** * The receiving queue buffer size. @@ -157,7 +158,7 @@ static void btif_a2dp_sink_clear_track_event_req(); static void btif_a2dp_sink_on_start_event(); static void btif_a2dp_sink_on_suspend_event(); -UNUSED_ATTR static const char* dump_media_event(uint16_t event) { +static const char* dump_media_event(uint16_t event) { switch (event) { CASE_RETURN_STR(BTIF_MEDIA_SINK_DECODER_UPDATE) CASE_RETURN_STR(BTIF_MEDIA_SINK_CLEAR_TRACK) @@ -172,11 +173,11 @@ UNUSED_ATTR static const char* dump_media_event(uint16_t event) { } bool btif_a2dp_sink_init() { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); if (btif_a2dp_sink_state != BTIF_A2DP_SINK_STATE_OFF) { - LOG_ERROR("%s: A2DP Sink media task already running", __func__); + log::error("A2DP Sink media task already running"); return false; } @@ -186,7 +187,7 @@ bool btif_a2dp_sink_init() { /* Start A2DP Sink media task */ btif_a2dp_sink_cb.worker_thread.StartUp(); if (!btif_a2dp_sink_cb.worker_thread.IsRunning()) { - LOG_ERROR("%s: unable to start up media thread", __func__); + log::error("unable to start up media thread"); btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_OFF; return false; } @@ -196,8 +197,7 @@ bool btif_a2dp_sink_init() { /* Schedule the rest of the operations */ if (!btif_a2dp_sink_cb.worker_thread.EnableRealTimeScheduling()) { #if defined(__ANDROID__) - LOG(FATAL) << __func__ - << ": Failed to increase A2DP decoder thread priority"; + log::fatal("Failed to increase A2DP decoder thread priority"); #endif } btif_a2dp_sink_cb.worker_thread.DoInThread( @@ -206,43 +206,41 @@ bool btif_a2dp_sink_init() { } static void btif_a2dp_sink_init_delayed() { - LOG_INFO("%s", __func__); + log::info(""); btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_RUNNING; } bool btif_a2dp_sink_startup() { - LOG_INFO("%s", __func__); + log::info(""); btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_startup_delayed)); return true; } static void btif_a2dp_sink_startup_delayed() { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); // Nothing to do } bool btif_a2dp_sink_start_session(const RawAddress& peer_address, std::promise peer_ready_promise) { - LOG(INFO) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address); + log::info("peer_address={}", ADDRESS_TO_LOGGABLE_STR(peer_address)); if (btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_start_session_delayed, std::move(peer_ready_promise)))) { return true; } else { // cannot set promise but triggers crash - LOG(FATAL) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " fails to context switch"; + log::fatal("peer_address={} fails to context switch", + ADDRESS_TO_LOGGABLE_STR(peer_address)); return false; } } static void btif_a2dp_sink_start_session_delayed( std::promise peer_ready_promise) { - LOG(INFO) << __func__; + log::info(""); LockGuard lock(g_mutex); peer_ready_promise.set_value(); // Nothing to do @@ -251,9 +249,9 @@ static void btif_a2dp_sink_start_session_delayed( bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address, const RawAddress& new_peer_address, std::promise peer_ready_promise) { - LOG(INFO) << __func__ << ": old_peer_address=" - << ADDRESS_TO_LOGGABLE_STR(old_peer_address) - << " new_peer_address=" << ADDRESS_TO_LOGGABLE_STR(new_peer_address); + log::info("old_peer_address={} new_peer_address={}", + ADDRESS_TO_LOGGABLE_STR(old_peer_address), + ADDRESS_TO_LOGGABLE_STR(new_peer_address)); CHECK(!new_peer_address.IsEmpty()); @@ -262,9 +260,8 @@ bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address, } if (!bta_av_co_set_active_peer(new_peer_address)) { - LOG(ERROR) << __func__ - << ": Cannot stream audio: cannot set active peer to " - << ADDRESS_TO_LOGGABLE_STR(new_peer_address); + log::error("Cannot stream audio: cannot set active peer to {}", + ADDRESS_TO_LOGGABLE_STR(new_peer_address)); peer_ready_promise.set_value(); return false; } @@ -278,33 +275,32 @@ bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address, } bool btif_a2dp_sink_end_session(const RawAddress& peer_address) { - LOG_INFO("%s: peer_address=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("peer_address={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_end_session_delayed)); return true; } static void btif_a2dp_sink_end_session_delayed() { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); // Nothing to do } void btif_a2dp_sink_shutdown() { - LOG_INFO("%s", __func__); + log::info(""); btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_shutdown_delayed)); } static void btif_a2dp_sink_shutdown_delayed() { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); // Nothing to do } void btif_a2dp_sink_cleanup() { - LOG_INFO("%s", __func__); + log::info(""); alarm_t* decode_alarm; @@ -334,7 +330,7 @@ void btif_a2dp_sink_cleanup() { } static void btif_a2dp_sink_cleanup_delayed() { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); fixed_queue_free(btif_a2dp_sink_cb.rx_audio_queue, nullptr); @@ -358,8 +354,7 @@ tA2DP_CHANNEL_COUNT btif_a2dp_sink_get_channel_count() { } static void btif_a2dp_sink_command_ready(BT_HDR_RIGID* p_msg) { - LOG_VERBOSE("%s: event %d %s", __func__, p_msg->event, - dump_media_event(p_msg->event)); + log::verbose("event {} {}", p_msg->event, dump_media_event(p_msg->event)); switch (p_msg->event) { case BTIF_MEDIA_SINK_DECODER_UPDATE: @@ -385,23 +380,23 @@ static void btif_a2dp_sink_command_ready(BT_HDR_RIGID* p_msg) { btif_a2dp_sink_on_suspend_event(); break; default: - LOG_ERROR("%s: unknown event %d", __func__, p_msg->event); + log::error("unknown event {}", p_msg->event); break; } - LOG_VERBOSE("%s: %s DONE", __func__, dump_media_event(p_msg->event)); + log::verbose("{} DONE", dump_media_event(p_msg->event)); osi_free(p_msg); } void btif_a2dp_sink_update_decoder(const uint8_t* p_codec_info) { - LOG_INFO("%s", __func__); + log::info(""); tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf = reinterpret_cast( osi_malloc(sizeof(tBTIF_MEDIA_SINK_DECODER_UPDATE))); - LOG_VERBOSE("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__, p_codec_info[1], - p_codec_info[2], p_codec_info[3], p_codec_info[4], - p_codec_info[5], p_codec_info[6]); + log::verbose("p_codec_info[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", p_codec_info[1], + p_codec_info[2], p_codec_info[3], p_codec_info[4], + p_codec_info[5], p_codec_info[6]); memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE); p_buf->hdr.event = BTIF_MEDIA_SINK_DECODER_UPDATE; @@ -412,7 +407,7 @@ void btif_a2dp_sink_update_decoder(const uint8_t* p_codec_info) { } void btif_a2dp_sink_on_idle() { - LOG_INFO("%s", __func__); + log::info(""); BT_HDR_RIGID* p_buf = reinterpret_cast(osi_malloc(sizeof(BT_HDR_RIGID))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; @@ -424,8 +419,8 @@ void btif_a2dp_sink_on_idle() { btif_a2dp_sink_clear_track_event_req(); } -void btif_a2dp_sink_on_stopped(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { - LOG_INFO("%s", __func__); +void btif_a2dp_sink_on_stopped(tBTA_AV_SUSPEND* /* p_av_suspend */) { + log::info(""); BT_HDR_RIGID* p_buf = reinterpret_cast(osi_malloc(sizeof(BT_HDR_RIGID))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; @@ -436,8 +431,8 @@ void btif_a2dp_sink_on_stopped(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { btif_a2dp_sink_audio_handle_stop_decoding(); } -void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { - LOG_INFO("%s", __func__); +void btif_a2dp_sink_on_suspended(tBTA_AV_SUSPEND* /* p_av_suspend */) { + log::info(""); BT_HDR_RIGID* p_buf = reinterpret_cast(osi_malloc(sizeof(BT_HDR_RIGID))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; @@ -449,7 +444,7 @@ void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { } bool btif_a2dp_sink_on_start() { - LOG_INFO("%s", __func__); + log::info(""); BT_HDR_RIGID* p_buf = reinterpret_cast(osi_malloc(sizeof(BT_HDR_RIGID))); @@ -461,7 +456,7 @@ bool btif_a2dp_sink_on_start() { } static void btif_a2dp_sink_audio_handle_stop_decoding() { - LOG_INFO("%s", __func__); + log::info(""); alarm_t* old_alarm; { LockGuard lock(g_mutex); @@ -485,14 +480,14 @@ static void btif_a2dp_sink_audio_handle_stop_decoding() { } } -static void btif_decode_alarm_cb(UNUSED_ATTR void* context) { +static void btif_decode_alarm_cb(void* /* context */) { LockGuard lock(g_mutex); btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_avk_handle_timer)); } static void btif_a2dp_sink_clear_track_event() { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); #ifdef __ANDROID__ @@ -504,7 +499,7 @@ static void btif_a2dp_sink_clear_track_event() { // Must be called while locked. static void btif_a2dp_sink_audio_handle_start_decoding() { - LOG_INFO("%s", __func__); + log::info(""); if (btif_a2dp_sink_cb.decode_alarm != nullptr) return; // Already started decoding @@ -514,7 +509,7 @@ static void btif_a2dp_sink_audio_handle_start_decoding() { btif_a2dp_sink_cb.decode_alarm = alarm_new_periodic("btif.a2dp_sink_decode"); if (btif_a2dp_sink_cb.decode_alarm == nullptr) { - LOG_ERROR("%s: unable to allocate decode alarm", __func__); + log::error("unable to allocate decode alarm"); return; } alarm_set(btif_a2dp_sink_cb.decode_alarm, BTIF_SINK_MEDIA_TIME_TICK_MS, @@ -532,13 +527,13 @@ static void btif_a2dp_sink_on_decode_complete(uint8_t* data, uint32_t len) { static void btif_a2dp_sink_handle_inc_media(BT_HDR* p_msg) { if ((btif_av_get_peer_sep() == AVDT_TSEP_SNK) || (btif_a2dp_sink_cb.rx_flush)) { - LOG_VERBOSE("%s: state changed happened in this tick", __func__); + log::verbose("state changed happened in this tick"); return; } CHECK(btif_a2dp_sink_cb.decoder_interface != nullptr); if (!btif_a2dp_sink_cb.decoder_interface->decode_packet(p_msg)) { - LOG_ERROR("%s: decoding failed", __func__); + log::error("decoding failed"); } } @@ -547,13 +542,13 @@ static void btif_a2dp_sink_avk_handle_timer() { BT_HDR* p_msg; if (fixed_queue_is_empty(btif_a2dp_sink_cb.rx_audio_queue)) { - LOG_VERBOSE("%s: empty queue", __func__); + log::verbose("empty queue"); return; } /* Don't do anything in case of focus not granted */ if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_NOT_GRANTED) { - LOG_VERBOSE("%s: skipping frames since focus is not present", __func__); + log::verbose("skipping frames since focus is not present"); return; } /* Play only in BTIF_A2DP_SINK_FOCUS_GRANTED case */ @@ -562,32 +557,32 @@ static void btif_a2dp_sink_avk_handle_timer() { return; } - LOG_VERBOSE("%s: process frames begin", __func__); + log::verbose("process frames begin"); while (true) { p_msg = (BT_HDR*)fixed_queue_try_dequeue(btif_a2dp_sink_cb.rx_audio_queue); if (p_msg == NULL) { break; } - LOG_VERBOSE("%s: number of packets in queue %zu", __func__, - fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue)); + log::verbose("number of packets in queue {}", + fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue)); /* Queue packet has less frames */ btif_a2dp_sink_handle_inc_media(p_msg); osi_free(p_msg); } - LOG_VERBOSE("%s: process frames end", __func__); + log::verbose("process frames end"); } /* when true media task discards any rx frames */ void btif_a2dp_sink_set_rx_flush(bool enable) { - LOG_INFO("%s: enable=%s", __func__, (enable) ? "true" : "false"); + log::info("enable={}", (enable) ? "true" : "false"); LockGuard lock(g_mutex); btif_a2dp_sink_cb.rx_flush = enable; } static void btif_a2dp_sink_audio_rx_flush_event() { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); // Flush all received encoded audio buffers fixed_queue_flush(btif_a2dp_sink_cb.rx_audio_queue, osi_free); @@ -595,30 +590,31 @@ static void btif_a2dp_sink_audio_rx_flush_event() { static void btif_a2dp_sink_decoder_update_event( tBTIF_MEDIA_SINK_DECODER_UPDATE* p_buf) { - LOG_INFO("%s", __func__); + log::info(""); LockGuard lock(g_mutex); - LOG_VERBOSE("%s: p_codec_info[%x:%x:%x:%x:%x:%x]", __func__, - p_buf->codec_info[1], p_buf->codec_info[2], p_buf->codec_info[3], - p_buf->codec_info[4], p_buf->codec_info[5], p_buf->codec_info[6]); + log::verbose("p_codec_info[{:x}:{:x}:{:x}:{:x}:{:x}:{:x}]", + p_buf->codec_info[1], p_buf->codec_info[2], p_buf->codec_info[3], + p_buf->codec_info[4], p_buf->codec_info[5], + p_buf->codec_info[6]); int sample_rate = A2DP_GetTrackSampleRate(p_buf->codec_info); if (sample_rate == -1) { - LOG_ERROR("%s: cannot get the track frequency", __func__); + log::error("cannot get the track frequency"); return; } int bits_per_sample = A2DP_GetTrackBitsPerSample(p_buf->codec_info); if (bits_per_sample == -1) { - LOG_ERROR("%s: cannot get the bits per sample", __func__); + log::error("cannot get the bits per sample"); return; } int channel_count = A2DP_GetTrackChannelCount(p_buf->codec_info); if (channel_count == -1) { - LOG_ERROR("%s: cannot get the channel count", __func__); + log::error("cannot get the channel count"); return; } int channel_type = A2DP_GetSinkTrackChannelType(p_buf->codec_info); if (channel_type == -1) { - LOG_ERROR("%s: cannot get the Sink channel type", __func__); + log::error("cannot get the Sink channel type"); return; } btif_a2dp_sink_cb.sample_rate = sample_rate; @@ -626,7 +622,7 @@ static void btif_a2dp_sink_decoder_update_event( btif_a2dp_sink_cb.channel_count = channel_count; btif_a2dp_sink_cb.rx_flush = false; - LOG_VERBOSE("%s: reset to Sink role", __func__); + log::verbose("reset to Sink role"); bta_av_co_save_codec(p_buf->codec_info); @@ -634,13 +630,13 @@ static void btif_a2dp_sink_decoder_update_event( A2DP_GetDecoderInterface(p_buf->codec_info); if (btif_a2dp_sink_cb.decoder_interface == nullptr) { - LOG_ERROR("%s: cannot stream audio: no source decoder interface", __func__); + log::error("cannot stream audio: no source decoder interface"); return; } if (!btif_a2dp_sink_cb.decoder_interface->decoder_init( btif_a2dp_sink_on_decode_complete)) { - LOG_ERROR("%s: failed to initialize decoder", __func__); + log::error("failed to initialize decoder"); return; } @@ -648,7 +644,7 @@ static void btif_a2dp_sink_decoder_update_event( btif_a2dp_sink_cb.decoder_interface->decoder_configure(p_buf->codec_info); } - LOG_VERBOSE("%s: create audio track", __func__); + log::verbose("create audio track"); btif_a2dp_sink_cb.audio_track = #ifdef __ANDROID__ BtifAvrcpAudioTrackCreate(sample_rate, bits_per_sample, channel_count); @@ -656,7 +652,7 @@ static void btif_a2dp_sink_decoder_update_event( NULL; #endif if (btif_a2dp_sink_cb.audio_track == nullptr) { - LOG_ERROR("%s: track creation failed", __func__); + log::error("track creation failed"); return; } } @@ -666,7 +662,7 @@ uint8_t btif_a2dp_sink_enqueue_buf(BT_HDR* p_pkt) { if (btif_a2dp_sink_cb.rx_flush) /* Flush enabled, do not enqueue */ return fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue); - LOG_VERBOSE("%s +", __func__); + log::verbose("+"); /* Allocate and queue this buffer */ BT_HDR* p_msg = reinterpret_cast(osi_malloc(sizeof(*p_msg) + p_pkt->len)); @@ -686,8 +682,8 @@ uint8_t btif_a2dp_sink_enqueue_buf(BT_HDR* p_pkt) { if (btif_a2dp_sink_cb.decode_alarm == nullptr && fixed_queue_length(btif_a2dp_sink_cb.rx_audio_queue) >= MAX_A2DP_DELAYED_START_FRAME_COUNT) { - LOG_VERBOSE("%s: Initiate decoding. Current focus state:%d", __func__, - btif_a2dp_sink_cb.rx_focus_state); + log::verbose("Initiate decoding. Current focus state:{}", + btif_a2dp_sink_cb.rx_focus_state); if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_GRANTED) { btif_a2dp_sink_audio_handle_start_decoding(); } @@ -697,7 +693,7 @@ uint8_t btif_a2dp_sink_enqueue_buf(BT_HDR* p_pkt) { } void btif_a2dp_sink_audio_rx_flush_req() { - LOG_INFO("%s", __func__); + log::info(""); if (fixed_queue_is_empty(btif_a2dp_sink_cb.rx_audio_queue)) { /* Queue is already empty */ return; @@ -710,12 +706,12 @@ void btif_a2dp_sink_audio_rx_flush_req() { FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); } -void btif_a2dp_sink_debug_dump(UNUSED_ATTR int fd) { +void btif_a2dp_sink_debug_dump(int /* fd */) { // Nothing to do } void btif_a2dp_sink_set_focus_state_req(btif_a2dp_sink_focus_state_t state) { - LOG_INFO("%s", __func__); + log::info(""); tBTIF_MEDIA_SINK_FOCUS_UPDATE* p_buf = reinterpret_cast( osi_malloc(sizeof(tBTIF_MEDIA_SINK_FOCUS_UPDATE))); @@ -728,10 +724,10 @@ void btif_a2dp_sink_set_focus_state_req(btif_a2dp_sink_focus_state_t state) { static void btif_a2dp_sink_set_focus_state_event( btif_a2dp_sink_focus_state_t state) { - LOG_INFO("%s: state=%d", __func__, state); + log::info("state={}", state); LockGuard lock(g_mutex); - LOG_VERBOSE("%s: setting focus state to %d", __func__, state); + log::verbose("setting focus state to {}", state); btif_a2dp_sink_cb.rx_focus_state = state; if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_NOT_GRANTED) { fixed_queue_flush(btif_a2dp_sink_cb.rx_audio_queue, osi_free); @@ -742,7 +738,7 @@ static void btif_a2dp_sink_set_focus_state_event( } void btif_a2dp_sink_set_audio_track_gain(float gain) { - LOG_DEBUG("%s: set gain to %f", __func__, gain); + log::debug("set gain to {:f}", gain); LockGuard lock(g_mutex); #ifdef __ANDROID__ @@ -756,7 +752,7 @@ void * btif_a2dp_sink_get_audio_track(void) } static void btif_a2dp_sink_clear_track_event_req() { - LOG_INFO("%s", __func__); + log::info(""); BT_HDR_RIGID* p_buf = reinterpret_cast(osi_malloc(sizeof(BT_HDR_RIGID))); @@ -766,7 +762,7 @@ static void btif_a2dp_sink_clear_track_event_req() { } static void btif_a2dp_sink_on_start_event() { - LOG_INFO("%s", __func__); + log::info(""); if ((btif_a2dp_sink_cb.decoder_interface != nullptr) && (btif_a2dp_sink_cb.decoder_interface->decoder_start != nullptr)) { @@ -777,7 +773,7 @@ static void btif_a2dp_sink_on_start_event() { } static void btif_a2dp_sink_on_suspend_event() { - LOG_INFO("%s", __func__); + log::info(""); if ((btif_a2dp_sink_cb.decoder_interface != nullptr) && (btif_a2dp_sink_cb.decoder_interface->decoder_suspend != nullptr)) { diff --git a/system/btif/src/btif_a2dp_source.cc b/system/btif/src/btif_a2dp_source.cc index c0cb38fd08487feddfb8bf978d46da969dd5df1d..6b6555ec88d2c79cedd65002c5d6e969c4d8dfd4 100644 --- a/system/btif/src/btif_a2dp_source.cc +++ b/system/btif/src/btif_a2dp_source.cc @@ -20,8 +20,10 @@ #define LOG_TAG "bt_btif_a2dp_source" #define ATRACE_TAG ATRACE_TAG_AUDIO +#include #include #include +#include #ifdef __ANDROID__ #include #endif @@ -35,21 +37,19 @@ #include "audio_a2dp_hw/include/audio_a2dp_hw.h" #include "audio_hal_interface/a2dp_encoding.h" #include "bta_av_ci.h" -#include "btif_a2dp.h" #include "btif_a2dp_control.h" #include "btif_a2dp_source.h" #include "btif_av.h" #include "btif_av_co.h" #include "btif_metrics_logging.h" -#include "btif_util.h" #include "common/message_loop_thread.h" #include "common/metrics.h" #include "common/repeating_timer.h" #include "common/time_util.h" +#include "include/check.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/fixed_queue.h" -#include "osi/include/log.h" -#include "osi/include/osi.h" #include "osi/include/wakelock.h" #include "stack/include/acl_api.h" #include "stack/include/acl_api_types.h" @@ -60,6 +60,7 @@ using bluetooth::common::A2dpSessionMetrics; using bluetooth::common::BluetoothMetricsLogger; using bluetooth::common::RepeatingTimer; +using namespace bluetooth; extern std::unique_ptr a2dp_uipc; @@ -330,25 +331,31 @@ void btif_a2dp_source_accumulate_stats(BtifMediaStats* src, } bool btif_a2dp_source_init(void) { - LOG_INFO("%s", __func__); + log::info(""); // Start A2DP Source media task btif_a2dp_source_thread.StartUp(); btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_init_delayed)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_init_delayed)); return true; } static void btif_a2dp_source_init_delayed(void) { - LOG_INFO("%s", __func__); - // Nothing to do + log::info(""); + // When codec extensibility is enabled in the audio HAL interface, + // the provider needs to be initialized earlier in order to ensure + // get_a2dp_configuration and parse_a2dp_configuration can be + // invoked before the stream is started. + if (IS_FLAG_ENABLED(a2dp_offload_codec_extensibility)) { + bluetooth::audio::a2dp::init(&btif_a2dp_source_thread); + } } bool btif_a2dp_source_startup(void) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateOff) { - LOG_ERROR("%s: A2DP Source media task already running", __func__); + log::error("A2DP Source media task already running"); return false; } @@ -358,24 +365,24 @@ bool btif_a2dp_source_startup(void) { // Schedule the rest of the operations btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_startup_delayed)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_startup_delayed)); return true; } static void btif_a2dp_source_startup_delayed() { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if (!btif_a2dp_source_thread.EnableRealTimeScheduling()) { #if defined(__ANDROID__) - LOG(FATAL) << __func__ << ": unable to enable real time scheduling"; + log::fatal("unable to enable real time scheduling"); #endif } if (!bluetooth::audio::a2dp::init(&btif_a2dp_source_thread)) { if (btif_av_is_a2dp_offload_enabled()) { // TODO: BluetoothA2dp@1.0 is deprecated - LOG(WARNING) << __func__ << ": Using BluetoothA2dp HAL"; + log::warn("Using BluetoothA2dp HAL"); } else { - LOG(WARNING) << __func__ << ": Using legacy HAL"; + log::warn("Using legacy HAL"); btif_a2dp_control_init(); } } @@ -384,9 +391,8 @@ static void btif_a2dp_source_startup_delayed() { bool btif_a2dp_source_start_session(const RawAddress& peer_address, std::promise peer_ready_promise) { - LOG(INFO) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " state=" << btif_a2dp_source_cb.StateStr(); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_STR(peer_address), + btif_a2dp_source_cb.StateStr()); btif_a2dp_source_setup_codec(peer_address); if (btif_a2dp_source_thread.DoInThread( FROM_HERE, @@ -395,21 +401,19 @@ bool btif_a2dp_source_start_session(const RawAddress& peer_address, return true; } else { // cannot set promise but triggers crash - LOG(FATAL) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " state=" << btif_a2dp_source_cb.StateStr() - << " fails to context switch"; + log::fatal("peer_address={} state={} fails to context switch", + ADDRESS_TO_LOGGABLE_STR(peer_address), + btif_a2dp_source_cb.StateStr()); return false; } } static void btif_a2dp_source_start_session_delayed( const RawAddress& peer_address, std::promise peer_ready_promise) { - LOG(INFO) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " state=" << btif_a2dp_source_cb.StateStr(); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_STR(peer_address), + btif_a2dp_source_cb.StateStr()); if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateRunning) { - LOG(ERROR) << __func__ << ": A2DP Source media task is not running"; + log::error("A2DP Source media task is not running"); peer_ready_promise.set_value(); return; } @@ -428,10 +432,10 @@ static void btif_a2dp_source_start_session_delayed( bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address, const RawAddress& new_peer_address, std::promise peer_ready_promise) { - LOG(INFO) << __func__ << ": old_peer_address=" - << ADDRESS_TO_LOGGABLE_STR(old_peer_address) - << " new_peer_address=" << ADDRESS_TO_LOGGABLE_STR(new_peer_address) - << " state=" << btif_a2dp_source_cb.StateStr(); + log::info("old_peer_address={} new_peer_address={} state={}", + ADDRESS_TO_LOGGABLE_STR(old_peer_address), + ADDRESS_TO_LOGGABLE_STR(new_peer_address), + btif_a2dp_source_cb.StateStr()); CHECK(!new_peer_address.IsEmpty()); @@ -455,26 +459,24 @@ bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address, } bool btif_a2dp_source_end_session(const RawAddress& peer_address) { - LOG_INFO("%s: peer_address=%s state=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - btif_a2dp_source_cb.StateStr().c_str()); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + btif_a2dp_source_cb.StateStr()); btif_a2dp_source_thread.DoInThread( FROM_HERE, - base::Bind(&btif_a2dp_source_end_session_delayed, peer_address)); + base::BindOnce(&btif_a2dp_source_end_session_delayed, peer_address)); btif_a2dp_source_cleanup_codec(); return true; } static void btif_a2dp_source_end_session_delayed( const RawAddress& peer_address) { - LOG_INFO("%s: peer_address=%s state=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - btif_a2dp_source_cb.StateStr().c_str()); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + btif_a2dp_source_cb.StateStr()); if ((btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning) || (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateShuttingDown)) { btif_av_stream_stop(peer_address); } else { - LOG_ERROR("%s: A2DP Source media task is not running", __func__); + log::error("A2DP Source media task is not running"); } if (bluetooth::audio::a2dp::is_hal_enabled()) { bluetooth::audio::a2dp::end_session(); @@ -487,7 +489,7 @@ static void btif_a2dp_source_end_session_delayed( } void btif_a2dp_source_shutdown(std::promise shutdown_complete_promise) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if ((btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) || (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateShuttingDown)) { @@ -504,7 +506,7 @@ void btif_a2dp_source_shutdown(std::promise shutdown_complete_promise) { static void btif_a2dp_source_shutdown_delayed( std::promise shutdown_complete_promise) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); // Stop the timer btif_a2dp_source_cb.media_alarm.CancelAndWait(); @@ -524,21 +526,21 @@ static void btif_a2dp_source_shutdown_delayed( } void btif_a2dp_source_cleanup(void) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); // Make sure the source is shutdown std::promise shutdown_complete_promise; btif_a2dp_source_shutdown(std::move(shutdown_complete_promise)); btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_cleanup_delayed)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_cleanup_delayed)); // Exit the thread btif_a2dp_source_thread.ShutDown(); } static void btif_a2dp_source_cleanup_delayed(void) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); // Nothing to do } @@ -556,9 +558,8 @@ bool btif_a2dp_source_is_streaming(void) { } static void btif_a2dp_source_setup_codec(const RawAddress& peer_address) { - LOG_INFO("%s: peer_address=%s state=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - btif_a2dp_source_cb.StateStr().c_str()); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + btif_a2dp_source_cb.StateStr()); // Check to make sure the platform has 8 bits/byte since // we're using that in frame size calculations now. @@ -567,32 +568,31 @@ static void btif_a2dp_source_setup_codec(const RawAddress& peer_address) { btif_a2dp_source_audio_tx_flush_req(); btif_a2dp_source_thread.DoInThread( FROM_HERE, - base::Bind(&btif_a2dp_source_setup_codec_delayed, peer_address)); + base::BindOnce(&btif_a2dp_source_setup_codec_delayed, peer_address)); } static void btif_a2dp_source_setup_codec_delayed( const RawAddress& peer_address) { - LOG_INFO("%s: peer_address=%s state=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - btif_a2dp_source_cb.StateStr().c_str()); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + btif_a2dp_source_cb.StateStr()); tA2DP_ENCODER_INIT_PEER_PARAMS peer_params; bta_av_co_get_peer_params(peer_address, &peer_params); if (!bta_av_co_set_active_peer(peer_address)) { - LOG_ERROR("%s: Cannot stream audio: cannot set active peer to %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("Cannot stream audio: cannot set active peer to {}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return; } btif_a2dp_source_cb.encoder_interface = bta_av_co_get_encoder_interface(); if (btif_a2dp_source_cb.encoder_interface == nullptr) { - LOG_ERROR("%s: Cannot stream audio: no source encoder interface", __func__); + log::error("Cannot stream audio: no source encoder interface"); return; } A2dpCodecConfig* a2dp_codec_config = bta_av_get_a2dp_current_codec(); if (a2dp_codec_config == nullptr) { - LOG_ERROR("%s: Cannot stream audio: current codec is not set", __func__); + log::error("Cannot stream audio: current codec is not set"); return; } @@ -610,15 +610,15 @@ static void btif_a2dp_source_setup_codec_delayed( } static void btif_a2dp_source_cleanup_codec() { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); // Must stop media task first before cleaning up the encoder btif_a2dp_source_stop_audio_req(); btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_cleanup_codec_delayed)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_cleanup_codec_delayed)); } static void btif_a2dp_source_cleanup_codec_delayed() { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if (btif_a2dp_source_cb.encoder_interface != nullptr) { btif_a2dp_source_cb.encoder_interface->encoder_cleanup(); btif_a2dp_source_cb.encoder_interface = nullptr; @@ -626,37 +626,35 @@ static void btif_a2dp_source_cleanup_codec_delayed() { } void btif_a2dp_source_start_audio_req(void) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_start_event)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_tx_start_event)); } void btif_a2dp_source_stop_audio_req(void) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_stop_event)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_tx_stop_event)); } void btif_a2dp_source_encoder_user_config_update_req( const RawAddress& peer_address, const std::vector& codec_user_preferences, std::promise peer_ready_promise) { - LOG(INFO) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " state=" << btif_a2dp_source_cb.StateStr() << " " - << codec_user_preferences.size() << " codec_preference(s)"; + log::info("peer_address={} state={} {} codec_preference(s)", + ADDRESS_TO_LOGGABLE_STR(peer_address), + btif_a2dp_source_cb.StateStr(), codec_user_preferences.size()); if (!btif_a2dp_source_thread.DoInThread( FROM_HERE, base::BindOnce(&btif_a2dp_source_encoder_user_config_update_event, peer_address, codec_user_preferences, std::move(peer_ready_promise)))) { // cannot set promise but triggers crash - LOG(FATAL) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " state=" << btif_a2dp_source_cb.StateStr() - << " fails to context switch"; + log::fatal("peer_address={} state={} fails to context switch", + ADDRESS_TO_LOGGABLE_STR(peer_address), + btif_a2dp_source_cb.StateStr()); } } @@ -670,11 +668,10 @@ static void btif_a2dp_source_encoder_user_config_update_event( success = bta_av_co_set_codec_user_config(peer_address, codec_user_config, &restart_output); if (success) { - LOG(INFO) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " state=" << btif_a2dp_source_cb.StateStr() - << " codec_preference={" << codec_user_config.ToString() - << "} restart_output=" << (restart_output ? "true" : "false"); + log::info( + "peer_address={} state={} codec_preference=[{}] restart_output={}", + ADDRESS_TO_LOGGABLE_STR(peer_address), btif_a2dp_source_cb.StateStr(), + codec_user_config.ToString(), (restart_output ? "true" : "false")); break; } } @@ -686,7 +683,7 @@ static void btif_a2dp_source_encoder_user_config_update_event( return; } if (!success) { - LOG(ERROR) << __func__ << ": cannot update codec user configuration(s)"; + log::error("cannot update codec user configuration(s)"); } if (!peer_address.IsEmpty() && peer_address == btif_av_source_active_peer()) { // No more actions needed with remote, and if succeed, user had changed the @@ -700,22 +697,22 @@ static void btif_a2dp_source_encoder_user_config_update_event( void btif_a2dp_source_feeding_update_req( const btav_a2dp_codec_config_t& codec_audio_config) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_audio_feeding_update_event, - codec_audio_config)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_feeding_update_event, + codec_audio_config)); } static void btif_a2dp_source_audio_feeding_update_event( const btav_a2dp_codec_config_t& codec_audio_config) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if (!bta_av_co_set_codec_audio_config(codec_audio_config)) { - LOG_ERROR("%s: cannot update codec audio feeding parameters", __func__); + log::error("cannot update codec audio feeding parameters"); } } void btif_a2dp_source_on_idle(void) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return; /* Make sure media task is stopped */ @@ -723,16 +720,16 @@ void btif_a2dp_source_on_idle(void) { } void btif_a2dp_source_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); btif_a2dp_source_cb.sw_audio_is_encoding = false; // allow using this API for other (acknowledgement and stopping media task) // than suspend if (p_av_suspend != nullptr && p_av_suspend->status != BTA_AV_SUCCESS) { - LOG_ERROR("%s: A2DP stop failed: status=%d, initiator=%s", __func__, - p_av_suspend->status, - (p_av_suspend->initiator ? "true" : "false")); + log::error("A2DP stop failed: status={}, initiator={}", + p_av_suspend->status, + (p_av_suspend->initiator ? "true" : "false")); if (p_av_suspend->initiator) { if (bluetooth::audio::a2dp::is_hal_enabled()) { bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_FAILURE); @@ -759,7 +756,7 @@ void btif_a2dp_source_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) { } void btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) return; @@ -767,9 +764,9 @@ void btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) { // check for status failures if (p_av_suspend->status != BTA_AV_SUCCESS) { - LOG_WARN("%s: A2DP suspend failed: status=%d, initiator=%s", __func__, - p_av_suspend->status, - (p_av_suspend->initiator ? "true" : "false")); + log::warn("A2DP suspend failed: status={}, initiator={}", + p_av_suspend->status, + (p_av_suspend->initiator ? "true" : "false")); if (p_av_suspend->initiator) { if (bluetooth::audio::a2dp::is_hal_enabled()) { bluetooth::audio::a2dp::ack_stream_suspended(A2DP_CTRL_ACK_FAILURE); @@ -793,15 +790,15 @@ void btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) { /* when true media task discards any tx frames */ void btif_a2dp_source_set_tx_flush(bool enable) { - LOG_INFO("%s: enable=%s state=%s", __func__, (enable) ? "true" : "false", - btif_a2dp_source_cb.StateStr().c_str()); + log::info("enable={} state={}", (enable) ? "true" : "false", + btif_a2dp_source_cb.StateStr()); btif_a2dp_source_cb.tx_flush = enable; } static void btif_a2dp_source_audio_tx_start_event(void) { - LOG_INFO("%s: streaming %s state=%s", __func__, - btif_a2dp_source_is_streaming() ? "true" : "false", - btif_a2dp_source_cb.StateStr().c_str()); + log::info("streaming {} state={}", + btif_a2dp_source_is_streaming() ? "true" : "false", + btif_a2dp_source_cb.StateStr()); if (btif_av_is_a2dp_offload_running()) return; @@ -809,8 +806,9 @@ static void btif_a2dp_source_audio_tx_start_event(void) { CHECK(btif_a2dp_source_cb.encoder_interface != nullptr); btif_a2dp_source_cb.encoder_interface->feeding_reset(); - LOG_VERBOSE("%s: starting timer %" PRIu64 " ms", __func__, - btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms()); + log::verbose( + "starting timer {} ms", + btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms()); /* audio engine starting, reset tx suspended flag */ btif_a2dp_source_cb.tx_flush = false; @@ -818,12 +816,8 @@ static void btif_a2dp_source_audio_tx_start_event(void) { wakelock_acquire(); btif_a2dp_source_cb.media_alarm.SchedulePeriodic( btif_a2dp_source_thread.GetWeakPtr(), FROM_HERE, - base::Bind(&btif_a2dp_source_audio_handle_timer), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds( -#else - base::Milliseconds( -#endif + base::BindRepeating(&btif_a2dp_source_audio_handle_timer), + std::chrono::milliseconds( btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms())); btif_a2dp_source_cb.sw_audio_is_encoding = true; @@ -844,9 +838,9 @@ static void btif_a2dp_source_audio_tx_start_event(void) { } static void btif_a2dp_source_audio_tx_stop_event(void) { - LOG_INFO("%s: streaming %s state=%s", __func__, - btif_a2dp_source_is_streaming() ? "true" : "false", - btif_a2dp_source_cb.StateStr().c_str()); + log::info("streaming {} state={}", + btif_a2dp_source_is_streaming() ? "true" : "false", + btif_a2dp_source_cb.StateStr()); if (btif_av_is_a2dp_offload_running()) return; if (!btif_a2dp_source_is_streaming()) return; @@ -915,7 +909,7 @@ static void btif_a2dp_source_audio_handle_timer(void) { log_tstamps_us("A2DP Source tx scheduling timer", timestamp_us); if (!btif_a2dp_source_is_streaming()) { - LOG_ERROR("%s: ERROR Media task Scheduled after Suspend", __func__); + log::error("ERROR Media task Scheduled after Suspend"); return; } CHECK(btif_a2dp_source_cb.encoder_interface != nullptr); @@ -946,8 +940,7 @@ static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len) { } if (btif_a2dp_source_cb.sw_audio_is_encoding && bytes_read < len) { - LOG_WARN("%s: UNDERFLOW: ONLY READ %d BYTES OUT OF %d", __func__, - bytes_read, len); + log::warn("UNDERFLOW: ONLY READ {} BYTES OUT OF {}", bytes_read, len); btif_a2dp_source_cb.stats.media_read_total_underflow_bytes += (len - bytes_read); btif_a2dp_source_cb.stats.media_read_total_underflow_count++; @@ -974,7 +967,7 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n, /* Check if the transmission queue has been flushed */ if (btif_a2dp_source_cb.tx_flush) { - LOG_VERBOSE("%s: tx suspended, discarded frame", __func__); + log::verbose("tx suspended, discarded frame"); btif_a2dp_source_cb.stats.tx_queue_total_flushed_messages += fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue); @@ -989,9 +982,9 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n, // TODO: Using frames_n here is probably wrong: should be "+ 1" instead. if (fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue) + frames_n > btif_a2dp_source_dynamic_audio_buffer_size) { - LOG_WARN("%s: TX queue buffer size now=%u adding=%u max=%d", __func__, - (uint32_t)fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue), - (uint32_t)frames_n, btif_a2dp_source_dynamic_audio_buffer_size); + log::warn("TX queue buffer size now={} adding={} max={}", + (uint32_t)fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue), + (uint32_t)frames_n, btif_a2dp_source_dynamic_audio_buffer_size); // Keep track of drop-outs btif_a2dp_source_cb.stats.tx_queue_dropouts++; btif_a2dp_source_cb.stats.tx_queue_last_dropouts_us = now_us; @@ -1021,7 +1014,7 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n, RawAddress peer_bda = btif_av_source_active_peer(); tBTM_STATUS status = BTM_ReadRSSI(peer_bda, btm_read_rssi_cb); if (status != BTM_CMD_STARTED) { - LOG_WARN("%s: Cannot read RSSI: status %d", __func__, status); + log::warn("Cannot read RSSI: status {}", status); } // Intel controllers don't handle ReadFailedContactCounter very well, it @@ -1034,15 +1027,14 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n, status = BTM_ReadFailedContactCounter(peer_bda, btm_read_failed_contact_counter_cb); if (status != BTM_CMD_STARTED) { - LOG_WARN("%s: Cannot read Failed Contact Counter: status %d", __func__, - status); + log::warn("Cannot read Failed Contact Counter: status {}", status); } #endif status = BTM_ReadTxPower(peer_bda, BT_TRANSPORT_BR_EDR, btm_read_tx_power_cb); if (status != BTM_CMD_STARTED) { - LOG_WARN("%s: Cannot read Tx Power: status %d", __func__, status); + log::warn("Cannot read Tx Power: status {}", status); } } @@ -1059,7 +1051,7 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n, static void btif_a2dp_source_audio_tx_flush_event(void) { /* Flush all enqueued audio buffers (encoded) */ - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); if (btif_av_is_a2dp_offload_running()) return; if (btif_a2dp_source_cb.encoder_interface != nullptr) @@ -1077,10 +1069,10 @@ static void btif_a2dp_source_audio_tx_flush_event(void) { } static bool btif_a2dp_source_audio_tx_flush_req(void) { - LOG_INFO("%s: state=%s", __func__, btif_a2dp_source_cb.StateStr().c_str()); + log::info("state={}", btif_a2dp_source_cb.StateStr()); btif_a2dp_source_thread.DoInThread( - FROM_HERE, base::Bind(&btif_a2dp_source_audio_tx_flush_event)); + FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_tx_flush_event)); return true; } @@ -1103,9 +1095,9 @@ BT_HDR* btif_a2dp_source_audio_readbuf(void) { static void log_tstamps_us(const char* comment, uint64_t timestamp_us) { static uint64_t prev_us = 0; - LOG_VERBOSE("%s: [%s] ts %08" PRIu64 ", diff : %08" PRIu64 ", queue sz %zu", - __func__, comment, timestamp_us, timestamp_us - prev_us, - fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue)); + log::verbose("[{}] ts {:08}, diff : {:08}, queue sz {}", comment, + timestamp_us, timestamp_us - prev_us, + fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue)); prev_us = timestamp_us; } @@ -1358,6 +1350,16 @@ static void btif_a2dp_source_update_metrics(void) { } } BluetoothMetricsLogger::GetInstance()->LogA2dpSession(metrics); + + if (metrics.audio_duration_ms != -1) { + log_a2dp_session_metrics_event( + btif_av_source_active_peer(), metrics.audio_duration_ms, + metrics.media_timer_min_ms, metrics.media_timer_max_ms, + metrics.media_timer_avg_ms, metrics.total_scheduling_count, + metrics.buffer_overruns_max_count, metrics.buffer_overruns_total, + metrics.buffer_underruns_average, metrics.buffer_underruns_count, + metrics.codec_index, metrics.is_a2dp_offload); + } } void btif_a2dp_source_set_dynamic_audio_buffer_size( @@ -1367,14 +1369,13 @@ void btif_a2dp_source_set_dynamic_audio_buffer_size( static void btm_read_rssi_cb(void* data) { if (data == nullptr) { - LOG_ERROR("%s: Read RSSI request timed out", __func__); + log::error("Read RSSI request timed out"); return; } tBTM_RSSI_RESULT* result = (tBTM_RSSI_RESULT*)data; if (result->status != BTM_SUCCESS) { - LOG_ERROR("%s: unable to read remote RSSI (status %d)", __func__, - result->status); + log::error("unable to read remote RSSI (status {})", result->status); return; } @@ -1382,48 +1383,47 @@ static void btm_read_rssi_cb(void* data) { bluetooth::common::kUnknownConnectionHandle, result->hci_status, result->rssi); - LOG_WARN("%s: device: %s, rssi: %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), result->rssi); + log::warn("device: {}, rssi: {}", ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), + result->rssi); } static void btm_read_failed_contact_counter_cb(void* data) { if (data == nullptr) { - LOG_ERROR("%s: Read Failed Contact Counter request timed out", __func__); + log::error("Read Failed Contact Counter request timed out"); return; } tBTM_FAILED_CONTACT_COUNTER_RESULT* result = (tBTM_FAILED_CONTACT_COUNTER_RESULT*)data; if (result->status != BTM_SUCCESS) { - LOG_ERROR("%s: unable to read Failed Contact Counter (status %d)", __func__, - result->status); + log::error("unable to read Failed Contact Counter (status {})", + result->status); return; } log_read_failed_contact_counter_result( result->rem_bda, bluetooth::common::kUnknownConnectionHandle, result->hci_status, result->failed_contact_counter); - LOG_WARN("%s: device: %s, Failed Contact Counter: %u", __func__, - ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), - result->failed_contact_counter); + log::warn("device: {}, Failed Contact Counter: {}", + ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), + result->failed_contact_counter); } static void btm_read_tx_power_cb(void* data) { if (data == nullptr) { - LOG_ERROR("%s: Read Tx Power request timed out", __func__); + log::error("Read Tx Power request timed out"); return; } tBTM_TX_POWER_RESULT* result = (tBTM_TX_POWER_RESULT*)data; if (result->status != BTM_SUCCESS) { - LOG_ERROR("%s: unable to read Tx Power (status %d)", __func__, - result->status); + log::error("unable to read Tx Power (status {})", result->status); return; } log_read_tx_power_level_result(result->rem_bda, bluetooth::common::kUnknownConnectionHandle, result->hci_status, result->tx_power); - LOG_WARN("%s: device: %s, Tx Power: %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), result->tx_power); + log::warn("device: {}, Tx Power: {}", + ADDRESS_TO_LOGGABLE_CSTR(result->rem_bda), result->tx_power); } diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc index eabf30ea9513bdda65653a2bf1da56f23cc7cd26..90d0361ae92adb0787f342033d61f61b2f23d271 100644 --- a/system/btif/src/btif_av.cc +++ b/system/btif/src/btif_av.cc @@ -20,10 +20,12 @@ #include "btif/include/btif_av.h" +#include #include #include #include #include +#include #include #include @@ -44,11 +46,12 @@ #include "btif/include/btif_profile_queue.h" #include "btif/include/btif_rc.h" #include "btif/include/btif_util.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "btif_metrics_logging.h" #include "common/state_machine.h" #include "device/include/device_iot_config.h" #include "hardware/bt_av.h" +#include "include/check.h" #include "include/hardware/bt_rc.h" #include "internal_include/bt_trace.h" #include "osi/include/alarm.h" @@ -56,10 +59,13 @@ #include "stack/include/avrc_api.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_uuid16.h" +#include "stack/include/btm_ble_api.h" #include "stack/include/btm_log_history.h" #include "stack/include/main_thread.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Constants & Macros *****************************************************************************/ @@ -393,7 +399,8 @@ class BtifAvSource { bt_status_t Init( btav_source_callbacks_t* callbacks, int max_connected_audio_devices, const std::vector& codec_priorities, - const std::vector& offloading_preference); + const std::vector& offloading_preference, + std::vector* supported_codecs); void Cleanup(); btav_source_callbacks_t* Callbacks() { return callbacks_; } @@ -450,11 +457,11 @@ class BtifAvSource { } BtifAvPeer* peer = FindPeer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: peer is null", __func__); + log::warn("peer is null"); return false; } if (!peer->IsConnected()) { - LOG_WARN("%s: peer is not connected", __func__); + log::warn("peer is not connected"); return false; } return peer->IsInSilenceMode(); @@ -471,15 +478,14 @@ class BtifAvSource { if (peer_address.IsEmpty()) { return false; } - LOG_INFO("%s: peer: %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("peer: {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); BtifAvPeer* peer = FindPeer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: peer is null", __func__); + log::warn("peer is null"); return false; } if (!peer->IsConnected()) { - LOG_WARN("%s: peer is not connected", __func__); + log::warn("peer is not connected"); return false; } peer->SetSilence(silence); @@ -495,22 +501,19 @@ class BtifAvSource { */ bool SetActivePeer(const RawAddress& peer_address, std::promise peer_ready_promise) { - LOG(INFO) << __PRETTY_FUNCTION__ << ": peer: " - << ADDRESS_TO_LOGGABLE_STR(peer_address); + log::info("peer: {}", ADDRESS_TO_LOGGABLE_STR(peer_address)); if (active_peer_ == peer_address) { peer_ready_promise.set_value(); return true; // Nothing has changed } if (peer_address.IsEmpty()) { - LOG_VERBOSE("%s: peer address is empty, shutdown the Audio source", - __func__); + log::verbose("peer address is empty, shutdown the Audio source"); if (!btif_av_src_sink_coexist_enabled() || (btif_av_src_sink_coexist_enabled() && btif_av_sink_active_peer().IsEmpty())) { if (!bta_av_co_set_active_peer(peer_address)) { - LOG(WARNING) << __func__ - << ": unable to set active peer to empty in BtaAvCo"; + log::warn("unable to set active peer to empty in BtaAvCo"); } } @@ -522,7 +525,7 @@ class BtifAvSource { using namespace std::chrono_literals; if (shutdown_complete_future.wait_for(1s) == std::future_status::timeout) { - LOG_ERROR("Timed out waiting for A2DP source shutdown to complete."); + log::error("Timed out waiting for A2DP source shutdown to complete."); } active_peer_ = peer_address; peer_ready_promise.set_value(); @@ -532,9 +535,8 @@ class BtifAvSource { if (btif_av_src_sink_coexist_enabled()) btif_av_sink_delete_active_peer(); BtifAvPeer* peer = FindPeer(peer_address); if (peer == nullptr || !peer->IsConnected()) { - LOG(ERROR) << __func__ << ": Error setting " - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " as active Source peer"; + log::error("Error setting {} as active Source peer", + ADDRESS_TO_LOGGABLE_STR(peer_address)); peer_ready_promise.set_value(); return false; } @@ -550,14 +552,13 @@ class BtifAvSource { void DeleteActivePeer(void) { std::promise shutdown_complete_promise; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (btif_av_sink_active_peer().IsEmpty()) { if (!bta_av_co_set_active_peer(RawAddress::kEmpty)) { - LOG_WARN("%s : unable to set active peer to empty in BtaAvCo", - __func__); + log::warn("unable to set active peer to empty in BtaAvCo"); } } else { - LOG_WARN("%s : there is an active peer as source role", __func__); + log::warn("there is an active peer as source role"); } btif_a2dp_source_end_session(active_peer_); btif_a2dp_source_shutdown(std::move(shutdown_complete_promise)); @@ -676,22 +677,19 @@ class BtifAvSink { */ bool SetActivePeer(const RawAddress& peer_address, std::promise peer_ready_promise) { - LOG(INFO) << __PRETTY_FUNCTION__ << ": peer: " - << ADDRESS_TO_LOGGABLE_STR(peer_address); + log::info("peer: {}", ADDRESS_TO_LOGGABLE_STR(peer_address)); if (active_peer_ == peer_address) { peer_ready_promise.set_value(); return true; // Nothing has changed } if (peer_address.IsEmpty()) { - LOG_VERBOSE("%s: peer address is empty, shutdown the Audio sink", - __func__); + log::verbose("peer address is empty, shutdown the Audio sink"); if (!btif_av_src_sink_coexist_enabled() || (btif_av_src_sink_coexist_enabled() && btif_av_source_active_peer().IsEmpty())) { if (!bta_av_co_set_active_peer(peer_address)) { - LOG(WARNING) << __func__ - << ": unable to set active peer to empty in BtaAvCo"; + log::warn("unable to set active peer to empty in BtaAvCo"); } } @@ -707,9 +705,8 @@ class BtifAvSink { } BtifAvPeer* peer = FindPeer(peer_address); if (peer == nullptr || !peer->IsConnected()) { - LOG(ERROR) << __func__ << ": Error setting " - << ADDRESS_TO_LOGGABLE_STR(peer_address) - << " as active Sink peer"; + log::error("Error setting {} as active Sink peer", + ADDRESS_TO_LOGGABLE_STR(peer_address)); peer_ready_promise.set_value(); return false; } @@ -719,21 +716,20 @@ class BtifAvSink { // cannot set promise but need to be handled within restart_session return false; } - LOG(INFO) << "Setting the active peer to peer address %s" - << ADDRESS_TO_LOGGABLE_STR(peer_address); + log::info("Setting the active peer to peer address {}", + ADDRESS_TO_LOGGABLE_STR(peer_address)); active_peer_ = peer_address; return true; } void DeleteActivePeer(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (btif_av_source_active_peer().IsEmpty()) { if (!bta_av_co_set_active_peer(RawAddress::kEmpty)) { - LOG(WARNING) << __func__ - << ": unable to set active peer to empty in BtaAvCo"; + log::warn("unable to set active peer to empty in BtaAvCo"); } } else { - LOG(WARNING) << __func__ << ": there is an active peer as sink role"; + log::warn("there is an active peer as sink role"); } btif_a2dp_sink_end_session(active_peer_); btif_a2dp_sink_shutdown(); @@ -1095,17 +1091,16 @@ const RawAddress& BtifAvPeer::ActivePeerAddress() const { if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) { RawAddress addr = btif_av_sink.ActivePeer(); if (RawAddress::kEmpty == addr) { - LOG(WARNING) << __PRETTY_FUNCTION__ << ": A2DP peer " - << btif_av_source.ActivePeer() << " is Sink"; + log::warn("A2DP peer {} is Sink", + ADDRESS_TO_LOGGABLE_STR(btif_av_source.ActivePeer())); return btif_av_source.ActivePeer(); } - LOG(WARNING) << __PRETTY_FUNCTION__ << ": A2DP peer " - << btif_av_sink.ActivePeer() << " is Source"; + log::warn("A2DP peer {} is Source", + ADDRESS_TO_LOGGABLE_STR(btif_av_sink.ActivePeer())); return btif_av_sink.ActivePeer(); } - LOG(FATAL) << __PRETTY_FUNCTION__ << ": A2DP peer " - << ADDRESS_TO_LOGGABLE_STR(PeerAddress()) - << " is neither Source nor Sink"; + log::fatal("A2DP peer {} is neither Source nor Sink", + ADDRESS_TO_LOGGABLE_STR(PeerAddress())); return RawAddress::kEmpty; } @@ -1125,9 +1120,9 @@ BtifAvSource::~BtifAvSource() { CleanupAllPeers(); } bt_status_t BtifAvSource::Init( btav_source_callbacks_t* callbacks, int max_connected_audio_devices, const std::vector& codec_priorities, - const std::vector& offloading_preference) { - LOG_INFO("%s: max_connected_audio_devices=%d", __PRETTY_FUNCTION__, - max_connected_audio_devices); + const std::vector& offloading_preference, + std::vector* supported_codecs) { + log::info("max_connected_audio_devices={}", max_connected_audio_devices); if (enabled_) return BT_STATUS_SUCCESS; CleanupAllPeers(); max_connected_peers_ = max_connected_audio_devices; @@ -1135,14 +1130,18 @@ bt_status_t BtifAvSource::Init( /* A2DP OFFLOAD */ a2dp_offload_enabled_ = GetInterfaceToProfiles()->config->isA2DPOffloadEnabled(); - LOG_VERBOSE("a2dp_offload.enable = %d", a2dp_offload_enabled_); + log::verbose("a2dp_offload.enable = {}", a2dp_offload_enabled_); callbacks_ = callbacks; if (a2dp_offload_enabled_) { + tBTM_BLE_VSC_CB vsc_cb = {}; + BTM_BleGetVendorCapabilities(&vsc_cb); + bool supports_a2dp_hw_offload_v2 = + vsc_cb.version_supported >= 0x0104 && vsc_cb.a2dp_offload_v2_support; bluetooth::audio::a2dp::update_codec_offloading_capabilities( - offloading_preference); + offloading_preference, supports_a2dp_hw_offload_v2); } - bta_av_co_init(codec_priorities); + bta_av_co_init(codec_priorities, supported_codecs); if (!btif_a2dp_source_init()) { return BT_STATUS_FAIL; @@ -1153,7 +1152,7 @@ bt_status_t BtifAvSource::Init( } void BtifAvSource::Cleanup() { - LOG_INFO("%s", __PRETTY_FUNCTION__); + log::info(""); if (!enabled_) return; enabled_ = false; @@ -1202,8 +1201,8 @@ BtifAvPeer* BtifAvSource::FindPeerByPeerId(uint8_t peer_id) { BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address, tBTA_AV_HNDL bta_handle) { std::unique_lock lock1(mutex_); - LOG_VERBOSE("%s: peer_address=%s bta_handle=0x%x", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle); + log::verbose("peer_address={} bta_handle=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle); BtifAvPeer* peer = FindPeer(peer_address); if (peer != nullptr) return peer; @@ -1221,10 +1220,10 @@ BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address, } } if (peer_id == kPeerIdMax) { - LOG_ERROR( - "%s: Cannot create peer for peer_address=%s : " - "cannot allocate unique Peer ID", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error( + "Cannot create peer for peer_address={} : cannot allocate unique Peer " + "ID", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return nullptr; } @@ -1232,18 +1231,17 @@ BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address, if (bta_handle == kBtaHandleUnknown) { auto it = peer_id2bta_handle_.find(peer_id); if (it == peer_id2bta_handle_.end() || it->second == kBtaHandleUnknown) { - LOG_ERROR( - "%s: Cannot create peer for peer_address=%s : " - "cannot convert Peer ID=%d to unique BTA Handle", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_address), peer_id); + log::error( + "Cannot create peer for peer_address={} : cannot convert Peer ID={} " + "to unique BTA Handle", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), peer_id); return nullptr; } bta_handle = it->second; } - LOG_INFO("%s: Create peer: peer_address=%s bta_handle=0x%x peer_id=%d", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_address), - bta_handle, peer_id); + log::info("Create peer: peer_address={} bta_handle=0x{:x} peer_id={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle, peer_id); peer = new BtifAvPeer(peer_address, AVDT_TSEP_SNK, bta_handle, peer_id); peers_.insert(std::make_pair(peer_address, peer)); peer->Init(); @@ -1253,9 +1251,9 @@ BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address, bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const { int connected = 0; if (btif_av_src_sink_coexist_enabled() && invalid_peer_check_) { - LOG_INFO( - "invalid_peer_check_ so allow to connect here, when" - " BTA_AV_OPEN_EVT coming, would check again!"); + log::info( + "invalid_peer_check_ so allow to connect here, when BTA_AV_OPEN_EVT " + "coming, would check again!"); return true; } @@ -1280,9 +1278,8 @@ bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const { } } if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) { - LOG_INFO("%s: connected=%d, max_connected_peers_=%d, sink_peers=%d", - __PRETTY_FUNCTION__, connected, max_connected_peers_, - (int)btif_av_sink.Peers().size()); + log::info("connected={}, max_connected_peers_={}, sink_peers={}", connected, + max_connected_peers_, (int)btif_av_sink.Peers().size()); /* if source device connected, don't connect sink device */ if (connected >= max_connected_peers_ || !btif_av_sink.Peers().empty()) { @@ -1309,8 +1306,8 @@ void BtifAvSource::DeleteIdlePeers() { BtifAvPeer* peer = it->second; auto prev_it = it++; if (!peer->CanBeDeleted()) continue; - LOG_INFO("%s: Deleting idle peer: %s bta_handle=0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), peer->BtaHandle()); + log::info("Deleting idle peer: {} bta_handle=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), peer->BtaHandle()); peer->Cleanup(); peers_.erase(prev_it); delete peer; @@ -1350,15 +1347,14 @@ void BtifAvSource::BtaHandleRegistered(uint8_t peer_id, BtifAvPeer* peer = FindPeerByPeerId(peer_id); if (peer != nullptr && peer->BtaHandle() != bta_handle) { if (peer->BtaHandle() == kBtaHandleUnknown) { - LOG_VERBOSE("%s: Assign peer: peer_address=%s bta_handle=0x%x peer_id=%d", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), bta_handle, - peer_id); + log::verbose("Assign peer: peer_address={} bta_handle=0x{:x} peer_id={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), bta_handle, + peer_id); } else { - LOG_WARN( - "%s: Correct peer: peer_address=%s bta_handle=0x%x->0x%x peer_id=%d", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - peer->BtaHandle(), bta_handle, peer_id); + log::warn( + "Correct peer: peer_address={} bta_handle=0x{:x}->0x{:x} peer_id={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), peer->BtaHandle(), + bta_handle, peer_id); } peer->SetBtaHandle(bta_handle); } @@ -1369,24 +1365,23 @@ BtifAvPeer* BtifAvSource::popPeer(const RawAddress& peer_address) { if (it == peers_.end()) return nullptr; BtifAvPeer* peer = it->second; peers_.erase(it); - LOG_INFO("%s: peer_address=%s, state=%d", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - peer->StateMachine().StateId()); + log::info("peer_address={}, state={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + peer->StateMachine().StateId()); return peer; } void BtifAvSource::AddPeer(BtifAvPeer* peer) { - LOG_INFO("%s: peer_address=%s, state=%d", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - peer->StateMachine().StateId()); + log::info("peer_address={}, state={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + peer->StateMachine().StateId()); peers_.insert(std::make_pair(peer->PeerAddress(), peer)); } BtifAvSink::~BtifAvSink() { CleanupAllPeers(); } bt_status_t BtifAvSink::Init(btav_sink_callbacks_t* callbacks, int max_connected_audio_devices) { - LOG_INFO("%s(max_connected_audio_devices=%d)", __PRETTY_FUNCTION__, - max_connected_audio_devices); + log::info("(max_connected_audio_devices={})", max_connected_audio_devices); if (enabled_) return BT_STATUS_SUCCESS; CleanupAllPeers(); @@ -1398,7 +1393,8 @@ bt_status_t BtifAvSink::Init(btav_sink_callbacks_t* callbacks, if (!btif_av_source.Enabled()) { std::vector codec_priorities; // Default priorities - bta_av_co_init(codec_priorities); + std::vector supported_codecs; + bta_av_co_init(codec_priorities, &supported_codecs); } if (!btif_a2dp_sink_init()) { @@ -1410,7 +1406,7 @@ bt_status_t BtifAvSink::Init(btav_sink_callbacks_t* callbacks, } void BtifAvSink::Cleanup() { - LOG_INFO("%s", __PRETTY_FUNCTION__); + log::info(""); if (!enabled_) return; enabled_ = false; @@ -1458,8 +1454,8 @@ BtifAvPeer* BtifAvSink::FindPeerByPeerId(uint8_t peer_id) { BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address, tBTA_AV_HNDL bta_handle) { - LOG_VERBOSE("%s: peer_address=%s bta_handle=0x%x", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle); + log::verbose("peer_address={} bta_handle=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle); BtifAvPeer* peer = FindPeer(peer_address); if (peer != nullptr) return peer; @@ -1478,10 +1474,10 @@ BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address, } } if (peer_id == kPeerIdMax) { - LOG_ERROR( - "%s: Cannot create peer for peer_address=%s : " - "cannot allocate unique Peer ID", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error( + "Cannot create peer for peer_address={} : cannot allocate unique Peer " + "ID", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return nullptr; } @@ -1489,18 +1485,17 @@ BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address, if (bta_handle == kBtaHandleUnknown) { auto it = peer_id2bta_handle_.find(peer_id); if (it == peer_id2bta_handle_.end() || it->second == kBtaHandleUnknown) { - LOG_ERROR( - "%s: Cannot create peer for peer_address=%s : " - "cannot convert Peer ID=%d to unique BTA Handle", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_address), peer_id); + log::error( + "Cannot create peer for peer_address={} : cannot convert Peer ID={} " + "to unique BTA Handle", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), peer_id); return nullptr; } bta_handle = it->second; } - LOG_INFO("%s: Create peer: peer_address=%s bta_handle=0x%x peer_id=%d", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_address), - bta_handle, peer_id); + log::info("Create peer: peer_address={} bta_handle=0x{:x} peer_id={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle, peer_id); peer = new BtifAvPeer(peer_address, AVDT_TSEP_SRC, bta_handle, peer_id); peers_.insert(std::make_pair(peer_address, peer)); peer->Init(); @@ -1511,9 +1506,9 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const { int connected = 0; if (btif_av_src_sink_coexist_enabled() && invalid_peer_check_) { - LOG_INFO( - "invalid_peer_check_ so allow to connect here, when" - " BTA_AV_OPEN_EVT coming, would check again!"); + log::info( + "invalid_peer_check_ so allow to connect here, when BTA_AV_OPEN_EVT " + "coming, would check again!"); return true; } // Count peers that are in the process of connecting or already connected @@ -1534,10 +1529,11 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const { case BtifAvStateMachine::kStateIdle: if ((btif_a2dp_sink_get_audio_track() != nullptr) && (peer->PeerAddress() != peer_address)) { - LOG_INFO("%s: there is another peer with audio track(%p), another=%s, peer=%s", - __PRETTY_FUNCTION__, btif_a2dp_sink_get_audio_track(), - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info( + "there is another peer with audio track({}), another={}, peer={}", + fmt::ptr(btif_a2dp_sink_get_audio_track()), + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); connected++; } break; @@ -1546,9 +1542,9 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const { } } if (btif_av_both_enable()) { - LOG_INFO("connected=%d, max_connected_peers_=%d, source_peers=%d", - connected, max_connected_peers_, - (int)btif_av_source.Peers().size()); + log::info("connected={}, max_connected_peers_={}, source_peers={}", + connected, max_connected_peers_, + (int)btif_av_source.Peers().size()); /* if source device connected, don't connect sink device */ return (connected < max_connected_peers_) && btif_av_source.Peers().empty(); } @@ -1571,8 +1567,8 @@ void BtifAvSink::DeleteIdlePeers() { BtifAvPeer* peer = it->second; auto prev_it = it++; if (!peer->CanBeDeleted()) continue; - LOG_INFO("%s: Deleting idle peer: %s bta_handle=0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), peer->BtaHandle()); + log::info("Deleting idle peer: {} bta_handle=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), peer->BtaHandle()); peer->Cleanup(); peers_.erase(prev_it); delete peer; @@ -1611,15 +1607,14 @@ void BtifAvSink::BtaHandleRegistered(uint8_t peer_id, tBTA_AV_HNDL bta_handle) { BtifAvPeer* peer = FindPeerByPeerId(peer_id); if (peer != nullptr && peer->BtaHandle() != bta_handle) { if (peer->BtaHandle() == kBtaHandleUnknown) { - LOG_VERBOSE("%s: Assign peer: peer_address=%s bta_handle=0x%x peer_id=%d", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), bta_handle, - peer_id); + log::verbose("Assign peer: peer_address={} bta_handle=0x{:x} peer_id={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), bta_handle, + peer_id); } else { - LOG_WARN( - "%s: Correct peer: peer_address=%s bta_handle=0x%x->0x%x peer_id=%d", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - peer->BtaHandle(), bta_handle, peer_id); + log::warn( + "Correct peer: peer_address={} bta_handle=0x{:x}->0x{:x} peer_id={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), peer->BtaHandle(), + bta_handle, peer_id); } peer->SetBtaHandle(bta_handle); } @@ -1630,22 +1625,21 @@ BtifAvPeer* BtifAvSink::popPeer(const RawAddress& peer_address) { if (it == peers_.end()) return nullptr; BtifAvPeer* peer = it->second; peers_.erase(it); - LOG_INFO("%s: peer_address=%s, state=%d", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - peer->StateMachine().StateId()); + log::info("peer_address={}, state={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + peer->StateMachine().StateId()); return peer; } void BtifAvSink::AddPeer(BtifAvPeer* peer) { - LOG_INFO("%s: peer_address=%s, state=%d", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - peer->StateMachine().StateId()); + log::info("peer_address={}, state={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + peer->StateMachine().StateId()); peers_.insert(std::make_pair(peer->PeerAddress(), peer)); } void BtifAvStateMachine::StateIdle::OnEnter() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); peer_.SetEdr(0); peer_.ClearAllFlags(); @@ -1681,16 +1675,14 @@ void BtifAvStateMachine::StateIdle::OnEnter() { } void BtifAvStateMachine::StateIdle::OnExit() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); } bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { - LOG_VERBOSE( - "%s: Peer %s : event=%s flags=%s active_peer=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), peer_.FlagsToString().c_str(), - logbool(peer_.IsActivePeer()).c_str()); + log::verbose("Peer {} : event={} flags={} active_peer={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), + logbool(peer_.IsActivePeer())); switch (event) { case BTA_AV_ENABLE_EVT: @@ -1727,10 +1719,8 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { if (!can_connect) sink_disconnect_src(peer_.PeerAddress()); } if (!can_connect) { - LOG_ERROR( - "%s: Cannot connect to peer %s: too many connected " - "peers", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::error("Cannot connect to peer {}: too many connected peers", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); if (peer_.SelfInitiatedConnection()) { btif_queue_advance(); } @@ -1764,10 +1754,9 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { // connection first and then immediately initiate the AV connection // // TODO: We may need to do this only on an AVRCP Play. FixMe - LOG_WARN("%s: Peer %s : event=%s received without AV", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : event={} received without AV", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); bool can_connect = true; // Check whether connection is allowed @@ -1789,10 +1778,8 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { } } if (!can_connect) { - LOG_ERROR( - "%s: Cannot connect to peer %s: too many connected " - "peers", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::error("Cannot connect to peer {}: too many connected peers", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); break; } /* if peer is source, then start timer for sink connect to src */ @@ -1842,12 +1829,11 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { tBTA_AV_STATUS status = p_bta_data->open.status; bool can_connect = true; - LOG_INFO( - "%s: Peer %s : event=%s flags=%s status=%d(%s) edr=0x%x", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), peer_.FlagsToString().c_str(), - status, (status == BTA_AV_SUCCESS) ? "SUCCESS" : "FAILED", - p_bta_data->open.edr); + log::info("Peer {} : event={} flags={} status={}({}) edr=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), status, + (status == BTA_AV_SUCCESS) ? "SUCCESS" : "FAILED", + p_bta_data->open.edr); btif_report_connection_state( peer_.PeerAddress(), BTAV_CONNECTION_STATE_CONNECTING, @@ -1856,15 +1842,15 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { if (p_bta_data->open.status == BTA_AV_SUCCESS) { peer_.SetEdr(p_bta_data->open.edr); if (btif_av_src_sink_coexist_enabled()) { - LOG_VERBOSE("%s: Peer %s sep=%d, open_sep=%d", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - peer_.PeerSep(), p_bta_data->open.sep); + log::verbose("Peer {} sep={}, open_sep={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + peer_.PeerSep(), p_bta_data->open.sep); /* if peer is wrong sep type, move it to BtifAvSxxx */ if (peer_.PeerSep() == AVDT_TSEP_SNK) { - LOG_VERBOSE("set source invalid_peer_check as false"); + log::verbose("set source invalid_peer_check as false"); btif_av_source.SetInvalidPeerCheck(false); } else { - LOG_VERBOSE("set sink invalid_peer_check as false"); + log::verbose("set sink invalid_peer_check as false"); btif_av_sink.SetInvalidPeerCheck(false); } if (peer_.PeerSep() != p_bta_data->open.sep) { @@ -1873,21 +1859,21 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { tmp_peer = btif_av_source.popPeer(peer_.PeerAddress()); if (peer_.PeerAddress() != tmp_peer->PeerAddress()) - LOG_ERROR("error, not same peer"); + log::error("error, not same peer"); btif_av_sink.AddPeer(tmp_peer); } else { tmp_peer = btif_av_sink.popPeer(peer_.PeerAddress()); if (peer_.PeerAddress() != tmp_peer->PeerAddress()) - LOG_ERROR("error, not same peer"); + log::error("error, not same peer"); btif_av_source.AddPeer(tmp_peer); } peer_.SetSep(p_bta_data->open.sep); } if (btif_rc_is_connected_peer(peer_.PeerAddress())) { - LOG_VERBOSE("%s, AVRCP connected, update avrc sep", __func__); + log::verbose("AVRCP connected, update avrc sep"); BTA_AvSetPeerSep(peer_.PeerAddress(), peer_.PeerSep()); } btif_rc_check_pending_cmd(p_bta_data->open.bd_addr); @@ -1899,11 +1885,8 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { : btif_av_sink.AllowedToConnect(peer_.PeerAddress()); if (!can_connect) { - LOG_ERROR( - "%s: Cannot connect to peer %s: too many connected " - "peers", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::error("Cannot connect to peer {}: too many connected peers", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); if (peer_.IsSink()) { src_disconnect_sink(peer_.PeerAddress()); @@ -1953,10 +1936,9 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { case BTIF_AV_AVRCP_CLOSE_EVT: case BTA_AV_RC_CLOSE_EVT: { - LOG_VERBOSE("%s: Peer %s : event=%s : Stopping AV timer", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::verbose("Peer {} : event={} : Stopping AV timer", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); alarm_cancel(peer_.AvOpenOnRcTimer()); if (event == BTA_AV_RC_CLOSE_EVT) { @@ -1965,17 +1947,16 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { } break; case BTIF_AV_OFFLOAD_START_REQ_EVT: - LOG_ERROR("%s: Peer %s : event=%s: stream is not Opened", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::error("Peer {} : event={}: stream is not Opened", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL); break; default: - LOG_WARN("%s: Peer %s : Unhandled event=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : Unhandled event={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); return false; } @@ -1983,8 +1964,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { } void BtifAvStateMachine::StateOpening::OnEnter() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); // Inform the application that we are entering connecting state if (btif_av_both_enable()) { @@ -1997,17 +1977,15 @@ void BtifAvStateMachine::StateOpening::OnEnter() { } void BtifAvStateMachine::StateOpening::OnExit() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); } bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, void* p_data) { - LOG_VERBOSE( - "%s: Peer %s : event=%s flags=%s active_peer=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), peer_.FlagsToString().c_str(), - logbool(peer_.IsActivePeer()).c_str()); + log::verbose("Peer {} : event={} flags={} active_peer={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), + logbool(peer_.IsActivePeer())); switch (event) { case BTIF_AV_STOP_STREAM_REQ_EVT: @@ -2018,11 +1996,10 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, // ACL Disconnected needs to be handled only in Opening state, because // it is in an intermediate state. In other states we can handle // incoming/outgoing connect/disconnect requests. - LOG_WARN( - "%s: Peer %s : event=%s: transitioning to Idle due to ACL " - "Disconnect", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn( + "Peer {} : event={}: transitioning to Idle due to ACL Disconnect", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum:: A2DP_CONNECTION_ACL_DISCONNECTED, 1); @@ -2035,10 +2012,9 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, } break; case BTA_AV_REJECT_EVT: - LOG_WARN("%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::warn("Peer {} : event={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum:: A2DP_CONNECTION_REJECT_EVT, 1); @@ -2056,26 +2032,25 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, int av_state; tBTA_AV_STATUS status = p_bta_data->open.status; - LOG_INFO( - "%s: Peer %s : event=%s flags=%s status=%d(%s) edr=0x%x", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), peer_.FlagsToString().c_str(), - status, (status == BTA_AV_SUCCESS) ? "SUCCESS" : "FAILED", - p_bta_data->open.edr); + log::info("Peer {} : event={} flags={} status={}({}) edr=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), status, + (status == BTA_AV_SUCCESS) ? "SUCCESS" : "FAILED", + p_bta_data->open.edr); if (p_bta_data->open.status == BTA_AV_SUCCESS) { av_state = BtifAvStateMachine::kStateOpened; peer_.SetEdr(p_bta_data->open.edr); if (btif_av_src_sink_coexist_enabled()) { - LOG_VERBOSE("%s: Peer %s sep=%d, open_sep=%d", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - peer_.PeerSep(), p_bta_data->open.sep); + log::verbose("Peer {} sep={}, open_sep={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + peer_.PeerSep(), p_bta_data->open.sep); /* if peer is wrong sep type, move it to BtifAvSxxx */ if (peer_.PeerSep() == AVDT_TSEP_SNK) { - LOG_VERBOSE("set source invalid_peer_check as false"); + log::verbose("set source invalid_peer_check as false"); btif_av_source.SetInvalidPeerCheck(false); } else { - LOG_VERBOSE("set sink invalid_peer_check as false"); + log::verbose("set sink invalid_peer_check as false"); btif_av_sink.SetInvalidPeerCheck(false); } if (peer_.PeerSep() != p_bta_data->open.sep) { @@ -2084,21 +2059,21 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, tmp_peer = btif_av_source.popPeer(peer_.PeerAddress()); if (peer_.PeerAddress() != tmp_peer->PeerAddress()) - LOG_ERROR("error, not same peer"); + log::error("error, not same peer"); btif_av_sink.AddPeer(tmp_peer); } else { tmp_peer = btif_av_sink.popPeer(peer_.PeerAddress()); if (peer_.PeerAddress() != tmp_peer->PeerAddress()) - LOG_ERROR("error, not same peer"); + log::error("error, not same peer"); btif_av_source.AddPeer(tmp_peer); } peer_.SetSep(p_bta_data->open.sep); } if (btif_rc_is_connected_peer(peer_.PeerAddress())) { - LOG_VERBOSE("%s, AVRCP connected, update avrc sep", __func__); + log::verbose("AVRCP connected, update avrc sep"); BTA_AvSetPeerSep(peer_.PeerAddress(), peer_.PeerSep()); } btif_rc_check_pending_cmd(p_bta_data->open.bd_addr); @@ -2133,8 +2108,8 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, if (btif_rc_is_connected_peer(peer_.PeerAddress())) { // Disconnect the AVRCP connection, in case the A2DP connectiton // failed for any reason. - LOG_WARN("%s: Peer %s : Disconnecting AVRCP", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::warn("Peer {} : Disconnecting AVRCP", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); uint8_t peer_handle = btif_rc_get_connected_peer_handle(peer_.PeerAddress()); if (peer_handle != BTRC_HANDLE_NONE) { @@ -2192,11 +2167,11 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, case BTIF_AV_CONNECT_REQ_EVT: { // The device has moved already to Opening, hence don't report the // connection state. - LOG_WARN( - "%s: Peer %s : event=%s : device is already connecting, " - "ignore Connect request", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn( + "Peer {} : event={} : device is already connecting, ignore Connect " + "request", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); log_counter_metrics_btif( android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, 1); @@ -2206,21 +2181,20 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, case BTA_AV_PENDING_EVT: { // The device has moved already to Opening, hence don't report the // connection state. - LOG_WARN( - "%s: Peer %s : event=%s : device is already connecting, " - "ignore incoming request", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn( + "Peer {} : event={} : device is already connecting, ignore incoming " + "request", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); log_counter_metrics_btif( android::bluetooth::CodePathCounterKeyEnum::A2DP_ALREADY_CONNECTING, 1); } break; case BTIF_AV_OFFLOAD_START_REQ_EVT: - LOG_ERROR("%s: Peer %s : event=%s: stream is not Opened", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::error("Peer {} : event={}: stream is not Opened", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL); log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum:: A2DP_OFFLOAD_START_REQ_FAILURE, @@ -2264,17 +2238,16 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, log_counter_metrics_btif(android::bluetooth::CodePathCounterKeyEnum:: A2DP_CONNECTION_UNKNOWN_EVENT, 1); - LOG_WARN("%s: Peer %s : Unhandled event=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : Unhandled event={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); return false; } return true; } void BtifAvStateMachine::StateOpened::OnEnter() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); peer_.ClearFlags(BtifAvPeer::kFlagLocalSuspendPending | BtifAvPeer::kFlagPendingStart | @@ -2289,15 +2262,14 @@ void BtifAvStateMachine::StateOpened::OnEnter() { std::promise peer_ready_promise; if (!btif_av_sink.SetActivePeer(peer_.PeerAddress(), std::move(peer_ready_promise))) { - LOG_ERROR("%s: Error setting %s as active Source peer", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::error("Error setting {} as active Source peer", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); } } } void BtifAvStateMachine::StateOpened::OnExit() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); peer_.ClearFlags(BtifAvPeer::kFlagPendingStart); } @@ -2306,18 +2278,16 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, void* p_data) { tBTA_AV* p_av = (tBTA_AV*)p_data; - LOG_VERBOSE( - "%s: Peer %s : event=%s flags=%s active_peer=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), peer_.FlagsToString().c_str(), - logbool(peer_.IsActivePeer()).c_str()); + log::verbose("Peer {} : event={} flags={} active_peer={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), + logbool(peer_.IsActivePeer())); if ((event == BTA_AV_REMOTE_CMD_EVT) && peer_.CheckFlags(BtifAvPeer::kFlagRemoteSuspend) && (p_av->remote_cmd.rc_id == AVRC_ID_PLAY)) { - LOG_VERBOSE("%s: Peer %s : Resetting remote suspend flag on RC PLAY", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {} : Resetting remote suspend flag on RC PLAY", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); peer_.ClearFlags(BtifAvPeer::kFlagRemoteSuspend); } @@ -2328,15 +2298,14 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, break; // Ignore case BTIF_AV_START_STREAM_REQ_EVT: { - LOG_INFO("%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::info("Peer {} : event={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); if (p_data) { const btif_av_start_stream_req_t* p_start_steam_req = static_cast(p_data); - LOG_INFO("Stream use_latency_mode=%s", - p_start_steam_req->use_latency_mode ? "true" : "false"); + log::info("Stream use_latency_mode={}", + p_start_steam_req->use_latency_mode ? "true" : "false"); peer_.SetUseLatencyMode(p_start_steam_req->use_latency_mode); } @@ -2345,13 +2314,11 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, } break; case BTA_AV_START_EVT: { - LOG_INFO( - "%s: Peer %s : event=%s status=%d suspending=%d " - "initiator=%d flags=%s", - __PRETTY_FUNCTION__, ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), p_av->start.status, - p_av->start.suspending, p_av->start.initiator, - peer_.FlagsToString().c_str()); + log::info( + "Peer {} : event={} status={} suspending={} initiator={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), p_av->start.status, + p_av->start.suspending, p_av->start.initiator, peer_.FlagsToString()); if ((p_av->start.status == BTA_SUCCESS) && p_av->start.suspending) return true; @@ -2363,14 +2330,12 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, if (peer_.IsSink()) { if (!peer_.CheckFlags(BtifAvPeer::kFlagPendingStart | BtifAvPeer::kFlagRemoteSuspend)) { - LOG(WARNING) << __PRETTY_FUNCTION__ << ": Peer " - << ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress()) - << " : trigger Suspend as remote initiated"; + log::warn("Peer {} : trigger Suspend as remote initiated", + ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress())); should_suspend = true; } else if (!peer_.IsActivePeer()) { - LOG(WARNING) << __PRETTY_FUNCTION__ << ": Peer " - << ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress()) - << " : trigger Suspend as non-active"; + log::warn("Peer {} : trigger Suspend as non-active", + ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress())); should_suspend = true; } @@ -2422,9 +2387,8 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, bt_status_t::BT_STATUS_SUCCESS, BTA_AV_SUCCESS); // Change state to Idle, send acknowledgement if start is pending if (peer_.CheckFlags(BtifAvPeer::kFlagPendingStart)) { - LOG_WARN("%s: Peer %s : failed pending start request", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::warn("Peer {} : failed pending start request", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); tBTA_AV_START av_start = {.chnl = p_av->close.chnl, .hndl = p_av->close.hndl, .status = BTA_AV_FAIL_STREAM, @@ -2445,13 +2409,11 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, case BTA_AV_RECONFIG_EVT: if (p_av->reconfig.status != BTA_AV_SUCCESS) { - LOG(WARNING) << __PRETTY_FUNCTION__ << ": Peer " - << ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress()) - << " : failed reconfiguration"; + log::warn("Peer {} : failed reconfiguration", + ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress())); if (peer_.CheckFlags(BtifAvPeer::kFlagPendingStart)) { - LOG(ERROR) << __PRETTY_FUNCTION__ << ": Peer " - << ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress()) - << " : cannot proceed to do AvStart"; + log::error("Peer {} : cannot proceed to do AvStart", + ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress())); peer_.ClearFlags(BtifAvPeer::kFlagPendingStart); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); } @@ -2464,43 +2426,40 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, } if (peer_.IsActivePeer()) { - LOG(INFO) << __PRETTY_FUNCTION__ << " : Peer " - << ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress()) - << " : Reconfig done - calling startSession() to audio HAL"; + log::info( + "Peer {} : Reconfig done - calling startSession() to audio HAL", + ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress())); std::promise peer_ready_promise; std::future peer_ready_future = peer_ready_promise.get_future(); btif_a2dp_source_start_session(peer_.PeerAddress(), std::move(peer_ready_promise)); } if (peer_.CheckFlags(BtifAvPeer::kFlagPendingStart)) { - LOG(INFO) << __PRETTY_FUNCTION__ << " : Peer " - << ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress()) - << " : Reconfig done - calling BTA_AvStart(" - << loghex(peer_.BtaHandle()) << ")"; + log::info("Peer {} : Reconfig done - calling BTA_AvStart({})", + ADDRESS_TO_LOGGABLE_STR(peer_.PeerAddress()), + loghex(peer_.BtaHandle())); BTA_AvStart(peer_.BtaHandle(), peer_.UseLatencyMode()); } break; case BTIF_AV_CONNECT_REQ_EVT: { - LOG_WARN("%s: Peer %s : Ignore %s for same device", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : Ignore {} for same device", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); btif_queue_advance(); } break; case BTIF_AV_OFFLOAD_START_REQ_EVT: - LOG_ERROR("%s: Peer %s : event=%s: stream is not Started", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::error("Peer {} : event={}: stream is not Started", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL); break; case BTIF_AV_AVRCP_REMOTE_PLAY_EVT: if (peer_.CheckFlags(BtifAvPeer::kFlagRemoteSuspend)) { - LOG_VERBOSE("%s: Peer %s : Resetting remote suspend flag on RC PLAY", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {} : Resetting remote suspend flag on RC PLAY", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); peer_.ClearFlags(BtifAvPeer::kFlagRemoteSuspend); } break; @@ -2510,27 +2469,25 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, case BTIF_AV_SET_LATENCY_REQ_EVT: { const btif_av_set_latency_req_t* p_set_latency_req = static_cast(p_data); - LOG_INFO("Peer %s : event=%s flags=%s is_low_latency=%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str(), - p_set_latency_req->is_low_latency ? "true" : "false"); + log::info("Peer {} : event={} flags={} is_low_latency={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), + p_set_latency_req->is_low_latency ? "true" : "false"); BTA_AvSetLatency(peer_.BtaHandle(), p_set_latency_req->is_low_latency); } break; default: - LOG_WARN("%s: Peer %s : Unhandled event=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : Unhandled event={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); return false; } return true; } void BtifAvStateMachine::StateStarted::OnEnter() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); // We are again in started state, clear any remote suspend flags peer_.ClearFlags(BtifAvPeer::kFlagRemoteSuspend); @@ -2543,29 +2500,26 @@ void BtifAvStateMachine::StateStarted::OnEnter() { } void BtifAvStateMachine::StateStarted::OnExit() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); } bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, void* p_data) { tBTA_AV* p_av = (tBTA_AV*)p_data; - LOG_VERBOSE( - "%s: Peer %s : event=%s flags=%s active_peer=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), peer_.FlagsToString().c_str(), - logbool(peer_.IsActivePeer()).c_str()); + log::verbose("Peer {} : event={} flags={} active_peer={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), + logbool(peer_.IsActivePeer())); switch (event) { case BTIF_AV_ACL_DISCONNECTED: break; // Ignore case BTIF_AV_START_STREAM_REQ_EVT: - LOG_INFO("%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::info("Peer {} : event={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); // We were started remotely, just ACK back the local request if (peer_.IsSink()) btif_a2dp_on_started(peer_.PeerAddress(), nullptr); break; @@ -2573,10 +2527,9 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, // FIXME -- use suspend = true always to work around issue with BTA AV case BTIF_AV_STOP_STREAM_REQ_EVT: case BTIF_AV_SUSPEND_STREAM_REQ_EVT: - LOG_INFO("%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::info("Peer {} : event={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); // There is a pending LocalSuspend already, ignore. if (peer_.CheckFlags(BtifAvPeer::kFlagLocalSuspendPending)) { @@ -2607,10 +2560,9 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, break; case BTIF_AV_DISCONNECT_REQ_EVT: - LOG_INFO("%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::info("Peer {} : event={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); // Request AVDTP to close BTA_AvClose(peer_.BtaHandle()); @@ -2628,11 +2580,10 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, break; case BTA_AV_SUSPEND_EVT: { - LOG_INFO("%s: Peer %s : event=%s status=%d initiator=%d flags=%s", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), p_av->suspend.status, - p_av->suspend.initiator, peer_.FlagsToString().c_str()); + log::info("Peer {} : event={} status={} initiator={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), p_av->suspend.status, + p_av->suspend.initiator, peer_.FlagsToString()); // A2DP suspended, stop A2DP encoder / decoder until resumed if (peer_.IsActivePeer() || !btif_av_stream_started_ready()) { @@ -2669,10 +2620,9 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, } break; case BTA_AV_STOP_EVT: - LOG_INFO("%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::info("Peer {} : event={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); peer_.SetFlags(BtifAvPeer::kFlagPendingStop); peer_.ClearFlags(BtifAvPeer::kFlagLocalSuspendPending); @@ -2692,10 +2642,9 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, break; case BTA_AV_CLOSE_EVT: - LOG_INFO("%s: Peer %s : event=%s flags=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::info("Peer {} : event={} flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); // Inform the application that we are disconnecting btif_report_connection_state( peer_.PeerAddress(), BTAV_CONNECTION_STATE_DISCONNECTING, @@ -2720,11 +2669,9 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, if (peer_.CheckFlags(BtifAvPeer::kFlagLocalSuspendPending | BtifAvPeer::kFlagRemoteSuspend | BtifAvPeer::kFlagPendingStop)) { - LOG_WARN("%s: Peer %s : event=%s flags=%s: stream is Suspending", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str()); + log::warn("Peer {} : event={} flags={}: stream is Suspending", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString()); btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL); break; } @@ -2738,11 +2685,10 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, case BTIF_AV_SET_LATENCY_REQ_EVT: { const btif_av_set_latency_req_t* p_set_latency_req = static_cast(p_data); - LOG_INFO("Peer %s : event=%s flags=%s is_low_latency=%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), - peer_.FlagsToString().c_str(), - p_set_latency_req->is_low_latency ? "true" : "false"); + log::info("Peer {} : event={} flags={} is_low_latency={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), + p_set_latency_req->is_low_latency ? "true" : "false"); BTA_AvSetLatency(peer_.BtaHandle(), p_set_latency_req->is_low_latency); } break; @@ -2750,9 +2696,9 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, CHECK_RC_EVENT(event, (tBTA_AV*)p_data); default: - LOG_WARN("%s: Peer %s : Unhandled event=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : Unhandled event={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); return false; } @@ -2760,8 +2706,7 @@ bool BtifAvStateMachine::StateStarted::ProcessEvent(uint32_t event, } void BtifAvStateMachine::StateClosing::OnEnter() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); if (peer_.IsActivePeer()) { if (peer_.IsSink()) { @@ -2775,17 +2720,15 @@ void BtifAvStateMachine::StateClosing::OnEnter() { } void BtifAvStateMachine::StateClosing::OnExit() { - LOG_VERBOSE("%s: Peer %s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress())); } bool BtifAvStateMachine::StateClosing::ProcessEvent(uint32_t event, void* p_data) { - LOG_VERBOSE( - "%s: Peer %s : event=%s flags=%s active_peer=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str(), peer_.FlagsToString().c_str(), - logbool(peer_.IsActivePeer()).c_str()); + log::verbose("Peer {} : event={} flags={} active_peer={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event), peer_.FlagsToString(), + logbool(peer_.IsActivePeer())); switch (event) { case BTIF_AV_SUSPEND_STREAM_REQ_EVT: @@ -2819,25 +2762,24 @@ bool BtifAvStateMachine::StateClosing::ProcessEvent(uint32_t event, break; case BTIF_AV_OFFLOAD_START_REQ_EVT: - LOG_ERROR("%s: Peer %s : event=%s: stream is not Opened", - __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::error("Peer {} : event={}: stream is not Opened", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); btif_a2dp_on_offload_started(peer_.PeerAddress(), BTA_AV_FAIL); break; case BTIF_AV_CONNECT_REQ_EVT: - LOG_WARN("%s: Peer %s : Ignore %s in StateClosing", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : Ignore {} in StateClosing", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); btif_queue_advance(); peer_.StateMachine().TransitionTo(BtifAvStateMachine::kStateIdle); break; default: - LOG_WARN("%s: Peer %s : Unhandled event=%s", __PRETTY_FUNCTION__, - ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), - BtifAvEvent::EventName(event).c_str()); + log::warn("Peer {} : Unhandled event={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_.PeerAddress()), + BtifAvEvent::EventName(event)); return false; } return true; @@ -2851,21 +2793,20 @@ bool BtifAvStateMachine::StateClosing::ProcessEvent(uint32_t event, static void btif_av_source_initiate_av_open_timer_timeout(void* data) { BtifAvPeer* peer = (BtifAvPeer*)data; - LOG_VERBOSE("%s: Peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); // Check if AVRCP is connected to the peer if (!btif_rc_is_connected_peer(peer->PeerAddress())) { - LOG_ERROR("%s: AVRCP peer %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); + log::error("AVRCP peer {} is not connected", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); return; } // Connect to the AVRCP peer if (btif_av_source.Enabled() && btif_av_source.FindPeer(peer->PeerAddress()) == peer) { - LOG_VERBOSE("%s: Connecting to AVRCP peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); + log::verbose("Connecting to AVRCP peer {}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); btif_av_source_dispatch_sm_event(peer->PeerAddress(), BTIF_AV_CONNECT_REQ_EVT); } @@ -2878,21 +2819,20 @@ static void btif_av_source_initiate_av_open_timer_timeout(void* data) { static void btif_av_sink_initiate_av_open_timer_timeout(void* data) { BtifAvPeer* peer = (BtifAvPeer*)data; - LOG_VERBOSE("%s: Peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); // Check if AVRCP is connected to the peer if (!btif_rc_is_connected_peer(peer->PeerAddress())) { - LOG_ERROR("%s: AVRCP peer %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); + log::error("AVRCP peer {} is not connected", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); return; } // Connect to the AVRCP peer if (btif_av_sink.Enabled() && btif_av_sink.FindPeer(peer->PeerAddress()) == peer) { - LOG_VERBOSE("%s: Connecting to AVRCP peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); + log::verbose("Connecting to AVRCP peer {}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress())); btif_av_sink_dispatch_sm_event(peer->PeerAddress(), BTIF_AV_CONNECT_REQ_EVT); } @@ -2908,12 +2848,12 @@ static void btif_report_connection_state(const RawAddress& peer_address, btav_connection_state_t state, bt_status_t status, uint8_t error_code) { - LOG_INFO("%s: peer_address=%s state=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), state); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + state); if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { - LOG_ERROR("%s: peer is null", __func__); + log::error("peer is null"); return; } @@ -2957,8 +2897,8 @@ static void btif_report_connection_state(const RawAddress& peer_address, */ static void btif_report_audio_state(const RawAddress& peer_address, btav_audio_state_t state) { - LOG_INFO("%s: peer_address=%s state=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), state); + log::info("peer_address={} state={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + state); if (btif_av_both_enable()) { BtifAvPeer* peer = btif_av_find_peer(peer_address); @@ -3010,8 +2950,7 @@ void btif_av_report_source_codec_state( const std::vector& codecs_local_capabilities, const std::vector& codecs_selectable_capabilities) { - LOG_VERBOSE("%s: peer_address=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::verbose("peer_address={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (btif_av_source.Enabled()) { do_in_jni_thread( FROM_HERE, @@ -3030,8 +2969,8 @@ void btif_av_report_source_codec_state( */ static void btif_av_report_sink_audio_config_state( const RawAddress& peer_address, int sample_rate, int channel_count) { - LOG_INFO("%s: Peer %s : sample_rate=%d channel_count=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), sample_rate, channel_count); + log::info("Peer {} : sample_rate={} channel_count={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), sample_rate, channel_count); if (btif_av_sink.Enabled()) { do_in_jni_thread(FROM_HERE, base::BindOnce(btif_av_sink.Callbacks()->audio_config_cb, @@ -3049,7 +2988,7 @@ static void btif_av_query_mandatory_codec_priority( const RawAddress& peer_address) { auto query_priority = [](const RawAddress& peer_address) { if (!btif_av_source.Enabled()) { - LOG_WARN("BTIF AV Source is not enabled"); + log::warn("BTIF AV Source is not enabled"); return; } btav_source_callbacks_t* callbacks = btif_av_source.Callbacks(); @@ -3059,7 +2998,7 @@ static void btif_av_query_mandatory_codec_priority( auto apply_priority = [](const RawAddress& peer_address, bool preferred) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("btif_av_query_mandatory_codec_priority: peer is null"); + log::warn("btif_av_query_mandatory_codec_priority: peer is null"); return; } peer->SetMandatoryCodecPreferred(preferred); @@ -3084,44 +3023,39 @@ static BtifAvPeer* btif_av_handle_both_peer(uint8_t peer_sep, /* if no this peer, default it's sink device */ if (peer == nullptr) { if (peer_sep == AVDT_TSEP_SRC) { - LOG_VERBOSE("%s: peer_sep(%d), create a new source peer", __func__, - peer_sep); + log::verbose("peer_sep({}), create a new source peer", peer_sep); peer = btif_av_sink.FindOrCreatePeer(peer_address, bta_handle); } else if (peer_sep == AVDT_TSEP_SNK) { - LOG_VERBOSE("%s: peer_sep(%d), create a new sink peer", __func__, - peer_sep); + log::verbose("peer_sep({}), create a new sink peer", peer_sep); peer = btif_av_source.FindOrCreatePeer(peer_address, bta_handle); } else { btif_av_source.SetInvalidPeerCheck(true); if (!btif_av_source.Peers().empty()) { - LOG_VERBOSE( - "%s: peer_sep invalid, and already has sink peer," - " so try create a new sink peer", - __func__); + log::verbose( + "peer_sep invalid, and already has sink peer, so try create a " + "new sink peer"); peer = btif_av_source.FindOrCreatePeer(peer_address, bta_handle); } else if (!btif_av_sink.Peers().empty()) { - LOG_VERBOSE( - "%s: peer_sep invalid, and already has source peer," - " so try create a new source peer", - __func__); + log::verbose( + "peer_sep invalid, and already has source peer, so try create " + "a new source peer"); peer = btif_av_sink.FindOrCreatePeer(peer_address, bta_handle); } else { - LOG_VERBOSE( - "%s: peer_sep invalid, and no active peer," - " so try create a new sink peer", - __func__); + log::verbose( + "peer_sep invalid, and no active peer, so try create a new " + "sink peer"); peer = btif_av_source.FindOrCreatePeer(peer_address, bta_handle); } } } } else { if (peer_sep == AVDT_TSEP_SNK) { - LOG_VERBOSE("%s: peer_sep(%d), only init src create a new source peer", - __func__, peer_sep); + log::verbose("peer_sep({}), only init src create a new source peer", + peer_sep); peer = btif_av_source.FindOrCreatePeer(peer_address, bta_handle); } else if (peer_sep == AVDT_TSEP_SRC) { - LOG_VERBOSE("%s: peer_sep(%d), only init sink create a new source peer", - __func__, peer_sep); + log::verbose("peer_sep({}), only init sink create a new source peer", + peer_sep); peer = btif_av_sink.FindOrCreatePeer(peer_address, bta_handle); } } @@ -3131,7 +3065,7 @@ static BtifAvPeer* btif_av_handle_both_peer(uint8_t peer_sep, } else if (peer_sep == AVDT_TSEP_SRC) { peer = btif_av_sink.FindPeerByHandle(bta_handle); } - LOG_VERBOSE("%s:peer is check 3", __func__); + log::verbose("peer is check 3"); } } else if (bta_handle != 0) { if (peer_sep == AVDT_TSEP_INVALID) { @@ -3164,8 +3098,8 @@ static void btif_av_handle_event(uint8_t peer_sep, const RawAddress& peer_address, tBTA_AV_HNDL bta_handle, const BtifAvEvent& btif_av_event) { - LOG_DEBUG("Handle event peer_address=%s bta_handle=0x%x", - ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle); + log::debug("Handle event peer_address={} bta_handle=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle); BtifAvPeer* peer = nullptr; @@ -3188,12 +3122,12 @@ static void btif_av_handle_event(uint8_t peer_sep, } } if (peer == nullptr) { - LOG_ERROR( - "jni_thread: Cannot find or create %s peer for peer_address=%s " - " bta_handle=0x%x : event dropped: %s", - peer_stream_endpoint_text(peer_sep).c_str(), + log::error( + "jni_thread: Cannot find or create {} peer for peer_address={} " + "bta_handle=0x{:x} : event dropped: {}", + peer_stream_endpoint_text(peer_sep), ADDRESS_TO_LOGGABLE_CSTR(peer_address), bta_handle, - btif_av_event.ToString().c_str()); + btif_av_event.ToString()); return; } @@ -3217,22 +3151,22 @@ static void btif_av_handle_bta_av_event(uint8_t peer_sep, tBTA_AV* p_data = (tBTA_AV*)btif_av_event.Data(); std::string msg; - LOG_DEBUG( - "jni_thread: Handle BTA AV or AVRCP event %s: peer_sep=%hhu event=%s", - peer_stream_endpoint_text(peer_sep).c_str(), peer_sep, - btif_av_event.ToString().c_str()); + log::debug( + "jni_thread: Handle BTA AV or AVRCP event {}: peer_sep={} event={}", + peer_stream_endpoint_text(peer_sep), peer_sep, btif_av_event.ToString()); switch (event) { case BTA_AV_ENABLE_EVT: { const tBTA_AV_ENABLE& enable = p_data->enable; - LOG_DEBUG("Enable features=0x%x", enable.features); + log::debug("Enable features=0x{:x}", enable.features); return; // Nothing to do } case BTA_AV_REGISTER_EVT: { const tBTA_AV_REGISTER& reg = p_data->reg; bta_handle = reg.hndl; uint8_t peer_id = reg.app_id; // The PeerId is used as AppId - LOG_DEBUG("Register bta_handle=0x%x app_id=%d", bta_handle, reg.app_id); + log::debug("Register bta_handle=0x{:x} app_id={}", bta_handle, + reg.app_id); if (btif_av_src_sink_coexist_enabled()) { if (peer_sep == AVDT_TSEP_INVALID) { if (reg.peer_sep == AVDT_TSEP_SNK) @@ -3385,7 +3319,7 @@ bool btif_av_src_sink_coexist_enabled(void) { static void bta_av_source_callback(tBTA_AV_EVT event, tBTA_AV* p_data) { BtifAvEvent btif_av_event(event, p_data, sizeof(tBTA_AV)); - LOG_VERBOSE("%s: event=%s", __func__, btif_av_event.ToString().c_str()); + log::verbose("event={}", btif_av_event.ToString()); do_in_main_thread( FROM_HERE, base::BindOnce(&btif_av_handle_bta_av_event, @@ -3420,7 +3354,7 @@ static void bta_av_event_callback(tBTA_AV_EVT event, tBTA_AV* p_data) { static void bta_av_sink_media_callback(const RawAddress& peer_address, tBTA_AV_EVT event, tBTA_AV_MEDIA* p_data) { - LOG_VERBOSE("%s: event=%d", __func__, event); + log::verbose("event={}", event); switch (event) { case BTA_AV_SINK_MEDIA_DATA_EVT: { @@ -3430,7 +3364,7 @@ static void bta_av_sink_media_callback(const RawAddress& peer_address, if ((state == BtifAvStateMachine::kStateStarted) || (state == BtifAvStateMachine::kStateOpened)) { uint8_t queue_len = btif_a2dp_sink_enqueue_buf((BT_HDR*)p_data); - LOG_VERBOSE("%s: Packets in Sink queue %d", __func__, queue_len); + log::verbose("Packets in Sink queue {}", queue_len); } } break; @@ -3438,8 +3372,8 @@ static void bta_av_sink_media_callback(const RawAddress& peer_address, case BTA_AV_SINK_MEDIA_CFG_EVT: { btif_av_sink_config_req_t config_req; - LOG_VERBOSE("%s: address=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_data->avk_config.bd_addr)); + log::verbose("address={}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->avk_config.bd_addr)); // Update the codec info of the A2DP Sink decoder btif_a2dp_sink_update_decoder((uint8_t*)(p_data->avk_config.codec_info)); @@ -3447,13 +3381,13 @@ static void bta_av_sink_media_callback(const RawAddress& peer_address, config_req.sample_rate = A2DP_GetTrackSampleRate(p_data->avk_config.codec_info); if (config_req.sample_rate == -1) { - LOG_ERROR("%s: Cannot get the track frequency", __func__); + log::error("Cannot get the track frequency"); break; } config_req.channel_count = A2DP_GetTrackChannelCount(p_data->avk_config.codec_info); if (config_req.channel_count == -1) { - LOG_ERROR("%s: Cannot get the channel count", __func__); + log::error("Cannot get the channel count"); break; } config_req.peer_address = p_data->avk_config.bd_addr; @@ -3475,35 +3409,37 @@ static void bta_av_sink_media_callback(const RawAddress& peer_address, static bt_status_t init_src( btav_source_callbacks_t* callbacks, int max_connected_audio_devices, const std::vector& codec_priorities, - const std::vector& offloading_preference) { - LOG_VERBOSE("%s", __func__); + const std::vector& offloading_preference, + std::vector* supported_codecs) { + log::verbose(""); return btif_av_source.Init(callbacks, max_connected_audio_devices, - codec_priorities, offloading_preference); + codec_priorities, offloading_preference, + supported_codecs); } // Initializes the AV interface for sink mode static bt_status_t init_sink(btav_sink_callbacks_t* callbacks, int max_connected_audio_devices) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return btif_av_sink.Init(callbacks, max_connected_audio_devices); } // Updates the final focus state reported by components calling this module static void update_audio_focus_state(int state) { - LOG_VERBOSE("%s: state=%d", __func__, state); + log::verbose("state={}", state); btif_a2dp_sink_set_focus_state_req((btif_a2dp_sink_focus_state_t)state); } // Updates the track gain (used for ducking). static void update_audio_track_gain(float gain) { - LOG_VERBOSE("%s: gain=%f", __func__, gain); + log::verbose("gain={:f}", gain); btif_a2dp_sink_set_audio_track_gain(gain); } // Establishes the AV signalling channel with the remote headset static bt_status_t connect_int(RawAddress* peer_address, uint16_t uuid) { - LOG_VERBOSE("%s: peer_address=%s uuid=0x%x", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*peer_address), uuid); + log::verbose("peer_address={} uuid=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(*peer_address), uuid); if (btif_av_both_enable()) { const RawAddress tmp = *peer_address; if (uuid == UUID_SERVCLASS_AUDIO_SOURCE) { @@ -3530,19 +3466,19 @@ static bt_status_t connect_int(RawAddress* peer_address, uint16_t uuid) { bt_status_t status = do_in_main_thread( FROM_HERE, base::BindOnce(connection_task, peer_address, uuid)); if (status != BT_STATUS_SUCCESS) { - LOG(ERROR) << __func__ << ": can't post connection task to main_thread"; + log::error("can't post connection task to main_thread"); } return status; } static void set_source_silence_peer_int(const RawAddress& peer_address, bool silence) { - LOG_VERBOSE("%s: peer_address=%s, silence=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - silence ? "true" : "false"); + log::verbose("peer_address={}, silence={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), + silence ? "true" : "false"); if (!btif_av_source.SetSilencePeer(peer_address, silence)) { - LOG_ERROR("%s: Error setting silence state to %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("Error setting silence state to {}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); } } @@ -3550,17 +3486,17 @@ static void set_source_silence_peer_int(const RawAddress& peer_address, static void set_active_peer_int(uint8_t peer_sep, const RawAddress& peer_address, std::promise peer_ready_promise) { - LOG_VERBOSE("%s: peer_sep=%s (%d) peer_address=%s", __func__, - (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::verbose("peer_sep={} ({}) peer_address={}", + (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep, + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); BtifAvPeer* peer = nullptr; if (peer_sep == AVDT_TSEP_SNK) { if (!btif_av_src_sink_coexist_enabled() || (btif_av_src_sink_coexist_enabled() && btif_av_both_enable() && (btif_av_sink.FindPeer(peer_address) == nullptr))) { btif_av_source.SetActivePeer(peer_address, std::move(peer_ready_promise)); - LOG_ERROR("%s: Error setting %s as active Sink peer", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("Error setting {} as active Sink peer", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); } return; } @@ -3569,39 +3505,39 @@ static void set_active_peer_int(uint8_t peer_sep, btif_av_both_enable() && (btif_av_source.FindPeer(peer_address) == nullptr))) { if (!btif_av_sink.SetActivePeer(peer_address, std::move(peer_ready_promise))) { - LOG_ERROR("%s: Error setting %s as active Source peer", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::error("Error setting {} as active Source peer", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); } } return; } // If reached here, we could not set the active peer - LOG_ERROR("%s: Cannot set active %s peer to %s: peer not %s", __func__, - (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - (peer == nullptr) ? "found" : "connected"); + log::error("Cannot set active {} peer to {}: peer not {}", + (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), + (peer == nullptr) ? "found" : "connected"); peer_ready_promise.set_value(); } static bt_status_t src_connect_sink(const RawAddress& peer_address) { if (!btif_av_source.Enabled()) { - LOG_WARN("BTIF AV Source is not enabled"); + log::warn("BTIF AV Source is not enabled"); return BT_STATUS_NOT_READY; } RawAddress peer_address_copy(peer_address); - LOG_DEBUG("Connecting to AV sink peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(peer_address_copy)); + log::debug("Connecting to AV sink peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address_copy)); return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, &peer_address_copy, connect_int); } static bt_status_t sink_connect_src(const RawAddress& peer_address) { - LOG_INFO("%s: Peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (!btif_av_sink.Enabled()) { - LOG_WARN("%s: BTIF AV Sink is not enabled", __func__); + log::warn("BTIF AV Sink is not enabled"); return BT_STATUS_NOT_READY; } @@ -3611,10 +3547,10 @@ static bt_status_t sink_connect_src(const RawAddress& peer_address) { } static bt_status_t src_disconnect_sink(const RawAddress& peer_address) { - LOG_INFO("%s: Peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (!btif_av_source.Enabled()) { - LOG_WARN("%s: BTIF AV Source is not enabled", __func__); + log::warn("BTIF AV Source is not enabled"); return BT_STATUS_NOT_READY; } @@ -3628,10 +3564,10 @@ static bt_status_t src_disconnect_sink(const RawAddress& peer_address) { } static bt_status_t sink_disconnect_src(const RawAddress& peer_address) { - LOG_INFO("%s: Peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (!btif_av_sink.Enabled()) { - LOG_WARN("%s: BTIF AV Sink is not enabled", __func__); + log::warn("BTIF AV Sink is not enabled"); return BT_STATUS_NOT_READY; } @@ -3645,10 +3581,10 @@ static bt_status_t sink_disconnect_src(const RawAddress& peer_address) { } static bt_status_t sink_set_active_device(const RawAddress& peer_address) { - LOG_VERBOSE("%s: Peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (!btif_av_sink.Enabled()) { - LOG(WARNING) << __func__ << ": BTIF AV Source is not enabled"; + log::warn("BTIF AV Source is not enabled"); return BT_STATUS_NOT_READY; } @@ -3661,16 +3597,16 @@ static bt_status_t sink_set_active_device(const RawAddress& peer_address) { if (status == BT_STATUS_SUCCESS) { peer_ready_future.wait(); } else { - LOG(WARNING) << __func__ << ": BTIF AV Sink fails to change peer"; + log::warn("BTIF AV Sink fails to change peer"); } return status; } static bt_status_t src_set_silence_sink(const RawAddress& peer_address, bool silence) { - LOG_VERBOSE("%s: Peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (!btif_av_source.Enabled()) { - LOG_WARN("%s: BTIF AV Source is not enabled", __func__); + log::warn("BTIF AV Source is not enabled"); return BT_STATUS_NOT_READY; } @@ -3680,10 +3616,10 @@ static bt_status_t src_set_silence_sink(const RawAddress& peer_address, } static bt_status_t src_set_active_sink(const RawAddress& peer_address) { - LOG_VERBOSE("%s: Peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::verbose("Peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (!btif_av_source.Enabled()) { - LOG(WARNING) << __func__ << ": BTIF AV Source is not enabled"; + log::warn("BTIF AV Source is not enabled"); return BT_STATUS_NOT_READY; } @@ -3696,7 +3632,7 @@ static bt_status_t src_set_active_sink(const RawAddress& peer_address) { if (status == BT_STATUS_SUCCESS) { peer_ready_future.wait(); } else { - LOG(WARNING) << __func__ << ": BTIF AV Source fails to change peer"; + log::warn("BTIF AV Source fails to change peer"); } return status; } @@ -3704,15 +3640,15 @@ static bt_status_t src_set_active_sink(const RawAddress& peer_address) { static bt_status_t codec_config_src( const RawAddress& peer_address, std::vector codec_preferences) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!btif_av_source.Enabled()) { - LOG(WARNING) << __func__ << ": BTIF AV Source is not enabled"; + log::warn("BTIF AV Source is not enabled"); return BT_STATUS_NOT_READY; } if (peer_address.IsEmpty()) { - LOG(WARNING) << __func__ << ": BTIF AV Source needs peer to config"; + log::warn("BTIF AV Source needs peer to config"); return BT_STATUS_PARM_INVALID; } @@ -3726,20 +3662,20 @@ static bt_status_t codec_config_src( if (status == BT_STATUS_SUCCESS) { peer_ready_future.wait(); } else { - LOG(WARNING) << __func__ << ": BTIF AV Source fails to config codec"; + log::warn("BTIF AV Source fails to config codec"); } return status; } static void cleanup_src(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); do_in_main_thread(FROM_HERE, base::BindOnce(&BtifAvSource::Cleanup, base::Unretained(&btif_av_source))); } static void cleanup_sink(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); do_in_main_thread(FROM_HERE, base::BindOnce(&BtifAvSink::Cleanup, base::Unretained(&btif_av_sink))); } @@ -3775,22 +3711,21 @@ bool btif_av_is_sink_enabled(void) { return btif_av_sink.Enabled(); } bool btif_av_is_source_enabled(void) { return btif_av_source.Enabled(); } void btif_av_stream_start(void) { - LOG_INFO("%s", __func__); + log::info(""); btif_av_source_dispatch_sm_event(btif_av_source_active_peer(), BTIF_AV_START_STREAM_REQ_EVT); } void btif_av_stream_start_with_latency(bool use_latency_mode) { - LOG_INFO("%s", __func__); + log::info(""); btif_av_start_stream_req_t start_stream_req; start_stream_req.use_latency_mode = use_latency_mode; BtifAvEvent btif_av_event(BTIF_AV_START_STREAM_REQ_EVT, &start_stream_req, sizeof(start_stream_req)); - LOG_INFO("peer_address=%s event=%s use_latency_mode=%s", - ADDRESS_TO_LOGGABLE_CSTR(btif_av_source_active_peer()), - btif_av_event.ToString().c_str(), - use_latency_mode ? "true" : "false"); + log::info("peer_address={} event={} use_latency_mode={}", + ADDRESS_TO_LOGGABLE_CSTR(btif_av_source_active_peer()), + btif_av_event.ToString(), use_latency_mode ? "true" : "false"); do_in_main_thread( FROM_HERE, base::BindOnce(&btif_av_handle_event, @@ -3821,7 +3756,7 @@ void src_do_suspend_in_main_thread(btif_av_sm_event_t event) { } void btif_av_stream_stop(const RawAddress& peer_address) { - LOG_INFO("%s peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (!peer_address.IsEmpty()) { btif_av_source_dispatch_sm_event(peer_address, BTIF_AV_STOP_STREAM_REQ_EVT); @@ -3834,40 +3769,40 @@ void btif_av_stream_stop(const RawAddress& peer_address) { } void btif_av_stream_suspend(void) { - LOG_INFO("%s", __func__); + log::info(""); // The active peer might have changed and we might be in the process // of reconfiguring the stream. We need to suspend the appropriate peer(s). src_do_suspend_in_main_thread(BTIF_AV_SUSPEND_STREAM_REQ_EVT); } void btif_av_stream_start_offload(void) { - LOG_INFO("%s", __func__); + log::info(""); btif_av_source_dispatch_sm_event(btif_av_source_active_peer(), BTIF_AV_OFFLOAD_START_REQ_EVT); } void btif_av_src_disconnect_sink(const RawAddress& peer_address) { - LOG_INFO("%s: peer %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("peer {}", ADDRESS_TO_LOGGABLE_CSTR(peer_address)); src_disconnect_sink(peer_address); } bool btif_av_stream_ready(void) { // Make sure the main adapter is enabled if (btif_is_enabled() == 0) { - LOG_VERBOSE("%s: Main adapter is not enabled", __func__); + log::verbose("Main adapter is not enabled"); return false; } BtifAvPeer* peer = btif_av_find_active_peer(); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } int state = peer->StateMachine().StateId(); - LOG_INFO("%s: Peer %s : state=%d, flags=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), state, - peer->FlagsToString().c_str()); + log::info("Peer {} : state={}, flags={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), state, + peer->FlagsToString()); // check if we are remotely suspended or stop is pending if (peer->CheckFlags(BtifAvPeer::kFlagRemoteSuspend | BtifAvPeer::kFlagPendingStop)) { @@ -3880,7 +3815,7 @@ bool btif_av_stream_ready(void) { bool btif_av_stream_started_ready(void) { BtifAvPeer* peer = btif_av_find_active_peer(); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } @@ -3894,9 +3829,9 @@ bool btif_av_stream_started_ready(void) { } else { ready = (state == BtifAvStateMachine::kStateStarted); } - LOG_INFO("%s: Peer %s : state=%d flags=%s ready=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), state, - peer->FlagsToString().c_str(), ready); + log::info("Peer {} : state={} flags={} ready={}", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), state, + peer->FlagsToString(), ready); return ready; } @@ -3904,9 +3839,9 @@ bool btif_av_stream_started_ready(void) { static void btif_av_source_dispatch_sm_event(const RawAddress& peer_address, btif_av_sm_event_t event) { BtifAvEvent btif_av_event(event, nullptr, 0); - LOG_VERBOSE("%s: peer_address=%s event=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - btif_av_event.ToString().c_str()); + log::verbose("peer_address={} event={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), + btif_av_event.ToString()); do_in_main_thread(FROM_HERE, base::BindOnce(&btif_av_handle_event, AVDT_TSEP_SNK, // peer_sep @@ -3917,9 +3852,9 @@ static void btif_av_source_dispatch_sm_event(const RawAddress& peer_address, static void btif_av_sink_dispatch_sm_event(const RawAddress& peer_address, btif_av_sm_event_t event) { BtifAvEvent btif_av_event(event, nullptr, 0); - LOG_VERBOSE("%s: peer_address=%s event=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), - btif_av_event.ToString().c_str()); + log::verbose("peer_address={} event={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), + btif_av_event.ToString()); do_in_main_thread(FROM_HERE, base::BindOnce(&btif_av_handle_event, AVDT_TSEP_SRC, // peer_sep @@ -3928,8 +3863,7 @@ static void btif_av_sink_dispatch_sm_event(const RawAddress& peer_address, } bt_status_t btif_av_source_execute_service(bool enable) { - LOG_VERBOSE("%s: Source service: %s", __func__, - (enable) ? "enable" : "disable"); + log::verbose("Source service: {}", (enable) ? "enable" : "disable"); if (enable) { // Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not @@ -3965,8 +3899,7 @@ bt_status_t btif_av_source_execute_service(bool enable) { } bt_status_t btif_av_sink_execute_service(bool enable) { - LOG_VERBOSE("%s: Sink service: %s", __func__, - (enable) ? "enable" : "disable"); + log::verbose("Sink service: {}", (enable) ? "enable" : "disable"); if (enable) { // Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not @@ -3997,41 +3930,40 @@ bt_status_t btif_av_sink_execute_service(bool enable) { // Get the AV callback interface for A2DP source profile const btav_source_interface_t* btif_av_get_src_interface(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return &bt_av_src_interface; } // Get the AV callback interface for A2DP sink profile const btav_sink_interface_t* btif_av_get_sink_interface(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return &bt_av_sink_interface; } bool btif_av_is_connected(void) { BtifAvPeer* peer = btif_av_find_active_peer(); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } bool connected = peer->IsConnected(); - LOG_VERBOSE("%s: Peer %s is %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - (connected) ? "connected" : "not connected"); + log::verbose("Peer {} is {}", ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + (connected) ? "connected" : "not connected"); return connected; } uint8_t btif_av_get_peer_sep(void) { BtifAvPeer* peer = btif_av_find_active_peer(); if (peer == nullptr) { - LOG_INFO("No active sink or source peer found"); + log::info("No active sink or source peer found"); return AVDT_TSEP_INVALID; } uint8_t peer_sep = peer->PeerSep(); - LOG_VERBOSE("Peer %s SEP is %s (%d)", - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep); + log::verbose("Peer {} SEP is {} ({})", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep); return peer_sep; } @@ -4039,12 +3971,12 @@ void btif_av_clear_remote_suspend_flag(void) { auto clear_remote_suspend_flag = []() { BtifAvPeer* peer = btif_av_find_active_peer(); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return; } - LOG_VERBOSE("%s: Peer %s : flags=%s are cleared", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - peer->FlagsToString().c_str()); + log::verbose("Peer {} : flags={} are cleared", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + peer->FlagsToString()); peer->ClearFlags(BtifAvPeer::kFlagRemoteSuspend); }; // switch to main thread to prevent a race condition of accessing peers @@ -4054,42 +3986,42 @@ void btif_av_clear_remote_suspend_flag(void) { bool btif_av_is_peer_edr(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No peer found for peer_address=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::warn("No peer found for peer_address={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return false; } if (!peer->IsConnected()) { - LOG_WARN("%s: Peer %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::warn("Peer {} is not connected", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return false; } bool is_edr = peer->IsEdr(); - LOG_VERBOSE("%s: Peer %s : is_edr=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), is_edr); + log::verbose("Peer {} : is_edr={}", ADDRESS_TO_LOGGABLE_CSTR(peer_address), + is_edr); return is_edr; } bool btif_av_peer_supports_3mbps(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No peer found for peer_address=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::warn("No peer found for peer_address={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return false; } bool is3mbps = peer->Is3Mbps(); bool is_connected = peer->IsConnected(); - LOG_VERBOSE("%s: Peer %s : connected=%d, edr_3mbps=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address), is_connected, is3mbps); + log::verbose("Peer {} : connected={}, edr_3mbps={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address), is_connected, is3mbps); return (is_connected && is3mbps); } bool btif_av_peer_prefers_mandatory_codec(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No peer found for peer_address=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::warn("No peer found for peer_address={}", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); return false; } return peer->IsMandatoryCodecPreferred(); @@ -4097,8 +4029,8 @@ bool btif_av_peer_prefers_mandatory_codec(const RawAddress& peer_address) { void btif_av_acl_disconnected(const RawAddress& peer_address) { // Inform the application that ACL is disconnected and move to idle state - LOG_INFO("%s: Peer %s : ACL Disconnected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer_address)); + log::info("Peer {} : ACL Disconnected", + ADDRESS_TO_LOGGABLE_CSTR(peer_address)); if (btif_av_both_enable()) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer != nullptr) { @@ -4243,15 +4175,15 @@ void btif_av_set_dynamic_audio_buffer_size(uint8_t dynamic_audio_buffer_size) { } void btif_av_set_low_latency(bool is_low_latency) { - LOG_INFO("is_low_latency: %s", is_low_latency ? "true" : "false"); + log::info("is_low_latency: {}", is_low_latency ? "true" : "false"); btif_av_set_latency_req_t set_latency_req; set_latency_req.is_low_latency = is_low_latency; BtifAvEvent btif_av_event(BTIF_AV_SET_LATENCY_REQ_EVT, &set_latency_req, sizeof(set_latency_req)); - LOG_INFO("peer_address=%s event=%s", - ADDRESS_TO_LOGGABLE_CSTR(btif_av_source_active_peer()), - btif_av_event.ToString().c_str()); + log::info("peer_address={} event={}", + ADDRESS_TO_LOGGABLE_CSTR(btif_av_source_active_peer()), + btif_av_event.ToString()); do_in_main_thread( FROM_HERE, base::BindOnce(&btif_av_handle_event, AVDT_TSEP_SNK, // peer_sep @@ -4270,49 +4202,46 @@ static void btif_av_source_delete_active_peer(void) { bool btif_av_is_connected_addr(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } bool connected = peer->IsConnected(); - LOG_VERBOSE("%s: Peer %s is %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - (connected) ? "connected" : "not connected"); + log::verbose("Peer {} is {}", ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + (connected) ? "connected" : "not connected"); return connected; } bool btif_av_peer_is_connected_sink(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_source_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } bool connected = peer->IsConnected(); - LOG_VERBOSE("%s: Peer %s is %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - (connected) ? "connected" : "not connected"); + log::verbose("Peer {} is {}", ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + (connected) ? "connected" : "not connected"); return connected; } bool btif_av_peer_is_connected_source(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_sink_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } bool connected = peer->IsConnected(); - LOG_VERBOSE("%s: Peer %s is %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - (connected) ? "connected" : "not connected"); + log::verbose("Peer {} is {}", ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + (connected) ? "connected" : "not connected"); return connected; } bool btif_av_peer_is_sink(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_source_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } @@ -4322,7 +4251,7 @@ bool btif_av_peer_is_sink(const RawAddress& peer_address) { bool btif_av_peer_is_source(const RawAddress& peer_address) { BtifAvPeer* peer = btif_av_sink_find_peer(peer_address); if (peer == nullptr) { - LOG_WARN("%s: No active peer found", __func__); + log::warn("No active peer found"); return false; } diff --git a/system/btif/src/btif_avrcp_audio_track.cc b/system/btif/src/btif_avrcp_audio_track.cc index e18befc36919d10a8942f029bacc0b6d9451eb78..12252b45b613c7ea280815f941f2c4843c2600f0 100644 --- a/system/btif/src/btif_avrcp_audio_track.cc +++ b/system/btif/src/btif_avrcp_audio_track.cc @@ -25,15 +25,18 @@ #include #include +#include #include #include #include +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" using namespace android; +using namespace bluetooth; typedef struct { AAudioStream* stream; @@ -84,8 +87,8 @@ void BtifAvrcpAudioErrorHandle() { trackHolder->stream = stream; if (trackHolder != NULL && trackHolder->stream != NULL) { - LOG_DEBUG("%s AAudio Error handle: restart A2dp Sink AudioTrack", __func__); - AAudioStream_requestStart(trackHolder->stream); + log::debug("AAudio Error handle: restart A2dp Sink AudioTrack"); + AAudioStream_requestStart(trackHolder->stream); } s_AudioEngine.thread = nullptr; } @@ -100,8 +103,8 @@ void ErrorCallback(AAudioStream* stream, void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample, int channelCount) { - LOG_INFO("%s Track.cpp: btCreateTrack freq %d bps %d channel %d ", __func__, - trackFreq, bitsPerSample, channelCount); + log::info("Track.cpp: btCreateTrack freq {} bps {} channel {}", trackFreq, + bitsPerSample, channelCount); AAudioStreamBuilder* builder; AAudioStream* stream; @@ -139,36 +142,36 @@ void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample, void BtifAvrcpAudioTrackStart(void* handle) { if (handle == NULL) { - LOG_ERROR("%s: handle is null!", __func__); + log::error("handle is null!"); return; } BtifAvrcpAudioTrack* trackHolder = static_cast(handle); CHECK(trackHolder != NULL); CHECK(trackHolder->stream != NULL); - LOG_VERBOSE("%s Track.cpp: btStartTrack", __func__); + log::verbose("Track.cpp: btStartTrack"); AAudioStream_requestStart(trackHolder->stream); } void BtifAvrcpAudioTrackStop(void* handle) { if (handle == NULL) { - LOG_INFO("%s handle is null.", __func__); + log::info("handle is null."); return; } BtifAvrcpAudioTrack* trackHolder = static_cast(handle); if (trackHolder != NULL && trackHolder->stream != NULL) { - LOG_VERBOSE("%s Track.cpp: btStopTrack", __func__); + log::verbose("Track.cpp: btStopTrack"); AAudioStream_requestStop(trackHolder->stream); } } void BtifAvrcpAudioTrackDelete(void* handle) { if (handle == NULL) { - LOG_INFO("%s handle is null.", __func__); + log::info("handle is null."); return; } BtifAvrcpAudioTrack* trackHolder = static_cast(handle); if (trackHolder != NULL && trackHolder->stream != NULL) { - LOG_VERBOSE("%s Track.cpp: btStartTrack", __func__); + log::verbose("Track.cpp: btStartTrack"); AAudioStream_close(trackHolder->stream); delete trackHolder->buffer; delete trackHolder; @@ -184,12 +187,12 @@ void BtifAvrcpAudioTrackDelete(void* handle) { void BtifAvrcpAudioTrackPause(void* handle) { if (handle == NULL) { - LOG_INFO("%s handle is null.", __func__); + log::info("handle is null."); return; } BtifAvrcpAudioTrack* trackHolder = static_cast(handle); if (trackHolder != NULL && trackHolder->stream != NULL) { - LOG_VERBOSE("%s Track.cpp: btPauseTrack", __func__); + log::verbose("Track.cpp: btPauseTrack"); AAudioStream_requestPause(trackHolder->stream); AAudioStream_requestFlush(trackHolder->stream); } @@ -197,18 +200,18 @@ void BtifAvrcpAudioTrackPause(void* handle) { void BtifAvrcpSetAudioTrackGain(void* handle, float gain) { if (handle == NULL) { - LOG_INFO("%s handle is null.", __func__); + log::info("handle is null."); return; } BtifAvrcpAudioTrack* trackHolder = static_cast(handle); if (trackHolder != NULL) { const float clampedGain = std::clamp(gain, kMinTrackGain, kMaxTrackGain); if (clampedGain != gain) { - LOG_WARN("Out of bounds gain set. Clamping the gain from :%f to %f", gain, - clampedGain); + log::warn("Out of bounds gain set. Clamping the gain from :{:f} to {:f}", + gain, clampedGain); } trackHolder->gain = clampedGain; - LOG_INFO("Avrcp audio track gain is set to %f", trackHolder->gain); + log::info("Avrcp audio track gain is set to {:f}", trackHolder->gain); } } @@ -293,8 +296,8 @@ int BtifAvrcpAudioTrackWriteData(void* handle, void* audioBuffer, trackHolder->stream, trackHolder->buffer, transcodedCount / (sampleSize * trackHolder->channelCount), kTimeoutNanos); - LOG_VERBOSE("%s Track.cpp: btWriteData len = %d ret = %d", __func__, - bufferLength, retval); + log::verbose("Track.cpp: btWriteData len = {} ret = {}", bufferLength, + retval); } while (transcodedCount < bufferLength); return transcodedCount; diff --git a/system/btif/src/btif_bqr.cc b/system/btif/src/btif_bqr.cc index 9f0fca859d9c14dfac7a60dbef1dbfe8ab7204b4..63e667daea7a0c7ca3f17049c2d3c0f9716b0286 100644 --- a/system/btif/src/btif_bqr.cc +++ b/system/btif/src/btif_bqr.cc @@ -19,20 +19,23 @@ #ifdef __ANDROID__ #include #endif +#include #include #include #include -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "btif_bqr.h" #include "btif_common.h" #include "btif_storage.h" #include "btm_api.h" #include "btm_ble_api.h" +#include "common/init_flags.h" #include "common/leaky_bonded_queue.h" #include "common/time_util.h" #include "core_callbacks.h" +#include "internal_include/bt_trace.h" #include "osi/include/properties.h" #include "raw_address.h" #include "stack/btm/btm_dev.h" @@ -56,10 +59,10 @@ std::unique_ptr bluetoothQualityReportInstance; void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length, const uint8_t* p_param_buf) { if (length < kLinkQualityParamTotalLen) { - LOG(FATAL) << __func__ - << ": Parameter total length: " << std::to_string(length) - << " is abnormal. It shall be not shorter than: " - << std::to_string(kLinkQualityParamTotalLen); + log::fatal( + "Parameter total length: {} is abnormal. It shall be not shorter than: " + "{}", + length, kLinkQualityParamTotalLen); return; } @@ -89,17 +92,13 @@ void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length, if (vendor_cap_supported_version >= kBqrVersion5_0) { if (length < kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen + kVersion5_0ParamsTotalLen) { - LOG(WARNING) << __func__ - << ": Parameter total length: " << std::to_string(length) - << " is abnormal. " - << "vendor_cap_supported_version: " - << vendor_cap_supported_version << " " - << " (>= " - << "kBqrVersion5_0=" << kBqrVersion5_0 << "), " - << "It should not be shorter than: " - << std::to_string(kLinkQualityParamTotalLen + - kISOLinkQualityParamTotalLen + - kVersion5_0ParamsTotalLen); + log::warn( + "Parameter total length: {} is abnormal. " + "vendor_cap_supported_version: {} (>= kBqrVersion5_0={}), It should " + "not be shorter than: {}", + length, vendor_cap_supported_version, kBqrVersion5_0, + kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen + + kVersion5_0ParamsTotalLen); } else { STREAM_TO_BDADDR(bqr_link_quality_event_.bdaddr, p_param_buf); STREAM_TO_UINT8(bqr_link_quality_event_.cal_failed_item_count, @@ -109,16 +108,12 @@ void BqrVseSubEvt::ParseBqrLinkQualityEvt(uint8_t length, if (vendor_cap_supported_version >= kBqrIsoVersion) { if (length < kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen) { - LOG(WARNING) << __func__ - << ": Parameter total length: " << std::to_string(length) - << " is abnormal. " - << "vendor_cap_supported_version: " - << vendor_cap_supported_version << " " - << " (>= " - << "kBqrIsoVersion=" << kBqrIsoVersion << "), " - << "It should not be shorter than: " - << std::to_string(kLinkQualityParamTotalLen + - kISOLinkQualityParamTotalLen); + log::warn( + "Parameter total length: {} is abnormal. " + "vendor_cap_supported_version: {} (>= kBqrIsoVersion={}), It should " + "not be shorter than: {}", + length, vendor_cap_supported_version, kBqrIsoVersion, + kLinkQualityParamTotalLen + kISOLinkQualityParamTotalLen); } else { STREAM_TO_UINT32(bqr_link_quality_event_.tx_total_packets, p_param_buf); STREAM_TO_UINT32(bqr_link_quality_event_.tx_unacked_packets, p_param_buf); @@ -311,7 +306,7 @@ std::string PacketTypeToString(uint8_t packet_type) { } void EnableBtQualityReport(bool is_enable) { - LOG(INFO) << __func__ << ": is_enable: " << logbool(is_enable); + log::info("is_enable: {}", logbool(is_enable)); char bqr_prop_evtmask[PROPERTY_VALUE_MAX] = {0}; char bqr_prop_interval_ms[PROPERTY_VALUE_MAX] = {0}; @@ -323,9 +318,10 @@ void EnableBtQualityReport(bool is_enable) { osi_property_get(kpPropertyVndTraceMask, bqr_prop_vnd_trace_mask, ""); if (strlen(bqr_prop_evtmask) == 0 || strlen(bqr_prop_interval_ms) == 0) { - LOG(WARNING) << __func__ << ": Bluetooth Quality Report is disabled." - << " bqr_prop_evtmask: " << bqr_prop_evtmask - << ", bqr_prop_interval_ms: " << bqr_prop_interval_ms; + log::warn( + "Bluetooth Quality Report is disabled. bqr_prop_evtmask: {}, " + "bqr_prop_interval_ms: {}", + bqr_prop_evtmask, bqr_prop_interval_ms); return; } @@ -353,11 +349,10 @@ void EnableBtQualityReport(bool is_enable) { BTM_BleGetVendorCapabilities(&cmn_vsc_cb); vendor_cap_supported_version = cmn_vsc_cb.version_supported; - LOG(INFO) << __func__ - << ": Event Mask: " << loghex(bqr_config.quality_event_mask) - << ", Interval: " << bqr_config.minimum_report_interval_ms - << ", vendor_cap_supported_version: " - << vendor_cap_supported_version; + log::info("Event Mask: {}, Interval: {}, vendor_cap_supported_version: {}", + loghex(bqr_config.quality_event_mask), + bqr_config.minimum_report_interval_ms, + vendor_cap_supported_version); ConfigureBqr(bqr_config); } @@ -365,17 +360,16 @@ void ConfigureBqr(const BqrConfiguration& bqr_config) { if (bqr_config.report_action > REPORT_ACTION_CLEAR || bqr_config.quality_event_mask > kQualityEventMaskAll || bqr_config.minimum_report_interval_ms > kMinReportIntervalMaxMs) { - LOG(FATAL) << __func__ << ": Invalid Parameter" - << ", Action: " << bqr_config.report_action - << ", Mask: " << loghex(bqr_config.quality_event_mask) - << ", Interval: " << bqr_config.minimum_report_interval_ms; + log::fatal("Invalid Parameter, Action: {}, Mask: {}, Interval: {}", + bqr_config.report_action, loghex(bqr_config.quality_event_mask), + bqr_config.minimum_report_interval_ms); return; } - LOG(INFO) << __func__ << ": Action: " - << loghex(static_cast(bqr_config.report_action)) - << ", Mask: " << loghex(bqr_config.quality_event_mask) - << ", Interval: " << bqr_config.minimum_report_interval_ms; + log::info("Action: {}, Mask: {}, Interval: {}", + loghex(static_cast(bqr_config.report_action)), + loghex(bqr_config.quality_event_mask), + bqr_config.minimum_report_interval_ms); uint8_t param[sizeof(BqrConfiguration)]; uint8_t* p_param = param; @@ -393,8 +387,7 @@ void ConfigureBqr(const BqrConfiguration& bqr_config) { void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) { if (p_vsc_cmpl_params->param_len < 1) { - LOG(ERROR) << __func__ - << ": The length of returned parameters is less than 1"; + log::error("The length of returned parameters is less than 1"); return; } @@ -410,8 +403,7 @@ void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) { // Vendor_Specific_Trace_Mask | 4 octets | vendor trace bit mask setting STREAM_TO_UINT8(status, p_event_param_buf); if (status != HCI_SUCCESS) { - LOG(ERROR) << __func__ - << ": Fail to configure BQR. status: " << loghex(status); + log::error("Fail to configure BQR. status: {}", loghex(status)); return; } @@ -420,9 +412,8 @@ void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) { } if (p_vsc_cmpl_params->param_len != command_complete_param_len) { - LOG(FATAL) << __func__ - << ": The length of returned parameters is incorrect: " - << std::to_string(p_vsc_cmpl_params->param_len); + log::fatal("The length of returned parameters is incorrect: {}", + p_vsc_cmpl_params->param_len); return; } @@ -434,10 +425,9 @@ void BqrVscCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) { STREAM_TO_UINT32(current_vnd_trace_mask, p_event_param_buf); } - LOG(INFO) << __func__ - << ", current event mask: " << loghex(current_quality_event_mask) - << ", vendor quality: " << loghex(current_vnd_quality_mask) - << ", vendor trace: " << loghex(current_vnd_trace_mask); + log::info("current event mask: {}, vendor quality: {}, vendor trace: {}", + loghex(current_quality_event_mask), + loghex(current_vnd_quality_mask), loghex(current_vnd_trace_mask)); ConfigureBqrCmpl(current_quality_event_mask); } @@ -455,8 +445,8 @@ void ConfigBqrA2dpScoThreshold() { sscanf(bqr_prop_threshold, "%hu,%hu", &a2dp_choppy_threshold, &sco_choppy_threshold); - LOG_WARN("a2dp_choppy_threshold: %d, sco_choppy_threshold: %d", - a2dp_choppy_threshold, sco_choppy_threshold); + log::warn("a2dp_choppy_threshold: {}, sco_choppy_threshold: {}", + a2dp_choppy_threshold, sco_choppy_threshold); UINT8_TO_STREAM(p_param, sub_opcode); @@ -481,7 +471,7 @@ void ConfigBqrA2dpScoThreshold() { } void ConfigureBqrCmpl(uint32_t current_evt_mask) { - LOG(INFO) << __func__ << ": current_evt_mask: " << loghex(current_evt_mask); + log::info("current_evt_mask: {}", loghex(current_evt_mask)); // (Un)Register for VSE of Bluetooth Quality Report sub event tBTM_STATUS btm_status = BTM_BT_Quality_Report_VSE_Register( current_evt_mask > kQualityEventMaskAllOff, CategorizeBqrEvent); @@ -493,20 +483,20 @@ void ConfigureBqrCmpl(uint32_t current_evt_mask) { } if (btm_status != BTM_SUCCESS) { - LOG(ERROR) << __func__ << ": Fail to (un)register VSE of BQR sub event." - << " status: " << btm_status; + log::error("Fail to (un)register VSE of BQR sub event. status: {}", + btm_status); return; } if (LmpLlMessageTraceLogFd != INVALID_FD && (current_evt_mask & kQualityEventMaskLmpMessageTrace) == 0) { - LOG(INFO) << __func__ << ": Closing LMP/LL log file."; + log::info("Closing LMP/LL log file."); close(LmpLlMessageTraceLogFd); LmpLlMessageTraceLogFd = INVALID_FD; } if (BtSchedulingTraceLogFd != INVALID_FD && (current_evt_mask & kQualityEventMaskBtSchedulingTrace) == 0) { - LOG(INFO) << __func__ << ": Closing Scheduling log file."; + log::info("Closing Scheduling log file."); close(BtSchedulingTraceLogFd); BtSchedulingTraceLogFd = INVALID_FD; } @@ -514,7 +504,7 @@ void ConfigureBqrCmpl(uint32_t current_evt_mask) { void CategorizeBqrEvent(uint8_t length, const uint8_t* p_bqr_event) { if (length == 0) { - LOG(WARNING) << __func__ << ": Lengths of all of the parameters are zero."; + log::warn("Lengths of all of the parameters are zero."); return; } @@ -527,10 +517,10 @@ void CategorizeBqrEvent(uint8_t length, const uint8_t* p_bqr_event) { case QUALITY_REPORT_ID_LE_AUDIO_CHOPPY: case QUALITY_REPORT_ID_CONNECT_FAIL: if (length < kLinkQualityParamTotalLen) { - LOG(FATAL) << __func__ - << ": Parameter total length: " << std::to_string(length) - << " is abnormal. It shall be not shorter than: " - << std::to_string(kLinkQualityParamTotalLen); + log::fatal( + "Parameter total length: {} is abnormal. It shall be not shorter " + "than: {}", + length, kLinkQualityParamTotalLen); return; } @@ -545,12 +535,11 @@ void CategorizeBqrEvent(uint8_t length, const uint8_t* p_bqr_event) { case QUALITY_REPORT_ID_BT_SCHEDULING_TRACE: case QUALITY_REPORT_ID_CONTROLLER_DBG_INFO: case QUALITY_REPORT_ID_VENDOR_SPECIFIC_TRACE: - LOG(WARNING) << __func__ - << ": Unexpected ID: " << loghex(quality_report_id); + log::warn("Unexpected ID: {}", loghex(quality_report_id)); break; default: - LOG(WARNING) << __func__ << ": Unknown ID: " << loghex(quality_report_id); + log::warn("Unknown ID: {}", loghex(quality_report_id)); break; } } @@ -562,7 +551,7 @@ void AddLinkQualityEventToQueue(uint8_t length, p_bqr_event->ParseBqrLinkQualityEvt(length, p_link_quality_event); - LOG(WARNING) << *p_bqr_event; + log::warn("{}", *p_bqr_event); GetInterfaceToProfiles()->events->invoke_link_quality_report_cb( bluetooth::common::time_get_os_boottime_ms(), p_bqr_event->bqr_link_quality_event_.quality_report_id, @@ -595,8 +584,7 @@ void AddLinkQualityEventToQueue(uint8_t length, p_bqr_event->bqr_link_quality_event_.buffer_overflow_bytes, p_bqr_event->bqr_link_quality_event_.buffer_underflow_bytes); if (ret < 0) { - LOG(WARNING) << __func__ << ": failed to log BQR event to statsd, error " - << ret; + log::warn("failed to log BQR event to statsd, error {}", ret); } #else // TODO(abps) Metrics for non-Android build @@ -621,11 +609,10 @@ void AddLinkQualityEventToQueue(uint8_t length, bqrItf->bqr_delivery_event(bd_addr, (uint8_t*)p_link_quality_event, length); } else { - LOG(WARNING) << __func__ << ": failed to deliver BQR, " - << "bdaddr is empty"; + log::warn("failed to deliver BQR, bdaddr is empty"); } } else { - LOG(WARNING) << __func__ << ": failed to deliver BQR, bqrItf is NULL"; + log::warn("failed to deliver BQR, bqrItf is NULL"); } } @@ -648,9 +635,8 @@ void DumpLmpLlMessage(uint8_t length, const uint8_t* p_lmp_ll_message_event) { int OpenLmpLlTraceLogFile() { if (rename(kpLmpLlMessageTraceLogPath, kpLmpLlMessageTraceLastLogPath) != 0 && errno != ENOENT) { - LOG(ERROR) << __func__ << ": Unable to rename '" - << kpLmpLlMessageTraceLogPath << "' to '" - << kpLmpLlMessageTraceLastLogPath << "' : " << strerror(errno); + log::error("Unable to rename '{}' to '{}' : {}", kpLmpLlMessageTraceLogPath, + kpLmpLlMessageTraceLastLogPath, strerror(errno)); } mode_t prevmask = umask(0); @@ -659,8 +645,8 @@ int OpenLmpLlTraceLogFile() { S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); umask(prevmask); if (logfile_fd == INVALID_FD) { - LOG(ERROR) << __func__ << ": Unable to open '" << kpLmpLlMessageTraceLogPath - << "' : " << strerror(errno); + log::error("Unable to open '{}' : {}", kpLmpLlMessageTraceLogPath, + strerror(errno)); } else { LmpLlMessageTraceCounter = 0; } @@ -683,9 +669,8 @@ void DumpBtScheduling(uint8_t length, const uint8_t* p_bt_scheduling_event) { int OpenBtSchedulingTraceLogFile() { if (rename(kpBtSchedulingTraceLogPath, kpBtSchedulingTraceLastLogPath) != 0 && errno != ENOENT) { - LOG(ERROR) << __func__ << ": Unable to rename '" - << kpBtSchedulingTraceLogPath << "' to '" - << kpBtSchedulingTraceLastLogPath << "' : " << strerror(errno); + log::error("Unable to rename '{}' to '{}' : {}", kpBtSchedulingTraceLogPath, + kpBtSchedulingTraceLastLogPath, strerror(errno)); } mode_t prevmask = umask(0); @@ -694,8 +679,8 @@ int OpenBtSchedulingTraceLogFile() { S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); umask(prevmask); if (logfile_fd == INVALID_FD) { - LOG(ERROR) << __func__ << ": Unable to open '" << kpBtSchedulingTraceLogPath - << "' : " << strerror(errno); + log::error("Unable to open '{}' : {}", kpBtSchedulingTraceLogPath, + strerror(errno)); } else { BtSchedulingTraceCounter = 0; } @@ -765,7 +750,7 @@ class BluetoothQualityReportInterfaceImpl ~BluetoothQualityReportInterfaceImpl() override = default; void init(BluetoothQualityReportCallbacks* callbacks) override { - LOG_INFO("BluetoothQualityReportInterfaceImpl "); + log::info("BluetoothQualityReportInterfaceImpl"); this->callbacks = callbacks; } @@ -773,7 +758,7 @@ class BluetoothQualityReportInterfaceImpl const uint8_t* bqr_raw_data, uint32_t bqr_raw_data_len) override { if (bqr_raw_data == NULL) { - LOG_ERROR("bqr data is null"); + log::error("bqr data is null"); return; } @@ -798,13 +783,13 @@ class BluetoothQualityReportInterfaceImpl uint16_t manufacturer_id = 0; btif_get_remote_version(bd_addr, lmp_ver, manufacturer_id, lmp_subver); - LOG_INFO( - "len: %d, addr: %s, lmp_ver: %d, manufacturer_id: %d, lmp_subver: %d", + log::info( + "len: {}, addr: {}, lmp_ver: {}, manufacturer_id: {}, lmp_subver: {}", bqr_raw_data_len, ADDRESS_TO_LOGGABLE_CSTR(bd_addr), lmp_ver, manufacturer_id, lmp_subver); if (callbacks == nullptr) { - LOG_ERROR("callbacks is nullptr"); + log::error("callbacks is nullptr"); return; } diff --git a/system/btif/src/btif_config.cc b/system/btif/src/btif_config.cc index 4958023573c5eb8a25c753ef802c4263a2ff5019..b3ea4a63960dc7879e882db9b8649a621c4eaffa 100644 --- a/system/btif/src/btif_config.cc +++ b/system/btif/src/btif_config.cc @@ -21,38 +21,28 @@ #include "btif_config.h" #include +#include #include #include -#include #include #include #include -#include #include -#include #include #include -#include "btcore/include/module.h" -#include "btif_api.h" -#include "btif_common.h" #include "btif_config_cache.h" #include "btif_keystore.h" #include "btif_metrics_logging.h" #include "common/address_obfuscator.h" #include "common/metric_id_allocator.h" +#include "include/check.h" #include "main/shim/config.h" #include "main/shim/shim.h" -#include "osi/include/alarm.h" -#include "osi/include/allocator.h" -#include "osi/include/compat.h" -#include "osi/include/config.h" -#include "osi/include/log.h" -#include "osi/include/osi.h" -#include "osi/include/properties.h" +#include "os/log.h" #include "raw_address.h" -#include "stack/include/bt_octets.h" +#include "storage/config_keys.h" #define TEMPORARY_SECTION_CAPACITY 10000 @@ -62,13 +52,10 @@ #define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS") #define DISABLED "disabled" -#define BT_CONFIG_METRICS_SECTION "Metrics" -#define BT_CONFIG_METRICS_SALT_256BIT "Salt256Bit" -#define BT_CONFIG_METRICS_ID_KEY "MetricsId" - using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface; using bluetooth::common::AddressObfuscator; using bluetooth::common::MetricIdAllocator; +using namespace bluetooth; // Key attestation static const std::string ENCRYPTED_STR = "encrypted"; @@ -96,28 +83,28 @@ static char btif_config_time_created[TIME_STRING_LENGTH]; static void read_or_set_metrics_salt() { AddressObfuscator::Octet32 metrics_salt = {}; size_t metrics_salt_length = metrics_salt.size(); - if (!btif_config_get_bin(BT_CONFIG_METRICS_SECTION, - BT_CONFIG_METRICS_SALT_256BIT, metrics_salt.data(), - &metrics_salt_length)) { - LOG(WARNING) << __func__ << ": Failed to read metrics salt from config"; + if (!btif_config_get_bin(BTIF_STORAGE_SECTION_METRICS, + BTIF_STORAGE_KEY_METRICS_SALT_256BIT, + metrics_salt.data(), &metrics_salt_length)) { + log::warn("Failed to read metrics salt from config"); // Invalidate salt metrics_salt.fill(0); } if (metrics_salt_length != metrics_salt.size()) { - LOG(ERROR) << __func__ << ": Metrics salt length incorrect, " - << metrics_salt_length << " instead of " << metrics_salt.size(); + log::error("Metrics salt length incorrect, {} instead of {}", + metrics_salt_length, metrics_salt.size()); // Invalidate salt metrics_salt.fill(0); } if (!AddressObfuscator::IsSaltValid(metrics_salt)) { - LOG(INFO) << __func__ << ": Metrics salt is invalid, creating new one"; + log::info("Metrics salt is invalid, creating new one"); if (RAND_bytes(metrics_salt.data(), metrics_salt.size()) != 1) { - LOG(FATAL) << __func__ << "Failed to generate salt for metrics"; + log::fatal("Failed to generate salt for metrics"); } - if (!btif_config_set_bin(BT_CONFIG_METRICS_SECTION, - BT_CONFIG_METRICS_SALT_256BIT, metrics_salt.data(), - metrics_salt.size())) { - LOG(FATAL) << __func__ << "Failed to write metrics salt to config"; + if (!btif_config_set_bin(BTIF_STORAGE_SECTION_METRICS, + BTIF_STORAGE_KEY_METRICS_SALT_256BIT, + metrics_salt.data(), metrics_salt.size())) { + log::fatal("Failed to write metrics salt to config"); } } AddressObfuscator::GetInstance()->Initialize(metrics_salt); @@ -139,10 +126,10 @@ static void init_metric_id_allocator() { auto addr_str = mac_address.ToString(); // if the section name is a mac address bool is_valid_id_found = false; - if (btif_config_exist(addr_str, BT_CONFIG_METRICS_ID_KEY)) { + if (btif_config_exist(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY)) { // there is one metric id under this mac_address int id = 0; - btif_config_get_int(addr_str, BT_CONFIG_METRICS_ID_KEY, &id); + btif_config_get_int(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY, &id); if (is_valid_id_from_metric_id_allocator(id)) { paired_device_map[mac_address] = id; is_valid_id_found = true; @@ -156,17 +143,18 @@ static void init_metric_id_allocator() { // Initialize MetricIdAllocator MetricIdAllocator::Callback save_device_callback = [](const RawAddress& address, const int id) { - return btif_config_set_int(address.ToString(), BT_CONFIG_METRICS_ID_KEY, - id); + return btif_config_set_int(address.ToString(), + BTIF_STORAGE_KEY_METRICS_ID_KEY, id); }; MetricIdAllocator::Callback forget_device_callback = [](const RawAddress& address, const int id) { - return btif_config_remove(address.ToString(), BT_CONFIG_METRICS_ID_KEY); + return btif_config_remove(address.ToString(), + BTIF_STORAGE_KEY_METRICS_ID_KEY); }; if (!init_metric_id_allocator(paired_device_map, std::move(save_device_callback), std::move(forget_device_callback))) { - LOG(FATAL) << __func__ << "Failed to initialize MetricIdAllocator"; + log::fatal("Failed to initialize MetricIdAllocator"); } // Add device_without_id @@ -215,10 +203,11 @@ bool btif_get_device_clockoffset(const RawAddress& bda, int* p_clock_offset) { std::string addrstr = bda.ToString(); const char* bd_addr_str = addrstr.c_str(); - if (!btif_config_get_int(bd_addr_str, "ClockOffset", p_clock_offset)) return false; + if (!btif_config_get_int(bd_addr_str, BTIF_STORAGE_KEY_CLOCK_OFFSET, + p_clock_offset)) + return false; - LOG_DEBUG("%s: Device [%s] clock_offset %d", __func__, bd_addr_str, - *p_clock_offset); + log::debug("Device [{}] clock_offset {}", bd_addr_str, *p_clock_offset); return true; } @@ -227,10 +216,11 @@ bool btif_set_device_clockoffset(const RawAddress& bda, int clock_offset) { std::string addrstr = bda.ToString(); const char* bd_addr_str = addrstr.c_str(); - if (!btif_config_set_int(bd_addr_str, "ClockOffset", clock_offset)) return false; + if (!btif_config_set_int(bd_addr_str, BTIF_STORAGE_KEY_CLOCK_OFFSET, + clock_offset)) + return false; - LOG_DEBUG("%s: Device [%s] clock_offset %d", __func__, bd_addr_str, - clock_offset); + log::debug("Device [{}] clock_offset {}", bd_addr_str, clock_offset); return true; } diff --git a/system/btif/src/btif_config_cache.cc b/system/btif/src/btif_config_cache.cc index 160ede4a977831537fc5b4dc598b519ad60496ac..05b1beca39315b2f9cc3cca52258c6860dc6c18e 100644 --- a/system/btif/src/btif_config_cache.cc +++ b/system/btif/src/btif_config_cache.cc @@ -16,22 +16,28 @@ #include "btif_config_cache.h" +#include +#include + #include +#include #include -#include "stack/include/bt_octets.h" +#include "storage/config_keys.h" #include "types/raw_address.h" -#include +using namespace bluetooth; namespace { const std::unordered_set kLinkKeyTypes = { - "LinkKey", "LE_KEY_PENC", "LE_KEY_PID", - "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK"}; + BTIF_STORAGE_KEY_LINK_KEY, BTIF_STORAGE_KEY_LE_KEY_PENC, + BTIF_STORAGE_KEY_LE_KEY_PID, BTIF_STORAGE_KEY_LE_KEY_PCSRK, + BTIF_STORAGE_KEY_LE_KEY_LENC, BTIF_STORAGE_KEY_LE_KEY_LCSRK}; -const std::unordered_set kLocalSectionNames = {"Info", "Metrics", - "Adapter"}; +const std::unordered_set kLocalSectionNames = { + BTIF_STORAGE_SECTION_INFO, BTIF_STORAGE_SECTION_METRICS, + BTIF_STORAGE_SECTION_ADAPTER}; bool is_link_key(const std::string& key) { return kLinkKeyTypes.find(key) != kLinkKeyTypes.end(); @@ -64,7 +70,7 @@ bool trim_new_line(std::string& value) { BtifConfigCache::BtifConfigCache(size_t capacity) : unpaired_devices_cache_(capacity, "bt_config_cache") { - LOG(INFO) << __func__ << ", capacity: " << capacity; + log::info("capacity: {}", capacity); } BtifConfigCache::~BtifConfigCache() { Clear(); } @@ -175,11 +181,11 @@ void BtifConfigCache::SetString(std::string section_name, std::string key, trim_new_line(key); trim_new_line(value); if (section_name.empty()) { - LOG(FATAL) << "Empty section not allowed"; + log::fatal("Empty section not allowed"); return; } if (key.empty()) { - LOG(FATAL) << "Empty key not allowed"; + log::fatal("Empty key not allowed"); return; } if (!paired_devices_list_.Has(section_name)) { @@ -211,7 +217,7 @@ void BtifConfigCache::SetString(std::string section_name, std::string key, // already have section in paired device list, add key-value entry. auto section_found = paired_devices_list_.Find(section_name); if (section_found == paired_devices_list_.sections.end()) { - LOG(WARNING) << __func__ << " , section_found not found!"; + log::warn("section_found not found!"); return; } section_found->Set(key, value); @@ -255,13 +261,14 @@ std::optional BtifConfigCache::GetInt(const std::string& section_name, char* endptr; long ret_long = strtol(value->c_str(), &endptr, 0); if (*endptr != '\0') { - LOG(WARNING) << "Failed to parse value to long for section " << section_name - << ", key " << key; + log::warn("Failed to parse value to long for section {}, key {}", + section_name, key); return std::nullopt; } if (ret_long >= std::numeric_limits::max()) { - LOG(WARNING) << "Integer overflow when parsing value to int for section " - << section_name << ", key " << key; + log::warn( + "Integer overflow when parsing value to int for section {}, key {}", + section_name, key); return std::nullopt; } return static_cast(ret_long); @@ -281,8 +288,8 @@ std::optional BtifConfigCache::GetUint64( char* endptr; uint64_t ret = strtoull(value->c_str(), &endptr, 0); if (*endptr != '\0') { - LOG(WARNING) << "Failed to parse value to uint64 for section " - << section_name << ", key " << key; + log::warn("Failed to parse value to uint64 for section {}, key {}", + section_name, key); return std::nullopt; } return ret; @@ -305,7 +312,7 @@ std::optional BtifConfigCache::GetBool(const std::string& section_name, if (*value == "false") { return false; } - LOG(WARNING) << "Failed to parse value to boolean for section " - << section_name << ", key " << key; + log::warn("Failed to parse value to boolean for section {}, key {}", + section_name, key); return std::nullopt; } diff --git a/system/btif/src/btif_core.cc b/system/btif/src/btif_core.cc index 33e278c084443b15a50851fda704af635f1dffc2..56ffd20f1ec161dd3d118d32d3ba82d945bf3d99 100644 --- a/system/btif/src/btif_core.cc +++ b/system/btif/src/btif_core.cc @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -45,11 +46,14 @@ #include "btif/include/btif_sock.h" #include "btif/include/btif_storage.h" #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "common/message_loop_thread.h" #include "device/include/controller.h" #include "device/include/device_iot_config.h" +#include "hci/controller_interface.h" #include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" +#include "main/shim/entry.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/future.h" @@ -58,12 +62,14 @@ #include "stack/include/bt_types.h" #include "stack/include/btm_api.h" #include "stack/include/btm_ble_api.h" +#include "storage/config_keys.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" using base::PlatformThread; using bluetooth::Uuid; using bluetooth::common::MessageLoopThread; +using namespace bluetooth; /******************************************************************************* * Constants & Macros @@ -107,9 +113,7 @@ static uid_set_t* uid_set; * Externs ******************************************************************************/ void btif_dm_enable_service(tBTA_SERVICE_ID service_id, bool enable); -#ifdef BTIF_DM_OOB_TEST void btif_dm_load_local_oob(void); -#endif /******************************************************************************* * @@ -152,11 +156,11 @@ void btif_init_ok() { * ******************************************************************************/ bt_status_t btif_init_bluetooth() { - LOG_INFO("%s entered", __func__); + log::info("entered"); exit_manager = new base::AtExitManager(); jni_thread_startup(); GetInterfaceToProfiles()->events->invoke_thread_evt_cb(ASSOCIATE_JVM); - LOG_INFO("%s finished", __func__); + log::info("finished"); return BT_STATUS_SUCCESS; } @@ -183,13 +187,15 @@ void btif_enable_bluetooth_evt() { char val[PROPERTY_VALUE_MAX] = ""; int val_size = PROPERTY_VALUE_MAX; - if (!btif_config_get_str("Adapter", "Address", val, &val_size) || + if (!btif_config_get_str(BTIF_STORAGE_SECTION_ADAPTER, + BTIF_STORAGE_KEY_ADDRESS, val, &val_size) || strcmp(bdstr.c_str(), val) != 0) { // We failed to get an address or the one in the config file does not match // the address given by the controller interface. Update the config cache - LOG_INFO("%s: Storing '%s' into the config file", __func__, - ADDRESS_TO_LOGGABLE_CSTR(local_bd_addr)); - btif_config_set_str("Adapter", "Address", bdstr.c_str()); + log::info("Storing '{}' into the config file", + ADDRESS_TO_LOGGABLE_CSTR(local_bd_addr)); + btif_config_set_str(BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_ADDRESS, + bdstr.c_str()); // fire HAL callback for property change bt_property_t prop; @@ -213,12 +219,10 @@ void btif_enable_bluetooth_evt() { /* load did configuration */ bte_load_did_conf(BTE_DID_CONF_FILE); -#ifdef BTIF_DM_OOB_TEST btif_dm_load_local_oob(); -#endif future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); - LOG_INFO("Bluetooth enable event completed"); + log::info("Bluetooth enable event completed"); } /******************************************************************************* @@ -232,7 +236,7 @@ void btif_enable_bluetooth_evt() { ******************************************************************************/ bt_status_t btif_cleanup_bluetooth() { - LOG_INFO("%s entered", __func__); + log::info("entered"); btif_dm_cleanup(); GetInterfaceToProfiles()->events->invoke_thread_evt_cb(DISASSOCIATE_JVM); btif_queue_release(); @@ -240,24 +244,10 @@ bt_status_t btif_cleanup_bluetooth() { delete exit_manager; exit_manager = nullptr; btif_dut_mode = 0; - LOG_INFO("%s finished", __func__); + log::info("finished"); return BT_STATUS_SUCCESS; } -/******************************************************************************* - * - * Function btif_dut_mode_cback - * - * Description Callback invoked on completion of vendor specific test mode - * command - * - * Returns None - * - ******************************************************************************/ -static void btif_dut_mode_cback(UNUSED_ATTR tBTM_VSC_CMPL* p) { - /* For now nothing to be done. */ -} - /******************************************************************************* * * Function btif_dut_mode_configure @@ -267,7 +257,7 @@ static void btif_dut_mode_cback(UNUSED_ATTR tBTM_VSC_CMPL* p) { * ******************************************************************************/ void btif_dut_mode_configure(uint8_t enable) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_dut_mode = enable; if (enable == 1) { @@ -286,8 +276,9 @@ void btif_dut_mode_configure(uint8_t enable) { * ******************************************************************************/ void btif_dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len) { - LOG_VERBOSE("%s", __func__); - BTM_VendorSpecificCommand(opcode, len, buf, btif_dut_mode_cback); + log::verbose(""); + /* For now nothing to be done. */ + BTM_VendorSpecificCommand(opcode, len, buf, [](tBTM_VSC_CMPL*) {}); } /***************************************************************************** @@ -412,7 +403,8 @@ static bt_status_t btif_in_get_remote_device_properties(RawAddress* bd_addr) { } static void btif_core_storage_adapter_write(bt_property_t* prop) { - LOG_VERBOSE("type: %d, len %d, 0x%p", prop->type, prop->len, prop->val); + log::verbose("type: {}, len {}, {}", prop->type, prop->len, + fmt::ptr(prop->val)); bt_status_t status = btif_storage_set_adapter_property(prop); GetInterfaceToProfiles()->events->invoke_adapter_properties_cb(status, 1, prop); @@ -438,7 +430,7 @@ void btif_remote_properties_evt(bt_status_t status, RawAddress* remote_addr, ******************************************************************************/ void btif_get_adapter_properties(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_in_get_adapter_properties(); } @@ -452,7 +444,7 @@ void btif_get_adapter_properties(void) { ******************************************************************************/ void btif_get_adapter_property(bt_property_type_t type) { - LOG_VERBOSE("%s %d", __func__, type); + log::verbose("{}", type); bt_status_t status = BT_STATUS_SUCCESS; char buf[512]; @@ -491,17 +483,17 @@ void btif_get_adapter_property(bt_property_type_t type) { cmn_vsc_cb.debug_logging_supported > 0; const controller_t* controller = controller_get_interface(); - if (controller->supports_ble_extended_advertising()) { + if (controller->SupportsBleExtendedAdvertising()) { local_le_features.max_adv_instance = controller->get_ble_number_of_supported_advertising_sets(); } - local_le_features.le_2m_phy_supported = controller->supports_ble_2m_phy(); + local_le_features.le_2m_phy_supported = controller->SupportsBle2mPhy(); local_le_features.le_coded_phy_supported = - controller->supports_ble_coded_phy(); + controller->SupportsBleCodedPhy(); local_le_features.le_extended_advertising_supported = - controller->supports_ble_extended_advertising(); + controller->SupportsBleExtendedAdvertising(); local_le_features.le_periodic_advertising_supported = - controller->supports_ble_periodic_advertising(); + controller->SupportsBlePeriodicAdvertising(); local_le_features.le_maximum_advertising_data_length = controller->get_ble_maximum_advertising_data_length(); @@ -509,14 +501,14 @@ void btif_get_adapter_property(bt_property_type_t type) { cmn_vsc_cb.dynamic_audio_buffer_support; local_le_features.le_periodic_advertising_sync_transfer_sender_supported = - controller->supports_ble_periodic_advertising_sync_transfer_sender(); + controller->SupportsBlePeriodicAdvertisingSyncTransferSender(); local_le_features.le_connected_isochronous_stream_central_supported = - controller->supports_ble_connected_isochronous_stream_central(); + controller->SupportsBleConnectedIsochronousStreamCentral(); local_le_features.le_isochronous_broadcast_supported = - controller->supports_ble_isochronous_broadcaster(); + controller->SupportsBleIsochronousBroadcaster(); local_le_features .le_periodic_advertising_sync_transfer_recipient_supported = - controller->supports_ble_periodic_advertising_sync_transfer_recipient(); + controller->SupportsBlePeriodicAdvertisingSyncTransferRecipient(); local_le_features.adv_filter_extended_features_mask = cmn_vsc_cb.adv_filter_extended_features_mask; @@ -529,7 +521,7 @@ void btif_get_adapter_property(bt_property_type_t type) { prop.len = sizeof(bt_dynamic_audio_buffer_item_t); if (GetInterfaceToProfiles()->config->isA2DPOffloadEnabled() == false) { - LOG_VERBOSE("%s Get buffer millis for A2DP software encoding", __func__); + log::verbose("Get buffer millis for A2DP software encoding"); for (int i = 0; i < CODEC_TYPE_NUMBER; i++) { dynamic_audio_buffer_item.dab_item[i] = { .default_buffer_time = DEFAULT_BUFFER_TIME, @@ -539,7 +531,7 @@ void btif_get_adapter_property(bt_property_type_t type) { memcpy(prop.val, &dynamic_audio_buffer_item, prop.len); } else { if (cmn_vsc_cb.dynamic_audio_buffer_support != 0) { - LOG_VERBOSE("%s Get buffer millis for A2DP Offload", __func__); + log::verbose("Get buffer millis for A2DP Offload"); tBTM_BT_DYNAMIC_AUDIO_BUFFER_CB bt_dynamic_audio_buffer_cb[CODEC_TYPE_NUMBER]; BTM_BleGetDynamicAudioBuffer(bt_dynamic_audio_buffer_cb); @@ -555,7 +547,7 @@ void btif_get_adapter_property(bt_property_type_t type) { } memcpy(prop.val, &dynamic_audio_buffer_item, prop.len); } else { - LOG_VERBOSE("%s Don't support Dynamic Audio Buffer", __func__); + log::verbose("Don't support Dynamic Audio Buffer"); } } } else { @@ -587,8 +579,8 @@ bt_property_t* property_deep_copy(const bt_property_t* prop) { ******************************************************************************/ void btif_set_adapter_property(bt_property_t* property) { - LOG_VERBOSE("btif_set_adapter_property type: %d, len %d, 0x%p", - property->type, property->len, property->val); + log::verbose("btif_set_adapter_property type: {}, len {}, {}", property->type, + property->len, fmt::ptr(property->val)); switch (property->type) { case BT_PROPERTY_BDNAME: { @@ -599,7 +591,7 @@ void btif_set_adapter_property(bt_property_t* property) { memcpy(bd_name, property->val, name_len); bd_name[name_len] = '\0'; - LOG_VERBOSE("set property name : %s", (char*)bd_name); + log::verbose("set property name : {}", (char*)bd_name); BTA_DmSetDeviceName((const char*)bd_name); @@ -608,7 +600,7 @@ void btif_set_adapter_property(bt_property_t* property) { case BT_PROPERTY_ADAPTER_SCAN_MODE: { bt_scan_mode_t mode = *(bt_scan_mode_t*)property->val; - LOG_VERBOSE("set property scan mode : %x", mode); + log::verbose("set property scan mode : {:x}", mode); if (BTA_DmSetVisibility(mode)) { btif_core_storage_adapter_write(property); @@ -703,7 +695,7 @@ tBTA_SERVICE_MASK btif_get_enabled_services_mask(void) { void btif_enable_service(tBTA_SERVICE_ID service_id) { btif_enabled_services |= (1 << service_id); - LOG_VERBOSE("%s: current services:0x%x", __func__, btif_enabled_services); + log::verbose("current services:0x{:x}", btif_enabled_services); if (btif_is_enabled()) { btif_dm_enable_service(service_id, true); @@ -721,82 +713,33 @@ void btif_enable_service(tBTA_SERVICE_ID service_id) { void btif_disable_service(tBTA_SERVICE_ID service_id) { btif_enabled_services &= (tBTA_SERVICE_MASK)(~(1 << service_id)); - LOG_VERBOSE("%s: Current Services:0x%x", __func__, btif_enabled_services); + log::verbose("Current Services:0x{:x}", btif_enabled_services); if (btif_is_enabled()) { btif_dm_enable_service(service_id, false); } } -void DynamicAudiobufferSizeCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) { - LOG(INFO) << __func__; - - if (p_vsc_cmpl_params->param_len < 1) { - LOG(ERROR) << __func__ - << ": The length of returned parameters is less than 1"; - return; - } - uint8_t* p_event_param_buf = p_vsc_cmpl_params->p_param_buf; - uint8_t status = 0xff; - uint8_t opcode = 0xff; - uint16_t respond_buffer_time = 0xffff; - - // [Return Parameter] | [Size] | [Purpose] - // Status | 1 octet | Command complete status - // Dynamic_Audio_Buffer_opcode| 1 octet | 0x02 - Set buffer time - // Audio_Codec_Buffer_Time | 2 octet | Current buffer time - STREAM_TO_UINT8(status, p_event_param_buf); - if (status != HCI_SUCCESS) { - LOG(ERROR) << __func__ - << ": Fail to configure DFTB. status: " << loghex(status); - return; - } - - if (p_vsc_cmpl_params->param_len != 4) { - LOG(FATAL) << __func__ - << ": The length of returned parameters is not equal to 4: " - << std::to_string(p_vsc_cmpl_params->param_len); - return; - } - - STREAM_TO_UINT8(opcode, p_event_param_buf); - LOG(INFO) << __func__ << ": opcode = " << loghex(opcode); - - if (opcode == 0x02) { - STREAM_TO_UINT16(respond_buffer_time, p_event_param_buf); - LOG(INFO) << __func__ - << ": Succeed to configure Media Tx Buffer, used_buffer_time = " - << loghex(respond_buffer_time); - } -} - bt_status_t btif_set_dynamic_audio_buffer_size(int codec, int size) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); tBTM_BLE_VSC_CB cmn_vsc_cb; BTM_BleGetVendorCapabilities(&cmn_vsc_cb); if (!GetInterfaceToProfiles()->config->isA2DPOffloadEnabled()) { - LOG_VERBOSE("%s Set buffer size (%d) for A2DP software encoding", __func__, - size); + log::verbose("Set buffer size ({}) for A2DP software encoding", size); GetInterfaceToProfiles() ->profileSpecific_HACK->btif_av_set_dynamic_audio_buffer_size( uint8_t(size)); } else { if (cmn_vsc_cb.dynamic_audio_buffer_support != 0) { - LOG_VERBOSE("%s Set buffer size (%d) for A2DP offload", __func__, size); + log::verbose("Set buffer size ({}) for A2DP offload", size); uint16_t firmware_tx_buffer_length_byte; - uint8_t param[3] = {0}; - uint8_t* p_param = param; - firmware_tx_buffer_length_byte = static_cast(size); - LOG(INFO) << __func__ << "firmware_tx_buffer_length_byte: " - << firmware_tx_buffer_length_byte; - - UINT8_TO_STREAM(p_param, HCI_CONTROLLER_DAB_SET_BUFFER_TIME); - UINT16_TO_STREAM(p_param, firmware_tx_buffer_length_byte); - BTM_VendorSpecificCommand(HCI_CONTROLLER_DAB, p_param - param, param, - DynamicAudiobufferSizeCompleteCallback); + log::info("firmware_tx_buffer_length_byte: {}", + firmware_tx_buffer_length_byte); + bluetooth::shim::GetController()->SetDabAudioBufferTime( + firmware_tx_buffer_length_byte); } } diff --git a/system/btif/src/btif_csis_client.cc b/system/btif/src/btif_csis_client.cc index 70271286d129da5641a47622111a4468f1d26518..387a8c2d1fcbb8868efc3f4f59610e1bb2a68971 100644 --- a/system/btif/src/btif_csis_client.cc +++ b/system/btif/src/btif_csis_client.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ using bluetooth::csis::CsisClientInterface; using bluetooth::csis::CsisGroupLockStatus; using bluetooth::csis::CsisClient; +using namespace bluetooth; namespace { std::unique_ptr csis_client_instance; @@ -62,9 +64,9 @@ class CsipSetCoordinatorServiceInterfaceImpl : public CsisClientInterface, void Connect(const RawAddress& addr) override { if (!initialized || !CsisClient::IsCsisClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -74,9 +76,9 @@ class CsipSetCoordinatorServiceInterfaceImpl : public CsisClientInterface, void Disconnect(const RawAddress& addr) override { if (!initialized || !CsisClient::IsCsisClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -86,9 +88,9 @@ class CsipSetCoordinatorServiceInterfaceImpl : public CsisClientInterface, void RemoveDevice(const RawAddress& addr) override { if (!initialized || !CsisClient::IsCsisClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not ready"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not ready"); /* Clear storage */ do_in_jni_thread(FROM_HERE, Bind(&btif_storage_remove_csis_device, addr)); @@ -103,9 +105,9 @@ class CsipSetCoordinatorServiceInterfaceImpl : public CsisClientInterface, void LockGroup(int group_id, bool lock) override { if (!initialized || !CsisClient::IsCsisClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -116,9 +118,9 @@ class CsipSetCoordinatorServiceInterfaceImpl : public CsisClientInterface, void Cleanup(void) override { if (!initialized || !CsisClient::IsCsisClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } diff --git a/system/btif/src/btif_debug_conn.cc b/system/btif/src/btif_debug_conn.cc index fa716d28d9b807dae2f6a6e11c20e1bc2136ad4c..fdddb7265a9ca642afad0f13466420abd1c03d3a 100644 --- a/system/btif/src/btif_debug_conn.cc +++ b/system/btif/src/btif_debug_conn.cc @@ -19,10 +19,10 @@ #include "btif/include/btif_debug_conn.h" #include -#include #include #include "common/time_util.h" +#include "os/logging/log_adapter.h" #include "types/raw_address.h" #define NUM_CONNECTION_EVENTS 16 diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 47188844557646da9fc8d6eb2179e1eb38f93fdd..c7f33ae72c0d0a8d496d4ca3b04f8db66a589c99 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -30,9 +30,11 @@ #include "btif_dm.h" +#include #include #include #include +#include #include #include #include @@ -51,9 +53,10 @@ #include #include "advertise_data_parser.h" +#include "bt_dev_class.h" #include "bta/dm/bta_dm_disc.h" #include "bta/include/bta_api.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "btif_api.h" #include "btif_bqr.h" #include "btif_config.h" @@ -62,16 +65,19 @@ #include "btif_profile_storage.h" #include "btif_storage.h" #include "btif_util.h" +#include "common/init_flags.h" +#include "common/lru_cache.h" #include "common/metrics.h" #include "device/include/controller.h" #include "device/include/interop.h" -#include "gd/common/lru_cache.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "internal_include/stack_config.h" #include "main/shim/le_advertising_manager.h" +#include "main_thread.h" #include "os/log.h" +#include "os/logging/log_adapter.h" #include "osi/include/allocator.h" -#include "osi/include/osi.h" #include "osi/include/properties.h" #include "osi/include/stack_power_telemetry.h" #include "stack/btm/btm_dev.h" @@ -81,6 +87,7 @@ #include "stack/include/bt_octets.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" +#include "stack/include/btm_ble_addr.h" #include "stack/include/btm_ble_api.h" #include "stack/include/btm_ble_sec_api.h" #include "stack/include/btm_ble_sec_api_types.h" @@ -90,6 +97,7 @@ #include "stack/include/btm_sec_api_types.h" #include "stack/include/smp_api.h" #include "stack/sdp/sdpint.h" +#include "storage/config_keys.h" #include "types/raw_address.h" #ifdef __ANDROID__ @@ -99,6 +107,7 @@ bool btif_get_device_type(const RawAddress& bda, int* p_device_type); using bluetooth::Uuid; +using namespace bluetooth; namespace { constexpr char kBtmLogTag[] = "API"; @@ -170,6 +179,12 @@ struct btif_dm_pairing_cb_t { ServiceDiscoveryState sdp_over_classic; }; +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt + // TODO(jpawlowski): unify ? // btif_dm_local_key_id_t == tBTM_BLE_LOCAL_ID_KEYS == tBTA_BLE_LOCAL_ID_KEYS typedef struct { @@ -311,7 +326,7 @@ void btif_dm_cleanup(void) { bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id, bool b_enable) { - LOG_VERBOSE("service_id:%d", service_id); + log::verbose("service_id:{}", service_id); if (service_id == BTA_SDP_SERVICE_ID) { btif_sdp_execute_service(b_enable); @@ -352,15 +367,15 @@ static void get_asha_service_data(const tBTA_DM_INQ_RES& inq_res, STREAM_TO_UINT16(uuid, p_uuid); if (uuid == 0xfdf0 /* ASHA service*/) { - LOG_INFO("ASHA found in %s", ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); + log::info("ASHA found in {}", ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); // ASHA advertisement service data length should be at least 8 if (service_data_len < 8) { - LOG_WARN("ASHA device service_data_len too short"); + log::warn("ASHA device service_data_len too short"); } else { // It is intended to save ASHA capability byte to int16_t asha_capability = p_service_data[3]; - LOG_INFO("asha_capability: %d", asha_capability); + log::info("asha_capability: {}", asha_capability); const uint8_t* p_truncated_hisyncid = &(p_service_data[4]); STREAM_TO_UINT32(asha_truncated_hi_sync_id, p_truncated_hisyncid); @@ -488,7 +503,7 @@ static uint32_t get_cod(const RawAddress* remote_bdaddr) { sizeof(uint32_t), &remote_cod); if (btif_storage_get_remote_device_property( (RawAddress*)remote_bdaddr, &prop_name) == BT_STATUS_SUCCESS) { - LOG_INFO("remote_cod=0x%08x", remote_cod); + log::info("remote_cod=0x{:08x}", remote_cod); return remote_cod; } @@ -573,9 +588,9 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, state = BT_BOND_STATE_NONE; } - LOG_INFO( - "Bond state changed to state=%d[0:none, 1:bonding, 2:bonded]," - "prev_state=%d, sdp_attempts=%d", + log::info( + "Bond state changed to state={}[0:none, 1:bonding, " + "2:bonded],prev_state={}, sdp_attempts={}", state, pairing_cb.state, pairing_cb.sdp_attempts); if (state == BT_BOND_STATE_NONE) { @@ -590,8 +605,8 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, } else if (state == BT_BOND_STATE_BONDED) { allocate_metric_id_from_metric_id_allocator(bd_addr); if (!save_metric_id_from_metric_id_allocator(bd_addr)) { - LOG_ERROR("Fail to save metric id for device:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Fail to save metric id for device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } BTM_LogHistory( @@ -606,8 +621,10 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, if ((state == BT_BOND_STATE_NONE) && (pairing_cb.bd_addr != bd_addr) && is_bonding_or_sdp()) { - LOG_WARN("Ignoring bond state changed for unexpected device: %s pairing: %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), ADDRESS_TO_LOGGABLE_CSTR(pairing_cb.bd_addr)); + log::warn( + "Ignoring bond state changed for unexpected device: {} pairing: {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + ADDRESS_TO_LOGGABLE_CSTR(pairing_cb.bd_addr)); return; } @@ -620,7 +637,7 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr, pairing_cb.state = state; pairing_cb.bd_addr = bd_addr; } else { - LOG_DEBUG("clearing btif pairing_cb"); + log::debug("clearing btif pairing_cb"); pairing_cb = {}; } } @@ -640,9 +657,9 @@ static void btif_update_remote_version_property(RawAddress* p_bd) { const bool version_info_valid = BTM_ReadRemoteVersion(*p_bd, &lmp_ver, &mfct_set, &lmp_subver); - LOG_INFO("Remote version info valid:%s [%s]:0x%x,0x%x,0x%x", - logbool(version_info_valid).c_str(), - ADDRESS_TO_LOGGABLE_CSTR((*p_bd)), lmp_ver, mfct_set, lmp_subver); + log::info("Remote version info valid:{} [{}]:0x{:x},0x{:x},0x{:x}", + logbool(version_info_valid), ADDRESS_TO_LOGGABLE_CSTR((*p_bd)), + lmp_ver, mfct_set, lmp_subver); if (version_info_valid) { // Always update cache to ensure we have availability whenever BTM API is @@ -684,18 +701,18 @@ static void btif_update_remote_properties(const RawAddress& bdaddr, cod = devclass2uint(dev_class); if ((cod == 0) || (cod == COD_UNCLASSIFIED)) { /* Try to retrieve cod from storage */ - LOG_VERBOSE("class of device (cod) is unclassified, checking storage"); + log::verbose("class of device (cod) is unclassified, checking storage"); BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties], BT_PROPERTY_CLASS_OF_DEVICE, sizeof(cod), &cod); status = btif_storage_get_remote_device_property( &bdaddr, &properties[num_properties]); - LOG_VERBOSE("cod retrieved from storage is 0x%06x", cod); + log::verbose("cod retrieved from storage is 0x{:06x}", cod); if (cod == 0) { - LOG_INFO("cod from storage is also unclassified"); + log::info("cod from storage is also unclassified"); cod = COD_UNCLASSIFIED; } } else { - LOG_INFO("class of device (cod) is 0x%06x", cod); + log::info("class of device (cod) is 0x{:06x}", cod); } BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties], @@ -747,6 +764,18 @@ bool is_device_le_audio_capable(const RawAddress bd_addr) { return false; } + /* First try reading device type from BTIF - it persists over multiple + * inquiry sessions */ + int dev_type = 0; + if (IS_FLAG_ENABLED(le_audio_dev_type_detection_fix) && + (btif_get_device_type(bd_addr, &dev_type) && + (dev_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE)) { + /* LE Audio capable device is discoverable over both LE and Classic using + * same address. Prefer to use LE transport, as we don't know if it can do + * CTKD from Classic to LE */ + return true; + } + tBT_DEVICE_TYPE tmp_dev_type; tBLE_ADDR_TYPE addr_type = BLE_ADDR_PUBLIC; BTM_ReadDevInfo(bd_addr, &tmp_dev_type, &addr_type); @@ -798,7 +827,7 @@ static void btif_dm_cb_create_bond(const RawAddress bd_addr, bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING); if (transport == BT_TRANSPORT_AUTO && is_device_le_audio_capable(bd_addr)) { - LOG_DEBUG("LE Audio capable, forcing LE transport for Bonding"); + log::debug("LE Audio capable, forcing LE transport for Bonding"); transport = BT_TRANSPORT_LE; } @@ -807,8 +836,8 @@ static void btif_dm_cb_create_bond(const RawAddress bd_addr, std::string addrstr = bd_addr.ToString(); const char* bdstr = addrstr.c_str(); if (transport == BT_TRANSPORT_LE) { - if (!btif_config_get_int(bdstr, "DevType", &device_type)) { - btif_config_set_int(bdstr, "DevType", BT_DEVICE_TYPE_BLE); + if (!btif_config_get_int(bdstr, BTIF_STORAGE_KEY_DEV_TYPE, &device_type)) { + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_DEV_TYPE, BT_DEVICE_TYPE_BLE); } if (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS) { @@ -822,7 +851,7 @@ static void btif_dm_cb_create_bond(const RawAddress bd_addr, btif_storage_set_remote_addr_type(&bd_addr, addr_type); } } - if ((btif_config_get_int(bdstr, "DevType", &device_type) && + if ((btif_config_get_int(bdstr, BTIF_STORAGE_KEY_DEV_TYPE, &device_type) && (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) == BT_STATUS_SUCCESS) && (device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE) || @@ -831,10 +860,15 @@ static void btif_dm_cb_create_bond(const RawAddress bd_addr, static_cast(device_type)); } - if (is_hid && (device_type & BT_DEVICE_TYPE_BLE) == 0) { + if (!IS_FLAG_ENABLED(connect_hid_after_service_discovery) && + is_hid && (device_type & BT_DEVICE_TYPE_BLE) == 0) { + tAclLinkSpec link_spec; + link_spec.addrt.bda = bd_addr; + link_spec.addrt.type = addr_type; + link_spec.transport = transport; const bt_status_t status = GetInterfaceToProfiles()->profileSpecific_HACK->btif_hh_connect( - &bd_addr); + &link_spec); if (status != BT_STATUS_SUCCESS) bond_state_changed(status, bd_addr, BT_BOND_STATE_NONE); } else { @@ -886,8 +920,8 @@ uint16_t btif_dm_get_connection_state(const RawAddress& bd_addr) { rc |= ENCRYPTED_LE; } } else { - LOG_INFO("Acl is not connected to peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Acl is not connected to peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } BTM_LogHistory( @@ -899,6 +933,51 @@ uint16_t btif_dm_get_connection_state(const RawAddress& bd_addr) { return rc; } +static uint16_t btif_dm_get_resolved_connection_state( + tBLE_BD_ADDR ble_bd_addr) { + uint16_t rc = 0; + if (maybe_resolve_address(&ble_bd_addr.bda, &ble_bd_addr.type)) { + if (BTA_DmGetConnectionState(ble_bd_addr.bda)) { + rc = 0x0001; + if (BTM_IsEncrypted(ble_bd_addr.bda, BT_TRANSPORT_BR_EDR)) { + rc |= ENCRYPTED_BREDR; + } + if (BTM_IsEncrypted(ble_bd_addr.bda, BT_TRANSPORT_LE)) { + rc |= ENCRYPTED_LE; + } + + BTM_LogHistory( + kBtmLogTag, ble_bd_addr.bda, "RESOLVED connection state", + base::StringPrintf( + "connected:%c classic_encrypted:%c le_encrypted:%c", + (rc & 0x0001) ? 'T' : 'F', (rc & ENCRYPTED_BREDR) ? 'T' : 'F', + (rc & ENCRYPTED_LE) ? 'T' : 'F')); + } + } + return rc; +} + +uint16_t btif_dm_get_connection_state_sync(const RawAddress& bd_addr) { + std::promise promise; + std::future future = promise.get_future(); + + ASSERT(BT_STATUS_SUCCESS == + do_in_main_thread( + FROM_HERE, + base::BindOnce( + [](const RawAddress bd_addr, std::promise promise) { + // Experiment to try with maybe resolved address + uint16_t state = btif_dm_get_resolved_connection_state({ + .type = BLE_ADDR_RANDOM, + .bda = bd_addr, + }); + state |= btif_dm_get_connection_state(bd_addr); + promise.set_value(state); + }, + bd_addr, std::move(promise)))); + return future.get(); +} + /****************************************************************************** * * BTIF DM callback events @@ -938,7 +1017,7 @@ static void btif_dm_pin_req_evt(tBTA_DM_PIN_REQ* p_pin_req) { if (pairing_cb.state == BT_BOND_STATE_BONDING && bd_addr != pairing_cb.bd_addr) { - LOG_WARN("already in bonding state, reject request"); + log::warn("already in bonding state, reject request"); return; } @@ -947,7 +1026,7 @@ static void btif_dm_pin_req_evt(tBTA_DM_PIN_REQ* p_pin_req) { cod = devclass2uint(p_pin_req->dev_class); if (cod == 0) { - LOG_WARN("cod is 0, set as unclassified"); + log::warn("cod is 0, set as unclassified"); cod = COD_UNCLASSIFIED; } @@ -964,7 +1043,7 @@ static void btif_dm_pin_req_evt(tBTA_DM_PIN_REQ* p_pin_req) { !interop_match_name(INTEROP_DISABLE_AUTO_PAIRING, (const char*)bd_name.name) && (pairing_cb.autopair_attempts == 0)) { - LOG_DEBUG("Attempting auto pair w/ IOP"); + log::debug("Attempting auto pair w/ IOP"); pin_code.pin[0] = 0x30; pin_code.pin[1] = 0x30; pin_code.pin[2] = 0x30; @@ -979,7 +1058,7 @@ static void btif_dm_pin_req_evt(tBTA_DM_PIN_REQ* p_pin_req) { if ((interop_match_addr(INTEROP_KEYBOARD_REQUIRES_FIXED_PIN, &bd_addr) == true) && (pairing_cb.autopair_attempts == 0)) { - LOG_DEBUG("Attempting auto pair w/ IOP"); + log::debug("Attempting auto pair w/ IOP"); pin_code.pin[0] = 0x30; pin_code.pin[1] = 0x30; pin_code.pin[2] = 0x30; @@ -1014,10 +1093,10 @@ static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ* p_ssp_cfm_req) { uint32_t cod; int dev_type; - LOG_VERBOSE("addr:%s, just_works:%d, loc_auth_req=%d, rmt_auth_req=%d", - ADDRESS_TO_LOGGABLE_CSTR(p_ssp_cfm_req->bd_addr), - p_ssp_cfm_req->just_works, p_ssp_cfm_req->loc_auth_req, - p_ssp_cfm_req->rmt_auth_req); + log::verbose("addr:{}, just_works:{}, loc_auth_req={}, rmt_auth_req={}", + ADDRESS_TO_LOGGABLE_CSTR(p_ssp_cfm_req->bd_addr), + p_ssp_cfm_req->just_works, p_ssp_cfm_req->loc_auth_req, + p_ssp_cfm_req->rmt_auth_req); /* Remote properties update */ if (BTM_GetPeerDeviceTypeFromFeatures(p_ssp_cfm_req->bd_addr) == BT_DEVICE_TYPE_DUMO) { @@ -1035,7 +1114,7 @@ static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ* p_ssp_cfm_req) { if (pairing_cb.state == BT_BOND_STATE_BONDING && bd_addr != pairing_cb.bd_addr) { - LOG_WARN("already in bonding state, reject request"); + log::warn("already in bonding state, reject request"); btif_dm_ssp_reply(bd_addr, BT_SSP_VARIANT_PASSKEY_CONFIRMATION, 0); return; } @@ -1063,7 +1142,8 @@ static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ* p_ssp_cfm_req) { * Incoming temporary pairing is detected */ if (is_incoming && pairing_cb.bond_type == BOND_TYPE_TEMPORARY) { - LOG_DEBUG("Auto-accept JustWorks incoming pairing for temporary bonding"); + log::debug( + "Auto-accept JustWorks incoming pairing for temporary bonding"); btif_dm_ssp_reply(bd_addr, BT_SSP_VARIANT_CONSENT, true); return; } @@ -1072,7 +1152,7 @@ static void btif_dm_ssp_cfm_req_evt(tBTA_DM_SP_CFM_REQ* p_ssp_cfm_req) { cod = devclass2uint(p_ssp_cfm_req->dev_class); if (cod == 0) { - LOG_WARN("cod is 0, set as unclassified"); + log::warn("cod is 0, set as unclassified"); cod = COD_UNCLASSIFIED; } @@ -1094,7 +1174,7 @@ static void btif_dm_ssp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif) { uint32_t cod; int dev_type; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_ssp_key_notif->bd_addr)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_ssp_key_notif->bd_addr)); /* Remote properties update */ if (BTM_GetPeerDeviceTypeFromFeatures(p_ssp_key_notif->bd_addr) == @@ -1117,7 +1197,7 @@ static void btif_dm_ssp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif) { cod = devclass2uint(p_ssp_key_notif->dev_class); if (cod == 0) { - LOG_WARN("cod is 0, set as unclassified"); + log::warn("cod is 0, set as unclassified"); cod = COD_UNCLASSIFIED; } @@ -1144,8 +1224,8 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { bt_bond_state_t state = BT_BOND_STATE_NONE; bool skip_sdp = false; - LOG_INFO("bond state=%d, success=%d, key_present=%d", pairing_cb.state, - p_auth_cmpl->success, p_auth_cmpl->key_present); + log::info("bond state={}, success={}, key_present={}", pairing_cb.state, + p_auth_cmpl->success, p_auth_cmpl->key_present); pairing_cb.fail_reason = p_auth_cmpl->fail_reason; @@ -1160,21 +1240,21 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { bt_status_t ret; if (!bd_addr.IsEmpty()) { - LOG_DEBUG("Storing link key. key_type=0x%x, bond_type=%d", - p_auth_cmpl->key_type, pairing_cb.bond_type); + log::debug("Storing link key. key_type=0x{:x}, bond_type={}", + p_auth_cmpl->key_type, pairing_cb.bond_type); ret = btif_storage_add_bonded_device(&bd_addr, p_auth_cmpl->key, p_auth_cmpl->key_type, pairing_cb.pin_code_len); } else { - LOG_WARN("bd_addr is empty"); + log::warn("bd_addr is empty"); ret = BT_STATUS_FAIL; } ASSERTC(ret == BT_STATUS_SUCCESS, "storing link key failed", ret); } else { - LOG_DEBUG("Temporary key. Not storing. key_type=0x%x, bond_type=%d", - p_auth_cmpl->key_type, pairing_cb.bond_type); + log::debug("Temporary key. Not storing. key_type=0x{:x}, bond_type={}", + p_auth_cmpl->key_type, pairing_cb.bond_type); if (pairing_cb.bond_type == BOND_TYPE_TEMPORARY) { - LOG_DEBUG("sending BT_BOND_STATE_NONE for Temp pairing"); + log::debug("sending BT_BOND_STATE_NONE for Temp pairing"); btif_storage_remove_bonded_device(&bd_addr); bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_NONE); return; @@ -1195,8 +1275,8 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { // the derived link key. if (p_auth_cmpl->bd_addr != pairing_cb.bd_addr && (!pairing_cb.ble.is_penc_key_rcvd)) { - LOG_WARN("skipping SDP for unknown device %s", - ADDRESS_TO_LOGGABLE_CSTR(p_auth_cmpl->bd_addr)); + log::warn("skipping SDP for unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(p_auth_cmpl->bd_addr)); return; } @@ -1211,13 +1291,13 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { bool is_crosskey = false; if (pairing_cb.state == BT_BOND_STATE_BONDING && p_auth_cmpl->is_ctkd) { - LOG_DEBUG("bonding initiated due to cross key pairing"); + log::debug("bonding initiated due to cross key pairing"); is_crosskey = true; } if (!is_crosskey) { btif_update_remote_properties(p_auth_cmpl->bd_addr, p_auth_cmpl->bd_name, - NULL, dev_type); + kDevClassEmpty, dev_type); } pairing_cb.timeout_retries = 0; @@ -1226,13 +1306,13 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { bd_addr = p_auth_cmpl->bd_addr; if (check_sdp_bl(&bd_addr) && check_cod_hid(&bd_addr)) { - LOG_WARN("skip SDP"); + log::warn("skip SDP"); skip_sdp = true; } if (!pairing_cb.is_local_initiated && skip_sdp) { bond_state_changed(status, bd_addr, state); - LOG_WARN("Incoming HID Connection"); + log::warn("Incoming HID Connection"); bt_property_t prop; Uuid uuid = Uuid::From16Bit(UUID_SERVCLASS_HUMAN_INTERFACE); @@ -1245,7 +1325,7 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { } else { /* If bonded due to cross-key, save the static address too*/ if (is_crosskey) { - LOG_DEBUG("bonding initiated due to cross key, adding static address"); + log::debug("bonding initiated due to cross key, adding static address"); pairing_cb.static_bdaddr = bd_addr; } if (!is_crosskey || @@ -1271,7 +1351,7 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { if (pairing_cb.sdp_over_classic == btif_dm_pairing_cb_t::ServiceDiscoveryState::NOT_STARTED) { - LOG_INFO("scheduling SDP for %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("scheduling SDP for {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); pairing_cb.sdp_over_classic = btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED; btif_dm_get_remote_services(bd_addr, BT_TRANSPORT_BR_EDR); @@ -1281,8 +1361,8 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { // Do not call bond_state_changed_cb yet. Wait until remote service // discovery is complete } else { - LOG_WARN("Bonding failed with failure reason:%s", - hci_reason_code_text(p_auth_cmpl->fail_reason).c_str()); + log::warn("Bonding failed with failure reason:{}", + hci_reason_code_text(p_auth_cmpl->fail_reason)); bool is_bonded_device_removed = false; // Map the HCI fail reason to bt status switch (p_auth_cmpl->fail_reason) { @@ -1290,8 +1370,8 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { case HCI_ERR_LMP_RESPONSE_TIMEOUT: if (interop_match_addr(INTEROP_AUTO_RETRY_PAIRING, &bd_addr) && pairing_cb.timeout_retries) { - LOG_WARN("Pairing timeout; retrying (%d) ...", - pairing_cb.timeout_retries); + log::warn("Pairing timeout; retrying ({}) ...", + pairing_cb.timeout_retries); --pairing_cb.timeout_retries; if (addr_type == BLE_ADDR_RANDOM) { btif_dm_cb_create_bond_le(bd_addr, addr_type); @@ -1322,11 +1402,11 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { case HCI_ERR_INSUFFCIENT_SECURITY: case HCI_ERR_PEER_USER: case HCI_ERR_UNSPECIFIED: - LOG_WARN("Authentication fail:%s", - hci_reason_code_text(p_auth_cmpl->fail_reason).c_str()); + log::warn("Authentication fail:{}", + hci_reason_code_text(p_auth_cmpl->fail_reason)); if (pairing_cb.autopair_attempts == 1) { /* Create the Bond once again */ - LOG_WARN("auto pair failed. Reinitiate Bond"); + log::warn("auto pair failed. Reinitiate Bond"); if (addr_type == BLE_ADDR_RANDOM) { btif_dm_cb_create_bond_le(bd_addr, addr_type); } else { @@ -1345,7 +1425,7 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { /* Special Handling for HID Devices */ if (check_cod_hid_major(bd_addr, COD_HID_POINTING)) { /* Remove Device as bonded in nvram as authentication failed */ - LOG_VERBOSE("removing hid pointing device from nvram"); + log::verbose("removing hid pointing device from nvram"); is_bonded_device_removed = false; } // Report bond state change to java only if we are bonding to a device or @@ -1367,7 +1447,7 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { *****************************************************************************/ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_search_data) { - LOG_VERBOSE("event=%s", dump_dm_search_event(event)); + log::verbose("event={}", dump_dm_search_event(event)); switch (event) { case BTA_DM_NAME_READ_EVT: { @@ -1395,16 +1475,21 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, BTIF_STORAGE_FILL_PROPERTY(&properties[2], BT_PROPERTY_CLASS_OF_DEVICE, sizeof(uint32_t), &cod); if (btif_storage_get_remote_device_property( &bdaddr, &properties[2]) == BT_STATUS_SUCCESS) { - LOG_VERBOSE("BTA_DM_NAME_READ_EVT, cod in storage=0x%08x", cod); + log::verbose("BTA_DM_NAME_READ_EVT, cod in storage=0x{:08x}", cod); } else { - LOG_DEBUG("BTA_DM_NAME_READ_EVT, no cod in storage"); + log::info("BTA_DM_NAME_READ_EVT, no cod in storage"); cod = 0; } if (cod != 0) { BTIF_STORAGE_FILL_PROPERTY(&properties[1], BT_PROPERTY_BDADDR, sizeof(bdaddr), &bdaddr); BTIF_STORAGE_FILL_PROPERTY(&properties[2], BT_PROPERTY_CLASS_OF_DEVICE, sizeof(uint32_t), &cod); - LOG_DEBUG("report new device to JNI"); + log::debug("report new device to JNI"); GetInterfaceToProfiles()->events->invoke_device_found_cb(3, properties); + } else { + log::info("Skipping RNR callback because cod is zero addr:{} name:{}", + ADDRESS_TO_LOGGABLE_CSTR(bdaddr), + PRIVATE_NAME(reinterpret_cast( + p_search_data->disc_res.bd_name))); } /** @} */ } @@ -1418,14 +1503,15 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, uint8_t num_uuids = 0, max_num_uuid = 32; uint8_t uuid_list[32 * Uuid::kNumBytes16]; - if (p_search_data->inq_res.inq_result_type != BTM_INQ_RESULT_BLE) { + if (p_search_data->inq_res.inq_result_type != BT_DEVICE_TYPE_BLE) { p_search_data->inq_res.remt_name_not_required = check_eir_remote_name(p_search_data, NULL, NULL); } RawAddress& bdaddr = p_search_data->inq_res.bd_addr; - LOG_VERBOSE("addr:%s device_type=0x%x", ADDRESS_TO_LOGGABLE_CSTR(bdaddr), - p_search_data->inq_res.device_type); + log::verbose("addr:{} device_type=0x{:x}", + ADDRESS_TO_LOGGABLE_CSTR(bdaddr), + p_search_data->inq_res.device_type); bdname.name[0] = 0; if (!check_eir_remote_name(p_search_data, bdname.name, &remote_name_len)) @@ -1461,7 +1547,7 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, /* DEV_CLASS */ uint32_t cod = devclass2uint(p_search_data->inq_res.dev_class); - LOG_VERBOSE("cod is 0x%06x", cod); + log::verbose("cod is 0x{:06x}", cod); if (cod != 0) { BTIF_STORAGE_FILL_PROPERTY(&properties[num_properties], BT_PROPERTY_CLASS_OF_DEVICE, sizeof(cod), @@ -1469,8 +1555,8 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, num_properties++; } - LOG_VERBOSE("clock_offset is 0x%x", - p_search_data->inq_res.clock_offset); + log::verbose("clock_offset is 0x{:x}", + p_search_data->inq_res.clock_offset); if (p_search_data->inq_res.clock_offset & BTM_CLOCK_OFFSET_VALID) { btif_set_device_clockoffset(bdaddr, (int)p_search_data->inq_res.clock_offset); } @@ -1551,10 +1637,10 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, auto triple = eir_uuids_cache.try_emplace(bdaddr, std::set{}); uuid_iter = std::get<0>(triple); } - LOG_INFO("EIR UUIDs for %s:", ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); + log::info("EIR UUIDs for {}:", ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); for (int i = 0; i < num_uuids; ++i) { Uuid uuid = Uuid::From16Bit(p_uuid16[i]); - LOG_INFO(" %s", uuid.ToString().c_str()); + log::info("{}", uuid.ToString()); uuid_iter->second.insert(uuid); } @@ -1595,8 +1681,8 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, if (restrict_report && p_search_data->inq_res.device_type == BT_DEVICE_TYPE_BLE && !(p_search_data->inq_res.ble_evt_type & BTM_BLE_CONNECTABLE_MASK)) { - LOG_DEBUG("Ble device %s is not connectable", - ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); + log::debug("Ble device {} is not connectable", + ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); break; } @@ -1632,7 +1718,7 @@ static void btif_dm_search_devices_evt(tBTA_DM_SEARCH_EVT event, case BTA_DM_DID_RES_EVT: case BTA_DM_GATT_OVER_SDP_RES_EVT: default: - LOG_WARN("Unhandled event:%s", bta_dm_search_evt_text(event).c_str()); + log::warn("Unhandled event:{}", bta_dm_search_evt_text(event)); break; } } @@ -1658,6 +1744,29 @@ static bool btif_should_ignore_uuid(const Uuid& uuid) { return uuid.IsEmpty() || uuid.IsBase(); } +static bool btif_is_gatt_service_discovery_post_pairing(const RawAddress bd_addr) { + if (!IS_FLAG_ENABLED(reset_pairing_only_for_related_service_discovery)) { + if (bd_addr == pairing_cb.bd_addr || bd_addr == pairing_cb.static_bdaddr) { + if (pairing_cb.gatt_over_le != + btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED) { + log::error( + "gatt_over_le should be SCHEDULED, did someone clear the control " + "block for {} ?", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + } + + return true; + } + + return false; + } + + return ((bd_addr == pairing_cb.bd_addr || + bd_addr == pairing_cb.static_bdaddr) && + (pairing_cb.gatt_over_le == + btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED)); +} + /******************************************************************************* * * Function btif_dm_search_services_evt @@ -1679,25 +1788,29 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, RawAddress& bd_addr = p_data->disc_res.bd_addr; - LOG_VERBOSE("result=0x%x, services 0x%x", p_data->disc_res.result, - p_data->disc_res.services); + log::verbose("result=0x{:x}, services 0x{:x}", p_data->disc_res.result, + p_data->disc_res.services); if (p_data->disc_res.result != BTA_SUCCESS && pairing_cb.state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts < BTIF_DM_MAX_SDP_ATTEMPTS_AFTER_PAIRING) { if (pairing_cb.sdp_attempts) { - LOG_WARN("SDP failed after bonding re-attempting for %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("SDP failed after bonding re-attempting for {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); pairing_cb.sdp_attempts++; - btif_dm_get_remote_services(bd_addr, BT_TRANSPORT_AUTO); + if (IS_FLAG_ENABLED(force_bredr_for_sdp_retry)) { + btif_dm_get_remote_services(bd_addr, BT_TRANSPORT_BR_EDR); + } else { + btif_dm_get_remote_services(bd_addr, BT_TRANSPORT_AUTO); + } } else { - LOG_WARN("SDP triggered by someone failed when bonding"); + log::warn("SDP triggered by someone failed when bonding"); } return; } if ((bd_addr == pairing_cb.bd_addr || bd_addr == pairing_cb.static_bdaddr)) { - LOG_INFO("SDP finished for %s:", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("SDP finished for {}:", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); pairing_cb.sdp_over_classic = btif_dm_pairing_cb_t::ServiceDiscoveryState::FINISHED; } @@ -1706,13 +1819,13 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, prop.len = 0; if ((p_data->disc_res.result == BTA_SUCCESS) && (p_data->disc_res.num_uuids > 0)) { - LOG_INFO("New UUIDs for %s:", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("New UUIDs for {}:", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); for (i = 0; i < p_data->disc_res.num_uuids; i++) { auto uuid = p_data->disc_res.p_uuid_list + i; if (btif_should_ignore_uuid(*uuid)) { continue; } - LOG_INFO("index:%d uuid:%s", i, uuid->ToString().c_str()); + log::info("index:{} uuid:{}", i, uuid->ToString()); uuids.insert(*uuid); } @@ -1725,8 +1838,7 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, continue; } if (btif_is_interesting_le_service(uuid)) { - LOG_INFO("interesting le service %s insert", - uuid.ToString().c_str()); + log::info("interesting le service {} insert", uuid.ToString()); uuids.insert(uuid); } } @@ -1762,7 +1874,7 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, if (pairing_cb.state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts && (p_data->disc_res.bd_addr == pairing_cb.bd_addr || p_data->disc_res.bd_addr == pairing_cb.static_bdaddr)) { - LOG_INFO("SDP search done for %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("SDP search done for {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); pairing_cb.sdp_attempts = 0; // Send UUIDs discovered through EIR to Java to unblock pairing intent @@ -1771,8 +1883,8 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, auto uuids_iter = eir_uuids_cache.find(bd_addr); if (uuids_iter != eir_uuids_cache.end()) { num_eir_uuids = uuids_iter->second.size(); - LOG_INFO("SDP failed, send %zu EIR UUIDs to unblock bonding %s", - num_eir_uuids, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("SDP failed, send {} EIR UUIDs to unblock bonding {}", + num_eir_uuids, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); for (auto eir_uuid : uuids_iter->second) { auto uuid_128bit = eir_uuid.To128BitBE(); property_value.insert(property_value.end(), uuid_128bit.begin(), @@ -1784,7 +1896,7 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, prop.val = (void*)property_value.data(); prop.len = num_eir_uuids * Uuid::kNumBytes128; } else { - LOG_WARN("SDP failed and we have no EIR UUIDs to report either"); + log::warn("SDP failed and we have no EIR UUIDs to report either"); prop.val = &uuid; prop.len = Uuid::kNumBytes128; } @@ -1794,7 +1906,7 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, // Both SDP and bonding are done, clear pairing control block in case // it is not already cleared pairing_cb = {}; - LOG_DEBUG("clearing btif pairing_cb"); + log::debug("clearing btif pairing_cb"); } } @@ -1813,9 +1925,9 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, ret); if (skip_reporting_wait_for_le) { - LOG_INFO( - "Bonding LE Audio sink - must wait for le services discovery " - "to pass all services to java %s", + log::info( + "Bonding LE Audio sink - must wait for le services discovery to " + "pass all services to java {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); /* For LE Audio capable devices, we care more about passing GATT LE * services than about just finishing pairing. Service discovery @@ -1850,19 +1962,11 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, is_le_audio_capable_during_service_discovery(bd_addr); if (event == BTA_DM_GATT_OVER_LE_RES_EVT) { - LOG_INFO("New GATT over LE UUIDs for %s:", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("New GATT over LE UUIDs for {}:", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); BTM_LogHistory(kBtmLogTag, bd_addr, "Discovered GATT services using LE transport"); - if ((bd_addr == pairing_cb.bd_addr || - bd_addr == pairing_cb.static_bdaddr)) { - if (pairing_cb.gatt_over_le != - btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED) { - LOG_ERROR( - "gatt_over_le should be SCHEDULED, did someone clear the " - "control block for %s ?", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); - } + if (btif_is_gatt_service_discovery_post_pairing(bd_addr)) { pairing_cb.gatt_over_le = btif_dm_pairing_cb_t::ServiceDiscoveryState::FINISHED; @@ -1870,13 +1974,29 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED) { // Both SDP and bonding are either done, or not scheduled, // we are safe to clear the service discovery part of CB. - LOG_DEBUG("clearing pairing_cb"); + log::debug("clearing pairing_cb"); pairing_cb = {}; } + + if (IS_FLAG_ENABLED(le_audio_fast_bond_params) && lea_supported) { + /* LE Audio profile should relax parameters when it connects. If + * profile is not enabled, relax parameters after timeout. */ + log::debug("Scheduling conn params unlock for {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + do_in_main_thread_delayed( + FROM_HERE, + base::BindOnce( + [](RawAddress bd_addr) { + L2CA_LockBleConnParamsForProfileConnection(bd_addr, + false); + }, + bd_addr), + std::chrono::seconds(15)); + } } } else { - LOG_DEBUG("New GATT over SDP UUIDs for %s:", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("New GATT over SDP UUIDs for {}:", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); BTM_LogHistory(kBtmLogTag, bd_addr, "Discovered GATT services using SDP transport"); } @@ -1886,14 +2006,14 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, if (btif_should_ignore_uuid(uuid)) { continue; } - LOG_INFO("index:%d uuid:%s", static_cast(uuids.size()), - uuid.ToString().c_str()); + log::info("index:{} uuid:{}", static_cast(uuids.size()), + uuid.ToString()); uuids.insert(uuid); } } if (uuids.empty()) { - LOG_INFO("No well known GATT services discovered"); + log::info("No well known GATT services discovered"); /* If services were returned as part of SDP discovery, we will * immediately send them with rest of SDP results in BTA_DM_DISC_RES_EVT @@ -1905,18 +2025,18 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, if (lea_supported) { if (bluetooth::common::init_flags:: sdp_return_classic_services_when_le_discovery_fails_is_enabled()) { - LOG_INFO( + log::info( "Will return Classic SDP results, if done, to unblock bonding"); } else { // LEA device w/o this flag // TODO: we might want to remove bond or do some action on // half-discovered device - LOG_WARN("No GATT service found for the LE Audio device %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("No GATT service found for the LE Audio device {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } } else { - LOG_INFO("LE audio not supported, no need to report any UUIDs"); + log::info("LE audio not supported, no need to report any UUIDs"); return; } } @@ -1928,8 +2048,8 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, btif_get_existing_uuids(&bd_addr, existing_uuids); if (existing_lookup_result != BT_STATUS_FAIL) { - LOG_INFO("Got some existing UUIDs by address %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Got some existing UUIDs by address {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); for (int i = 0; i < BT_MAX_NUM_UUIDS; i++) { Uuid uuid = existing_uuids[i]; @@ -1945,8 +2065,8 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, existing_lookup_result = btif_get_existing_uuids(&static_addr_copy, existing_uuids); if (existing_lookup_result != BT_STATUS_FAIL) { - LOG_INFO("Got some existing UUIDs by static address %s", - ADDRESS_TO_LOGGABLE_CSTR(static_addr_copy)); + log::info("Got some existing UUIDs by static address {}", + ADDRESS_TO_LOGGABLE_CSTR(static_addr_copy)); for (int i = 0; i < BT_MAX_NUM_UUIDS; i++) { Uuid uuid = existing_uuids[i]; if (uuid.IsEmpty()) { @@ -2020,7 +2140,39 @@ static void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, } break; case BTA_DM_NAME_READ_EVT: { - LOG_INFO("Skipping name read event - called on bad callback."); + if (IS_FLAG_ENABLED(rnr_present_during_service_discovery)) { + const tBTA_DM_DISC_RES& disc_res = p_data->disc_res; + if (disc_res.hci_status != HCI_SUCCESS) { + log::warn("Received RNR event with bad status addr:{} hci_status:{}", + ADDRESS_TO_LOGGABLE_CSTR(disc_res.bd_addr), + hci_error_code_text(disc_res.hci_status)); + break; + } + if (disc_res.bd_name[0] == '\0') { + log::warn("Received RNR event without valid name addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(disc_res.bd_addr)); + break; + } + bt_property_t properties[] = {{ + .type = BT_PROPERTY_BDNAME, + .len = (int)strlen((char*)disc_res.bd_name), + .val = (void*)disc_res.bd_name, + }}; + const bt_status_t status = btif_storage_set_remote_device_property( + &disc_res.bd_addr, properties); + ASSERT_LOG(status == BT_STATUS_SUCCESS, + "Failed to save remote device property status:%s", + bt_status_text(status).c_str()); + const size_t num_props = sizeof(properties) / sizeof(bt_property_t); + GetInterfaceToProfiles()->events->invoke_remote_device_properties_cb( + status, disc_res.bd_addr, (int)num_props, properties); + log::info( + "Callback for read name event addr:{} name:{}", + ADDRESS_TO_LOGGABLE_CSTR(disc_res.bd_addr), + PRIVATE_NAME(reinterpret_cast(disc_res.bd_name))); + } else { + log::info("Skipping name read event - called on bad callback."); + } } break; default: { @@ -2034,14 +2186,14 @@ static void btif_dm_update_allowlisted_media_players() { bt_property_t wlplayers_prop; list_t* wl_players = list_new(nullptr); if (!wl_players) { - LOG_ERROR("Unable to allocate space for allowlist players"); + log::error("Unable to allocate space for allowlist players"); return; } - LOG_DEBUG("btif_dm_update_allowlisted_media_players"); + log::debug("btif_dm_update_allowlisted_media_players"); wlplayers_prop.len = 0; if (!interop_get_allowlisted_media_players_list(wl_players)) { - LOG_DEBUG("Allowlisted media players not found"); + log::debug("Allowlisted media players not found"); list_free(wl_players); return; } @@ -2068,27 +2220,19 @@ static void btif_dm_update_allowlisted_media_players() { list_free(wl_players); } -void BTIF_dm_report_inquiry_status_change(tBTM_STATUS status) { - if (status == BTM_INQUIRY_STARTED) { +void BTIF_dm_report_inquiry_status_change(tBTM_INQUIRY_STATE status) { + btif_dm_inquiry_in_progress = + (status == tBTM_INQUIRY_STATE::BTM_INQUIRY_STARTED); + + if (status == tBTM_INQUIRY_STATE::BTM_INQUIRY_STARTED) { GetInterfaceToProfiles()->events->invoke_discovery_state_changed_cb( BT_DISCOVERY_STARTED); - btif_dm_inquiry_in_progress = true; - } else if (status == BTM_INQUIRY_CANCELLED) { + } else if (status == tBTM_INQUIRY_STATE::BTM_INQUIRY_CANCELLED) { GetInterfaceToProfiles()->events->invoke_discovery_state_changed_cb( BT_DISCOVERY_STOPPED); - btif_dm_inquiry_in_progress = false; - } else if (status == BTM_INQUIRY_COMPLETE) { - btif_dm_inquiry_in_progress = false; } } -void BTIF_dm_on_hw_error() { - LOG_ERROR("Received H/W Error"); - usleep(100000); /* 100milliseconds */ - /* Killing the process to force a restart as part of fault tolerance */ - kill(getpid(), SIGKILL); -} - void BTIF_dm_enable() { BD_NAME bdname; bt_status_t status; @@ -2112,7 +2256,7 @@ void BTIF_dm_enable() { bool ble_privacy_enabled = osi_property_get_bool(PROPERTY_BLE_PRIVACY_ENABLED, /*default=*/true); - LOG_INFO("Local BLE Privacy enabled:%d", ble_privacy_enabled); + log::info("Local BLE Privacy enabled:{}", ble_privacy_enabled); BTA_DmBleConfigLocalPrivacy(ble_privacy_enabled); /* for each of the enabled services in the mask, trigger the profile @@ -2149,7 +2293,7 @@ void BTIF_dm_disable() { } } bluetooth::bqr::EnableBtQualityReport(false); - LOG_INFO("Stack device manager shutdown finished"); + log::info("Stack device manager shutdown finished"); future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); } @@ -2165,7 +2309,7 @@ void BTIF_dm_disable() { void btif_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { RawAddress bd_addr; - LOG_VERBOSE("ev:%s", dump_dm_event(event)); + log::verbose("ev:{}", dump_dm_event(event)); switch (event) { case BTA_DM_PIN_REQ_EVT: @@ -2202,8 +2346,8 @@ void btif_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { break; case BTA_DM_BLE_KEY_EVT: - LOG_VERBOSE("BTA_DM_BLE_KEY_EVT key_type=0x%02x ", - p_data->ble_key.key_type); + log::verbose("BTA_DM_BLE_KEY_EVT key_type=0x{:02x}", + p_data->ble_key.key_type); /* If this pairing is by-product of local initiated GATT client Read or Write, @@ -2212,93 +2356,94 @@ void btif_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { have setup properly. Setup pairing_cb and notify App about Bonding state now*/ if (pairing_cb.state != BT_BOND_STATE_BONDING) { - LOG_VERBOSE("Bond state not sent to App so far.Notify the app now"); + log::verbose("Bond state not sent to App so far.Notify the app now"); bond_state_changed(BT_STATUS_SUCCESS, p_data->ble_key.bd_addr, BT_BOND_STATE_BONDING); } else if (pairing_cb.bd_addr != p_data->ble_key.bd_addr) { - LOG_ERROR("BD mismatch discard BLE key_type=%d ", - p_data->ble_key.key_type); + log::error("BD mismatch discard BLE key_type={}", + p_data->ble_key.key_type); break; } switch (p_data->ble_key.key_type) { case BTM_LE_KEY_PENC: - LOG_VERBOSE("Rcv BTM_LE_KEY_PENC"); + log::verbose("Rcv BTM_LE_KEY_PENC"); pairing_cb.ble.is_penc_key_rcvd = true; pairing_cb.ble.penc_key = p_data->ble_key.p_key_value->penc_key; break; case BTM_LE_KEY_PID: - LOG_VERBOSE("Rcv BTM_LE_KEY_PID"); + log::verbose("Rcv BTM_LE_KEY_PID"); pairing_cb.ble.is_pid_key_rcvd = true; pairing_cb.ble.pid_key = p_data->ble_key.p_key_value->pid_key; break; case BTM_LE_KEY_PCSRK: - LOG_VERBOSE("Rcv BTM_LE_KEY_PCSRK"); + log::verbose("Rcv BTM_LE_KEY_PCSRK"); pairing_cb.ble.is_pcsrk_key_rcvd = true; pairing_cb.ble.pcsrk_key = p_data->ble_key.p_key_value->pcsrk_key; break; case BTM_LE_KEY_LENC: - LOG_VERBOSE("Rcv BTM_LE_KEY_LENC"); + log::verbose("Rcv BTM_LE_KEY_LENC"); pairing_cb.ble.is_lenc_key_rcvd = true; pairing_cb.ble.lenc_key = p_data->ble_key.p_key_value->lenc_key; break; case BTM_LE_KEY_LCSRK: - LOG_VERBOSE("Rcv BTM_LE_KEY_LCSRK"); + log::verbose("Rcv BTM_LE_KEY_LCSRK"); pairing_cb.ble.is_lcsrk_key_rcvd = true; pairing_cb.ble.lcsrk_key = p_data->ble_key.p_key_value->lcsrk_key; break; case BTM_LE_KEY_LID: - LOG_VERBOSE("Rcv BTM_LE_KEY_LID"); + log::verbose("Rcv BTM_LE_KEY_LID"); pairing_cb.ble.is_lidk_key_rcvd = true; break; default: - LOG_ERROR("unknown BLE key type (0x%02x)", p_data->ble_key.key_type); + log::error("unknown BLE key type (0x{:02x})", + p_data->ble_key.key_type); break; } break; case BTA_DM_BLE_CONSENT_REQ_EVT: - LOG_VERBOSE("BTA_DM_BLE_CONSENT_REQ_EVT"); + log::verbose("BTA_DM_BLE_CONSENT_REQ_EVT"); btif_dm_ble_sec_req_evt(&p_data->ble_req, true); break; case BTA_DM_BLE_SEC_REQ_EVT: - LOG_VERBOSE("BTA_DM_BLE_SEC_REQ_EVT"); + log::verbose("BTA_DM_BLE_SEC_REQ_EVT"); btif_dm_ble_sec_req_evt(&p_data->ble_req, false); break; case BTA_DM_BLE_PASSKEY_NOTIF_EVT: - LOG_VERBOSE("BTA_DM_BLE_PASSKEY_NOTIF_EVT"); + log::verbose("BTA_DM_BLE_PASSKEY_NOTIF_EVT"); btif_dm_ble_key_notif_evt(&p_data->key_notif); break; case BTA_DM_BLE_PASSKEY_REQ_EVT: - LOG_VERBOSE("BTA_DM_BLE_PASSKEY_REQ_EVT"); + log::verbose("BTA_DM_BLE_PASSKEY_REQ_EVT"); btif_dm_ble_passkey_req_evt(&p_data->pin_req); break; case BTA_DM_BLE_NC_REQ_EVT: - LOG_VERBOSE("BTA_DM_BLE_PASSKEY_REQ_EVT"); + log::verbose("BTA_DM_BLE_PASSKEY_REQ_EVT"); btif_dm_ble_key_nc_req_evt(&p_data->key_notif); break; case BTA_DM_BLE_OOB_REQ_EVT: - LOG_VERBOSE("BTA_DM_BLE_OOB_REQ_EVT"); + log::verbose("BTA_DM_BLE_OOB_REQ_EVT"); btif_dm_ble_oob_req_evt(&p_data->rmt_oob); break; case BTA_DM_BLE_SC_OOB_REQ_EVT: - LOG_VERBOSE("BTA_DM_BLE_SC_OOB_REQ_EVT"); + log::verbose("BTA_DM_BLE_SC_OOB_REQ_EVT"); btif_dm_ble_sc_oob_req_evt(&p_data->rmt_oob); break; case BTA_DM_BLE_SC_CR_LOC_OOB_EVT: - LOG_VERBOSE("BTA_DM_BLE_SC_CR_LOC_OOB_EVT"); + log::verbose("BTA_DM_BLE_SC_CR_LOC_OOB_EVT"); btif_dm_proc_loc_oob(BT_TRANSPORT_LE, true, p_data->local_oob_data.local_oob_c, p_data->local_oob_data.local_oob_r); break; case BTA_DM_BLE_LOCAL_IR_EVT: - LOG_VERBOSE("BTA_DM_BLE_LOCAL_IR_EVT"); + log::verbose("BTA_DM_BLE_LOCAL_IR_EVT"); ble_local_key_cb.is_id_keys_rcvd = true; ble_local_key_cb.id_keys.irk = p_data->ble_id_keys.irk; ble_local_key_cb.id_keys.ir = p_data->ble_id_keys.ir; @@ -2311,7 +2456,7 @@ void btif_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { BTIF_DM_LE_LOCAL_KEY_DHK); break; case BTA_DM_BLE_LOCAL_ER_EVT: - LOG_VERBOSE("BTA_DM_BLE_LOCAL_ER_EVT"); + log::verbose("BTA_DM_BLE_LOCAL_ER_EVT"); ble_local_key_cb.is_er_rcvd = true; ble_local_key_cb.er = p_data->ble_er; btif_storage_add_ble_local_key(ble_local_key_cb.er, @@ -2319,7 +2464,7 @@ void btif_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { break; case BTA_DM_BLE_AUTH_CMPL_EVT: - LOG_VERBOSE("BTA_DM_BLE_AUTH_CMPL_EVT"); + log::verbose("BTA_DM_BLE_AUTH_CMPL_EVT"); btif_dm_ble_auth_cmpl_evt(&p_data->auth_cmpl); break; @@ -2333,8 +2478,13 @@ void btif_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { p_data->proc_id_addr.pairing_bda, p_data->proc_id_addr.id_addr); break; + case BTA_DM_KEY_MISSING_EVT: + GetInterfaceToProfiles()->events->invoke_key_missing_cb( + p_data->key_missing.bd_addr); + break; + default: - LOG_WARN("unhandled event(%d)", event); + log::warn("unhandled event({})", event); break; } } @@ -2354,7 +2504,7 @@ void btif_dm_acl_evt(tBTA_DM_ACL_EVT event, tBTA_DM_ACL* p_data) { switch (event) { case BTA_DM_LINK_UP_EVT: bd_addr = p_data->link_up.bd_addr; - LOG_VERBOSE("BTA_DM_LINK_UP_EVT. Sending BT_ACL_STATE_CONNECTED"); + log::verbose("BTA_DM_LINK_UP_EVT. Sending BT_ACL_STATE_CONNECTED"); btif_update_remote_version_property(&bd_addr); @@ -2365,6 +2515,13 @@ void btif_dm_acl_evt(tBTA_DM_ACL_EVT event, tBTA_DM_ACL* p_data) { ? bt_conn_direction_t::BT_CONN_DIRECTION_OUTGOING : bt_conn_direction_t::BT_CONN_DIRECTION_INCOMING, p_data->link_up.acl_handle); + + if (IS_FLAG_ENABLED(le_audio_fast_bond_params) && + p_data->link_up.transport_link_type == BT_TRANSPORT_LE && + pairing_cb.bd_addr == bd_addr && + is_device_le_audio_capable(bd_addr)) { + L2CA_LockBleConnParamsForProfileConnection(bd_addr, true); + } break; case BTA_DM_LINK_UP_FAILED_EVT: @@ -2402,13 +2559,12 @@ void btif_dm_acl_evt(tBTA_DM_ACL_EVT event, tBTA_DM_ACL* p_data) { (int)p_data->link_down.transport_link_type, static_cast(btm_get_acl_disc_reason_code()), direction, INVALID_ACL_HANDLE); - LOG_DEBUG( + log::debug( "Sent BT_ACL_STATE_DISCONNECTED upward as ACL link down event " - "device:%s reason:%s", + "device:{} reason:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), hci_reason_code_text( - static_cast(btm_get_acl_disc_reason_code())) - .c_str()); + static_cast(btm_get_acl_disc_reason_code()))); } break; case BTA_DM_LE_FEATURES_READ: btif_get_adapter_property(BT_PROPERTY_LOCAL_LE_FEATURES); @@ -2416,7 +2572,7 @@ void btif_dm_acl_evt(tBTA_DM_ACL_EVT event, tBTA_DM_ACL* p_data) { default: { - LOG_ERROR("Unexpected tBTA_DM_ACL_EVT:%d", event); + log::error("Unexpected tBTA_DM_ACL_EVT:{}", event); } break; } @@ -2437,9 +2593,9 @@ static void bta_energy_info_cb(tBTM_BLE_TX_TIME_MS tx_time, tBTM_BLE_ENERGY_USED energy_used, tBTM_CONTRL_STATE ctrl_state, tBTA_STATUS status) { - LOG_VERBOSE( - "energy_info_cb-Status:%d,state=%d,tx_t=%u, rx_t=%u, " - "idle_time=%u,used=%u", + log::verbose( + "energy_info_cb-Status:{},state={},tx_t={}, rx_t={}, " + "idle_time={},used={}", status, ctrl_state, tx_time, rx_time, idle_time, energy_used); if (uid_set != nullptr) { @@ -2454,7 +2610,7 @@ static void bta_energy_info_cb(tBTM_BLE_TX_TIME_MS tx_time, bt_uid_traffic_t* data = uid_set_read_and_clear(uid_set); GetInterfaceToProfiles()->events->invoke_energy_info_cb(energy_info, data); } else { - LOG_WARN("Energy info event dropped as module is inactive"); + log::warn("Energy info event dropped as module is inactive"); } } @@ -2472,7 +2628,7 @@ static void bta_energy_info_cb(tBTM_BLE_TX_TIME_MS tx_time, * ******************************************************************************/ void btif_dm_start_discovery(void) { - LOG_VERBOSE("start device discover/inquiry"); + log::verbose("start device discover/inquiry"); BTM_LogHistory( kBtmLogTag, RawAddress::kEmpty, "Device discovery", @@ -2481,7 +2637,7 @@ void btif_dm_start_discovery(void) { /* no race here because we're guaranteed to be in the main thread */ if (bta_dm_is_search_request_queued()) { - LOG_INFO("skipping start discovery because a request is queued"); + log::info("skipping start discovery because a request is queued"); return; } @@ -2500,7 +2656,7 @@ void btif_dm_start_discovery(void) { * ******************************************************************************/ void btif_dm_cancel_discovery(void) { - LOG_INFO("Cancel search"); + log::info("Cancel search"); BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Cancel discovery"); BTA_DmSearchCancel(); @@ -2518,8 +2674,8 @@ bool btif_dm_pairing_is_busy() { * ******************************************************************************/ void btif_dm_create_bond(const RawAddress bd_addr, int transport) { - LOG_VERBOSE("bd_addr=%s, transport=%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - transport); + log::verbose("bd_addr={}, transport={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + transport); BTM_LogHistory( kBtmLogTag, bd_addr, "Create bond", @@ -2541,8 +2697,8 @@ void btif_dm_create_bond(const RawAddress bd_addr, int transport) { ******************************************************************************/ void btif_dm_create_bond_le(const RawAddress bd_addr, tBLE_ADDR_TYPE addr_type) { - LOG_VERBOSE("bd_addr=%s, addr_type=%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - addr_type); + log::verbose("bd_addr={}, addr_type={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + addr_type); const tBLE_BD_ADDR ble_bd_addr{ .type = addr_type, .bda = bd_addr, @@ -2606,13 +2762,13 @@ void btif_dm_create_bond_out_of_band(const RawAddress bd_addr, // The controller only supports P192 switch (oob_cb.data_present) { case BTM_OOB_PRESENT_192_AND_256: - LOG_INFO("Have both P192 and P256"); + log::info("Have both P192 and P256"); [[fallthrough]]; case BTM_OOB_PRESENT_192: - LOG_INFO("Using P192"); + log::info("Using P192"); break; case BTM_OOB_PRESENT_256: - LOG_INFO("Using P256"); + log::info("Using P256"); // TODO(181889116): // Upgrade to support p256 (for now we just ignore P256) // because the controllers do not yet support it. @@ -2620,27 +2776,27 @@ void btif_dm_create_bond_out_of_band(const RawAddress bd_addr, BT_BOND_STATE_NONE); return; default: - LOG_ERROR("Invalid data present for controller:%d", - oob_cb.data_present); + log::error("Invalid data present for controller:{}", + oob_cb.data_present); bond_state_changed(BT_STATUS_PARM_INVALID, bd_addr, BT_BOND_STATE_NONE); return; } pairing_cb.is_local_initiated = true; - LOG_ERROR("Classic not implemented yet"); + log::error("Classic not implemented yet"); bond_state_changed(BT_STATUS_UNSUPPORTED, bd_addr, BT_BOND_STATE_NONE); return; case BT_TRANSPORT_LE: { // Guess default RANDOM for address type for LE tBLE_ADDR_TYPE address_type = BLE_ADDR_RANDOM; - LOG_INFO("Using LE Transport"); + log::info("Using LE Transport"); switch (oob_cb.data_present) { case BTM_OOB_PRESENT_192_AND_256: - LOG_INFO("Have both P192 and P256"); + log::info("Have both P192 and P256"); [[fallthrough]]; // Always prefer 256 for LE case BTM_OOB_PRESENT_256: - LOG_INFO("Using P256"); + log::info("Using P256"); // If we have an address, lets get the type if (memcmp(p256_data.address, empty, 7) != 0) { /* byte no 7 is address type in LE Bluetooth Address OOB data */ @@ -2648,7 +2804,7 @@ void btif_dm_create_bond_out_of_band(const RawAddress bd_addr, } break; case BTM_OOB_PRESENT_192: - LOG_INFO("Using P192"); + log::info("Using P192"); // If we have an address, lets get the type if (memcmp(p192_data.address, empty, 7) != 0) { /* byte no 7 is address type in LE Bluetooth Address OOB data */ @@ -2663,7 +2819,7 @@ void btif_dm_create_bond_out_of_band(const RawAddress bd_addr, break; } default: - LOG_ERROR("Invalid transport: %d", transport); + log::error("Invalid transport: {}", transport); bond_state_changed(BT_STATUS_PARM_INVALID, bd_addr, BT_BOND_STATE_NONE); return; } @@ -2677,7 +2833,7 @@ void btif_dm_create_bond_out_of_band(const RawAddress bd_addr, * ******************************************************************************/ void btif_dm_cancel_bond(const RawAddress bd_addr) { - LOG_VERBOSE("bd_addr=%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("bd_addr={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); BTM_LogHistory(kBtmLogTag, bd_addr, "Cancel bond"); @@ -2736,7 +2892,7 @@ void btif_dm_hh_open_failed(RawAddress* bdaddr) { ******************************************************************************/ void btif_dm_remove_bond(const RawAddress bd_addr) { - LOG_VERBOSE("bd_addr=%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("bd_addr={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); BTM_LogHistory(kBtmLogTag, bd_addr, "Remove bond"); @@ -2748,11 +2904,16 @@ void btif_dm_remove_bond(const RawAddress bd_addr) { // there is a valid hid connection with this bd_addr. If yes VUP will be // issued. #if (BTA_HH_INCLUDED == TRUE) + tAclLinkSpec link_spec; + link_spec.addrt.bda = bd_addr; + link_spec.transport = BT_TRANSPORT_AUTO; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + if (GetInterfaceToProfiles()->profileSpecific_HACK->btif_hh_virtual_unplug( - &bd_addr) != BT_STATUS_SUCCESS) + &link_spec) != BT_STATUS_SUCCESS) #endif { - LOG_DEBUG("Removing HH device"); + log::debug("Removing HH device"); BTA_DmRemoveDevice(bd_addr); } } @@ -2767,7 +2928,7 @@ void btif_dm_remove_bond(const RawAddress bd_addr) { void btif_dm_pin_reply(const RawAddress bd_addr, uint8_t accept, uint8_t pin_len, bt_pin_code_t pin_code) { - LOG_VERBOSE("accept=%d", accept); + log::verbose("accept={}", accept); if (pairing_cb.is_le_only) { int i; @@ -2778,7 +2939,7 @@ void btif_dm_pin_reply(const RawAddress bd_addr, uint8_t accept, } // TODO: // FIXME: should we hide part of passkey here? - LOG_VERBOSE("btif_dm_pin_reply: passkey: %d", passkey); + log::verbose("btif_dm_pin_reply: passkey: {}", passkey); BTA_DmBlePasskeyReply(bd_addr, accept, passkey); } else { @@ -2797,7 +2958,7 @@ void btif_dm_pin_reply(const RawAddress bd_addr, uint8_t accept, ******************************************************************************/ void btif_dm_ssp_reply(const RawAddress bd_addr, bt_ssp_variant_t variant, uint8_t accept) { - LOG_VERBOSE("accept=%d", accept); + log::verbose("accept={}", accept); BTM_LogHistory( kBtmLogTag, bd_addr, "Ssp reply", base::StringPrintf( @@ -2825,15 +2986,12 @@ void btif_dm_ssp_reply(const RawAddress bd_addr, bt_ssp_variant_t variant, * * Description Reads the system property configured class of device * - * Inputs A pointer to a DEV_CLASS that you want filled with the - * current class of device. Size is assumed to be 3. - * - * Returns Nothing. device_class will contain the current class of - * device. If no value is present, or the value is malformed - * the default "unclassified" value will be used + * Returns A DEV_CLASS containing the current class of device. + * If no value is present, or the value is malformed + * the default kEmpty value will be used * ******************************************************************************/ -void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { +DEV_CLASS btif_dm_get_local_class_of_device() { /* A class of device is a {SERVICE_CLASS, MAJOR_CLASS, MINOR_CLASS} * * The input is expected to be a string of the following format: @@ -2843,18 +3001,13 @@ void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { * * Notice there is always two commas and no spaces. */ - - device_class[0] = 0x00; - device_class[1] = BTM_COD_MAJOR_UNCLASSIFIED; - device_class[2] = BTM_COD_MINOR_UNCLASSIFIED; - char prop_cod[PROPERTY_VALUE_MAX]; osi_property_get(PROPERTY_CLASS_OF_DEVICE, prop_cod, ""); // If the property is empty, use the default if (prop_cod[0] == '\0') { - LOG_ERROR("COD property is empty"); - return; + log::error("COD property is empty"); + return kDevClassUnclassified; } // Start reading the contents of the property string. If at any point anything @@ -2870,29 +3023,29 @@ void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { prop_cod[i] != '\0') { char c = prop_cod[i++]; if (!std::isdigit(c)) { - LOG_ERROR("COD malformed, '%c' is a non-digit", c); - return; + log::error("COD malformed, '{:c}' is a non-digit", c); + return kDevClassUnclassified; } value += c; } // If we hit the end and it wasn't null terminated then return the default if (i == PROPERTY_VALUE_MAX && prop_cod[PROPERTY_VALUE_MAX - 1] != '\0') { - LOG_ERROR("COD malformed, value was truncated"); - return; + log::error("COD malformed, value was truncated"); + return kDevClassUnclassified; } // Each number in the list must be one byte, meaning 0 (0x00) -> 255 (0xFF) if (value.size() > 3 || value.size() == 0) { - LOG_ERROR("COD malformed, '%s' must be between [0, 255]", value.c_str()); - return; + log::error("COD malformed, '{}' must be between [0, 255]", value); + return kDevClassUnclassified; } // Grab the value. If it's too large, then return the default uint32_t uint32_val = static_cast(std::stoul(value.c_str())); if (uint32_val > 0xFF) { - LOG_ERROR("COD malformed, '%s' must be between [0, 255]", value.c_str()); - return; + log::error("COD malformed, '{}' must be between [0, 255]", value); + return kDevClassUnclassified; } // Otherwise, it's safe to use @@ -2901,8 +3054,8 @@ void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { // If we've reached 3 numbers then make sure we're at a null terminator if (j >= 3) { if (prop_cod[i] != '\0') { - LOG_ERROR("COD malformed, more than three numbers"); - return; + log::error("COD malformed, more than three numbers"); + return kDevClassUnclassified; } break; } @@ -2917,16 +3070,18 @@ void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { } // We must have read exactly 3 numbers + DEV_CLASS device_class = kDevClassUnclassified; if (j == 3) { device_class[0] = temp_device_class[0]; device_class[1] = temp_device_class[1]; device_class[2] = temp_device_class[2]; } else { - LOG_ERROR("COD malformed, fewer than three numbers"); + log::error("COD malformed, fewer than three numbers"); } - LOG_DEBUG("Using class of device '0x%x, 0x%x, 0x%x' from CoD system property", - device_class[0], device_class[1], device_class[2]); + log::debug( + "Using class of device '0x{:x}, 0x{:x}, 0x{:x}' from CoD system property", + device_class[0], device_class[1], device_class[2]); #ifdef __ANDROID__ // Per BAP 1.0.1, 8.2.3. Device discovery, the stack needs to set Class of @@ -2945,11 +3100,12 @@ void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { } else { device_class[1] &= ~(0x01 << 6); } - LOG_DEBUG( - "Check LE audio enabled status, update class of device to '0x%x, 0x%x, " - "0x%x'", + log::debug( + "Check LE audio enabled status, update class of device to '0x{:x}, " + "0x{:x}, 0x{:x}'", device_class[0], device_class[1], device_class[2]); #endif + return device_class; } /******************************************************************************* @@ -2962,7 +3118,7 @@ void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { * ******************************************************************************/ bt_status_t btif_dm_get_adapter_property(bt_property_t* prop) { - LOG_VERBOSE("type=0x%x", prop->type); + log::verbose("type=0x{:x}", prop->type); switch (prop->type) { case BT_PROPERTY_BDNAME: { bt_bdname_t* bd_name = (bt_bdname_t*)prop->val; @@ -3013,9 +3169,8 @@ bt_status_t btif_dm_get_adapter_property(bt_property_t* prop) { * ******************************************************************************/ void btif_dm_get_remote_services(RawAddress remote_addr, const int transport) { - LOG_VERBOSE("transport=%s, remote_addr=%s", - bt_transport_text(transport).c_str(), - ADDRESS_TO_LOGGABLE_CSTR(remote_addr)); + log::verbose("transport={}, remote_addr={}", bt_transport_text(transport), + ADDRESS_TO_LOGGABLE_CSTR(remote_addr)); BTM_LogHistory( kBtmLogTag, remote_addr, "Service discovery", @@ -3051,7 +3206,7 @@ void btif_dm_proc_io_req(tBTM_AUTH_REQ* p_auth_req, bool is_orig) { ** as a fallback set MITM+GB if peer had MITM set */ - LOG_VERBOSE("original p_auth_req=%d", *p_auth_req); + log::verbose("original p_auth_req={}", *p_auth_req); if (pairing_cb.is_local_initiated) { /* if initing/responding to a dedicated bonding, use dedicate bonding bit */ *p_auth_req = BTA_AUTH_DD_BOND | BTA_AUTH_SP_YES; @@ -3059,8 +3214,8 @@ void btif_dm_proc_io_req(tBTM_AUTH_REQ* p_auth_req, bool is_orig) { /* peer initiated paring. They probably know what they want. ** Copy the mitm from peer device. */ - LOG_DEBUG("peer initiated, setting p_auth_req to peer's: %d", - pairing_cb.auth_req); + log::debug("peer initiated, setting p_auth_req to peer's: {}", + pairing_cb.auth_req); *p_auth_req = (pairing_cb.auth_req & BTA_AUTH_BONDS); /* copy over the MITM bit as well. In addition if the peer has DisplayYesNo, @@ -3071,14 +3226,13 @@ void btif_dm_proc_io_req(tBTM_AUTH_REQ* p_auth_req, bool is_orig) { /* set the general bonding bit for stored device */ *p_auth_req = BTA_AUTH_GEN_BOND | yes_no_bit; } - LOG_VERBOSE("updated p_auth_req=%d", *p_auth_req); + log::verbose("updated p_auth_req={}", *p_auth_req); } -void btif_dm_proc_io_rsp(UNUSED_ATTR const RawAddress& bd_addr, - tBTM_IO_CAP io_cap, UNUSED_ATTR tBTM_OOB_DATA oob_data, - tBTM_AUTH_REQ auth_req) { +void btif_dm_proc_io_rsp(const RawAddress& /* bd_addr */, tBTM_IO_CAP io_cap, + tBTM_OOB_DATA /* oob_data */, tBTM_AUTH_REQ auth_req) { if (auth_req & BTA_AUTH_BONDS) { - LOG_DEBUG("auth_req:%d", auth_req); + log::debug("auth_req:{}", auth_req); pairing_cb.auth_req = auth_req; pairing_cb.io_cap = io_cap; } @@ -3090,7 +3244,7 @@ void btif_dm_set_oob_for_io_req(tBTM_OOB_DATA* p_has_oob_data) { } else { *p_has_oob_data = true; } - LOG_VERBOSE("*p_has_oob_data=%d", *p_has_oob_data); + log::verbose("*p_has_oob_data={}", *p_has_oob_data); } void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, @@ -3098,11 +3252,11 @@ void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, tBTM_LE_AUTH_REQ* p_auth_req) { switch (oob_cb.data_present) { case BTM_OOB_PRESENT_192_AND_256: - LOG_INFO("Have both P192 and P256"); + log::info("Have both P192 and P256"); [[fallthrough]]; // Always prefer 256 for LE case BTM_OOB_PRESENT_256: - LOG_INFO("Using P256"); + log::info("Using P256"); if (!is_empty_128bit(oob_cb.p256_data.c) && !is_empty_128bit(oob_cb.p256_data.r)) { /* make sure OOB data is for this particular device */ @@ -3111,7 +3265,7 @@ void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, *p_has_oob_data = true; } else { *p_has_oob_data = false; - LOG_WARN("P256-1: Remote address didn't match OOB data address"); + log::warn("P256-1: Remote address didn't match OOB data address"); } } else if (!is_empty_128bit(oob_cb.p256_data.sm_tk)) { /* We have security manager TK */ @@ -3124,14 +3278,14 @@ void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, *p_has_oob_data = true; } else { *p_has_oob_data = false; - LOG_WARN("P256-2: Remote address didn't match OOB data address"); + log::warn("P256-2: Remote address didn't match OOB data address"); } } else { *p_has_oob_data = false; } break; case BTM_OOB_PRESENT_192: - LOG_INFO("Using P192"); + log::info("Using P192"); if (!is_empty_128bit(oob_cb.p192_data.c) && !is_empty_128bit(oob_cb.p192_data.r)) { /* make sure OOB data is for this particular device */ @@ -3140,7 +3294,7 @@ void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, *p_has_oob_data = true; } else { *p_has_oob_data = false; - LOG_WARN("P192-1: Remote address didn't match OOB data address"); + log::warn("P192-1: Remote address didn't match OOB data address"); } } else if (!is_empty_128bit(oob_cb.p192_data.sm_tk)) { /* We have security manager TK */ @@ -3153,24 +3307,23 @@ void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, *p_has_oob_data = true; } else { *p_has_oob_data = false; - LOG_WARN("P192-2: Remote address didn't match OOB data address"); + log::warn("P192-2: Remote address didn't match OOB data address"); } } else { *p_has_oob_data = false; } break; } - LOG_VERBOSE("*p_has_oob_data=%d", *p_has_oob_data); + log::verbose("*p_has_oob_data={}", *p_has_oob_data); } -#ifdef BTIF_DM_OOB_TEST void btif_dm_load_local_oob(void) { char prop_oob[PROPERTY_VALUE_MAX]; osi_property_get("service.brcm.bt.oob", prop_oob, "3"); - LOG_VERBOSE("prop_oob = %s", prop_oob); + log::verbose("prop_oob = {}", prop_oob); if (prop_oob[0] != '3') { if (is_empty_128bit(oob_cb.p192_data.c)) { - LOG_VERBOSE("read OOB, call BTA_DmLocalOob()"); + log::verbose("read OOB, call BTA_DmLocalOob()"); BTA_DmLocalOob(); } } @@ -3180,7 +3333,7 @@ static bool waiting_on_oob_advertiser_start = false; static std::optional oob_advertiser_id_; static void stop_oob_advertiser() { // For chasing an advertising bug b/237023051 - LOG_DEBUG("oob_advertiser_id: %d", oob_advertiser_id_.value()); + log::debug("oob_advertiser_id: {}", oob_advertiser_id_.value()); auto advertiser = bluetooth::shim::get_ble_advertiser_instance(); advertiser->Unregister(oob_advertiser_id_.value()); oob_advertiser_id_ = {}; @@ -3196,7 +3349,7 @@ static void stop_oob_advertiser() { * ******************************************************************************/ void btif_dm_generate_local_oob_data(tBT_TRANSPORT transport) { - LOG_DEBUG("Transport %s", bt_transport_text(transport).c_str()); + log::debug("Transport {}", bt_transport_text(transport)); if (transport == BT_TRANSPORT_BR_EDR) { BTM_ReadLocalOobData(); } else if (transport == BT_TRANSPORT_LE) { @@ -3205,7 +3358,7 @@ void btif_dm_generate_local_oob_data(tBT_TRANSPORT transport) { // advertising then request the address. if (!waiting_on_oob_advertiser_start) { // For chasing an advertising bug b/237023051 - LOG_DEBUG("oob_advertiser_id: %d", oob_advertiser_id_.value_or(255)); + log::debug("oob_advertiser_id: {}", oob_advertiser_id_.value_or(255)); if (oob_advertiser_id_.has_value()) { stop_oob_advertiser(); } @@ -3236,7 +3389,7 @@ static void start_advertising_callback(uint8_t id, tBT_TRANSPORT transport, bool is_valid, const Octet16& c, const Octet16& r, tBTM_STATUS status) { if (status != 0) { - LOG_INFO("OOB get advertiser ID failed with status %hhd", status); + log::info("OOB get advertiser ID failed with status {}", status); GetInterfaceToProfiles()->events->invoke_oob_data_request_cb( transport, false, c, r, RawAddress{}, 0x00); SMP_ClearLocScOobData(); @@ -3244,15 +3397,14 @@ static void start_advertising_callback(uint8_t id, tBT_TRANSPORT transport, oob_advertiser_id_ = {}; return; } - LOG_DEBUG("OOB advertiser with id %hhd", id); + log::debug("OOB advertiser with id {}", id); auto advertiser = bluetooth::shim::get_ble_advertiser_instance(); advertiser->GetOwnAddress( id, base::Bind(&get_address_callback, transport, is_valid, c, r)); } static void timeout_cb(uint8_t id, tBTM_STATUS status) { - LOG_INFO("OOB advertiser with id %hhd timed out with status %hhd", id, - status); + log::info("OOB advertiser with id {} timed out with status {}", id, status); auto advertiser = bluetooth::shim::get_ble_advertiser_instance(); advertiser->Unregister(id); SMP_ClearLocScOobData(); @@ -3265,7 +3417,7 @@ static void id_status_callback(tBT_TRANSPORT transport, bool is_valid, const Octet16& c, const Octet16& r, uint8_t id, tBTM_STATUS status) { if (status != 0) { - LOG_INFO("OOB get advertiser ID failed with status %hhd", status); + log::info("OOB get advertiser ID failed with status {}", status); GetInterfaceToProfiles()->events->invoke_oob_data_request_cb( transport, false, c, r, RawAddress{}, 0x00); SMP_ClearLocScOobData(); @@ -3275,7 +3427,7 @@ static void id_status_callback(tBT_TRANSPORT transport, bool is_valid, } oob_advertiser_id_ = id; - LOG_INFO("oob_advertiser_id: %d", id); + log::info("oob_advertiser_id: {}", id); auto advertiser = bluetooth::shim::get_ble_advertiser_instance(); AdvertiseParameters parameters{}; @@ -3347,7 +3499,7 @@ void btif_dm_proc_loc_oob(tBT_TRANSPORT transport, bool is_valid, bool btif_dm_get_smp_config(tBTE_APPL_CFG* p_cfg) { const std::string* recv = stack_config_get_interface()->get_pts_smp_options(); if (!recv) { - LOG_WARN("SMP pairing options not found in stack configuration"); + log::warn("SMP pairing options not found in stack configuration"); return false; } @@ -3398,23 +3550,23 @@ bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, Octet16* p_c, const char* path = NULL; char prop_oob[PROPERTY_VALUE_MAX]; osi_property_get("service.brcm.bt.oob", prop_oob, "3"); - LOG_DEBUG("prop_oob = %s", prop_oob); + log::debug("prop_oob = {}", prop_oob); if (prop_oob[0] == '1') path = path_b; else if (prop_oob[0] == '2') path = path_a; if (!path) { - LOG_DEBUG("can't open path!"); + log::debug("can't open path!"); return false; } FILE* fp = fopen(path, "rb"); if (fp == NULL) { - LOG_DEBUG("failed to read OOB keys from %s", path); + log::debug("failed to read OOB keys from {}", path); return false; } - LOG_VERBOSE("read OOB data from %s", path); + log::verbose("read OOB data from {}", path); (void)fread(p_c->data(), 1, OCTET16_LEN, fp); (void)fread(p_r->data(), 1, OCTET16_LEN, fp); fclose(fp); @@ -3422,7 +3574,6 @@ bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, Octet16* p_c, bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING); return true; } -#endif /* BTIF_DM_OOB_TEST */ static void btif_dm_ble_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif) { RawAddress bd_addr; @@ -3430,15 +3581,15 @@ static void btif_dm_ble_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif) { uint32_t cod; int dev_type; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_ssp_key_notif->bd_addr)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_ssp_key_notif->bd_addr)); /* Remote name update */ if (!btif_get_device_type(p_ssp_key_notif->bd_addr, &dev_type)) { dev_type = BT_DEVICE_TYPE_BLE; } - btif_dm_update_ble_remote_properties( - p_ssp_key_notif->bd_addr, p_ssp_key_notif->bd_name, - nullptr /* dev_class */, (tBT_DEVICE_TYPE)dev_type); + btif_dm_update_ble_remote_properties(p_ssp_key_notif->bd_addr, + p_ssp_key_notif->bd_name, kDevClassEmpty, + (tBT_DEVICE_TYPE)dev_type); bd_addr = p_ssp_key_notif->bd_addr; memcpy(bd_name.name, p_ssp_key_notif->bd_name, BD_NAME_LEN); bd_name.name[BD_NAME_LEN] = '\0'; @@ -3457,6 +3608,18 @@ static void btif_dm_ble_key_notif_evt(tBTA_DM_SP_KEY_NOTIF* p_ssp_key_notif) { p_ssp_key_notif->passkey); } +static bool btif_dm_ble_is_temp_pairing(RawAddress& bd_addr, bool ctkd) { + if (btm_get_bond_type_dev(bd_addr) == BOND_TYPE_TEMPORARY) { + if (!IS_FLAG_ENABLED(ignore_bond_type_for_le)) { + return true; + } + + return ctkd; + } + + return false; +} + /******************************************************************************* * * Function btif_dm_ble_auth_cmpl_evt @@ -3489,8 +3652,8 @@ static void btif_dm_ble_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { btif_storage_set_remote_addr_type(&bd_addr, p_auth_cmpl->addr_type); /* Test for temporary bonding */ - if (btm_get_bond_type_dev(bd_addr) == BOND_TYPE_TEMPORARY) { - LOG_DEBUG("sending BT_BOND_STATE_NONE for Temp pairing"); + if (btif_dm_ble_is_temp_pairing(bd_addr, p_auth_cmpl->is_ctkd)) { + log::debug("sending BT_BOND_STATE_NONE for Temp pairing"); btif_storage_remove_bonded_device(&bd_addr); state = BT_BOND_STATE_NONE; } else { @@ -3498,15 +3661,15 @@ static void btif_dm_ble_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { if (pairing_cb.gatt_over_le == btif_dm_pairing_cb_t::ServiceDiscoveryState::NOT_STARTED) { - LOG_INFO("scheduling GATT discovery over LE for %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("scheduling GATT discovery over LE for {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); pairing_cb.gatt_over_le = btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED; btif_dm_get_remote_services(bd_addr, BT_TRANSPORT_LE); } else { - LOG_INFO( + log::info( "skipping GATT discovery over LE - was already scheduled or " - "finished for %s, state: %d", + "finished for {}, state: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), pairing_cb.gatt_over_le); } } @@ -3514,8 +3677,8 @@ static void btif_dm_ble_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { /* Map the HCI fail reason to bt status */ // TODO This is not a proper use of the type uint8_t fail_reason = static_cast(p_auth_cmpl->fail_reason); - LOG_ERROR("LE authentication for %s failed with reason %d", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p_auth_cmpl->fail_reason); + log::error("LE authentication for {} failed with reason {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p_auth_cmpl->fail_reason); switch (fail_reason) { case BTA_DM_AUTH_SMP_PAIR_AUTH_FAIL: case BTA_DM_AUTH_SMP_CONFIRM_VALUE_FAIL: @@ -3526,15 +3689,15 @@ static void btif_dm_ble_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { case BTA_DM_AUTH_SMP_CONN_TOUT: { if (!p_auth_cmpl->is_ctkd && btm_sec_is_a_bonded_dev(bd_addr)) { - LOG_WARN( - "Bonded device addr=%s, timed out - will not remove the keys", + log::warn( + "Bonded device addr={}, timed out - will not remove the keys", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); // Don't send state change to upper layers - otherwise Java think we // unbonded, and will disconnect HID profile. return; } - LOG_INFO( - "Removing ble bonding keys on SMP_CONN_TOUT during crosskey: %d", + log::info( + "Removing ble bonding keys on SMP_CONN_TOUT during crosskey: {}", p_auth_cmpl->is_ctkd); btif_dm_remove_ble_bonding_keys(); status = BT_STATUS_AUTH_FAILURE; @@ -3565,7 +3728,7 @@ void btif_dm_load_ble_local_keys(void) { if (btif_storage_get_ble_local_key( BTIF_DM_LE_LOCAL_KEY_ER, &ble_local_key_cb.er) == BT_STATUS_SUCCESS) { ble_local_key_cb.is_er_rcvd = true; - LOG_VERBOSE("BLE ER key loaded"); + log::verbose("BLE ER key loaded"); } if ((btif_storage_get_ble_local_key(BTIF_DM_LE_LOCAL_KEY_IR, @@ -3578,7 +3741,7 @@ void btif_dm_load_ble_local_keys(void) { &ble_local_key_cb.id_keys.dhk) == BT_STATUS_SUCCESS)) { ble_local_key_cb.is_id_keys_rcvd = true; - LOG_VERBOSE("BLE ID keys loaded"); + log::verbose("BLE ID keys loaded"); } } void btif_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK* p_key_mask, @@ -3598,14 +3761,14 @@ void btif_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK* p_key_mask, p_id_keys->dhk = ble_local_key_cb.id_keys.dhk; *p_key_mask |= BTA_BLE_LOCAL_KEY_TYPE_ID; } - LOG_VERBOSE("*p_key_mask=0x%02x", *p_key_mask); + log::verbose("*p_key_mask=0x{:02x}", *p_key_mask); } static void btif_dm_save_ble_bonding_keys(RawAddress& bd_addr) { - LOG_VERBOSE("%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (bd_addr.IsEmpty()) { - LOG_WARN("bd_addr is empty"); + log::warn("bd_addr is empty"); return; } @@ -3646,7 +3809,7 @@ static void btif_dm_save_ble_bonding_keys(RawAddress& bd_addr) { } static void btif_dm_remove_ble_bonding_keys(void) { - LOG_VERBOSE("removing ble bonding keys"); + log::verbose("removing ble bonding keys"); RawAddress bd_addr = pairing_cb.bd_addr; btif_storage_remove_ble_bonding_keys(&bd_addr); @@ -3667,10 +3830,10 @@ static void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, uint32_t cod; int dev_type; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_ble_req->bd_addr)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_ble_req->bd_addr)); if (!is_consent && pairing_cb.state == BT_BOND_STATE_BONDING) { - LOG_WARN("Discard security request"); + log::warn("Discard security request"); return; } @@ -3679,7 +3842,7 @@ static void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, dev_type = BT_DEVICE_TYPE_BLE; } btif_dm_update_ble_remote_properties(p_ble_req->bd_addr, p_ble_req->bd_name, - nullptr /* dev_class */, + kDevClassEmpty, (tBT_DEVICE_TYPE)dev_type); RawAddress bd_addr = p_ble_req->bd_addr; @@ -3723,7 +3886,7 @@ static void btif_dm_ble_passkey_req_evt(tBTA_DM_PIN_REQ* p_pin_req) { dev_type = BT_DEVICE_TYPE_BLE; } btif_dm_update_ble_remote_properties(p_pin_req->bd_addr, p_pin_req->bd_name, - nullptr /* dev_class */, + kDevClassEmpty, (tBT_DEVICE_TYPE)dev_type); RawAddress bd_addr = p_pin_req->bd_addr; @@ -3743,11 +3906,11 @@ static void btif_dm_ble_passkey_req_evt(tBTA_DM_PIN_REQ* p_pin_req) { } static void btif_dm_ble_key_nc_req_evt(tBTA_DM_SP_KEY_NOTIF* p_notif_req) { /* TODO implement key notification for numeric comparison */ - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_notif_req->bd_addr)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_notif_req->bd_addr)); /* Remote name update */ btif_update_remote_properties(p_notif_req->bd_addr, p_notif_req->bd_name, - nullptr /* dev_class */, BT_DEVICE_TYPE_BLE); + kDevClassEmpty, BT_DEVICE_TYPE_BLE); RawAddress bd_addr = p_notif_req->bd_addr; @@ -3771,7 +3934,7 @@ static void btif_dm_ble_key_nc_req_evt(tBTA_DM_SP_KEY_NOTIF* p_notif_req) { } static void btif_dm_ble_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(req_oob_type->bd_addr)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(req_oob_type->bd_addr)); RawAddress bd_addr = req_oob_type->bd_addr; /* We already checked if OOB data is present in @@ -3784,13 +3947,13 @@ static void btif_dm_ble_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) { /* make sure OOB data is for this particular device */ if (req_oob_type->bd_addr != oob_cb.bdaddr) { - LOG_WARN("remote address didn't match OOB data address"); + log::warn("remote address didn't match OOB data address"); return; } /* Remote name update */ btif_update_remote_properties(req_oob_type->bd_addr, req_oob_type->bd_name, - nullptr /* dev_class */, BT_DEVICE_TYPE_BLE); + kDevClassEmpty, BT_DEVICE_TYPE_BLE); bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING); pairing_cb.is_ssp = false; @@ -3802,12 +3965,12 @@ static void btif_dm_ble_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) { static void btif_dm_ble_sc_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) { RawAddress bd_addr = req_oob_type->bd_addr; - LOG_VERBOSE("bd_addr: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); - LOG_VERBOSE("oob_cb.bdaddr: %s", ADDRESS_TO_LOGGABLE_CSTR(oob_cb.bdaddr)); + log::verbose("bd_addr: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("oob_cb.bdaddr: {}", ADDRESS_TO_LOGGABLE_CSTR(oob_cb.bdaddr)); /* make sure OOB data is for this particular device */ if (req_oob_type->bd_addr != oob_cb.bdaddr) { - LOG_ERROR("remote address didn't match OOB data address"); + log::error("remote address didn't match OOB data address"); return; } @@ -3818,23 +3981,23 @@ static void btif_dm_ble_sc_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) { bt_oob_data_t oob_data_to_use = {}; switch (oob_cb.data_present) { case BTM_OOB_PRESENT_192_AND_256: - LOG_INFO("Have both P192 and P256"); + log::info("Have both P192 and P256"); [[fallthrough]]; // Always prefer 256 for LE case BTM_OOB_PRESENT_256: - LOG_INFO("Using P256"); + log::info("Using P256"); if (is_empty_128bit(oob_cb.p256_data.c) && is_empty_128bit(oob_cb.p256_data.r)) { - LOG_WARN("P256 LE SC OOB data is empty"); + log::warn("P256 LE SC OOB data is empty"); return; } oob_data_to_use = oob_cb.p256_data; break; case BTM_OOB_PRESENT_192: - LOG_INFO("Using P192"); + log::info("Using P192"); if (is_empty_128bit(oob_cb.p192_data.c) && is_empty_128bit(oob_cb.p192_data.r)) { - LOG_WARN("P192 LE SC OOB data is empty"); + log::warn("P192 LE SC OOB data is empty"); return; } oob_data_to_use = oob_cb.p192_data; @@ -3843,8 +4006,8 @@ static void btif_dm_ble_sc_oob_req_evt(tBTA_DM_SP_RMT_OOB* req_oob_type) { /* Remote name update */ btif_update_remote_properties(req_oob_type->bd_addr, - oob_data_to_use.device_name, - nullptr /* dev_class */, BT_DEVICE_TYPE_BLE); + oob_data_to_use.device_name, kDevClassEmpty, + BT_DEVICE_TYPE_BLE); bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING); pairing_cb.is_ssp = false; @@ -3902,7 +4065,7 @@ void btif_ble_test_end() { BTM_BleTestEnd(btif_dm_ble_test_end_cback); } void btif_dm_on_disable() { /* cancel any pending pairing requests */ if (is_bonding_or_sdp()) { - LOG_VERBOSE("Cancel pending pairing request"); + log::verbose("Cancel pending pairing request"); btif_dm_cancel_bond(pairing_cb.bd_addr); } } @@ -4012,6 +4175,9 @@ void btif_debug_bond_event_dump(int fd) { case BTIF_DM_FUNC_BOND_STATE_CHANGED: func_name = "bond_state_changed "; break; + case BTIF_DM_FUNC_CANCEL_BOND: + func_name = "btif_dm_cancel_bond"; + break; default: func_name = "Invalid value "; break; @@ -4044,10 +4210,12 @@ bool btif_get_device_type(const RawAddress& bda, int* p_device_type) { std::string addrstr = bda.ToString(); const char* bd_addr_str = addrstr.c_str(); - if (!btif_config_get_int(bd_addr_str, "DevType", p_device_type)) return false; + if (!btif_config_get_int(bd_addr_str, BTIF_STORAGE_KEY_DEV_TYPE, + p_device_type)) + return false; tBT_DEVICE_TYPE device_type = static_cast(*p_device_type); - LOG_DEBUG("bd_addr:%s device_type:%s", ADDRESS_TO_LOGGABLE_CSTR(bda), - DeviceTypeText(device_type).c_str()); + log::debug("bd_addr:{} device_type:{}", ADDRESS_TO_LOGGABLE_CSTR(bda), + DeviceTypeText(device_type)); return true; } @@ -4059,10 +4227,11 @@ bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type) { const char* bd_addr_str = addrstr.c_str(); int val = 0; - if (!btif_config_get_int(bd_addr_str, "AddrType", &val)) return false; + if (!btif_config_get_int(bd_addr_str, BTIF_STORAGE_KEY_ADDR_TYPE, &val)) + return false; *p_addr_type = static_cast(val); - LOG_DEBUG("bd_addr:%s[%s]", ADDRESS_TO_LOGGABLE_CSTR(bda), - AddressTypeText(*p_addr_type).c_str()); + log::debug("bd_addr:{}[{}]", ADDRESS_TO_LOGGABLE_CSTR(bda), + AddressTypeText(*p_addr_type)); return true; } @@ -4110,7 +4279,8 @@ void btif_dm_metadata_changed(const RawAddress& remote_bd_addr, int key, static const int METADATA_LE_AUDIO = 26; /* If METADATA_LE_AUDIO is present, device is LE Audio capable */ if (key == METADATA_LE_AUDIO) { - LOG_INFO("Device is LE Audio Capable %s", ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); + log::info("Device is LE Audio Capable {}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); metadata_cb.le_audio_cache.insert_or_assign(remote_bd_addr, value); } } @@ -4128,6 +4298,11 @@ void bta_energy_info_cb(tBTM_BLE_TX_TIME_MS tx_time, status); } +void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, + tBTA_DM_SEARCH* p_data) { + ::btif_dm_search_services_evt(event, p_data); +} + } // namespace testing } // namespace legacy } // namespace bluetooth diff --git a/system/btif/src/btif_gatt_client.cc b/system/btif/src/btif_gatt_client.cc index 5e5c9c3f728db719af38a1640bfd07d8d8ef35c9..73bf14975df17a268d48f720ecd0dbd6d3bf5b39 100644 --- a/system/btif/src/btif_gatt_client.cc +++ b/system/btif/src/btif_gatt_client.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -44,11 +45,13 @@ #include "btif_gatt.h" #include "btif_gatt_util.h" #include "device/include/controller.h" +#include "include/check.h" #include "os/log.h" #include "osi/include/allocator.h" #include "stack/include/acl_api.h" #include "stack/include/acl_api_types.h" #include "stack/include/main_thread.h" +#include "storage/config_keys.h" #include "types/ble_address_with_type.h" #include "types/bluetooth/uuid.h" #include "types/bt_transport.h" @@ -58,6 +61,7 @@ using base::Bind; using base::Owned; using bluetooth::Uuid; using std::vector; +using namespace bluetooth; bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type); bool btif_get_device_type(const RawAddress& bda, int* p_device_type); @@ -72,7 +76,7 @@ extern const btgatt_callbacks_t* bt_gatt_callbacks; #define CLI_CBACK_WRAP_IN_JNI(P_CBACK, P_CBACK_WRAP) \ do { \ if (bt_gatt_callbacks && bt_gatt_callbacks->client->P_CBACK) { \ - LOG_VERBOSE("HAL bt_gatt_callbacks->client->%s", #P_CBACK); \ + log::verbose("HAL bt_gatt_callbacks->client->{}", #P_CBACK); \ do_in_jni_thread(P_CBACK_WRAP); \ } else { \ ASSERTC(0, "Callback is NULL", 0); \ @@ -82,21 +86,21 @@ extern const btgatt_callbacks_t* bt_gatt_callbacks; #define CLI_CBACK_IN_JNI(P_CBACK, ...) \ do { \ if (bt_gatt_callbacks && bt_gatt_callbacks->client->P_CBACK) { \ - LOG_VERBOSE("HAL bt_gatt_callbacks->client->%s", #P_CBACK); \ + log::verbose("HAL bt_gatt_callbacks->client->{}", #P_CBACK); \ do_in_jni_thread(Bind(bt_gatt_callbacks->client->P_CBACK, __VA_ARGS__)); \ } else { \ ASSERTC(0, "Callback is NULL", 0); \ } \ } while (0) -#define CHECK_BTGATT_INIT() \ - do { \ - if (bt_gatt_callbacks == NULL) { \ - LOG_WARN("%s: BTGATT not initialized", __func__); \ - return BT_STATUS_NOT_READY; \ - } else { \ - LOG_DEBUG("%s", __func__); \ - } \ +#define CHECK_BTGATT_INIT() \ + do { \ + if (bt_gatt_callbacks == NULL) { \ + log::warn("BTGATT not initialized"); \ + return BT_STATUS_NOT_READY; \ + } else { \ + log::debug(""); \ + } \ } while (0) namespace { @@ -104,9 +108,8 @@ namespace { uint8_t rssi_request_client_if; static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) { - LOG_DEBUG("Event %s [%d]", - gatt_client_event_text(static_cast(event)).c_str(), - event); + log::debug("Event {} [{}]", + gatt_client_event_text(static_cast(event)), event); tBTA_GATTC* p_data = (tBTA_GATTC*)p_param; switch (event) { @@ -142,8 +145,8 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) { } case BTA_GATTC_OPEN_EVT: { - LOG_DEBUG("BTA_GATTC_OPEN_EVT %s", - ADDRESS_TO_LOGGABLE_CSTR(p_data->open.remote_bda)); + log::debug("BTA_GATTC_OPEN_EVT {}", + ADDRESS_TO_LOGGABLE_CSTR(p_data->open.remote_bda)); HAL_CBACK(bt_gatt_callbacks, client->open_cb, p_data->open.conn_id, p_data->open.status, p_data->open.client_if, p_data->open.remote_bda); @@ -171,7 +174,7 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) { case BTA_GATTC_SEARCH_RES_EVT: case BTA_GATTC_CANCEL_OPEN_EVT: case BTA_GATTC_SRVC_DISC_DONE_EVT: - LOG_DEBUG("Ignoring event (%d)", event); + log::debug("Ignoring event ({})", event); break; case BTA_GATTC_CFG_MTU_EVT: { @@ -212,14 +215,14 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) { break; default: - LOG_ERROR("Unhandled event (%d)!", event); + log::error("Unhandled event ({})!", event); break; } } static void bta_gattc_cback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { - LOG_DEBUG(" gatt client callback event:%s [%d]", - gatt_client_event_text(event).c_str(), event); + log::debug("gatt client callback event:{} [{}]", + gatt_client_event_text(event), event); bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt, (uint16_t)event, (char*)p_data, sizeof(tBTA_GATTC), NULL); @@ -296,7 +299,7 @@ void btif_gattc_open_impl(int client_if, RawAddress address, // Check for privacy 1.0 and 1.1 controller and do not start background // connection if RPA offloading is not supported, since it will not // connect after change of random address - if (!controller_get_interface()->supports_ble_privacy() && + if (!controller_get_interface()->SupportsBlePrivacy() && (addr_type == BLE_ADDR_RANDOM) && BTM_BLE_IS_RESOLVE_BDA(address)) { tBTM_BLE_VSC_CB vnd_capabilities; BTM_BleGetVendorCapabilities(&vnd_capabilities); @@ -328,14 +331,14 @@ void btif_gattc_open_impl(int client_if, RawAddress address, transport = BT_TRANSPORT_BR_EDR; break; default: - LOG_ERROR("Unknown device type %d", +device_type); + log::error("Unknown device type {}", device_type); break; } } // Connect! - LOG_INFO("Transport=%d, device type=%d, address type =%d, phy=%d", transport, - device_type, addr_type, initiating_phys); + log::info("Transport={}, device type={}, address type ={}, phy={}", transport, + device_type, addr_type, initiating_phys); tBTM_BLE_CONN_TYPE type = is_direct ? BTM_BLE_DIRECT_CONNECTION : BTM_BLE_BKG_CONNECT_ALLOW_LIST; BTA_GATTC_Open(client_if, address, addr_type, type, transport, opportunistic, @@ -354,8 +357,8 @@ static bt_status_t btif_gattc_open(int client_if, const RawAddress& bd_addr, } void btif_gattc_close_impl(int client_if, RawAddress address, int conn_id) { - LOG_INFO("client_if=%d, conn_id=%d, address=%s", client_if, conn_id, - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("client_if={}, conn_id={}, address={}", client_if, conn_id, + ADDRESS_TO_LOGGABLE_CSTR(address)); // Disconnect established connections if (conn_id != 0) { BTA_GATTC_Close(conn_id); @@ -650,7 +653,8 @@ static bt_status_t btif_gattc_read_phy( static int btif_gattc_get_device_type(const RawAddress& bd_addr) { int device_type = 0; - if (btif_config_get_int(bd_addr.ToString().c_str(), "DevType", &device_type)) + if (btif_config_get_int(bd_addr.ToString().c_str(), BTIF_STORAGE_KEY_DEV_TYPE, + &device_type)) return device_type; return 0; } diff --git a/system/btif/src/btif_gatt_server.cc b/system/btif/src/btif_gatt_server.cc index 7f4ecdb58f1232f30d509fbeb8f0d10fb9637f58..8b5fe9d016aeca0c80bbd8190501ca72234bc627 100644 --- a/system/btif/src/btif_gatt_server.cc +++ b/system/btif/src/btif_gatt_server.cc @@ -27,6 +27,7 @@ #define LOG_TAG "bt_btif_gatt" #include +#include #include #include #include @@ -53,19 +54,20 @@ bool btif_get_device_type(const RawAddress& bda, int* p_device_type); using base::Bind; using bluetooth::Uuid; using std::vector; +using namespace bluetooth; /******************************************************************************* * Constants & Macros ******************************************************************************/ -#define CHECK_BTGATT_INIT() \ - do { \ - if (bt_gatt_callbacks == NULL) { \ - LOG_WARN("%s: BTGATT not initialized", __func__); \ - return BT_STATUS_NOT_READY; \ - } else { \ - LOG_VERBOSE("%s", __func__); \ - } \ +#define CHECK_BTGATT_INIT() \ + do { \ + if (bt_gatt_callbacks == NULL) { \ + log::warn("BTGATT not initialized"); \ + return BT_STATUS_NOT_READY; \ + } else { \ + log::verbose(""); \ + } \ } while (0) /******************************************************************************* @@ -124,7 +126,7 @@ static void btapp_gatts_free_req_data(uint16_t event, tBTA_GATTS* p_data) { } static void btapp_gatts_handle_cback(uint16_t event, char* p_param) { - LOG_VERBOSE("%s: Event %d", __func__, event); + log::verbose("Event {}", event); tBTA_GATTS* p_data = (tBTA_GATTS*)p_param; switch (event) { @@ -229,7 +231,7 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) { case BTA_GATTS_OPEN_EVT: case BTA_GATTS_CANCEL_OPEN_EVT: case BTA_GATTS_CLOSE_EVT: - LOG_INFO("%s: Empty event (%d)!", __func__, event); + log::info("Empty event ({})!", event); break; case BTA_GATTS_PHY_UPDATE_EVT: @@ -253,7 +255,7 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) { break; default: - LOG_ERROR("%s: Unhandled event (%d)!", __func__, event); + log::error("Unhandled event ({})!", event); break; } @@ -362,7 +364,7 @@ static void add_service_impl(int server_if, // refactored, and one can distinguish stack-internal aps from external apps if (service[0].uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER) || service[0].uuid == Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER)) { - LOG_ERROR("%s: Attept to register restricted service", __func__); + log::error("Attept to register restricted service"); HAL_CBACK(bt_gatt_callbacks, server->service_added_cb, BT_STATUS_FAIL, server_if, service.data(), service.size()); return; diff --git a/system/btif/src/btif_gatt_test.cc b/system/btif/src/btif_gatt_test.cc index d423c6a6655c54e801f0ad6e83be4e42745045d8..e8ac0276c815c819bd3a8552f7860978276204c3 100644 --- a/system/btif/src/btif_gatt_test.cc +++ b/system/btif/src/btif_gatt_test.cc @@ -18,6 +18,7 @@ #define LOG_TAG "bt_btif_gatt" +#include #include #include #include @@ -27,13 +28,14 @@ #include "gatt_api.h" #include "internal_include/bte_appl.h" #include "os/log.h" -#include "osi/include/osi.h" #include "stack/include/btm_ble_sec_api.h" #include "types/ble_address_with_type.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; + /******************************************************************************* * Typedefs & Macros ******************************************************************************/ @@ -63,15 +65,15 @@ static btif_test_cb_t test_cb; static void btif_test_connect_cback(tGATT_IF, const RawAddress&, uint16_t conn_id, bool connected, tGATT_DISCONN_REASON, tBT_TRANSPORT) { - LOG_INFO("%s: conn_id=%d, connected=%d", __func__, conn_id, connected); + log::info("conn_id={}, connected={}", conn_id, connected); test_cb.conn_id = connected ? conn_id : 0; } static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE* p_data) { - LOG_INFO("%s: op_code=0x%02x, conn_id=0x%x. status=0x%x", __func__, op, - conn_id, status); + log::info("op_code=0x{:02x}, conn_id=0x{:x}. status=0x{:x}", op, conn_id, + status); switch (op) { case GATTC_OPTYPE_READ: @@ -86,69 +88,67 @@ static void btif_test_command_complete_cback(uint16_t conn_id, tGATTC_OPTYPE op, break; default: - LOG_INFO("%s: Unknown op_code (0x%02x)", __func__, op); + log::info("Unknown op_code (0x{:02x})", op); break; } } -static void btif_test_discovery_result_cback(UNUSED_ATTR uint16_t conn_id, +static void btif_test_discovery_result_cback(uint16_t /* conn_id */, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES* p_data) { - LOG_INFO("------ GATT Discovery result %-22s -------", disc_name[disc_type]); - LOG_INFO(" Attribute handle: 0x%04x (%d)", p_data->handle, - p_data->handle); + log::info("------ GATT Discovery result {:<22s} -------", + disc_name[disc_type]); + log::info("Attribute handle: 0x{:04x} ({})", p_data->handle, p_data->handle); if (disc_type != GATT_DISC_CHAR_DSCPT) { - LOG_INFO(" Attribute type: %s", p_data->type.ToString().c_str()); + log::info("Attribute type: {}", p_data->type.ToString()); } switch (disc_type) { case GATT_DISC_SRVC_ALL: - LOG_INFO(" Handle range: 0x%04x ~ 0x%04x (%d ~ %d)", - p_data->handle, p_data->value.group_value.e_handle, - p_data->handle, p_data->value.group_value.e_handle); - LOG_INFO(" Service UUID: %s", - p_data->value.group_value.service_type.ToString().c_str()); + log::info("Handle range: 0x{:04x} ~ 0x{:04x} ({} ~ {})", p_data->handle, + p_data->value.group_value.e_handle, p_data->handle, + p_data->value.group_value.e_handle); + log::info("Service UUID: {}", + p_data->value.group_value.service_type.ToString()); break; case GATT_DISC_SRVC_BY_UUID: - LOG_INFO(" Handle range: 0x%04x ~ 0x%04x (%d ~ %d)", - p_data->handle, p_data->value.handle, p_data->handle, - p_data->value.handle); + log::info("Handle range: 0x{:04x} ~ 0x{:04x} ({} ~ {})", p_data->handle, + p_data->value.handle, p_data->handle, p_data->value.handle); break; case GATT_DISC_INC_SRVC: - LOG_INFO(" Handle range: 0x%04x ~ 0x%04x (%d ~ %d)", - p_data->value.incl_service.s_handle, - p_data->value.incl_service.e_handle, - p_data->value.incl_service.s_handle, - p_data->value.incl_service.e_handle); - LOG_INFO(" Service UUID: %s", - p_data->value.incl_service.service_type.ToString().c_str()); + log::info("Handle range: 0x{:04x} ~ 0x{:04x} ({} ~ {})", + p_data->value.incl_service.s_handle, + p_data->value.incl_service.e_handle, + p_data->value.incl_service.s_handle, + p_data->value.incl_service.e_handle); + log::info("Service UUID: {}", + p_data->value.incl_service.service_type.ToString()); break; case GATT_DISC_CHAR: - LOG_INFO(" Properties: 0x%02x", - p_data->value.dclr_value.char_prop); - LOG_INFO(" Characteristic UUID: %s", - p_data->value.dclr_value.char_uuid.ToString().c_str()); + log::info("Properties: 0x{:02x}", p_data->value.dclr_value.char_prop); + log::info("Characteristic UUID: {}", + p_data->value.dclr_value.char_uuid.ToString()); break; case GATT_DISC_CHAR_DSCPT: - LOG_INFO(" Descriptor UUID: %s", p_data->type.ToString().c_str()); + log::info("Descriptor UUID: {}", p_data->type.ToString()); break; case GATT_DISC_MAX: - LOG_ERROR(" Unknown discovery item"); + log::error("Unknown discovery item"); break; } - LOG_INFO("-----------------------------------------------------------"); + log::info("-----------------------------------------------------------"); } -static void btif_test_discovery_complete_cback( - UNUSED_ATTR uint16_t conn_id, UNUSED_ATTR tGATT_DISC_TYPE disc_type, - tGATT_STATUS status) { - LOG_INFO("%s: status=%d", __func__, status); +static void btif_test_discovery_complete_cback(uint16_t /* conn_id */, + tGATT_DISC_TYPE /* disc_type */, + tGATT_STATUS status) { + log::info("status={}", status); } static tGATT_CBACK btif_test_callbacks = { @@ -173,7 +173,7 @@ bt_status_t btif_gattc_test_command_impl(int command, switch (command) { case 0x01: /* Enable */ { - LOG_INFO("%s: ENABLE - enable=%d", __func__, params->u1); + log::info("ENABLE - enable={}", params->u1); if (params->u1) { std::array tmp; tmp.fill(0xAE); @@ -190,8 +190,9 @@ bt_status_t btif_gattc_test_command_impl(int command, case 0x02: /* Connect */ { - LOG_INFO("%s: CONNECT - device=%s (dev_type=%d, addr_type=%d)", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*params->bda1), params->u1, params->u2); + log::info("CONNECT - device={} (dev_type={}, addr_type={})", + ADDRESS_TO_LOGGABLE_CSTR(*params->bda1), params->u1, + params->u2); if (params->u1 == BT_DEVICE_TYPE_BLE) BTM_SecAddBleDevice(*params->bda1, BT_DEVICE_TYPE_BLE, @@ -199,14 +200,14 @@ bt_status_t btif_gattc_test_command_impl(int command, if (!GATT_Connect(test_cb.gatt_if, *params->bda1, BTM_BLE_DIRECT_CONNECTION, BT_TRANSPORT_LE, false)) { - LOG_ERROR("%s: GATT_Connect failed!", __func__); + log::error("GATT_Connect failed!"); } break; } case 0x03: /* Disconnect */ { - LOG_INFO("%s: DISCONNECT - conn_id=%d", __func__, test_cb.conn_id); + log::info("DISCONNECT - conn_id={}", test_cb.conn_id); GATT_Disconnect(test_cb.conn_id); break; } @@ -214,22 +215,21 @@ bt_status_t btif_gattc_test_command_impl(int command, case 0x04: /* Discover */ { if (params->u1 >= GATT_DISC_MAX) { - LOG_ERROR("%s: DISCOVER - Invalid type (%d)!", __func__, params->u1); + log::error("DISCOVER - Invalid type ({})!", params->u1); return (bt_status_t)0; } - LOG_INFO("%s: DISCOVER (%s), conn_id=%d, uuid=%s, handles=0x%04x-0x%04x", - __func__, disc_name[params->u1], test_cb.conn_id, - params->uuid1->ToString().c_str(), params->u2, params->u3); + log::info("DISCOVER ({}), conn_id={}, uuid={}, handles=0x{:04x}-0x{:04x}", + disc_name[params->u1], test_cb.conn_id, + params->uuid1->ToString(), params->u2, params->u3); GATTC_Discover(test_cb.conn_id, static_cast(params->u1), params->u2, params->u3, *params->uuid1); break; } case 0xF0: /* Pairing configuration */ - LOG_INFO("%s: Setting pairing config auth=%d, iocaps=%d, keys=%d/%d/%d", - __func__, params->u1, params->u2, params->u3, params->u4, - params->u5); + log::info("Setting pairing config auth={}, iocaps={}, keys={}/{}/{}", + params->u1, params->u2, params->u3, params->u4, params->u5); bte_appl_cfg.ble_auth_req = params->u1; bte_appl_cfg.ble_io_cap = params->u2; @@ -239,7 +239,7 @@ bt_status_t btif_gattc_test_command_impl(int command, break; default: - LOG_ERROR("%s: UNKNOWN TEST COMMAND 0x%02x", __func__, command); + log::error("UNKNOWN TEST COMMAND 0x{:02x}", command); break; } return (bt_status_t)0; diff --git a/system/btif/src/btif_gatt_util.cc b/system/btif/src/btif_gatt_util.cc index 36365316bf69f153dba82fe8f40064f2c28a6c35..b7f89b2b895b87d404807dc40100717124953c1b 100644 --- a/system/btif/src/btif_gatt_util.cc +++ b/system/btif/src/btif_gatt_util.cc @@ -22,6 +22,7 @@ #include "btif_gatt_util.h" +#include #include #include #include @@ -32,10 +33,9 @@ #include "bta/include/bta_sec_api.h" #include "btif_storage.h" #include "common/init_flags.h" -#include "gd/os/system_properties.h" #include "os/log.h" +#include "os/system_properties.h" #include "osi/include/allocator.h" -#include "osi/include/osi.h" #include "stack/btm/btm_sec.h" #include "stack/include/acl_api.h" #include "types/ble_address_with_type.h" @@ -44,6 +44,7 @@ #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; /******************************************************************************* * BTIF -> BTA conversion functions @@ -65,11 +66,11 @@ static bool btif_gatt_is_link_encrypted(const RawAddress& bd_addr) { BTM_IsEncrypted(bd_addr, BT_TRANSPORT_LE); } -static void btif_gatt_set_encryption_cb(UNUSED_ATTR const RawAddress& bd_addr, - UNUSED_ATTR tBT_TRANSPORT transport, +static void btif_gatt_set_encryption_cb(const RawAddress& /* bd_addr */, + tBT_TRANSPORT /* transport */, tBTA_STATUS result) { if (result != BTA_SUCCESS && result != BTA_BUSY) { - LOG_WARN("%s() - Encryption failed (%d)", __func__, result); + log::warn("Encryption failed ({})", result); } } @@ -80,14 +81,14 @@ void btif_gatt_check_encrypted_link(RawAddress bd_addr, BTM_ReadConnectionAddr(bd_addr, raw_local_addr, &local_addr_type); tBLE_BD_ADDR local_addr{local_addr_type, raw_local_addr}; if (!local_addr.IsPublic() && !local_addr.IsAddressResolvable()) { - LOG_DEBUG("Not establishing encryption since address type is NRPA"); + log::debug("Not establishing encryption since address type is NRPA"); return; } static const bool check_encrypted = bluetooth::os::GetSystemPropertyBool( "bluetooth.gatt.check_encrypted_link.enabled", true); if (!check_encrypted) { - LOG_DEBUG("Check skipped due to system config"); + log::debug("Check skipped due to system config"); return; } tBTM_LE_PENC_KEYS key; @@ -95,9 +96,9 @@ void btif_gatt_check_encrypted_link(RawAddress bd_addr, bd_addr, BTM_LE_KEY_PENC, (uint8_t*)&key, sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) && !btif_gatt_is_link_encrypted(bd_addr)) { - LOG_DEBUG("Checking gatt link peer:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport_link).c_str()); + log::debug("Checking gatt link peer:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport_link)); BTA_DmSetEncryption(bd_addr, transport_link, &btif_gatt_set_encryption_cb, BTM_BLE_SEC_ENCRYPT); } diff --git a/system/btif/src/btif_hd.cc b/system/btif/src/btif_hd.cc index 53d0a463a33ec985de6555fe346795c1f39f9dd3..4112c16061a9b4da86a4fb8954e0ac510e9fd658 100644 --- a/system/btif/src/btif_hd.cc +++ b/system/btif/src/btif_hd.cc @@ -29,17 +29,19 @@ #include "btif/include/btif_hd.h" +#include + #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/include/bta_hd_api.h" -#include "bta_sec_api.h" #include "bta/sys/bta_sys.h" +#include "bta_sec_api.h" #include "btif/include/btif_common.h" #include "btif/include/btif_profile_storage.h" #include "btif/include/btif_util.h" -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "include/hardware/bt_hd.h" +#include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "types/raw_address.h" @@ -54,6 +56,8 @@ #define COD_HID_COMBO 0x05C0 #define COD_HID_MAJOR 0x0500 +using namespace bluetooth; + bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr); bool check_cod_hid(const RawAddress* remote_bdaddr); bool check_cod_hid(const RawAddress& bd_addr); @@ -142,11 +146,11 @@ void btif_hd_remove_device(RawAddress bd_addr) { static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { tBTA_HD* p_data = (tBTA_HD*)p_param; - LOG_VERBOSE("%s: event=%s", __func__, dump_hd_event(event)); + log::verbose("event={}", dump_hd_event(event)); switch (event) { case BTA_HD_ENABLE_EVT: - LOG_VERBOSE("%s: status=%d", __func__, p_data->status); + log::verbose("status={}", p_data->status); if (p_data->status == BTA_HD_OK) { btif_storage_load_hidd(); btif_hd_cb.status = BTIF_HD_ENABLED; @@ -157,16 +161,16 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { } } else { btif_hd_cb.status = BTIF_HD_DISABLED; - LOG_WARN("Failed to enable BT-HD, status=%d", p_data->status); + log::warn("Failed to enable BT-HD, status={}", p_data->status); } break; case BTA_HD_DISABLE_EVT: - LOG_VERBOSE("%s: status=%d", __func__, p_data->status); + log::verbose("status={}", p_data->status); btif_hd_cb.status = BTIF_HD_DISABLED; if (btif_hd_cb.service_dereg_active) { bta_sys_deregister(BTA_ID_HD); - LOG_WARN("registering hid host now"); + log::warn("registering hid host now"); btif_hh_service_registration(TRUE); btif_hd_cb.service_dereg_active = FALSE; } @@ -174,7 +178,7 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { if (p_data->status == BTA_HD_OK) memset(&btif_hd_cb, 0, sizeof(btif_hd_cb)); else - LOG_WARN("Failed to disable BT-HD, status=%d", p_data->status); + log::warn("Failed to disable BT-HD, status={}", p_data->status); break; case BTA_HD_REGISTER_APP_EVT: { @@ -184,7 +188,7 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { addr = NULL; } - LOG_INFO("Registering HID device app"); + log::info("Registering HID device app"); btif_hd_cb.app_registered = TRUE; HAL_CBACK(bt_hd_callbacks, application_state_cb, addr, BTHD_APP_STATE_REGISTERED); @@ -195,7 +199,7 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { HAL_CBACK(bt_hd_callbacks, application_state_cb, NULL, BTHD_APP_STATE_NOT_REGISTERED); if (btif_hd_cb.service_dereg_active) { - LOG_WARN("disabling hid device service now"); + log::warn("disabling hid device service now"); if (!bluetooth::common::init_flags:: delay_hidh_cleanup_until_hidh_ready_start_is_enabled()) { btif_hd_free_buf(); @@ -206,11 +210,11 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { case BTA_HD_OPEN_EVT: { RawAddress* addr = (RawAddress*)&p_data->conn.bda; - LOG_WARN("BTA_HD_OPEN_EVT, address=%s", ADDRESS_TO_LOGGABLE_CSTR(*addr)); + log::warn("BTA_HD_OPEN_EVT, address={}", ADDRESS_TO_LOGGABLE_CSTR(*addr)); /* Check if the connection is from hid host and not hid device */ if (check_cod_hid(addr)) { /* Incoming connection from hid device, reject it */ - LOG_WARN("remote device is not hid host, disconnecting"); + log::warn("remote device is not hid host, disconnecting"); btif_hd_cb.forced_disc = TRUE; BTA_HdDisconnect(); break; @@ -224,7 +228,7 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { case BTA_HD_CLOSE_EVT: if (btif_hd_cb.forced_disc) { RawAddress* addr = (RawAddress*)&p_data->conn.bda; - LOG_WARN("remote device was forcefully disconnected"); + log::warn("remote device was forcefully disconnected"); btif_hd_remove_device(*addr); btif_hd_cb.forced_disc = FALSE; break; @@ -257,15 +261,11 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { HAL_CBACK(bt_hd_callbacks, connection_state_cb, (RawAddress*)&p_data->conn.bda, BTHD_CONN_STATE_DISCONNECTED); if (bta_dm_check_if_only_hd_connected(p_data->conn.bda)) { - LOG_VERBOSE("%s: Removing bonding as only HID profile connected", - __func__); + log::verbose("Removing bonding as only HID profile connected"); BTA_DmRemoveDevice(p_data->conn.bda); } else { RawAddress* bd_addr = (RawAddress*)&p_data->conn.bda; - LOG_VERBOSE( - "%s: Only removing HID data as some other profiles " - "connected", - __func__); + log::verbose("Only removing HID data as some other profiles connected"); btif_hd_remove_device(*bd_addr); } HAL_CBACK(bt_hd_callbacks, vc_unplug_cb); @@ -278,7 +278,7 @@ static void btif_hd_upstreams_evt(uint16_t event, char* p_param) { break; default: - LOG_WARN("%s: unknown event (%d)", __func__, event); + log::warn("unknown event ({})", event); break; } } @@ -298,7 +298,7 @@ static void bte_hd_evt(tBTA_HD_EVT event, tBTA_HD* p_data) { int param_len = 0; tBTIF_COPY_CBACK* p_copy_cback = NULL; - LOG_VERBOSE("%s event=%d", __func__, event); + log::verbose("event={}", event); switch (event) { case BTA_HD_ENABLE_EVT: @@ -353,7 +353,7 @@ static void bte_hd_evt(tBTA_HD_EVT event, tBTA_HD* p_data) { * ******************************************************************************/ static bt_status_t init(bthd_callbacks_t* callbacks) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); bt_hd_callbacks = callbacks; memset(&btif_hd_cb, 0, sizeof(btif_hd_cb)); @@ -373,7 +373,7 @@ static bt_status_t init(bthd_callbacks_t* callbacks) { * ******************************************************************************/ static void cleanup(void) { - LOG_VERBOSE("hd:%s", __func__); + log::verbose(""); if (bt_hd_callbacks) { /* update flag, not to enable hid host service now as BT is switching off */ @@ -395,10 +395,10 @@ static void cleanup(void) { static bt_status_t register_app(bthd_app_param_t* p_app_param, bthd_qos_param_t* p_in_qos, bthd_qos_param_t* p_out_qos) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (btif_hd_cb.app_registered) { - LOG_WARN("%s: application already registered", __func__); + log::warn("application already registered"); return BT_STATUS_DONE; } @@ -447,20 +447,20 @@ static bt_status_t register_app(bthd_app_param_t* p_app_param, * ******************************************************************************/ static bt_status_t unregister_app(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!btif_hd_cb.app_registered) { - LOG_WARN("%s: application not yet registered", __func__); + log::warn("application not yet registered"); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { - LOG_WARN("%s: BT-HD not enabled, status=%d", __func__, btif_hd_cb.status); + log::warn("BT-HD not enabled, status={}", btif_hd_cb.status); return BT_STATUS_NOT_READY; } if (btif_hd_cb.service_dereg_active) { - LOG_WARN("%s: BT-HD deregistering in progress", __func__); + log::warn("BT-HD deregistering in progress"); return BT_STATUS_BUSY; } @@ -480,15 +480,15 @@ static bt_status_t unregister_app(void) { * ******************************************************************************/ static bt_status_t connect(RawAddress* bd_addr) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!btif_hd_cb.app_registered) { - LOG_WARN("%s: application not yet registered", __func__); + log::warn("application not yet registered"); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { - LOG_WARN("%s: BT-HD not enabled, status=%d", __func__, btif_hd_cb.status); + log::warn("BT-HD not enabled, status={}", btif_hd_cb.status); return BT_STATUS_NOT_READY; } @@ -507,15 +507,15 @@ static bt_status_t connect(RawAddress* bd_addr) { * ******************************************************************************/ static bt_status_t disconnect(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!btif_hd_cb.app_registered) { - LOG_WARN("%s: application not yet registered", __func__); + log::warn("application not yet registered"); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { - LOG_WARN("%s: BT-HD not enabled, status=%d", __func__, btif_hd_cb.status); + log::warn("BT-HD not enabled, status={}", btif_hd_cb.status); return BT_STATUS_NOT_READY; } @@ -537,15 +537,15 @@ static bt_status_t send_report(bthd_report_type_t type, uint8_t id, uint16_t len, uint8_t* p_data) { tBTA_HD_REPORT report; - LOG_VERBOSE("%s: type=%d id=%d len=%d", __func__, type, id, len); + log::verbose("type={} id={} len={}", type, id, len); if (!btif_hd_cb.app_registered) { - LOG_WARN("%s: application not yet registered", __func__); + log::warn("application not yet registered"); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { - LOG_WARN("%s: BT-HD not enabled, status=%d", __func__, btif_hd_cb.status); + log::warn("BT-HD not enabled, status={}", btif_hd_cb.status); return BT_STATUS_NOT_READY; } @@ -576,15 +576,15 @@ static bt_status_t send_report(bthd_report_type_t type, uint8_t id, * ******************************************************************************/ static bt_status_t report_error(uint8_t error) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!btif_hd_cb.app_registered) { - LOG_WARN("%s: application not yet registered", __func__); + log::warn("application not yet registered"); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { - LOG_WARN("%s: BT-HD not enabled, status=%d", __func__, btif_hd_cb.status); + log::warn("BT-HD not enabled, status={}", btif_hd_cb.status); return BT_STATUS_NOT_READY; } @@ -603,15 +603,15 @@ static bt_status_t report_error(uint8_t error) { * ******************************************************************************/ static bt_status_t virtual_cable_unplug(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!btif_hd_cb.app_registered) { - LOG_WARN("%s: application not yet registered", __func__); + log::warn("application not yet registered"); return BT_STATUS_NOT_READY; } if (btif_hd_cb.status != BTIF_HD_ENABLED) { - LOG_WARN("%s: BT-HD not enabled, status=%d", __func__, btif_hd_cb.status); + log::warn("BT-HD not enabled, status={}", btif_hd_cb.status); return BT_STATUS_NOT_READY; } @@ -643,7 +643,7 @@ static const bthd_interface_t bthdInterface = { * ******************************************************************************/ bt_status_t btif_hd_execute_service(bool b_enable) { - LOG_VERBOSE("%s: b_enable=%d", __func__, b_enable); + log::verbose("b_enable={}", b_enable); if (!b_enable) BTA_HdDisable(); @@ -660,7 +660,7 @@ bt_status_t btif_hd_execute_service(bool b_enable) { * ******************************************************************************/ const bthd_interface_t* btif_hd_get_interface() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return &bthdInterface; } @@ -674,7 +674,7 @@ const bthd_interface_t* btif_hd_get_interface() { * ******************************************************************************/ void btif_hd_service_registration() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* enable HD */ if (bt_hd_callbacks != NULL) { BTA_HdEnable(bte_hd_evt); diff --git a/system/btif/src/btif_hf.cc b/system/btif/src/btif_hf.cc index 1fec690400072b5679ace3fc9a453629afbf8ed2..6539d66df7bb94fc69d767520968e296b2f18706 100644 --- a/system/btif/src/btif_hf.cc +++ b/system/btif/src/btif_hf.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,7 @@ #include "btif/include/btif_util.h" #include "common/metrics.h" #include "device/include/device_iot_config.h" +#include "include/check.h" #include "include/hardware/bluetooth_headset_callbacks.h" #include "include/hardware/bluetooth_headset_interface.h" #include "include/hardware/bt_hf.h" @@ -93,14 +95,14 @@ static RawAddress active_bda = {}; ******************************************************************************/ static Callbacks* bt_hf_callbacks = nullptr; -#define CHECK_BTHF_INIT() \ - do { \ - if (!bt_hf_callbacks) { \ - LOG_WARN("BTHF: %s: BTHF not initialized", __func__); \ - return BT_STATUS_NOT_READY; \ - } else { \ - LOG_VERBOSE("BTHF: %s", __func__); \ - } \ +#define CHECK_BTHF_INIT() \ + do { \ + if (!bt_hf_callbacks) { \ + log::warn("BTHF not initialized"); \ + return BT_STATUS_NOT_READY; \ + } else { \ + log::verbose("BTHF ok"); \ + } \ } while (false) /* BTIF-HF control block to map bdaddr to BTA handle */ @@ -151,9 +153,8 @@ static tBTA_SERVICE_MASK get_BTIF_HF_SERVICES() { /* HF features supported at runtime */ static uint32_t get_hf_features() { #if TARGET_FLOSS -#define DEFAULT_BTIF_HF_FEATURES \ - (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECS | BTA_AG_FEAT_CODEC | BTA_AG_FEAT_UNAT | \ - BTA_AG_FEAT_HF_IND) +#define DEFAULT_BTIF_HF_FEATURES \ + (BTA_AG_FEAT_ECS | BTA_AG_FEAT_CODEC | BTA_AG_FEAT_UNAT | BTA_AG_FEAT_HF_IND) #else #define DEFAULT_BTIF_HF_FEATURES \ (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | BTA_AG_FEAT_REJECT | \ @@ -285,13 +286,13 @@ static void reset_control_block(btif_hf_cb_t* hf_cb) { */ static bool IsSlcConnected(RawAddress* bd_addr) { if (!bd_addr) { - LOG(WARNING) << __func__ << ": bd_addr is null"; + log::warn("bd_addr is null"); return false; } int idx = btif_hf_idx_by_bdaddr(bd_addr); if (idx < 0 || idx > BTA_AG_MAX_NUM_CLIENTS) { - LOG(WARNING) << __func__ << ": invalid index " << idx << " for " - << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::warn("invalid index {} for {}", idx, + ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return false; } return btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_SLC_CONNECTED; @@ -308,32 +309,32 @@ static bool IsSlcConnected(RawAddress* bd_addr) { ******************************************************************************/ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { if (event == BTA_AG_ENABLE_EVT || event == BTA_AG_DISABLE_EVT) { - LOG(INFO) << __func__ << ": AG enable/disable event " << event; + log::info("AG enable/disable event {}", event); return; } if (p_param == nullptr) { - LOG(ERROR) << __func__ << ": parameter is null"; + log::error("parameter is null"); return; } tBTA_AG* p_data = (tBTA_AG*)p_param; int idx = p_data->hdr.handle - 1; - LOG_DEBUG("HF Upstream event:%s", dump_hf_event(event)); + log::debug("HF Upstream event:{}", dump_hf_event(event)); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s Invalid client index:%d", dump_hf_event(event), idx); + log::error("{} Invalid client index:{}", dump_hf_event(event), idx); return; } if (!bt_hf_callbacks) { - LOG_ERROR("%s Headset callback is not set", dump_hf_event(event)); + log::error("{} Headset callback is not set", dump_hf_event(event)); return; } switch (event) { case BTA_AG_REGISTER_EVT: btif_hf_cb[idx].handle = p_data->reg.hdr.handle; - LOG_DEBUG("%s idx:%d btif_hf_cb.handle = %d", dump_hf_event(event), idx, - btif_hf_cb[idx].handle); + log::debug("{} idx:{} btif_hf_cb.handle = {}", dump_hf_event(event), idx, + btif_hf_cb[idx].handle); break; // RFCOMM connected or failed to connect case BTA_AG_OPEN_EVT: @@ -349,22 +350,21 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { // Check if the incoming open event and the outgoing connection are // for the same device. if (p_data->open.bd_addr == btif_hf_cb[idx].connected_bda) { - LOG(WARNING) << __func__ << ": btif_hf_cb state[" - << p_data->open.status - << "] is not expected, possible connection collision, " - "ignoring AG open " - "failure event for the same device " - << ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr); + log::warn( + "btif_hf_cb state[{}] is not expected, possible connection " + "collision, ignoring AG open failure event for the same device " + "{}", + p_data->open.status, + ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr)); } else { - LOG(WARNING) << __func__ << ": btif_hf_cb state[" - << p_data->open.status - << "] is not expected, possible connection collision, " - "ignoring AG open failure " - "event for the different devices btif_hf_cb bda: " - << btif_hf_cb[idx].connected_bda - << ", p_data bda: " - << ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr) - << ", report disconnect state for p_data bda."; + log::warn( + "btif_hf_cb state[{}] is not expected, possible connection " + "collision, ignoring AG open failure event for the different " + "devices btif_hf_cb bda: {}, p_data bda: {}, report disconnect " + "state for p_data bda.", + p_data->open.status, + ADDRESS_TO_LOGGABLE_STR(btif_hf_cb[idx].connected_bda), + ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr)); bt_hf_callbacks->ConnectionStateCallback( BTHF_CONNECTION_STATE_DISCONNECTED, &(p_data->open.bd_addr)); log_counter_metrics_btif( @@ -384,14 +384,12 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { // Check if the incoming open event and the outgoing connection are // for the same device. if (btif_hf_cb[idx].connected_bda != p_data->open.bd_addr) { - LOG(WARNING) << __func__ - << ": possible connection collision, ignore the " - "outgoing connection for the " - "different devices btif_hf_cb bda: " - << ADDRESS_TO_LOGGABLE_STR(btif_hf_cb[idx].connected_bda) - << ", p_data bda: " - << ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr) - << ", report disconnect state for btif_hf_cb bda."; + log::warn( + "possible connection collision, ignore the outgoing connection " + "for the different devices btif_hf_cb bda: {}, p_data bda: {}, " + "report disconnect state for btif_hf_cb bda.", + ADDRESS_TO_LOGGABLE_STR(btif_hf_cb[idx].connected_bda), + ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr)); bt_hf_callbacks->ConnectionStateCallback( BTHF_CONNECTION_STATE_DISCONNECTED, &(btif_hf_cb[idx].connected_bda)); @@ -425,16 +423,14 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { } else { if (!btif_hf_cb[idx].is_initiator) { // Ignore remote initiated open failures - LOG(WARNING) << __func__ << ": Unexpected AG open failure " - << std::to_string(p_data->open.status) << " for " - << ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr) - << " is ignored"; + log::warn("Unexpected AG open failure {} for {} is ignored", + p_data->open.status, + ADDRESS_TO_LOGGABLE_STR(p_data->open.bd_addr)); break; } - LOG(ERROR) << __func__ << ": self initiated AG open failed for " - << ADDRESS_TO_LOGGABLE_STR(btif_hf_cb[idx].connected_bda) - << ", status " - << std::to_string(p_data->open.status); + log::error("self initiated AG open failed for {}, status {}", + ADDRESS_TO_LOGGABLE_STR(btif_hf_cb[idx].connected_bda), + p_data->open.status); RawAddress connected_bda = btif_hf_cb[idx].connected_bda; reset_control_block(&btif_hf_cb[idx]); bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, @@ -448,9 +444,9 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { } break; case BTA_AG_CLOSE_EVT: { - LOG_DEBUG( - "SLC and RFCOMM both disconnected event:%s idx:%d" - " btif_hf_cb.handle:%d", + log::debug( + "SLC and RFCOMM both disconnected event:{} idx:{} " + "btif_hf_cb.handle:{}", dump_hf_event(event), idx, btif_hf_cb[idx].handle); RawAddress connected_bda = btif_hf_cb[idx].connected_bda; bt_hf_callbacks->ConnectionStateCallback( @@ -465,7 +461,8 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, &connected_bda); if (failed_to_setup_slc) { - LOG(ERROR) << __func__ << ": failed to setup SLC for " << connected_bda; + log::error("failed to setup SLC for {}", + ADDRESS_TO_LOGGABLE_STR(connected_bda)); log_counter_metrics_btif( android::bluetooth::CodePathCounterKeyEnum::HFP_SLC_SETUP_FAILED, 1); @@ -486,7 +483,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { btif_hf_cb[idx].connected_bda, IOT_CONF_KEY_HFP_FEATURES, p_data->conn.peer_feat, IOT_CONF_BYTE_NUM_2); - LOG_DEBUG("SLC connected event:%s idx:%d", dump_hf_event(event), idx); + log::debug("SLC connected event:{} idx:{}", dump_hf_event(event), idx); btif_hf_cb[idx].peer_feat = p_data->conn.peer_feat; btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_SLC_CONNECTED; bt_hf_callbacks->ConnectionStateCallback(btif_hf_cb[idx].state, @@ -497,13 +494,13 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { break; case BTA_AG_AUDIO_OPEN_EVT: - LOG_DEBUG("Audio open event:%s", dump_hf_event(event)); + log::debug("Audio open event:{}", dump_hf_event(event)); bt_hf_callbacks->AudioStateCallback(BTHF_AUDIO_STATE_CONNECTED, &btif_hf_cb[idx].connected_bda); break; case BTA_AG_AUDIO_CLOSE_EVT: - LOG_DEBUG("Audio close event:%s", dump_hf_event(event)); + log::debug("Audio close event:{}", dump_hf_event(event)); DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(btif_hf_cb[idx].connected_bda, IOT_CONF_KEY_HFP_SCO_CONN_FAIL_COUNT); @@ -514,8 +511,8 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { case BTA_AG_SPK_EVT: case BTA_AG_MIC_EVT: - LOG_DEBUG("BTA auto-responds, silently discard event:%s", - dump_hf_event(event)); + log::debug("BTA auto-responds, silently discard event:{}", + dump_hf_event(event)); bt_hf_callbacks->VolumeControlCallback( (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK : BTHF_VOLUME_TYPE_MIC, @@ -569,8 +566,8 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { break; case BTA_AG_CODEC_EVT: - LOG_VERBOSE( - "BTA_AG_CODEC_EVT Set codec status %d codec %d 1=CVSD 2=MSBC 4=LC3", + log::verbose( + "BTA_AG_CODEC_EVT Set codec status {} codec {} 1=CVSD 2=MSBC 4=LC3", p_data->val.hdr.status, p_data->val.num); if (p_data->val.num == BTM_SCO_CODEC_CVSD) { bt_hf_callbacks->WbsCallback(BTHF_WBS_NO, @@ -597,8 +594,8 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { if (is_hfp_aptx_voice_enabled()) { codec = BTHF_SWB_CODEC_VENDOR_APTX; - LOG_VERBOSE( - "AG final selected SWB codec is 0x%02x 0=Q0 4=Q1 6=Q2 7=Q3", + log::verbose( + "AG final selected SWB codec is 0x{:02x} 0=Q0 4=Q1 6=Q2 7=Q3", p_data->val.num); if (p_data->val.num == BTA_AG_SCO_APTX_SWB_SETTINGS_Q0 || p_data->val.num == BTA_AG_SCO_APTX_SWB_SETTINGS_Q1 || @@ -644,27 +641,27 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED, idx); break; case BTA_AG_AT_BAC_EVT: - LOG_VERBOSE("AG Bitmap of peer-codecs %d", p_data->val.num); + log::verbose("AG Bitmap of peer-codecs {}", p_data->val.num); /* If the peer supports mSBC and the BTIF preferred codec is also mSBC, * then we should set the BTA AG Codec to mSBC. This would trigger a +BCS * to mSBC at the time of SCO connection establishment */ if (hfp_hal_interface::get_swb_supported() && (p_data->val.num & BTM_SCO_CODEC_LC3)) { - LOG_VERBOSE("%s: btif_hf override-Preferred Codec to LC3", __func__); + log::verbose("btif_hf override-Preferred Codec to LC3"); BTA_AgSetCodec(btif_hf_cb[idx].handle, BTM_SCO_CODEC_LC3); } else if (hfp_hal_interface::get_wbs_supported() && (p_data->val.num & BTM_SCO_CODEC_MSBC)) { - LOG_VERBOSE("%s: btif_hf override-Preferred Codec to mSBC", __func__); + log::verbose("btif_hf override-Preferred Codec to mSBC"); BTA_AgSetCodec(btif_hf_cb[idx].handle, BTM_SCO_CODEC_MSBC); } else { - LOG_VERBOSE("%s btif_hf override-Preferred Codec to CVSD", __func__); + log::verbose("btif_hf override-Preferred Codec to CVSD"); BTA_AgSetCodec(btif_hf_cb[idx].handle, BTM_SCO_CODEC_CVSD); } break; case BTA_AG_AT_BCS_EVT: - LOG_VERBOSE("AG final selected codec is 0x%02x 1=CVSD 2=MSBC", - p_data->val.num); + log::verbose("AG final selected codec is 0x{:02x} 1=CVSD 2=MSBC", + p_data->val.num); /* No BTHF_WBS_NONE case, because HF1.6 supported device can send BCS */ /* Only CVSD is considered narrow band speech */ bt_hf_callbacks->WbsCallback( @@ -704,13 +701,12 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { case BTA_AG_AT_QCS_EVT: if (!is_hfp_aptx_voice_enabled()) { - LOG(WARNING) << __func__ << ": unhandled event " << event - << ". Aptx codec is not enabled"; + log::warn("unhandled event {}. Aptx codec is not enabled", event); break; } - LOG_INFO("AG final selected SWB codec is %#02x 0=Q0 4=Q1 6=Q2 7=Q3", - p_data->val.num); + log::info("AG final selected SWB codec is {:#02x} 0=Q0 4=Q1 6=Q2 7=Q3", + p_data->val.num); bt_hf_callbacks->SwbCallback( BTHF_SWB_CODEC_VENDOR_APTX, p_data->val.num <= BTA_AG_SCO_APTX_SWB_SETTINGS_Q3 ? BTHF_SWB_YES @@ -719,7 +715,7 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) { break; default: - LOG(WARNING) << __func__ << ": unhandled event " << event; + log::warn("unhandled event {}", event); break; } } @@ -773,8 +769,8 @@ static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG* p_data) { static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) { CHECK_BTHF_INIT(); if (is_connected(bd_addr)) { - LOG_WARN("%s: device %s is already connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::warn("device {} is already connected", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_DONE; } btif_hf_cb_t* hf_cb = nullptr; @@ -787,15 +783,14 @@ static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) { // control block should be in connecting state // Crash here to prevent future code changes from breaking this mechanism if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTING) { - LOG(FATAL) << __func__ << ": " - << ADDRESS_TO_LOGGABLE_STR(btif_hf_cb[i].connected_bda) - << ", handle " << btif_hf_cb[i].handle - << ", is still in connecting state " << btif_hf_cb[i].state; + log::fatal("{}, handle {}, is still in connecting state {}", + ADDRESS_TO_LOGGABLE_STR(btif_hf_cb[i].connected_bda), + btif_hf_cb[i].handle, btif_hf_cb[i].state); } } if (hf_cb == nullptr) { - LOG_WARN("%s: Cannot connect %s: maximum %d clients already connected", - __func__, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr), btif_max_hf_clients); + log::warn("Cannot connect {}: maximum {} clients already connected", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr), btif_max_hf_clients); return BT_STATUS_BUSY; } hf_cb->state = BTHF_CONNECTION_STATE_CONNECTING; @@ -901,10 +896,9 @@ bt_status_t HeadsetInterface::Init(Callbacks* callbacks, int max_hf_clients, " maximum is " << BTA_AG_MAX_NUM_CLIENTS << " was given " << max_hf_clients; btif_max_hf_clients = max_hf_clients; - LOG_VERBOSE("%s: btif_hf_features=%" PRIu32 - ", max_hf_clients=%d, inband_ringing_enabled=%d", - __func__, btif_hf_features, btif_max_hf_clients, - inband_ringing_enabled); + log::verbose( + "btif_hf_features={}, max_hf_clients={}, inband_ringing_enabled={}", + btif_hf_features, btif_max_hf_clients, inband_ringing_enabled); bt_hf_callbacks = callbacks; for (btif_hf_cb_t& hf_cb : btif_hf_cb) { reset_control_block(&hf_cb); @@ -931,12 +925,11 @@ bt_status_t HeadsetInterface::Disconnect(RawAddress* bd_addr) { CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } BTA_AgClose(btif_hf_cb[idx].handle); @@ -948,13 +941,12 @@ bt_status_t HeadsetInterface::ConnectAudio(RawAddress* bd_addr, CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } /* Check if SLC is connected */ if (!IsSlcConnected(bd_addr)) { - LOG(ERROR) << ": SLC not connected for " - << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::error("SLC not connected for {}", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return BT_STATUS_NOT_READY; } do_in_jni_thread(base::BindOnce(&Callbacks::AudioStateCallback, @@ -973,12 +965,11 @@ bt_status_t HeadsetInterface::DisconnectAudio(RawAddress* bd_addr) { CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } BTA_AgAudioClose(btif_hf_cb[idx].handle); @@ -989,7 +980,7 @@ bt_status_t HeadsetInterface::isNoiseReductionSupported(RawAddress* bd_addr) { CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_ECNR)) { @@ -1002,7 +993,7 @@ bt_status_t HeadsetInterface::isVoiceRecognitionSupported(RawAddress* bd_addr) { CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)) { @@ -1015,17 +1006,16 @@ bt_status_t HeadsetInterface::StartVoiceRecognition(RawAddress* bd_addr) { CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_NOT_READY; } if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)) { - LOG_ERROR("%s: voice recognition not supported, features=0x%x", __func__, - btif_hf_cb[idx].peer_feat); + log::error("voice recognition not supported, features=0x{:x}", + btif_hf_cb[idx].peer_feat); return BT_STATUS_UNSUPPORTED; } tBTA_AG_RES_DATA ag_res = {}; @@ -1039,17 +1029,16 @@ bt_status_t HeadsetInterface::StopVoiceRecognition(RawAddress* bd_addr) { int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_NOT_READY; } if (!(btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)) { - LOG_ERROR("%s: voice recognition not supported, features=0x%x", __func__, - btif_hf_cb[idx].peer_feat); + log::error("voice recognition not supported, features=0x{:x}", + btif_hf_cb[idx].peer_feat); return BT_STATUS_UNSUPPORTED; } tBTA_AG_RES_DATA ag_res = {}; @@ -1063,12 +1052,11 @@ bt_status_t HeadsetInterface::VolumeControl(bthf_volume_type_t type, int volume, CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } tBTA_AG_RES_DATA ag_res = {}; @@ -1084,13 +1072,13 @@ bt_status_t HeadsetInterface::DeviceStatusNotification( int batt_chg, RawAddress* bd_addr) { CHECK_BTHF_INIT(); if (!bd_addr) { - LOG_WARN("%s: bd_addr is null", __func__); + log::warn("bd_addr is null"); return BT_STATUS_FAIL; } int idx = btif_hf_idx_by_bdaddr(bd_addr); if (idx < 0 || idx > BTA_AG_MAX_NUM_CLIENTS) { - LOG_WARN("%s: invalid index %d for %s", __func__, idx, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::warn("invalid index {} for {}", idx, + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } const btif_hf_cb_t& control_block = btif_hf_cb[idx]; @@ -1113,12 +1101,11 @@ bt_status_t HeadsetInterface::CopsResponse(const char* cops, CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } tBTA_AG_RES_DATA ag_res = {}; @@ -1137,12 +1124,11 @@ bt_status_t HeadsetInterface::CindResponse(int svc, int num_active, CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } tBTA_AG_RES_DATA ag_res = {}; @@ -1167,12 +1153,11 @@ bt_status_t HeadsetInterface::FormattedAtResponse(const char* rsp, tBTA_AG_RES_DATA ag_res = {}; int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } /* Format the response and send */ @@ -1186,12 +1171,11 @@ bt_status_t HeadsetInterface::AtResponse(bthf_at_response_t response_code, CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } send_at_result( @@ -1207,12 +1191,11 @@ bt_status_t HeadsetInterface::ClccResponse( CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d", __func__, idx); + log::error("Invalid index {}", idx); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s is not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} is not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } tBTA_AG_RES_DATA ag_res = {}; @@ -1221,8 +1204,8 @@ bt_status_t HeadsetInterface::ClccResponse( ag_res.ok_flag = BTA_AG_OK_DONE; } else { std::string cell_number(number ? number : ""); - LOG_VERBOSE( - "clcc_response: [%d] dir %d state %d mode %d number = %s type = %d", + log::verbose( + "clcc_response: [{}] dir {} state {} mode {} number = {} type = {}", index, dir, state, mode, PRIVATE_CELL(cell_number), type); int res_strlen = snprintf(ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d", index, dir, state, mode, mpty); @@ -1259,38 +1242,37 @@ bt_status_t HeadsetInterface::PhoneStateChange( RawAddress* bd_addr) { CHECK_BTHF_INIT(); if (bd_addr == nullptr) { - LOG_WARN("bd_addr is null"); + log::warn("bd_addr is null"); return BT_STATUS_FAIL; } const RawAddress raw_address(*bd_addr); int idx = btif_hf_idx_by_bdaddr(bd_addr); if (idx < 0 || idx >= BTA_AG_MAX_NUM_CLIENTS) { - LOG_WARN("Invalid index %d for %s", idx, ADDRESS_TO_LOGGABLE_CSTR(raw_address)); + log::warn("Invalid index {} for {}", idx, + ADDRESS_TO_LOGGABLE_CSTR(raw_address)); return BT_STATUS_FAIL; } const btif_hf_cb_t& control_block = btif_hf_cb[idx]; if (!IsSlcConnected(bd_addr)) { - LOG(WARNING) << ": SLC not connected for " - << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::warn("SLC not connected for {}", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return BT_STATUS_NOT_READY; } if (call_setup_state == BTHF_CALL_STATE_DISCONNECTED) { // HFP spec does not handle cases when a call is being disconnected. // Since DISCONNECTED state must lead to IDLE state, ignoring it here.s - LOG(INFO) << __func__ - << ": Ignore call state change to DISCONNECTED, idx=" << idx - << ", addr=" - << ADDRESS_TO_LOGGABLE_STR(*bd_addr) - << ", num_active=" << num_active - << ", num_held=" << num_held; + log::info( + "Ignore call state change to DISCONNECTED, idx={}, addr={}, " + "num_active={}, num_held={}", + idx, ADDRESS_TO_LOGGABLE_STR(*bd_addr), num_active, num_held); return BT_STATUS_SUCCESS; } - LOG_DEBUG( - "bd_addr:%s active_bda:%s num_active:%u prev_num_active:%u num_held:%u " - "prev_num_held:%u call_state:%s prev_call_state:%s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), ADDRESS_TO_LOGGABLE_CSTR(active_bda), num_active, + log::debug( + "bd_addr:{} active_bda:{} num_active:{} prev_num_active:{} num_held:{} " + "prev_num_held:{} call_state:{} prev_call_state:{}", + ADDRESS_TO_LOGGABLE_CSTR((*bd_addr)), + ADDRESS_TO_LOGGABLE_CSTR(active_bda), num_active, control_block.num_active, num_held, control_block.num_held, dump_hf_call_state(call_setup_state), dump_hf_call_state(control_block.call_setup_state)); @@ -1329,10 +1311,8 @@ bt_status_t HeadsetInterface::PhoneStateChange( (control_block.num_held == 0) && (control_block.call_setup_state == BTHF_CALL_STATE_IDLE)) { tBTA_AG_RES_DATA ag_res = {}; - LOG_VERBOSE( - "%s: Active/Held call notification received without call setup " - "update", - __func__); + log::verbose( + "Active/Held call notification received without call setup update"); ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE; // Addition call setup with the Active call @@ -1351,9 +1331,9 @@ bt_status_t HeadsetInterface::PhoneStateChange( if (call_setup_state != control_block.call_setup_state) { tBTA_AG_RES_DATA ag_res = {}; ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE; - LOG_VERBOSE("%s: Call setup states changed. old: %s new: %s", __func__, - dump_hf_call_state(control_block.call_setup_state), - dump_hf_call_state(call_setup_state)); + log::verbose("Call setup states changed. old: {} new: {}", + dump_hf_call_state(control_block.call_setup_state), + dump_hf_call_state(call_setup_state)); switch (call_setup_state) { case BTHF_CALL_STATE_IDLE: { switch (control_block.call_setup_state) { @@ -1376,8 +1356,8 @@ bt_status_t HeadsetInterface::PhoneStateChange( res = BTA_AG_CALL_CANCEL_RES; break; default: - LOG_ERROR("%s: Incorrect call state prev=%d, now=%d", __func__, - control_block.call_setup_state, call_setup_state); + log::error("Incorrect call state prev={}, now={}", + control_block.call_setup_state, call_setup_state); status = BT_STATUS_PARM_INVALID; break; } @@ -1464,13 +1444,13 @@ bt_status_t HeadsetInterface::PhoneStateChange( res = BTA_AG_OUT_CALL_ALERT_RES; break; default: - LOG_ERROR("%s: Incorrect call state prev=%d, now=%d", __func__, - control_block.call_setup_state, call_setup_state); + log::error("Incorrect call state prev={}, now={}", + control_block.call_setup_state, call_setup_state); status = BT_STATUS_PARM_INVALID; break; } - LOG_VERBOSE("%s: Call setup state changed. res=%d, audio_handle=%d", - __func__, res, ag_res.audio_handle); + log::verbose("Call setup state changed. res={}, audio_handle={}", res, + ag_res.audio_handle); if (res != 0xFF) { BTA_AgResult(control_block.handle, res, ag_res); @@ -1500,9 +1480,9 @@ bt_status_t HeadsetInterface::PhoneStateChange( if (!active_call_updated && ((num_active + num_held) != (control_block.num_active + control_block.num_held))) { - VLOG(1) << __func__ << ": in progress call states changed, active=[" - << control_block.num_active << "->" << num_active << "], held=[" - << control_block.num_held << "->" << num_held; + log::verbose( + "in progress call states changed, active=[{}->{}], held=[{}->{}]", + control_block.num_active, num_active, control_block.num_held, num_held); send_indicator_update(control_block, BTA_AG_IND_CALL, ((num_active + num_held) > 0) ? BTA_AG_CALL_ACTIVE : BTA_AG_CALL_INACTIVE); @@ -1511,8 +1491,8 @@ bt_status_t HeadsetInterface::PhoneStateChange( /* Held Changed? */ if (num_held != control_block.num_held || ((num_active == 0) && ((num_held + control_block.num_held) > 1))) { - LOG_VERBOSE("%s: Held call states changed. old: %d new: %d", __func__, - control_block.num_held, num_held); + log::verbose("Held call states changed. old: {} new: {}", + control_block.num_held, num_held); send_indicator_update(control_block, BTA_AG_IND_CALLHELD, ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); } @@ -1521,7 +1501,7 @@ bt_status_t HeadsetInterface::PhoneStateChange( if ((call_setup_state == control_block.call_setup_state) && (num_active && num_held) && (num_active == control_block.num_active) && (num_held == control_block.num_held)) { - LOG_VERBOSE("%s: Calls swapped", __func__); + log::verbose("Calls swapped"); send_indicator_update(control_block, BTA_AG_IND_CALLHELD, 1); } @@ -1548,7 +1528,7 @@ bt_status_t HeadsetInterface::PhoneStateChange( } void HeadsetInterface::Cleanup() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_queue_cleanup(UUID_SERVCLASS_AG_HANDSFREE); @@ -1583,13 +1563,12 @@ bt_status_t HeadsetInterface::SendBsir(bool value, RawAddress* bd_addr) { CHECK_BTHF_INIT(); int idx = btif_hf_idx_by_bdaddr(bd_addr); if ((idx < 0) || (idx >= BTA_AG_MAX_NUM_CLIENTS)) { - LOG_ERROR("%s: Invalid index %d for %s", __func__, idx, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Invalid index {} for {}", idx, + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } if (!is_connected(bd_addr)) { - LOG_ERROR("%s: %s not connected", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("{} not connected", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } tBTA_AG_RES_DATA ag_result = {}; @@ -1628,7 +1607,7 @@ bt_status_t HeadsetInterface::DebugDump() { * ******************************************************************************/ bt_status_t ExecuteService(bool b_enable) { - LOG_INFO("service starts to: %s", b_enable ? "Initialize" : "Shutdown"); + log::info("service starts to: {}", b_enable ? "Initialize" : "Shutdown"); const char* service_names_raw[] = BTIF_HF_SERVICE_NAMES; std::vector service_names; for (const char* service_name_raw : service_names_raw) { @@ -1664,7 +1643,7 @@ bt_status_t ExecuteService(bool b_enable) { * ******************************************************************************/ Interface* GetInterface() { - VLOG(0) << __func__; + log::verbose(""); return HeadsetInterface::GetInstance(); } diff --git a/system/btif/src/btif_hf_client.cc b/system/btif/src/btif_hf_client.cc index 16b3ed777664a71a7b23f05b5f7eddb003dd9fdf..b66b48b2e383c29983209341479d95f4fc2a0bd3 100644 --- a/system/btif/src/btif_hf_client.cc +++ b/system/btif/src/btif_hf_client.cc @@ -47,6 +47,7 @@ #endif #include +#include #include #include #include @@ -55,7 +56,6 @@ #include "btif_common.h" #include "btif_profile_queue.h" #include "btif_util.h" -#include "osi/include/osi.h" #include "osi/include/properties.h" #include "stack/btm/btm_sco_hfp_hal.h" #include "stack/include/bt_uuid16.h" @@ -69,6 +69,8 @@ #define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree") #endif +using namespace bluetooth; + /******************************************************************************* * Local type definitions ******************************************************************************/ @@ -113,28 +115,28 @@ static const char* dump_hf_client_conn_state(uint16_t event) { } } -#define CHECK_BTHF_CLIENT_INIT() \ - do { \ - if (bt_hf_client_callbacks == NULL) { \ - LOG_WARN("BTHF CLIENT: %s: not initialized", __func__); \ - return BT_STATUS_NOT_READY; \ - } else { \ - LOG_VERBOSE("BTHF CLIENT: %s", __func__); \ - } \ +#define CHECK_BTHF_CLIENT_INIT() \ + do { \ + if (bt_hf_client_callbacks == NULL) { \ + log::warn("BTHF CLIENT: not initialized"); \ + return BT_STATUS_NOT_READY; \ + } else { \ + log::verbose("BTHF CLIENT: ok"); \ + } \ } while (0) -#define CHECK_BTHF_CLIENT_SLC_CONNECTED(cb) \ - do { \ - if (bt_hf_client_callbacks == NULL) { \ - LOG_WARN("BTHF CLIENT: %s: not initialized", __func__); \ - return BT_STATUS_NOT_READY; \ - } else if ((cb)->state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) { \ - LOG_WARN("BTHF CLIENT: %s: SLC connection not up. state=%s", __func__, \ - dump_hf_client_conn_state((cb)->state)); \ - return BT_STATUS_NOT_READY; \ - } else { \ - LOG_VERBOSE("BTHF CLIENT: %s", __func__); \ - } \ +#define CHECK_BTHF_CLIENT_SLC_CONNECTED(cb) \ + do { \ + if (bt_hf_client_callbacks == NULL) { \ + log::warn("BTHF CLIENT: not initialized"); \ + return BT_STATUS_NOT_READY; \ + } else if ((cb)->state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) { \ + log::warn("BTHF CLIENT: SLC connection not up. state={}", \ + dump_hf_client_conn_state((cb)->state)); \ + return BT_STATUS_NOT_READY; \ + } else { \ + log::verbose("BTHF CLIENT: ok"); \ + } \ } while (0) static btif_hf_client_cb_arr_t btif_hf_client_cb_arr; @@ -154,23 +156,24 @@ static btif_hf_client_cb_arr_t btif_hf_client_cb_arr; * Returns void * ******************************************************************************/ +constexpr uint16_t BTIF_HF_CLIENT_CB_AUDIO_CONNECTING = 0x8501; static void btif_in_hf_client_generic_evt(uint16_t event, char* p_param) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); RawAddress* bd_addr = (RawAddress*)p_param; btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr); if (cb == NULL || !is_connected(cb)) { - LOG_ERROR("%s: failed to find block for bda", __func__); + log::error("failed to find block for bda"); return; } - LOG_VERBOSE("%s: event=%d", __func__, event); + log::verbose("event={}", event); switch (event) { case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING: { HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, &cb->peer_bda, (bthf_client_audio_state_t)BTHF_CLIENT_AUDIO_STATE_CONNECTING); } break; default: { - LOG_WARN("%s: : Unknown event 0x%x", __func__, event); + log::warn(": Unknown event 0x{:x}", event); } break; } } @@ -183,7 +186,7 @@ bool is_connected(const btif_hf_client_cb_t* cb) { (cb->state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED)) return true; - LOG_ERROR("%s: not connected!", __func__); + log::error("not connected!"); return false; } @@ -197,7 +200,7 @@ bool is_connected(const btif_hf_client_cb_t* cb) { * ******************************************************************************/ btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle) { - LOG_VERBOSE("%s: cb by handle %d", __func__, handle); + log::verbose("cb by handle {}", handle); for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { // Block is valid only if it is allocated i.e. state is not DISCONNECTED if (btif_hf_client_cb_arr.cb[i].state != @@ -206,7 +209,7 @@ btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle) { return &btif_hf_client_cb_arr.cb[i]; } } - LOG_ERROR("%s: could not find block for handle %d", __func__, handle); + log::error("could not find block for handle {}", handle); return NULL; } @@ -220,7 +223,7 @@ btif_hf_client_cb_t* btif_hf_client_get_cb_by_handle(uint16_t handle) { * ******************************************************************************/ btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& bd_addr) { - VLOG(1) << __func__ << " incoming addr " << ADDRESS_TO_LOGGABLE_CSTR(bd_addr); + log::verbose("incoming addr {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) { // Block is valid only if it is allocated i.e. state is not DISCONNECTED @@ -230,7 +233,7 @@ btif_hf_client_cb_t* btif_hf_client_get_cb_by_bda(const RawAddress& bd_addr) { return &btif_hf_client_cb_arr.cb[i]; } } - LOG_ERROR("%s: could not find block for bdaddr", __func__); + log::error("could not find block for bdaddr"); return NULL; } @@ -250,7 +253,7 @@ btif_hf_client_cb_t* btif_hf_client_allocate_cb() { return cb; } } - LOG_ERROR("%s: unable to allocate control block", __func__); + log::error("unable to allocate control block"); return NULL; } @@ -270,7 +273,7 @@ btif_hf_client_cb_t* btif_hf_client_allocate_cb() { * ******************************************************************************/ static bt_status_t init(bthf_client_callbacks_t* callbacks) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); bt_hf_client_callbacks = callbacks; @@ -293,7 +296,7 @@ static bt_status_t init(bthf_client_callbacks_t* callbacks) { static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) { btif_hf_client_cb_t* cb = btif_hf_client_allocate_cb(); if (cb == NULL) { - LOG_ERROR("%s: could not allocate block!", __func__); + log::error("could not allocate block!"); return BT_STATUS_BUSY; } @@ -311,7 +314,7 @@ static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) { } static bt_status_t connect(const RawAddress* bd_addr) { - LOG_VERBOSE("HFP Client version is %s", btif_hf_client_version); + log::verbose("HFP Client version is {}", btif_hf_client_version); CHECK_BTHF_CLIENT_INIT(); return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int); } @@ -469,8 +472,7 @@ static bt_status_t volume_control(const RawAddress* bd_addr, * Returns bt_status_t * ******************************************************************************/ -static bt_status_t dial(UNUSED_ATTR const RawAddress* bd_addr, - const char* number) { +static bt_status_t dial(const RawAddress* bd_addr, const char* number) { btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr); if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL; @@ -602,7 +604,7 @@ static bt_status_t handle_call_action(const RawAddress* bd_addr, * Returns bt_status_t * ******************************************************************************/ -static bt_status_t query_current_calls(UNUSED_ATTR const RawAddress* bd_addr) { +static bt_status_t query_current_calls(const RawAddress* bd_addr) { btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr); if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL; @@ -705,7 +707,7 @@ static bt_status_t request_last_voice_tag_number(const RawAddress* bd_addr) { * ******************************************************************************/ static void cleanup(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_queue_cleanup(UUID_SERVCLASS_HF_HANDSFREE); if (bt_hf_client_callbacks) { @@ -730,8 +732,8 @@ static bt_status_t send_at_cmd(const RawAddress* bd_addr, int cmd, int val1, CHECK_BTHF_CLIENT_SLC_CONNECTED(cb); - LOG_VERBOSE("%s: Cmd %d val1 %d val2 %d arg %s", __func__, cmd, val1, val2, - (arg != NULL) ? arg : ""); + log::verbose("Cmd {} val1 {} val2 {} arg {}", cmd, val1, val2, + (arg != NULL) ? arg : ""); BTA_HfClientSendAT(cb->handle, cmd, val1, val2, arg); return BT_STATUS_SUCCESS; @@ -752,7 +754,7 @@ static bt_status_t send_android_at(const RawAddress* bd_addr, const char* arg) { CHECK_BTHF_CLIENT_SLC_CONNECTED(cb); - LOG_VERBOSE("%s: val1 %s", __func__, arg); + log::verbose("val1 {}", arg); BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ANDROID, 0, 0, arg); return BT_STATUS_SUCCESS; @@ -782,7 +784,7 @@ static const bthf_client_interface_t bthfClientInterface = { }; static void process_ind_evt(tBTA_HF_CLIENT_IND* ind) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(ind->bd_addr); if (cb == NULL || !is_connected(cb)) return; @@ -841,23 +843,20 @@ static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) { btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(p_data->bd_addr); if (cb == NULL && event == BTA_HF_CLIENT_OPEN_EVT) { - LOG_VERBOSE("%s: event BTA_HF_CLIENT_OPEN_EVT allocating block", __func__); + log::verbose("event BTA_HF_CLIENT_OPEN_EVT allocating block"); cb = btif_hf_client_allocate_cb(); if (cb == NULL) { - LOG_ERROR("%s: event BTA_HF_CLIENT_OPEN_EVT failed to allocate cb", - __func__); + log::error("event BTA_HF_CLIENT_OPEN_EVT failed to allocate cb"); return; } cb->handle = p_data->open.handle; cb->peer_bda = p_data->open.bd_addr; } else if (cb == NULL) { - LOG_ERROR("%s: event %d but not allocating block: cb not found", __func__, - event); + log::error("event {} but not allocating block: cb not found", event); return; } - LOG_VERBOSE("%s: event=%s (%u)", __func__, dump_hf_client_event(event), - event); + log::verbose("event={} ({})", dump_hf_client_event(event), event); switch (event) { case BTA_HF_CLIENT_OPEN_EVT: @@ -869,10 +868,10 @@ static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) { } else if (cb->state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING) { cb->state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED; } else { - LOG_WARN( - "%s: HF CLient open failed, but another device connected. " - "status=%d state=%d connected device=%s", - __func__, p_data->open.status, cb->state, + log::warn( + "HF CLient open failed, but another device connected. status={} " + "state={} connected device={}", + p_data->open.status, cb->state, ADDRESS_TO_LOGGABLE_CSTR(cb->peer_bda)); break; } @@ -1041,7 +1040,7 @@ static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) { p_data->unknown.event_string); break; default: - LOG_WARN("%s: Unhandled event: %d", __func__, event); + log::warn("Unhandled event: {}", event); break; } } @@ -1079,7 +1078,7 @@ static void bta_hf_client_evt(tBTA_HF_CLIENT_EVT event, * ******************************************************************************/ bt_status_t btif_hf_client_execute_service(bool b_enable) { - LOG_VERBOSE("%s: enable: %d", __func__, b_enable); + log::verbose("enable: {}", b_enable); tBTA_HF_CLIENT_FEAT features = get_default_hf_client_features(); uint16_t hfp_version = get_default_hfp_version(); @@ -1093,7 +1092,7 @@ bt_status_t btif_hf_client_execute_service(bool b_enable) { if (b_enable) { /* Enable and register with BTA-HFClient */ - LOG_VERBOSE("%s: support codec negotiation %d ", __func__, features); + log::verbose("support codec negotiation {}", features); BTA_HfClientEnable(bta_hf_client_evt, features, BTIF_HF_CLIENT_SERVICE_NAME); } else { @@ -1112,6 +1111,6 @@ bt_status_t btif_hf_client_execute_service(bool b_enable) { * ******************************************************************************/ const bthf_client_interface_t* btif_hf_client_get_interface(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return &bthfClientInterface; } diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc index e476c18fbdaf262c6871e2b70f5ed8dda9b0bfc2..56887822a07514669c23e62c614b37de12a98d81 100644 --- a/system/btif/src/btif_hh.cc +++ b/system/btif/src/btif_hh.cc @@ -30,21 +30,22 @@ #include "btif/include/btif_hh.h" #include +#include #include -#include "bta_sec_api.h" #include "bta_hh_co.h" +#include "bta_sec_api.h" #include "btif/include/btif_common.h" #include "btif/include/btif_profile_storage.h" +#include "btif/include/btif_storage.h" #include "btif/include/btif_util.h" #include "include/hardware/bt_hh.h" #include "main/shim/dumpsys.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "stack/include/bt_hdr.h" #include "stack/include/hidh_api.h" -#include "stack/include/l2c_api.h" #include "types/raw_address.h" #define COD_HID_KEYBOARD 0x0540 @@ -62,6 +63,8 @@ #define LOGITECH_KB_MX5500_VENDOR_ID 0x046D #define LOGITECH_KB_MX5500_PRODUCT_ID 0xB30B +using namespace bluetooth; + static int btif_hh_keylockstates = 0; // The current key state of each key #define BTIF_TIMEOUT_VUP_MS (3 * 1000) @@ -103,12 +106,12 @@ static tHID_KB_LIST hid_kb_numlock_on_list[] = {{LOGITECH_KB_MX5500_PRODUCT_ID, LOGITECH_KB_MX5500_VENDOR_ID, "Logitech MX5500 Keyboard"}}; -#define CHECK_BTHH_INIT() \ - do { \ - if (bt_hh_callbacks == NULL) { \ - LOG_WARN("BTHH: %s: BTHH not initialized", __func__); \ - return BT_STATUS_NOT_READY; \ - } \ +#define CHECK_BTHH_INIT() \ + do { \ + if (bt_hh_callbacks == NULL) { \ + log::warn("BTHH: BTHH not initialized"); \ + return BT_STATUS_NOT_READY; \ + } \ } while (0) /******************************************************************************* @@ -160,8 +163,7 @@ static void set_keylockstate(int keymask, bool isSet) { ******************************************************************************/ static void toggle_os_keylockstates(int fd, int changedlockstates) { - LOG_VERBOSE("%s: fd = %d, changedlockstates = 0x%x", __func__, fd, - changedlockstates); + log::verbose("fd = {}, changedlockstates = 0x{:x}", fd, changedlockstates); uint8_t hidreport[9]; int reportIndex; memset(hidreport, 0, 9); @@ -169,40 +171,32 @@ static void toggle_os_keylockstates(int fd, int changedlockstates) { reportIndex = 4; if (changedlockstates & BTIF_HH_KEYSTATE_MASK_CAPSLOCK) { - LOG_VERBOSE("%s Setting CAPSLOCK", __func__); + log::verbose("Setting CAPSLOCK"); hidreport[reportIndex++] = (uint8_t)HID_REPORT_CAPSLOCK; } if (changedlockstates & BTIF_HH_KEYSTATE_MASK_NUMLOCK) { - LOG_VERBOSE("%s Setting NUMLOCK", __func__); + log::verbose("Setting NUMLOCK"); hidreport[reportIndex++] = (uint8_t)HID_REPORT_NUMLOCK; } if (changedlockstates & BTIF_HH_KEYSTATE_MASK_SCROLLLOCK) { - LOG_VERBOSE("%s Setting SCROLLLOCK", __func__); + log::verbose("Setting SCROLLLOCK"); hidreport[reportIndex++] = (uint8_t)HID_REPORT_SCROLLLOCK; } - LOG_VERBOSE( - "Writing hidreport #1 to os: " - "%s: %x %x %x", - __func__, hidreport[0], hidreport[1], hidreport[2]); - LOG_VERBOSE("%s: %x %x %x", __func__, hidreport[3], hidreport[4], - hidreport[5]); - LOG_VERBOSE("%s: %x %x %x", __func__, hidreport[6], hidreport[7], - hidreport[8]); + log::verbose("Writing hidreport #1 to os:"); + log::verbose("| {:x} {:x} {:x}", hidreport[0], hidreport[1], hidreport[2]); + log::verbose("| {:x} {:x} {:x}", hidreport[3], hidreport[4], hidreport[5]); + log::verbose("| {:x} {:x} {:x}", hidreport[6], hidreport[7], hidreport[8]); bta_hh_co_write(fd, hidreport, sizeof(hidreport)); usleep(200000); memset(hidreport, 0, 9); hidreport[0] = 1; - LOG_VERBOSE( - "Writing hidreport #2 to os: " - "%s: %x %x %x", - __func__, hidreport[0], hidreport[1], hidreport[2]); - LOG_VERBOSE("%s: %x %x %x", __func__, hidreport[3], hidreport[4], - hidreport[5]); - LOG_VERBOSE("%s: %x %x %x ", __func__, hidreport[6], hidreport[7], - hidreport[8]); + log::verbose("Writing hidreport #2 to os:"); + log::verbose("| {:x} {:x} {:x}", hidreport[0], hidreport[1], hidreport[2]); + log::verbose("| {:x} {:x} {:x}", hidreport[3], hidreport[4], hidreport[5]); + log::verbose("| {:x} {:x} {:x}", hidreport[6], hidreport[7], hidreport[8]); bta_hh_co_write(fd, hidreport, sizeof(hidreport)); } @@ -241,14 +235,14 @@ static void update_keyboard_lockstates(btif_hh_device_t* p_dev) { static_cast(btif_hh_keylockstates)}; /* keystate */ /* Set report for other keyboards */ - LOG_VERBOSE("%s: setting report on dev_handle %d to 0x%x", __func__, - p_dev->dev_handle, btif_hh_keylockstates); + log::verbose("setting report on dev_handle {} to 0x{:x}", p_dev->dev_handle, + btif_hh_keylockstates); /* Get SetReport buffer */ p_buf = create_pbuf(len, data); if (p_buf != NULL) { p_buf->layer_specific = BTA_HH_RPTT_OUTPUT; - BTA_HhSendData(p_dev->dev_handle, p_dev->bd_addr, p_buf); + BTA_HhSendData(p_dev->dev_handle, p_dev->link_spec, p_buf); } } @@ -265,10 +259,7 @@ static void update_keyboard_lockstates(btif_hh_device_t* p_dev) { static void sync_lockstate_on_connect(btif_hh_device_t* p_dev) { int keylockstates; - LOG_VERBOSE( - "%s: Syncing keyboard lock states after " - "reconnect...", - __func__); + log::verbose("Syncing keyboard lock states after reconnect..."); /*If the device is connected, update keyboard state */ update_keyboard_lockstates(p_dev); @@ -277,17 +268,15 @@ static void sync_lockstate_on_connect(btif_hh_device_t* p_dev) { so the lockstate is in sync */ keylockstates = get_keylockstates(); if (keylockstates) { - LOG_VERBOSE( - "%s: Sending hid report to kernel " - "indicating lock key state 0x%x", - __func__, keylockstates); + log::verbose( + "Sending hid report to kernel indicating lock key state 0x{:x}", + keylockstates); usleep(200000); toggle_os_keylockstates(p_dev->fd, keylockstates); } else { - LOG_VERBOSE( - "%s: NOT sending hid report to kernel " - "indicating lock key state 0x%x", - __func__, keylockstates); + log::verbose( + "NOT sending hid report to kernel indicating lock key state 0x{:x}", + keylockstates); } } @@ -319,11 +308,12 @@ btif_hh_device_t* btif_hh_find_connected_dev_by_handle(uint8_t handle) { * * Returns Device entry pointer in the device table ******************************************************************************/ -static btif_hh_device_t* btif_hh_find_dev_by_bda(const RawAddress& bd_addr) { +static btif_hh_device_t* btif_hh_find_dev_by_bda( + const tAclLinkSpec& link_spec) { uint32_t i; for (i = 0; i < BTIF_HH_MAX_HID; i++) { if (btif_hh_cb.devices[i].dev_status != BTHH_CONN_STATE_UNKNOWN && - btif_hh_cb.devices[i].bd_addr == bd_addr) { + btif_hh_cb.devices[i].link_spec.addrt.bda == link_spec.addrt.bda) { return &btif_hh_cb.devices[i]; } } @@ -340,11 +330,11 @@ static btif_hh_device_t* btif_hh_find_dev_by_bda(const RawAddress& bd_addr) { * Returns Device entry pointer in the device table ******************************************************************************/ static btif_hh_device_t* btif_hh_find_connected_dev_by_bda( - const RawAddress& bd_addr) { + const tAclLinkSpec& link_spec) { uint32_t i; for (i = 0; i < BTIF_HH_MAX_HID; i++) { if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_CONNECTED && - btif_hh_cb.devices[i].bd_addr == bd_addr) { + btif_hh_cb.devices[i].link_spec.addrt.bda == link_spec.addrt.bda) { return &btif_hh_cb.devices[i]; } } @@ -359,11 +349,11 @@ static btif_hh_device_t* btif_hh_find_connected_dev_by_bda( * * Returns void ******************************************************************************/ -static void btif_hh_stop_vup_timer(RawAddress* bd_addr) { - btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); +static void btif_hh_stop_vup_timer(tAclLinkSpec* link_spec) { + btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*link_spec); if (p_dev != NULL) { - LOG_VERBOSE("stop VUP timer"); + log::verbose("stop VUP timer"); alarm_free(p_dev->vup_timer); p_dev->vup_timer = NULL; } @@ -376,10 +366,10 @@ static void btif_hh_stop_vup_timer(RawAddress* bd_addr) { * * Returns void ******************************************************************************/ -static void btif_hh_start_vup_timer(const RawAddress* bd_addr) { - LOG_VERBOSE("%s", __func__); +static void btif_hh_start_vup_timer(const tAclLinkSpec* link_spec) { + log::verbose(""); - btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*link_spec); CHECK(p_dev != NULL); alarm_free(p_dev->vup_timer); @@ -388,7 +378,7 @@ static void btif_hh_start_vup_timer(const RawAddress* bd_addr) { btif_hh_timer_timeout, p_dev); } -static void hh_connect_complete(uint8_t handle, RawAddress& bda, +static void hh_connect_complete(uint8_t handle, tAclLinkSpec& link_spec, BTIF_HH_STATUS status) { bthh_connection_state_t state = BTHH_CONN_STATE_CONNECTED; btif_hh_cb.status = status; @@ -397,32 +387,32 @@ static void hh_connect_complete(uint8_t handle, RawAddress& bda, state = BTHH_CONN_STATE_DISCONNECTED; BTA_HhClose(handle); } - HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bda, state); + HAL_CBACK(bt_hh_callbacks, connection_state_cb, &link_spec.addrt.bda, state); } static void hh_open_handler(tBTA_HH_CONN& conn) { - LOG_DEBUG("status = %d, handle = %d", conn.status, conn.handle); + log::debug("status = {}, handle = {}", conn.status, conn.handle); - HAL_CBACK(bt_hh_callbacks, connection_state_cb, (RawAddress*)&conn.bda, - BTHH_CONN_STATE_CONNECTING); - btif_hh_cb.pending_conn_address = RawAddress::kEmpty; + HAL_CBACK(bt_hh_callbacks, connection_state_cb, + (RawAddress*)&conn.link_spec.addrt.bda, BTHH_CONN_STATE_CONNECTING); + btif_hh_cb.pending_link_spec = {}; if (conn.status != BTA_HH_OK) { - btif_dm_hh_open_failed(&conn.bda); - btif_hh_device_t* p_dev = btif_hh_find_dev_by_bda(conn.bda); + btif_dm_hh_open_failed(&conn.link_spec.addrt.bda); + btif_hh_device_t* p_dev = btif_hh_find_dev_by_bda(conn.link_spec); if (p_dev != NULL) { - btif_hh_stop_vup_timer(&(p_dev->bd_addr)); + btif_hh_stop_vup_timer(&(p_dev->link_spec)); p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; } - hh_connect_complete(conn.handle, conn.bda, BTIF_HH_DEV_DISCONNECTED); + hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_DISCONNECTED); return; } /* Initialize device driver */ if (!bta_hh_co_open(conn.handle, conn.sub_class, conn.attr_mask, conn.app_id)) { - LOG_WARN("Failed to find the uhid driver"); - hh_connect_complete(conn.handle, conn.bda, BTIF_HH_DEV_DISCONNECTED); + log::warn("Failed to find the uhid driver"); + hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_DISCONNECTED); return; } @@ -430,19 +420,19 @@ static void hh_open_handler(tBTA_HH_CONN& conn) { if (p_dev == NULL) { /* The connect request must have come from device side and exceeded the * connected HID device number. */ - LOG_WARN("Cannot find device with handle %d", conn.handle); - hh_connect_complete(conn.handle, conn.bda, BTIF_HH_DEV_DISCONNECTED); + log::warn("Cannot find device with handle {}", conn.handle); + hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_DISCONNECTED); return; } - LOG_INFO("Found device, getting dscp info for handle %d", conn.handle); + log::info("Found device, getting dscp info for handle {}", conn.handle); - p_dev->bd_addr = conn.bda; + p_dev->link_spec = conn.link_spec; p_dev->dev_status = BTHH_CONN_STATE_CONNECTED; - hh_connect_complete(conn.handle, conn.bda, BTIF_HH_DEV_CONNECTED); + hh_connect_complete(conn.handle, conn.link_spec, BTIF_HH_DEV_CONNECTED); // Send set_idle if the peer_device is a keyboard - if (check_cod_hid_major(conn.bda, COD_HID_KEYBOARD) || - check_cod_hid_major(conn.bda, COD_HID_COMBO)) { + if (check_cod_hid_major(conn.link_spec.addrt.bda, COD_HID_KEYBOARD) || + check_cod_hid_major(conn.link_spec.addrt.bda, COD_HID_COMBO)) { BTA_HhSetIdle(conn.handle, 0); } BTA_HhGetDscpInfo(conn.handle); @@ -456,25 +446,27 @@ static void hh_open_handler(tBTA_HH_CONN& conn) { * * Returns true if add successfully, otherwise false. ******************************************************************************/ -bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask) { +bool btif_hh_add_added_dev(const tAclLinkSpec& link_spec, + tBTA_HH_ATTR_MASK attr_mask) { int i; for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { - if (btif_hh_cb.added_devices[i].bd_addr == bda) { - LOG(WARNING) << " Device " << ADDRESS_TO_LOGGABLE_STR(bda) << " already added"; + if (btif_hh_cb.added_devices[i].link_spec.addrt.bda == + link_spec.addrt.bda) { + log::warn("Device {} already added", ADDRESS_TO_LOGGABLE_STR(link_spec)); return false; } } for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { - if (btif_hh_cb.added_devices[i].bd_addr.IsEmpty()) { - LOG(WARNING) << " Added device " << ADDRESS_TO_LOGGABLE_STR(bda); - btif_hh_cb.added_devices[i].bd_addr = bda; + if (btif_hh_cb.added_devices[i].link_spec.addrt.bda.IsEmpty()) { + log::warn("Added device {}", ADDRESS_TO_LOGGABLE_STR(link_spec)); + btif_hh_cb.added_devices[i].link_spec = link_spec; btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE; btif_hh_cb.added_devices[i].attr_mask = attr_mask; return true; } } - LOG_WARN("%s: Error, out of space to add device", __func__); + log::warn("Error, out of space to add device"); return false; } @@ -486,27 +478,27 @@ bool btif_hh_add_added_dev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask) { ** ** Returns void ******************************************************************************/ -void btif_hh_remove_device(RawAddress bd_addr) { +void btif_hh_remove_device(const tAclLinkSpec& link_spec) { int i; btif_hh_device_t* p_dev; btif_hh_added_device_t* p_added_dev; - LOG(INFO) << __func__ << ": bda = " << ADDRESS_TO_LOGGABLE_STR(bd_addr); + log::info("transport = {}", link_spec.ToString()); for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { p_added_dev = &btif_hh_cb.added_devices[i]; - if (p_added_dev->bd_addr == bd_addr) { + if (p_added_dev->link_spec.addrt.bda == link_spec.addrt.bda) { BTA_HhRemoveDev(p_added_dev->dev_handle); - btif_storage_remove_hid_info(p_added_dev->bd_addr); - p_added_dev->bd_addr = RawAddress::kEmpty; + btif_storage_remove_hid_info(p_added_dev->link_spec.addrt.bda); + p_added_dev->link_spec = {}; p_added_dev->dev_handle = BTA_HH_INVALID_HANDLE; break; } } - p_dev = btif_hh_find_dev_by_bda(bd_addr); + p_dev = btif_hh_find_dev_by_bda(link_spec); if (p_dev == NULL) { - LOG(WARNING) << " Oops, can't find device " << ADDRESS_TO_LOGGABLE_STR(bd_addr); + log::warn("Oops, can't find device {}", ADDRESS_TO_LOGGABLE_STR(link_spec)); return; } @@ -518,7 +510,7 @@ void btif_hh_remove_device(RawAddress bd_addr) { HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bd_addr, BTHH_CONN_STATE_DISCONNECTED); }, - p_dev->bd_addr)); + p_dev->link_spec.addrt.bda)); p_dev->dev_status = BTHH_CONN_STATE_UNKNOWN; p_dev->dev_handle = BTA_HH_INVALID_HANDLE; @@ -527,7 +519,7 @@ void btif_hh_remove_device(RawAddress bd_addr) { if (btif_hh_cb.device_num > 0) { btif_hh_cb.device_num--; } else { - LOG_WARN("%s: device_num = 0", __func__); + log::warn("device_num = 0"); } bta_hh_co_close(p_dev); @@ -563,44 +555,44 @@ bool btif_hh_copy_hid_info(tBTA_HH_DEV_DSCP_INFO* dest, * ******************************************************************************/ -bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) { - LOG_VERBOSE("%s", __func__); +bt_status_t btif_hh_virtual_unplug(const tAclLinkSpec* link_spec) { + log::verbose(""); btif_hh_device_t* p_dev; - p_dev = btif_hh_find_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_dev_by_bda(*link_spec); if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) && (p_dev->attr_mask & HID_VIRTUAL_CABLE)) { - LOG_VERBOSE("%s: Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG for: %s", - __func__, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::verbose("Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG for: {}", + ADDRESS_TO_LOGGABLE_CSTR(*link_spec)); /* start the timer */ - btif_hh_start_vup_timer(bd_addr); + btif_hh_start_vup_timer(link_spec); p_dev->local_vup = true; BTA_HhSendCtrl(p_dev->dev_handle, BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG); return BT_STATUS_SUCCESS; } else if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED)) { - LOG_ERROR("%s: Virtual unplug not supported, disconnecting device: %s", - __func__, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Virtual unplug not supported, disconnecting device: {}", + ADDRESS_TO_LOGGABLE_CSTR(*link_spec)); /* start the timer */ - btif_hh_start_vup_timer(bd_addr); + btif_hh_start_vup_timer(link_spec); p_dev->local_vup = true; BTA_HhClose(p_dev->dev_handle); return BT_STATUS_SUCCESS; } else { - LOG_ERROR("%s: Error, device %s not opened, status = %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr), btif_hh_cb.status); - if ((btif_hh_cb.pending_conn_address == *bd_addr) && + log::error("Error, device {} not opened, status = {}", + ADDRESS_TO_LOGGABLE_CSTR(*link_spec), btif_hh_cb.status); + if ((btif_hh_cb.pending_link_spec.addrt.bda == link_spec->addrt.bda) && (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING)) { btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED; - btif_hh_cb.pending_conn_address = RawAddress::kEmpty; + btif_hh_cb.pending_link_spec = {}; /* need to notify up-layer device is disconnected to avoid * state out of sync with up-layer */ do_in_jni_thread(base::Bind( - [](RawAddress bd_addrcb) { - HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bd_addrcb, - BTHH_CONN_STATE_DISCONNECTED); - }, - *bd_addr)); + [](RawAddress bd_addrcb) { + HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bd_addrcb, + BTHH_CONN_STATE_DISCONNECTED); + }, + link_spec->addrt.bda)); } return BT_STATUS_FAIL; } @@ -616,42 +608,42 @@ bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr) { * ******************************************************************************/ -bt_status_t btif_hh_connect(const RawAddress* bd_addr) { +bt_status_t btif_hh_connect(const tAclLinkSpec* link_spec) { btif_hh_added_device_t* added_dev = NULL; + CHECK_BTHH_INIT(); - LOG_VERBOSE("BTHH: %s", __func__); - btif_hh_device_t* dev = btif_hh_find_dev_by_bda(*bd_addr); + log::verbose("BTHH"); + btif_hh_device_t* dev = btif_hh_find_dev_by_bda(*link_spec); if (!dev && btif_hh_cb.device_num >= BTIF_HH_MAX_HID) { // No space for more HID device now. - LOG_WARN("%s: Error, exceeded the maximum supported HID device number %d", - __func__, BTIF_HH_MAX_HID); + log::warn("Error, exceeded the maximum supported HID device number {}", + BTIF_HH_MAX_HID); return BT_STATUS_NOMEM; } for (int i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { - if (btif_hh_cb.added_devices[i].bd_addr == *bd_addr) { + if (btif_hh_cb.added_devices[i].link_spec.addrt.bda == + link_spec->addrt.bda) { added_dev = &btif_hh_cb.added_devices[i]; - LOG(WARNING) << __func__ << ": Device " << ADDRESS_TO_LOGGABLE_STR(*bd_addr) - << " already added, attr_mask = 0x" << std::hex - << added_dev->attr_mask; + log::warn("Device {} already added, attr_mask = 0x{:x}", + ADDRESS_TO_LOGGABLE_STR(*link_spec), added_dev->attr_mask); } } if (added_dev != NULL) { if (added_dev->dev_handle == BTA_HH_INVALID_HANDLE) { // No space for more HID device now. - LOG(ERROR) << __func__ << ": Error, device " - << ADDRESS_TO_LOGGABLE_STR(*bd_addr) - << " added but addition failed"; - added_dev->bd_addr = RawAddress::kEmpty; + log::error("Error, device {} added but addition failed", + ADDRESS_TO_LOGGABLE_STR(*link_spec)); + added_dev->link_spec = {}; added_dev->dev_handle = BTA_HH_INVALID_HANDLE; return BT_STATUS_NOMEM; } } if (dev && dev->dev_status == BTHH_CONN_STATE_CONNECTED) { - LOG_DEBUG("HidHost profile already connected for %s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); + log::debug("HidHost profile already connected for {}", + ADDRESS_TO_LOGGABLE_CSTR((*link_spec))); return BT_STATUS_SUCCESS; } @@ -661,15 +653,15 @@ bt_status_t btif_hh_connect(const RawAddress* bd_addr) { not in pagescan mode, we will do 2 retries to connect before giving up */ btif_hh_cb.status = BTIF_HH_DEV_CONNECTING; - btif_hh_cb.pending_conn_address = *bd_addr; - BTA_HhOpen(*bd_addr); + btif_hh_cb.pending_link_spec = *link_spec; + BTA_HhOpen(btif_hh_cb.pending_link_spec); do_in_jni_thread(base::Bind( [](RawAddress bd_addr) { HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bd_addr, BTHH_CONN_STATE_CONNECTING); }, - *bd_addr)); + link_spec->addrt.bda)); return BT_STATUS_SUCCESS; } @@ -682,16 +674,16 @@ bt_status_t btif_hh_connect(const RawAddress* bd_addr) { * Returns void * ******************************************************************************/ -void btif_hh_disconnect(RawAddress* bd_addr) { - CHECK(bd_addr != nullptr); - const btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); +void btif_hh_disconnect(tAclLinkSpec* link_spec) { + CHECK(link_spec != nullptr); + const btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*link_spec); if (p_dev == nullptr) { - LOG_DEBUG("Unable to disconnect unknown HID device:%s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); + log::debug("Unable to disconnect unknown HID device:{}", + ADDRESS_TO_LOGGABLE_CSTR((*link_spec))); return; } - LOG_DEBUG("Disconnect and close request for HID device:%s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); + log::debug("Disconnect and close request for HID device:{}", + ADDRESS_TO_LOGGABLE_CSTR((*link_spec))); BTA_HhClose(p_dev->dev_handle); } @@ -708,8 +700,7 @@ void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type, uint16_t size, uint8_t* report) { BT_HDR* p_buf = create_pbuf(size, report); if (p_buf == NULL) { - LOG_ERROR("%s: Error, failed to allocate RPT buffer, size = %d", __func__, - size); + log::error("Error, failed to allocate RPT buffer, size = {}", size); return; } BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf); @@ -727,12 +718,11 @@ void btif_hh_setreport(btif_hh_device_t* p_dev, bthh_report_type_t r_type, void btif_hh_senddata(btif_hh_device_t* p_dev, uint16_t size, uint8_t* report) { BT_HDR* p_buf = create_pbuf(size, report); if (p_buf == NULL) { - LOG_ERROR("%s: Error, failed to allocate RPT buffer, size = %d", __func__, - size); + log::error("Error, failed to allocate RPT buffer, size = {}", size); return; } p_buf->layer_specific = BTA_HH_RPTT_OUTPUT; - BTA_HhSendData(p_dev->dev_handle, p_dev->bd_addr, p_buf); + BTA_HhSendData(p_dev->dev_handle, p_dev->link_spec, p_buf); } /******************************************************************************* @@ -745,9 +735,9 @@ void btif_hh_senddata(btif_hh_device_t* p_dev, uint16_t size, uint8_t* report) { * ******************************************************************************/ void btif_hh_service_registration(bool enable) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); - LOG_VERBOSE("enable = %d", enable); + log::verbose("enable = {}", enable); if (bt_hh_callbacks == NULL) { // The HID Host service was never initialized (it is either disabled or not // available in this build). We should proceed directly to changing the HID @@ -804,22 +794,21 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { int i; int len, tmplen; - LOG_VERBOSE("%s: event=%s dereg = %d", __func__, dump_hh_event(event), - btif_hh_cb.service_dereg_active); + log::verbose("event={} dereg = {}", dump_hh_event(event), + btif_hh_cb.service_dereg_active); switch (event) { case BTA_HH_ENABLE_EVT: - LOG_VERBOSE("%s: BTA_HH_ENABLE_EVT: status =%d", __func__, - p_data->status); + log::verbose("BTA_HH_ENABLE_EVT: status ={}", p_data->status); if (p_data->status == BTA_HH_OK) { btif_hh_cb.status = BTIF_HH_ENABLED; - LOG_VERBOSE("%s--Loading added devices", __func__); + log::verbose("Loading added devices"); /* Add hid descriptors for already bonded hid devices*/ btif_storage_load_bonded_hid_info(); } else { btif_hh_cb.status = BTIF_HH_DISABLED; - LOG_WARN("BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = %d", - p_data->status); + log::warn("BTA_HH_ENABLE_EVT: Error, HH enabling failed, status = {}", + p_data->status); } break; @@ -830,7 +819,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { btif_hh_cb.status = BTIF_HH_DISABLED; if (btif_hh_cb.service_dereg_active) { - LOG_VERBOSE("BTA_HH_DISABLE_EVT: enabling HID Device service"); + log::verbose("BTA_HH_DISABLE_EVT: enabling HID Device service"); btif_hd_service_registration(); btif_hh_cb.service_dereg_active = FALSE; } @@ -845,8 +834,8 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN; } } else - LOG_WARN("BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = %d", - p_data->status); + log::warn("BTA_HH_DISABLE_EVT: Error, HH disabling failed, status = {}", + p_data->status); break; case BTA_HH_OPEN_EVT: @@ -854,45 +843,44 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { break; case BTA_HH_CLOSE_EVT: - LOG_VERBOSE("BTA_HH_CLOSE_EVT: status = %d, handle = %d", - p_data->dev_status.status, p_data->dev_status.handle); + log::verbose("BTA_HH_CLOSE_EVT: status = {}, handle = {}", + p_data->dev_status.status, p_data->dev_status.handle); p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); if (p_dev != NULL) { - HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), - BTHH_CONN_STATE_DISCONNECTING); - LOG_VERBOSE("%s: uhid fd=%d local_vup=%d", __func__, p_dev->fd, - p_dev->local_vup); - btif_hh_stop_vup_timer(&(p_dev->bd_addr)); + HAL_CBACK(bt_hh_callbacks, connection_state_cb, + &(p_dev->link_spec.addrt.bda), BTHH_CONN_STATE_DISCONNECTING); + log::verbose("uhid fd={} local_vup={}", p_dev->fd, p_dev->local_vup); + btif_hh_stop_vup_timer(&(p_dev->link_spec)); /* If this is a locally initiated VUP, remove the bond as ACL got * disconnected while VUP being processed. */ if (p_dev->local_vup) { p_dev->local_vup = false; - BTA_DmRemoveDevice(p_dev->bd_addr); + BTA_DmRemoveDevice(p_dev->link_spec.addrt.bda); } else if (p_data->dev_status.status == BTA_HH_HS_SERVICE_CHANGED) { /* Local disconnection due to service change in the HOGP device. HID descriptor would be read again, so remove it from cache. */ - LOG_WARN( - "Removing cached descriptor due to service change, handle = %d", + log::warn( + "Removing cached descriptor due to service change, handle = {}", p_data->dev_status.handle); - btif_storage_remove_hid_info(p_dev->bd_addr); + btif_storage_remove_hid_info(p_dev->link_spec.addrt.bda); } btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED; p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; bta_hh_co_close(p_dev); - HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), - p_dev->dev_status); + HAL_CBACK(bt_hh_callbacks, connection_state_cb, + &(p_dev->link_spec.addrt.bda), p_dev->dev_status); } else { - LOG_WARN("Error: cannot find device with handle %d", - p_data->dev_status.handle); + log::warn("Error: cannot find device with handle {}", + p_data->dev_status.handle); } break; case BTA_HH_GET_RPT_EVT: { - LOG_VERBOSE("BTA_HH_GET_RPT_EVT: status = %d, handle = %d", - p_data->hs_data.status, p_data->hs_data.handle); + log::verbose("BTA_HH_GET_RPT_EVT: status = {}, handle = {}", + p_data->hs_data.status, p_data->hs_data.handle); p_dev = btif_hh_find_connected_dev_by_handle(p_data->hs_data.handle); if (p_dev) { BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data; @@ -901,7 +889,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { uint8_t* data = (uint8_t*)(hdr + 1) + hdr->offset; uint16_t len = hdr->len; HAL_CBACK(bt_hh_callbacks, get_report_cb, - (RawAddress*)&(p_dev->bd_addr), + (RawAddress*)&(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->hs_data.status, data, len); bta_hh_co_get_rpt_rsp(p_dev->dev_handle, @@ -909,22 +897,23 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { len); } else { /* Handshake */ HAL_CBACK(bt_hh_callbacks, handshake_cb, - (RawAddress*)&(p_dev->bd_addr), + (RawAddress*)&(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->hs_data.status); } } else { - LOG_WARN("Error: cannot find device with handle %d", - p_data->hs_data.handle); + log::warn("Error: cannot find device with handle {}", + p_data->hs_data.handle); } break; } case BTA_HH_SET_RPT_EVT: - LOG_VERBOSE("BTA_HH_SET_RPT_EVT: status = %d, handle = %d", - p_data->dev_status.status, p_data->dev_status.handle); + log::verbose("BTA_HH_SET_RPT_EVT: status = {}, handle = {}", + p_data->dev_status.status, p_data->dev_status.handle); p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); if (p_dev != NULL) { - HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr), + HAL_CBACK(bt_hh_callbacks, handshake_cb, + (RawAddress*)&(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->hs_data.status); bta_hh_co_set_rpt_rsp(p_dev->dev_handle, p_data->dev_status.status); @@ -934,13 +923,13 @@ 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) { - LOG_WARN( - "BTA_HH_GET_PROTO_EVT: Error, cannot find device with handle %d", + log::warn( + "BTA_HH_GET_PROTO_EVT: Error, cannot find device with handle {}", p_data->hs_data.handle); return; } - LOG_WARN( - "BTA_HH_GET_PROTO_EVT: status = %d, handle = %d, proto = [%d], %s", + log::warn( + "BTA_HH_GET_PROTO_EVT: status = {}, handle = {}, proto = [{}], {}", p_data->hs_data.status, p_data->hs_data.handle, p_data->hs_data.rsp_data.proto_mode, (p_data->hs_data.rsp_data.proto_mode == BTA_HH_PROTO_RPT_MODE) @@ -950,55 +939,57 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { : "Unsupported"); if (p_data->hs_data.rsp_data.proto_mode != BTA_HH_PROTO_UNKNOWN) { HAL_CBACK(bt_hh_callbacks, protocol_mode_cb, - (RawAddress*)&(p_dev->bd_addr), + (RawAddress*)&(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->hs_data.status, (bthh_protocol_mode_t)p_data->hs_data.rsp_data.proto_mode); } else { - HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr), + HAL_CBACK(bt_hh_callbacks, handshake_cb, + (RawAddress*)&(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->hs_data.status); } break; case BTA_HH_SET_PROTO_EVT: - LOG_VERBOSE("BTA_HH_SET_PROTO_EVT: status = %d, handle = %d", - p_data->dev_status.status, p_data->dev_status.handle); + log::verbose("BTA_HH_SET_PROTO_EVT: status = {}, handle = {}", + p_data->dev_status.status, p_data->dev_status.handle); p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); if (p_dev) { - HAL_CBACK(bt_hh_callbacks, handshake_cb, (RawAddress*)&(p_dev->bd_addr), + HAL_CBACK(bt_hh_callbacks, handshake_cb, + (RawAddress*)&(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->hs_data.status); } break; case BTA_HH_GET_IDLE_EVT: - LOG_VERBOSE("BTA_HH_GET_IDLE_EVT: handle = %d, status = %d, rate = %d", - p_data->hs_data.handle, p_data->hs_data.status, - p_data->hs_data.rsp_data.idle_rate); + log::verbose("BTA_HH_GET_IDLE_EVT: handle = {}, status = {}, rate = {}", + 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); if (p_dev) { - HAL_CBACK(bt_hh_callbacks, idle_time_cb, (RawAddress*)&(p_dev->bd_addr), + HAL_CBACK(bt_hh_callbacks, idle_time_cb, + (RawAddress*)&(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->hs_data.status, p_data->hs_data.rsp_data.idle_rate); } break; case BTA_HH_SET_IDLE_EVT: - LOG_VERBOSE("BTA_HH_SET_IDLE_EVT: status = %d, handle = %d", - p_data->dev_status.status, p_data->dev_status.handle); + log::verbose("BTA_HH_SET_IDLE_EVT: status = {}, handle = {}", + p_data->dev_status.status, p_data->dev_status.handle); break; case BTA_HH_GET_DSCP_EVT: len = p_data->dscp_info.descriptor.dl_len; - LOG_VERBOSE("BTA_HH_GET_DSCP_EVT: len = %d", len); + log::verbose("BTA_HH_GET_DSCP_EVT: len = {}", len); p_dev = btif_hh_find_connected_dev_by_handle(p_data->dscp_info.hid_handle); if (p_dev == NULL) { - LOG_ERROR("BTA_HH_GET_DSCP_EVT: No HID device is currently connected"); + log::error("BTA_HH_GET_DSCP_EVT: No HID device is currently connected"); p_data->dscp_info.hid_handle = BTA_HH_INVALID_HANDLE; return; } if (p_dev->fd < 0) { - LOG_ERROR( - + log::error( "BTA_HH_GET_DSCP_EVT: Error, failed to find the uhid driver..."); return; } @@ -1009,29 +1000,29 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { BTIF_STORAGE_FILL_PROPERTY(&prop_name, BT_PROPERTY_BDNAME, sizeof(bt_bdname_t), &bdname); if (btif_storage_get_remote_device_property( - &p_dev->bd_addr, &prop_name) == BT_STATUS_SUCCESS) { + &p_dev->link_spec.addrt.bda, &prop_name) == BT_STATUS_SUCCESS) { cached_name = (char*)bdname.name; } else { cached_name = "Bluetooth HID"; } - LOG_WARN("%s: name = %s", __func__, cached_name); + log::warn("name = {}", cached_name); bta_hh_co_send_hid_info(p_dev, cached_name, p_data->dscp_info.vendor_id, p_data->dscp_info.product_id, p_data->dscp_info.version, p_data->dscp_info.ctry_code, len, p_data->dscp_info.descriptor.dsc_list); - if (btif_hh_add_added_dev(p_dev->bd_addr, p_dev->attr_mask)) { + if (btif_hh_add_added_dev(p_dev->link_spec, p_dev->attr_mask)) { tBTA_HH_DEV_DSCP_INFO dscp_info; bt_status_t ret; btif_hh_copy_hid_info(&dscp_info, &p_data->dscp_info); - VLOG(1) << "BTA_HH_GET_DSCP_EVT:bda = " - << ADDRESS_TO_LOGGABLE_STR(p_dev->bd_addr); - BTA_HhAddDev(p_dev->bd_addr, p_dev->attr_mask, p_dev->sub_class, + log::verbose("BTA_HH_GET_DSCP_EVT:bda = {}", + ADDRESS_TO_LOGGABLE_STR(p_dev->link_spec.addrt.bda)); + BTA_HhAddDev(p_dev->link_spec, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id, dscp_info); // write hid info to nvram ret = btif_storage_add_hid_device_info( - &(p_dev->bd_addr), p_dev->attr_mask, p_dev->sub_class, + &(p_dev->link_spec.addrt.bda), p_dev->attr_mask, p_dev->sub_class, p_dev->app_id, p_data->dscp_info.vendor_id, p_data->dscp_info.product_id, p_data->dscp_info.version, p_data->dscp_info.ctry_code, p_data->dscp_info.ssr_max_latency, @@ -1039,7 +1030,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { p_data->dscp_info.descriptor.dsc_list); ASSERTC(ret == BT_STATUS_SUCCESS, "storing hid info failed", ret); - LOG_WARN("BTA_HH_GET_DSCP_EVT: Called add device"); + log::warn("BTA_HH_GET_DSCP_EVT: Called add device"); // Free buffer created for dscp_info; if (dscp_info.descriptor.dl_len > 0 && @@ -1049,7 +1040,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { } } else { // Device already added. - LOG_WARN("%s: Device already added ", __func__); + log::warn("Device already added"); } /*Sync HID Keyboard lockstates */ tmplen = sizeof(hid_kb_numlock_on_list) / sizeof(tHID_KB_LIST); @@ -1058,10 +1049,8 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { hid_kb_numlock_on_list[i].version_id && p_data->dscp_info.product_id == hid_kb_numlock_on_list[i].product_id) { - LOG_VERBOSE( - "%s() idx[%d] Enabling " - "NUMLOCK for device :: %s", - __func__, i, hid_kb_numlock_on_list[i].kb_name); + log::verbose("idx[{}] Enabling NUMLOCK for device :: {}", i, + hid_kb_numlock_on_list[i].kb_name); /* Enable NUMLOCK by default so that numeric keys work from first keyboard connect */ set_keylockstate(BTIF_HH_KEYSTATE_MASK_NUMLOCK, true); @@ -1074,15 +1063,16 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { break; case BTA_HH_ADD_DEV_EVT: - LOG_WARN("BTA_HH_ADD_DEV_EVT: status = %d, handle = %d", - p_data->dev_info.status, p_data->dev_info.handle); + log::warn("BTA_HH_ADD_DEV_EVT: status = {}, handle = {}", + p_data->dev_info.status, p_data->dev_info.handle); int i; for (i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { - if (btif_hh_cb.added_devices[i].bd_addr == p_data->dev_info.bda) { + if (btif_hh_cb.added_devices[i].link_spec.addrt.bda == + p_data->dev_info.link_spec.addrt.bda) { if (p_data->dev_info.status == BTA_HH_OK) { btif_hh_cb.added_devices[i].dev_handle = p_data->dev_info.handle; } else { - btif_hh_cb.added_devices[i].bd_addr = RawAddress::kEmpty; + btif_hh_cb.added_devices[i].link_spec = {}; btif_hh_cb.added_devices[i].dev_handle = BTA_HH_INVALID_HANDLE; } break; @@ -1090,44 +1080,48 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) { } break; case BTA_HH_RMV_DEV_EVT: - LOG_VERBOSE("BTA_HH_RMV_DEV_EVT: status = %d, handle = %d", - p_data->dev_info.status, p_data->dev_info.handle); - VLOG(1) << "BTA_HH_RMV_DEV_EVT:bda = " << p_data->dev_info.bda; + log::verbose("BTA_HH_RMV_DEV_EVT: status = {}, handle = {}", + p_data->dev_info.status, p_data->dev_info.handle); + log::verbose( + "BTA_HH_RMV_DEV_EVT:bda = {}", + ADDRESS_TO_LOGGABLE_STR(p_data->dev_info.link_spec.addrt.bda)); break; case BTA_HH_VC_UNPLUG_EVT: - LOG_VERBOSE("BTA_HH_VC_UNPLUG_EVT: status = %d, handle = %d", - p_data->dev_status.status, p_data->dev_status.handle); + log::verbose("BTA_HH_VC_UNPLUG_EVT: status = {}, handle = {}", + p_data->dev_status.status, p_data->dev_status.handle); p_dev = btif_hh_find_connected_dev_by_handle(p_data->dev_status.handle); btif_hh_cb.status = (BTIF_HH_STATUS)BTIF_HH_DEV_DISCONNECTED; if (p_dev != NULL) { - VLOG(1) << "BTA_HH_VC_UNPLUG_EVT:bda = " << p_dev->bd_addr; + log::verbose("BTA_HH_VC_UNPLUG_EVT:bda = {}", + ADDRESS_TO_LOGGABLE_STR(p_dev->link_spec.addrt.bda)); /* Stop the VUP timer */ - btif_hh_stop_vup_timer(&(p_dev->bd_addr)); + btif_hh_stop_vup_timer(&(p_dev->link_spec)); p_dev->dev_status = BTHH_CONN_STATE_DISCONNECTED; - LOG_VERBOSE("%s---Sending connection state change", __func__); - HAL_CBACK(bt_hh_callbacks, connection_state_cb, &(p_dev->bd_addr), - p_dev->dev_status); - LOG_VERBOSE("%s---Removing HID bond", __func__); + log::verbose("--Sending connection state change"); + HAL_CBACK(bt_hh_callbacks, connection_state_cb, + &(p_dev->link_spec.addrt.bda), p_dev->dev_status); + log::verbose("--Removing HID bond"); /* If it is locally initiated VUP or remote device has its major COD as Peripheral removed the bond.*/ - if (p_dev->local_vup || check_cod_hid(&(p_dev->bd_addr))) { + if (p_dev->local_vup || check_cod_hid(&(p_dev->link_spec.addrt.bda))) { p_dev->local_vup = false; - BTA_DmRemoveDevice(p_dev->bd_addr); + BTA_DmRemoveDevice(p_dev->link_spec.addrt.bda); } else - btif_hh_remove_device(p_dev->bd_addr); - HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb, &(p_dev->bd_addr), + btif_hh_remove_device(p_dev->link_spec); + HAL_CBACK(bt_hh_callbacks, virtual_unplug_cb, + &(p_dev->link_spec.addrt.bda), (bthh_status_t)p_data->dev_status.status); } break; case BTA_HH_API_ERR_EVT: - LOG_INFO("BTA_HH API_ERR"); + log::info("BTA_HH API_ERR"); break; default: - LOG_WARN("%s: Unhandled event: %d", __func__, event); + log::warn("Unhandled event: {}", event); break; } } @@ -1149,7 +1143,7 @@ static void btif_hh_hsdata_rpt_copy_cb(uint16_t event, char* p_dest, BT_HDR* hdr; if (!p_src) { - LOG_ERROR("%s: Nothing to copy", __func__); + log::error("Nothing to copy"); return; } @@ -1227,39 +1221,39 @@ static void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) { static void btif_hh_handle_evt(uint16_t event, char* p_param) { CHECK(p_param != nullptr); - RawAddress* bd_addr = (RawAddress*)p_param; + tAclLinkSpec* p_link_spec = (tAclLinkSpec*)p_param; switch (event) { case BTIF_HH_CONNECT_REQ_EVT: { - LOG_DEBUG("Connect request received remote:%s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); - if (btif_hh_connect(bd_addr) == BT_STATUS_SUCCESS) { - HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr, + log::debug("Connect request received remote:{}", + ADDRESS_TO_LOGGABLE_CSTR((*p_link_spec))); + if (btif_hh_connect(p_link_spec) == BT_STATUS_SUCCESS) { + HAL_CBACK(bt_hh_callbacks, connection_state_cb, &p_link_spec->addrt.bda, BTHH_CONN_STATE_CONNECTING); } else - HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr, + HAL_CBACK(bt_hh_callbacks, connection_state_cb, &p_link_spec->addrt.bda, BTHH_CONN_STATE_DISCONNECTED); } break; case BTIF_HH_DISCONNECT_REQ_EVT: { - LOG_DEBUG("Disconnect request received remote:%s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); - btif_hh_disconnect(bd_addr); - HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr, + log::debug("Disconnect request received remote:{}", + ADDRESS_TO_LOGGABLE_CSTR((*p_link_spec))); + btif_hh_disconnect(p_link_spec); + HAL_CBACK(bt_hh_callbacks, connection_state_cb, &p_link_spec->addrt.bda, BTHH_CONN_STATE_DISCONNECTING); } break; case BTIF_HH_VUP_REQ_EVT: { - LOG_DEBUG("Virtual unplug request received remote:%s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); - if (btif_hh_virtual_unplug(bd_addr) != BT_STATUS_SUCCESS) { - LOG_WARN("Unable to virtual unplug device remote:%s", - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); + log::debug("Virtual unplug request received remote:{}", + ADDRESS_TO_LOGGABLE_CSTR((*p_link_spec))); + if (btif_hh_virtual_unplug(p_link_spec) != BT_STATUS_SUCCESS) { + log::warn("Unable to virtual unplug device remote:{}", + ADDRESS_TO_LOGGABLE_CSTR((*p_link_spec))); } } break; default: { - LOG_WARN("Unknown event received:%d remote:%s", event, - ADDRESS_TO_LOGGABLE_CSTR((*bd_addr))); + log::warn("Unknown event received:{} remote:{}", event, + ADDRESS_TO_LOGGABLE_CSTR((*p_link_spec))); } break; } } @@ -1278,7 +1272,7 @@ void btif_hh_timer_timeout(void* data) { tBTA_HH p_data; int param_len = sizeof(tBTA_HH_CBDATA); - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (p_dev->dev_status != BTHH_CONN_STATE_CONNECTED) return; memset(&p_data, 0, sizeof(tBTA_HH)); @@ -1301,7 +1295,7 @@ void btif_hh_timer_timeout(void* data) { ******************************************************************************/ static bt_status_t init(bthh_callbacks_t* callbacks) { uint32_t i; - LOG_VERBOSE("%s", __func__); + log::verbose(""); bt_hh_callbacks = callbacks; memset(&btif_hh_cb, 0, sizeof(btif_hh_cb)); @@ -1325,32 +1319,37 @@ static bt_status_t init(bthh_callbacks_t* callbacks) { ******************************************************************************/ static bt_status_t connect(RawAddress* bd_addr) { btif_hh_device_t* p_dev; + tAclLinkSpec link_spec; if (btif_hh_cb.status == BTIF_HH_DEV_CONNECTING) { - LOG_WARN("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::warn("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_BUSY; } else if (btif_hh_cb.status == BTIF_HH_DISABLED || btif_hh_cb.status == BTIF_HH_DISABLING) { - LOG_WARN("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::warn("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_NOT_READY; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev) { if (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED || p_dev->dev_status == BTHH_CONN_STATE_CONNECTING) { - LOG_ERROR("%s: Error, device %s already connected.", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Error, device {} already connected.", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_DONE; } else if (p_dev->dev_status == BTHH_CONN_STATE_DISCONNECTING) { - LOG_ERROR("%s: Error, device %s is busy with (dis)connecting.", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Error, device {} is busy with (dis)connecting.", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_BUSY; } } return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_CONNECT_REQ_EVT, - (char*)bd_addr, sizeof(RawAddress), NULL); + (char*)&link_spec, sizeof(tAclLinkSpec), NULL); } /******************************************************************************* @@ -1364,35 +1363,40 @@ static bt_status_t connect(RawAddress* bd_addr) { ******************************************************************************/ static bt_status_t disconnect(RawAddress* bd_addr) { CHECK_BTHH_INIT(); - LOG_VERBOSE("BTHH: %s", __func__); + log::verbose("BTHH"); btif_hh_device_t* p_dev; + tAclLinkSpec link_spec; if (btif_hh_cb.status == BTIF_HH_DISABLED || btif_hh_cb.status == BTIF_HH_DISABLING) { - LOG_WARN("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::warn("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_UNHANDLED; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (!p_dev) { - LOG_ERROR("%s: Error, device %s not opened.", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Error, device {} not opened.", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_UNHANDLED; } if (p_dev->dev_status == BTHH_CONN_STATE_DISCONNECTED || p_dev->dev_status == BTHH_CONN_STATE_DISCONNECTING) { - LOG_ERROR("%s: Error, device %s already disconnected.", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Error, device {} already disconnected.", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_DONE; } else if (p_dev->dev_status == BTHH_CONN_STATE_CONNECTING) { - LOG_ERROR("%s: Error, device %s is busy with (dis)connecting.", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Error, device {} is busy with (dis)connecting.", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_BUSY; } return btif_transfer_context(btif_hh_handle_evt, BTIF_HH_DISCONNECT_REQ_EVT, - (char*)bd_addr, sizeof(RawAddress), NULL); + (char*)&link_spec, sizeof(tAclLinkSpec), NULL); } /******************************************************************************* @@ -1406,20 +1410,26 @@ static bt_status_t disconnect(RawAddress* bd_addr) { ******************************************************************************/ static bt_status_t virtual_unplug(RawAddress* bd_addr) { CHECK_BTHH_INIT(); - LOG_VERBOSE("BTHH: %s", __func__); + log::verbose("BTHH"); btif_hh_device_t* p_dev; + tAclLinkSpec link_spec; if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } - p_dev = btif_hh_find_dev_by_bda(*bd_addr); + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; + + p_dev = btif_hh_find_dev_by_bda(link_spec); if (!p_dev) { - LOG_ERROR("%s: Error, device %s not opened.", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::error("Error, device {} not opened.", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } - btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, (char*)bd_addr, - sizeof(RawAddress), NULL); + btif_transfer_context(btif_hh_handle_evt, BTIF_HH_VUP_REQ_EVT, + (char*)&link_spec, sizeof(tAclLinkSpec), NULL); return BT_STATUS_SUCCESS; } @@ -1434,15 +1444,20 @@ static bt_status_t virtual_unplug(RawAddress* bd_addr) { *******************************************************************************/ static bt_status_t get_idle_time(RawAddress* bd_addr) { CHECK_BTHH_INIT(); + tAclLinkSpec link_spec; - LOG_VERBOSE("%s: addr = %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::verbose("addr = {}", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev == NULL) return BT_STATUS_FAIL; BTA_HhGetIdle(p_dev->dev_handle); @@ -1460,19 +1475,23 @@ static bt_status_t get_idle_time(RawAddress* bd_addr) { *******************************************************************************/ static bt_status_t set_idle_time(RawAddress* bd_addr, uint8_t idle_time) { CHECK_BTHH_INIT(); + tAclLinkSpec link_spec; - LOG_VERBOSE("%s: addr = %s, idle time = %d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr), idle_time); + log::verbose("addr = {}, idle time = {}", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr), + idle_time); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev == NULL) { - LOG_WARN("%s: addr = %s not opened", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); + log::warn("addr = {} not opened", ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } @@ -1492,16 +1511,17 @@ static bt_status_t set_idle_time(RawAddress* bd_addr, uint8_t idle_time) { static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) { CHECK_BTHH_INIT(); tBTA_HH_DEV_DSCP_INFO dscp_info; + tAclLinkSpec link_spec; - VLOG(1) << __func__ << " BTHH: addr = " << *bd_addr; - LOG_VERBOSE( - "BTHH: %s: sub_class = 0x%02x, app_id = %d, vendor_id = 0x%04x, " - "product_id = 0x%04x, version= 0x%04x", - __func__, hid_info.sub_class, hid_info.app_id, hid_info.vendor_id, + log::verbose("BTHH: addr = {}", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); + log::verbose( + "BTHH: sub_class = 0x{:02x}, app_id = {}, vendor_id = 0x{:04x}, " + "product_id = 0x{:04x}, version= 0x{:04x}", + hid_info.sub_class, hid_info.app_id, hid_info.vendor_id, hid_info.product_id, hid_info.version); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } @@ -1516,8 +1536,13 @@ static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) { (uint8_t*)osi_malloc(dscp_info.descriptor.dl_len); memcpy(dscp_info.descriptor.dsc_list, &(hid_info.dsc_list), hid_info.dl_len); - if (btif_hh_add_added_dev(*bd_addr, hid_info.attr_mask)) { - BTA_HhAddDev(*bd_addr, hid_info.attr_mask, hid_info.sub_class, + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; + + if (btif_hh_add_added_dev(link_spec, hid_info.attr_mask)) { + BTA_HhAddDev(link_spec, hid_info.attr_mask, hid_info.sub_class, hid_info.app_id, dscp_info); } @@ -1536,17 +1561,22 @@ static bt_status_t set_info(RawAddress* bd_addr, bthh_hid_info_t hid_info) { * ******************************************************************************/ static bt_status_t get_protocol(RawAddress* bd_addr, - UNUSED_ATTR bthh_protocol_mode_t protocolMode) { + bthh_protocol_mode_t /* protocolMode */) { CHECK_BTHH_INIT(); + tAclLinkSpec link_spec; - VLOG(1) << __func__ << " BTHH: addr = " << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::verbose("BTHH: addr = {}", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + btif_hh_device_t* p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (!p_dev) return BT_STATUS_FAIL; BTA_HhGetProtoMode(p_dev->dev_handle); @@ -1567,22 +1597,27 @@ static bt_status_t set_protocol(RawAddress* bd_addr, CHECK_BTHH_INIT(); btif_hh_device_t* p_dev; uint8_t proto_mode = protocolMode; + tAclLinkSpec link_spec; - VLOG(1) << __func__ << " BTHH: proto_mod=" << protocolMode - << " addr = " << *bd_addr; + log::verbose("BTHH: proto_mod={} addr = {}", protocolMode, + ADDRESS_TO_LOGGABLE_STR(*bd_addr)); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev == NULL) { - LOG(WARNING) << " Error, device" << ADDRESS_TO_LOGGABLE_STR(*bd_addr) << " not opened"; + log::warn("Error, device {} not opened", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return BT_STATUS_FAIL; } else if (protocolMode != BTA_HH_PROTO_RPT_MODE && protocolMode != BTA_HH_PROTO_BOOT_MODE) { - LOG_WARN("%s: Error, device proto_mode = %d.", __func__, proto_mode); + log::warn("Error, device proto_mode = {}.", proto_mode); return BT_STATUS_FAIL; } else { BTA_HhSetProtoMode(p_dev->dev_handle, protocolMode); @@ -1605,23 +1640,29 @@ static bt_status_t get_report(RawAddress* bd_addr, int bufferSize) { CHECK_BTHH_INIT(); btif_hh_device_t* p_dev; + tAclLinkSpec link_spec; - VLOG(1) << __func__ << " BTHH: r_type = " << reportType - << ", rpt_id = " << reportId << ", buf_size = " << bufferSize - << " addr = " << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::verbose("BTHH: r_type = {}, rpt_id = {}, buf_size = {} addr = {}", + reportType, reportId, bufferSize, + ADDRESS_TO_LOGGABLE_STR(*bd_addr)); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev == NULL) { - LOG(ERROR) << " Error, device" << ADDRESS_TO_LOGGABLE_STR(*bd_addr) << " not opened"; + log::error("Error, device {} not opened", + ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return BT_STATUS_FAIL; } else if (((int)reportType) <= BTA_HH_RPTT_RESRV || ((int)reportType) > BTA_HH_RPTT_FEATURE) { - LOG(ERROR) << " Error, report type=" << +reportType << " not supported"; + log::error("Error, report type={} not supported", reportType); return BT_STATUS_FAIL; } else { BTA_HhGetReport(p_dev->dev_handle, reportType, reportId, bufferSize); @@ -1643,17 +1684,23 @@ static bt_status_t get_report_reply(RawAddress* bd_addr, bthh_status_t status, char* report, uint16_t size) { CHECK_BTHH_INIT(); btif_hh_device_t* p_dev; + tAclLinkSpec link_spec; - VLOG(1) << __func__ << " BTHH: addr=" << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::verbose("BTHH: addr={}", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev == NULL) { - LOG(ERROR) << " Error, device" << ADDRESS_TO_LOGGABLE_STR(*bd_addr) << " not opened"; + log::error("Error, device {} not opened", + ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return BT_STATUS_FAIL; } @@ -1675,22 +1722,27 @@ static bt_status_t set_report(RawAddress* bd_addr, bthh_report_type_t reportType, char* report) { CHECK_BTHH_INIT(); btif_hh_device_t* p_dev; + tAclLinkSpec link_spec; - VLOG(1) << __func__ << " BTHH: reportType=" << reportType - << " addr=" << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::verbose("BTHH: reportType={} addr={}", reportType, + ADDRESS_TO_LOGGABLE_STR(*bd_addr)); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev == NULL) { - LOG(ERROR) << " Error, device" << ADDRESS_TO_LOGGABLE_STR(*bd_addr) << " not opened"; + log::error("Error, device{} not opened", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return BT_STATUS_FAIL; } else if (((int)reportType) <= BTA_HH_RPTT_RESRV || ((int)reportType) > BTA_HH_RPTT_FEATURE) { - LOG(ERROR) << " Error, report type=" << +reportType << " not supported"; + log::error("Error, report type={} not supported", reportType); return BT_STATUS_FAIL; } else { int hex_bytes_filled; @@ -1700,12 +1752,12 @@ static bt_status_t set_report(RawAddress* bd_addr, /* Build a SetReport data buffer */ // TODO hex_bytes_filled = ascii_2_hex(report, len, hexbuf); - LOG_INFO("Hex bytes filled, hex value: %d", hex_bytes_filled); + log::info("Hex bytes filled, hex value: {}", hex_bytes_filled); if (hex_bytes_filled) { BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf); if (p_buf == NULL) { - LOG_ERROR("%s: Error, failed to allocate RPT buffer, len = %d", - __func__, hex_bytes_filled); + log::error("Error, failed to allocate RPT buffer, len = {}", + hex_bytes_filled); osi_free(hexbuf); return BT_STATUS_FAIL; } @@ -1730,18 +1782,22 @@ static bt_status_t set_report(RawAddress* bd_addr, static bt_status_t send_data(RawAddress* bd_addr, char* data) { CHECK_BTHH_INIT(); btif_hh_device_t* p_dev; + tAclLinkSpec link_spec; - VLOG(1) << __func__ << " addr=" << ADDRESS_TO_LOGGABLE_STR(*bd_addr); + log::verbose("addr={}", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); if (btif_hh_cb.status == BTIF_HH_DISABLED) { - LOG_ERROR("%s: Error, HH status = %d", __func__, btif_hh_cb.status); + log::error("Error, HH status = {}", btif_hh_cb.status); return BT_STATUS_FAIL; } + link_spec.addrt.bda = *bd_addr; + // Todo: fill with params received + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; - p_dev = btif_hh_find_connected_dev_by_bda(*bd_addr); + p_dev = btif_hh_find_connected_dev_by_bda(link_spec); if (p_dev == NULL) { - LOG(ERROR) << " Error, device" - << ADDRESS_TO_LOGGABLE_STR(*bd_addr) << " not opened"; + log::error("Error, device{} not opened", ADDRESS_TO_LOGGABLE_STR(*bd_addr)); return BT_STATUS_FAIL; } @@ -1752,18 +1808,18 @@ static bt_status_t send_data(RawAddress* bd_addr, char* data) { /* Build a SendData data buffer */ hex_bytes_filled = ascii_2_hex(data, len, hexbuf); - LOG_ERROR("Hex bytes filled, hex value: %d, %zu", hex_bytes_filled, len); + log::error("Hex bytes filled, hex value: {}, {}", hex_bytes_filled, len); if (hex_bytes_filled) { BT_HDR* p_buf = create_pbuf(hex_bytes_filled, hexbuf); if (p_buf == NULL) { - LOG_ERROR("%s: Error, failed to allocate RPT buffer, len = %d", - __func__, hex_bytes_filled); + log::error("Error, failed to allocate RPT buffer, len = {}", + hex_bytes_filled); osi_free(hexbuf); return BT_STATUS_FAIL; } p_buf->layer_specific = BTA_HH_RPTT_OUTPUT; - BTA_HhSendData(p_dev->dev_handle, *bd_addr, p_buf); + BTA_HhSendData(p_dev->dev_handle, link_spec, p_buf); osi_free(hexbuf); return BT_STATUS_SUCCESS; } @@ -1782,13 +1838,13 @@ static bt_status_t send_data(RawAddress* bd_addr, char* data) { * ******************************************************************************/ static void cleanup(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_hh_device_t* p_dev; int i; if (btif_hh_cb.status == BTIF_HH_DISABLED || btif_hh_cb.status == BTIF_HH_DISABLING) { - LOG_WARN("%s: HH disabling or disabled already, status = %d", __func__, - btif_hh_cb.status); + log::warn("HH disabling or disabled already, status = {}", + btif_hh_cb.status); return; } if (bt_hh_callbacks) { @@ -1801,7 +1857,7 @@ static void cleanup(void) { for (i = 0; i < BTIF_HH_MAX_HID; i++) { p_dev = &btif_hh_cb.devices[i]; if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->fd >= 0) { - LOG_VERBOSE("%s: Closing uhid fd = %d", __func__, p_dev->fd); + log::verbose("Closing uhid fd = {}", p_dev->fd); bta_hh_co_close(p_dev); } } @@ -1872,7 +1928,7 @@ bt_status_t btif_hh_execute_service(bool b_enable) { * ******************************************************************************/ const bthh_interface_t* btif_hh_get_interface() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return &bthhInterface; } @@ -1885,9 +1941,10 @@ void DumpsysHid(int fd) { LOG_DUMPSYS(fd, "status:%s", btif_hh_status_text(btif_hh_cb.status).c_str()); for (unsigned i = 0; i < BTIF_HH_MAX_HID; i++) { const btif_hh_device_t* p_dev = &btif_hh_cb.devices[i]; - if (p_dev->bd_addr != RawAddress::kEmpty) { + if (p_dev->link_spec.addrt.bda != RawAddress::kEmpty) { LOG_DUMPSYS(fd, " %u: addr:%s fd:%d state:%s ready:%s thread_id:%d", i, - ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr), p_dev->fd, + ADDRESS_TO_LOGGABLE_CSTR(p_dev->link_spec.addrt.bda), + p_dev->fd, bthh_connection_state_text(p_dev->dev_status).c_str(), (p_dev->ready_for_data) ? ("T") : ("F"), static_cast(p_dev->hh_poll_thread_id)); @@ -1895,8 +1952,9 @@ void DumpsysHid(int fd) { } for (unsigned i = 0; i < BTIF_HH_MAX_ADDED_DEV; i++) { const btif_hh_added_device_t* p_dev = &btif_hh_cb.added_devices[i]; - if (p_dev->bd_addr != RawAddress::kEmpty) { - LOG_DUMPSYS(fd, " %u: addr:%s", i, ADDRESS_TO_LOGGABLE_CSTR(p_dev->bd_addr)); + if (p_dev->link_spec.addrt.bda != RawAddress::kEmpty) { + LOG_DUMPSYS(fd, " %u: addr:%s", i, + ADDRESS_TO_LOGGABLE_CSTR(p_dev->link_spec.addrt.bda)); } } } diff --git a/system/btif/src/btif_iot_config.cc b/system/btif/src/btif_iot_config.cc index 967df79eadd1f977bfcc96cff0defdd4d70d68dd..59b513f013293c7843b1ccd7a771cee6eb7c9c73 100644 --- a/system/btif/src/btif_iot_config.cc +++ b/system/btif/src/btif_iot_config.cc @@ -16,6 +16,8 @@ * ******************************************************************************/ +#include + #include "bta_sec_api.h" #include "btif_storage.h" #include "device/include/device_iot_config.h" @@ -23,6 +25,8 @@ #include "os/log.h" #include "stack/include/btm_ble_api.h" +using namespace bluetooth; + /******************************************************************************* * Constants & Macros ******************************************************************************/ @@ -100,9 +104,9 @@ void btif_iot_update_remote_info(tBTA_DM_AUTH_CMPL* p_auth_cmpl, bool is_ble, if (btif_storage_get_remote_device_property(&p_auth_cmpl->bd_addr, &properties[num_properties]) == BT_STATUS_SUCCESS) - LOG_VERBOSE("%s cod retrieved from storage is 0x%06x", __func__, cod); + log::verbose("cod retrieved from storage is 0x{:06x}", cod); if (cod == 0) { - LOG_VERBOSE("%s cod is 0, set as unclassified", __func__); + log::verbose("cod is 0, set as unclassified"); cod = COD_UNCLASSIFIED; } DEVICE_IOT_CONFIG_ADDR_SET_INT(p_auth_cmpl->bd_addr, IOT_CONF_KEY_DEVCLASS, @@ -118,7 +122,7 @@ void btif_iot_update_remote_info(tBTA_DM_AUTH_CMPL* p_auth_cmpl, bool is_ble, if (btif_storage_get_remote_device_property(&p_auth_cmpl->bd_addr, &properties[num_properties]) == BT_STATUS_SUCCESS) { - LOG_VERBOSE("%s retrieve dev type from storage", __func__); + log::verbose("retrieve dev type from storage"); dev_type = (bt_device_type_t)(remote_dev_type | p_auth_cmpl->dev_type); } else { dev_type = (bt_device_type_t)(p_auth_cmpl->dev_type); diff --git a/system/btif/src/btif_jni_task.cc b/system/btif/src/btif_jni_task.cc index 7d41efa6a5eef1bb46ff4defa3ba7ae838ae38c3..083515c872356b1acd0f9f80163fec5e6b77515f 100644 --- a/system/btif/src/btif_jni_task.cc +++ b/system/btif/src/btif_jni_task.cc @@ -16,10 +16,11 @@ #include "btif/include/btif_jni_task.h" -#include +#include #include #include #include +#include #include #include @@ -30,6 +31,7 @@ #include "stack/include/bt_types.h" using base::PlatformThread; +using namespace bluetooth; static bluetooth::common::MessageLoopThread jni_thread("bt_jni_thread"); @@ -76,7 +78,7 @@ bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, tBTIF_CONTEXT_SWITCH_CBACK* p_msg = (tBTIF_CONTEXT_SWITCH_CBACK*)osi_malloc( sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len); - LOG_VERBOSE("btif_transfer_context event %d, len %d", event, param_len); + log::verbose("btif_transfer_context event {}, len {}", event, param_len); /* allocate and send message that will be executed in btif context */ p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */ @@ -101,7 +103,7 @@ bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, bt_status_t do_in_jni_thread(const base::Location& from_here, base::OnceClosure task) { if (!jni_thread.DoInThread(from_here, std::move(task))) { - LOG(ERROR) << __func__ << ": Post task to task runner failed!"; + log::error("Post task to task runner failed!"); return BT_STATUS_FAIL; } return BT_STATUS_SUCCESS; diff --git a/system/btif/src/btif_keystore.cc b/system/btif/src/btif_keystore.cc index 022c78bdc13dff4fe3a6a0bc91497e24fa21102d..734fb3d8f8da355d8d884d4227d83135f1fe603c 100644 --- a/system/btif/src/btif_keystore.cc +++ b/system/btif/src/btif_keystore.cc @@ -21,15 +21,16 @@ #include #include #include +#include #include #include #include "btif_common.h" #include "btif_storage.h" -#include "gd/os/parameter_provider.h" #include "main/shim/config.h" #include "main/shim/shim.h" +#include "os/parameter_provider.h" using base::Bind; using base::Unretained; @@ -47,7 +48,7 @@ class BluetoothKeystoreInterfaceImpl ~BluetoothKeystoreInterfaceImpl() override = default; void init(BluetoothKeystoreCallbacks* callbacks) override { - VLOG(2) << __func__; + log::verbose(""); this->callbacks = callbacks; bluetooth::os::ParameterProvider::SetCommonCriteriaConfigCompareResult( @@ -56,9 +57,9 @@ class BluetoothKeystoreInterfaceImpl } void ConvertEncryptOrDecryptKeyIfNeeded() { - VLOG(2) << __func__; + log::verbose(""); if (!callbacks) { - LOG(INFO) << __func__ << " callback isn't ready."; + log::info("callback isn't ready."); return; } do_in_jni_thread( @@ -69,10 +70,10 @@ class BluetoothKeystoreInterfaceImpl bool set_encrypt_key_or_remove_key(std::string prefix, std::string decryptedString) override { - VLOG(2) << __func__ << " prefix: " << prefix; + log::verbose("prefix: {}", prefix); if (!callbacks) { - LOG(WARNING) << __func__ << " callback isn't ready. prefix: " << prefix; + log::warn("callback isn't ready. prefix: {}", prefix); return false; } @@ -87,10 +88,10 @@ class BluetoothKeystoreInterfaceImpl } std::string get_key(std::string prefix) override { - VLOG(2) << __func__ << " prefix: " << prefix; + log::verbose("prefix: {}", prefix); if (!callbacks) { - LOG(WARNING) << __func__ << " callback isn't ready. prefix: " << prefix; + log::warn("callback isn't ready. prefix: {}", prefix); return ""; } @@ -101,7 +102,7 @@ class BluetoothKeystoreInterfaceImpl decryptedString = callbacks->get_key(prefix); // Save the value into a map. key_map[prefix] = decryptedString; - VLOG(2) << __func__ << ": get key from bluetoothkeystore."; + log::verbose("get key from bluetoothkeystore."); } else { decryptedString = iter->second; } @@ -109,7 +110,7 @@ class BluetoothKeystoreInterfaceImpl } void clear_map() override { - VLOG(2) << __func__; + log::verbose(""); std::map empty_map; key_map.swap(empty_map); diff --git a/system/btif/src/btif_le_audio.cc b/system/btif/src/btif_le_audio.cc index 90931d2dfabb719e077335d5dc8fee1d6b8f7d8d..65760220f28b77c2511981a6a3906123956f4f1d 100644 --- a/system/btif/src/btif_le_audio.cc +++ b/system/btif/src/btif_le_audio.cc @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -32,9 +33,11 @@ using bluetooth::le_audio::btle_audio_codec_config_t; using bluetooth::le_audio::ConnectionState; using bluetooth::le_audio::GroupNodeStatus; using bluetooth::le_audio::GroupStatus; +using bluetooth::le_audio::GroupStreamStatus; using bluetooth::le_audio::LeAudioClientCallbacks; using bluetooth::le_audio::LeAudioClientInterface; using bluetooth::le_audio::UnicastMonitorModeStatus; +using namespace bluetooth; namespace { class LeAudioClientInterfaceImpl; @@ -140,13 +143,20 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, Unretained(callbacks), direction, status)); } + void OnGroupStreamStatus(int group_id, + GroupStreamStatus group_stream_status) override { + do_in_jni_thread( + FROM_HERE, Bind(&LeAudioClientCallbacks::OnGroupStreamStatus, + Unretained(callbacks), group_id, group_stream_status)); + } + void Initialize(LeAudioClientCallbacks* callbacks, const std::vector& offloading_preference) override { this->callbacks = callbacks; for (auto codec : offloading_preference) { - LOG_INFO("supported codec: %s", codec.ToString().c_str()); + log::info("supported codec: {}", codec.ToString()); } do_in_main_thread( @@ -166,9 +176,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void Cleanup(void) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -179,9 +189,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void RemoveDevice(const RawAddress& address) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); do_in_jni_thread(FROM_HERE, Bind(&btif_storage_remove_leaudio, address)); return; @@ -196,9 +206,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void Connect(const RawAddress& address) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -209,9 +219,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void Disconnect(const RawAddress& address) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -222,9 +232,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void SetEnableState(const RawAddress& address, bool enabled) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -235,9 +245,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void GroupAddNode(const int group_id, const RawAddress& address) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -248,9 +258,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void GroupRemoveNode(const int group_id, const RawAddress& address) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -261,9 +271,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void GroupSetActive(const int group_id) override { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -276,9 +286,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, btle_audio_codec_config_t input_codec_config, btle_audio_codec_config_t output_codec_config) { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } do_in_main_thread(FROM_HERE, @@ -289,9 +299,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void SetCcidInformation(int ccid, int context_type) { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -302,9 +312,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, void SetInCall(bool in_call) { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -331,9 +341,9 @@ class LeAudioClientInterfaceImpl : public LeAudioClientInterface, bool is_output_preference_le_audio, bool is_duplex_preference_le_audio) { if (!initialized || !LeAudioClient::IsLeAudioClientRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } diff --git a/system/btif/src/btif_metrics_logging.cc b/system/btif/src/btif_metrics_logging.cc index 8af5033a03b0ee09c7a7fd66236584f9a97bc50a..dadd14eea1d2a72b2716844cefe3df7caf7b26a1 100644 --- a/system/btif/src/btif_metrics_logging.cc +++ b/system/btif/src/btif_metrics_logging.cc @@ -47,6 +47,19 @@ void log_a2dp_playback_event(const RawAddress& address, int playback_state, audio_coding_mode); } +void log_a2dp_session_metrics_event( + const RawAddress& address, int64_t audio_duration_ms, + int media_timer_min_ms, int media_timer_max_ms, int media_timer_avg_ms, + int total_scheduling_count, int buffer_overruns_max_count, + int buffer_overruns_total, float buffer_underruns_average, + int buffer_underruns_count, int64_t codec_index, bool is_a2dp_offload) { + bluetooth::shim::LogMetricA2dpSessionMetricsEvent( + address, audio_duration_ms, media_timer_min_ms, media_timer_max_ms, + media_timer_avg_ms, total_scheduling_count, buffer_overruns_max_count, + buffer_overruns_total, buffer_underruns_average, buffer_underruns_count, + codec_index, is_a2dp_offload); +} + void log_read_rssi_result(const RawAddress& address, uint16_t handle, uint32_t cmd_status, int8_t rssi) { bluetooth::shim::LogMetricReadRssiResult(address, handle, cmd_status, rssi); diff --git a/system/btif/src/btif_pan.cc b/system/btif/src/btif_pan.cc index e2c5b1a21e8f16ce4c83eb79d1d8db97f353884b..b69d8867860924c72ba9a6c7f1c27727a5b476f0 100644 --- a/system/btif/src/btif_pan.cc +++ b/system/btif/src/btif_pan.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -44,12 +45,12 @@ #include "btif/include/btif_pan_internal.h" #include "btif/include/btif_sock_thread.h" #include "device/include/controller.h" +#include "include/check.h" #include "include/hardware/bt_pan.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" -#include "osi/include/osi.h" #include "stack/include/bt_hdr.h" #include "stack/include/main_thread.h" #include "stack/include/pan_api.h" @@ -64,15 +65,15 @@ #define FORWARD_FAILURE (-1) #define FORWARD_CONGEST (-2) -#define asrt(s) \ - do { \ - if (!(s)) \ - LOG_ERROR("btif_pan: ## %s assert %s failed at line:%d ##", __func__, \ - #s, __LINE__); \ +#define asrt(s) \ + do { \ + if (!(s)) log::error("btif_pan: ## assert {} failed ##", #s); \ } while (0) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) +using namespace bluetooth; + btpan_cb_t btpan_cb; static bool jni_initialized; @@ -108,12 +109,12 @@ const btpan_interface_t* btif_pan_get_interface() { return &pan_if; } ** ******************************************************************************/ void btif_pan_init() { - LOG_VERBOSE("jni_initialized = %d, btpan_cb.enabled:%d", jni_initialized, - btpan_cb.enabled); + log::verbose("jni_initialized = {}, btpan_cb.enabled:{}", jni_initialized, + btpan_cb.enabled); stack_initialized = true; if (jni_initialized && !btpan_cb.enabled) { - LOG_VERBOSE("Enabling PAN...."); + log::verbose("Enabling PAN...."); memset(&btpan_cb, 0, sizeof(btpan_cb)); btpan_cb.tap_fd = INVALID_FD; btpan_cb.flow = 1; @@ -158,8 +159,8 @@ void btif_pan_cleanup() { static btpan_callbacks_t callback; static bt_status_t btpan_jni_init(const btpan_callbacks_t* callbacks) { - LOG_VERBOSE("stack_initialized = %d, btpan_cb.enabled:%d", stack_initialized, - btpan_cb.enabled); + log::verbose("stack_initialized = {}, btpan_cb.enabled:{}", stack_initialized, + btpan_cb.enabled); callback = *callbacks; jni_initialized = true; if (stack_initialized && !btpan_cb.enabled) btif_pan_init(); @@ -210,8 +211,9 @@ static bt_status_t btpan_connect(const RawAddress* bd_addr, int local_role, return BT_STATUS_SUCCESS; } +constexpr uint16_t BTIF_PAN_CB_DISCONNECTING = 0x8401; static void btif_in_pan_generic_evt(uint16_t event, char* p_param) { - LOG_VERBOSE("%s: event=%d", __func__, event); + log::verbose("event={}", event); switch (event) { case BTIF_PAN_CB_DISCONNECTING: { RawAddress* bd_addr = (RawAddress*)p_param; @@ -228,7 +230,7 @@ static void btif_in_pan_generic_evt(uint16_t event, char* p_param) { } } break; default: { - LOG_WARN("%s : Unknown event 0x%x", __func__, event); + log::warn("Unknown event 0x{:x}", event); } break; } } @@ -272,8 +274,8 @@ static int tap_if_up(const char* devname, const RawAddress* addr) { strlcpy(ifr.ifr_name, devname, IFNAMSIZ); err = ioctl(sk, SIOCGIFHWADDR, &ifr); if (err < 0) { - LOG_ERROR("Could not get network hardware for interface:%s, errno:%s", - devname, strerror(errno)); + log::error("Could not get network hardware for interface:{}, errno:{}", + devname, strerror(errno)); close(sk); return -1; } @@ -290,15 +292,15 @@ static int tap_if_up(const char* devname, const RawAddress* addr) { * Mask this bit to avoid any issue with auto generated address. */ if (ifr.ifr_hwaddr.sa_data[0] & 0x01) { - LOG_WARN("Not a unicast MAC address, force multicast bit flipping"); + log::warn("Not a unicast MAC address, force multicast bit flipping"); ifr.ifr_hwaddr.sa_data[0] &= ~0x01; } err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr); if (err < 0) { - LOG_ERROR("Could not set bt address for interface:%s, errno:%s", devname, - strerror(errno)); + log::error("Could not set bt address for interface:{}, errno:{}", devname, + strerror(errno)); close(sk); return -1; } @@ -313,13 +315,13 @@ static int tap_if_up(const char* devname, const RawAddress* addr) { err = ioctl(sk, SIOCSIFFLAGS, (caddr_t)&ifr); if (err < 0) { - LOG_ERROR("Could not bring up network interface:%s, errno:%d", devname, - errno); + log::error("Could not bring up network interface:{}, errno:{}", devname, + errno); close(sk); return -1; } close(sk); - LOG_VERBOSE("network interface: %s is up", devname); + log::verbose("network interface: {} is up", devname); return 0; } @@ -362,7 +364,7 @@ int btpan_tap_open() { fd = open(clonedev, O_RDWR); if (fd < 0) { - LOG_VERBOSE("could not open %s, err:%d", clonedev, errno); + log::verbose("could not open {}, err:{}", clonedev, errno); return fd; } @@ -374,7 +376,7 @@ int btpan_tap_open() { /* try to create the device */ err = ioctl(fd, TUNSETIFF, (void*)&ifr); if (err < 0) { - LOG_VERBOSE("ioctl error:%d, errno:%s", err, strerror(errno)); + log::verbose("ioctl error:{}, errno:{}", err, strerror(errno)); close(fd); return err; } @@ -383,14 +385,14 @@ int btpan_tap_open() { fcntl(fd, F_SETFL, flags | O_NONBLOCK); return fd; } - LOG_ERROR("can not bring up tap interface:%s", TAP_IF_NAME); + log::error("can not bring up tap interface:{}", TAP_IF_NAME); close(fd); return INVALID_FD; } int btpan_tap_send(int tap_fd, const RawAddress& src, const RawAddress& dst, uint16_t proto, const char* buf, uint16_t len, - UNUSED_ATTR bool ext, UNUSED_ATTR bool forward) { + bool /* ext */, bool /* forward */) { if (tap_fd != INVALID_FD) { tETH_HDR eth_hdr; eth_hdr.h_dest = dst; @@ -399,7 +401,7 @@ int btpan_tap_send(int tap_fd, const RawAddress& src, const RawAddress& dst, char packet[TAP_MAX_PKT_WRITE_LEN + sizeof(tETH_HDR)]; memcpy(packet, ð_hdr, sizeof(tETH_HDR)); if (len > TAP_MAX_PKT_WRITE_LEN) { - LOG_ERROR("btpan_tap_send eth packet size:%d is exceeded limit!", len); + log::error("btpan_tap_send eth packet size:{} is exceeded limit!", len); return -1; } memcpy(packet + sizeof(tETH_HDR), buf, len); @@ -407,7 +409,7 @@ int btpan_tap_send(int tap_fd, const RawAddress& src, const RawAddress& dst, /* Send data to network interface */ ssize_t ret; OSI_NO_INTR(ret = write(tap_fd, packet, len + sizeof(tETH_HDR))); - LOG_VERBOSE("ret:%zd", ret); + log::verbose("ret:{}", ret); return (int)ret; } return -1; @@ -434,18 +436,18 @@ btpan_conn_t* btpan_find_conn_addr(const RawAddress& addr) { } static void btpan_open_conn(btpan_conn_t* conn, tBTA_PAN* p_data) { - LOG_VERBOSE( - "btpan_open_conn: local_role:%d, peer_role: %d, handle:%d, conn: %p", + log::verbose( + "btpan_open_conn: local_role:{}, peer_role: {}, handle:{}, conn: {}", p_data->open.local_role, p_data->open.peer_role, p_data->open.handle, - conn); + fmt::ptr(conn)); if (conn == NULL) conn = btpan_new_conn(p_data->open.handle, p_data->open.bd_addr, p_data->open.local_role, p_data->open.peer_role); if (conn) { - LOG_VERBOSE( - "btpan_open_conn:tap_fd:%d, open_count:%d, " - "conn->handle:%d should = handle:%d, local_role:%d, remote_role:%d", + log::verbose( + "btpan_open_conn:tap_fd:{}, open_count:{}, conn->handle:{} should = " + "handle:{}, local_role:{}, remote_role:{}", btpan_cb.tap_fd, btpan_cb.open_count, conn->handle, p_data->open.handle, conn->local_role, conn->remote_role); @@ -464,10 +466,10 @@ static void btpan_open_conn(btpan_conn_t* conn, tBTA_PAN* p_data) { } static void btpan_close_conn(btpan_conn_t* conn) { - LOG_VERBOSE("btpan_close_conn: %p", conn); + log::verbose("btpan_close_conn: {}", fmt::ptr(conn)); if (conn && conn->state == PAN_STATE_OPEN) { - LOG_VERBOSE("btpan_close_conn: PAN_STATE_OPEN"); + log::verbose("btpan_close_conn: PAN_STATE_OPEN"); conn->state = PAN_STATE_CLOSE; btpan_cb.open_count--; @@ -497,9 +499,8 @@ btpan_conn_t* btpan_new_conn(int handle, const RawAddress& addr, tBTA_PAN_ROLE remote_role) { for (int i = 0; i < MAX_PAN_CONNS; i++) { if (btpan_cb.conns[i].handle == -1) { - LOG_DEBUG( - "Allocated new pan connection handle:%d local_role:%hhu" - " remote_role:%hhu", + log::debug( + "Allocated new pan connection handle:{} local_role:{} remote_role:{}", handle, local_role, remote_role); btpan_cb.conns[i].handle = handle; btpan_cb.conns[i].peer = addr; @@ -508,12 +509,12 @@ btpan_conn_t* btpan_new_conn(int handle, const RawAddress& addr, return &btpan_cb.conns[i]; } } - LOG_WARN("Unable to create new pan connection max:%d", MAX_PAN_CONNS); + log::warn("Unable to create new pan connection max:{}", MAX_PAN_CONNS); return nullptr; } void btpan_close_handle(btpan_conn_t* p) { - LOG_VERBOSE("btpan_close_handle : close handle %d", p->handle); + log::verbose("btpan_close_handle : close handle {}", p->handle); p->handle = -1; p->local_role = -1; p->remote_role = -1; @@ -524,7 +525,7 @@ static inline bool should_forward(tETH_HDR* hdr) { uint16_t proto = ntohs(hdr->h_proto); if (proto == ETH_P_IP || proto == ETH_P_ARP || proto == ETH_P_IPV6) return true; - LOG_VERBOSE("unknown proto:%x", proto); + log::verbose("unknown proto:{:x}", proto); return false; } @@ -558,7 +559,7 @@ static void bta_pan_callback_transfer(uint16_t event, char* p_param) { switch (event) { case BTA_PAN_ENABLE_EVT: - LOG_VERBOSE("BTA_PAN_ENABLE_EVT"); + log::verbose("BTA_PAN_ENABLE_EVT"); break; case BTA_PAN_SET_ROLE_EVT: { int btpan_role = bta_role_to_btpan(p_data->set_role.role); @@ -571,9 +572,9 @@ static void bta_pan_callback_transfer(uint16_t event, char* p_param) { } case BTA_PAN_OPENING_EVT: { btpan_conn_t* conn; - LOG_VERBOSE("BTA_PAN_OPENING_EVT handle %d, addr: %s", - p_data->opening.handle, - ADDRESS_TO_LOGGABLE_CSTR(p_data->opening.bd_addr)); + log::verbose("BTA_PAN_OPENING_EVT handle {}, addr: {}", + p_data->opening.handle, + ADDRESS_TO_LOGGABLE_CSTR(p_data->opening.bd_addr)); conn = btpan_find_conn_addr(p_data->opening.bd_addr); asrt(conn != NULL); @@ -585,7 +586,7 @@ static void bta_pan_callback_transfer(uint16_t event, char* p_param) { &p_data->opening.bd_addr, btpan_conn_local_role, btpan_remote_role); } else - LOG_ERROR("connection not found"); + log::error("connection not found"); break; } case BTA_PAN_OPEN_EVT: { @@ -593,8 +594,7 @@ static void bta_pan_callback_transfer(uint16_t event, char* p_param) { bt_status_t status; btpan_conn_t* conn = btpan_find_conn_handle(p_data->open.handle); - LOG_VERBOSE("%s pan connection open status: %d", __func__, - p_data->open.status); + log::verbose("pan connection open status: {}", p_data->open.status); if (p_data->open.status) { state = BTPAN_STATE_CONNECTED; status = BT_STATUS_SUCCESS; @@ -615,8 +615,7 @@ static void bta_pan_callback_transfer(uint16_t event, char* p_param) { break; } case BTA_PAN_CLOSE_EVT: { - LOG_INFO("%s: event = BTA_PAN_CLOSE_EVT handle %d", __func__, - p_data->close.handle); + log::info("event = BTA_PAN_CLOSE_EVT handle {}", p_data->close.handle); btpan_conn_t* conn = btpan_find_conn_handle(p_data->close.handle); btpan_close_conn(conn); @@ -628,11 +627,11 @@ static void bta_pan_callback_transfer(uint16_t event, char* p_param) { btpan_remote_role); btpan_cleanup_conn(conn); } else - LOG_ERROR("pan handle not found (%d)", p_data->close.handle); + log::error("pan handle not found ({})", p_data->close.handle); break; } default: - LOG_WARN("Unknown pan event %d", event); + log::warn("Unknown pan event {}", event); break; } } @@ -669,14 +668,13 @@ static void btu_exec_tap_fd_read(int fd) { sizeof(btpan_cb.congest_packet))); switch (ret) { case -1: - LOG_ERROR("%s unable to read from driver: %s", __func__, - strerror(errno)); + log::error("unable to read from driver: {}", strerror(errno)); osi_free(buffer); // add fd back to monitor thread to try it again later btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0); return; case 0: - LOG_WARN("%s end of file reached.", __func__); + log::warn("end of file reached."); osi_free(buffer); // add fd back to monitor thread to process the exception btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0); @@ -705,7 +703,7 @@ static void btu_exec_tap_fd_read(int fd) { if (forward_bnep(&hdr, buffer) != FORWARD_CONGEST) btpan_cb.congest_packet_size = 0; } else { - LOG_WARN("%s dropping packet of length %d", __func__, buffer->len); + log::warn("dropping packet of length {}", buffer->len); btpan_cb.congest_packet_size = 0; osi_free(buffer); } @@ -739,8 +737,7 @@ static void btpan_tap_fd_signaled(int fd, int type, int flags, CHECK(btpan_cb.tap_fd == INVALID_FD || btpan_cb.tap_fd == fd); if (btpan_cb.tap_fd != fd) { - LOG_WARN("%s Signaled on mismatched fds exp:%d act:%d\n", __func__, - btpan_cb.tap_fd, fd); + log::warn("Signaled on mismatched fds exp:{} act:{}", btpan_cb.tap_fd, fd); return; } diff --git a/system/btif/src/btif_profile_queue.cc b/system/btif/src/btif_profile_queue.cc index 32417f783dd32e763138ebbb0f7f8d28abeb61ff..74788c2264249ef1b0fb354e22a42ab9a3244b8b 100644 --- a/system/btif/src/btif_profile_queue.cc +++ b/system/btif/src/btif_profile_queue.cc @@ -32,15 +32,18 @@ #include #include #include +#include #include #include -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "btif_common.h" -#include "main/shim/dumpsys.h" +#include "include/check.h" #include "types/raw_address.h" +using namespace bluetooth; + /******************************************************************************* * Local type definitions ******************************************************************************/ @@ -101,13 +104,13 @@ static void queue_int_add(uint16_t uuid, const RawAddress& bda, ConnectNode param(bda, uuid, connect_cb); for (const auto& node : connect_queue) { if (node.uuid() == param.uuid() && node.address() == param.address()) { - LOG_ERROR("Dropping duplicate profile connection request:%s", - param.ToString().c_str()); + log::error("Dropping duplicate profile connection request:{}", + param.ToString()); return; } } - LOG_INFO("Queueing profile connection request:%s", param.ToString().c_str()); + log::info("Queueing profile connection request:{}", param.ToString()); connect_queue.push_back(param); btif_queue_connect_next(); @@ -117,22 +120,20 @@ static void queue_int_advance() { if (connect_queue.empty()) return; const ConnectNode& head = connect_queue.front(); - LOG_INFO("%s: removing connection request: %s", __func__, - head.ToString().c_str()); + log::info("removing connection request: {}", head.ToString()); connect_queue.pop_front(); btif_queue_connect_next(); } static void queue_int_cleanup(uint16_t uuid) { - LOG_INFO("%s: UUID=%04X", __func__, uuid); + log::info("UUID={:04X}", uuid); for (auto it = connect_queue.begin(); it != connect_queue.end();) { auto it_prev = it++; const ConnectNode& node = *it_prev; if (node.uuid() == uuid) { - LOG_INFO("%s: removing connection request: %s", __func__, - node.ToString().c_str()); + log::info("removing connection request: {}", node.ToString()); connect_queue.erase(it_prev); } } @@ -194,11 +195,11 @@ bt_status_t btif_queue_connect_next(void) { ConnectNode& head = connect_queue.front(); - LOG_INFO("Executing profile connection request:%s", head.ToString().c_str()); + log::info("Executing profile connection request:{}", head.ToString()); bt_status_t b_status = head.connect(); if (b_status != BT_STATUS_SUCCESS) { - LOG_INFO("%s: connect %s failed, advance to next scheduled connection.", - __func__, head.ToString().c_str()); + log::info("connect {} failed, advance to next scheduled connection.", + head.ToString()); btif_queue_advance(); } return b_status; @@ -214,9 +215,9 @@ bt_status_t btif_queue_connect_next(void) { * ******************************************************************************/ void btif_queue_release() { - LOG_INFO("%s", __func__); + log::info(""); if (do_in_jni_thread(FROM_HERE, base::BindOnce(&queue_int_release)) != BT_STATUS_SUCCESS) { - LOG(FATAL) << __func__ << ": Failed to schedule on JNI thread"; + log::fatal("Failed to schedule on JNI thread"); } } diff --git a/system/btif/src/btif_profile_storage.cc b/system/btif/src/btif_profile_storage.cc index 568b827b7dad7fd85621954ba4933ba07ef9641c..2884fb15d0d31f9bbd0309a83e94741f6d3a8b95 100644 --- a/system/btif/src/btif_profile_storage.cc +++ b/system/btif/src/btif_profile_storage.cc @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,7 @@ #include "btif_storage.h" #include "stack/include/bt_uuid16.h" #include "stack/include/main_thread.h" +#include "storage/config_keys.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -49,26 +51,11 @@ using base::Bind; using bluetooth::Uuid; using bluetooth::csis::CsisClient; using bluetooth::groups::DeviceGroups; +using namespace bluetooth; /******************************************************************************* * Constants & Macros ******************************************************************************/ -#define BTIF_STORAGE_PATH_REMOTE_DEVCLASS "DevClass" - -#define BTIF_STORAGE_CSIS_AUTOCONNECT "CsisAutoconnect" -#define BTIF_STORAGE_CSIS_SET_INFO_BIN "CsisSetInfoBin" -#define BTIF_STORAGE_LEAUDIO_AUTOCONNECT "LeAudioAutoconnect" -#define BTIF_STORAGE_LEAUDIO_HANDLES_BIN "LeAudioHandlesBin" -#define BTIF_STORAGE_LEAUDIO_SINK_PACS_BIN "SinkPacsBin" -#define BTIF_STORAGE_LEAUDIO_SOURCE_PACS_BIN "SourcePacsBin" -#define BTIF_STORAGE_LEAUDIO_ASES_BIN "AsesBin" -#define BTIF_STORAGE_LEAUDIO_SINK_AUDIOLOCATION "SinkAudioLocation" -#define BTIF_STORAGE_LEAUDIO_SOURCE_AUDIOLOCATION "SourceAudioLocation" -#define BTIF_STORAGE_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE \ - "SinkSupportedContextType" -#define BTIF_STORAGE_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE \ - "SourceSupportedContextType" -#define BTIF_STORAGE_DEVICE_GROUP_BIN "DeviceGroupBin" #define STORAGE_HID_ATRR_MASK_SIZE (4) #define STORAGE_HID_SUB_CLASS_SIZE (2) @@ -110,18 +97,22 @@ bt_status_t btif_storage_add_hid_device_info( uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version, uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout, uint16_t dl_len, uint8_t* dsc_list) { - LOG_VERBOSE("btif_storage_add_hid_device_info:"); + log::verbose("btif_storage_add_hid_device_info:"); std::string bdstr = remote_bd_addr->ToString(); - btif_config_set_int(bdstr, "HidAttrMask", attr_mask); - btif_config_set_int(bdstr, "HidSubClass", sub_class); - btif_config_set_int(bdstr, "HidAppId", app_id); - btif_config_set_int(bdstr, "HidVendorId", vendor_id); - btif_config_set_int(bdstr, "HidProductId", product_id); - btif_config_set_int(bdstr, "HidVersion", version); - btif_config_set_int(bdstr, "HidCountryCode", ctry_code); - btif_config_set_int(bdstr, "HidSSRMaxLatency", ssr_max_latency); - btif_config_set_int(bdstr, "HidSSRMinTimeout", ssr_min_tout); - if (dl_len > 0) btif_config_set_bin(bdstr, "HidDescriptor", dsc_list, dl_len); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_ATTR_MASK, attr_mask); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_SUB_CLASS, sub_class); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_APP_ID, app_id); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_VENDOR_ID, vendor_id); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_PRODUCT_ID, product_id); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_VERSION, version); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_COUNTRY_CODE, ctry_code); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_SSR_MAX_LATENCY, + ssr_max_latency); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HID_SSR_MIN_TIMEOUT, + ssr_min_tout); + if (dl_len > 0) + btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_HID_DESCRIPTOR, dsc_list, + dl_len); return BT_STATUS_SUCCESS; } @@ -138,11 +129,13 @@ bt_status_t btif_storage_add_hid_device_info( bt_status_t btif_storage_load_bonded_hid_info(void) { for (const auto& bd_addr : btif_config_get_paired_devices()) { auto name = bd_addr.ToString(); + tAclLinkSpec link_spec; - LOG_VERBOSE("Remote device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Remote device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); int value; - if (!btif_config_get_int(name, "HidAttrMask", &value)) continue; + if (!btif_config_get_int(name, BTIF_STORAGE_KEY_HID_ATTR_MASK, &value)) + continue; uint16_t attr_mask = (uint16_t)value; if (btif_in_fetch_bonded_device(name) != BT_STATUS_SUCCESS) { @@ -153,43 +146,47 @@ bt_status_t btif_storage_load_bonded_hid_info(void) { tBTA_HH_DEV_DSCP_INFO dscp_info; memset(&dscp_info, 0, sizeof(dscp_info)); - btif_config_get_int(name, "HidSubClass", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_SUB_CLASS, &value); uint8_t sub_class = (uint8_t)value; - btif_config_get_int(name, "HidAppId", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_APP_ID, &value); uint8_t app_id = (uint8_t)value; - btif_config_get_int(name, "HidVendorId", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_VENDOR_ID, &value); dscp_info.vendor_id = (uint16_t)value; - btif_config_get_int(name, "HidProductId", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_PRODUCT_ID, &value); dscp_info.product_id = (uint16_t)value; - btif_config_get_int(name, "HidVersion", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_VERSION, &value); dscp_info.version = (uint16_t)value; - btif_config_get_int(name, "HidCountryCode", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_COUNTRY_CODE, &value); dscp_info.ctry_code = (uint8_t)value; value = 0; - btif_config_get_int(name, "HidSSRMaxLatency", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_SSR_MAX_LATENCY, &value); dscp_info.ssr_max_latency = (uint16_t)value; value = 0; - btif_config_get_int(name, "HidSSRMinTimeout", &value); + btif_config_get_int(name, BTIF_STORAGE_KEY_HID_SSR_MIN_TIMEOUT, &value); dscp_info.ssr_min_tout = (uint16_t)value; - size_t len = btif_config_get_bin_length(name, "HidDescriptor"); + size_t len = + btif_config_get_bin_length(name, BTIF_STORAGE_KEY_HID_DESCRIPTOR); if (len > 0) { dscp_info.descriptor.dl_len = (uint16_t)len; dscp_info.descriptor.dsc_list = (uint8_t*)alloca(len); - btif_config_get_bin(name, "HidDescriptor", + btif_config_get_bin(name, BTIF_STORAGE_KEY_HID_DESCRIPTOR, (uint8_t*)dscp_info.descriptor.dsc_list, &len); } // add extracted information to BTA HH - if (btif_hh_add_added_dev(bd_addr, attr_mask)) { - BTA_HhAddDev(bd_addr, attr_mask, sub_class, app_id, dscp_info); + link_spec.addrt.bda = bd_addr; + link_spec.addrt.type = BLE_ADDR_PUBLIC; + link_spec.transport = BT_TRANSPORT_AUTO; + if (btif_hh_add_added_dev(link_spec, attr_mask)) { + BTA_HhAddDev(link_spec, attr_mask, sub_class, app_id, dscp_info); } } @@ -210,18 +207,18 @@ bt_status_t btif_storage_load_bonded_hid_info(void) { bt_status_t btif_storage_remove_hid_info(const RawAddress& remote_bd_addr) { std::string bdstr = remote_bd_addr.ToString(); - btif_config_remove(bdstr, "HidAttrMask"); - btif_config_remove(bdstr, "HidSubClass"); - btif_config_remove(bdstr, "HidAppId"); - btif_config_remove(bdstr, "HidVendorId"); - btif_config_remove(bdstr, "HidProductId"); - btif_config_remove(bdstr, "HidVersion"); - btif_config_remove(bdstr, "HidCountryCode"); - btif_config_remove(bdstr, "HidSSRMaxLatency"); - btif_config_remove(bdstr, "HidSSRMinTimeout"); - btif_config_remove(bdstr, "HidDescriptor"); - btif_config_remove(bdstr, "HidReport"); - btif_config_remove(bdstr, "HidReportVersion"); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_ATTR_MASK); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_SUB_CLASS); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_APP_ID); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_VENDOR_ID); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_PRODUCT_ID); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_VERSION); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_COUNTRY_CODE); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_SSR_MAX_LATENCY); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_SSR_MIN_TIMEOUT); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_DESCRIPTOR); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_REPORT); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_HID_REPORT_VERSION); return BT_STATUS_SUCCESS; } @@ -230,7 +227,7 @@ static bool btif_device_supports_profile(const std::string& device, const Uuid& profile) { int size = STORAGE_UUID_STRING_SIZE * BT_MAX_NUM_UUIDS; char uuid_str[size]; - if (btif_config_get_str(device, BTIF_STORAGE_PATH_REMOTE_SERVICE, uuid_str, + if (btif_config_get_str(device, BTIF_STORAGE_KEY_REMOTE_SERVICE, uuid_str, &size)) { Uuid p_uuid[BT_MAX_NUM_UUIDS]; size_t num_uuids = @@ -277,7 +274,7 @@ std::vector> btif_storage_get_le_hid_devices( btif_get_address_type(bd_addr, &type); hid_addresses.push_back({bd_addr, type}); - LOG_DEBUG("Remote device: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Remote device: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } @@ -297,68 +294,61 @@ std::vector btif_storage_get_wake_capable_classic_hid_devices( constexpr int kHidMask = COD_HID_MAJOR; constexpr int kKeyboardMouseMask = COD_HID_COMBO & ~COD_HID_MAJOR; int cod_value; - if (!btif_config_get_int(name, BTIF_STORAGE_PATH_REMOTE_DEVCLASS, - &cod_value) || + if (!btif_config_get_int(name, BTIF_STORAGE_KEY_DEV_CLASS, &cod_value) || (cod_value & kHidMask) != kHidMask || (cod_value & kKeyboardMouseMask) == 0) { continue; } hid_addresses.push_back(bd_addr); - LOG_DEBUG("Remote device: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Remote device: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } return hid_addresses; } -constexpr char HEARING_AID_READ_PSM_HANDLE[] = "HearingAidReadPsmHandle"; -constexpr char HEARING_AID_CAPABILITIES[] = "HearingAidCapabilities"; -constexpr char HEARING_AID_CODECS[] = "HearingAidCodecs"; -constexpr char HEARING_AID_AUDIO_CONTROL_POINT[] = - "HearingAidAudioControlPoint"; -constexpr char HEARING_AID_VOLUME_HANDLE[] = "HearingAidVolumeHandle"; -constexpr char HEARING_AID_AUDIO_STATUS_HANDLE[] = - "HearingAidAudioStatusHandle"; -constexpr char HEARING_AID_AUDIO_STATUS_CCC_HANDLE[] = - "HearingAidAudioStatusCccHandle"; -constexpr char HEARING_AID_SERVICE_CHANGED_CCC_HANDLE[] = - "HearingAidServiceChangedCccHandle"; -constexpr char HEARING_AID_SYNC_ID[] = "HearingAidSyncId"; -constexpr char HEARING_AID_RENDER_DELAY[] = "HearingAidRenderDelay"; -constexpr char HEARING_AID_PREPARATION_DELAY[] = "HearingAidPreparationDelay"; -constexpr char HEARING_AID_IS_ACCEPTLISTED[] = "HearingAidIsAcceptlisted"; - void btif_storage_add_hearing_aid(const HearingDevice& dev_info) { do_in_jni_thread( FROM_HERE, Bind( [](const HearingDevice& dev_info) { std::string bdstr = dev_info.address.ToString(); - VLOG(2) << "saving hearing aid device: " - << ADDRESS_TO_LOGGABLE_STR(dev_info.address); - btif_config_set_int(bdstr, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, - dev_info.service_changed_ccc_handle); - btif_config_set_int(bdstr, HEARING_AID_READ_PSM_HANDLE, + log::verbose("saving hearing aid device: {}", + ADDRESS_TO_LOGGABLE_STR(dev_info.address)); + btif_config_set_int( + bdstr, BTIF_STORAGE_KEY_HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, + dev_info.service_changed_ccc_handle); + btif_config_set_int(bdstr, + BTIF_STORAGE_KEY_HEARING_AID_READ_PSM_HANDLE, dev_info.read_psm_handle); - btif_config_set_int(bdstr, HEARING_AID_CAPABILITIES, + btif_config_set_int(bdstr, + BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES, dev_info.capabilities); - btif_config_set_int(bdstr, HEARING_AID_CODECS, dev_info.codecs); - btif_config_set_int(bdstr, HEARING_AID_AUDIO_CONTROL_POINT, - dev_info.audio_control_point_handle); - btif_config_set_int(bdstr, HEARING_AID_VOLUME_HANDLE, + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_HEARING_AID_CODECS, + dev_info.codecs); + btif_config_set_int( + bdstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_CONTROL_POINT, + dev_info.audio_control_point_handle); + btif_config_set_int(bdstr, + BTIF_STORAGE_KEY_HEARING_AID_VOLUME_HANDLE, dev_info.volume_handle); - btif_config_set_int(bdstr, HEARING_AID_AUDIO_STATUS_HANDLE, - dev_info.audio_status_handle); - btif_config_set_int(bdstr, HEARING_AID_AUDIO_STATUS_CCC_HANDLE, - dev_info.audio_status_ccc_handle); - btif_config_set_uint64(bdstr, HEARING_AID_SYNC_ID, + btif_config_set_int( + bdstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_HANDLE, + dev_info.audio_status_handle); + btif_config_set_int( + bdstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_CCC_HANDLE, + dev_info.audio_status_ccc_handle); + btif_config_set_uint64(bdstr, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID, dev_info.hi_sync_id); - btif_config_set_int(bdstr, HEARING_AID_RENDER_DELAY, + btif_config_set_int(bdstr, + BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY, dev_info.render_delay); - btif_config_set_int(bdstr, HEARING_AID_PREPARATION_DELAY, + btif_config_set_int(bdstr, + BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY, dev_info.preparation_delay); - btif_config_set_int(bdstr, HEARING_AID_IS_ACCEPTLISTED, true); + btif_config_set_int( + bdstr, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED, true); }, dev_info)); } @@ -371,7 +361,7 @@ void btif_storage_load_bonded_hearing_aids() { int size = STORAGE_UUID_STRING_SIZE * BT_MAX_NUM_UUIDS; char uuid_str[size]; bool isHearingaidDevice = false; - if (btif_config_get_str(name, BTIF_STORAGE_PATH_REMOTE_SERVICE, uuid_str, + if (btif_config_get_str(name, BTIF_STORAGE_KEY_REMOTE_SERVICE, uuid_str, &size)) { Uuid p_uuid[BT_MAX_NUM_UUIDS]; size_t num_uuids = @@ -387,7 +377,7 @@ void btif_storage_load_bonded_hearing_aids() { continue; } - LOG_VERBOSE("Remote device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Remote device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (btif_in_fetch_bonded_device(name) != BT_STATUS_SUCCESS) { btif_storage_remove_hearing_aid(bd_addr); @@ -396,52 +386,64 @@ void btif_storage_load_bonded_hearing_aids() { int value; uint8_t capabilities = 0; - if (btif_config_get_int(name, HEARING_AID_CAPABILITIES, &value)) + if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES, + &value)) capabilities = value; uint16_t codecs = 0; - if (btif_config_get_int(name, HEARING_AID_CODECS, &value)) codecs = value; + if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_CODECS, &value)) + codecs = value; uint16_t audio_control_point_handle = 0; - if (btif_config_get_int(name, HEARING_AID_AUDIO_CONTROL_POINT, &value)) + if (btif_config_get_int( + name, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_CONTROL_POINT, &value)) audio_control_point_handle = value; uint16_t audio_status_handle = 0; - if (btif_config_get_int(name, HEARING_AID_AUDIO_STATUS_HANDLE, &value)) + if (btif_config_get_int( + name, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_HANDLE, &value)) audio_status_handle = value; uint16_t audio_status_ccc_handle = 0; - if (btif_config_get_int(name, HEARING_AID_AUDIO_STATUS_CCC_HANDLE, &value)) + if (btif_config_get_int( + name, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_CCC_HANDLE, &value)) audio_status_ccc_handle = value; uint16_t service_changed_ccc_handle = 0; - if (btif_config_get_int(name, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, - &value)) + if (btif_config_get_int( + name, BTIF_STORAGE_KEY_HEARING_AID_SERVICE_CHANGED_CCC_HANDLE, + &value)) service_changed_ccc_handle = value; uint16_t volume_handle = 0; - if (btif_config_get_int(name, HEARING_AID_VOLUME_HANDLE, &value)) + if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_VOLUME_HANDLE, + &value)) volume_handle = value; uint16_t read_psm_handle = 0; - if (btif_config_get_int(name, HEARING_AID_READ_PSM_HANDLE, &value)) + if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_READ_PSM_HANDLE, + &value)) read_psm_handle = value; uint64_t lvalue; uint64_t hi_sync_id = 0; - if (btif_config_get_uint64(name, HEARING_AID_SYNC_ID, &lvalue)) + if (btif_config_get_uint64(name, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID, + &lvalue)) hi_sync_id = lvalue; uint16_t render_delay = 0; - if (btif_config_get_int(name, HEARING_AID_RENDER_DELAY, &value)) + if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY, + &value)) render_delay = value; uint16_t preparation_delay = 0; - if (btif_config_get_int(name, HEARING_AID_PREPARATION_DELAY, &value)) + if (btif_config_get_int( + name, BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY, &value)) preparation_delay = value; bool is_acceptlisted = false; - if (btif_config_get_int(name, HEARING_AID_IS_ACCEPTLISTED, &value)) + if (btif_config_get_int(name, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED, + &value)) is_acceptlisted = value; // add extracted information to BTA Hearing Aid @@ -460,18 +462,20 @@ void btif_storage_load_bonded_hearing_aids() { /** Deletes the bonded hearing aid device info from NVRAM */ void btif_storage_remove_hearing_aid(const RawAddress& address) { std::string addrstr = address.ToString(); - btif_config_remove(addrstr, HEARING_AID_READ_PSM_HANDLE); - btif_config_remove(addrstr, HEARING_AID_CAPABILITIES); - btif_config_remove(addrstr, HEARING_AID_CODECS); - btif_config_remove(addrstr, HEARING_AID_AUDIO_CONTROL_POINT); - btif_config_remove(addrstr, HEARING_AID_VOLUME_HANDLE); - btif_config_remove(addrstr, HEARING_AID_AUDIO_STATUS_HANDLE); - btif_config_remove(addrstr, HEARING_AID_AUDIO_STATUS_CCC_HANDLE); - btif_config_remove(addrstr, HEARING_AID_SERVICE_CHANGED_CCC_HANDLE); - btif_config_remove(addrstr, HEARING_AID_SYNC_ID); - btif_config_remove(addrstr, HEARING_AID_RENDER_DELAY); - btif_config_remove(addrstr, HEARING_AID_PREPARATION_DELAY); - btif_config_remove(addrstr, HEARING_AID_IS_ACCEPTLISTED); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_READ_PSM_HANDLE); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CODECS); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_CONTROL_POINT); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_VOLUME_HANDLE); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_HANDLE); + btif_config_remove(addrstr, + BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_CCC_HANDLE); + btif_config_remove(addrstr, + BTIF_STORAGE_KEY_HEARING_AID_SERVICE_CHANGED_CCC_HANDLE); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED); } /** Set/Unset the hearing aid device HEARING_AID_IS_ACCEPTLISTED flag. */ @@ -479,7 +483,8 @@ void btif_storage_set_hearing_aid_acceptlist(const RawAddress& address, bool add_to_acceptlist) { std::string addrstr = address.ToString(); - btif_config_set_int(addrstr, HEARING_AID_IS_ACCEPTLISTED, add_to_acceptlist); + btif_config_set_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED, + add_to_acceptlist); } /** Get the hearing aid device properties. */ @@ -489,32 +494,37 @@ bool btif_storage_get_hearing_aid_prop( std::string addrstr = address.ToString(); int value; - if (btif_config_get_int(addrstr, HEARING_AID_CAPABILITIES, &value)) { + if (btif_config_get_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES, + &value)) { *capabilities = value; } else { return false; } - if (btif_config_get_int(addrstr, HEARING_AID_CODECS, &value)) { + if (btif_config_get_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_CODECS, + &value)) { *codecs = value; } else { return false; } - if (btif_config_get_int(addrstr, HEARING_AID_RENDER_DELAY, &value)) { + if (btif_config_get_int(addrstr, BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY, + &value)) { *render_delay = value; } else { return false; } - if (btif_config_get_int(addrstr, HEARING_AID_PREPARATION_DELAY, &value)) { + if (btif_config_get_int( + addrstr, BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY, &value)) { *preparation_delay = value; } else { return false; } uint64_t lvalue; - if (btif_config_get_uint64(addrstr, HEARING_AID_SYNC_ID, &lvalue)) { + if (btif_config_get_uint64(addrstr, BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID, + &lvalue)) { *hi_sync_id = lvalue; } else { return false; @@ -529,10 +539,12 @@ void btif_storage_set_leaudio_autoconnect(const RawAddress& addr, do_in_jni_thread(FROM_HERE, Bind( [](const RawAddress& addr, bool autoconnect) { std::string bdstr = addr.ToString(); - VLOG(2) << "saving le audio device: " - << ADDRESS_TO_LOGGABLE_CSTR(addr); + log::verbose( + "saving le audio device: {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); btif_config_set_int( - bdstr, BTIF_STORAGE_LEAUDIO_AUTOCONNECT, + bdstr, + BTIF_STORAGE_KEY_LEAUDIO_AUTOCONNECT, autoconnect); }, addr, autoconnect)); @@ -548,7 +560,7 @@ void btif_storage_leaudio_update_handles_bin(const RawAddress& addr) { Bind( [](const RawAddress& bd_addr, std::vector handles) { auto bdstr = bd_addr.ToString(); - btif_config_set_bin(bdstr, BTIF_STORAGE_LEAUDIO_HANDLES_BIN, + btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN, handles.data(), handles.size()); }, addr, std::move(handles))); @@ -565,7 +577,7 @@ void btif_storage_leaudio_update_pacs_bin(const RawAddress& addr) { Bind( [](const RawAddress& bd_addr, std::vector sink_pacs) { auto bdstr = bd_addr.ToString(); - btif_config_set_bin(bdstr, BTIF_STORAGE_LEAUDIO_SINK_PACS_BIN, + btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN, sink_pacs.data(), sink_pacs.size()); }, addr, std::move(sink_pacs))); @@ -578,7 +590,8 @@ void btif_storage_leaudio_update_pacs_bin(const RawAddress& addr) { Bind( [](const RawAddress& bd_addr, std::vector source_pacs) { auto bdstr = bd_addr.ToString(); - btif_config_set_bin(bdstr, BTIF_STORAGE_LEAUDIO_SOURCE_PACS_BIN, + btif_config_set_bin(bdstr, + BTIF_STORAGE_KEY_LEAUDIO_SOURCE_PACS_BIN, source_pacs.data(), source_pacs.size()); }, addr, std::move(source_pacs))); @@ -595,7 +608,7 @@ void btif_storage_leaudio_update_ase_bin(const RawAddress& addr) { Bind( [](const RawAddress& bd_addr, std::vector ases) { auto bdstr = bd_addr.ToString(); - btif_config_set_bin(bdstr, BTIF_STORAGE_LEAUDIO_ASES_BIN, + btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN, ases.data(), ases.size()); }, addr, std::move(ases))); @@ -611,12 +624,13 @@ void btif_storage_set_leaudio_audio_location(const RawAddress& addr, Bind( [](const RawAddress& addr, int sink_location, int source_location) { std::string bdstr = addr.ToString(); - LOG_DEBUG("saving le audio device: %s", - ADDRESS_TO_LOGGABLE_CSTR(addr)); - btif_config_set_int(bdstr, BTIF_STORAGE_LEAUDIO_SINK_AUDIOLOCATION, + log::debug("saving le audio device: {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); + btif_config_set_int(bdstr, + BTIF_STORAGE_KEY_LEAUDIO_SINK_AUDIOLOCATION, sink_location); btif_config_set_int(bdstr, - BTIF_STORAGE_LEAUDIO_SOURCE_AUDIOLOCATION, + BTIF_STORAGE_KEY_LEAUDIO_SOURCE_AUDIOLOCATION, source_location); }, addr, sink_location, source_location)); @@ -632,13 +646,13 @@ void btif_storage_set_leaudio_supported_context_types( [](const RawAddress& addr, int sink_supported_context_type, int source_supported_context_type) { std::string bdstr = addr.ToString(); - LOG_DEBUG("saving le audio device: %s", - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::debug("saving le audio device: {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); btif_config_set_int( - bdstr, BTIF_STORAGE_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE, + bdstr, BTIF_STORAGE_KEY_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE, sink_supported_context_type); btif_config_set_int( - bdstr, BTIF_STORAGE_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE, + bdstr, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE, source_supported_context_type); }, addr, sink_supported_context_type, source_supported_context_type)); @@ -652,7 +666,7 @@ void btif_storage_load_bonded_leaudio() { int size = STORAGE_UUID_STRING_SIZE * BT_MAX_NUM_UUIDS; char uuid_str[size]; bool isLeAudioDevice = false; - if (btif_config_get_str(name, BTIF_STORAGE_PATH_REMOTE_SERVICE, uuid_str, + if (btif_config_get_str(name, BTIF_STORAGE_KEY_REMOTE_SERVICE, uuid_str, &size)) { Uuid p_uuid[BT_MAX_NUM_UUIDS]; size_t num_uuids = @@ -668,62 +682,63 @@ void btif_storage_load_bonded_leaudio() { continue; } - LOG_VERBOSE("Remote device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Remote device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); int value; bool autoconnect = false; - if (btif_config_get_int(name, BTIF_STORAGE_LEAUDIO_AUTOCONNECT, &value)) + if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_AUTOCONNECT, &value)) autoconnect = !!value; int sink_audio_location = 0; - if (btif_config_get_int(name, BTIF_STORAGE_LEAUDIO_SINK_AUDIOLOCATION, + if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_SINK_AUDIOLOCATION, &value)) sink_audio_location = value; int source_audio_location = 0; - if (btif_config_get_int(name, BTIF_STORAGE_LEAUDIO_SOURCE_AUDIOLOCATION, + if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_AUDIOLOCATION, &value)) source_audio_location = value; int sink_supported_context_type = 0; if (btif_config_get_int( - name, BTIF_STORAGE_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE, &value)) + name, BTIF_STORAGE_KEY_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE, &value)) sink_supported_context_type = value; int source_supported_context_type = 0; if (btif_config_get_int( - name, BTIF_STORAGE_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE, &value)) + name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE, + &value)) source_supported_context_type = value; size_t buffer_size = - btif_config_get_bin_length(name, BTIF_STORAGE_LEAUDIO_HANDLES_BIN); + btif_config_get_bin_length(name, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN); std::vector handles(buffer_size); if (buffer_size > 0) { - btif_config_get_bin(name, BTIF_STORAGE_LEAUDIO_HANDLES_BIN, + btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN, handles.data(), &buffer_size); } - buffer_size = - btif_config_get_bin_length(name, BTIF_STORAGE_LEAUDIO_SINK_PACS_BIN); + buffer_size = btif_config_get_bin_length( + name, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN); std::vector sink_pacs(buffer_size); if (buffer_size > 0) { - btif_config_get_bin(name, BTIF_STORAGE_LEAUDIO_SINK_PACS_BIN, + btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN, sink_pacs.data(), &buffer_size); } - buffer_size = - btif_config_get_bin_length(name, BTIF_STORAGE_LEAUDIO_SOURCE_PACS_BIN); + buffer_size = btif_config_get_bin_length( + name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_PACS_BIN); std::vector source_pacs(buffer_size); if (buffer_size > 0) { - btif_config_get_bin(name, BTIF_STORAGE_LEAUDIO_SOURCE_PACS_BIN, + btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_SOURCE_PACS_BIN, source_pacs.data(), &buffer_size); } buffer_size = - btif_config_get_bin_length(name, BTIF_STORAGE_LEAUDIO_ASES_BIN); + btif_config_get_bin_length(name, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN); std::vector ases(buffer_size); if (buffer_size > 0) { - btif_config_get_bin(name, BTIF_STORAGE_LEAUDIO_ASES_BIN, ases.data(), + btif_config_get_bin(name, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN, ases.data(), &buffer_size); } @@ -739,22 +754,17 @@ void btif_storage_load_bonded_leaudio() { void btif_storage_leaudio_clear_service_data(const RawAddress& address) { auto bdstr = address.ToString(); - btif_config_remove(bdstr, BTIF_STORAGE_LEAUDIO_HANDLES_BIN); - btif_config_remove(bdstr, BTIF_STORAGE_LEAUDIO_SINK_PACS_BIN); - btif_config_remove(bdstr, BTIF_STORAGE_LEAUDIO_ASES_BIN); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN); + btif_config_remove(bdstr, BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN); } /** Remove the Le Audio device from storage */ void btif_storage_remove_leaudio(const RawAddress& address) { std::string addrstr = address.ToString(); - btif_config_set_int(addrstr, BTIF_STORAGE_LEAUDIO_AUTOCONNECT, false); + btif_config_set_int(addrstr, BTIF_STORAGE_KEY_LEAUDIO_AUTOCONNECT, false); } -constexpr char HAS_IS_ACCEPTLISTED[] = "LeAudioHasIsAcceptlisted"; -constexpr char HAS_FEATURES[] = "LeAudioHasFlags"; -constexpr char HAS_ACTIVE_PRESET[] = "LeAudioHasActivePreset"; -constexpr char HAS_SERIALIZED_PRESETS[] = "LeAudioHasSerializedPresets"; - void btif_storage_add_leaudio_has_device(const RawAddress& address, std::vector presets_bin, uint8_t features, @@ -766,12 +776,17 @@ void btif_storage_add_leaudio_has_device(const RawAddress& address, uint8_t features, uint8_t active_preset) { const std::string& name = address.ToString(); - btif_config_set_int(name, HAS_FEATURES, features); - btif_config_set_int(name, HAS_ACTIVE_PRESET, active_preset); - btif_config_set_bin(name, HAS_SERIALIZED_PRESETS, + btif_config_set_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS, + features); + btif_config_set_int(name, + BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET, + active_preset); + btif_config_set_bin(name, + BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS, presets_bin.data(), presets_bin.size()); - btif_config_set_int(name, HAS_IS_ACCEPTLISTED, true); + btif_config_set_int( + name, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED, true); }, address, std::move(presets_bin), features, active_preset)); } @@ -783,8 +798,9 @@ void btif_storage_set_leaudio_has_active_preset(const RawAddress& address, [](const RawAddress& address, uint8_t active_preset) { const std::string& name = address.ToString(); - btif_config_set_int(name, HAS_ACTIVE_PRESET, - active_preset); + btif_config_set_int( + name, BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET, + active_preset); }, address, active_preset)); } @@ -794,7 +810,8 @@ bool btif_storage_get_leaudio_has_features(const RawAddress& address, std::string name = address.ToString(); int value; - if (!btif_config_get_int(name, HAS_FEATURES, &value)) return false; + if (!btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS, &value)) + return false; features = value; return true; @@ -807,7 +824,9 @@ void btif_storage_set_leaudio_has_features(const RawAddress& address, [](const RawAddress& address, uint8_t features) { const std::string& name = address.ToString(); - btif_config_set_int(name, HAS_FEATURES, features); + btif_config_set_int(name, + BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS, + features); }, address, features)); } @@ -816,21 +835,25 @@ void btif_storage_load_bonded_leaudio_has_devices() { for (const auto& bd_addr : btif_config_get_paired_devices()) { const std::string& name = bd_addr.ToString(); - if (!btif_config_exist(name, HAS_IS_ACCEPTLISTED) && - !btif_config_exist(name, HAS_FEATURES)) + if (!btif_config_exist(name, + BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED) && + !btif_config_exist(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS)) continue; #ifndef TARGET_FLOSS int value; uint16_t is_acceptlisted = 0; - if (btif_config_get_int(name, HAS_IS_ACCEPTLISTED, &value)) + if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED, + &value)) is_acceptlisted = value; uint8_t features = 0; - if (btif_config_get_int(name, HAS_FEATURES, &value)) features = value; + if (btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS, &value)) + features = value; - do_in_main_thread(FROM_HERE, Bind(&le_audio::has::HasClient::AddFromStorage, - bd_addr, features, is_acceptlisted)); + do_in_main_thread(FROM_HERE, + Bind(&::le_audio::has::HasClient::AddFromStorage, bd_addr, + features, is_acceptlisted)); #else ASSERT_LOG(false, "TODO - Fix LE audio build."); #endif @@ -839,17 +862,18 @@ void btif_storage_load_bonded_leaudio_has_devices() { void btif_storage_remove_leaudio_has(const RawAddress& address) { std::string addrstr = address.ToString(); - btif_config_remove(addrstr, HAS_IS_ACCEPTLISTED); - btif_config_remove(addrstr, HAS_FEATURES); - btif_config_remove(addrstr, HAS_ACTIVE_PRESET); - btif_config_remove(addrstr, HAS_SERIALIZED_PRESETS); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS); } void btif_storage_set_leaudio_has_acceptlist(const RawAddress& address, bool add_to_acceptlist) { std::string addrstr = address.ToString(); - btif_config_set_int(addrstr, HAS_IS_ACCEPTLISTED, add_to_acceptlist); + btif_config_set_int(addrstr, BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED, + add_to_acceptlist); } void btif_storage_set_leaudio_has_presets(const RawAddress& address, @@ -860,7 +884,8 @@ void btif_storage_set_leaudio_has_presets(const RawAddress& address, [](const RawAddress& address, std::vector presets_bin) { const std::string& name = address.ToString(); - btif_config_set_bin(name, HAS_SERIALIZED_PRESETS, + btif_config_set_bin(name, + BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS, presets_bin.data(), presets_bin.size()); }, address, std::move(presets_bin))); @@ -872,13 +897,17 @@ bool btif_storage_get_leaudio_has_presets(const RawAddress& address, std::string name = address.ToString(); int value; - if (!btif_config_get_int(name, HAS_ACTIVE_PRESET, &value)) return false; + if (!btif_config_get_int(name, BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET, + &value)) + return false; active_preset = value; - auto bin_sz = btif_config_get_bin_length(name, HAS_SERIALIZED_PRESETS); + auto bin_sz = btif_config_get_bin_length( + name, BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS); presets_bin.resize(bin_sz); - if (!btif_config_get_bin(name, HAS_SERIALIZED_PRESETS, presets_bin.data(), - &bin_sz)) + if (!btif_config_get_bin(name, + BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS, + presets_bin.data(), &bin_sz)) return false; return true; @@ -895,7 +924,7 @@ void btif_storage_add_groups(const RawAddress& addr) { Bind( [](const RawAddress& bd_addr, std::vector group_info) { auto bdstr = bd_addr.ToString(); - btif_config_set_bin(bdstr, BTIF_STORAGE_DEVICE_GROUP_BIN, + btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN, group_info.data(), group_info.size()); }, addr, std::move(group_info))); @@ -904,7 +933,7 @@ void btif_storage_add_groups(const RawAddress& addr) { /** Deletes the bonded Le Audio device grouping info from the NVRAM */ void btif_storage_remove_groups(const RawAddress& address) { std::string addrstr = address.ToString(); - btif_config_remove(addrstr, BTIF_STORAGE_DEVICE_GROUP_BIN); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN); } /** Loads information about bonded group devices */ @@ -912,13 +941,13 @@ void btif_storage_load_bonded_groups(void) { for (const auto& bd_addr : btif_config_get_paired_devices()) { auto name = bd_addr.ToString(); size_t buffer_size = - btif_config_get_bin_length(name, BTIF_STORAGE_DEVICE_GROUP_BIN); + btif_config_get_bin_length(name, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN); if (buffer_size == 0) continue; - LOG_VERBOSE("Grouped device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Grouped device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); std::vector in(buffer_size); - if (btif_config_get_bin(name, BTIF_STORAGE_DEVICE_GROUP_BIN, in.data(), + if (btif_config_get_bin(name, BTIF_STORAGE_KEY_DEVICE_GROUP_BIN, in.data(), &buffer_size)) { do_in_main_thread(FROM_HERE, Bind(&DeviceGroups::AddFromStorage, bd_addr, std::move(in))); @@ -938,20 +967,6 @@ void btif_storage_load_bonded_volume_control_devices(void) { } } -void btif_storage_set_csis_autoconnect(const RawAddress& addr, - bool autoconnect) { - do_in_jni_thread(FROM_HERE, Bind( - [](const RawAddress& addr, bool autoconnect) { - std::string bdstr = addr.ToString(); - VLOG(2) << "Storing CSIS device: " - << ADDRESS_TO_LOGGABLE_CSTR(addr); - btif_config_set_int( - bdstr, BTIF_STORAGE_CSIS_AUTOCONNECT, - autoconnect); - }, - addr, autoconnect)); -} - /** Stores information about the bonded CSIS device */ void btif_storage_update_csis_info(const RawAddress& addr) { std::vector set_info; @@ -963,7 +978,7 @@ void btif_storage_update_csis_info(const RawAddress& addr) { Bind( [](const RawAddress& bd_addr, std::vector set_info) { auto bdstr = bd_addr.ToString(); - btif_config_set_bin(bdstr, BTIF_STORAGE_CSIS_SET_INFO_BIN, + btif_config_set_bin(bdstr, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN, set_info.data(), set_info.size()); }, addr, std::move(set_info))); @@ -974,31 +989,26 @@ void btif_storage_load_bonded_csis_devices(void) { for (const auto& bd_addr : btif_config_get_paired_devices()) { auto name = bd_addr.ToString(); - LOG_VERBOSE("Loading CSIS device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); - - int value; - bool autoconnect = false; - if (btif_config_get_int(name, BTIF_STORAGE_CSIS_AUTOCONNECT, &value)) - autoconnect = !!value; + log::verbose("Loading CSIS device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); size_t buffer_size = - btif_config_get_bin_length(name, BTIF_STORAGE_CSIS_SET_INFO_BIN); + btif_config_get_bin_length(name, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN); std::vector in(buffer_size); if (buffer_size != 0) - btif_config_get_bin(name, BTIF_STORAGE_CSIS_SET_INFO_BIN, in.data(), + btif_config_get_bin(name, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN, in.data(), &buffer_size); - if (buffer_size != 0 || autoconnect) - do_in_main_thread(FROM_HERE, Bind(&CsisClient::AddFromStorage, bd_addr, - std::move(in), autoconnect)); + if (buffer_size != 0) + do_in_main_thread( + FROM_HERE, Bind(&CsisClient::AddFromStorage, bd_addr, std::move(in))); } } /** Removes information about the bonded CSIS device */ void btif_storage_remove_csis_device(const RawAddress& address) { std::string addrstr = address.ToString(); - btif_config_remove(addrstr, BTIF_STORAGE_CSIS_AUTOCONNECT); - btif_config_remove(addrstr, BTIF_STORAGE_CSIS_SET_INFO_BIN); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_CSIS_AUTOCONNECT); + btif_config_remove(addrstr, BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN); } /******************************************************************************* @@ -1013,10 +1023,11 @@ bt_status_t btif_storage_load_hidd(void) { for (const auto& bd_addr : btif_config_get_paired_devices()) { auto name = bd_addr.ToString(); - LOG_VERBOSE("Remote device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Remote device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); int value; if (btif_in_fetch_bonded_device(name) == BT_STATUS_SUCCESS) { - if (btif_config_get_int(name, "HidDeviceCabled", &value)) { + if (btif_config_get_int(name, BTIF_STORAGE_KEY_HID_DEVICE_CABLED, + &value)) { BTA_HdAddDevice(bd_addr); break; } @@ -1042,11 +1053,12 @@ bt_status_t btif_storage_set_hidd(const RawAddress& remote_bd_addr) { auto name = bd_addr.ToString(); if (bd_addr == remote_bd_addr) continue; if (btif_in_fetch_bonded_device(name) == BT_STATUS_SUCCESS) { - btif_config_remove(name, "HidDeviceCabled"); + btif_config_remove(name, BTIF_STORAGE_KEY_HID_DEVICE_CABLED); } } - btif_config_set_int(remote_device_address_string, "HidDeviceCabled", 1); + btif_config_set_int(remote_device_address_string, + BTIF_STORAGE_KEY_HID_DEVICE_CABLED, 1); return BT_STATUS_SUCCESS; } @@ -1060,7 +1072,8 @@ bt_status_t btif_storage_set_hidd(const RawAddress& remote_bd_addr) { * ******************************************************************************/ bt_status_t btif_storage_remove_hidd(RawAddress* remote_bd_addr) { - btif_config_remove(remote_bd_addr->ToString(), "HidDeviceCabled"); + btif_config_remove(remote_bd_addr->ToString(), + BTIF_STORAGE_KEY_HID_DEVICE_CABLED); return BT_STATUS_SUCCESS; } @@ -1075,14 +1088,14 @@ bt_status_t btif_storage_remove_hidd(RawAddress* remote_bd_addr) { ******************************************************************************/ void btif_storage_set_pce_profile_version(const RawAddress& remote_bd_addr, uint16_t peer_pce_version) { - LOG_VERBOSE("peer_pce_version : 0x%x", peer_pce_version); + log::verbose("peer_pce_version : 0x{:x}", peer_pce_version); if (btif_config_set_bin( - remote_bd_addr.ToString(), BT_CONFIG_KEY_PBAP_PCE_VERSION, + remote_bd_addr.ToString(), BTIF_STORAGE_KEY_PBAP_PCE_VERSION, (const uint8_t*)&peer_pce_version, sizeof(peer_pce_version))) { } else { - LOG_WARN("Failed to store peer_pce_version for %s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); + log::warn("Failed to store peer_pce_version for {}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); } } @@ -1102,10 +1115,10 @@ bool btif_storage_is_pce_version_102(const RawAddress& remote_bd_addr) { uint16_t pce_version = 0; size_t version_value_size = sizeof(pce_version); if (!btif_config_get_bin(remote_bd_addr.ToString(), - BT_CONFIG_KEY_PBAP_PCE_VERSION, + BTIF_STORAGE_KEY_PBAP_PCE_VERSION, (uint8_t*)&pce_version, &version_value_size)) { - LOG_VERBOSE("Failed to read cached peer PCE version for %s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); + log::verbose("Failed to read cached peer PCE version for {}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); return entry_found; } @@ -1113,8 +1126,8 @@ bool btif_storage_is_pce_version_102(const RawAddress& remote_bd_addr) { entry_found = true; } - LOG_VERBOSE("read cached peer PCE version 0x%04x for %s", pce_version, - ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); + log::verbose("read cached peer PCE version 0x{:04x} for {}", pce_version, + ADDRESS_TO_LOGGABLE_CSTR(remote_bd_addr)); return entry_found; } diff --git a/system/btif/src/btif_rc.cc b/system/btif/src/btif_rc.cc index 82d9c9f2c79ed51762a25b03db4d40cdcad0fe6e..80159e8ba7353e7e0160a1305081917dabbf306a 100644 --- a/system/btif/src/btif_rc.cc +++ b/system/btif/src/btif_rc.cc @@ -27,6 +27,7 @@ #include "btif_rc.h" #include +#include #include #include #include @@ -45,11 +46,11 @@ #include "btif_common.h" #include "btif_util.h" #include "device/include/interop.h" +#include "include/check.h" #include "os/log.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "osi/include/list.h" -#include "osi/include/osi.h" // UNUSED_ATTR #include "osi/include/properties.h" #include "stack/include/avrc_api.h" #include "stack/include/avrc_defs.h" @@ -95,22 +96,24 @@ #define PLAY_STATUS_PLAYING 1 #define BTIF_RC_NUM_CONN BT_RC_NUM_APP -#define CHECK_RC_CONNECTED(p_dev) \ - do { \ - if ((p_dev) == NULL || !(p_dev)->rc_connected) { \ - LOG_WARN("%s: called when RC is not connected", __func__); \ - return BT_STATUS_NOT_READY; \ - } \ +#define CHECK_RC_CONNECTED(p_dev) \ + do { \ + if ((p_dev) == NULL || !(p_dev)->rc_connected) { \ + log::warn("called when RC is not connected"); \ + return BT_STATUS_NOT_READY; \ + } \ } while (0) -#define CHECK_BR_CONNECTED(p_dev) \ - do { \ - if ((p_dev) == NULL || !(p_dev)->br_connected) { \ - LOG_WARN("%s: called when BR is not connected", __func__); \ - return BT_STATUS_NOT_READY; \ - } \ +#define CHECK_BR_CONNECTED(p_dev) \ + do { \ + if ((p_dev) == NULL || !(p_dev)->br_connected) { \ + log::warn("called when BR is not connected"); \ + return BT_STATUS_NOT_READY; \ + } \ } while (0) +using namespace bluetooth; + /***************************************************************************** * Local type definitions *****************************************************************************/ @@ -411,18 +414,18 @@ static const uint8_t media_attr_list_no_cover_art_size = bool check_cod(const RawAddress& remote_bdaddr, uint32_t cod); void btif_rc_get_addr_by_handle(uint8_t handle, RawAddress& rc_addr) { - LOG_VERBOSE("%s: handle: 0x%x", __func__, handle); + log::verbose("handle: 0x{:x}", handle); for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) && (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) { - LOG_VERBOSE("%s: btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x%x", __func__, - btif_rc_cb.rc_multi_cb[idx].rc_handle); + log::verbose("btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x{:x}", + btif_rc_cb.rc_multi_cb[idx].rc_handle); rc_addr = btif_rc_cb.rc_multi_cb[idx].rc_addr; return; } } - LOG_ERROR("%s: returning NULL", __func__); + log::error("returning NULL"); rc_addr = RawAddress::kEmpty; return; } @@ -479,22 +482,21 @@ void initialize_device(btif_rc_device_cb_t* p_dev) { } static btif_rc_device_cb_t* get_connected_device(int index) { - LOG_VERBOSE("%s: index: %d", __func__, index); + log::verbose("index: {}", index); if (index >= BTIF_RC_NUM_CONN) { - LOG_ERROR("%s: can't support more than %d connections", __func__, - BTIF_RC_NUM_CONN); + log::error("can't support more than {} connections", BTIF_RC_NUM_CONN); return NULL; } if (btif_rc_cb.rc_multi_cb[index].rc_state != BTRC_CONNECTION_STATE_CONNECTED) { - LOG_ERROR("%s: returning NULL", __func__); + log::error("returning NULL"); return NULL; } return (&btif_rc_cb.rc_multi_cb[index]); } btif_rc_device_cb_t* btif_rc_get_device_by_bda(const RawAddress& bd_addr) { - VLOG(1) << __func__ << ": bd_addr: " << ADDRESS_TO_LOGGABLE_STR(bd_addr); + log::verbose("bd_addr: {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { if ((btif_rc_cb.rc_multi_cb[idx].rc_state != @@ -503,22 +505,22 @@ btif_rc_device_cb_t* btif_rc_get_device_by_bda(const RawAddress& bd_addr) { return (&btif_rc_cb.rc_multi_cb[idx]); } } - LOG_ERROR("%s: device not found, returning NULL!", __func__); + log::error("device not found, returning NULL!"); return NULL; } btif_rc_device_cb_t* btif_rc_get_device_by_handle(uint8_t handle) { - LOG_VERBOSE("%s: handle: 0x%x", __func__, handle); + log::verbose("handle: 0x{:x}", handle); for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) && (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) { - LOG_VERBOSE("%s: btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x%x", __func__, - btif_rc_cb.rc_multi_cb[idx].rc_handle); + log::verbose("btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x{:x}", + btif_rc_cb.rc_multi_cb[idx].rc_handle); return (&btif_rc_cb.rc_multi_cb[idx]); } } - LOG_ERROR("%s: returning NULL", __func__); + log::error("returning NULL"); return NULL; } @@ -549,15 +551,15 @@ void fill_avrc_attr_entry(tAVRC_ATTR_ENTRY* attr_vals, int num_attrs, attr_vals[attr_cnt].name.str_len = (uint16_t)strlen((char*)p_attrs[attr_cnt].text); attr_vals[attr_cnt].name.p_str = p_attrs[attr_cnt].text; - LOG_VERBOSE("%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", - __func__, (unsigned int)attr_vals[attr_cnt].attr_id, - attr_vals[attr_cnt].name.charset_id, - attr_vals[attr_cnt].name.str_len, - attr_vals[attr_cnt].name.p_str); + log::verbose("attr_id: 0x{:x}, charset_id: 0x{:x}, str_len: {}, str: {}", + (unsigned int)attr_vals[attr_cnt].attr_id, + attr_vals[attr_cnt].name.charset_id, + attr_vals[attr_cnt].name.str_len, + reinterpret_cast(attr_vals[attr_cnt].name.p_str)); } } -void rc_cleanup_sent_cmd(void* p_data) { LOG_VERBOSE("%s: ", __func__); } +void rc_cleanup_sent_cmd(void* p_data) { log::verbose(""); } void handle_rc_ctrl_features_all(btif_rc_device_cb_t* p_dev) { if (!(p_dev->peer_tg_features & BTA_AV_FEAT_RCTG) && @@ -568,10 +570,10 @@ void handle_rc_ctrl_features_all(btif_rc_device_cb_t* p_dev) { int rc_features = 0; - LOG_VERBOSE( - "%s: peer_tg_features: 0x%x, rc_features_processed=%d, connected=%d, " - "peer_is_src:%d", - __func__, p_dev->peer_tg_features, p_dev->rc_features_processed, + log::verbose( + "peer_tg_features: 0x{:x}, rc_features_processed={}, connected={}, " + "peer_is_src:{}", + p_dev->peer_tg_features, p_dev->rc_features_processed, btif_av_is_connected_addr(p_dev->rc_addr), btif_av_peer_is_source(p_dev->rc_addr)); @@ -601,8 +603,8 @@ void handle_rc_ctrl_features_all(btif_rc_device_cb_t* p_dev) { } } } else { - LOG_VERBOSE("%s: %s is not connected, pending", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr)); + log::verbose("{} is not connected, pending", + ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr)); p_dev->launch_cmd_pending |= (RC_PENDING_ACT_GET_CAP | RC_PENDING_ACT_REG_VOL); } @@ -618,7 +620,7 @@ void handle_rc_ctrl_features_all(btif_rc_device_cb_t* p_dev) { } if (bt_rc_ctrl_callbacks != NULL) { - LOG_VERBOSE("%s: Update rc features to CTRL: %d", __func__, rc_features); + log::verbose("Update rc features to CTRL: {}", rc_features); do_in_jni_thread(FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, p_dev->rc_addr, rc_features)); @@ -670,7 +672,7 @@ void handle_rc_ctrl_features(btif_rc_device_cb_t* p_dev) { rc_features |= BTRC_FEAT_COVER_ARTWORK; } - LOG_VERBOSE("%s: Update rc features to CTRL: %d", __func__, rc_features); + log::verbose("Update rc features to CTRL: {}", rc_features); do_in_jni_thread(FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, p_dev->rc_addr, rc_features)); @@ -679,15 +681,15 @@ void btif_rc_check_pending_cmd(const RawAddress& peer_address) { btif_rc_device_cb_t* p_dev = NULL; p_dev = btif_rc_get_device_by_bda(peer_address); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } - LOG_VERBOSE( - "%s: launch_cmd_pending=%d, rc_connected=%d, peer_ct_features=0x%x, " - "peer_tg_features=0x%x", - __FUNCTION__, p_dev->launch_cmd_pending, p_dev->rc_connected, - p_dev->peer_ct_features, p_dev->peer_tg_features); + log::verbose( + "launch_cmd_pending={}, rc_connected={}, peer_ct_features=0x{:x}, " + "peer_tg_features=0x{:x}", + p_dev->launch_cmd_pending, p_dev->rc_connected, p_dev->peer_ct_features, + p_dev->peer_tg_features); if (p_dev->launch_cmd_pending && p_dev->rc_connected) { if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_REG_VOL) && btif_av_peer_is_sink(p_dev->rc_addr)) { @@ -714,8 +716,7 @@ void btif_rc_check_pending_cmd(const RawAddress& peer_address) { void handle_rc_ctrl_psm(btif_rc_device_cb_t* p_dev) { uint16_t cover_art_psm = p_dev->rc_cover_art_psm; - LOG_VERBOSE("%s: Update rc cover art psm to CTRL: %d", __func__, - cover_art_psm); + log::verbose("Update rc cover art psm to CTRL: {}", cover_art_psm); if (bt_rc_ctrl_callbacks != NULL) { do_in_jni_thread(FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->get_cover_art_psm_cb, @@ -731,11 +732,10 @@ void handle_rc_features(btif_rc_device_cb_t* p_dev) { RawAddress avdtp_source_active_peer_addr = btif_av_source_active_peer(); RawAddress avdtp_sink_active_peer_addr = btif_av_sink_active_peer(); - LOG_VERBOSE( - "%s: AVDTP Source Active Peer Address: %s " - "AVDTP Sink Active Peer Address: %s " - "AVCTP address: %s", - __func__, ADDRESS_TO_LOGGABLE_CSTR(avdtp_source_active_peer_addr), + log::verbose( + "AVDTP Source Active Peer Address: {} AVDTP Sink Active Peer Address: {} " + "AVCTP address: {}", + ADDRESS_TO_LOGGABLE_CSTR(avdtp_source_active_peer_addr), ADDRESS_TO_LOGGABLE_CSTR(avdtp_sink_active_peer_addr), ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr)); @@ -764,12 +764,11 @@ void handle_rc_features(btif_rc_device_cb_t* p_dev) { (btrc_remote_features_t)(rc_features | BTRC_FEAT_ABSOLUTE_VOLUME); } - LOG_VERBOSE("%s: rc_features: 0x%x", __func__, rc_features); + log::verbose("rc_features: 0x{:x}", rc_features); HAL_CBACK(bt_rc_callbacks, remote_features_cb, p_dev->rc_addr, rc_features); - LOG_VERBOSE( - "%s: Checking for feature flags in btif_rc_handler with label: %d", - __func__, p_dev->rc_vol_label); + log::verbose("Checking for feature flags in btif_rc_handler with label: {}", + p_dev->rc_vol_label); // Register for volume change on connect if (p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL && p_dev->rc_features & BTA_AV_FEAT_RCTG) { @@ -786,13 +785,13 @@ void handle_rc_features(btif_rc_device_cb_t* p_dev) { * ***************************************************************************/ void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) { - LOG_VERBOSE("%s: rc_handle %d status %d", __func__, p_rc_br_open->rc_handle, - p_rc_br_open->status); + log::verbose("rc_handle {} status {}", p_rc_br_open->rc_handle, + p_rc_br_open->status); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(p_rc_br_open->rc_handle); if (!p_dev) { - LOG_ERROR("%s p_dev is null", __func__); + log::error("p_dev is null"); return; } @@ -811,7 +810,7 @@ void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) { } } else { p_dev->launch_cmd_pending |= RC_PENDING_ACT_REPORT_CONN; - LOG_VERBOSE("%s: pending rc browse connection event", __func__); + log::verbose("pending rc browse connection event"); } } else { if (bt_rc_ctrl_callbacks != NULL) { @@ -820,7 +819,7 @@ void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) { base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, true, p_dev->rc_addr)); } else { - LOG_WARN("%s: bt_rc_ctrl_callbacks is null.", __func__); + log::warn("bt_rc_ctrl_callbacks is null."); } } } @@ -835,17 +834,16 @@ void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) { * ***************************************************************************/ void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) { - LOG_VERBOSE("%s: rc_handle: %d", __func__, p_rc_open->rc_handle); + log::verbose("rc_handle: {}", p_rc_open->rc_handle); btif_rc_device_cb_t* p_dev = alloc_device(); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev is NULL", __func__); + log::error("p_dev is NULL"); return; } if (!(p_rc_open->status == BTA_AV_SUCCESS)) { - LOG_ERROR("%s: Connect failed with error code: %d", __func__, - p_rc_open->status); + log::error("Connect failed with error code: {}", p_rc_open->status); p_dev->rc_connected = false; BTA_AvCloseRc(p_rc_open->rc_handle); p_dev->rc_handle = 0; @@ -868,7 +866,7 @@ void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) { __func__, p_dev->rc_handle, p_rc_open->rc_handle); if (p_dev->rc_handle != p_rc_open->rc_handle && p_dev->rc_addr != p_rc_open->peer_addr) { - LOG_VERBOSE("%s: Got RC connected for some other handle", __func__); + log::verbose("Got RC connected for some other handle"); BTA_AvCloseRc(p_rc_open->rc_handle); return; } @@ -881,12 +879,11 @@ void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) { p_dev->rc_vol_label = MAX_LABEL; p_dev->rc_volume = MAX_VOLUME; - LOG_VERBOSE( - "%s: handle_rc_connect in features=%#x, out features=%#x, " - "ct_feature=%#x, tg_feature=%#x, cover art psm=%#x", - __func__, p_rc_open->peer_features, p_dev->rc_features, - p_dev->peer_ct_features, p_dev->peer_tg_features, - p_dev->rc_cover_art_psm); + log::verbose( + "handle_rc_connect in features={:#x}, out features={:#x}, " + "ct_feature={:#x}, tg_feature={:#x}, cover art psm={:#x}", + p_rc_open->peer_features, p_dev->rc_features, p_dev->peer_ct_features, + p_dev->peer_tg_features, p_dev->rc_cover_art_psm); p_dev->rc_connected = true; p_dev->rc_handle = p_rc_open->rc_handle; @@ -897,7 +894,7 @@ void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) { if (btif_av_src_sink_coexist_enabled() && !btif_av_peer_is_connected_source(p_dev->rc_addr)) { p_dev->launch_cmd_pending |= RC_PENDING_ACT_REPORT_CONN; - LOG_VERBOSE("%s: pending rc connection event", __func__); + log::verbose("pending rc connection event"); return; } if (bt_rc_ctrl_callbacks != NULL) { @@ -922,17 +919,17 @@ void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) { ***************************************************************************/ void handle_rc_disconnect(tBTA_AV_RC_CLOSE* p_rc_close) { btif_rc_device_cb_t* p_dev = NULL; - LOG_VERBOSE("%s: rc_handle: %d", __func__, p_rc_close->rc_handle); + log::verbose("rc_handle: {}", p_rc_close->rc_handle); p_dev = btif_rc_get_device_by_handle(p_rc_close->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: Got disconnect from invalid rc handle", __func__); + log::error("Got disconnect from invalid rc handle"); return; } if (p_rc_close->rc_handle != p_dev->rc_handle && p_dev->rc_addr != p_rc_close->peer_addr) { - LOG_ERROR("Got disconnect of unknown device"); + log::error("Got disconnect of unknown device"); return; } @@ -959,24 +956,24 @@ void handle_rc_disconnect(tBTA_AV_RC_CLOSE* p_rc_close) { ***************************************************************************/ void handle_rc_passthrough_cmd(tBTA_AV_REMOTE_CMD* p_remote_cmd) { if (p_remote_cmd == NULL) { - LOG_ERROR("%s: No remote command!", __func__); + log::error("No remote command!"); return; } btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(p_remote_cmd->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: Got passthrough command from invalid rc handle", __func__); + log::error("Got passthrough command from invalid rc handle"); return; } - LOG_VERBOSE("%s: p_remote_cmd->rc_id: %d", __func__, p_remote_cmd->rc_id); + log::verbose("p_remote_cmd->rc_id: {}", p_remote_cmd->rc_id); /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up * this PLAY */ if ((p_remote_cmd->rc_id == AVRC_ID_PLAY) && (!btif_av_is_connected())) { if (p_remote_cmd->key_state == AVRC_STATE_PRESS) { - LOG_WARN("%s: AVDT not open, queuing the PLAY command", __func__); + log::warn("AVDT not open, queuing the PLAY command"); p_dev->rc_pending_play = true; } return; @@ -984,22 +981,22 @@ void handle_rc_passthrough_cmd(tBTA_AV_REMOTE_CMD* p_remote_cmd) { /* If we previously queued a play and we get a PAUSE, clear it. */ if ((p_remote_cmd->rc_id == AVRC_ID_PAUSE) && (p_dev->rc_pending_play)) { - LOG_WARN("%s: Clear the pending PLAY on PAUSE received", __func__); + log::warn("Clear the pending PLAY on PAUSE received"); p_dev->rc_pending_play = false; return; } if ((p_remote_cmd->rc_id == AVRC_ID_STOP) && (!btif_av_stream_started_ready())) { - LOG_WARN("%s: Stream suspended, ignore STOP cmd", __func__); + log::warn("Stream suspended, ignore STOP cmd"); return; } int pressed = (p_remote_cmd->key_state == AVRC_STATE_PRESS) ? 1 : 0; /* pass all commands up */ - LOG_VERBOSE("%s: rc_features: %d, cmd->rc_id: %d, pressed: %d", __func__, - p_dev->rc_features, p_remote_cmd->rc_id, pressed); + log::verbose("rc_features: {}, cmd->rc_id: {}, pressed: {}", + p_dev->rc_features, p_remote_cmd->rc_id, pressed); HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed, p_dev->rc_addr); } @@ -1017,18 +1014,18 @@ void handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) { p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: passthrough response for Invalid rc handle", __func__); + log::error("passthrough response for Invalid rc handle"); return; } if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG)) { - LOG_ERROR("%s: DUT does not support AVRCP controller role", __func__); + log::error("DUT does not support AVRCP controller role"); return; } const char* status = (p_remote_rsp->key_state == 1) ? "released" : "pressed"; - LOG_VERBOSE("%s: rc_id: %d state: %s", __func__, p_remote_rsp->rc_id, status); + log::verbose("rc_id: {} state: {}", p_remote_rsp->rc_id, status); release_transaction(p_dev, p_remote_rsp->label); if (bt_rc_ctrl_callbacks != NULL) { @@ -1054,7 +1051,7 @@ void handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) { p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: Got vendorunique rsp from invalid rc handle", __func__); + log::error("Got vendorunique rsp from invalid rc handle"); return; } @@ -1073,14 +1070,14 @@ void handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) { vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN - 1]; osi_free_and_reset((void**)&p_remote_rsp->p_data); } - LOG_VERBOSE("%s: vendor_id: %d status: %s", __func__, vendor_id, status); + log::verbose("vendor_id: {} status: {}", vendor_id, status); release_transaction(p_dev, p_remote_rsp->label); do_in_jni_thread( FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->groupnavigation_rsp_cb, vendor_id, key_state)); } else { - LOG_ERROR("%s: Remote does not support AVRCP TG role", __func__); + log::error("Remote does not support AVRCP TG role"); } } @@ -1101,33 +1098,33 @@ void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { btif_rc_device_cb_t* p_dev = NULL; if (NULL == pmeta_msg) { - LOG_VERBOSE("%s: Exiting as pmeta_msg is NULL", __func__); + log::verbose("Exiting as pmeta_msg is NULL"); return; } if (NULL == pmeta_msg->p_msg) { - LOG_VERBOSE("%s: Exiting as pmeta_msg->p_msg is NULL", __func__); + log::verbose("Exiting as pmeta_msg->p_msg is NULL"); return; } - LOG_VERBOSE("%s: pmeta_msg: opcode: %x, code: %x", __func__, - pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); + log::verbose("pmeta_msg: opcode: {:x}, code: {:x}", + pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: Meta msg event for Invalid rc handle", __func__); + log::error("Meta msg event for Invalid rc handle"); return; } if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR && pmeta_msg->p_msg->hdr.opcode != AVRC_OP_BROWSE) { - LOG_WARN("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode); + log::warn("Invalid opcode: {:x}", pmeta_msg->p_msg->hdr.opcode); return; } if (pmeta_msg->len < 3) { - LOG_WARN("%s: Invalid length. opcode: 0x%x, len: 0x%x", __func__, - pmeta_msg->p_msg->hdr.opcode, pmeta_msg->len); + log::warn("Invalid length. opcode: 0x{:x}, len: 0x{:x}", + pmeta_msg->p_msg->hdr.opcode, pmeta_msg->len); return; } @@ -1138,8 +1135,8 @@ void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { if (transaction != NULL) { handle_rc_metamsg_rsp(pmeta_msg, p_dev); } else { - LOG_VERBOSE("%s: Discard vendor dependent rsp. code: %d label: %d.", - __func__, pmeta_msg->code, pmeta_msg->label); + log::verbose("Discard vendor dependent rsp. code: {} label: {}.", + pmeta_msg->code, pmeta_msg->label); } return; } @@ -1147,14 +1144,13 @@ void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { status = AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf)); - LOG_VERBOSE("%s: Received vendor command.code,PDU and label: %d, %d, %d", - __func__, pmeta_msg->code, avrc_command.cmd.pdu, - pmeta_msg->label); + log::verbose("Received vendor command.code,PDU and label: {}, {}, {}", + pmeta_msg->code, avrc_command.cmd.pdu, pmeta_msg->label); if (status != AVRC_STS_NO_ERROR) { /* return error */ - LOG_WARN("%s: Error in parsing received metamsg command. status: 0x%02x", - __func__, status); + log::warn("Error in parsing received metamsg command. status: 0x{:02x}", + status); send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status, pmeta_msg->p_msg->hdr.opcode); @@ -1164,10 +1160,10 @@ void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) { uint8_t event_id = avrc_command.reg_notif.event_id; - LOG_VERBOSE( - "%s: New register notification received.event_id: %s, label: 0x%x, " - "code: %x", - __func__, dump_rc_notification_event_id(event_id), pmeta_msg->label, + log::verbose( + "New register notification received.event_id: {}, label: 0x{:x}, " + "code: {:x}", + dump_rc_notification_event_id(event_id), pmeta_msg->label, pmeta_msg->code); p_dev->rc_notif[event_id - 1].bNotify = true; p_dev->rc_notif[event_id - 1].label = pmeta_msg->label; @@ -1182,8 +1178,8 @@ void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { avrc_command.cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME) { return; } - LOG_VERBOSE("%s: Passing received metamsg command to app. pdu: %s", - __func__, dump_rc_pdu(avrc_command.cmd.pdu)); + log::verbose("Passing received metamsg command to app. pdu: {}", + dump_rc_pdu(avrc_command.cmd.pdu)); /* Since handle_rc_metamsg_cmd() itself is called from *btif context, no context switching is required. Invoke @@ -1201,12 +1197,13 @@ void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { ** ***************************************************************************/ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { - LOG_VERBOSE("%s: event: %s", __func__, dump_rc_event(event)); + log::verbose("event: {}", dump_rc_event(event)); btif_rc_device_cb_t* p_dev = NULL; switch (event) { case BTA_AV_RC_OPEN_EVT: { - LOG_VERBOSE("%s: Peer_features: 0x%x Cover Art PSM: 0x%x", __func__, - p_data->rc_open.peer_features, p_data->rc_open.cover_art_psm); + log::verbose("Peer_features: 0x{:x} Cover Art PSM: 0x{:x}", + p_data->rc_open.peer_features, + p_data->rc_open.cover_art_psm); handle_rc_connect(&(p_data->rc_open)); } break; @@ -1221,23 +1218,22 @@ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { } break; case BTA_AV_RC_BROWSE_CLOSE_EVT: { - LOG_VERBOSE("%s: BTA_AV_RC_BROWSE_CLOSE_EVT", __func__); + log::verbose("BTA_AV_RC_BROWSE_CLOSE_EVT"); } break; case BTA_AV_REMOTE_CMD_EVT: { if (bt_rc_callbacks != NULL) { - LOG_VERBOSE("%s: rc_id: 0x%x key_state: %d", __func__, - p_data->remote_cmd.rc_id, p_data->remote_cmd.key_state); + log::verbose("rc_id: 0x{:x} key_state: {}", p_data->remote_cmd.rc_id, + p_data->remote_cmd.key_state); handle_rc_passthrough_cmd((&p_data->remote_cmd)); } else { - LOG_ERROR("%s: AVRCP TG role not up, drop passthrough commands", - __func__); + log::error("AVRCP TG role not up, drop passthrough commands"); } } break; case BTA_AV_REMOTE_RSP_EVT: { - LOG_VERBOSE("%s: RSP: rc_id: 0x%x key_state: %d", __func__, - p_data->remote_rsp.rc_id, p_data->remote_rsp.key_state); + log::verbose("RSP: rc_id: 0x{:x} key_state: {}", p_data->remote_rsp.rc_id, + p_data->remote_rsp.key_state); if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR) { handle_rc_vendorunique_rsp((&p_data->remote_rsp)); @@ -1247,20 +1243,19 @@ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { } break; case BTA_AV_RC_FEAT_EVT: { - LOG_VERBOSE("%s: Peer_features: %x", __func__, - p_data->rc_feat.peer_features); + log::verbose("Peer_features: {:x}", p_data->rc_feat.peer_features); p_dev = btif_rc_get_device_by_handle(p_data->rc_feat.rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: RC Feature event for Invalid rc handle", __func__); + log::error("RC Feature event for Invalid rc handle"); break; } - LOG_VERBOSE("%s peer_ct_features:0x%x, peer_tg_features=0x%x", __func__, - p_data->rc_feat.peer_ct_features, - p_data->rc_feat.peer_tg_features); + log::verbose("peer_ct_features:0x{:x}, peer_tg_features=0x{:x}", + p_data->rc_feat.peer_ct_features, + p_data->rc_feat.peer_tg_features); if (btif_av_src_sink_coexist_enabled() && (p_dev->peer_ct_features == p_data->rc_feat.peer_ct_features) && (p_dev->peer_tg_features == p_data->rc_feat.peer_tg_features)) { - LOG_ERROR( + log::error( "do SDP twice, no need callback rc_feature to framework again"); break; } @@ -1278,11 +1273,11 @@ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { } break; case BTA_AV_RC_PSM_EVT: { - LOG_VERBOSE("%s: Peer cover art PSM: %x", __func__, - p_data->rc_cover_art_psm.cover_art_psm); + log::verbose("Peer cover art PSM: {:x}", + p_data->rc_cover_art_psm.cover_art_psm); p_dev = btif_rc_get_device_by_handle(p_data->rc_cover_art_psm.rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: RC PSM event for Invalid rc handle", __func__); + log::error("RC PSM event for Invalid rc handle"); break; } @@ -1294,11 +1289,11 @@ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { case BTA_AV_META_MSG_EVT: { if (bt_rc_callbacks != NULL) { - LOG_VERBOSE("%s: BTA_AV_META_MSG_EVT code: %d label: %d", __func__, - p_data->meta_msg.code, p_data->meta_msg.label); - LOG_VERBOSE("%s: company_id: 0x%x len: %d handle: %d", __func__, - p_data->meta_msg.company_id, p_data->meta_msg.len, - p_data->meta_msg.rc_handle); + log::verbose("BTA_AV_META_MSG_EVT code: {} label: {}", + p_data->meta_msg.code, p_data->meta_msg.label); + log::verbose("company_id: 0x{:x} len: {} handle: {}", + p_data->meta_msg.company_id, p_data->meta_msg.len, + p_data->meta_msg.rc_handle); /* handle the metamsg command */ handle_rc_metamsg_cmd(&(p_data->meta_msg)); @@ -1306,14 +1301,13 @@ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { /* Free the Memory allocated for tAVRC_MSG */ } else if (bt_rc_ctrl_callbacks != NULL) { /* This is case of Sink + CT + TG(for abs vol)) */ - LOG_VERBOSE( - "%s BTA_AV_META_MSG_EVT code:%d label:%d opcode %d ctype %d", - __func__, p_data->meta_msg.code, p_data->meta_msg.label, - p_data->meta_msg.p_msg->hdr.opcode, - p_data->meta_msg.p_msg->hdr.ctype); - LOG_VERBOSE("%s company_id:0x%x len:%d handle:%d", __func__, - p_data->meta_msg.company_id, p_data->meta_msg.len, - p_data->meta_msg.rc_handle); + log::verbose("BTA_AV_META_MSG_EVT code:{} label:{} opcode {} ctype {}", + p_data->meta_msg.code, p_data->meta_msg.label, + p_data->meta_msg.p_msg->hdr.opcode, + p_data->meta_msg.p_msg->hdr.ctype); + log::verbose("company_id:0x{:x} len:{} handle:{}", + p_data->meta_msg.company_id, p_data->meta_msg.len, + p_data->meta_msg.rc_handle); switch (p_data->meta_msg.p_msg->hdr.opcode) { case AVRC_OP_VENDOR: if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL) && @@ -1335,12 +1329,12 @@ void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) { break; } } else { - LOG_ERROR("Neither CTRL, nor TG is up, drop meta commands"); + log::error("Neither CTRL, nor TG is up, drop meta commands"); } } break; default: - LOG_VERBOSE("%s: Unhandled RC event : 0x%x", __func__, event); + log::verbose("Unhandled RC event : 0x{:x}", event); } } @@ -1367,7 +1361,7 @@ uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr) { p_dev = btif_rc_get_device_by_bda(peer_addr); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return BTRC_HANDLE_NONE; } return p_dev->rc_handle; @@ -1389,15 +1383,15 @@ void btif_rc_check_handle_pending_play(const RawAddress& peer_addr, p_dev = btif_rc_get_device_by_bda(peer_addr); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } - LOG_VERBOSE("%s: bSendToApp: %d", __func__, bSendToApp); + log::verbose("bSendToApp: {}", bSendToApp); if (p_dev->rc_pending_play) { if (bSendToApp) { tBTA_AV_REMOTE_CMD remote_cmd; - LOG_VERBOSE("%s: Sending queued PLAYED event to app", __func__); + log::verbose("Sending queued PLAYED event to app"); memset(&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD)); remote_cmd.rc_handle = p_dev->rc_handle; @@ -1438,13 +1432,13 @@ static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu, status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg); if (status != AVRC_STS_NO_ERROR) { - LOG_ERROR("%s: status not AVRC_STS_NO_ERROR", __func__); + log::error("status not AVRC_STS_NO_ERROR"); return; } - LOG_VERBOSE( - "%s: Sending error notification to handle: %d. pdu: %s,status: 0x%02x", - __func__, rc_handle, dump_rc_pdu(pdu), status); + log::verbose( + "Sending error notification to handle: {}. pdu: {},status: 0x{:02x}", + rc_handle, dump_rc_pdu(pdu), status); BTA_AvMetaRsp(rc_handle, label, ctype, p_msg); } @@ -1491,21 +1485,21 @@ static void send_metamsg_rsp(btif_rc_device_cb_t* p_dev, int index, uint8_t ctype; if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } if (pmetamsg_resp == NULL) { - LOG_WARN("%s: Invalid response received from application", __func__); + log::warn("Invalid response received from application"); return; } - LOG_VERBOSE("%s: rc_handle: %d, index: %d, label: %d, code: 0x%02x, pdu: %s", - __func__, p_dev->rc_handle, index, label, code, - dump_rc_pdu(pmetamsg_resp->rsp.pdu)); + log::verbose("rc_handle: {}, index: {}, label: {}, code: 0x{:02x}, pdu: {}", + p_dev->rc_handle, index, label, code, + dump_rc_pdu(pmetamsg_resp->rsp.pdu)); if (index >= 0 && !p_dev->rc_pdu_info[index].is_rsp_pending) { - LOG_ERROR("%s: is_rsp_pending false, returning", __func__); + log::error("is_rsp_pending false, returning"); return; } @@ -1522,23 +1516,21 @@ static void send_metamsg_rsp(btif_rc_device_cb_t* p_dev, int index, /* de-register this notification for a CHANGED response */ p_dev->rc_notif[event_id - 1].bNotify = false; - LOG_VERBOSE("%s: rc_handle: %d. event_id: 0x%02d bNotify: %u", __func__, - p_dev->rc_handle, event_id, bNotify); + log::verbose("rc_handle: {}. event_id: 0x{:02} bNotify: {}", + p_dev->rc_handle, event_id, bNotify); if (bNotify) { BT_HDR* p_msg = NULL; tAVRC_STS status; if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse( p_dev->rc_handle, pmetamsg_resp, &p_msg))) { - LOG_VERBOSE( - "%s: Sending notification to rc_handle: %d. event_id: 0x%02d", - __func__, p_dev->rc_handle, event_id); + log::verbose("Sending notification to rc_handle: {}. event_id: 0x{:02}", + p_dev->rc_handle, event_id); bSent = true; BTA_AvMetaRsp(p_dev->rc_handle, p_dev->rc_notif[event_id - 1].label, ctype, p_msg); } else { - LOG_WARN("%s: failed to build metamsg response. status: 0x%02x", - __func__, status); + log::warn("failed to build metamsg response. status: 0x{:02x}", status); } } @@ -1559,8 +1551,7 @@ static void send_metamsg_rsp(btif_rc_device_cb_t* p_dev, int index, if (status == AVRC_STS_NO_ERROR) { BTA_AvMetaRsp(p_dev->rc_handle, label, ctype, p_msg); } else { - LOG_ERROR("%s: failed to build metamsg response. status: 0x%02x", - __func__, status); + log::error("failed to build metamsg response. status: 0x{:02x}", status); } } @@ -1669,9 +1660,9 @@ static uint8_t fill_attribute_id_array( static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, uint8_t ctype, uint8_t label, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: pdu: %s handle: 0x%x ctype: %x label: %x event ID: %x", - __func__, dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle, ctype, - label, pavrc_cmd->reg_notif.event_id); + log::verbose("pdu: {} handle: 0x{:x} ctype: {:x} label: {:x} event ID: {:x}", + dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle, ctype, label, + pavrc_cmd->reg_notif.event_id); switch (event) { case AVRC_PDU_GET_PLAY_STATUS: { @@ -1694,8 +1685,7 @@ static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, pavrc_cmd->get_elem_attrs.num_attr, pavrc_cmd->get_elem_attrs.attrs, BTRC_MAX_ELEM_ATTR_SIZE, element_attrs); if (num_attr == 0) { - LOG_ERROR("%s: No valid attributes requested in GET_ELEMENT_ATTRIBUTES", - __func__); + log::error("No valid attributes requested in GET_ELEMENT_ATTRIBUTES"); send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode); return; @@ -1707,9 +1697,7 @@ static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, case AVRC_PDU_REGISTER_NOTIFICATION: { if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED && pavrc_cmd->reg_notif.param == 0) { - LOG_WARN( - "%s: Device registering position changed with illegal param 0.", - __func__); + log::warn("Device registering position changed with illegal param 0."); send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode); /* de-register this notification for a rejected response */ @@ -1722,7 +1710,7 @@ static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, } break; case AVRC_PDU_INFORM_DISPLAY_CHARSET: { tAVRC_RESPONSE avrc_rsp; - LOG_VERBOSE("%s: AVRC_PDU_INFORM_DISPLAY_CHARSET", __func__); + log::verbose("AVRC_PDU_INFORM_DISPLAY_CHARSET"); if (p_dev->rc_connected) { memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP)); avrc_rsp.inform_charset.opcode = @@ -1782,8 +1770,8 @@ static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, } break; case AVRC_PDU_REQUEST_CONTINUATION_RSP: { - LOG_VERBOSE("%s() REQUEST CONTINUATION: target_pdu: 0x%02d", __func__, - pavrc_cmd->continu.target_pdu); + log::verbose("REQUEST CONTINUATION: target_pdu: 0x{:02d}", + pavrc_cmd->continu.target_pdu); tAVRC_RESPONSE avrc_rsp; if (p_dev->rc_connected == TRUE) { memset(&(avrc_rsp.continu), 0, sizeof(tAVRC_NEXT_RSP)); @@ -1797,8 +1785,8 @@ static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, } break; case AVRC_PDU_ABORT_CONTINUATION_RSP: { - LOG_VERBOSE("%s() ABORT CONTINUATION: target_pdu: 0x%02d", __func__, - pavrc_cmd->abort.target_pdu); + log::verbose("ABORT CONTINUATION: target_pdu: 0x{:02d}", + pavrc_cmd->abort.target_pdu); tAVRC_RESPONSE avrc_rsp; if (p_dev->rc_connected == TRUE) { memset(&(avrc_rsp.abort), 0, sizeof(tAVRC_NEXT_RSP)); @@ -1830,14 +1818,13 @@ static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd, pavrc_cmd->get_attrs.attr_count, pavrc_cmd->get_attrs.p_attr_list, BTRC_MAX_ELEM_ATTR_SIZE, item_attrs); if (num_attr == 0) { - LOG_ERROR("%s: No valid attributes requested in GET_ITEM_ATTRIBUTES", - __func__); + log::error("No valid attributes requested in GET_ITEM_ATTRIBUTES"); send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode); return; } fill_pdu_queue(IDX_GET_ITEM_ATTR_RSP, ctype, label, true, p_dev); - LOG_VERBOSE("%s: GET_ITEM_ATTRIBUTES: num_attr: %d", __func__, num_attr); + log::verbose("GET_ITEM_ATTRIBUTES: num_attr: {}", num_attr); HAL_CBACK(bt_rc_callbacks, get_item_attr_cb, pavrc_cmd->get_attrs.scope, pavrc_cmd->get_attrs.uid, pavrc_cmd->get_attrs.uid_counter, num_attr, item_attrs, p_dev->rc_addr); @@ -1884,8 +1871,8 @@ static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, tAVRC_COMMAND* pavrc_cmd, uint8_t label, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: pdu: %s: handle: 0x%x", __func__, - dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle); + log::verbose("pdu: {}: handle: 0x{:x}", dump_rc_pdu(pavrc_cmd->pdu), + p_dev->rc_handle); switch (event) { case AVRC_PDU_SET_ABSOLUTE_VOLUME: do_in_jni_thread( @@ -1917,8 +1904,8 @@ static void btif_rc_upstreams_rsp_evt(uint16_t event, tAVRC_RESPONSE* pavrc_resp, uint8_t ctype, uint8_t label, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: pdu: %s: handle: 0x%x ctype: %x label: %x", __func__, - dump_rc_pdu(pavrc_resp->pdu), p_dev->rc_handle, ctype, label); + log::verbose("pdu: {}: handle: 0x{:x} ctype: {:x} label: {:x}", + dump_rc_pdu(pavrc_resp->pdu), p_dev->rc_handle, ctype, label); switch (event) { case AVRC_PDU_REGISTER_NOTIFICATION: { @@ -1929,10 +1916,9 @@ static void btif_rc_upstreams_rsp_evt(uint16_t event, } break; case AVRC_PDU_SET_ABSOLUTE_VOLUME: { - LOG_VERBOSE( - "%s: Set absolute volume change event received: volume: %d, ctype: " - "%d", - __func__, pavrc_resp->volume.volume, ctype); + log::verbose( + "Set absolute volume change event received: volume: {}, ctype: {}", + pavrc_resp->volume.volume, ctype); if (AVRC_RSP_ACCEPT == ctype) p_dev->rc_volume = pavrc_resp->volume.volume; HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->volume.volume, @@ -1958,7 +1944,7 @@ static void btif_rc_upstreams_rsp_evt(uint16_t event, * ******************************************************************************/ static bt_status_t init(btrc_callbacks_t* callbacks) { - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); bt_status_t result = BT_STATUS_SUCCESS; if (bt_rc_callbacks) return BT_STATUS_DONE; @@ -1983,7 +1969,7 @@ static bt_status_t init(btrc_callbacks_t* callbacks) { * ******************************************************************************/ static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks) { - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); bt_status_t result = BT_STATUS_SUCCESS; if (bt_rc_ctrl_callbacks) return BT_STATUS_DONE; @@ -2000,7 +1986,7 @@ static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks) { static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev) { if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -2030,7 +2016,7 @@ static bt_status_t get_play_status_rsp(const RawAddress& bd_addr, tAVRC_RESPONSE avrc_rsp; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s: song len %d song pos %d", __func__, song_len, song_pos); + log::verbose("song len {} song pos {}", song_len, song_pos); CHECK_RC_CONNECTED(p_dev); memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP)); @@ -2072,13 +2058,12 @@ static bt_status_t get_element_attr_rsp(const RawAddress& bd_addr, tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); if (num_attr > BTRC_MAX_ELEM_ATTR_SIZE) { - LOG(WARNING) << __func__ - << " Exceeded number attributes:" << static_cast(num_attr) - << " max:" << BTRC_MAX_ELEM_ATTR_SIZE; + log::warn("Exceeded number attributes:{} max:{}", + static_cast(num_attr), BTRC_MAX_ELEM_ATTR_SIZE); num_attr = BTRC_MAX_ELEM_ATTR_SIZE; } memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); @@ -2092,10 +2077,11 @@ static bt_status_t get_element_attr_rsp(const RawAddress& bd_addr, element_attrs[i].name.str_len = (uint16_t)strnlen((char*)p_attrs[i].text, BTRC_MAX_ATTR_STR_LEN); element_attrs[i].name.p_str = p_attrs[i].text; - LOG_VERBOSE("%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", - __func__, (unsigned int)element_attrs[i].attr_id, - element_attrs[i].name.charset_id, - element_attrs[i].name.str_len, element_attrs[i].name.p_str); + log::verbose("attr_id: 0x{:x}, charset_id: 0x{:x}, str_len: {}, str: {}", + (unsigned int)element_attrs[i].attr_id, + element_attrs[i].name.charset_id, + element_attrs[i].name.str_len, + reinterpret_cast(element_attrs[i].name.p_str)); } avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR; } @@ -2126,12 +2112,11 @@ static bt_status_t register_notification_rsp( btrc_event_id_t event_id, btrc_notification_type_t type, btrc_register_notification_t* p_param) { tAVRC_RESPONSE avrc_rsp; - LOG_VERBOSE("%s: event_id: %s", __func__, - dump_rc_notification_event_id(event_id)); + log::verbose("event_id: {}", dump_rc_notification_event_id(event_id)); std::unique_lock lock(btif_rc_cb.lock); if (event_id > MAX_RC_NOTIFICATIONS) { - LOG_ERROR("Invalid event id"); + log::error("Invalid event id"); return BT_STATUS_PARM_INVALID; } @@ -2146,20 +2131,20 @@ static bt_status_t register_notification_rsp( memset(&(avrc_rsp.reg_notif.param), 0, sizeof(tAVRC_NOTIF_RSP_PARAM)); if (!(btif_rc_cb.rc_multi_cb[idx].rc_connected)) { - LOG_ERROR("%s: Avrcp device is not connected, handle: 0x%x", __func__, - btif_rc_cb.rc_multi_cb[idx].rc_handle); + log::error("Avrcp device is not connected, handle: 0x{:x}", + btif_rc_cb.rc_multi_cb[idx].rc_handle); continue; } if (!btif_rc_cb.rc_multi_cb[idx].rc_notif[event_id - 1].bNotify) { - LOG_WARN( - "%s: Avrcp Event id is not registered: event_id: %x, handle: 0x%x", - __func__, event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle); + log::warn( + "Avrcp Event id is not registered: event_id: {:x}, handle: 0x{:x}", + event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle); continue; } - LOG_VERBOSE("%s: Avrcp Event id is registered: event_id: %x handle: 0x%x", - __func__, event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle); + log::verbose("Avrcp Event id is registered: event_id: {:x} handle: 0x{:x}", + event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle); switch (event_id) { case BTRC_EVT_PLAY_STATUS_CHANGED: @@ -2190,7 +2175,7 @@ static bt_status_t register_notification_rsp( break; default: - LOG_WARN("%s: Unhandled event ID: 0x%x", __func__, event_id); + log::warn("Unhandled event ID: 0x{:x}", event_id); return BT_STATUS_UNHANDLED; } @@ -2234,13 +2219,12 @@ static bt_status_t get_folder_items_list_rsp(const RawAddress& bd_addr, btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); btrc_folder_items_t* cur_item = NULL; - LOG_VERBOSE("%s: uid_counter %d num_items %d", __func__, uid_counter, - num_items); + log::verbose("uid_counter {} num_items {}", uid_counter, num_items); CHECK_RC_CONNECTED(p_dev); /* check if rsp to previous cmd was completed */ if (!p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].is_rsp_pending) { - LOG_WARN("%s: Not sending response as no PDU was registered", __func__); + log::warn("Not sending response as no PDU was registered"); return BT_STATUS_UNHANDLED; } @@ -2252,9 +2236,9 @@ static bt_status_t get_folder_items_list_rsp(const RawAddress& bd_addr, avrc_rsp.get_items.status = status_code_map[rsp_status]; if (avrc_rsp.get_items.status != AVRC_STS_NO_ERROR) { - LOG_WARN( - "%s: Error in parsing the received getfolderitems cmd. status: 0x%02x", - __func__, avrc_rsp.get_items.status); + log::warn( + "Error in parsing the received getfolderitems cmd. status: 0x{:02x}", + avrc_rsp.get_items.status); status = avrc_rsp.get_items.status; } else { avrc_rsp.get_items.uid_counter = uid_counter; @@ -2313,8 +2297,8 @@ static bt_status_t get_folder_items_list_rsp(const RawAddress& bd_addr, } break; default: { - LOG_ERROR("%s: Unknown item_type: %d. Internal Error", __func__, - p_items->item_type); + log::error("Unknown item_type: {}. Internal Error", + p_items->item_type); status = AVRC_STS_INTERNAL_ERR; } break; } @@ -2330,10 +2314,10 @@ static bt_status_t get_folder_items_list_rsp(const RawAddress& bd_addr, } int len_before = p_msg ? p_msg->len : 0; - LOG_VERBOSE("%s: item_cnt: %d len: %d", __func__, item_cnt, len_before); + log::verbose("item_cnt: {} len: {}", item_cnt, len_before); status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); - LOG_VERBOSE("%s: Build rsp status: %d len: %d", __func__, status, - (p_msg ? p_msg->len : 0)); + log::verbose("Build rsp status: {} len: {}", status, + (p_msg ? p_msg->len : 0)); int len_after = p_msg ? p_msg->len : 0; if (status != AVRC_STS_NO_ERROR || len_before == len_after) { /* Error occured in build response or we ran out of buffer so break the @@ -2355,8 +2339,8 @@ static bt_status_t get_folder_items_list_rsp(const RawAddress& bd_addr, p_msg); } else /* Error occured, send reject response */ { - LOG_ERROR("%s: Error status: 0x%02X. Sending reject rsp", __func__, - avrc_rsp.rsp.status); + log::error("Error status: 0x{:02X}. Sending reject rsp", + avrc_rsp.rsp.status); send_reject_response( p_dev->rc_handle, p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].label, avrc_rsp.pdu, avrc_rsp.get_items.status, avrc_rsp.get_items.opcode); @@ -2387,7 +2371,7 @@ static bt_status_t set_addressed_player_rsp(const RawAddress& bd_addr, tAVRC_RESPONSE avrc_rsp; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); avrc_rsp.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER; @@ -2444,12 +2428,12 @@ static bt_status_t set_browsed_player_rsp(const RawAddress& bd_addr, avrc_rsp.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER; avrc_rsp.br_player.opcode = opcode_from_pdu(AVRC_PDU_SET_BROWSED_PLAYER); - LOG_VERBOSE("%s: rsp_status: 0x%02X avrc_rsp.br_player.status: 0x%02X", - __func__, rsp_status, avrc_rsp.br_player.status); + log::verbose("rsp_status: 0x{:02X} avrc_rsp.br_player.status: 0x{:02X}", + rsp_status, avrc_rsp.br_player.status); /* check if rsp to previous cmd was completed */ if (!p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].is_rsp_pending) { - LOG_WARN("%s: Not sending response as no PDU was registered", __func__); + log::warn("Not sending response as no PDU was registered"); return BT_STATUS_UNHANDLED; } @@ -2459,15 +2443,15 @@ static bt_status_t set_browsed_player_rsp(const RawAddress& bd_addr, avrc_rsp.br_player.folder_depth = folder_depth; avrc_rsp.br_player.p_folders = (tAVRC_NAME*)p_folders; - LOG_VERBOSE("%s: folder_depth: 0x%02X num_items: %d", __func__, - folder_depth, num_items); + log::verbose("folder_depth: 0x{:02X} num_items: {}", folder_depth, + num_items); if (folder_depth > 0) { /* Iteratively build response for all folders across folder depth upto * current path */ avrc_rsp.br_player.folder_depth = 1; for (item_cnt = 0; item_cnt < folder_depth; item_cnt++) { - LOG_VERBOSE("%s: iteration: %d", __func__, item_cnt); + log::verbose("iteration: {}", item_cnt); item.str_len = p_folders[item_cnt].str_len; item.p_str = p_folders[item_cnt].p_str; avrc_rsp.br_player.p_folders = &item; @@ -2475,7 +2459,7 @@ static bt_status_t set_browsed_player_rsp(const RawAddress& bd_addr, /* Add current item to buffer and build response */ status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); if (AVRC_STS_NO_ERROR != status) { - LOG_WARN("%s: Build rsp status: %d", __func__, status); + log::warn("Build rsp status: {}", status); /* if the build fails, it is likely that we ran out of buffer. so if * we have * some items to send, reset this error to no error for sending what we @@ -2495,9 +2479,9 @@ static bt_status_t set_browsed_player_rsp(const RawAddress& bd_addr, avrc_rsp.br_player.status = status; } else /* error received from above layer */ { - LOG_WARN( - "%s: Error in parsing the received setbrowsed command. status: 0x%02x", - __func__, avrc_rsp.br_player.status); + log::warn( + "Error in parsing the received setbrowsed command. status: 0x{:02x}", + avrc_rsp.br_player.status); status = avrc_rsp.br_player.status; } @@ -2510,8 +2494,8 @@ static bt_status_t set_browsed_player_rsp(const RawAddress& bd_addr, p_msg); } else /* Error occured, send reject response */ { - LOG_ERROR("%s: Error status: 0x%02X. Sending reject rsp", __func__, - avrc_rsp.br_player.status); + log::error("Error status: 0x{:02X}. Sending reject rsp", + avrc_rsp.br_player.status); send_reject_response( p_dev->rc_handle, p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].label, avrc_rsp.pdu, avrc_rsp.br_player.status, avrc_rsp.get_items.opcode); @@ -2543,7 +2527,7 @@ static bt_status_t change_path_rsp(const RawAddress& bd_addr, tAVRC_RESPONSE avrc_rsp; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); avrc_rsp.chg_path.pdu = AVRC_PDU_CHANGE_PATH; @@ -2576,7 +2560,7 @@ static bt_status_t search_rsp(const RawAddress& bd_addr, tAVRC_RESPONSE avrc_rsp; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); avrc_rsp.search.pdu = AVRC_PDU_SEARCH; @@ -2611,7 +2595,7 @@ static bt_status_t get_item_attr_rsp(const RawAddress& bd_addr, tAVRC_ATTR_ENTRY item_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); memset(item_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); @@ -2651,7 +2635,7 @@ static bt_status_t add_to_now_playing_rsp(const RawAddress& bd_addr, tAVRC_RESPONSE avrc_rsp; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); avrc_rsp.add_to_play.pdu = AVRC_PDU_ADD_TO_NOW_PLAYING; @@ -2683,7 +2667,7 @@ static bt_status_t play_item_rsp(const RawAddress& bd_addr, tAVRC_RESPONSE avrc_rsp; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); avrc_rsp.play_item.pdu = AVRC_PDU_PLAY_ITEM; @@ -2717,7 +2701,7 @@ static bt_status_t get_total_num_of_items_rsp(const RawAddress& bd_addr, tAVRC_RESPONSE avrc_rsp; btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); avrc_rsp.get_num_of_items.pdu = AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS; @@ -2751,7 +2735,7 @@ static bt_status_t get_total_num_of_items_rsp(const RawAddress& bd_addr, * **************************************************************************/ static bt_status_t set_volume(uint8_t volume) { - LOG_VERBOSE("%s: volume: %d", __func__, volume); + log::verbose("volume: {}", volume); tAVRC_STS status = BT_STATUS_UNSUPPORTED; for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) { @@ -2760,8 +2744,7 @@ static bt_status_t set_volume(uint8_t volume) { if (p_dev->rc_volume == volume) { status = BT_STATUS_DONE; - LOG_ERROR("%s: volume value already set earlier: 0x%02x", __func__, - volume); + log::error("volume value already set earlier: 0x{:02x}", volume); continue; } @@ -2779,8 +2762,7 @@ static bt_status_t set_volume(uint8_t volume) { if (!(p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL)) continue; - LOG_VERBOSE("%s: Peer supports absolute volume. newVolume: %d", __func__, - volume); + log::verbose("Peer supports absolute volume. newVolume: {}", volume); tAVRC_COMMAND avrc_cmd = {.volume = {.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME, .status = AVRC_STS_NO_ERROR, @@ -2789,8 +2771,8 @@ static bt_status_t set_volume(uint8_t volume) { BT_HDR* p_msg = NULL; if (AVRC_BldCommand(&avrc_cmd, &p_msg) != AVRC_STS_NO_ERROR) { - LOG_ERROR("%s: failed to build absolute volume command. status: 0x%02x", - __func__, status); + log::error("failed to build absolute volume command. status: 0x{:02x}", + status); status = BT_STATUS_FAIL; continue; } @@ -2806,14 +2788,13 @@ static bt_status_t set_volume(uint8_t volume) { if (tran_status != BT_STATUS_SUCCESS || !p_transaction) { osi_free_and_reset((void**)&p_msg); - LOG_ERROR("%s: failed to get label, pdu_id=%s, status=0x%02x", __func__, - dump_rc_pdu(avrc_cmd.pdu), tran_status); + log::error("failed to get label, pdu_id={}, status=0x{:02x}", + dump_rc_pdu(avrc_cmd.pdu), tran_status); status = BT_STATUS_FAIL; continue; } - LOG_VERBOSE("%s: msgreq being sent out with label: %d", __func__, - p_transaction->label); + log::verbose("msgreq being sent out with label: {}", p_transaction->label); BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->label, AVRC_CMD_CTRL, p_msg); status = BT_STATUS_SUCCESS; start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS); @@ -2833,7 +2814,7 @@ static bt_status_t set_volume(uint8_t volume) { static void register_volumechange(btif_rc_device_cb_t* p_dev) { if (p_dev == nullptr) { - LOG_ERROR("%s: device was null", __func__); + log::error("device was null"); return; } @@ -2854,8 +2835,7 @@ static void register_volumechange(btif_rc_device_cb_t* p_dev) { } else { p_transaction = get_transaction_by_lbl(p_dev, p_dev->rc_vol_label); if (NULL != p_transaction) { - LOG_VERBOSE("%s: already in progress for label: %d", __func__, - p_dev->rc_vol_label); + log::verbose("already in progress for label: {}", p_dev->rc_vol_label); return; } status = get_transaction(p_dev, context, &p_transaction); @@ -2864,11 +2844,11 @@ static void register_volumechange(btif_rc_device_cb_t* p_dev) { if (BT_STATUS_SUCCESS == status && NULL != p_transaction) { p_dev->rc_vol_label = p_transaction->label; } else { - LOG_ERROR("%s: failed to get a transaction label", __func__); + log::error("failed to get a transaction label"); return; } - LOG_VERBOSE("%s: label: %d", __func__, p_dev->rc_vol_label); + log::verbose("label: {}", p_dev->rc_vol_label); avrc_cmd.cmd.opcode = 0x00; avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION; @@ -2880,9 +2860,9 @@ static void register_volumechange(btif_rc_device_cb_t* p_dev) { if (AVRC_STS_NO_ERROR == BldResp && p_msg) { BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->label, AVRC_CMD_NOTIF, p_msg); - LOG_VERBOSE("%s: BTA_AvMetaCmd called", __func__); + log::verbose("BTA_AvMetaCmd called"); } else { - LOG_ERROR("%s: failed to build command: %d", __func__, BldResp); + log::error("failed to build command: {}", BldResp); } } @@ -2901,7 +2881,7 @@ static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg, uint8_t scratch_buf[512] = {0}; tAVRC_STS status = BT_STATUS_UNSUPPORTED; - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); if (AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode && (AVRC_RSP_CHANGED == pmeta_msg->code || @@ -2910,9 +2890,9 @@ static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg, AVRC_RSP_NOT_IMPL == pmeta_msg->code)) { status = AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf)); - LOG_VERBOSE( - "%s: code:%d, event ID: %d, PDU: %x, parsing status: %d, label: %d", - __func__, pmeta_msg->code, avrc_response.reg_notif.event_id, + log::verbose( + "code:{}, event ID: {}, PDU: {:x}, parsing status: {}, label: {}", + pmeta_msg->code, avrc_response.reg_notif.event_id, avrc_response.reg_notif.pdu, status, pmeta_msg->label); if (status != AVRC_STS_NO_ERROR) { @@ -2932,9 +2912,9 @@ static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg, p_dev->rc_vol_label != pmeta_msg->label) { // Just discard the message, if the device sends back with an incorrect // label - LOG_VERBOSE( - "%s: Discarding register notification in rsp.code: %d and label: %d", - __func__, pmeta_msg->code, pmeta_msg->label); + log::verbose( + "Discarding register notification in rsp.code: {} and label: {}", + pmeta_msg->code, pmeta_msg->label); return; } @@ -2942,16 +2922,16 @@ static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg, AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id && (AVRC_RSP_REJ == pmeta_msg->code || AVRC_RSP_NOT_IMPL == pmeta_msg->code)) { - LOG_VERBOSE("%s remove AbsoluteVolume feature flag.", __func__); + log::verbose("remove AbsoluteVolume feature flag."); p_dev->rc_features &= ~BTA_AV_FEAT_ADV_CTRL; handle_rc_features(p_dev); return; } } else { - LOG_VERBOSE( - "%s: Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not " + log::verbose( + "Received vendor dependent in adv ctrl rsp. code: {} len: {}. Not " "processing it.", - __func__, pmeta_msg->code, pmeta_msg->len); + pmeta_msg->code, pmeta_msg->len); return; } @@ -2966,8 +2946,8 @@ static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg, release_transaction(p_dev, pmeta_msg->label); } - LOG_VERBOSE("%s: Passing received metamsg response to app. pdu: %s", __func__, - dump_rc_pdu(avrc_response.pdu)); + log::verbose("Passing received metamsg response to app. pdu: {}", + dump_rc_pdu(avrc_response.pdu)); btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code, pmeta_msg->label, p_dev); } @@ -3007,8 +2987,8 @@ bool iterate_supported_event_list_for_interim_rsp(void* data, void* cb_data) { static void rc_notification_interim_timeout(btif_rc_device_cb_t* p_dev, uint8_t event_id) { /* Device disconnections clear the event list but can't free the timer */ - if (p_dev == NULL || p_dev->rc_supported_event_list) { - LOG_WARN("%s: timeout for null device or event list", __func__); + if (p_dev == NULL || p_dev->rc_supported_event_list == NULL) { + log::warn("timeout for null device or event list"); return; } @@ -3063,7 +3043,7 @@ static void register_for_event_notification(btif_rc_supported_event_t* p_event, bt_status_t status = register_notification_cmd(p_event->event_id, interval_in_seconds, p_dev); if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("%s: failed, status=%d", __func__, status); + log::error("failed, status={}", status); return; } @@ -3100,8 +3080,8 @@ static bt_status_t build_and_send_vendor_cmd(tAVRC_COMMAND* avrc_cmd, bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction); if (BT_STATUS_SUCCESS != tran_status || p_transaction == NULL) { - LOG_ERROR("%s: failed to get label, pdu_id=%s, status=0x%02x", __func__, - dump_rc_pdu(avrc_cmd->pdu), tran_status); + log::error("failed to get label, pdu_id={}, status=0x{:02x}", + dump_rc_pdu(avrc_cmd->pdu), tran_status); return BT_STATUS_FAIL; } @@ -3109,14 +3089,14 @@ static bt_status_t build_and_send_vendor_cmd(tAVRC_COMMAND* avrc_cmd, tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg); if (status == AVRC_STS_NO_ERROR && p_msg != NULL) { uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset; - LOG_VERBOSE("%s: %s msgreq being sent out with label: %d", __func__, - dump_rc_pdu(avrc_cmd->pdu), p_transaction->label); + log::verbose("{} msgreq being sent out with label: {}", + dump_rc_pdu(avrc_cmd->pdu), p_transaction->label); BTA_AvVendorCmd(p_dev->rc_handle, p_transaction->label, cmd_code, data_start, p_msg->len); status = BT_STATUS_SUCCESS; start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS); } else { - LOG_ERROR("%s: failed to build command. status: 0x%02x", __func__, status); + log::error("failed to build command. status: 0x{:02x}", status); release_transaction(p_dev, p_transaction->label); } osi_free(p_msg); @@ -3146,21 +3126,21 @@ static bt_status_t build_and_send_browsing_cmd(tAVRC_COMMAND* avrc_cmd, bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction); if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) { - LOG_ERROR("%s: failed to get label, pdu_id=%s, status=0x%02x", __func__, - dump_rc_pdu(avrc_cmd->pdu), tran_status); + log::error("failed to get label, pdu_id={}, status=0x{:02x}", + dump_rc_pdu(avrc_cmd->pdu), tran_status); return BT_STATUS_FAIL; } BT_HDR* p_msg = NULL; tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg); if (status != AVRC_STS_NO_ERROR) { - LOG_ERROR("%s: failed to build command status %d", __func__, status); + log::error("failed to build command status {}", status); release_transaction(p_dev, p_transaction->label); return BT_STATUS_FAIL; } - LOG_VERBOSE("%s: Send pdu_id=%s, label=%d", __func__, - dump_rc_pdu(avrc_cmd->pdu), p_transaction->label); + log::verbose("Send pdu_id={}, label={}", dump_rc_pdu(avrc_cmd->pdu), + p_transaction->label); BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->label, AVRC_CMD_CTRL, p_msg); start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS); return BT_STATUS_SUCCESS; @@ -3184,7 +3164,7 @@ static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, /* Todo: Do we need to retry on command timeout */ if (p_rsp->status != AVRC_STS_NO_ERROR) { - LOG_ERROR("%s: Error capability response: 0x%02X", __func__, p_rsp->status); + log::error("Error capability response: 0x{:02X}", p_rsp->status); return; } @@ -3226,9 +3206,9 @@ static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, } } else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) { getcapabilities_cmd(AVRC_CAP_EVENTS_SUPPORTED, p_dev); - LOG_VERBOSE("%s: AVRC_CAP_COMPANY_ID: ", __func__); + log::verbose("AVRC_CAP_COMPANY_ID:"); for (xx = 0; xx < p_rsp->count; xx++) { - LOG_VERBOSE("%s: company_id: %d", __func__, p_rsp->param.company_id[xx]); + log::verbose("company_id: {}", p_rsp->param.company_id[xx]); } } } @@ -3268,16 +3248,14 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } if (btif_av_src_sink_coexist_enabled() && p_rsp->event_id == AVRC_EVT_VOLUME_CHANGE) { - LOG_ERROR( - "%s: legacy TG don't handle absolute volume change. leave it to new " - "avrcp", - __func__); + log::error( + "legacy TG don't handle absolute volume change. leave it to new avrcp"); return; } @@ -3288,7 +3266,7 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_supported_event_t* p_event; list_node_t* node; - LOG_VERBOSE("%s: Interim response: 0x%2X ", __func__, p_rsp->event_id); + log::verbose("Interim response: 0x{:2X}", p_rsp->event_id); switch (p_rsp->event_id) { case AVRC_EVT_PLAY_STATUS_CHANGE: get_play_status_cmd(p_dev); @@ -3323,7 +3301,7 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, break; case AVRC_EVT_AVAL_PLAYERS_CHANGE: - LOG_VERBOSE("%s: AVRC_EVT_AVAL_PLAYERS_CHANGE", __func__); + log::verbose("AVRC_EVT_AVAL_PLAYERS_CHANGE"); do_in_jni_thread( FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->available_player_changed_cb, @@ -3352,8 +3330,7 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, case AVRC_EVT_BATTERY_STATUS_CHANGE: case AVRC_EVT_SYSTEM_STATUS_CHANGE: default: - LOG_ERROR("%s: Unhandled interim response: 0x%2X", __func__, - p_rsp->event_id); + log::error("Unhandled interim response: 0x{:2X}", p_rsp->event_id); return; } @@ -3381,8 +3358,7 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, if (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING) { list_player_app_setting_attrib_cmd(p_dev); } else { - LOG_VERBOSE("%s: App setting not supported, complete procedure", - __func__); + log::verbose("App setting not supported, complete procedure"); rc_ctrl_procedure_complete(p_dev); } } @@ -3390,8 +3366,7 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_supported_event_t* p_event; list_node_t* node; - LOG_VERBOSE("%s: Notification completed: 0x%2X ", __func__, - p_rsp->event_id); + log::verbose("Notification completed: 0x{:2X}", p_rsp->event_id); node = list_begin(p_dev->rc_supported_event_list); @@ -3463,8 +3438,7 @@ static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, case AVRC_EVT_BATTERY_STATUS_CHANGE: case AVRC_EVT_SYSTEM_STATUS_CHANGE: default: - LOG_ERROR("%s: Unhandled completion response: 0x%2X", __func__, - p_rsp->event_id); + log::error("Unhandled completion response: 0x{:2X}", p_rsp->event_id); return; } } @@ -3486,8 +3460,8 @@ static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) { - LOG_ERROR("%s: Error getting Player application settings: 0x%2X", __func__, - p_rsp->status); + log::error("Error getting Player application settings: 0x{:2X}", + p_rsp->status); rc_ctrl_procedure_complete(p_dev); return; } @@ -3514,7 +3488,7 @@ static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, list_player_app_setting_value_cmd(p_dev->rc_app_settings.attrs[0].attr_id, p_dev); } else { - LOG_ERROR("%s: No Player application settings found", __func__); + log::error("No Player application settings found"); } } @@ -3540,8 +3514,7 @@ static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, /* Todo: Do we need to retry on command timeout */ if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) { - LOG_ERROR("%s: Error fetching attribute values: 0x%02X", __func__, - p_rsp->status); + log::error("Error fetching attribute values: 0x{:02X}", p_rsp->status); return; } @@ -3616,13 +3589,12 @@ static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg, /* Todo: Do we need to retry on command timeout */ if (p_rsp->status != AVRC_STS_NO_ERROR) { - LOG_ERROR("%s: Error fetching current settings: 0x%02X", __func__, - p_rsp->status); + log::error("Error fetching current settings: 0x{:02X}", p_rsp->status); return; } p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: Error in getting Device Address", __func__); + log::error("Error in getting Device Address"); osi_free_and_reset((void**)&p_rsp->p_vals); return; } @@ -3671,7 +3643,7 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -3681,8 +3653,7 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg, if (p_rsp->status != AVRC_STS_NO_ERROR) { uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE]; - LOG_ERROR("%s: Error fetching attribute text: 0x%02X", __func__, - p_rsp->status); + log::error("Error fetching attribute text: 0x{:02X}", p_rsp->status); /* Not able to fetch Text for extended Menu, skip the process * and cleanup used memory. Proceed to get the current settings * for standard attributes. @@ -3751,7 +3722,7 @@ static void handle_app_attr_val_txt_response( btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -3761,8 +3732,7 @@ static void handle_app_attr_val_txt_response( if (p_rsp->status != AVRC_STS_NO_ERROR) { uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE]; - LOG_ERROR("%s: Error fetching attribute value text: 0x%02X", __func__, - p_rsp->status); + log::error("Error fetching attribute value text: 0x{:02X}", p_rsp->status); /* Not able to fetch Text for extended Menu, skip the process * and cleanup used memory. Proceed to get the current settings @@ -3796,8 +3766,8 @@ static void handle_app_attr_val_txt_response( } if (p_app_settings->ext_val_index >= AVRC_MAX_APP_ATTR_SIZE) { - LOG_ERROR("ext_val_index is 0x%02x, overflow!", - p_app_settings->ext_val_index); + log::error("ext_val_index is 0x{:02x}, overflow!", + p_app_settings->ext_val_index); return; } @@ -3888,7 +3858,7 @@ static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -3925,7 +3895,7 @@ static void handle_get_metadata_attr_response(tBTA_AV_META_MSG* pmeta_msg, (btrc_element_attr_val_t*)osi_calloc(buf_size); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -3954,8 +3924,7 @@ static void handle_get_metadata_attr_response(tBTA_AV_META_MSG* pmeta_msg, const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev); get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev); } else { - LOG_ERROR("%s: Error in get element attr procedure: %d", __func__, - p_rsp->status); + log::error("Error in get element attr procedure: {}", p_rsp->status); } } @@ -3975,7 +3944,7 @@ static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -3990,8 +3959,7 @@ static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg, base::BindOnce(bt_rc_ctrl_callbacks->play_position_changed_cb, p_dev->rc_addr, p_rsp->song_len, p_rsp->song_pos)); } else { - LOG_ERROR("%s: Error in get play status procedure: %d", __func__, - p_rsp->status); + log::error("Error in get play status procedure: {}", p_rsp->status); } } @@ -4011,7 +3979,7 @@ static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -4021,8 +3989,7 @@ static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->set_addressed_player_cb, p_dev->rc_addr, p_rsp->status)); } else { - LOG_ERROR("%s: Error in get play status procedure %d", __func__, - p_rsp->status); + log::error("Error in get play status procedure {}", p_rsp->status); } } @@ -4050,10 +4017,10 @@ static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg, for (uint8_t i = 0; i < item_count; i++) { const tAVRC_ITEM* avrc_item = &(p_rsp->p_item_list[i]); btrc_folder_items_t* btrc_item = &(btrc_items[i]); - LOG_VERBOSE("%s folder item type %d", __func__, avrc_item->item_type); + log::verbose("folder item type {}", avrc_item->item_type); switch (avrc_item->item_type) { case AVRC_ITEM_MEDIA: - LOG_VERBOSE("%s setting type to %d", __func__, BTRC_ITEM_MEDIA); + log::verbose("setting type to {}", BTRC_ITEM_MEDIA); /* Allocate Space for Attributes */ btrc_item->media.num_attrs = avrc_item->u.media.attr_count; btrc_item->media.p_attrs = (btrc_element_attr_val_t*)osi_malloc( @@ -4062,18 +4029,18 @@ static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg, break; case AVRC_ITEM_FOLDER: - LOG_VERBOSE("%s setting type to BTRC_ITEM_FOLDER", __func__); + log::verbose("setting type to BTRC_ITEM_FOLDER"); get_folder_item_type_folder(avrc_item, btrc_item); break; case AVRC_ITEM_PLAYER: - LOG_VERBOSE("%s setting type to BTRC_ITEM_PLAYER", __func__); + log::verbose("setting type to BTRC_ITEM_PLAYER"); get_folder_item_type_player(avrc_item, btrc_item); break; default: - LOG_ERROR("%s cannot understand folder item type %d", __func__, - avrc_item->item_type); + log::error("cannot understand folder item type {}", + avrc_item->item_type); } } @@ -4096,9 +4063,9 @@ static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg, do_in_jni_thread(FROM_HERE, base::BindOnce(cleanup_btrc_folder_items, btrc_items, item_count)); - LOG_VERBOSE("%s get_folder_items_cb sent to JNI thread", __func__); + log::verbose("get_folder_items_cb sent to JNI thread"); } else { - LOG_ERROR("%s: Error %d", __func__, p_rsp->status); + log::error("Error {}", p_rsp->status); do_in_jni_thread( FROM_HERE, base::BindOnce(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr, (btrc_status_t)p_rsp->status, @@ -4126,7 +4093,7 @@ static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items, /*Nothing to free*/ break; default: - LOG_WARN("%s free unspecified type", __func__); + log::warn("free unspecified type"); } } osi_free(btrc_items); @@ -4165,8 +4132,8 @@ void get_folder_item_type_media(const tAVRC_ITEM* avrc_item, btrc_item_media->charset_id = avrc_item_media->name.charset_id; /* Copy the name */ - LOG_VERBOSE("%s max len %d str len %d", __func__, BTRC_MAX_ATTR_STR_LEN, - avrc_item_media->name.str_len); + log::verbose("max len {} str len {}", BTRC_MAX_ATTR_STR_LEN, + avrc_item_media->name.str_len); memset(btrc_item_media->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t)); memcpy(btrc_item_media->name, avrc_item_media->name.p_str, sizeof(uint8_t) * (avrc_item_media->name.str_len)); @@ -4176,7 +4143,7 @@ void get_folder_item_type_media(const tAVRC_ITEM* avrc_item, btrc_element_attr_val_t* btrc_attr_pair = &(btrc_item_media->p_attrs[i]); tAVRC_ATTR_ENTRY* avrc_attr_pair = &(avrc_item_media->p_attr_list[i]); - LOG_VERBOSE("%s media attr id 0x%x", __func__, avrc_attr_pair->attr_id); + log::verbose("media attr id 0x{:x}", avrc_attr_pair->attr_id); switch (avrc_attr_pair->attr_id) { case AVRC_MEDIA_ATTR_ID_TITLE: @@ -4204,8 +4171,7 @@ void get_folder_item_type_media(const tAVRC_ITEM* avrc_item, btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_COVER_ARTWORK_HANDLE; break; default: - LOG_ERROR("%s invalid media attr id: 0x%x", __func__, - avrc_attr_pair->attr_id); + log::error("invalid media attr id: 0x{:x}", avrc_attr_pair->attr_id); btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_INVALID; } @@ -4263,8 +4229,8 @@ void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item, btrc_item_folder->playable = avrc_item_folder->playable; /* Copy name */ - LOG_VERBOSE("%s max len %d str len %d", __func__, BTRC_MAX_ATTR_STR_LEN, - avrc_item_folder->name.str_len); + log::verbose("max len {} str len {}", BTRC_MAX_ATTR_STR_LEN, + avrc_item_folder->name.str_len); memset(btrc_item_folder->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t)); memcpy(btrc_item_folder->name, avrc_item_folder->name.p_str, avrc_item_folder->name.str_len * sizeof(uint8_t)); @@ -4319,7 +4285,7 @@ static void handle_change_path_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: Invalid rc handle", __func__); + log::error("Invalid rc handle"); return; } @@ -4328,8 +4294,7 @@ static void handle_change_path_response(tBTA_AV_META_MSG* pmeta_msg, base::BindOnce(bt_rc_ctrl_callbacks->change_folder_path_cb, p_dev->rc_addr, p_rsp->num_items)); } else { - LOG_ERROR("%s error in handle_change_path_response %d", __func__, - p_rsp->status); + log::error("error in handle_change_path_response {}", p_rsp->status); } } @@ -4348,7 +4313,7 @@ static void handle_set_browsed_player_response(tBTA_AV_META_MSG* pmeta_msg, btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: Invalid rc handle", __func__); + log::error("Invalid rc handle"); return; } @@ -4358,7 +4323,7 @@ static void handle_set_browsed_player_response(tBTA_AV_META_MSG* pmeta_msg, base::BindOnce(bt_rc_ctrl_callbacks->set_browsed_player_cb, p_dev->rc_addr, p_rsp->num_items, p_rsp->folder_depth)); } else { - LOG_ERROR("%s error %d", __func__, p_rsp->status); + log::error("error {}", p_rsp->status); } } @@ -4375,7 +4340,7 @@ static void clear_cmd_timeout(btif_rc_device_cb_t* p_dev, uint8_t label) { p_txn = get_transaction_by_lbl(p_dev, label); if (p_txn == NULL) { - LOG_ERROR("%s: Error in transaction label lookup", __func__); + log::error("Error in transaction label lookup"); return; } @@ -4402,8 +4367,8 @@ static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) { tAVRC_STS status; btif_rc_device_cb_t* p_dev = NULL; - LOG_VERBOSE("%s: opcode: %d rsp_code: %d ", __func__, - pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); + log::verbose("opcode: {} rsp_code: {}", pmeta_msg->p_msg->hdr.opcode, + pmeta_msg->code); p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle); status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, @@ -4411,8 +4376,8 @@ static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) { if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) && (pmeta_msg->code <= AVRC_RSP_INTERIM)) { - LOG_VERBOSE("%s parse status %d pdu = %d rsp_status = %d", __func__, status, - avrc_response.pdu, pmeta_msg->p_msg->vendor.hdr.ctype); + log::verbose("parse status {} pdu = {} rsp_status = {}", status, + avrc_response.pdu, pmeta_msg->p_msg->vendor.hdr.ctype); switch (avrc_response.pdu) { case AVRC_PDU_REGISTER_NOTIFICATION: @@ -4468,7 +4433,7 @@ static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) { break; } } else if (AVRC_OP_BROWSE == pmeta_msg->p_msg->hdr.opcode) { - LOG_VERBOSE("%s AVRC_OP_BROWSE pdu %d", __func__, avrc_response.pdu); + log::verbose("AVRC_OP_BROWSE pdu {}", avrc_response.pdu); /* check what kind of command it is for browsing */ switch (avrc_response.pdu) { case AVRC_PDU_GET_FOLDER_ITEMS: @@ -4484,16 +4449,14 @@ static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) { handle_get_metadata_attr_response(pmeta_msg, &avrc_response.get_attrs); break; default: - LOG_ERROR("%s cannot handle browse pdu %d", __func__, - pmeta_msg->p_msg->hdr.opcode); + log::error("cannot handle browse pdu {}", pmeta_msg->p_msg->hdr.opcode); } } else { - LOG_VERBOSE( - "%s: Invalid Vendor Command code: %d len: %d. Not processing it.", - __func__, pmeta_msg->code, pmeta_msg->len); + log::verbose("Invalid Vendor Command code: {} len: {}. Not processing it.", + pmeta_msg->code, pmeta_msg->len); return; } - LOG_VERBOSE("%s: release transaction %d", __func__, pmeta_msg->label); + log::verbose("release transaction {}", pmeta_msg->label); release_transaction(p_dev, pmeta_msg->label); } @@ -4511,18 +4474,18 @@ static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { tAVRC_STS status = BT_STATUS_UNSUPPORTED; btif_rc_device_cb_t* p_dev = NULL; - LOG_VERBOSE("%s: opcode: %d rsp_code: %d", __func__, - pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code); + log::verbose("opcode: {} rsp_code: {}", pmeta_msg->p_msg->hdr.opcode, + pmeta_msg->code); status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd); if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && (pmeta_msg->code <= AVRC_CMD_GEN_INQ)) { - LOG_VERBOSE("%s Received vendor command.code %d, PDU %d label %d", __func__, - pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label); + log::verbose("Received vendor command.code {}, PDU {} label {}", + pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label); if (status != AVRC_STS_NO_ERROR) { /* return error */ - LOG_WARN("%s: Error in parsing received metamsg command. status: 0x%02x", - __func__, status); + log::warn("Error in parsing received metamsg command. status: 0x{:02x}", + status); if (true == btif_av_both_enable()) { if (AVRC_PDU_GET_CAPABILITIES == avrc_cmd.pdu || AVRC_PDU_GET_ELEMENT_ATTR == avrc_cmd.pdu || @@ -4536,25 +4499,24 @@ static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { } else { p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle); if (p_dev == NULL) { - LOG_ERROR("%s: avk rc meta msg cmd for Invalid rc handle", __func__); + log::error("avk rc meta msg cmd for Invalid rc handle"); return; } if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) { uint8_t event_id = avrc_cmd.reg_notif.event_id; - LOG_VERBOSE("%s: Register notification event_id: %s", __func__, - dump_rc_notification_event_id(event_id)); + log::verbose("Register notification event_id: {}", + dump_rc_notification_event_id(event_id)); } else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME) { - LOG_VERBOSE("%s: Abs Volume Cmd Recvd", __func__); + log::verbose("Abs Volume Cmd Recvd"); } btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label, p_dev); } } else { - LOG_VERBOSE( - "%s: Invalid Vendor Command code: %d len: %d. Not processing it.", - __func__, pmeta_msg->code, pmeta_msg->len); + log::verbose("Invalid Vendor Command code: {} len: {}. Not processing it.", + pmeta_msg->code, pmeta_msg->len); return; } } @@ -4569,7 +4531,7 @@ static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) { * **************************************************************************/ static void cleanup() { - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); if (bt_rc_callbacks) { bt_rc_callbacks = NULL; } @@ -4580,7 +4542,7 @@ static void cleanup() { sizeof(btif_rc_cb.rc_multi_cb[idx])); } - LOG_VERBOSE("%s: completed", __func__); + log::verbose("completed"); } /*************************************************************************** @@ -4593,7 +4555,7 @@ static void cleanup() { * **************************************************************************/ static void cleanup_ctrl() { - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); if (bt_rc_ctrl_callbacks) { bt_rc_ctrl_callbacks = NULL; @@ -4606,7 +4568,7 @@ static void cleanup_ctrl() { } memset(&btif_rc_cb.rc_multi_cb, 0, sizeof(btif_rc_cb.rc_multi_cb)); - LOG_VERBOSE("%s: completed", __func__); + log::verbose("completed"); } /*************************************************************************** @@ -4620,7 +4582,7 @@ static void cleanup_ctrl() { **************************************************************************/ static bt_status_t getcapabilities_cmd(uint8_t cap_id, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: cap_id: %d", __func__, cap_id); + log::verbose("cap_id: {}", cap_id); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -4643,7 +4605,7 @@ static bt_status_t getcapabilities_cmd(uint8_t cap_id, **************************************************************************/ static bt_status_t list_player_app_setting_attrib_cmd( btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -4665,7 +4627,7 @@ static bt_status_t list_player_app_setting_attrib_cmd( **************************************************************************/ static bt_status_t list_player_app_setting_value_cmd( uint8_t attrib_id, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: attrib_id: %d", __func__, attrib_id); + log::verbose("attrib_id: {}", attrib_id); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -4689,7 +4651,7 @@ static bt_status_t list_player_app_setting_value_cmd( static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: num_attrib: %d", __func__, num_attrib); + log::verbose("num_attrib: {}", num_attrib); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -4716,10 +4678,10 @@ static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, * **************************************************************************/ static bt_status_t get_current_metadata_cmd(const RawAddress& bd_addr) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return BT_STATUS_FAIL; } const uint32_t* attr_list = get_requested_attributes_list(p_dev); @@ -4738,7 +4700,7 @@ static bt_status_t get_current_metadata_cmd(const RawAddress& bd_addr) { * **************************************************************************/ static bt_status_t get_playback_state_cmd(const RawAddress& bd_addr) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); return get_play_status_cmd(p_dev); } @@ -4759,7 +4721,7 @@ static bt_status_t get_playback_state_cmd(const RawAddress& bd_addr) { static bt_status_t get_now_playing_list_cmd(const RawAddress& bd_addr, uint32_t start_item, uint32_t end_item) { - LOG_VERBOSE("%s start, end: (%d, %d)", __func__, start_item, end_item); + log::verbose("start, end: ({}, {})", start_item, end_item); return get_folder_items_cmd(bd_addr, AVRC_SCOPE_NOW_PLAYING, start_item, end_item); } @@ -4808,7 +4770,7 @@ static bt_status_t get_item_attribute_cmd(uint64_t uid, int scope, **************************************************************************/ static bt_status_t get_folder_list_cmd(const RawAddress& bd_addr, uint32_t start_item, uint32_t end_item) { - LOG_VERBOSE("%s start, end: (%d, %d)", __func__, start_item, end_item); + log::verbose("start, end: ({}, {})", start_item, end_item); return get_folder_items_cmd(bd_addr, AVRC_SCOPE_FILE_SYSTEM, start_item, end_item); } @@ -4828,7 +4790,7 @@ static bt_status_t get_folder_list_cmd(const RawAddress& bd_addr, **************************************************************************/ static bt_status_t get_player_list_cmd(const RawAddress& bd_addr, uint32_t start_item, uint32_t end_item) { - LOG_VERBOSE("%s start, end: (%d, %d)", __func__, start_item, end_item); + log::verbose("start, end: ({}, {})", start_item, end_item); return get_folder_items_cmd(bd_addr, AVRC_SCOPE_PLAYER_LIST, start_item, end_item); } @@ -4850,7 +4812,7 @@ static bt_status_t get_player_list_cmd(const RawAddress& bd_addr, **************************************************************************/ static bt_status_t change_folder_path_cmd(const RawAddress& bd_addr, uint8_t direction, uint8_t* uid) { - LOG_VERBOSE("%s: direction %d", __func__, direction); + log::verbose("direction {}", direction); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); CHECK_RC_CONNECTED(p_dev); CHECK_BR_CONNECTED(p_dev); @@ -4883,7 +4845,7 @@ static bt_status_t change_folder_path_cmd(const RawAddress& bd_addr, **************************************************************************/ static bt_status_t set_browsed_player_cmd(const RawAddress& bd_addr, uint16_t id) { - LOG_VERBOSE("%s: id %d", __func__, id); + log::verbose("id {}", id); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); CHECK_RC_CONNECTED(p_dev); CHECK_BR_CONNECTED(p_dev); @@ -4911,7 +4873,7 @@ static bt_status_t set_browsed_player_cmd(const RawAddress& bd_addr, ***************************************************************************/ static bt_status_t set_addressed_player_cmd(const RawAddress& bd_addr, uint16_t id) { - LOG_VERBOSE("%s: id %d", __func__, id); + log::verbose("id {}", id); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); CHECK_RC_CONNECTED(p_dev); @@ -4947,7 +4909,7 @@ static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr, uint32_t end_item) { /* Check that both avrcp and browse channel are connected. */ btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); CHECK_BR_CONNECTED(p_dev); @@ -4979,7 +4941,7 @@ static bt_status_t change_player_app_setting(const RawAddress& bd_addr, uint8_t num_attrib, uint8_t* attrib_ids, uint8_t* attrib_vals) { - LOG_VERBOSE("%s: num_attrib: %d", __func__, num_attrib); + log::verbose("num_attrib: {}", num_attrib); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); CHECK_RC_CONNECTED(p_dev); @@ -5011,7 +4973,7 @@ static bt_status_t change_player_app_setting(const RawAddress& bd_addr, **************************************************************************/ static bt_status_t play_item_cmd(const RawAddress& bd_addr, uint8_t scope, uint8_t* uid, uint16_t uid_counter) { - LOG_VERBOSE("%s: scope %d uid_counter %d", __func__, scope, uid_counter); + log::verbose("scope {} uid_counter {}", scope, uid_counter); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); CHECK_RC_CONNECTED(p_dev); CHECK_BR_CONNECTED(p_dev); @@ -5038,7 +5000,7 @@ static bt_status_t play_item_cmd(const RawAddress& bd_addr, uint8_t scope, **************************************************************************/ static bt_status_t get_player_app_setting_attr_text_cmd( uint8_t* attrs, uint8_t num_attrs, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: num attrs: %d", __func__, num_attrs); + log::verbose("num attrs: {}", num_attrs); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -5064,7 +5026,7 @@ static bt_status_t get_player_app_setting_attr_text_cmd( **************************************************************************/ static bt_status_t get_player_app_setting_value_text_cmd( uint8_t* vals, uint8_t num_vals, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: num_vals: %d", __func__, num_vals); + log::verbose("num_vals: {}", num_vals); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -5091,8 +5053,7 @@ static bt_status_t get_player_app_setting_value_text_cmd( static bt_status_t register_notification_cmd(uint8_t event_id, uint32_t event_value, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: event_id: %d event_value %d", __func__, event_id, - event_value); + log::verbose("event_id: {} event_value {}", event_id, event_value); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -5120,8 +5081,8 @@ static bt_status_t register_notification_cmd(uint8_t event_id, static bt_status_t get_metadata_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: num_attribute: %d attribute_id: %d", __func__, num_attribute, - p_attr_ids[0]); + log::verbose("num_attribute: {} attribute_id: {}", num_attribute, + p_attr_ids[0]); // If browsing is connected then send the command out that channel if (p_dev->br_connected) { @@ -5146,8 +5107,8 @@ static bt_status_t get_metadata_attribute_cmd(uint8_t num_attribute, static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids, btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s: num_attribute: %d attribute_id: %d", __func__, num_attribute, - p_attr_ids[0]); + log::verbose("num_attribute: {} attribute_id: {}", num_attribute, + p_attr_ids[0]); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR; @@ -5171,7 +5132,7 @@ static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, * **************************************************************************/ static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); CHECK_RC_CONNECTED(p_dev); tAVRC_COMMAND avrc_cmd = {0}; @@ -5200,7 +5161,7 @@ static bt_status_t set_volume_rsp(const RawAddress& bd_addr, uint8_t abs_vol, CHECK_RC_CONNECTED(p_dev); - LOG_VERBOSE("%s: abs_vol: %d", __func__, abs_vol); + log::verbose("abs_vol: {}", abs_vol); avrc_rsp.volume.opcode = AVRC_OP_VENDOR; avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME; @@ -5209,15 +5170,14 @@ static bt_status_t set_volume_rsp(const RawAddress& bd_addr, uint8_t abs_vol, status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); if (status == AVRC_STS_NO_ERROR) { uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset; - LOG_VERBOSE("%s: msgreq being sent out with label: %d", __func__, - p_dev->rc_vol_label); + log::verbose("msgreq being sent out with label: {}", p_dev->rc_vol_label); if (p_msg != NULL) { BTA_AvVendorRsp(p_dev->rc_handle, label, AVRC_RSP_ACCEPT, data_start, p_msg->len, 0); status = BT_STATUS_SUCCESS; } } else { - LOG_ERROR("%s: failed to build command. status: 0x%02x", __func__, status); + log::error("failed to build command. status: 0x{:02x}", status); } osi_free(p_msg); return (bt_status_t)status; @@ -5238,7 +5198,7 @@ static bt_status_t volume_change_notification_rsp( tAVRC_STS status = BT_STATUS_UNSUPPORTED; tAVRC_RESPONSE avrc_rsp; BT_HDR* p_msg = NULL; - LOG_VERBOSE("%s: rsp_type: %d abs_vol: %d", __func__, rsp_type, abs_vol); + log::verbose("rsp_type: {} abs_vol: {}", rsp_type, abs_vol); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); @@ -5252,7 +5212,7 @@ static bt_status_t volume_change_notification_rsp( status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg); if (status == AVRC_STS_NO_ERROR) { - LOG_VERBOSE("%s: msgreq being sent out with label: %d", __func__, label); + log::verbose("msgreq being sent out with label: {}", label); uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset; BTA_AvVendorRsp(p_dev->rc_handle, label, (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) @@ -5261,7 +5221,7 @@ static bt_status_t volume_change_notification_rsp( data_start, p_msg->len, 0); status = BT_STATUS_SUCCESS; } else { - LOG_ERROR("%s: failed to build command. status: 0x%02x", __func__, status); + log::error("failed to build command. status: 0x{:02x}", status); } osi_free(p_msg); @@ -5282,7 +5242,7 @@ static bt_status_t send_groupnavigation_cmd(const RawAddress& bd_addr, uint8_t key_state) { tAVRC_STS status = BT_STATUS_UNSUPPORTED; rc_transaction_t* p_transaction = NULL; - LOG_VERBOSE("%s: key-code: %d, key-state: %d", __func__, key_code, key_state); + log::verbose("key-code: {}, key-state: {}", key_code, key_state); btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr); CHECK_RC_CONNECTED(p_dev); @@ -5305,16 +5265,16 @@ static bt_status_t send_groupnavigation_cmd(const RawAddress& bd_addr, AVRC_PASS_THRU_GROUP_LEN); status = BT_STATUS_SUCCESS; start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS); - LOG_VERBOSE("%s: Send command, key-code=%d, key-state=%d, label=%d", - __func__, key_code, key_state, p_transaction->label); + log::verbose("Send command, key-code={}, key-state={}, label={}", + key_code, key_state, p_transaction->label); } else { status = BT_STATUS_FAIL; - LOG_ERROR("%s: failed to get label, key-code=%d, key-state=%d, status=%d", - __func__, key_code, key_state, tran_status); + log::error("failed to get label, key-code={}, key-state={}, status={}", + key_code, key_state, tran_status); } } else { status = BT_STATUS_FAIL; - LOG_VERBOSE("%s: feature not supported", __func__); + log::verbose("feature not supported"); } return (bt_status_t)status; } @@ -5332,13 +5292,13 @@ static bt_status_t send_passthrough_cmd(const RawAddress& bd_addr, uint8_t key_code, uint8_t key_state) { tAVRC_STS status = BT_STATUS_UNSUPPORTED; btif_rc_device_cb_t* p_dev = NULL; - LOG_ERROR("%s: calling btif_rc_get_device_by_bda", __func__); + log::error("calling btif_rc_get_device_by_bda"); p_dev = btif_rc_get_device_by_bda(bd_addr); CHECK_RC_CONNECTED(p_dev); rc_transaction_t* p_transaction = NULL; - LOG_VERBOSE("%s: key-code: %d, key-state: %d", __func__, key_code, key_state); + log::verbose("key-code: {}, key-state: {}", key_code, key_state); if (p_dev->rc_features & BTA_AV_FEAT_RCTG) { rc_transaction_context_t context = { .rc_addr = p_dev->rc_addr, @@ -5351,16 +5311,16 @@ static bt_status_t send_passthrough_cmd(const RawAddress& bd_addr, (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state); status = BT_STATUS_SUCCESS; start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS); - LOG_VERBOSE("%s: Send command, key-code=%d, key-state=%d, label=%d", - __func__, key_code, key_state, p_transaction->label); + log::verbose("Send command, key-code={}, key-state={}, label={}", + key_code, key_state, p_transaction->label); } else { status = BT_STATUS_FAIL; - LOG_ERROR("%s: failed to get label, key-code=%d, key-state=%d, status=%d", - __func__, key_code, key_state, tran_status); + log::error("failed to get label, key-code={}, key-state={}, status={}", + key_code, key_state, tran_status); } } else { status = BT_STATUS_FAIL; - LOG_VERBOSE("%s: feature not supported", __func__); + log::verbose("feature not supported"); } return (bt_status_t)status; } @@ -5420,7 +5380,7 @@ static const btrc_ctrl_interface_t bt_rc_ctrl_interface = { * ******************************************************************************/ const btrc_interface_t* btif_rc_get_interface(void) { - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); return &bt_rc_interface; } @@ -5434,7 +5394,7 @@ const btrc_interface_t* btif_rc_get_interface(void) { * ******************************************************************************/ const btrc_ctrl_interface_t* btif_rc_ctrl_get_interface(void) { - LOG_VERBOSE("%s: ", __func__); + log::verbose(""); return &bt_rc_ctrl_interface; } @@ -5532,13 +5492,12 @@ static bt_status_t get_transaction(btif_rc_device_cb_t* p_dev, transaction_set->transaction[i].context = context; transaction_set->transaction[i].in_use = true; *ptransaction = &(transaction_set->transaction[i]); - LOG_VERBOSE("%s: Assigned transaction=%s", __func__, - dump_transaction(*ptransaction).c_str()); + log::verbose("Assigned transaction={}", dump_transaction(*ptransaction)); return BT_STATUS_SUCCESS; } } - LOG_ERROR("%s: p_dev=%s, failed to find free transaction", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr)); + log::error("p_dev={}, failed to find free transaction", + ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr)); return BT_STATUS_NOMEM; } @@ -5556,12 +5515,12 @@ static void start_transaction_timer(btif_rc_device_cb_t* p_dev, uint8_t label, uint64_t timeout_ms) { rc_transaction_t* transaction = get_transaction_by_lbl(p_dev, label); if (transaction == nullptr) { - LOG_ERROR("%s: transaction is null", __func__); + log::error("transaction is null"); return; } if (alarm_is_scheduled(transaction->timer)) { - LOG_WARN("%s: Restarting timer that's already scheduled", __func__); + log::warn("Restarting timer that's already scheduled"); } std::stringstream ss; @@ -5582,9 +5541,9 @@ static void start_transaction_timer(btif_rc_device_cb_t* p_dev, uint8_t label, * Returns bt_status_t ******************************************************************************/ void release_transaction(btif_rc_device_cb_t* p_dev, uint8_t lbl) { - LOG_VERBOSE("%s: p_dev=%s, label=%d", __func__, - p_dev == NULL ? "null" : ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), - lbl); + log::verbose( + "p_dev={}, label={}", + p_dev == NULL ? "null" : ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), lbl); if (p_dev == nullptr) return; rc_transaction_set_t* transaction_set = &(p_dev->transaction_set); @@ -5657,17 +5616,17 @@ static void vendor_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label, rc_vendor_context_t* p_context) { if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } tAVRC_RESPONSE avrc_response = {0}; tBTA_AV_META_MSG meta_msg = {.rc_handle = p_dev->rc_handle}; - LOG_WARN("%s: timeout, addr=%s, label=%d, pdu_id=%s, event_id=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), label, - dump_rc_pdu(p_context->pdu_id), - dump_rc_notification_event_id(p_context->event_id)); + log::warn("timeout, addr={}, label={}, pdu_id={}, event_id={}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), label, + dump_rc_pdu(p_context->pdu_id), + dump_rc_notification_event_id(p_context->event_id)); switch (p_context->pdu_id) { case AVRC_PDU_REGISTER_NOTIFICATION: @@ -5724,8 +5683,7 @@ static void vendor_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, break; default: - LOG_WARN("%s: timeout for unknown pdu_id=%d", __func__, - p_context->pdu_id); + log::warn("timeout for unknown pdu_id={}", p_context->pdu_id); break; } } @@ -5742,7 +5700,7 @@ static void browse_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label, rc_browse_context_t* p_context) { if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } @@ -5757,9 +5715,9 @@ static void browse_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, .p_msg = nullptr, }; - LOG_WARN("%s: timeout, addr=%s, label=%d, pdu_id=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), label, - dump_rc_pdu(p_context->pdu_id)); + log::warn("timeout, addr={}, label={}, pdu_id={}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), label, + dump_rc_pdu(p_context->pdu_id)); switch (p_context->pdu_id) { case AVRC_PDU_GET_FOLDER_ITEMS: @@ -5779,8 +5737,7 @@ static void browse_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, handle_get_metadata_attr_response(&meta_msg, &avrc_response.get_attrs); break; default: - LOG_WARN("%s: timeout for unknown pdu_id=%d", __func__, - p_context->pdu_id); + log::warn("timeout for unknown pdu_id={}", p_context->pdu_id); break; } } @@ -5797,13 +5754,13 @@ static void passthru_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label, rc_passthru_context_t* p_context) { if (p_dev == NULL) { - LOG_ERROR("%s: p_dev NULL", __func__); + log::error("p_dev NULL"); return; } - LOG_WARN("%s: timeout, addr=%s, label=%d, rc_id=%d, key_state=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), label, p_context->rc_id, - p_context->key_state); + log::warn("timeout, addr={}, label={}, rc_id={}, key_state={}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev->rc_addr), label, p_context->rc_id, + p_context->key_state); // Other requests are wrapped in a tAVRC_RESPONSE response object, but these // passthru events are not in there. As well, the upper layers don't handle @@ -5820,17 +5777,17 @@ static void passthru_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, * Returns None * **************************************************************************/ -static void btif_rc_transaction_timeout_handler(UNUSED_ATTR uint16_t event, +static void btif_rc_transaction_timeout_handler(uint16_t /* event */, char* data) { rc_transaction_context_t* p_context = (rc_transaction_context_t*)data; if (p_context == nullptr) { - LOG_ERROR("%s: p_context is null", __func__); + log::error("p_context is null"); return; } btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(p_context->rc_addr); if (p_dev == NULL) { - LOG_ERROR("%s: p_dev is null", __func__); + log::error("p_dev is null"); return; } @@ -5847,8 +5804,7 @@ static void btif_rc_transaction_timeout_handler(UNUSED_ATTR uint16_t event, &(p_context->command.passthru)); break; default: - LOG_WARN("%s: received timeout for unknown opcode=%d", __func__, - p_context->opcode); + log::warn("received timeout for unknown opcode={}", p_context->opcode); return; } release_transaction(p_dev, label); @@ -5926,7 +5882,7 @@ static bool absolute_volume_disabled() { char volume_disabled[PROPERTY_VALUE_MAX] = {0}; osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false"); if (strncmp(volume_disabled, "true", 4) == 0) { - LOG_WARN("%s: Absolute volume disabled by property", __func__); + log::warn("Absolute volume disabled by property"); return true; } return false; diff --git a/system/btif/src/btif_sdp.cc b/system/btif/src/btif_sdp.cc index 0169a7f22c63da11c1f879bf50f421f6c93bc605..7688c3cc7661f2efb54a2a9f1f3e0652b2264a20 100644 --- a/system/btif/src/btif_sdp.cc +++ b/system/btif/src/btif_sdp.cc @@ -28,6 +28,7 @@ #define LOG_TAG "bt_btif_sdp" +#include #include #include #include @@ -40,6 +41,7 @@ #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; /***************************************************************************** * Functions implemented in sdp_server.c @@ -65,7 +67,7 @@ static btsdp_callbacks_t* bt_sdp_callbacks = NULL; static void btif_sdp_search_comp_evt(uint16_t event, char* p_param) { tBTA_SDP_SEARCH_COMP* evt_data = (tBTA_SDP_SEARCH_COMP*)p_param; - LOG_VERBOSE("%s: event = %d", __func__, event); + log::verbose("event = {}", event); if (event != BTA_SDP_SEARCH_COMP_EVT) return; @@ -116,7 +118,7 @@ static void sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, } static bt_status_t init(btsdp_callbacks_t* callbacks) { - LOG_VERBOSE("Sdp Search %s", __func__); + log::verbose("Sdp Search Init"); bt_sdp_callbacks = callbacks; sdp_server_init(); @@ -127,7 +129,7 @@ static bt_status_t init(btsdp_callbacks_t* callbacks) { } static bt_status_t deinit() { - LOG_VERBOSE("Sdp Search %s", __func__); + log::verbose("Sdp Search Deinit"); bt_sdp_callbacks = NULL; sdp_server_cleanup(); @@ -146,7 +148,7 @@ static const btsdp_interface_t sdp_if = { remove_sdp_record}; const btsdp_interface_t* btif_sdp_get_interface(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return &sdp_if; } @@ -160,7 +162,7 @@ const btsdp_interface_t* btif_sdp_get_interface(void) { * ******************************************************************************/ bt_status_t btif_sdp_execute_service(bool b_enable) { - LOG_VERBOSE("%s enable:%d", __func__, b_enable); + log::verbose("enable:{}", b_enable); if (b_enable) { BTA_SdpEnable(sdp_dm_cback); diff --git a/system/btif/src/btif_sdp_server.cc b/system/btif/src/btif_sdp_server.cc index e861aeb595e9c387ab1085b0f19b6fece305f82f..6591791d0f7e8b47c469e7634989ae4dbd6539d1 100644 --- a/system/btif/src/btif_sdp_server.cc +++ b/system/btif/src/btif_sdp_server.cc @@ -28,6 +28,7 @@ #define LOG_TAG "bt_btif_sdp_server" +#include #include #include #include @@ -40,6 +41,7 @@ #include "bta/sys/bta_sys.h" #include "btif_common.h" #include "btif_sock_sdp.h" +#include "common/init_flags.h" #include "osi/include/allocator.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" @@ -49,6 +51,7 @@ #include "utl.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; // Protects the sdp_slots array from concurrent access. static std::recursive_mutex sdp_lock; @@ -68,6 +71,11 @@ typedef struct { bluetooth_sdp_record* record_data; } sdp_slot_t; +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #define MAX_SDP_SLOTS 128 static sdp_slot_t sdp_slots[MAX_SDP_SLOTS]; @@ -108,13 +116,13 @@ static void init_sdp_slots() { } bt_status_t sdp_server_init() { - LOG_VERBOSE("Sdp Server %s", __func__); + log::verbose("Sdp Server Init"); init_sdp_slots(); return BT_STATUS_SUCCESS; } void sdp_server_cleanup() { - LOG_VERBOSE("Sdp Server %s", __func__); + log::verbose("Sdp Server Cleanup"); std::unique_lock lock(sdp_lock); int i; for (i = 0; i < MAX_SDP_SLOTS; i++) { @@ -212,7 +220,7 @@ static int alloc_sdp_slot(bluetooth_sdp_record* in_record) { } } } - LOG_ERROR("%s() failed - no more free slots!", __func__); + log::error("failed - no more free slots!"); /* Rearly the optimist is too optimistic, and cleanup is needed...*/ osi_free(record); return -1; @@ -222,7 +230,7 @@ static int free_sdp_slot(int id) { int handle = -1; bluetooth_sdp_record* record = NULL; if (id < 0 || id >= MAX_SDP_SLOTS) { - LOG_ERROR("%s() failed - id %d is invalid", __func__, id); + log::error("failed - id {} is invalid", id); return handle; } @@ -252,17 +260,16 @@ static int free_sdp_slot(int id) { */ static const sdp_slot_t* start_create_sdp(int id) { if (id >= MAX_SDP_SLOTS) { - LOG_ERROR("%s() failed - id %d is invalid", __func__, id); + log::error("failed - id {} is invalid", id); return NULL; } std::unique_lock lock(sdp_lock); if (sdp_slots[id].state != SDP_RECORD_ALLOCED) { /* The record have been removed before this event occurred - e.g. deinit */ - LOG_ERROR( - "%s() failed - state for id %d is " - "sdp_slots[id].state = %d expected %d", - __func__, id, sdp_slots[id].state, SDP_RECORD_ALLOCED); + log::error( + "failed - state for id {} is sdp_slots[id].state = {} expected {}", id, + sdp_slots[id].state, SDP_RECORD_ALLOCED); return NULL; } @@ -279,7 +286,7 @@ bt_status_t create_sdp_record(bluetooth_sdp_record* record, int handle; handle = alloc_sdp_slot(record); - LOG_VERBOSE("%s() handle = 0x%08x", __func__, handle); + log::verbose("handle = 0x{:08x}", handle); if (handle < 0) return BT_STATUS_FAIL; @@ -331,16 +338,14 @@ bt_status_t remove_sdp_record(int record_id) { /* Get the Record handle, and free the slot */ handle = free_sdp_slot(record_id); - LOG_VERBOSE("Sdp Server %s id=%d to handle=0x%08x", __func__, record_id, - handle); + log::verbose("Sdp Server id={} to handle=0x{:08x}", record_id, handle); /* Pass the actual record handle */ if (handle > 0) { BTA_SdpRemoveRecordByUser(INT_TO_PTR(handle)); return BT_STATUS_SUCCESS; } - LOG_VERBOSE("Sdp Server %s - record already removed - or never created", - __func__); + log::verbose("Sdp Server - record already removed - or never created"); return BT_STATUS_FAIL; } @@ -356,7 +361,7 @@ void on_create_record_event(int id) { * 3) Update state on completion * 4) What to do at fail? * */ - LOG_VERBOSE("Sdp Server %s", __func__); + log::verbose("Sdp Server"); const sdp_slot_t* sdp_slot = start_create_sdp(id); tBTA_SERVICE_ID service_id = -1; bluetooth_sdp_record* record; @@ -396,7 +401,7 @@ void on_create_record_event(int id) { } break; default: - LOG_VERBOSE("Record type %d is not supported", record->hdr.type); + log::verbose("Record type {} is not supported", record->hdr.type); break; } if (handle != -1) { @@ -418,14 +423,14 @@ void on_create_record_event(int id) { } void on_remove_record_event(int handle) { - LOG_VERBOSE("Sdp Server %s", __func__); + log::verbose("Sdp Server"); // User data carries the actual SDP handle, not the ID. if (handle != -1 && handle != 0) { bool result; result = get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle); if (!result) { - LOG_ERROR(" Unable to remove handle 0x%08x", handle); + log::error("Unable to remove handle 0x{:08x}", handle); } } } @@ -448,7 +453,7 @@ static int add_maps_sdp(const bluetooth_sdp_mas_record* rec) { sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("Unable to register MAPS Service"); + log::error("Unable to register MAPS Service"); return sdp_handle; } @@ -509,10 +514,10 @@ static int add_maps_sdp(const bluetooth_sdp_mas_record* rec) { if (!status) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); sdp_handle = 0; - LOG_ERROR("%s() FAILED", __func__); + log::error("FAILED"); } else { bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */ - LOG_VERBOSE("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle); } return sdp_handle; } @@ -530,7 +535,7 @@ static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec) { sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("Unable to register MAP Notification Service"); + log::error("Unable to register MAP Notification Service"); return sdp_handle; } @@ -581,10 +586,10 @@ static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec) { if (!status) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); sdp_handle = 0; - LOG_ERROR("%s() FAILED", __func__); + log::error("FAILED"); } else { bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */ - LOG_VERBOSE("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle); } return sdp_handle; } @@ -599,7 +604,7 @@ static int add_pbapc_sdp(const bluetooth_sdp_pce_record* rec) { sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("Unable to register PBAP Client Service"); + log::error("Unable to register PBAP Client Service"); return sdp_handle; } @@ -623,11 +628,11 @@ static int add_pbapc_sdp(const bluetooth_sdp_pce_record* rec) { if (!status) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); sdp_handle = 0; - LOG_ERROR("%s() FAILED", __func__); + log::error("FAILED"); return sdp_handle; } bta_sys_add_uuid(service); /* UUID_SERVCLASS_PBAP_PCE */ - LOG_VERBOSE("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle); return sdp_handle; } @@ -644,7 +649,7 @@ static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec) { sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("Unable to register PBAP Server Service"); + log::error("Unable to register PBAP Server Service"); return sdp_handle; } @@ -687,8 +692,8 @@ static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec) { status &= get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES, UINT_DESC_TYPE, (uint32_t)1, (uint8_t*)&supported_repositories_1_1); - LOG_VERBOSE(" supported_repositories_1_1: 0x%x", - supported_repositories_1_1); + log::verbose("supported_repositories_1_1: 0x{:x}", + supported_repositories_1_1); sdp_save_local_pse_record_attributes( rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.profile_version, rec->supported_features, @@ -753,10 +758,10 @@ static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec) { if (!status) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); sdp_handle = 0; - LOG_ERROR("%s() FAILED", __func__); + log::error("FAILED"); } else { bta_sys_add_uuid(service); /* UUID_SERVCLASS_MESSAGE_ACCESS */ - LOG_VERBOSE("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle); } return sdp_handle; } @@ -779,7 +784,7 @@ static int add_opps_sdp(const bluetooth_sdp_ops_record* rec) { sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("Unable to register Object Push Server Service"); + log::error("Unable to register Object Push Server Service"); return sdp_handle; } @@ -836,14 +841,14 @@ static int add_opps_sdp(const bluetooth_sdp_ops_record* rec) { if (!status) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); sdp_handle = 0; - LOG_ERROR("%s() FAILED", __func__); + log::error("FAILED"); } else { /* set class of device */ cod.service = BTM_COD_SERVICE_OBJ_TRANSFER; utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS); bta_sys_add_uuid(service); /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */ - LOG_VERBOSE("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle); } return sdp_handle; } @@ -859,7 +864,7 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec) { sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("Unable to register SAPS Service"); + log::error("Unable to register SAPS Service"); return sdp_handle; } @@ -897,10 +902,10 @@ static int add_saps_sdp(const bluetooth_sdp_sap_record* rec) { if (!status) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); sdp_handle = 0; - LOG_ERROR("%s(): FAILED deleting record", __func__); + log::error("FAILED deleting record"); } else { bta_sys_add_uuid(UUID_SERVCLASS_SAP); - LOG_VERBOSE("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle); } return sdp_handle; } @@ -915,7 +920,7 @@ static int add_mps_sdp(const bluetooth_sdp_mps_record* rec) { sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("Unable to register MPS record"); + log::error("Unable to register MPS record"); return sdp_handle; } @@ -946,10 +951,10 @@ static int add_mps_sdp(const bluetooth_sdp_mps_record* rec) { if (!status) { get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); sdp_handle = 0; - LOG_ERROR("%s() FAILED", __func__); + log::error("FAILED"); return sdp_handle; } bta_sys_add_uuid(service); /* UUID_SERVCLASS_MPS_SC */ - LOG_VERBOSE("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); + log::verbose("SDP Registered (handle 0x{:08x})", sdp_handle); return sdp_handle; } diff --git a/system/btif/src/btif_sock.cc b/system/btif/src/btif_sock.cc index c35c1ed3c2c39d44781686653081950bf629a775..a8416c359d13aeb6721617f33f8b5f82c02c2269 100644 --- a/system/btif/src/btif_sock.cc +++ b/system/btif/src/btif_sock.cc @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -29,17 +30,17 @@ #include +#include "bta/include/bta_api.h" #include "bta_sec_api.h" -#include "btif_common.h" -#include "btif_config.h" #include "btif_metrics_logging.h" #include "btif_sock_l2cap.h" #include "btif_sock_rfc.h" #include "btif_sock_sco.h" -#include "btif_sock_sdp.h" #include "btif_sock_thread.h" #include "btif_uid.h" -#include "btif_util.h" +#include "include/check.h" +#include "os/log.h" +#include "osi/include/osi.h" // INVALID_FD #include "osi/include/thread.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -48,6 +49,7 @@ bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type); bool btif_get_device_type(const RawAddress& bda, int* p_device_type); using bluetooth::Uuid; +using namespace bluetooth; static bt_status_t btsock_listen(btsock_type_t type, const char* service_name, const Uuid* uuid, int channel, int* sock_fd, @@ -105,32 +107,32 @@ bt_status_t btif_sock_init(uid_set_t* uid_set) { btsock_thread_init(); thread_handle = btsock_thread_create(btsock_signaled, NULL); if (thread_handle == -1) { - LOG_ERROR("%s unable to create btsock_thread.", __func__); + log::error("unable to create btsock_thread."); goto error; } status = btsock_rfc_init(thread_handle, uid_set); if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("%s error initializing RFCOMM sockets: %d", __func__, status); + log::error("error initializing RFCOMM sockets: {}", status); goto error; } status = btsock_l2cap_init(thread_handle, uid_set); if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("%s error initializing L2CAP sockets: %d", __func__, status); + log::error("error initializing L2CAP sockets: {}", status); goto error; } thread = thread_new("btif_sock"); if (!thread) { - LOG_ERROR("%s error creating new thread.", __func__); + log::error("error creating new thread."); btsock_rfc_cleanup(); goto error; } status = btsock_sco_init(thread); if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("%s error initializing SCO sockets: %d", __func__, status); + log::error("error initializing SCO sockets: {}", status); btsock_rfc_cleanup(); goto error; } @@ -160,8 +162,8 @@ void btif_sock_cleanup(void) { void btif_sock_connection_logger(int state, int role, const RawAddress& addr, int channel, const char* server_name) { - LOG_INFO("address=%s, state=%d, role=%d, server_name=%s, channel=%d", - ADDRESS_TO_LOGGABLE_CSTR(addr), state, role, server_name, channel); + log::info("address={}, state={}, role={}, server_name={}, channel={}", + ADDRESS_TO_LOGGABLE_CSTR(addr), state, role, server_name, channel); uint8_t index = logger_index++ % SOCK_LOGGER_SIZE_MAX; @@ -288,15 +290,13 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name, /* Set channel to zero so that it will be assigned */ channel = 0; } else if (channel <= 0) { - LOG_ERROR("%s: type BTSOCK_L2CAP_LE: invalid channel=%d", __func__, - channel); + log::error("type BTSOCK_L2CAP_LE: invalid channel={}", channel); break; } flags |= BTSOCK_FLAG_LE_COC; - LOG_INFO( - - "%s: type=BTSOCK_L2CAP_LE, channel=0x%x, original=0x%x, flags=0x%x", - __func__, channel, original_channel, flags); + log::info( + "type=BTSOCK_L2CAP_LE, channel=0x{:x}, original=0x{:x}, flags=0x{:x}", + channel, original_channel, flags); status = btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid); break; @@ -305,7 +305,7 @@ static bt_status_t btsock_listen(btsock_type_t type, const char* service_name, break; default: - LOG_ERROR("%s unknown/unsupported socket type: %d", __func__, type); + log::error("unknown/unsupported socket type: {}", type); status = BT_STATUS_UNSUPPORTED; break; } @@ -328,7 +328,7 @@ static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type, CHECK(bd_addr != NULL); CHECK(sock_fd != NULL); - LOG_INFO("%s", __func__); + log::info(""); *sock_fd = INVALID_FD; bt_status_t status = BT_STATUS_FAIL; @@ -364,8 +364,8 @@ static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type, BTA_DmAddBleDevice(*bd_addr, addr_type, device_type); } - LOG_INFO("%s: type=BTSOCK_L2CAP_LE, channel=0x%x, flags=0x%x", __func__, - channel, flags); + log::info("type=BTSOCK_L2CAP_LE, channel=0x{:x}, flags=0x{:x}", channel, + flags); status = btsock_l2cap_connect(bd_addr, channel, sock_fd, flags, app_uid); break; } @@ -375,7 +375,7 @@ static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type, break; default: - LOG_ERROR("%s unknown/unsupported socket type: %d", __func__, type); + log::error("unknown/unsupported socket type: {}", type); status = BT_STATUS_UNSUPPORTED; break; } @@ -408,8 +408,8 @@ static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) { btsock_l2cap_signaled(fd, flags, user_id); break; default: - LOG(FATAL) << "Invalid socket type! type=" << type << " fd=" << fd - << " flags=" << flags << " user_id=" << user_id; + log::fatal("Invalid socket type! type={} fd={} flags={} user_id={}", type, + fd, flags, user_id); break; } } @@ -421,8 +421,7 @@ static bt_status_t btsock_disconnect_all(const RawAddress* bd_addr) { bt_status_t l2cap_status = btsock_l2cap_disconnect(bd_addr); /* SCO is disconnected via btif_hf, so is not handled here. */ - LOG_INFO("%s: rfc status: %d, l2cap status: %d", __func__, rfc_status, - l2cap_status); + log::info("rfc status: {}, l2cap status: {}", rfc_status, l2cap_status); /* Return error status, if any. */ if (rfc_status == BT_STATUS_SUCCESS) { diff --git a/system/btif/src/btif_sock_l2cap.cc b/system/btif/src/btif_sock_l2cap.cc index 8e1150f086544cedfe152ca07f6a7bd322328499..a7583d5e42ff9215b525c7ca6afe85e216e1ac4e 100644 --- a/system/btif/src/btif_sock_l2cap.cc +++ b/system/btif/src/btif_sock_l2cap.cc @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -38,6 +39,8 @@ #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + struct packet { struct packet *next, *prev; uint32_t len; @@ -163,8 +166,8 @@ static char packet_put_head_l(l2cap_socket* sock, const void* data, static char packet_put_tail_l(l2cap_socket* sock, const void* data, uint32_t len) { if (sock->bytes_buffered >= L2CAP_MAX_RX_BUFFER) { - LOG_ERROR("Unable to add to buffer due to buffer overflow socket_id:%u", - sock->id); + log::error("Unable to add to buffer due to buffer overflow socket_id:{}", + sock->id); return false; } @@ -230,8 +233,8 @@ static void btsock_l2cap_free_l(l2cap_socket* sock) { if (sock->app_fd != -1) { close(sock->app_fd); } else { - LOG_INFO("Application has already closed l2cap socket socket_id:%u", - sock->id); + log::info("Application has already closed l2cap socket socket_id:{}", + sock->id); } while (packet_get_head_l(sock, &buf, NULL)) osi_free(buf); @@ -244,8 +247,8 @@ static void btsock_l2cap_free_l(l2cap_socket* sock) { } if ((sock->channel >= 0) && (sock->server)) { BTA_JvFreeChannel(sock->channel, BTA_JV_CONN_TYPE_L2CAP_LE); - LOG_INFO("Stopped L2CAP LE COC server socket_id:%u channel:%u", sock->id, - sock->channel); + log::info("Stopped L2CAP LE COC server socket_id:{} channel:{}", sock->id, + sock->channel); BTA_JvL2capStopServer(sock->channel, sock->id); } } else { @@ -285,7 +288,7 @@ static l2cap_socket* btsock_l2cap_alloc_l(const char* name, sock_type = SOCK_STREAM; #endif if (socketpair(AF_LOCAL, sock_type, 0, fds)) { - LOG_ERROR("socketpair failed:%s", strerror(errno)); + log::error("socketpair failed:{}", strerror(errno)); goto fail_sockpair; } @@ -328,7 +331,7 @@ static l2cap_socket* btsock_l2cap_alloc_l(const char* name, sock->id++; } last_sock_id = sock->id; - LOG_INFO("Allocated l2cap socket structure socket_id:%u", sock->id); + log::info("Allocated l2cap socket structure socket_id:{}", sock->id); return sock; fail_sockpair: @@ -352,15 +355,15 @@ bt_status_t btsock_l2cap_cleanup() { } static inline bool send_app_psm_or_chan_l(l2cap_socket* sock) { - LOG_INFO("Sending l2cap socket socket_id:%u channel:%d", sock->id, - sock->channel); + log::info("Sending l2cap socket socket_id:{} channel:{}", sock->id, + sock->channel); return sock_send_all(sock->our_fd, (const uint8_t*)&sock->channel, sizeof(sock->channel)) == sizeof(sock->channel); } static bool send_app_err_code(l2cap_socket* sock, tBTA_JV_L2CAP_REASON code) { - LOG_INFO("Sending l2cap failure reason socket_id:%u reason code:%d", sock->id, - code); + log::info("Sending l2cap failure reason socket_id:{} reason code:{}", + sock->id, code); int err_channel = 0; if (sock_send_all(sock->our_fd, (const uint8_t*)&err_channel, sizeof(err_channel)) != sizeof(err_channel)) { @@ -388,7 +391,7 @@ static bool send_app_connect_signal(int fd, const RawAddress* addr, int channel, return true; } - LOG_ERROR("Unable to send data to socket fd:%d send_fd:%d", fd, send_fd); + log::error("Unable to send data to socket fd:{} send_fd:{}", fd, send_fd); return false; } @@ -399,12 +402,12 @@ static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START* p_start, std::unique_lock lock(state_lock); sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_ERROR("Unable to find l2cap socket with socket_id:%u", id); + log::error("Unable to find l2cap socket with socket_id:{}", id); return; } if (p_start->status != BTA_JV_SUCCESS) { - LOG_ERROR("Unable to start l2cap server socket_id:%u", sock->id); + log::error("Unable to start l2cap server socket_id:{}", sock->id); btsock_l2cap_free_l(sock); return; } @@ -427,7 +430,7 @@ static void on_srv_l2cap_listen_started(tBTA_JV_L2CAP_START* p_start, if (!sock->server_psm_sent) { if (!send_app_psm_or_chan_l(sock)) { // closed - LOG_INFO("Unable to send socket to application socket_id:%u", sock->id); + log::info("Unable to send socket to application socket_id:{}", sock->id); btsock_l2cap_free_l(sock); } else { sock->server_psm_sent = true; @@ -441,12 +444,12 @@ static void on_cl_l2cap_init(tBTA_JV_L2CAP_CL_INIT* p_init, uint32_t id) { std::unique_lock lock(state_lock); sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_ERROR("Unable to find l2cap socket with socket_id:%u", id); + log::error("Unable to find l2cap socket with socket_id:{}", id); return; } if (p_init->status != BTA_JV_SUCCESS) { - LOG_ERROR("Initialization status failed socket_id:%u", id); + log::error("Initialization status failed socket_id:{}", id); btsock_l2cap_free_l(sock); return; } @@ -512,15 +515,15 @@ static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open, sock->tx_mtu = p_open->tx_mtu; if (!send_app_psm_or_chan_l(sock)) { - LOG_ERROR("Unable to send l2cap socket to application socket_id:%u", - sock->id); + log::error("Unable to send l2cap socket to application socket_id:{}", + sock->id); return; } if (!send_app_connect_signal(sock->our_fd, &sock->addr, sock->channel, 0, -1, sock->rx_mtu, p_open->tx_mtu)) { - LOG_ERROR("Unable to connect l2cap socket to application socket_id:%u", - sock->id); + log::error("Unable to connect l2cap socket to application socket_id:{}", + sock->id); return; } @@ -539,7 +542,7 @@ static void on_cl_l2cap_psm_connect_l(tBTA_JV_L2CAP_OPEN* p_open, // start monitoring the socketpair to get call back when app writing data btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id); - LOG_INFO("Connected l2cap socket socket_id:%u", sock->id); + log::info("Connected l2cap socket socket_id:{}", sock->id); sock->connected = true; } @@ -551,7 +554,7 @@ static void on_l2cap_connect(tBTA_JV* p_data, uint32_t id) { std::unique_lock lock(state_lock); sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_ERROR("Unable to find l2cap socket with socket_id:%u", id); + log::error("Unable to find l2cap socket with socket_id:{}", id); return; } @@ -563,8 +566,8 @@ static void on_l2cap_connect(tBTA_JV* p_data, uint32_t id) { on_srv_l2cap_psm_connect_l(psm_open, sock); } } else { - LOG_ERROR("Unable to open socket after receiving connection socket_id:%u", - sock->id); + log::error("Unable to open socket after receiving connection socket_id:{}", + sock->id); btsock_l2cap_free_l(sock); } } @@ -575,8 +578,8 @@ static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) { std::unique_lock lock(state_lock); sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_INFO( - "Unable to find probably already closed l2cap socket with socket_id:%u", + log::info( + "Unable to find probably already closed l2cap socket with socket_id:{}", id); return; } @@ -594,8 +597,8 @@ static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) { : android::bluetooth::SOCKET_ROLE_CONNECTION); if (!send_app_err_code(sock, p_close->reason)) { - LOG_ERROR("Unable to send l2cap socket to application socket_id:%u", - sock->id); + log::error("Unable to send l2cap socket to application socket_id:{}", + sock->id); } // TODO: This does not seem to be called... // I'm not sure if this will be called for non-server sockets? @@ -611,15 +614,15 @@ static void on_l2cap_outgoing_congest(tBTA_JV_L2CAP_CONG* p, uint32_t id) { std::unique_lock lock(state_lock); sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_ERROR("Unable to find l2cap socket with socket_id:%u", id); + log::error("Unable to find l2cap socket with socket_id:{}", id); return; } sock->outgoing_congest = p->cong ? 1 : 0; if (!sock->outgoing_congest) { - LOG_VERBOSE("Monitoring l2cap socket for outgoing data socket_id:%u", - sock->id); + log::verbose("Monitoring l2cap socket for outgoing data socket_id:{}", + sock->id); btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id); } @@ -629,7 +632,7 @@ static void on_l2cap_write_done(uint16_t len, uint32_t id) { std::unique_lock lock(state_lock); l2cap_socket* sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_ERROR("Unable to find l2cap socket with socket_id:%u", id); + log::error("Unable to find l2cap socket with socket_id:{}", id); return; } @@ -638,7 +641,7 @@ static void on_l2cap_write_done(uint16_t len, uint32_t id) { btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_RD, sock->id); } else { - LOG_INFO("Socket congestion on socket_id:%u", sock->id); + log::info("Socket congestion on socket_id:{}", sock->id); } sock->tx_bytes += len; @@ -654,7 +657,7 @@ static void on_l2cap_data_ind(tBTA_JV* evt, uint32_t id) { std::unique_lock lock(state_lock); sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_ERROR("Unable to find l2cap socket with socket_id:%u", id); + log::error("Unable to find l2cap socket with socket_id:{}", id); return; } @@ -671,8 +674,9 @@ static void on_l2cap_data_ind(tBTA_JV* evt, uint32_t id) { btsock_thread_add_fd(pth, sock->our_fd, BTSOCK_L2CAP, SOCK_THREAD_FD_WR, sock->id); } else { // connection must be dropped - LOG_WARN("Closing socket as unable to push data to socket socket_id:%u", - sock->id); + log::warn( + "Closing socket as unable to push data to socket socket_id:{}", + sock->id); BTA_JvL2capClose(sock->handle); btsock_l2cap_free_l(sock); return; @@ -721,8 +725,8 @@ static void btsock_l2cap_cbk(tBTA_JV_EVT event, tBTA_JV* p_data, break; default: - LOG_ERROR("Unhandled event:%hu l2cap_socket_id:%u", event, - l2cap_socket_id); + log::error("Unhandled event:{} l2cap_socket_id:{}", event, + l2cap_socket_id); break; } } @@ -743,7 +747,7 @@ void on_l2cap_psm_assigned(int id, int psm) { std::unique_lock lock(state_lock); l2cap_socket* sock = btsock_l2cap_find_by_id_l(id); if (!sock) { - LOG_ERROR("Unable to find l2cap socket with socket_id:%u", id); + log::error("Unable to find l2cap socket with socket_id:{}", id); return; } @@ -785,7 +789,7 @@ static bt_status_t btsock_l2cap_listen_or_connect(const char* name, bool is_le_coc = (flags & BTSOCK_FLAG_LE_COC) != 0; if (!sock_fd) { - LOG_INFO("Invalid socket descriptor"); + log::info("Invalid socket descriptor"); return BT_STATUS_PARM_INVALID; } @@ -925,7 +929,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) { if (count > sock->tx_mtu) { /* This can't happen thanks to check in BluetoothSocket.java but leave * this in case this socket is ever used anywhere else*/ - LOG(ERROR) << "recv more than MTU. Data will be lost: " << count; + log::error("recv more than MTU. Data will be lost: {}", count); count = sock->tx_mtu; } diff --git a/system/btif/src/btif_sock_rfc.cc b/system/btif/src/btif_sock_rfc.cc index 90cade264bb6a0264559e8ed7048d6f6341f3847..78cc1feedc0f817e8e2478103895ded88b3864fc 100644 --- a/system/btif/src/btif_sock_rfc.cc +++ b/system/btif/src/btif_sock_rfc.cc @@ -18,6 +18,7 @@ #define LOG_TAG "bt_btif_sock_rfcomm" +#include #include #include #include @@ -26,32 +27,28 @@ #include #include -#include "bt_target.h" // Must be first to define build configuration #include "bta/include/bta_jv_api.h" #include "bta/include/bta_rfcomm_scn.h" #include "btif/include/btif_metrics_logging.h" -/* The JV interface can have only one user, hence we need to call a few - * L2CAP functions from this file. */ #include "btif/include/btif_sock.h" #include "btif/include/btif_sock_l2cap.h" #include "btif/include/btif_sock_sdp.h" #include "btif/include/btif_sock_thread.h" #include "btif/include/btif_sock_util.h" -#include "btif/include/btif_uid.h" +#include "include/check.h" #include "include/hardware/bt_sock.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "osi/include/list.h" -#include "osi/include/log.h" #include "osi/include/osi.h" // INVALID_FD #include "stack/include/bt_hdr.h" -#include "stack/include/btm_api.h" -#include "stack/include/btm_api_types.h" #include "stack/include/port_api.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; // Maximum number of RFCOMM channels (1-30 inclusive). #define MAX_RFC_CHANNEL 30 @@ -79,8 +76,8 @@ typedef struct { Uuid service_uuid; char service_name[256]; int fd; - int app_fd; // Temporary storage for the half of the socketpair that's sent - // back to upper layers. + int app_fd; // Temporary storage for the half of the socketpair that's + // sent back to upper layers. int app_uid; // UID of the app for which this socket was created. int mtu; uint8_t* packet; @@ -143,6 +140,8 @@ void btsock_rfc_cleanup(void) { } uid_set = NULL; + + log::debug("cleanup finished"); } static rfc_slot_t* find_free_slot(void) { @@ -175,7 +174,10 @@ static rfc_slot_t* find_rfc_slot_by_pending_sdp(void) { static bool is_requesting_sdp(void) { for (size_t i = 0; i < ARRAY_SIZE(rfc_slots); ++i) - if (rfc_slots[i].id && rfc_slots[i].f.doing_sdp_request) return true; + if (rfc_slots[i].id && rfc_slots[i].f.doing_sdp_request) { + log::info("slot id {} is doing sdp request", rfc_slots[i].id); + return true; + } return false; } @@ -194,13 +196,13 @@ static rfc_slot_t* alloc_rfc_slot(const RawAddress* addr, const char* name, rfc_slot_t* slot = find_free_slot(); if (!slot) { - LOG_ERROR("%s unable to find free RFCOMM slot.", __func__); + log::error("unable to find free RFCOMM slot."); return NULL; } int fds[2] = {INVALID_FD, INVALID_FD}; if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) == -1) { - LOG_ERROR("%s error creating socketpair: %s", __func__, strerror(errno)); + log::error("error creating socketpair: {}", strerror(errno)); return NULL; } @@ -241,7 +243,7 @@ static rfc_slot_t* create_srv_accept_rfc_slot(rfc_slot_t* srv_rs, rfc_slot_t* accept_rs = alloc_rfc_slot( addr, srv_rs->service_name, srv_rs->service_uuid, srv_rs->scn, 0, false); if (!accept_rs) { - LOG_ERROR("%s unable to allocate RFCOMM slot.", __func__); + log::error("unable to allocate RFCOMM slot."); return NULL; } @@ -275,7 +277,7 @@ bt_status_t btsock_rfc_control_req(uint8_t dlci, const RawAddress& bd_addr, RFCOMM_ControlReqFromBTSOCK(dlci, bd_addr, modem_signal, break_signal, discard_buffers, break_signal_seq, fc); if (status != PORT_SUCCESS) { - LOG_WARN("failed to send control parameters, status=%d", status); + log::warn("failed to send control parameters, status={}", status); return BT_STATUS_FAIL; } return BT_STATUS_SUCCESS; @@ -293,9 +295,12 @@ bt_status_t btsock_rfc_listen(const char* service_name, // TODO(sharvil): not sure that this check makes sense; seems like a logic // error to call - // functions on RFCOMM sockets before initializing the module. Probably should - // be an assert. - if (!is_init_done()) return BT_STATUS_NOT_READY; + // functions on RFCOMM sockets before initializing the module. Probably + // should be an assert. + if (!is_init_done()) { + log::error("BT not ready"); + return BT_STATUS_NOT_READY; + } if ((flags & BTSOCK_FLAG_NO_SDP) == 0) { if (!service_uuid || service_uuid->IsEmpty()) { @@ -315,11 +320,11 @@ bt_status_t btsock_rfc_listen(const char* service_name, rfc_slot_t* slot = alloc_rfc_slot(NULL, service_name, *service_uuid, channel, flags, true); if (!slot) { - LOG_ERROR("unable to allocate RFCOMM slot"); + log::error("unable to allocate RFCOMM slot"); return BT_STATUS_FAIL; } - LOG_INFO("Adding listening socket service_name: %s - channel: %d", - service_name, channel); + log::info("Adding listening socket service_name: {} - channel: {}", + service_name, channel); BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, slot->id, channel); *sock_fd = slot->app_fd; // Transfer ownership of fd to caller. /*TODO: @@ -350,14 +355,18 @@ bt_status_t btsock_rfc_connect(const RawAddress* bd_addr, // error to call // functions on RFCOMM sockets before initializing the module. Probably should // be an assert. - if (!is_init_done()) return BT_STATUS_NOT_READY; + if (!is_init_done()) { + log::error("BT not ready"); + return BT_STATUS_NOT_READY; + } std::unique_lock lock(slot_lock); rfc_slot_t* slot = alloc_rfc_slot(bd_addr, NULL, *service_uuid, channel, flags, false); if (!slot) { - LOG_ERROR("%s unable to allocate RFCOMM slot.", __func__); + log::error("unable to allocate RFCOMM slot. bd_addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(*bd_addr)); return BT_STATUS_FAIL; } @@ -366,17 +375,22 @@ bt_status_t btsock_rfc_connect(const RawAddress* bd_addr, BTA_JvRfcommConnect(slot->security, slot->role, slot->scn, slot->addr, rfcomm_cback, slot->id); if (ret != BTA_JV_SUCCESS) { - LOG_ERROR("%s unable to initiate RFCOMM connection: %d", __func__, ret); + log::error( + "unable to initiate RFCOMM connection. status:{}, scn:{}, bd_addr:{}", + ret, slot->scn, ADDRESS_TO_LOGGABLE_CSTR(slot->addr)); cleanup_rfc_slot(slot); return BT_STATUS_FAIL; } if (!send_app_scn(slot)) { - LOG_ERROR("%s unable to send channel number.", __func__); + log::error("send_app_scn() failed, closing slot->id:{}", slot->id); cleanup_rfc_slot(slot); return BT_STATUS_FAIL; } } else { + log::info("service_uuid:{}, bd_addr:{}, slot_id:{}", + service_uuid->ToString(), ADDRESS_TO_LOGGABLE_CSTR(*bd_addr), + slot->id); if (!is_requesting_sdp()) { BTA_JvStartDiscovery(*bd_addr, 1, service_uuid, slot->id); slot->f.pending_sdp_request = false; @@ -464,9 +478,11 @@ static void cleanup_rfc_slot(rfc_slot_t* slot) { static bool send_app_scn(rfc_slot_t* slot) { if (slot->scn_notified) { - // already send, just return success. + // already sent, just return success. return true; } + log::debug("Sending scn for slot {}. bd_addr:{}", slot->id, + ADDRESS_TO_LOGGABLE_CSTR(slot->addr)); slot->scn_notified = true; return sock_send_all(slot->fd, (const uint8_t*)&slot->scn, sizeof(slot->scn)) == sizeof(slot->scn); @@ -492,11 +508,11 @@ static void on_cl_rfc_init(tBTA_JV_RFCOMM_CL_INIT* p_init, uint32_t id) { std::unique_lock lock(slot_lock); rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found. p_init->status=%u", id, - p_init->status); + log::error("RFCOMM slot with id {} not found. p_init->status={}", id, + p_init->status); } else if (p_init->status != BTA_JV_SUCCESS) { - LOG_WARN("INIT unsuccessful, status %u. Cleaning up slot with id %u", - p_init->status, slot->id); + log::warn("INIT unsuccessful, status {}. Cleaning up slot with id {}", + p_init->status, slot->id); cleanup_rfc_slot(slot); } else { slot->rfc_handle = p_init->handle; @@ -508,11 +524,11 @@ static void on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START* p_start, std::unique_lock lock(slot_lock); rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found", id); + log::error("RFCOMM slot with id {} not found", id); return; } else if (p_start->status != BTA_JV_SUCCESS) { - LOG_WARN("START unsuccessful, status %u. Cleaning up slot with id %u", - p_start->status, slot->id); + log::warn("START unsuccessful, status {}. Cleaning up slot with id {}", + p_start->status, slot->id); cleanup_rfc_slot(slot); return; } @@ -533,11 +549,12 @@ static void on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START* p_start, static uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN* p_open, uint32_t id) { + log::verbose("id:{}", id); std::unique_lock lock(slot_lock); rfc_slot_t* accept_rs; rfc_slot_t* srv_rs = find_rfc_slot_by_id(id); if (!srv_rs) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return 0; } @@ -569,16 +586,17 @@ static uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN* p_open, } static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN* p_open, uint32_t id) { + log::verbose("id:{}", id); std::unique_lock lock(slot_lock); rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return; } if (p_open->status != BTA_JV_SUCCESS) { - LOG_WARN("CONNECT unsuccessful, status %u. Cleaning up slot with id %u", - p_open->status, slot->id); + log::warn("CONNECT unsuccessful, status {}. Cleaning up slot with id {}", + p_open->status, slot->id); cleanup_rfc_slot(slot); return; } @@ -600,19 +618,19 @@ static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN* p_open, uint32_t id) { if (send_app_connect_signal(slot->fd, &slot->addr, slot->scn, 0, -1)) { slot->f.connected = true; } else { - LOG_ERROR("%s unable to send connect completion signal to caller.", - __func__); + log::error("unable to send connect completion signal to caller."); } } static void on_rfc_close(UNUSED_ATTR tBTA_JV_RFCOMM_CLOSE* p_close, uint32_t id) { + log::verbose("id:{}", id); std::unique_lock lock(slot_lock); // rfc_handle already closed when receiving rfcomm close event from stack. rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_WARN("RFCOMM slot with id %u not found.", id); + log::warn("RFCOMM slot with id {} not found.", id); return; } log_socket_connection_state( @@ -626,8 +644,7 @@ static void on_rfc_close(UNUSED_ATTR tBTA_JV_RFCOMM_CLOSE* p_close, static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE* p, uint32_t id) { if (p->status != BTA_JV_SUCCESS) { - LOG_ERROR("%s error writing to RFCOMM socket with slot %u.", __func__, - p->req_id); + log::error("error writing to RFCOMM socket with slot {}.", p->req_id); return; } @@ -636,7 +653,7 @@ static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE* p, uint32_t id) { rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return; } app_uid = slot->app_uid; @@ -652,7 +669,7 @@ static void on_rfc_outgoing_congest(tBTA_JV_RFCOMM_CONG* p, uint32_t id) { rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return; } @@ -666,6 +683,13 @@ static uint32_t rfcomm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t rfcomm_slot_id) { uint32_t id = 0; + // Write events are too frequent to log at info level + if (event != BTA_JV_RFCOMM_WRITE_EVT) { + log::info("handling event:{} id:{}", event, rfcomm_slot_id); + } else { + log::verbose("handling event:{} id:{}", event, rfcomm_slot_id); + } + switch (event) { case BTA_JV_RFCOMM_START_EVT: on_srv_rfc_listen_started(&p_data->rfc_start, rfcomm_slot_id); @@ -688,7 +712,8 @@ static uint32_t rfcomm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, break; case BTA_JV_RFCOMM_CLOSE_EVT: - LOG_VERBOSE("BTA_JV_RFCOMM_CLOSE_EVT: rfcomm_slot_id:%d", rfcomm_slot_id); + log::verbose("BTA_JV_RFCOMM_CLOSE_EVT: rfcomm_slot_id:{}", + rfcomm_slot_id); on_rfc_close(&p_data->rfc_close, rfcomm_slot_id); break; @@ -705,26 +730,26 @@ static uint32_t rfcomm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, break; default: - LOG_ERROR("%s unhandled event %d, slot id: %u", __func__, event, - rfcomm_slot_id); + log::error("unhandled event {}, slot id: {}", event, rfcomm_slot_id); break; } return id; } static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) { + log::info("handling event:{}, id:{}", event, id); switch (event) { case BTA_JV_GET_SCN_EVT: { std::unique_lock lock(slot_lock); rfc_slot_t* rs = find_rfc_slot_by_id(id); if (!rs) { - LOG_ERROR("RFCOMM slot with id %u not found. event:%d", id, event); + log::error("RFCOMM slot with id {} not found. event:{}", id, event); break; } if (p_data->scn == 0) { - LOG_ERROR( - "Unable to allocate scn: all resources exhausted. slot found: %p", - rs); + log::error( + "Unable to allocate scn: all resources exhausted. slot found: {}", + fmt::ptr(rs)); cleanup_rfc_slot(rs); break; } @@ -732,7 +757,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) { rs->scn = p_data->scn; // Send channel ID to java layer if (!send_app_scn(rs)) { - LOG_DEBUG("send_app_scn() failed, closing rs->id:%d", rs->id); + log::warn("send_app_scn() failed, closing rs->id:{}", rs->id); cleanup_rfc_slot(rs); break; } @@ -746,7 +771,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) { // thread needed for the java layer to get a RFCOMM channel. // create_sdp_record() will be called from Java when it has received the // RFCOMM and L2CAP channel numbers through the sockets. - LOG_DEBUG( + log::debug( "Since UUID is not valid; not setting SDP-record and just starting " "the RFCOMM server"); // now start the rfcomm server after sdp & channel # assigned @@ -757,7 +782,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) { } case BTA_JV_GET_PSM_EVT: { - LOG_VERBOSE("Received PSM: 0x%04x", p_data->psm); + log::verbose("Received PSM: 0x{:04x}", p_data->psm); on_l2cap_psm_assigned(id, p_data->psm); break; } @@ -767,12 +792,12 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) { rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found. event:%d", id, event); + log::error("RFCOMM slot with id {} not found. event:{}", id, event); break; } if (!create_server_sdp_record(slot)) { - LOG_ERROR("cannot start server, slot found: %p", slot); + log::error("cannot start server, slot found: {}", fmt::ptr(slot)); cleanup_rfc_slot(slot); break; } @@ -798,7 +823,7 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) { } default: - LOG_DEBUG("unhandled event:%d, slot id:%d", event, id); + log::debug("unhandled event:{}, slot id:{}", event, id); break; } } @@ -806,23 +831,23 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV* p_data, uint32_t id) { static void handle_discovery_comp(tBTA_JV_STATUS status, int scn, uint32_t id) { rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR( - "RFCOMM slot with id %u not found. event: BTA_JV_DISCOVERY_COMP_EVT", + log::error( + "RFCOMM slot with id {} not found. event: BTA_JV_DISCOVERY_COMP_EVT", id); return; } if (!slot->f.doing_sdp_request) { - LOG_ERROR( - "SDP response returned but RFCOMM slot %d did not request SDP record.", + log::error( + "SDP response returned but RFCOMM slot {} did not request SDP record.", id); return; } if (status != BTA_JV_SUCCESS || !scn) { - LOG_ERROR( - "SDP service discovery completed for slot id: %u with the result " - "status: %u, scn: %d", + log::error( + "SDP service discovery completed for slot id: {} with the result " + "status: {}, scn: {}", id, status, scn); cleanup_rfc_slot(slot); return; @@ -830,9 +855,9 @@ static void handle_discovery_comp(tBTA_JV_STATUS status, int scn, uint32_t id) { if (BTA_JvRfcommConnect(slot->security, slot->role, scn, slot->addr, rfcomm_cback, slot->id) != BTA_JV_SUCCESS) { - LOG_WARN( + log::warn( "BTA_JvRfcommConnect() returned BTA_JV_FAILURE for RFCOMM slot with " - "id: %u", + "id: {}", id); cleanup_rfc_slot(slot); return; @@ -842,6 +867,7 @@ static void handle_discovery_comp(tBTA_JV_STATUS status, int scn, uint32_t id) { slot->f.doing_sdp_request = false; if (!send_app_scn(slot)) { + log::warn("send_app_scn() failed, closing slot->id {}", slot->id); cleanup_rfc_slot(slot); return; } @@ -863,8 +889,7 @@ static sent_status_t send_data_to_app(int fd, BT_HDR* p_buf) { if (sent == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) return SENT_NONE; - LOG_ERROR("%s error writing RFCOMM data back to app: %s", __func__, - strerror(errno)); + log::error("error writing RFCOMM data back to app: {}", strerror(errno)); return SENT_FAILED; } @@ -900,8 +925,8 @@ static bool flush_incoming_que_on_wr_signal(rfc_slot_t* slot) { // app is ready to receive data, tell stack to start the data flow // fix me: need a jv flow control api to serialize the call in stack - LOG_VERBOSE( - "enable data flow, rfc_handle:0x%x, rfc_port_handle:0x%x, user_id:%d", + log::verbose( + "enable data flow, rfc_handle:0x{:x}, rfc_port_handle:0x{:x}, user_id:{}", slot->rfc_handle, slot->rfc_port_handle, slot->id); PORT_FlowControl_MaxCredit(slot->rfc_port_handle, true); return true; @@ -912,7 +937,7 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t id) { std::unique_lock lock(slot_lock); rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return; } @@ -926,10 +951,9 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t id) { BTA_JvRfcommWrite(slot->rfc_handle, slot->id); } } else { - LOG_ERROR( - "%s socket signaled for read while disconnected, slot: %d, " - "channel: %d", - __func__, slot->id, slot->scn); + log::error( + "socket signaled for read while disconnected, slot: {}, channel: {}", + slot->id, slot->scn); need_close = true; } } @@ -937,10 +961,10 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t id) { if (flags & SOCK_THREAD_FD_WR) { // App is ready to receive more data, tell stack to enable data flow. if (!slot->f.connected || !flush_incoming_que_on_wr_signal(slot)) { - LOG_ERROR( - "%s socket signaled for write while disconnected (or write " - "failure), slot: %d, channel: %d", - __func__, slot->id, slot->scn); + log::error( + "socket signaled for write while disconnected (or write failure), " + "slot: {}, channel: {}", + slot->id, slot->scn); need_close = true; } } @@ -960,7 +984,7 @@ int bta_co_rfc_data_incoming(uint32_t id, BT_HDR* p_buf) { std::unique_lock lock(slot_lock); rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return 0; } @@ -1001,13 +1025,13 @@ int bta_co_rfc_data_outgoing_size(uint32_t id, int* size) { std::unique_lock lock(slot_lock); rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return false; } if (ioctl(slot->fd, FIONREAD, size) != 0) { - LOG_ERROR("%s unable to determine bytes remaining to be read on fd %d: %s", - __func__, slot->fd, strerror(errno)); + log::error("unable to determine bytes remaining to be read on fd {}: {}", + slot->fd, strerror(errno)); cleanup_rfc_slot(slot); return false; } @@ -1019,7 +1043,7 @@ int bta_co_rfc_data_outgoing(uint32_t id, uint8_t* buf, uint16_t size) { std::unique_lock lock(slot_lock); rfc_slot_t* slot = find_rfc_slot_by_id(id); if (!slot) { - LOG_ERROR("RFCOMM slot with id %u not found.", id); + log::error("RFCOMM slot with id {} not found.", id); return false; } @@ -1027,8 +1051,7 @@ int bta_co_rfc_data_outgoing(uint32_t id, uint8_t* buf, uint16_t size) { OSI_NO_INTR(received = recv(slot->fd, buf, size, 0)); if (received != size) { - LOG_ERROR("%s error receiving RFCOMM data from app: %s", __func__, - strerror(errno)); + log::error("error receiving RFCOMM data from app: {}", strerror(errno)); cleanup_rfc_slot(slot); return false; } @@ -1038,7 +1061,10 @@ int bta_co_rfc_data_outgoing(uint32_t id, uint8_t* buf, uint16_t size) { bt_status_t btsock_rfc_disconnect(const RawAddress* bd_addr) { CHECK(bd_addr != NULL); - if (!is_init_done()) return BT_STATUS_NOT_READY; + if (!is_init_done()) { + log::error("BT not ready"); + return BT_STATUS_NOT_READY; + } std::unique_lock lock(slot_lock); for (size_t i = 0; i < ARRAY_SIZE(rfc_slots); ++i) { diff --git a/system/btif/src/btif_sock_sco.cc b/system/btif/src/btif_sock_sco.cc index 9cdd5fcce0bbf899008bacf6ecbc64e6b3caf858..66fee0349fe6f4301ef78f519d471de717f0f1bd 100644 --- a/system/btif/src/btif_sock_sco.cc +++ b/system/btif/src/btif_sock_sco.cc @@ -18,6 +18,7 @@ #define LOG_TAG "bt_btif_sock_sco" +#include #include #include #include @@ -25,11 +26,12 @@ #include #include +#include "include/check.h" #include "include/hardware/bt_sock.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/list.h" -#include "osi/include/log.h" -#include "osi/include/osi.h" // UNUSED_ATTR +#include "osi/include/osi.h" // INVALID_FD #include "osi/include/socket.h" #include "osi/include/thread.h" #include "stack/include/btm_api.h" @@ -53,6 +55,8 @@ // socket_read_ready_cb() - local host closed SCO socket // disconnect_completed_cb() - connection terminated +using namespace bluetooth; + typedef struct { uint16_t sco_handle; socket_t* socket; @@ -97,7 +101,7 @@ bt_status_t btsock_sco_cleanup(void) { return BT_STATUS_SUCCESS; } -bt_status_t btsock_sco_listen(int* sock_fd, UNUSED_ATTR int flags) { +bt_status_t btsock_sco_listen(int* sock_fd, int /* flags */) { CHECK(sock_fd != NULL); std::unique_lock lock(sco_lock); @@ -112,7 +116,7 @@ bt_status_t btsock_sco_listen(int* sock_fd, UNUSED_ATTR int flags) { } bt_status_t btsock_sco_connect(const RawAddress* bd_addr, int* sock_fd, - UNUSED_ATTR int flags) { + int /* flags */) { CHECK(bd_addr != NULL); CHECK(sock_fd != NULL); @@ -133,14 +137,13 @@ static sco_socket_t* sco_socket_establish_locked(bool is_listening, tBTM_STATUS status; enh_esco_params_t params; if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pair) == -1) { - LOG_ERROR("%s unable to allocate socket pair: %s", __func__, - strerror(errno)); + log::error("unable to allocate socket pair: {}", strerror(errno)); goto error; } sco_socket = sco_socket_new(); if (!sco_socket) { - LOG_ERROR("%s unable to allocate new SCO socket.", __func__); + log::error("unable to allocate new SCO socket."); goto error; } @@ -149,14 +152,13 @@ static sco_socket_t* sco_socket_establish_locked(bool is_listening, &sco_socket->sco_handle, connect_completed_cb, disconnect_completed_cb); if (status != BTM_CMD_STARTED) { - LOG_ERROR("%s unable to create SCO socket: %d", __func__, status); + log::error("unable to create SCO socket: {}", status); goto error; } socket = socket_new_from_fd(pair[1]); if (!socket) { - LOG_ERROR("%s unable to allocate socket from file descriptor %d.", __func__, - pair[1]); + log::error("unable to allocate socket from file descriptor {}.", pair[1]); goto error; } @@ -221,22 +223,19 @@ static void connection_request_cb(tBTM_ESCO_EVT event, sco_socket_t* new_sco_socket; if (!sco_socket) { - LOG_ERROR("%s unable to find sco_socket for handle: %hu", __func__, - conn_data->sco_inx); + log::error("unable to find sco_socket for handle: {}", conn_data->sco_inx); goto error; } if (sco_socket != listen_sco_socket) { - LOG_ERROR( - - "%s received connection request on non-listening socket handle: %hu", - __func__, conn_data->sco_inx); + log::error("received connection request on non-listening socket handle: {}", + conn_data->sco_inx); goto error; } new_sco_socket = sco_socket_establish_locked(true, NULL, &client_fd); if (!new_sco_socket) { - LOG_ERROR("%s unable to allocate new sco_socket.", __func__); + log::error("unable to allocate new sco_socket."); goto error; } @@ -254,8 +253,7 @@ static void connection_request_cb(tBTM_ESCO_EVT event, if (socket_write_and_transfer_fd(sco_socket->socket, &connect_signal, sizeof(connect_signal), client_fd) != sizeof(connect_signal)) { - LOG_ERROR("%s unable to send new file descriptor to listening socket.", - __func__); + log::error("unable to send new file descriptor to listening socket."); goto error; } @@ -274,8 +272,7 @@ static void connect_completed_cb(uint16_t sco_handle) { sco_socket_t* sco_socket = sco_socket_find_locked(sco_handle); if (!sco_socket) { - LOG_ERROR("%s SCO socket not found on connect for handle: %hu", __func__, - sco_handle); + log::error("SCO socket not found on connect for handle: {}", sco_handle); return; } @@ -296,15 +293,14 @@ static void disconnect_completed_cb(uint16_t sco_handle) { sco_socket_t* sco_socket = sco_socket_find_locked(sco_handle); if (!sco_socket) { - LOG_ERROR("%s SCO socket not found on disconnect for handle: %hu", __func__, - sco_handle); + log::error("SCO socket not found on disconnect for handle: {}", sco_handle); return; } list_remove(sco_sockets, sco_socket); } -static void socket_read_ready_cb(UNUSED_ATTR socket_t* socket, void* context) { +static void socket_read_ready_cb(socket_t* /* socket */, void* context) { std::unique_lock lock(sco_lock); sco_socket_t* sco_socket = (sco_socket_t*)context; diff --git a/system/btif/src/btif_sock_sdp.cc b/system/btif/src/btif_sock_sdp.cc index b550bf30598b13f88e45faabd00bcd92bb595a97..5c53bdf2119f1da2cedba1b295c95041e3317128 100644 --- a/system/btif/src/btif_sock_sdp.cc +++ b/system/btif/src/btif_sock_sdp.cc @@ -20,6 +20,8 @@ #include "btif/include/btif_sock_sdp.h" +#include + #include "bta/include/bta_jv_api.h" #include "bta/include/bta_op_api.h" #include "bta/include/utl.h" @@ -33,6 +35,7 @@ #include "types/bluetooth/uuid.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; using bluetooth::Uuid; @@ -90,8 +93,8 @@ static const tBTA_OP_FMT bta_ops_obj_fmt[OBEX_PUSH_NUM_FORMATS] = { // Returns true if successful, otherwise false. static bool create_base_record(const uint32_t sdp_handle, const char* name, const uint16_t channel, const bool with_obex) { - LOG_VERBOSE("create_base_record: scn: %d, name: %s, with_obex: %d", channel, - name, with_obex); + log::verbose("create_base_record: scn: {}, name: {}, with_obex: {}", channel, + name, with_obex); // Setup the protocol list and add it. tSDP_PROTOCOL_ELEM proto_list[SDP_MAX_LIST_ELEMS]; @@ -132,16 +135,16 @@ static bool create_base_record(const uint32_t sdp_handle, const char* name, sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &list)) goto error; - LOG_VERBOSE( - "create_base_record: successfully created base service " - "record, handle: 0x%08x, scn: %d, name: %s, with_obex: %d", + log::verbose( + "create_base_record: successfully created base service record, handle: " + "0x{:08x}, scn: {}, name: {}, with_obex: {}", sdp_handle, channel, name, with_obex); return true; error: - LOG_ERROR( - "create_base_record: failed to create base service " - "record, stage: %s, scn: %d, name: %s, with_obex: %d", + log::error( + "create_base_record: failed to create base service record, stage: {}, " + "scn: {}, name: {}, with_obex: {}", stage, channel, name, with_obex); return false; } @@ -151,13 +154,13 @@ error: // class sequence. static int add_sdp_by_uuid(const char* name, const Uuid& uuid, const uint16_t channel) { - LOG_VERBOSE("%s: uuid: %s, scn: %d, service_name: %s", __func__, - uuid.ToString().c_str(), channel, name); + log::verbose("uuid: {}, scn: {}, service_name: {}", uuid.ToString(), channel, + name); uint32_t handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (handle == 0) { - LOG_ERROR("%s: failed to create sdp record, scn: %d, service_name: %s", - __func__, channel, name); + log::error("failed to create sdp record, scn: {}, service_name: {}", + channel, name); return 0; } @@ -188,9 +191,9 @@ static int add_sdp_by_uuid(const char* name, const Uuid& uuid, &type_buf_ptr)) goto error; - LOG_VERBOSE( - "%s: service registered successfully, service_name: %s, handle: 0x%08x", - __func__, name, handle); + log::verbose( + "service registered successfully, service_name: {}, handle: 0x{:08x}", + name, handle); { // Write the custom 128-bit UUID to EIR @@ -202,22 +205,20 @@ static int add_sdp_by_uuid(const char* name, const Uuid& uuid, error: get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle); - LOG_ERROR("%s: failed to register service stage: %s, service_name: %s", - __func__, stage, name); + log::error("failed to register service stage: {}, service_name: {}", stage, + name); return 0; } // Registers a service with the given |name| and |channel| in the SDP // database as a PBAP protocol. static int add_pbap_sdp(const char* name, const int channel) { - LOG_VERBOSE("add_pbap_sdp: scn %d, service_name %s", channel, name); + log::verbose("add_pbap_sdp: scn {}, service_name {}", channel, name); uint32_t handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (handle == 0) { - LOG_ERROR( - "add_pbap_sdp: failed to create sdp record, " - "service_name: %s", - name); + log::error("add_pbap_sdp: failed to create sdp record, service_name: {}", + name); return 0; } @@ -249,32 +250,30 @@ static int add_pbap_sdp(const char* name, const int channel) { // Notify the system that we've got a new service class UUID. bta_sys_add_uuid(UUID_SERVCLASS_PBAP_PSE); - LOG_VERBOSE( - "add_pbap_sdp: service registered successfully, " - "service_name: %s, handle: 0x%08x", + log::verbose( + "add_pbap_sdp: service registered successfully, service_name: {}, " + "handle: 0x{:08x}", name, handle); return handle; error: get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle); - LOG_ERROR( - "add_pbap_sdp: failed to register PBAP service, stage: %s, " - "service_name: %s", + log::error( + "add_pbap_sdp: failed to register PBAP service, stage: {}, service_name: " + "{}", stage, name); return 0; } // Registers a service with the given |name| and |channel| as an OBEX Push // protocol. static int add_ops_sdp(const char* name, const int channel) { - LOG_VERBOSE("add_ops_sdp: scn %d, service_name %s", channel, name); + log::verbose("add_ops_sdp: scn {}, service_name {}", channel, name); uint32_t handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (handle == 0) { - LOG_ERROR( - "add_ops_sdp: failed to create sdp record, " - "service_name: %s", - name); + log::error("add_ops_sdp: failed to create sdp record, service_name: {}", + name); return 0; } @@ -325,18 +324,18 @@ static int add_ops_sdp(const char* name, const int channel) { // Notify the system that we've got a new service class UUID. bta_sys_add_uuid(UUID_SERVCLASS_OBEX_OBJECT_PUSH); - LOG_VERBOSE( - "ad_maps_sdp: service registered successfully, " - "service_name: %s, handle 0x%08x)", + log::verbose( + "ad_maps_sdp: service registered successfully, service_name: {}, handle " + "0x{:08x})", name, handle); return handle; error: get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle); - LOG_ERROR( - "add_ops_sdp: failed to register OPS service, " - "stage: %s, service_name: %s", + log::error( + "add_ops_sdp: failed to register OPS service, stage: {}, service_name: " + "{}", stage, name); return 0; } @@ -344,14 +343,12 @@ error: // Registers a service with the given |name| and |channel| as a serial port // profile protocol. static int add_spp_sdp(const char* name, const int channel) { - LOG_VERBOSE("add_spp_sdp: scn %d, service_name %s", channel, name); + log::verbose("add_spp_sdp: scn {}, service_name {}", channel, name); int handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (handle == 0) { - LOG_ERROR( - "add_spp_sdp: failed to create sdp record, " - "service_name: %s", - name); + log::error("add_spp_sdp: failed to create sdp record, service_name: {}", + name); return 0; } @@ -372,18 +369,18 @@ static int add_spp_sdp(const char* name, const int channel) { handle, UUID_SERVCLASS_SERIAL_PORT, SPP_PROFILE_VERSION)) goto error; - LOG_VERBOSE( - "add_spp_sdp: service registered successfully, " - "service_name: %s, handle 0x%08x)", + log::verbose( + "add_spp_sdp: service registered successfully, service_name: {}, handle " + "0x{:08x})", name, handle); return handle; error: get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(handle); - LOG_ERROR( - "add_spp_sdp: failed to register SPP service, " - "stage: %s, service_name: %s", + log::error( + "add_spp_sdp: failed to register SPP service, stage: {}, service_name: " + "{}", stage, name); return 0; } @@ -394,8 +391,8 @@ error: // number if the |uuid| matches one of the preregistered bluez SDP records. static int add_rfc_sdp_by_uuid(const char* name, const Uuid& uuid, const int channel) { - LOG_VERBOSE("%s: uuid: %s, service_name: %s, channel: %d", __func__, - uuid.ToString().c_str(), name, channel); + log::verbose("uuid: {}, service_name: {}, channel: {}", uuid.ToString(), name, + channel); /* * Bluetooth Socket API relies on having preregistered bluez sdp records for @@ -479,7 +476,7 @@ int add_rfc_sdp_rec(const char* name, Uuid uuid, const int channel) { // Deletes an SDP record with the given |handle|. void del_rfc_sdp_rec(int handle) { - LOG_VERBOSE("del_rfc_sdp_rec: handle:0x%x", handle); + log::verbose("del_rfc_sdp_rec: handle:0x{:x}", handle); if ((handle != -1) && (handle != 0)) { // Remove the custom 128-bit UUID from EIR diff --git a/system/btif/src/btif_sock_thread.cc b/system/btif/src/btif_sock_thread.cc index 7dbdf79cb9f07b0ff49abb297f5a82c02f805622..c3cefcbd74d1063b34993167eee0fec643c64b76 100644 --- a/system/btif/src/btif_sock_thread.cc +++ b/system/btif/src/btif_sock_thread.cc @@ -29,6 +29,7 @@ #include "btif_sock_thread.h" #include +#include #include #include #include @@ -50,11 +51,9 @@ #include "os/log.h" #include "osi/include/osi.h" // OSI_NO_INTR -#define asrt(s) \ - do { \ - if (!(s)) \ - LOG_ERROR("## %s assert %s failed at line:%d ##", __func__, #s, \ - __LINE__); \ +#define asrt(s) \ + do { \ + if (!(s)) log::error("## assert {} failed ##", #s); \ } while (0) #define MAX_THREAD 8 @@ -70,6 +69,8 @@ #define CMD_REMOVE_FD 4 #define CMD_USER_PRIVATE 5 +using namespace bluetooth; + struct poll_slot_t { struct pollfd pfd; uint32_t user_id; @@ -108,7 +109,7 @@ static inline int create_thread(void* (*start_routine)(void*), void* arg, ret = pthread_create(thread_id, &thread_attr, start_routine, arg); if (ret != 0) { - LOG_ERROR("pthread_create : %s", strerror(errno)); + log::error("pthread_create : {}", strerror(errno)); return ret; } /* We need to lower the priority of this thread to ensure the stack gets @@ -132,7 +133,7 @@ static int alloc_thread_slot() { return i; } } - LOG_ERROR("execeeded max thread count"); + log::error("execeeded max thread count"); return -1; } static void free_thread_slot(int h) { @@ -140,7 +141,7 @@ static void free_thread_slot(int h) { close_cmd_fd(h); ts[h].used = 0; } else - LOG_ERROR("invalid thread handle:%d", h); + log::error("invalid thread handle:{}", h); } void btsock_thread_init() { static int initialized; @@ -166,7 +167,7 @@ int btsock_thread_create(btsock_signaled_cb callback, pthread_t thread; int status = create_thread(sock_poll_thread, (void*)(uintptr_t)h, &thread); if (status) { - LOG_ERROR("create_thread failed: %s", strerror(status)); + log::error("create_thread failed: {}", strerror(status)); free_thread_slot(h); return -1; } @@ -182,7 +183,7 @@ int btsock_thread_create(btsock_signaled_cb callback, static inline void init_cmd_fd(int h) { asrt(ts[h].cmd_fdr == -1 && ts[h].cmd_fdw == -1); if (socketpair(AF_UNIX, SOCK_STREAM, 0, &ts[h].cmd_fdr) < 0) { - LOG_ERROR("socketpair failed: %s", strerror(errno)); + log::error("socketpair failed: {}", strerror(errno)); return; } // add the cmd fd for read & write @@ -207,11 +208,11 @@ typedef struct { } sock_cmd_t; int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) { if (h < 0 || h >= MAX_THREAD) { - LOG_ERROR("invalid bt thread handle:%d", h); + log::error("invalid bt thread handle:{}", h); return false; } if (ts[h].cmd_fdw == -1) { - LOG_ERROR("cmd socket is not created. socket thread may not initialized"); + log::error("cmd socket is not created. socket thread may not initialized"); return false; } if (flags & SOCK_THREAD_ADD_FD_SYNC) { @@ -222,7 +223,7 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) { add_poll(h, fd, type, flags, user_id); return true; } - LOG_WARN( + log::warn( "THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async"); } sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id}; @@ -235,11 +236,11 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) { bool btsock_thread_remove_fd_and_close(int thread_handle, int fd) { if (thread_handle < 0 || thread_handle >= MAX_THREAD) { - LOG_ERROR("%s invalid thread handle: %d", __func__, thread_handle); + log::error("invalid thread handle: {}", thread_handle); return false; } if (fd == -1) { - LOG_ERROR("%s invalid file descriptor.", __func__); + log::error("invalid file descriptor."); return false; } @@ -254,11 +255,11 @@ bool btsock_thread_remove_fd_and_close(int thread_handle, int fd) { int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id) { if (h < 0 || h >= MAX_THREAD) { - LOG_ERROR("invalid bt thread handle:%d", h); + log::error("invalid bt thread handle:{}", h); return false; } if (ts[h].cmd_fdw == -1) { - LOG_ERROR("cmd socket is not created. socket thread may not initialized"); + log::error("cmd socket is not created. socket thread may not initialized"); return false; } sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id}; @@ -271,8 +272,8 @@ int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, *cmd_send = cmd; memcpy(cmd_send + 1, data, size); } else { - LOG_ERROR("alloca failed at h:%d, cmd type:%d, size:%d", h, type, - size_send); + log::error("alloca failed at h:{}, cmd type:{}, size:{}", h, type, + size_send); return false; } } @@ -284,11 +285,11 @@ int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, } int btsock_thread_wakeup(int h) { if (h < 0 || h >= MAX_THREAD) { - LOG_ERROR("invalid bt thread handle:%d", h); + log::error("invalid bt thread handle:{}", h); return false; } if (ts[h].cmd_fdw == -1) { - LOG_ERROR("thread handle:%d, cmd socket is not created", h); + log::error("thread handle:{}, cmd socket is not created", h); return false; } sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0}; @@ -300,11 +301,11 @@ int btsock_thread_wakeup(int h) { } int btsock_thread_exit(int h) { if (h < 0 || h >= MAX_THREAD) { - LOG_ERROR("invalid bt thread slot:%d", h); + log::error("invalid bt thread slot:{}", h); return false; } if (ts[h].cmd_fdw == -1) { - LOG_ERROR("cmd socket is not created"); + log::error("cmd socket is not created"); return false; } sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0}; @@ -347,8 +348,8 @@ static inline void set_poll(poll_slot_t* ps, int fd, int type, int flags, ps->pfd.fd = fd; ps->user_id = user_id; if (ps->type != 0 && ps->type != type) - LOG_ERROR("poll socket type should not changed! type was:%d, type now:%d", - ps->type, type); + log::error("poll socket type should not changed! type was:{}, type now:{}", + ps->type, type); ps->type = type; ps->flags = flags; ps->pfd.events = flags2pevents(flags); @@ -376,7 +377,7 @@ static inline void add_poll(int h, int fd, int type, int flags, ++ts[h].poll_count; return; } - LOG_ERROR("exceeded max poll slot:%d!", MAX_POLL); + log::error("exceeded max poll slot:{}!", MAX_POLL); } static inline void remove_poll(int h, poll_slot_t* ps, int flags) { if (flags == ps->flags) { @@ -399,7 +400,7 @@ static int process_cmd_sock(int h) { OSI_NO_INTR(ret = recv(fd, &cmd, sizeof(cmd), MSG_WAITALL)); if (ret != sizeof(cmd)) { - LOG_ERROR("recv cmd errno:%d", errno); + log::error("recv cmd errno:{}", errno); return false; } switch (cmd.id) { @@ -426,7 +427,7 @@ static int process_cmd_sock(int h) { case CMD_EXIT: return false; default: - LOG_WARN("unknown cmd: %d", cmd.id); + log::warn("unknown cmd: {}", cmd.id); break; } return true; @@ -440,7 +441,7 @@ static void process_data_sock(int h, struct pollfd* pfds, int pfds_count, 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"); + log::info("Socket has been removed from poll set"); continue; } asrt(pfds[i].fd == ts[h].ps[ps_i].pfd.fd); @@ -472,9 +473,9 @@ static void prepare_poll_fds(int h, struct pollfd* pfds) { asrt(ts[h].poll_count <= MAX_POLL); while (count < ts[h].poll_count) { if (ps_i >= MAX_POLL) { - LOG_ERROR( - "exceed max poll range, ps_i:%d, MAX_POLL:%d, count:%d, " - "ts[h].poll_count:%d", + log::error( + "exceed max poll range, ps_i:{}, MAX_POLL:{}, count:{}, " + "ts[h].poll_count:{}", ps_i, MAX_POLL, count, ts[h].poll_count); return; } @@ -497,8 +498,8 @@ static void* sock_poll_thread(void* arg) { int ret; OSI_NO_INTR(ret = poll(pfds.data(), ts[h].poll_count, -1)); if (ret == -1) { - LOG_ERROR("poll ret -1, exit the thread, errno:%d, err:%s", errno, - strerror(errno)); + log::error("poll ret -1, exit the thread, errno:{}, err:{}", errno, + strerror(errno)); break; } if (ret != 0) { @@ -508,7 +509,7 @@ static void* sock_poll_thread(void* arg) { { asrt(pfds[0].fd == ts[h].cmd_fdr); if (!process_cmd_sock(h)) { - LOG_INFO("h:%d, process_cmd_sock return false, exit...", h); + log::info("h:{}, process_cmd_sock return false, exit...", h); break; } if (ret == 1) @@ -519,9 +520,9 @@ static void* sock_poll_thread(void* arg) { if (need_process_data_fd) process_data_sock(h, pfds.data(), pfds_count, ret); } else { - LOG_INFO("no data, select ret: %d", ret); + log::info("no data, select ret: {}", ret); }; } - LOG_INFO("socket poll thread exiting, h:%d", h); + log::info("socket poll thread exiting, h:{}", h); return 0; } diff --git a/system/btif/src/btif_sock_util.cc b/system/btif/src/btif_sock_util.cc index 72f7bbb9724afa40c94d34b4d68f7e8f5cb59138..536f824d9e04cc5e8b63580e110098aa95e6f28a 100644 --- a/system/btif/src/btif_sock_util.cc +++ b/system/btif/src/btif_sock_util.cc @@ -21,6 +21,7 @@ #include "btif_sock_util.h" #include +#include #include #include #include @@ -37,13 +38,13 @@ #include "os/log.h" #include "osi/include/osi.h" -#define asrt(s) \ - do { \ - if (!(s)) \ - LOG_ERROR("## %s assert %s failed at line:%d ##", __func__, #s, \ - __LINE__); \ +#define asrt(s) \ + do { \ + if (!(s)) log::error("## assert {} failed ##", #s); \ } while (0) +using namespace bluetooth; + int sock_send_all(int sock_fd, const uint8_t* buf, int len) { int s = len; @@ -51,7 +52,7 @@ int sock_send_all(int sock_fd, const uint8_t* buf, int len) { ssize_t ret; OSI_NO_INTR(ret = send(sock_fd, buf, s, 0)); if (ret <= 0) { - LOG_ERROR("sock fd:%d send errno:%d, ret:%zd", sock_fd, errno, ret); + log::error("sock fd:{} send errno:{}, ret:{}", sock_fd, errno, ret); return -1; } buf += ret; @@ -66,7 +67,7 @@ int sock_recv_all(int sock_fd, uint8_t* buf, int len) { ssize_t ret; OSI_NO_INTR(ret = recv(sock_fd, buf, r, MSG_WAITALL)); if (ret <= 0) { - LOG_ERROR("sock fd:%d recv errno:%d, ret:%zd", sock_fd, errno, ret); + log::error("sock fd:{} recv errno:{}, ret:{}", sock_fd, errno, ret); return -1; } buf += ret; @@ -109,8 +110,8 @@ int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd) { ssize_t ret; OSI_NO_INTR(ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL)); if (ret < 0) { - LOG_ERROR("fd:%d, send_fd:%d, sendmsg ret:%d, errno:%d, %s", sock_fd, - send_fd, (int)ret, errno, strerror(errno)); + log::error("fd:{}, send_fd:{}, sendmsg ret:{}, errno:{}, {}", sock_fd, + send_fd, (int)ret, errno, strerror(errno)); ret_len = -1; break; } @@ -121,7 +122,7 @@ int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd) { // Wipes out any msg_control too memset(&msg, 0, sizeof(msg)); } - LOG_VERBOSE("close fd:%d after sent", send_fd); + log::verbose("close fd:{} after sent", send_fd); // TODO: This seems wrong - if the FD is not opened in JAVA before this is // called // we get a "socket closed" exception in java, when reading from the diff --git a/system/btif/src/btif_storage.cc b/system/btif/src/btif_storage.cc index 50a90814b6f7ba6e7c9cf5b7cb34a35506742308..ab6c1cab7d67cbb76f7b034d00703c6888c90db2 100644 --- a/system/btif/src/btif_storage.cc +++ b/system/btif/src/btif_storage.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -41,69 +42,33 @@ #include #include -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "btif_api.h" #include "btif_config.h" #include "btif_storage.h" #include "btif_util.h" +#include "common/init_flags.h" #include "core_callbacks.h" #include "device/include/controller.h" #include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "stack/include/bt_octets.h" #include "stack/include/bt_uuid16.h" +#include "storage/config_keys.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +/* This is a local property to add a device found */ +#define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF + using base::Bind; using bluetooth::Uuid; +using namespace bluetooth; /******************************************************************************* * Constants & Macros ******************************************************************************/ -// TODO(armansito): Find a better way than using a hardcoded path. -#define BTIF_STORAGE_PATH_BLUEDROID "/data/misc/bluedroid" - -#define BTIF_STORAGE_SECTION_ADAPTER "Adapter" - -#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_IR "LE_LOCAL_KEY_IR" -#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK "LE_LOCAL_KEY_IRK" -#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_DHK "LE_LOCAL_KEY_DHK" -#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_ER "LE_LOCAL_KEY_ER" - -#define BTIF_STORAGE_KEY_TIMESTAMP "Timestamp" -#define BTIF_STORAGE_KEY_DEV_CLASS "DevClass" -#define BTIF_STORAGE_KEY_DEV_TYPE "DevType" -#define BTIF_STORAGE_KEY_NAME "Name" -#define BTIF_STORAGE_KEY_APPEARANCE "Appearance" -#define BTIF_STORAGE_KEY_ADDR_TYPE "AddrType" -#define BTIF_STORAGE_KEY_ALIASE "Aliase" -#define BTIF_STORAGE_KEY_SCANMODE "ScanMode" -#define BTIF_STORAGE_KEY_LOCAL_IO_CAPS "LocalIOCaps" -#define BTIF_STORAGE_KEY_DISC_TIMEOUT "DiscoveryTimeout" -#define BTIF_STORAGE_KEY_GATT_CLIENT_SUPPORTED "GattClientSupportedFeatures" -#define BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH "GattClientDatabaseHash" -#define BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED "GattServerSupportedFeatures" -#define BTIF_STORAGE_KEY_LINK_KEY "LinkKey" -#define BTIF_STORAGE_KEY_LINK_KEY_TYPE "LinkKeyType" -#define BTIF_STORAGE_KEY_PIN_LENGTH "PinLength" -#define BTIF_STORAGE_KEY_LE_KEY_PENC "LE_KEY_PENC" -#define BTIF_STORAGE_KEY_LE_KEY_PID "LE_KEY_PID" -#define BTIF_STORAGE_KEY_LE_KEY_PCSRK "LE_KEY_PCSRK" -#define BTIF_STORAGE_KEY_LE_KEY_LENC "LE_KEY_LENC" -#define BTIF_STORAGE_KEY_LE_KEY_LCSRK "LE_KEY_LCSRK" -#define BTIF_STORAGE_KEY_LE_KEY_LID "LE_KEY_LID" -#define BTIF_STORAGE_KEY_VENDOR_ID_SOURCE "VendorIdSource" -#define BTIF_STORAGE_KEY_VENDOR_ID "VendorId" -#define BTIF_STORAGE_KEY_PRODUCT_ID "ProductId" -#define BTIF_STORAGE_KEY_VERSION "ProductVersion" -#define BTIF_STORAGE_KEY_RESTRICTED "Restricted" -#define BTIF_STORAGE_KEY_ADDR_TYPE "AddrType" - -/* This is a local property to add a device found */ -#define BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP 0xFF - struct BtifStorageKey { uint8_t type; const std::string& name; @@ -149,8 +114,8 @@ static bool btif_has_ble_keys(const std::string& bdstr); static void btif_storage_set_mode(RawAddress* remote_bd_addr) { std::string bdstr = remote_bd_addr->ToString(); if (GetInterfaceToProfiles()->config->isRestrictedMode()) { - LOG_INFO("%s will be removed exiting restricted mode", - ADDRESS_TO_LOGGABLE_CSTR(*remote_bd_addr)); + log::info("{} will be removed exiting restricted mode", + ADDRESS_TO_LOGGABLE_CSTR(*remote_bd_addr)); btif_config_set_int(bdstr, BTIF_STORAGE_KEY_RESTRICTED, 1); } } @@ -163,9 +128,9 @@ static bool prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) { char value[1024]; if (prop->len <= 0 || prop->len > (int)sizeof(value) - 1) { - LOG_WARN( - "Unable to save property to configuration file type:%d, " - " len:%d is invalid", + log::warn( + "Unable to save property to configuration file type:{}, len:{} is " + "invalid", prop->type, prop->len); return false; } @@ -190,7 +155,7 @@ static bool prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) { case BT_PROPERTY_REMOTE_FRIENDLY_NAME: strncpy(value, (char*)prop->val, prop->len); value[prop->len] = '\0'; - btif_config_set_str(bdstr, BTIF_STORAGE_KEY_ALIASE, value); + btif_config_set_str(bdstr, BTIF_STORAGE_KEY_ALIAS, value); break; case BT_PROPERTY_ADAPTER_SCAN_MODE: btif_config_set_int(BTIF_STORAGE_SECTION_ADAPTER, @@ -216,7 +181,7 @@ static bool prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) { for (size_t i = 0; i < cnt; i++) { val += (reinterpret_cast(prop->val) + i)->ToString() + " "; } - btif_config_set_str(bdstr, BTIF_STORAGE_PATH_REMOTE_SERVICE, val); + btif_config_set_str(bdstr, BTIF_STORAGE_KEY_REMOTE_SERVICE, val); break; } case BT_PROPERTY_REMOTE_VERSION_INFO: { @@ -224,10 +189,11 @@ static bool prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) { if (!info) return false; - btif_config_set_int(bdstr, BT_CONFIG_KEY_REMOTE_VER_MFCT, + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_REMOTE_VER_MFCT, info->manufacturer); - btif_config_set_int(bdstr, BT_CONFIG_KEY_REMOTE_VER_VER, info->version); - btif_config_set_int(bdstr, BT_CONFIG_KEY_REMOTE_VER_SUBVER, + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_REMOTE_VER_VER, + info->version); + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_REMOTE_VER_SUBVER, info->sub_ver); } break; case BT_PROPERTY_APPEARANCE: { @@ -247,10 +213,18 @@ static bool prop2cfg(const RawAddress* remote_bd_addr, bt_property_t* prop) { case BT_PROPERTY_REMOTE_MODEL_NUM: { strncpy(value, (char*)prop->val, prop->len); value[prop->len] = '\0'; - btif_config_set_str(bdstr, BT_CONFIG_KEY_DIS_MODEL_NUM, value); + btif_config_set_str(bdstr, BTIF_STORAGE_KEY_DIS_MODEL_NUM, value); } break; + case BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED: + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_SECURE_CONNECTIONS_SUPPORTED, + *(uint8_t*)prop->val); + break; + case BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE: + btif_config_set_int(bdstr, BTIF_STORAGE_KEY_MAX_SESSION_KEY_SIZE, + *(uint8_t*)prop->val); + break; default: - LOG_ERROR("Unknown prop type:%d", prop->type); + log::error("Unknown prop type:{}", prop->type); return false; } @@ -263,8 +237,8 @@ static bool cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { bdstr = remote_bd_addr->ToString(); } if (prop->len <= 0) { - LOG_WARN("Invalid property read from configuration file type:%d, len:%d", - prop->type, prop->len); + log::warn("Invalid property read from configuration file type:{}, len:{}", + prop->type, prop->len); return false; } bool ret = false; @@ -293,8 +267,8 @@ static bool cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { } case BT_PROPERTY_REMOTE_FRIENDLY_NAME: { int len = prop->len; - ret = btif_config_get_str(bdstr, BTIF_STORAGE_KEY_ALIASE, - (char*)prop->val, &len); + ret = btif_config_get_str(bdstr, BTIF_STORAGE_KEY_ALIAS, (char*)prop->val, + &len); if (ret && len && len <= prop->len) prop->len = len - 1; else { @@ -334,7 +308,7 @@ static bool cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { case BT_PROPERTY_UUIDS: { char value[1280]; int size = sizeof(value); - if (btif_config_get_str(bdstr, BTIF_STORAGE_PATH_REMOTE_SERVICE, value, + if (btif_config_get_str(bdstr, BTIF_STORAGE_KEY_REMOTE_SERVICE, value, &size)) { Uuid* p_uuid = reinterpret_cast(prop->val); size_t num_uuids = @@ -351,15 +325,15 @@ static bool cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { bt_remote_version_t* info = (bt_remote_version_t*)prop->val; if (prop->len >= (int)sizeof(bt_remote_version_t)) { - ret = btif_config_get_int(bdstr, BT_CONFIG_KEY_REMOTE_VER_MFCT, + ret = btif_config_get_int(bdstr, BTIF_STORAGE_KEY_REMOTE_VER_MFCT, &info->manufacturer); if (ret) - ret = btif_config_get_int(bdstr, BT_CONFIG_KEY_REMOTE_VER_VER, + ret = btif_config_get_int(bdstr, BTIF_STORAGE_KEY_REMOTE_VER_VER, &info->version); if (ret) - ret = btif_config_get_int(bdstr, BT_CONFIG_KEY_REMOTE_VER_SUBVER, + ret = btif_config_get_int(bdstr, BTIF_STORAGE_KEY_REMOTE_VER_SUBVER, &info->sub_ver); } } break; @@ -399,7 +373,7 @@ static bool cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { case BT_PROPERTY_REMOTE_MODEL_NUM: { int len = prop->len; - ret = btif_config_get_str(bdstr, BT_CONFIG_KEY_DIS_MODEL_NUM, + ret = btif_config_get_str(bdstr, BTIF_STORAGE_KEY_DIS_MODEL_NUM, (char*)prop->val, &len); if (ret && len && len <= prop->len) prop->len = len - 1; @@ -418,8 +392,28 @@ static bool cfg2prop(const RawAddress* remote_bd_addr, bt_property_t* prop) { } } break; + case BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED: { + int val; + + if (prop->len >= (int)sizeof(uint8_t)) { + ret = btif_config_get_int( + bdstr, BTIF_STORAGE_KEY_SECURE_CONNECTIONS_SUPPORTED, &val); + *(uint8_t*)prop->val = (uint8_t)val; + } + } break; + + case BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE: { + int val; + + if (prop->len >= (int)sizeof(uint8_t)) { + ret = btif_config_get_int(bdstr, BTIF_STORAGE_KEY_MAX_SESSION_KEY_SIZE, + &val); + *(uint8_t*)prop->val = (uint8_t)val; + } + } break; + default: - LOG_ERROR("Unknown prop type:%d", prop->type); + log::error("Unknown prop type:{}", prop->type); return false; } return ret; @@ -478,7 +472,7 @@ static bt_status_t btif_in_fetch_bonded_devices( for (const auto& bd_addr : btif_config_get_paired_devices()) { auto name = bd_addr.ToString(); - LOG_VERBOSE("Remote device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Remote device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); LinkKey link_key; size_t size = sizeof(link_key); if (btif_config_get_bin(name, BTIF_STORAGE_KEY_LINK_KEY, link_key.data(), @@ -491,7 +485,7 @@ static bt_status_t btif_in_fetch_bonded_devices( int cod; int pin_length = 0; if (btif_config_get_int(name, BTIF_STORAGE_KEY_DEV_CLASS, &cod)) - uint2devclass((uint32_t)cod, dev_class); + dev_class = uint2devclass((uint32_t)cod); btif_config_get_int(name, BTIF_STORAGE_KEY_PIN_LENGTH, &pin_length); BTA_DmAddDevice(bd_addr, dev_class, link_key, (uint8_t)linkkey_type, pin_length); @@ -506,7 +500,7 @@ static bt_status_t btif_in_fetch_bonded_devices( if (p_bonded_devices->num_devices < BTM_SEC_MAX_DEVICE_RECORDS) { p_bonded_devices->devices[p_bonded_devices->num_devices++] = bd_addr; } else { - LOG_WARN("Exceed the max number of bonded devices"); + log::warn("Exceed the max number of bonded devices"); } } else { bt_linkkey_file_found = false; @@ -514,8 +508,8 @@ static bt_status_t btif_in_fetch_bonded_devices( } if (!btif_in_fetch_bonded_ble_device(name, add, p_bonded_devices) && !bt_linkkey_file_found) { - LOG_VERBOSE("No link key or ble key found for device:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("No link key or ble key found for device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } return BT_STATUS_SUCCESS; @@ -539,8 +533,8 @@ static void btif_read_le_key(const uint8_t key_type, const size_t key_len, *device_added = true; } - LOG_VERBOSE("Adding key type %d for %s", key_type, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Adding key type {} for {}", key_type, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); BTA_DmAddBleKey(bd_addr, &key, key_type); } @@ -655,11 +649,11 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t* property) { /* Fetch the local BD ADDR */ const controller_t* controller = controller_get_interface(); if (!controller->get_is_ready()) { - LOG_ERROR("Controller not ready! Unable to return Bluetooth Address"); + log::error("Controller not ready! Unable to return Bluetooth Address"); *bd_addr = RawAddress::kEmpty; return BT_STATUS_FAIL; } else { - LOG_INFO("Controller ready!"); + log::info("Controller ready!"); *bd_addr = *controller->get_address(); } property->len = RawAddress::kLength; @@ -669,8 +663,8 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t* property) { btif_in_fetch_bonded_devices(&bonded_devices, 0); - LOG_VERBOSE( - "BT_PROPERTY_ADAPTER_BONDED_DEVICES: Number of bonded devices=%d", + log::verbose( + "BT_PROPERTY_ADAPTER_BONDED_DEVICES: Number of bonded devices={}", bonded_devices.num_devices); property->len = bonded_devices.num_devices * RawAddress::kLength; @@ -685,7 +679,7 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t* property) { uint32_t i; tBTA_SERVICE_MASK service_mask = btif_get_enabled_services_mask(); - LOG_INFO("Service_mask=0x%x", service_mask); + log::info("Service_mask=0x{:x}", service_mask); for (i = 0; i < BTA_MAX_SERVICE_ID; i++) { /* This should eventually become a function when more services are enabled */ @@ -893,8 +887,8 @@ bt_status_t btif_storage_add_bonded_device(RawAddress* remote_bd_addr, bt_status_t btif_storage_remove_bonded_device( const RawAddress* remote_bd_addr) { std::string bdstr = remote_bd_addr->ToString(); - LOG_INFO("Removing bonded device addr=%s", - ADDRESS_TO_LOGGABLE_CSTR(*remote_bd_addr)); + log::info("Removing bonded device addr={}", + ADDRESS_TO_LOGGABLE_CSTR(*remote_bd_addr)); btif_config_remove_device(bdstr); @@ -902,7 +896,7 @@ bt_status_t btif_storage_remove_bonded_device( auto paired_devices = btif_config_get_paired_devices(); if (paired_devices.empty() && bluetooth::common::init_flags::irk_rotation_is_enabled()) { - LOG_INFO("Last paired device removed, resetting IRK"); + log::info("Last paired device removed, resetting IRK"); BTA_DmBleResetId(); } return BT_STATUS_SUCCESS; @@ -933,8 +927,8 @@ static void remove_devices_with_sample_ltk() { } for (RawAddress address : bad_ltk) { - LOG_ERROR("Removing bond to device using test TLK: %s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::error("Removing bond to device using test TLK: {}", + ADDRESS_TO_LOGGABLE_CSTR(address)); btif_storage_remove_bonded_device(&address); } @@ -968,13 +962,13 @@ void btif_storage_load_le_devices(void) { bonded_devices.devices[i], BTM_LE_KEY_PID, (uint8_t*)&key, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) { if (bonded_devices.devices[i] != key.pid_key.identity_addr) { - LOG_INFO("Found device with a known identity address %s %s", - ADDRESS_TO_LOGGABLE_CSTR(bonded_devices.devices[i]), - ADDRESS_TO_LOGGABLE_CSTR(key.pid_key.identity_addr)); + log::info("Found device with a known identity address {} {}", + ADDRESS_TO_LOGGABLE_CSTR(bonded_devices.devices[i]), + ADDRESS_TO_LOGGABLE_CSTR(key.pid_key.identity_addr)); if (bonded_devices.devices[i].IsEmpty() || key.pid_key.identity_addr.IsEmpty()) { - LOG_WARN("Address is empty! Skip"); + log::warn("Address is empty! Skip"); } else { consolidated_devices.emplace_back(bonded_devices.devices[i], key.pid_key.identity_addr); @@ -1101,7 +1095,7 @@ bt_status_t btif_storage_load_bonded_devices(void) { osi_free(devices_list); } - LOG_VERBOSE("Number of bonded devices found=%d", bonded_devices.num_devices); + log::verbose("Number of bonded devices found={}", bonded_devices.num_devices); { for (i = 0; i < bonded_devices.num_devices; i++) { @@ -1210,7 +1204,7 @@ bt_status_t btif_storage_add_ble_bonding_key(RawAddress* remote_bd_addr, } } - LOG_WARN("Unknown LE key type: %d", key_type); + log::warn("Unknown LE key type: {}", key_type); return BT_STATUS_FAIL; } @@ -1238,7 +1232,7 @@ bt_status_t btif_storage_get_ble_bonding_key(const RawAddress& remote_bd_addr, } } - LOG_WARN("Unknown LE key type: %d", key_type); + log::warn("Unknown LE key type: {}", key_type); return BT_STATUS_FAIL; } @@ -1255,8 +1249,8 @@ bt_status_t btif_storage_get_ble_bonding_key(const RawAddress& remote_bd_addr, bt_status_t btif_storage_remove_ble_bonding_keys( const RawAddress* remote_bd_addr) { std::string bdstr = remote_bd_addr->ToString(); - LOG_INFO("Removing bonding keys for bd addr:%s", - ADDRESS_TO_LOGGABLE_CSTR(*remote_bd_addr)); + log::info("Removing bonding keys for bd addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(*remote_bd_addr)); bool ret = true; for (size_t i = 0; i < std::size(BTIF_STORAGE_LE_KEYS); i++) { auto key_name = BTIF_STORAGE_LE_KEYS[i].name; @@ -1288,7 +1282,7 @@ bt_status_t btif_storage_add_ble_local_key(const Octet16& key_value, return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } } - LOG_WARN("Unknown LE key type: %d", key_type); + log::warn("Unknown LE key type: {}", key_type); return BT_STATUS_FAIL; } @@ -1308,7 +1302,7 @@ bt_status_t btif_storage_get_ble_local_key(uint8_t key_type, return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } } - LOG_WARN("Unknown LE key type: %d", key_type); + log::warn("Unknown LE key type: {}", key_type); return BT_STATUS_FAIL; } @@ -1349,7 +1343,7 @@ bt_status_t btif_in_fetch_bonded_ble_device( if ((device_type & BT_DEVICE_TYPE_BLE) == BT_DEVICE_TYPE_BLE || btif_has_ble_keys(remote_bd_addr)) { - LOG_VERBOSE("Found a LE device: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("Found a LE device: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (btif_storage_get_remote_addr_type(&bd_addr, &addr_type) != BT_STATUS_SUCCESS) { @@ -1368,7 +1362,7 @@ bt_status_t btif_in_fetch_bonded_ble_device( if (p_bonded_devices->num_devices < BTM_SEC_MAX_DEVICE_RECORDS) { p_bonded_devices->devices[p_bonded_devices->num_devices++] = bd_addr; } else { - LOG_WARN("Exceed the max number of bonded devices"); + log::warn("Exceed the max number of bonded devices"); } btif_gatts_add_bonded_dev_from_nv(bd_addr); } @@ -1406,7 +1400,7 @@ void btif_storage_set_remote_addr_type(const RawAddress& remote_bd_addr, if (!btif_config_set_int(remote_bd_addr.ToString(), BTIF_STORAGE_KEY_ADDR_TYPE, static_cast(addr_type))) - LOG_ERROR("Unable to set storage property"); + log::error("Unable to set storage property"); else { #if TARGET_FLOSS // Floss needs to get address type for diagnosis API. @@ -1419,7 +1413,7 @@ void btif_storage_set_remote_device_type(const RawAddress& remote_bd_addr, const tBT_DEVICE_TYPE& device_type) { if (!btif_config_set_int(remote_bd_addr.ToString(), BTIF_STORAGE_KEY_DEV_TYPE, static_cast(device_type))) - LOG_ERROR("Unable to set storage property"); + log::error("Unable to set storage property"); } bool btif_has_ble_keys(const std::string& bdstr) { @@ -1469,9 +1463,10 @@ void btif_storage_set_gatt_sr_supp_feat(const RawAddress& addr, uint8_t feat) { FROM_HERE, Bind( [](const RawAddress& addr, uint8_t feat) { std::string bdstr = addr.ToString(); - VLOG(2) << "GATT server supported features for: " - << ADDRESS_TO_LOGGABLE_STR(addr) - << " features: " << +feat; + log::verbose( + "GATT server supported features for: {} features: " + "{}", + ADDRESS_TO_LOGGABLE_STR(addr), feat); btif_config_set_int( bdstr, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED, feat); }, @@ -1484,8 +1479,8 @@ uint8_t btif_storage_get_sr_supp_feat(const RawAddress& bd_addr) { int value = 0; btif_config_get_int(name, BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED, &value); - LOG_VERBOSE("Remote device: %s GATT server supported features 0x%02x", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), value); + log::verbose("Remote device: {} GATT server supported features 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), value); return value; } @@ -1532,8 +1527,8 @@ void btif_storage_set_gatt_cl_supp_feat(const RawAddress& bd_addr, FROM_HERE, Bind( [](const RawAddress& bd_addr, uint8_t feat) { std::string bdstr = bd_addr.ToString(); - VLOG(2) << "saving gatt client supported feat: " - << ADDRESS_TO_LOGGABLE_STR(bd_addr); + log::verbose("saving gatt client supported feat: {}", + ADDRESS_TO_LOGGABLE_STR(bd_addr)); btif_config_set_int( bdstr, BTIF_STORAGE_KEY_GATT_CLIENT_SUPPORTED, feat); }, @@ -1546,8 +1541,8 @@ uint8_t btif_storage_get_gatt_cl_supp_feat(const RawAddress& bd_addr) { int value = 0; btif_config_get_int(name, BTIF_STORAGE_KEY_GATT_CLIENT_SUPPORTED, &value); - LOG_VERBOSE("Remote device: %s GATT client supported features 0x%02x", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), value); + log::verbose("Remote device: {} GATT client supported features 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), value); return value; } diff --git a/system/btif/src/btif_util.cc b/system/btif/src/btif_util.cc index 874e55561bb1612e20491b7e8069ad01b826a245..7dcbc74dc3ae015bffa57a9b26da2212f10c4f08 100644 --- a/system/btif/src/btif_util.cc +++ b/system/btif/src/btif_util.cc @@ -57,20 +57,22 @@ * Logging helper functions ****************************************************************************/ -uint32_t devclass2uint(DEV_CLASS dev_class) { +uint32_t devclass2uint(const DEV_CLASS dev_class) { uint32_t cod = 0; - if (dev_class != NULL) { + if (dev_class != kDevClassEmpty) { /* if COD is 0, irrespective of the device type set it to Unclassified * device */ cod = (dev_class[2]) | (dev_class[1] << 8) | (dev_class[0] << 16); } return cod; } -void uint2devclass(uint32_t cod, DEV_CLASS dev_class) { +DEV_CLASS uint2devclass(uint32_t cod) { + DEV_CLASS dev_class; dev_class[2] = (uint8_t)cod; dev_class[1] = (uint8_t)(cod >> 8); dev_class[0] = (uint8_t)(cod >> 16); + return dev_class; } /***************************************************************************** @@ -160,6 +162,7 @@ const char* dump_dm_event(uint16_t event) { CASE_RETURN_STR(BTA_DM_DEV_UNPAIRED_EVT) CASE_RETURN_STR(BTA_DM_ENER_INFO_READ) CASE_RETURN_STR(BTA_DM_SIRK_VERIFICATION_REQ_EVT) + CASE_RETURN_STR(BTA_DM_KEY_MISSING_EVT) default: return "UNKNOWN DM EVENT"; diff --git a/system/btif/src/btif_vc.cc b/system/btif/src/btif_vc.cc index 21e8edc77c5aa4fbc69627f2450b126fb2ec273e..3a29255e438d796209d4d9aac0b65f6fdaf331ba 100644 --- a/system/btif/src/btif_vc.cc +++ b/system/btif/src/btif_vc.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ using base::Unretained; using bluetooth::vc::ConnectionState; using bluetooth::vc::VolumeControlCallbacks; using bluetooth::vc::VolumeControlInterface; +using namespace bluetooth; namespace { std::unique_ptr vc_instance; @@ -119,9 +121,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void Connect(const RawAddress& address) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -132,9 +134,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void Disconnect(const RawAddress& address) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } do_in_main_thread(FROM_HERE, @@ -145,9 +147,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void SetVolume(std::variant addr_or_group_id, uint8_t volume) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -158,9 +160,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void Mute(std::variant addr_or_group_id) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -171,9 +173,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void Unmute(std::variant addr_or_group_id) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -184,9 +186,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void RemoveDevice(const RawAddress& address) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -201,9 +203,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void GetExtAudioOutVolumeOffset(const RawAddress& address, uint8_t ext_output_id) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -217,9 +219,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, uint8_t ext_output_id, int16_t offset_val) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -232,9 +234,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void GetExtAudioOutLocation(const RawAddress& address, uint8_t ext_output_id) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -246,9 +248,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void SetExtAudioOutLocation(const RawAddress& address, uint8_t ext_output_id, uint32_t location) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -260,9 +262,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void GetExtAudioOutDescription(const RawAddress& address, uint8_t ext_output_id) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -275,9 +277,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, uint8_t ext_output_id, std::string descr) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } @@ -288,9 +290,9 @@ class VolumeControlInterfaceImpl : public VolumeControlInterface, void Cleanup(void) override { if (!initialized || !VolumeControl::IsVolumeControlRunning()) { - VLOG(1) << __func__ - << " call ignored, due to already started cleanup procedure or " - "service being not read"; + log::verbose( + "call ignored, due to already started cleanup procedure or service " + "being not read"); return; } diff --git a/system/btif/src/stack_manager.cc b/system/btif/src/stack_manager.cc index aafa132756edc27ec541a42445980cd779ffbeeb..d388e6f4c92611936d0f3f370058e08718f16987 100644 --- a/system/btif/src/stack_manager.cc +++ b/system/btif/src/stack_manager.cc @@ -18,8 +18,7 @@ #define LOG_TAG "bt_stack_manager" -#include "btif/include/stack_manager.h" - +#include #include #include @@ -27,13 +26,14 @@ #include "btcore/include/module.h" #include "btcore/include/osi_module.h" +#include "btif/include/stack_manager_t.h" #include "btif_api.h" #include "btif_common.h" #include "common/message_loop_thread.h" #include "core_callbacks.h" +#include "include/check.h" #include "main/shim/shim.h" #include "os/log.h" -#include "osi/include/osi.h" #include "stack/include/acl_api.h" #include "stack/include/btm_client_interface.h" #include "stack/include/main_thread.h" @@ -106,12 +106,11 @@ static_assert( " Host interface device profile is always enabled in the bluetooth stack" "*** Conditional Compilation Directive error"); -void main_thread_shut_down(); -void main_thread_start_up(); void BTA_dm_on_hw_on(); void BTA_dm_on_hw_off(); using bluetooth::common::MessageLoopThread; +using namespace bluetooth; static MessageLoopThread management_thread("bt_stack_manager_thread"); @@ -163,13 +162,13 @@ static void start_up_stack_async(bluetooth::core::CoreInterface* interface, ProfileStartCallback startProfiles, ProfileStopCallback stopProfiles) { management_thread.DoInThread( - FROM_HERE, - base::Bind(event_start_up_stack, interface, startProfiles, stopProfiles)); + FROM_HERE, base::BindOnce(event_start_up_stack, interface, startProfiles, + stopProfiles)); } static void shut_down_stack_async(ProfileStopCallback stopProfiles) { - management_thread.DoInThread(FROM_HERE, - base::Bind(event_shut_down_stack, stopProfiles)); + management_thread.DoInThread( + FROM_HERE, base::BindOnce(event_shut_down_stack, stopProfiles)); } static void clean_up_stack(ProfileStopCallback stopProfiles) { @@ -186,7 +185,7 @@ static void clean_up_stack(ProfileStopCallback stopProfiles) { if (status == std::future_status::ready) { management_thread.ShutDown(); } else { - LOG_ERROR("cleanup could not be completed in time, abandon it"); + log::error("cleanup could not be completed in time, abandon it"); } } @@ -231,7 +230,7 @@ inline const module_t* get_local_module(const char* name) { } } - LOG_ALWAYS_FATAL("Cannot find module %s, aborting", name); + log::fatal("Cannot find module {}, aborting", name); return nullptr; } @@ -259,15 +258,15 @@ static void init_stack_internal(bluetooth::core::CoreInterface* interface) { // Synchronous function to initialize the stack static void event_init_stack(std::promise promise, bluetooth::core::CoreInterface* interface) { - LOG_INFO("is initializing the stack"); + log::info("is initializing the stack"); if (stack_is_initialized) { - LOG_INFO("found the stack already in initialized state"); + log::info("found the stack already in initialized state"); } else { init_stack_internal(interface); } - LOG_INFO("finished"); + log::info("finished"); promise.set_value(); } @@ -275,7 +274,7 @@ static void event_init_stack(std::promise promise, static void ensure_stack_is_initialized( bluetooth::core::CoreInterface* interface) { if (!stack_is_initialized) { - LOG_WARN("found the stack was uninitialized. Initializing now."); + log::warn("found the stack was uninitialized. Initializing now."); // No future needed since we are calling it directly init_stack_internal(interface); } @@ -286,17 +285,17 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface, ProfileStartCallback startProfiles, ProfileStopCallback stopProfiles) { if (stack_is_running) { - LOG_INFO("%s stack already brought up", __func__); + log::info("stack already brought up"); return; } ensure_stack_is_initialized(interface); - LOG_INFO("%s is bringing up the stack", __func__); + log::info("is bringing up the stack"); future_t* local_hack_future = future_new(); hack_future = local_hack_future; - LOG_INFO("%s Gd shim module enabled", __func__); + log::info("Gd shim module enabled"); get_btm_client_interface().lifecycle.btm_init(); module_start_up(get_local_module(BTIF_CONFIG_MODULE)); @@ -319,7 +318,6 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface, BTA_dm_init(); bta_dm_enable(btif_dm_sec_evt, btif_dm_acl_evt); - bta_set_forward_hw_failures(true); btm_acl_device_down(); CHECK(module_start_up(get_local_module(GD_CONTROLLER_MODULE))); BTM_reset_complete(); @@ -327,7 +325,7 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface, BTA_dm_on_hw_on(); if (future_await(local_hack_future) != FUTURE_SUCCESS) { - LOG_ERROR("%s failed to start up the stack", __func__); + log::error("failed to start up the stack"); stack_is_running = true; // So stack shutdown actually happens event_shut_down_stack(stopProfiles); return; @@ -336,18 +334,18 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface, module_start_up(get_local_module(RUST_MODULE)); stack_is_running = true; - LOG_INFO("%s finished", __func__); + log::info("finished"); do_in_jni_thread(FROM_HERE, base::BindOnce(event_signal_stack_up, nullptr)); } // Synchronous function to shut down the stack static void event_shut_down_stack(ProfileStopCallback stopProfiles) { if (!stack_is_running) { - LOG_INFO("%s stack is already brought down", __func__); + log::info("stack is already brought down"); return; } - LOG_INFO("%s is bringing down the stack", __func__); + log::info("is bringing down the stack"); future_t* local_hack_future = future_new(); hack_future = local_hack_future; stack_is_running = false; @@ -368,7 +366,6 @@ static void event_shut_down_stack(ProfileStopCallback stopProfiles) { hack_future = local_hack_future; bta_sys_disable(); - bta_set_forward_hw_failures(false); BTA_dm_on_hw_off(); module_shut_down(get_local_module(BTIF_CONFIG_MODULE)); @@ -388,13 +385,12 @@ static void event_shut_down_stack(ProfileStopCallback stopProfiles) { hack_future = future_new(); do_in_jni_thread(FROM_HERE, base::BindOnce(event_signal_stack_down, nullptr)); future_await(hack_future); - LOG_INFO("%s finished", __func__); + log::info("finished"); } static void ensure_stack_is_not_running(ProfileStopCallback stopProfiles) { if (stack_is_running) { - LOG_WARN("%s found the stack was still running. Bringing it down now.", - __func__); + log::warn("found the stack was still running. Bringing it down now."); event_shut_down_stack(stopProfiles); } } @@ -403,13 +399,13 @@ static void ensure_stack_is_not_running(ProfileStopCallback stopProfiles) { static void event_clean_up_stack(std::promise promise, ProfileStopCallback stopProfiles) { if (!stack_is_initialized) { - LOG_INFO("%s found the stack already in a clean state", __func__); + log::info("found the stack already in a clean state"); goto cleanup; } ensure_stack_is_not_running(stopProfiles); - LOG_INFO("%s is cleaning up the stack", __func__); + log::info("is cleaning up the stack"); stack_is_initialized = false; btif_cleanup_bluetooth(); @@ -421,19 +417,19 @@ static void event_clean_up_stack(std::promise promise, module_clean_up(get_local_module(DEVICE_IOT_CONFIG_MODULE)); module_clean_up(get_local_module(OSI_MODULE)); - LOG_INFO("%s Gd shim module disabled", __func__); + log::info("Gd shim module disabled"); module_shut_down(get_local_module(GD_SHIM_MODULE)); main_thread_shut_down(); module_management_stop(); - LOG_INFO("%s finished", __func__); + log::info("finished"); cleanup:; promise.set_value(); } -static void event_signal_stack_up(UNUSED_ATTR void* context) { +static void event_signal_stack_up(void* /* context */) { // Notify BTIF connect queue that we've brought up the stack. It's // now time to dispatch all the pending profile connect requests. btif_queue_connect_next(); @@ -441,7 +437,7 @@ static void event_signal_stack_up(UNUSED_ATTR void* context) { BT_STATE_ON); } -static void event_signal_stack_down(UNUSED_ATTR void* context) { +static void event_signal_stack_down(void* /* context */) { GetInterfaceToProfiles()->events->invoke_adapter_state_changed_cb( BT_STATE_OFF); future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); @@ -452,7 +448,7 @@ static void ensure_manager_initialized() { management_thread.StartUp(); if (!management_thread.IsRunning()) { - LOG_ERROR("%s unable to start stack management thread", __func__); + log::error("unable to start stack management thread"); return; } } diff --git a/system/btif/test/btif_config_cache_test.cc b/system/btif/test/btif_config_cache_test.cc index 903031d6191920c41f529f46fef3d974f58e2a88..d1a44dcdf261097fb4e660e5403147f154418ad8 100644 --- a/system/btif/test/btif_config_cache_test.cc +++ b/system/btif/test/btif_config_cache_test.cc @@ -22,6 +22,7 @@ #include #include "stack/include/bt_octets.h" +#include "storage/config_keys.h" namespace { @@ -35,7 +36,7 @@ const std::string kBtAddr5 = "11:AA:22:BB:33:CD"; const std::string kBtLocalAddr = "12:34:56:78:90:AB"; const std::string kBtInfo = "Info"; const std::string kBtMetrics = "Metrics"; -const std::string kBtAdapter = "Adapter"; +const std::string kBtAdapter = BTIF_STORAGE_SECTION_ADAPTER; const std::string kBtAddrInvalid1 = "AB:CD:EF:12:34"; const std::string kBtAddrInvalid2 = "AB:CD:EF:12:34:56:78"; const std::string kBtAddrInvalid3 = "ABCDEF123456"; @@ -67,27 +68,32 @@ TEST(BtifConfigCacheTest, test_setup_btif_config_cache) { test_btif_config_cache.SetString(kBtMetrics, "Salt256Bit", "92a331174d20f2bb"); // Adapter Section - test_btif_config_cache.SetString(kBtAdapter, "Address", kBtLocalAddr); + test_btif_config_cache.SetString(kBtAdapter, BTIF_STORAGE_KEY_ADDRESS, + kBtLocalAddr); EXPECT_TRUE(test_btif_config_cache.HasSection(kBtAdapter)); // bt_device_1 - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "Name")); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_NAME)); test_btif_config_cache.SetInt(kBtAddr1, "Property_Int", 1); EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "Property_Int")); // bt_device_2 - test_btif_config_cache.SetString(kBtAddr2, "Name", "Headset_2"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr2, "Name")); + test_btif_config_cache.SetString(kBtAddr2, BTIF_STORAGE_KEY_NAME, + "Headset_2"); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr2, BTIF_STORAGE_KEY_NAME)); // bt_device_3 - test_btif_config_cache.SetString(kBtAddr3, "Name", "Headset_3"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr3, "Name")); + test_btif_config_cache.SetString(kBtAddr3, BTIF_STORAGE_KEY_NAME, + "Headset_3"); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr3, BTIF_STORAGE_KEY_NAME)); // bt_device_4 - test_btif_config_cache.SetString(kBtAddr4, "Name", "Headset_4"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr4, "Name")); + test_btif_config_cache.SetString(kBtAddr4, BTIF_STORAGE_KEY_NAME, + "Headset_4"); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr4, BTIF_STORAGE_KEY_NAME)); // out out the capacty of unpair devices cache, the bt_device_1 be ruled out EXPECT_FALSE(test_btif_config_cache.HasSection(kBtAddr1)); @@ -104,57 +110,72 @@ TEST(BtifConfigCacheTest, test_set_up_config_cache_with_invalid_section) { BtifConfigCache test_btif_config_cache(kCapacity); // kBtAddrInvalid1 - test_btif_config_cache.SetString(kBtAddrInvalid1, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid1, "Name")); + test_btif_config_cache.SetString(kBtAddrInvalid1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddrInvalid1, BTIF_STORAGE_KEY_NAME)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid1)); // get the LinkKey - test_btif_config_cache.SetString(kBtAddrInvalid1, "LinkKey", + test_btif_config_cache.SetString(kBtAddrInvalid1, BTIF_STORAGE_KEY_LINK_KEY, "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid1, "LinkKey")); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid1, + BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid1)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddrInvalid1)); // kBtAddrInvalid2 - test_btif_config_cache.SetString(kBtAddrInvalid2, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid2, "Name")); + test_btif_config_cache.SetString(kBtAddrInvalid2, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddrInvalid2, BTIF_STORAGE_KEY_NAME)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid2)); // get the LinkKey - test_btif_config_cache.SetString(kBtAddrInvalid2, "LinkKey", + test_btif_config_cache.SetString(kBtAddrInvalid2, BTIF_STORAGE_KEY_LINK_KEY, "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid2, "LinkKey")); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid2, + BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid2)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddrInvalid2)); // kBtAddrInvalid3 - test_btif_config_cache.SetString(kBtAddrInvalid3, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid3, "Name")); + test_btif_config_cache.SetString(kBtAddrInvalid3, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddrInvalid3, BTIF_STORAGE_KEY_NAME)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid3)); // get the LinkKey - test_btif_config_cache.SetString(kBtAddrInvalid3, "LinkKey", + test_btif_config_cache.SetString(kBtAddrInvalid3, BTIF_STORAGE_KEY_LINK_KEY, "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid3, "LinkKey")); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid3, + BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid3)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddrInvalid3)); // kBtAddrInvalid4 - test_btif_config_cache.SetString(kBtAddrInvalid4, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid4, "Name")); + test_btif_config_cache.SetString(kBtAddrInvalid4, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddrInvalid4, BTIF_STORAGE_KEY_NAME)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid4)); // get the LinkKey - test_btif_config_cache.SetString(kBtAddrInvalid4, "LinkKey", + test_btif_config_cache.SetString(kBtAddrInvalid4, BTIF_STORAGE_KEY_LINK_KEY, "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid4, "LinkKey")); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddrInvalid4, + BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddrInvalid4)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddrInvalid4)); // kBtSectionInvalid1 - test_btif_config_cache.SetString(kBtSectionInvalid1, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtSectionInvalid1, "Name")); + test_btif_config_cache.SetString(kBtSectionInvalid1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtSectionInvalid1, BTIF_STORAGE_KEY_NAME)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtSectionInvalid1)); // get the LinkKey - test_btif_config_cache.SetString(kBtSectionInvalid1, "LinkKey", - "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtSectionInvalid1, "LinkKey")); + test_btif_config_cache.SetString( + kBtSectionInvalid1, BTIF_STORAGE_KEY_LINK_KEY, "1122334455667788"); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtSectionInvalid1, + BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtSectionInvalid1)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtSectionInvalid1)); } @@ -170,9 +191,10 @@ TEST(BtifConfigCacheTest, test_set_up_config_cache_with_invalid_section) { TEST(BtifConfigCacheTest, test_get_set_key_value_test) { BtifConfigCache test_btif_config_cache(kCapacity); // test in unpaired cache - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "Name")); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_NAME)); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("Headset_1"))); test_btif_config_cache.SetInt(kBtAddr1, "Property_Int", 65536); @@ -191,21 +213,24 @@ TEST(BtifConfigCacheTest, test_get_set_key_value_test) { Optional(IsTrue())); // empty value - test_btif_config_cache.SetString(kBtAddr1, "Name", ""); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "Name")); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, ""); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_NAME)); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq(""))); // get the LinkKey - test_btif_config_cache.SetString(kBtAddr1, "LinkKey", "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "LinkKey")); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY, + "1122334455667788"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_FALSE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); // test in unpaired cache - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "Name")); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_NAME)); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("Headset_1"))); test_btif_config_cache.SetInt(kBtAddr1, "Property_Int", 65536); @@ -224,40 +249,47 @@ TEST(BtifConfigCacheTest, test_get_set_key_value_test) { Optional(IsTrue())); // empty section is disallowed - EXPECT_DEATH({ test_btif_config_cache.SetString("", "name", "Headset_1"); }, - "Empty section not allowed"); + EXPECT_DEATH( + { + test_btif_config_cache.SetString("", BTIF_STORAGE_KEY_NAME, + "Headset_1"); + }, + "Empty section not allowed"); // empty key is disallowed EXPECT_DEATH({ test_btif_config_cache.SetString(kBtAddr1, "", "Headset_1"); }, "Empty key not allowed"); EXPECT_FALSE(test_btif_config_cache.HasKey(kBtAddr1, "")); // empty value is allowed - test_btif_config_cache.SetString(kBtAddr1, "Name", ""); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "Name")); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, ""); + EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_NAME)); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq(""))); } /* Test to set values in the same key * Receiving the same key with different values in a section, the new incoming * value will be updated but the key will not be added repeatedly. test this - * feature in both unpaired devic cache and paired device list cache + * feature in both unpaired device cache and paired device list cache */ TEST(BtifConfigCacheTest, test_set_values_in_the_same_key) { BtifConfigCache test_btif_config_cache(kCapacity); - // add new a key "Name" - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1"); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + // add new a key BTIF_STORAGE_KEY_NAME + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("Headset_1"))); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); - // add the same key "Name" with different value - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1A"); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + // add the same key BTIF_STORAGE_KEY_NAME with different value + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1A"); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("Headset_1A"))); - // add the same key "Name" with different value - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_2A"); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + // add the same key BTIF_STORAGE_KEY_NAME with different value + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_2A"); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("Headset_2A"))); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); @@ -276,19 +308,23 @@ TEST(BtifConfigCacheTest, test_set_values_in_the_same_key) { Optional(Eq(uint64_t(4294967296)))); // get the LinkKey and set values in the same key in paired device list - test_btif_config_cache.SetString(kBtAddr1, "LinkKey", "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "LinkKey")); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY, + "1122334455667788"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_FALSE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); - // add the same key "Name" with the different value - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1A"); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + // add the same key BTIF_STORAGE_KEY_NAME with the different value + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1A"); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("Headset_1A"))); - // add the same key "Name" with the value different - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_2A"); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "Name"), + // add the same key BTIF_STORAGE_KEY_NAME with the value different + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_2A"); + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("Headset_2A"))); test_btif_config_cache.SetInt(kBtAddr1, "Property_Int", 64); @@ -305,30 +341,34 @@ TEST(BtifConfigCacheTest, test_set_values_in_the_same_key) { /* Stress test to pair with device then unpair device * 1. paired with device by adding a "LinKey" to device and check the device be * moved into paired devices list - * 2. unpaired with the device by removing the "LinkKey" and check the device be - * moved back to unpaired devices cache + * 2. unpaired with the device by removing the BTIF_STORAGE_KEY_LINK_KEY and + * check the device be moved back to unpaired devices cache * 3. loop for 30 times */ TEST(BtifConfigCacheTest, test_pair_unpair_device_stress_test) { BtifConfigCache test_btif_config_cache(kCapacity); // pair with Headset_1 11:22:33:44:55:66 - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1"); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); for (int i = 0; i < kTestRepeatCount; ++i) { // get the LinkKey, the device will be moved from the unpaired cache to // paired cache - test_btif_config_cache.SetString(kBtAddr1, "LinkKey", "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "LinkKey")); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY, + "1122334455667788"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_FALSE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); // remove the LinkKey, the device will be moved from the paired cache to // unpaired cache - test_btif_config_cache.RemoveKey(kBtAddr1, "LinkKey"); - EXPECT_FALSE(test_btif_config_cache.HasKey(kBtAddr1, "LinkKey")); + test_btif_config_cache.RemoveKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY); + EXPECT_FALSE( + test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); } @@ -338,92 +378,111 @@ TEST(BtifConfigCacheTest, test_pair_unpair_device_stress_test) { * 1. Pired with 4 devices with Link-Key type key in order, to check these 4 * devices are in the paired devices list cache * 2. unpair with these 4 devices by removed Link-Key type key in order, to - * check the fisrt device was ruled-out from unpaired devices cache due to + * check the first device was ruled-out from unpaired devices cache due to * capacity limitation, and other 3 devices are be moved to unpaired device * cache. */ TEST(BtifConfigCacheTest, test_multi_pair_unpair_with_devices) { BtifConfigCache test_btif_config_cache(kCapacity); // pair with 4 bt address devices by add different type linkkey. - test_btif_config_cache.SetString(kBtAddr1, "name", "kBtAddr1"); - test_btif_config_cache.SetString(kBtAddr1, "LinkKey", "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "LinkKey")); - - test_btif_config_cache.SetString(kBtAddr2, "name", "kBtAddr2"); - test_btif_config_cache.SetString(kBtAddr2, "LE_KEY_PENC", "aabbccddeeff9900"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr2, "LE_KEY_PENC")); - - test_btif_config_cache.SetString(kBtAddr3, "name", "kBtAddr3"); - test_btif_config_cache.SetString(kBtAddr3, "LE_KEY_PID", "a1b2c3d4e5feeeee"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr3, "LE_KEY_PID")); - - test_btif_config_cache.SetString(kBtAddr4, "LE_KEY_PCSRK", + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, "kBtAddr1"); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY, + "1122334455667788"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY)); + + test_btif_config_cache.SetString(kBtAddr2, BTIF_STORAGE_KEY_NAME, "kBtAddr2"); + test_btif_config_cache.SetString(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC, + "aabbccddeeff9900"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC)); + + test_btif_config_cache.SetString(kBtAddr3, BTIF_STORAGE_KEY_NAME, "kBtAddr3"); + test_btif_config_cache.SetString(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID, + "a1b2c3d4e5feeeee"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID)); + + test_btif_config_cache.SetString(kBtAddr4, BTIF_STORAGE_KEY_LE_KEY_PCSRK, "aaaabbbbccccdddd"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr4, "LE_KEY_PCSRK")); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr4, BTIF_STORAGE_KEY_LE_KEY_PCSRK)); - test_btif_config_cache.SetString(kBtAddr5, "name", "kBtAddr5"); - test_btif_config_cache.SetString(kBtAddr5, "LE_KEY_LENC", "jilkjlkjlkn"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr5, "LE_KEY_LENC")); + test_btif_config_cache.SetString(kBtAddr5, BTIF_STORAGE_KEY_NAME, "kBtAddr5"); + test_btif_config_cache.SetString(kBtAddr5, BTIF_STORAGE_KEY_LE_KEY_LENC, + "jilkjlkjlkn"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr5, BTIF_STORAGE_KEY_LE_KEY_LENC)); // checking these 4 devices are in paired list cache and the content are // correct. EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "LinkKey"), - Optional(StrEq("1122334455667788"))); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY), + Optional(StrEq("1122334455667788"))); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr2)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr2, "LE_KEY_PENC"), - Optional(StrEq("aabbccddeeff9900"))); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC), + Optional(StrEq("aabbccddeeff9900"))); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr3)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr3, "LE_KEY_PID"), - Optional(StrEq("a1b2c3d4e5feeeee"))); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID), + Optional(StrEq("a1b2c3d4e5feeeee"))); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr4)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr4, "LE_KEY_PCSRK"), - Optional(StrEq("aaaabbbbccccdddd"))); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr4, BTIF_STORAGE_KEY_LE_KEY_PCSRK), + Optional(StrEq("aaaabbbbccccdddd"))); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr5)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr5, "LE_KEY_LENC"), - Optional(StrEq("jilkjlkjlkn"))); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr5, BTIF_STORAGE_KEY_LE_KEY_LENC), + Optional(StrEq("jilkjlkjlkn"))); // unpair with these 4 bt address devices by removed the linkkey. // unpair kBtAddr1 11:22:33:44:55:66 - test_btif_config_cache.RemoveKey(kBtAddr1, "LinkKey"); - EXPECT_FALSE(test_btif_config_cache.HasKey(kBtAddr1, "LinkKey")); + test_btif_config_cache.RemoveKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY); + EXPECT_FALSE( + test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY)); // no empty section is moved to unpaired EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr1)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "name"), + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_NAME), Optional(StrEq("kBtAddr1"))); // unpair with kBtAddr2 aa:bb:cc:dd:ee:ff - test_btif_config_cache.RemoveKey(kBtAddr2, "LE_KEY_PENC"); - EXPECT_FALSE(test_btif_config_cache.HasKey(kBtAddr2, "LE_KEY_PENC")); + test_btif_config_cache.RemoveKey(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC); + EXPECT_FALSE( + test_btif_config_cache.HasKey(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddr2)); EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr2)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr2, "name"), + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr2, BTIF_STORAGE_KEY_NAME), Optional(StrEq("kBtAddr2"))); // unpair with kBtAddr3 AB:CD:EF:12:34:56 - test_btif_config_cache.RemoveKey(kBtAddr3, "LE_KEY_PID"); - EXPECT_FALSE(test_btif_config_cache.HasKey(kBtAddr3, "LE_KEY_PID")); + test_btif_config_cache.RemoveKey(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID); + EXPECT_FALSE( + test_btif_config_cache.HasKey(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddr3)); // no empty section is moved to unpaired EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr3)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr3, "name"), + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr3, BTIF_STORAGE_KEY_NAME), Optional(StrEq("kBtAddr3"))); // unpair with kBtAddr4 11:AA:22:BB:33:CC - test_btif_config_cache.RemoveKey(kBtAddr4, "LE_KEY_PCSRK"); - EXPECT_FALSE(test_btif_config_cache.HasKey(kBtAddr4, "LE_KEY_PCSRK")); + test_btif_config_cache.RemoveKey(kBtAddr4, BTIF_STORAGE_KEY_LE_KEY_PCSRK); + EXPECT_FALSE( + test_btif_config_cache.HasKey(kBtAddr4, BTIF_STORAGE_KEY_LE_KEY_PCSRK)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddr4)); // empty section is removed EXPECT_FALSE(test_btif_config_cache.HasUnpairedSection(kBtAddr4)); // unpair with kBtAddr5 11:AA:22:BB:33:CD - test_btif_config_cache.RemoveKey(kBtAddr5, "LE_KEY_LENC"); - EXPECT_FALSE(test_btif_config_cache.HasKey(kBtAddr5, "LE_KEY_LENC")); + test_btif_config_cache.RemoveKey(kBtAddr5, BTIF_STORAGE_KEY_LE_KEY_LENC); + EXPECT_FALSE( + test_btif_config_cache.HasKey(kBtAddr5, BTIF_STORAGE_KEY_LE_KEY_LENC)); EXPECT_FALSE(test_btif_config_cache.HasPersistentSection(kBtAddr5)); // no empty section is moved to unpaired EXPECT_TRUE(test_btif_config_cache.HasUnpairedSection(kBtAddr5)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr5, "name"), + EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr5, BTIF_STORAGE_KEY_NAME), Optional(StrEq("kBtAddr5"))); // checking the oldest unpaired device kBtAddr1 was ruled out from cache due @@ -432,26 +491,33 @@ TEST(BtifConfigCacheTest, test_multi_pair_unpair_with_devices) { } /* Test to remove sections with the specific key - * paired with sections with the specific "Restricted" key and then removed the - * "Restricted" key, check if the sections with the specific "Restricted" key - * are removed. + * paired with sections with the specific BTIF_STORAGE_KEY_RESTRICTED key and + * then removed the BTIF_STORAGE_KEY_RESTRICTED key, check if the sections with + * the specific BTIF_STORAGE_KEY_RESTRICTED key are removed. */ TEST(BtifConfigCacheTest, test_remove_sections_with_key) { BtifConfigCache test_btif_config_cache(kCapacity); // pair with Headset_1 (kBtAddr1), Headset_2 (kBtAddr1), Heasdet_3 (kBtAddr3) - // , and Headset_1 (kBtAddr1), Headset_3 (kBtAddr3) have sepcific "Restricted" - // key - test_btif_config_cache.SetString(kBtAddr1, "Name", "Headset_1"); - test_btif_config_cache.SetString(kBtAddr1, "Restricted", "1"); - test_btif_config_cache.SetString(kBtAddr1, "LinkKey", "1122334455667788"); - test_btif_config_cache.SetString(kBtAddr2, "Name", "Headset_2"); - test_btif_config_cache.SetString(kBtAddr2, "LinkKey", "aabbccddeeff9900"); - test_btif_config_cache.SetString(kBtAddr3, "Name", "Headset_3"); - test_btif_config_cache.SetString(kBtAddr3, "LinkKey", "a1b2c3d4e5feeeee"); - test_btif_config_cache.SetString(kBtAddr3, "Restricted", "1"); - - // remove sections with "Restricted" key - test_btif_config_cache.RemovePersistentSectionsWithKey("Restricted"); + // , and Headset_1 (kBtAddr1), Headset_3 (kBtAddr3) have specific + // BTIF_STORAGE_KEY_RESTRICTED key + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_NAME, + "Headset_1"); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_RESTRICTED, "1"); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY, + "1122334455667788"); + test_btif_config_cache.SetString(kBtAddr2, BTIF_STORAGE_KEY_NAME, + "Headset_2"); + test_btif_config_cache.SetString(kBtAddr2, BTIF_STORAGE_KEY_LINK_KEY, + "aabbccddeeff9900"); + test_btif_config_cache.SetString(kBtAddr3, BTIF_STORAGE_KEY_NAME, + "Headset_3"); + test_btif_config_cache.SetString(kBtAddr3, BTIF_STORAGE_KEY_LINK_KEY, + "a1b2c3d4e5feeeee"); + test_btif_config_cache.SetString(kBtAddr3, BTIF_STORAGE_KEY_RESTRICTED, "1"); + + // remove sections with BTIF_STORAGE_KEY_RESTRICTED key + test_btif_config_cache.RemovePersistentSectionsWithKey( + BTIF_STORAGE_KEY_RESTRICTED); // checking the kBtAddr1 and kBtAddr3 can not be found in config cache, only // keep kBtAddr2 in config cache. @@ -465,23 +531,32 @@ TEST(BtifConfigCacheTest, test_PersistentSectionCopy_Init) { BtifConfigCache test_btif_config_cache(kCapacity); config_t config_paired = {}; // pair with 3 bt devices, kBtAddr1, kBtAddr2, kBtAddr3 - test_btif_config_cache.SetString(kBtAddr1, "LinkKey", "1122334455667788"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr1, "LinkKey")); + test_btif_config_cache.SetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY, + "1122334455667788"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr1)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr1, "LinkKey"), - Optional(StrEq("1122334455667788"))); - - test_btif_config_cache.SetString(kBtAddr2, "LE_KEY_PENC", "aabbccddeeff9900"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr2, "LE_KEY_PENC")); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr1, BTIF_STORAGE_KEY_LINK_KEY), + Optional(StrEq("1122334455667788"))); + + test_btif_config_cache.SetString(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC, + "aabbccddeeff9900"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC)); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr2)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr2, "LE_KEY_PENC"), - Optional(StrEq("aabbccddeeff9900"))); - - test_btif_config_cache.SetString(kBtAddr3, "LE_KEY_PID", "a1b2c3d4e5feeeee"); - EXPECT_TRUE(test_btif_config_cache.HasKey(kBtAddr3, "LE_KEY_PID")); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr2, BTIF_STORAGE_KEY_LE_KEY_PENC), + Optional(StrEq("aabbccddeeff9900"))); + + test_btif_config_cache.SetString(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID, + "a1b2c3d4e5feeeee"); + EXPECT_TRUE( + test_btif_config_cache.HasKey(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID)); EXPECT_TRUE(test_btif_config_cache.HasPersistentSection(kBtAddr3)); - EXPECT_THAT(test_btif_config_cache.GetString(kBtAddr3, "LE_KEY_PID"), - Optional(StrEq("a1b2c3d4e5feeeee"))); + EXPECT_THAT( + test_btif_config_cache.GetString(kBtAddr3, BTIF_STORAGE_KEY_LE_KEY_PID), + Optional(StrEq("a1b2c3d4e5feeeee"))); // check GetPersistentSections int num_of_paired_devices = 0; diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc index e08e43f4d9c744d04daeeb40aa68f59107fdf466..b9a2b35bdde6622989c1d2c5e4761d451dbfce49 100644 --- a/system/btif/test/btif_core_test.cc +++ b/system/btif/test/btif_core_test.cc @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include @@ -28,10 +29,11 @@ #include "btif/include/btif_api.h" #include "btif/include/btif_common.h" #include "btif/include/btif_util.h" +#include "hci/controller_interface_mock.h" #include "include/hardware/bluetooth.h" #include "include/hardware/bt_av.h" #include "test/common/core_interface.h" -#include "test/mock/mock_main_shim_controller.h" +#include "test/mock/mock_main_shim_entry.h" #include "test/mock/mock_stack_btm_sec.h" #include "types/raw_address.h" @@ -39,6 +41,7 @@ void set_hal_cbacks(bt_callbacks_t* callbacks); const tBTA_AG_RES_DATA tBTA_AG_RES_DATA::kEmpty = {}; +using testing::Return; module_t bt_utils_module; module_t gd_controller_module; module_t gd_shim_module; @@ -136,6 +139,7 @@ class BtifCoreTest : public ::testing::Test { protected: void SetUp() override { callback_map_.clear(); + bluetooth::hci::testing::mock_controller_ = &controller_; set_hal_cbacks(&callbacks); auto promise = std::promise(); auto future = promise.get_future(); @@ -155,27 +159,19 @@ class BtifCoreTest : public ::testing::Test { }; CleanCoreInterface(); ASSERT_EQ(std::future_status::ready, future.wait_for(timeout_time)); + bluetooth::hci::testing::mock_controller_ = nullptr; callback_map_.erase("callback_thread_event"); } + bluetooth::hci::testing::MockControllerInterface controller_; }; -namespace { -controller_t controller = {}; -} - class BtifCoreWithControllerTest : public BtifCoreTest { void SetUp() override { BtifCoreTest::SetUp(); - controller.supports_sniff_subrating = []() { return true; }; - bluetooth::testing::controller = &controller; - ASSERT_TRUE(controller_get_interface() != nullptr); + ON_CALL(controller_, SupportsSniffSubrating).WillByDefault(Return(true)); } - void TearDown() override { - bluetooth::testing::controller = nullptr; - controller = {}; - BtifCoreTest::TearDown(); - } + void TearDown() override { BtifCoreTest::TearDown(); } }; std::promise promise0; @@ -753,3 +749,21 @@ TEST_F(BtifCoreWithControllerTest, ASSERT_EQ(7, btif_dm_get_connection_state(kRawAddress)); test::mock::stack_btm_sec::BTM_IsEncrypted = {}; } + +TEST_F(BtifCoreWithControllerTest, btif_dm_get_connection_state_sync) { + bta_dm_acl_up(kRawAddress, BT_TRANSPORT_AUTO, 0x123); + + test::mock::stack_btm_sec::BTM_IsEncrypted.body = + [](const RawAddress& /* bd_addr */, tBT_TRANSPORT transport) { + switch (transport) { + case BT_TRANSPORT_BR_EDR: + return true; + case BT_TRANSPORT_LE: + return true; + } + return false; + }; + ASSERT_EQ(7, btif_dm_get_connection_state_sync(kRawAddress)); + + test::mock::stack_btm_sec::BTM_IsEncrypted = {}; +} diff --git a/system/btif/test/btif_dm_test.cc b/system/btif/test/btif_dm_test.cc index 68cff1d336c4feccd8d3916d36f9be763fa77917..4df1a38fc347e289e457e3881cabb9983180b463 100644 --- a/system/btif/test/btif_dm_test.cc +++ b/system/btif/test/btif_dm_test.cc @@ -16,16 +16,30 @@ #include "btif/include/btif_dm.h" +#include +#include #include #include #include "bta/include/bta_api_data_types.h" +#include "btif/include/btif_dm.h" #include "btif/include/mock_core_callbacks.h" -#include "stack/include/btm_api_types.h" +#include "main/shim/stack.h" +#include "module.h" +#include "stack/include/bt_dev_class.h" #include "stack/include/btm_ble_api_types.h" +#include "storage/storage_module.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_osi_properties.h" using bluetooth::core::testing::MockCoreInterface; +using ::testing::ElementsAre; + +namespace { +const RawAddress kRawAddress = {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}}; +constexpr char kBdName[] = {'k', 'B', 'd', 'N', 'a', 'm', 'e', '\0'}; +} // namespace namespace bluetooth { namespace legacy { @@ -40,6 +54,9 @@ void bta_energy_info_cb(tBTM_BLE_TX_TIME_MS tx_time, tBTM_BLE_ENERGY_USED energy_used, tBTM_CONTRL_STATE ctrl_state, tBTA_STATUS status); +void btif_dm_search_services_evt(tBTA_DM_SEARCH_EVT event, + tBTA_DM_SEARCH* p_data); + } // namespace testing } // namespace legacy } // namespace bluetooth @@ -54,6 +71,7 @@ constexpr tBTM_BLE_ENERGY_USED energy_used = 0x13579bdf; class BtifDmTest : public ::testing::Test { protected: void SetUp() override { + fake_osi_ = std::make_unique(); mock_core_interface_ = std::make_unique(); bluetooth::legacy::testing::set_interface_to_profiles( mock_core_interface_.get()); @@ -61,6 +79,7 @@ class BtifDmTest : public ::testing::Test { void TearDown() override {} + std::unique_ptr fake_osi_; std::unique_ptr mock_core_interface_; }; @@ -105,3 +124,107 @@ TEST_F(BtifDmWithUidTest, bta_energy_info_cb__with_uid) { ASSERT_TRUE(invoke_energy_info_cb_entered); } + +class BtifDmWithStackTest : public BtifDmTest { + protected: + void SetUp() override { + BtifDmTest::SetUp(); + modules_.add(); + bluetooth::shim::Stack::GetInstance()->StartModuleStack( + &modules_, + new bluetooth::os::Thread("gd_stack_thread", + bluetooth::os::Thread::Priority::NORMAL)); + } + + void TearDown() override { + bluetooth::shim::Stack::GetInstance()->Stop(); + BtifDmTest::TearDown(); + } + bluetooth::ModuleList modules_; +}; + +#define MY_PACKAGE com::android::bluetooth::flags + +TEST_F_WITH_FLAGS(BtifDmWithStackTest, + btif_dm_search_services_evt__BTA_DM_NAME_READ_EVT, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( + MY_PACKAGE, rnr_present_during_service_discovery))) { + static struct { + bt_status_t status; + RawAddress bd_addr; + int num_properties; + std::vector properties; + } invoke_remote_device_properties_cb{ + .status = BT_STATUS_NOT_READY, + .bd_addr = RawAddress::kEmpty, + .num_properties = -1, + .properties = {}, + }; + + bluetooth::core::testing::mock_event_callbacks + .invoke_remote_device_properties_cb = + [](bt_status_t status, RawAddress bd_addr, int num_properties, + bt_property_t* properties) { + invoke_remote_device_properties_cb = { + .status = status, + .bd_addr = bd_addr, + .num_properties = num_properties, + .properties = std::vector( + properties, properties + (size_t)num_properties), + }; + }; + + tBTA_DM_SEARCH data = { + .disc_res = + { + // tBTA_DM_DISC_RES + .bd_addr = kRawAddress, + .bd_name = {}, + .services = 0, + .device_type = BT_DEVICE_TYPE_UNKNOWN, + .num_uuids = 0, + .p_uuid_list = nullptr, + .result = BTA_SUCCESS, + .hci_status = HCI_SUCCESS, + }, + }; + bd_name_copy(data.disc_res.bd_name, kBdName); + + bluetooth::legacy::testing::btif_dm_search_services_evt(BTA_DM_NAME_READ_EVT, + &data); + + ASSERT_EQ(BT_STATUS_SUCCESS, invoke_remote_device_properties_cb.status); + ASSERT_EQ(kRawAddress, invoke_remote_device_properties_cb.bd_addr); + ASSERT_EQ(1, invoke_remote_device_properties_cb.num_properties); + ASSERT_EQ(BT_PROPERTY_BDNAME, + invoke_remote_device_properties_cb.properties[0].type); + ASSERT_EQ((int)strlen(kBdName), + invoke_remote_device_properties_cb.properties[0].len); + ASSERT_STREQ( + kBdName, + (const char*)invoke_remote_device_properties_cb.properties[0].val); +} + +TEST_F(BtifDmWithStackTest, btif_dm_get_local_class_of_device__default) { + DEV_CLASS dev_class = btif_dm_get_local_class_of_device(); + ASSERT_EQ(dev_class, kDevClassUnclassified); +} + +std::string kClassOfDeviceText = "1,2,3"; +DEV_CLASS kClassOfDevice = {1, 2, 3}; +TEST_F(BtifDmWithStackTest, btif_dm_get_local_class_of_device__with_property) { + test::mock::osi_properties::osi_property_get.body = + [](const char* /* key */, char* value, const char* /* default_value */) { + std::copy(kClassOfDeviceText.begin(), kClassOfDeviceText.end(), value); + return kClassOfDeviceText.size(); + }; + + DEV_CLASS dev_class = btif_dm_get_local_class_of_device(); + if (dev_class != kClassOfDevice) { + // If BAP is enabled, an extra bit gets set. + DEV_CLASS dev_class_with_bap = kClassOfDevice; + dev_class_with_bap[1] |= 0x01 << 6; + ASSERT_EQ(dev_class, dev_class_with_bap); + } + test::mock::osi_properties::osi_property_get = {}; +} diff --git a/system/btif/test/btif_hh_test.cc b/system/btif/test/btif_hh_test.cc index f064efc5e9d6d2261b1d523551f0e58eda35d088..a7088b6c362aa217b23ef6d09494bda7991e6b02 100644 --- a/system/btif/test/btif_hh_test.cc +++ b/system/btif/test/btif_hh_test.cc @@ -26,6 +26,7 @@ #include "bta/include/bta_ag_api.h" #include "bta/include/bta_hh_api.h" #include "btcore/include/module.h" +#include "common/init_flags.h" #include "include/hardware/bt_hh.h" #include "osi/include/allocator.h" #include "test/common/core_interface.h" @@ -46,8 +47,8 @@ module_t rust_module; const tBTA_AG_RES_DATA tBTA_AG_RES_DATA::kEmpty = {}; const bthh_interface_t* btif_hh_get_interface(); -bt_status_t btif_hh_connect(const RawAddress* bd_addr); -bt_status_t btif_hh_virtual_unplug(const RawAddress* bd_addr); +bt_status_t btif_hh_connect(const tAclLinkSpec* link_spec); +bt_status_t btif_hh_virtual_unplug(const tAclLinkSpec* link_spec); namespace bluetooth { namespace legacy { @@ -75,7 +76,11 @@ std::array data32 = { const RawAddress kDeviceAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); const RawAddress kDeviceAddressConnecting({0x66, 0x55, 0x44, 0x33, 0x22, 0x11}); const uint16_t kHhHandle = 123; - +const tBLE_ADDR_TYPE kDeviceAddrType = BLE_ADDR_PUBLIC; +const tBT_TRANSPORT kDeviceTransport = BT_TRANSPORT_AUTO; +const tAclLinkSpec kDeviceConnecting = {.addrt.type = kDeviceAddrType, + .addrt.bda = kDeviceAddressConnecting, + .transport = kDeviceTransport}; // Callback parameters grouped into a structure struct get_report_cb_t { RawAddress raw_address; @@ -194,7 +199,9 @@ class BtifHhWithDevice : public BtifHhAdapterReady { BtifHhAdapterReady::SetUp(); // Short circuit a connected device - btif_hh_cb.devices[0].bd_addr = kDeviceAddress; + btif_hh_cb.devices[0].link_spec.addrt.bda = kDeviceAddress; + btif_hh_cb.devices[0].link_spec.addrt.type = kDeviceAddrType; + btif_hh_cb.devices[0].link_spec.transport = kDeviceTransport; btif_hh_cb.devices[0].dev_status = BTHH_CONN_STATE_CONNECTED; btif_hh_cb.devices[0].dev_handle = kHhHandle; } @@ -278,7 +285,7 @@ TEST_F(BtifHHVirtualUnplugTest, test_btif_hh_virtual_unplug_device_not_open) { auto future = g_bthh_connection_state_promise.get_future(); /* Make device in connecting state */ - ASSERT_EQ(btif_hh_connect(&kDeviceAddressConnecting), BT_STATUS_SUCCESS); + ASSERT_EQ(btif_hh_connect(&kDeviceConnecting), BT_STATUS_SUCCESS); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); @@ -290,7 +297,7 @@ TEST_F(BtifHHVirtualUnplugTest, test_btif_hh_virtual_unplug_device_not_open) { g_bthh_connection_state_promise = std::promise(); future = g_bthh_connection_state_promise.get_future(); - btif_hh_virtual_unplug(&kDeviceAddressConnecting); + btif_hh_virtual_unplug(&kDeviceConnecting); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); diff --git a/system/btif/test/btif_profile_queue_test.cc b/system/btif/test/btif_profile_queue_test.cc index a525fb471511db66ea8b19814193f2afcafb1f90..716a1093e6fbcdbc81f3814e79b897d75f95a055 100644 --- a/system/btif/test/btif_profile_queue_test.cc +++ b/system/btif/test/btif_profile_queue_test.cc @@ -22,7 +22,7 @@ #include #include -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" diff --git a/system/btif/test/btif_rc_test.cc b/system/btif/test/btif_rc_test.cc index 221cb4f9de4820cccfdeda855389c9fef75834ed..8b6d8bccf7e3b2a1e2db964067152efb2f2f71aa 100644 --- a/system/btif/test/btif_rc_test.cc +++ b/system/btif/test/btif_rc_test.cc @@ -17,6 +17,7 @@ #undef LOG_TAG // Undefine the LOG_TAG by this compilation unit #include "btif/src/btif_rc.cc" +#include #include #include @@ -27,6 +28,7 @@ #include "btif/include/btif_common.h" #include "common/message_loop_thread.h" #include "device/include/interop.h" +#include "include/check.h" #include "include/hardware/bt_rc.h" #include "test/common/mock_functions.h" #include "test/mock/mock_osi_alarm.h" @@ -106,7 +108,7 @@ static bluetooth::common::MessageLoopThread jni_thread("bt_jni_thread"); bt_status_t do_in_jni_thread(const base::Location& from_here, base::OnceClosure task) { if (!jni_thread.DoInThread(from_here, std::move(task))) { - LOG(ERROR) << __func__ << ": Post task to task runner failed!"; + log::error("Post task to task runner failed!"); return BT_STATUS_FAIL; } return BT_STATUS_SUCCESS; @@ -263,7 +265,7 @@ TEST_F(BtifRcWithCallbacksTest, handle_rc_ctrl_features) { CHECK(std::future_status::ready == future.wait_for(std::chrono::seconds(2))); auto res = future.get(); - LOG_INFO("FEATURES:%d", res.feature); + log::info("FEATURES:{}", res.feature); CHECK(res.feature == (BTRC_FEAT_ABSOLUTE_VOLUME | BTRC_FEAT_METADATA | BTRC_FEAT_BROWSE | BTRC_FEAT_COVER_ARTWORK)); } diff --git a/system/build/dpkg/floss/build-dpkg b/system/build/dpkg/floss/build-dpkg index e9cb70b9feb7df5ccaba4b876972fc6d30060115..fececbc68951371a159ab4300a155eb171c8c132 100755 --- a/system/build/dpkg/floss/build-dpkg +++ b/system/build/dpkg/floss/build-dpkg @@ -48,7 +48,7 @@ export PATH="${PATH}:${BIN_DIR}" # Check dependencies # libchrome requires modp_b64 -APT_REQUIRED="modp-b64 libchrome flatbuffers-compiler flex g++-multilib gcc-multilib generate-ninja gnupg gperf libc++-dev libdbus-1-dev libevent-dev libevent-dev libflatbuffers-dev libflatbuffers1 libgl1-mesa-dev libglib2.0-dev liblz4-tool libncurses5 libnss3-dev libprotobuf-dev libre2-9 libssl-dev libtinyxml2-dev libx11-dev libxml2-utils ninja-build openssl protobuf-compiler unzip x11proto-core-dev xsltproc zip zlib1g-dev" +APT_REQUIRED="modp-b64 libchrome flatbuffers-compiler flex g++-multilib gcc-multilib generate-ninja gnupg gperf libc++-dev libdbus-1-dev libevent-dev libevent-dev libflatbuffers-dev libflatbuffers1 libfmt-dev libgl1-mesa-dev libglib2.0-dev liblz4-tool libncurses5 libnss3-dev libprotobuf-dev libre2-9 libssl-dev libtinyxml2-dev libx11-dev libxml2-utils ninja-build openssl protobuf-compiler unzip x11proto-core-dev xsltproc zip zlib1g-dev" # SPEED UP TEST, REMOVE ME APT_REQUIRED="modp-b64 libchrome flatbuffers-compiler" diff --git a/system/build/dpkg/floss/install-dependencies b/system/build/dpkg/floss/install-dependencies index a1b33a74a66c10a629941d166719dc5935e79862..e215399f6faab95d23e8c8de119f6abb57d3692b 100755 --- a/system/build/dpkg/floss/install-dependencies +++ b/system/build/dpkg/floss/install-dependencies @@ -24,7 +24,7 @@ function ctrl_c() { # APT dependencies APT_REQUIRED="git curl wget flatbuffers-compiler flex g++-multilib gcc-multilib generate-ninja \ -gnupg gperf libc++-dev libdbus-1-dev libevent-dev libflatbuffers-dev libflatbuffers1 \ +gnupg gperf libc++-dev libdbus-1-dev libevent-dev libflatbuffers-dev libfmt-dev libflatbuffers1 \ libgl1-mesa-dev libglib2.0-dev liblz4-tool libncurses5 libnss3-dev libprotobuf-dev libre2-9 \ libssl-dev libtinyxml2-dev libx11-dev libxml2-utils ninja-build openssl protobuf-compiler unzip \ x11proto-core-dev xsltproc zip zlib1g-dev libc++abi-dev cmake debmake ninja-build libgtest-dev \ diff --git a/system/build/dpkg/floss/package/DEBIAN/control b/system/build/dpkg/floss/package/DEBIAN/control index 3bb5d35eb9f946139243010277ff264cab05d573..d5f4520c6cfa9b27dc9720c081f1f02fef1f2dd8 100644 --- a/system/build/dpkg/floss/package/DEBIAN/control +++ b/system/build/dpkg/floss/package/DEBIAN/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: Martin Brabham Version: 0.1 Homepage: https://www.google.com -Depends: debmake, ninja-build, flatbuffers-compiler, flex, g++-multilib, gcc-multilib, generate-ninja, gnupg, gperf, libc++-dev, libdbus-1-dev, libevent-dev, libevent-dev, libflatbuffers-dev, libflatbuffers1, libgl1-mesa-dev, libglib2.0-dev, liblz4-tool, libncurses5, libnss3-dev, libprotobuf-dev, libre2-9, libssl-dev, libtinyxml2-dev, libx11-dev, libxml2-utils, ninja-build, openssl, protobuf-compiler, unzip, x11proto-core-dev, xsltproc, zip, zlib1g-dev, modp-b64, libchrome +Depends: debmake, ninja-build, flatbuffers-compiler, flex, g++-multilib, gcc-multilib, generate-ninja, gnupg, gperf, libc++-dev, libdbus-1-dev, libevent-dev, libevent-dev, libflatbuffers-dev, libflatbuffers1, libfmt-dev, libfmt9, libgl1-mesa-dev, libglib2.0-dev, liblz4-tool, libncurses5, libnss3-dev, libprotobuf-dev, libre2-9, libssl-dev, libtinyxml2-dev, libx11-dev, libxml2-utils, ninja-build, openssl, protobuf-compiler, unzip, x11proto-core-dev, xsltproc, zip, zlib1g-dev, modp-b64, libchrome Architecture: all Essential: no Installed-Size: 490MB diff --git a/system/common/Android.bp b/system/common/Android.bp index 6fd7ff021d491f68623c4db78e830fd85931a45e..379ec9802ac23ba58cfaab0414fe9850a263895b 100644 --- a/system/common/Android.bp +++ b/system/common/Android.bp @@ -55,6 +55,7 @@ cc_library_static { header_libs: ["libbluetooth_headers"], static_libs: [ "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbt-platform-protos-lite", "libbt_shim_bridge", ], @@ -102,6 +103,7 @@ cc_test { static_libs: [ "libbluetooth-types", "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -124,7 +126,10 @@ cc_test { "mts_defaults", ], test_suites: ["general-tests"], - include_dirs: ["packages/modules/Bluetooth/system"], + include_dirs: [ + "packages/modules/Bluetooth/system", + "packages/modules/Bluetooth/system/gd", + ], host_supported: true, srcs: [ "test/thread_performance_test.cc", @@ -149,7 +154,10 @@ cc_benchmark { "fluoride_defaults", ], host_supported: true, - include_dirs: ["packages/modules/Bluetooth/system"], + include_dirs: [ + "packages/modules/Bluetooth/system", + "packages/modules/Bluetooth/system/gd", + ], srcs: [ "benchmark/thread_performance_benchmark.cc", ], diff --git a/system/common/BUILD.gn b/system/common/BUILD.gn index b3cb62992a0fff0c2ec3cab06726bbd262f612c4..58c3a9d40abdb633c1fa35f8439d16195c216575 100644 --- a/system/common/BUILD.gn +++ b/system/common/BUILD.gn @@ -30,7 +30,6 @@ static_library("common") { "//bt/system/", "//bt/system/stack/include", "//bt/system/linux_include", - "//bt/system/internal_include", ] deps = [ @@ -38,7 +37,10 @@ static_library("common") { "//bt/system/gd/rust/shim:init_flags_bridge_header", ] - configs += [ "//bt/system:target_defaults" ] + configs += [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] } if (use.test) { diff --git a/system/common/address_obfuscator.cc b/system/common/address_obfuscator.cc index 94f0afa6411deb2bef497ec0da2bfbed5b57e536..ea719c0823f880de85f3dbe21d49a879db56b557 100644 --- a/system/common/address_obfuscator.cc +++ b/system/common/address_obfuscator.cc @@ -23,6 +23,7 @@ #include +#include "include/check.h" #include "internal_include/bt_trace.h" #include "types/raw_address.h" diff --git a/system/common/address_obfuscator.h b/system/common/address_obfuscator.h index 9118b07af86f9c721d96985af472c3fe4885be04..fef975321d7390c52ce1dcdcc080f1c28b2e4460 100644 --- a/system/common/address_obfuscator.h +++ b/system/common/address_obfuscator.h @@ -21,7 +21,7 @@ #include #include -#include "gd/hci/octets.h" +#include "hci/octets.h" #include "raw_address.h" namespace bluetooth { diff --git a/system/common/base_bind_unittest.cc b/system/common/base_bind_unittest.cc index a5dc1574c029e2498b608cbd9d7ead1ba0bb6b67..7c77f97f91ad47e4267a7e5c34b20154a7704a14 100644 --- a/system/common/base_bind_unittest.cc +++ b/system/common/base_bind_unittest.cc @@ -24,7 +24,7 @@ #include #include -#include "osi/include/log.h" +#include "os/log.h" class BaseBindThreadTest : public ::testing::Test { public: diff --git a/system/common/benchmark/thread_performance_benchmark.cc b/system/common/benchmark/thread_performance_benchmark.cc index 0f718801e9d8fca03bf86158853f48812ff67521..f6a287d3d00b12d33bdb1b3cbc124d21ae63d861 100644 --- a/system/common/benchmark/thread_performance_benchmark.cc +++ b/system/common/benchmark/thread_performance_benchmark.cc @@ -19,12 +19,14 @@ #include #include #include + #include #include #include #include "abstract_message_loop.h" #include "common/message_loop_thread.h" +#include "include/check.h" #include "osi/include/fixed_queue.h" #include "osi/include/thread.h" diff --git a/system/common/message_loop_thread.cc b/system/common/message_loop_thread.cc index e6921cc0ad7b76873c8b68a097c32faf2ca5cb4d..faca7f075452b04c6986bc1c651b2082de17bbfb 100644 --- a/system/common/message_loop_thread.cc +++ b/system/common/message_loop_thread.cc @@ -16,22 +16,32 @@ #include "message_loop_thread.h" +#include +#include #include #include +#include #include #include +#include +#include +#include #include -#include "gd/common/init_flags.h" -#include "osi/include/log.h" - namespace bluetooth { - namespace common { static constexpr int kRealTimeFifoSchedulingPriority = 1; +static base::TimeDelta timeDeltaFromMicroseconds(std::chrono::microseconds t) { +#if BASE_VER < 931007 + return base::TimeDelta::FromMicroseconds(t.count()); +#else + return base::Microseconds(t.count()); +#endif +} + MessageLoopThread::MessageLoopThread(const std::string& thread_name) : thread_name_(thread_name), message_loop_(nullptr), @@ -62,12 +72,13 @@ void MessageLoopThread::StartUp() { bool MessageLoopThread::DoInThread(const base::Location& from_here, base::OnceClosure task) { - return DoInThreadDelayed(from_here, std::move(task), base::TimeDelta()); + return DoInThreadDelayed(from_here, std::move(task), + std::chrono::microseconds(0)); } bool MessageLoopThread::DoInThreadDelayed(const base::Location& from_here, base::OnceClosure task, - const base::TimeDelta& delay) { + std::chrono::microseconds delay) { std::lock_guard api_lock(api_mutex_); if (message_loop_ == nullptr) { @@ -75,8 +86,8 @@ bool MessageLoopThread::DoInThreadDelayed(const base::Location& from_here, << ", from " << from_here.ToString(); return false; } - if (!message_loop_->task_runner()->PostDelayedTask(from_here, std::move(task), - delay)) { + if (!message_loop_->task_runner()->PostDelayedTask( + from_here, std::move(task), timeDeltaFromMicroseconds(delay))) { LOG(ERROR) << __func__ << ": failed to post task to message loop for thread " << *this << ", from " << from_here.ToString(); @@ -205,5 +216,4 @@ void MessageLoopThread::Post(base::OnceClosure closure) { } } // namespace common - } // namespace bluetooth diff --git a/system/common/message_loop_thread.h b/system/common/message_loop_thread.h index 2f0c5a35176082a8d9682c5af3538a3e81ef6553..525fcf2ba7088f545f0d7fecf77c7228a4ea704a 100644 --- a/system/common/message_loop_thread.h +++ b/system/common/message_loop_thread.h @@ -27,8 +27,8 @@ #include #include "abstract_message_loop.h" -#include "gd/common/contextual_callback.h" -#include "gd/common/i_postable_context.h" +#include "common/contextual_callback.h" +#include "common/i_postable_context.h" namespace bluetooth { @@ -166,48 +166,40 @@ class MessageLoopThread final : public IPostableContext { * scheduled */ bool DoInThreadDelayed(const base::Location& from_here, - base::OnceClosure task, const base::TimeDelta& delay); + base::OnceClosure task, + std::chrono::microseconds delay); /** * Wrapper around DoInThread without a location. */ void Post(base::OnceClosure closure) override; template - common::ContextualOnceCallback> - BindOnce(Functor&& functor, Args&&... args) { - return common::ContextualOnceCallback< - common::MakeUnboundRunType>( + auto BindOnce(Functor&& functor, Args&&... args) { + return common::ContextualOnceCallback( common::BindOnce(std::forward(functor), std::forward(args)...), this); } template - common::ContextualOnceCallback< - common::MakeUnboundRunType> - BindOnceOn(T* obj, Functor&& functor, Args&&... args) { - return common::ContextualOnceCallback< - common::MakeUnboundRunType>( + auto BindOnceOn(T* obj, Functor&& functor, Args&&... args) { + return common::ContextualOnceCallback( common::BindOnce(std::forward(functor), common::Unretained(obj), std::forward(args)...), this); } template - common::ContextualCallback> Bind( - Functor&& functor, Args&&... args) { - return common::ContextualCallback< - common::MakeUnboundRunType>( + auto Bind(Functor&& functor, Args&&... args) { + return common::ContextualCallback( common::Bind(std::forward(functor), std::forward(args)...), this); } template - common::ContextualCallback> - BindOn(T* obj, Functor&& functor, Args&&... args) { - return common::ContextualCallback< - common::MakeUnboundRunType>( + auto BindOn(T* obj, Functor&& functor, Args&&... args) { + return common::ContextualCallback( common::Bind(std::forward(functor), common::Unretained(obj), std::forward(args)...), this); diff --git a/system/common/message_loop_thread_unittest.cc b/system/common/message_loop_thread_unittest.cc index 80d64023efae13220457aded98ac0aa3116be090..74d628784eb7bf5500412acc7c98fcf957940280 100644 --- a/system/common/message_loop_thread_unittest.cc +++ b/system/common/message_loop_thread_unittest.cc @@ -119,8 +119,8 @@ TEST_F(MessageLoopThreadTest, test_do_in_thread_before_start) { std::string name = "test_thread"; MessageLoopThread message_loop_thread(name); ASSERT_FALSE(message_loop_thread.DoInThread( - FROM_HERE, base::Bind(&MessageLoopThreadTest::ShouldNotHappen, - base::Unretained(this)))); + FROM_HERE, base::BindOnce(&MessageLoopThreadTest::ShouldNotHappen, + base::Unretained(this)))); } TEST_F(MessageLoopThreadTest, test_do_in_thread_after_shutdown) { @@ -129,8 +129,8 @@ TEST_F(MessageLoopThreadTest, test_do_in_thread_after_shutdown) { message_loop_thread.StartUp(); message_loop_thread.ShutDown(); ASSERT_FALSE(message_loop_thread.DoInThread( - FROM_HERE, base::Bind(&MessageLoopThreadTest::ShouldNotHappen, - base::Unretained(this)))); + FROM_HERE, base::BindOnce(&MessageLoopThreadTest::ShouldNotHappen, + base::Unretained(this)))); } TEST_F(MessageLoopThreadTest, test_name) { diff --git a/system/common/metrics.cc b/system/common/metrics.cc index b243fd78b7f1d98afcf8d94c087959c7fd8bca98..b9a1e2d180ac514b784df35696e5cfd2a0543558 100644 --- a/system/common/metrics.cc +++ b/system/common/metrics.cc @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -36,13 +35,13 @@ #include "address_obfuscator.h" #include "bluetooth/metrics/bluetooth.pb.h" -#include "gd/metrics/metrics_state.h" -#include "gd/hci/address.h" -#include "gd/os/metrics.h" +#include "hci/address.h" +#include "internal_include/bt_trace.h" #include "leaky_bonded_queue.h" #include "metric_id_allocator.h" +#include "metrics/metrics_state.h" +#include "os/metrics.h" #include "osi/include/osi.h" -#include "stack/include/btm_api_types.h" #include "time_util.h" #include "types/raw_address.h" diff --git a/system/common/metrics.h b/system/common/metrics.h index 273cbdab194d26b07e8dcaa8f03ffe20cdb78842..182d0b03879b4485cd6888cafa4f42ed8ac1fc5d 100644 --- a/system/common/metrics.h +++ b/system/common/metrics.h @@ -28,9 +28,9 @@ #include #include -#include "gd/os/metrics.h" -#include "types/raw_address.h" #include "hci/address.h" +#include "os/metrics.h" +#include "types/raw_address.h" namespace bluetooth { diff --git a/system/common/repeating_timer.cc b/system/common/repeating_timer.cc index 11762264e058602e5aac7bfed2ca86b5649f90a0..9abea46b725c47f57e05c61930ec356a5fe5b968 100644 --- a/system/common/repeating_timer.cc +++ b/system/common/repeating_timer.cc @@ -26,11 +26,8 @@ namespace bluetooth { namespace common { -#if BASE_VER < 931007 -constexpr base::TimeDelta kMinimumPeriod = base::TimeDelta::FromMicroseconds(1); -#else -constexpr base::TimeDelta kMinimumPeriod = base::Microseconds(1); -#endif +constexpr std::chrono::microseconds kMinimumPeriod = + std::chrono::microseconds(1); // This runs on user thread RepeatingTimer::~RepeatingTimer() { @@ -43,15 +40,16 @@ RepeatingTimer::~RepeatingTimer() { // This runs on user thread bool RepeatingTimer::SchedulePeriodic( const base::WeakPtr& thread, - const base::Location& from_here, base::Closure task, - base::TimeDelta period) { + const base::Location& from_here, base::RepeatingClosure task, + std::chrono::microseconds period) { if (period < kMinimumPeriod) { - LOG(ERROR) << __func__ << ": period must be at least " << kMinimumPeriod; + LOG(ERROR) << __func__ << ": period must be at least " + << kMinimumPeriod.count(); return false; } uint64_t time_now_us = time_get_os_boottime_us(); - uint64_t time_next_task_us = time_now_us + period.InMicroseconds(); + uint64_t time_next_task_us = time_now_us + period.count(); std::lock_guard api_lock(api_mutex_); if (thread == nullptr) { LOG(ERROR) << __func__ << ": thread must be non-null"; @@ -67,11 +65,7 @@ bool RepeatingTimer::SchedulePeriodic( uint64_t time_until_next_us = time_next_task_us - time_get_os_boottime_us(); if (!thread->DoInThreadDelayed( from_here, task_wrapper_.callback(), -#if BASE_VER < 931007 - base::TimeDelta::FromMicroseconds(time_until_next_us))) { -#else - base::Microseconds(time_until_next_us))) { -#endif + std::chrono::microseconds(time_until_next_us))) { LOG(ERROR) << __func__ << ": failed to post task to message loop for thread " << *thread << ", from " << from_here.ToString(); @@ -124,7 +118,7 @@ void RepeatingTimer::CancelClosure(std::promise promise) { #else task_ = base::NullCallback(); #endif - period_ = base::TimeDelta(); + period_ = std::chrono::microseconds(0); expected_time_next_task_us_ = 0; promise.set_value(); } @@ -146,7 +140,7 @@ void RepeatingTimer::RunTask() { base::PlatformThread::CurrentId()) << ": task must run on message loop thread"; - int64_t period_us = period_.InMicroseconds(); + int64_t period_us = period_.count(); expected_time_next_task_us_ += period_us; uint64_t time_now_us = time_get_os_boottime_us(); int64_t remaining_time_us = expected_time_next_task_us_ - time_now_us; @@ -157,21 +151,17 @@ void RepeatingTimer::RunTask() { } message_loop_thread_->DoInThreadDelayed( FROM_HERE, task_wrapper_.callback(), -#if BASE_VER < 931007 - base::TimeDelta::FromMicroseconds(remaining_time_us)); -#else - base::Microseconds(remaining_time_us)); -#endif + std::chrono::microseconds(remaining_time_us)); uint64_t time_before_task_us = time_get_os_boottime_us(); task_.Run(); uint64_t time_after_task_us = time_get_os_boottime_us(); auto task_time_us = static_cast(time_after_task_us - time_before_task_us); - if (task_time_us > period_.InMicroseconds()) { + if (task_time_us > period_.count()) { LOG(ERROR) << __func__ << ": Periodic task execution took " << task_time_us - << " microseconds, longer than interval " - << period_.InMicroseconds() << " microseconds"; + << " microseconds, longer than interval " << period_.count() + << " microseconds"; } } diff --git a/system/common/repeating_timer.h b/system/common/repeating_timer.h index 9319fa98806c1bb2b5f2e3b779f5c374287a5e04..6398af224b225d8447ce9a76f57dd6a3cec86ee6 100644 --- a/system/common/repeating_timer.h +++ b/system/common/repeating_timer.h @@ -19,8 +19,8 @@ #include #include #include -#include +#include #include namespace bluetooth { @@ -58,7 +58,8 @@ class RepeatingTimer final { */ bool SchedulePeriodic(const base::WeakPtr& thread, const base::Location& from_here, - base::RepeatingClosure task, base::TimeDelta period); + base::RepeatingClosure task, + std::chrono::microseconds period); /** * Post an event which cancels the current task asynchronously @@ -81,7 +82,7 @@ class RepeatingTimer final { base::WeakPtr message_loop_thread_; base::CancelableClosure task_wrapper_; base::RepeatingClosure task_; - base::TimeDelta period_; + std::chrono::microseconds period_; uint64_t expected_time_next_task_us_; // Using clock boot time in time_util.h mutable std::recursive_mutex api_mutex_; void CancelHelper(std::promise promise); diff --git a/system/common/repeating_timer_unittest.cc b/system/common/repeating_timer_unittest.cc index 65bee83b7683d4a1a4f2d6878ec33b6997e4a657..510e2483fed6a15232991d551a8e9f8e0531e415 100644 --- a/system/common/repeating_timer_unittest.cc +++ b/system/common/repeating_timer_unittest.cc @@ -86,11 +86,7 @@ class RepeatingTimerTest : public ::testing::Test { base::Unretained(this), start_time, interval_between_tasks_ms, scheduled_tasks, task_length_ms, promise_), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(interval_between_tasks_ms)); -#else - base::Milliseconds(interval_between_tasks_ms)); -#endif + std::chrono::milliseconds(interval_between_tasks_ms)); future.get(); timer_->CancelAndWait(); } @@ -147,11 +143,7 @@ TEST_F(RepeatingTimerTest, periodic_run) { message_loop_thread.GetWeakPtr(), FROM_HERE, base::BindRepeating(&RepeatingTimerTest::IncreaseTaskCounter, base::Unretained(this), num_tasks, promise_), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(delay_ms)); -#else - base::Milliseconds(delay_ms)); -#endif + std::chrono::milliseconds(delay_ms)); future.get(); ASSERT_GE(counter_, num_tasks); timer_->CancelAndWait(); @@ -167,11 +159,7 @@ TEST_F(RepeatingTimerTest, schedule_periodic_task_zero_interval) { message_loop_thread.GetWeakPtr(), FROM_HERE, base::BindRepeating(&RepeatingTimerTest::ShouldNotHappen, base::Unretained(this)), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(interval_ms))); -#else - base::Milliseconds(interval_ms))); -#endif + std::chrono::milliseconds(interval_ms))); std::this_thread::sleep_for(std::chrono::milliseconds(delay_error_ms)); } @@ -185,11 +173,7 @@ TEST_F(RepeatingTimerTest, periodic_delete_without_cancel) { message_loop_thread.GetWeakPtr(), FROM_HERE, base::BindRepeating(&RepeatingTimerTest::ShouldNotHappen, base::Unretained(this)), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(delay_ms)); -#else - base::Milliseconds(delay_ms)); -#endif + std::chrono::milliseconds(delay_ms)); delete timer_; timer_ = nullptr; std::this_thread::sleep_for(std::chrono::milliseconds(delay_error_ms)); @@ -202,11 +186,7 @@ TEST_F(RepeatingTimerTest, cancel_single_task_near_fire_no_race_condition) { uint32_t delay_ms = 5; timer_->SchedulePeriodic(message_loop_thread.GetWeakPtr(), FROM_HERE, base::DoNothing(), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(delay_ms)); -#else - base::Milliseconds(delay_ms)); -#endif + std::chrono::milliseconds(delay_ms)); std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); timer_->CancelAndWait(); } @@ -223,11 +203,7 @@ TEST_F(RepeatingTimerTest, cancel_periodic_task) { message_loop_thread.GetWeakPtr(), FROM_HERE, base::BindRepeating(&RepeatingTimerTest::IncreaseTaskCounter, base::Unretained(this), num_tasks, promise_), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(delay_ms)); -#else - base::Milliseconds(delay_ms)); -#endif + std::chrono::milliseconds(delay_ms)); future.wait(); timer_->CancelAndWait(); std::this_thread::sleep_for( @@ -264,11 +240,7 @@ TEST_F(RepeatingTimerTest, message_loop_thread.GetWeakPtr(), FROM_HERE, base::BindRepeating(&RepeatingTimerTest::IncreaseTaskCounter, base::Unretained(this), num_tasks, promise_), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(delay_ms)); -#else - base::Milliseconds(delay_ms)); -#endif + std::chrono::milliseconds(delay_ms)); future.wait(); message_loop_thread.ShutDown(); std::this_thread::sleep_for( diff --git a/system/common/state_machine.h b/system/common/state_machine.h index 62d92d2636f2f4846adf103389de48d06b070968..8a0a64645593eee4e591a518eb219e456f567c13 100644 --- a/system/common/state_machine.h +++ b/system/common/state_machine.h @@ -16,10 +16,12 @@ #pragma once +#include + #include #include -#include +#include "include/check.h" namespace bluetooth { diff --git a/system/common/stop_watch_legacy.cc b/system/common/stop_watch_legacy.cc index f7d8ba959869c0cf5699fe6af859ce443676c89d..6b783cba0350aa224e5ce55295d0ba77abd72e9b 100644 --- a/system/common/stop_watch_legacy.cc +++ b/system/common/stop_watch_legacy.cc @@ -18,13 +18,15 @@ #include "common/stop_watch_legacy.h" +#include + #include #include #include #include -#include -#include "osi/include/log.h" +#include "common/init_flags.h" +#include "os/log.h" namespace bluetooth { namespace common { diff --git a/system/common/test/thread_performance_test.cc b/system/common/test/thread_performance_test.cc index 1e764f8dac16c5dd24a82b55707ae683f6d03edd..84eecdf216989bfc570440c42eebca455db611ac 100644 --- a/system/common/test/thread_performance_test.cc +++ b/system/common/test/thread_performance_test.cc @@ -281,8 +281,8 @@ class WorkerThreadPerformanceTest : public PerformanceTest { new MessageLoopThread("WorkerThreadPerformanceTest thread"); worker_thread_->StartUp(); worker_thread_->DoInThread( - FROM_HERE, base::Bind(&std::promise::set_value, - base::Unretained(set_up_promise_.get()))); + FROM_HERE, base::BindOnce(&std::promise::set_value, + base::Unretained(set_up_promise_.get()))); set_up_future.wait(); } @@ -307,7 +307,7 @@ TEST_F(WorkerThreadPerformanceTest, worker_thread_speed_test) { for (int i = 0; i < NUM_MESSAGES_TO_SEND; i++) { fixed_queue_enqueue(bt_msg_queue_, (void*)&g_counter); worker_thread_->DoInThread( - FROM_HERE, base::Bind(&callback_batch, bt_msg_queue_, nullptr)); + FROM_HERE, base::BindOnce(&callback_batch, bt_msg_queue_, nullptr)); } counter_future.wait(); diff --git a/system/conf/interop_database.conf b/system/conf/interop_database.conf index 84853bc01a883bc5ab2dd46893078131824c3a7b..ecc878e617e95303c2fca5e2c06d9a9aa7967f40 100644 --- a/system/conf/interop_database.conf +++ b/system/conf/interop_database.conf @@ -856,3 +856,4 @@ fc:3f:a6 = Address_Based # SMP key exchange completed. [INTEROP_SUSPEND_ATT_TRAFFIC_DURING_PAIRING] ORN = Name_Based +EPG = Name_Based diff --git a/system/device/Android.bp b/system/device/Android.bp index 5b6216d1836131c479f3b439a9f0d13ab80d7c6b..313ce17ace84167eefdce972a00845a5e0d78f1e 100644 --- a/system/device/Android.bp +++ b/system/device/Android.bp @@ -18,7 +18,6 @@ cc_library_static { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ], srcs: [ @@ -39,6 +38,7 @@ cc_library_static { static_libs: [ "bluetooth_flags_c_lib", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt_shim_bridge", "libflatbuffers-cpp", "server_configurable_flags", @@ -59,11 +59,13 @@ cc_test { "test/interop_test.cc", ], shared_libs: [ + "libbase", "liblog", ], static_libs: [ "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt_shim_bridge", "libbt_shim_ffi", "libbtcore", @@ -94,11 +96,13 @@ cc_test { "test/device_iot_config_test.cc", ], shared_libs: [ + "libbase", "libdl", "liblog", ], static_libs: [ "libbluetooth-types", + "libbluetooth_log", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", diff --git a/system/device/BUILD.gn b/system/device/BUILD.gn index 8b1ffd45d04e8b2e43cff763dab45c4d9ffa8446..1d8c938099742debc5c2881c60b8a7d17ef1919e 100644 --- a/system/device/BUILD.gn +++ b/system/device/BUILD.gn @@ -25,12 +25,12 @@ static_library("device") { include_dirs = [ "//bt/system/", - "//bt/system/internal_include", "//bt/system/stack/include", ] configs += [ "//bt/system:target_defaults", + "//bt/system/log:log_defaults", ] deps = [ diff --git a/system/device/fuzzer/Android.bp b/system/device/fuzzer/Android.bp index 35cf3d092dc1009c4b9388d04e11320b2a52810c..e600270558ae21fb09cf7d92e793092850c3e885 100644 --- a/system/device/fuzzer/Android.bp +++ b/system/device/fuzzer/Android.bp @@ -34,6 +34,7 @@ cc_fuzz { "libbluetooth_headers", ], shared_libs: [ + "libbase", "libdl", "liblog", "server_configurable_flags", @@ -46,6 +47,7 @@ cc_fuzz { "libbluetooth-types", "libbluetooth_gd", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt_shim_bridge", "libbt_shim_ffi", "libbtcore", @@ -59,9 +61,6 @@ cc_fuzz { "packages/modules/Bluetooth/system/device/include", "packages/modules/Bluetooth/system/gd", ], - cflags: [ - "-DBUILDCFG", - ], fuzz_config: { cc: ["android-bluetooth-security@google.com"], componentid: 27441, diff --git a/system/device/include/controller.h b/system/device/include/controller.h index bddf06bcba202e4a9aa3f2a9b9042a969faaaafb..3c04d137b3816fb7592e45e8c28d01028fa8d7f8 100644 --- a/system/device/include/controller.h +++ b/system/device/include/controller.h @@ -36,62 +36,31 @@ typedef struct controller_t { const uint8_t* (*get_ble_supported_states)(void); - bool (*supports_simple_pairing)(void); - bool (*supports_secure_connections)(void); - bool (*supports_simultaneous_le_bredr)(void); - bool (*supports_reading_remote_extended_features)(void); - bool (*supports_interlaced_inquiry_scan)(void); - bool (*supports_rssi_with_inquiry_results)(void); - bool (*supports_extended_inquiry_response)(void); - bool (*supports_central_peripheral_role_switch)(void); bool (*supports_enhanced_setup_synchronous_connection)(void); bool (*supports_enhanced_accept_synchronous_connection)(void); - bool (*supports_3_slot_packets)(void); - bool (*supports_5_slot_packets)(void); - bool (*supports_classic_2m_phy)(void); - bool (*supports_classic_3m_phy)(void); - bool (*supports_3_slot_edr_packets)(void); - bool (*supports_5_slot_edr_packets)(void); - bool (*supports_sco)(void); - bool (*supports_hv2_packets)(void); - bool (*supports_hv3_packets)(void); - bool (*supports_ev3_packets)(void); - bool (*supports_ev4_packets)(void); - bool (*supports_ev5_packets)(void); - bool (*supports_esco_2m_phy)(void); - bool (*supports_esco_3m_phy)(void); - bool (*supports_3_slot_esco_edr_packets)(void); - bool (*supports_role_switch)(void); - bool (*supports_hold_mode)(void); - bool (*supports_sniff_mode)(void); - bool (*supports_park_mode)(void); - bool (*supports_non_flushable_pb)(void); - bool (*supports_sniff_subrating)(void); - bool (*supports_encryption_pause)(void); bool (*supports_configure_data_path)(void); bool (*supports_set_min_encryption_key_size)(void); bool (*supports_read_encryption_key_size)(void); - bool (*supports_ble)(void); - bool (*supports_ble_packet_extension)(void); - bool (*supports_ble_connection_parameters_request)(void); - bool (*supports_ble_privacy)(void); + bool (*SupportsBle)(void); + bool (*SupportsBleDataPacketLengthExtension)(void); + bool (*SupportsBleConnectionParametersRequest)(void); + bool (*SupportsBlePrivacy)(void); bool (*supports_ble_set_privacy_mode)(void); - bool (*supports_ble_2m_phy)(void); - bool (*supports_ble_coded_phy)(void); - bool (*supports_ble_extended_advertising)(void); - bool (*supports_ble_periodic_advertising)(void); - bool (*supports_ble_peripheral_initiated_feature_exchange)(void); - bool (*supports_ble_connection_parameter_request)(void); - bool (*supports_ble_periodic_advertising_sync_transfer_sender)(void); - bool (*supports_ble_periodic_advertising_sync_transfer_recipient)(void); - bool (*supports_ble_connected_isochronous_stream_central)(void); - bool (*supports_ble_connected_isochronous_stream_peripheral)(void); - bool (*supports_ble_isochronous_broadcaster)(void); - bool (*supports_ble_synchronized_receiver)(void); - - bool (*supports_ble_connection_subrating)(void); - bool (*supports_ble_connection_subrating_host)(void); + bool (*SupportsBle2mPhy)(void); + bool (*SupportsBleCodedPhy)(void); + bool (*SupportsBleExtendedAdvertising)(void); + bool (*SupportsBlePeriodicAdvertising)(void); + bool (*SupportsBlePeripheralInitiatedFeaturesExchange)(void); + bool (*SupportsBlePeriodicAdvertisingSyncTransferSender)(void); + bool (*SupportsBlePeriodicAdvertisingSyncTransferRecipient)(void); + bool (*SupportsBleConnectedIsochronousStreamCentral)(void); + bool (*SupportsBleConnectedIsochronousStreamPeripheral)(void); + bool (*SupportsBleIsochronousBroadcaster)(void); + bool (*SupportsBleSynchronizedReceiver)(void); + + bool (*SupportsBleConnectionSubrating)(void); + bool (*SupportsBleConnectionSubratingHost)(void); // Get the cached acl data sizes for the controller. uint16_t (*get_acl_data_size_classic)(void); diff --git a/system/device/include/device_iot_config.h b/system/device/include/device_iot_config.h index 060b0bdd0d84442e2152bac1f0dd55cfb5f3753a..74ef574dd9e56ea872e7013a519e3365de3c4d10 100644 --- a/system/device/include/device_iot_config.h +++ b/system/device/include/device_iot_config.h @@ -22,9 +22,10 @@ #include #include -#include "bt_target.h" +#include + #include "device_iot_conf_defs.h" -#include "raw_address.h" +#include "internal_include/bt_target.h" static const char DEVICE_IOT_CONFIG_MODULE[] = "device_iot_config_module"; diff --git a/system/device/include/interop.h b/system/device/include/interop.h index a1c5b243afc119664184870a89b34a3bdc80a7e4..f763fd79fbfd03a280990cc612d7be5339e7de07 100644 --- a/system/device/include/interop.h +++ b/system/device/include/interop.h @@ -343,6 +343,10 @@ typedef enum { // It is required for some devices to provide sound. INTEROP_INSERT_CALL_WHEN_SCO_START, + // Some device need the host to delay authentication process to avoid + // collision. + INTEROP_DELAY_AUTH, + END_OF_INTEROP_LIST } interop_feature_t; diff --git a/system/device/src/device_iot_config.cc b/system/device/src/device_iot_config.cc index ff0a759d30389a7c98bced43306ff686d4e55bb2..7517366fab2580c5886c00d0deb3157b8cfa5b12 100644 --- a/system/device/src/device_iot_config.cc +++ b/system/device/src/device_iot_config.cc @@ -16,7 +16,7 @@ * limitations under the License. * ******************************************************************************/ -#include "bt_target.h" +#include "internal_include/bt_target.h" #define LOG_TAG "device_iot_config" #include @@ -29,19 +29,15 @@ #include #include -#include "btcore/include/module.h" -#include "btif/include/btif_api.h" -#include "btif/include/btif_util.h" #include "common/init_flags.h" #include "device/include/device_iot_config.h" #include "device_iot_config_int.h" +#include "include/check.h" +#include "os/log.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "osi/include/config.h" -#include "osi/include/log.h" -#include "osi/include/osi.h" -#include "osi/include/properties.h" enum ConfigSource device_iot_config_source = NOT_LOADED; diff --git a/system/device/src/device_iot_config_int.cc b/system/device/src/device_iot_config_int.cc index c99b269d5eec274ce0027c2b9764b0a20b00540c..fc4d1a43e04980294231ecbdb3488196ba8e659c 100644 --- a/system/device/src/device_iot_config_int.cc +++ b/system/device/src/device_iot_config_int.cc @@ -21,7 +21,6 @@ #include "device_iot_config_int.h" #include -#include #include #include #include @@ -31,17 +30,17 @@ #include #include "btcore/include/module.h" -#include "btif/include/btif_api.h" -#include "btif/include/btif_util.h" +#include "btif/include/btif_common.h" #include "common/init_flags.h" #include "device/include/device_iot_config.h" +#include "include/check.h" +#include "os/log.h" #include "osi/include/alarm.h" -#include "osi/include/allocator.h" -#include "osi/include/compat.h" #include "osi/include/config.h" -#include "osi/include/log.h" +#include "osi/include/future.h" #include "osi/include/osi.h" #include "osi/include/properties.h" +#include "types/raw_address.h" extern enum ConfigSource device_iot_config_source; @@ -324,4 +323,4 @@ bool device_iot_config_is_factory_reset(void) { void device_iot_config_delete_files(void) { remove(IOT_CONFIG_FILE_PATH); remove(IOT_CONFIG_BACKUP_PATH); -} \ No newline at end of file +} diff --git a/system/device/src/esco_parameters.cc b/system/device/src/esco_parameters.cc index 684450a80bc3968e74b8919c7ad0b6213338ce52..15f13970871c69b7affa94a98f0979367ab8b1b0 100644 --- a/system/device/src/esco_parameters.cc +++ b/system/device/src/esco_parameters.cc @@ -22,7 +22,7 @@ #include "base/logging.h" #include "check.h" -#include "hci/controller.h" +#include "hci/controller_interface.h" #include "main/shim/entry.h" static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { @@ -339,8 +339,8 @@ enh_esco_params_t esco_parameters_for_codec(esco_codec_t codec, bool offload) { codecIds = controller->GetLocalSupportedBrEdrCodecIds(); if (std::find(codecIds.begin(), codecIds.end(), ESCO_CODING_FORMAT_LC3) == codecIds.end()) { - LOG_INFO("BT controller does not support LC3 codec, use DSP codec"); if (codec == ESCO_CODEC_LC3_T1 || codec == ESCO_CODEC_LC3_T2) { + LOG_INFO("BT controller does not support LC3 codec, use DSP codec"); enh_esco_params_t param = default_esco_parameters[codec]; param.input_coding_format.coding_format = ESCO_CODING_FORMAT_LC3; param.output_coding_format.coding_format = ESCO_CODING_FORMAT_LC3; diff --git a/system/device/src/interop.cc b/system/device/src/interop.cc index 5a4700e4bd2c6c6ac1d022f5e4a16a18d20d8bb1..6058a481f88e0d8c0abdb995968598e6a4ece295 100644 --- a/system/device/src/interop.cc +++ b/system/device/src/interop.cc @@ -42,11 +42,11 @@ #include "check.h" #include "device/include/interop_config.h" #include "device/include/interop_database.h" +#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" #include "osi/include/config.h" #include "osi/include/list.h" -#include "osi/include/log.h" #include "osi/include/osi.h" #include "types/raw_address.h" @@ -394,6 +394,7 @@ static const char* interop_feature_string_(const interop_feature_t feature) { CASE_RETURN_STR(INTEROP_IGNORE_DISC_BEFORE_SIGNALLING_TIMEOUT); CASE_RETURN_STR(INTEROP_SUSPEND_ATT_TRAFFIC_DURING_PAIRING); CASE_RETURN_STR(INTEROP_INSERT_CALL_WHEN_SCO_START); + CASE_RETURN_STR(INTEROP_DELAY_AUTH); } return UNKNOWN_INTEROP_FEATURE; } diff --git a/system/embdrv/sbc/BUILD.gn b/system/embdrv/sbc/BUILD.gn index 061cd8138239a94d70040c03be7aedfbfffd936b..4b31762babe59bd5d9d0f8c6858d4c9fe65e157e 100644 --- a/system/embdrv/sbc/BUILD.gn +++ b/system/embdrv/sbc/BUILD.gn @@ -51,7 +51,6 @@ source_set("sbc_encoder") { include_dirs = [ "encoder/include", - "//bt/system/internal_include", "//bt/system/stack/include", ] diff --git a/system/embdrv/sbc/encoder/Android.bp b/system/embdrv/sbc/encoder/Android.bp index e1140664898659f8456521d4fc7b29bcb4e4a768..5a4cc5d80cfd9153a7b22d62aba71db55e109520 100644 --- a/system/embdrv/sbc/encoder/Android.bp +++ b/system/embdrv/sbc/encoder/Android.bp @@ -26,7 +26,6 @@ cc_library_static { ], include_dirs: [ "packages/modules/Bluetooth/system", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ], host_supported: true, diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 07a5dcafbd26c5fc5c94b21d89de948c8c137c77..ef881e6918e9ed1dde02b3c4703779a84f3d8d70 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -143,12 +143,11 @@ cc_defaults { ":BluetoothOsSources", ":BluetoothPacketSources", ":BluetoothSecuritySources", - ":BluetoothShimSources", ":BluetoothStorageSources", ":BluetoothSyspropsSources", "module.cc", "module_dumper.cc", - "module_dumper_flatbuffer.cc", + "module_state_dumper.cc", "stack_manager.cc", ], generated_headers: [ @@ -176,10 +175,12 @@ cc_defaults { "libbluetooth-protos", "libbluetooth-types", "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbluetooth_rust_interop", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", + "libcom.android.sysprop.bluetooth.wrapped", "libosi", "server_configurable_flags", ], @@ -205,6 +206,25 @@ cc_library { static_libs: ["libchrome"], } +cc_library_static { + name: "libbluetooth-gdx", + defaults: [ + "libbluetooth_gd_defaults", + ], + srcs: [ + ":BluetoothDiscoverySources", + ":BluetoothShimSources", + ], + include_dirs: [ + "packages/modules/Bluetooth/system", + ], + apex_available: [ + "com.android.btservices", + ], + min_sdk_version: "31", + static_libs: ["libchrome"], +} + cc_library { name: "libbluetooth_gd_fuzzing", defaults: [ @@ -287,21 +307,25 @@ cc_binary { static_libs: [ "breakpad_client", "libbluetooth-dumpsys", + "libbluetooth-gdx", "libbluetooth-protos", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_rust_interop", "libbluetooth_smp_pdl", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", + "libcom.android.sysprop.bluetooth.wrapped", "libflatbuffers-cpp", "libosi", ], shared_libs: [ + "libPlatformProperties", "libcrypto", "libgrpc++", "libgrpc_wrap", @@ -345,6 +369,7 @@ cc_test { "mts_defaults", ], include_dirs: [ + "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/include", "packages/modules/Bluetooth/system/types", ], @@ -391,7 +416,6 @@ cc_test { srcs: [ ":BluetoothCommonTestSources", ":BluetoothCryptoToolboxTestSources", - ":BluetoothDumpsysTestSources", ":BluetoothHalTestSources", ":BluetoothHciUnitTestSources", ":BluetoothL2capUnitTestSources", @@ -399,7 +423,6 @@ cc_test { ":BluetoothOsTestSources", ":BluetoothPacketTestSources", ":BluetoothSecurityUnitTestSources", - ":BluetoothShimTestSources", ":BluetoothStorageUnitTestSources", "module_unittest.cc", "stack_manager_unittest.cc", @@ -411,29 +434,28 @@ cc_test { "BluetoothGeneratedDumpsysTestData_h", ], static_libs: [ - "libbluetooth-dumpsys", - "libbluetooth-dumpsys-test", - "libbluetooth-dumpsys-unittest", "libbluetooth-protos", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd_unit_tests", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_rust_interop", "libbluetooth_smp_pdl", "libbt-platform-protos-lite", - "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", "libc++fs", "libchrome", + "libcom.android.sysprop.bluetooth.wrapped", "libflagtest", "libflatbuffers-cpp", "libgmock", "libosi", ], shared_libs: [ + "libPlatformProperties", "libbase", "libcrypto", "server_configurable_flags", @@ -459,8 +481,14 @@ cc_test { ], host_supported: true, srcs: [ + ":BluetoothDiscoveryTestSources", + ":BluetoothDumpsysTestSources", + ":BluetoothShimTestSources", ":TestCommonMockFunctions", + "module_gdx_unittest.cc", + "module_jniloop_unittest.cc", "module_mainloop_unittest.cc", + "module_state_dumper_unittest.cc", ], generated_headers: [ "BluetoothGeneratedBundlerSchema_h_bfbs", @@ -469,14 +497,29 @@ cc_test { "BluetoothGeneratedDumpsysTestData_h", ], static_libs: [ + "libbase", + "libbluetooth-dumpsys", + "libbluetooth-dumpsys-test", + "libbluetooth-dumpsys-unittest", + "libbluetooth-gdx", + "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt-btu-main-thread", "libbt-common", + "libbt-jni-thread", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", "libevent", "libflatbuffers-cpp", + "libgmock", + "liblog", + "libosi", + "server_configurable_flags", + ], + shared_libs: [ + "libcrypto", ], sanitize: { address: true, @@ -508,6 +551,7 @@ cc_test { cfi: true, }, static_libs: [ + "libbluetooth_log", "libbluetooth_rust_interop", "libbt_shim_bridge", "libbt_shim_ffi", @@ -543,10 +587,12 @@ cc_defaults { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd_fuzzing", + "libbluetooth_log", "libbluetooth_rust_interop", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", + "libcom.android.sysprop.bluetooth.wrapped", "libgmock", "libgtest", "libosi", @@ -556,6 +602,7 @@ cc_defaults { "BluetoothGeneratedDumpsysDataSchema_h", ], shared_libs: [ + "libPlatformProperties", "libbase", "libcrypto", "libgrpc++", diff --git a/system/gd/BUILD.gn b/system/gd/BUILD.gn index ce72aae9292247402fa349b3d3740faba425fc77..8b5a0d0c090dcd9fec7809effb7469b310e4778b 100644 --- a/system/gd/BUILD.gn +++ b/system/gd/BUILD.gn @@ -35,7 +35,10 @@ config("gd_defaults") { ] include_dirs = [ "//bt/system/gd" ] - configs = [ "//bt/system:target_defaults" ] + configs = [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] } config("rust_defaults") { @@ -56,7 +59,7 @@ static_library("libbluetooth_gd") { sources = [ "module.cc", "module_dumper.cc", - "module_dumper_flatbuffer.cc", + "module_state_dumper.cc", "stack_manager.cc", ] diff --git a/system/gd/common/bind.h b/system/gd/common/bind.h index 5692e02b0386812e156ddbb9d25e68a129a65fd7..f653976431a2fbf50a55d95782cedf237ef1e396 100644 --- a/system/gd/common/bind.h +++ b/system/gd/common/bind.h @@ -24,19 +24,13 @@ namespace common { using base::Bind; using base::BindOnce; using base::IgnoreResult; -#if defined(BASE_VER) && BASE_VER >= 860220 -// TODO(b/189293646): find a way to avoid base::internal. -using base::internal::MakeUnboundRunType; -#else -using base::MakeUnboundRunType; -#endif using base::Owned; using base::Passed; using base::RetainedRef; using base::Unretained; template -inline base::Callback> BindOn(T* obj, Functor&& functor, Args&&... args) { +inline auto BindOn(T* obj, Functor&& functor, Args&&... args) { return common::Bind(std::forward(functor), common::Unretained(obj), std::forward(args)...); } diff --git a/system/gd/common/circular_buffer.h b/system/gd/common/circular_buffer.h index 46d6972fe1da6a2d2cdce7054213eff36b2eb465..64d7f2317321c7f55922722414d2f9c20ff6d8de 100644 --- a/system/gd/common/circular_buffer.h +++ b/system/gd/common/circular_buffer.h @@ -17,10 +17,11 @@ #pragma once #include +#include #include #include #include -#include +#include namespace bluetooth { namespace common { diff --git a/system/gd/common/contextual_callback.h b/system/gd/common/contextual_callback.h index af4929663a47bdf7098e5810959d2d202eb2be4c..6c8dcc1e1d3dbdfc68cd1c95409c3fadc4c26545 100644 --- a/system/gd/common/contextual_callback.h +++ b/system/gd/common/contextual_callback.h @@ -59,6 +59,10 @@ class ContextualOnceCallback { IPostableContext* context_; }; +template +ContextualOnceCallback(Callback&& callback, IPostableContext* context) + -> ContextualOnceCallback; + template class ContextualCallback; @@ -95,5 +99,9 @@ class ContextualCallback { IPostableContext* context_; }; +template +ContextualCallback(Callback&& callback, IPostableContext* context) + -> ContextualCallback; + } // namespace common } // namespace bluetooth diff --git a/system/gd/common/init_flags.h b/system/gd/common/init_flags.h index 9f0f12a1238c96c079fb29dd22cecb48787cdb3d..764ced5797380cfc25af1e29d5ec81ceb7959adb 100644 --- a/system/gd/common/init_flags.h +++ b/system/gd/common/init_flags.h @@ -34,14 +34,6 @@ class InitFlags final { init_flags::load(std::move(rusted_flags)); } - inline static int GetLogLevelForTag(const std::string& tag) { - return init_flags::get_log_level_for_tag(tag); - } - - inline static int GetDefaultLogLevel() { - return init_flags::get_default_log_level(); - } - inline static bool IsDeviceIotConfigLoggingEnabled() { return init_flags::device_iot_config_logging_is_enabled(); } diff --git a/system/gd/common/init_flags_test.cc b/system/gd/common/init_flags_test.cc index 8c4e357fcd310264ceed8e68248e6cbdd94cdd05..ea0019fdb433b834348c1f499b0f3316a6266024 100644 --- a/system/gd/common/init_flags_test.cc +++ b/system/gd/common/init_flags_test.cc @@ -20,8 +20,6 @@ #include -#include "os/log_tags.h" - using bluetooth::common::InitFlags; TEST(InitFlagsTest, test_enable_btm_flush_discovery_queue_on_search_cancel) { @@ -36,51 +34,6 @@ TEST(InitFlagsTest, test_leaudio_targeted_announcement_reconnection_mode) { ASSERT_TRUE(InitFlags::IsTargetedAnnouncementReconnectionMode()); } -TEST(InitFlagsTest, test_enable_debug_logging_for_all) { - const char* input[] = {"INIT_default_log_level=5", nullptr}; - InitFlags::Load(input); - ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_DEBUG); - ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_DEBUG); - ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_DEBUG); -} - -TEST(InitFlagsTest, test_enable_debug_logging_for_tags) { - const char* input[] = {"INIT_logging_debug_enabled_for_tags=foo,bar,hello", nullptr}; - InitFlags::Load(input); - ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_VERBOSE); - ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_VERBOSE); - ASSERT_EQ(InitFlags::GetLogLevelForTag("hello"), LOG_TAG_VERBOSE); - ASSERT_EQ(InitFlags::GetLogLevelForTag("Foo"), LOG_TAG_INFO); - ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_INFO); -} - -TEST(InitFlagsTest, test_disable_debug_logging_for_tags) { - const char* input[] = { - "INIT_logging_debug_disabled_for_tags=foo,bar,hello", - "INIT_default_log_level_str=LOG_DEBUG", - nullptr}; - InitFlags::Load(input); - ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_INFO); - ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_INFO); - ASSERT_EQ(InitFlags::GetLogLevelForTag("hello"), LOG_TAG_INFO); - ASSERT_EQ(InitFlags::GetLogLevelForTag("Foo"), LOG_TAG_DEBUG); - ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_DEBUG); -} - -TEST(InitFlagsTest, test_debug_logging_multiple_flags) { - const char* input[] = { - "INIT_logging_debug_enabled_for_tags=foo,hello", - "INIT_logging_debug_disabled_for_tags=foo,bar", - "INIT_default_log_level_str=LOG_WARN", - nullptr}; - InitFlags::Load(input); - ASSERT_EQ(InitFlags::GetLogLevelForTag("foo"), LOG_TAG_INFO); - ASSERT_EQ(InitFlags::GetLogLevelForTag("bar"), LOG_TAG_INFO); - ASSERT_EQ(InitFlags::GetLogLevelForTag("hello"), LOG_TAG_VERBOSE); - ASSERT_EQ(InitFlags::GetLogLevelForTag("Foo"), LOG_TAG_WARN); - ASSERT_EQ(InitFlags::GetDefaultLogLevel(), LOG_TAG_WARN); -} - TEST(InitFlagsTest, test_device_iot_config_logging_is_enabled) { const char* input[] = {"INIT_device_iot_config_logging=true", nullptr}; InitFlags::Load(input); diff --git a/system/gd/common/testing/wired_pair_of_bidi_queues.h b/system/gd/common/testing/wired_pair_of_bidi_queues.h index 92c6a1f109f24308faa82a0d4a9bc4a19e851b1e..b0603c57347dd0b29638b146b6f6d0785750c34e 100644 --- a/system/gd/common/testing/wired_pair_of_bidi_queues.h +++ b/system/gd/common/testing/wired_pair_of_bidi_queues.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include "common/bidi_queue.h" #include "os/handler.h" diff --git a/system/gd/crypto_toolbox/BUILD.gn b/system/gd/crypto_toolbox/BUILD.gn index 1983ff921f58c549e34d6f5d1ec078551d242977..fac31aba29544e3afdf56b75545ff8bd93f5fdb5 100644 --- a/system/gd/crypto_toolbox/BUILD.gn +++ b/system/gd/crypto_toolbox/BUILD.gn @@ -22,5 +22,8 @@ static_library("crypto_toolbox") { include_dirs = [ "//bt/system/gd" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } diff --git a/system/gd/discovery/Android.bp b/system/gd/discovery/Android.bp new file mode 100644 index 0000000000000000000000000000000000000000..fd042493ef770b6e83a5b3f0c7d133fe2fd9f33f --- /dev/null +++ b/system/gd/discovery/Android.bp @@ -0,0 +1,18 @@ +filegroup { + name: "BluetoothDiscoverySources", + srcs: [ + "device/bt_property.cc", + "device/data_parser.cc", + "device/eir_data.cc", + ], +} + +filegroup { + name: "BluetoothDiscoveryTestSources", + srcs: [ + "device/bt_property_unittest.cc", + "device/data_parser_unittest.cc", + "device/eir_data_unittest.cc", + "device/eir_test_data_packets.cc", + ], +} diff --git a/system/gd/discovery/device/bt_property.cc b/system/gd/discovery/device/bt_property.cc new file mode 100644 index 0000000000000000000000000000000000000000..223000fb15857c4d798802bc2eefc55b5bb93e77 --- /dev/null +++ b/system/gd/discovery/device/bt_property.cc @@ -0,0 +1,373 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "discovery/device/bt_property.h" + +#include + +#include + +#include "include/hardware/bluetooth.h" +#include "os/log.h" +#include "stack/include/bt_name.h" +#include "types/bluetooth/uuid.h" + +std::string bt_property_type_text(const bt_property_type_t& type) { + switch (type) { + CASE_RETURN_TEXT(BT_PROPERTY_BDNAME); + CASE_RETURN_TEXT(BT_PROPERTY_BDADDR); + CASE_RETURN_TEXT(BT_PROPERTY_UUIDS); + CASE_RETURN_TEXT(BT_PROPERTY_CLASS_OF_DEVICE); + CASE_RETURN_TEXT(BT_PROPERTY_TYPE_OF_DEVICE); + 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_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); + CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_LE_FEATURES); + CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_IO_CAPS); + CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0F); + CASE_RETURN_TEXT(BT_PROPERTY_DYNAMIC_AUDIO_BUFFER); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER); + CASE_RETURN_TEXT(BT_PROPERTY_APPEARANCE); + CASE_RETURN_TEXT(BT_PROPERTY_VENDOR_PRODUCT_INFO); + CASE_RETURN_TEXT(BT_PROPERTY_WL_MEDIA_PLAYERS_LIST); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ASHA_CAPABILITY); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_MODEL_NUM); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ADDR_TYPE); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE); + } + return base::StringPrintf("Unknown [%d]", (int)type); +} + +std::string bt_property_text(const bt_property_t& property) { + switch (property.type) { + case BT_PROPERTY_BDNAME: + return base::StringPrintf( + "type:%s name:%s", + bt_property_type_text(property.type).c_str(), + (const char*)property.val); + case BT_PROPERTY_BDADDR: + return base::StringPrintf( + "type:%s addr:%s", + bt_property_type_text(property.type).c_str(), + ((const RawAddress*)property.val)->ToString().c_str()); + case BT_PROPERTY_UUIDS: { + std::ostringstream oss; + const bluetooth::Uuid* it = (const bluetooth::Uuid*)property.val; + for (size_t i = 0; i < (size_t)property.len; i += sizeof(bluetooth::Uuid), it++) { + (i == 0) ? oss << *it : oss << " " << *it; + } + return base::StringPrintf( + "type:%s uuids:%s", bt_property_type_text(property.type).c_str(), oss.str().c_str()); + } + case BT_PROPERTY_CLASS_OF_DEVICE: + return base::StringPrintf( + "type:%s cod:0x%x", + bt_property_type_text(property.type).c_str(), + *(uint32_t*)(property.val)); + + case BT_PROPERTY_TYPE_OF_DEVICE: + return base::StringPrintf( + "type:%s type_of_device:%d", + bt_property_type_text(property.type).c_str(), + *(uint32_t*)(property.val)); + + case BT_PROPERTY_SERVICE_RECORD: + return base::StringPrintf( + "type:%s uuid:%s channel:%u name:\"%s\"", + bt_property_type_text(property.type).c_str(), + (((bt_service_record_t*)property.val)->uuid).ToString().c_str(), + (((bt_service_record_t*)property.val)->channel), + (((bt_service_record_t*)property.val)->name)); + + case BT_PROPERTY_ADAPTER_SCAN_MODE: + return base::StringPrintf( + "type:%s scan_mode:%u", + bt_property_type_text(property.type).c_str(), + *((bt_scan_mode_t*)property.val)); + + case BT_PROPERTY_ADAPTER_BONDED_DEVICES: { + std::ostringstream oss; + const RawAddress* it = (const RawAddress*)property.val; + for (size_t i = 0; i < (size_t)property.len; i += sizeof(RawAddress), it++) { + (i == 0) ? oss << *it : oss << " " << *it; + } + return base::StringPrintf( + "type:%s addrs:%s", bt_property_type_text(property.type).c_str(), oss.str().c_str()); + } + case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT: + return base::StringPrintf( + "type:%s discoverable_timeout:%u", + bt_property_type_text(property.type).c_str(), + *((uint32_t*)property.val)); + + case BT_PROPERTY_REMOTE_FRIENDLY_NAME: + return base::StringPrintf( + "type:%s remote_friendly_name:%s", + bt_property_type_text(property.type).c_str(), + (uint8_t*)property.val); + + case BT_PROPERTY_REMOTE_RSSI: + return base::StringPrintf( + "type:%s rssi:%hhd", + bt_property_type_text(property.type).c_str(), + *(int8_t*)property.val); + + case BT_PROPERTY_REMOTE_VERSION_INFO: + return base::StringPrintf( + "type:%s version:%d sub:%d mfr:%d", + bt_property_type_text(property.type).c_str(), + ((bt_remote_version_t*)property.val)->version, + ((bt_remote_version_t*)property.val)->sub_ver, + ((bt_remote_version_t*)property.val)->manufacturer); + + case BT_PROPERTY_LOCAL_LE_FEATURES: + return base::StringPrintf( + "type:%s version_supported:%d local_privacy_enabled:%d" + " max_adv_instance:%d rpa_offload_supported:%d max_irk_list_size:%d" + " max_adv_filter_supported:%d activity_energy_info_supported:%d" + " scan_result_storage_size:%d total_trackable_advertisers:%d" + " extended_scan_support:%d debug_logging_supported:%d le_2m_phy_supported:%d" + " le_coded_phy_supported:%d le_extended_advertising_supported:%d" + " le_periodic_advertising_supported:%d le_maximum_advertising_data_length:%d" + " dynamic_audio_buffer_supported:%d " + "le_periodic_advertising_sync_transfer_sender_supported:%d" + " le_connected_isochronous_stream_central_supported:%d " + "le_isochronous_broadcast_supported:%d" + " le_periodic_advertising_sync_transfer_recipient_supported:%d " + "adv_filter_extended_features_mask:%d", + bt_property_type_text(property.type).c_str(), + ((bt_local_le_features_t*)property.val)->version_supported, + ((bt_local_le_features_t*)property.val)->local_privacy_enabled, + ((bt_local_le_features_t*)property.val)->max_adv_instance, + ((bt_local_le_features_t*)property.val)->rpa_offload_supported, + ((bt_local_le_features_t*)property.val)->max_irk_list_size, + ((bt_local_le_features_t*)property.val)->max_adv_filter_supported, + ((bt_local_le_features_t*)property.val)->activity_energy_info_supported, + ((bt_local_le_features_t*)property.val)->scan_result_storage_size, + ((bt_local_le_features_t*)property.val)->total_trackable_advertisers, + ((bt_local_le_features_t*)property.val)->extended_scan_support, + ((bt_local_le_features_t*)property.val)->debug_logging_supported, + ((bt_local_le_features_t*)property.val)->le_2m_phy_supported, + ((bt_local_le_features_t*)property.val)->le_coded_phy_supported, + ((bt_local_le_features_t*)property.val)->le_extended_advertising_supported, + ((bt_local_le_features_t*)property.val)->le_periodic_advertising_supported, + ((bt_local_le_features_t*)property.val)->le_maximum_advertising_data_length, + ((bt_local_le_features_t*)property.val)->dynamic_audio_buffer_supported, + ((bt_local_le_features_t*)property.val) + ->le_periodic_advertising_sync_transfer_sender_supported, + ((bt_local_le_features_t*)property.val) + ->le_connected_isochronous_stream_central_supported, + ((bt_local_le_features_t*)property.val)->le_isochronous_broadcast_supported, + ((bt_local_le_features_t*)property.val) + ->le_periodic_advertising_sync_transfer_recipient_supported, + ((bt_local_le_features_t*)property.val)->adv_filter_extended_features_mask); + + case BT_PROPERTY_LOCAL_IO_CAPS: + return base::StringPrintf( + "type:%s local_io_caps:%d", + bt_property_type_text(property.type).c_str(), + *(bt_io_cap_t*)property.val); + + case BT_PROPERTY_RESERVED_0F: + return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str()); + + case BT_PROPERTY_DYNAMIC_AUDIO_BUFFER: + return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str()); + + case BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER: + return base::StringPrintf( + "type:%s is_coordinated_set_member:%s", + bt_property_type_text(property.type).c_str(), + (*(bool*)property.val) ? "true" : "false"); + + case BT_PROPERTY_APPEARANCE: + return base::StringPrintf( + "type:%s appearance:0x%x", + bt_property_type_text(property.type).c_str(), + (*(uint16_t*)property.val)); + + case BT_PROPERTY_VENDOR_PRODUCT_INFO: + return base::StringPrintf( + "type:%s vendor_id_src:%hhu vendor_id:%hu product_id:%hu version:%hu", + bt_property_type_text(property.type).c_str(), + ((bt_vendor_product_info_t*)property.val)->vendor_id_src, + ((bt_vendor_product_info_t*)property.val)->vendor_id, + ((bt_vendor_product_info_t*)property.val)->product_id, + ((bt_vendor_product_info_t*)property.val)->version); + + case BT_PROPERTY_WL_MEDIA_PLAYERS_LIST: + return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str()); + + case BT_PROPERTY_REMOTE_ASHA_CAPABILITY: + return base::StringPrintf( + "type:%s remote_asha_capability:%hd", + bt_property_type_text(property.type).c_str(), + (*(int16_t*)property.val)); + + case BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID: + return base::StringPrintf( + "type:%s remote_asha_truncated_hisyncid:%u", + bt_property_type_text(property.type).c_str(), + (*(uint32_t*)property.val)); + + case BT_PROPERTY_REMOTE_MODEL_NUM: + return base::StringPrintf( + "type:%s remote_model_num:%s", + bt_property_type_text(property.type).c_str(), + (char*)property.val); + + case BT_PROPERTY_REMOTE_ADDR_TYPE: + return base::StringPrintf( + "type:%s remote_asha_truncated_hisyncid:0x%x", + bt_property_type_text(property.type).c_str(), + (*(uint8_t*)property.val)); + + case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: + return base::StringPrintf("type:%s", bt_property_type_text(property.type).c_str()); + + case BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED: + return base::StringPrintf( + "type:%s remote secure connections supported:%hhd", + bt_property_type_text(property.type).c_str(), + (*(uint8_t*)property.val)); + + case BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE: + return base::StringPrintf( + "type:%s remote max session key size:%hhd", + bt_property_type_text(property.type).c_str(), + (*(uint8_t*)property.val)); + } + return std::string("Unknown"); +} + +namespace bluetooth::property { + +BtPropertyLegacy::BtPropertyLegacy(const std::vector>& bt_properties) + : bt_properties_(bt_properties) { + properties_.resize(bt_properties.size()); + std::vector::iterator it = properties_.begin(); + for (const auto& p : bt_properties) { + *it++ = { + .type = p->Type(), + .len = (int)p->Size(), + .val = (void*)p->Val(), + }; + } +} + +void BtPropertyLegacy::Export(bt_property_t* bt_properties, size_t size) { + ASSERT(bt_properties != nullptr); + ASSERT(size >= properties_.size()); + + for (const auto& p : bt_properties_) { + *bt_properties++ = { + .type = p->Type(), + .len = (int)p->Size(), + .val = (void*)p->Val(), + }; + } +} + +size_t BtPropertyLegacy::NumProperties() const { + return properties_.size(); +} + +const std::vector& BtPropertyLegacy::Properties() const { + return properties_; +} + +std::shared_ptr BdName::Create(const BD_NAME bd_name) { + return std::make_shared(BdName(bd_name)); +} +std::shared_ptr BdAddr::Create(const RawAddress& bd_addr) { + return std::make_shared(BdAddr(bd_addr)); +} +std::shared_ptr Uuids::Create(const std::vector& uuids) { + return std::make_shared(Uuids(uuids)); +} +std::shared_ptr ClassOfDevice::Create(const uint32_t& cod) { + return std::make_shared(ClassOfDevice(cod)); +} +std::shared_ptr TypeOfDevice::Create(const bt_device_type_t& type) { + return std::make_shared(TypeOfDevice(type)); +} +std::shared_ptr ServiceRecord::Create(const bt_service_record_t& record) { + return std::make_shared(ServiceRecord(record)); +} +std::shared_ptr AdapterScanMode::Create(const bt_scan_mode_t& mode) { + return std::make_shared(AdapterScanMode(mode)); +} +std::shared_ptr AdapterBondedDevices::Create( + const RawAddress* bd_addr, size_t len) { + ASSERT(bd_addr != nullptr); + return std::make_shared(AdapterBondedDevices(bd_addr, len)); +} +std::shared_ptr AdapterDiscoverableTimeout::Create( + const uint32_t& timeout) { + return std::make_shared(AdapterDiscoverableTimeout(timeout)); +} +std::shared_ptr RemoteFriendlyName::Create( + const uint8_t bd_name[], size_t len) { + return std::make_shared(RemoteFriendlyName(bd_name, len)); +} +std::shared_ptr RemoteRSSI::Create(const int8_t& rssi) { + return std::make_shared(RemoteRSSI(rssi)); +} +std::shared_ptr RemoteVersionInfo::Create(const bt_remote_version_t& info) { + return std::make_shared(RemoteVersionInfo(info)); +} +std::shared_ptr LocalLeFeatures::Create(const bt_local_le_features_t& features) { + return std::make_shared(LocalLeFeatures(features)); +} +std::shared_ptr LocalIOCaps::Create(const bt_io_cap_t& caps) { + return std::make_shared(LocalIOCaps(caps)); +} +std::shared_ptr RemoteIsCoordinatedSetMember::Create( + const bool& is_set_member) { + return std::make_shared( + RemoteIsCoordinatedSetMember(is_set_member)); +} +std::shared_ptr Appearance::Create(const uint16_t& appearance) { + return std::make_shared(Appearance(appearance)); +} +std::shared_ptr VendorProductInfo::Create(const bt_vendor_product_info_t& info) { + return std::make_shared(VendorProductInfo(info)); +} +std::shared_ptr RemoteASHACapability::Create(const int16_t& capability) { + return std::make_shared(RemoteASHACapability(capability)); +} +std::shared_ptr RemoteASHATruncatedHiSyncId::Create( + const uint32_t& id) { + return std::make_shared(RemoteASHATruncatedHiSyncId(id)); +} +std::shared_ptr RemoteModelNum::Create(const bt_bdname_t& name) { + return std::make_shared(RemoteModelNum(name)); +} +std::shared_ptr RemoteAddrType::Create(const uint8_t& addr) { + return std::make_shared(RemoteAddrType(addr)); +} +std::shared_ptr RemoteDeviceTimestamp::Create(const int& timestamp) { + return std::make_shared(RemoteDeviceTimestamp(timestamp)); +} + +} // namespace bluetooth::property diff --git a/system/gd/discovery/device/bt_property.h b/system/gd/discovery/device/bt_property.h new file mode 100644 index 0000000000000000000000000000000000000000..8d4583d6ea6f56bbf8674e5b80101e6fe5e3fe66 --- /dev/null +++ b/system/gd/discovery/device/bt_property.h @@ -0,0 +1,308 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#include "hardware/bluetooth.h" +#include "include/hardware/bluetooth.h" +#include "stack/include/bt_name.h" + +std::string bt_property_text(const bt_property_t& property); +std::string bt_property_type_text(const bt_property_type_t& type); + +namespace bluetooth { +namespace property { + +class BtProperty { + public: + // Return size in bytes of property data value + virtual size_t Size() const = 0; + // Returns raw pointer to the data value + virtual const void* Val() const = 0; + + bt_property_type_t Type() const { + return type_; + } + + std::string ToString() const { + return bt_property_type_text(type_); + } + + protected: + BtProperty(bt_property_type_t type) : type_(type) {} + virtual ~BtProperty() = default; + + private: + const bt_property_type_t type_; +}; + +// Provide pointer/size access to properties for legacy jni API +class BtPropertyLegacy { + public: + BtPropertyLegacy(const std::vector>& bt_properties); + + void Export(bt_property_t* bt_properties, size_t size); + + size_t NumProperties() const; + + const std::vector& Properties() const; + + bt_property_t* Ptr() const { + return const_cast(&properties_[0]); + } + int Len() const { + return static_cast(properties_.size()); + } + + private: + const std::vector> bt_properties_; + std::vector properties_; +}; + +template +class BtPropertySimple : public BtProperty { + public: + virtual size_t Size() const override { + return sizeof(T); + } + + const void* Val() const override { + return (const void*)val_.get(); + } + + protected: + BtPropertySimple(bt_property_type_t type, T val) + : BtProperty(type), val_(std::make_shared(val)) {} + + private: + std::shared_ptr val_; +}; + +template +class BtPropertyVector : public BtProperty { + public: + virtual size_t Size() const override { + return sizeof(T) * val_->size(); + } + const void* Val() const override { + return (const void*)&(*val_)[0]; + } + + protected: + // Create a vector property from another vector + BtPropertyVector(bt_property_type_t type, const std::vector& val) + : BtProperty(type), val_(std::make_shared>(val)) {} + + // Create a vector property from a raw pointer and size + BtPropertyVector(bt_property_type_t type, const T* val, size_t size) + : BtProperty(type), val_(std::make_shared>(val, val + size)) {} + + protected: + std::shared_ptr> val_; +}; + +template +class BtPropertyVectorWithPad : public BtPropertyVector { + protected: + // Create a vector property from a raw pointer and size with pad element + BtPropertyVectorWithPad(bt_property_type_t type, const T* val, size_t size, T pad) + : BtPropertyVector(type, val, size) { + BtPropertyVector::val_->push_back(pad); + } +}; + +class BdName : public BtPropertyVectorWithPad { + public: + BdName(const BD_NAME bd_name) + : BtPropertyVectorWithPad(BT_PROPERTY_BDNAME, bd_name, kBdNameLength, kBdNameDelim) { + } + + static std::shared_ptr Create(const BD_NAME bd_name); +}; + +class BdAddr : public BtPropertySimple { + public: + BdAddr(const RawAddress& bd_addr) : BtPropertySimple(BT_PROPERTY_BDADDR, bd_addr) {} + + static std::shared_ptr Create(const RawAddress& bd_addr); +}; + +class Uuids : public BtPropertyVector { + public: + Uuids(const std::vector& uuids) + : BtPropertyVector(BT_PROPERTY_UUIDS, uuids) {} + + static std::shared_ptr Create(const std::vector& uuids); +}; + +class ClassOfDevice : public BtPropertySimple { + public: + ClassOfDevice(const uint32_t& cod) + : BtPropertySimple(BT_PROPERTY_CLASS_OF_DEVICE, cod) {} + static std::shared_ptr Create(const uint32_t& bd_addr); +}; + +class TypeOfDevice : public BtPropertySimple { + public: + TypeOfDevice(const bt_device_type_t& device_type) + : BtPropertySimple(BT_PROPERTY_TYPE_OF_DEVICE, device_type) {} + static std::shared_ptr Create(const bt_device_type_t& device_type); +}; + +class ServiceRecord : public BtPropertySimple { + public: + ServiceRecord(const bt_service_record_t& record) + : BtPropertySimple(BT_PROPERTY_SERVICE_RECORD, record) {} + static std::shared_ptr Create(const bt_service_record_t& record); +}; + +class AdapterScanMode : public BtPropertySimple { + public: + AdapterScanMode(const bt_scan_mode_t& mode) + : BtPropertySimple(BT_PROPERTY_ADAPTER_SCAN_MODE, mode) {} + static std::shared_ptr Create(const bt_scan_mode_t& mode); +}; + +class AdapterBondedDevices : public BtPropertyVector { + public: + AdapterBondedDevices(const RawAddress* bd_addr, size_t len) + : BtPropertyVector(BT_PROPERTY_ADAPTER_BONDED_DEVICES, bd_addr, len) {} + + static std::shared_ptr Create(const RawAddress* bd_addr, size_t len); +}; + +class AdapterDiscoverableTimeout : public BtPropertySimple { + public: + AdapterDiscoverableTimeout(const uint32_t& timeout) + : BtPropertySimple(BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT, timeout) {} + + static std::shared_ptr Create(const uint32_t& timeout); +}; + +class RemoteFriendlyName : public BtPropertyVectorWithPad { + public: + RemoteFriendlyName(const uint8_t bd_name[], size_t len) + : BtPropertyVectorWithPad( + BT_PROPERTY_REMOTE_FRIENDLY_NAME, bd_name, len, kBdNameDelim) {} + + static std::shared_ptr Create(const uint8_t bd_name[], size_t len); +}; + +class RemoteRSSI : public BtPropertySimple { + public: + RemoteRSSI(const int8_t& rssi) : BtPropertySimple(BT_PROPERTY_REMOTE_RSSI, rssi) {} + + static std::shared_ptr Create(const int8_t& rssi); +}; + +class RemoteVersionInfo : public BtPropertySimple { + public: + RemoteVersionInfo(const bt_remote_version_t& info) + : BtPropertySimple(BT_PROPERTY_REMOTE_VERSION_INFO, info) {} + + static std::shared_ptr Create(const bt_remote_version_t& info); +}; + +class LocalLeFeatures : public BtPropertySimple { + public: + LocalLeFeatures(const bt_local_le_features_t& features) + : BtPropertySimple(BT_PROPERTY_LOCAL_LE_FEATURES, features) {} + + static std::shared_ptr Create(const bt_local_le_features_t& features); +}; + +class LocalIOCaps : public BtPropertySimple { + public: + LocalIOCaps(const bt_io_cap_t& cap) + : BtPropertySimple(BT_PROPERTY_LOCAL_IO_CAPS, cap) {} + + static std::shared_ptr Create(const bt_io_cap_t& cap); +}; + +class RemoteIsCoordinatedSetMember : public BtPropertySimple { + public: + RemoteIsCoordinatedSetMember(const bool& is_set_member) + : BtPropertySimple(BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER, is_set_member) {} + + static std::shared_ptr Create(const bool& is_set_member); +}; + +class Appearance : public BtPropertySimple { + public: + Appearance(const uint16_t& appearance) + : BtPropertySimple(BT_PROPERTY_APPEARANCE, appearance) {} + + static std::shared_ptr Create(const uint16_t& appearance); +}; + +class VendorProductInfo : public BtPropertySimple { + public: + VendorProductInfo(const bt_vendor_product_info_t& info) + : BtPropertySimple(BT_PROPERTY_VENDOR_PRODUCT_INFO, info) {} + + static std::shared_ptr Create(const bt_vendor_product_info_t& info); +}; + +class RemoteASHACapability : public BtPropertySimple { + public: + RemoteASHACapability(const int16_t capability) + : BtPropertySimple(BT_PROPERTY_REMOTE_ASHA_CAPABILITY, capability) {} + + static std::shared_ptr Create(const int16_t& capability); +}; + +class RemoteASHATruncatedHiSyncId : public BtPropertySimple { + public: + RemoteASHATruncatedHiSyncId(const uint32_t id) + : BtPropertySimple(BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID, id) {} + + static std::shared_ptr Create(const uint32_t& id); +}; + +class RemoteModelNum : public BtPropertyVectorWithPad { + public: + RemoteModelNum(const bt_bdname_t& name) + : BtPropertyVectorWithPad( + BT_PROPERTY_REMOTE_MODEL_NUM, + name.name, + sizeof(bt_bdname_t) - sizeof(kBdNameDelim), + kBdNameDelim) {} + + static std::shared_ptr Create(const bt_bdname_t& name); +}; + +class RemoteAddrType : public BtPropertySimple { + public: + RemoteAddrType(const uint8_t& type) + : BtPropertySimple(BT_PROPERTY_REMOTE_ADDR_TYPE, type) {} + + static std::shared_ptr Create(const uint8_t& type); +}; + +class RemoteDeviceTimestamp : public BtPropertySimple { + public: + RemoteDeviceTimestamp(const int& timestamp) + : BtPropertySimple(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, timestamp) {} + + static std::shared_ptr Create(const int& timestamp); +}; + +} // namespace property +} // namespace bluetooth diff --git a/system/gd/discovery/device/bt_property_unittest.cc b/system/gd/discovery/device/bt_property_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..e486deea9f911c078b527d241bd9d76fc30f8cdf --- /dev/null +++ b/system/gd/discovery/device/bt_property_unittest.cc @@ -0,0 +1,922 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "discovery/device/bt_property.h" + +#include +#include + +#include "gtest/gtest.h" +#include "hardware/bluetooth.h" +#include "os/log.h" +#include "stack/include/bt_name.h" + +using namespace bluetooth::property; + +namespace { + +constexpr size_t kNumberTestedProperties = 22; + +constexpr size_t kBdPropNameLength = kBdNameLength + sizeof(kBdNameDelim); + +constexpr uint8_t kReallyLongName[kBdPropNameLength] = + "aaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaa" + "aaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaa" + "aAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaaaAaaaaaaaa"; + +// BT_PROPERTY_BDNAME +constexpr BD_NAME kBdName{'k', 'B', 'd', 'N', 'a', 'm', 'e', '\0'}; + +// BT_PROPERTY_BDADDR +const RawAddress kRawAddress{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}}; + +// BT_PROPERTY_UUIDS +const bluetooth::Uuid uuids[] = { + {bluetooth::Uuid::FromString("00000001-1001-1000-8000-00805f9b34fb")}, + {bluetooth::Uuid::FromString("00000001-1002-1000-8000-00805f9b34fb")}, + {bluetooth::Uuid::FromString("00000001-1003-1000-8000-00805f9b34fb")}, +}; +const std::vector kUuids(uuids, uuids + sizeof(uuids) / sizeof(uuids[0])); + +// BT_PROPERTY_CLASS_OF_DEVICE +constexpr uint32_t kClassOfDevice{0x99663300}; + +// BT_PROPERTY_TYPE_OF_DEVICE +constexpr bt_device_type_t kTypeOfDevice{BT_DEVICE_DEVTYPE_BREDR}; + +// BT_PROPERTY_SERVICE_RECORD +const bt_service_record_t kServiceRecord{ + .uuid = uuids[0], + .channel = 0x1234, + .name = {'k', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'R', 'e', + 'c', 'o', 'r', 'd', '.', 'n', 'a', 'm', 'e', '\0'}, +}; + +// BT_PROPERTY_ADAPTER_SCAN_MODE +constexpr bt_scan_mode_t kAdapterScanMode{BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE}; +// +// BT_PROPERTY_ADAPTER_BONDED_DEVICES +const RawAddress kAdapterBondedDevices[] = { + {{0x11, 0x22, 0x33, 0x44, 0x55}}, + {{0x12, 0x22, 0x33, 0x44, 0x55}}, + {{0x13, 0x22, 0x33, 0x44, 0x55}}, + {{0x14, 0x22, 0x33, 0x44, 0x55}}, + {{0x15, 0x22, 0x33, 0x44, 0x55}}, +}; +constexpr size_t kNumBondedDevices = + sizeof(kAdapterBondedDevices) / sizeof(kAdapterBondedDevices[0]); + +// BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT +constexpr uint32_t kAdapterDiscoverableTimeout{0x4488cc00}; + +// BT_PROPERTY_REMOTE_FRIENDLY_NAME +const uint8_t kRemoteFriendlyName[] = {'k', 'R', 'e', 'm', 'o', 't', 'e', 'F', 'r', 'i', + 'e', 'n', 'd', 'l', 'y', 'N', 'a', 'm', 'e', '\0'}; + +// BT_PROPERTY_REMOTE_RSSI +constexpr int8_t kRemoteRssi{0x10}; + +// BT_PROPERTY_REMOTE_VERSION_INFO +bt_remote_version_t kRemoteVersionInfo{ + .version = 1, + .sub_ver = 2, + .manufacturer = 3, +}; + +// BT_PROPERTY_LOCAL_LE_FEATURES +constexpr bt_local_le_features_t kLocalLeFeatures{ + .version_supported = 0x1234, + .local_privacy_enabled = 0x11, + .max_adv_instance = 0x22, + .rpa_offload_supported = 0x33, + .max_irk_list_size = 0x44, + .max_adv_filter_supported = 0x55, + .activity_energy_info_supported = 0x66, + .scan_result_storage_size = 0x5678, + .total_trackable_advertisers = 0x9abc, + .extended_scan_support = true, + .debug_logging_supported = true, + .le_2m_phy_supported = true, + .le_coded_phy_supported = true, + .le_extended_advertising_supported = true, + .le_periodic_advertising_supported = true, + .le_maximum_advertising_data_length = 0x1357, + .dynamic_audio_buffer_supported = 0x22446688, + .le_periodic_advertising_sync_transfer_sender_supported = true, + .le_connected_isochronous_stream_central_supported = true, + .le_isochronous_broadcast_supported = true, + .le_periodic_advertising_sync_transfer_recipient_supported = true, + .adv_filter_extended_features_mask = 0x3366, +}; + +// BT_PROPERTY_LOCAL_IO_CAPS +constexpr bt_io_cap_t kLocalIoCaps{BT_IO_CAP_UNKNOWN}; + +// BT_PROPERTY_RESERVED_0F +// BT_PROPERTY_DYNAMIC_AUDIO_BUFFER + +// BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER +constexpr bool kRemoteIsCoordinatedSetMember{true}; + +// BT_PROPERTY_APPEARANCE +constexpr uint16_t kAppearance{0x44}; + +// BT_PROPERTY_VENDOR_PRODUCT_INFO +constexpr bt_vendor_product_info_t kVendorProductInfo{ + .vendor_id_src = 0x02, + .vendor_id = 0x1235, + .product_id = 0x5679, + .version = 0x9abd, +}; + +// BT_PROPERTY_WL_MEDIA_PLAYERS_LIST + +// BT_PROPERTY_REMOTE_ASHA_CAPABILITY +constexpr int16_t kRemoteAshaCapability{0x89}; + +// BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID +constexpr uint32_t kRemoteAshaTruncatedHisyncId{0x22446688}; + +// BT_PROPERTY_REMOTE_MODEL_NUM +constexpr bt_bdname_t kRemoteModelNum{ + .name = {'k', 'R', 'e', 'm', 'o', 't', 'e', 'M', 'o', 'd', 'e', 'l', 'N', 'u', 'm', '\0'}, +}; + +// BT_PROPERTY_REMOTE_ADDR_TYPE +constexpr uint8_t kRemoteAddrType{0x55}; + +// BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP +constexpr int kRemoteDeviceTimestamp{0x12345678}; + +// Fill the given property type with the well known property data set +void fill_property( + const bt_property_type_t& type, std::vector>& properties) { + switch (type) { + case BT_PROPERTY_BDNAME: { + properties.push_back(BdName::Create(kBdName)); + ASSERT_EQ(kBdPropNameLength, properties.back()->Size()); + } break; + + case BT_PROPERTY_BDADDR: + properties.push_back(BdAddr::Create(kRawAddress)); + ASSERT_EQ(sizeof(RawAddress), properties.back()->Size()); + break; + + case BT_PROPERTY_UUIDS: { + properties.push_back(Uuids::Create(kUuids)); + ASSERT_EQ(sizeof(bluetooth::Uuid) * kUuids.size(), properties.back()->Size()); + } break; + + case BT_PROPERTY_CLASS_OF_DEVICE: + properties.push_back(ClassOfDevice::Create(kClassOfDevice)); + ASSERT_EQ(sizeof(uint32_t), properties.back()->Size()); + break; + + case BT_PROPERTY_TYPE_OF_DEVICE: + properties.push_back(TypeOfDevice::Create(kTypeOfDevice)); + ASSERT_EQ(sizeof(bt_device_type_t), properties.back()->Size()); + break; + + case BT_PROPERTY_SERVICE_RECORD: + properties.push_back(ServiceRecord::Create(kServiceRecord)); + ASSERT_EQ(sizeof(bt_service_record_t), properties.back()->Size()); + break; + + case BT_PROPERTY_ADAPTER_SCAN_MODE: + properties.push_back(AdapterScanMode::Create(kAdapterScanMode)); + ASSERT_EQ(sizeof(bt_scan_mode_t), properties.back()->Size()); + break; + + case BT_PROPERTY_ADAPTER_BONDED_DEVICES: { + properties.push_back(AdapterBondedDevices::Create(kAdapterBondedDevices, kNumBondedDevices)); + ASSERT_EQ(sizeof(RawAddress) * kNumBondedDevices, properties.back()->Size()); + } break; + + case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT: + properties.push_back(AdapterDiscoverableTimeout::Create(kAdapterDiscoverableTimeout)); + ASSERT_EQ(sizeof(uint32_t), properties.back()->Size()); + break; + + case BT_PROPERTY_REMOTE_FRIENDLY_NAME: { + properties.push_back( + RemoteFriendlyName::Create(kRemoteFriendlyName, sizeof(kRemoteFriendlyName))); + ASSERT_EQ(sizeof(kRemoteFriendlyName) + sizeof(kBdNameDelim), properties.back()->Size()); + } break; + + case BT_PROPERTY_REMOTE_RSSI: + properties.push_back(RemoteRSSI::Create(kRemoteRssi)); + ASSERT_EQ(sizeof(int8_t), properties.back()->Size()); + break; + + case BT_PROPERTY_REMOTE_VERSION_INFO: + properties.push_back(RemoteVersionInfo::Create(kRemoteVersionInfo)); + ASSERT_EQ(sizeof(bt_remote_version_t), properties.back()->Size()); + break; + + case BT_PROPERTY_LOCAL_LE_FEATURES: + properties.push_back(LocalLeFeatures::Create(kLocalLeFeatures)); + ASSERT_EQ(sizeof(kLocalLeFeatures), properties.back()->Size()); + break; + + case BT_PROPERTY_LOCAL_IO_CAPS: + properties.push_back(LocalIOCaps::Create(kLocalIoCaps)); + ASSERT_EQ(sizeof(kLocalIoCaps), properties.back()->Size()); + break; + + case BT_PROPERTY_RESERVED_0F: + case BT_PROPERTY_DYNAMIC_AUDIO_BUFFER: + break; + + case BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER: + properties.push_back(RemoteIsCoordinatedSetMember::Create(kRemoteIsCoordinatedSetMember)); + ASSERT_EQ(sizeof(kRemoteIsCoordinatedSetMember), properties.back()->Size()); + break; + + case BT_PROPERTY_APPEARANCE: + properties.push_back(Appearance::Create(kAppearance)); + ASSERT_EQ(sizeof(kAppearance), properties.back()->Size()); + break; + + case BT_PROPERTY_VENDOR_PRODUCT_INFO: + properties.push_back(VendorProductInfo::Create(kVendorProductInfo)); + ASSERT_EQ(sizeof(kVendorProductInfo), properties.back()->Size()); + break; + + case BT_PROPERTY_WL_MEDIA_PLAYERS_LIST: + break; + + case BT_PROPERTY_REMOTE_ASHA_CAPABILITY: + properties.push_back(RemoteASHACapability::Create(kRemoteAshaCapability)); + ASSERT_EQ(sizeof(kRemoteAshaCapability), properties.back()->Size()); + break; + + case BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID: + properties.push_back(RemoteASHATruncatedHiSyncId::Create(kRemoteAshaTruncatedHisyncId)); + ASSERT_EQ(sizeof(kRemoteAshaTruncatedHisyncId), properties.back()->Size()); + break; + + case BT_PROPERTY_REMOTE_MODEL_NUM: { + properties.push_back(RemoteModelNum::Create(kRemoteModelNum)); + ASSERT_EQ(sizeof(kRemoteModelNum), properties.back()->Size()); + } break; + + case BT_PROPERTY_REMOTE_ADDR_TYPE: + properties.push_back(RemoteAddrType::Create(kRemoteAddrType)); + ASSERT_EQ(sizeof(kRemoteAddrType), properties.back()->Size()); + break; + + case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: + properties.push_back(RemoteDeviceTimestamp::Create(kRemoteDeviceTimestamp)); + ASSERT_EQ(sizeof(kRemoteDeviceTimestamp), properties.back()->Size()); + break; + + default: + FAIL() << "Illegal property type:" << type; + break; + } +} + +// Verify the given property type with the well known property data set +void verify_property(const bt_property_type_t& type, const bt_property_t& property) { + ASSERT_EQ(type, property.type); + switch (property.type) { + case BT_PROPERTY_BDNAME: + ASSERT_EQ((int)kBdPropNameLength, property.len); + ASSERT_STREQ((const char*)kBdName, (const char*)property.val); + break; + + case BT_PROPERTY_BDADDR: + ASSERT_EQ((int)sizeof(RawAddress), property.len); + ASSERT_EQ(kRawAddress, *((RawAddress*)property.val)); + break; + + case BT_PROPERTY_UUIDS: { + ASSERT_EQ((int)(sizeof(bluetooth::Uuid) * kUuids.size()), property.len); + const bluetooth::Uuid* uuid = (const bluetooth::Uuid*)property.val; + ASSERT_EQ(uuids[0], *uuid++); + ASSERT_EQ(uuids[1], *uuid++); + ASSERT_EQ(uuids[2], *uuid++); + } break; + + case BT_PROPERTY_CLASS_OF_DEVICE: + ASSERT_EQ((int)sizeof(uint32_t), property.len); + ASSERT_EQ(kClassOfDevice, *((uint32_t*)property.val)); + break; + + case BT_PROPERTY_TYPE_OF_DEVICE: + ASSERT_EQ((int)sizeof(uint32_t), property.len); + ASSERT_EQ(kTypeOfDevice, *((uint32_t*)property.val)); + break; + + case BT_PROPERTY_SERVICE_RECORD: + ASSERT_EQ((int)sizeof(bt_service_record_t), property.len); + ASSERT_EQ(kServiceRecord.uuid, ((bt_service_record_t*)property.val)->uuid); + ASSERT_EQ(kServiceRecord.channel, ((bt_service_record_t*)property.val)->channel); + ASSERT_STREQ(kServiceRecord.name, ((bt_service_record_t*)property.val)->name); + break; + + case BT_PROPERTY_ADAPTER_SCAN_MODE: + ASSERT_EQ((int)sizeof(bt_scan_mode_t), property.len); + ASSERT_EQ(kAdapterScanMode, *((bt_scan_mode_t*)property.val)); + break; + + case BT_PROPERTY_ADAPTER_BONDED_DEVICES: { + ASSERT_EQ((int)sizeof(kAdapterBondedDevices), property.len); + const RawAddress* raw_address = static_cast(property.val); + for (size_t i = 0; i < kNumBondedDevices; i++, raw_address++) { + ASSERT_EQ(kAdapterBondedDevices[i], *raw_address); + } + } break; + + case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT: + ASSERT_EQ((int)sizeof(uint32_t), property.len); + ASSERT_EQ(kAdapterDiscoverableTimeout, *((uint32_t*)property.val)); + break; + + case BT_PROPERTY_REMOTE_FRIENDLY_NAME: + ASSERT_EQ((int)(sizeof(kRemoteFriendlyName) + sizeof(kBdNameDelim)), property.len); + ASSERT_STREQ((const char*)kRemoteFriendlyName, (const char*)property.val); + break; + + case BT_PROPERTY_REMOTE_RSSI: + ASSERT_EQ((int)sizeof(int8_t), property.len); + ASSERT_EQ(kRemoteRssi, *((int8_t*)property.val)); + break; + + case BT_PROPERTY_REMOTE_VERSION_INFO: + ASSERT_EQ((int)sizeof(bt_remote_version_t), property.len); + ASSERT_EQ(kRemoteVersionInfo.version, ((bt_remote_version_t*)property.val)->version); + ASSERT_EQ(kRemoteVersionInfo.sub_ver, ((bt_remote_version_t*)property.val)->sub_ver); + ASSERT_EQ( + kRemoteVersionInfo.manufacturer, ((bt_remote_version_t*)property.val)->manufacturer); + break; + + case BT_PROPERTY_LOCAL_LE_FEATURES: + ASSERT_EQ((int)sizeof(bt_local_le_features_t), property.len); + ASSERT_EQ( + kLocalLeFeatures.version_supported, + ((bt_local_le_features_t*)property.val)->version_supported); + ASSERT_EQ( + kLocalLeFeatures.local_privacy_enabled, + ((bt_local_le_features_t*)property.val)->local_privacy_enabled); + ASSERT_EQ( + kLocalLeFeatures.local_privacy_enabled, + ((bt_local_le_features_t*)property.val)->local_privacy_enabled); + ASSERT_EQ( + kLocalLeFeatures.max_adv_instance, + ((bt_local_le_features_t*)property.val)->max_adv_instance); + ASSERT_EQ( + kLocalLeFeatures.rpa_offload_supported, + ((bt_local_le_features_t*)property.val)->rpa_offload_supported); + ASSERT_EQ( + kLocalLeFeatures.max_irk_list_size, + ((bt_local_le_features_t*)property.val)->max_irk_list_size); + ASSERT_EQ( + kLocalLeFeatures.max_adv_filter_supported, + ((bt_local_le_features_t*)property.val)->max_adv_filter_supported); + ASSERT_EQ( + kLocalLeFeatures.activity_energy_info_supported, + ((bt_local_le_features_t*)property.val)->activity_energy_info_supported); + ASSERT_EQ( + kLocalLeFeatures.scan_result_storage_size, + ((bt_local_le_features_t*)property.val)->scan_result_storage_size); + ASSERT_EQ( + kLocalLeFeatures.total_trackable_advertisers, + ((bt_local_le_features_t*)property.val)->total_trackable_advertisers); + ASSERT_EQ( + kLocalLeFeatures.extended_scan_support, + ((bt_local_le_features_t*)property.val)->extended_scan_support); + ASSERT_EQ( + kLocalLeFeatures.debug_logging_supported, + ((bt_local_le_features_t*)property.val)->debug_logging_supported); + ASSERT_EQ( + kLocalLeFeatures.le_2m_phy_supported, + ((bt_local_le_features_t*)property.val)->le_2m_phy_supported); + ASSERT_EQ( + kLocalLeFeatures.le_coded_phy_supported, + ((bt_local_le_features_t*)property.val)->le_coded_phy_supported); + ASSERT_EQ( + kLocalLeFeatures.le_extended_advertising_supported, + ((bt_local_le_features_t*)property.val)->le_extended_advertising_supported); + ASSERT_EQ( + kLocalLeFeatures.le_periodic_advertising_supported, + ((bt_local_le_features_t*)property.val)->le_periodic_advertising_supported); + ASSERT_EQ( + kLocalLeFeatures.le_maximum_advertising_data_length, + ((bt_local_le_features_t*)property.val)->le_maximum_advertising_data_length); + ASSERT_EQ( + kLocalLeFeatures.dynamic_audio_buffer_supported, + ((bt_local_le_features_t*)property.val)->dynamic_audio_buffer_supported); + ASSERT_EQ( + kLocalLeFeatures.le_periodic_advertising_sync_transfer_sender_supported, + ((bt_local_le_features_t*)property.val) + ->le_periodic_advertising_sync_transfer_sender_supported); + ASSERT_EQ( + kLocalLeFeatures.le_connected_isochronous_stream_central_supported, + ((bt_local_le_features_t*)property.val) + ->le_connected_isochronous_stream_central_supported); + ASSERT_EQ( + kLocalLeFeatures.le_isochronous_broadcast_supported, + ((bt_local_le_features_t*)property.val)->le_isochronous_broadcast_supported); + ASSERT_EQ( + kLocalLeFeatures.le_periodic_advertising_sync_transfer_recipient_supported, + ((bt_local_le_features_t*)property.val) + ->le_periodic_advertising_sync_transfer_recipient_supported); + ASSERT_EQ( + kLocalLeFeatures.adv_filter_extended_features_mask, + ((bt_local_le_features_t*)property.val)->adv_filter_extended_features_mask); + break; + + case BT_PROPERTY_LOCAL_IO_CAPS: + ASSERT_EQ((int)sizeof(bt_io_cap_t), property.len); + ASSERT_EQ(kLocalIoCaps, *((bt_io_cap_t*)property.val)); + break; + + case BT_PROPERTY_RESERVED_0F: + case BT_PROPERTY_DYNAMIC_AUDIO_BUFFER: + break; + + case BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER: + ASSERT_EQ((int)sizeof(bool), property.len); + ASSERT_EQ(kRemoteIsCoordinatedSetMember, *((bool*)property.val)); + break; + + case BT_PROPERTY_APPEARANCE: + ASSERT_EQ((int)sizeof(uint16_t), property.len); + ASSERT_EQ(kAppearance, *((uint16_t*)property.val)); + break; + + case BT_PROPERTY_VENDOR_PRODUCT_INFO: + ASSERT_EQ((int)sizeof(bt_vendor_product_info_t), property.len); + ASSERT_EQ( + kVendorProductInfo.vendor_id_src, + ((bt_vendor_product_info_t*)property.val)->vendor_id_src); + ASSERT_EQ(kVendorProductInfo.vendor_id, ((bt_vendor_product_info_t*)property.val)->vendor_id); + ASSERT_EQ( + kVendorProductInfo.product_id, ((bt_vendor_product_info_t*)property.val)->product_id); + ASSERT_EQ(kVendorProductInfo.version, ((bt_vendor_product_info_t*)property.val)->version); + break; + + case BT_PROPERTY_WL_MEDIA_PLAYERS_LIST: + break; + + case BT_PROPERTY_REMOTE_ASHA_CAPABILITY: + ASSERT_EQ((int)sizeof(int16_t), property.len); + ASSERT_EQ(kRemoteAshaCapability, *((int16_t*)property.val)); + break; + + case BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID: + ASSERT_EQ((int)sizeof(uint32_t), property.len); + ASSERT_EQ(kRemoteAshaTruncatedHisyncId, *((uint32_t*)property.val)); + break; + + case BT_PROPERTY_REMOTE_MODEL_NUM: + ASSERT_EQ((int)sizeof(kRemoteModelNum.name), property.len); + ASSERT_STREQ((const char*)kRemoteModelNum.name, ((const char*)property.val)); + break; + + case BT_PROPERTY_REMOTE_ADDR_TYPE: + ASSERT_EQ((int)sizeof(uint8_t), property.len); + ASSERT_EQ(kRemoteAddrType, *((uint8_t*)property.val)); + break; + + case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: + ASSERT_EQ((int)sizeof(int), property.len); + ASSERT_EQ(kRemoteDeviceTimestamp, *((int*)property.val)); + break; + + default: + FAIL() << "Illegal property type:" << type; + break; + } +} + +// Fill a property container with all possible property types +void fill_properties(std::vector>& properties) { + fill_property(BT_PROPERTY_BDNAME, properties); + fill_property(BT_PROPERTY_BDADDR, properties); + fill_property(BT_PROPERTY_UUIDS, properties); + fill_property(BT_PROPERTY_CLASS_OF_DEVICE, properties); + fill_property(BT_PROPERTY_TYPE_OF_DEVICE, properties); + fill_property(BT_PROPERTY_SERVICE_RECORD, properties); + fill_property(BT_PROPERTY_ADAPTER_SCAN_MODE, properties); + fill_property(BT_PROPERTY_ADAPTER_BONDED_DEVICES, properties); + fill_property(BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT, properties); + fill_property(BT_PROPERTY_REMOTE_FRIENDLY_NAME, properties); + fill_property(BT_PROPERTY_REMOTE_RSSI, properties); + fill_property(BT_PROPERTY_REMOTE_VERSION_INFO, properties); + fill_property(BT_PROPERTY_LOCAL_LE_FEATURES, properties); + fill_property(BT_PROPERTY_LOCAL_IO_CAPS, properties); + fill_property(BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER, properties); + fill_property(BT_PROPERTY_APPEARANCE, properties); + fill_property(BT_PROPERTY_VENDOR_PRODUCT_INFO, properties); + fill_property(BT_PROPERTY_REMOTE_ASHA_CAPABILITY, properties); + fill_property(BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID, properties); + fill_property(BT_PROPERTY_REMOTE_MODEL_NUM, properties); + fill_property(BT_PROPERTY_REMOTE_ADDR_TYPE, properties); + fill_property(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, properties); + ASSERT_EQ(kNumberTestedProperties, properties.size()); +} + +} // namespace + // +class BtPropertyTest : public testing::Test { + protected: + void SetUp() override {} + void TearDown() override {} +}; + +TEST_F(BtPropertyTest, bt_property_text_test) { + { + bt_property_t prop = { + .type = BT_PROPERTY_BDNAME, + .len = (int)sizeof(kBdName), + .val = (void*)kBdName, + }; + ASSERT_STREQ("type:BT_PROPERTY_BDNAME name:kBdName", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_BDADDR, + .len = (int)sizeof(kRawAddress), + .val = (void*)&kRawAddress, + }; + ASSERT_STREQ("type:BT_PROPERTY_BDADDR addr:11:22:33:44:55:66", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_UUIDS, + .len = (int)(sizeof(bluetooth::Uuid) * kUuids.size()), + .val = (void*)&kUuids[0], + }; + ASSERT_STREQ( + "type:BT_PROPERTY_UUIDS uuids:00000001-1001-1000-8000-00805f9b34fb " + "00000001-1002-1000-8000-00805f9b34fb 00000001-1003-1000-8000-00805f9b34fb", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_CLASS_OF_DEVICE, + .len = (int)sizeof(kClassOfDevice), + .val = (void*)&kClassOfDevice, + }; + ASSERT_STREQ("type:BT_PROPERTY_CLASS_OF_DEVICE cod:0x99663300", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_TYPE_OF_DEVICE, + .len = (int)sizeof(kTypeOfDevice), + .val = (void*)&kTypeOfDevice, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_TYPE_OF_DEVICE type_of_device:1", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_SERVICE_RECORD, + .len = (int)sizeof(kServiceRecord), + .val = (void*)&kServiceRecord, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_SERVICE_RECORD uuid:00000001-1001-1000-8000-00805f9b34fb channel:4660 " + "name:\"kServiceRecord.name\"", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_ADAPTER_SCAN_MODE, + .len = (int)sizeof(kAdapterScanMode), + .val = (void*)&kAdapterScanMode, + }; + ASSERT_STREQ("type:BT_PROPERTY_ADAPTER_SCAN_MODE scan_mode:2", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_ADAPTER_BONDED_DEVICES, + .len = (int)(sizeof(kAdapterBondedDevices)), + .val = (void*)kAdapterBondedDevices, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_ADAPTER_BONDED_DEVICES addrs:11:22:33:44:55:00 12:22:33:44:55:00 " + "13:22:33:44:55:00 14:22:33:44:55:00 15:22:33:44:55:00", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT, + .len = (int)sizeof(kAdapterDiscoverableTimeout), + .val = (void*)&kAdapterDiscoverableTimeout, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT discoverable_timeout:1149815808", + bt_property_text(prop).c_str()); + } + + { + bt_bdname_t bd_name; + bd_name_copy(bd_name.name, kRemoteFriendlyName); + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_FRIENDLY_NAME, + .len = (int)sizeof(bd_name.name), + .val = (void*)&bd_name.name, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_REMOTE_FRIENDLY_NAME remote_friendly_name:kRemoteFriendlyName", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_RSSI, + .len = (int)sizeof(kRemoteRssi), + .val = (void*)&kRemoteRssi, + }; + ASSERT_STREQ("type:BT_PROPERTY_REMOTE_RSSI rssi:16", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_VERSION_INFO, + .len = (int)sizeof(kRemoteVersionInfo), + .val = (void*)&kRemoteVersionInfo, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_REMOTE_VERSION_INFO version:1 sub:2 mfr:3", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_LOCAL_LE_FEATURES, + .len = (int)sizeof(kLocalLeFeatures), + .val = (void*)&kLocalLeFeatures, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_LOCAL_LE_FEATURES version_supported:4660 local_privacy_enabled:17 " + "max_adv_instance:34 rpa_offload_supported:51 max_irk_list_size:68 " + "max_adv_filter_supported:85 activity_energy_info_supported:102 " + "scan_result_storage_size:22136 total_trackable_advertisers:39612 extended_scan_support:1 " + "debug_logging_supported:1 le_2m_phy_supported:1 le_coded_phy_supported:1 " + "le_extended_advertising_supported:1 le_periodic_advertising_supported:1 " + "le_maximum_advertising_data_length:4951 dynamic_audio_buffer_supported:574908040 " + "le_periodic_advertising_sync_transfer_sender_supported:1 " + "le_connected_isochronous_stream_central_supported:1 le_isochronous_broadcast_supported:1 " + "le_periodic_advertising_sync_transfer_recipient_supported:1 " + "adv_filter_extended_features_mask:13158", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_LOCAL_IO_CAPS, + .len = (int)sizeof(kLocalIoCaps), + .val = (void*)&kLocalIoCaps, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_LOCAL_IO_CAPS local_io_caps:255", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER, + .len = (int)sizeof(kRemoteIsCoordinatedSetMember), + .val = (void*)&kRemoteIsCoordinatedSetMember, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER is_coordinated_set_member:true", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_APPEARANCE, + .len = (int)sizeof(kAppearance), + .val = (void*)&kAppearance, + }; + ASSERT_STREQ("type:BT_PROPERTY_APPEARANCE appearance:0x44", bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_VENDOR_PRODUCT_INFO, + .len = (int)sizeof(kVendorProductInfo), + .val = (void*)&kVendorProductInfo, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_VENDOR_PRODUCT_INFO vendor_id_src:2 vendor_id:4661 product_id:22137 " + "version:39613", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_ASHA_CAPABILITY, + .len = (int)sizeof(kRemoteAshaCapability), + .val = (void*)&kRemoteAshaCapability, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_REMOTE_ASHA_CAPABILITY remote_asha_capability:137", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID, + .len = (int)sizeof(kRemoteAshaTruncatedHisyncId), + .val = (void*)&kRemoteAshaTruncatedHisyncId, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID remote_asha_truncated_hisyncid:574908040", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_MODEL_NUM, + .len = (int)sizeof(kRemoteModelNum.name), + .val = (void*)kRemoteModelNum.name, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_REMOTE_MODEL_NUM remote_model_num:kRemoteModelNum", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_ADDR_TYPE, + .len = (int)sizeof(kRemoteAddrType), + .val = (void*)&kRemoteAddrType, + }; + ASSERT_STREQ( + "type:BT_PROPERTY_REMOTE_ADDR_TYPE remote_asha_truncated_hisyncid:0x55", + bt_property_text(prop).c_str()); + } + + { + bt_property_t prop = { + .type = BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, + .len = (int)sizeof(kRemoteDeviceTimestamp), + .val = (void*)&kRemoteDeviceTimestamp, + }; + ASSERT_STREQ("type:BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP", bt_property_text(prop).c_str()); + } +} + +TEST_F(BtPropertyTest, verify_property_sizes) { + std::vector> properties; + fill_properties(properties); +} + +TEST_F(BtPropertyTest, fill_and_serialize) { + std::vector> properties; + fill_properties(properties); + + BtPropertyLegacy legacy(properties); + + ASSERT_EQ(kNumberTestedProperties, legacy.NumProperties()); +} + +TEST_F(BtPropertyTest, serialize_and_verify) { + std::vector> properties; + fill_properties(properties); + + BtPropertyLegacy legacy(properties); + + for (const auto p : legacy.Properties()) { + verify_property(p.type, p); + } +} + +TEST_F(BtPropertyTest, name_too_long) { + std::vector> properties; + BD_NAME bd_name; + for (size_t i = 0; i < kBdPropNameLength; i++) { + bd_name[i] = ((i + 1) % 10) ? 'a' : 'A'; + } + + properties.push_back(BdName::Create(bd_name)); + BtPropertyLegacy legacy(properties); + ASSERT_EQ(1U, legacy.NumProperties()); + + bt_property_t bt_properties[1]; + legacy.Export(bt_properties, 1U); + + ASSERT_STREQ((const char*)kReallyLongName, (const char*)bt_properties[0].val); +} + +class BtPropertyArrayTest : public testing::Test { + protected: + void SetUp() override { + fill_properties(properties); + } + void TearDown() override {} + std::vector> properties; + bt_property_t props[kNumberTestedProperties]; +}; + +TEST_F(BtPropertyArrayTest, serialize_and_verify) { + BtPropertyLegacy legacy(properties); + + for (const auto p : legacy.Properties()) { + verify_property(p.type, p); + } +} + +TEST_F(BtPropertyArrayTest, async_data) { + auto future = std::async(std::launch::async, []() { + std::vector> properties; + fill_properties(properties); + return properties; + }); + + auto properties = future.get(); + + BtPropertyLegacy legacy(properties); + + for (const auto p : legacy.Properties()) { + verify_property(p.type, p); + } +} + +class BtPropertyDynamicArrayTest : public testing::Test { + protected: + void SetUp() override { + fill_properties(properties); + props = (bt_property_t*)malloc(sizeof(bt_property_t) * properties.size()); + } + void TearDown() override { + free(props); + } + + bt_property_t* props{nullptr}; + std::vector> properties; +}; + +TEST_F(BtPropertyDynamicArrayTest, serialize_and_verify) { + BtPropertyLegacy legacy(properties); + // Legacy now has complete copy of properties + properties.clear(); + + legacy.Export(props, kNumberTestedProperties); + + bt_property_t* p = props; + for (size_t i = 0; i < kNumberTestedProperties; i++) { + verify_property(p->type, *p); + } +} + +class BtPropertyMultiAllocationTest : public testing::Test { + protected: + static constexpr size_t kNumProperties = 1; + static constexpr size_t kNumThreads = 20; + + void SetUp() override {} + void TearDown() override {} + + std::vector>>> future_vector; + bt_property_t bt_properties[kNumberTestedProperties][kNumThreads] = {}; + + std::vector> properties; +}; + +TEST_F(BtPropertyMultiAllocationTest, async_data_multi) { + for (size_t i = 0; i < kNumThreads; i++) { + future_vector.push_back(std::async(std::launch::async, [i]() { + std::vector> properties; + properties.push_back(RemoteDeviceTimestamp::Create((uint32_t)i)); + return properties; + })); + } + + for (size_t i = 0; i < kNumThreads; i++) { + std::vector> props = future_vector[i].get(); + BtPropertyLegacy legacy(props); + memcpy( + bt_properties[i], (const void*)legacy.Ptr(), (size_t)legacy.Len() * sizeof(bt_property_t)); + + ASSERT_EQ(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, (int)bt_properties[i]->type); + ASSERT_EQ((int)sizeof(uint32_t), bt_properties[i]->len); + ASSERT_EQ((int)i, *(int*)bt_properties[i]->val); + } +} diff --git a/system/gd/discovery/device/data_parser.cc b/system/gd/discovery/device/data_parser.cc new file mode 100644 index 0000000000000000000000000000000000000000..2e9acdc78ef8cf31705d3a22a9603fc4d1e94d8d --- /dev/null +++ b/system/gd/discovery/device/data_parser.cc @@ -0,0 +1,53 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "discovery/device/data_parser.h" + +#include "hci/hci_packets.h" +#include "packet/iterator.h" + +using namespace bluetooth; + +using namespace bluetooth::hci; +using namespace bluetooth::packet; + +namespace bluetooth::discovery::device { + +DataParser::DataParser(const std::vector& data) { + auto it = Iterator(std::make_shared>(data)); + + while (it.NumBytesRemaining()) { + GapData gap_data; + it = GapData::Parse(&gap_data, it); + gap_data_.push_back(gap_data); + } +} + +size_t DataParser::GetNumGapData() const { + return gap_data_.size(); +} + +std::vector DataParser::GetData() const { + return std::vector(gap_data_); +} + +std::vector DataParser::GetDataTypes() const { + std::vector types; + for (const auto& gap_data : gap_data_) types.push_back(gap_data.data_type_); + return types; +} + +} // namespace bluetooth::discovery::device diff --git a/system/gd/discovery/device/data_parser.h b/system/gd/discovery/device/data_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..d96726ea636a477499fbe70864092e03a237e3fb --- /dev/null +++ b/system/gd/discovery/device/data_parser.h @@ -0,0 +1,41 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "hci/hci_packets.h" + +namespace bluetooth { +namespace discovery { +namespace device { + +class DataParser { + public: + DataParser(const std::vector& data); + + std::vector GetData() const; + std::vector GetDataTypes() const; + size_t GetNumGapData() const; + + protected: + std::vector gap_data_; +}; + +} // namespace device +} // namespace discovery +} // namespace bluetooth diff --git a/system/gd/discovery/device/data_parser_unittest.cc b/system/gd/discovery/device/data_parser_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..b512f8791dbe2c654b3680be393ab488c59a2c35 --- /dev/null +++ b/system/gd/discovery/device/data_parser_unittest.cc @@ -0,0 +1,267 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "discovery/device/data_parser.h" + +#include + +#include "gtest/gtest.h" +#include "hci/hci_packets.h" + +using namespace bluetooth::hci; +using bluetooth::discovery::device::DataParser; + +namespace { +constexpr uint8_t kOneFlag32Data[] = { + 0x5, static_cast(GapDataType::FLAGS), 0xde, 0xad, 0xbe, 0xef}; +constexpr uint8_t kTwoFlag32Data[] = { + 0x5, + static_cast(GapDataType::FLAGS), + 0xde, + 0xad, + 0xbe, + 0xef, + 0x5, + static_cast(GapDataType::FLAGS), + 0x11, + 0x22, + 0x33, + 0x44}; +constexpr uint8_t kNoUuid16Data[] = { + 0x2, static_cast(GapDataType::COMPLETE_LIST_16_BIT_UUIDS)}; +constexpr uint8_t kPartialUuid16Data[] = { + 0x2, static_cast(GapDataType::COMPLETE_LIST_16_BIT_UUIDS), 0x12}; +constexpr uint8_t kOneUuid16Data[] = { + 0x3, static_cast(GapDataType::COMPLETE_LIST_16_BIT_UUIDS), 0x12, 0x34}; + +uint32_t toLeInt(const std::vector& v) { + return v[3] | (v[2] << 8) | (v[1] << 16) | (v[0] << 24); +} + +} // namespace + +TEST(DataParserTest, no_data) { + auto data = std::make_shared>(); + + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); +} + +TEST(DataParserTest, one_element_data) { + auto data = std::make_shared>(1); + data->push_back(0xff); + + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); +} + +TEST(DataParserTest, two_element_data) { + auto data = std::make_shared>(2); + data->push_back(0xff); + data->push_back(0xff); + + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); +} + +TEST(DataParserTest, all_ones_data) { + auto data = std::make_shared>(256); + std::fill(data->begin(), data->end(), 0xff); + + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); +} + +TEST(DataParserTest, simple_flag) { + auto data = std::make_shared>( + kOneFlag32Data, kOneFlag32Data + sizeof(kOneFlag32Data)); + + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); + ASSERT_EQ(gap_data.data_type_, GapDataType::FLAGS); + ASSERT_EQ(0xdeadbeef, toLeInt(gap_data.data_)); +} + +TEST(DataParserTest, two_flags) { + auto data = std::make_shared>( + kTwoFlag32Data, kTwoFlag32Data + sizeof(kTwoFlag32Data)); + + auto it = Iterator(data); + GapData gap_data[2]; + it = GapData::Parse(&gap_data[0], it); + + ASSERT_EQ(it.NumBytesRemaining(), 1U /* length */ + 1U /* type */ + 4U /* data */); + ASSERT_EQ(gap_data[0].data_type_, GapDataType::FLAGS); + ASSERT_EQ((unsigned)0xdeadbeef, toLeInt(gap_data[0].data_)); + + it = GapData::Parse(&gap_data[1], it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); + ASSERT_EQ(gap_data[1].data_type_, GapDataType::FLAGS); + ASSERT_EQ((unsigned)0x11223344, toLeInt(gap_data[1].data_)); +} + +TEST(DataParserTest, no_uuid16) { + auto data = + std::make_shared>(kNoUuid16Data, kNoUuid16Data + sizeof(kNoUuid16Data)); + + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); + ASSERT_EQ(gap_data.data_type_, GapDataType::COMPLETE_LIST_16_BIT_UUIDS); + ASSERT_EQ(0U, gap_data.data_.size()); +} + +TEST(DataParserTest, partial_uuid16) { + auto data = std::make_shared>( + kPartialUuid16Data, kPartialUuid16Data + sizeof(kPartialUuid16Data)); + + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); + ASSERT_EQ(gap_data.data_type_, GapDataType::COMPLETE_LIST_16_BIT_UUIDS); + ASSERT_EQ(1U, gap_data.data_.size()); +} + +TEST(DataParserTest, one_uuid16) { + auto data = std::make_shared>( + kOneUuid16Data, kOneUuid16Data + sizeof(kOneUuid16Data)); + auto it = Iterator(data); + GapData gap_data; + it = GapData::Parse(&gap_data, it); + + ASSERT_EQ(it.NumBytesRemaining(), 0U); + ASSERT_EQ(gap_data.data_type_, GapDataType::COMPLETE_LIST_16_BIT_UUIDS); + ASSERT_EQ(2U, gap_data.data_.size()); +} + +TEST(DataParserTest, simple_data_parser) { + std::vector v(kTwoFlag32Data, kTwoFlag32Data + sizeof(kTwoFlag32Data)); + DataParser data_parser(v); + ASSERT_EQ(2U, data_parser.GetNumGapData()); + + std::vector flags; + std::vector gap_data = data_parser.GetData(); + for (const auto& data : gap_data) { + ASSERT_EQ(bluetooth::hci::GapDataType::FLAGS, data.data_type_); + flags.push_back(data); + } + + ASSERT_EQ(2U, flags.size()); + uint32_t value[2] = { + toLeInt(flags[0].data_), + toLeInt(flags[1].data_), + }; + ASSERT_EQ((unsigned)0xdeadbeef, value[0]); + ASSERT_EQ((unsigned)0x11223344, value[1]); +} + +TEST(DataParserTest, two_flags_backing_store_cleared) { + std::vector* v = new std::vector(sizeof(kTwoFlag32Data)); + std::copy(kTwoFlag32Data, kTwoFlag32Data + sizeof(kTwoFlag32Data), v->begin()); + DataParser data_parser(*v); + v->clear(); + ASSERT_EQ(2U, data_parser.GetNumGapData()); + + std::vector flags; + std::vector gap_data = data_parser.GetData(); + for (const auto& data : gap_data) { + ASSERT_EQ(bluetooth::hci::GapDataType::FLAGS, data.data_type_); + flags.push_back(data); + } + + ASSERT_EQ(2U, flags.size()); + uint32_t value[2] = { + toLeInt(flags[0].data_), + toLeInt(flags[1].data_), + }; + ASSERT_EQ((unsigned)0xdeadbeef, value[0]); + ASSERT_EQ((unsigned)0x11223344, value[1]); + + delete v; +} + +TEST(DataParserTest, backing_store_freed) { + uint8_t* data = (uint8_t*)malloc(sizeof(kTwoFlag32Data)); + std::copy(kTwoFlag32Data, kTwoFlag32Data + sizeof(kTwoFlag32Data), data); + DataParser data_parser(std::vector(data, data + sizeof(kTwoFlag32Data))); + free(data); + ASSERT_EQ(2U, data_parser.GetNumGapData()); + + std::vector flags; + std::vector gap_data = data_parser.GetData(); + for (const auto& data : gap_data) { + ASSERT_EQ(bluetooth::hci::GapDataType::FLAGS, data.data_type_); + flags.push_back(data); + } + + ASSERT_EQ(2U, flags.size()); + uint32_t value[2] = { + toLeInt(flags[0].data_), + toLeInt(flags[1].data_), + }; + ASSERT_EQ((unsigned)0xdeadbeef, value[0]); + ASSERT_EQ((unsigned)0x11223344, value[1]); +} + +std::string GapDataToString(const GapData& data) { + std::stringstream ss; + ss << std::hex << std::showbase << "LengthAndData { "; + ss << "data = " + << "VECTOR["; + for (size_t index = 0; index < data.data_.size(); index++) { + ss << ((index == 0) ? "" : ", ") << static_cast((data.data_[index])); + } + ss << "]"; + ss << " }"; + return ss.str(); +} + +TEST(DataParserTest, random) { + constexpr int kMaxLoop = 1000; + auto data = std::vector(512); + + for (int i = 0; i < kMaxLoop; i++) { + size_t size = rand() % 512; + for (size_t i = 0; i < size; i++) { + data[i] = rand() % 256; + } + DataParser data_parser(data); + + if (((i + 1) % 100) == 0) { + LOG_INFO("loop %d", i); + } + } +} diff --git a/system/gd/discovery/device/eir_data.cc b/system/gd/discovery/device/eir_data.cc new file mode 100644 index 0000000000000000000000000000000000000000..50a4f8ed785f17dff91e4b0d34e9783c3420373b --- /dev/null +++ b/system/gd/discovery/device/eir_data.cc @@ -0,0 +1,203 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "discovery/device/eir_data.h" + +#include +#include +#include +#include + +#include "hci/hci_packets.h" +#include "hci/uuid.h" + +using namespace bluetooth; + +using namespace bluetooth::hci; +using namespace bluetooth::packet; + +namespace bluetooth::discovery::device { + +EirData::EirData(const std::vector& data) : DataParser(data) {} + +bool EirData::GetCompleteNames(std::vector>& names) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::COMPLETE_LOCAL_NAME) { + std::array array; + std::copy(gap_data.data_.begin(), gap_data.data_.end(), array.begin()); + names.push_back(array); + } + } + return !names.empty(); +} + +bool EirData::GetShortenedNames(std::vector>& names) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::SHORTENED_LOCAL_NAME) { + std::array array; + std::copy(gap_data.data_.begin(), gap_data.data_.end(), array.begin()); + names.push_back(array); + } + } + return !names.empty(); +} + +bool EirData::GetUuids16(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::COMPLETE_LIST_16_BIT_UUIDS) { + auto it = gap_data.data_.begin(); + while (std::distance(it, gap_data.data_.end()) >= (signed)Uuid::kNumBytes16) { + uuids.push_back(*it | *(it + 1) << 8); + it += Uuid::kNumBytes16; + } + } + } + return !uuids.empty(); +} + +bool EirData::GetUuidsIncomplete16(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::INCOMPLETE_LIST_16_BIT_UUIDS) { + auto it = gap_data.data_.begin(); + while (std::distance(it, gap_data.data_.end()) >= (signed)Uuid::kNumBytes16) { + uuids.push_back(*it | *(it + 1) << 8); + it += Uuid::kNumBytes16; + } + } + } + return !uuids.empty(); +} + +bool EirData::GetUuids32(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::COMPLETE_LIST_32_BIT_UUIDS) { + auto it = gap_data.data_.begin(); + while (std::distance(it, gap_data.data_.end()) >= (signed)Uuid::kNumBytes32) { + uuids.push_back(*it | *(it + 1) << 8 | *(it + 2) << 16 | *(it + 3) << 24); + it += Uuid::kNumBytes32; + } + } + } + return !uuids.empty(); +} + +bool EirData::GetUuidsIncomplete32(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::INCOMPLETE_LIST_32_BIT_UUIDS) { + auto it = gap_data.data_.begin(); + while (std::distance(it, gap_data.data_.end()) >= (signed)Uuid::kNumBytes32) { + uuids.push_back(*it | *(it + 1) << 8 | *(it + 2) << 16 | *(it + 3) << 24); + it += Uuid::kNumBytes32; + } + } + } + return !uuids.empty(); +} + +bool EirData::GetUuids128(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::COMPLETE_LIST_128_BIT_UUIDS) { + auto it = gap_data.data_.begin(); + while (std::distance(it, gap_data.data_.end()) >= (long)Uuid::kNumBytes128) { + auto uuid = bluetooth::hci::Uuid::From128BitLE(&it[0]); + uuids.push_back(uuid); + it += Uuid::kNumBytes128; + } + } + } + return !uuids.empty(); +} + +bool EirData::GetUuidsIncomplete128(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::INCOMPLETE_LIST_128_BIT_UUIDS) { + auto it = gap_data.data_.begin(); + while (std::distance(it, gap_data.data_.end()) >= (long)Uuid::kNumBytes128) { + auto uuid = bluetooth::hci::Uuid::From128BitLE(&it[0]); + uuids.push_back(uuid); + it += Uuid::kNumBytes128; + } + } + } + return !uuids.empty(); +} + +bool EirData::GetDeviceId(std::vector>& device_ids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::DEVICE_ID) { + device_ids.push_back(gap_data.data_); + } + } + return !device_ids.empty(); +} + +bool EirData::GetManufacturerSpecificData(std::vector>& data) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::MANUFACTURER_SPECIFIC_DATA) { + data.push_back(gap_data.data_); + } + } + return !data.empty(); +} + +bool EirData::GetSecurityManagerOobFlags(std::vector>& flags) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::SECURITY_MANAGER_OOB_FLAGS) { + flags.push_back(gap_data.data_); + } + } + return !flags.empty(); +} + +bool EirData::GetServiceUuuids16(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::SERVICE_DATA_16_BIT_UUIDS) { + if (gap_data.data_.size() < Uuid::kNumBytes16) continue; + auto it = gap_data.data_.begin(); + uuids.push_back({ + .uuid = (uint16_t)(*it | *(it + 1) << 8), + .data = std::vector(it + Uuid::kNumBytes16, gap_data.data_.end()), + }); + } + } + return !uuids.empty(); +} + +bool EirData::GetServiceUuuids32(std::vector& uuids) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::SERVICE_DATA_32_BIT_UUIDS) { + if (gap_data.data_.size() < Uuid::kNumBytes32) continue; + auto it = gap_data.data_.begin(); + uuids.push_back({ + .uuid = (uint32_t)(*it | *(it + 1) << 8 | *(it + 2) << 16 | *(it + 3) << 24), + .data = std::vector(it + Uuid::kNumBytes32, gap_data.data_.end()), + }); + } + } + return !uuids.empty(); +} + +bool EirData::GetTxPowerLevel(std::vector& tx_power_level) const { + for (const auto& gap_data : gap_data_) { + if (gap_data.data_type_ == hci::GapDataType::TX_POWER_LEVEL) { + if (gap_data.data_.size() == 1U) + tx_power_level.push_back(static_cast(gap_data.data_[0])); + } + } + return !tx_power_level.empty(); +} + +} // namespace bluetooth::discovery::device diff --git a/system/gd/discovery/device/eir_data.h b/system/gd/discovery/device/eir_data.h new file mode 100644 index 0000000000000000000000000000000000000000..d4752aec18cd97eb2d5a568473976e647b19d74d --- /dev/null +++ b/system/gd/discovery/device/eir_data.h @@ -0,0 +1,65 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "discovery/device/data_parser.h" +#include "hci/uuid.h" + +namespace bluetooth { +namespace discovery { +namespace device { + +struct service_uuid16_t { + uint16_t uuid; + std::vector data; +}; + +struct service_uuid32_t { + uint32_t uuid; + std::vector data; +}; + +class EirData : public DataParser { + public: + EirData(const std::vector& data); + + bool GetCompleteNames(std::vector>&) const; + bool GetShortenedNames(std::vector>&) const; + + bool GetUuids16(std::vector&) const; + bool GetUuidsIncomplete16(std::vector&) const; + bool GetUuids32(std::vector&) const; + bool GetUuidsIncomplete32(std::vector&) const; + bool GetUuids128(std::vector&) const; + bool GetUuidsIncomplete128(std::vector&) const; + + bool GetDeviceId(std::vector>&) const; + + bool GetManufacturerSpecificData(std::vector>&) const; + + bool GetSecurityManagerOobFlags(std::vector>&) const; + bool GetServiceUuuids16(std::vector&) const; + bool GetServiceUuuids32(std::vector&) const; + bool GetTxPowerLevel(std::vector&) const; +}; + +} // namespace device +} // namespace discovery +} // namespace bluetooth diff --git a/system/gd/discovery/device/eir_data_unittest.cc b/system/gd/discovery/device/eir_data_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..3d1ea720584ae888aa2a900ebff47e1a1f663e45 --- /dev/null +++ b/system/gd/discovery/device/eir_data_unittest.cc @@ -0,0 +1,239 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "discovery/device/eir_data.h" + +#include "discovery/device/eir_test_data_packets.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "hci/hci_packets.h" +#include "os/log.h" + +using namespace bluetooth; +using bluetooth::discovery::device::EirData; + +namespace { +constexpr uint8_t kPartialUuid16Data[] = { + 0x2, static_cast(hci::GapDataType::COMPLETE_LIST_16_BIT_UUIDS), 0x34}; +constexpr uint8_t kOneUuid16Data[] = { + 0x3, static_cast(hci::GapDataType::COMPLETE_LIST_16_BIT_UUIDS), 0x34, 0x12}; +constexpr char kAudiMmi9962[] = "Audi_MMI_9962"; +constexpr char kChromeBoxForMeetings[] = "Chromebox for Meetings"; + +} // namespace + +namespace debug { +void LogUuids16(const std::vector& uuids16) { + for (const auto& uuid : uuids16) { + LOG_INFO(" uuid:0x%x", uuid); + } +} + +void LogUuids128(const std::vector& uuids128) { + for (const auto& uuid : uuids128) { + LOG_INFO(" uuid:%s", uuid.ToString().c_str()); + } +} +} // namespace debug + +TEST(EirDataTest, partial_uuid16) { + const EirData eir_data( + std::vector(kPartialUuid16Data, kPartialUuid16Data + sizeof(kPartialUuid16Data))); + + std::vector uuids; + ASSERT_FALSE(eir_data.GetUuids16(uuids)); +} + +TEST(EirDataTest, one_uuid16) { + const EirData eir_data( + std::vector(kOneUuid16Data, kOneUuid16Data + sizeof(kOneUuid16Data))); + + std::vector uuids; + ASSERT_TRUE(eir_data.GetUuids16(uuids)); + ASSERT_EQ(1U, uuids.size()); + ASSERT_EQ(0x1234, uuids[0]); +} + +TEST(EirDataTest, test_data_packets__data_type) { + ASSERT_EQ(1U, selected_packets.count("pkt34639")); + const auto& pkt = selected_packets["pkt34639"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector gap_data_types = eir_data.GetDataTypes(); + ASSERT_EQ(6U, gap_data_types.size()); +} + +TEST(EirDataTest, test_data_packets__complete_name) { + ASSERT_EQ(1U, selected_packets.count("pkt34639")); + const auto& pkt = selected_packets["pkt34639"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector> names; + ASSERT_TRUE(eir_data.GetCompleteNames(names)); + ASSERT_EQ(1U, names.size()); + std::string name(names[0].begin(), names[0].end()); + ASSERT_STREQ(kAudiMmi9962, name.c_str()); +} + +TEST(EirDataTest, test_data_packets__uuids16) { + ASSERT_EQ(1U, selected_packets.count("pkt34639")); + const auto& pkt = selected_packets["pkt34639"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector uuids16; + ASSERT_TRUE(eir_data.GetUuids16(uuids16)); + ASSERT_EQ(14U, uuids16.size()); + ASSERT_EQ(0x112e, uuids16[0]); + ASSERT_EQ(0x180a, uuids16[13]); +} + +TEST(EirDataTest, test_data_packets__uuids16_incomplete) { + ASSERT_EQ(1U, selected_packets.count("pkt19200")); + const auto& pkt = selected_packets["pkt19200"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector uuids16; + ASSERT_TRUE(eir_data.GetUuidsIncomplete16(uuids16)); + ASSERT_EQ(7U, uuids16.size()); + ASSERT_EQ(0x110d, uuids16[0]); + ASSERT_EQ(0x1131, uuids16[6]); +} + +TEST(EirDataTest, test_data_packets__device_id) { + ASSERT_EQ(1U, selected_packets.count("pkt2062")); + const auto& pkt = selected_packets["pkt2062"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector> device_ids; + ASSERT_TRUE(eir_data.GetDeviceId(device_ids)); + ASSERT_EQ(1U, device_ids.size()); + ASSERT_EQ(0x01, device_ids[0][0]); +} + +TEST(EirDataTest, test_data_packets__manufacturer_data) { + ASSERT_EQ(1U, selected_packets.count("pkt26171")); + const auto& pkt = selected_packets["pkt26171"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector> mfr_data; + ASSERT_TRUE(eir_data.GetManufacturerSpecificData(mfr_data)); + ASSERT_EQ(1U, mfr_data.size()); + ASSERT_EQ(0, mfr_data[0][0]); +} + +TEST(EirDataTest, test_data_packets__security_manager_oob_flags) { + ASSERT_EQ(1U, selected_packets.count("pkt26171")); + const auto& pkt = selected_packets["pkt26171"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector> oob_flags; + ASSERT_TRUE(eir_data.GetManufacturerSpecificData(oob_flags)); + ASSERT_EQ(1U, oob_flags.size()); + ASSERT_EQ(0, oob_flags[0][0]); +} + +TEST(EirDataTest, test_data_packets__service_uuids16) { + ASSERT_EQ(1U, selected_packets.count("pktAsha")); + const auto& pkt = selected_packets["pktAsha"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector service_uuids16; + ASSERT_TRUE(eir_data.GetServiceUuuids16(service_uuids16)); + ASSERT_EQ(1U, service_uuids16.size()); + ASSERT_EQ(0xfdf0, service_uuids16[0].uuid); +} + +TEST(EirDataTest, test_data_packets__service_uuids32) { + for (const auto& pkt : data_packets) { + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + std::vector service_uuids32; + ASSERT_FALSE(eir_data.GetServiceUuuids32(service_uuids32)); + } +} + +TEST(EirDataTest, test_data_packets__tx_power_level) { + ASSERT_EQ(1U, selected_packets.count("pkt34639")); + const auto& pkt = selected_packets["pkt34639"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector levels; + ASSERT_TRUE(eir_data.GetTxPowerLevel(levels)); + ASSERT_EQ(1U, levels.size()); + ASSERT_EQ(4, levels[0]); +} + +TEST(EirDataTest, test_select_packets__pktAsha) { + ASSERT_EQ(1U, selected_packets.count("pktAsha")); + const auto& pkt = selected_packets["pktAsha"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector> names; + ASSERT_TRUE(eir_data.GetCompleteNames(names)); + std::string name(names[0].begin(), names[0].end()); + ASSERT_STREQ(kChromeBoxForMeetings, name.c_str()); + + std::vector tx_power_level; + ASSERT_TRUE(eir_data.GetTxPowerLevel(tx_power_level)); + ASSERT_EQ(10, tx_power_level[0]); + + const std::vector v1 = + std::vector({0x01, 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00}); + std::vector> device_ids; + ASSERT_TRUE(eir_data.GetDeviceId(device_ids)); + ASSERT_EQ(v1.size(), device_ids[0].size()); + ASSERT_THAT(v1, testing::ContainerEq(device_ids[0])); + + const std::vector v2 = + std::vector({0x1800, 0x1801, 0x180a, 0x110e, 0x110c, 0x111f, 0x110a}); + std::vector uuids16; + ASSERT_TRUE(eir_data.GetUuids16(uuids16)); + ASSERT_EQ(v2.size(), uuids16.size()); + ASSERT_THAT(v2, testing::ContainerEq(uuids16)); + + std::vector service_uuids16; + ASSERT_TRUE(eir_data.GetServiceUuuids16(service_uuids16)); + ASSERT_EQ(1U, service_uuids16.size()); + ASSERT_EQ(0xfdf0, service_uuids16[0].uuid); +} + +TEST(EirDataTest, test_select_packets__pkt34639) { + ASSERT_EQ(1U, selected_packets.count("pkt34639")); + const auto& pkt = selected_packets["pkt34639"]; + const EirData eir_data(std::vector(&pkt[kEirOffset], &pkt[kEirOffset] + kEirSize)); + + std::vector uuids16; + ASSERT_TRUE(eir_data.GetUuids16(uuids16)); + ASSERT_EQ(14U, uuids16.size()); + ASSERT_EQ(0x112e, uuids16[0]); + ASSERT_EQ(0x180a, uuids16[13]); + + std::vector uuids32; + ASSERT_FALSE(eir_data.GetUuids32(uuids32)); + ASSERT_EQ(0U, uuids32.size()); + + std::vector uuids128; + ASSERT_TRUE(eir_data.GetUuids128(uuids128)); + + ASSERT_EQ(hci::Uuid::FromString("00000000-deca-fade-deca-deafdecacaff"), uuids128[0]); + + std::vector tx_power_level; + ASSERT_TRUE(eir_data.GetTxPowerLevel(tx_power_level)); + ASSERT_EQ(4, tx_power_level[0]); + + std::vector> names; + ASSERT_TRUE(eir_data.GetCompleteNames(names)); + ASSERT_STREQ("Audi_MMI_9962", std::string(names[0].begin(), names[0].end()).data()); +} diff --git a/system/gd/discovery/device/eir_test_data_packets.cc b/system/gd/discovery/device/eir_test_data_packets.cc new file mode 100644 index 0000000000000000000000000000000000000000..cf2a21c99f438f4cc066be6d1cfa87911c89273c --- /dev/null +++ b/system/gd/discovery/device/eir_test_data_packets.cc @@ -0,0 +1,13502 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +// Frame (258 bytes) +static const unsigned char pkt34638[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x0b, 0x7e, 0x2c, 0x2d, // ./...~,- + 0x7c, 0x00, 0x01, 0x00, 0x3c, 0x04, 0x0c, 0xba, // |...<... + 0x0a, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34639[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x16, 0xaa, 0x9c, 0x85, // ./...... + 0x5a, 0x88, 0x01, 0x00, 0x08, 0x04, 0x34, 0xc7, // Z.....4. + 0x71, 0xc0, 0x1d, 0x03, 0x2e, 0x11, 0x05, 0x11, // q....... + 0x00, 0x12, 0x00, 0x18, 0x01, 0x18, 0x4c, 0xfe, // ......L. + 0x0e, 0x11, 0x0f, 0x11, 0x0c, 0x11, 0x0b, 0x11, // ........ + 0x1e, 0x11, 0x03, 0x12, 0x1f, 0x11, 0x0a, 0x18, // ........ + 0x01, 0x05, 0x31, 0x07, 0xff, 0xca, 0xca, 0xde, // ..1..... + 0xaf, 0xde, 0xca, 0xde, 0xde, 0xfa, 0xca, 0xde, // ........ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x9a, 0x0c, 0x20, // ....f.. + 0x00, 0x08, 0xf4, 0xbd, 0xe6, 0x11, 0xcb, 0x52, // .......R + 0x00, 0x7a, 0xe1, 0x4d, 0xd3, 0x1f, 0xbf, 0x50, // .z.M...P + 0x5d, 0x57, 0x27, 0x97, 0xa2, 0x40, 0x41, 0xcd, // ]W'..@A. + 0x48, 0x43, 0x88, 0xec, 0x02, 0x0a, 0x04, 0x0e, // HC...... + 0x09, 0x41, 0x75, 0x64, 0x69, 0x5f, 0x4d, 0x4d, // .Audi_MM + 0x49, 0x5f, 0x39, 0x39, 0x36, 0x32, 0x00, 0x00, // I_9962.. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2048[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x2f, 0xa9, 0x08, 0x71, // ./../..q + 0xeb, 0x50, 0x01, 0x00, 0x04, 0x01, 0x48, 0xb9, // .P....H. + 0x57, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // W...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2062[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x97, 0xa8, 0x0a, 0x71, // ./.....q + 0xeb, 0x50, 0x01, 0x00, 0x04, 0x01, 0x48, 0x49, // .P....HI + 0x42, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // B...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2063[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x4f, 0xd1, 0xf1, 0x2a, // ./..O..* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0x5e, // ......H^ + 0x43, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // C...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2064[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x4f, 0xd1, 0xf1, 0x2a, // ./..O..* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0x5e, // ......H^ + 0x43, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // C...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2067[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x9c, 0xa1, 0x20, 0x23, // ./.... # + 0xce, 0xf4, 0x01, 0x00, 0x04, 0x01, 0x48, 0x93, // ......H. + 0x36, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // 6...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0c, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2072[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc6, 0x4b, 0xd8, 0xb6, // ./...K.. + 0x80, 0x5c, 0x01, 0x00, 0x04, 0x01, 0x48, 0xfb, // .\....H. + 0x41, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // A...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2075[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x77, 0x08, 0x25, 0x99, // ./..w.%. + 0xec, 0x40, 0x01, 0x00, 0x04, 0x01, 0x48, 0xf4, // .@....H. + 0x18, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt2076[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc4, 0x8d, 0x25, 0x99, // ./....%. + 0xec, 0x40, 0x01, 0x00, 0x04, 0x01, 0x48, 0x41, // .@....HA + 0x5d, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ]...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19189[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc6, 0x4b, 0xd8, 0xb6, // ./...K.. + 0x80, 0x5c, 0x01, 0x00, 0x04, 0x01, 0x48, 0xfa, // .\....H. + 0x41, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // A...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19190[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf6, 0x8b, 0xf4, 0x2a, // ./.....* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0xfc, // ......H. + 0x75, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // u...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19191[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x77, 0x08, 0x25, 0x99, // ./..w.%. + 0xec, 0x40, 0x01, 0x00, 0x04, 0x01, 0x48, 0xf2, // .@....H. + 0x18, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19192[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x2f, 0xa9, 0x08, 0x71, // ./../..q + 0xeb, 0x50, 0x01, 0x00, 0x04, 0x01, 0x48, 0xb8, // .P....H. + 0x57, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // W...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19193[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x4f, 0xd1, 0xf1, 0x2a, // ./..O..* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0x5c, // ......H + 0x43, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // C...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19194[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x5e, 0x64, 0xc3, 0x50, // ./..^d.P + 0x59, 0xa0, 0x01, 0x00, 0x04, 0x01, 0x48, 0xac, // Y.....H. + 0x5a, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // Z...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0c, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19198[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf1, 0xaf, 0xf3, 0x2a, // ./.....* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0xba, // ......H. + 0x10, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19200[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x98, 0xa7, 0xcd, 0xd2, // ./...... + 0x96, 0x7c, 0x01, 0x00, 0x18, 0x04, 0x24, 0x21, // .|....$! + 0x55, 0x7f, 0x09, 0x10, 0x01, 0x00, 0x0a, 0x00, // U....... + 0xff, 0xff, 0xff, 0xff, 0x02, 0x0a, 0x04, 0x0f, // ........ + 0x02, 0x0d, 0x11, 0x0b, 0x11, 0x0e, 0x11, 0x0f, // ........ + 0x11, 0x1e, 0x11, 0x08, 0x11, 0x31, 0x11, 0x06, // .....1.. + 0x09, 0x41, 0x63, 0x72, 0x75, 0x78, 0x00, 0x00, // .Acrux.. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19201[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x1d, 0xee, 0x9d, 0xdf, // ./...... + 0xcc, 0x90, 0x01, 0x00, 0x04, 0x01, 0x48, 0x76, // ......Hv + 0x1b, 0x7f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19835[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc6, 0x4b, 0xd8, 0xb6, // ./...K.. + 0x80, 0x5c, 0x01, 0x00, 0x04, 0x01, 0x48, 0xfa, // .\....H. + 0x41, 0xbe, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // A...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19844[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf6, 0x8b, 0xf4, 0x2a, // ./.....* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0xfb, // ......H. + 0x75, 0xb5, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // u...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19845[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x77, 0x08, 0x25, 0x99, // ./..w.%. + 0xec, 0x40, 0x01, 0x00, 0x04, 0x01, 0x48, 0xf2, // .@....H. + 0x18, 0xb3, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19846[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x21, 0x51, 0xeb, 0xd5, // ./..!Q.. + 0xab, 0xd0, 0x01, 0x00, 0x04, 0x01, 0x48, 0x99, // ......H. + 0x06, 0xc6, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19857[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xdc, 0xd0, 0xf1, 0x2a, // ./.....* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0xbb, // ......H. + 0x6b, 0x13, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // k...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19863[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x4f, 0xd1, 0xf1, 0x2a, // ./..O..* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0x5c, // ......H + 0x43, 0xb7, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // C...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19871[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf1, 0xaf, 0xf3, 0x2a, // ./.....* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0xb8, // ......H. + 0x10, 0xaf, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19885[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xa1, 0x7b, 0x78, 0x83, // ./...{x. + 0xf8, 0xd8, 0x01, 0x00, 0x04, 0x01, 0x48, 0x80, // ......H. + 0x7f, 0xae, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19886[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x1d, 0xee, 0x9d, 0xdf, // ./...... + 0xcc, 0x90, 0x01, 0x00, 0x04, 0x01, 0x48, 0x75, // ......Hu + 0x1b, 0xa7, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19898[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xe0, 0x76, 0x2f, 0xd5, // ./...v/. + 0xab, 0xd0, 0x01, 0x00, 0x04, 0x01, 0x48, 0xcc, // ......H. + 0x13, 0xad, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19899[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x87, 0xa8, 0xf1, 0x2a, // ./.....* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0xf1, // ......H. + 0x15, 0xa7, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19904[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x09, 0x1e, 0x87, 0x83, // ./...... + 0xf8, 0xd8, 0x01, 0x00, 0x04, 0x01, 0x48, 0x1b, // ......H. + 0x4d, 0x9f, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // M...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19908[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc4, 0x8d, 0x25, 0x99, // ./....%. + 0xec, 0x40, 0x01, 0x00, 0x04, 0x01, 0x48, 0x40, // .@....H@ + 0x5d, 0xb5, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ]...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt33190[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x98, 0xa7, 0xcd, 0xd2, // ./...... + 0x96, 0x7c, 0x01, 0x00, 0x18, 0x04, 0x24, 0xc0, // .|....$. + 0x46, 0xd1, 0x09, 0x10, 0x01, 0x00, 0x0a, 0x00, // F....... + 0xff, 0xff, 0xff, 0xff, 0x02, 0x0a, 0x04, 0x0f, // ........ + 0x02, 0x0d, 0x11, 0x0b, 0x11, 0x0e, 0x11, 0x0f, // ........ + 0x11, 0x1e, 0x11, 0x08, 0x11, 0x31, 0x11, 0x06, // .....1.. + 0x09, 0x41, 0x63, 0x72, 0x75, 0x78, 0x00, 0x00, // .Acrux.. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt33191[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x1a, 0x02, 0xd8, 0xb6, // ./...... + 0x80, 0x5c, 0x01, 0x00, 0x04, 0x01, 0x48, 0xff, // .\....H. + 0x06, 0xa4, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt33217[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc4, 0x8d, 0x25, 0x99, // ./....%. + 0xec, 0x40, 0x01, 0x00, 0x04, 0x01, 0x48, 0x3f, // .@....H? + 0x5d, 0xb6, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ]...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34019[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xa1, 0x7b, 0x78, 0x83, // ./...{x. + 0xf8, 0xd8, 0x01, 0x00, 0x04, 0x01, 0x48, 0x7e, // ......H~ + 0x7f, 0xa9, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34020[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x98, 0xa7, 0xcd, 0xd2, // ./...... + 0x96, 0x7c, 0x01, 0x00, 0x18, 0x04, 0x24, 0xa7, // .|....$. + 0x42, 0xd0, 0x09, 0x10, 0x01, 0x00, 0x0a, 0x00, // B....... + 0xff, 0xff, 0xff, 0xff, 0x02, 0x0a, 0x04, 0x0f, // ........ + 0x02, 0x0d, 0x11, 0x0b, 0x11, 0x0e, 0x11, 0x0f, // ........ + 0x11, 0x1e, 0x11, 0x08, 0x11, 0x31, 0x11, 0x06, // .....1.. + 0x09, 0x41, 0x63, 0x72, 0x75, 0x78, 0x00, 0x00, // .Acrux.. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19975[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x72, 0x5f, 0x1e, 0x2a, // ./..r_.* + 0x9a, 0xb8, 0x01, 0x00, 0x04, 0x01, 0x48, 0xa0, // ......H. + 0x04, 0xa9, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // ....Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x6c, 0x00, 0x0f, // .....l.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19988[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x03, 0xe3, 0x63, 0x83, // ./....c. + 0x1c, 0x40, 0x01, 0x00, 0x04, 0x01, 0x48, 0x2c, // .@....H, + 0x27, 0xaf, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // '...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x72, 0x00, 0x0f, // .....r.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt20036[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x83, 0x35, 0x3c, 0x4b, // ./...5.. + 0x01, 0x07, 0xe1, 0xb5, 0x0b, 0x70, 0x00, 0x00, // .....p.. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt29927[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x4c, 0xd6, 0x93, 0xd5, // ./..L... + 0xd6, 0x48, 0x01, 0x00, 0x00, 0x04, 0x24, 0x78, // .H....$x + 0x79, 0xc3, 0x07, 0x09, 0x53, 0x68, 0x69, 0x65, // y...Shie + 0x6c, 0x64, 0xff, 0x11, 0x00, 0x00, 0x00, 0x00, // ld...... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x24, // .......$ + 0xb8, 0xcb, 0xed, 0x03, 0xe5, 0x3e, 0x01, 0x05, // .....>.. + 0x01, 0x07, 0xe1, 0xb5, 0x0b, 0x70, 0x00, 0x00, // .....p.. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt29928[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xa8, 0xc7, 0xb3, 0x4b, // ./.....K + 0x04, 0x00, 0x01, 0x00, 0x24, 0x04, 0x28, 0x32, // ....$.(2 + 0x27, 0xc7, 0x07, 0x09, 0x53, 0x68, 0x69, 0x65, // '...Shie + 0x6c, 0x64, 0x09, 0x03, 0x0a, 0x11, 0x0c, 0x11, // ld...... + 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, 0x81, 0x07, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt29931[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x4c, 0xd6, 0x93, 0xd5, // ./..L... + 0xd6, 0x48, 0x01, 0x00, 0x00, 0x04, 0x24, 0x78, // .H....$x + 0x79, 0xc8, 0x09, 0x09, 0x48, 0x6f, 0x6d, 0x65, // y...Home + 0x20, 0x4d, 0x61, 0x78, 0x09, 0x03, 0x0b, 0x11, // Max.... + 0x0c, 0x11, 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, // ........ + 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt23904[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf9, 0xe8, 0xa0, 0x26, // ./.....& + 0xe5, 0xee, 0x01, 0x00, 0x04, 0x44, 0x24, 0x4b, // .....D$K + 0x1e, 0xb6, 0x0e, 0x09, 0x4c, 0x52, 0x31, 0x30, // ....LR10 + 0x5f, 0x4e, 0x46, 0x46, 0x5f, 0x65, 0x38, 0x66, // _NFF_e8f + 0x39, 0x09, 0x03, 0x0b, 0x11, 0x0c, 0x11, 0x0e, // 9....... + 0x11, 0x1e, 0x11, 0x51, 0x07, 0xb5, 0xf7, 0x08, // ...Q.... + 0xa7, 0x64, 0xf7, 0x51, 0x89, 0x4c, 0x4c, 0xce, // .d.Q.LL. + 0x24, 0xf7, 0x7f, 0xe9, 0x25, 0x7c, 0x92, 0x67, // $...%|.g + 0x4d, 0x2c, 0xf1, 0x86, 0x88, 0xdb, 0x4f, 0x15, // M,....O. + 0x25, 0x2c, 0xfe, 0x21, 0xdf, 0xb4, 0xf7, 0x08, // %,.!.... + 0xa7, 0x64, 0xf7, 0x51, 0x89, 0x4c, 0x4c, 0xce, // .d.Q.LL. + 0x24, 0xf7, 0x7f, 0xe9, 0x25, 0x85, 0x98, 0xa9, // $...%... + 0x83, 0x48, 0xfe, 0x2f, 0x85, 0x15, 0x41, 0xe5, // .H./..A. + 0xd5, 0x65, 0xcc, 0xe6, 0xfb, 0xf5, 0x21, 0x01, // .e....!. + 0xeb, 0x59, 0x9d, 0x19, 0x86, 0x36, 0x47, 0x26, // .Y...6G& + 0xce, 0xf0, 0x0b, 0x27, 0x4b, 0x00, 0x00, 0x00, // ...'K... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt24033[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf1, 0x53, 0xf3, 0xfe, // ./...S.. + 0x72, 0x70, 0x01, 0x00, 0x0c, 0x01, 0x28, 0xa0, // rp....(. + 0x2b, 0xc6, 0x1c, 0x09, 0x4d, 0x6f, 0x72, 0x74, // +...Mort + 0x65, 0x7a, 0x61, 0xe2, 0x80, 0x99, 0x73, 0x20, // eza...s + 0x4d, 0x61, 0x63, 0x42, 0x6f, 0x6f, 0x6b, 0x20, // MacBook + 0x50, 0x72, 0x6f, 0x20, 0x28, 0x32, 0x29, 0x0b, // Pro (2). + 0x03, 0x00, 0x12, 0x1f, 0x11, 0x0a, 0x11, 0x0c, // ........ + 0x11, 0x01, 0x18, 0x01, 0x05, 0x01, 0x07, 0x27, // .......' + 0xff, 0x00, 0x4c, 0x02, 0x24, 0x02, 0x00, 0x00, // ..L.$... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt24158[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x5c, 0xfa, 0x47, 0x2c, // ./..\.G, + 0x3a, 0xd4, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x04, // :....BZ. + 0x72, 0xd6, 0x0b, 0x09, 0x48, 0x69, 0x20, 0x72, // r...Hi r + 0x65, 0x6e, 0x65, 0x73, 0x61, 0x73, 0x19, 0x03, // enesas.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt24446[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6f, 0xff, 0xf6, 0x11, // ./..o... + 0x8c, 0xfc, 0x01, 0x00, 0x0c, 0x41, 0x2a, 0x03, // .....A*. + 0x64, 0xcc, 0x09, 0x09, 0x4d, 0x53, 0x46, 0x54, // d...MSFT + 0x55, 0x50, 0x46, 0x31, 0x02, 0x0a, 0x0b, 0x0d, // UPF1.... + 0x03, 0x0a, 0x11, 0x0b, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt24658[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xdf, 0xf4, 0x7f, 0x79, // ./.....y + 0x50, 0x7c, 0x01, 0x00, 0x0c, 0x41, 0x2a, 0x66, // P|...A*f + 0x51, 0xc1, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // Q...DESK + 0x54, 0x4f, 0x50, 0x2d, 0x48, 0x4c, 0x48, 0x46, // TOP-HLHF + 0x52, 0x30, 0x49, 0x02, 0x0a, 0x0c, 0x0d, 0x03, // R0I..... + 0x0a, 0x11, 0x0b, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt25745[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xaa, 0xcc, 0x40, 0x6a, // ./....@j + 0x01, 0x43, 0x01, 0x00, 0x04, 0x44, 0x24, 0x82, // .C...D$. + 0x37, 0xc5, 0x06, 0x09, 0x61, 0x34, 0x63, 0x63, // 7...a4cc + 0x63, 0x09, 0x03, 0x0b, 0x11, 0x0c, 0x11, 0x0e, // c....... + 0x11, 0x1e, 0x11, 0x51, 0x07, 0xfb, 0x34, 0x9b, // ...Q..4. + 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, // _....... + 0x00, 0x01, 0x11, 0x00, 0x00, 0x7c, 0x92, 0x67, // .....|.g + 0x4d, 0x2c, 0xf1, 0x86, 0x88, 0xdb, 0x4f, 0x15, // M,....O. + 0x25, 0x2c, 0xfe, 0x21, 0xdf, 0x95, 0xa8, 0x7e, // %,.!...~ + 0x16, 0x9f, 0xa6, 0x6d, 0x97, 0x40, 0x4e, 0xe3, // ...m.@N. + 0xb2, 0x66, 0xd6, 0x34, 0x12, 0x15, 0x0e, 0x33, // .f.4...3 + 0xc9, 0x96, 0xff, 0x24, 0x80, 0x34, 0x43, 0x66, // ...$.4Cf + 0x79, 0xe4, 0xfb, 0xd1, 0xf8, 0x51, 0x33, 0x59, // y....Q3Y + 0x88, 0xf9, 0x05, 0xff, 0xa1, 0x3e, 0x44, 0x91, // .....>D. + 0x05, 0x2a, 0xe7, 0xc2, 0x81, 0x00, 0x00, 0x00, // .*...... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt25751[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x15, 0xb8, 0xde, 0xea, // ./...... + 0x5f, 0xac, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x93, // _.....Z. + 0x42, 0xb5, 0x0b, 0x09, 0x4f, 0x6e, 0x65, 0x50, // B...OneP + 0x6c, 0x75, 0x73, 0x20, 0x38, 0x54, 0x17, 0x03, // lus 8T.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, // /...2... + 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt26171[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf1, 0x53, 0xf3, 0xfe, // ./...S.. + 0x72, 0x70, 0x01, 0x00, 0x0c, 0x01, 0x28, 0xa1, // rp....(. + 0x2b, 0xb9, 0x1c, 0x09, 0x4d, 0x6f, 0x72, 0x74, // +...Mort + 0x65, 0x7a, 0x61, 0xe2, 0x80, 0x99, 0x73, 0x20, // eza...s + 0x4d, 0x61, 0x63, 0x42, 0x6f, 0x6f, 0x6b, 0x20, // MacBook + 0x50, 0x72, 0x6f, 0x20, 0x28, 0x32, 0x29, 0x0b, // Pro (2). + 0x03, 0x00, 0x12, 0x1f, 0x11, 0x0a, 0x11, 0x0c, // ........ + 0x11, 0x01, 0x18, 0x01, 0x05, 0x01, 0x07, 0x27, // .......' + 0xff, 0x00, 0x4c, 0x02, 0x24, 0x02, 0x00, 0x00, // ..L.$... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt26175[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x51, 0x33, 0x33, 0x22, // ./..Q33" + 0x11, 0x11, 0x01, 0x00, 0x04, 0x44, 0x24, 0xeb, // .....D$. + 0x43, 0xbc, 0x0a, 0x09, 0x42, 0x45, 0x53, 0x2d, // C...BES- + 0x42, 0x52, 0x45, 0x44, 0x52, 0x15, 0x03, 0x01, // BREDR... + 0x00, 0x0e, 0x11, 0x0f, 0x11, 0x0c, 0x11, 0x0b, // ........ + 0x11, 0x1e, 0x11, 0x03, 0x12, 0x08, 0x11, 0x03, // ........ + 0x12, 0x01, 0x11, 0x01, 0x05, 0x01, 0x07, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt26328[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x02, 0x00, 0xf4, 0x35, // ./.....5 + 0x23, 0x48, 0x00, 0x00, 0x18, 0x04, 0x00, 0x3a, // #H.....: + 0x33, 0xc0, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x32, // 3...App2 + 0x5f, 0x30, 0x30, 0x30, 0x32, 0x00, 0x00, 0x00, // _0002... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt26463[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x9f, 0x73, 0x56, 0x2c, // ./...sV, + 0x3a, 0xd4, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xa5, // :....BZ. + 0x2d, 0xad, 0x08, 0x09, 0x50, 0x69, 0x78, 0x65, // -...Pixe + 0x6c, 0x20, 0x38, 0x19, 0x03, 0x05, 0x11, 0x0a, // l 8..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34640[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd5, 0x29, 0xa3, 0x34, // ./...).4 + 0x29, 0x24, 0x01, 0x00, 0x04, 0x44, 0x24, 0xbf, // )$...D$. + 0x78, 0xcf, 0x1a, 0x09, 0x73, 0x69, 0x64, 0x68, // x...sidh + 0x74, 0x65, 0x73, 0x74, 0x27, 0x73, 0x20, 0x2a, // test's * + 0x2a, 0x2a, 0x2a, 0x2a, 0x20, 0x2a, 0x2a, 0x2a, // **** *** + 0x2a, 0x20, 0x2a, 0x2a, 0x2a, 0x09, 0x03, 0x0b, // * ***... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x1e, 0x11, 0x51, // .......Q + 0x07, 0xb5, 0xf7, 0x08, 0xa7, 0x64, 0xf7, 0x51, // .....d.Q + 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, 0x7f, 0xe9, // .LL.$... + 0x25, 0x7c, 0x92, 0x67, 0x4d, 0x2c, 0xf1, 0x86, // %|.gM,.. + 0x88, 0xdb, 0x4f, 0x15, 0x25, 0x2c, 0xfe, 0x21, // ..O.%,.! + 0xdf, 0xb4, 0xf7, 0x08, 0xa7, 0x64, 0xf7, 0x51, // .....d.Q + 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, 0x7f, 0xe9, // .LL.$... + 0x25, 0x15, 0x0e, 0x33, 0xc9, 0x96, 0xff, 0x24, // %..3...$ + 0x80, 0x34, 0x43, 0x66, 0x79, 0xe4, 0xfb, 0xd1, // .4Cfy... + 0xf8, 0x51, 0x33, 0x59, 0x88, 0xf9, 0x05, 0xff, // .Q3Y.... + 0xa1, 0x3e, 0x44, 0x91, 0x05, 0x2a, 0xe7, 0xc2, // .>D..*.. + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34666[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x7f, 0xf4, 0xc3, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1d, // tt....Z. + 0x6d, 0xc1, 0x08, 0x09, 0x50, 0x69, 0x78, 0x65, // m...Pixe + 0x6c, 0x20, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, // l 6..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34778[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x7f, 0xf4, 0xc3, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1c, // tt....Z. + 0x6d, 0xbf, 0x08, 0x09, 0x50, 0x69, 0x78, 0x65, // m...Pixe + 0x6c, 0x20, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, // l 6..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34779[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd5, 0x29, 0xa3, 0x34, // ./...).4 + 0x29, 0x24, 0x01, 0x00, 0x04, 0x44, 0x24, 0xbf, // )$...D$. + 0x78, 0xd1, 0x1a, 0x09, 0x73, 0x69, 0x64, 0x68, // x...sidh + 0x74, 0x65, 0x73, 0x74, 0x27, 0x73, 0x20, 0x2a, // test's * + 0x2a, 0x2a, 0x2a, 0x2a, 0x20, 0x2a, 0x2a, 0x2a, // **** *** + 0x2a, 0x20, 0x2a, 0x2a, 0x2a, 0x09, 0x03, 0x0b, // * ***... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x1e, 0x11, 0x51, // .......Q + 0x07, 0xb5, 0xf7, 0x08, 0xa7, 0x64, 0xf7, 0x51, // .....d.Q + 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, 0x7f, 0xe9, // .LL.$... + 0x25, 0x7c, 0x92, 0x67, 0x4d, 0x2c, 0xf1, 0x86, // %|.gM,.. + 0x88, 0xdb, 0x4f, 0x15, 0x25, 0x2c, 0xfe, 0x21, // ..O.%,.! + 0xdf, 0xb4, 0xf7, 0x08, 0xa7, 0x64, 0xf7, 0x51, // .....d.Q + 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, 0x7f, 0xe9, // .LL.$... + 0x25, 0x15, 0x0e, 0x33, 0xc9, 0x96, 0xff, 0x24, // %..3...$ + 0x80, 0x34, 0x43, 0x66, 0x79, 0xe4, 0xfb, 0xd1, // .4Cfy... + 0xf8, 0x51, 0x33, 0x59, 0x88, 0xf9, 0x05, 0xff, // .Q3Y.... + 0xa1, 0x3e, 0x44, 0x91, 0x05, 0x2a, 0xe7, 0xc2, // .>D..*.. + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34843[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd5, 0x29, 0xa3, 0x34, // ./...).4 + 0x29, 0x24, 0x01, 0x00, 0x04, 0x44, 0x24, 0xc0, // )$...D$. + 0x78, 0xd3, 0x1a, 0x09, 0x73, 0x69, 0x64, 0x68, // x...sidh + 0x74, 0x65, 0x73, 0x74, 0x27, 0x73, 0x20, 0x2a, // test's * + 0x2a, 0x2a, 0x2a, 0x2a, 0x20, 0x2a, 0x2a, 0x2a, // **** *** + 0x2a, 0x20, 0x2a, 0x2a, 0x2a, 0x09, 0x03, 0x0b, // * ***... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x1e, 0x11, 0x51, // .......Q + 0x07, 0xb5, 0xf7, 0x08, 0xa7, 0x64, 0xf7, 0x51, // .....d.Q + 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, 0x7f, 0xe9, // .LL.$... + 0x25, 0x7c, 0x92, 0x67, 0x4d, 0x2c, 0xf1, 0x86, // %|.gM,.. + 0x88, 0xdb, 0x4f, 0x15, 0x25, 0x2c, 0xfe, 0x21, // ..O.%,.! + 0xdf, 0xb4, 0xf7, 0x08, 0xa7, 0x64, 0xf7, 0x51, // .....d.Q + 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, 0x7f, 0xe9, // .LL.$... + 0x25, 0x15, 0x0e, 0x33, 0xc9, 0x96, 0xff, 0x24, // %..3...$ + 0x80, 0x34, 0x43, 0x66, 0x79, 0xe4, 0xfb, 0xd1, // .4Cfy... + 0xf8, 0x51, 0x33, 0x59, 0x88, 0xf9, 0x05, 0xff, // .Q3Y.... + 0xa1, 0x3e, 0x44, 0x91, 0x05, 0x2a, 0xe7, 0xc2, // .>D..*.. + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34847[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x7f, 0xf4, 0xc3, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1d, // tt....Z. + 0x6d, 0xc0, 0x08, 0x09, 0x50, 0x69, 0x78, 0x65, // m...Pixe + 0x6c, 0x20, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, // l 6..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34848[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x8b, 0x6e, 0xf0, 0x85, // ./...n.. + 0xe0, 0x50, 0x01, 0x00, 0x04, 0x01, 0x48, 0x85, // .P....H. + 0x7a, 0xb3, 0x17, 0x09, 0x43, 0x68, 0x72, 0x6f, // z...Chro + 0x6d, 0x65, 0x62, 0x6f, 0x78, 0x20, 0x66, 0x6f, // mebox fo + 0x72, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, // r Meetin + 0x67, 0x73, 0x02, 0x0a, 0x0a, 0x09, 0x10, 0x01, // gs...... + 0x00, 0xe0, 0x00, 0x05, 0xc4, 0x67, 0x00, 0x0f, // .....g.. + 0x03, 0x00, 0x18, 0x01, 0x18, 0x0a, 0x18, 0x0e, // ........ + 0x11, 0x0c, 0x11, 0x1f, 0x11, 0x0a, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt34875[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x7f, 0xf4, 0xc3, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1c, // tt....Z. + 0x6d, 0xbd, 0x08, 0x09, 0x50, 0x69, 0x78, 0x65, // m...Pixe + 0x6c, 0x20, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, // l 6..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt19294[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xcb, 0x29, 0xa3, 0x34, // ./...).4 + 0x29, 0x24, 0x01, 0x00, 0x04, 0x44, 0x24, 0x97, // )$...D$. + 0x19, 0xd3, 0x0c, 0x09, 0x41, 0x31, 0x31, 0x5f, // ....A11_ + 0x46, 0x46, 0x5f, 0x32, 0x39, 0x63, 0x62, 0x09, // FF_29cb. + 0x03, 0x0b, 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x1e, // ........ + 0x11, 0x51, 0x07, 0xb5, 0xf7, 0x08, 0xa7, 0x64, // .Q.....d + 0xf7, 0x51, 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, // .Q.LL.$. + 0x7f, 0xe9, 0x25, 0x7c, 0x92, 0x67, 0x4d, 0x2c, // ..%|.gM, + 0xf1, 0x86, 0x88, 0xdb, 0x4f, 0x15, 0x25, 0x2c, // ....O.%, + 0xfe, 0x21, 0xdf, 0xb4, 0xf7, 0x08, 0xa7, 0x64, // .!.....d + 0xf7, 0x51, 0x89, 0x4c, 0x4c, 0xce, 0x24, 0xf7, // .Q.LL.$. + 0x7f, 0xe9, 0x25, 0x15, 0x0e, 0x33, 0xc9, 0x96, // ..%..3.. + 0xff, 0x24, 0x80, 0x34, 0x43, 0x66, 0x79, 0xe4, // .$.4Cfy. + 0xfb, 0xd1, 0xf8, 0x51, 0x33, 0x59, 0x88, 0xf9, // ...Q3Y.. + 0x05, 0xff, 0xa1, 0x3e, 0x44, 0x91, 0x05, 0x2a, // ...>D..* + 0xe7, 0xc2, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4073[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x52, 0xb4, 0x2e, 0x13, // ./..R... + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xac, // .....BZ. + 0x1c, 0xd5, 0x4d, 0x09, 0x49, 0x7a, 0x6b, 0x33, // ..M.Izk3 + 0x55, 0x6c, 0x6a, 0x38, 0x6e, 0x31, 0x34, 0x41, // Ulj8n14A + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, // AAAAAAAA + 0x4b, 0x53, 0x49, 0x66, 0x39, 0x54, 0x71, 0x61, // KSIf9Tqa + 0x51, 0x7a, 0x79, 0x6a, 0x36, 0x78, 0x32, 0x72, // Qzyj6x2r + 0x67, 0x35, 0x46, 0x50, 0x52, 0x50, 0x70, 0x5f, // g5FPRPp_ + 0x46, 0x31, 0x4a, 0x46, 0x51, 0x30, 0x56, 0x4a, // F1JFQ0VJ + 0x56, 0x6b, 0x56, 0x53, 0x4c, 0x54, 0x49, 0x30, // VkVSLTI0 + 0x4d, 0x54, 0x4d, 0x78, 0x52, 0x6b, 0x52, 0x49, // MTMxRkRI + 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x44, 0x5a, 0x4d, // MjAwMDZM + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x71, 0x06, 0x5a, 0x6c, // 2...q.Zl + 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, 0xde, 0x3d, // ..m....= + 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, 0x00, 0x00, // \.!..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4075[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x36, 0x1a, 0x37, 0x08, // ./..6.7. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xff, // ......Z. + 0x08, 0xd0, 0x4d, 0x09, 0x49, 0x7a, 0x4e, 0x42, // ..M.IzNB + 0x52, 0x31, 0x6a, 0x38, 0x6e, 0x31, 0x34, 0x41, // R1j8n14A + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, // AAAAAAAA + 0x4b, 0x53, 0x4c, 0x6e, 0x58, 0x75, 0x31, 0x73, // KSLnXu1s + 0x6d, 0x64, 0x54, 0x55, 0x65, 0x4d, 0x50, 0x43, // mdTUeMPC + 0x63, 0x32, 0x35, 0x67, 0x2d, 0x6e, 0x5a, 0x6f, // c25g-nZo + 0x46, 0x31, 0x4a, 0x46, 0x51, 0x30, 0x56, 0x4a, // F1JFQ0VJ + 0x56, 0x6b, 0x56, 0x53, 0x4c, 0x54, 0x41, 0x7a, // VkVSLTAz + 0x4d, 0x54, 0x49, 0x78, 0x53, 0x6b, 0x56, 0x44, // MTIxSkVD + 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x44, 0x59, 0x31, // MjAwMDY1 + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x71, 0x06, 0x5a, 0x6c, // 2...q.Zl + 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, 0xde, 0x3d, // ..m....= + 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, 0x00, 0x00, // \.!..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4883[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x52, 0xb4, 0x2e, 0x13, // ./..R... + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xac, // .....BZ. + 0x1c, 0xd4, 0x4d, 0x09, 0x49, 0x7a, 0x6b, 0x33, // ..M.Izk3 + 0x55, 0x6c, 0x6a, 0x38, 0x6e, 0x31, 0x34, 0x41, // Ulj8n14A + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, // AAAAAAAA + 0x4b, 0x53, 0x49, 0x37, 0x31, 0x59, 0x74, 0x6f, // KSI71Yto + 0x4a, 0x52, 0x6b, 0x31, 0x74, 0x72, 0x51, 0x79, // JRk1trQy + 0x4a, 0x77, 0x53, 0x71, 0x65, 0x35, 0x44, 0x45, // JwSqe5DE + 0x46, 0x31, 0x4a, 0x46, 0x51, 0x30, 0x56, 0x4a, // F1JFQ0VJ + 0x56, 0x6b, 0x56, 0x53, 0x4c, 0x54, 0x49, 0x30, // VkVSLTI0 + 0x4d, 0x54, 0x4d, 0x78, 0x52, 0x6b, 0x52, 0x49, // MTMxRkRI + 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x44, 0x5a, 0x4d, // MjAwMDZM + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x71, 0x06, 0x5a, 0x6c, // 2...q.Zl + 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, 0xde, 0x3d, // ..m....= + 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, 0x00, 0x00, // \.!..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt7384[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x36, 0x1a, 0x37, 0x08, // ./..6.7. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x00, // ......Z. + 0x09, 0xd1, 0x4d, 0x09, 0x49, 0x30, 0x63, 0x33, // ..M.I0c3 + 0x53, 0x46, 0x6e, 0x38, 0x6e, 0x31, 0x34, 0x41, // SFn8n14A + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, // AAAAAAAA + 0x4b, 0x53, 0x4c, 0x4e, 0x4b, 0x47, 0x35, 0x41, // KSLNKG5A + 0x43, 0x7a, 0x6a, 0x44, 0x35, 0x4e, 0x43, 0x38, // CzjD5NC8 + 0x68, 0x78, 0x55, 0x45, 0x61, 0x5f, 0x36, 0x74, // hxUEa_6t + 0x46, 0x31, 0x4a, 0x46, 0x51, 0x30, 0x56, 0x4a, // F1JFQ0VJ + 0x56, 0x6b, 0x56, 0x53, 0x4c, 0x54, 0x41, 0x7a, // VkVSLTAz + 0x4d, 0x54, 0x49, 0x78, 0x53, 0x6b, 0x56, 0x44, // MTIxSkVD + 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x44, 0x59, 0x31, // MjAwMDY1 + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x71, 0x06, 0x5a, 0x6c, // 2...q.Zl + 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, 0xde, 0x3d, // ..m....= + 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, 0x00, 0x00, // \.!..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt7385[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x52, 0xb4, 0x2e, 0x13, // ./..R... + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xad, // .....BZ. + 0x1c, 0xd6, 0x4d, 0x09, 0x49, 0x7a, 0x4a, 0x56, // ..M.IzJV + 0x4e, 0x45, 0x6a, 0x38, 0x6e, 0x31, 0x34, 0x41, // NEj8n14A + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, // AAAAAAAA + 0x4b, 0x53, 0x4a, 0x54, 0x43, 0x67, 0x54, 0x59, // KSJTCgTY + 0x30, 0x34, 0x55, 0x61, 0x54, 0x71, 0x57, 0x37, // 04UaTqW7 + 0x39, 0x78, 0x62, 0x76, 0x5f, 0x37, 0x69, 0x73, // 9xbv_7is + 0x46, 0x31, 0x4a, 0x46, 0x51, 0x30, 0x56, 0x4a, // F1JFQ0VJ + 0x56, 0x6b, 0x56, 0x53, 0x4c, 0x54, 0x49, 0x30, // VkVSLTI0 + 0x4d, 0x54, 0x4d, 0x78, 0x52, 0x6b, 0x52, 0x49, // MTMxRkRI + 0x4d, 0x6a, 0x41, 0x77, 0x4d, 0x44, 0x5a, 0x4d, // MjAwMDZM + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x71, 0x06, 0x5a, 0x6c, // 2...q.Zl + 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, 0xde, 0x3d, // ..m....= + 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, 0x00, 0x00, // \.!..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10784[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x64, 0x6f, 0x36, 0x08, // ./..do6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x0d, // ......Z. + 0x0c, 0xbd, 0x0f, 0x09, 0x39, 0x42, 0x32, 0x37, // ....9B27 + 0x31, 0x46, 0x51, 0x43, 0x32, 0x30, 0x30, 0x30, // 1FQC2000 + 0x37, 0x38, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 78...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10786[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc4, 0xd3, 0x3e, 0x13, // ./....>. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xf2, // .....BZ. + 0x6d, 0xd0, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x30, // m...2610 + 0x31, 0x46, 0x44, 0x48, 0x33, 0x30, 0x30, 0x30, // 1FDH3000 + 0x43, 0x39, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // C9...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10787[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x88, 0xc6, 0xd5, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x4f, // tt...BZO + 0x3e, 0xe3, 0x0f, 0x09, 0x33, 0x33, 0x31, 0x33, // >...3313 + 0x31, 0x46, 0x44, 0x48, 0x53, 0x30, 0x30, 0x30, // 1FDHS000 + 0x34, 0x4b, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 4K...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10789[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x85, 0xb3, 0x7e, 0x2f, // ./....~/ + 0x95, 0x24, 0x01, 0x00, 0x10, 0x41, 0x5a, 0x3e, // .$...AZ> + 0x38, 0xd1, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x30, // 8...2610 + 0x31, 0x46, 0x44, 0x48, 0x33, 0x30, 0x30, 0x30, // 1FDH3000 + 0x43, 0x39, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // C9...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10799[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x3b, 0x8e, 0x1d, 0x52, // ./..;..R + 0xcb, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x33, // .X....Z3 + 0x2f, 0xd5, 0x0b, 0x09, 0x39, 0x33, 0x36, 0x41, // /...936A + 0x58, 0x30, 0x34, 0x57, 0x37, 0x4c, 0x19, 0x03, // X04W7L.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10800[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf4, 0x9a, 0x38, 0x6e, // ./....8n + 0xb7, 0x60, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x74, // .`....Zt + 0x3f, 0xd6, 0x0f, 0x09, 0x30, 0x42, 0x31, 0x31, // ?...0B11 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x30, // 1FQCB000 + 0x36, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 63...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10801[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x26, 0x75, 0x2f, 0x13, // ./..&u/. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xa2, // .....BZ. + 0x6b, 0xc8, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x36, // k...2616 + 0x31, 0x46, 0x44, 0x48, 0x32, 0x30, 0x30, 0x31, // 1FDH2001 + 0x35, 0x59, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 5Y...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10804[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x0b, 0x06, 0x7b, 0x43, // ./....{C + 0x37, 0xac, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xb9, // 7.....Z. + 0x22, 0xcb, 0x0d, 0x09, 0x48, 0x54, 0x36, 0x41, // "...HT6A + 0x36, 0x30, 0x32, 0x30, 0x33, 0x31, 0x33, 0x36, // 60203136 + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 2....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10806[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6f, 0x07, 0xa5, 0x46, // ./..o..F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xa2, // tt...BZ. + 0x12, 0xc9, 0x0f, 0x09, 0x32, 0x37, 0x32, 0x39, // ....2729 + 0x31, 0x46, 0x51, 0x48, 0x4e, 0x30, 0x30, 0x31, // 1FQHN001 + 0x31, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 13...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10807[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xe0, 0xd5, 0x3d, 0x1f, // ./....=. + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x9d, // T.....Z. + 0x6e, 0xe5, 0x0f, 0x09, 0x30, 0x34, 0x33, 0x30, // n...0430 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x32, // 1FQCB002 + 0x36, 0x34, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 64...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10808[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xa2, 0x70, 0x36, 0x08, // ./...p6. + 0x9e, 0x08, 0x01, 0x00, 0x18, 0x04, 0x34, 0x25, // ......4% + 0x6d, 0xc5, 0x05, 0x09, 0x5a, 0x32, 0x45, 0x77, // m...Z2Ew + 0x11, 0x03, 0x05, 0x11, 0x0b, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x1e, 0x11, 0x2e, 0x11, 0x00, 0x12, // ........ + 0x33, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 3....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10809[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xe4, 0xa5, 0xd5, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x49, // tt...BZI + 0x2c, 0xe1, 0x0f, 0x09, 0x33, 0x33, 0x30, 0x37, // ,...3307 + 0x31, 0x46, 0x44, 0x48, 0x53, 0x30, 0x30, 0x30, // 1FDHS000 + 0x36, 0x48, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 6H...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10816[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x86, 0x4b, 0x99, 0x3b, // ./...K.; + 0x22, 0x14, 0x01, 0x00, 0x04, 0x07, 0x2a, 0x3c, // ".....*< + 0x2f, 0xbc, 0x13, 0x09, 0x47, 0x6f, 0x6f, 0x67, // /...Goog + 0x6c, 0x65, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, // le Pixel + 0x20, 0x57, 0x61, 0x74, 0x63, 0x68, 0x0d, 0x03, // Watch.. + 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x1e, 0x11, // ........ + 0x1f, 0x11, 0x00, 0x12, 0x01, 0x05, 0x81, 0x07, // ........ + 0x66, 0x9a, 0x0c, 0x20, 0x00, 0x08, 0xe2, 0xa5, // f.. .... + 0xe3, 0x11, 0x25, 0x95, 0xb0, 0x45, 0x89, 0x5e, // ..%..E.^ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10818[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x03, 0xf1, 0xdc, 0x20, // ./..... + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x53, // .<....ZS + 0x16, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10821[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x70, 0x30, 0xf4, 0x2b, // ./..p0.+ + 0x1a, 0xf8, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x86, // ......Z. + 0x78, 0xcc, 0x0f, 0x09, 0x32, 0x31, 0x30, 0x36, // x...2106 + 0x31, 0x46, 0x51, 0x47, 0x52, 0x30, 0x30, 0x31, // 1FQGR001 + 0x30, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 03...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10823[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x70, 0x31, 0xf4, 0x2b, // ./..p1.+ + 0x1a, 0xf8, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1c, // ......Z. + 0x61, 0xcd, 0x0f, 0x09, 0x32, 0x31, 0x30, 0x36, // a...2106 + 0x31, 0x46, 0x51, 0x47, 0x52, 0x30, 0x30, 0x31, // 1FQGR001 + 0x30, 0x32, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 02...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10826[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x0d, 0xa2, 0xd5, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x9a, // tt...BZ. + 0x14, 0xd8, 0x0f, 0x09, 0x33, 0x33, 0x30, 0x36, // ....3306 + 0x31, 0x46, 0x44, 0x48, 0x53, 0x30, 0x30, 0x30, // 1FDHS000 + 0x37, 0x42, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 7B...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10838[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x61, 0x4a, 0xdd, 0x20, // ./..aJ. + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x03, // .<....Z. + 0x01, 0xbb, 0x0b, 0x09, 0x38, 0x42, 0x4c, 0x41, // ....8BLA + 0x59, 0x30, 0x30, 0x44, 0x55, 0x43, 0x19, 0x03, // Y00DUC.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10839[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x98, 0xc3, 0xf3, 0x2b, // ./.....+ + 0x1a, 0xf8, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x8e, // ......Z. + 0x71, 0xcd, 0x0f, 0x09, 0x32, 0x31, 0x30, 0x36, // q...2106 + 0x31, 0x46, 0x51, 0x47, 0x52, 0x30, 0x30, 0x31, // 1FQGR001 + 0x36, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 63...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10840[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xda, 0xb2, 0x0a, 0x1f, // ./...... + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x60, // T.....Z` + 0x34, 0xd2, 0x0f, 0x09, 0x30, 0x34, 0x31, 0x36, // 4...0416 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x30, // 1FQCB000 + 0x31, 0x32, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 12...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10841[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xaa, 0xb2, 0x0a, 0x1f, // ./...... + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x96, // T.....Z. + 0x00, 0xd2, 0x0f, 0x09, 0x30, 0x34, 0x31, 0x33, // ....0413 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x34, // 1FQCB004 + 0x36, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 66...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10842[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6c, 0x9c, 0xdc, 0x5b, // ./..l..[ + 0xe5, 0xdc, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xfc, // ......Z. + 0x2b, 0xc1, 0x0f, 0x09, 0x31, 0x39, 0x32, 0x30, // +...1920 + 0x31, 0x46, 0x44, 0x45, 0x45, 0x30, 0x30, 0x38, // 1FDEE008 + 0x33, 0x44, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 3D...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10843[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x9b, 0xee, 0x36, 0x08, // ./....6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xea, // ......Z. + 0x55, 0xd2, 0x0f, 0x09, 0x30, 0x37, 0x32, 0x38, // U...0728 + 0x31, 0x4a, 0x45, 0x43, 0x42, 0x30, 0x30, 0x33, // 1JECB003 + 0x35, 0x37, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 57...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10845[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x10, 0xbe, 0xf3, 0x2b, // ./.....+ + 0x1a, 0xf8, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x53, // ......ZS + 0x51, 0xd0, 0x0f, 0x09, 0x32, 0x31, 0x30, 0x36, // Q...2106 + 0x31, 0x46, 0x51, 0x47, 0x52, 0x30, 0x30, 0x31, // 1FQGR001 + 0x36, 0x34, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 64...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10857[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xaf, 0x05, 0x7b, 0x43, // ./....{C + 0x37, 0xac, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x6b, // 7.....Zk + 0x5f, 0xcc, 0x0d, 0x09, 0x48, 0x54, 0x36, 0x41, // _...HT6A + 0x36, 0x30, 0x32, 0x30, 0x33, 0x31, 0x32, 0x37, // 60203127 + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 2....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10858[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x24, 0x4c, 0xd4, 0x29, // ./..$L.) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x47, // $X....ZG + 0x41, 0xc0, 0x0f, 0x09, 0x31, 0x37, 0x30, 0x37, // A...1707 + 0x31, 0x46, 0x44, 0x45, 0x45, 0x30, 0x30, 0x32, // 1FDEE002 + 0x33, 0x47, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 3G...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10859[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x81, 0x6a, 0x2f, 0x13, // ./...j/. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xdc, // .....BZ. + 0x1b, 0xca, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x35, // ....2615 + 0x31, 0x46, 0x44, 0x48, 0x32, 0x30, 0x30, 0x30, // 1FDH2000 + 0x5a, 0x4d, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // ZM...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10860[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xe1, 0xd1, 0x3e, 0x13, // ./....>. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x40, // .....BZ@ + 0x1a, 0xcc, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x31, // ....2611 + 0x31, 0x46, 0x44, 0x48, 0x33, 0x30, 0x30, 0x30, // 1FDH3000 + 0x34, 0x41, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 4A...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10871[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xac, 0xb8, 0xd5, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x44, // tt...BZD + 0x65, 0xe4, 0x0f, 0x09, 0x33, 0x33, 0x30, 0x36, // e...3306 + 0x31, 0x46, 0x44, 0x48, 0x53, 0x30, 0x30, 0x30, // 1FDHS000 + 0x34, 0x45, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 4E...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10872[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xe7, 0x2e, 0xf4, 0x2b, // ./.....+ + 0x1a, 0xf8, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xf2, // ......Z. + 0x5b, 0xd4, 0x0f, 0x09, 0x32, 0x31, 0x30, 0x36, // [...2106 + 0x31, 0x46, 0x51, 0x47, 0x52, 0x30, 0x30, 0x31, // 1FQGR001 + 0x32, 0x30, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 20...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10874[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x69, 0x98, 0x38, 0x6e, // ./..i.8n + 0xb7, 0x60, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xe6, // .`....Z. + 0x0a, 0xcc, 0x0f, 0x09, 0x30, 0x42, 0x31, 0x31, // ....0B11 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x31, // 1FQCB001 + 0x30, 0x38, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 08...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10876[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x98, 0x6b, 0x36, 0x08, // ./...... + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x65, // ......Ze + 0x27, 0xc9, 0x0f, 0x09, 0x39, 0x42, 0x32, 0x37, // '...9B27 + 0x31, 0x46, 0x51, 0x43, 0x32, 0x30, 0x30, 0x32, // 1FQC2002 + 0x34, 0x37, 0x17, 0x03, 0x05, 0x11, 0x0a, 0x11, // 47...... + 0x0c, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 2....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10877[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x73, 0x94, 0xf3, 0x2b, // ./..s..+ + 0x1a, 0xf8, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xab, // ......Z. + 0x12, 0xd6, 0x0f, 0x09, 0x31, 0x39, 0x32, 0x37, // ....1927 + 0x31, 0x46, 0x51, 0x47, 0x52, 0x30, 0x30, 0x30, // 1FQGR000 + 0x32, 0x38, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 28...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10887[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xe9, 0x6e, 0x36, 0x08, // ./...n6. + 0x9e, 0x08, 0x01, 0x00, 0x18, 0x04, 0x34, 0x62, // ......4b + 0x35, 0xc6, 0x05, 0x09, 0x4b, 0x6c, 0x54, 0x76, // 5...KlTv + 0x11, 0x03, 0x05, 0x11, 0x0b, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x1e, 0x11, 0x2e, 0x11, 0x00, 0x12, // ........ + 0x33, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 3....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10888[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x72, 0x70, 0x36, 0x08, // ./..rp6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x7b, // ......Z{ + 0x39, 0xcd, 0x0f, 0x09, 0x39, 0x43, 0x30, 0x34, // 9...9C04 + 0x31, 0x46, 0x51, 0x43, 0x32, 0x30, 0x30, 0x33, // 1FQC2003 + 0x30, 0x38, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 08...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10890[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x5a, 0x6d, 0x36, 0x08, // ./..Zm6. + 0x9e, 0x08, 0x01, 0x00, 0x18, 0x04, 0x34, 0xc4, // ......4. + 0x5c, 0xc8, 0x05, 0x09, 0x50, 0x4e, 0x54, 0x39, // \...PNT9 + 0x11, 0x03, 0x05, 0x11, 0x0b, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x1e, 0x11, 0x2e, 0x11, 0x00, 0x12, // ........ + 0x33, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 3....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10891[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd8, 0x8b, 0x3e, 0x13, // ./....>. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x26, // .....BZ& + 0x3c, 0xc5, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x31, // <...2611 + 0x31, 0x46, 0x44, 0x48, 0x33, 0x30, 0x30, 0x30, // 1FDH3000 + 0x31, 0x38, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 18...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10893[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x36, 0xcc, 0xa4, 0x46, // ./..6..F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xe3, // tt...BZ. + 0x38, 0xcd, 0x0f, 0x09, 0x32, 0x39, 0x30, 0x38, // 8...2908 + 0x31, 0x46, 0x51, 0x48, 0x4e, 0x30, 0x30, 0x31, // 1FQHN001 + 0x35, 0x34, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 54...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10895[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x59, 0x80, 0x36, 0x08, // ./..Y.6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x47, // ......ZG + 0x17, 0xcd, 0x0f, 0x09, 0x39, 0x43, 0x31, 0x32, // ....9C12 + 0x31, 0x46, 0x51, 0x43, 0x32, 0x30, 0x30, 0x32, // 1FQC2002 + 0x33, 0x32, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 32...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10904[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x5f, 0xc8, 0xdc, 0x20, // ./.._.. + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x8f, // .<....Z. + 0x1c, 0xc3, 0x0b, 0x09, 0x38, 0x39, 0x4e, 0x41, // ....89NA + 0x58, 0x30, 0x30, 0x36, 0x45, 0x4a, 0x19, 0x03, // X006EJ.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10906[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xad, 0xad, 0x36, 0x08, // ./....6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x73, // ......Zs + 0x44, 0xdf, 0x0f, 0x09, 0x30, 0x31, 0x30, 0x38, // D...0108 + 0x31, 0x46, 0x51, 0x43, 0x32, 0x30, 0x30, 0x37, // 1FQC2007 + 0x34, 0x37, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 47...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10910[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x5d, 0x39, 0x57, 0x2c, // ./..]9W, + 0x3a, 0xd4, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x5b, // :....BZ[ + 0x71, 0xc7, 0x0f, 0x09, 0x33, 0x33, 0x31, 0x34, // q...3314 + 0x31, 0x46, 0x44, 0x4a, 0x47, 0x30, 0x30, 0x30, // 1FDJG000 + 0x50, 0x41, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // PA...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10911[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf8, 0x4a, 0xd4, 0x29, // ./...J.) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x0d, // $X....Z. + 0x1a, 0xd1, 0x0f, 0x09, 0x31, 0x37, 0x30, 0x37, // ....1707 + 0x31, 0x46, 0x44, 0x45, 0x45, 0x30, 0x30, 0x32, // 1FDEE002 + 0x34, 0x47, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 4G...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10915[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x93, 0x02, 0xd4, 0x29, // ./.....) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x24, // $X....Z$ + 0x77, 0xd2, 0x0f, 0x09, 0x31, 0x34, 0x32, 0x38, // w...1428 + 0x31, 0x46, 0x44, 0x45, 0x45, 0x30, 0x30, 0x30, // 1FDEE000 + 0x44, 0x47, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // DG...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10916[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x5a, 0x75, 0x39, 0x6e, // ./..Zu9n + 0xb7, 0x60, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x45, // .`....ZE + 0x3a, 0xdb, 0x0f, 0x09, 0x31, 0x34, 0x32, 0x30, // :...1420 + 0x31, 0x4a, 0x45, 0x43, 0x42, 0x30, 0x30, 0x32, // 1JECB002 + 0x34, 0x32, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 42...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10922[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x31, 0x5b, 0x7f, 0x2f, // ./..1[./ + 0x95, 0x24, 0x01, 0x00, 0x10, 0x41, 0x5a, 0xf1, // .$...AZ. + 0x19, 0xd4, 0x0f, 0x09, 0x33, 0x32, 0x30, 0x32, // ....3202 + 0x31, 0x30, 0x35, 0x48, 0x38, 0x30, 0x33, 0x43, // 105H803C + 0x4e, 0x57, 0x13, 0x03, 0x05, 0x11, 0x0a, 0x11, // NW...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x00, 0x12, 0x01, 0x05, // ........ + 0x81, 0x07, 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, // ..Zl..m. + 0xbc, 0x9b, 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, // ...=\.!. + 0x2e, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10927[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x4d, 0x7a, 0x4f, 0x52, // ./..MzOR + 0xcb, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xd9, // .X....Z. + 0x45, 0xcd, 0x0b, 0x09, 0x39, 0x35, 0x39, 0x41, // E...959A + 0x58, 0x30, 0x46, 0x36, 0x4a, 0x5a, 0x19, 0x03, // X0F6JZ.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10928[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x34, 0x64, 0x3e, 0x13, // ./..4d>. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xc4, // .....BZ. + 0x7d, 0xd1, 0x0f, 0x09, 0x32, 0x35, 0x30, 0x35, // }...2505 + 0x31, 0x46, 0x44, 0x48, 0x33, 0x30, 0x30, 0x30, // 1FDH3000 + 0x34, 0x37, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 47...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10930[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x23, 0x47, 0x04, 0x36, // ./..#G.6 + 0x4e, 0x40, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x8b, // N@....Z. + 0x45, 0xcb, 0x0d, 0x09, 0x48, 0x54, 0x37, 0x33, // E...HT73 + 0x52, 0x31, 0x41, 0x30, 0x30, 0x30, 0x30, 0x35, // R1A00005 + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 2....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10931[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xb2, 0x65, 0xdd, 0x20, // ./...e. + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xe8, // .<....Z. + 0x45, 0xc7, 0x0b, 0x09, 0x38, 0x39, 0x4e, 0x41, // E...89NA + 0x59, 0x30, 0x30, 0x38, 0x32, 0x44, 0x19, 0x03, // Y0082D.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10932[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x62, 0x38, 0xd5, 0x46, // ./..b8.F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xc7, // tt...BZ. + 0x2e, 0xca, 0x0f, 0x09, 0x33, 0x32, 0x30, 0x34, // ....3204 + 0x31, 0x46, 0x44, 0x48, 0x53, 0x30, 0x30, 0x30, // 1FDHS000 + 0x36, 0x59, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 6Y...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10934[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x06, 0x82, 0x52, 0x52, // ./....RR + 0xcb, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x44, // .X....ZD + 0x28, 0xca, 0x0b, 0x09, 0x39, 0x36, 0x4b, 0x41, // (...96KA + 0x58, 0x30, 0x48, 0x32, 0x5a, 0x32, 0x19, 0x03, // X0H2Z2.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10940[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x30, 0xcb, 0xd5, 0x46, // ./..0..F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x8d, // tt...BZ. + 0x7c, 0xe3, 0x0f, 0x09, 0x33, 0x33, 0x31, 0x33, // |...3313 + 0x31, 0x46, 0x44, 0x48, 0x53, 0x30, 0x30, 0x30, // 1FDHS000 + 0x34, 0x35, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 45...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10952[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xae, 0xee, 0x55, 0x52, // ./....UR + 0xcb, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xbb, // .X....Z. + 0x1d, 0xc2, 0x0b, 0x09, 0x39, 0x39, 0x47, 0x41, // ....99GA + 0x58, 0x30, 0x4b, 0x42, 0x44, 0x31, 0x19, 0x03, // X0KBD1.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10953[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xec, 0xd5, 0x3d, 0x1f, // ./....=. + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xe7, // T.....Z. + 0x57, 0xd8, 0x0f, 0x09, 0x30, 0x34, 0x33, 0x30, // W...0430 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x32, // 1FQCB002 + 0x36, 0x30, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 60...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10959[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xa7, 0x67, 0xdd, 0x20, // ./...g. + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xe6, // .<....Z. + 0x0e, 0xc3, 0x0b, 0x09, 0x38, 0x39, 0x37, 0x41, // ....897A + 0x59, 0x30, 0x30, 0x31, 0x5a, 0x58, 0x17, 0x03, // Y001ZX.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x12, 0x11, // ........ + 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, // ......-. + 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, // /...2... + 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10962[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x18, 0xae, 0xdd, 0x29, // ./.....) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xbe, // $X....Z. + 0x50, 0xcc, 0x0f, 0x09, 0x31, 0x37, 0x31, 0x33, // P...1713 + 0x31, 0x46, 0x44, 0x46, 0x36, 0x30, 0x30, 0x30, // 1FDF6000 + 0x43, 0x4a, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // CJ...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10965[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x2a, 0x4e, 0xd4, 0x29, // ./..*N.) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xa1, // $X....Z. + 0x38, 0xcb, 0x0f, 0x09, 0x31, 0x37, 0x30, 0x37, // 8...1707 + 0x31, 0x46, 0x44, 0x45, 0x45, 0x30, 0x30, 0x32, // 1FDEE002 + 0x39, 0x32, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 92...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10967[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xa8, 0x4f, 0xd4, 0x29, // ./...O.) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x23, // $X....Z# + 0x47, 0xc4, 0x0f, 0x09, 0x31, 0x37, 0x30, 0x37, // G...1707 + 0x31, 0x46, 0x44, 0x45, 0x45, 0x30, 0x30, 0x32, // 1FDEE002 + 0x36, 0x42, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 6B...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10973[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x9f, 0x98, 0x38, 0x6e, // ./....8n + 0xb7, 0x60, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xf4, // .`....Z. + 0x2c, 0xcf, 0x0f, 0x09, 0x30, 0x42, 0x31, 0x31, // ,...0B11 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x30, // 1FQCB000 + 0x38, 0x39, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 89...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10976[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x85, 0x6f, 0x36, 0x08, // ./...o6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x32, // ......Z2 + 0x0c, 0xc8, 0x0f, 0x09, 0x39, 0x42, 0x32, 0x37, // ....9B27 + 0x31, 0x46, 0x51, 0x43, 0x32, 0x30, 0x30, 0x31, // 1FQC2001 + 0x39, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 93...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10982[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x79, 0xb0, 0x7e, 0x2f, // ./..y.~/ + 0x95, 0x24, 0x01, 0x00, 0x10, 0x41, 0x5a, 0x66, // .$...AZf + 0x05, 0xca, 0x0f, 0x09, 0x33, 0x32, 0x30, 0x32, // ....3202 + 0x31, 0x30, 0x35, 0x48, 0x38, 0x30, 0x31, 0x31, // 105H8011 + 0x4e, 0x31, 0x13, 0x03, 0x05, 0x11, 0x0a, 0x11, // N1...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x00, 0x12, 0x01, 0x05, // ........ + 0x81, 0x07, 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, // ..Zl..m. + 0xbc, 0x9b, 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, // ...=\.!. + 0x2e, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10984[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x82, 0xba, 0xdc, 0x20, // ./..... + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x93, // .<....Z. + 0x47, 0xc8, 0x0b, 0x09, 0x38, 0x39, 0x4d, 0x41, // G...89MA + 0x58, 0x30, 0x30, 0x36, 0x34, 0x34, 0x19, 0x03, // X00644.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10986[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xa9, 0x51, 0x2f, 0x13, // ./...Q/. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xba, // .....BZ. + 0x30, 0xc3, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x36, // 0...2616 + 0x31, 0x46, 0x44, 0x48, 0x32, 0x30, 0x30, 0x31, // 1FDH2001 + 0x36, 0x31, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 61...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10987[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf5, 0xd5, 0x3d, 0x1f, // ./....=. + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x20, // T.....Z + 0x17, 0xd9, 0x0f, 0x09, 0x30, 0x34, 0x33, 0x30, // ....0430 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x31, // 1FQCB001 + 0x35, 0x35, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 55...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10997[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd7, 0xb2, 0x0a, 0x1f, // ./...... + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xb9, // T.....Z. + 0x08, 0xd4, 0x0f, 0x09, 0x30, 0x34, 0x31, 0x36, // ....0416 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x31, // 1FQCB001 + 0x30, 0x32, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 02...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt10999[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc6, 0xcf, 0x0a, 0x1f, // ./...... + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x7f, // T.....Z. + 0x26, 0xd7, 0x0f, 0x09, 0x30, 0x36, 0x31, 0x30, // &...0610 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x33, // 1FQCB003 + 0x34, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 43...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11008[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd6, 0xb0, 0x2e, 0x13, // ./...... + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x58, // .....BZX + 0x73, 0xd3, 0x0f, 0x09, 0x32, 0x31, 0x30, 0x35, // s...2105 + 0x31, 0x46, 0x44, 0x48, 0x32, 0x30, 0x30, 0x30, // 1FDH2000 + 0x33, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 36...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11009[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd9, 0x91, 0x57, 0x2c, // ./....W, + 0x3a, 0xd4, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xa9, // :....BZ. + 0x06, 0xc1, 0x0f, 0x09, 0x33, 0x33, 0x31, 0x36, // ....3316 + 0x31, 0x46, 0x44, 0x4a, 0x47, 0x30, 0x30, 0x30, // 1FDJG000 + 0x38, 0x31, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 81...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11020[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xbc, 0x67, 0xdd, 0x20, // ./...g. + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x0e, // .<....Z. + 0x06, 0xc8, 0x0b, 0x09, 0x38, 0x39, 0x37, 0x41, // ....897A + 0x59, 0x30, 0x30, 0x32, 0x30, 0x34, 0x19, 0x03, // Y00204.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11021[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x88, 0x8f, 0x1d, 0x52, // ./.....R + 0xcb, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x2a, // .X....Z* + 0x75, 0xb9, 0x0b, 0x09, 0x39, 0x33, 0x36, 0x41, // u...936A + 0x58, 0x30, 0x34, 0x55, 0x4b, 0x33, 0x19, 0x03, // X04UK3.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11023[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xe3, 0xd5, 0x3d, 0x1f, // ./....=. + 0x54, 0x88, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x8b, // T.....Z. + 0x5f, 0xd3, 0x0f, 0x09, 0x30, 0x34, 0x33, 0x30, // _...0430 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x31, // 1FQCB001 + 0x33, 0x39, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 39...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11025[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf5, 0xdf, 0x3e, 0x13, // ./....>. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xee, // .....BZ. + 0x37, 0xc8, 0x0f, 0x09, 0x32, 0x36, 0x31, 0x31, // 7...2611 + 0x31, 0x46, 0x44, 0x48, 0x33, 0x30, 0x30, 0x30, // 1FDH3000 + 0x33, 0x46, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 3F...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11039[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xeb, 0xd2, 0xa4, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x5b, // tt...BZ[ + 0x6f, 0xcc, 0x0f, 0x09, 0x32, 0x39, 0x30, 0x38, // o...2908 + 0x31, 0x46, 0x51, 0x48, 0x4e, 0x30, 0x30, 0x31, // 1FQHN001 + 0x32, 0x34, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 24...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11047[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x85, 0xb3, 0x7e, 0x2f, // ./....~/ + 0x95, 0x24, 0x01, 0x00, 0x10, 0x41, 0x5a, 0x3e, // .$...AZ> + 0x38, 0xce, 0x0f, 0x09, 0x33, 0x32, 0x30, 0x32, // 8...3202 + 0x31, 0x30, 0x35, 0x48, 0x38, 0x30, 0x31, 0x4c, // 105H801L + 0x47, 0x4d, 0x13, 0x03, 0x05, 0x11, 0x0a, 0x11, // GM...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x00, 0x12, 0x01, 0x05, // ........ + 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11048[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x03, 0xf1, 0xdc, 0x20, // ./..... + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x53, // .<....ZS + 0x16, 0xb2, 0x0b, 0x09, 0x38, 0x39, 0x4d, 0x41, // ....89MA + 0x58, 0x30, 0x30, 0x35, 0x5a, 0x42, 0x19, 0x03, // X005ZB.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11049[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xdb, 0x04, 0x7b, 0x43, // ./....{C + 0x37, 0xac, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xff, // 7.....Z. + 0x56, 0xce, 0x0d, 0x09, 0x48, 0x54, 0x36, 0x41, // V...HT6A + 0x36, 0x30, 0x32, 0x30, 0x33, 0x30, 0x39, 0x34, // 60203094 + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 2....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11067[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x90, 0x60, 0xdd, 0x20, // ./...`. + 0x8d, 0x3c, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x94, // .<....Z. + 0x2f, 0xbb, 0x0b, 0x09, 0x38, 0x39, 0x4c, 0x41, // /...89LA + 0x59, 0x30, 0x30, 0x37, 0x35, 0x33, 0x19, 0x03, // Y00753.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11080[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xdf, 0x8c, 0x1d, 0x52, // ./.....R + 0xcb, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xcd, // .X....Z. + 0x39, 0xbb, 0x0b, 0x09, 0x39, 0x33, 0x36, 0x41, // 9...936A + 0x58, 0x30, 0x34, 0x56, 0x31, 0x4e, 0x19, 0x03, // X04V1N.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11081[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x8a, 0xcf, 0x2e, 0x13, // ./...... + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xd6, // .....BZ. + 0x1b, 0xbe, 0x0f, 0x09, 0x32, 0x34, 0x32, 0x35, // ....2425 + 0x31, 0x46, 0x44, 0x48, 0x32, 0x30, 0x30, 0x31, // 1FDH2001 + 0x32, 0x58, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 2X...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11083[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x74, 0x4b, 0x7f, 0x2f, // ./..tK./ + 0x95, 0x24, 0x01, 0x00, 0x10, 0x41, 0x5a, 0xb0, // .$...AZ. + 0x0b, 0xc4, 0x0f, 0x09, 0x33, 0x32, 0x30, 0x32, // ....3202 + 0x31, 0x30, 0x35, 0x48, 0x38, 0x30, 0x32, 0x30, // 105H8020 + 0x51, 0x4c, 0x13, 0x03, 0x05, 0x11, 0x0a, 0x11, // QL...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x00, 0x12, 0x01, 0x05, // ........ + 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11092[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x18, 0x6d, 0x36, 0x08, // ./...m6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x57, // ......ZW + 0x28, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11093[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x5a, 0x7c, 0x36, 0x08, // ./..Z|6. + 0x9e, 0x08, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xaa, // ......Z. + 0x4c, 0xc1, 0x0f, 0x09, 0x39, 0x43, 0x31, 0x37, // L...9C17 + 0x31, 0x46, 0x51, 0x43, 0x32, 0x30, 0x30, 0x34, // 1FQC2004 + 0x33, 0x34, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 34...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11108[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x9c, 0x98, 0x38, 0x6e, // ./....8n + 0xb7, 0x60, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xf3, // .`....Z. + 0x26, 0xc8, 0x0f, 0x09, 0x30, 0x42, 0x31, 0x31, // &...0B11 + 0x31, 0x46, 0x51, 0x43, 0x42, 0x30, 0x30, 0x31, // 1FQCB001 + 0x30, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 06...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11141[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x55, 0x11, 0x3e, 0x13, // ./..U.>. + 0xc4, 0x0c, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xfc, // .....BZ. + 0x0b, 0xc6, 0x0f, 0x09, 0x32, 0x32, 0x32, 0x34, // ....2224 + 0x31, 0x46, 0x44, 0x48, 0x33, 0x30, 0x30, 0x30, // 1FDH3000 + 0x30, 0x4b, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 0K...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11152[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x30, 0xdc, 0xa4, 0x46, // ./..0..F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0xbd, // tt...BZ. + 0x79, 0xcb, 0x05, 0x09, 0x4a, 0x5a, 0x6f, 0x46, // y...JZoF + 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, // ........ + 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, // ..-./... + 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 2....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11154[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x14, 0x90, 0x2a, 0x52, // ./....*R + 0xcb, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xdd, // .X....Z. + 0x66, 0xc9, 0x0b, 0x09, 0x39, 0x33, 0x58, 0x41, // f...93XA + 0x58, 0x30, 0x42, 0x52, 0x57, 0x4c, 0x19, 0x03, // X0BRWL.. + 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, // ........ + 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, 0x11, // ........ + 0x2d, 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, // -./...2. + 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11155[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x80, 0x6b, 0x36, 0x08, // ./...... + 0x9e, 0x08, 0x01, 0x00, 0x18, 0x04, 0x34, 0xa0, // ......4. + 0x13, 0xbf, 0x05, 0x09, 0x4c, 0x34, 0x50, 0x6d, // ....L4Pm + 0x11, 0x03, 0x05, 0x11, 0x0b, 0x11, 0x0c, 0x11, // ........ + 0x0e, 0x11, 0x1e, 0x11, 0x2e, 0x11, 0x00, 0x12, // ........ + 0x33, 0x11, 0x01, 0x05, 0x81, 0x07, 0x00, 0x00, // 3....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11156[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xb5, 0x4b, 0x99, 0x3b, // ./...K.; + 0x22, 0x14, 0x01, 0x00, 0x04, 0x07, 0x2a, 0x10, // ".....*. + 0x77, 0xc2, 0x13, 0x09, 0x47, 0x6f, 0x6f, 0x67, // w...Goog + 0x6c, 0x65, 0x20, 0x50, 0x69, 0x78, 0x65, 0x6c, // le Pixel + 0x20, 0x57, 0x61, 0x74, 0x63, 0x68, 0x0d, 0x03, // Watch.. + 0x0a, 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x1e, 0x11, // ........ + 0x1f, 0x11, 0x00, 0x12, 0x01, 0x05, 0x81, 0x07, // ........ + 0x66, 0x9a, 0x0c, 0x20, 0x00, 0x08, 0xe2, 0xa5, // f.. .... + 0xe3, 0x11, 0x25, 0x95, 0xb0, 0x45, 0x89, 0x5e, // ..%..E.^ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11158[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x89, 0x0c, 0xa6, 0x46, // ./.....F + 0x74, 0x74, 0x01, 0x00, 0x0c, 0x42, 0x5a, 0x0d, // tt...BZ. + 0x4c, 0xd1, 0x0f, 0x09, 0x32, 0x42, 0x32, 0x31, // L...2B21 + 0x31, 0x4a, 0x45, 0x48, 0x4e, 0x30, 0x38, 0x35, // 1JEHN085 + 0x38, 0x39, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 89...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt11159[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc2, 0x09, 0x87, 0x2c, // ./....., + 0x3a, 0xd4, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xba, // :.....Z. + 0x28, 0xc4, 0x0f, 0x09, 0x32, 0x39, 0x31, 0x39, // (...2919 + 0x31, 0x4a, 0x45, 0x47, 0x52, 0x31, 0x30, 0x34, // 1JEGR104 + 0x31, 0x34, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 14...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt473[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf8, 0xdf, 0x28, 0xf4, // ./....(. + 0x81, 0x34, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x59, // .4.....Y + 0x20, 0xb8, 0x10, 0x09, 0x45, 0x54, 0x2d, 0x42, // ...ET-B + 0x54, 0x47, 0x50, 0x53, 0x2d, 0x37, 0x30, 0x39, // TGPS-709 + 0x31, 0x33, 0x38, 0x05, 0xff, 0x42, 0x4d, 0x37, // 138..BM7 + 0x38, 0x02, 0x0a, 0x02, 0x03, 0x02, 0x01, 0x11, // 8....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt474[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf1, 0xd6, 0x28, 0xf4, // ./....(. + 0x81, 0x34, 0x01, 0x00, 0x00, 0x1f, 0x00, 0xa6, // .4...... + 0x7b, 0xb1, 0x10, 0x09, 0x45, 0x54, 0x2d, 0x42, // {...ET-B + 0x54, 0x47, 0x50, 0x53, 0x2d, 0x37, 0x30, 0x39, // TGPS-709 + 0x31, 0x33, 0x34, 0x05, 0xff, 0x42, 0x4d, 0x37, // 134..BM7 + 0x38, 0x02, 0x0a, 0x02, 0x03, 0x02, 0x01, 0x11, // 8....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt488[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x0e, 0x8b, 0x20, 0xa5, // ./.... . + 0x92, 0x00, 0x01, 0x00, 0x20, 0x04, 0x36, 0x9a, // .... .6. + 0x09, 0xc0, 0x0a, 0x09, 0x4d, 0x6f, 0x74, 0x72, // ....Motr + 0x65, 0x78, 0x20, 0x48, 0x55, 0x0b, 0x03, 0x0b, // ex HU... + 0x11, 0x1e, 0x11, 0x2e, 0x11, 0x00, 0x12, 0x33, // .......3 + 0x11, 0x41, 0x07, 0xd3, 0x1f, 0xbf, 0x50, 0x5d, // .A....P] + 0x57, 0x27, 0x97, 0xa2, 0x40, 0x41, 0xcd, 0x48, // W'..@A.H + 0x43, 0x88, 0xec, 0xff, 0xca, 0xca, 0xde, 0xaf, // C....... + 0xde, 0xca, 0xde, 0xde, 0xfa, 0xca, 0xde, 0x00, // ........ + 0x00, 0x00, 0x00, 0x66, 0x9a, 0x0c, 0x20, 0x00, // ...f.. . + 0x08, 0xf4, 0xbd, 0xe6, 0x11, 0xcb, 0x52, 0x00, // ......R. + 0x7a, 0xe1, 0x4d, 0x7c, 0x92, 0x67, 0x4d, 0x2c, // z.M|.gM, + 0xf1, 0x86, 0x88, 0xdb, 0x4f, 0x15, 0x25, 0x2c, // ....O.%, + 0xfe, 0x21, 0xdf, 0x02, 0x0a, 0x04, 0x00, 0x00, // .!...... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt489[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6c, 0x53, 0xdf, 0x05, // ./..lS.. + 0x05, 0x30, 0x01, 0x00, 0x0c, 0x01, 0x08, 0x44, // .0.....D + 0x4d, 0xd5, 0x10, 0x09, 0x4d, 0x47, 0x4b, 0x52, // M...MGKR + 0x44, 0x31, 0x30, 0x2d, 0x4e, 0x41, 0x31, 0x30, // D10-NA10 + 0x4d, 0x49, 0x50, 0x02, 0x0a, 0x0b, 0x09, 0x03, // MIP..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt512[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x74, 0x15, 0x29, 0xf4, // ./..t.). + 0x81, 0x34, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x84, // .4...... + 0x5f, 0xbf, 0x10, 0x09, 0x45, 0x54, 0x2d, 0x42, // _...ET-B + 0x54, 0x41, 0x46, 0x44, 0x2d, 0x37, 0x30, 0x39, // TAFD-709 + 0x30, 0x36, 0x33, 0x05, 0xff, 0x42, 0x4d, 0x37, // 063..BM7 + 0x38, 0x02, 0x0a, 0x02, 0x03, 0x02, 0x01, 0x11, // 8....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt513[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x02, 0xd8, 0x28, 0xf4, // ./....(. + 0x81, 0x34, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x85, // .4...... + 0x5a, 0xbf, 0x10, 0x09, 0x45, 0x54, 0x2d, 0x42, // Z...ET-B + 0x54, 0x47, 0x50, 0x53, 0x2d, 0x37, 0x30, 0x39, // TGPS-709 + 0x31, 0x34, 0x30, 0x05, 0xff, 0x42, 0x4d, 0x37, // 140..BM7 + 0x38, 0x02, 0x0a, 0x02, 0x03, 0x02, 0x01, 0x11, // 8....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt530[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x14, 0xdc, 0x28, 0xf4, // ./....(. + 0x81, 0x34, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x74, // .4.....t + 0x01, 0xb6, 0x10, 0x09, 0x45, 0x54, 0x2d, 0x42, // ....ET-B + 0x54, 0x41, 0x46, 0x44, 0x2d, 0x37, 0x30, 0x39, // TAFD-709 + 0x30, 0x38, 0x35, 0x05, 0xff, 0x42, 0x4d, 0x37, // 085..BM7 + 0x38, 0x02, 0x0a, 0x02, 0x03, 0x02, 0x01, 0x11, // 8....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt545[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xcd, 0x7b, 0xc0, 0x68, // ./...{.h + 0x10, 0xd8, 0x01, 0x00, 0x20, 0x04, 0x74, 0xf0, // .... .t. + 0x23, 0xb5, 0x17, 0x03, 0x3b, 0x11, 0x00, 0x12, // #...;... + 0x1e, 0x11, 0x03, 0x12, 0x2e, 0x11, 0x33, 0x11, // ......3. + 0x01, 0x11, 0x0b, 0x11, 0x0e, 0x11, 0x0f, 0x11, // ........ + 0x0c, 0x11, 0x01, 0x05, 0x41, 0x07, 0x1b, 0xc5, // ....A... + 0xd5, 0xa5, 0x02, 0x00, 0xa0, 0x80, 0xe4, 0x11, // ........ + 0x16, 0xe4, 0x40, 0xed, 0x28, 0x37, 0xff, 0xca, // ..@.(7.. + 0xca, 0xde, 0xaf, 0xde, 0xca, 0xde, 0xde, 0xfa, // ........ + 0xca, 0xde, 0x00, 0x00, 0x00, 0x00, 0xec, 0x88, // ........ + 0x43, 0x48, 0xcd, 0x41, 0x40, 0xa2, 0x97, 0x27, // CH.A@..' + 0x57, 0x5d, 0x50, 0xbf, 0x1f, 0xd3, 0x66, 0x9a, // W]P...f. + 0x0c, 0x20, 0x00, 0x08, 0xf4, 0xbd, 0xe6, 0x11, // . ...... + 0xcb, 0x52, 0x00, 0x7a, 0xe1, 0x4d, 0x02, 0x0a, // .R.z.M.. + 0x06, 0x0b, 0x09, 0x4d, 0x79, 0x20, 0x56, 0x57, // ...My VW + 0x20, 0x37, 0x42, 0x43, 0x44, 0x00, 0x00, 0x00, // 7BCD... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt871[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6c, 0x53, 0xdf, 0x05, // ./..lS.. + 0x05, 0x30, 0x01, 0x00, 0x0c, 0x01, 0x08, 0x44, // .0.....D + 0x4d, 0xd5, 0x10, 0x09, 0x4d, 0x47, 0x4b, 0x52, // M...MGKR + 0x44, 0x31, 0x30, 0x2d, 0x4e, 0x41, 0x31, 0x30, // D10-NA10 + 0x4d, 0x49, 0x50, 0x02, 0x0a, 0x0b, 0x09, 0x03, // MIP..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt27834[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xb8, 0x20, 0xb8, 0x68, // ./... .h + 0x10, 0xd8, 0x01, 0x00, 0x20, 0x04, 0x74, 0xda, // .... .t. + 0x68, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // h....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt27876[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xb8, 0x20, 0xb8, 0x68, // ./... .h + 0x10, 0xd8, 0x01, 0x00, 0x20, 0x04, 0x74, 0x6a, // .... .tj + 0x6a, 0xc4, 0x19, 0x03, 0x3b, 0x11, 0x00, 0x12, // j...;... + 0x1e, 0x11, 0x03, 0x12, 0x2e, 0x11, 0x33, 0x11, // ......3. + 0x0b, 0x11, 0x0e, 0x11, 0x0f, 0x11, 0xae, 0x7f, // ........ + 0x0c, 0x11, 0xad, 0x7f, 0x01, 0x05, 0x41, 0x07, // ......A. + 0x1b, 0xc5, 0xd5, 0xa5, 0x02, 0x00, 0xa0, 0x80, // ........ + 0xe4, 0x11, 0x16, 0xe4, 0x40, 0xed, 0x28, 0x37, // ....@.(7 + 0xff, 0xca, 0xca, 0xde, 0xaf, 0xde, 0xca, 0xde, // ........ + 0xde, 0xfa, 0xca, 0xde, 0x00, 0x00, 0x00, 0x00, // ........ + 0xec, 0x88, 0x43, 0x48, 0xcd, 0x41, 0x40, 0xa2, // ..CH.A@. + 0x97, 0x27, 0x57, 0x5d, 0x50, 0xbf, 0x1f, 0xd3, // .'W]P... + 0x66, 0x9a, 0x0c, 0x20, 0x00, 0x08, 0xf4, 0xbd, // f.. .... + 0xe6, 0x11, 0xcb, 0x52, 0x00, 0x7a, 0xe1, 0x4d, // ...R.z.M + 0x02, 0x0a, 0x04, 0x0b, 0x09, 0x4d, 0x79, 0x20, // .....My + 0x56, 0x57, 0x20, 0x32, 0x36, 0x36, 0x33, 0x00, // VW 2663. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt649[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf6, 0xc5, 0x54, 0x1a, // ./....T. + 0x94, 0xa0, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xfe, // ......Z. + 0x0a, 0xc5, 0x1c, 0x09, 0xe3, 0x82, 0x81, 0xe3, // ........ + 0x82, 0x81, 0xe3, 0x81, 0xbf, 0xe3, 0x81, 0xa1, // ........ + 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0xe4, 0xb8, // ........ + 0x80, 0xe6, 0x8e, 0xa8, 0xe3, 0x81, 0x97, 0x17, // ........ + 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, // ........ + 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, // ./...2.. + 0x05, 0x81, 0x07, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xaa, 0x9e, 0xa4, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xcc, 0x9e, 0xa4, 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, // ...Zl..m + 0xf1, 0xbc, 0x9b, 0xde, 0x3d, 0x5c, 0xae, 0x21, // ....=\.! + 0xfa, 0x2e, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt677[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc9, 0xfd, 0x14, 0x45, // ./.....E + 0x0a, 0x00, 0x01, 0x00, 0x04, 0x04, 0x24, 0x66, // ......$f + 0x17, 0xb2, 0x0e, 0x09, 0x41, 0x54, 0x48, 0x2d, // ....ATH- + 0x43, 0x4b, 0x53, 0x33, 0x33, 0x30, 0x58, 0x42, // CKS330XB + 0x54, 0x15, 0x03, 0x31, 0x11, 0x08, 0x11, 0x03, // T..1.... + 0x12, 0x1e, 0x11, 0x0c, 0x11, 0x0f, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x00, 0x12, 0x00, 0x10, 0x01, // ........ + 0x05, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt689[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd3, 0x4d, 0x3b, 0xe9, // ./...M;. + 0xbc, 0x4c, 0x01, 0x00, 0x3c, 0x24, 0x0c, 0xe3, // .L..<$.. + 0x49, 0xae, 0x1a, 0x09, 0x5b, 0x4c, 0x47, 0x5d, // I...[LG] + 0x20, 0x77, 0x65, 0x62, 0x4f, 0x53, 0x20, 0x54, // webOS T + 0x56, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x35, 0x35, // V OLED55 + 0x43, 0x31, 0x50, 0x53, 0x42, 0x07, 0x03, 0x0b, // C1PSB... + 0x11, 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, 0x01, // ........ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt709[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6a, 0x78, 0xbf, 0x09, // ./..jx.. + 0x95, 0x3c, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xdf, // .<....*. + 0x15, 0xa6, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // ....DESK + 0x54, 0x4f, 0x50, 0x2d, 0x39, 0x38, 0x41, 0x31, // TOP-98A1 + 0x41, 0x42, 0x53, 0x02, 0x0a, 0x00, 0x0d, 0x03, // ABS..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt763[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x30, 0x25, 0x92, 0xda, // ./..0%.. + 0xb0, 0xcc, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x5c, // ......* + 0x04, 0xb2, 0x0b, 0x09, 0x54, 0x32, 0x32, 0x30, // ....T220 + 0x34, 0x30, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 40-DUT.. + 0x00, 0x0d, 0x03, 0x0c, 0x11, 0x0a, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt771[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x39, 0xf0, 0x33, 0xd3, // ./..9.3. + 0x5f, 0x98, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xb0, // _.....*. + 0x20, 0xcc, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // ...DESK + 0x54, 0x4f, 0x50, 0x2d, 0x56, 0x38, 0x30, 0x41, // TOP-V80A + 0x51, 0x4a, 0x34, 0x02, 0x0a, 0x04, 0x0d, 0x03, // QJ4..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt795[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x44, 0xc6, 0xee, 0x6b, // ./..D..k + 0x21, 0x00, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xe5, // !.....*. + 0x62, 0xa7, 0x0b, 0x09, 0x31, 0x31, 0x30, 0x30, // b...1100 + 0x30, 0x37, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 07-DUT.. + 0x0c, 0x0b, 0x03, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt951[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf6, 0xc5, 0x54, 0x1a, // ./....T. + 0x94, 0xa0, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xff, // ......Z. + 0x0a, 0xc6, 0x1c, 0x09, 0xe3, 0x82, 0x81, 0xe3, // ........ + 0x82, 0x81, 0xe3, 0x81, 0xbf, 0xe3, 0x81, 0xa1, // ........ + 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0xe4, 0xb8, // ........ + 0x80, 0xe6, 0x8e, 0xa8, 0xe3, 0x81, 0x97, 0x17, // ........ + 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, // ........ + 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, // ./...2.. + 0x05, 0x81, 0x07, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xaa, 0x9e, 0xa4, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xcc, 0x9e, 0xa4, 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, // ...Zl..m + 0xf1, 0xbc, 0x9b, 0xde, 0x3d, 0x5c, 0xae, 0x21, // ....=\.! + 0xfa, 0x2e, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt952[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x39, 0xf0, 0x33, 0xd3, // ./..9.3. + 0x5f, 0x98, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xb0, // _.....*. + 0x20, 0xd1, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // ...DESK + 0x54, 0x4f, 0x50, 0x2d, 0x56, 0x38, 0x30, 0x41, // TOP-V80A + 0x51, 0x4a, 0x34, 0x02, 0x0a, 0x04, 0x0d, 0x03, // QJ4..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt953[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd3, 0x4d, 0x3b, 0xe9, // ./...M;. + 0xbc, 0x4c, 0x01, 0x00, 0x3c, 0x24, 0x0c, 0xe3, // .L..<$.. + 0x49, 0xb2, 0x1a, 0x09, 0x5b, 0x4c, 0x47, 0x5d, // I...[LG] + 0x20, 0x77, 0x65, 0x62, 0x4f, 0x53, 0x20, 0x54, // webOS T + 0x56, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x35, 0x35, // V OLED55 + 0x43, 0x31, 0x50, 0x53, 0x42, 0x07, 0x03, 0x0b, // C1PSB... + 0x11, 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, 0x01, // ........ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt954[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6a, 0x78, 0xbf, 0x09, // ./..jx.. + 0x95, 0x3c, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xdf, // .<....*. + 0x15, 0xad, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // ....DESK + 0x54, 0x4f, 0x50, 0x2d, 0x39, 0x38, 0x41, 0x31, // TOP-98A1 + 0x41, 0x42, 0x53, 0x02, 0x0a, 0x00, 0x0d, 0x03, // ABS..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt451[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf6, 0xc5, 0x54, 0x1a, // ./....T. + 0x94, 0xa0, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x98, // ......Z. + 0x44, 0xc5, 0x1c, 0x09, 0xe3, 0x82, 0x81, 0xe3, // D....... + 0x82, 0x81, 0xe3, 0x81, 0xbf, 0xe3, 0x81, 0xa1, // ........ + 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0xe4, 0xb8, // ........ + 0x80, 0xe6, 0x8e, 0xa8, 0xe3, 0x81, 0x97, 0x17, // ........ + 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, // ........ + 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, // ./...2.. + 0x05, 0x81, 0x07, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xaa, 0x9e, 0xa4, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xcc, 0x9e, 0xa4, 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, // ...Zl..m + 0xf1, 0xbc, 0x9b, 0xde, 0x3d, 0x5c, 0xae, 0x21, // ....=\.! + 0xfa, 0x2e, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt482[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x30, 0x25, 0x92, 0xda, // ./..0%.. + 0xb0, 0xcc, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xf9, // ......*. + 0x3d, 0xbe, 0x0b, 0x09, 0x54, 0x32, 0x32, 0x30, // =...T220 + 0x34, 0x30, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 40-DUT.. + 0x00, 0x0d, 0x03, 0x0c, 0x11, 0x0a, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt496[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x44, 0xc6, 0xee, 0x6b, // ./..D..k + 0x21, 0x00, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x7e, // !.....*~ + 0x1c, 0xaf, 0x0b, 0x09, 0x31, 0x31, 0x30, 0x30, // ....1100 + 0x30, 0x37, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 07-DUT.. + 0x0c, 0x0b, 0x03, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt511[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd3, 0x4d, 0x3b, 0xe9, // ./...M;. + 0xbc, 0x4c, 0x01, 0x00, 0x3c, 0x24, 0x0c, 0x8b, // .L..<$.. + 0x03, 0xae, 0x1a, 0x09, 0x5b, 0x4c, 0x47, 0x5d, // ....[LG] + 0x20, 0x77, 0x65, 0x62, 0x4f, 0x53, 0x20, 0x54, // webOS T + 0x56, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x35, 0x35, // V OLED55 + 0x43, 0x31, 0x50, 0x53, 0x42, 0x07, 0x03, 0x0b, // C1PSB... + 0x11, 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, 0x01, // ........ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt523[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc9, 0xfd, 0x14, 0x45, // ./.....E + 0x0a, 0x00, 0x01, 0x00, 0x04, 0x04, 0x24, 0x16, // ......$. + 0x51, 0xbe, 0x0e, 0x09, 0x41, 0x54, 0x48, 0x2d, // Q...ATH- + 0x43, 0x4b, 0x53, 0x33, 0x33, 0x30, 0x58, 0x42, // CKS330XB + 0x54, 0x15, 0x03, 0x31, 0x11, 0x08, 0x11, 0x03, // T..1.... + 0x12, 0x1e, 0x11, 0x0c, 0x11, 0x0f, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x00, 0x12, 0x00, 0x10, 0x01, // ........ + 0x05, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt534[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6a, 0x78, 0xbf, 0x09, // ./..jx.. + 0x95, 0x3c, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x7c, // .<....*| + 0x4f, 0xbb, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // O...DESK + 0x54, 0x4f, 0x50, 0x2d, 0x39, 0x38, 0x41, 0x31, // TOP-98A1 + 0x41, 0x42, 0x53, 0x02, 0x0a, 0x00, 0x0d, 0x03, // ABS..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt706[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x1c, 0xfb, 0xd3, 0x29, // ./.....) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1a, // $X....Z. + 0x0c, 0xbe, 0x0f, 0x09, 0x50, 0x69, 0x78, 0x65, // ....Pixe + 0x6c, 0x20, 0x36, 0x20, 0x50, 0x72, 0x6f, 0x20, // l 6 Pro + 0x30, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 06...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x22, 0x1e, 0x7e, 0xb0, 0x4e, 0x50, 0x5d, 0x8b, // ".~.NP]. + 0x27, 0x47, 0x79, 0x5f, 0x63, 0x0b, 0xe5, 0xce, // 'Gy_c... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt707[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xda, 0xbd, 0x68, 0x72, // ./....hr + 0x6e, 0xb0, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xc7, // n.....Z. + 0x5b, 0xab, 0x10, 0x09, 0x72, 0x65, 0x61, 0x6c, // [...real + 0x6d, 0x65, 0x20, 0x47, 0x54, 0x20, 0x4e, 0x45, // me GT NE + 0x4f, 0x20, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, // O 3..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0xdf, 0x0c, 0xa9, 0x80, 0xbb, 0x4f, // .......O + 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, 0xaa, 0x9e, // .\I..... + 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt786[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x30, 0x25, 0x92, 0xda, // ./..0%.. + 0xb0, 0xcc, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xf8, // ......*. + 0x3d, 0xb5, 0x0b, 0x09, 0x54, 0x32, 0x32, 0x30, // =...T220 + 0x34, 0x30, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 40-DUT.. + 0x00, 0x0d, 0x03, 0x0c, 0x11, 0x0a, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt787[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xf6, 0xc5, 0x54, 0x1a, // ./....T. + 0x94, 0xa0, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x98, // ......Z. + 0x44, 0xc6, 0x1c, 0x09, 0xe3, 0x82, 0x81, 0xe3, // D....... + 0x82, 0x81, 0xe3, 0x81, 0xbf, 0xe3, 0x81, 0xa1, // ........ + 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c, 0xe4, 0xb8, // ........ + 0x80, 0xe6, 0x8e, 0xa8, 0xe3, 0x81, 0x97, 0x17, // ........ + 0x03, 0x05, 0x11, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x12, 0x11, 0x15, 0x11, 0x16, 0x11, 0x1f, // ........ + 0x11, 0x2f, 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, // ./...2.. + 0x05, 0x81, 0x07, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xaa, 0x9e, 0xa4, 0x00, 0xdf, 0x0c, 0xa9, 0x80, // ........ + 0xbb, 0x4f, 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, // .O.\I... + 0xcc, 0x9e, 0xa4, 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, // ...Zl..m + 0xf1, 0xbc, 0x9b, 0xde, 0x3d, 0x5c, 0xae, 0x21, // ....=\.! + 0xfa, 0x2e, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt800[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x44, 0xc6, 0xee, 0x6b, // ./..D..k + 0x21, 0x00, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x7f, // !.....*. + 0x1c, 0xb0, 0x0b, 0x09, 0x31, 0x31, 0x30, 0x30, // ....1100 + 0x30, 0x37, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 07-DUT.. + 0x0c, 0x0b, 0x03, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt821[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6a, 0x78, 0xbf, 0x09, // ./..jx.. + 0x95, 0x3c, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x7c, // .<....*| + 0x4f, 0xb2, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // O...DESK + 0x54, 0x4f, 0x50, 0x2d, 0x39, 0x38, 0x41, 0x31, // TOP-98A1 + 0x41, 0x42, 0x53, 0x02, 0x0a, 0x00, 0x0d, 0x03, // ABS..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt840[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x1c, 0xfb, 0xd3, 0x29, // ./.....) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1a, // $X....Z. + 0x0c, 0xba, 0x0f, 0x09, 0x50, 0x69, 0x78, 0x65, // ....Pixe + 0x6c, 0x20, 0x36, 0x20, 0x50, 0x72, 0x6f, 0x20, // l 6 Pro + 0x30, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 06...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x22, 0x1e, 0x7e, 0xb0, 0x4e, 0x50, 0x5d, 0x8b, // ".~.NP]. + 0x27, 0x47, 0x79, 0x5f, 0x63, 0x0b, 0xe5, 0xce, // 'Gy_c... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt848[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd3, 0x4d, 0x3b, 0xe9, // ./...M;. + 0xbc, 0x4c, 0x01, 0x00, 0x3c, 0x24, 0x0c, 0x8a, // .L..<$.. + 0x03, 0xac, 0x1a, 0x09, 0x5b, 0x4c, 0x47, 0x5d, // ....[LG] + 0x20, 0x77, 0x65, 0x62, 0x4f, 0x53, 0x20, 0x54, // webOS T + 0x56, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x35, 0x35, // V OLED55 + 0x43, 0x31, 0x50, 0x53, 0x42, 0x07, 0x03, 0x0b, // C1PSB... + 0x11, 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, 0x01, // ........ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt865[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc9, 0xfd, 0x14, 0x45, // ./.....E + 0x0a, 0x00, 0x01, 0x00, 0x04, 0x04, 0x24, 0x16, // ......$. + 0x51, 0xb5, 0x0e, 0x09, 0x41, 0x54, 0x48, 0x2d, // Q...ATH- + 0x43, 0x4b, 0x53, 0x33, 0x33, 0x30, 0x58, 0x42, // CKS330XB + 0x54, 0x15, 0x03, 0x31, 0x11, 0x08, 0x11, 0x03, // T..1.... + 0x12, 0x1e, 0x11, 0x0c, 0x11, 0x0f, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x00, 0x12, 0x00, 0x10, 0x01, // ........ + 0x05, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt910[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xb0, 0x27, 0x7f, 0x19, // ./...'.. + 0x28, 0xf8, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xee, // (.....*. + 0x75, 0xae, 0x0b, 0x09, 0x31, 0x30, 0x34, 0x30, // u...1040 + 0x38, 0x39, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 89-DUT.. + 0x00, 0x0b, 0x03, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt911[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xda, 0xbd, 0x68, 0x72, // ./....hr + 0x6e, 0xb0, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xc7, // n.....Z. + 0x5b, 0xac, 0x10, 0x09, 0x72, 0x65, 0x61, 0x6c, // [...real + 0x6d, 0x65, 0x20, 0x47, 0x54, 0x20, 0x4e, 0x45, // me GT NE + 0x4f, 0x20, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, // O 3..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0xdf, 0x0c, 0xa9, 0x80, 0xbb, 0x4f, // .......O + 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, 0xaa, 0x9e, // .\I..... + 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt1093[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc2, 0x3c, 0x42, 0xd9, // ./...\....za + 0x06, 0xaf, 0x12, 0x09, 0xe5, 0x98, 0x8e, 0xe5, // ........ + 0x98, 0x8e, 0x20, 0xe7, 0x9a, 0x84, 0x20, 0x69, // .. ... i + 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x11, 0x03, 0x00, // Phone... + 0x12, 0x1f, 0x11, 0x2f, 0x11, 0x0a, 0x11, 0x0c, // .../.... + 0x11, 0x16, 0x11, 0x32, 0x11, 0x01, 0x18, 0x01, // ...2.... + 0x05, 0x31, 0x07, 0xfe, 0xca, 0xca, 0xde, 0xaf, // .1...... + 0xde, 0xca, 0xde, 0xde, 0xfa, 0xca, 0xde, 0x00, // ........ + 0x00, 0x00, 0x00, 0x77, 0x0a, 0x6a, 0x10, 0xa2, // ...w.j.. + 0x22, 0xf2, 0x86, 0x5f, 0x41, 0x19, 0x1d, 0x02, // ".._A... + 0x03, 0x03, 0x02, 0x1a, 0x29, 0xea, 0xab, 0x01, // ....)... + 0x73, 0xbc, 0x88, 0x1c, 0x45, 0x4d, 0xe1, 0x66, // s...EM.f + 0x24, 0x8d, 0x2d, 0x27, 0xff, 0x00, 0x4c, 0x02, // $.-'..L. + 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // $....... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt3393[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd3, 0x4d, 0x3b, 0xe9, // ./...M;. + 0xbc, 0x4c, 0x01, 0x00, 0x3c, 0x24, 0x0c, 0x85, // .L..<$.. + 0x03, 0xaa, 0x1a, 0x09, 0x5b, 0x4c, 0x47, 0x5d, // ....[LG] + 0x20, 0x77, 0x65, 0x62, 0x4f, 0x53, 0x20, 0x54, // webOS T + 0x56, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x35, 0x35, // V OLED55 + 0x43, 0x31, 0x50, 0x53, 0x42, 0x07, 0x03, 0x0b, // C1PSB... + 0x11, 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, 0x01, // ........ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt3436[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6a, 0x78, 0xbf, 0x09, // ./..jx.. + 0x95, 0x3c, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x79, // .<....*y + 0x4f, 0xba, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // O...DESK + 0x54, 0x4f, 0x50, 0x2d, 0x39, 0x38, 0x41, 0x31, // TOP-98A1 + 0x41, 0x42, 0x53, 0x02, 0x0a, 0x00, 0x0d, 0x03, // ABS..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt3437[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x30, 0x25, 0x92, 0xda, // ./..0%.. + 0xb0, 0xcc, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xf6, // ......*. + 0x3d, 0xb9, 0x0b, 0x09, 0x54, 0x32, 0x32, 0x30, // =...T220 + 0x34, 0x30, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 40-DUT.. + 0x00, 0x0d, 0x03, 0x0c, 0x11, 0x0a, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt3439[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xda, 0xbd, 0x68, 0x72, // ./....hr + 0x6e, 0xb0, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0xc4, // n.....Z. + 0x5b, 0xb1, 0x10, 0x09, 0x72, 0x65, 0x61, 0x6c, // [...real + 0x6d, 0x65, 0x20, 0x47, 0x54, 0x20, 0x4e, 0x45, // me GT NE + 0x4f, 0x20, 0x33, 0x19, 0x03, 0x05, 0x11, 0x0a, // O 3..... + 0x11, 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, // ........ + 0x11, 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, // .....-./ + 0x11, 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, // ...2.... + 0x07, 0x00, 0xdf, 0x0c, 0xa9, 0x80, 0xbb, 0x4f, // .......O + 0x9f, 0x5c, 0x49, 0x06, 0xcb, 0x15, 0xaa, 0x9e, // .\I..... + 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4807[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x44, 0xc6, 0xee, 0x6b, // ./..D..k + 0x21, 0x00, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x7c, // !.....*| + 0x1c, 0xab, 0x0b, 0x09, 0x31, 0x31, 0x30, 0x30, // ....1100 + 0x30, 0x37, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 07-DUT.. + 0x0c, 0x0b, 0x03, 0x0a, 0x11, 0x0c, 0x11, 0x0e, // ........ + 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4817[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xd3, 0x4d, 0x3b, 0xe9, // ./...M;. + 0xbc, 0x4c, 0x01, 0x00, 0x3c, 0x24, 0x0c, 0x81, // .L..<$.. + 0x03, 0xb6, 0x1a, 0x09, 0x5b, 0x4c, 0x47, 0x5d, // ....[LG] + 0x20, 0x77, 0x65, 0x62, 0x4f, 0x53, 0x20, 0x54, // webOS T + 0x56, 0x20, 0x4f, 0x4c, 0x45, 0x44, 0x35, 0x35, // V OLED55 + 0x43, 0x31, 0x50, 0x53, 0x42, 0x07, 0x03, 0x0b, // C1PSB... + 0x11, 0x0e, 0x11, 0x00, 0x12, 0x01, 0x05, 0x01, // ........ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4844[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x6a, 0x78, 0xbf, 0x09, // ./..jx.. + 0x95, 0x3c, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0x79, // .<....*y + 0x4f, 0xbc, 0x10, 0x09, 0x44, 0x45, 0x53, 0x4b, // O...DESK + 0x54, 0x4f, 0x50, 0x2d, 0x39, 0x38, 0x41, 0x31, // TOP-98A1 + 0x41, 0x42, 0x53, 0x02, 0x0a, 0x00, 0x0d, 0x03, // ABS..... + 0x0c, 0x11, 0x0a, 0x11, 0x0e, 0x11, 0x0b, 0x11, // ........ + 0x1f, 0x11, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4845[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x30, 0x25, 0x92, 0xda, // ./..0%.. + 0xb0, 0xcc, 0x01, 0x00, 0x0c, 0x01, 0x2a, 0xf6, // ......*. + 0x3d, 0xb6, 0x0b, 0x09, 0x54, 0x32, 0x32, 0x30, // =...T220 + 0x34, 0x30, 0x2d, 0x44, 0x55, 0x54, 0x02, 0x0a, // 40-DUT.. + 0x00, 0x0d, 0x03, 0x0c, 0x11, 0x0a, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x1f, 0x11, 0x1e, 0x11, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4925[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc9, 0xfd, 0x14, 0x45, // ./.....E + 0x0a, 0x00, 0x01, 0x00, 0x04, 0x04, 0x24, 0x09, // ......$. + 0x51, 0xac, 0x0e, 0x09, 0x41, 0x54, 0x48, 0x2d, // Q...ATH- + 0x43, 0x4b, 0x53, 0x33, 0x33, 0x30, 0x58, 0x42, // CKS330XB + 0x54, 0x15, 0x03, 0x31, 0x11, 0x08, 0x11, 0x03, // T..1.... + 0x12, 0x1e, 0x11, 0x0c, 0x11, 0x0f, 0x11, 0x0e, // ........ + 0x11, 0x0b, 0x11, 0x00, 0x12, 0x00, 0x10, 0x01, // ........ + 0x05, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4962[258] = { + 0x04, 0x2f, 0xff, 0x01, 0x1c, 0xfb, 0xd3, 0x29, // ./.....) + 0x24, 0x58, 0x01, 0x00, 0x0c, 0x02, 0x5a, 0x1c, // $X....Z. + 0x0c, 0xc0, 0x0f, 0x09, 0x50, 0x69, 0x78, 0x65, // ....Pixe + 0x6c, 0x20, 0x36, 0x20, 0x50, 0x72, 0x6f, 0x20, // l 6 Pro + 0x30, 0x36, 0x19, 0x03, 0x05, 0x11, 0x0a, 0x11, // 06...... + 0x0c, 0x11, 0x0e, 0x11, 0x12, 0x11, 0x15, 0x11, // ........ + 0x16, 0x11, 0x1f, 0x11, 0x2d, 0x11, 0x2f, 0x11, // ....-./. + 0x00, 0x12, 0x32, 0x11, 0x01, 0x05, 0x81, 0x07, // ..2..... + 0x22, 0x1e, 0x7e, 0xb0, 0x4e, 0x50, 0x5d, 0x8b, // ".~.NP]. + 0x27, 0x47, 0x79, 0x5f, 0x63, 0x0b, 0xe5, 0xce, // 'Gy_c... + 0x5a, 0x6c, 0xb1, 0xa7, 0x6d, 0xf1, 0xbc, 0x9b, // Zl..m... + 0xde, 0x3d, 0x5c, 0xae, 0x21, 0xfa, 0x2e, 0xa8, // .=\.!... + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ + 0x00, 0x00 // .. +}; + +// Frame (258 bytes) +static const unsigned char pkt4979[258] = { + 0x04, 0x2f, 0xff, 0x01, 0xc2, 0x3c, 0x42, 0xd9, // ./... selected_packets = { + {"pkt19200", pkt19200}, + {"pkt2062", pkt2062}, + {"pkt26171", pkt26171}, + {"pkt34639", pkt34639}, + {"pktAsha", pktAsha}, +}; + +std::vector data_packets = { + pkt34638, pkt34639, pkt2048, pkt2062, pkt2063, pkt2064, pkt2067, pkt2072, pkt2075, + pkt2076, pkt19189, pkt19190, pkt19191, pkt19192, pkt19193, pkt19194, pkt19198, pkt19200, + pkt19201, pkt19835, pkt19844, pkt19845, pkt19846, pkt19857, pkt19863, pkt19871, pkt19885, + pkt19886, pkt19898, pkt19899, pkt19904, pkt19908, pkt33190, pkt33191, pkt33217, pkt34019, + pkt34020, pkt19975, pkt19988, pkt20036, pkt575, pkt764, pkt29692, pkt29730, pkt29777, + pkt29785, pkt29830, pkt29836, pkt29922, pkt29927, pkt29928, pkt29931, pkt23904, pkt24033, + pkt24158, pkt24446, pkt24658, pkt25745, pkt25751, pkt26171, pkt26175, pkt26328, pkt26463, + pkt34640, pkt34666, pkt34778, pkt34779, pkt34843, pkt34847, pkt34848, pkt34875, pkt19294, + pkt4073, pkt4075, pkt4883, pkt7384, pkt7385, pkt10784, pkt10786, pkt10787, pkt10789, + pkt10799, pkt10800, pkt10801, pkt10804, pkt10806, pkt10807, pkt10808, pkt10809, pkt10816, + pkt10818, pkt10821, pkt10823, pkt10826, pkt10838, pkt10839, pkt10840, pkt10841, pkt10842, + pkt10843, pkt10845, pkt10857, pkt10858, pkt10859, pkt10860, pkt10871, pkt10872, pkt10874, + pkt10876, pkt10877, pkt10887, pkt10888, pkt10890, pkt10891, pkt10893, pkt10895, pkt10904, + pkt10906, pkt10910, pkt10911, pkt10915, pkt10916, pkt10922, pkt10927, pkt10928, pkt10930, + pkt10931, pkt10932, pkt10934, pkt10940, pkt10952, pkt10953, pkt10959, pkt10962, pkt10965, + pkt10967, pkt10973, pkt10976, pkt10982, pkt10984, pkt10986, pkt10987, pkt10997, pkt10999, + pkt11008, pkt11009, pkt11020, pkt11021, pkt11023, pkt11025, pkt11039, pkt11047, pkt11048, + pkt11049, pkt11067, pkt11080, pkt11081, pkt11083, pkt11092, pkt11093, pkt11108, pkt11141, + pkt11152, pkt11154, pkt11155, pkt11156, pkt11158, pkt11159, pkt473, pkt474, pkt488, + pkt489, pkt512, pkt513, pkt530, pkt545, pkt871, pkt27834, pkt27876, pkt649, + pkt677, pkt689, pkt709, pkt763, pkt771, pkt795, pkt951, pkt952, pkt953, + pkt954, pkt451, pkt482, pkt496, pkt511, pkt523, pkt534, pkt706, pkt707, + pkt786, pkt787, pkt800, pkt821, pkt840, pkt848, pkt865, pkt910, pkt911, + pkt1093, pkt1128, pkt1148, pkt1150, pkt1242, pkt1243, pkt1263, pkt1302, pkt1316, + pkt1358, pkt1359, pkt1428, pkt1564, pkt1587, pkt1596, pkt1597, pkt1614, pkt1615, + pkt1662, pkt1678, pkt1764, pkt1775, pkt1796, pkt1797, pkt1821, pkt1840, pkt1855, + pkt2092, pkt2098, pkt2128, pkt2150, pkt2151, pkt2204, pkt2304, pkt2432, pkt2450, + pkt2457, pkt2458, pkt2468, pkt2469, pkt2506, pkt2516, pkt2599, pkt2759, pkt2761, + pkt2778, pkt2779, pkt2780, pkt2788, pkt2818, pkt2890, pkt2931, pkt3390, pkt3391, + pkt3392, pkt3393, pkt3436, pkt3437, pkt3439, pkt4807, pkt4817, pkt4844, pkt4845, + pkt4925, pkt4962, pkt4979, pkt5162, pkt5163, pkt5178, pkt5192, pkt5193, pkt5238, + pkt5264, pkt5448, pkt5482, pkt5501, pkt5509, pkt5511, pkt5544, pkt5633, pkt5634, + pkt22626, pkt22660, pkt22727, pkt22959, pkt36316, pkt36383, pkt41746, pkt3253, pkt3259, + pkt3805, pkt3837, pkt3841, pkt4170, pkt4171, pkt4183, pkt4209, pkt4226, pkt4227, + pkt4247, pkt4257, pkt4266, pkt4450, pkt4459, pkt4468, pkt4469, pkt4473, pkt4485, + pkt4486, pkt4490, pkt4491, pkt4504, pkt4518, pkt4528, pkt5034, pkt5036, pkt5082, + pkt5118, pkt5119, pkt5261, pkt5306, pkt5318, pkt5328, pkt5878, pkt5920, pkt6423, + pkt6434, pkt6503, pkt6504, pkt6511, pkt6512, pkt6513, pkt6518, pkt6525, pkt6540, + pkt6567, pkt6854, pkt6867, pkt6870, pkt6871, pkt6875, pkt6876, pkt6886, pkt6895, + pkt6900, pkt6901, pkt6907, pkt6908, pkt6935, pkt7024, pkt7030, pkt7035, pkt7038, + pkt7049, pkt7050, pktAsha, +}; diff --git a/system/gd/discovery/device/eir_test_data_packets.h b/system/gd/discovery/device/eir_test_data_packets.h new file mode 100644 index 0000000000000000000000000000000000000000..1efa62f28cff7536207a59681dacdeefdd5aebb8 --- /dev/null +++ b/system/gd/discovery/device/eir_test_data_packets.h @@ -0,0 +1,41 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +struct header { + uint8_t event; + uint8_t event_code; + uint8_t length; + uint8_t num_rsp; + uint8_t raw_address[6]; + uint8_t scan_mode; + uint8_t reserved11; + uint8_t cod[3]; + uint16_t clock_offset; + uint8_t rssi; + uint8_t eir_data[]; +} __attribute__((packed)); + +constexpr size_t kEirOffset = sizeof(header); +constexpr size_t kEirSize = 240U; + +extern std::unordered_map selected_packets; +extern std::vector data_packets; diff --git a/system/gd/dumpsys/BUILD.gn b/system/gd/dumpsys/BUILD.gn index 7944263c1bd6cd643cb476103b602702c507a95c..327089c2edb043c438a04ae38d8136f7bb0c7ac4 100644 --- a/system/gd/dumpsys/BUILD.gn +++ b/system/gd/dumpsys/BUILD.gn @@ -24,7 +24,10 @@ source_set("BluetoothDumpsysSources") { cflags_cc = [ "-Wno-enum-compare-switch" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] } @@ -33,5 +36,8 @@ bt_flatc_bundler("libbluetooth-dumpsys") { filename = "generated_dumpsys_bundled_schema" namespace = "bluetooth::dumpsys" deps = [ "//bt/system/gd:BluetoothGeneratedDumpsysBinarySchema_bfbs" ] - configs = [ "//bt/system/gd:gd_defaults" ] + configs = [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } diff --git a/system/gd/dumpsys/bundler/Android.bp b/system/gd/dumpsys/bundler/Android.bp index 0a5f57d3687de6f0878aa31c247c2d58f1ad582d..46bb005c9198b3a0d8eb6849b257bb6d7092e614 100644 --- a/system/gd/dumpsys/bundler/Android.bp +++ b/system/gd/dumpsys/bundler/Android.bp @@ -29,9 +29,11 @@ filegroup { genrule { name: "BluetoothGeneratedBundlerSchema_h_bfbs", visibility: [ + "//packages/modules/Bluetooth/system/btif", "//packages/modules/Bluetooth/system/gd", "//packages/modules/Bluetooth/system/main", "//packages/modules/Bluetooth/system/rust", + "//packages/modules/Bluetooth/system/stack", ], tools: [ "flatc", diff --git a/system/gd/facade/facade_main.cc b/system/gd/facade/facade_main.cc index b16cde018bae2dc1094cd8abcd3861297e33b677..205267d89648a0da3b12297c687bcd6aebe4da1e 100644 --- a/system/gd/facade/facade_main.cc +++ b/system/gd/facade/facade_main.cc @@ -35,6 +35,7 @@ #include "facade/grpc_root_server.h" #include "hal/hci_hal_host.h" #include "hal/snoop_logger.h" +#include "include/check.h" #include "os/log.h" #include "os/parameter_provider.h" #include "os/system_properties.h" diff --git a/system/gd/hal/Android.bp b/system/gd/hal/Android.bp index 27e6b6f204821a7d4c23f54112cc063cdb7f3e4a..c583cab7e44ef31fd8c6b69498d266bcf1d6b1c1 100644 --- a/system/gd/hal/Android.bp +++ b/system/gd/hal/Android.bp @@ -10,7 +10,7 @@ package { filegroup { name: "BluetoothHalSources", srcs: [ - "nocp_iso_clocker.cc", + "link_clocker.cc", "snoop_logger.cc", "snoop_logger_socket.cc", "snoop_logger_socket_thread.cc", diff --git a/system/gd/hal/BUILD.gn b/system/gd/hal/BUILD.gn index 67034e1cc069544a3cb30d2942ea3b1dfb051149..affd15172330391f1757d305ccada27f61bb8ac9 100644 --- a/system/gd/hal/BUILD.gn +++ b/system/gd/hal/BUILD.gn @@ -16,7 +16,7 @@ source_set("BluetoothHalSources") { sources = [ - "nocp_iso_clocker.cc", + "link_clocker.cc", "snoop_logger.cc", "snoop_logger_socket.cc", "snoop_logger_socket_thread.cc", diff --git a/system/gd/hal/fuzz/fuzz_hci_hal.cc b/system/gd/hal/fuzz/fuzz_hci_hal.cc index 741fb6d369865af7b46ff53451818039f9d83769..cc41a17829291dc540db401076a1b9ecf0ed6316 100644 --- a/system/gd/hal/fuzz/fuzz_hci_hal.cc +++ b/system/gd/hal/fuzz/fuzz_hci_hal.cc @@ -58,6 +58,7 @@ void FuzzHciHal::sendHciCommand(HciPacket packet) { waiting_opcode_ = command.GetOpCode(); waiting_for_status_ = hci::fuzz::uses_command_status(waiting_opcode_); + waiting_for_complete_ = !waiting_for_status_; } void FuzzHciHal::injectHciEvent(std::vector data) { @@ -68,11 +69,10 @@ void FuzzHciHal::injectHciEvent(std::vector data) { hci::CommandCompleteView complete = hci::CommandCompleteView::Create(event); if (complete.IsValid()) { - if (waiting_for_status_ || complete.GetCommandOpCode() != waiting_opcode_) { + if (!waiting_for_complete_ || complete.GetCommandOpCode() != waiting_opcode_) { return; } - } else if (!waiting_for_status_) { - return; + waiting_for_complete_ = false; } hci::CommandStatusView status = hci::CommandStatusView::Create(event); @@ -80,8 +80,7 @@ void FuzzHciHal::injectHciEvent(std::vector data) { if (!waiting_for_status_ || status.GetCommandOpCode() != waiting_opcode_) { return; } - } else if (waiting_for_status_) { - return; + waiting_for_status_ = false; } callbacks_->hciEventReceived(data); diff --git a/system/gd/hal/fuzz/fuzz_hci_hal.h b/system/gd/hal/fuzz/fuzz_hci_hal.h index b2c48a6c62d9a9310f41f7b053dca723619648a2..845607ba36cca7ebc8af491fcf980eccab19c71d 100644 --- a/system/gd/hal/fuzz/fuzz_hci_hal.h +++ b/system/gd/hal/fuzz/fuzz_hci_hal.h @@ -54,8 +54,9 @@ class FuzzHciHal : public HciHal { void injectIsoData(std::vector data); HciHalCallbacks* callbacks_; - hci::OpCode waiting_opcode_; - bool waiting_for_status_; + hci::OpCode waiting_opcode_{}; + bool waiting_for_complete_{}; + bool waiting_for_status_{}; }; } // namespace fuzz diff --git a/system/gd/hal/hci_hal_android_hidl.cc b/system/gd/hal/hci_hal_android_hidl.cc index 686b9510cf6d14fb1f47caf9bdf8770e608ab417..daef43372e140169e097e2f3e5efde017272dda0 100644 --- a/system/gd/hal/hci_hal_android_hidl.cc +++ b/system/gd/hal/hci_hal_android_hidl.cc @@ -38,7 +38,7 @@ #include "common/stop_watch.h" #include "common/strings.h" #include "hal/hci_hal.h" -#include "hal/nocp_iso_clocker.h" +#include "hal/link_clocker.h" #include "hal/snoop_logger.h" #include "os/alarm.h" #include "os/log.h" @@ -83,8 +83,8 @@ std::string GetTimerText(const char* func_name, VecType vec) { class InternalHciCallbacks : public IBluetoothHciCallbacks_1_1 { public: - InternalHciCallbacks(SnoopLogger* btsnoop_logger, NocpIsoClocker* nocp_iso_clocker) - : btsnoop_logger_(btsnoop_logger), nocp_iso_clocker_(nocp_iso_clocker) { + InternalHciCallbacks(SnoopLogger* btsnoop_logger, LinkClocker* link_clocker) + : btsnoop_logger_(btsnoop_logger), link_clocker_(link_clocker) { init_promise_ = new std::promise(); } @@ -115,7 +115,7 @@ class InternalHciCallbacks : public IBluetoothHciCallbacks_1_1 { Return hciEventReceived(const hidl_vec& event) override { common::StopWatch stop_watch(GetTimerText(__func__, event)); std::vector received_hci_packet(event.begin(), event.end()); - nocp_iso_clocker_->OnHciEvent(received_hci_packet); + link_clocker_->OnHciEvent(received_hci_packet); btsnoop_logger_->Capture( received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT); { @@ -130,6 +130,7 @@ class InternalHciCallbacks : public IBluetoothHciCallbacks_1_1 { Return aclDataReceived(const hidl_vec& data) override { common::StopWatch stop_watch(GetTimerText(__func__, data)); std::vector received_hci_packet(data.begin(), data.end()); + link_clocker_->OnAclDataReceived(received_hci_packet); btsnoop_logger_->Capture( received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); { @@ -174,7 +175,7 @@ class InternalHciCallbacks : public IBluetoothHciCallbacks_1_1 { std::promise* init_promise_ = nullptr; HciHalCallbacks* callback_ = nullptr; SnoopLogger* btsnoop_logger_ = nullptr; - NocpIsoClocker* nocp_iso_clocker_ = nullptr; + LinkClocker* link_clocker_ = nullptr; }; static constexpr char kBluetoothAidlHalServiceName[] = @@ -182,8 +183,8 @@ static constexpr char kBluetoothAidlHalServiceName[] = class AidlHciCallbacks : public ::aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks { public: - AidlHciCallbacks(SnoopLogger* btsnoop_logger, NocpIsoClocker* nocp_iso_clocker) - : btsnoop_logger_(btsnoop_logger), nocp_iso_clocker_(nocp_iso_clocker) { + AidlHciCallbacks(SnoopLogger* btsnoop_logger, LinkClocker* link_clocker) + : btsnoop_logger_(btsnoop_logger), link_clocker_(link_clocker) { init_promise_ = new std::promise(); } @@ -212,7 +213,7 @@ class AidlHciCallbacks : public ::aidl::android::hardware::bluetooth::BnBluetoot ::ndk::ScopedAStatus hciEventReceived(const std::vector& event) override { common::StopWatch stop_watch(GetTimerText(__func__, event)); std::vector received_hci_packet(event.begin(), event.end()); - nocp_iso_clocker_->OnHciEvent(received_hci_packet); + link_clocker_->OnHciEvent(received_hci_packet); btsnoop_logger_->Capture( received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT); bool sent = false; @@ -232,6 +233,7 @@ class AidlHciCallbacks : public ::aidl::android::hardware::bluetooth::BnBluetoot ::ndk::ScopedAStatus aclDataReceived(const std::vector& data) override { common::StopWatch stop_watch(GetTimerText(__func__, data)); std::vector received_hci_packet(data.begin(), data.end()); + link_clocker_->OnAclDataReceived(received_hci_packet); btsnoop_logger_->Capture( received_hci_packet, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); bool sent = false; @@ -291,7 +293,7 @@ class AidlHciCallbacks : public ::aidl::android::hardware::bluetooth::BnBluetoot std::promise* init_promise_ = nullptr; HciHalCallbacks* callback_ = nullptr; SnoopLogger* btsnoop_logger_ = nullptr; - NocpIsoClocker* nocp_iso_clocker_ = nullptr; + LinkClocker* link_clocker_ = nullptr; }; } // namespace @@ -362,7 +364,7 @@ class HciHalHidl : public HciHal { protected: void ListDependencies(ModuleList* list) const { - list->add(); + list->add(); list->add(); } @@ -374,7 +376,7 @@ class HciHalHidl : public HciHal { ASSERT(bt_hci_1_1_ == nullptr); ASSERT(aidl_hci_ == nullptr); - nocp_iso_clocker_ = GetDependency(); + link_clocker_ = GetDependency(); btsnoop_logger_ = GetDependency(); if (AServiceManager_isDeclared(kBluetoothAidlHalServiceName)) { @@ -408,7 +410,7 @@ class HciHalHidl : public HciHal { death_link == STATUS_OK, "Unable to set the death recipient for the Bluetooth HAL"); aidl_callbacks_ = - ::ndk::SharedRefBase::make(btsnoop_logger_, nocp_iso_clocker_); + ::ndk::SharedRefBase::make(btsnoop_logger_, link_clocker_); aidl_hci_->initialize(aidl_callbacks_); } } @@ -448,7 +450,7 @@ class HciHalHidl : public HciHal { ASSERT(bt_hci_ != nullptr); auto death_link = bt_hci_->linkToDeath(hci_death_recipient_, 0); ASSERT_LOG(death_link.isOk(), "Unable to set the death recipient for the Bluetooth HAL"); - hidl_callbacks_ = new InternalHciCallbacks(btsnoop_logger_, nocp_iso_clocker_); + hidl_callbacks_ = new InternalHciCallbacks(btsnoop_logger_, link_clocker_); if (bt_hci_1_1_ != nullptr) { bt_hci_1_1_->initialize_1_1(hidl_callbacks_); @@ -507,7 +509,7 @@ class HciHalHidl : public HciHal { std::shared_ptr aidl_callbacks_; ::ndk::ScopedAIBinder_DeathRecipient aidl_death_recipient_; SnoopLogger* btsnoop_logger_; - NocpIsoClocker* nocp_iso_clocker_; + LinkClocker* link_clocker_; }; const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHidl(); }); diff --git a/system/gd/hal/hci_hal_host.cc b/system/gd/hal/hci_hal_host.cc index b3d9c0840c55d48992c41071c38f5d9fbeb5b471..e05fda06b404f84d5d5b0943df9c3c545a4f6e70 100644 --- a/system/gd/hal/hci_hal_host.cc +++ b/system/gd/hal/hci_hal_host.cc @@ -28,10 +28,10 @@ #include #include -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "hal/hci_hal.h" +#include "hal/link_clocker.h" #include "hal/mgmt.h" -#include "hal/nocp_iso_clocker.h" #include "hal/snoop_logger.h" #include "metrics/counter_metrics.h" #include "os/log.h" @@ -285,7 +285,7 @@ class HciHalHost : public HciHal { protected: void ListDependencies(ModuleList* list) const { - list->add(); + list->add(); list->add(); list->add(); } @@ -307,7 +307,7 @@ class HciHalHost : public HciHal { common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)), common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this))); hci_incoming_thread_.GetReactor()->ModifyRegistration(reactable_, os::Reactor::REACT_ON_READ_ONLY); - nocp_iso_clocker_ = GetDependency(); + link_clocker_ = GetDependency(); btsnoop_logger_ = GetDependency(); LOG_INFO("HAL opened successfully"); } @@ -348,7 +348,7 @@ class HciHalHost : public HciHal { bluetooth::os::Reactor::Reactable* reactable_ = nullptr; std::queue> hci_outgoing_queue_; SnoopLogger* btsnoop_logger_ = nullptr; - NocpIsoClocker* nocp_iso_clocker_ = nullptr; + LinkClocker* link_clocker_ = nullptr; void write_to_fd(HciPacket packet) { // TODO: replace this with new queue when it's ready @@ -414,7 +414,7 @@ class HciHalHost : public HciHal { HciPacket receivedHciPacket; receivedHciPacket.assign(buf + kH4HeaderSize, buf + kH4HeaderSize + kHciEvtHeaderSize + payload_size); - nocp_iso_clocker_->OnHciEvent(receivedHciPacket); + link_clocker_->OnHciEvent(receivedHciPacket); btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::EVT); { std::lock_guard incoming_packet_callback_lock(incoming_packet_callback_mutex_); @@ -440,6 +440,7 @@ class HciHalHost : public HciHal { HciPacket receivedHciPacket; receivedHciPacket.assign(buf + kH4HeaderSize, buf + kH4HeaderSize + kHciAclHeaderSize + payload_size); + link_clocker_->OnAclDataReceived(receivedHciPacket); btsnoop_logger_->Capture(receivedHciPacket, SnoopLogger::Direction::INCOMING, SnoopLogger::PacketType::ACL); { std::lock_guard incoming_packet_callback_lock(incoming_packet_callback_mutex_); diff --git a/system/gd/hal/hci_hal_host.h b/system/gd/hal/hci_hal_host.h index 9b73b151ad50130578e46e3c4ebce0fd2e31852d..f6ef81ab65d06431bb713305f2ea9d6861ec04a8 100644 --- a/system/gd/hal/hci_hal_host.h +++ b/system/gd/hal/hci_hal_host.h @@ -16,6 +16,7 @@ #pragma once +#include #include namespace bluetooth { diff --git a/system/gd/hal/link_clocker.cc b/system/gd/hal/link_clocker.cc new file mode 100644 index 0000000000000000000000000000000000000000..d0d09d9b3b76e1afc55686efb84c9e8b690da846 --- /dev/null +++ b/system/gd/hal/link_clocker.cc @@ -0,0 +1,228 @@ +/* + * Copyright 2023 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 "hal/link_clocker.h" + +#include + +namespace bluetooth::hal { + +static constexpr uint16_t kInvalidConnectionHandle = 0xFFFF; + +static class : public bluetooth::audio::asrc::ClockHandler { + void OnEvent(uint32_t, int, int) override {} +} g_empty_handler; + +static std::atomic g_nocp_iso_handler = &g_empty_handler; + +static struct { + std::mutex mutex; + bluetooth::audio::asrc::ClockHandler* handler; + struct { + uint16_t connection_handle; + uint16_t stream_cid; + } links[2]; +} g_credit_ind_handler = {.handler = &g_empty_handler, .links = {{}, {}}}; + +NocpIsoEvents::~NocpIsoEvents() { + g_nocp_iso_handler = &g_empty_handler; +} + +void NocpIsoEvents::Bind(bluetooth::audio::asrc::ClockHandler* handler) { + g_nocp_iso_handler = handler; +} + +L2capCreditIndEvents::~L2capCreditIndEvents() { + std::lock_guard guard(g_credit_ind_handler.mutex); + g_credit_ind_handler.handler = &g_empty_handler; + g_credit_ind_handler.links[0].connection_handle = kInvalidConnectionHandle; + g_credit_ind_handler.links[1].connection_handle = kInvalidConnectionHandle; +} + +void L2capCreditIndEvents::Bind(bluetooth::audio::asrc::ClockHandler* handler) { + std::lock_guard guard(g_credit_ind_handler.mutex); + g_credit_ind_handler.handler = handler; + g_credit_ind_handler.links[0].connection_handle = kInvalidConnectionHandle; + g_credit_ind_handler.links[1].connection_handle = kInvalidConnectionHandle; +} + +void L2capCreditIndEvents::Update(int link_id, uint16_t connection_handle, uint16_t stream_cid) { + std::lock_guard guard(g_credit_ind_handler.mutex); + g_credit_ind_handler.links[link_id].connection_handle = connection_handle; + g_credit_ind_handler.links[link_id].stream_cid = stream_cid; +} + +LinkClocker::LinkClocker() : cig_id_(-1), cis_handle_(-1) {} + +void LinkClocker::OnHciEvent(const HciPacket& packet) { + const int HCI_CMD_SET_CIG_PARAMETERS = 0x2062; + const int HCI_EVT_COMMAND_COMPLETE = 0x0e; + const int HCI_EVT_NUMBER_OF_COMPLETED_PACKETS = 0x13; + + // HCI Event [Core 4.E.5.4.4] + // | [0] Event Code + // | [1] Parameter Total Length + // | [2+] Parameters + + if (packet.size() < 2) return; + + const uint8_t* payload = packet.data() + 2; + size_t payload_length = std::min(size_t(packet[1]), packet.size() - 2); + + switch (packet[0]) { + // HCI Command Complete Event [Core 4.E.7.7.14] + // | [0] Num_HCI_Command_Packets, Ignored + // | [1..2] Command_Opcode, catch `HCI_LE_Set_CIG_Parameters` + // | [3+] Return Parameters + + case HCI_EVT_COMMAND_COMPLETE: { + if (payload_length < 3) return; + + int cmd_opcode = payload[1] | (payload[2] << 8); + if (cmd_opcode != HCI_CMD_SET_CIG_PARAMETERS) return; + + const uint8_t* parameters = payload + 3; + size_t parameters_length = payload_length - 3; + + // HCI LE Set CIG Parameters return parameters [4.E.7.8.97] + // | [0] Status, 0 when OK + // | [1] CIG_ID + // | [2] CIS_Count + // | [3..4] Connection_Handle[0] + + if (parameters_length < 3) return; + + int status = parameters[0]; + int cig_id = parameters[1]; + int cis_count = parameters[2]; + + if (status != 0) return; + + if (cig_id_ >= 0 && cis_handle_ >= 0 && cig_id_ != cig_id) { + LOG_WARN("Multiple groups not supported"); + return; + } + + cig_id_ = -1; + cis_handle_ = -1; + + if (cis_count > 0 && parameters_length >= 5) { + cig_id_ = cig_id; + cis_handle_ = (parameters[3] | (parameters[4] << 8)) & 0xfff; + } + + break; + } + + // HCI Number Of Completed Packets event [Core 4.E.7.7.19] + // | [0] Num_Handles + // | FOR each `Num_Handles` connection handles + // | | [0..1] Connection_Handle, catch the CIS Handle + // | | [2..3] Num_Completed_Packets + + case HCI_EVT_NUMBER_OF_COMPLETED_PACKETS: { + if (payload_length < 1) return; + + int i, num_handles = payload[0]; + const uint8_t* item = payload + 1; + if (payload_length < size_t(1 + 4 * num_handles)) return; + + for (i = 0; i < num_handles && ((item[0] | (item[1] << 8)) & 0xfff) != cis_handle_; + i++, item += 4) + ; + if (i >= num_handles) return; + + auto timestamp = std::chrono::system_clock::now().time_since_epoch(); + unsigned timestamp_us = + std::chrono::duration_cast(timestamp).count(); + int num_of_completed_packets = item[2] | (item[3] << 8); + (*g_nocp_iso_handler).OnEvent(timestamp_us, 0, num_of_completed_packets); + + break; + } + } +} + +/// Filter received L2CAP PDUs for Credit acknowledgments for the registered +/// L2CAP channels. +void LinkClocker::OnAclDataReceived(const HciPacket& packet) { + const int L2CAP_LE_U_CID = 0x0005; + const int L2CAP_FLOW_CONTROL_CREDIT_IND = 0x16; + + // HCI ACL Data Packets [4.E.5.4.2] + // | [0..1] Handle | PBF | BC + // | [2..3] Data Total Length + // | [4+] Data + + if (packet.size() < 4) return; + + uint16_t handle = packet[0] | (packet[1] << 8); + int packet_boundary_flag = (handle >> 12) & 0x3; + handle &= 0xfff; + uint16_t data_total_length = std::min(size_t(packet[2] | (packet[3] << 8)), packet.size() - 4); + const uint8_t* data = packet.data() + 4; + + if (data_total_length < 4 || packet_boundary_flag == 0b01 || packet_boundary_flag == 0b11) return; + + // L2CAP Signalling PDU Format [3.A.4] + // | [0..1] PDU Length + // | [2..3] Channel ID + // | [4+] PDU + uint16_t pdu_length = std::min(data[0] | (data[1] << 8), data_total_length - 4); + uint16_t channel_id = data[2] | (data[3] << 8); + data += 4; + + if (channel_id != L2CAP_LE_U_CID) return; + + while (pdu_length >= 4) { + // | FOR each command in the PDU + // | | [0] Command Code + // | | [1] Command Identifier + // | | [2..3] Data Length + // | | [4+] Data + uint8_t command_code = data[0]; + uint16_t data_length = std::min(data[2] | (data[3] << 8), pdu_length - 4); + + if (command_code == L2CAP_FLOW_CONTROL_CREDIT_IND && data_length == 4) { + // | L2CAP Flow Control Credit Ind [3.A.4.24] + // | | [4..5] CID + // | | [6..7] Credits + uint16_t channel_id = data[4] | (data[5] << 8); + uint16_t credits = data[6] | (data[7] << 8); + + auto timestamp = std::chrono::system_clock::now().time_since_epoch(); + unsigned timestamp_us = + std::chrono::duration_cast(timestamp).count(); + + { + std::lock_guard guard(g_credit_ind_handler.mutex); + for (int link_id = 0; link_id < 2; link_id++) { + auto const& link = g_credit_ind_handler.links[link_id]; + if (link.connection_handle == handle && link.stream_cid == channel_id) { + g_credit_ind_handler.handler->OnEvent(timestamp_us, link_id, credits); + } + } + } + } + + data += data_length + 4; + pdu_length -= data_length + 4; + } +} + +const ModuleFactory LinkClocker::Factory = ModuleFactory([]() { return new LinkClocker(); }); + +} // namespace bluetooth::hal diff --git a/system/gd/hal/nocp_iso_clocker.h b/system/gd/hal/link_clocker.h similarity index 61% rename from system/gd/hal/nocp_iso_clocker.h rename to system/gd/hal/link_clocker.h index e8d860403a372d55281a06f069ce3376cd45a99e..c0a7278cabdb95ac915616c7da9a8cd984461d11 100644 --- a/system/gd/hal/nocp_iso_clocker.h +++ b/system/gd/hal/link_clocker.h @@ -16,25 +16,35 @@ #pragma once +#include "audio/asrc/asrc_resampler.h" #include "hci_hal.h" #include "module.h" namespace bluetooth::hal { -class NocpIsoHandler { +class NocpIsoEvents : public bluetooth::audio::asrc::ClockSource { public: - virtual ~NocpIsoHandler() = default; - virtual void OnEvent(uint32_t timestamp_us, int num_of_completed_packets) = 0; + NocpIsoEvents() = default; + ~NocpIsoEvents() override; + + void Bind(bluetooth::audio::asrc::ClockHandler*) override; +}; + +class L2capCreditIndEvents : public bluetooth::audio::asrc::ClockSource { + public: + L2capCreditIndEvents() {} + ~L2capCreditIndEvents() override; + + void Bind(bluetooth::audio::asrc::ClockHandler*) override; + void Update(int link_id, uint16_t connection_handle, uint16_t stream_cid); }; -class NocpIsoClocker : public ::bluetooth::Module { +class LinkClocker : public ::bluetooth::Module { public: static const ModuleFactory Factory; void OnHciEvent(const HciPacket& packet); - - static void Register(NocpIsoHandler* handler); - static void Unregister(); + void OnAclDataReceived(const HciPacket& packet); protected: void ListDependencies(ModuleList*) const override{}; @@ -42,10 +52,10 @@ class NocpIsoClocker : public ::bluetooth::Module { void Stop() override{}; std::string ToString() const override { - return std::string("NocpIsoClocker"); + return std::string("LinkClocker"); } - NocpIsoClocker(); + LinkClocker(); private: int cig_id_; diff --git a/system/gd/hal/nocp_iso_clocker.cc b/system/gd/hal/nocp_iso_clocker.cc deleted file mode 100644 index 1fb1c500eb2a6dd5536af282a6ab0eee9cf04d76..0000000000000000000000000000000000000000 --- a/system/gd/hal/nocp_iso_clocker.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2023 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 "hal/nocp_iso_clocker.h" - -namespace bluetooth::hal { - -static class : public NocpIsoHandler { - void OnEvent(uint32_t, int) override {} -} g_empty_handler; - -static std::atomic g_handler = &g_empty_handler; - -NocpIsoClocker::NocpIsoClocker() : cig_id_(-1), cis_handle_(-1) {} - -void NocpIsoClocker::OnHciEvent(const HciPacket& packet) { - const int HCI_CMD_SET_CIG_PARAMETERS = 0x2062; - const int HCI_EVT_COMMAND_COMPLETE = 0x0e; - const int HCI_EVT_NUMBER_OF_COMPLETED_PACKETS = 0x13; - - // HCI Event [Core 4.E.5.4.4] - // | [0] Event Code - // | [1] Parameter Total Length - // | [2+] Parameters - - if (packet.size() < 2) return; - - const uint8_t* payload = packet.data() + 2; - size_t payload_length = std::min(size_t(packet[1]), packet.size() - 2); - - switch (packet[0]) { - // HCI Command Complete Event [Core 4.E.7.7.14] - // | [0] Num_HCI_Command_Packets, Ignored - // | [1..2] Command_Opcode, catch `HCI_LE_Set_CIG_Parameters` - // | [3+] Return Parameters - - case HCI_EVT_COMMAND_COMPLETE: { - if (payload_length < 3) return; - - int cmd_opcode = payload[1] | (payload[2] << 8); - if (cmd_opcode != HCI_CMD_SET_CIG_PARAMETERS) return; - - const uint8_t* parameters = payload + 3; - size_t parameters_length = payload_length - 3; - - // HCI LE Set CIG Parameters return parameters [4.E.7.8.97] - // | [0] Status, 0 when OK - // | [1] CIG_ID - // | [2] CIS_Count - // | [3..4] Connection_Handle[0] - - if (parameters_length < 3) return; - - int status = parameters[0]; - int cig_id = parameters[1]; - int cis_count = parameters[2]; - - if (status != 0) return; - - if (cig_id_ >= 0 && cis_handle_ >= 0 && cig_id_ != cig_id) { - LOG_WARN("Multiple groups not supported"); - return; - } - - cig_id_ = -1; - cis_handle_ = -1; - - if (cis_count > 0 && parameters_length >= 5) { - cig_id_ = cig_id; - cis_handle_ = (parameters[3] | (parameters[4] << 8)) & 0xfff; - } - - break; - } - - // HCI Number Of Completed Packets event [Core 4.E.7.7.19] - // | [0] Num_Handles - // | FOR each `Num_Handles` connection handles - // | | [0..1] Connection_Handle, catch the CIS Handle - // | | [2..3] Num_Completed_Packets - - case HCI_EVT_NUMBER_OF_COMPLETED_PACKETS: { - if (payload_length < 1) return; - - int i, num_handles = payload[0]; - const uint8_t* item = payload + 1; - if (payload_length < size_t(1 + 4 * num_handles)) return; - - for (i = 0; i < num_handles && ((item[0] | (item[1] << 8)) & 0xfff) != cis_handle_; - i++, item += 4) - ; - if (i >= num_handles) return; - - auto timestamp = std::chrono::system_clock::now().time_since_epoch(); - unsigned timestamp_us = - std::chrono::duration_cast(timestamp).count(); - int num_of_completed_packets = item[2] | (item[3] << 8); - (*g_handler).OnEvent(timestamp_us, num_of_completed_packets); - - break; - } - } -} - -void NocpIsoClocker::Register(NocpIsoHandler* handler) { - g_handler = handler; -} -void NocpIsoClocker::Unregister() { - g_handler = &g_empty_handler; -} - -const ModuleFactory NocpIsoClocker::Factory = ModuleFactory([]() { return new NocpIsoClocker(); }); - -} // namespace bluetooth::hal diff --git a/system/gd/hal/serialize_packet.h b/system/gd/hal/serialize_packet.h index 621dcec6a9940583473ee693c546f4f65b596f7b..70466fc164b43944d336c57ae58e51472d1a862c 100644 --- a/system/gd/hal/serialize_packet.h +++ b/system/gd/hal/serialize_packet.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include "packet/base_packet_builder.h" diff --git a/system/gd/hal/snoop_logger.h b/system/gd/hal/snoop_logger.h index 7eb1d1f7220d2b22b521e6e78ab93fbe01af6e98..7a35f84ce32b41d861f2d60882bb9d11171d5b33 100644 --- a/system/gd/hal/snoop_logger.h +++ b/system/gd/hal/snoop_logger.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "common/circular_buffer.h" #include "hal/hci_hal.h" diff --git a/system/gd/hci/acl_builder_test.cc b/system/gd/hci/acl_builder_test.cc index 4a86c3172d1bd641043bc1a73ce2c378f0c63df0..00dc7473813bdb560352d1ac8813701d0882faef 100644 --- a/system/gd/hci/acl_builder_test.cc +++ b/system/gd/hci/acl_builder_test.cc @@ -14,12 +14,11 @@ * limitations under the License. */ -#include "hci/hci_packets.h" - #include + #include -#include "os/log.h" +#include "hci/hci_packets.h" #include "packet/bit_inserter.h" #include "packet/raw_builder.h" diff --git a/system/gd/hci/acl_connection_interface.h b/system/gd/hci/acl_connection_interface.h index f4932eefabe4cb82e07437b8ab9388ad05ab8083..e46d34090c0d437684c1552a858506d5c17ea4c8 100644 --- a/system/gd/hci/acl_connection_interface.h +++ b/system/gd/hci/acl_connection_interface.h @@ -16,10 +16,8 @@ #pragma once -#include "common/callback.h" #include "hci/command_interface.h" #include "hci/hci_packets.h" -#include "os/utils.h" namespace bluetooth { namespace hci { @@ -28,7 +26,6 @@ constexpr EventCode AclConnectionEvents[] = { EventCode::CONNECTION_PACKET_TYPE_CHANGED, EventCode::ROLE_CHANGE, EventCode::CONNECTION_COMPLETE, - EventCode::CONNECTION_REQUEST, EventCode::AUTHENTICATION_COMPLETE, EventCode::READ_CLOCK_OFFSET_COMPLETE, EventCode::MODE_CHANGE, diff --git a/system/gd/hci/acl_manager.cc b/system/gd/hci/acl_manager.cc index 6f58a4ac8bff36c3982614fb16b508d44e01e331..78d6d46e00b384d75ff0efb68f4e4cc3d66eae97 100644 --- a/system/gd/hci/acl_manager.cc +++ b/system/gd/hci/acl_manager.cc @@ -21,6 +21,7 @@ #include #include "common/bidi_queue.h" +#include "common/byte_array.h" #include "dumpsys_data_generated.h" #include "hci/acl_manager/acl_scheduler.h" #include "hci/acl_manager/classic_impl.h" @@ -33,6 +34,7 @@ #include "hci/remote_name_request.h" #include "hci_acl_manager_generated.h" #include "security/security_module.h" +#include "storage/config_keys.h" #include "storage/storage_module.h" namespace bluetooth { @@ -280,8 +282,8 @@ void AclManager::SetPrivacyPolicyForInitiatorAddress( std::chrono::milliseconds minimum_rotation_time, std::chrono::milliseconds maximum_rotation_time) { Octet16 rotation_irk{}; - auto irk_prop = - GetDependency()->GetProperty("Adapter", "LE_LOCAL_KEY_IRK"); + auto irk_prop = GetDependency()->GetProperty( + BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK); if (irk_prop.has_value()) { auto irk = common::ByteArray<16>::FromString(irk_prop.value()); if (irk.has_value()) { @@ -410,10 +412,6 @@ uint16_t AclManager::HACK_GetLeHandle(Address address) { return pimpl_->le_impl_->HACK_get_handle(address); } -void AclManager::HACK_SetNonAclDisconnectCallback(std::function callback) { - pimpl_->classic_impl_->HACK_SetNonAclDisconnectCallback(callback); -} - void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) { CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority); } @@ -445,7 +443,7 @@ AclManager::~AclManager() = default; void AclManager::impl::Dump( std::promise> promise, flatbuffers::FlatBufferBuilder* fb_builder) const { const std::lock_guard lock(dumpsys_mutex_); - const auto connect_list = (le_impl_ != nullptr) ? le_impl_->connect_list : std::unordered_set(); + const auto accept_list = (le_impl_ != nullptr) ? le_impl_->accept_list : std::unordered_set(); const auto le_connectability_state_text = (le_impl_ != nullptr) ? connectability_state_machine_text(le_impl_->connectability_state_) : "INDETERMINATE"; const auto le_create_connection_timeout_alarms_count = @@ -454,17 +452,17 @@ void AclManager::impl::Dump( auto title = fb_builder->CreateString("----- Acl Manager Dumpsys -----"); auto le_connectability_state = fb_builder->CreateString(le_connectability_state_text); - flatbuffers::Offset strings[connect_list.size()]; + flatbuffers::Offset strings[accept_list.size()]; size_t cnt = 0; - for (const auto& it : connect_list) { + for (const auto& it : accept_list) { strings[cnt++] = fb_builder->CreateString(it.ToString()); } - auto vecofstrings = fb_builder->CreateVector(strings, connect_list.size()); + auto vecofstrings = fb_builder->CreateVector(strings, accept_list.size()); AclManagerDataBuilder builder(*fb_builder); builder.add_title(title); - builder.add_le_filter_accept_list_count(connect_list.size()); + builder.add_le_filter_accept_list_count(accept_list.size()); builder.add_le_filter_accept_list(vecofstrings); builder.add_le_connectability_state(le_connectability_state); builder.add_le_create_connection_timeout_alarms_count(le_create_connection_timeout_alarms_count); diff --git a/system/gd/hci/acl_manager.h b/system/gd/hci/acl_manager.h index f7fa63fd2e2035d706b7daa21fd2bdba4a22d0e7..6814f85a78672550ebcafa96dfc88ed40f132037 100644 --- a/system/gd/hci/acl_manager.h +++ b/system/gd/hci/acl_manager.h @@ -172,11 +172,6 @@ class AclManager : public Module { virtual uint16_t HACK_GetHandle(const Address address); virtual uint16_t HACK_GetLeHandle(const Address address); - // Hack for the shim to get non-acl disconnect callback. Shim needs to post to - // their handler! - virtual void HACK_SetNonAclDisconnectCallback( - std::function); - virtual void HACK_SetAclTxPriority(uint8_t handle, bool high_priority); struct impl; diff --git a/system/gd/hci/acl_manager/acl_connection.h b/system/gd/hci/acl_manager/acl_connection.h index 1347c8232a740a7a6e89bba78e99db9906906f2a..e2514e1b60d460bf8ed2f17a2dbabd56d3feed94 100644 --- a/system/gd/hci/acl_manager/acl_connection.h +++ b/system/gd/hci/acl_manager/acl_connection.h @@ -16,8 +16,6 @@ #pragma once -#include - #include "common/bidi_queue.h" #include "hci/hci_packets.h" diff --git a/system/gd/hci/acl_manager/acl_fragmenter.cc b/system/gd/hci/acl_manager/acl_fragmenter.cc index 16cbe6970675af480ee480111b0bd9798fdc293c..3264ded78da942268156d786c08b5306be190307 100644 --- a/system/gd/hci/acl_manager/acl_fragmenter.cc +++ b/system/gd/hci/acl_manager/acl_fragmenter.cc @@ -16,7 +16,6 @@ #include "hci/acl_manager/acl_fragmenter.h" -#include "os/log.h" #include "packet/fragmenting_inserter.h" namespace bluetooth { diff --git a/system/gd/hci/acl_manager/acl_fragmenter.h b/system/gd/hci/acl_manager/acl_fragmenter.h index 37badef29abf2c712c8a4787600b16be314ba788..a7379c6f8b81627c081ae916444dfe3fd8b13b3f 100644 --- a/system/gd/hci/acl_manager/acl_fragmenter.h +++ b/system/gd/hci/acl_manager/acl_fragmenter.h @@ -16,9 +16,6 @@ #pragma once -#include -#include -#include #include #include diff --git a/system/gd/hci/acl_manager/acl_scheduler.cc b/system/gd/hci/acl_manager/acl_scheduler.cc index d6be6b2b88a0f770315e74976957830adc4dff92..9f4a9f1051f1ed716eceb622f9f895dbd00f3f80 100644 --- a/system/gd/hci/acl_manager/acl_scheduler.cc +++ b/system/gd/hci/acl_manager/acl_scheduler.cc @@ -17,7 +17,6 @@ #include "acl_scheduler.h" #include -#include #include #include diff --git a/system/gd/hci/acl_manager/acl_scheduler.h b/system/gd/hci/acl_manager/acl_scheduler.h index 995b80ae926f846df8d05b867d65b1aff27f377e..77bf2a5f69a2cb7969f8e809bcbc511d073b8a3b 100644 --- a/system/gd/hci/acl_manager/acl_scheduler.h +++ b/system/gd/hci/acl_manager/acl_scheduler.h @@ -18,10 +18,9 @@ #include #include -#include #include "common/contextual_callback.h" -#include "hci/hci_packets.h" +#include "hci/address.h" #include "module.h" namespace bluetooth { diff --git a/system/gd/hci/acl_manager/acl_scheduler_test.cc b/system/gd/hci/acl_manager/acl_scheduler_test.cc index 16fd704c43bd5f5a2df45684cfc89589b3b3e670..1c64c8c3222a0a9c11ab64965a32550adcdf2719 100644 --- a/system/gd/hci/acl_manager/acl_scheduler_test.cc +++ b/system/gd/hci/acl_manager/acl_scheduler_test.cc @@ -19,13 +19,9 @@ #include #include -#include #include #include -#include -#include "common/bind.h" -#include "common/init_flags.h" #include "hci/address.h" #include "os/thread.h" diff --git a/system/gd/hci/acl_manager/assembler.h b/system/gd/hci/acl_manager/assembler.h index 2bc0a2cdc4760156483a6145269b2fa098e557ba..245fe893cbf9e08fe93a4e31d2806edc9b007a7e 100644 --- a/system/gd/hci/acl_manager/assembler.h +++ b/system/gd/hci/acl_manager/assembler.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "hci/acl_manager/acl_connection.h" #include "hci/address_with_type.h" diff --git a/system/gd/hci/acl_manager/classic_acl_connection.h b/system/gd/hci/acl_manager/classic_acl_connection.h index 6870114e0665ec0f054b1278b2842407cf003a1b..560c97eccbf91de5fdfa1a279ceb484db8b35e7e 100644 --- a/system/gd/hci/acl_manager/classic_acl_connection.h +++ b/system/gd/hci/acl_manager/classic_acl_connection.h @@ -16,7 +16,6 @@ #pragma once -#include #include #include "hci/acl_connection_interface.h" diff --git a/system/gd/hci/acl_manager/classic_impl.h b/system/gd/hci/acl_manager/classic_impl.h index 85d9dfce0b172bf7be21963d4f4fe9bd891b5d8f..35c82b71c0e582199ffc2d698e22fb77b28bb2df 100644 --- a/system/gd/hci/acl_manager/classic_impl.h +++ b/system/gd/hci/acl_manager/classic_impl.h @@ -16,15 +16,14 @@ #pragma once -#include #include -#include #include "common/bind.h" #include "common/init_flags.h" #include "hci/acl_manager/acl_scheduler.h" #include "hci/acl_manager/assembler.h" #include "hci/acl_manager/round_robin_scheduler.h" +#include "hci/class_of_device.h" #include "hci/controller.h" #include "hci/event_checkers.h" #include "hci/remote_name_request.h" @@ -70,6 +69,7 @@ struct classic_impl : public security::ISecurityManagerListener { acl_connection_interface_ = hci_layer_->GetAclConnectionInterface( handler_->BindOn(this, &classic_impl::on_classic_event), handler_->BindOn(this, &classic_impl::on_classic_disconnect), + handler_->BindOn(this, &classic_impl::on_incoming_connection), handler_->BindOn(this, &classic_impl::on_read_remote_version_information)); } @@ -85,9 +85,6 @@ struct classic_impl : public security::ISecurityManagerListener { case EventCode::CONNECTION_COMPLETE: on_connection_complete(event_packet); break; - case EventCode::CONNECTION_REQUEST: - on_incoming_connection(event_packet); - break; case EventCode::CONNECTION_PACKET_TYPE_CHANGED: on_connection_packet_type_changed(event_packet); break; @@ -243,10 +240,7 @@ struct classic_impl : public security::ISecurityManagerListener { return connections.send_packet_upward(handle, cb); } - void on_incoming_connection(EventView packet) { - ConnectionRequestView request = ConnectionRequestView::Create(packet); - ASSERT(request.IsValid()); - Address address = request.GetBdAddr(); + void on_incoming_connection(Address address, ClassOfDevice cod) { if (client_callbacks_ == nullptr) { LOG_ERROR("No callbacks to call"); auto reason = RejectConnectionReason::LIMITED_RESOURCES; @@ -254,39 +248,15 @@ struct classic_impl : public security::ISecurityManagerListener { return; } - switch (request.GetLinkType()) { - case ConnectionRequestLinkType::SCO: - client_handler_->CallOn( - client_callbacks_, &ConnectionCallbacks::HACK_OnScoConnectRequest, address, request.GetClassOfDevice()); - return; - - case ConnectionRequestLinkType::ACL: - // Need to upstream Cod information when getting connection_request - client_handler_->CallOn( - client_callbacks_, - &ConnectionCallbacks::OnConnectRequest, - address, - request.GetClassOfDevice()); - break; - - case ConnectionRequestLinkType::ESCO: - client_handler_->CallOn( - client_callbacks_, &ConnectionCallbacks::HACK_OnEscoConnectRequest, address, request.GetClassOfDevice()); - return; - - default: - LOG_ERROR( - "Request has unknown ConnectionRequestLinkType %s", - ConnectionRequestLinkTypeText(request.GetLinkType()).c_str()); - return; - } + client_handler_->CallOn( + client_callbacks_, &ConnectionCallbacks::OnConnectRequest, address, cod); acl_scheduler_->RegisterPendingIncomingConnection(address); if (is_classic_link_already_connected(address)) { auto reason = RejectConnectionReason::UNACCEPTABLE_BD_ADDR; this->reject_connection(RejectConnectionRequestBuilder::Create(address, reason)); - } else if (should_accept_connection_.Run(address, request.GetClassOfDevice())) { + } else if (should_accept_connection_.Run(address, cod)) { this->accept_connection(address); } else { auto reason = RejectConnectionReason::LIMITED_RESOURCES; // TODO: determine reason @@ -398,29 +368,6 @@ struct classic_impl : public security::ISecurityManagerListener { auto status = connection_complete.GetStatus(); auto address = connection_complete.GetBdAddr(); - // TODO(b/261610529) - Some controllers incorrectly return connection - // failures via HCI Connect Complete instead of SCO connect complete. - // Temporarily just drop these packets until we have finer grained control - // over these ASSERTs. -#if TARGET_FLOSS - auto handle = connection_complete.GetConnectionHandle(); - auto link_type = connection_complete.GetLinkType(); - - // HACK: Some failed SCO connections are reporting failures via - // ConnectComplete instead of ScoConnectionComplete. - // The pattern of it is that the handle is always 0xffff. - // We check it with 0x0fff since PDL only extracts 12 bits for handle. - // Drop such packets when the pattern is matched. - if (handle == 0x0fff && link_type == LinkType::SCO) { - LOG_ERROR( - "ConnectionComplete with invalid handle(%u), link type(%u) and status(%d). Dropping packet.", - handle, - link_type, - status); - return; - } -#endif - acl_scheduler_->ReportAclConnectionCompletion( address, handler_->BindOnceOn( @@ -488,10 +435,6 @@ struct classic_impl : public security::ISecurityManagerListener { callbacks->OnDisconnection(reason); }, kRemoveConnectionAfterwards); - // This handle is probably for SCO, so we use the callback workaround. - if (non_acl_disconnect_callback_ != nullptr) { - non_acl_disconnect_callback_(handle, static_cast(reason)); - } connections.crash_on_unknown_handle_ = event_also_routes_to_other_receivers; } @@ -800,10 +743,6 @@ struct classic_impl : public security::ISecurityManagerListener { return connections.HACK_get_handle(address); } - void HACK_SetNonAclDisconnectCallback(std::function callback) { - non_acl_disconnect_callback_ = callback; - } - void handle_register_callbacks(ConnectionCallbacks* callbacks, os::Handler* handler) { ASSERT(client_callbacks_ == nullptr); ASSERT(client_handler_ == nullptr); @@ -832,8 +771,6 @@ struct classic_impl : public security::ISecurityManagerListener { std::unique_ptr delayed_role_change_ = nullptr; std::unique_ptr security_manager_; - - std::function non_acl_disconnect_callback_; }; } // namespace acl_manager diff --git a/system/gd/hci/acl_manager/classic_impl_test.cc b/system/gd/hci/acl_manager/classic_impl_test.cc index c8caf1fc4185df3b0efb702826721000dba2ec94..3f7fddae5fd207ddbdb869b606bb720e797cf711 100644 --- a/system/gd/hci/acl_manager/classic_impl_test.cc +++ b/system/gd/hci/acl_manager/classic_impl_test.cc @@ -20,12 +20,9 @@ #include #include -#include #include "common/bidi_queue.h" -#include "common/callback.h" #include "common/testing/log_capture.h" -#include "hci/acl_manager.h" #include "hci/acl_manager/acl_scheduler.h" #include "hci/acl_manager/connection_callbacks_mock.h" #include "hci/acl_manager/connection_management_callbacks_mock.h" @@ -34,7 +31,6 @@ #include "hci/hci_layer_fake.h" #include "hci/hci_packets.h" #include "os/handler.h" -#include "os/log.h" #include "packet/bit_inserter.h" #include "packet/raw_builder.h" @@ -161,7 +157,7 @@ class ClassicImplTest : public ::testing::Test { bluetooth::common::InitFlags::SetAllForTesting(); thread_ = new Thread("thread", Thread::Priority::NORMAL); handler_ = new Handler(thread_); - hci_layer_ = new TestHciLayer(); + hci_layer_ = new HciLayerFake(); controller_ = new testing::MockController(); EXPECT_CALL(*controller_, GetNumAclPacketBuffers); @@ -246,7 +242,7 @@ class ClassicImplTest : public ::testing::Test { Thread* thread_; Handler* handler_; - TestHciLayer* hci_layer_{nullptr}; + HciLayerFake* hci_layer_{nullptr}; testing::MockController* controller_; acl_manager::RoundRobinScheduler* round_robin_scheduler_{nullptr}; diff --git a/system/gd/hci/acl_manager/connection_callbacks.h b/system/gd/hci/acl_manager/connection_callbacks.h index ea34243851c5c0f16596a8b7337d203df6e49354..5b11da9436348ea9e994c3d03e523fbbe0dbee39 100644 --- a/system/gd/hci/acl_manager/connection_callbacks.h +++ b/system/gd/hci/acl_manager/connection_callbacks.h @@ -17,11 +17,11 @@ #pragma once #include + #include "hci/acl_manager/classic_acl_connection.h" #include "hci/address.h" #include "hci/class_of_device.h" #include "hci/hci_packets.h" -#include "os/handler.h" namespace bluetooth { namespace hci { @@ -36,9 +36,6 @@ class ConnectionCallbacks { virtual void OnConnectRequest(Address, ClassOfDevice) = 0; // Invoked when controller sends Connection Complete event with non-Success error code virtual void OnConnectFail(Address, ErrorCode reason, bool locally_initiated) = 0; - - virtual void HACK_OnEscoConnectRequest(Address, ClassOfDevice) = 0; - virtual void HACK_OnScoConnectRequest(Address, ClassOfDevice) = 0; }; } // namespace acl_manager diff --git a/system/gd/hci/acl_manager/connection_callbacks_mock.h b/system/gd/hci/acl_manager/connection_callbacks_mock.h index 4f50b8a72bc93d077d947b53cb67c23acb26412b..ead64e694e40e69216e086d3c6087b42df60a6d6 100644 --- a/system/gd/hci/acl_manager/connection_callbacks_mock.h +++ b/system/gd/hci/acl_manager/connection_callbacks_mock.h @@ -16,7 +16,8 @@ #pragma once -#include +#include + #include #include "hci/acl_manager/connection_callbacks.h" @@ -32,9 +33,6 @@ class MockConnectionCallback : public ConnectionCallbacks { void, OnConnectSuccess, (std::unique_ptr connection), (override)); MOCK_METHOD(void, OnConnectRequest, (Address, ClassOfDevice), (override)); MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason, bool locally_initiated), (override)); - - MOCK_METHOD(void, HACK_OnEscoConnectRequest, (Address, ClassOfDevice), (override)); - MOCK_METHOD(void, HACK_OnScoConnectRequest, (Address, ClassOfDevice), (override)); }; } // namespace acl_manager diff --git a/system/gd/hci/acl_manager/connection_management_callbacks.h b/system/gd/hci/acl_manager/connection_management_callbacks.h index 1b2eea28d9774bccecee632357e68b5767aa2561..a88945e09c7d978432d867757965639057d12b3b 100644 --- a/system/gd/hci/acl_manager/connection_management_callbacks.h +++ b/system/gd/hci/acl_manager/connection_management_callbacks.h @@ -17,7 +17,7 @@ #pragma once #include -#include + #include "hci/hci_packets.h" namespace bluetooth { diff --git a/system/gd/hci/acl_manager/connection_management_callbacks_mock.h b/system/gd/hci/acl_manager/connection_management_callbacks_mock.h index 88ab212f26e73e006c625d2a28e1be85db8ea916..9a6700c45c3b75328c849a86c26460a38bb32da3 100644 --- a/system/gd/hci/acl_manager/connection_management_callbacks_mock.h +++ b/system/gd/hci/acl_manager/connection_management_callbacks_mock.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include diff --git a/system/gd/hci/acl_manager/le_acceptlist_callbacks.h b/system/gd/hci/acl_manager/le_acceptlist_callbacks.h index 57780b6fae83050f1fd8e0497d422b342df4701c..666addb4579f144994c84d6f95da836b35ed6164 100644 --- a/system/gd/hci/acl_manager/le_acceptlist_callbacks.h +++ b/system/gd/hci/acl_manager/le_acceptlist_callbacks.h @@ -16,12 +16,8 @@ #pragma once -#include - -#include "hci/acl_manager/le_acl_connection.h" #include "hci/address_with_type.h" #include "hci/hci_packets.h" -#include "os/handler.h" namespace bluetooth { namespace hci { diff --git a/system/gd/hci/acl_manager/le_acl_connection.h b/system/gd/hci/acl_manager/le_acl_connection.h index b42da543466f431ea0b31ff9d8142ca88387ae90..05a3a6787fcbef3d56e8e231842c2914265a7b19 100644 --- a/system/gd/hci/acl_manager/le_acl_connection.h +++ b/system/gd/hci/acl_manager/le_acl_connection.h @@ -16,7 +16,6 @@ #pragma once -#include #include #include diff --git a/system/gd/hci/acl_manager/le_connection_callbacks.h b/system/gd/hci/acl_manager/le_connection_callbacks.h index 07abc9a21c3dcf9ed3615b420531c4529cba0e8f..451e3f65a40744d1f30846096b07bc74726e665c 100644 --- a/system/gd/hci/acl_manager/le_connection_callbacks.h +++ b/system/gd/hci/acl_manager/le_connection_callbacks.h @@ -17,10 +17,10 @@ #pragma once #include + #include "hci/acl_manager/le_acl_connection.h" #include "hci/address_with_type.h" #include "hci/hci_packets.h" -#include "os/handler.h" namespace bluetooth { namespace hci { diff --git a/system/gd/hci/acl_manager/le_connection_callbacks_mock.h b/system/gd/hci/acl_manager/le_connection_callbacks_mock.h index 85204315cc08de129af4d4a0a3cab10cefc8e52a..dc3bd3b8ddc7a52939fa278bee665b9f15e4ac84 100644 --- a/system/gd/hci/acl_manager/le_connection_callbacks_mock.h +++ b/system/gd/hci/acl_manager/le_connection_callbacks_mock.h @@ -21,6 +21,7 @@ #include #include "hci/acl_manager/le_acl_connection.h" +#include "hci/acl_manager/le_connection_callbacks.h" #include "hci/address_with_type.h" #include "hci/hci_packets.h" diff --git a/system/gd/hci/acl_manager/le_connection_management_callbacks.h b/system/gd/hci/acl_manager/le_connection_management_callbacks.h index 5315880672db97a48d812cfd54ec29e2f97b12d3..7776ff67feb25f68c11250b21e54039ae1a7a7d9 100644 --- a/system/gd/hci/acl_manager/le_connection_management_callbacks.h +++ b/system/gd/hci/acl_manager/le_connection_management_callbacks.h @@ -16,9 +16,6 @@ #pragma once -#include - -#include "hci/address_with_type.h" #include "hci/hci_packets.h" namespace bluetooth { diff --git a/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h b/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h index 9d828382f40ec5743a715f2ce148d6b6eaa2a4a1..0cf874747ee4786505a2856145948ab06e36a0f0 100644 --- a/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h +++ b/system/gd/hci/acl_manager/le_connection_management_callbacks_mock.h @@ -21,7 +21,6 @@ #include #include "hci/acl_manager/le_connection_management_callbacks.h" -#include "hci/address_with_type.h" #include "hci/hci_packets.h" namespace bluetooth { diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h index 602423e2d9ed6fdc084e36ea6ec221488416dbd1..946c8e698925e79e4c3adbf490ff10a9426869d4 100644 --- a/system/gd/hci/acl_manager/le_impl.h +++ b/system/gd/hci/acl_manager/le_impl.h @@ -22,11 +22,14 @@ #include #include #include +#include #include "common/bind.h" #include "common/init_flags.h" #include "hci/acl_manager/assembler.h" #include "hci/acl_manager/le_acceptlist_callbacks.h" +#include "hci/acl_manager/le_acl_connection.h" +#include "hci/acl_manager/le_connection_callbacks.h" #include "hci/acl_manager/le_connection_management_callbacks.h" #include "hci/acl_manager/round_robin_scheduler.h" #include "hci/controller.h" @@ -151,10 +154,8 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { SubeventCode code = event_packet.GetSubeventCode(); switch (code) { case SubeventCode::CONNECTION_COMPLETE: - on_le_connection_complete(event_packet); - break; case SubeventCode::ENHANCED_CONNECTION_COMPLETE: - on_le_enhanced_connection_complete(event_packet); + on_le_connection_complete(event_packet); break; case SubeventCode::CONNECTION_UPDATE_COMPLETE: on_le_connection_update_complete(event_packet); @@ -327,22 +328,58 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } connecting_le_.clear(); - if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { - create_connection_timeout_alarms_.at(address_with_type).Cancel(); - create_connection_timeout_alarms_.erase(address_with_type); - } + direct_connect_remove(address_with_type); } void on_le_connection_complete(LeMetaEventView packet) { - LeConnectionCompleteView connection_complete = LeConnectionCompleteView::Create(packet); - ASSERT(connection_complete.IsValid()); - auto status = connection_complete.GetStatus(); - auto address = connection_complete.GetPeerAddress(); - auto peer_address_type = connection_complete.GetPeerAddressType(); - auto role = connection_complete.GetRole(); - AddressWithType remote_address(address, peer_address_type); - AddressWithType local_address = le_address_manager_->GetInitiatorAddress(); - const bool in_filter_accept_list = is_device_in_connect_list(remote_address); + ErrorCode status; + Address address; + AddressType peer_address_type; + Role role; + AddressWithType remote_address; + uint16_t handle, conn_interval, conn_latency, supervision_timeout; + + if (packet.GetSubeventCode() == SubeventCode::CONNECTION_COMPLETE) { + LeConnectionCompleteView connection_complete = LeConnectionCompleteView::Create(packet); + ASSERT(connection_complete.IsValid()); + status = connection_complete.GetStatus(); + address = connection_complete.GetPeerAddress(); + peer_address_type = connection_complete.GetPeerAddressType(); + role = connection_complete.GetRole(); + handle = connection_complete.GetConnectionHandle(); + conn_interval = connection_complete.GetConnInterval(); + conn_latency = connection_complete.GetConnLatency(); + supervision_timeout = connection_complete.GetSupervisionTimeout(); + remote_address = AddressWithType(address, peer_address_type); + } else if (packet.GetSubeventCode() == SubeventCode::ENHANCED_CONNECTION_COMPLETE) { + LeEnhancedConnectionCompleteView connection_complete = + LeEnhancedConnectionCompleteView::Create(packet); + ASSERT(connection_complete.IsValid()); + status = connection_complete.GetStatus(); + address = connection_complete.GetPeerAddress(); + peer_address_type = connection_complete.GetPeerAddressType(); + role = connection_complete.GetRole(); + handle = connection_complete.GetConnectionHandle(); + conn_interval = connection_complete.GetConnInterval(); + conn_latency = connection_complete.GetConnLatency(); + supervision_timeout = connection_complete.GetSupervisionTimeout(); + AddressType remote_address_type; + switch (peer_address_type) { + case AddressType::PUBLIC_DEVICE_ADDRESS: + case AddressType::PUBLIC_IDENTITY_ADDRESS: + remote_address_type = AddressType::PUBLIC_DEVICE_ADDRESS; + break; + case AddressType::RANDOM_DEVICE_ADDRESS: + case AddressType::RANDOM_IDENTITY_ADDRESS: + remote_address_type = AddressType::RANDOM_DEVICE_ADDRESS; + break; + } + remote_address = AddressWithType(address, remote_address_type); + } else { + LOG_ALWAYS_FATAL("Bad subevent code:%02x", packet.GetSubeventCode()); + } + + const bool in_filter_accept_list = is_device_in_accept_list(remote_address); if (role == hci::Role::CENTRAL) { connectability_state_ = ConnectabilityState::DISARMED; @@ -368,9 +405,9 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { arm_on_resume_ = false; ready_to_unregister = true; - remove_device_from_connect_list(remote_address); + remove_device_from_accept_list(remote_address); - if (!connect_list.empty()) { + if (!accept_list.empty()) { AddressWithType empty(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS); handler_->Post(common::BindOnce(&le_impl::create_le_connection, common::Unretained(this), empty, false, false)); } @@ -402,23 +439,15 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { LOG_INFO( "Received incoming connection of device in filter accept_list, %s", ADDRESS_TO_LOGGABLE_CSTR(remote_address)); - remove_device_from_connect_list(remote_address); - if (create_connection_timeout_alarms_.find(remote_address) != create_connection_timeout_alarms_.end()) { - create_connection_timeout_alarms_.at(remote_address).Cancel(); - create_connection_timeout_alarms_.erase(remote_address); - } + direct_connect_remove(remote_address); + remove_device_from_accept_list(remote_address); } } - uint16_t conn_interval = connection_complete.GetConnInterval(); - uint16_t conn_latency = connection_complete.GetConnLatency(); - uint16_t supervision_timeout = connection_complete.GetSupervisionTimeout(); if (!check_connection_parameters(conn_interval, conn_interval, conn_latency, supervision_timeout)) { LOG_ERROR("Receive connection complete with invalid connection parameters"); return; } - - uint16_t handle = connection_complete.GetConnectionHandle(); auto role_specific_data = initialize_role_specific_data(role); auto queue = std::make_shared(10); auto queue_down_end = queue->GetDownEnd(); @@ -435,151 +464,20 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { connection->supervision_timeout_ = supervision_timeout; connection->in_filter_accept_list_ = in_filter_accept_list; connection->locally_initiated_ = (role == hci::Role::CENTRAL); - auto connection_callbacks = connection->GetEventCallbacks( - [this](uint16_t handle) { this->connections.invalidate(handle); }); - if (std::holds_alternative(role_specific_data)) { - // the OnLeConnectSuccess event will be sent after receiving the On Advertising Set Terminated - // event, since we need it to know what local_address / advertising set the peer connected to. - // In the meantime, we store it as a pending_connection. - connections.add( - handle, - remote_address, - std::move(connection), - queue_down_end, - handler_, - connection_callbacks); - } else { - connections.add( - handle, remote_address, nullptr, queue_down_end, handler_, connection_callbacks); - le_client_handler_->Post(common::BindOnce( - &LeConnectionCallbacks::OnLeConnectSuccess, - common::Unretained(le_client_callbacks_), - remote_address, - std::move(connection))); - if (le_acceptlist_callbacks_ != nullptr) { - le_acceptlist_callbacks_->OnLeConnectSuccess(remote_address); - } - } - } - - void on_le_enhanced_connection_complete(LeMetaEventView packet) { - LeEnhancedConnectionCompleteView connection_complete = LeEnhancedConnectionCompleteView::Create(packet); - ASSERT(connection_complete.IsValid()); - auto status = connection_complete.GetStatus(); - auto address = connection_complete.GetPeerAddress(); - auto peer_address_type = connection_complete.GetPeerAddressType(); - auto peer_resolvable_address = connection_complete.GetPeerResolvablePrivateAddress(); - auto role = connection_complete.GetRole(); - - AddressType remote_address_type; - switch (peer_address_type) { - case AddressType::PUBLIC_DEVICE_ADDRESS: - case AddressType::PUBLIC_IDENTITY_ADDRESS: - remote_address_type = AddressType::PUBLIC_DEVICE_ADDRESS; - break; - case AddressType::RANDOM_DEVICE_ADDRESS: - case AddressType::RANDOM_IDENTITY_ADDRESS: - remote_address_type = AddressType::RANDOM_DEVICE_ADDRESS; - break; - } - AddressWithType remote_address(address, remote_address_type); - const bool in_filter_accept_list = is_device_in_connect_list(remote_address); - - - if (role == hci::Role::CENTRAL) { - connectability_state_ = ConnectabilityState::DISARMED; - - if (status == ErrorCode::UNKNOWN_CONNECTION && pause_connection) { - on_le_connection_canceled_on_pause(); - return; - } - - on_common_le_connection_complete(remote_address); - if (status == ErrorCode::UNKNOWN_CONNECTION) { - if (remote_address.GetAddress() != Address::kEmpty) { - LOG_INFO("Controller send non-empty address field:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); - } - // direct connect canceled due to connection timeout, start background connect - create_le_connection(remote_address, false, false); - return; - } - - arm_on_resume_ = false; - ready_to_unregister = true; - remove_device_from_connect_list(remote_address); - - if (!connect_list.empty()) { - AddressWithType empty(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS); - handler_->Post(common::BindOnce(&le_impl::create_le_connection, common::Unretained(this), empty, false, false)); - } - - if (le_client_handler_ == nullptr) { - LOG_ERROR("No callbacks to call"); - return; - } - if (status != ErrorCode::SUCCESS) { - report_le_connection_failure(remote_address, status); - return; - } - - } else { - LOG_INFO("Received connection complete with Peripheral role"); - if (le_client_handler_ == nullptr) { - LOG_ERROR("No callbacks to call"); - return; - } + if (packet.GetSubeventCode() == SubeventCode::ENHANCED_CONNECTION_COMPLETE) { + LeEnhancedConnectionCompleteView connection_complete = + LeEnhancedConnectionCompleteView::Create(packet); + ASSERT(connection_complete.IsValid()); - if (status != ErrorCode::SUCCESS) { - std::string error_code = ErrorCodeText(status); - LOG_WARN("Received on_le_enhanced_connection_complete with error code %s", error_code.c_str()); - report_le_connection_failure(remote_address, status); - return; - } - - if (in_filter_accept_list) { - LOG_INFO( - "Received incoming connection of device in filter accept_list, %s", - ADDRESS_TO_LOGGABLE_CSTR(remote_address)); - remove_device_from_connect_list(remote_address); - if (create_connection_timeout_alarms_.find(remote_address) != create_connection_timeout_alarms_.end()) { - create_connection_timeout_alarms_.at(remote_address).Cancel(); - create_connection_timeout_alarms_.erase(remote_address); - } - } + connection->local_resolvable_private_address_ = + connection_complete.GetLocalResolvablePrivateAddress(); + connection->peer_resolvable_private_address_ = + connection_complete.GetPeerResolvablePrivateAddress(); } - auto role_specific_data = initialize_role_specific_data(role); - uint16_t conn_interval = connection_complete.GetConnInterval(); - uint16_t conn_latency = connection_complete.GetConnLatency(); - uint16_t supervision_timeout = connection_complete.GetSupervisionTimeout(); - if (!check_connection_parameters(conn_interval, conn_interval, conn_latency, supervision_timeout)) { - LOG_ERROR("Receive enhenced connection complete with invalid connection parameters"); - return; - } - uint16_t handle = connection_complete.GetConnectionHandle(); - auto queue = std::make_shared(10); - auto queue_down_end = queue->GetDownEnd(); - round_robin_scheduler_->Register(RoundRobinScheduler::ConnectionType::LE, handle, queue); - std::unique_ptr connection(new LeAclConnection( - std::move(queue), - le_acl_connection_interface_, - handle, - role_specific_data, - remote_address)); - connection->peer_address_with_type_ = AddressWithType(address, peer_address_type); - connection->interval_ = conn_interval; - connection->latency_ = conn_latency; - connection->supervision_timeout_ = supervision_timeout; - connection->local_resolvable_private_address_ = connection_complete.GetLocalResolvablePrivateAddress(); - connection->peer_resolvable_private_address_ = connection_complete.GetPeerResolvablePrivateAddress(); - connection->in_filter_accept_list_ = in_filter_accept_list; - connection->locally_initiated_ = (role == hci::Role::CENTRAL); - auto connection_callbacks = connection->GetEventCallbacks( [this](uint16_t handle) { this->connections.invalidate(handle); }); - if (std::holds_alternative(role_specific_data)) { // the OnLeConnectSuccess event will be sent after receiving the On Advertising Set Terminated // event, since we need it to know what local_address / advertising set the peer connected to. @@ -643,9 +541,9 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { connections.crash_on_unknown_handle_ = event_also_routes_to_other_receivers; if (background_connections_.count(remote_address) == 1) { - LOG_INFO("re-add device to connect list"); + LOG_INFO("re-add device to accept list"); arm_on_resume_ = true; - add_device_to_connect_list(remote_address); + add_device_to_accept_list(remote_address); } } @@ -765,46 +663,71 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } } - void add_device_to_connect_list(AddressWithType address_with_type) { + void direct_connect_add(AddressWithType address_with_type) { + direct_connections_.insert(address_with_type); + if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { + return; + } + + auto emplace_result = create_connection_timeout_alarms_.emplace( + std::piecewise_construct, + std::forward_as_tuple(address_with_type.GetAddress(), address_with_type.GetAddressType()), + std::forward_as_tuple(handler_)); + uint32_t connection_timeout = + os::GetSystemPropertyUint32(kPropertyDirectConnTimeout, kCreateConnectionTimeoutMs); + emplace_result.first->second.Schedule( + common::BindOnce(&le_impl::on_create_connection_timeout, common::Unretained(this), address_with_type), + std::chrono::milliseconds(connection_timeout)); + } + + void direct_connect_remove(AddressWithType address_with_type) { + auto it = create_connection_timeout_alarms_.find(address_with_type); + if (it != create_connection_timeout_alarms_.end()) { + it->second.Cancel(); + create_connection_timeout_alarms_.erase(it); + } + direct_connections_.erase(address_with_type); + } + + void add_device_to_accept_list(AddressWithType address_with_type) { if (connections.alreadyConnected(address_with_type)) { LOG_INFO("Device already connected, return"); return; } - if (connect_list.find(address_with_type) != connect_list.end()) { + if (accept_list.find(address_with_type) != accept_list.end()) { LOG_WARN( "Device already exists in acceptlist and cannot be added: %s", ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); return; } - connect_list.insert(address_with_type); + accept_list.insert(address_with_type); register_with_address_manager(); le_address_manager_->AddDeviceToFilterAcceptList( address_with_type.ToFilterAcceptListAddressType(), address_with_type.GetAddress()); } - bool is_device_in_connect_list(AddressWithType address_with_type) { - return (connect_list.find(address_with_type) != connect_list.end()); + bool is_device_in_accept_list(AddressWithType address_with_type) { + return (accept_list.find(address_with_type) != accept_list.end()); } - void remove_device_from_connect_list(AddressWithType address_with_type) { - if (connect_list.find(address_with_type) == connect_list.end()) { + void remove_device_from_accept_list(AddressWithType address_with_type) { + if (accept_list.find(address_with_type) == accept_list.end()) { LOG_WARN( "Device not in acceptlist and cannot be removed: %s", ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); return; } - connect_list.erase(address_with_type); + accept_list.erase(address_with_type); connecting_le_.erase(address_with_type); - direct_connections_.erase(address_with_type); register_with_address_manager(); le_address_manager_->RemoveDeviceFromFilterAcceptList( address_with_type.ToFilterAcceptListAddressType(), address_with_type.GetAddress()); } void clear_filter_accept_list() { - connect_list.clear(); + accept_list.clear(); register_with_address_manager(); le_address_manager_->ClearFilterAcceptList(); } @@ -876,13 +799,13 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { connectability_state_machine_text(connectability_state_).c_str()); return; } - if (connect_list.empty()) { + if (accept_list.empty()) { LOG_INFO("Ignored request to re-arm le connection state machine when filter accept list is empty"); return; } AddressWithType empty(Address::kEmpty, AddressType::RANDOM_DEVICE_ADDRESS); connectability_state_ = ConnectabilityState::ARMING; - connecting_le_ = connect_list; + connecting_le_ = accept_list; uint16_t le_scan_interval = os::GetSystemPropertyUint32(kPropertyConnScanIntervalSlow, kScanIntervalSlow); uint16_t le_scan_window = os::GetSystemPropertyUint32(kPropertyConnScanWindowSlow, kScanWindowSlow); @@ -1011,7 +934,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } } - void create_le_connection(AddressWithType address_with_type, bool add_to_connect_list, bool is_direct) { + void create_le_connection(AddressWithType address_with_type, bool add_to_accept_list, bool is_direct) { if (le_client_callbacks_ == nullptr) { LOG_ERROR("No callbacks to call"); return; @@ -1022,27 +945,15 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { return; } - bool already_in_connect_list = connect_list.find(address_with_type) != connect_list.end(); + bool already_in_accept_list = accept_list.find(address_with_type) != accept_list.end(); // TODO: Configure default LE connection parameters? - if (add_to_connect_list) { - if (!already_in_connect_list) { - add_device_to_connect_list(address_with_type); + if (add_to_accept_list) { + if (!already_in_accept_list) { + add_device_to_accept_list(address_with_type); } if (is_direct) { - direct_connections_.insert(address_with_type); - if (create_connection_timeout_alarms_.find(address_with_type) == create_connection_timeout_alarms_.end()) { - create_connection_timeout_alarms_.emplace( - std::piecewise_construct, - std::forward_as_tuple(address_with_type.GetAddress(), address_with_type.GetAddressType()), - std::forward_as_tuple(handler_)); - uint32_t connection_timeout = - os::GetSystemPropertyUint32(kPropertyDirectConnTimeout, kCreateConnectionTimeoutMs); - create_connection_timeout_alarms_.at(address_with_type) - .Schedule( - common::BindOnce(&le_impl::on_create_connection_timeout, common::Unretained(this), address_with_type), - std::chrono::milliseconds(connection_timeout)); - } + direct_connect_add(address_with_type); } } @@ -1065,7 +976,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { switch (connectability_state_) { case ConnectabilityState::ARMED: case ConnectabilityState::ARMING: - if (already_in_connect_list) { + if (already_in_accept_list) { arm_on_disarm_ = true; disarm_connectability(); } else { @@ -1079,7 +990,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { default: // If we added to filter accept list then the arming of the le state machine // must wait until the filter accept list command as completed - if (add_to_connect_list) { + if (add_to_accept_list) { arm_on_resume_ = true; LOG_DEBUG("Deferred until filter accept list has completed"); } else { @@ -1092,32 +1003,24 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { void on_create_connection_timeout(AddressWithType address_with_type) { LOG_INFO("on_create_connection_timeout, address: %s", ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); - if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { - create_connection_timeout_alarms_.at(address_with_type).Cancel(); - create_connection_timeout_alarms_.erase(address_with_type); + direct_connect_remove(address_with_type); - if (background_connections_.find(address_with_type) != background_connections_.end()) { - direct_connections_.erase(address_with_type); - disarm_connectability(); - } else { - cancel_connect(address_with_type); - } - le_client_handler_->Post(common::BindOnce( - &LeConnectionCallbacks::OnLeConnectFail, - common::Unretained(le_client_callbacks_), - address_with_type, - ErrorCode::CONNECTION_ACCEPT_TIMEOUT)); + if (background_connections_.find(address_with_type) != background_connections_.end()) { + disarm_connectability(); + } else { + remove_device_from_accept_list(address_with_type); } + le_client_handler_->Post(common::BindOnce( + &LeConnectionCallbacks::OnLeConnectFail, + common::Unretained(le_client_callbacks_), + address_with_type, + ErrorCode::CONNECTION_ACCEPT_TIMEOUT)); } void cancel_connect(AddressWithType address_with_type) { - // Remove any alarms for this peer, if any - if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { - create_connection_timeout_alarms_.at(address_with_type).Cancel(); - create_connection_timeout_alarms_.erase(address_with_type); - } + direct_connect_remove(address_with_type); // the connection will be canceled by LeAddressManager.OnPause() - remove_device_from_connect_list(address_with_type); + remove_device_from_accept_list(address_with_type); } void set_le_suggested_default_data_parameters(uint16_t length, uint16_t time) { @@ -1312,9 +1215,10 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { bool arm_on_resume_{}; bool arm_on_disarm_{}; std::unordered_set direct_connections_{}; - // Set of devices that will not be removed from connect list after direct connect timeout + // Set of devices that will not be removed from accept list after direct connect timeout std::unordered_set background_connections_; - std::unordered_set connect_list; + /* This is content of controller "Filter Accept List"*/ + std::unordered_set accept_list; AddressWithType connection_peer_address_with_type_; // Direct peer address UNSUPPORTEDD bool address_manager_registered = false; bool ready_to_unregister = false; diff --git a/system/gd/hci/acl_manager/le_impl_test.cc b/system/gd/hci/acl_manager/le_impl_test.cc index 2332fcd930d607cdbfc28eed1478bdc70fdab0a8..1ea01214b7a9b03238616f8bde989d102f5dc98d 100644 --- a/system/gd/hci/acl_manager/le_impl_test.cc +++ b/system/gd/hci/acl_manager/le_impl_test.cc @@ -20,7 +20,6 @@ #include #include -#include #include "common/bidi_queue.h" #include "common/testing/log_capture.h" @@ -28,7 +27,9 @@ #include "hci/acl_manager/le_connection_management_callbacks.h" #include "hci/address_with_type.h" #include "hci/controller.h" +#include "hci/hci_layer_fake.h" #include "hci/hci_packets.h" +#include "hci/le_acl_connection_interface.h" #include "hci/octets.h" #include "os/handler.h" #include "os/log.h" @@ -123,23 +124,18 @@ std::shared_ptr> Serialize(std::unique_ptr build) { } template -T CreateCommandView(std::shared_ptr> bytes) { - return T::Create(hci::CommandView::Create(hci::PacketView(bytes))); +T CreateAclCommandView(hci::CommandView command) { + return T::Create(hci::AclCommandView::Create(command)); } template -T CreateAclCommandView(std::shared_ptr> bytes) { - return T::Create(CreateCommandView(bytes)); +T CreateLeConnectionManagementCommandView(hci::CommandView command) { + return T::Create(CreateAclCommandView(command)); } template -T CreateLeConnectionManagementCommandView(std::shared_ptr> bytes) { - return T::Create(CreateAclCommandView(bytes)); -} - -template -T CreateLeSecurityCommandView(std::shared_ptr> bytes) { - return T::Create(CreateCommandView(bytes)); +T CreateLeSecurityCommandView(hci::CommandView command) { + return T::Create(hci::LeSecurityCommandView::Create(command)); } template @@ -147,14 +143,14 @@ T CreateLeEventView(std::shared_ptr> bytes) { return T::Create(hci::LeMetaEventView::Create(hci::EventView::Create(hci::PacketView(bytes)))); } -[[maybe_unused]] hci::CommandCompleteView ReturnCommandComplete(hci::OpCode op_code, hci::ErrorCode error_code) { +hci::CommandCompleteView ReturnCommandComplete(hci::OpCode op_code, hci::ErrorCode error_code) { std::vector success_vector{static_cast(error_code)}; auto builder = hci::CommandCompleteBuilder::Create(uint8_t{1}, op_code, std::make_unique(success_vector)); auto bytes = Serialize(std::move(builder)); return hci::CommandCompleteView::Create(hci::EventView::Create(hci::PacketView(bytes))); } -[[maybe_unused]] hci::CommandStatusView ReturnCommandStatus(hci::OpCode op_code, hci::ErrorCode error_code) { +hci::CommandStatusView ReturnCommandStatus(hci::OpCode op_code, hci::ErrorCode error_code) { std::vector success_vector{static_cast(error_code)}; auto builder = hci::CommandStatusBuilder::Create( hci::ErrorCode::SUCCESS, uint8_t{1}, op_code, std::make_unique(success_vector)); @@ -170,14 +166,6 @@ namespace acl_manager { namespace { -PacketView GetPacketView(std::unique_ptr packet) { - auto bytes = std::make_shared>(); - BitInserter i(*bytes); - bytes->reserve(packet->size()); - packet->Serialize(i); - return packet::PacketView(bytes); -} - class TestController : public Controller { public: bool IsSupported(OpCode op_code) const override { @@ -233,174 +221,6 @@ class TestController : public Controller { std::set supported_opcodes_{}; }; -class TestHciLayer : public HciLayer { - // This is a springboard class that converts from `AclCommandBuilder` - // to `ComandBuilder` for use in the hci layer. - template - class CommandInterfaceImpl : public CommandInterface { - public: - explicit CommandInterfaceImpl(HciLayer& hci) : hci_(hci) {} - ~CommandInterfaceImpl() = default; - - void EnqueueCommand( - std::unique_ptr command, common::ContextualOnceCallback on_complete) override { - hci_.EnqueueCommand(std::move(command), std::move(on_complete)); - } - - void EnqueueCommand( - std::unique_ptr command, common::ContextualOnceCallback on_status) override { - hci_.EnqueueCommand(std::move(command), std::move(on_status)); - } - HciLayer& hci_; - }; - - void EnqueueCommand( - std::unique_ptr command, - common::ContextualOnceCallback on_status) override { - const std::lock_guard lock(command_queue_mutex_); - command_queue_.push(std::move(command)); - command_status_callbacks.push_back(std::move(on_status)); - if (command_promise_ != nullptr) { - std::promise* prom = command_promise_.release(); - prom->set_value(); - delete prom; - } - } - - void EnqueueCommand( - std::unique_ptr command, - common::ContextualOnceCallback on_complete) override { - const std::lock_guard lock(command_queue_mutex_); - command_queue_.push(std::move(command)); - command_complete_callbacks.push_back(std::move(on_complete)); - if (command_promise_ != nullptr) { - std::promise* prom = command_promise_.release(); - prom->set_value(); - delete prom; - } - } - - public: - std::unique_ptr DequeueCommand() { - const std::lock_guard lock(command_queue_mutex_); - auto packet = std::move(command_queue_.front()); - command_queue_.pop(); - return std::move(packet); - } - - std::shared_ptr> DequeueCommandBytes() { - auto command = DequeueCommand(); - auto bytes = std::make_shared>(); - packet::BitInserter bi(*bytes); - command->Serialize(bi); - return bytes; - } - - bool IsPacketQueueEmpty() const { - const std::lock_guard lock(command_queue_mutex_); - return command_queue_.empty(); - } - - size_t NumberOfQueuedCommands() const { - const std::lock_guard lock(command_queue_mutex_); - return command_queue_.size(); - } - - void SetCommandFuture() { - ASSERT_EQ(command_promise_, nullptr) << "Promises, Promises, ... Only one at a time."; - command_promise_ = std::make_unique>(); - command_future_ = std::make_unique>(command_promise_->get_future()); - } - - CommandView GetLastCommand() { - if (command_queue_.empty()) { - return CommandView::Create(PacketView(std::make_shared>())); - } - auto last = std::move(command_queue_.front()); - command_queue_.pop(); - return CommandView::Create(GetPacketView(std::move(last))); - } - - std::optional GetCommandOptional(OpCode op_code) { - if (!command_queue_.empty()) { - std::lock_guard lock(command_queue_mutex_); - if (command_future_ != nullptr) { - command_future_.reset(); - command_promise_.reset(); - } - } else if (command_future_ != nullptr) { - command_future_->wait_for(std::chrono::milliseconds(1000)); - } - std::lock_guard lock(command_queue_mutex_); - if (command_queue_.empty()) { - return std::nullopt; - } else { - CommandView command_packet_view = GetLastCommand(); - EXPECT_TRUE(command_packet_view.IsValid()); - EXPECT_EQ(command_packet_view.GetOpCode(), op_code); - return command_packet_view; - } - } - - CommandView GetCommand(OpCode op_code) { - std::optional command = GetCommandOptional(op_code); - ASSERT_LOG( - command.has_value(), - "Expecting command %s but command queue was empty", - OpCodeText(op_code).c_str()); - return command.value(); - } - - void CommandCompleteCallback(std::unique_ptr event_builder) { - auto event = EventView::Create(GetPacketView(std::move(event_builder))); - CommandCompleteView complete_view = CommandCompleteView::Create(event); - ASSERT_TRUE(complete_view.IsValid()); - ASSERT_NE((uint16_t)command_complete_callbacks.size(), 0); - std::move(command_complete_callbacks.front()).Invoke(complete_view); - command_complete_callbacks.pop_front(); - } - - void CommandStatusCallback(std::unique_ptr event_builder) { - auto event = EventView::Create(GetPacketView(std::move(event_builder))); - CommandStatusView status_view = CommandStatusView::Create(event); - ASSERT_TRUE(status_view.IsValid()); - ASSERT_NE((uint16_t)command_status_callbacks.size(), 0); - std::move(command_status_callbacks.front()).Invoke(status_view); - command_status_callbacks.pop_front(); - } - - void IncomingLeMetaEvent(std::unique_ptr event_builder) { - auto packet = GetPacketView(std::move(event_builder)); - EventView event = EventView::Create(packet); - LeMetaEventView meta_event_view = LeMetaEventView::Create(event); - EXPECT_TRUE(meta_event_view.IsValid()); - le_event_handler_.Invoke(meta_event_view); - } - - LeAclConnectionInterface* GetLeAclConnectionInterface( - common::ContextualCallback event_handler, - common::ContextualCallback on_disconnect, - common::ContextualCallback< - void(hci::ErrorCode hci_status, uint16_t, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version)> - on_read_remote_version) override { - disconnect_handlers_.push_back(on_disconnect); - read_remote_version_handlers_.push_back(on_read_remote_version); - le_event_handler_ = event_handler; - return &le_acl_connection_manager_interface_; - } - - void PutLeAclConnectionInterface() override {} - - private: - std::list> command_complete_callbacks; - std::list> command_status_callbacks; - common::ContextualCallback le_event_handler_; - std::queue> command_queue_; - mutable std::mutex command_queue_mutex_; - std::unique_ptr> command_promise_; - std::unique_ptr> command_future_; - CommandInterfaceImpl le_acl_connection_manager_interface_{*this}; -}; } // namespace class MockLeConnectionCallbacks : public LeConnectionCallbacks { @@ -464,7 +284,7 @@ class LeImplTest : public ::testing::Test { thread_ = new Thread("thread", Thread::Priority::NORMAL); handler_ = new Handler(thread_); controller_ = new TestController(); - hci_layer_ = new TestHciLayer(); + hci_layer_ = new HciLayerFake(); round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_queue_.GetUpEnd()); hci_queue_.GetDownEnd()->RegisterDequeue( @@ -485,7 +305,6 @@ class LeImplTest : public ::testing::Test { void set_random_device_address_policy() { // Set address policy - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); hci::Address address; Address::FromString("D0:05:04:03:02:01", address); hci::AddressWithType address_with_type(address, hci::AddressType::RANDOM_DEVICE_ADDRESS); @@ -499,7 +318,7 @@ class LeImplTest : public ::testing::Test { minimum_rotation_time, maximum_rotation_time); hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); - hci_layer_->CommandCompleteCallback(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } void TearDown() override { @@ -572,7 +391,7 @@ class LeImplTest : public ::testing::Test { Thread* thread_; Handler* handler_; - TestHciLayer* hci_layer_{nullptr}; + HciLayerFake* hci_layer_{nullptr}; TestController* controller_; RoundRobinScheduler* round_robin_scheduler_{nullptr}; @@ -642,56 +461,55 @@ class LeImplWithConnectionTest : public LeImplTest { std::unique_ptr connection_; }; -TEST_F(LeImplTest, add_device_to_connect_list) { - le_impl_->add_device_to_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(1UL, le_impl_->connect_list.size()); +TEST_F(LeImplTest, add_device_to_accept_list) { + le_impl_->add_device_to_accept_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(1UL, le_impl_->accept_list.size()); - le_impl_->add_device_to_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(2UL, le_impl_->connect_list.size()); + le_impl_->add_device_to_accept_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(2UL, le_impl_->accept_list.size()); - le_impl_->add_device_to_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(2UL, le_impl_->connect_list.size()); + le_impl_->add_device_to_accept_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(2UL, le_impl_->accept_list.size()); - le_impl_->add_device_to_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(2UL, le_impl_->connect_list.size()); + le_impl_->add_device_to_accept_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(2UL, le_impl_->accept_list.size()); } -TEST_F(LeImplTest, remove_device_from_connect_list) { - le_impl_->add_device_to_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); - le_impl_->add_device_to_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); - le_impl_->add_device_to_connect_list({{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS}); - le_impl_->add_device_to_connect_list({{0x31, 0x32, 0x33, 0x34, 0x35, 0x36}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(4UL, le_impl_->connect_list.size()); +TEST_F(LeImplTest, remove_device_from_accept_list) { + le_impl_->add_device_to_accept_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); + le_impl_->add_device_to_accept_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); + le_impl_->add_device_to_accept_list({{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS}); + le_impl_->add_device_to_accept_list({{0x31, 0x32, 0x33, 0x34, 0x35, 0x36}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(4UL, le_impl_->accept_list.size()); - le_impl_->remove_device_from_connect_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(3UL, le_impl_->connect_list.size()); + le_impl_->remove_device_from_accept_list({{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(3UL, le_impl_->accept_list.size()); - le_impl_->remove_device_from_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(2UL, le_impl_->connect_list.size()); + le_impl_->remove_device_from_accept_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(2UL, le_impl_->accept_list.size()); - le_impl_->remove_device_from_connect_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(2UL, le_impl_->connect_list.size()); + le_impl_->remove_device_from_accept_list({{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(2UL, le_impl_->accept_list.size()); - le_impl_->remove_device_from_connect_list({Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(2UL, le_impl_->connect_list.size()); + le_impl_->remove_device_from_accept_list({Address::kEmpty, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(2UL, le_impl_->accept_list.size()); - le_impl_->remove_device_from_connect_list({{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS}); - le_impl_->remove_device_from_connect_list({{0x31, 0x32, 0x33, 0x34, 0x35, 0x36}, AddressType::PUBLIC_DEVICE_ADDRESS}); - ASSERT_EQ(0UL, le_impl_->connect_list.size()); + le_impl_->remove_device_from_accept_list({{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS}); + le_impl_->remove_device_from_accept_list({{0x31, 0x32, 0x33, 0x34, 0x35, 0x36}, AddressType::PUBLIC_DEVICE_ADDRESS}); + ASSERT_EQ(0UL, le_impl_->accept_list.size()); } TEST_F(LeImplTest, connection_complete_with_periperal_role) { set_random_device_address_policy(); // Create connection - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); le_impl_->create_le_connection( {{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS}, true, false); hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); - hci_layer_->CommandCompleteCallback(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - hci_layer_->CommandStatusCallback(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); sync_handler(); // Check state is ARMED @@ -723,14 +541,14 @@ TEST_F(LeImplTest, enhanced_connection_complete_with_periperal_role) { controller_->AddSupported(OpCode::LE_EXTENDED_CREATE_CONNECTION); // Create connection - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); le_impl_->create_le_connection( {{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS}, true, false); hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); - hci_layer_->CommandCompleteCallback(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); hci_layer_->GetCommand(OpCode::LE_EXTENDED_CREATE_CONNECTION); - hci_layer_->CommandStatusCallback(LeExtendedCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + hci_layer_->IncomingEvent( + LeExtendedCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); sync_handler(); // Check state is ARMED @@ -766,13 +584,12 @@ TEST_F(LeImplTest, connection_complete_with_central_role) { Address::FromString("D0:05:04:03:02:01", remote_address); hci::AddressWithType address_with_type(remote_address, hci::AddressType::PUBLIC_DEVICE_ADDRESS); // Create connection - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); le_impl_->create_le_connection(address_with_type, true, false); hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); - hci_layer_->CommandCompleteCallback(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - hci_layer_->CommandStatusCallback(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); sync_handler(); // Check state is ARMED @@ -804,13 +621,13 @@ TEST_F(LeImplTest, enhanced_connection_complete_with_central_role) { Address::FromString("D0:05:04:03:02:01", remote_address); hci::AddressWithType address_with_type(remote_address, hci::AddressType::PUBLIC_DEVICE_ADDRESS); // Create connection - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); le_impl_->create_le_connection(address_with_type, true, false); hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); - hci_layer_->CommandCompleteCallback(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); hci_layer_->GetCommand(OpCode::LE_EXTENDED_CREATE_CONNECTION); - hci_layer_->CommandStatusCallback(LeExtendedCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + hci_layer_->IncomingEvent( + LeExtendedCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); sync_handler(); // Check state is ARMED @@ -1099,7 +916,7 @@ TEST_F(LeImplTest, DISABLED_add_device_to_resolving_list) { // Let LeAddressManager::resume_registered_clients execute sync_handler(); - ASSERT_EQ(0UL, hci_layer_->NumberOfQueuedCommands()); + hci_layer_->AssertNoQueuedCommand(); // le_impl should not be registered with address manager ASSERT_FALSE(le_impl_->address_manager_registered); @@ -1118,10 +935,10 @@ TEST_F(LeImplTest, DISABLED_add_device_to_resolving_list) { le_impl_->le_address_manager_->AckPause(le_impl_); sync_handler(); // Allow |LeAddressManager::ack_pause| to complete - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); { // Inform controller to disable address resolution - auto command = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto command = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(Enable::DISABLED, command.GetAddressResolutionEnable()); le_impl_->le_address_manager_->OnCommandComplete( @@ -1129,9 +946,9 @@ TEST_F(LeImplTest, DISABLED_add_device_to_resolving_list) { } sync_handler(); // |LeAddressManager::check_cached_commands| - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); { - auto command = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto command = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, command.GetPeerIdentityAddressType()); ASSERT_EQ(remote_public_address_with_type_.GetAddress(), command.GetPeerIdentityAddress()); @@ -1142,9 +959,9 @@ TEST_F(LeImplTest, DISABLED_add_device_to_resolving_list) { } sync_handler(); // |LeAddressManager::check_cached_commands| - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); { - auto command = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto command = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(Enable::ENABLED, command.GetAddressResolutionEnable()); le_impl_->le_address_manager_->OnCommandComplete( @@ -1152,7 +969,7 @@ TEST_F(LeImplTest, DISABLED_add_device_to_resolving_list) { } sync_handler(); // |LeAddressManager::check_cached_commands| - ASSERT_TRUE(hci_layer_->IsPacketQueueEmpty()); + hci_layer_->AssertNoQueuedCommand(); ASSERT_TRUE(le_impl_->address_manager_registered); le_impl_->ready_to_unregister = true; @@ -1171,7 +988,7 @@ TEST_F(LeImplTest, add_device_to_resolving_list__SupportsBlePrivacy) { // Let LeAddressManager::resume_registered_clients execute sync_handler(); - ASSERT_EQ(0UL, hci_layer_->NumberOfQueuedCommands()); + hci_layer_->AssertNoQueuedCommand(); // le_impl should not be registered with address manager ASSERT_FALSE(le_impl_->address_manager_registered); @@ -1190,10 +1007,10 @@ TEST_F(LeImplTest, add_device_to_resolving_list__SupportsBlePrivacy) { le_impl_->le_address_manager_->AckPause(le_impl_); sync_handler(); // Allow |LeAddressManager::ack_pause| to complete - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); { // Inform controller to disable address resolution - auto command = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto command = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(Enable::DISABLED, command.GetAddressResolutionEnable()); le_impl_->le_address_manager_->OnCommandComplete( @@ -1201,9 +1018,9 @@ TEST_F(LeImplTest, add_device_to_resolving_list__SupportsBlePrivacy) { } sync_handler(); // |LeAddressManager::check_cached_commands| - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); { - auto command = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto command = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, command.GetPeerIdentityAddressType()); ASSERT_EQ(remote_public_address_with_type_.GetAddress(), command.GetPeerIdentityAddress()); @@ -1214,9 +1031,8 @@ TEST_F(LeImplTest, add_device_to_resolving_list__SupportsBlePrivacy) { } sync_handler(); // |LeAddressManager::check_cached_commands| - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); { - auto command = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto command = CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(PrivacyMode::DEVICE, command.GetPrivacyMode()); ASSERT_EQ(remote_public_address_with_type_.GetAddress(), command.GetPeerIdentityAddress()); @@ -1226,9 +1042,9 @@ TEST_F(LeImplTest, add_device_to_resolving_list__SupportsBlePrivacy) { } sync_handler(); // |LeAddressManager::check_cached_commands| - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); { - auto command = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto command = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(Enable::ENABLED, command.GetAddressResolutionEnable()); le_impl_->le_address_manager_->OnCommandComplete( @@ -1236,7 +1052,6 @@ TEST_F(LeImplTest, add_device_to_resolving_list__SupportsBlePrivacy) { } sync_handler(); // |LeAddressManager::check_cached_commands| - ASSERT_TRUE(hci_layer_->IsPacketQueueEmpty()); ASSERT_TRUE(le_impl_->address_manager_registered); le_impl_->ready_to_unregister = true; @@ -1416,10 +1231,8 @@ TEST_F(LeImplWithConnectionTest, on_le_event__REMOTE_CONNECTION_PARAMETER_REQUES sync_handler(); - ASSERT_FALSE(hci_layer_->IsPacketQueueEmpty()); - auto view = CreateLeConnectionManagementCommandView( - hci_layer_->DequeueCommandBytes()); + hci_layer_->GetCommand()); ASSERT_TRUE(view.IsValid()); ASSERT_EQ(kIntervalMin, view.GetIntervalMin()); @@ -1436,9 +1249,9 @@ TEST_F(LeImplRegisteredWithAddressManagerTest, DISABLED_clear_resolving_list) { sync_handler(); // Allow |LeAddressManager::pause_registered_clients| to complete sync_handler(); // Allow |LeAddressManager::handle_next_command| to complete - ASSERT_EQ(1UL, hci_layer_->NumberOfQueuedCommands()); { - auto view = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto view = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(view.IsValid()); ASSERT_EQ(Enable::DISABLED, view.GetAddressResolutionEnable()); le_impl_->le_address_manager_->OnCommandComplete( @@ -1446,24 +1259,23 @@ TEST_F(LeImplRegisteredWithAddressManagerTest, DISABLED_clear_resolving_list) { } sync_handler(); // Allow |LeAddressManager::check_cached_commands| to complete - ASSERT_EQ(1UL, hci_layer_->NumberOfQueuedCommands()); { - auto view = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto view = CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(view.IsValid()); le_impl_->le_address_manager_->OnCommandComplete( ReturnCommandComplete(OpCode::LE_CLEAR_RESOLVING_LIST, ErrorCode::SUCCESS)); } sync_handler(); // Allow |LeAddressManager::handle_next_command| to complete - ASSERT_EQ(1UL, hci_layer_->NumberOfQueuedCommands()); { - auto view = CreateLeSecurityCommandView(hci_layer_->DequeueCommandBytes()); + auto view = + CreateLeSecurityCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(view.IsValid()); ASSERT_EQ(Enable::ENABLED, view.GetAddressResolutionEnable()); le_impl_->le_address_manager_->OnCommandComplete( ReturnCommandComplete(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE, ErrorCode::SUCCESS)); } - ASSERT_TRUE(hci_layer_->IsPacketQueueEmpty()); + hci_layer_->AssertNoQueuedCommand(); } TEST_F(LeImplRegisteredWithAddressManagerTest, ignore_on_pause_on_resume_after_unregistered) { @@ -1528,8 +1340,8 @@ TEST_F(LeImplTest, cancel_connect) { TEST_F(LeImplTest, set_le_suggested_default_data_parameters) { le_impl_->set_le_suggested_default_data_parameters(kLength, kTime); sync_handler(); - auto view = - CreateLeConnectionManagementCommandView(hci_layer_->DequeueCommandBytes()); + auto view = CreateLeConnectionManagementCommandView( + hci_layer_->GetCommand()); ASSERT_TRUE(view.IsValid()); ASSERT_EQ(kLength, view.GetTxOctets()); ASSERT_EQ(kTime, view.GetTxTime()); @@ -1539,7 +1351,7 @@ TEST_F(LeImplTest, LeSetDefaultSubrate) { le_impl_->LeSetDefaultSubrate( kIntervalMin, kIntervalMax, kLatency, kContinuationNumber, kTimeout); sync_handler(); - auto view = CreateAclCommandView(hci_layer_->DequeueCommandBytes()); + auto view = CreateAclCommandView(hci_layer_->GetCommand()); ASSERT_TRUE(view.IsValid()); ASSERT_EQ(kIntervalMin, view.GetSubrateMin()); ASSERT_EQ(kIntervalMax, view.GetSubrateMax()); @@ -1828,24 +1640,19 @@ TEST_F(LeImplTest, direct_connection_after_background_connection) { {0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, AddressType::PUBLIC_DEVICE_ADDRESS); // arrange: Create background connection - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); le_impl_->create_le_connection(address, true, /* is_direct */ false); hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); - hci_layer_->CommandCompleteCallback( + hci_layer_->IncomingEvent( LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); auto raw_bg_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); - hci_layer_->CommandStatusCallback( - LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + hci_layer_->IncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); sync_handler(); // act: Create direct connection - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); le_impl_->create_le_connection(address, true, /* is_direct */ true); - auto cancel_connection = hci_layer_->GetCommandOptional(OpCode::LE_CREATE_CONNECTION_CANCEL); - if (cancel_connection) { - ASSERT_NO_FATAL_FAILURE(hci_layer_->SetCommandFuture()); - hci_layer_->CommandCompleteCallback( + auto cancel_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL); + if (cancel_connection.IsValid()) { + hci_layer_->IncomingEvent( LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); hci_layer_->IncomingLeMetaEvent(LeConnectionCompleteBuilder::Create( ErrorCode::UNKNOWN_CONNECTION, @@ -1858,16 +1665,15 @@ TEST_F(LeImplTest, direct_connection_after_background_connection) { 0x0000, ClockAccuracy::PPM_30)); } - auto raw_direct_create_connection = hci_layer_->GetCommandOptional(OpCode::LE_CREATE_CONNECTION); + auto raw_direct_create_connection = hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); // assert - ASSERT_TRUE(raw_direct_create_connection.has_value()); auto bg_create_connection = LeCreateConnectionView::Create( LeConnectionManagementCommandView::Create(AclCommandView::Create(raw_bg_create_connection))); EXPECT_TRUE(bg_create_connection.IsValid()); auto direct_create_connection = LeCreateConnectionView::Create(LeConnectionManagementCommandView::Create( - AclCommandView::Create(*raw_direct_create_connection))); + AclCommandView::Create(raw_direct_create_connection))); EXPECT_TRUE(direct_create_connection.IsValid()); LOG_INFO("Scan Interval %u", direct_create_connection.GetLeScanInterval()); ASSERT_NE(direct_create_connection.GetLeScanInterval(), bg_create_connection.GetLeScanInterval()); diff --git a/system/gd/hci/acl_manager/round_robin_scheduler.h b/system/gd/hci/acl_manager/round_robin_scheduler.h index 7d287bfb47ab3aefc6cb4586a4ede66597d22fa0..18a8ad81a4094809681789ad4ef804552c4e930e 100644 --- a/system/gd/hci/acl_manager/round_robin_scheduler.h +++ b/system/gd/hci/acl_manager/round_robin_scheduler.h @@ -20,7 +20,7 @@ #include "common/bidi_queue.h" #include "common/multi_priority_queue.h" -#include "hci/acl_manager.h" +#include "hci/acl_manager/acl_connection.h" #include "hci/controller.h" #include "hci/hci_packets.h" #include "os/handler.h" @@ -78,4 +78,4 @@ class RoundRobinScheduler { } // namespace acl_manager } // namespace hci -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/gd/hci/acl_manager/round_robin_scheduler_test.cc b/system/gd/hci/acl_manager/round_robin_scheduler_test.cc index aa01a175c3efed492698ba7b1c19c8a41be64f48..034f86bd32963d131692c336bc29196a4ce36c67 100644 --- a/system/gd/hci/acl_manager/round_robin_scheduler_test.cc +++ b/system/gd/hci/acl_manager/round_robin_scheduler_test.cc @@ -20,7 +20,6 @@ #include "common/bidi_queue.h" #include "common/callback.h" -#include "hci/acl_manager.h" #include "hci/controller.h" #include "hci/hci_packets.h" #include "os/handler.h" diff --git a/system/gd/hci/acl_manager_mock.h b/system/gd/hci/acl_manager_mock.h index cf90df7e6b5f2555746bdb97afd5e9ebf6260b14..d19a9156fd998a61dc2706027c95ea5d61a5952d 100644 --- a/system/gd/hci/acl_manager_mock.h +++ b/system/gd/hci/acl_manager_mock.h @@ -82,10 +82,6 @@ class MockAclManager : public AclManager { std::chrono::milliseconds minimum_rotation_time, std::chrono::milliseconds maximum_rotation_time), (override)); - - // PRIVATE TO SHIM - MOCK_METHOD( - void, HACK_SetNonAclDisconnectCallback, (std::function)); }; } // namespace testing diff --git a/system/gd/hci/acl_manager_test.cc b/system/gd/hci/acl_manager_test.cc index 9cb0643834f935a88374976ed3f0482d038ee9a0..45b43c0c3d7555023c64322dcf70aa879101ac63 100644 --- a/system/gd/hci/acl_manager_test.cc +++ b/system/gd/hci/acl_manager_test.cc @@ -19,10 +19,8 @@ #include #include -#include #include #include -#include #include "common/bind.h" #include "hci/acl_manager/connection_callbacks_mock.h" @@ -112,7 +110,7 @@ class TestController : public testing::MockController { class AclManagerNoCallbacksTest : public ::testing::Test { protected: void SetUp() override { - test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry + test_hci_layer_ = new HciLayerFake; // Ownership is transferred to registry test_controller_ = new TestController; // Ownership is transferred to registry EXPECT_CALL(*test_controller_, GetMacAddress()); @@ -172,14 +170,14 @@ class AclManagerNoCallbacksTest : public ::testing::Test { } TestModuleRegistry fake_registry_; - TestHciLayer* test_hci_layer_ = nullptr; + HciLayerFake* test_hci_layer_ = nullptr; TestController* test_controller_ = nullptr; os::Thread& thread_ = fake_registry_.GetTestThread(); AclManager* acl_manager_ = nullptr; os::Handler* client_handler_ = nullptr; Address remote; AddressWithType my_initiating_address; - const bool use_connect_list_ = true; // gd currently only supports connect list + const bool use_accept_list_ = true; // gd currently only supports connect list std::future GetConnectionFuture() { ASSERT_LOG(connection_promise_ == nullptr, "Promises promises ... Only one at a time"); @@ -366,7 +364,7 @@ class AclManagerWithLeConnectionTest : public AclManagerTest { LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT_TRUE(command_view.IsValid()); - if (use_connect_list_) { + if (use_accept_list_) { ASSERT_EQ(command_view.GetPeerAddress(), empty_address_with_type.GetAddress()); ASSERT_EQ(command_view.GetPeerAddressType(), empty_address_with_type.GetAddressType()); } else { @@ -457,7 +455,7 @@ TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_fail) { LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT_TRUE(command_view.IsValid()); - if (use_connect_list_) { + if (use_accept_list_) { ASSERT_EQ(command_view.GetPeerAddress(), hci::Address::kEmpty); } else { ASSERT_EQ(command_view.GetPeerAddress(), remote); @@ -1170,7 +1168,7 @@ TEST_F(AclManagerWithConnectionTest, send_read_clock) { class AclManagerWithResolvableAddressTest : public AclManagerNoCallbacksTest { protected: void SetUp() override { - test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry + test_hci_layer_ = new HciLayerFake; // Ownership is transferred to registry test_controller_ = new TestController; fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_); fake_registry_.InjectTestModule(&Controller::Factory, test_controller_); @@ -1291,7 +1289,7 @@ TEST_F(AclManagerLifeCycleTest, unregister_le_before_connection_complete) { LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT_TRUE(command_view.IsValid()); - if (use_connect_list_) { + if (use_accept_list_) { ASSERT_EQ(command_view.GetPeerAddress(), hci::Address::kEmpty); } else { ASSERT_EQ(command_view.GetPeerAddress(), remote); @@ -1332,7 +1330,7 @@ TEST_F(AclManagerLifeCycleTest, unregister_le_before_enhanced_connection_complet LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT_TRUE(command_view.IsValid()); - if (use_connect_list_) { + if (use_accept_list_) { ASSERT_EQ(command_view.GetPeerAddress(), hci::Address::kEmpty); } else { ASSERT_EQ(command_view.GetPeerAddress(), remote); @@ -1364,30 +1362,6 @@ TEST_F(AclManagerLifeCycleTest, unregister_le_before_enhanced_connection_complet ASSERT_NE(connection_future_status, std::future_status::ready); } -TEST_F(AclManagerWithConnectionTest, remote_sco_connect_request) { - ClassOfDevice class_of_device; - - EXPECT_CALL(mock_connection_callback_, HACK_OnScoConnectRequest(remote, class_of_device)); - - test_hci_layer_->IncomingEvent( - ConnectionRequestBuilder::Create(remote, class_of_device, ConnectionRequestLinkType::SCO)); - fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20)); - fake_registry_.SynchronizeModuleHandler(&AclManager::Factory, std::chrono::milliseconds(20)); - fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20)); -} - -TEST_F(AclManagerWithConnectionTest, remote_esco_connect_request) { - ClassOfDevice class_of_device; - - EXPECT_CALL(mock_connection_callback_, HACK_OnEscoConnectRequest(remote, class_of_device)); - - test_hci_layer_->IncomingEvent( - ConnectionRequestBuilder::Create(remote, class_of_device, ConnectionRequestLinkType::ESCO)); - fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20)); - fake_registry_.SynchronizeModuleHandler(&AclManager::Factory, std::chrono::milliseconds(20)); - fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20)); -} - class AclManagerWithConnectionAssemblerTest : public AclManagerWithConnectionTest { protected: void SetUp() override { diff --git a/system/gd/hci/acl_manager_unittest.cc b/system/gd/hci/acl_manager_unittest.cc index f1273631b7644a3452bd3a932106b7f032c43eda..d953128482fb54d71d060a7c30c52d6339215f22 100644 --- a/system/gd/hci/acl_manager_unittest.cc +++ b/system/gd/hci/acl_manager_unittest.cc @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include "hci/class_of_device.h" #include "hci/controller.h" #include "hci/hci_layer.h" +#include "hci/hci_layer_fake.h" #include "os/thread.h" #include "packet/raw_builder.h" @@ -71,14 +71,6 @@ struct { }; } // namespace -PacketView GetPacketView(std::unique_ptr packet) { - auto bytes = std::make_shared>(); - BitInserter i(*bytes); - bytes->reserve(packet->size()); - packet->Serialize(i); - return packet::PacketView(bytes); -} - std::unique_ptr NextPayload(uint16_t handle) { static uint32_t packet_number = 1; auto payload = std::make_unique(); @@ -89,12 +81,6 @@ std::unique_ptr NextPayload(uint16_t handle) { return std::move(payload); } -std::unique_ptr NextAclPacket(uint16_t handle) { - PacketBoundaryFlag packet_boundary_flag = PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE; - BroadcastFlag broadcast_flag = BroadcastFlag::POINT_TO_POINT; - return AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, NextPayload(handle)); -} - class TestController : public Controller { public: uint16_t GetAclPacketLength() const override { @@ -127,219 +113,6 @@ class TestController : public Controller { common::ContextualCallback acl_cb_; }; -class TestHciLayer : public HciLayer { - public: - void EnqueueCommand( - std::unique_ptr command, - common::ContextualOnceCallback on_status) override { - command_queue_.push(std::move(command)); - command_status_callbacks.push_back(std::move(on_status)); - Notify(); - } - - void EnqueueCommand( - std::unique_ptr command, - common::ContextualOnceCallback on_complete) override { - command_queue_.push(std::move(command)); - command_complete_callbacks.push_back(std::move(on_complete)); - Notify(); - } - - void SetCommandFuture() { - ASSERT_EQ(hci_command_promise_, nullptr) << "Promises, Promises, ... Only one at a time."; - hci_command_promise_ = std::make_unique>(); - command_future_ = std::make_unique>(hci_command_promise_->get_future()); - } - - std::future GetOutgoingCommandFuture() { - hci_command_promise_ = std::make_unique>(); - return hci_command_promise_->get_future(); - } - - CommandView GetLastCommand() { - if (command_queue_.size() == 0) { - return CommandView::Create(PacketView(std::make_shared>())); - } - auto last = std::move(command_queue_.front()); - command_queue_.pop(); - return CommandView::Create(GetPacketView(std::move(last))); - } - - ConnectionManagementCommandView GetCommand(OpCode /* op_code */) { - if (command_future_ != nullptr) { - command_future_->wait_for(std::chrono::milliseconds(1000)); - } - if (command_queue_.empty()) { - return ConnectionManagementCommandView::Create(AclCommandView::Create( - CommandView::Create(PacketView(std::make_shared>())))); - } - CommandView command_packet_view = GetLastCommand(); - ConnectionManagementCommandView command = - ConnectionManagementCommandView::Create(AclCommandView::Create(command_packet_view)); - - return command; - } - - ConnectionManagementCommandView GetLastCommand(OpCode /* op_code */) { - if (!command_queue_.empty() && command_future_ != nullptr) { - command_future_.reset(); - hci_command_promise_.reset(); - } else if (command_future_ != nullptr) { - command_future_->wait_for(std::chrono::milliseconds(1000)); - hci_command_promise_.reset(); - } - if (command_queue_.empty()) { - return ConnectionManagementCommandView::Create(AclCommandView::Create( - CommandView::Create(PacketView(std::make_shared>())))); - } - CommandView command_packet_view = GetLastCommand(); - ConnectionManagementCommandView command = - ConnectionManagementCommandView::Create(AclCommandView::Create(command_packet_view)); - - return command; - } - - ConnectionManagementCommandView GetLastOutgoingCommand() { - if (command_queue_.empty()) { - // An empty packet will force a failure on |IsValid()| required by all packets before usage - return ConnectionManagementCommandView::Create(AclCommandView::Create( - CommandView::Create(PacketView(std::make_shared>())))); - } else { - CommandView command_packet_view = GetLastCommand(); - ConnectionManagementCommandView command = - ConnectionManagementCommandView::Create(AclCommandView::Create(command_packet_view)); - return command; - } - } - - void RegisterEventHandler(EventCode event_code, common::ContextualCallback event_handler) override { - registered_events_[event_code] = event_handler; - } - - void UnregisterEventHandler(EventCode event_code) override { - registered_events_.erase(event_code); - } - - void RegisterLeEventHandler( - SubeventCode subevent_code, common::ContextualCallback event_handler) override { - registered_le_events_[subevent_code] = event_handler; - } - - void UnregisterLeEventHandler(SubeventCode subevent_code) override { - registered_le_events_.erase(subevent_code); - } - - void SendIncomingEvent(std::unique_ptr event_builder) { - auto packet = GetPacketView(std::move(event_builder)); - EventView event = EventView::Create(packet); - ASSERT_TRUE(event.IsValid()); - EventCode event_code = event.GetEventCode(); - ASSERT_NE(registered_events_.find(event_code), registered_events_.end()) << EventCodeText(event_code); - registered_events_[event_code].Invoke(event); - } - - void IncomingLeMetaEvent(std::unique_ptr event_builder) { - auto packet = GetPacketView(std::move(event_builder)); - EventView event = EventView::Create(packet); - LeMetaEventView meta_event_view = LeMetaEventView::Create(event); - ASSERT_TRUE(meta_event_view.IsValid()); - SubeventCode subevent_code = meta_event_view.GetSubeventCode(); - ASSERT_TRUE(registered_le_events_.find(subevent_code) != registered_le_events_.end()); - registered_le_events_[subevent_code].Invoke(meta_event_view); - } - - void IncomingAclData(uint16_t handle) { - os::Handler* hci_handler = GetHandler(); - auto* queue_end = acl_queue_.GetDownEnd(); - std::promise promise; - auto future = promise.get_future(); - queue_end->RegisterEnqueue( - hci_handler, - common::Bind( - [](decltype(queue_end) queue_end, uint16_t handle, std::promise promise) { - auto packet = GetPacketView(NextAclPacket(handle)); - AclView acl2 = AclView::Create(packet); - queue_end->UnregisterEnqueue(); - promise.set_value(); - return std::make_unique(acl2); - }, - queue_end, - handle, - common::Passed(std::move(promise)))); - auto status = future.wait_for(2s); - ASSERT_EQ(status, std::future_status::ready); - } - - void AssertNoOutgoingAclData() { - auto queue_end = acl_queue_.GetDownEnd(); - ASSERT_EQ(queue_end->TryDequeue(), nullptr); - } - - void CommandCompleteCallback(EventView event) { - CommandCompleteView complete_view = CommandCompleteView::Create(event); - ASSERT_TRUE(complete_view.IsValid()); - std::move(command_complete_callbacks.front()).Invoke(complete_view); - command_complete_callbacks.pop_front(); - } - - void CommandStatusCallback(EventView event) { - CommandStatusView status_view = CommandStatusView::Create(event); - ASSERT_TRUE(status_view.IsValid()); - std::move(command_status_callbacks.front()).Invoke(status_view); - command_status_callbacks.pop_front(); - } - - PacketView OutgoingAclData() { - auto queue_end = acl_queue_.GetDownEnd(); - std::unique_ptr received; - do { - received = queue_end->TryDequeue(); - } while (received == nullptr); - - return GetPacketView(std::move(received)); - } - - BidiQueueEnd* GetAclQueueEnd() override { - return acl_queue_.GetUpEnd(); - } - - void ListDependencies(ModuleList* /* list */) const {} - void Start() override { - RegisterEventHandler( - EventCode::COMMAND_COMPLETE, GetHandler()->BindOn(this, &TestHciLayer::CommandCompleteCallback)); - RegisterEventHandler(EventCode::COMMAND_STATUS, GetHandler()->BindOn(this, &TestHciLayer::CommandStatusCallback)); - } - void Stop() override {} - - void Disconnect(uint16_t handle, ErrorCode reason) override { - GetHandler()->Post(common::BindOnce(&TestHciLayer::do_disconnect, common::Unretained(this), handle, reason)); - } - - std::unique_ptr> hci_command_promise_; - - private: - void Notify() { - if (hci_command_promise_ != nullptr) { - std::promise* prom = hci_command_promise_.release(); - prom->set_value(); - delete prom; - } - } - - std::map> registered_events_; - std::map> registered_le_events_; - std::list> command_complete_callbacks; - std::list> command_status_callbacks; - BidiQueue acl_queue_{3 /* TODO: Set queue depth */}; - - std::queue> command_queue_; - std::unique_ptr> command_future_; - - void do_disconnect(uint16_t handle, ErrorCode reason) { - HciLayer::Disconnect(handle, reason); - } -}; - class MockConnectionCallback : public ConnectionCallbacks { public: void OnConnectSuccess(std::unique_ptr connection) override { @@ -353,9 +126,6 @@ class MockConnectionCallback : public ConnectionCallbacks { MOCK_METHOD(void, OnConnectRequest, (Address, ClassOfDevice), (override)); MOCK_METHOD(void, OnConnectFail, (Address, ErrorCode reason, bool locally_initiated), (override)); - MOCK_METHOD(void, HACK_OnEscoConnectRequest, (Address, ClassOfDevice), (override)); - MOCK_METHOD(void, HACK_OnScoConnectRequest, (Address, ClassOfDevice), (override)); - size_t NumberOfConnections() const { return connections_.size(); } @@ -391,15 +161,13 @@ class AclManagerBaseTest : public ::testing::Test { protected: void SetUp() override { common::InitFlags::SetAllForTesting(); - test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry - ASSERT_TRUE(test_hci_layer_->hci_command_promise_ == nullptr) << "hci command is nullptr"; + test_hci_layer_ = new HciLayerFake; // Ownership is transferred to registry test_controller_ = new TestController; fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_); fake_registry_.InjectTestModule(&Controller::Factory, test_controller_); client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory); ASSERT_NE(client_handler_, nullptr); fake_registry_.Start(&thread_); - ASSERT_TRUE(test_hci_layer_->hci_command_promise_ == nullptr) << "hci command is nullptr"; } void TearDown() override { @@ -415,7 +183,7 @@ class AclManagerBaseTest : public ::testing::Test { ASSERT_EQ(future_status, std::future_status::ready); } - TestHciLayer* test_hci_layer_ = nullptr; + HciLayerFake* test_hci_layer_ = nullptr; TestController* test_controller_ = nullptr; TestModuleRegistry fake_registry_; @@ -428,26 +196,19 @@ class AclManagerNoCallbacksTest : public AclManagerBaseTest { protected: void SetUp() override { AclManagerBaseTest::SetUp(); - ASSERT_TRUE(test_hci_layer_->hci_command_promise_ == nullptr) << "hci command is nullptr"; acl_manager_ = static_cast(fake_registry_.GetModuleUnderTest(&AclManager::Factory)); local_address_with_type_ = AddressWithType( Address::FromString(kLocalRandomAddressString).value(), hci::AddressType::RANDOM_DEVICE_ADDRESS); - ASSERT_TRUE(test_hci_layer_->hci_command_promise_ == nullptr) << "hci command is nullptr"; - auto future = test_hci_layer_->GetOutgoingCommandFuture(); - acl_manager_->SetPrivacyPolicyForInitiatorAddress( LeAddressManager::AddressPolicy::USE_STATIC_ADDRESS, local_address_with_type_, kMinimumRotationTime, kMaximumRotationTime); - ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); - sync_client_handler(); - ASSERT_TRUE(test_hci_layer_->hci_command_promise_ == nullptr) << "hci command is nullptr"; - auto command = test_hci_layer_->GetLastOutgoingCommand(); + auto command = test_hci_layer_->GetCommand(); ASSERT_TRUE(command.IsValid()); ASSERT_EQ(OpCode::LE_SET_RANDOM_ADDRESS, command.GetOpCode()); } @@ -457,7 +218,7 @@ class AclManagerNoCallbacksTest : public AclManagerBaseTest { } AddressWithType local_address_with_type_; - const bool use_connect_list_ = true; // gd currently only supports connect list + const bool use_accept_list_ = true; // gd currently only supports connect list void SendAclData(uint16_t handle, AclConnection::QueueUpEnd* queue_end) { std::promise promise; @@ -484,7 +245,6 @@ class AclManagerWithCallbacksTest : public AclManagerNoCallbacksTest { AclManagerNoCallbacksTest::SetUp(); acl_manager_->RegisterCallbacks(&mock_connection_callbacks_, client_handler_); acl_manager_->RegisterLeCallbacks(&mock_le_connection_callbacks_, client_handler_); - ASSERT_TRUE(test_hci_layer_->hci_command_promise_ == nullptr) << "hci command is nullptr"; } void TearDown() override { @@ -554,15 +314,12 @@ class AclManagerWithConnectionTest : public AclManagerWithCallbacksTest { // Wait for the connection request auto last_command = test_hci_layer_->GetCommand(OpCode::CREATE_CONNECTION); - while (!last_command.IsValid()) { - last_command = test_hci_layer_->GetCommand(OpCode::CREATE_CONNECTION); - } EXPECT_CALL(mock_connection_management_callbacks_, OnRoleChange(hci::ErrorCode::SUCCESS, Role::CENTRAL)); auto first_connection = GetConnectionFuture(); - test_hci_layer_->SendIncomingEvent( - ConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, handle_, remote, LinkType::ACL, Enable::DISABLED)); + test_hci_layer_->IncomingEvent(ConnectionCompleteBuilder::Create( + ErrorCode::SUCCESS, handle_, remote, LinkType::ACL, Enable::DISABLED)); auto first_connection_status = first_connection.wait_for(2s); ASSERT_EQ(first_connection_status, std::future_status::ready); @@ -646,17 +403,16 @@ class AclManagerWithLeConnectionTest : public AclManagerWithCallbacksTest { Address remote_public_address = Address::FromString(kRemotePublicDeviceStringA).value(); remote_with_type_ = AddressWithType(remote_public_address, AddressType::PUBLIC_DEVICE_ADDRESS); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); acl_manager_->CreateLeConnection(remote_with_type_, true); test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - test_hci_layer_->SendIncomingEvent(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); + test_hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); auto packet = test_hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION); auto le_connection_management_command_view = LeConnectionManagementCommandView::Create(AclCommandView::Create(packet)); auto command_view = LeCreateConnectionView::Create(le_connection_management_command_view); ASSERT_TRUE(command_view.IsValid()); - if (use_connect_list_) { + if (use_accept_list_) { ASSERT_EQ(command_view.GetPeerAddress(), empty_address_with_type.GetAddress()); ASSERT_EQ(command_view.GetPeerAddressType(), empty_address_with_type.GetAddressType()); } else { @@ -664,7 +420,8 @@ class AclManagerWithLeConnectionTest : public AclManagerWithCallbacksTest { ASSERT_EQ(command_view.GetPeerAddressType(), AddressType::PUBLIC_DEVICE_ADDRESS); } - test_hci_layer_->SendIncomingEvent(LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); + test_hci_layer_->IncomingEvent( + LeCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01)); auto first_connection = GetLeConnectionFuture(); @@ -679,9 +436,8 @@ class AclManagerWithLeConnectionTest : public AclManagerWithCallbacksTest { 0x0C80, ClockAccuracy::PPM_30)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); test_hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST); - test_hci_layer_->SendIncomingEvent( + test_hci_layer_->IncomingEvent( LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); auto first_connection_status = first_connection.wait_for(2s); @@ -738,13 +494,12 @@ class AclManagerWithLeConnectionTest : public AclManagerWithCallbacksTest { class AclManagerWithResolvableAddressTest : public AclManagerWithCallbacksTest { protected: void SetUp() override { - test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry + test_hci_layer_ = new HciLayerFake; // Ownership is transferred to registry test_controller_ = new TestController; fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_); fake_registry_.InjectTestModule(&Controller::Factory, test_controller_); client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory); ASSERT_NE(client_handler_, nullptr); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); fake_registry_.Start(&thread_); acl_manager_ = static_cast(fake_registry_.GetModuleUnderTest(&AclManager::Factory)); hci::Address address; @@ -760,8 +515,9 @@ class AclManagerWithResolvableAddressTest : public AclManagerWithCallbacksTest { minimum_rotation_time, maximum_rotation_time); - test_hci_layer_->GetLastCommand(OpCode::LE_SET_RANDOM_ADDRESS); - test_hci_layer_->SendIncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + test_hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); + test_hci_layer_->IncomingEvent( + LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } }; @@ -779,16 +535,14 @@ TEST_F(AclManagerNoCallbacksTest, unregister_classic_before_connection_request) future.get(); // Inject peer sending connection request - test_hci_layer_->SendIncomingEvent(ConnectionRequestBuilder::Create( + test_hci_layer_->IncomingEvent(ConnectionRequestBuilder::Create( local_address_with_type_.GetAddress(), class_of_device, ConnectionRequestLinkType::ACL)); sync_client_handler(); // There should be no connections ASSERT_EQ(0UL, mock_connection_callbacks_.NumberOfConnections()); - auto command = test_hci_layer_->GetLastOutgoingCommand(); - ASSERT_TRUE(command.IsValid()); - ASSERT_EQ(OpCode::REJECT_CONNECTION_REQUEST, command.GetOpCode()); + auto command = test_hci_layer_->GetCommand(OpCode::REJECT_CONNECTION_REQUEST); } TEST_F(AclManagerWithCallbacksTest, two_remote_connection_requests_ABAB) { @@ -797,28 +551,24 @@ TEST_F(AclManagerWithCallbacksTest, two_remote_connection_requests_ABAB) { { // Device A sends connection request - auto future = test_hci_layer_->GetOutgoingCommandFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionRequestBuilder::Create( - remote_device[0].address, remote_device[0].class_of_device, ConnectionRequestLinkType::ACL)); + test_hci_layer_->IncomingEvent(ConnectionRequestBuilder::Create( + remote_device[0].address, + remote_device[0].class_of_device, + ConnectionRequestLinkType::ACL)); sync_client_handler(); // Verify we accept this connection - ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); - auto command = test_hci_layer_->GetLastOutgoingCommand(); - ASSERT_TRUE(command.IsValid()); - ASSERT_EQ(OpCode::ACCEPT_CONNECTION_REQUEST, command.GetOpCode()); + auto command = test_hci_layer_->GetCommand(OpCode::ACCEPT_CONNECTION_REQUEST); } { // Device B sends connection request - auto future = test_hci_layer_->GetOutgoingCommandFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionRequestBuilder::Create( - remote_device[1].address, remote_device[1].class_of_device, ConnectionRequestLinkType::ACL)); + test_hci_layer_->IncomingEvent(ConnectionRequestBuilder::Create( + remote_device[1].address, + remote_device[1].class_of_device, + ConnectionRequestLinkType::ACL)); sync_client_handler(); // Verify we accept this connection - ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); - auto command = test_hci_layer_->GetLastOutgoingCommand(); - ASSERT_TRUE(command.IsValid()); - ASSERT_EQ(OpCode::ACCEPT_CONNECTION_REQUEST, command.GetOpCode()); + auto command = test_hci_layer_->GetCommand(OpCode::ACCEPT_CONNECTION_REQUEST); } ASSERT_EQ(0UL, NumberOfConnections()); @@ -826,8 +576,12 @@ TEST_F(AclManagerWithCallbacksTest, two_remote_connection_requests_ABAB) { { // Device A completes first connection auto future = GetConnectionFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionCompleteBuilder::Create( - ErrorCode::SUCCESS, remote_device[0].handle, remote_device[0].address, LinkType::ACL, Enable::DISABLED)); + test_hci_layer_->IncomingEvent(ConnectionCompleteBuilder::Create( + ErrorCode::SUCCESS, + remote_device[0].handle, + remote_device[0].address, + LinkType::ACL, + Enable::DISABLED)); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)) << "Timeout waiting for first connection complete"; ASSERT_EQ(1UL, NumberOfConnections()); auto connection = future.get(); @@ -837,8 +591,12 @@ TEST_F(AclManagerWithCallbacksTest, two_remote_connection_requests_ABAB) { { // Device B completes second connection auto future = GetConnectionFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionCompleteBuilder::Create( - ErrorCode::SUCCESS, remote_device[1].handle, remote_device[1].address, LinkType::ACL, Enable::DISABLED)); + test_hci_layer_->IncomingEvent(ConnectionCompleteBuilder::Create( + ErrorCode::SUCCESS, + remote_device[1].handle, + remote_device[1].address, + LinkType::ACL, + Enable::DISABLED)); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)) << "Timeout waiting for second connection complete"; ASSERT_EQ(2UL, NumberOfConnections()); auto connection = future.get(); @@ -852,28 +610,24 @@ TEST_F(AclManagerWithCallbacksTest, two_remote_connection_requests_ABBA) { { // Device A sends connection request - auto future = test_hci_layer_->GetOutgoingCommandFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionRequestBuilder::Create( - remote_device[0].address, remote_device[0].class_of_device, ConnectionRequestLinkType::ACL)); + test_hci_layer_->IncomingEvent(ConnectionRequestBuilder::Create( + remote_device[0].address, + remote_device[0].class_of_device, + ConnectionRequestLinkType::ACL)); sync_client_handler(); // Verify we accept this connection - ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); - auto command = test_hci_layer_->GetLastOutgoingCommand(); - ASSERT_TRUE(command.IsValid()); - ASSERT_EQ(OpCode::ACCEPT_CONNECTION_REQUEST, command.GetOpCode()); + auto command = test_hci_layer_->GetCommand(OpCode::ACCEPT_CONNECTION_REQUEST); } { // Device B sends connection request - auto future = test_hci_layer_->GetOutgoingCommandFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionRequestBuilder::Create( - remote_device[1].address, remote_device[1].class_of_device, ConnectionRequestLinkType::ACL)); + test_hci_layer_->IncomingEvent(ConnectionRequestBuilder::Create( + remote_device[1].address, + remote_device[1].class_of_device, + ConnectionRequestLinkType::ACL)); sync_client_handler(); // Verify we accept this connection - ASSERT_EQ(std::future_status::ready, future.wait_for(2s)); - auto command = test_hci_layer_->GetLastOutgoingCommand(); - ASSERT_TRUE(command.IsValid()); - ASSERT_EQ(OpCode::ACCEPT_CONNECTION_REQUEST, command.GetOpCode()); + auto command = test_hci_layer_->GetCommand(OpCode::ACCEPT_CONNECTION_REQUEST); } ASSERT_EQ(0UL, NumberOfConnections()); @@ -881,8 +635,12 @@ TEST_F(AclManagerWithCallbacksTest, two_remote_connection_requests_ABBA) { { // Device B completes first connection auto future = GetConnectionFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionCompleteBuilder::Create( - ErrorCode::SUCCESS, remote_device[1].handle, remote_device[1].address, LinkType::ACL, Enable::DISABLED)); + test_hci_layer_->IncomingEvent(ConnectionCompleteBuilder::Create( + ErrorCode::SUCCESS, + remote_device[1].handle, + remote_device[1].address, + LinkType::ACL, + Enable::DISABLED)); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)) << "Timeout waiting for first connection complete"; ASSERT_EQ(1UL, NumberOfConnections()); auto connection = future.get(); @@ -892,8 +650,12 @@ TEST_F(AclManagerWithCallbacksTest, two_remote_connection_requests_ABBA) { { // Device A completes second connection auto future = GetConnectionFuture(); - test_hci_layer_->SendIncomingEvent(ConnectionCompleteBuilder::Create( - ErrorCode::SUCCESS, remote_device[0].handle, remote_device[0].address, LinkType::ACL, Enable::DISABLED)); + test_hci_layer_->IncomingEvent(ConnectionCompleteBuilder::Create( + ErrorCode::SUCCESS, + remote_device[0].handle, + remote_device[0].address, + LinkType::ACL, + Enable::DISABLED)); ASSERT_EQ(std::future_status::ready, future.wait_for(2s)) << "Timeout waiting for second connection complete"; ASSERT_EQ(2UL, NumberOfConnections()); auto connection = future.get(); diff --git a/system/gd/hci/controller.cc b/system/gd/hci/controller.cc index 7b78be8aa419b2de2a5133000d994f6722ee6137..6facfef4c3109d51d5d7da2e73aca4c20c012fd7 100644 --- a/system/gd/hci/controller.cc +++ b/system/gd/hci/controller.cc @@ -17,6 +17,8 @@ #include "hci/controller.h" #include +#include + #include #include #include @@ -24,9 +26,11 @@ #include "common/init_flags.h" #include "dumpsys_data_generated.h" +#include "hci/controller_interface.h" #include "hci/event_checkers.h" #include "hci/hci_layer.h" #include "hci_controller_generated.h" +#include "os/log.h" #include "os/metrics.h" #include "os/system_properties.h" #include "sysprops/sysprops_module.h" @@ -108,7 +112,7 @@ struct Controller::impl { hci_->EnqueueCommand( LeReadFilterAcceptListSizeBuilder::Create(), - handler->BindOnceOn(this, &Controller::impl::le_read_connect_list_size_handler)); + handler->BindOnceOn(this, &Controller::impl::le_read_accept_list_size_handler)); if (is_supported(OpCode::LE_READ_RESOLVING_LIST_SIZE) && module_.SupportsBlePrivacy()) { hci_->EnqueueCommand( @@ -199,9 +203,16 @@ struct Controller::impl { // Skip vendor capabilities check if configured. if (os::GetSystemPropertyBool( kPropertyVendorCapabilitiesEnabled, kDefaultVendorCapabilitiesEnabled)) { + // More commands can be enqueued from le_get_vendor_capabilities_handler + std::promise vendor_promise; + auto vendor_future = vendor_promise.get_future(); hci_->EnqueueCommand( LeGetVendorCapabilitiesBuilder::Create(), - handler->BindOnceOn(this, &Controller::impl::le_get_vendor_capabilities_handler)); + handler->BindOnceOn( + this, + &Controller::impl::le_get_vendor_capabilities_handler, + std::move(vendor_promise))); + vendor_future.wait(); } else { vendor_capabilities_.is_supported_ = 0x00; } @@ -487,12 +498,12 @@ struct Controller::impl { le_supported_states_ = complete_view.GetLeStates(); } - void le_read_connect_list_size_handler(CommandCompleteView view) { + void le_read_accept_list_size_handler(CommandCompleteView view) { auto complete_view = LeReadFilterAcceptListSizeCompleteView::Create(view); ASSERT(complete_view.IsValid()); ErrorCode status = complete_view.GetStatus(); ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str()); - le_connect_list_size_ = complete_view.GetFilterAcceptListSize(); + le_accept_list_size_ = complete_view.GetFilterAcceptListSize(); } void le_read_resolving_list_size_handler(CommandCompleteView view) { @@ -543,7 +554,8 @@ struct Controller::impl { le_periodic_advertiser_list_size_ = complete_view.GetPeriodicAdvertiserListSize(); } - void le_get_vendor_capabilities_handler(CommandCompleteView view) { + void le_get_vendor_capabilities_handler( + std::promise vendor_promise, CommandCompleteView view) { auto complete_view = LeGetVendorCapabilitiesCompleteView::Create(view); vendor_capabilities_.is_supported_ = 0x00; @@ -562,61 +574,171 @@ struct Controller::impl { vendor_capabilities_.le_address_generation_offloading_support_ = 0x00; vendor_capabilities_.a2dp_source_offload_capability_mask_ = 0x00; vendor_capabilities_.bluetooth_quality_report_support_ = 0x00; + vendor_capabilities_.a2dp_offload_v2_support_ = 0x00; - if (complete_view.IsValid()) { - vendor_capabilities_.is_supported_ = 0x01; - - // v0.55 - BaseVendorCapabilities base_vendor_capabilities = complete_view.GetBaseVendorCapabilities(); - vendor_capabilities_.max_advt_instances_ = base_vendor_capabilities.max_advt_instances_; - vendor_capabilities_.offloaded_resolution_of_private_address_ = - base_vendor_capabilities.offloaded_resolution_of_private_address_; - vendor_capabilities_.total_scan_results_storage_ = base_vendor_capabilities.total_scan_results_storage_; - vendor_capabilities_.max_irk_list_sz_ = base_vendor_capabilities.max_irk_list_sz_; - vendor_capabilities_.filtering_support_ = base_vendor_capabilities.filtering_support_; - vendor_capabilities_.max_filter_ = base_vendor_capabilities.max_filter_; - vendor_capabilities_.activity_energy_info_support_ = base_vendor_capabilities.activity_energy_info_support_; - if (complete_view.GetPayload().size() == 0) { - vendor_capabilities_.version_supported_ = 55; - return; - } + if (!complete_view.IsValid()) { + vendor_promise.set_value(); + return; + } + vendor_capabilities_.is_supported_ = 0x01; + + // v0.55 + BaseVendorCapabilities base_vendor_capabilities = complete_view.GetBaseVendorCapabilities(); + vendor_capabilities_.max_advt_instances_ = base_vendor_capabilities.max_advt_instances_; + vendor_capabilities_.offloaded_resolution_of_private_address_ = + base_vendor_capabilities.offloaded_resolution_of_private_address_; + vendor_capabilities_.total_scan_results_storage_ = + base_vendor_capabilities.total_scan_results_storage_; + vendor_capabilities_.max_irk_list_sz_ = base_vendor_capabilities.max_irk_list_sz_; + vendor_capabilities_.filtering_support_ = base_vendor_capabilities.filtering_support_; + vendor_capabilities_.max_filter_ = base_vendor_capabilities.max_filter_; + vendor_capabilities_.activity_energy_info_support_ = + base_vendor_capabilities.activity_energy_info_support_; + + if (complete_view.GetPayload().size() == 0) { + vendor_capabilities_.version_supported_ = 55; + vendor_promise.set_value(); + return; + } - // v0.95 - auto v95 = LeGetVendorCapabilitiesComplete095View::Create(complete_view); - if (!v95.IsValid()) { - LOG_ERROR("invalid data for hci requirements v0.95"); - return; - } - vendor_capabilities_.version_supported_ = v95.GetVersionSupported(); - vendor_capabilities_.total_num_of_advt_tracked_ = v95.GetTotalNumOfAdvtTracked(); - vendor_capabilities_.extended_scan_support_ = v95.GetExtendedScanSupport(); - vendor_capabilities_.debug_logging_supported_ = v95.GetDebugLoggingSupported(); - if (vendor_capabilities_.version_supported_ <= 95 || complete_view.GetPayload().size() == 0) { - return; - } + // v0.95 + auto v95 = LeGetVendorCapabilitiesComplete095View::Create(complete_view); + if (!v95.IsValid()) { + LOG_INFO("invalid data for hci requirements v0.95"); + vendor_promise.set_value(); + return; + } + vendor_capabilities_.version_supported_ = v95.GetVersionSupported(); + vendor_capabilities_.total_num_of_advt_tracked_ = v95.GetTotalNumOfAdvtTracked(); + vendor_capabilities_.extended_scan_support_ = v95.GetExtendedScanSupport(); + vendor_capabilities_.debug_logging_supported_ = v95.GetDebugLoggingSupported(); + if (vendor_capabilities_.version_supported_ <= 95 || complete_view.GetPayload().size() == 0) { + vendor_promise.set_value(); + return; + } - // v0.96 - auto v96 = LeGetVendorCapabilitiesComplete096View::Create(v95); - if (!v96.IsValid()) { - LOG_ERROR("invalid data for hci requirements v0.96"); - return; + // v0.96 + auto v96 = LeGetVendorCapabilitiesComplete096View::Create(v95); + if (!v96.IsValid()) { + LOG_INFO("invalid data for hci requirements v0.96"); + vendor_promise.set_value(); + return; + } + vendor_capabilities_.le_address_generation_offloading_support_ = + v96.GetLeAddressGenerationOffloadingSupport(); + if (vendor_capabilities_.version_supported_ <= 96 || complete_view.GetPayload().size() == 0) { + vendor_promise.set_value(); + return; + } + + // v0.98 + auto v98 = LeGetVendorCapabilitiesComplete098View::Create(v96); + if (!v98.IsValid()) { + LOG_INFO("invalid data for hci requirements v0.98"); + vendor_promise.set_value(); + return; + } + vendor_capabilities_.a2dp_source_offload_capability_mask_ = + v98.GetA2dpSourceOffloadCapabilityMask(); + vendor_capabilities_.bluetooth_quality_report_support_ = v98.GetBluetoothQualityReportSupport(); + + // v1.03 + auto v103 = LeGetVendorCapabilitiesComplete103View::Create(v98); + if (!v103.IsValid()) { + LOG_INFO("invalid data for hci requirements v1.03"); + vendor_promise.set_value(); + return; + } + vendor_capabilities_.dynamic_audio_buffer_support_ = v103.GetDynamicAudioBufferSupport(); + + if (IS_FLAG_ENABLED(a2dp_offload_codec_extensibility)) { + // v1.04 + auto v104 = LeGetVendorCapabilitiesComplete104View::Create(v103); + if (!v104.IsValid()) { + LOG_INFO("invalid data for hci requirements v1.04"); + } else { + vendor_capabilities_.a2dp_offload_v2_support_ = v104.GetA2dpOffloadV2Support(); } - vendor_capabilities_.le_address_generation_offloading_support_ = v96.GetLeAddressGenerationOffloadingSupport(); - if (vendor_capabilities_.version_supported_ <= 96 || complete_view.GetPayload().size() == 0) { + + if (vendor_capabilities_.dynamic_audio_buffer_support_) { + hci_->EnqueueCommand( + DabGetAudioBufferTimeCapabilityBuilder::Create(), + module_.GetHandler()->BindOnceOn( + this, + &Controller::impl::le_get_dynamic_audio_buffer_support_handler, + std::move(vendor_promise))); return; } - // v0.98 - auto v98 = LeGetVendorCapabilitiesComplete098View::Create(v96); - if (!v98.IsValid()) { - LOG_ERROR("invalid data for hci requirements v0.98"); + vendor_promise.set_value(); + } else { + if (vendor_capabilities_.dynamic_audio_buffer_support_ == 0) { + vendor_promise.set_value(); return; } - vendor_capabilities_.a2dp_source_offload_capability_mask_ = v98.GetA2dpSourceOffloadCapabilityMask(); - vendor_capabilities_.bluetooth_quality_report_support_ = v98.GetBluetoothQualityReportSupport(); + hci_->EnqueueCommand( + DabGetAudioBufferTimeCapabilityBuilder::Create(), + module_.GetHandler()->BindOnceOn( + this, + &Controller::impl::le_get_dynamic_audio_buffer_support_handler, + std::move(vendor_promise))); } } + void le_get_dynamic_audio_buffer_support_handler( + std::promise vendor_promise, CommandCompleteView view) { + vendor_promise.set_value(); + auto dab_complete_view = DynamicAudioBufferCompleteView::Create(view); + if (!dab_complete_view.IsValid()) { + LOG_WARN("Invalid command complete"); + return; + } + + if (dab_complete_view.GetStatus() != ErrorCode::SUCCESS) { + LOG_WARN("Unexpected error code %s", ErrorCodeText(dab_complete_view.GetStatus()).c_str()); + return; + } + + auto complete_view = DabGetAudioBufferTimeCapabilityCompleteView::Create(dab_complete_view); + if (!complete_view.IsValid()) { + LOG_WARN("Invalid get complete"); + return; + } + dab_supported_codecs_ = complete_view.GetAudioCodecTypeSupported(); + dab_codec_capabilities_ = complete_view.GetAudioCodecCapabilities(); + } + + void set_controller_dab_audio_buffer_time_complete(CommandCompleteView complete) { + auto dab_complete = DynamicAudioBufferCompleteView::Create(complete); + if (!dab_complete.IsValid()) { + LOG_WARN("Invalid command complete"); + return; + } + + if (dab_complete.GetStatus() != ErrorCode::SUCCESS) { + LOG_WARN("Unexpected return code %s", ErrorCodeText(dab_complete.GetStatus()).c_str()); + return; + } + + auto dab_set_complete = DabSetAudioBufferTimeCompleteView::Create(dab_complete); + + if (!dab_set_complete.IsValid()) { + LOG_WARN("Invalid set complete"); + return; + } + + LOG_INFO( + "Configured Media Tx Buffer, time returned = %d", + dab_set_complete.GetCurrentBufferTimeMs()); + } + + void set_controller_dab_audio_buffer_time(uint16_t buffer_time_ms) { + hci_->EnqueueCommand( + DabSetAudioBufferTimeBuilder::Create(buffer_time_ms), + module_.GetHandler()->BindOnceOn( + this, &Controller::impl::set_controller_dab_audio_buffer_time_complete)); + } + void set_event_mask(uint64_t event_mask) { std::unique_ptr packet = SetEventMaskBuilder::Create(event_mask); hci_->EnqueueCommand( @@ -1045,6 +1167,8 @@ struct Controller::impl { return vendor_capabilities_.a2dp_source_offload_capability_mask_ != 0x00; case OpCode::CONTROLLER_BQR: return vendor_capabilities_.bluetooth_quality_report_support_ == 0x01; + case OpCode::DYNAMIC_AUDIO_BUFFER: + return vendor_capabilities_.dynamic_audio_buffer_support_ > 0x00; // Before MSFT extension is fully supported, return false for the following MSFT_OPCODE_XXXX for now. case OpCode::MSFT_OPCODE_INTEL: return false; @@ -1099,7 +1223,7 @@ struct Controller::impl { LeBufferSize iso_buffer_size_{}; uint64_t le_local_supported_features_{}; uint64_t le_supported_states_{}; - uint8_t le_connect_list_size_{}; + uint8_t le_accept_list_size_{}; uint8_t le_resolving_list_size_{}; LeMaximumDataLength le_maximum_data_length_{}; uint16_t le_maximum_advertising_data_length_{}; @@ -1107,6 +1231,8 @@ struct Controller::impl { uint8_t le_number_supported_advertising_sets_{}; uint8_t le_periodic_advertiser_list_size_{}; VendorCapabilities vendor_capabilities_{}; + uint32_t dab_supported_codecs_{}; + std::array dab_codec_capabilities_{}; }; // namespace hci Controller::Controller() : impl_(std::make_unique(*this)) {} @@ -1350,7 +1476,7 @@ uint64_t Controller::GetLeSupportedStates() const { } uint8_t Controller::GetLeFilterAcceptListSize() const { - return impl_->le_connect_list_size_; + return impl_->le_accept_list_size_; } uint8_t Controller::GetLeResolvingListSize() const { @@ -1377,6 +1503,23 @@ Controller::VendorCapabilities Controller::GetVendorCapabilities() const { return impl_->vendor_capabilities_; } +uint32_t Controller::GetDabSupportedCodecs() const { + return impl_->dab_supported_codecs_; +} + +const std::array& Controller::GetDabCodecCapabilities() + const { + return impl_->dab_codec_capabilities_; +} + +void Controller::SetDabAudioBufferTime(uint16_t buffer_time_ms) { + if (impl_->vendor_capabilities_.dynamic_audio_buffer_support_ == 0) { + LOG_WARN("Dynamic Audio Buffer not supported"); + return; + } + impl_->set_controller_dab_audio_buffer_time(buffer_time_ms); +} + uint8_t Controller::GetLePeriodicAdvertiserListSize() const { return impl_->le_periodic_advertiser_list_size_; } @@ -1488,7 +1631,7 @@ void Controller::impl::Dump( builder.add_iso_buffer_size(&iso_buffer_size_data); builder.add_le_buffer_size(&le_buffer_size_data); - builder.add_le_connect_list_size(le_connect_list_size_); + builder.add_le_accept_list_size(le_accept_list_size_); builder.add_le_resolving_list_size(le_resolving_list_size_); builder.add_le_maximum_data_length(&le_maximum_data_length_data); diff --git a/system/gd/hci/controller.h b/system/gd/hci/controller.h index b83b215e099481189f72c51b8d3ccdaef62e3392..0501326d958c042176b8751016eb58d22fca8b02 100644 --- a/system/gd/hci/controller.h +++ b/system/gd/hci/controller.h @@ -16,7 +16,10 @@ #pragma once +#include + #include "hci/address.h" +#include "hci/controller_interface.h" #include "hci/hci_packets.h" #include "hci/le_rand_callback.h" #include "module.h" @@ -27,7 +30,7 @@ namespace bluetooth { namespace hci { -class Controller : public Module { +class Controller : public Module, public ControllerInterface { public: Controller(); Controller(const Controller&) = delete; @@ -35,177 +38,167 @@ class Controller : public Module { virtual ~Controller(); - using CompletedAclPacketsCallback = - common::ContextualCallback; - virtual void RegisterCompletedAclPacketsCallback(CompletedAclPacketsCallback cb); - - virtual void UnregisterCompletedAclPacketsCallback(); - - virtual void RegisterCompletedMonitorAclPacketsCallback(CompletedAclPacketsCallback cb); - virtual void UnregisterCompletedMonitorAclPacketsCallback(); - - virtual std::string GetLocalName() const; - - virtual LocalVersionInformation GetLocalVersionInformation() const; - - virtual bool SupportsSimplePairing() const; - virtual bool SupportsSecureConnections() const; - virtual bool SupportsSimultaneousLeBrEdr() const; - virtual bool SupportsInterlacedInquiryScan() const; - virtual bool SupportsRssiWithInquiryResults() const; - virtual bool SupportsExtendedInquiryResponse() const; - virtual bool SupportsRoleSwitch() const; - virtual bool Supports3SlotPackets() const; - virtual bool Supports5SlotPackets() const; - virtual bool SupportsClassic2mPhy() const; - virtual bool SupportsClassic3mPhy() const; - virtual bool Supports3SlotEdrPackets() const; - virtual bool Supports5SlotEdrPackets() const; - virtual bool SupportsSco() const; - virtual bool SupportsHv2Packets() const; - virtual bool SupportsHv3Packets() const; - virtual bool SupportsEv3Packets() const; - virtual bool SupportsEv4Packets() const; - virtual bool SupportsEv5Packets() const; - virtual bool SupportsEsco2mPhy() const; - virtual bool SupportsEsco3mPhy() const; - virtual bool Supports3SlotEscoEdrPackets() const; - virtual bool SupportsHoldMode() const; - virtual bool SupportsSniffMode() const; - virtual bool SupportsParkMode() const; - virtual bool SupportsNonFlushablePb() const; - virtual bool SupportsSniffSubrating() const; - virtual bool SupportsEncryptionPause() const; - virtual bool SupportsBle() const; - - virtual bool SupportsBleEncryption() const; - virtual bool SupportsBleConnectionParametersRequest() const; - virtual bool SupportsBleExtendedReject() const; - virtual bool SupportsBlePeripheralInitiatedFeaturesExchange() const; - virtual bool SupportsBlePing() const; - virtual bool SupportsBleDataPacketLengthExtension() const; - virtual bool SupportsBlePrivacy() const; - virtual bool SupportsBleExtendedScannerFilterPolicies() const; - virtual bool SupportsBle2mPhy() const; - virtual bool SupportsBleStableModulationIndexTx() const; - virtual bool SupportsBleStableModulationIndexRx() const; - virtual bool SupportsBleCodedPhy() const; - virtual bool SupportsBleExtendedAdvertising() const; - virtual bool SupportsBlePeriodicAdvertising() const; - virtual bool SupportsBleChannelSelectionAlgorithm2() const; - virtual bool SupportsBlePowerClass1() const; - virtual bool SupportsBleMinimumUsedChannels() const; - virtual bool SupportsBleConnectionCteRequest() const; - virtual bool SupportsBleConnectionCteResponse() const; - virtual bool SupportsBleConnectionlessCteTransmitter() const; - virtual bool SupportsBleConnectionlessCteReceiver() const; - virtual bool SupportsBleAntennaSwitchingDuringCteTx() const; - virtual bool SupportsBleAntennaSwitchingDuringCteRx() const; - virtual bool SupportsBleReceivingConstantToneExtensions() const; - virtual bool SupportsBlePeriodicAdvertisingSyncTransferSender() const; - virtual bool SupportsBlePeriodicAdvertisingSyncTransferRecipient() const; - virtual bool SupportsBleSleepClockAccuracyUpdates() const; - virtual bool SupportsBleRemotePublicKeyValidation() const; - virtual bool SupportsBleConnectedIsochronousStreamCentral() const; - virtual bool SupportsBleConnectedIsochronousStreamPeripheral() const; - virtual bool SupportsBleIsochronousBroadcaster() const; - virtual bool SupportsBleSynchronizedReceiver() const; - virtual bool SupportsBleIsochronousChannelsHostSupport() const; - virtual bool SupportsBlePowerControlRequest() const; - virtual bool SupportsBlePowerChangeIndication() const; - virtual bool SupportsBlePathLossMonitoring() const; - virtual bool SupportsBlePeriodicAdvertisingAdi() const; - virtual bool SupportsBleConnectionSubrating() const; - virtual bool SupportsBleConnectionSubratingHost() const; - - virtual uint16_t GetAclPacketLength() const; - - virtual uint16_t GetNumAclPacketBuffers() const; - - virtual uint8_t GetScoPacketLength() const; - - virtual uint16_t GetNumScoPacketBuffers() const; - - virtual Address GetMacAddress() const; - - virtual void SetEventMask(uint64_t event_mask); - - virtual void Reset(); - - virtual void LeRand(LeRandCallback cb); - - virtual void SetEventFilterClearAll(); - - virtual void SetEventFilterInquiryResultAllDevices(); - - virtual void SetEventFilterInquiryResultClassOfDevice(ClassOfDevice class_of_device, - ClassOfDevice class_of_device_mask); - - virtual void SetEventFilterInquiryResultAddress(Address address); - - virtual void SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag auto_accept_flag); - - virtual void SetEventFilterConnectionSetupClassOfDevice(ClassOfDevice class_of_device, - ClassOfDevice class_of_device_mask, - AutoAcceptFlag auto_accept_flag); - - virtual void SetEventFilterConnectionSetupAddress(Address address, AutoAcceptFlag auto_accept_flag); - - virtual void WriteLocalName(std::string local_name); - - virtual void HostBufferSize(uint16_t host_acl_data_packet_length, uint8_t host_synchronous_data_packet_length, - uint16_t host_total_num_acl_data_packets, - uint16_t host_total_num_synchronous_data_packets); + virtual void RegisterCompletedAclPacketsCallback(CompletedAclPacketsCallback cb) override; + + virtual void UnregisterCompletedAclPacketsCallback() override; + + virtual void RegisterCompletedMonitorAclPacketsCallback(CompletedAclPacketsCallback cb) override; + virtual void UnregisterCompletedMonitorAclPacketsCallback() override; + + virtual std::string GetLocalName() const override; + + virtual LocalVersionInformation GetLocalVersionInformation() const override; + + virtual bool SupportsSimplePairing() const override; + virtual bool SupportsSecureConnections() const override; + virtual bool SupportsSimultaneousLeBrEdr() const override; + virtual bool SupportsInterlacedInquiryScan() const override; + virtual bool SupportsRssiWithInquiryResults() const override; + virtual bool SupportsExtendedInquiryResponse() const override; + virtual bool SupportsRoleSwitch() const override; + virtual bool Supports3SlotPackets() const override; + virtual bool Supports5SlotPackets() const override; + virtual bool SupportsClassic2mPhy() const override; + virtual bool SupportsClassic3mPhy() const override; + virtual bool Supports3SlotEdrPackets() const override; + virtual bool Supports5SlotEdrPackets() const override; + virtual bool SupportsSco() const override; + virtual bool SupportsHv2Packets() const override; + virtual bool SupportsHv3Packets() const override; + virtual bool SupportsEv3Packets() const override; + virtual bool SupportsEv4Packets() const override; + virtual bool SupportsEv5Packets() const override; + virtual bool SupportsEsco2mPhy() const override; + virtual bool SupportsEsco3mPhy() const override; + virtual bool Supports3SlotEscoEdrPackets() const override; + virtual bool SupportsHoldMode() const override; + virtual bool SupportsSniffMode() const override; + virtual bool SupportsParkMode() const override; + virtual bool SupportsNonFlushablePb() const override; + virtual bool SupportsSniffSubrating() const override; + virtual bool SupportsEncryptionPause() const override; + virtual bool SupportsBle() const override; + + virtual bool SupportsBleEncryption() const override; + virtual bool SupportsBleConnectionParametersRequest() const override; + virtual bool SupportsBleExtendedReject() const override; + virtual bool SupportsBlePeripheralInitiatedFeaturesExchange() const override; + virtual bool SupportsBlePing() const override; + virtual bool SupportsBleDataPacketLengthExtension() const override; + virtual bool SupportsBlePrivacy() const override; + virtual bool SupportsBleExtendedScannerFilterPolicies() const override; + virtual bool SupportsBle2mPhy() const override; + virtual bool SupportsBleStableModulationIndexTx() const override; + virtual bool SupportsBleStableModulationIndexRx() const override; + virtual bool SupportsBleCodedPhy() const override; + virtual bool SupportsBleExtendedAdvertising() const override; + virtual bool SupportsBlePeriodicAdvertising() const override; + virtual bool SupportsBleChannelSelectionAlgorithm2() const override; + virtual bool SupportsBlePowerClass1() const override; + virtual bool SupportsBleMinimumUsedChannels() const override; + virtual bool SupportsBleConnectionCteRequest() const override; + virtual bool SupportsBleConnectionCteResponse() const override; + virtual bool SupportsBleConnectionlessCteTransmitter() const override; + virtual bool SupportsBleConnectionlessCteReceiver() const override; + virtual bool SupportsBleAntennaSwitchingDuringCteTx() const override; + virtual bool SupportsBleAntennaSwitchingDuringCteRx() const override; + virtual bool SupportsBleReceivingConstantToneExtensions() const override; + virtual bool SupportsBlePeriodicAdvertisingSyncTransferSender() const override; + virtual bool SupportsBlePeriodicAdvertisingSyncTransferRecipient() const override; + virtual bool SupportsBleSleepClockAccuracyUpdates() const override; + virtual bool SupportsBleRemotePublicKeyValidation() const override; + virtual bool SupportsBleConnectedIsochronousStreamCentral() const override; + virtual bool SupportsBleConnectedIsochronousStreamPeripheral() const override; + virtual bool SupportsBleIsochronousBroadcaster() const override; + virtual bool SupportsBleSynchronizedReceiver() const override; + virtual bool SupportsBleIsochronousChannelsHostSupport() const override; + virtual bool SupportsBlePowerControlRequest() const override; + virtual bool SupportsBlePowerChangeIndication() const override; + virtual bool SupportsBlePathLossMonitoring() const override; + virtual bool SupportsBlePeriodicAdvertisingAdi() const override; + virtual bool SupportsBleConnectionSubrating() const override; + virtual bool SupportsBleConnectionSubratingHost() const override; + + virtual uint16_t GetAclPacketLength() const override; + + virtual uint16_t GetNumAclPacketBuffers() const override; + + virtual uint8_t GetScoPacketLength() const override; + + virtual uint16_t GetNumScoPacketBuffers() const override; + + virtual Address GetMacAddress() const override; + + virtual void SetEventMask(uint64_t event_mask) override; + + virtual void Reset() override; + + virtual void LeRand(LeRandCallback cb) override; + + virtual void SetEventFilterClearAll() override; + + virtual void SetEventFilterInquiryResultAllDevices() override; + + virtual void SetEventFilterInquiryResultClassOfDevice( + ClassOfDevice class_of_device, ClassOfDevice class_of_device_mask) override; + + virtual void SetEventFilterInquiryResultAddress(Address address) override; + + virtual void SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag auto_accept_flag) override; + + virtual void SetEventFilterConnectionSetupClassOfDevice( + ClassOfDevice class_of_device, + ClassOfDevice class_of_device_mask, + AutoAcceptFlag auto_accept_flag) override; + + virtual void SetEventFilterConnectionSetupAddress( + Address address, AutoAcceptFlag auto_accept_flag) override; + + virtual void WriteLocalName(std::string local_name) override; + + virtual void HostBufferSize( + uint16_t host_acl_data_packet_length, + uint8_t host_synchronous_data_packet_length, + uint16_t host_total_num_acl_data_packets, + uint16_t host_total_num_synchronous_data_packets) override; // LE controller commands - virtual void LeSetEventMask(uint64_t le_event_mask); + virtual void LeSetEventMask(uint64_t le_event_mask) override; - virtual LeBufferSize GetLeBufferSize() const; + virtual LeBufferSize GetLeBufferSize() const override; - virtual uint64_t GetLeSupportedStates() const; + virtual uint64_t GetLeSupportedStates() const override; - virtual LeBufferSize GetControllerIsoBufferSize() const; + virtual LeBufferSize GetControllerIsoBufferSize() const override; - virtual uint64_t GetControllerLeLocalSupportedFeatures() const; + virtual uint64_t GetControllerLeLocalSupportedFeatures() const override; - virtual uint8_t GetLeFilterAcceptListSize() const; + virtual uint8_t GetLeFilterAcceptListSize() const override; - virtual uint8_t GetLeResolvingListSize() const; + virtual uint8_t GetLeResolvingListSize() const override; - virtual LeMaximumDataLength GetLeMaximumDataLength() const; + virtual LeMaximumDataLength GetLeMaximumDataLength() const override; - virtual uint16_t GetLeMaximumAdvertisingDataLength() const; + virtual uint16_t GetLeMaximumAdvertisingDataLength() const override; - virtual uint16_t GetLeSuggestedDefaultDataLength() const; + virtual uint16_t GetLeSuggestedDefaultDataLength() const override; - virtual uint8_t GetLeNumberOfSupportedAdverisingSets() const; + virtual uint8_t GetLeNumberOfSupportedAdverisingSets() const override; - virtual uint8_t GetLePeriodicAdvertiserListSize() const; + virtual uint8_t GetLePeriodicAdvertiserListSize() const override; // 7.4.8 Read Local Supported Codecs command v1 only returns codecs on the BR/EDR transport - virtual std::vector GetLocalSupportedBrEdrCodecIds() const; - - struct VendorCapabilities { - uint8_t is_supported_; - uint8_t max_advt_instances_; - uint8_t offloaded_resolution_of_private_address_; - uint16_t total_scan_results_storage_; - uint8_t max_irk_list_sz_; - uint8_t filtering_support_; - uint8_t max_filter_; - uint8_t activity_energy_info_support_; - uint16_t version_supported_; - uint16_t total_num_of_advt_tracked_; - uint8_t extended_scan_support_; - uint8_t debug_logging_supported_; - uint8_t le_address_generation_offloading_support_; - uint32_t a2dp_source_offload_capability_mask_; - uint8_t bluetooth_quality_report_support_; - }; - - virtual VendorCapabilities GetVendorCapabilities() const; - - virtual bool IsSupported(OpCode op_code) const; + virtual std::vector GetLocalSupportedBrEdrCodecIds() const override; + + virtual VendorCapabilities GetVendorCapabilities() const override; + + virtual uint32_t GetDabSupportedCodecs() const override; + virtual const std::array& GetDabCodecCapabilities() + const override; + + virtual void SetDabAudioBufferTime(uint16_t buffer_time_ms) override; + + virtual bool IsSupported(OpCode op_code) const override; static const ModuleFactory Factory; diff --git a/system/gd/hci/controller_interface.h b/system/gd/hci/controller_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..d0fe20605bcf39f5cbd2b9ffe1cbbcc4e2f72dbe --- /dev/null +++ b/system/gd/hci/controller_interface.h @@ -0,0 +1,218 @@ +/* + * Copyright 2023 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 "common/contextual_callback.h" +#include "hci/address.h" +#include "hci/class_of_device.h" +#include "hci/hci_packets.h" +#include "hci/le_rand_callback.h" + +namespace bluetooth { +namespace hci { + +class ControllerInterface { + public: + ControllerInterface() = default; + virtual ~ControllerInterface() = default; + + using CompletedAclPacketsCallback = + common::ContextualCallback; + virtual void RegisterCompletedAclPacketsCallback(CompletedAclPacketsCallback cb) = 0; + + virtual void UnregisterCompletedAclPacketsCallback() = 0; + + virtual void RegisterCompletedMonitorAclPacketsCallback(CompletedAclPacketsCallback cb) = 0; + virtual void UnregisterCompletedMonitorAclPacketsCallback() = 0; + + virtual std::string GetLocalName() const = 0; + virtual LocalVersionInformation GetLocalVersionInformation() const = 0; + + virtual bool SupportsSimplePairing() const = 0; + virtual bool SupportsSecureConnections() const = 0; + virtual bool SupportsSimultaneousLeBrEdr() const = 0; + virtual bool SupportsInterlacedInquiryScan() const = 0; + virtual bool SupportsRssiWithInquiryResults() const = 0; + virtual bool SupportsExtendedInquiryResponse() const = 0; + virtual bool SupportsRoleSwitch() const = 0; + virtual bool Supports3SlotPackets() const = 0; + virtual bool Supports5SlotPackets() const = 0; + virtual bool SupportsClassic2mPhy() const = 0; + virtual bool SupportsClassic3mPhy() const = 0; + virtual bool Supports3SlotEdrPackets() const = 0; + virtual bool Supports5SlotEdrPackets() const = 0; + virtual bool SupportsSco() const = 0; + virtual bool SupportsHv2Packets() const = 0; + virtual bool SupportsHv3Packets() const = 0; + virtual bool SupportsEv3Packets() const = 0; + virtual bool SupportsEv4Packets() const = 0; + virtual bool SupportsEv5Packets() const = 0; + virtual bool SupportsEsco2mPhy() const = 0; + virtual bool SupportsEsco3mPhy() const = 0; + virtual bool Supports3SlotEscoEdrPackets() const = 0; + virtual bool SupportsHoldMode() const = 0; + virtual bool SupportsSniffMode() const = 0; + virtual bool SupportsParkMode() const = 0; + virtual bool SupportsNonFlushablePb() const = 0; + virtual bool SupportsSniffSubrating() const = 0; + virtual bool SupportsEncryptionPause() const = 0; + virtual bool SupportsBle() const = 0; + + virtual bool SupportsBleEncryption() const = 0; + virtual bool SupportsBleConnectionParametersRequest() const = 0; + virtual bool SupportsBleExtendedReject() const = 0; + virtual bool SupportsBlePeripheralInitiatedFeaturesExchange() const = 0; + virtual bool SupportsBlePing() const = 0; + virtual bool SupportsBleDataPacketLengthExtension() const = 0; + virtual bool SupportsBlePrivacy() const = 0; + virtual bool SupportsBleExtendedScannerFilterPolicies() const = 0; + virtual bool SupportsBle2mPhy() const = 0; + virtual bool SupportsBleStableModulationIndexTx() const = 0; + virtual bool SupportsBleStableModulationIndexRx() const = 0; + virtual bool SupportsBleCodedPhy() const = 0; + virtual bool SupportsBleExtendedAdvertising() const = 0; + virtual bool SupportsBlePeriodicAdvertising() const = 0; + virtual bool SupportsBleChannelSelectionAlgorithm2() const = 0; + virtual bool SupportsBlePowerClass1() const = 0; + virtual bool SupportsBleMinimumUsedChannels() const = 0; + virtual bool SupportsBleConnectionCteRequest() const = 0; + virtual bool SupportsBleConnectionCteResponse() const = 0; + virtual bool SupportsBleConnectionlessCteTransmitter() const = 0; + virtual bool SupportsBleConnectionlessCteReceiver() const = 0; + virtual bool SupportsBleAntennaSwitchingDuringCteTx() const = 0; + virtual bool SupportsBleAntennaSwitchingDuringCteRx() const = 0; + virtual bool SupportsBleReceivingConstantToneExtensions() const = 0; + virtual bool SupportsBlePeriodicAdvertisingSyncTransferSender() const = 0; + virtual bool SupportsBlePeriodicAdvertisingSyncTransferRecipient() const = 0; + virtual bool SupportsBleSleepClockAccuracyUpdates() const = 0; + virtual bool SupportsBleRemotePublicKeyValidation() const = 0; + virtual bool SupportsBleConnectedIsochronousStreamCentral() const = 0; + virtual bool SupportsBleConnectedIsochronousStreamPeripheral() const = 0; + virtual bool SupportsBleIsochronousBroadcaster() const = 0; + virtual bool SupportsBleSynchronizedReceiver() const = 0; + virtual bool SupportsBleIsochronousChannelsHostSupport() const = 0; + virtual bool SupportsBlePowerControlRequest() const = 0; + virtual bool SupportsBlePowerChangeIndication() const = 0; + virtual bool SupportsBlePathLossMonitoring() const = 0; + virtual bool SupportsBlePeriodicAdvertisingAdi() const = 0; + virtual bool SupportsBleConnectionSubrating() const = 0; + virtual bool SupportsBleConnectionSubratingHost() const = 0; + + virtual uint16_t GetAclPacketLength() const = 0; + + virtual uint16_t GetNumAclPacketBuffers() const = 0; + + virtual uint8_t GetScoPacketLength() const = 0; + + virtual uint16_t GetNumScoPacketBuffers() const = 0; + + virtual Address GetMacAddress() const = 0; + + virtual void SetEventMask(uint64_t event_mask) = 0; + + virtual void Reset() = 0; + + virtual void LeRand(LeRandCallback cb) = 0; + + virtual void SetEventFilterClearAll() = 0; + + virtual void SetEventFilterInquiryResultAllDevices() = 0; + + virtual void SetEventFilterInquiryResultClassOfDevice( + ClassOfDevice class_of_device, ClassOfDevice class_of_device_mask) = 0; + + virtual void SetEventFilterInquiryResultAddress(Address address) = 0; + + virtual void SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag auto_accept_flag) = 0; + + virtual void SetEventFilterConnectionSetupClassOfDevice( + ClassOfDevice class_of_device, + ClassOfDevice class_of_device_mask, + AutoAcceptFlag auto_accept_flag) = 0; + + virtual void SetEventFilterConnectionSetupAddress( + Address address, AutoAcceptFlag auto_accept_flag) = 0; + + virtual void WriteLocalName(std::string local_name) = 0; + + virtual void HostBufferSize( + uint16_t host_acl_data_packet_length, + uint8_t host_synchronous_data_packet_length, + uint16_t host_total_num_acl_data_packets, + uint16_t host_total_num_synchronous_data_packets) = 0; + + // LE controller commands + virtual void LeSetEventMask(uint64_t le_event_mask) = 0; + + virtual LeBufferSize GetLeBufferSize() const = 0; + + virtual uint64_t GetLeSupportedStates() const = 0; + + virtual LeBufferSize GetControllerIsoBufferSize() const = 0; + + virtual uint64_t GetControllerLeLocalSupportedFeatures() const = 0; + + virtual uint8_t GetLeFilterAcceptListSize() const = 0; + + virtual uint8_t GetLeResolvingListSize() const = 0; + + virtual LeMaximumDataLength GetLeMaximumDataLength() const = 0; + + virtual uint16_t GetLeMaximumAdvertisingDataLength() const = 0; + + virtual uint16_t GetLeSuggestedDefaultDataLength() const = 0; + + virtual uint8_t GetLeNumberOfSupportedAdverisingSets() const = 0; + + virtual uint8_t GetLePeriodicAdvertiserListSize() const = 0; + + // 7.4.8 Read Local Supported Codecs command v1 only returns codecs on the BR/EDR transport + virtual std::vector GetLocalSupportedBrEdrCodecIds() const = 0; + + struct VendorCapabilities { + uint8_t is_supported_; + uint8_t max_advt_instances_; + uint8_t offloaded_resolution_of_private_address_; + uint16_t total_scan_results_storage_; + uint8_t max_irk_list_sz_; + uint8_t filtering_support_; + uint8_t max_filter_; + uint8_t activity_energy_info_support_; + uint16_t version_supported_; + uint16_t total_num_of_advt_tracked_; + uint8_t extended_scan_support_; + uint8_t debug_logging_supported_; + uint8_t le_address_generation_offloading_support_; + uint32_t a2dp_source_offload_capability_mask_; + uint8_t bluetooth_quality_report_support_; + uint32_t dynamic_audio_buffer_support_; + uint8_t a2dp_offload_v2_support_; + }; + + virtual uint32_t GetDabSupportedCodecs() const = 0; + virtual const std::array& GetDabCodecCapabilities() + const = 0; + + virtual void SetDabAudioBufferTime(uint16_t buffer_time_ms) = 0; + + virtual VendorCapabilities GetVendorCapabilities() const = 0; + + virtual bool IsSupported(OpCode op_code) const = 0; +}; + +} // namespace hci +} // namespace bluetooth diff --git a/system/gd/hci/controller_interface_mock.h b/system/gd/hci/controller_interface_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..482bea7f6f5dbabed113674b942400d38c1f21fa --- /dev/null +++ b/system/gd/hci/controller_interface_mock.h @@ -0,0 +1,173 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +#include + +#include "hci/address.h" +#include "hci/controller_interface.h" +#include "hci/hci_packets.h" +#include "hci/le_rand_callback.h" + +// Unit test interfaces +namespace bluetooth { +namespace hci { +namespace testing { + +class MockControllerInterface : public ControllerInterface { + public: + MOCK_METHOD(void, RegisterCompletedAclPacketsCallback, (CompletedAclPacketsCallback cb)); + MOCK_METHOD(void, UnregisterCompletedAclPacketsCallback, ()); + MOCK_METHOD(void, RegisterCompletedMonitorAclPacketsCallback, (CompletedAclPacketsCallback cb)); + MOCK_METHOD(void, UnregisterCompletedMonitorAclPacketsCallback, ()); + MOCK_METHOD(std::string, GetLocalName, (), (const)); + MOCK_METHOD(LocalVersionInformation, GetLocalVersionInformation, (), (const)); + MOCK_METHOD(bool, SupportsSimplePairing, (), (const)); + MOCK_METHOD(bool, SupportsSecureConnections, (), (const)); + MOCK_METHOD(bool, SupportsSimultaneousLeBrEdr, (), (const)); + MOCK_METHOD(bool, SupportsInterlacedInquiryScan, (), (const)); + MOCK_METHOD(bool, SupportsRssiWithInquiryResults, (), (const)); + MOCK_METHOD(bool, SupportsExtendedInquiryResponse, (), (const)); + MOCK_METHOD(bool, SupportsRoleSwitch, (), (const)); + MOCK_METHOD(bool, Supports3SlotPackets, (), (const)); + MOCK_METHOD(bool, Supports5SlotPackets, (), (const)); + MOCK_METHOD(bool, SupportsClassic2mPhy, (), (const)); + MOCK_METHOD(bool, SupportsClassic3mPhy, (), (const)); + MOCK_METHOD(bool, Supports3SlotEdrPackets, (), (const)); + MOCK_METHOD(bool, Supports5SlotEdrPackets, (), (const)); + MOCK_METHOD(bool, SupportsSco, (), (const)); + MOCK_METHOD(bool, SupportsHv2Packets, (), (const)); + MOCK_METHOD(bool, SupportsHv3Packets, (), (const)); + MOCK_METHOD(bool, SupportsEv3Packets, (), (const)); + MOCK_METHOD(bool, SupportsEv4Packets, (), (const)); + MOCK_METHOD(bool, SupportsEv5Packets, (), (const)); + MOCK_METHOD(bool, SupportsEsco2mPhy, (), (const)); + MOCK_METHOD(bool, SupportsEsco3mPhy, (), (const)); + MOCK_METHOD(bool, Supports3SlotEscoEdrPackets, (), (const)); + MOCK_METHOD(bool, SupportsHoldMode, (), (const)); + MOCK_METHOD(bool, SupportsSniffMode, (), (const)); + MOCK_METHOD(bool, SupportsParkMode, (), (const)); + MOCK_METHOD(bool, SupportsNonFlushablePb, (), (const)); + MOCK_METHOD(bool, SupportsSniffSubrating, (), (const)); + MOCK_METHOD(bool, SupportsEncryptionPause, (), (const)); + MOCK_METHOD(bool, SupportsBle, (), (const)); + + MOCK_METHOD(bool, SupportsBleEncryption, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionParametersRequest, (), (const)); + MOCK_METHOD(bool, SupportsBleExtendedReject, (), (const)); + MOCK_METHOD(bool, SupportsBlePeripheralInitiatedFeaturesExchange, (), (const)); + MOCK_METHOD(bool, SupportsBlePing, (), (const)); + MOCK_METHOD(bool, SupportsBleDataPacketLengthExtension, (), (const)); + MOCK_METHOD(bool, SupportsBlePrivacy, (), (const)); + MOCK_METHOD(bool, SupportsBleExtendedScannerFilterPolicies, (), (const)); + MOCK_METHOD(bool, SupportsBle2mPhy, (), (const)); + MOCK_METHOD(bool, SupportsBleStableModulationIndexTx, (), (const)); + MOCK_METHOD(bool, SupportsBleStableModulationIndexRx, (), (const)); + MOCK_METHOD(bool, SupportsBleCodedPhy, (), (const)); + MOCK_METHOD(bool, SupportsBleExtendedAdvertising, (), (const)); + MOCK_METHOD(bool, SupportsBlePeriodicAdvertising, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionParameterRequest, (), (const)); + MOCK_METHOD(bool, SupportsBleChannelSelectionAlgorithm2, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerClass1, (), (const)); + MOCK_METHOD(bool, SupportsBleMinimumUsedChannels, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionCteRequest, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionCteResponse, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionlessCteTransmitter, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionlessCteReceiver, (), (const)); + MOCK_METHOD(bool, SupportsBleAntennaSwitchingDuringCteTx, (), (const)); + MOCK_METHOD(bool, SupportsBleAntennaSwitchingDuringCteRx, (), (const)); + MOCK_METHOD(bool, SupportsBleReceivingConstantToneExtensions, (), (const)); + MOCK_METHOD(bool, SupportsBlePeriodicAdvertisingSyncTransferSender, (), (const)); + MOCK_METHOD(bool, SupportsBlePeriodicAdvertisingSyncTransferRecipient, (), (const)); + MOCK_METHOD(bool, SupportsBleSleepClockAccuracyUpdates, (), (const)); + MOCK_METHOD(bool, SupportsBleRemotePublicKeyValidation, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectedIsochronousStreamCentral, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectedIsochronousStreamPeripheral, (), (const)); + MOCK_METHOD(bool, SupportsBleIsochronousBroadcaster, (), (const)); + MOCK_METHOD(bool, SupportsBleSynchronizedReceiver, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerChannelHostSupport, (), (const)); + MOCK_METHOD(bool, SupportsBleIsochronousChannelsHostSupport, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerControlRequest, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerChangeIndication, (), (const)); + MOCK_METHOD(bool, SupportsBlePathLossMonitoring, (), (const)); + MOCK_METHOD(bool, SupportsBlePeriodicAdvertisingAdi, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionSubrating, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionSubratingHost, (), (const)); + MOCK_METHOD(uint16_t, GetAclPacketLength, (), (const)); + MOCK_METHOD(uint16_t, GetNumAclPacketBuffers, (), (const)); + MOCK_METHOD(uint8_t, GetScoPacketLength, (), (const)); + MOCK_METHOD(uint16_t, GetNumScoPacketBuffers, (), (const)); + MOCK_METHOD(Address, GetMacAddress, (), (const)); + MOCK_METHOD(void, SetEventMask, (uint64_t event_mask)); + MOCK_METHOD(void, Reset, ()); + MOCK_METHOD(void, LeRand, (LeRandCallback cb)); + MOCK_METHOD(void, SetEventFilterClearAll, ()); + MOCK_METHOD(void, SetEventFilterInquiryResultAllDevices, ()); + MOCK_METHOD( + void, + SetEventFilterInquiryResultClassOfDevice, + (ClassOfDevice class_of_device, ClassOfDevice class_of_device_mask)); + MOCK_METHOD(void, SetEventFilterInquiryResultAddress, (Address address)); + MOCK_METHOD(void, SetEventFilterConnectionSetupAllDevices, (AutoAcceptFlag auto_accept_flag)); + MOCK_METHOD( + void, + SetEventFilterConnectionSetupClassOfDevice, + (ClassOfDevice class_of_device, + ClassOfDevice class_of_device_mask, + AutoAcceptFlag auto_accept_flag)); + MOCK_METHOD( + void, + SetEventFilterConnectionSetupAddress, + (Address address, AutoAcceptFlag auto_accept_flag)); + MOCK_METHOD(void, WriteLocalName, (std::string local_name)); + MOCK_METHOD( + void, + HostBufferSize, + (uint16_t host_acl_data_packet_length, + uint8_t host_synchronous_data_packet_length, + uint16_t host_total_num_acl_data_packets, + uint16_t host_total_num_synchronous_data_packets)); + // LE controller commands + MOCK_METHOD(void, LeSetEventMask, (uint64_t le_event_mask)); + MOCK_METHOD(LeBufferSize, GetLeBufferSize, (), (const)); + MOCK_METHOD(uint64_t, GetLeSupportedStates, (), (const)); + MOCK_METHOD(LeBufferSize, GetControllerIsoBufferSize, (), (const)); + MOCK_METHOD(uint64_t, GetControllerLeLocalSupportedFeatures, (), (const)); + MOCK_METHOD(uint8_t, GetLeFilterAcceptListSize, (), (const)); + MOCK_METHOD(uint8_t, GetLeResolvingListSize, (), (const)); + MOCK_METHOD(LeMaximumDataLength, GetLeMaximumDataLength, (), (const)); + MOCK_METHOD(uint16_t, GetLeMaximumAdvertisingDataLength, (), (const)); + MOCK_METHOD(uint16_t, GetLeSuggestedDefaultDataLength, (), (const)); + MOCK_METHOD(uint8_t, GetLeNumberOfSupportedAdverisingSets, (), (const)); + MOCK_METHOD(uint8_t, GetLePeriodicAdvertiserListSize, (), (const)); + MOCK_METHOD(std::vector, GetLocalSupportedBrEdrCodecIds, (), (const)); + MOCK_METHOD(VendorCapabilities, GetVendorCapabilities, (), (const)); + MOCK_METHOD(bool, IsSupported, (OpCode op_code), (const)); + + MOCK_METHOD(uint32_t, GetDabSupportedCodecs, (), (const)); + MOCK_METHOD( + (const std::array&), + GetDabCodecCapabilities, + (), + (const)); + MOCK_METHOD(void, SetDabAudioBufferTime, (uint16_t buffer_time_ms)); +}; + +} // namespace testing +} // namespace hci +} // namespace bluetooth diff --git a/system/gd/hci/controller_mock.h b/system/gd/hci/controller_mock.h index a585943b6a53ce73aa28d6546b5f436e855a5bf7..c4351587734487c5d39c27c1983691123b1d52c2 100644 --- a/system/gd/hci/controller_mock.h +++ b/system/gd/hci/controller_mock.h @@ -68,22 +68,48 @@ class MockController : public Controller { MOCK_METHOD(bool, SupportsSniffSubrating, (), (const)); MOCK_METHOD(bool, SupportsEncryptionPause, (), (const)); MOCK_METHOD(bool, SupportsBle, (), (const)); - MOCK_METHOD(bool, SupportsBlePrivacy, (), (const)); - MOCK_METHOD(bool, SupportsBlePacketExtension, (), (const)); + + MOCK_METHOD(bool, SupportsBleEncryption, (), (const)); MOCK_METHOD(bool, SupportsBleConnectionParametersRequest, (), (const)); + MOCK_METHOD(bool, SupportsBleExtendedReject, (), (const)); + MOCK_METHOD(bool, SupportsBlePeripheralInitiatedFeaturesExchange, (), (const)); + MOCK_METHOD(bool, SupportsBlePing, (), (const)); + MOCK_METHOD(bool, SupportsBleDataPacketLengthExtension, (), (const)); + MOCK_METHOD(bool, SupportsBlePrivacy, (), (const)); + MOCK_METHOD(bool, SupportsBleExtendedScannerFilterPolicies, (), (const)); MOCK_METHOD(bool, SupportsBle2mPhy, (), (const)); + MOCK_METHOD(bool, SupportsBleStableModulationIndexTx, (), (const)); + MOCK_METHOD(bool, SupportsBleStableModulationIndexRx, (), (const)); MOCK_METHOD(bool, SupportsBleCodedPhy, (), (const)); MOCK_METHOD(bool, SupportsBleExtendedAdvertising, (), (const)); MOCK_METHOD(bool, SupportsBlePeriodicAdvertising, (), (const)); - MOCK_METHOD(bool, SupportsBlePeripheralInitiatedFeatureExchange, (), (const)); MOCK_METHOD(bool, SupportsBleConnectionParameterRequest, (), (const)); + MOCK_METHOD(bool, SupportsBleChannelSelectionAlgorithm2, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerClass1, (), (const)); + MOCK_METHOD(bool, SupportsBleMinimumUsedChannels, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionCteRequest, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionCteResponse, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionlessCteTransmitter, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionlessCteReceiver, (), (const)); + MOCK_METHOD(bool, SupportsBleAntennaSwitchingDuringCteTx, (), (const)); + MOCK_METHOD(bool, SupportsBleAntennaSwitchingDuringCteRx, (), (const)); + MOCK_METHOD(bool, SupportsBleReceivingConstantToneExtensions, (), (const)); MOCK_METHOD(bool, SupportsBlePeriodicAdvertisingSyncTransferSender, (), (const)); MOCK_METHOD(bool, SupportsBlePeriodicAdvertisingSyncTransferRecipient, (), (const)); + MOCK_METHOD(bool, SupportsBleSleepClockAccuracyUpdates, (), (const)); + MOCK_METHOD(bool, SupportsBleRemotePublicKeyValidation, (), (const)); MOCK_METHOD(bool, SupportsBleConnectedIsochronousStreamCentral, (), (const)); MOCK_METHOD(bool, SupportsBleConnectedIsochronousStreamPeripheral, (), (const)); MOCK_METHOD(bool, SupportsBleIsochronousBroadcaster, (), (const)); MOCK_METHOD(bool, SupportsBleSynchronizedReceiver, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerChannelHostSupport, (), (const)); + MOCK_METHOD(bool, SupportsBleIsochronousChannelsHostSupport, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerControlRequest, (), (const)); + MOCK_METHOD(bool, SupportsBlePowerChangeIndication, (), (const)); + MOCK_METHOD(bool, SupportsBlePathLossMonitoring, (), (const)); MOCK_METHOD(bool, SupportsBlePeriodicAdvertisingAdi, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionSubrating, (), (const)); + MOCK_METHOD(bool, SupportsBleConnectionSubratingHost, (), (const)); MOCK_METHOD(uint16_t, GetAclPacketLength, (), (const)); MOCK_METHOD(uint16_t, GetNumAclPacketBuffers, (), (const)); MOCK_METHOD(uint8_t, GetScoPacketLength, (), (const)); @@ -91,6 +117,7 @@ class MockController : public Controller { MOCK_METHOD(Address, GetMacAddress, (), (const)); MOCK_METHOD(void, SetEventMask, (uint64_t event_mask)); MOCK_METHOD(void, Reset, ()); + MOCK_METHOD(void, LeRand, (LeRandCallback cb)); MOCK_METHOD(void, SetEventFilterClearAll, ()); MOCK_METHOD(void, SetEventFilterInquiryResultAllDevices, ()); MOCK_METHOD( @@ -125,10 +152,17 @@ class MockController : public Controller { MOCK_METHOD(uint16_t, GetLeSuggestedDefaultDataLength, (), (const)); MOCK_METHOD(uint8_t, GetLeNumberOfSupportedAdverisingSets, (), (const)); MOCK_METHOD(uint8_t, GetLePeriodicAdvertiserListSize, (), (const)); + MOCK_METHOD(std::vector, GetLocalSupportedBrEdrCodecIds, (), (const)); MOCK_METHOD(VendorCapabilities, GetVendorCapabilities, (), (const)); MOCK_METHOD(bool, IsSupported, (OpCode op_code), (const)); - MOCK_METHOD(void, LeRand, (LeRandCallback cb)); - MOCK_METHOD(void, AllowWakeByHid, ()); + + MOCK_METHOD(uint32_t, GetDabSupportedCodecs, (), (const)); + MOCK_METHOD( + (const std::array&), + GetDabCodecCapabilities, + (), + (const)); + MOCK_METHOD(void, SetDabAudioBufferTime, (uint16_t buffer_time_ms)); }; } // namespace testing diff --git a/system/gd/hci/controller_test.cc b/system/gd/hci/controller_test.cc index 7a16b203ff2cab0f9c92f422f5e7807cccfeb401..669da6f6ecb161f4d9ef450c7ec836f36356ef49 100644 --- a/system/gd/hci/controller_test.cc +++ b/system/gd/hci/controller_test.cc @@ -16,16 +16,19 @@ #include "hci/controller.h" +#include #include +#include #include #include #include +#include #include "common/bind.h" #include "common/init_flags.h" #include "hci/address.h" -#include "hci/hci_layer.h" +#include "hci/hci_layer_fake.h" #include "module_dumper.h" #include "os/thread.h" #include "packet/raw_builder.h" @@ -47,28 +50,25 @@ constexpr uint16_t kCredits1 = 0x78; constexpr uint16_t kHandle2 = 0x456; constexpr uint16_t kCredits2 = 0x9a; constexpr uint64_t kRandomNumber = 0x123456789abcdef0; +/*sbc_supported= 1, aac_supported= 1, aptx_supported= 0, aptx_hd_supported= 0, ldac_supported= 1 */ +constexpr uint32_t kDynamicAudioBufferSupport = 0x13; uint16_t feature_spec_version = 55; constexpr char title[] = "hci_controller_test"; -PacketView GetPacketView(std::unique_ptr packet) { - auto bytes = std::make_shared>(); - BitInserter i(*bytes); - bytes->reserve(packet->size()); - packet->Serialize(i); - return packet::PacketView(bytes); -} - } // namespace namespace { -class TestHciLayer : public HciLayer { +class HciLayerFakeForController : public HciLayerFake { public: void EnqueueCommand( std::unique_ptr command, common::ContextualOnceCallback on_complete) override { GetHandler()->Post(common::BindOnce( - &TestHciLayer::HandleCommand, common::Unretained(this), std::move(command), std::move(on_complete))); + &HciLayerFakeForController::HandleCommand, + common::Unretained(this), + std::move(command), + std::move(on_complete))); } void EnqueueCommand( @@ -80,7 +80,11 @@ class TestHciLayer : public HciLayer { void HandleCommand( std::unique_ptr command_builder, common::ContextualOnceCallback on_complete) { - auto packet_view = GetPacketView(std::move(command_builder)); + auto bytes = std::make_shared>(); + BitInserter i(*bytes); + bytes->reserve((command_builder)->size()); + command_builder->Serialize(i); + auto packet_view = packet::PacketView(bytes); CommandView command = CommandView::Create(packet_view); ASSERT_TRUE(command.IsValid()); @@ -170,24 +174,50 @@ class TestHciLayer : public HciLayer { event_builder = LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, 0xF0); } break; - case (OpCode::LE_GET_VENDOR_CAPABILITIES): { - BaseVendorCapabilities base_vendor_capabilities; - base_vendor_capabilities.max_advt_instances_ = 0x10; - base_vendor_capabilities.offloaded_resolution_of_private_address_ = 0x01; - base_vendor_capabilities.total_scan_results_storage_ = 0x2800; - base_vendor_capabilities.max_irk_list_sz_ = 0x20; - base_vendor_capabilities.filtering_support_ = 0x01; - base_vendor_capabilities.max_filter_ = 0x10; - base_vendor_capabilities.activity_energy_info_support_ = 0x01; - - auto payload = std::make_unique(); - if (feature_spec_version > 55) { - std::vector payload_bytes = {0x20, 0x00, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00}; - payload->AddOctets2(feature_spec_version); - payload->AddOctets(payload_bytes); + case (OpCode::LE_GET_VENDOR_CAPABILITIES): + if (vendor_capabilities_ == nullptr) { + BaseVendorCapabilities base_vendor_capabilities; + base_vendor_capabilities.max_advt_instances_ = 0x10; + base_vendor_capabilities.offloaded_resolution_of_private_address_ = 0x01; + base_vendor_capabilities.total_scan_results_storage_ = 0x2800; + base_vendor_capabilities.max_irk_list_sz_ = 0x20; + base_vendor_capabilities.filtering_support_ = 0x01; + base_vendor_capabilities.max_filter_ = 0x10; + base_vendor_capabilities.activity_energy_info_support_ = 0x01; + + auto payload = std::make_unique(); + if (feature_spec_version > 55) { + std::vector payload_bytes = { + 0x20, 0x00, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00}; + payload->AddOctets2(feature_spec_version); + payload->AddOctets(payload_bytes); + } + event_builder = LeGetVendorCapabilitiesCompleteBuilder::Create( + num_packets, ErrorCode::SUCCESS, base_vendor_capabilities, std::move(payload)); + } else { + event_builder = std::move(vendor_capabilities_); + vendor_capabilities_.reset(); + } + break; + case (OpCode::DYNAMIC_AUDIO_BUFFER): { + auto dab_command = + DynamicAudioBufferView::CreateOptional(VendorCommandView::Create(command)); + if (dab_command->GetDabCommand() == DabCommand::GET_AUDIO_BUFFER_TIME_CAPABILITY) { + std::array capabilities{}; + capabilities[0] = + DynamicAudioBufferCodecCapability(0x123, 0x103, 0x1234); // sbc_capabilities + capabilities[1] = + DynamicAudioBufferCodecCapability(0x223, 0x123, 0x2340); // aac_capabilities + capabilities[4] = + DynamicAudioBufferCodecCapability(0x323, 0x223, 0x3456); // ldac_capabilities + event_builder = DabGetAudioBufferTimeCapabilityCompleteBuilder::Create( + 1, ErrorCode::SUCCESS, kDynamicAudioBufferSupport, capabilities); + } else { + auto set_command = DabSetAudioBufferTimeView::CreateOptional(*dab_command); + dynamic_audio_buffer_time = set_command->GetBufferTimeMs(); + event_builder = DabSetAudioBufferTimeCompleteBuilder::Create( + 1, ErrorCode::SUCCESS, dynamic_audio_buffer_time); } - event_builder = LeGetVendorCapabilitiesCompleteBuilder::Create( - num_packets, ErrorCode::SUCCESS, base_vendor_capabilities, std::move(payload)); } break; case (OpCode::SET_EVENT_MASK): { auto view = SetEventMaskView::Create(command); @@ -208,14 +238,15 @@ class TestHciLayer : public HciLayer { event_builder = LeRandCompleteBuilder::Create(num_packets, ErrorCode::SUCCESS, kRandomNumber); } break; + // Let the test check and handle these commands. case (OpCode::RESET): case (OpCode::SET_EVENT_FILTER): case (OpCode::HOST_BUFFER_SIZE): - command_queue_.push(command); - not_empty_.notify_all(); + HciLayerFake::EnqueueCommand(std::move(command_builder), std::move(on_complete)); return; + default: - LOG_INFO("Dropping unhandled packet"); + LOG_INFO("Dropping unhandled packet (%s)", OpCodeText(command.GetOpCode()).c_str()); return; } auto packet = GetPacketView(std::move(event_builder)); @@ -226,16 +257,6 @@ class TestHciLayer : public HciLayer { on_complete.Invoke(std::move(command_complete)); } - void RegisterEventHandler(EventCode event_code, common::ContextualCallback event_handler) override { - ASSERT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed"; - number_of_completed_packets_callback_ = event_handler; - } - - void UnregisterEventHandler(EventCode event_code) override { - ASSERT_EQ(event_code, EventCode::NUMBER_OF_COMPLETED_PACKETS) << "Only NUMBER_OF_COMPLETED_PACKETS is needed"; - number_of_completed_packets_callback_ = {}; - } - void IncomingCredit() { std::vector completed_packets; CompletedPackets cp; @@ -245,47 +266,17 @@ class TestHciLayer : public HciLayer { cp.host_num_of_completed_packets_ = kCredits2; cp.connection_handle_ = kHandle2; completed_packets.push_back(cp); - auto event_builder = NumberOfCompletedPacketsBuilder::Create(completed_packets); - auto packet = GetPacketView(std::move(event_builder)); - EventView event = EventView::Create(packet); - ASSERT_TRUE(event.IsValid()); - number_of_completed_packets_callback_.Invoke(event); - } - - CommandView GetCommand(OpCode /* op_code */) { - std::unique_lock lock(mutex_); - std::chrono::milliseconds time = std::chrono::milliseconds(3000); - - // wait for command - while (command_queue_.size() == 0UL) { - if (not_empty_.wait_for(lock, time) == std::cv_status::timeout) { - break; - } - } - if (command_queue_.empty()) { - return CommandView::Create(PacketView(std::make_shared>())); - } - CommandView command = command_queue_.front(); - command_queue_.pop(); - return command; + IncomingEvent(NumberOfCompletedPacketsBuilder::Create(completed_packets)); } - void ListDependencies(ModuleList* /* list */) const {} - void Start() override {} - void Stop() override {} - + std::unique_ptr vendor_capabilities_ = nullptr; constexpr static uint16_t acl_data_packet_length = 1024; constexpr static uint8_t synchronous_data_packet_length = 60; constexpr static uint16_t total_num_acl_data_packets = 10; constexpr static uint16_t total_num_synchronous_data_packets = 12; uint64_t event_mask = 0; uint64_t le_event_mask = 0; - - private: - common::ContextualCallback number_of_completed_packets_callback_; - std::queue command_queue_; - mutable std::mutex mutex_; - std::condition_variable not_empty_; + uint16_t dynamic_audio_buffer_time = 0; }; class ControllerTest : public ::testing::Test { @@ -293,7 +284,9 @@ class ControllerTest : public ::testing::Test { void SetUp() override { feature_spec_version = feature_spec_version_; bluetooth::common::InitFlags::SetAllForTesting(); - test_hci_layer_ = new TestHciLayer; + test_hci_layer_ = new HciLayerFakeForController; + test_hci_layer_->vendor_capabilities_ = std::move(vendor_capabilities_); + vendor_capabilities_.reset(); fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_); client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory); fake_registry_.Start(&thread_); @@ -305,11 +298,12 @@ class ControllerTest : public ::testing::Test { } TestModuleRegistry fake_registry_; - TestHciLayer* test_hci_layer_ = nullptr; + HciLayerFakeForController* test_hci_layer_ = nullptr; os::Thread& thread_ = fake_registry_.GetTestThread(); Controller* controller_ = nullptr; os::Handler* client_handler_ = nullptr; uint16_t feature_spec_version_ = 98; + std::unique_ptr vendor_capabilities_ = nullptr; }; } // namespace @@ -337,6 +331,65 @@ class Controller096Test : public ControllerTest { } }; +class Controller103Test : public ControllerTest { + protected: + void SetUp() override { + feature_spec_version_ = 0x100 + 0x03; + BaseVendorCapabilities base_vendor_capabilities; + base_vendor_capabilities.max_advt_instances_ = 0x10; + base_vendor_capabilities.offloaded_resolution_of_private_address_ = 0x01; + base_vendor_capabilities.total_scan_results_storage_ = 0x2800; + base_vendor_capabilities.max_irk_list_sz_ = 0x20; + base_vendor_capabilities.filtering_support_ = 0x01; + base_vendor_capabilities.max_filter_ = 0x10; + base_vendor_capabilities.activity_energy_info_support_ = 0x01; + vendor_capabilities_ = LeGetVendorCapabilitiesComplete103Builder::Create( + 1, + ErrorCode::SUCCESS, + base_vendor_capabilities, + feature_spec_version_, + 0x102, + /*extended_scan_support=*/1, + /*debug_logging_supported=*/1, + /*le_address_generation_offloading_support=*/0, + /*a2dp_source_offload_capability_mask=*/0x4, + /*bluetooth_quality_report_support=*/1, + kDynamicAudioBufferSupport, + std::make_unique()); + ControllerTest::SetUp(); + } +}; + +class Controller104Test : public ControllerTest { + protected: + void SetUp() override { + feature_spec_version_ = 0x100 + 0x04; + BaseVendorCapabilities base_vendor_capabilities; + base_vendor_capabilities.max_advt_instances_ = 0x10; + base_vendor_capabilities.offloaded_resolution_of_private_address_ = 0x01; + base_vendor_capabilities.total_scan_results_storage_ = 0x2800; + base_vendor_capabilities.max_irk_list_sz_ = 0x20; + base_vendor_capabilities.filtering_support_ = 0x01; + base_vendor_capabilities.max_filter_ = 0x10; + base_vendor_capabilities.activity_energy_info_support_ = 0x01; + vendor_capabilities_ = LeGetVendorCapabilitiesComplete104Builder::Create( + 1, + ErrorCode::SUCCESS, + base_vendor_capabilities, + feature_spec_version_, + 0x102, + /*extended_scan_support=*/1, + /*debug_logging_supported=*/1, + /*le_address_generation_offloading_support=*/0, + /*a2dp_source_offload_capability_mask=*/0x4, + /*bluetooth_quality_report_support=*/1, + kDynamicAudioBufferSupport, + /*a2dp_offload_v2_support=*/1, + std::make_unique()); + ControllerTest::SetUp(); + } +}; + TEST_F(ControllerTest, startup_teardown) {} TEST_F(ControllerTest, read_controller_info) { @@ -470,6 +523,64 @@ TEST_F(ControllerTest, feature_spec_version_098_test) { ASSERT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); } +TEST_F(ControllerTest, feature_spec_version_098_no_dab_test) { + ASSERT_FALSE(controller_->IsSupported(OpCode::DYNAMIC_AUDIO_BUFFER)); +} + +TEST_F(ControllerTest, set_dynamic_audio_buffer_time) { + controller_->SetDabAudioBufferTime(123); + thread_.GetReactor()->WaitForIdle(std::chrono::seconds(1)); + ASSERT_EQ(0, test_hci_layer_->dynamic_audio_buffer_time); +} + +TEST_F(Controller103Test, feature_spec_version_103_dab_test) { + ASSERT_EQ(controller_->GetVendorCapabilities().version_supported_, 0x100 + 3); + ASSERT_FALSE(controller_->GetVendorCapabilities().a2dp_offload_v2_support_); + ASSERT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); + ASSERT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); + ASSERT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); + ASSERT_TRUE(controller_->IsSupported(OpCode::DYNAMIC_AUDIO_BUFFER)); + ASSERT_EQ(controller_->GetDabSupportedCodecs(), kDynamicAudioBufferSupport); + for (size_t bit = 0; bit < 32; bit++) { + if (kDynamicAudioBufferSupport & (1u << bit)) { + ASSERT_GT(controller_->GetDabCodecCapabilities()[bit].maximum_time_ms_, 0) << " bit " << bit; + } else { + ASSERT_EQ(controller_->GetDabCodecCapabilities()[bit].maximum_time_ms_, 0); + ASSERT_EQ(controller_->GetDabCodecCapabilities()[bit].minimum_time_ms_, 0); + ASSERT_EQ(controller_->GetDabCodecCapabilities()[bit].default_time_ms_, 0); + } + } +} + +TEST_F(Controller103Test, set_dynamic_audio_buffer_time) { + controller_->SetDabAudioBufferTime(123); + thread_.GetReactor()->WaitForIdle(std::chrono::seconds(1)); + ASSERT_EQ(123, test_hci_layer_->dynamic_audio_buffer_time); +} + +TEST_F(Controller104Test, feature_spec_version_104_test) { + ASSERT_EQ(controller_->GetVendorCapabilities().version_supported_, 0x100 + 4); + if (IS_FLAG_ENABLED(a2dp_offload_codec_extensibility)) { + ASSERT_TRUE(controller_->GetVendorCapabilities().a2dp_offload_v2_support_); + } else { + ASSERT_FALSE(controller_->GetVendorCapabilities().a2dp_offload_v2_support_); + } + ASSERT_TRUE(controller_->IsSupported(OpCode::LE_MULTI_ADVT)); + ASSERT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_DEBUG_INFO)); + ASSERT_TRUE(controller_->IsSupported(OpCode::CONTROLLER_A2DP_OPCODE)); + ASSERT_TRUE(controller_->IsSupported(OpCode::DYNAMIC_AUDIO_BUFFER)); + ASSERT_EQ(controller_->GetDabSupportedCodecs(), kDynamicAudioBufferSupport); + for (size_t bit = 0; bit < 32; bit++) { + if (kDynamicAudioBufferSupport & (1u << bit)) { + ASSERT_GT(controller_->GetDabCodecCapabilities()[bit].maximum_time_ms_, 0) << " bit " << bit; + } else { + ASSERT_EQ(controller_->GetDabCodecCapabilities()[bit].maximum_time_ms_, 0); + ASSERT_EQ(controller_->GetDabCodecCapabilities()[bit].minimum_time_ms_, 0); + ASSERT_EQ(controller_->GetDabCodecCapabilities()[bit].default_time_ms_, 0); + } + } +} + std::promise credits1_set; std::promise credits2_set; @@ -532,10 +643,11 @@ TEST_F(ControllerTest, leRandTest) { } TEST_F(ControllerTest, Dumpsys) { - ModuleDumper dumper(fake_registry_, title); + ModuleDumper dumper(STDOUT_FILENO, fake_registry_, title); std::string output; - dumper.DumpState(&output); + std::ostringstream oss; + dumper.DumpState(&output, oss); ASSERT_TRUE(output.find("Hci Controller Dumpsys") != std::string::npos); } diff --git a/system/gd/hci/distance_measurement_manager.cc b/system/gd/hci/distance_measurement_manager.cc index b7379ca287adfe0bd8cb29e3f77d76cfe104c60e..e91107b3c5df5174fdec6e35d1c38de03d5f5af9 100644 --- a/system/gd/hci/distance_measurement_manager.cc +++ b/system/gd/hci/distance_measurement_manager.cc @@ -15,8 +15,10 @@ */ #include "hci/distance_measurement_manager.h" +#include #include +#include #include #include "common/strings.h" @@ -27,6 +29,8 @@ #include "module.h" #include "os/handler.h" #include "os/log.h" +#include "os/repeating_alarm.h" +#include "packet/packet_view.h" namespace bluetooth { namespace hci { @@ -54,8 +58,51 @@ static constexpr uint32_t kMinSubeventLen = 0x0004E2; // 1250us static constexpr uint32_t kMaxSubeventLen = 0x3d0900; // 4s static constexpr uint8_t kToneAntennaConfigSelection = 0x07; // 2x2 static constexpr uint8_t kTxPwrDelta = 0x00; +static constexpr uint8_t kProcedureDataBufferSize = 0x10; // Buffer size of Procedure data +static constexpr uint8_t kReportWithNoAbort = 0x00; struct DistanceMeasurementManager::impl { + struct CsProcedureData { + CsProcedureData(uint16_t procedure_counter, uint8_t num_antenna_paths) + : counter(procedure_counter), num_antenna_paths(num_antenna_paths) { + local_status = CsProcedureDoneStatus::PARTIAL_RESULTS; + remote_status = CsProcedureDoneStatus::PARTIAL_RESULTS; + // In ascending order of antenna position with tone extension data at the end + uint16_t num_tone_data = num_antenna_paths + 1; + for (uint8_t i = 0; i < num_tone_data; i++) { + std::vector> empty_complex_vector; + tone_pct_initiator.push_back(empty_complex_vector); + tone_pct_reflector.push_back(empty_complex_vector); + std::vector empty_vector; + tone_quality_indicator_initiator.push_back(empty_vector); + tone_quality_indicator_reflector.push_back(empty_vector); + } + } + // Procedure counter + uint16_t counter; + // Number of antenna paths (1 to 4) reported in the procedure + uint8_t num_antenna_paths; + // Frequency Compensation indicates fractional frequency offset (FFO) value of initiator, in + // 0.01ppm + std::vector frequency_compensation; + // The channel indices of every step in a CS procedure (in time order) + std::vector step_channel; + // Measured Frequency Offset from mode 0, relative to the remote device, in 0.01ppm + std::vector measured_freq_offset; + // Initiator's PCT (complex value) measured from mode-2 or mode-3 steps in a CS procedure (in + // time order) + std::vector>> tone_pct_initiator; + // Reflector's PCT (complex value) measured from mode-2 or mode-3 steps in a CS procedure (in + // time order) + std::vector>> tone_pct_reflector; + std::vector> tone_quality_indicator_initiator; + std::vector> tone_quality_indicator_reflector; + CsProcedureDoneStatus local_status; + CsProcedureDoneStatus remote_status; + // If the procedure is aborted by either the local or remote side. + bool aborted = false; + }; + ~impl() {} void start(os::Handler* handler, hci::HciLayer* hci_layer, hci::AclManager* acl_manager) { handler_ = handler; @@ -64,6 +111,10 @@ struct DistanceMeasurementManager::impl { hci_layer_->RegisterLeEventHandler( hci::SubeventCode::TRANSMIT_POWER_REPORTING, handler_->BindOn(this, &impl::on_transmit_power_reporting)); + if (!IS_FLAG_ENABLED(channel_sounding_in_stack)) { + LOG_INFO("IS_FLAG_ENABLED channel_sounding_in_stack: false"); + return; + } distance_measurement_interface_ = hci_layer_->GetDistanceMeasurementInterface( handler_->BindOn(this, &DistanceMeasurementManager::impl::handle_event)); distance_measurement_interface_->EnqueueCommand( @@ -80,7 +131,7 @@ struct DistanceMeasurementManager::impl { } void start_distance_measurement( - const Address& address, uint16_t frequency, DistanceMeasurementMethod method) { + const Address& address, uint16_t interval, DistanceMeasurementMethod method) { LOG_INFO("Address:%s, method:%d", ADDRESS_TO_LOGGABLE_CSTR(address), method); uint16_t connection_handle = acl_manager_->HACK_GetLeHandle(address); @@ -97,31 +148,38 @@ struct DistanceMeasurementManager::impl { case METHOD_RSSI: { if (rssi_trackers.find(address) == rssi_trackers.end()) { rssi_trackers[address].handle = connection_handle; - rssi_trackers[address].frequency = frequency; + rssi_trackers[address].interval_ms = interval; rssi_trackers[address].remote_tx_power = kTxPowerNotAvailable; rssi_trackers[address].started = false; - rssi_trackers[address].alarm = std::make_unique(handler_); + rssi_trackers[address].repeating_alarm = std::make_unique(handler_); hci_layer_->EnqueueCommand( LeReadRemoteTransmitPowerLevelBuilder::Create( acl_manager_->HACK_GetLeHandle(address), 0x01), handler_->BindOnceOn( this, &impl::on_read_remote_transmit_power_level_status, address)); } else { - rssi_trackers[address].frequency = frequency; + rssi_trackers[address].interval_ms = interval; } } break; case METHOD_CS: { - start_distance_measurement_with_cs(address, connection_handle); + start_distance_measurement_with_cs(address, connection_handle, interval); } break; } } void start_distance_measurement_with_cs( - const Address& cs_remote_address, uint16_t connection_handle) { + const Address& cs_remote_address, uint16_t connection_handle, uint16_t interval) { LOG_INFO( "connection_handle: %d, address: %s", connection_handle, ADDRESS_TO_LOGGABLE_CSTR(cs_remote_address)); + if (!IS_FLAG_ENABLED(channel_sounding_in_stack)) { + LOG_ERROR("Channel Sounding is not enabled"); + distance_measurement_callbacks_->OnDistanceMeasurementStartFail( + cs_remote_address, REASON_INTERNAL_ERROR, METHOD_CS); + return; + } + if (cs_trackers_.find(connection_handle) != cs_trackers_.end() && cs_trackers_[connection_handle].address != cs_remote_address) { LOG_WARN("Remove old tracker for %s ", ADDRESS_TO_LOGGABLE_CSTR(cs_remote_address)); @@ -133,13 +191,32 @@ struct DistanceMeasurementManager::impl { cs_trackers_[connection_handle].address = cs_remote_address; // TODO: Check ROLE via CS config. (b/304295768) cs_trackers_[connection_handle].role = CsRole::INITIATOR; + cs_trackers_[connection_handle].repeating_alarm = + std::make_unique(handler_); } + cs_trackers_[connection_handle].interval_ms = interval; + cs_trackers_[connection_handle].waiting_for_start_callback = true; if (!cs_trackers_[connection_handle].setup_complete) { send_le_cs_read_remote_supported_capabilities(connection_handle); - send_le_cs_set_default_settings(connection_handle); - send_le_cs_security_enable(connection_handle); + return; + } + if (!cs_trackers_[connection_handle].config_set) { + send_le_cs_create_config(connection_handle); + return; } + LOG_INFO( + "enable cs procedure regularly with interval: %d ms", + cs_trackers_[connection_handle].interval_ms); + cs_trackers_[connection_handle].repeating_alarm->Cancel(); + send_le_cs_procedure_enable(connection_handle, Enable::ENABLED); + cs_trackers_[connection_handle].repeating_alarm->Schedule( + common::Bind( + &impl::send_le_cs_procedure_enable, + common::Unretained(this), + connection_handle, + Enable::ENABLED), + std::chrono::milliseconds(cs_trackers_[connection_handle].interval_ms)); } void stop_distance_measurement(const Address& address, DistanceMeasurementMethod method) { @@ -154,8 +231,8 @@ struct DistanceMeasurementManager::impl { LeSetTransmitPowerReportingEnableBuilder::Create( rssi_trackers[address].handle, 0x00, 0x00), handler_->BindOnce(check_complete)); - rssi_trackers[address].alarm->Cancel(); - rssi_trackers[address].alarm.reset(); + rssi_trackers[address].repeating_alarm->Cancel(); + rssi_trackers[address].repeating_alarm.reset(); rssi_trackers.erase(address); } } break; @@ -164,13 +241,16 @@ struct DistanceMeasurementManager::impl { if (cs_trackers_.find(connection_handle) == cs_trackers_.end()) { LOG_WARN("Can't find CS tracker for %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); } else { + cs_trackers_[connection_handle].repeating_alarm->Cancel(); + cs_trackers_[connection_handle].repeating_alarm.reset(); + send_le_cs_procedure_enable(connection_handle, Enable::DISABLED); cs_trackers_.erase(connection_handle); } } break; } } - void read_rssi_regularly(const Address& address, uint16_t frequency) { + void send_read_rssi(const Address& address) { if (rssi_trackers.find(address) == rssi_trackers.end()) { LOG_WARN("Can't find rssi tracker for %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); return; @@ -181,8 +261,8 @@ struct DistanceMeasurementManager::impl { if (rssi_trackers.find(address) != rssi_trackers.end()) { distance_measurement_callbacks_->OnDistanceMeasurementStopped( address, REASON_NO_LE_CONNECTION, METHOD_RSSI); - rssi_trackers[address].alarm->Cancel(); - rssi_trackers[address].alarm.reset(); + rssi_trackers[address].repeating_alarm->Cancel(); + rssi_trackers[address].repeating_alarm.reset(); rssi_trackers.erase(address); } return; @@ -191,10 +271,6 @@ struct DistanceMeasurementManager::impl { hci_layer_->EnqueueCommand( ReadRssiBuilder::Create(connection_handle), handler_->BindOnceOn(this, &impl::on_read_rssi_complete, address)); - - rssi_trackers[address].alarm->Schedule( - common::BindOnce(&impl::read_rssi_regularly, common::Unretained(this), address, frequency), - std::chrono::milliseconds(rssi_trackers[address].frequency)); } void handle_event(LeMetaEventView event) { @@ -204,11 +280,13 @@ struct DistanceMeasurementManager::impl { } switch (event.GetSubeventCode()) { case hci::SubeventCode::LE_CS_TEST_END_COMPLETE: - case hci::SubeventCode::LE_CS_SUBEVENT_RESULT_CONTINUE: - case hci::SubeventCode::LE_CS_SUBEVENT_RESULT: case hci::SubeventCode::LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE: { LOG_WARN("Unhandled subevent %s", hci::SubeventCodeText(event.GetSubeventCode()).c_str()); } break; + case hci::SubeventCode::LE_CS_SUBEVENT_RESULT_CONTINUE: + case hci::SubeventCode::LE_CS_SUBEVENT_RESULT: { + on_cs_subevent(event); + } break; case hci::SubeventCode::LE_CS_PROCEDURE_ENABLE_COMPLETE: { on_cs_procedure_enable_complete(LeCsProcedureEnableCompleteView::Create(event)); } break; @@ -227,12 +305,6 @@ struct DistanceMeasurementManager::impl { } } - void send_le_cs_read_local_supported_capabilities() { - hci_layer_->EnqueueCommand( - LeCsReadLocalSupportedCapabilitiesBuilder::Create(), - handler_->BindOnceOn(this, &impl::on_cs_read_local_supported_capabilities)); - } - void send_le_cs_read_remote_supported_capabilities(uint16_t connection_handle) { hci_layer_->EnqueueCommand( LeCsReadRemoteSupportedCapabilitiesBuilder::Create(connection_handle), @@ -305,6 +377,22 @@ struct DistanceMeasurementManager::impl { } void send_le_cs_procedure_enable(uint16_t connection_handle, Enable enable) { + if (cs_trackers_.find(connection_handle) == cs_trackers_.end()) { + LOG_WARN("Can't find cs tracker for connection %d", connection_handle); + return; + } + Address address = cs_trackers_[connection_handle].address; + // Check if the connection still exists + uint16_t connection_handle_from_acl_manager = acl_manager_->HACK_GetLeHandle(address); + if (connection_handle_from_acl_manager == kIllegalConnectionHandle) { + LOG_WARN("Can't find connection for %s ", ADDRESS_TO_LOGGABLE_CSTR(address)); + distance_measurement_callbacks_->OnDistanceMeasurementStopped( + address, REASON_NO_LE_CONNECTION, METHOD_CS); + cs_trackers_[connection_handle].repeating_alarm->Cancel(); + cs_trackers_[connection_handle].repeating_alarm.reset(); + cs_trackers_.erase(connection_handle); + return; + } hci_layer_->EnqueueCommand( LeCsProcedureEnableBuilder::Create(connection_handle, kConfigId, enable), handler_->BindOnce(check_status)); @@ -341,11 +429,13 @@ struct DistanceMeasurementManager::impl { return; } uint16_t connection_handle = event_view.GetConnectionHandle(); + send_le_cs_set_default_settings(event_view.GetConnectionHandle()); if (cs_trackers_.find(connection_handle) == cs_trackers_.end()) { // Create a cs tracker with role reflector // TODO: Check ROLE via CS config. (b/304295768) cs_trackers_[connection_handle].role = CsRole::REFLECTOR; - send_le_cs_set_default_settings(event_view.GetConnectionHandle()); + } else { + send_le_cs_security_enable(connection_handle); } if (event_view.GetOptionalSubfeaturesSupported().phase_based_ranging_ == 0x01) { @@ -444,23 +534,329 @@ struct DistanceMeasurementManager::impl { } if (cs_trackers_[connection_handle].role == CsRole::INITIATOR) { - send_le_cs_procedure_enable(complete_view.GetConnectionHandle(), Enable::ENABLED); + LOG_INFO( + "enable cs procedure regularly with interval: %d ms", + cs_trackers_[connection_handle].interval_ms); + cs_trackers_[connection_handle].repeating_alarm->Cancel(); + send_le_cs_procedure_enable(connection_handle, Enable::ENABLED); + cs_trackers_[connection_handle].repeating_alarm->Schedule( + common::Bind( + &impl::send_le_cs_procedure_enable, + common::Unretained(this), + connection_handle, + Enable::ENABLED), + std::chrono::milliseconds(cs_trackers_[connection_handle].interval_ms)); } } void on_cs_procedure_enable_complete(LeCsProcedureEnableCompleteView event_view) { - if (!event_view.IsValid()) { - LOG_WARN("Get invalid LeCsProcedureEnableCompleteView"); - return; - } else if (event_view.GetStatus() != ErrorCode::SUCCESS) { + ASSERT(event_view.IsValid()); + uint16_t connection_handle = event_view.GetConnectionHandle(); + if (event_view.GetStatus() != ErrorCode::SUCCESS) { std::string error_code = ErrorCodeText(event_view.GetStatus()); LOG_WARN("Received LeCsProcedureEnableCompleteView with error code %s", error_code.c_str()); + if (cs_trackers_.find(connection_handle) != cs_trackers_.end() && + cs_trackers_[connection_handle].waiting_for_start_callback) { + cs_trackers_[connection_handle].waiting_for_start_callback = false; + distance_measurement_callbacks_->OnDistanceMeasurementStartFail( + cs_trackers_[connection_handle].address, REASON_INTERNAL_ERROR, METHOD_CS); + } return; } if (event_view.GetState() == Enable::ENABLED) { - LOG_INFO("Procedure enabled, %s", event_view.ToString().c_str()); + LOG_DEBUG("Procedure enabled, %s", event_view.ToString().c_str()); + if (cs_trackers_.find(connection_handle) != cs_trackers_.end() && + cs_trackers_[connection_handle].waiting_for_start_callback) { + cs_trackers_[connection_handle].waiting_for_start_callback = false; + distance_measurement_callbacks_->OnDistanceMeasurementStarted( + cs_trackers_[connection_handle].address, METHOD_CS); + } + } + } + + void on_cs_subevent(LeMetaEventView event) { + if (!event.IsValid()) { + LOG_ERROR("Received invalid LeMetaEventView"); + return; + } + + // Common data for LE_CS_SUBEVENT_RESULT and LE_CS_SUBEVENT_RESULT_CONTINUE, + uint16_t connection_handle = 0; + uint8_t abort_reason = kReportWithNoAbort; + CsProcedureDoneStatus procedure_done_status; + CsSubeventDoneStatus subevent_done_status; + std::vector result_data_structures; + if (event.GetSubeventCode() == SubeventCode::LE_CS_SUBEVENT_RESULT) { + auto cs_event_result = LeCsSubeventResultView::Create(event); + if (!cs_event_result.IsValid()) { + LOG_WARN("Get invalid LeCsSubeventResultView"); + return; + } + connection_handle = cs_event_result.GetConnectionHandle(); + abort_reason = cs_event_result.GetAbortReason(); + procedure_done_status = cs_event_result.GetProcedureDoneStatus(); + subevent_done_status = cs_event_result.GetSubeventDoneStatus(); + result_data_structures = cs_event_result.GetResultDataStructures(); + init_cs_procedure_data( + connection_handle, + cs_event_result.GetProcedureCounter(), + cs_event_result.GetNumAntennaPaths(), + true); + CsProcedureData* procedure_data = + get_procedure_data(connection_handle, cs_event_result.GetProcedureCounter()); + if (procedure_data != nullptr && cs_trackers_[connection_handle].role == CsRole::INITIATOR) { + procedure_data->frequency_compensation.push_back( + cs_event_result.GetFrequencyCompensation()); + } + } else { + auto cs_event_result = LeCsSubeventResultContinueView::Create(event); + if (!cs_event_result.IsValid()) { + LOG_WARN("Get invalid LeCsSubeventResultContinueView"); + return; + } + connection_handle = cs_event_result.GetConnectionHandle(); + abort_reason = cs_event_result.GetAbortReason(); + procedure_done_status = cs_event_result.GetProcedureDoneStatus(); + subevent_done_status = cs_event_result.GetSubeventDoneStatus(); + result_data_structures = cs_event_result.GetResultDataStructures(); + } + + uint16_t counter = cs_trackers_[connection_handle].local_counter; + LOG_DEBUG( + "Connection_handle %d, procedure_done_status: %s, subevent_done_status: %s, " + "counter: " + "%d", + connection_handle, + CsProcedureDoneStatusText(procedure_done_status).c_str(), + CsSubeventDoneStatusText(subevent_done_status).c_str(), + counter); + + if (procedure_done_status == CsProcedureDoneStatus::ABORTED || + subevent_done_status == CsSubeventDoneStatus::ABORTED) { + LOG_WARN( + "Received CS Subevent with abort reason: %02x, connection_handle:%d, counter:%d", + abort_reason, + connection_handle, + counter); + } + + CsProcedureData* procedure_data = get_procedure_data(connection_handle, counter); + if (procedure_data == nullptr) { + return; + } + + if (abort_reason != kReportWithNoAbort) { + // Even the procedure is aborted, we should keep following process and + // handle it when all corresponding remote data received. + procedure_data->aborted = true; + } else { + parse_cs_result_data( + result_data_structures, *procedure_data, cs_trackers_[connection_handle].role); + } + // Update procedure status + procedure_data->local_status = procedure_done_status; + check_cs_procedure_complete(procedure_data, connection_handle); + } + + void init_cs_procedure_data( + uint16_t connection_handle, + uint16_t procedure_counter, + uint8_t num_antenna_paths, + bool local) { + if (cs_trackers_.find(connection_handle) == cs_trackers_.end()) { + LOG_WARN("Can't find any tracker for %d", connection_handle); + return; + } + // Update procedure count + if (local) { + cs_trackers_[connection_handle].local_counter = procedure_counter; + } else { + cs_trackers_[connection_handle].remote_counter = procedure_counter; + } + + std::vector& data_list = cs_trackers_[connection_handle].procedure_data_list; + for (CsProcedureData procedure_data : data_list) { + if (procedure_data.counter == procedure_counter) { + // Data already exist, return + return; + } + } + LOG_INFO("Create data for procedure_counter: %d", procedure_counter); + data_list.emplace_back(procedure_counter, num_antenna_paths); + + if (data_list.size() > kProcedureDataBufferSize) { + LOG_WARN("buffer full, drop procedure data with counter: %d", data_list.front().counter); + data_list.erase(data_list.begin()); + } + } + + CsProcedureData* get_procedure_data(uint16_t connection_handle, uint16_t counter) { + std::vector& data_list = cs_trackers_[connection_handle].procedure_data_list; + CsProcedureData* procedure_data = nullptr; + for (uint8_t i = 0; i < data_list.size(); i++) { + if (data_list[i].counter == counter) { + procedure_data = &data_list[i]; + break; + } + } + if (procedure_data == nullptr) { + LOG_WARN("Can't find data for connection_handle:%d, counter: %d", connection_handle, counter); + } + return procedure_data; + } + + void check_cs_procedure_complete(CsProcedureData* procedure_data, uint16_t connection_handle) { + if (procedure_data->local_status == CsProcedureDoneStatus::ALL_RESULTS_COMPLETE && + procedure_data->remote_status == CsProcedureDoneStatus::ALL_RESULTS_COMPLETE && + !procedure_data->aborted) { + LOG_DEBUG( + "Procedure complete counter:%d data size:%d, main_mode_type:%d, sub_mode_type:%d", + (uint16_t)procedure_data->counter, + (uint16_t)procedure_data->step_channel.size(), + (uint16_t)cs_trackers_[connection_handle].main_mode_type, + (uint16_t)cs_trackers_[connection_handle].sub_mode_type); + } + + // If the procedure is completed or aborted, delete all previous data + if (procedure_data->local_status != CsProcedureDoneStatus::PARTIAL_RESULTS && + procedure_data->remote_status != CsProcedureDoneStatus::PARTIAL_RESULTS) { + std::vector& data_list = cs_trackers_[connection_handle].procedure_data_list; + while (data_list.begin()->counter != procedure_data->counter) { + LOG_DEBUG("Delete obsolete procedure data, counter:%d", data_list.begin()->counter); + data_list.erase(data_list.begin()); + } + } + } + + void parse_cs_result_data( + std::vector result_data_structures, + CsProcedureData& procedure_data, + CsRole role) { + uint8_t num_antenna_paths = procedure_data.num_antenna_paths; + for (auto result_data_structure : result_data_structures) { + uint16_t mode = result_data_structure.step_mode_; + uint16_t step_channel = result_data_structure.step_channel_; + LOG_VERBOSE( + "mode: %d, channel: %d, data_length: %d", + mode, + step_channel, + (uint16_t)result_data_structure.step_data_.size()); + + // Parse data into structs from an iterator + auto bytes = std::make_shared>(); + if (mode == 0x02 || mode == 0x03) { + // Add one byte for the length of Tone_PCT[k], Tone_Quality_Indicator[k] + bytes->emplace_back(num_antenna_paths + 1); + } + bytes->reserve(bytes->size() + result_data_structure.step_data_.size()); + bytes->insert( + bytes->end(), + result_data_structure.step_data_.begin(), + result_data_structure.step_data_.end()); + Iterator iterator(bytes); + switch (mode) { + case 0: { + if (role == CsRole::INITIATOR) { + LeCsMode0InitatorData tone_data_view; + auto after = LeCsMode0InitatorData::Parse(&tone_data_view, iterator); + if (after == iterator) { + LOG_WARN("Received invalid mode %d data, role:%s", mode, CsRoleText(role).c_str()); + print_raw_data(result_data_structure.step_data_); + continue; + } + LOG_VERBOSE("step_data: %s", tone_data_view.ToString().c_str()); + procedure_data.measured_freq_offset.push_back(tone_data_view.measured_freq_offset_); + } else { + LeCsMode0ReflectorData tone_data_view; + auto after = LeCsMode0ReflectorData::Parse(&tone_data_view, iterator); + if (after == iterator) { + LOG_WARN("Received invalid mode %d data, role:%s", mode, CsRoleText(role).c_str()); + print_raw_data(result_data_structure.step_data_); + continue; + } + LOG_VERBOSE("step_data: %s", tone_data_view.ToString().c_str()); + } + } break; + case 2: { + LeCsMode2Data tone_data_view; + auto after = LeCsMode2Data::Parse(&tone_data_view, iterator); + if (after == iterator) { + LOG_WARN("Received invalid mode %d data, role:%s", mode, CsRoleText(role).c_str()); + print_raw_data(result_data_structure.step_data_); + continue; + } + LOG_VERBOSE("step_data: %s", tone_data_view.ToString().c_str()); + if (role == CsRole::INITIATOR) { + procedure_data.step_channel.push_back(step_channel); + } + auto tone_data = tone_data_view.tone_data_; + uint8_t permutation_index = tone_data_view.antenna_permutation_index_; + // Parse in ascending order of antenna position with tone extension data at the end + uint16_t num_tone_data = num_antenna_paths + 1; + for (uint16_t k = 0; k < num_tone_data; k++) { + uint8_t antenna_path = k == num_antenna_paths + ? num_antenna_paths + : cs_antenna_permutation_array_[permutation_index][k] - 1; + double i_value = get_iq_value(tone_data[k].i_sample_); + double q_value = get_iq_value(tone_data[k].q_sample_); + uint8_t tone_quality_indicator = tone_data[k].tone_quality_indicator_; + LOG_VERBOSE("antenna_path %d, %f, %f", (uint16_t)(antenna_path + 1), i_value, q_value); + if (role == CsRole::INITIATOR) { + procedure_data.tone_pct_initiator[antenna_path].emplace_back(i_value, q_value); + procedure_data.tone_quality_indicator_initiator[antenna_path].emplace_back( + tone_quality_indicator); + } else { + procedure_data.tone_pct_reflector[antenna_path].emplace_back(i_value, q_value); + procedure_data.tone_quality_indicator_reflector[antenna_path].emplace_back( + tone_quality_indicator); + } + } + } break; + case 1: + case 3: + LOG_DEBUG("Unsupported mode: %d ", mode); + break; + default: { + LOG_WARN("Invalid mode %d ", mode); + } + } + } + } + + double get_iq_value(uint16_t sample) { + int16_t signed_sample = convert_to_signed(sample, 12); + double value = 1.0 * signed_sample / 2048; + return value; + } + + int16_t convert_to_signed(uint16_t num_unsigned, uint8_t bits) { + unsigned msb_mask = 1 << (bits - 1); // setup a mask for most significant bit + int16_t num_signed = num_unsigned; + if ((num_signed & msb_mask) != 0) { + num_signed |= ~(msb_mask - 1); // extend the MSB + } + return num_signed; + } + + void print_raw_data(std::vector raw_data) { + std::string raw_data_str = ""; + auto for_end = raw_data.size() - 1; + for (size_t i = 0; i < for_end; i++) { + char buff[10]; + snprintf(buff, sizeof(buff), "%02x ", (uint8_t)raw_data[i]); + std::string buffAsStdStr = buff; + raw_data_str.append(buffAsStdStr); + if (i % 100 == 0 && i != 0) { + LOG_VERBOSE("%s", raw_data_str.c_str()); + raw_data_str = ""; + } } + char buff[10]; + snprintf(buff, sizeof(buff), "%02x", (uint8_t)raw_data[for_end]); + std::string buffAsStdStr = buff; + raw_data_str.append(buffAsStdStr); + LOG_VERBOSE("%s", raw_data_str.c_str()); } void on_read_remote_transmit_power_level_status(Address address, CommandStatusView view) { @@ -557,7 +953,9 @@ struct DistanceMeasurementManager::impl { LOG_INFO("Track rssi for address %s", ADDRESS_TO_LOGGABLE_CSTR(address)); rssi_trackers[address].started = true; distance_measurement_callbacks_->OnDistanceMeasurementStarted(address, METHOD_RSSI); - read_rssi_regularly(address, rssi_trackers[address].frequency); + rssi_trackers[address].repeating_alarm->Schedule( + common::Bind(&impl::send_read_rssi, common::Unretained(this), address), + std::chrono::milliseconds(rssi_trackers[address].interval_ms)); } } @@ -588,10 +986,10 @@ struct DistanceMeasurementManager::impl { struct RSSITracker { uint16_t handle; - uint16_t frequency; + uint16_t interval_ms; uint8_t remote_tx_power; bool started; - std::unique_ptr alarm; + std::unique_ptr repeating_alarm; }; struct CsTracker { @@ -605,6 +1003,10 @@ struct DistanceMeasurementManager::impl { CsSubModeType sub_mode_type; CsRttType rtt_type; bool remote_support_phase_based_ranging = false; + std::vector procedure_data_list; + uint16_t interval_ms; + bool waiting_for_start_callback = false; + std::unique_ptr repeating_alarm; }; os::Handler* handler_; @@ -616,6 +1018,12 @@ struct DistanceMeasurementManager::impl { std::unordered_map cs_trackers_; DistanceMeasurementCallbacks* distance_measurement_callbacks_; CsOptionalSubfeaturesSupported cs_subfeature_supported_; + // Antenna path permutations. See Channel Sounding CR_PR for the details. + uint8_t cs_antenna_permutation_array_[24][4] = { + {1, 2, 3, 4}, {2, 1, 3, 4}, {1, 3, 2, 4}, {3, 1, 2, 4}, {3, 2, 1, 4}, {2, 3, 1, 4}, + {1, 2, 4, 3}, {2, 1, 4, 3}, {1, 4, 2, 3}, {4, 1, 2, 3}, {4, 2, 1, 3}, {2, 4, 1, 3}, + {1, 4, 3, 2}, {4, 1, 3, 2}, {1, 3, 4, 2}, {3, 1, 4, 2}, {3, 4, 1, 2}, {4, 3, 1, 2}, + {4, 2, 3, 1}, {2, 4, 3, 1}, {4, 3, 2, 1}, {3, 4, 2, 1}, {3, 2, 4, 1}, {2, 3, 4, 1}}; }; DistanceMeasurementManager::DistanceMeasurementManager() { @@ -647,8 +1055,8 @@ void DistanceMeasurementManager::RegisterDistanceMeasurementCallbacks( } void DistanceMeasurementManager::StartDistanceMeasurement( - const Address& address, uint16_t frequency, DistanceMeasurementMethod method) { - CallOn(pimpl_.get(), &impl::start_distance_measurement, address, frequency, method); + const Address& address, uint16_t interval, DistanceMeasurementMethod method) { + CallOn(pimpl_.get(), &impl::start_distance_measurement, address, interval, method); } void DistanceMeasurementManager::StopDistanceMeasurement( diff --git a/system/gd/hci/distance_measurement_manager.h b/system/gd/hci/distance_measurement_manager.h index 2dd2a1b4cb9e331f7428978b23cbaec3a4c41690..edcc2b0891917213af1a40220bf858281596cb97 100644 --- a/system/gd/hci/distance_measurement_manager.h +++ b/system/gd/hci/distance_measurement_manager.h @@ -73,7 +73,7 @@ class DistanceMeasurementManager : public bluetooth::Module { void RegisterDistanceMeasurementCallbacks(DistanceMeasurementCallbacks* callbacks); void StartDistanceMeasurement( - const Address&, uint16_t frequency, DistanceMeasurementMethod method); + const Address&, uint16_t interval, DistanceMeasurementMethod method); void StopDistanceMeasurement(const Address& address, DistanceMeasurementMethod method); static const ModuleFactory Factory; diff --git a/system/gd/hci/facade/acl_manager_facade.cc b/system/gd/hci/facade/acl_manager_facade.cc index 94269fe4e2fc45ac16cd82c0c09dfd4086d3f77e..4dcddb868f8c44db4b648de1e5b1e0f7e35c7e9c 100644 --- a/system/gd/hci/facade/acl_manager_facade.cc +++ b/system/gd/hci/facade/acl_manager_facade.cc @@ -397,14 +397,6 @@ class AclManagerFacadeService : public AclManagerFacade::Service, public Connect current_connection_request_++; } - void HACK_OnEscoConnectRequest(Address /* address */, ClassOfDevice /* cod */) override { - LOG_ERROR("Remote ESCO connect request unimplemented"); - } - - void HACK_OnScoConnectRequest(Address /* address */, ClassOfDevice /* cod */) override { - LOG_ERROR("Remote SCO connect request unimplemented"); - } - class Connection : public ConnectionManagementCallbacks { public: Connection( diff --git a/system/gd/hci/fuzz/fuzz_hci_layer.cc b/system/gd/hci/fuzz/fuzz_hci_layer.cc index 902ba547bf8f1092910b0591ba9a12e81e5468f2..38fd22a7fb6bb84a4022aaab54d91f95b45dbbce 100644 --- a/system/gd/hci/fuzz/fuzz_hci_layer.cc +++ b/system/gd/hci/fuzz/fuzz_hci_layer.cc @@ -15,7 +15,9 @@ */ #include "hci/fuzz/fuzz_hci_layer.h" + #include "fuzz/helpers.h" +#include "hci/class_of_device.h" namespace bluetooth { namespace hci { @@ -38,6 +40,7 @@ hci::LeSecurityInterface* FuzzHciLayer::GetLeSecurityInterface( hci::AclConnectionInterface* FuzzHciLayer::GetAclConnectionInterface( ContextualCallback /* event_handler */, ContextualCallback /* on_disconnect */, + ContextualCallback /* on_connection_request */, ContextualCallback + +#include + +#include "fuzz/helpers.h" +#include "hci/class_of_device.h" #include "hci/command_interface.h" #include "hci/hci_layer.h" #include "os/fuzz/dev_null_queue.h" #include "os/fuzz/fuzz_inject_queue.h" #include "os/log.h" -#include -#include "fuzz/helpers.h" - namespace bluetooth { namespace hci { namespace fuzz { @@ -112,8 +115,10 @@ class FuzzHciLayer : public HciLayer { hci::AclConnectionInterface* GetAclConnectionInterface( common::ContextualCallback event_handler, common::ContextualCallback on_disconnect, - common::ContextualCallback - on_read_remote_version) override; + common::ContextualCallback on_connection_request, + common::ContextualCallback on_read_remote_version) + override; void PutAclConnectionInterface() override {} hci::LeAclConnectionInterface* GetLeAclConnectionInterface( diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_client.cc b/system/gd/hci/fuzz/hci_layer_fuzz_client.cc index fa51a2cdf25ec9b7fa5a3afd431712b5d64495c2..0a6dfa5b6dab64dbaef8e7fdbb62cc523c4db10e 100644 --- a/system/gd/hci/fuzz/hci_layer_fuzz_client.cc +++ b/system/gd/hci/fuzz/hci_layer_fuzz_client.cc @@ -15,7 +15,9 @@ */ #include "hci/fuzz/hci_layer_fuzz_client.h" + #include "fuzz/helpers.h" +#include "hci/class_of_device.h" namespace bluetooth { namespace hci { @@ -37,6 +39,7 @@ void HciLayerFuzzClient::Start() { acl_connection_interface_ = hci_->GetAclConnectionInterface( GetHandler()->Bind([](EventView) {}), GetHandler()->Bind([](uint16_t, hci::ErrorCode) {}), + GetHandler()->Bind([](Address, ClassOfDevice) {}), GetHandler()->Bind([](hci::ErrorCode, uint16_t, uint8_t, uint16_t, uint16_t) {})); le_acl_connection_interface_ = hci_->GetLeAclConnectionInterface( GetHandler()->Bind([](LeMetaEventView) {}), diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_client.h b/system/gd/hci/fuzz/hci_layer_fuzz_client.h index c2151bf652c452296c9adf7c419f6a061fdea14d..144f65063b9dadfc63d01b9cdf602fc1dcc4f02f 100644 --- a/system/gd/hci/fuzz/hci_layer_fuzz_client.h +++ b/system/gd/hci/fuzz/hci_layer_fuzz_client.h @@ -16,8 +16,12 @@ #pragma once +#include #include #include + +#include + #include "hci/fuzz/status_vs_complete_commands.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" @@ -25,8 +29,6 @@ #include "os/fuzz/dev_null_queue.h" #include "os/fuzz/fuzz_inject_queue.h" -#include - namespace bluetooth { namespace hci { namespace fuzz { diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc index 60d9bab4336fc8bd09440c8b23f134f99d5a8c1a..8288f628cdaa95c04b0704b2b0089c0307658730 100644 --- a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc +++ b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc @@ -31,28 +31,22 @@ using bluetooth::fuzz::GetArbitraryBytes; using bluetooth::hal::HciHal; using bluetooth::hal::fuzz::FuzzHciHal; using bluetooth::hci::fuzz::HciLayerFuzzClient; -using bluetooth::os::fake_timer::fake_timerfd_advance; -using bluetooth::os::fake_timer::fake_timerfd_cap_at; using bluetooth::os::fake_timer::fake_timerfd_reset; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider dataProvider(data, size); - fake_timerfd_cap_at(1999); // prevent command timeouts static FuzzTestModuleRegistry moduleRegistry = FuzzTestModuleRegistry(); FuzzHciHal* fuzzHal = moduleRegistry.Inject(&HciHal::Factory); HciLayerFuzzClient* fuzzClient = moduleRegistry.Start(); while (dataProvider.remaining_bytes() > 0) { - const uint8_t action = dataProvider.ConsumeIntegralInRange(0, 5); + const uint8_t action = dataProvider.ConsumeIntegralInRange(1, 2); switch (action) { case 1: - fake_timerfd_advance(dataProvider.ConsumeIntegral()); - break; - case 2: fuzzHal->injectArbitrary(dataProvider); break; - case 3: + case 2: fuzzClient->injectArbitrary(dataProvider); break; } diff --git a/system/gd/hci/hci_controller.fbs b/system/gd/hci/hci_controller.fbs index ce142b6687965a82d5ffefd3d19492877345f213..b5547090a448ccbdea669be67b4e4761c871b1c0 100644 --- a/system/gd/hci/hci_controller.fbs +++ b/system/gd/hci/hci_controller.fbs @@ -52,7 +52,7 @@ table ControllerData { sco_buffer_size : BufferSizeData (privacy:"Any"); iso_buffer_size : BufferSizeData (privacy:"Any"); le_buffer_size : BufferSizeData (privacy:"Any"); - le_connect_list_size : uint64 (privacy:"Any"); + le_accept_list_size : uint64 (privacy:"Any"); le_resolving_list_size : uint64 (privacy:"Any"); le_maximum_data_length : LeMaximumDataLengthData (privacy:"Any"); le_maximum_advertising_data_length : ushort (privacy:"Any"); diff --git a/system/gd/hci/hci_layer.cc b/system/gd/hci/hci_layer.cc index 0b61fd4a4a19f6b9703b4d1c3b85232dd62ef8f1..d91bb1480d79d983dfd9286753c8999c0ffa931e 100644 --- a/system/gd/hci/hci_layer.cc +++ b/system/gd/hci/hci_layer.cc @@ -16,9 +16,14 @@ #include "hci/hci_layer.h" +#ifdef TARGET_FLOSS +#include +#endif + #include "common/bind.h" #include "common/init_flags.h" #include "common/stop_watch.h" +#include "hci/class_of_device.h" #include "hci/hci_metrics_logging.h" #include "os/alarm.h" #include "os/metrics.h" @@ -222,6 +227,24 @@ struct HciLayer::impl { } } +#ifdef TARGET_FLOSS + // Although UNKNOWN_CONNECTION might be a controller issue in some command status, we treat it + // as a disconnect event to maintain consistent connection state between stack and controller + // since there might not be further HCI Disconnect Event after this status event. + // Currently only do this on LE_READ_REMOTE_FEATURES because it is the only one we know that + // would return UNKNOWN_CONNECTION in some cases. + if (op_code == OpCode::LE_READ_REMOTE_FEATURES && is_status && status_view.IsValid() && + status_view.GetStatus() == ErrorCode::UNKNOWN_CONNECTION) { + auto& command_view = *command_queue_.front().command_view; + auto le_read_features_view = bluetooth::hci::LeReadRemoteFeaturesView::Create( + LeConnectionManagementCommandView::Create(AclCommandView::Create(command_view))); + if (le_read_features_view.IsValid()) { + uint16_t handle = le_read_features_view.GetConnectionHandle(); + module_.Disconnect(handle, ErrorCode::UNKNOWN_CONNECTION); + } + } +#endif + command_queue_.pop_front(); waiting_command_ = OpCode::NONE; if (hci_timeout_alarm_ != nullptr) { @@ -293,6 +316,11 @@ struct HciLayer::impl { "Can not register handler for %02hhx (%s)", EventCode::LE_META_EVENT, EventCodeText(EventCode::LE_META_EVENT).c_str()); + // Allow GD Cert tests to register for CONNECTION_REQUEST + if (event == EventCode::CONNECTION_REQUEST && module_.on_acl_connection_request_.IsEmpty()) { + LOG_INFO("Registering test for CONNECTION_REQUEST, since there's no ACL"); + event_handlers_.erase(event); + } ASSERT_LOG( event_handlers_.count(event) == 0, "Can not register a second handler for %02hhx (%s)", @@ -400,6 +428,9 @@ struct HciLayer::impl { case EventCode::LE_META_EVENT: on_le_meta_event(event); break; + case EventCode::HARDWARE_ERROR: + on_hardware_error(event); + break; default: if (event_handlers_.find(event_code) == event_handlers_.end()) { LOG_WARN( @@ -412,6 +443,20 @@ struct HciLayer::impl { } } + void on_hardware_error(EventView event) { + HardwareErrorView event_view = HardwareErrorView::Create(event); + ASSERT(event_view.IsValid()); +#ifdef TARGET_FLOSS + LOG_WARN("Hardware Error Event with code 0x%02x", event_view.GetHardwareCode()); + // Sending SIGINT to process the exception from BT controller. + // The Floss daemon will be restarted. HCI reset during restart will clear the + // error state of the BT controller. + kill(getpid(), SIGINT); +#else + LOG_ALWAYS_FATAL("Hardware Error Event with code 0x%02x", event_view.GetHardwareCode()); +#endif + } + void on_le_meta_event(EventView event) { LeMetaEventView meta_event_view = LeMetaEventView::Create(event); ASSERT(meta_event_view.IsValid()); @@ -542,6 +587,35 @@ void HciLayer::on_disconnection_complete(EventView event_view) { Disconnect(handle, reason); } +void HciLayer::on_connection_request(EventView event_view) { + auto view = ConnectionRequestView::Create(event_view); + if (!view.IsValid()) { + LOG_INFO("Dropping invalid connection request packet"); + return; + } + + Address address = view.GetBdAddr(); + ClassOfDevice cod = view.GetClassOfDevice(); + ConnectionRequestLinkType link_type = view.GetLinkType(); + switch (link_type) { + case ConnectionRequestLinkType::ACL: + if (on_acl_connection_request_.IsEmpty()) { + LOG_WARN("No callback registered for ACL connection requests."); + } else { + on_acl_connection_request_.Invoke(address, cod); + } + break; + case ConnectionRequestLinkType::SCO: + case ConnectionRequestLinkType::ESCO: + if (on_sco_connection_request_.IsEmpty()) { + LOG_WARN("No callback registered for SCO connection requests."); + } else { + on_sco_connection_request_.Invoke(address, cod, link_type); + } + break; + } +} + void HciLayer::Disconnect(uint16_t handle, ErrorCode reason) { std::unique_lock lock(callback_handlers_guard_); for (auto callback : disconnect_handlers_) { @@ -549,6 +623,11 @@ void HciLayer::Disconnect(uint16_t handle, ErrorCode reason) { } } +void HciLayer::RegisterForDisconnects(ContextualCallback on_disconnect) { + std::unique_lock lock(callback_handlers_guard_); + disconnect_handlers_.push_back(on_disconnect); +} + void HciLayer::on_read_remote_version_complete(EventView event_view) { auto view = ReadRemoteVersionInformationCompleteView::Create(event_view); ASSERT_LOG(view.IsValid(), "Read remote version information packet invalid"); @@ -571,13 +650,18 @@ void HciLayer::ReadRemoteVersion( AclConnectionInterface* HciLayer::GetAclConnectionInterface( ContextualCallback event_handler, ContextualCallback on_disconnect, - ContextualCallback< - void(hci::ErrorCode hci_status, uint16_t, uint8_t version, uint16_t manufacturer_name, uint16_t sub_version)> - on_read_remote_version) { + ContextualCallback on_connection_request, + ContextualCallback on_read_remote_version) { { std::unique_lock lock(callback_handlers_guard_); disconnect_handlers_.push_back(on_disconnect); read_remote_version_handlers_.push_back(on_read_remote_version); + on_acl_connection_request_ = on_connection_request; } for (const auto event : AclConnectionEvents) { RegisterEventHandler(event, event_handler); @@ -624,6 +708,13 @@ void HciLayer::PutLeAclConnectionInterface() { } } +void HciLayer::RegisterForScoConnectionRequests( + common::ContextualCallback + on_sco_connection_request) { + std::unique_lock lock(callback_handlers_guard_); + on_sco_connection_request_ = on_sco_connection_request; +} + SecurityInterface* HciLayer::GetSecurityInterface(ContextualCallback event_handler) { for (const auto event : SecurityEvents) { RegisterEventHandler(event, event_handler); @@ -684,6 +775,13 @@ void HciLayer::Start() { impl_->sco_queue_.GetDownEnd()->RegisterDequeue(handler, BindOn(impl_, &impl::on_outbound_sco_ready)); impl_->iso_queue_.GetDownEnd()->RegisterDequeue( handler, BindOn(impl_, &impl::on_outbound_iso_ready)); + StartWithNoHalDependencies(handler); + hal->registerIncomingPacketCallback(hal_callbacks_); + EnqueueCommand(ResetBuilder::Create(), handler->BindOnce(&fail_if_reset_complete_not_success)); +} + +// Initialize event handlers that don't depend on the HAL +void HciLayer::StartWithNoHalDependencies(Handler* handler) { RegisterEventHandler(EventCode::DISCONNECTION_COMPLETE, handler->BindOn(this, &HciLayer::on_disconnection_complete)); RegisterEventHandler( EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE, @@ -691,9 +789,8 @@ void HciLayer::Start() { auto drop_packet = handler->BindOn(impl_, &impl::drop); RegisterEventHandler(EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE, drop_packet); RegisterEventHandler(EventCode::MAX_SLOTS_CHANGE, drop_packet); - - hal->registerIncomingPacketCallback(hal_callbacks_); - EnqueueCommand(ResetBuilder::Create(), handler->BindOnce(&fail_if_reset_complete_not_success)); + RegisterEventHandler( + EventCode::CONNECTION_REQUEST, handler->BindOn(this, &HciLayer::on_connection_request)); } void HciLayer::Stop() { diff --git a/system/gd/hci/hci_layer.h b/system/gd/hci/hci_layer.h index 0acc3dd9e8a95e93b8a22349362ed89dc66f4d06..ea0b9ca78b801065a90ff4725cd30d36288a2a9f 100644 --- a/system/gd/hci/hci_layer.h +++ b/system/gd/hci/hci_layer.h @@ -39,6 +39,7 @@ #include "hci/le_security_interface.h" #include "hci/security_interface.h" #include "module.h" +#include "os/handler.h" #include "os/utils.h" namespace bluetooth { @@ -76,6 +77,9 @@ class HciLayer : public Module, public CommandInterface { virtual void UnregisterLeEventHandler(SubeventCode subevent_code); + virtual void RegisterForDisconnects( + common::ContextualCallback on_disconnect); + virtual SecurityInterface* GetSecurityInterface(common::ContextualCallback event_handler); virtual LeSecurityInterface* GetLeSecurityInterface(common::ContextualCallback event_handler); @@ -83,6 +87,7 @@ class HciLayer : public Module, public CommandInterface { virtual AclConnectionInterface* GetAclConnectionInterface( common::ContextualCallback event_handler, common::ContextualCallback on_disconnect, + common::ContextualCallback on_connection_request, common::ContextualCallback on_read_remote_version_complete); virtual void PutAclConnectionInterface(); @@ -99,6 +104,10 @@ class HciLayer : public Module, public CommandInterface { virtual LeScanningInterface* GetLeScanningInterface(common::ContextualCallback event_handler); + virtual void RegisterForScoConnectionRequests( + common::ContextualCallback + on_sco_connection_request); + virtual LeIsoInterface* GetLeIsoInterface(common::ContextualCallback event_handler); virtual DistanceMeasurementInterface* GetDistanceMeasurementInterface( @@ -119,6 +128,8 @@ class HciLayer : public Module, public CommandInterface { void Start() override; + void StartWithNoHalDependencies(os::Handler* handler); + void Stop() override; virtual void Disconnect(uint16_t handle, ErrorCode reason); @@ -158,9 +169,15 @@ class HciLayer : public Module, public CommandInterface { }; std::mutex callback_handlers_guard_; + void on_connection_request(EventView event_view); void on_disconnection_complete(EventView event_view); void on_read_remote_version_complete(EventView event_view); + common::ContextualCallback on_acl_connection_request_{}; + common::ContextualCallback + on_sco_connection_request_{}; + // Interfaces CommandInterfaceImpl acl_connection_manager_interface_{*this}; CommandInterfaceImpl le_acl_connection_manager_interface_{*this}; diff --git a/system/gd/hci/hci_layer_fake.cc b/system/gd/hci/hci_layer_fake.cc index f0b10af740890457aae505ef40b6438fe19494fe..78f1e5214ec008a790951ad8f26c1c7089ec3f87 100644 --- a/system/gd/hci/hci_layer_fake.cc +++ b/system/gd/hci/hci_layer_fake.cc @@ -55,8 +55,9 @@ static std::unique_ptr NextAclPacket(uint16_t handle) { return AclBuilder::Create(handle, packet_boundary_flag, broadcast_flag, NextPayload(handle)); } -void TestHciLayer::EnqueueCommand( - std::unique_ptr command, common::ContextualOnceCallback on_status) { +void HciLayerFake::EnqueueCommand( + std::unique_ptr command, + common::ContextualOnceCallback on_status) { std::lock_guard lock(mutex_); command_queue_.push(std::move(command)); @@ -68,8 +69,9 @@ void TestHciLayer::EnqueueCommand( } } -void TestHciLayer::EnqueueCommand( - std::unique_ptr command, common::ContextualOnceCallback on_complete) { +void HciLayerFake::EnqueueCommand( + std::unique_ptr command, + common::ContextualOnceCallback on_complete) { std::lock_guard lock(mutex_); command_queue_.push(std::move(command)); @@ -81,7 +83,7 @@ void TestHciLayer::EnqueueCommand( } } -CommandView TestHciLayer::GetCommand() { +CommandView HciLayerFake::GetCommand() { EXPECT_EQ(command_future_.wait_for(std::chrono::milliseconds(1000)), std::future_status::ready); std::lock_guard lock(mutex_); @@ -104,29 +106,37 @@ CommandView TestHciLayer::GetCommand() { return command_packet_view; } -void TestHciLayer::AssertNoQueuedCommand() { +CommandView HciLayerFake::GetCommand(OpCode op_code) { + auto next_command = GetCommand(); + while (next_command.GetOpCode() != op_code) { + next_command = GetCommand(); + } + return next_command; +} + +void HciLayerFake::AssertNoQueuedCommand() { EXPECT_TRUE(command_queue_.empty()); } -void TestHciLayer::RegisterEventHandler( +void HciLayerFake::RegisterEventHandler( EventCode event_code, common::ContextualCallback event_handler) { registered_events_[event_code] = event_handler; } -void TestHciLayer::UnregisterEventHandler(EventCode event_code) { +void HciLayerFake::UnregisterEventHandler(EventCode event_code) { registered_events_.erase(event_code); } -void TestHciLayer::RegisterLeEventHandler( +void HciLayerFake::RegisterLeEventHandler( SubeventCode subevent_code, common::ContextualCallback event_handler) { registered_le_events_[subevent_code] = event_handler; } -void TestHciLayer::UnregisterLeEventHandler(SubeventCode subevent_code) { +void HciLayerFake::UnregisterLeEventHandler(SubeventCode subevent_code) { registered_le_events_.erase(subevent_code); } -void TestHciLayer::IncomingEvent(std::unique_ptr event_builder) { +void HciLayerFake::IncomingEvent(std::unique_ptr event_builder) { auto packet = GetPacketView(std::move(event_builder)); EventView event = EventView::Create(packet); ASSERT_TRUE(event.IsValid()); @@ -141,7 +151,7 @@ void TestHciLayer::IncomingEvent(std::unique_ptr event_builder) { } } -void TestHciLayer::IncomingLeMetaEvent(std::unique_ptr event_builder) { +void HciLayerFake::IncomingLeMetaEvent(std::unique_ptr event_builder) { auto packet = GetPacketView(std::move(event_builder)); EventView event = EventView::Create(packet); LeMetaEventView meta_event_view = LeMetaEventView::Create(event); @@ -151,28 +161,28 @@ void TestHciLayer::IncomingLeMetaEvent(std::unique_ptr event registered_le_events_[subevent_code].Invoke(meta_event_view); } -void TestHciLayer::CommandCompleteCallback(EventView event) { +void HciLayerFake::CommandCompleteCallback(EventView event) { CommandCompleteView complete_view = CommandCompleteView::Create(event); ASSERT_TRUE(complete_view.IsValid()); std::move(command_complete_callbacks.front()).Invoke(complete_view); command_complete_callbacks.pop_front(); } -void TestHciLayer::CommandStatusCallback(EventView event) { +void HciLayerFake::CommandStatusCallback(EventView event) { CommandStatusView status_view = CommandStatusView::Create(event); ASSERT_TRUE(status_view.IsValid()); std::move(command_status_callbacks.front()).Invoke(status_view); command_status_callbacks.pop_front(); } -void TestHciLayer::InitEmptyCommand() { +void HciLayerFake::InitEmptyCommand() { auto payload = std::make_unique(); auto command_builder = CommandBuilder::Create(OpCode::NONE, std::move(payload)); empty_command_view_ = CommandView::Create(GetPacketView(std::move(command_builder))); ASSERT_TRUE(empty_command_view_.IsValid()); } -void TestHciLayer::IncomingAclData(uint16_t handle, std::unique_ptr acl_builder) { +void HciLayerFake::IncomingAclData(uint16_t handle, std::unique_ptr acl_builder) { os::Handler* hci_handler = GetHandler(); auto* queue_end = acl_queue_.GetDownEnd(); std::promise promise; @@ -198,16 +208,16 @@ void TestHciLayer::IncomingAclData(uint16_t handle, std::unique_ptr ASSERT_EQ(status, std::future_status::ready); } -void TestHciLayer::IncomingAclData(uint16_t handle) { +void HciLayerFake::IncomingAclData(uint16_t handle) { IncomingAclData(handle, NextAclPacket(handle)); } -void TestHciLayer::AssertNoOutgoingAclData() { +void HciLayerFake::AssertNoOutgoingAclData() { auto queue_end = acl_queue_.GetDownEnd(); EXPECT_EQ(queue_end->TryDequeue(), nullptr); } -PacketView TestHciLayer::OutgoingAclData() { +PacketView HciLayerFake::OutgoingAclData() { auto queue_end = acl_queue_.GetDownEnd(); std::unique_ptr received; do { @@ -217,25 +227,27 @@ PacketView TestHciLayer::OutgoingAclData() { return GetPacketView(std::move(received)); } -BidiQueueEnd* TestHciLayer::GetAclQueueEnd() { +BidiQueueEnd* HciLayerFake::GetAclQueueEnd() { return acl_queue_.GetUpEnd(); } -void TestHciLayer::Disconnect(uint16_t handle, ErrorCode reason) { +void HciLayerFake::Disconnect(uint16_t handle, ErrorCode reason) { GetHandler()->Post( - common::BindOnce(&TestHciLayer::do_disconnect, common::Unretained(this), handle, reason)); + common::BindOnce(&HciLayerFake::do_disconnect, common::Unretained(this), handle, reason)); } -void TestHciLayer::do_disconnect(uint16_t handle, ErrorCode reason) { +void HciLayerFake::do_disconnect(uint16_t handle, ErrorCode reason) { HciLayer::Disconnect(handle, reason); } -void TestHciLayer::ListDependencies(ModuleList* /* list */) const {} -void TestHciLayer::Start() { +void HciLayerFake::ListDependencies(ModuleList* /* list */) const {} +void HciLayerFake::Start() { std::lock_guard lock(mutex_); InitEmptyCommand(); + os::Handler* handler = GetHandler(); + StartWithNoHalDependencies(handler); } -void TestHciLayer::Stop() {} +void HciLayerFake::Stop() {} } // namespace hci } // namespace bluetooth diff --git a/system/gd/hci/hci_layer_fake.h b/system/gd/hci/hci_layer_fake.h index 939ae4eb335991b8510918adf5ec1a6299442ec1..9722154c9f49de4e6867d09c5dd77ad5a0b9664e 100644 --- a/system/gd/hci/hci_layer_fake.h +++ b/system/gd/hci/hci_layer_fake.h @@ -16,6 +16,7 @@ #include #include +#include #include "common/bind.h" #include "hci/address.h" @@ -30,7 +31,7 @@ packet::PacketView GetPacketView( std::unique_ptr NextPayload(uint16_t handle); -class TestHciLayer : public HciLayer { +class HciLayerFake : public HciLayer { public: void EnqueueCommand( std::unique_ptr command, @@ -42,6 +43,8 @@ class TestHciLayer : public HciLayer { CommandView GetCommand(); + CommandView GetCommand(OpCode op_code); + void AssertNoQueuedCommand(); void RegisterEventHandler(EventCode event_code, common::ContextualCallback event_handler) override; @@ -112,4 +115,4 @@ class TestHciLayer : public HciLayer { }; } // namespace hci -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/gd/hci/hci_layer_mock.h b/system/gd/hci/hci_layer_mock.h index 38e37deddc7d75ba5f984a3d002820671b999e9c..84af1bf2461f5e72c53acd912e3e11fe18e5dcb3 100644 --- a/system/gd/hci/hci_layer_mock.h +++ b/system/gd/hci/hci_layer_mock.h @@ -75,6 +75,7 @@ class MockHciLayer : public HciLayer { GetAclConnectionInterface, (common::ContextualCallback event_handler, common::ContextualCallback on_disconnect, + common::ContextualCallback on_connection_request, common::ContextualCallback on_read_remote_version_complete), (override)); diff --git a/system/gd/hci/hci_layer_unittest.cc b/system/gd/hci/hci_layer_unittest.cc index 52cbb0bf96031cdb85f0e4660d0c7bfd4bb56cd5..adfa8a12f05fb03401e44da591f330dce9c4d768 100644 --- a/system/gd/hci/hci_layer_unittest.cc +++ b/system/gd/hci/hci_layer_unittest.cc @@ -191,6 +191,18 @@ TEST_F(HciLayerDeathTest, abort_on_root_inflammation_event) { ""); } +TEST_F(HciLayerDeathTest, abort_on_hardware_error) { + FailIfResetNotSent(); + + ASSERT_DEATH( + { + sync_handler(); + hal_->InjectEvent(HardwareErrorBuilder::Create(0xbb)); + sync_handler(); + }, + ""); +} + TEST_F(HciLayerTest, successful_reset) { FailIfResetNotSent(); hal_->InjectEvent(ResetCompleteBuilder::Create(1, ErrorCode::SUCCESS)); @@ -272,6 +284,7 @@ TEST_F(HciLayerTest, our_acl_event_callback_is_invoked) { hci_handler_->Bind( [](EventView /* view */) { LOG_DEBUG("%s", kOurAclEventHandlerWasInvoked); }), hci_handler_->Bind([](uint16_t /* handle */, ErrorCode /* reason */) {}), + hci_handler_->Bind([](Address /* bd_addr */, ClassOfDevice /* cod */) {}), hci_handler_->Bind([](hci::ErrorCode /* hci_status */, uint16_t /* handle */, uint8_t /* version */, @@ -287,6 +300,7 @@ TEST_F(HciLayerTest, our_disconnect_callback_is_invoked) { hci_handler_->Bind([](uint16_t /* handle */, ErrorCode /* reason */) { LOG_DEBUG("%s", kOurDisconnectHandlerWasInvoked); }), + hci_handler_->Bind([](Address /* bd_addr */, ClassOfDevice /* cod */) {}), hci_handler_->Bind([](hci::ErrorCode /* hci_status */, uint16_t /* handle */, uint8_t /* version */, @@ -301,6 +315,7 @@ TEST_F(HciLayerTest, our_read_remote_version_callback_is_invoked) { hci_->GetAclConnectionInterface( hci_handler_->Bind([](EventView /* view */) {}), hci_handler_->Bind([](uint16_t /* handle */, ErrorCode /* reason */) {}), + hci_handler_->Bind([](Address /* bd_addr */, ClassOfDevice /* cod */) {}), hci_handler_->Bind([](hci::ErrorCode /* hci_status */, uint16_t /* handle */, uint8_t /* version */, diff --git a/system/gd/hci/hci_metrics_logging.cc b/system/gd/hci/hci_metrics_logging.cc index 8ea24d1f8ec815d2a59a45bf085e3253986816cc..f72ec314df1740d5c408a23ac845467b8f83a590 100644 --- a/system/gd/hci/hci_metrics_logging.cc +++ b/system/gd/hci/hci_metrics_logging.cc @@ -201,19 +201,19 @@ void log_link_layer_connection_command(std::unique_ptr& command_vie break; } case OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST: { - auto le_add_device_to_connect_list_view = LeAddDeviceToFilterAcceptListView::Create( + auto le_add_device_to_accept_list_view = LeAddDeviceToFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(std::move(connection_management_command_view))); - ASSERT(le_add_device_to_connect_list_view.IsValid()); - address = le_add_device_to_connect_list_view.GetAddress(); + ASSERT(le_add_device_to_accept_list_view.IsValid()); + address = le_add_device_to_accept_list_view.GetAddress(); direction = android::bluetooth::DIRECTION_INCOMING; link_type = android::bluetooth::LINK_TYPE_ACL; break; } case OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST: { - auto le_remove_device_from_connect_list_view = LeRemoveDeviceFromFilterAcceptListView::Create( + auto le_remove_device_from_accept_list_view = LeRemoveDeviceFromFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(std::move(connection_management_command_view))); - ASSERT(le_remove_device_from_connect_list_view.IsValid()); - address = le_remove_device_from_connect_list_view.GetAddress(); + ASSERT(le_remove_device_from_accept_list_view.IsValid()); + address = le_remove_device_from_accept_list_view.GetAddress(); direction = android::bluetooth::DIRECTION_INCOMING; link_type = android::bluetooth::LINK_TYPE_ACL; break; @@ -381,19 +381,19 @@ void log_link_layer_connection_command_status(std::unique_ptr& comm break; } case OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST: { - auto le_add_device_to_connect_list_view = LeAddDeviceToFilterAcceptListView::Create( + auto le_add_device_to_accept_list_view = LeAddDeviceToFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(std::move(connection_management_command_view))); - ASSERT(le_add_device_to_connect_list_view.IsValid()); - address = le_add_device_to_connect_list_view.GetAddress(); + ASSERT(le_add_device_to_accept_list_view.IsValid()); + address = le_add_device_to_accept_list_view.GetAddress(); direction = android::bluetooth::DIRECTION_INCOMING; link_type = android::bluetooth::LINK_TYPE_ACL; break; } case OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST: { - auto le_remove_device_from_connect_list_view = LeRemoveDeviceFromFilterAcceptListView::Create( + auto le_remove_device_from_accept_list_view = LeRemoveDeviceFromFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(std::move(connection_management_command_view))); - ASSERT(le_remove_device_from_connect_list_view.IsValid()); - address = le_remove_device_from_connect_list_view.GetAddress(); + ASSERT(le_remove_device_from_accept_list_view.IsValid()); + address = le_remove_device_from_accept_list_view.GetAddress(); direction = android::bluetooth::DIRECTION_INCOMING; link_type = android::bluetooth::LINK_TYPE_ACL; break; @@ -443,19 +443,19 @@ void log_link_layer_connection_command_complete(EventView event_view, std::uniqu break; } case OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST: { - auto le_add_device_to_connect_list_view = LeAddDeviceToFilterAcceptListView::Create( + auto le_add_device_to_accept_list_view = LeAddDeviceToFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(std::move(connection_management_command_view))); - ASSERT(le_add_device_to_connect_list_view.IsValid()); - address = le_add_device_to_connect_list_view.GetAddress(); + ASSERT(le_add_device_to_accept_list_view.IsValid()); + address = le_add_device_to_accept_list_view.GetAddress(); direction = android::bluetooth::DIRECTION_INCOMING; link_type = android::bluetooth::LINK_TYPE_ACL; break; } case OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST: { - auto le_remove_device_from_connect_list_view = LeRemoveDeviceFromFilterAcceptListView::Create( + auto le_remove_device_from_accept_list_view = LeRemoveDeviceFromFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(std::move(connection_management_command_view))); - ASSERT(le_remove_device_from_connect_list_view.IsValid()); - address = le_remove_device_from_connect_list_view.GetAddress(); + ASSERT(le_remove_device_from_accept_list_view.IsValid()); + address = le_remove_device_from_accept_list_view.GetAddress(); direction = android::bluetooth::DIRECTION_INCOMING; link_type = android::bluetooth::LINK_TYPE_ACL; break; diff --git a/system/gd/hci/le_address_manager.cc b/system/gd/hci/le_address_manager.cc index 1c954a36c3e06fc0409e4e4a5a0502e7002744e7..6836ac9d8da53fdd35291d4081e046150836aa25 100644 --- a/system/gd/hci/le_address_manager.cc +++ b/system/gd/hci/le_address_manager.cc @@ -16,6 +16,8 @@ #include "hci/le_address_manager.h" +#include + #include "common/init_flags.h" #include "hci/octets.h" #include "os/log.h" @@ -30,12 +32,12 @@ LeAddressManager::LeAddressManager( common::Callback)> enqueue_command, os::Handler* handler, Address public_address, - uint8_t connect_list_size, + uint8_t accept_list_size, uint8_t resolving_list_size) : enqueue_command_(enqueue_command), handler_(handler), public_address_(public_address), - connect_list_size_(connect_list_size), + accept_list_size_(accept_list_size), resolving_list_size_(resolving_list_size){}; LeAddressManager::~LeAddressManager() { @@ -72,6 +74,11 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddress( supports_ble_privacy_ = supports_ble_privacy; LOG_INFO("SetPrivacyPolicyForInitiatorAddress with policy %d", address_policy); + if (IS_FLAG_ENABLED(nrpa_non_connectable_adv)) { + minimum_rotation_time_ = minimum_rotation_time; + maximum_rotation_time_ = maximum_rotation_time; + } + switch (address_policy_) { case AddressPolicy::USE_PUBLIC_ADDRESS: le_address_ = AddressWithType(public_address_, AddressType::PUBLIC_DEVICE_ADDRESS); @@ -97,8 +104,10 @@ void LeAddressManager::SetPrivacyPolicyForInitiatorAddress( case AddressPolicy::USE_RESOLVABLE_ADDRESS: le_address_ = fixed_address; rotation_irk_ = rotation_irk; - minimum_rotation_time_ = minimum_rotation_time; - maximum_rotation_time_ = maximum_rotation_time; + if (!IS_FLAG_ENABLED(nrpa_non_connectable_adv)) { + minimum_rotation_time_ = minimum_rotation_time; + maximum_rotation_time_ = maximum_rotation_time; + } address_rotation_alarm_ = std::make_unique(handler_); set_random_address(); break; @@ -228,7 +237,9 @@ AddressWithType LeAddressManager::NewResolvableAddress() { } AddressWithType LeAddressManager::NewNonResolvableAddress() { - ASSERT(RotatingAddress()); + if (!IS_FLAG_ENABLED(nrpa_non_connectable_adv)) { + ASSERT(RotatingAddress()); + } hci::Address address = generate_nrpa(); auto random_address = AddressWithType(address, AddressType::RANDOM_DEVICE_ADDRESS); return random_address; @@ -431,7 +442,7 @@ std::chrono::milliseconds LeAddressManager::GetNextPrivateAddressIntervalMs() { } uint8_t LeAddressManager::GetFilterAcceptListSize() { - return connect_list_size_; + return accept_list_size_; } uint8_t LeAddressManager::GetResolvingListSize() { @@ -468,9 +479,9 @@ void LeAddressManager::handle_next_command() { } void LeAddressManager::AddDeviceToFilterAcceptList( - FilterAcceptListAddressType connect_list_address_type, bluetooth::hci::Address address) { - auto packet_builder = hci::LeAddDeviceToFilterAcceptListBuilder::Create(connect_list_address_type, address); - Command command = {CommandType::ADD_DEVICE_TO_CONNECT_LIST, HCICommand{std::move(packet_builder)}}; + FilterAcceptListAddressType accept_list_address_type, bluetooth::hci::Address address) { + auto packet_builder = hci::LeAddDeviceToFilterAcceptListBuilder::Create(accept_list_address_type, address); + Command command = {CommandType::ADD_DEVICE_TO_ACCEPT_LIST, HCICommand{std::move(packet_builder)}}; handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke(); } @@ -513,9 +524,9 @@ void LeAddressManager::AddDeviceToResolvingList( } void LeAddressManager::RemoveDeviceFromFilterAcceptList( - FilterAcceptListAddressType connect_list_address_type, bluetooth::hci::Address address) { - auto packet_builder = hci::LeRemoveDeviceFromFilterAcceptListBuilder::Create(connect_list_address_type, address); - Command command = {CommandType::REMOVE_DEVICE_FROM_CONNECT_LIST, HCICommand{std::move(packet_builder)}}; + FilterAcceptListAddressType accept_list_address_type, bluetooth::hci::Address address) { + auto packet_builder = hci::LeRemoveDeviceFromFilterAcceptListBuilder::Create(accept_list_address_type, address); + Command command = {CommandType::REMOVE_DEVICE_FROM_ACCEPT_LIST, HCICommand{std::move(packet_builder)}}; handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke(); } @@ -549,7 +560,7 @@ void LeAddressManager::RemoveDeviceFromResolvingList( void LeAddressManager::ClearFilterAcceptList() { auto packet_builder = hci::LeClearFilterAcceptListBuilder::Create(); - Command command = {CommandType::CLEAR_CONNECT_LIST, HCICommand{std::move(packet_builder)}}; + Command command = {CommandType::CLEAR_ACCEPT_LIST, HCICommand{std::move(packet_builder)}}; handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke(); } diff --git a/system/gd/hci/le_address_manager.h b/system/gd/hci/le_address_manager.h index 6f882a64936a58d62693b5d257b4749e41b35640..ae5eef28436e8872eef86ad3b61e90fe7b6a139b 100644 --- a/system/gd/hci/le_address_manager.h +++ b/system/gd/hci/le_address_manager.h @@ -42,7 +42,7 @@ class LeAddressManager { common::Callback)> enqueue_command, os::Handler* handler, Address public_address, - uint8_t connect_list_size, + uint8_t accept_list_size, uint8_t resolving_list_size); virtual ~LeAddressManager(); @@ -84,13 +84,13 @@ class LeAddressManager { uint8_t GetFilterAcceptListSize(); uint8_t GetResolvingListSize(); - void AddDeviceToFilterAcceptList(FilterAcceptListAddressType connect_list_address_type, Address address); + void AddDeviceToFilterAcceptList(FilterAcceptListAddressType accept_list_address_type, Address address); void AddDeviceToResolvingList( PeerAddressType peer_identity_address_type, Address peer_identity_address, const std::array& peer_irk, const std::array& local_irk); - void RemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType connect_list_address_type, Address address); + void RemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType accept_list_address_type, Address address); void RemoveDeviceFromResolvingList(PeerAddressType peer_identity_address_type, Address peer_identity_address); void ClearFilterAcceptList(); void ClearResolvingList(); @@ -117,9 +117,9 @@ class LeAddressManager { enum CommandType { ROTATE_RANDOM_ADDRESS, - ADD_DEVICE_TO_CONNECT_LIST, - REMOVE_DEVICE_FROM_CONNECT_LIST, - CLEAR_CONNECT_LIST, + ADD_DEVICE_TO_ACCEPT_LIST, + REMOVE_DEVICE_FROM_ACCEPT_LIST, + CLEAR_ACCEPT_LIST, ADD_DEVICE_TO_RESOLVING_LIST, REMOVE_DEVICE_FROM_RESOLVING_LIST, CLEAR_RESOLVING_LIST, @@ -174,7 +174,7 @@ class LeAddressManager { Address public_address_; std::unique_ptr address_rotation_alarm_; Octet16 rotation_irk_; - uint8_t connect_list_size_; + uint8_t accept_list_size_; uint8_t resolving_list_size_; std::queue cached_commands_; bool supports_ble_privacy_{false}; diff --git a/system/gd/hci/le_address_manager_test.cc b/system/gd/hci/le_address_manager_test.cc index aee27db67c5df0952a3395d7c9ffb39f4ae70c1e..180f91941302fef2b836de31de14c48eaf6c834d 100644 --- a/system/gd/hci/le_address_manager_test.cc +++ b/system/gd/hci/le_address_manager_test.cc @@ -20,6 +20,7 @@ #include "common/init_flags.h" #include "hci/hci_layer.h" +#include "hci/hci_layer_fake.h" #include "hci/octets.h" #include "os/log.h" #include "packet/raw_builder.h" @@ -28,20 +29,6 @@ using ::bluetooth::hci::Octet16; using ::bluetooth::os::Handler; using ::bluetooth::os::Thread; -namespace { - -using namespace bluetooth; - -packet::PacketView GetPacketView(std::unique_ptr packet) { - auto bytes = std::make_shared>(); - packet::BitInserter i(*bytes); - bytes->reserve(packet->size()); - packet->Serialize(i); - return packet::PacketView(bytes); -} - -} // namespace - namespace bluetooth { namespace hci { namespace { @@ -50,82 +37,6 @@ using packet::kLittleEndian; using packet::PacketView; using packet::RawBuilder; -class TestHciLayer : public HciLayer { - public: - void EnqueueCommand( - std::unique_ptr command, - common::ContextualOnceCallback on_complete) override { - std::lock_guard lock(mutex_); - command_queue_.push(std::move(command)); - command_complete_callbacks.push_back(std::move(on_complete)); - if (command_promise_ != nullptr) { - std::promise* prom = command_promise_.release(); - prom->set_value(); - delete prom; - } - } - - void SetCommandFuture() { - ASSERT_EQ(command_promise_, nullptr) << "Promises, Promises, ... Only one at a time."; - command_promise_ = std::make_unique>(); - command_future_ = std::make_unique>(command_promise_->get_future()); - } - - CommandView GetLastCommand() { - if (command_queue_.size() == 0) { - return CommandView::Create(PacketView(std::make_shared>())); - } - auto last = std::move(command_queue_.front()); - command_queue_.pop(); - return CommandView::Create(GetPacketView(std::move(last))); - } - - CommandView GetCommand(OpCode op_code) { - if (!command_queue_.empty()) { - std::lock_guard lock(mutex_); - if (command_future_ != nullptr) { - command_future_.reset(); - command_promise_.reset(); - } - } else if (command_future_ != nullptr) { - auto result = command_future_->wait_for(std::chrono::milliseconds(1000)); - EXPECT_NE(std::future_status::timeout, result); - } - std::lock_guard lock(mutex_); - ASSERT_LOG( - !command_queue_.empty(), "Expecting command %s but command queue was empty", OpCodeText(op_code).c_str()); - CommandView command_packet_view = GetLastCommand(); - EXPECT_TRUE(command_packet_view.IsValid()); - EXPECT_EQ(command_packet_view.GetOpCode(), op_code); - return command_packet_view; - } - - void IncomingEvent(std::unique_ptr event_builder) { - auto packet = GetPacketView(std::move(event_builder)); - EventView event = EventView::Create(packet); - ASSERT_TRUE(event.IsValid()); - CommandCompleteCallback(event); - } - - void CommandCompleteCallback(EventView event) { - CommandCompleteView complete_view = CommandCompleteView::Create(event); - ASSERT_TRUE(complete_view.IsValid()); - std::move(command_complete_callbacks.front()).Invoke(complete_view); - command_complete_callbacks.pop_front(); - } - - void ListDependencies(ModuleList* /* list */) const {} - void Start() override {} - void Stop() override {} - - private: - std::list> command_complete_callbacks; - std::queue> command_queue_; - std::unique_ptr> command_promise_; - std::unique_ptr> command_future_; - mutable std::mutex mutex_; -}; - class RotatorClient : public LeAddressManagerCallback { public: RotatorClient(LeAddressManager* le_address_manager, size_t id) : le_address_manager_(le_address_manager), id_(id){}; @@ -165,7 +76,7 @@ class LeAddressManagerTest : public ::testing::Test { void SetUp() override { thread_ = new Thread("thread", Thread::Priority::NORMAL); handler_ = new Handler(thread_); - test_hci_layer_ = new TestHciLayer; + hci_layer_ = new HciLayerFake(); Address address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06}); le_address_manager_ = new LeAddressManager( common::Bind(&LeAddressManagerTest::enqueue_command, common::Unretained(this)), handler_, address, 0x3F, 0x3F); @@ -183,7 +94,7 @@ class LeAddressManagerTest : public ::testing::Test { void TearDown() override { sync_handler(handler_); delete le_address_manager_; - delete test_hci_layer_; + delete hci_layer_; handler_->Clear(); delete handler_; delete thread_; @@ -197,14 +108,15 @@ class LeAddressManagerTest : public ::testing::Test { } void enqueue_command(std::unique_ptr command_packet) { - test_hci_layer_->EnqueueCommand( + hci_layer_->EnqueueCommand( std::move(command_packet), - handler_->BindOnce(&LeAddressManager::OnCommandComplete, common::Unretained(le_address_manager_))); + handler_->BindOnce( + &LeAddressManager::OnCommandComplete, common::Unretained(le_address_manager_))); } Thread* thread_; Handler* handler_; - TestHciLayer* test_hci_layer_ = nullptr; + HciLayerFake* hci_layer_ = nullptr; LeAddressManager* le_address_manager_; std::vector> clients; }; @@ -231,11 +143,10 @@ TEST_F(LeAddressManagerTest, rotator_address_for_single_client) { minimum_rotation_time, maximum_rotation_time); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->Register(clients[0].get()); sync_handler(handler_); - test_hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); - test_hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); + hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); clients[0].get()->WaitForResume(); le_address_manager_->Unregister(clients[0].get()); sync_handler(handler_); @@ -254,11 +165,10 @@ TEST_F(LeAddressManagerTest, rotator_non_resolvable_address_for_single_client) { minimum_rotation_time, maximum_rotation_time); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->Register(clients[0].get()); sync_handler(handler_); - test_hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); - test_hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); + hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); clients[0].get()->WaitForResume(); le_address_manager_->Unregister(clients[0].get()); sync_handler(handler_); @@ -295,7 +205,7 @@ class LeAddressManagerWithSingleClientTest : public LeAddressManagerTest { bluetooth::common::InitFlags::SetAllForTesting(); thread_ = new Thread("thread", Thread::Priority::NORMAL); handler_ = new Handler(thread_); - test_hci_layer_ = new TestHciLayer; + hci_layer_ = new HciLayerFake(); Address address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06}); le_address_manager_ = new LeAddressManager( common::Bind(&LeAddressManagerWithSingleClientTest::enqueue_command, common::Unretained(this)), @@ -317,78 +227,78 @@ class LeAddressManagerWithSingleClientTest : public LeAddressManagerTest { minimum_rotation_time, maximum_rotation_time); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->Register(clients[0].get()); sync_handler(handler_); - test_hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); - test_hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_SET_RANDOM_ADDRESS); + hci_layer_->IncomingEvent(LeSetRandomAddressCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } void enqueue_command(std::unique_ptr command_packet) { - test_hci_layer_->EnqueueCommand( + hci_layer_->EnqueueCommand( std::move(command_packet), - handler_->BindOnce(&LeAddressManager::OnCommandComplete, common::Unretained(le_address_manager_))); + handler_->BindOnce( + &LeAddressManager::OnCommandComplete, common::Unretained(le_address_manager_))); } void TearDown() override { le_address_manager_->Unregister(clients[0].get()); sync_handler(handler_); delete le_address_manager_; - delete test_hci_layer_; + delete hci_layer_; handler_->Clear(); delete handler_; delete thread_; } }; -TEST_F(LeAddressManagerWithSingleClientTest, add_device_to_connect_list) { +TEST_F(LeAddressManagerWithSingleClientTest, add_device_to_accept_list) { Address address; Address::FromString("01:02:03:04:05:06", address); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->AddDeviceToFilterAcceptList(FilterAcceptListAddressType::RANDOM, address); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); + auto packet = hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); auto packet_view = LeAddDeviceToFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(AclCommandView::Create(packet))); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(FilterAcceptListAddressType::RANDOM, packet_view.GetAddressType()); ASSERT_EQ(address, packet_view.GetAddress()); - test_hci_layer_->IncomingEvent(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); clients[0].get()->WaitForResume(); } -TEST_F(LeAddressManagerWithSingleClientTest, remove_device_from_connect_list) { +TEST_F(LeAddressManagerWithSingleClientTest, remove_device_from_accept_list) { Address address; Address::FromString("01:02:03:04:05:06", address); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->AddDeviceToFilterAcceptList(FilterAcceptListAddressType::RANDOM, address); - test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - test_hci_layer_->IncomingEvent(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->RemoveDeviceFromFilterAcceptList(FilterAcceptListAddressType::RANDOM, address); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST); + auto packet = hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST); auto packet_view = LeRemoveDeviceFromFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(AclCommandView::Create(packet))); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(FilterAcceptListAddressType::RANDOM, packet_view.GetAddressType()); ASSERT_EQ(address, packet_view.GetAddress()); - test_hci_layer_->IncomingEvent(LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeRemoveDeviceFromFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); clients[0].get()->WaitForResume(); } TEST_F(LeAddressManagerWithSingleClientTest, clear_filter_accept_list) { Address address; Address::FromString("01:02:03:04:05:06", address); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->AddDeviceToFilterAcceptList(FilterAcceptListAddressType::RANDOM, address); - test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); - test_hci_layer_->IncomingEvent(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->ClearFilterAcceptList(); - test_hci_layer_->GetCommand(OpCode::LE_CLEAR_FILTER_ACCEPT_LIST); - test_hci_layer_->IncomingEvent(LeClearFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_CLEAR_FILTER_ACCEPT_LIST); + hci_layer_->IncomingEvent( + LeClearFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); clients[0].get()->WaitForResume(); } @@ -399,34 +309,34 @@ TEST_F(LeAddressManagerWithSingleClientTest, DISABLED_add_device_to_resolving_li Octet16 peer_irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b}; Octet16 local_irk = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->AddDeviceToResolvingList( PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address, peer_irk, local_irk); { - auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + auto packet = hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); auto packet_view = LeSetAddressResolutionEnableView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(Enable::DISABLED, packet_view.GetAddressResolutionEnable()); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } { - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST); + auto packet = hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST); auto packet_view = LeAddDeviceToResolvingListView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, packet_view.GetPeerIdentityAddressType()); ASSERT_EQ(address, packet_view.GetPeerIdentityAddress()); ASSERT_EQ(peer_irk, packet_view.GetPeerIrk()); ASSERT_EQ(local_irk, packet_view.GetLocalIrk()); - test_hci_layer_->IncomingEvent(LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } { - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + auto packet = hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); auto packet_view = LeSetAddressResolutionEnableView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(Enable::ENABLED, packet_view.GetAddressResolutionEnable()); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } clients[0].get()->WaitForResume(); } @@ -436,44 +346,60 @@ TEST_F(LeAddressManagerWithSingleClientTest, DISABLED_remove_device_from_resolvi Address address; Address::FromString("01:02:03:04:05:06", address); Octet16 peer_irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b}; - Octet16 local_irk = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); + Octet16 local_irk = { + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10}; le_address_manager_->AddDeviceToResolvingList( PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address, peer_irk, local_irk); - test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST); - test_hci_layer_->IncomingEvent(LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); + hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST); + hci_layer_->IncomingEvent( + LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + le_address_manager_->RemoveDeviceFromResolvingList(PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address); { - auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + auto packet = hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); auto packet_view = LeSetAddressResolutionEnableView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(Enable::DISABLED, packet_view.GetAddressResolutionEnable()); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } { - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST); + auto packet = hci_layer_->GetCommand(OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST); auto packet_view = LeRemoveDeviceFromResolvingListView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, packet_view.GetPeerIdentityAddressType()); ASSERT_EQ(address, packet_view.GetPeerIdentityAddress()); - test_hci_layer_->IncomingEvent(LeRemoveDeviceFromResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeRemoveDeviceFromResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } { - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + auto packet = hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); auto packet_view = LeSetAddressResolutionEnableView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(Enable::ENABLED, packet_view.GetAddressResolutionEnable()); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } clients[0].get()->WaitForResume(); } @@ -483,42 +409,58 @@ TEST_F(LeAddressManagerWithSingleClientTest, DISABLED_clear_resolving_list) { Address address; Address::FromString("01:02:03:04:05:06", address); Octet16 peer_irk = {0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05, 0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b}; - Octet16 local_irk = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}; - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); + Octet16 local_irk = { + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10}; le_address_manager_->AddDeviceToResolvingList( PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, address, peer_irk, local_irk); - test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST); - test_hci_layer_->IncomingEvent(LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); - - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); + hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST); + hci_layer_->IncomingEvent( + LeAddDeviceToResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + le_address_manager_->ClearResolvingList(); { - auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + auto packet = hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); auto packet_view = LeSetAddressResolutionEnableView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(Enable::DISABLED, packet_view.GetAddressResolutionEnable()); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } { - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_CLEAR_RESOLVING_LIST); + auto packet = hci_layer_->GetCommand(OpCode::LE_CLEAR_RESOLVING_LIST); auto packet_view = LeClearResolvingListView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); - test_hci_layer_->IncomingEvent(LeClearResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeClearResolvingListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } { - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); + auto packet = hci_layer_->GetCommand(OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE); auto packet_view = LeSetAddressResolutionEnableView::Create(LeSecurityCommandView::Create(packet)); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(Enable::ENABLED, packet_view.GetAddressResolutionEnable()); - test_hci_layer_->IncomingEvent(LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeSetAddressResolutionEnableCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); } clients[0].get()->WaitForResume(); @@ -527,18 +469,17 @@ TEST_F(LeAddressManagerWithSingleClientTest, DISABLED_clear_resolving_list) { TEST_F(LeAddressManagerWithSingleClientTest, register_during_command_complete) { Address address; Address::FromString("01:02:03:04:05:06", address); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->AddDeviceToFilterAcceptList(FilterAcceptListAddressType::RANDOM, address); - auto packet = test_hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); + auto packet = hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST); auto packet_view = LeAddDeviceToFilterAcceptListView::Create( LeConnectionManagementCommandView::Create(AclCommandView::Create(packet))); ASSERT_TRUE(packet_view.IsValid()); ASSERT_EQ(FilterAcceptListAddressType::RANDOM, packet_view.GetAddressType()); ASSERT_EQ(address, packet_view.GetAddress()); - test_hci_layer_->IncomingEvent(LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); + hci_layer_->IncomingEvent( + LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS)); AllocateClients(1); - ASSERT_NO_FATAL_FAILURE(test_hci_layer_->SetCommandFuture()); le_address_manager_->Register(clients[1].get()); clients[0].get()->WaitForResume(); clients[1].get()->WaitForResume(); diff --git a/system/gd/hci/le_advertising_manager.cc b/system/gd/hci/le_advertising_manager.cc index 5d4be6313a9715b237a58113138ca9d0a54a2506..86a831118f5227a960a416dd5f7e16e488bab566 100644 --- a/system/gd/hci/le_advertising_manager.cc +++ b/system/gd/hci/le_advertising_manager.cc @@ -110,6 +110,26 @@ AdvertiserAddressType GetAdvertiserAddressTypeFromRequestedTypeAndPolicy( } } +/** + * Determines the address type to use for non-connectable advertisement. + * (1) if the host only supports public/static address policy, non-connectable advertisement + * can use both Public and NRPA if requested. Use NRPA if RPA is requested. + * (2) in other cases, based on the requested type and the address manager policy. + */ +AdvertiserAddressType GetAdvertiserAddressTypeNonConnectable( + AdvertiserAddressType requested_address_type, LeAddressManager::AddressPolicy address_policy) { + switch (address_policy) { + case LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS: + case LeAddressManager::AddressPolicy::USE_STATIC_ADDRESS: + return requested_address_type == AdvertiserAddressType::RESOLVABLE_RANDOM + ? AdvertiserAddressType::NONRESOLVABLE_RANDOM + : requested_address_type; + default: + return GetAdvertiserAddressTypeFromRequestedTypeAndPolicy( + requested_address_type, address_policy); + } +} + struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallback { impl(Module* module) : module_(module), le_advertising_interface_(nullptr), num_instances_(0) {} @@ -203,6 +223,12 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb return num_instances_; } + size_t GetNumberOfAdvertisingInstancesInUse() const { + return std::count_if(advertising_sets_.begin(), advertising_sets_.end(), [](const auto& set) { + return set.second.in_use; + }); + } + int get_advertiser_reg_id(AdvertiserId advertiser_id) { return id_map_[advertiser_id]; } @@ -440,9 +466,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb address_manager_registered = true; } - advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy( - config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy()); - + if (IS_FLAG_ENABLED(nrpa_non_connectable_adv) && !config.connectable) { + advertising_sets_[id].address_type = GetAdvertiserAddressTypeNonConnectable( + config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy()); + } else { + advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy( + config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy()); + } advertising_sets_[id].current_address = new_advertiser_address(id); set_parameters(id, config); @@ -572,8 +602,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb advertising_sets_[id].duration = duration; advertising_sets_[id].max_extended_advertising_events = max_ext_adv_events; advertising_sets_[id].handler = handler; - advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy( - config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy()); + if (IS_FLAG_ENABLED(nrpa_non_connectable_adv) && !config.connectable) { + advertising_sets_[id].address_type = GetAdvertiserAddressTypeNonConnectable( + config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy()); + } else { + advertising_sets_[id].address_type = GetAdvertiserAddressTypeFromRequestedTypeAndPolicy( + config.requested_advertiser_address_type, le_address_manager_->GetAddressPolicy()); + } advertising_sets_[id].current_address = new_advertiser_address(id); set_parameters(id, config); @@ -1458,16 +1493,12 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb case (AdvertisingApiType::LEGACY): { le_advertising_interface_->EnqueueCommand( hci::LeSetAdvertisingEnableBuilder::Create(Enable::ENABLED), - common::init_flags:: - trigger_advertising_callbacks_on_first_resume_after_pause_is_enabled() - ? module_handler_->BindOnceOn( - this, - &impl::on_set_advertising_enable_complete< - LeSetAdvertisingEnableCompleteView>, - true, - enabled_sets, - false /* trigger_callbacks */) - : module_handler_->BindOnce(check_complete)); + module_handler_->BindOnceOn( + this, + &impl::on_set_advertising_enable_complete, + true, + enabled_sets, + false /* trigger_callbacks */)); } break; case (AdvertisingApiType::ANDROID_HCI): { for (size_t i = 0; i < enabled_sets_.size(); i++) { @@ -1475,15 +1506,12 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb if (id != kInvalidHandle) { le_advertising_interface_->EnqueueCommand( hci::LeMultiAdvtSetEnableBuilder::Create(Enable::ENABLED, id), - common::init_flags:: - trigger_advertising_callbacks_on_first_resume_after_pause_is_enabled() - ? module_handler_->BindOnceOn( - this, - &impl::on_set_advertising_enable_complete, - true, - enabled_sets, - false /* trigger_callbacks */) - : module_handler_->BindOnce(check_complete)); + module_handler_->BindOnceOn( + this, + &impl::on_set_advertising_enable_complete, + true, + enabled_sets, + false /* trigger_callbacks */)); } } } break; @@ -1491,17 +1519,13 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb if (enabled_sets.size() != 0) { le_advertising_interface_->EnqueueCommand( hci::LeSetExtendedAdvertisingEnableBuilder::Create(Enable::ENABLED, enabled_sets), - common::init_flags:: - trigger_advertising_callbacks_on_first_resume_after_pause_is_enabled() - ? module_handler_->BindOnceOn( - this, - &impl::on_set_extended_advertising_enable_complete< - LeSetExtendedAdvertisingEnableCompleteView>, - true, - enabled_sets, - false /* trigger_callbacks */) - : module_handler_->BindOnce( - check_complete)); + module_handler_->BindOnceOn( + this, + &impl::on_set_extended_advertising_enable_complete< + LeSetExtendedAdvertisingEnableCompleteView>, + true, + enabled_sets, + false /* trigger_callbacks */)); } } break; } @@ -1823,6 +1847,10 @@ size_t LeAdvertisingManager::GetNumberOfAdvertisingInstances() const { return pimpl_->GetNumberOfAdvertisingInstances(); } +size_t LeAdvertisingManager::GetNumberOfAdvertisingInstancesInUse() const { + return pimpl_->GetNumberOfAdvertisingInstancesInUse(); +} + int LeAdvertisingManager::GetAdvertiserRegId(AdvertiserId advertiser_id) { return pimpl_->get_advertiser_reg_id(advertiser_id); } diff --git a/system/gd/hci/le_advertising_manager.h b/system/gd/hci/le_advertising_manager.h index 448bde83f7b629ee942f14c7e2a3ea99e2876802..65d6820ff22c11983643f458eb6baf797de49a49 100644 --- a/system/gd/hci/le_advertising_manager.h +++ b/system/gd/hci/le_advertising_manager.h @@ -16,6 +16,7 @@ #pragma once #include +#include #include "common/callback.h" #include "hci/address_with_type.h" @@ -113,6 +114,8 @@ class LeAdvertisingManager : public bluetooth::Module { size_t GetNumberOfAdvertisingInstances() const; + size_t GetNumberOfAdvertisingInstancesInUse() const; + int GetAdvertiserRegId(AdvertiserId advertiser_id); void ExtendedCreateAdvertiser( diff --git a/system/gd/hci/le_advertising_manager_test.cc b/system/gd/hci/le_advertising_manager_test.cc index a048b0e99c988c081484a045b123bcc5dcb20445..bf2bcbcffed6d937038347b76d628cc1513ba5ad 100644 --- a/system/gd/hci/le_advertising_manager_test.cc +++ b/system/gd/hci/le_advertising_manager_test.cc @@ -103,10 +103,10 @@ class TestLeAddressManager : public LeAddressManager { common::Callback)> enqueue_command, os::Handler* handler, Address public_address, - uint8_t connect_list_size, + uint8_t accept_list_size, uint8_t resolving_list_size) : LeAddressManager( - enqueue_command, handler, public_address, connect_list_size, resolving_list_size) { + enqueue_command, handler, public_address, accept_list_size, resolving_list_size) { address_policy_ = AddressPolicy::USE_STATIC_ADDRESS; minimum_rotation_time_ = 0ms; maximum_rotation_time_ = 100ms; @@ -187,7 +187,7 @@ class TestAclManager : public AclManager { class LeAdvertisingManagerTest : public ::testing::Test { protected: void SetUp() override { - test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry + test_hci_layer_ = new HciLayerFake; // Ownership is transferred to registry test_controller_ = new TestController; test_acl_manager_ = new TestAclManager; test_controller_->AddSupported(param_opcode_); @@ -210,7 +210,7 @@ class LeAdvertisingManagerTest : public ::testing::Test { } TestModuleRegistry fake_registry_; - TestHciLayer* test_hci_layer_ = nullptr; + HciLayerFake* test_hci_layer_ = nullptr; TestController* test_controller_ = nullptr; TestAclManager* test_acl_manager_ = nullptr; os::Thread& thread_ = fake_registry_.GetTestThread(); @@ -1801,13 +1801,14 @@ TEST_F(LeExtendedAdvertisingManagerTest, use_rpa) { test_acl_manager_->SetAddressPolicy(LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS); // act: start advertising set with RPA + AdvertisingConfig config{}; + config.requested_advertiser_address_type = AdvertiserAddressType::RESOLVABLE_RANDOM; + config.channel_map = 1; + le_advertising_manager_->ExtendedCreateAdvertiser( kAdvertiserClientIdJni, 0x00, - AdvertisingConfig{ - .requested_advertiser_address_type = AdvertiserAddressType::RESOLVABLE_RANDOM, - .channel_map = 1, - }, + config, scan_callback, set_terminated_callback, 0, @@ -1829,13 +1830,14 @@ TEST_F(LeExtendedAdvertisingManagerTest, use_non_resolvable_address) { test_acl_manager_->SetAddressPolicy(LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS); // start advertising set with NRPA + AdvertisingConfig config{}; + config.requested_advertiser_address_type = AdvertiserAddressType::NONRESOLVABLE_RANDOM; + config.channel_map = 1; + le_advertising_manager_->ExtendedCreateAdvertiser( kAdvertiserClientIdJni, 0x00, - AdvertisingConfig{ - .requested_advertiser_address_type = AdvertiserAddressType::NONRESOLVABLE_RANDOM, - .channel_map = 1, - }, + config, scan_callback, set_terminated_callback, 0, @@ -1866,13 +1868,89 @@ TEST_F(LeExtendedAdvertisingManagerTest, use_public_address_type_if_public_addre test_acl_manager_->SetAddressPolicy(LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS); // act: start advertising set with RPA + AdvertisingConfig config{}; + config.requested_advertiser_address_type = AdvertiserAddressType::RESOLVABLE_RANDOM; + config.channel_map = 1; + le_advertising_manager_->ExtendedCreateAdvertiser( kAdvertiserClientIdJni, 0x00, - AdvertisingConfig{ - .requested_advertiser_address_type = AdvertiserAddressType::RESOLVABLE_RANDOM, - .channel_map = 1, - }, + config, + scan_callback, + set_terminated_callback, + 0, + 0, + client_handler_); + auto command = LeAdvertisingCommandView::Create(test_hci_layer_->GetCommand()); + + // assert + ASSERT_TRUE(command.IsValid()); + EXPECT_EQ(command.GetOpCode(), OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS); + + auto set_parameters_command = + LeSetExtendedAdvertisingParametersView::Create(LeAdvertisingCommandView::Create(command)); + ASSERT_TRUE(set_parameters_command.IsValid()); + EXPECT_EQ(set_parameters_command.GetOwnAddressType(), OwnAddressType::PUBLIC_DEVICE_ADDRESS); +} + +TEST_F_WITH_FLAGS( + LeExtendedAdvertisingManagerTest, + use_nrpa_if_public_address_policy_non_connectable, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, nrpa_non_connectable_adv))) { + // arrange: use PUBLIC address policy + test_acl_manager_->SetAddressPolicy(LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS); + + // act: start non-connectable advertising set with RPA + AdvertisingConfig config{}; + config.requested_advertiser_address_type = AdvertiserAddressType::RESOLVABLE_RANDOM; + config.channel_map = 1; + config.connectable = false; + + le_advertising_manager_->ExtendedCreateAdvertiser( + kAdvertiserClientIdJni, + 0x00, + config, + scan_callback, + set_terminated_callback, + 0, + 0, + client_handler_); + ASSERT_EQ( + test_hci_layer_->GetCommand().GetOpCode(), OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS); + test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingParametersCompleteBuilder::Create( + uint8_t{1}, ErrorCode::SUCCESS, static_cast(-23))); + + auto command = LeAdvertisingCommandView::Create(test_hci_layer_->GetCommand()); + ASSERT_TRUE(command.IsValid()); + ASSERT_EQ(command.GetOpCode(), OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS); + + auto set_address_command = + LeSetAdvertisingSetRandomAddressView::Create(LeAdvertisingCommandView::Create(command)); + ASSERT_TRUE(set_address_command.IsValid()); + EXPECT_EQ(set_address_command.GetOpCode(), OpCode::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS); + + // checking that it is an NRPA (first two bits = 0b00) + Address address = set_address_command.GetRandomAddress(); + EXPECT_EQ(address.data()[5] >> 6, 0b00); +} + +TEST_F_WITH_FLAGS( + LeExtendedAdvertisingManagerTest, + use_public_if_requested_with_public_address_policy_non_connectable, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, nrpa_non_connectable_adv))) { + // arrange: use PUBLIC address policy + test_acl_manager_->SetAddressPolicy(LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS); + + // act: start non-connectable advertising set with PUBLIC + AdvertisingConfig config{}; + config.requested_advertiser_address_type = AdvertiserAddressType::PUBLIC; + config.channel_map = 1; + config.connectable = false; + + le_advertising_manager_->ExtendedCreateAdvertiser( + kAdvertiserClientIdJni, + 0x00, + config, scan_callback, set_terminated_callback, 0, diff --git a/system/gd/hci/le_periodic_sync_manager.h b/system/gd/hci/le_periodic_sync_manager.h index 9036597ac5fc861815da0ccecfab82fb3fc8e2d7..2c9b06d512fb890f5ff2aee3fa57a605e2253d83 100644 --- a/system/gd/hci/le_periodic_sync_manager.h +++ b/system/gd/hci/le_periodic_sync_manager.h @@ -15,6 +15,8 @@ */ #pragma once +#include + #include #include #include @@ -26,6 +28,7 @@ #include "hci/hci_packets.h" #include "hci/le_scanning_callback.h" #include "hci/le_scanning_interface.h" +#include "hci/le_scanning_reassembler.h" #include "hci/uuid.h" #include "module.h" #include "os/alarm.h" @@ -313,13 +316,23 @@ class PeriodicSyncManager { LOG_ERROR("[PSync]: index not found for handle %u", sync_handle); return; } + + auto complete_advertising_data = + IS_FLAG_ENABLED(le_periodic_scanning_reassembler) + ? scanning_reassembler_.ProcessPeriodicAdvertisingReport( + sync_handle, DataStatus(event_view.GetDataStatus()), event_view.GetData()) + : event_view.GetData(); + if (!complete_advertising_data.has_value()) { + return; + } + LOG_DEBUG("%s", "[PSync]: invoking callback"); callbacks_->OnPeriodicSyncReport( sync_handle, event_view.GetTxPower(), event_view.GetRssi(), (uint16_t)event_view.GetDataStatus(), - event_view.GetData()); + complete_advertising_data.value()); } void HandleLePeriodicAdvertisingSyncLost(LePeriodicAdvertisingSyncLostView event_view) { @@ -532,6 +545,7 @@ class PeriodicSyncManager { std::list pending_sync_requests_; std::list periodic_syncs_; std::list periodic_sync_transfers_; + LeScanningReassembler scanning_reassembler_; bool sync_received_callback_registered_ = false; int sync_received_callback_id{}; }; diff --git a/system/gd/hci/le_scanning_callback.h b/system/gd/hci/le_scanning_callback.h index 211d09441b8d22020d6af676bff0b950abe52517..ef50933964452a2ec8d4b53c87ff65f24661e806 100644 --- a/system/gd/hci/le_scanning_callback.h +++ b/system/gd/hci/le_scanning_callback.h @@ -16,6 +16,7 @@ #pragma once #include +#include #include "common/callback.h" #include "hci/address_with_type.h" diff --git a/system/gd/hci/le_scanning_manager.cc b/system/gd/hci/le_scanning_manager.cc index a075c38b797167b1fd991197d2464851454552b3..7c5b934c41c88b6bdd5bc0b09b13f0abe1ff70cb 100644 --- a/system/gd/hci/le_scanning_manager.cc +++ b/system/gd/hci/le_scanning_manager.cc @@ -15,6 +15,8 @@ */ #include "hci/le_scanning_manager.h" +#include + #include #include @@ -377,8 +379,15 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { extended_event_type = transform_to_extended_event_type({.legacy = true}); break; case AdvertisingEventType::SCAN_RESPONSE: - extended_event_type = transform_to_extended_event_type( - {.connectable = true, .scannable = true, .scan_response = true, .legacy = true}); + if (IS_FLAG_ENABLED(fix_nonconnectable_scannable_advertisement)) { + // We don't know if the initial advertising report was connectable or not. + // LeScanningReassembler fixes the connectable field. + extended_event_type = transform_to_extended_event_type( + {.scannable = true, .scan_response = true, .legacy = true}); + } else { + extended_event_type = transform_to_extended_event_type( + {.connectable = true, .scannable = true, .scan_response = true, .legacy = true}); + } break; default: LOG_WARN("Unsupported event type:%d", (uint16_t)report.event_type_); @@ -452,12 +461,14 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { // with hardware-filtering features should we ignore waiting for scan response, and make sure // scan responses are still reported too. scanning_reassembler_.SetIgnoreScanResponses( + le_scan_type_ == LeScanType::PASSIVE || filter_policy_ == LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY); - auto complete_advertising_data = scanning_reassembler_.ProcessAdvertisingReport( - event_type, address_type, address, advertising_sid, advertising_data); + std::optional processed_report = + scanning_reassembler_.ProcessAdvertisingReport( + event_type, address_type, address, advertising_sid, advertising_data); - if (complete_advertising_data.has_value()) { + if (processed_report.has_value()) { switch (address_type) { case (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS: case (uint8_t)AddressType::PUBLIC_IDENTITY_ADDRESS: @@ -469,8 +480,12 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { break; } + const uint16_t result_event_type = IS_FLAG_ENABLED(fix_nonconnectable_scannable_advertisement) + ? processed_report->extended_event_type + : event_type; + scanning_callbacks_->OnScanResult( - event_type, + result_event_type, address_type, address, primary_phy, @@ -479,7 +494,7 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { tx_power, get_rssi_after_calibration(rssi), periodic_advertising_interval, - complete_advertising_data.value()); + std::move(processed_report->data)); } } @@ -594,7 +609,14 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { case ScanApiType::EXTENDED: le_scanning_interface_->EnqueueCommand( LeSetExtendedScanEnableBuilder::Create( - Enable::ENABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0), + Enable::ENABLED, +#if TARGET_FLOSS + FilterDuplicates::ENABLED /* filter duplicates */, +#else + FilterDuplicates::DISABLED /* filter duplicates */, +#endif + 0, + 0), module_handler_->BindOnce(check_complete)); break; case ScanApiType::ANDROID_HCI: @@ -618,7 +640,14 @@ struct LeScanningManager::impl : public LeAddressManagerCallback { case ScanApiType::EXTENDED: le_scanning_interface_->EnqueueCommand( LeSetExtendedScanEnableBuilder::Create( - Enable::DISABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0), + Enable::DISABLED, +#if TARGET_FLOSS + FilterDuplicates::ENABLED /* filter duplicates */, +#else + FilterDuplicates::DISABLED /* filter duplicates */, +#endif + 0, + 0), module_handler_->BindOnce(check_complete)); break; case ScanApiType::ANDROID_HCI: diff --git a/system/gd/hci/le_scanning_manager.h b/system/gd/hci/le_scanning_manager.h index 526728fc0e2a0fba9c8424b884d8b6e490191db4..64886f00d77ba984db8b91b516587de21c39803a 100644 --- a/system/gd/hci/le_scanning_manager.h +++ b/system/gd/hci/le_scanning_manager.h @@ -16,6 +16,7 @@ #pragma once #include +#include #include "common/callback.h" #include "hci/address_with_type.h" diff --git a/system/gd/hci/le_scanning_manager_test.cc b/system/gd/hci/le_scanning_manager_test.cc index 41539ee8c080591328de49b1c221c79873d4a1ab..95dddcc403883ba8c7cf7b0fa22823ce4d5ed86f 100644 --- a/system/gd/hci/le_scanning_manager_test.cc +++ b/system/gd/hci/le_scanning_manager_test.cc @@ -16,6 +16,7 @@ #include "hci/le_scanning_manager.h" +#include #include #include @@ -29,12 +30,12 @@ #include #include -#include "hci/hci_layer_fake.h" #include "common/bind.h" #include "hci/acl_manager.h" #include "hci/address.h" #include "hci/controller.h" #include "hci/hci_layer.h" +#include "hci/hci_layer_fake.h" #include "hci/uuid.h" #include "os/thread.h" #include "packet/raw_builder.h" @@ -51,6 +52,13 @@ using packet::RawBuilder; namespace { +// Event type fields. +// TODO(b/315496838): Use a common enum for event type bits. +static constexpr uint16_t kConnectable = 0x1; +static constexpr uint16_t kScannable = 0x2; +static constexpr uint16_t kScanResponse = 0x8; +static constexpr uint16_t kLegacy = 0x10; + hci::AdvertisingPacketContentFilterCommand make_filter(const hci::ApcfFilterType& filter_type) { hci::AdvertisingPacketContentFilterCommand filter{}; filter.filter_type = filter_type; @@ -160,9 +168,9 @@ class TestLeAddressManager : public LeAddressManager { common::Callback)> enqueue_command, os::Handler* handler, Address public_address, - uint8_t connect_list_size, + uint8_t accept_list_size, uint8_t resolving_list_size) - : LeAddressManager(enqueue_command, handler, public_address, connect_list_size, resolving_list_size) {} + : LeAddressManager(enqueue_command, handler, public_address, accept_list_size, resolving_list_size) {} AddressPolicy Register(LeAddressManagerCallback* callback) override { client_ = callback; @@ -280,7 +288,7 @@ class MockCallbacks : public bluetooth::hci::ScanningCallback { class LeScanningManagerTest : public ::testing::Test { protected: void SetUp() override { - test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry + test_hci_layer_ = new HciLayerFake; // Ownership is transferred to registry test_controller_ = new TestController; test_acl_manager_ = new TestAclManager; fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_); @@ -311,7 +319,7 @@ class LeScanningManagerTest : public ::testing::Test { } TestModuleRegistry fake_registry_; - TestHciLayer* test_hci_layer_ = nullptr; + HciLayerFake* test_hci_layer_ = nullptr; TestController* test_controller_ = nullptr; TestAclManager* test_acl_manager_ = nullptr; os::Thread& thread_ = fake_registry_.GetTestThread(); @@ -362,9 +370,11 @@ TEST_F(LeScanningManagerTest, start_scan_test) { // Enable scan le_scanning_manager->Scan(true); ASSERT_EQ(OpCode::LE_SET_SCAN_PARAMETERS, test_hci_layer_->GetCommand().GetOpCode()); - test_hci_layer_->IncomingEvent(LeSetScanParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); + test_hci_layer_->IncomingEvent( + LeSetScanParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); ASSERT_EQ(OpCode::LE_SET_SCAN_ENABLE, test_hci_layer_->GetCommand().GetOpCode()); - test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); + test_hci_layer_->IncomingEvent( + LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); LeAdvertisingResponse report = make_advertising_report(); EXPECT_CALL(mock_callbacks_, OnScanResult); @@ -372,6 +382,62 @@ TEST_F(LeScanningManagerTest, start_scan_test) { test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report})); } +TEST_F(LeScanningManagerTest, legacy_adv_scan_ind_report_with_scan_response) { + start_le_scanning_manager(); + + le_scanning_manager->Scan(true); + ASSERT_EQ(OpCode::LE_SET_SCAN_PARAMETERS, test_hci_layer_->GetCommand().GetOpCode()); + test_hci_layer_->IncomingEvent( + LeSetScanParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); + ASSERT_EQ(OpCode::LE_SET_SCAN_ENABLE, test_hci_layer_->GetCommand().GetOpCode()); + test_hci_layer_->IncomingEvent( + LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); + + LeAdvertisingResponse report = make_advertising_report(); + // Scannable & not connectable! + report.event_type_ = AdvertisingEventType::ADV_SCAN_IND; + + test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report})); + + LeAdvertisingResponse scan_response = make_advertising_report(); + scan_response.event_type_ = AdvertisingEventType::SCAN_RESPONSE; + + // The 'connectable' bit should NOT be set. + uint16_t extended_event_type = kLegacy | kScannable | kScanResponse; + if (!IS_FLAG_ENABLED(fix_nonconnectable_scannable_advertisement)) { + extended_event_type |= kConnectable; + } + EXPECT_CALL(mock_callbacks_, OnScanResult(extended_event_type, _, _, _, _, _, _, _, _, _)); + + test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({scan_response})); +} + +TEST_F(LeScanningManagerTest, legacy_adv_ind_report_with_scan_response) { + start_le_scanning_manager(); + + le_scanning_manager->Scan(true); + ASSERT_EQ(OpCode::LE_SET_SCAN_PARAMETERS, test_hci_layer_->GetCommand().GetOpCode()); + test_hci_layer_->IncomingEvent( + LeSetScanParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); + ASSERT_EQ(OpCode::LE_SET_SCAN_ENABLE, test_hci_layer_->GetCommand().GetOpCode()); + test_hci_layer_->IncomingEvent( + LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); + + LeAdvertisingResponse report = make_advertising_report(); + // Scannable & connectable! + report.event_type_ = AdvertisingEventType::ADV_IND; + + test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report})); + + LeAdvertisingResponse scan_response = make_advertising_report(); + scan_response.event_type_ = AdvertisingEventType::SCAN_RESPONSE; + + uint16_t extended_event_type = kLegacy | kScannable | kConnectable | kScanResponse; + EXPECT_CALL(mock_callbacks_, OnScanResult(extended_event_type, _, _, _, _, _, _, _, _, _)); + + test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({scan_response})); +} + TEST_F(LeScanningManagerTest, is_ad_type_filter_supported_false_test) { start_le_scanning_manager(); ASSERT_TRUE(fake_registry_.IsStarted(&HciLayer::Factory)); diff --git a/system/gd/hci/le_scanning_reassembler.cc b/system/gd/hci/le_scanning_reassembler.cc index 69998945932e350ef89da686439a0d1578b0be17..7d825fcb9c075201de26d27dead917a4a263e255 100644 --- a/system/gd/hci/le_scanning_reassembler.cc +++ b/system/gd/hci/le_scanning_reassembler.cc @@ -32,7 +32,8 @@ namespace bluetooth::hci { -std::optional> LeScanningReassembler::ProcessAdvertisingReport( +std::optional +LeScanningReassembler::ProcessAdvertisingReport( uint16_t event_type, uint8_t address_type, Address address, @@ -67,7 +68,7 @@ std::optional> LeScanningReassembler::ProcessAdvertisingRep // Concatenate the data with existing fragments. std::list::iterator advertising_fragment = - AppendFragment(key, advertising_data); + AppendFragment(key, event_type, advertising_data); // Trim the advertising data when the complete payload is received. if (data_status != DataStatus::CONTINUING) { @@ -89,9 +90,30 @@ std::optional> LeScanningReassembler::ProcessAdvertisingRep // Otherwise the full advertising report has been reassembled, // removed the cache entry and return the complete advertising data. - std::vector complete_advertising_data = std::move(advertising_fragment->data); + CompleteAdvertisingData result{ + .extended_event_type = advertising_fragment->extended_event_type, + .data = std::move(advertising_fragment->data)}; cache_.erase(advertising_fragment); - return complete_advertising_data; + return result; +} + +std::optional> LeScanningReassembler::ProcessPeriodicAdvertisingReport( + uint16_t sync_handle, DataStatus data_status, const std::vector& advertising_data) { + // Concatenate the data with existing fragments. + std::list::iterator advertising_fragment = + AppendPeriodicFragment(sync_handle, advertising_data); + + // Return and wait for additional fragments if the data is marked as + // incomplete. + if (data_status == DataStatus::CONTINUING) { + return {}; + } + + // The complete payload has been received; trim the advertising data, + // remove the cache entry and return the complete advertising data. + std::vector result = TrimAdvertisingData(advertising_fragment->data); + periodic_cache_.erase(advertising_fragment); + return result; } /// Trim the advertising data by removing empty or overflowing @@ -140,9 +162,19 @@ bool LeScanningReassembler::AdvertisingKey::operator==(const AdvertisingKey& oth /// If the advertiser is unknown a new entry is added, optionally by /// dropping the oldest advertiser. std::list::iterator -LeScanningReassembler::AppendFragment(const AdvertisingKey& key, const std::vector& data) { +LeScanningReassembler::AppendFragment( + const AdvertisingKey& key, uint16_t extended_event_type, const std::vector& data) { auto it = FindFragment(key); if (it != cache_.end()) { + // Legacy scan responses don't contain a 'connectable' bit, so this adds the + // 'connectable' bit from the initial report. + if ((extended_event_type & (1 << kLegacyBit)) && + (extended_event_type & (1 << kScanResponseBit))) { + it->extended_event_type = + extended_event_type | (it->extended_event_type & (1 << kConnectableBit)); + } else { + it->extended_event_type = extended_event_type; + } it->data.insert(it->data.end(), data.cbegin(), data.cend()); return it; } @@ -151,7 +183,7 @@ LeScanningReassembler::AppendFragment(const AdvertisingKey& key, const std::vect cache_.pop_back(); } - cache_.emplace_front(key, data); + cache_.emplace_front(key, extended_event_type, data); return cache_.begin(); } @@ -176,4 +208,34 @@ std::list::iterator LeScanningReasse return cache_.end(); } +/// Append to the current advertising data of the selected periodic advertiser. +/// If the advertiser is unknown a new entry is added, optionally by +/// dropping the oldest advertiser. +std::list::iterator +LeScanningReassembler::AppendPeriodicFragment( + uint16_t sync_handle, const std::vector& data) { + auto it = FindPeriodicFragment(sync_handle); + if (it != periodic_cache_.end()) { + it->data.insert(it->data.end(), data.cbegin(), data.cend()); + return it; + } + + if (periodic_cache_.size() > kMaximumPeriodicCacheSize) { + periodic_cache_.pop_back(); + } + + periodic_cache_.emplace_front(sync_handle, data); + return periodic_cache_.begin(); +} + +std::list::iterator +LeScanningReassembler::FindPeriodicFragment(uint16_t sync_handle) { + for (auto it = periodic_cache_.begin(); it != periodic_cache_.end(); it++) { + if (it->sync_handle == sync_handle) { + return it; + } + } + return periodic_cache_.end(); +} + } // namespace bluetooth::hci diff --git a/system/gd/hci/le_scanning_reassembler.h b/system/gd/hci/le_scanning_reassembler.h index 3708de210750d904544897cdb456676bc25eec49..e5e416e1f8e7b4ac904f52abe54ddadae8a0574d 100644 --- a/system/gd/hci/le_scanning_reassembler.h +++ b/system/gd/hci/le_scanning_reassembler.h @@ -29,14 +29,21 @@ namespace bluetooth::hci { /// The LE Scanning reassembler is responsible for defragmenting /// LE advertising reports that are too large to fit inside an HCI event -/// and were fragmented by the compiler. +/// and were fragmented by the controller. /// The reassembler also joins scan response data with the /// matching advertising data. class LeScanningReassembler { public: + struct CompleteAdvertisingData { + uint16_t extended_event_type; + std::vector data; + }; + LeScanningReassembler(){}; + LeScanningReassembler(const LeScanningReassembler&) = delete; + LeScanningReassembler& operator=(const LeScanningReassembler&) = delete; /// Process an incoming advertsing report, extracted from any of the @@ -44,13 +51,20 @@ class LeScanningReassembler { /// events. /// Returns the completed advertising data if the event was complete, or the /// completion of a fragmented advertising event. - std::optional> ProcessAdvertisingReport( + std::optional ProcessAdvertisingReport( uint16_t event_type, uint8_t address_type, Address address, uint8_t advertising_sid, const std::vector& advertising_data); + /// Process an incoming periodic advertising report, extracted from the + /// HCI LE Periodic Advertising Report events. + /// Returns the completed advertising data if the event was complete, + /// or the completion of a fragmented advertising event. + std::optional> ProcessPeriodicAdvertisingReport( + uint16_t sync_handle, DataStatus status, const std::vector& advertising_data); + /// Configure the scan response filter. /// If true all scan responses are ignored. void SetIgnoreScanResponses(bool ignore_scan_responses) { @@ -62,6 +76,7 @@ class LeScanningReassembler { bool ignore_scan_responses_{false}; /// Constants for parsing event_type. + static constexpr uint8_t kConnectableBit = 0; static constexpr uint8_t kScannableBit = 1; static constexpr uint8_t kDirectedBit = 2; static constexpr uint8_t kScanResponseBit = 3; @@ -89,10 +104,21 @@ class LeScanningReassembler { /// Packs incomplete advertising data. struct AdvertisingFragment { AdvertisingKey key; + uint16_t extended_event_type; + std::vector data; + + AdvertisingFragment( + const AdvertisingKey& key, uint16_t extended_event_type, const std::vector& data) + : key(key), extended_event_type(extended_event_type), data(data.begin(), data.end()) {} + }; + + /// Packs incomplete periodic advertising data. + struct PeriodicAdvertisingFragment { + std::optional sync_handle; std::vector data; - AdvertisingFragment(const AdvertisingKey& key, const std::vector& data) - : key(key), data(data.begin(), data.end()) {} + PeriodicAdvertisingFragment(uint16_t sync_handle, const std::vector& data) + : sync_handle(sync_handle), data(data.begin(), data.end()) {} }; /// Advertising cache for de-fragmenting extended advertising reports, @@ -105,11 +131,23 @@ class LeScanningReassembler { /// Advertising cache management methods. std::list::iterator AppendFragment( - const AdvertisingKey& key, const std::vector& data); + const AdvertisingKey& key, uint16_t extended_event_type, const std::vector& data); + void RemoveFragment(const AdvertisingKey& key); + bool ContainsFragment(const AdvertisingKey& key); + std::list::iterator FindFragment(const AdvertisingKey& key); + /// Advertising cache for de-fragmenting periodic advertising reports. + static constexpr size_t kMaximumPeriodicCacheSize = 16; + std::list periodic_cache_; + + std::list::iterator AppendPeriodicFragment( + uint16_t sync_handle, const std::vector& data); + + std::list::iterator FindPeriodicFragment(uint16_t sync_handle); + /// Trim the advertising data by removing empty or overflowing /// GAP Data entries. static std::vector TrimAdvertisingData(const std::vector& advertising_data); diff --git a/system/gd/hci/le_scanning_reassembler_test.cc b/system/gd/hci/le_scanning_reassembler_test.cc index 573d685378f1153115dc29fb7cc92688e9032960..828699fb78b44f0e2aa3f093d603aa02162fafed 100644 --- a/system/gd/hci/le_scanning_reassembler_test.cc +++ b/system/gd/hci/le_scanning_reassembler_test.cc @@ -28,6 +28,7 @@ using namespace std::chrono_literals; namespace bluetooth::hci { // Event type fields. +static constexpr uint16_t kConnectable = 0x1; static constexpr uint16_t kScannable = 0x2; static constexpr uint16_t kScanResponse = 0x8; static constexpr uint16_t kLegacy = 0x10; @@ -41,6 +42,10 @@ static constexpr uint8_t kSidNotPresent = 0xff; // Test addresses. static const Address kTestAddress = Address({0, 1, 2, 3, 4, 5}); +// Test sync handles. +static const uint16_t kTestSyncHandle1 = 0x4242; +static const uint16_t kTestSyncHandle2 = 0x4243; + class LeScanningReassemblerTest : public ::testing::Test { public: LeScanningReassembler reassembler_; @@ -66,16 +71,19 @@ TEST_F(LeScanningReassemblerTest, trim_advertising_data) { TEST_F(LeScanningReassemblerTest, non_scannable_legacy_advertising) { // Test non scannable legacy advertising. ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kLegacy | kComplete, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x1, 0x2}), + reassembler_ + .ProcessAdvertisingReport( + kLegacy | kComplete, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x1, 0x2}) + .value() + .data, std::vector({0x1, 0x2})); } -TEST_F(LeScanningReassemblerTest, scannable_legacy_advertising) { +TEST_F(LeScanningReassemblerTest, scannable_non_connectable_legacy_advertising) { // Test scannable legacy advertising with well formed advertising and // scan response payload. ASSERT_FALSE(reassembler_ @@ -87,14 +95,15 @@ TEST_F(LeScanningReassemblerTest, scannable_legacy_advertising) { {0x1, 0x2}) .has_value()); - ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kLegacy | kScannable | kScanResponse | kComplete, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x3, 0x4, 0x5, 0x6}), - std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); + auto processed_report = reassembler_.ProcessAdvertisingReport( + kLegacy | kScannable | kScanResponse | kComplete, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x3, 0x4, 0x5, 0x6}); + ASSERT_TRUE(processed_report.has_value()); + ASSERT_EQ(processed_report.value().extended_event_type, kLegacy | kScannable | kScanResponse); + ASSERT_EQ(processed_report.value().data, std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); // Test scannable legacy advertising with padding after the // advertising and scan response data. @@ -108,15 +117,41 @@ TEST_F(LeScanningReassemblerTest, scannable_legacy_advertising) { .has_value()); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kLegacy | kScannable | kScanResponse | kComplete, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x3, 0x4, 0x5, 0x6, 0x0, 0x0}), + reassembler_ + .ProcessAdvertisingReport( + kLegacy | kScannable | kScanResponse | kComplete, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x3, 0x4, 0x5, 0x6, 0x0, 0x0}) + .value() + .data, std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); } +TEST_F(LeScanningReassemblerTest, scannable_connectable_legacy_advertising) { + ASSERT_FALSE(reassembler_ + .ProcessAdvertisingReport( + kLegacy | kScannable | kConnectable, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x1, 0x2}) + .has_value()); + + auto processed_report = reassembler_.ProcessAdvertisingReport( + kLegacy | kScannable | kScanResponse, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x3, 0x4, 0x5, 0x6}); + ASSERT_TRUE(processed_report.has_value()); + ASSERT_EQ( + processed_report.value().extended_event_type, + kLegacy | kScannable | kScanResponse | kConnectable); + ASSERT_EQ(processed_report.value().data, std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); +} + TEST_F(LeScanningReassemblerTest, non_scannable_extended_advertising) { // Test fragmented non scannable extended advertising. // The split may occur in the middle of a GAP entry. @@ -129,14 +164,15 @@ TEST_F(LeScanningReassemblerTest, non_scannable_extended_advertising) { {0x1, 0x2, 0x3}) .has_value()); - ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kComplete, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x4, 0x5, 0x6}), - std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); + auto processed_report = reassembler_.ProcessAdvertisingReport( + kComplete, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x4, 0x5, 0x6}); + ASSERT_TRUE(processed_report.has_value()); + ASSERT_EQ(processed_report.value().extended_event_type, kComplete); + ASSERT_EQ(processed_report.value().data, std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); // Test fragmented and truncated non scannable extended advertising. // The split may occur in the middle of a GAP entry. @@ -150,12 +186,15 @@ TEST_F(LeScanningReassemblerTest, non_scannable_extended_advertising) { .has_value()); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kTruncated, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x4, 0x5, 0x6, 0x7}), + reassembler_ + .ProcessAdvertisingReport( + kTruncated, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x4, 0x5, 0x6, 0x7}) + .value() + .data, std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); // Test fragmented and truncated anonymous, non scannable @@ -170,12 +209,15 @@ TEST_F(LeScanningReassemblerTest, non_scannable_extended_advertising) { .has_value()); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kTruncated, - (uint8_t)DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED, - Address::kEmpty, - kSidNotPresent, - {0x4, 0x5, 0x6, 0x7}), + reassembler_ + .ProcessAdvertisingReport( + kTruncated, + (uint8_t)DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED, + Address::kEmpty, + kSidNotPresent, + {0x4, 0x5, 0x6, 0x7}) + .value() + .data, std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); } @@ -211,12 +253,15 @@ TEST_F(LeScanningReassemblerTest, scannable_extended_advertising) { .has_value()); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kTruncated, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0xb, 0xc, 0xd, 0xe, 0x0}), + reassembler_ + .ProcessAdvertisingReport( + kTruncated, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0xb, 0xc, 0xd, 0xe, 0x0}) + .value() + .data, std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe})); } @@ -232,23 +277,29 @@ TEST_F(LeScanningReassemblerTest, ignore_scan_responses) { .has_value()); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kComplete, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x1, 0x2}), + reassembler_ + .ProcessAdvertisingReport( + kComplete, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x1, 0x2}) + .value() + .data, std::vector({0x1, 0x2})); // The option ignore_scan_responses forces scan responses to be dropped. reassembler_.SetIgnoreScanResponses(true); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kScannable | kComplete, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x1, 0x2}), + reassembler_ + .ProcessAdvertisingReport( + kScannable | kComplete, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x1, 0x2}) + .value() + .data, std::vector({0x1, 0x2})); } @@ -292,36 +343,92 @@ TEST_F(LeScanningReassemblerTest, interleaved_advertising) { .has_value()); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kComplete, - (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x0}), + reassembler_ + .ProcessAdvertisingReport( + kComplete, + (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x0}) + .value() + .data, std::vector({0x2, 0x0, 0x0})); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kComplete, - (uint8_t)AddressType::RANDOM_DEVICE_ADDRESS, - kTestAddress, - kSidNotPresent, - {0x1}), + reassembler_ + .ProcessAdvertisingReport( + kComplete, + (uint8_t)AddressType::RANDOM_DEVICE_ADDRESS, + kTestAddress, + kSidNotPresent, + {0x1}) + .value() + .data, std::vector({0x2, 0x1, 0x1})); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kComplete, (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, kTestAddress, 0x1, {0x2}), + reassembler_ + .ProcessAdvertisingReport( + kComplete, (uint8_t)AddressType::PUBLIC_DEVICE_ADDRESS, kTestAddress, 0x1, {0x2}) + .value() + .data, std::vector({0x2, 0x2, 0x2})); ASSERT_EQ( - reassembler_.ProcessAdvertisingReport( - kComplete, - (uint8_t)DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED, - Address::kEmpty, - 0x1, - {0x3}), + reassembler_ + .ProcessAdvertisingReport( + kComplete, + (uint8_t)DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED, + Address::kEmpty, + 0x1, + {0x3}) + .value() + .data, std::vector({0x2, 0x3, 0x3})); } +TEST_F(LeScanningReassemblerTest, periodic_advertising) { + // Test periodic advertising. + ASSERT_FALSE( + reassembler_ + .ProcessPeriodicAdvertisingReport(kTestSyncHandle1, DataStatus::CONTINUING, {0x1, 0x2}) + .has_value()); + + auto processed_report = reassembler_.ProcessPeriodicAdvertisingReport( + kTestSyncHandle1, DataStatus::COMPLETE, {0x3, 0x4, 0x5, 0x6}); + ASSERT_TRUE(processed_report.has_value()); + ASSERT_EQ(processed_report.value(), std::vector({0x1, 0x2, 0x3, 0x4, 0x5, 0x6})); + + // Test periodic advertising with the same handle + // to validate that the context was cleared. + processed_report = reassembler_.ProcessPeriodicAdvertisingReport( + kTestSyncHandle1, DataStatus::COMPLETE, {0x4, 0xa0, 0xb0, 0xc0, 0xd0}); + ASSERT_TRUE(processed_report.has_value()); + ASSERT_EQ(processed_report.value(), std::vector({0x4, 0xa0, 0xb0, 0xc0, 0xd0})); +} + +TEST_F(LeScanningReassemblerTest, interleaved_periodic_advertising) { + // The reassembler must disambiguate advertising events by address, + // address type, and SID. + ASSERT_FALSE( + reassembler_ + .ProcessPeriodicAdvertisingReport(kTestSyncHandle1, DataStatus::CONTINUING, {0x2, 0x0}) + .has_value()); + + ASSERT_FALSE( + reassembler_ + .ProcessPeriodicAdvertisingReport(kTestSyncHandle2, DataStatus::CONTINUING, {0x2, 0x1}) + .has_value()); + + ASSERT_EQ( + reassembler_.ProcessPeriodicAdvertisingReport(kTestSyncHandle1, DataStatus::COMPLETE, {0x0}) + .value(), + std::vector({0x2, 0x0, 0x0})); + + ASSERT_EQ( + reassembler_.ProcessPeriodicAdvertisingReport(kTestSyncHandle2, DataStatus::COMPLETE, {0x1}) + .value(), + std::vector({0x2, 0x1, 0x1})); +} + } // namespace bluetooth::hci diff --git a/system/gd/hci/remote_name_request.cc b/system/gd/hci/remote_name_request.cc index 5c5c5c8cc182f1d21403b053c081d1c488d98f06..ad5075b65f0e14a7c38b2b99aa76e7ce023120fd 100644 --- a/system/gd/hci/remote_name_request.cc +++ b/system/gd/hci/remote_name_request.cc @@ -16,14 +16,12 @@ #include "remote_name_request.h" -#include -#include -#include -#include +#include #include "hci/acl_manager/acl_scheduler.h" #include "hci/event_checkers.h" #include "hci/hci_layer.h" +#include "hci/hci_packets.h" namespace bluetooth { namespace hci { @@ -144,9 +142,9 @@ struct RemoteNameRequestModule::impl { #endif ASSERT(status.GetCommandOpCode() == OpCode::REMOTE_NAME_REQUEST); LOG_INFO( - "Got status %hhu when starting remote name request to to %s", - status.GetStatus(), - address.ToString().c_str()); + "Started remote name request peer:%s status:%s", + address.ToString().c_str(), + ErrorCodeText(status.GetStatus()).c_str()); on_completion.Invoke(status.GetStatus()); if (status.GetStatus() != ErrorCode::SUCCESS /* pending */) { pending_ = false; @@ -155,11 +153,26 @@ struct RemoteNameRequestModule::impl { } void actually_cancel_remote_name_request(Address address) { - ASSERT(pending_ == true); - LOG_INFO("Cancelling remote name request to %s", address.ToRedactedStringForLogging().c_str()); - hci_layer_->EnqueueCommand( - RemoteNameRequestCancelBuilder::Create(address), - handler_->BindOnce(check_complete)); + if (IS_FLAG_ENABLED(rnr_cancel_before_event_race)) { + if (pending_) { + LOG_INFO( + "Cancelling remote name request to %s", address.ToRedactedStringForLogging().c_str()); + hci_layer_->EnqueueCommand( + RemoteNameRequestCancelBuilder::Create(address), + handler_->BindOnce(check_complete)); + } else { + LOG_INFO( + "Ignoring cancel RNR as RNR event already received to %s", + address.ToRedactedStringForLogging().c_str()); + } + } else { + ASSERT(pending_ == true); + LOG_INFO( + "Cancelling remote name request to %s", address.ToRedactedStringForLogging().c_str()); + hci_layer_->EnqueueCommand( + RemoteNameRequestCancelBuilder::Create(address), + handler_->BindOnce(check_complete)); + } } void on_remote_host_supported_features_notification(EventView view) { @@ -254,4 +267,4 @@ void RemoteNameRequestModule::Stop() { } } // namespace hci -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/gd/hci/remote_name_request_test.cc b/system/gd/hci/remote_name_request_test.cc index ebddd0112313e10255d80beeb4e88458fcc9270f..b6ef89f5464615d3e992a72ea6ac916a7c1e5da9 100644 --- a/system/gd/hci/remote_name_request_test.cc +++ b/system/gd/hci/remote_name_request_test.cc @@ -16,19 +16,18 @@ #include "hci/remote_name_request.h" +#include +#include #include #include #include #include #include -#include #include +#include -#include "common/bind.h" -#include "common/init_flags.h" #include "hci/address.h" -#include "hci/controller_mock.h" #include "hci/hci_layer_fake.h" #include "os/thread.h" @@ -65,7 +64,7 @@ MATCHER_P(IsSetWithValue, matcher, "Future is not set with value") { class RemoteNameRequestModuleTest : public ::testing::Test { protected: void SetUp() override { - test_hci_layer_ = new TestHciLayer; + test_hci_layer_ = new HciLayerFake; fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_); fake_registry_.Start(&thread_); @@ -120,7 +119,7 @@ class RemoteNameRequestModuleTest : public ::testing::Test { TestModuleRegistry fake_registry_; os::Thread& thread_ = fake_registry_.GetTestThread(); - TestHciLayer* test_hci_layer_ = nullptr; + HciLayerFake* test_hci_layer_ = nullptr; RemoteNameRequestModule* remote_name_request_module_ = nullptr; os::Handler* client_handler_ = nullptr; }; @@ -254,7 +253,7 @@ TEST_F(RemoteNameRequestModuleTest, SendCommandThenCancelItCallback) { future, IsSetWithValue(Eq(std::make_tuple(ErrorCode::UNKNOWN_CONNECTION, remote_name1)))); } -// TODO(aryarahul) - unify TestHciLayer so this test can be run +// TODO(aryarahul) - unify HciLayerFake so this test can be run TEST_F(RemoteNameRequestModuleTest, DISABLED_SendCommandThenCancelItCallbackInteropWorkaround) { // Some controllers INCORRECTLY give us an ACL Connection Complete event, rather than a Remote // Name Request Complete event, if we issue a cancellation. We should nonetheless handle this @@ -630,6 +629,49 @@ TEST_F(RemoteNameRequestModuleTest, FailToSendCommandThenDequeueNext) { EXPECT_EQ(rnr_command.GetBdAddr(), address2); } +#define MY_PACKAGE com::android::bluetooth::flags + +TEST_F_WITH_FLAGS( + RemoteNameRequestModuleTest, + CancelJustWhenRNREventReturns, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(MY_PACKAGE, rnr_cancel_before_event_race))) { + auto promise = std::promise>>{}; + auto future = promise.get_future(); + + // start a remote name request + remote_name_request_module_->StartRemoteNameRequest( + address1, + RemoteNameRequestBuilder::Create( + address1, PageScanRepetitionMode::R0, 3, ClockOffsetValid::INVALID), + emptyCallback(), + impossibleCallback(), + capturingPromiseCallback>(std::move(promise))); + + // we successfully start + test_hci_layer_->GetCommand(); + + auto promise2 = std::promise(); + auto future2 = promise2.get_future(); + client_handler_->Post(base::BindOnce( + [](RemoteNameRequestModule* remote_name_request_module, + HciLayerFake* test_hci_layer, + std::promise promise2) { + // but then the request is cancelled successfully (the status doesn't matter) + remote_name_request_module->CancelRemoteNameRequest(address1); + + // Send an rnr event completed with page timeout status + test_hci_layer->IncomingEvent( + RemoteNameRequestStatusBuilder::Create(ErrorCode::PAGE_TIMEOUT, 1)); + + promise2.set_value(); + }, + remote_name_request_module_, + test_hci_layer_, + std::move(promise2))); + + future2.wait(); +} + } // namespace } // namespace hci } // namespace bluetooth diff --git a/system/gd/iso/internal/iso_manager_impl.h b/system/gd/iso/internal/iso_manager_impl.h index b29702505dfa0e80ced2e1960667c54cfa2cd264..c83a182743674de701d237a94e4ec238110b24f6 100644 --- a/system/gd/iso/internal/iso_manager_impl.h +++ b/system/gd/iso/internal/iso_manager_impl.h @@ -16,13 +16,14 @@ #pragma once +#include +#include + #include "hci/controller.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" #include "os/handler.h" -#include - namespace bluetooth { namespace iso { using SetCigParametersCallback = common::ContextualOnceCallback)>; diff --git a/system/gd/l2cap/classic/internal/link_manager.cc b/system/gd/l2cap/classic/internal/link_manager.cc index 87f36b6e91c29dad89950b4128eedf7a7c37f517..adc4c43fb6a5da1d5ef6c8bdff4a2aea15042209 100644 --- a/system/gd/l2cap/classic/internal/link_manager.cc +++ b/system/gd/l2cap/classic/internal/link_manager.cc @@ -320,16 +320,6 @@ void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason, bool pending_links_.erase(pending_link); } -void LinkManager::HACK_OnEscoConnectRequest( - hci::Address /* device */, hci::ClassOfDevice /* cod */) { - LOG_ERROR("Remote ESCO connect request unimplemented"); -} - -void LinkManager::HACK_OnScoConnectRequest( - hci::Address /* device */, hci::ClassOfDevice /* cod */) { - LOG_ERROR("Remote SCO connect request unimplemented"); -} - void LinkManager::OnDisconnect(hci::Address device, hci::ErrorCode status) { auto* link = GetLink(device); ASSERT_LOG( diff --git a/system/gd/l2cap/classic/internal/link_manager.h b/system/gd/l2cap/classic/internal/link_manager.h index 1b982c9ef185a97156be6af290b3ff2986edc9ec..482c07c6f0e555494fe312d54608f5b31f2e5fd4 100644 --- a/system/gd/l2cap/classic/internal/link_manager.h +++ b/system/gd/l2cap/classic/internal/link_manager.h @@ -18,6 +18,7 @@ #include #include +#include #include "hci/acl_manager/classic_acl_connection.h" #include "hci/address.h" @@ -71,9 +72,6 @@ class LinkManager : public hci::acl_manager::ConnectionCallbacks { void OnConnectRequest(hci::Address, hci::ClassOfDevice) override; void OnConnectFail(hci::Address device, hci::ErrorCode reason, bool locally_initiated) override; - void HACK_OnEscoConnectRequest(hci::Address, hci::ClassOfDevice) override; - void HACK_OnScoConnectRequest(hci::Address, hci::ClassOfDevice) override; - virtual void OnDisconnect(hci::Address device, hci::ErrorCode status); void OnAuthenticationComplete(hci::ErrorCode hci_status, hci::Address device); void OnEncryptionChange(hci::Address device, hci::EncryptionEnabled enabled); diff --git a/system/gd/l2cap/fuzz/Android.bp b/system/gd/l2cap/fuzz/Android.bp index 7cd46ce4fcbfc5977a1be3b4ff9f4592caaa29b8..72194fd61a3e69d23f678a55f109ae060469e368 100644 --- a/system/gd/l2cap/fuzz/Android.bp +++ b/system/gd/l2cap/fuzz/Android.bp @@ -17,11 +17,9 @@ cc_fuzz { "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/sys", "packages/modules/Bluetooth/system/btif/co", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/embdrv/sbc/decoder/include", "packages/modules/Bluetooth/system/embdrv/sbc/encoder/include", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/a2dp", "packages/modules/Bluetooth/system/stack/avdt", "packages/modules/Bluetooth/system/stack/btm", diff --git a/system/gd/l2cap/fuzz/channel_fuzz_controller.h b/system/gd/l2cap/fuzz/channel_fuzz_controller.h index ade2026ec519558c26d91115f4ccd061d1aa4a15..a6128204d354c3b7b5689dccfab126861fbcde24 100644 --- a/system/gd/l2cap/fuzz/channel_fuzz_controller.h +++ b/system/gd/l2cap/fuzz/channel_fuzz_controller.h @@ -17,7 +17,10 @@ // dylan.katz@leviathansecurity.com #pragma once -#include "gd/fuzz/helpers.h" + +#include + +#include "fuzz/helpers.h" #include "l2cap/classic/internal/fixed_channel_impl.h" #include "l2cap/internal/dynamic_channel_impl.h" #include "l2cap/l2cap_packets.h" diff --git a/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager.h b/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager.h index 22b529185d0f5e08f7539cc1b864278b55c2d651..ce9c6bd8b67611643a5c18919711cfa42d0bb7a3 100644 --- a/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager.h +++ b/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager.h @@ -18,19 +18,12 @@ #pragma once -#include -#include -#include -#include - +#include "fuzz_dynamic_channel_manager_impl.h" #include "hci/address.h" #include "l2cap/classic/dynamic_channel_configuration_option.h" #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/security_policy.h" #include "l2cap/psm.h" -#include "os/handler.h" - -#include "fuzz_dynamic_channel_manager_impl.h" namespace bluetooth { namespace shim { diff --git a/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager_impl.h b/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager_impl.h index 9962c65717bd170e61803acacb0add4151ba55c0..d8a8b3f35d752ebad1f6f106363e7d3854190173 100644 --- a/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager_impl.h +++ b/system/gd/l2cap/fuzz/fuzz_dynamic_channel_manager_impl.h @@ -18,7 +18,6 @@ #pragma once -#include #include #include @@ -27,7 +26,6 @@ #include "l2cap/classic/dynamic_channel_manager.h" #include "l2cap/classic/security_policy.h" #include "l2cap/psm.h" -#include "os/handler.h" namespace bluetooth { namespace shim { diff --git a/system/gd/l2cap/fuzz/shim_l2cap.h b/system/gd/l2cap/fuzz/shim_l2cap.h index 1d59f866e73dfe62583f1b599fc31cb8032e53e4..2bd27d5c542701ccc2f661745e80933b554ff19d 100644 --- a/system/gd/l2cap/fuzz/shim_l2cap.h +++ b/system/gd/l2cap/fuzz/shim_l2cap.h @@ -19,19 +19,19 @@ #pragma once #include -#include -#include -#include -#include + #include #include +#include "fuzz_l2cap_classic_module.h" #include "hci/fuzz/fuzz_hci_layer.h" +#include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h" +#include "l2cap/classic/internal/fixed_channel_service_manager_impl.h" +#include "l2cap/classic/internal/link_manager.h" #include "l2cap/classic/l2cap_classic_module.h" +#include "l2cap/internal/parameter_provider.h" #include "os/handler.h" -#include "fuzz_l2cap_classic_module.h" - namespace bluetooth { namespace shim { diff --git a/system/gd/l2cap/le/internal/link_manager.h b/system/gd/l2cap/le/internal/link_manager.h index 836a3f6e8cfb02f49bd300aa7245b04e0a4ce2a4..3a9814375635791fd23cd212c8db17952e8d5203 100644 --- a/system/gd/l2cap/le/internal/link_manager.h +++ b/system/gd/l2cap/le/internal/link_manager.h @@ -20,8 +20,7 @@ #include #include #include - -#include "os/handler.h" +#include #include "hci/acl_manager/le_acl_connection.h" #include "hci/address.h" @@ -34,6 +33,7 @@ #include "l2cap/le/internal/fixed_channel_service_manager_impl.h" #include "l2cap/le/internal/link.h" #include "l2cap/le/link_property_listener.h" +#include "os/handler.h" namespace bluetooth { namespace l2cap { diff --git a/system/gd/metrics/BUILD.gn b/system/gd/metrics/BUILD.gn index 3f248bab2f5a3845bf420c8ff73afc3565ea9e39..b0be59cc8995bdab38f6fb385649dba94cebc003 100644 --- a/system/gd/metrics/BUILD.gn +++ b/system/gd/metrics/BUILD.gn @@ -22,12 +22,18 @@ source_set("BluetoothMetricsSources_chromeos") { ] deps = [ "//bt/system/gd:gd_default_deps" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } source_set("BluetoothMetricsSources_linux") { sources = [ "linux/metrics.cc" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } source_set("BluetoothMetricsSources") { @@ -37,7 +43,10 @@ source_set("BluetoothMetricsSources") { "metrics_state.cc" ] - configs += [ "//bt/system/gd:gd_defaults"] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] if (target_os == "chromeos") { diff --git a/system/gd/metrics/chromeos/metrics.cc b/system/gd/metrics/chromeos/metrics.cc index 9ee8f05b2ccb8da10692d656d57b2bedccd8c437..1b9bca0042383250172751f94e56f29140f682b9 100644 --- a/system/gd/metrics/chromeos/metrics.cc +++ b/system/gd/metrics/chromeos/metrics.cc @@ -15,15 +15,15 @@ */ #define LOG_TAG "BluetoothMetrics" -#include "gd/metrics/metrics.h" +#include "metrics/metrics.h" #include #include "common/time_util.h" -#include "gd/metrics/chromeos/metrics_allowlist.h" -#include "gd/metrics/chromeos/metrics_event.h" -#include "gd/metrics/utils.h" -#include "gd/os/log.h" +#include "metrics/chromeos/metrics_allowlist.h" +#include "metrics/chromeos/metrics_event.h" +#include "metrics/utils.h" +#include "os/log.h" namespace bluetooth { namespace metrics { @@ -318,5 +318,24 @@ void LogMetricsChipsetInfoReport() { } } +void LogMetricsSuspendIdState(uint32_t state) { + int64_t suspend_id_state = 0; + int64_t boot_time; + std::string boot_id; + + if (!GetBootId(&boot_id)) return; + + boot_time = bluetooth::common::time_get_os_boottime_us(); + + suspend_id_state = (int64_t)ToSuspendIdState(state); + LOG_DEBUG("SuspendIdState: %s, %d, %d", boot_id.c_str(), boot_time, suspend_id_state); + + ::metrics::structured::events::bluetooth::BluetoothSuspendIdStateChanged() + .SetBootId(boot_id) + .SetSystemTime(boot_time) + .SetSuspendIdState(suspend_id_state) + .Record(); +} + } // namespace metrics } // namespace bluetooth diff --git a/system/gd/metrics/chromeos/metrics_event.cc b/system/gd/metrics/chromeos/metrics_event.cc index a1efc368fff58868508d5ab30b32d44d266e379b..f884c0b1bc5a645c93fb3461375d44e5ae23ad7d 100644 --- a/system/gd/metrics/chromeos/metrics_event.cc +++ b/system/gd/metrics/chromeos/metrics_event.cc @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gd/metrics/chromeos/metrics_event.h" +#include "metrics/chromeos/metrics_event.h" #include #include @@ -25,7 +25,7 @@ #include #include -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "hci/hci_packets.h" #include "include/hardware/bluetooth.h" #include "include/hardware/bt_av.h" @@ -234,6 +234,10 @@ AdapterState ToAdapterState(uint32_t state) { return state == 1 ? AdapterState::ON : AdapterState::OFF; } +SuspendIdState ToSuspendIdState(uint32_t state) { + return state == 1 ? SuspendIdState::Recorded : SuspendIdState::NoRecord; +} + ConnectionType ToPairingDeviceType(std::string addr, uint32_t device_type) { // A map stores the pending ConnectionType used to match a pairing event with unknown type. // map diff --git a/system/gd/metrics/chromeos/metrics_event.h b/system/gd/metrics/chromeos/metrics_event.h index 3a641f807402b618895f301cb3a25d6940da6009..b67ee2c711429152a9af7b5d77c1ac2a5397449e 100644 --- a/system/gd/metrics/chromeos/metrics_event.h +++ b/system/gd/metrics/chromeos/metrics_event.h @@ -195,6 +195,10 @@ enum class MetricTransportType { TRANSPORT_TYPE_SDIO = 3, }; +// ENUM definition for suspend id state that in sync with ChromeOS structured metrics +// BluetoothSuspendIdStateChanged/SuspendIdState. +enum class SuspendIdState : int64_t { NoRecord = 0, Recorded = 1 }; + // A struct holds the parsed profile connection event. struct ProfileConnectionEvent { int64_t type; @@ -205,6 +209,9 @@ struct ProfileConnectionEvent { // Convert topshim::btif::BtState to AdapterState. AdapterState ToAdapterState(uint32_t state); +// Convert to SuspendIdState. +SuspendIdState ToSuspendIdState(uint32_t state); + // Convert topshim::btif::BtDeviceType to ConnectionType ConnectionType ToPairingDeviceType(std::string addr, uint32_t device_type); diff --git a/system/gd/metrics/linux/metrics.cc b/system/gd/metrics/linux/metrics.cc index 601675b413e1f7ef3f83acbcea80cd4ff957061b..9792edf7e43a6310e2734dbc6a07f63b22e243be 100644 --- a/system/gd/metrics/linux/metrics.cc +++ b/system/gd/metrics/linux/metrics.cc @@ -15,7 +15,7 @@ */ #define LOG_TAG "BluetoothMetrics" -#include "gd/metrics/metrics.h" +#include "metrics/metrics.h" namespace bluetooth { namespace metrics { @@ -51,5 +51,7 @@ void LogMetricsAclConnectionStateChanged( void LogMetricsChipsetInfoReport() {} +void LogMetricsSuspendIdState(uint32_t state){}; + } // namespace metrics } // namespace bluetooth diff --git a/system/gd/metrics/metrics.h b/system/gd/metrics/metrics.h index 6e22318c408e9c2254abd61174c59e9ac8a8c5a0..16b95a1c6555bfa118f55cc5430ebbac22d6cbbd 100644 --- a/system/gd/metrics/metrics.h +++ b/system/gd/metrics/metrics.h @@ -40,5 +40,7 @@ void LogMetricsAclConnectionStateChanged( RawAddress* addr, uint32_t transport, uint32_t status, uint32_t acl_state, uint32_t direction, uint32_t hci_reason); void LogMetricsChipsetInfoReport(); +void LogMetricsSuspendIdState(uint32_t state); + } // namespace metrics } // namespace bluetooth diff --git a/system/gd/module.cc b/system/gd/module.cc index ee3c62f02191115b4a0df9b58c4f97475f3c5dc1..218335cc2e9fda683d716baf8b9abef965b2625e 100644 --- a/system/gd/module.cc +++ b/system/gd/module.cc @@ -18,7 +18,6 @@ #include "module.h" #include "common/init_flags.h" -#include "module_dumper_flatbuffer.h" using ::bluetooth::os::Handler; using ::bluetooth::os::Thread; @@ -35,10 +34,6 @@ Handler* Module::GetHandler() const { return handler_; } -DumpsysDataFinisher Module::GetDumpsysData(flatbuffers::FlatBufferBuilder* /* builder */) const { - return EmptyDumpsysDataFinisher; -} - const ModuleRegistry* Module::GetModuleRegistry() const { return registry_; } diff --git a/system/gd/module.h b/system/gd/module.h index 7083fa0725fe2f6cba836a3f991f0a2dd64d453e..f71fdb8ee8b5933db72a1f4cb8fd49a941d1ada0 100644 --- a/system/gd/module.h +++ b/system/gd/module.h @@ -16,7 +16,6 @@ #pragma once -#include #include #include #include @@ -26,7 +25,7 @@ #include #include "common/bind.h" -#include "dumpsys_data_generated.h" +#include "module_state_dumper.h" #include "os/handler.h" #include "os/log.h" #include "os/thread.h" @@ -60,12 +59,15 @@ public: list_.push_back(&T::Factory); } + // Return the number of modules in this list + size_t NumModules() const { + return list_.size(); + } + private: std::vector list_; }; -using DumpsysDataFinisher = std::function; - // Each leaf node module must have a factory like so: // // static const ModuleFactory Factory; @@ -73,7 +75,7 @@ using DumpsysDataFinisher = std::function + #include "common/init_flags.h" #include "dumpsys_data_generated.h" #include "module.h" @@ -26,7 +28,7 @@ using ::bluetooth::os::WakelockManager; namespace bluetooth { -void ModuleDumper::DumpState(std::string* output) const { +void ModuleDumper::DumpState(std::string* output, std::ostringstream& oss) const { ASSERT(output != nullptr); flatbuffers::FlatBufferBuilder builder(1024); @@ -51,6 +53,9 @@ void ModuleDumper::DumpState(std::string* output) const { it++) { auto instance = module_registry_.started_modules_.find(*it); ASSERT(instance != module_registry_.started_modules_.end()); + instance->second->GetDumpsysData(); + instance->second->GetDumpsysData(fd_); + instance->second->GetDumpsysData(oss); queue.push(instance->second->GetDumpsysData(&builder)); } diff --git a/system/gd/module_dumper.h b/system/gd/module_dumper.h index 95863c916ff58f01ef3f5dfa3c8f7ea22f195aa9..94706f7ffba722134c4c6cf2f969c61c36e1da3c 100644 --- a/system/gd/module_dumper.h +++ b/system/gd/module_dumper.h @@ -16,19 +16,23 @@ #pragma once +#include #include +#include "module.h" + namespace bluetooth { class ModuleRegistry; class ModuleDumper { public: - ModuleDumper(const ModuleRegistry& module_registry, const char* title) - : module_registry_(module_registry), title_(title) {} - void DumpState(std::string* output) const; + ModuleDumper(int fd, const ModuleRegistry& module_registry, const char* title) + : fd_(fd), module_registry_(module_registry), title_(title) {} + void DumpState(std::string* output, std::ostringstream& oss) const; private: + const int fd_{-1}; const ModuleRegistry& module_registry_; const std::string title_; }; diff --git a/system/gd/module_gdx_unittest.cc b/system/gd/module_gdx_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..b7d0b1380bad328cc9dc1cc57ea781d20a2c871e --- /dev/null +++ b/system/gd/module_gdx_unittest.cc @@ -0,0 +1,341 @@ +/* + * Copyright 2023 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 "module_gdx_unittest.h" + +#include +#include +#include +#include +#include + +#include + +#include "gtest/gtest.h" +#include "module.h" +#include "os/handler.h" + +using namespace bluetooth; + +namespace { +constexpr int sync_timeout_in_ms = 3000; + +std::promise gdx_external_function_promise; +std::promise private_impl_promise; +std::promise protected_method_promise; + +} // namespace + +// Global function with C linkage +void external_function_gdx(int /* a */, double /* b */, char /* c */) { + gdx_external_function_promise.set_value(base::PlatformThread::CurrentId()); +} + +// Module private implementation that is inaccessible externally +struct TestGdxModule::PrivateImpl : public ModuleMainloop, public ModuleJniloop { + const int kMaxTestGdxModuleRecurseDepth = 10; + + void privateCallableMethod(int /* a */, double /* b */, char /* c */) { + private_impl_promise.set_value(base::PlatformThread::CurrentId()); + } + + void repostMethodTest(int /* a */, double /* b */, char /* c */) { + private_impl_promise.set_value(base::PlatformThread::CurrentId()); + } + + void privateCallableRepostOnMainMethod( + std::shared_ptr ptr, int a, double b, char c) { + PostMethodOnMain(ptr, &PrivateImpl::repostMethodTest, a, b, c); + } + + void privateCallableRepostOnJniMethod( + std::shared_ptr ptr, int a, double b, char c) { + PostMethodOnJni(ptr, &PrivateImpl::repostMethodTest, a, b, c); + } + + void privateCallableRecursiveOnMainMethod( + std::shared_ptr ptr, int depth, double b, char c) { + if (depth > kMaxTestGdxModuleRecurseDepth) { + private_impl_promise.set_value(base::PlatformThread::CurrentId()); + return; + } + PostMethodOnMain(ptr, &PrivateImpl::privateCallableRecursiveOnMainMethod, ptr, depth + 1, b, c); + } + + void privateCallableRecursiveOnJniMethod( + std::shared_ptr ptr, int depth, double b, char c) { + if (depth > kMaxTestGdxModuleRecurseDepth) { + private_impl_promise.set_value(base::PlatformThread::CurrentId()); + return; + } + PostMethodOnJni(ptr, &PrivateImpl::privateCallableRecursiveOnJniMethod, ptr, depth + 1, b, c); + } +}; + +// Protected module method executed on handler +void TestGdxModule::call_on_handler_protected_method(int loop_tid, int a, int b, int c) { + protected_method_promise = std::promise(); + auto future = protected_method_promise.get_future(); + CallOn(this, &TestGdxModule::protected_method, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Global external function executed on main loop +void TestGdxModule::call_on_main_external_function(int loop_tid, int a, double b, char c) { + gdx_external_function_promise = std::promise(); + auto future = gdx_external_function_promise.get_future(); + PostFunctionOnMain(&external_function_gdx, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on main loop +void TestGdxModule::call_on_main(int loop_tid, int a, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnMain(pimpl_, &TestGdxModule::PrivateImpl::privateCallableMethod, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on main loop and reposted +void TestGdxModule::call_on_main_repost(int loop_tid, int a, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnMain( + pimpl_, &TestGdxModule::PrivateImpl::privateCallableRepostOnMainMethod, pimpl_, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on main loop recursively +void TestGdxModule::call_on_main_recurse(int loop_tid, int depth, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnMain( + pimpl_, + &TestGdxModule::PrivateImpl::privateCallableRecursiveOnMainMethod, + pimpl_, + depth, + b, + c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Global external function executed on main loop +void TestGdxModule::call_on_jni_external_function(int loop_tid, int a, double b, char c) { + gdx_external_function_promise = std::promise(); + auto future = gdx_external_function_promise.get_future(); + PostFunctionOnJni(&external_function_gdx, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on main loop +void TestGdxModule::call_on_jni(int loop_tid, int a, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnJni(pimpl_, &TestGdxModule::PrivateImpl::privateCallableMethod, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on main loop and reposted +void TestGdxModule::call_on_jni_repost(int loop_tid, int a, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnJni( + pimpl_, &TestGdxModule::PrivateImpl::privateCallableRepostOnJniMethod, pimpl_, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on main loop recursively +void TestGdxModule::call_on_jni_recurse(int loop_tid, int depth, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnJni( + pimpl_, + &TestGdxModule::PrivateImpl::privateCallableRecursiveOnJniMethod, + pimpl_, + depth, + b, + c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} +void TestGdxModule::protected_method(int /* a */, int /* b */, int /* c */) { + protected_method_promise.set_value(base::PlatformThread::CurrentId()); +} + +bool TestGdxModule::IsStarted() const { + return pimpl_ != nullptr; +} + +void TestGdxModule::Start() { + ASSERT_FALSE(IsStarted()); + pimpl_ = std::make_shared(); +} + +void TestGdxModule::Stop() { + ASSERT_TRUE(IsStarted()); + pimpl_.reset(); +} + +std::string TestGdxModule::ToString() const { + return std::string(__func__); +} + +const bluetooth::ModuleFactory TestGdxModule::Factory = + bluetooth::ModuleFactory([]() { return new TestGdxModule(); }); + +// +// Module GDx Testing Below +// +class ModuleGdxTest : public ::testing::Test { + protected: + void SetUp() override { + test_framework_tid_ = base::PlatformThread::CurrentId(); + module_ = new TestGdxModule(); + main_thread_start_up(); + mainloop_tid_ = get_mainloop_tid(); + jni_thread_startup(); + jniloop_tid_ = get_jniloop_tid(); + } + + void TearDown() override { + sync_main_handler(); + main_thread_shut_down(); + jni_thread_shutdown(); + delete module_; + } + + void sync_main_handler() { + std::promise promise = std::promise(); + std::future future = promise.get_future(); + post_on_bt_main([&promise]() { promise.set_value(); }); + future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms)); + }; + + void sync_jni_handler() { + std::promise promise = std::promise(); + std::future future = promise.get_future(); + post_on_bt_jni([&promise]() { promise.set_value(); }); + future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms)); + }; + + static pid_t get_mainloop_tid() { + std::promise pid_promise = std::promise(); + auto future = pid_promise.get_future(); + post_on_bt_main([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); }); + return future.get(); + } + + static pid_t get_jniloop_tid() { + std::promise pid_promise = std::promise(); + auto future = pid_promise.get_future(); + post_on_bt_jni([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); }); + return future.get(); + } + + pid_t test_framework_tid_{-1}; + pid_t mainloop_tid_{-1}; + pid_t jniloop_tid_{-1}; + TestModuleRegistry module_registry_; + TestGdxModule* module_; +}; + +class ModuleGdxWithStackTest : public ModuleGdxTest { + protected: + void SetUp() override { + ModuleGdxTest::SetUp(); + module_registry_.InjectTestModule(&TestGdxModule::Factory, module_ /* pass ownership */); + module_ = nullptr; // ownership is passed + handler_tid_ = get_handler_tid(module_registry_.GetTestModuleHandler(&TestGdxModule::Factory)); + } + + static pid_t get_handler_tid(os::Handler* handler) { + std::promise handler_tid_promise = std::promise(); + std::future future = handler_tid_promise.get_future(); + handler->Post(common::BindOnce( + [](std::promise promise) { promise.set_value(base::PlatformThread::CurrentId()); }, + std::move(handler_tid_promise))); + return future.get(); + } + + void TearDown() override { + module_registry_.StopAll(); + ModuleGdxTest::TearDown(); + } + + TestGdxModule* Mod() { + return module_registry_.GetModuleUnderTest(); + } + + pid_t handler_tid_{-1}; +}; + +TEST_F(ModuleGdxTest, nop) {} + +TEST_F(ModuleGdxTest, lifecycle) { + ::bluetooth::os::Thread* thread = + new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME); + ASSERT_FALSE(module_registry_.IsStarted()); + module_registry_.Start(thread); + ASSERT_TRUE(module_registry_.IsStarted()); + module_registry_.StopAll(); + ASSERT_FALSE(module_registry_.IsStarted()); + delete thread; +} + +// internal handler +TEST_F(ModuleGdxWithStackTest, call_on_handler_protected_method) { + Mod()->call_on_handler_protected_method(handler_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithStackTest, test_call_on_main) { + Mod()->call_on_main(mainloop_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithStackTest, test_call_gdx_external_function_on_main) { + Mod()->call_on_main_external_function(mainloop_tid_, 1, 2.3, 'c'); +} + +TEST_F(ModuleGdxWithStackTest, test_call_on_main_repost) { + Mod()->call_on_main_repost(mainloop_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithStackTest, test_call_on_main_recurse) { + Mod()->call_on_main_recurse(mainloop_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithStackTest, test_call_on_jni) { + Mod()->call_on_jni(jniloop_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithStackTest, test_call_gdx_external_function_on_jni) { + Mod()->call_on_jni_external_function(jniloop_tid_, 1, 2.3, 'c'); +} + +TEST_F(ModuleGdxWithStackTest, test_call_on_jni_repost) { + Mod()->call_on_jni_repost(jniloop_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithStackTest, test_call_on_jni_recurse) { + Mod()->call_on_jni_recurse(jniloop_tid_, 1, 2, 3); +} diff --git a/system/gd/module_gdx_unittest.h b/system/gd/module_gdx_unittest.h new file mode 100644 index 0000000000000000000000000000000000000000..f3636442db6e0fb643e44daf44e0cabdf4c62c84 --- /dev/null +++ b/system/gd/module_gdx_unittest.h @@ -0,0 +1,64 @@ +/* + * Copyright 2023 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 +#include +#include + +#include + +#include "module.h" +#include "module_jniloop.h" +#include "module_mainloop.h" + +using namespace bluetooth; + +void external_function(int /* a */, double /* b */, char /* c */); + +class TestGdxModule : public Module, public ModuleMainloop, public ModuleJniloop { + public: + void call_on_handler_protected_method(pid_t tid, int a, int b, int c); + void call_on_main_external_function(pid_t tid, int a, double b, char c); + void call_on_main(pid_t tid, int a, int b, int c); + void call_on_main_repost(pid_t tid, int a, int b, int c); + void call_on_main_recurse(pid_t tid, int a, int b, int c); + + void call_on_jni_external_function(pid_t tid, int a, double b, char c); + void call_on_jni(pid_t tid, int a, int b, int c); + void call_on_jni_repost(pid_t tid, int a, int b, int c); + void call_on_jni_recurse(pid_t tid, int a, int b, int c); + + static const bluetooth::ModuleFactory Factory; + + protected: + void protected_method(int a, int b, int c); + void call_on_main_internal(int a, int b, int c); + void call_on_jni_internal(int a, int b, int c); + bool IsStarted() const; + + void ListDependencies(bluetooth::ModuleList* /* list */) const override {} + void Start() override; + void Stop() override; + std::string ToString() const override; + + private: + struct PrivateImpl; + std::shared_ptr pimpl_; + + bool started_ = false; + + friend bluetooth::ModuleRegistry; +}; diff --git a/system/gd/module_jniloop.h b/system/gd/module_jniloop.h new file mode 100644 index 0000000000000000000000000000000000000000..04105d37ebfd64dbcbbd74b956a666ce0bee74d8 --- /dev/null +++ b/system/gd/module_jniloop.h @@ -0,0 +1,58 @@ +/* + * Copyright 2023 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 +#include +#include + +#include "btif/include/btif_jni_task.h" + +namespace bluetooth { + +class ModuleJniloop { + protected: + ModuleJniloop() noexcept = default; + virtual ~ModuleJniloop() = default; + ModuleJniloop(const ModuleJniloop& mod) = delete; + + // Threadsafe post onto jni loop a function with copyable arguments + template + void PostFunctionOnJni(Functor&& functor, Args&&... args) const { + do_in_jni_thread( + FROM_HERE, base::BindOnce(std::forward(functor), std::forward(args)...)); + } + + // Threadsafe post onto jni loop a method and context with copyable arguments + template + void PostMethodOnJni(std::shared_ptr ref, Functor&& functor, Args... args) const { + do_in_jni_thread( + FROM_HERE, + base::BindOnce( + [](std::weak_ptr ref, Functor&& functor, Args&&... args) { + if (std::shared_ptr spt = ref.lock()) { + base::BindOnce(std::forward(functor), spt, std::forward(args)...) + .Run(); + } + }, + std::weak_ptr(ref), + std::forward(functor), + std::forward(args)...)); + } +}; + +} // namespace bluetooth diff --git a/system/gd/module_jniloop_unittest.cc b/system/gd/module_jniloop_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..5884210465127e145b819dfbe175bdc1a7a58c02 --- /dev/null +++ b/system/gd/module_jniloop_unittest.cc @@ -0,0 +1,247 @@ +/* + * Copyright 2023 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 "module_jniloop_unittest.h" + +#include +#include +#include +#include +#include + +#include + +#include "btif/include/btif_jni_task.h" +#include "gtest/gtest.h" +#include "module.h" +#include "os/handler.h" +#include "os/thread.h" + +using namespace bluetooth; + +namespace { +constexpr int sync_timeout_in_ms = 3000; + +std::promise external_function_promise; +std::promise private_impl_promise; +std::promise protected_method_promise; + +} // namespace + +// Global function with C linkage +void external_function_jni(int /* a */, double /* b */, char /* c */) { + external_function_promise.set_value(base::PlatformThread::CurrentId()); +} + +// Module private implementation that is inaccessible externally +struct TestJniModule::PrivateImpl : public ModuleJniloop { + const int kMaxTestModuleRecurseDepth = 10; + + void privateCallableMethod(int /* a */, double /* b */, char /* c */) { + private_impl_promise.set_value(base::PlatformThread::CurrentId()); + } + + void repostMethodTest(int /* a */, double /* b */, char /* c */) { + private_impl_promise.set_value(base::PlatformThread::CurrentId()); + } + + void privateCallableRepostMethod( + std::shared_ptr ptr, int a, double b, char c) { + PostMethodOnJni(ptr, &PrivateImpl::repostMethodTest, a, b, c); + } + + void privateCallableRecursiveMethod( + std::shared_ptr ptr, int depth, double b, char c) { + if (depth > kMaxTestModuleRecurseDepth) { + private_impl_promise.set_value(base::PlatformThread::CurrentId()); + return; + } + PostMethodOnJni(ptr, &PrivateImpl::privateCallableRecursiveMethod, ptr, depth + 1, b, c); + } +}; + +// Protected module method executed on handler +void TestJniModule::call_on_handler_protected_method(int loop_tid, int a, int b, int c) { + protected_method_promise = std::promise(); + auto future = protected_method_promise.get_future(); + CallOn(this, &TestJniModule::protected_method, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Global external function executed on jni loop +void TestJniModule::call_on_jni_external_function(int loop_tid, int a, double b, char c) { + external_function_promise = std::promise(); + auto future = external_function_promise.get_future(); + PostFunctionOnJni(&external_function_jni, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on main loop +void TestJniModule::call_on_jni(int loop_tid, int a, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnJni(pimpl_, &TestJniModule::PrivateImpl::privateCallableMethod, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on jni loop and reposted +void TestJniModule::call_on_jni_repost(int loop_tid, int a, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnJni( + pimpl_, &TestJniModule::PrivateImpl::privateCallableRepostMethod, pimpl_, a, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +// Private implementation method executed on jni loop recursively +void TestJniModule::call_on_jni_recurse(int loop_tid, int depth, int b, int c) { + private_impl_promise = std::promise(); + auto future = private_impl_promise.get_future(); + PostMethodOnJni( + pimpl_, &TestJniModule::PrivateImpl::privateCallableRecursiveMethod, pimpl_, depth, b, c); + ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); + ASSERT_EQ(future.get(), loop_tid); +} + +void TestJniModule::protected_method(int /* a */, int /* b */, int /* c */) { + protected_method_promise.set_value(base::PlatformThread::CurrentId()); +} + +bool TestJniModule::IsStarted() const { + return pimpl_ != nullptr; +} + +void TestJniModule::Start() { + ASSERT_FALSE(IsStarted()); + pimpl_ = std::make_shared(); +} + +void TestJniModule::Stop() { + ASSERT_TRUE(IsStarted()); + pimpl_.reset(); +} + +std::string TestJniModule::ToString() const { + return std::string(__func__); +} + +const bluetooth::ModuleFactory TestJniModule::Factory = + bluetooth::ModuleFactory([]() { return new TestJniModule(); }); + +// +// Module GDx Testing Below +// +class ModuleGdxJniTest : public ::testing::Test { + protected: + void SetUp() override { + test_framework_tid_ = base::PlatformThread::CurrentId(); + module_ = new TestJniModule(); + jni_thread_startup(); + jniloop_tid_ = get_jniloop_tid(); + } + + void TearDown() override { + sync_jni_handler(); + jni_thread_shutdown(); + delete module_; + } + + void sync_jni_handler() { + std::promise promise = std::promise(); + std::future future = promise.get_future(); + post_on_bt_jni([&promise]() { promise.set_value(); }); + future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms)); + }; + + static pid_t get_jniloop_tid() { + std::promise pid_promise = std::promise(); + auto future = pid_promise.get_future(); + post_on_bt_jni([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); }); + return future.get(); + } + + pid_t test_framework_tid_{-1}; + pid_t jniloop_tid_{-1}; + TestModuleRegistry module_registry_; + TestJniModule* module_; +}; + +class ModuleGdxWithJniStackTest : public ModuleGdxJniTest { + protected: + void SetUp() override { + ModuleGdxJniTest::SetUp(); + module_registry_.InjectTestModule(&TestJniModule::Factory, module_ /* pass ownership */); + module_ = nullptr; // ownership is passed + handler_tid_ = get_handler_tid(module_registry_.GetTestModuleHandler(&TestJniModule::Factory)); + } + + static pid_t get_handler_tid(os::Handler* handler) { + std::promise handler_tid_promise = std::promise(); + std::future future = handler_tid_promise.get_future(); + handler->Post(common::BindOnce( + [](std::promise promise) { promise.set_value(base::PlatformThread::CurrentId()); }, + std::move(handler_tid_promise))); + return future.get(); + } + + void TearDown() override { + module_registry_.StopAll(); + ModuleGdxJniTest::TearDown(); + } + + TestJniModule* Mod() { + return module_registry_.GetModuleUnderTest(); + } + + pid_t handler_tid_{-1}; +}; + +TEST_F(ModuleGdxJniTest, nop) {} + +TEST_F(ModuleGdxJniTest, lifecycle) { + ::bluetooth::os::Thread* thread = + new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME); + ASSERT_FALSE(module_registry_.IsStarted()); + module_registry_.Start(thread); + ASSERT_TRUE(module_registry_.IsStarted()); + module_registry_.StopAll(); + ASSERT_FALSE(module_registry_.IsStarted()); + delete thread; +} + +TEST_F(ModuleGdxWithJniStackTest, call_on_handler_protected_method) { + Mod()->call_on_handler_protected_method(handler_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithJniStackTest, test_call_on_jni) { + Mod()->call_on_jni(jniloop_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithJniStackTest, test_call_external_function) { + Mod()->call_on_jni_external_function(jniloop_tid_, 1, 2.3, 'c'); +} + +TEST_F(ModuleGdxWithJniStackTest, test_call_on_jni_repost) { + Mod()->call_on_jni_repost(jniloop_tid_, 1, 2, 3); +} + +TEST_F(ModuleGdxWithJniStackTest, test_call_on_jni_recurse) { + Mod()->call_on_jni_recurse(jniloop_tid_, 1, 2, 3); +} diff --git a/system/gd/module_jniloop_unittest.h b/system/gd/module_jniloop_unittest.h new file mode 100644 index 0000000000000000000000000000000000000000..52a4c28e7e485e5474d01a9c9a19e043e11ffa47 --- /dev/null +++ b/system/gd/module_jniloop_unittest.h @@ -0,0 +1,57 @@ +/* + * Copyright 2023 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 +#include +#include + +#include + +#include "module.h" +#include "module_jniloop.h" + +using namespace bluetooth; + +void external_function(int /* a */, double /* b */, char /* c */); + +class TestJniModule : public Module, public ModuleJniloop { + public: + void call_on_handler_protected_method(pid_t tid, int a, int b, int c); + void call_on_jni_external_function(pid_t tid, int a, double b, char c); + void call_on_jni(pid_t tid, int a, int b, int c); + void call_on_jni_repost(pid_t tid, int a, int b, int c); + void call_on_jni_recurse(pid_t tid, int a, int b, int c); + + static const bluetooth::ModuleFactory Factory; + + protected: + void protected_method(int a, int b, int c); + void call_on_jni_internal(int a, int b, int c); + bool IsStarted() const; + + void ListDependencies(bluetooth::ModuleList* /* list */) const override {} + void Start() override; + void Stop() override; + std::string ToString() const override; + + private: + struct PrivateImpl; + std::shared_ptr pimpl_; + + bool started_ = false; + + friend bluetooth::ModuleRegistry; +}; diff --git a/system/gd/module_mainloop.h b/system/gd/module_mainloop.h index 0f1b46085db3d351206caef6df1fd35c04809806..41ba42f8683166ddb43f3f8c26c612c447d29aa0 100644 --- a/system/gd/module_mainloop.h +++ b/system/gd/module_mainloop.h @@ -25,12 +25,11 @@ namespace bluetooth { class ModuleMainloop { - public: + protected: ModuleMainloop() noexcept = default; virtual ~ModuleMainloop() = default; ModuleMainloop(const ModuleMainloop& mod) = delete; - protected: // Threadsafe post onto mainloop a function with copyable arguments template void PostFunctionOnMain(Functor&& functor, Args&&... args) const { @@ -38,7 +37,7 @@ class ModuleMainloop { FROM_HERE, base::BindOnce(std::forward(functor), std::forward(args)...)); } - // Threadsafe post onto mainloop a method and contex with copyable arguments + // Threadsafe post onto mainloop a method and context with copyable arguments template void PostMethodOnMain(std::shared_ptr ref, Functor&& functor, Args... args) const { do_in_main_thread( diff --git a/system/gd/module_mainloop_unittest.cc b/system/gd/module_mainloop_unittest.cc index b01a50e0c1d0405c2d706df482e79d73b7df554a..e59b6623d46aaf868897ce14877807f3896d11c1 100644 --- a/system/gd/module_mainloop_unittest.cc +++ b/system/gd/module_mainloop_unittest.cc @@ -27,7 +27,6 @@ #include "gtest/gtest.h" #include "module.h" #include "os/handler.h" -#include "os/log.h" #include "os/thread.h" #include "stack/include/main_thread.h" @@ -43,7 +42,7 @@ std::promise protected_method_promise; } // namespace // Global function with C linkage -void external_function(int /* a */, double /* b */, char /* c */) { +void external_function_main(int /* a */, double /* b */, char /* c */) { external_function_promise.set_value(base::PlatformThread::CurrentId()); } @@ -75,49 +74,49 @@ struct TestModule::PrivateImpl : public ModuleMainloop { }; // Protected module method executed on handler -void TestModule::call_on_handler_protected_method(int handler_tid, int a, int b, int c) { +void TestModule::call_on_handler_protected_method(int loop_tid, int a, int b, int c) { protected_method_promise = std::promise(); auto future = protected_method_promise.get_future(); CallOn(this, &TestModule::protected_method, a, b, c); ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); - ASSERT_EQ(future.get(), handler_tid); + ASSERT_EQ(future.get(), loop_tid); } // Global external function executed on main loop -void TestModule::call_on_main_external_function(int mainloop_tid, int a, double b, char c) { +void TestModule::call_on_main_external_function(int loop_tid, int a, double b, char c) { external_function_promise = std::promise(); auto future = external_function_promise.get_future(); - PostFunctionOnMain(&external_function, a, b, c); + PostFunctionOnMain(&external_function_main, a, b, c); ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); - ASSERT_EQ(future.get(), mainloop_tid); + ASSERT_EQ(future.get(), loop_tid); } // Private implementation method executed on main loop -void TestModule::call_on_main(int mainloop_tid, int a, int b, int c) { +void TestModule::call_on_main(int loop_tid, int a, int b, int c) { private_impl_promise = std::promise(); auto future = private_impl_promise.get_future(); PostMethodOnMain(pimpl_, &TestModule::PrivateImpl::privateCallableMethod, a, b, c); ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); - ASSERT_EQ(future.get(), mainloop_tid); + ASSERT_EQ(future.get(), loop_tid); } // Private implementation method executed on main loop and reposted -void TestModule::call_on_main_repost(int mainloop_tid, int a, int b, int c) { +void TestModule::call_on_main_repost(int loop_tid, int a, int b, int c) { private_impl_promise = std::promise(); auto future = private_impl_promise.get_future(); PostMethodOnMain(pimpl_, &TestModule::PrivateImpl::privateCallableRepostMethod, pimpl_, a, b, c); ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); - ASSERT_EQ(future.get(), mainloop_tid); + ASSERT_EQ(future.get(), loop_tid); } // Private implementation method executed on main loop recursively -void TestModule::call_on_main_recurse(int mainloop_tid, int depth, int b, int c) { +void TestModule::call_on_main_recurse(int loop_tid, int depth, int b, int c) { private_impl_promise = std::promise(); auto future = private_impl_promise.get_future(); PostMethodOnMain( pimpl_, &TestModule::PrivateImpl::privateCallableRecursiveMethod, pimpl_, depth, b, c); ASSERT_EQ(future.wait_for(std::chrono::seconds(3)), std::future_status::ready); - ASSERT_EQ(future.get(), mainloop_tid); + ASSERT_EQ(future.get(), loop_tid); } void TestModule::protected_method(int /* a */, int /* b */, int /* c */) { @@ -148,7 +147,7 @@ const bluetooth::ModuleFactory TestModule::Factory = // // Module GDx Testing Below // -class ModuleGdxTest : public ::testing::Test { +class ModuleMainGdxTest : public ::testing::Test { protected: void SetUp() override { test_framework_tid_ = base::PlatformThread::CurrentId(); @@ -183,10 +182,10 @@ class ModuleGdxTest : public ::testing::Test { TestModule* module_; }; -class ModuleGdxWithStackTest : public ModuleGdxTest { +class ModuleMainGdxWithStackTest : public ModuleMainGdxTest { protected: void SetUp() override { - ModuleGdxTest::SetUp(); + ModuleMainGdxTest::SetUp(); module_registry_.InjectTestModule(&TestModule::Factory, module_ /* pass ownership */); module_ = nullptr; // ownership is passed handler_tid_ = get_handler_tid(module_registry_.GetTestModuleHandler(&TestModule::Factory)); @@ -203,7 +202,7 @@ class ModuleGdxWithStackTest : public ModuleGdxTest { void TearDown() override { module_registry_.StopAll(); - ModuleGdxTest::TearDown(); + ModuleMainGdxTest::TearDown(); } TestModule* Mod() { @@ -213,9 +212,9 @@ class ModuleGdxWithStackTest : public ModuleGdxTest { pid_t handler_tid_{-1}; }; -TEST_F(ModuleGdxTest, nop) {} +TEST_F(ModuleMainGdxTest, nop) {} -TEST_F(ModuleGdxTest, lifecycle) { +TEST_F(ModuleMainGdxTest, lifecycle) { ::bluetooth::os::Thread* thread = new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME); ASSERT_FALSE(module_registry_.IsStarted()); @@ -226,22 +225,22 @@ TEST_F(ModuleGdxTest, lifecycle) { delete thread; } -TEST_F(ModuleGdxWithStackTest, call_on_handler_protected_method) { +TEST_F(ModuleMainGdxWithStackTest, call_on_handler_protected_method) { Mod()->call_on_handler_protected_method(handler_tid_, 1, 2, 3); } -TEST_F(ModuleGdxWithStackTest, test_call_on_main) { +TEST_F(ModuleMainGdxWithStackTest, test_call_on_main) { Mod()->call_on_main(mainloop_tid_, 1, 2, 3); } -TEST_F(ModuleGdxWithStackTest, test_call_external_function) { +TEST_F(ModuleMainGdxWithStackTest, test_call_external_function) { Mod()->call_on_main_external_function(mainloop_tid_, 1, 2.3, 'c'); } -TEST_F(ModuleGdxWithStackTest, test_call_on_main_repost) { +TEST_F(ModuleMainGdxWithStackTest, test_call_on_main_repost) { Mod()->call_on_main_repost(mainloop_tid_, 1, 2, 3); } -TEST_F(ModuleGdxWithStackTest, test_call_on_main_recurse) { +TEST_F(ModuleMainGdxWithStackTest, test_call_on_main_recurse) { Mod()->call_on_main_recurse(mainloop_tid_, 1, 2, 3); } diff --git a/system/gd/module_state_dumper.cc b/system/gd/module_state_dumper.cc new file mode 100644 index 0000000000000000000000000000000000000000..eeb951bdd23610a3d61d94be403d0848dd2ad5f6 --- /dev/null +++ b/system/gd/module_state_dumper.cc @@ -0,0 +1,34 @@ +/* + * Copyright 2023 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 "module_state_dumper.h" + +namespace bluetooth { + +bluetooth::DumpsysDataFinisher EmptyDumpsysDataFinisher = + [](bluetooth::DumpsysDataBuilder* /* dumpsys_data_builder */) {}; + +DumpsysDataFinisher ModuleStateDumper::GetDumpsysData( + flatbuffers::FlatBufferBuilder* /* builder */) const { + return EmptyDumpsysDataFinisher; +} +void ModuleStateDumper::GetDumpsysData(int /* fd */) const {} + +void ModuleStateDumper::GetDumpsysData() const {} + +void ModuleStateDumper::GetDumpsysData(std::ostringstream& /* oss */) const {} + +} // namespace bluetooth diff --git a/system/gd/module_state_dumper.h b/system/gd/module_state_dumper.h new file mode 100644 index 0000000000000000000000000000000000000000..68c0c89f0aac64ae1e36af9a2b3a0a2570a0291f --- /dev/null +++ b/system/gd/module_state_dumper.h @@ -0,0 +1,43 @@ +/* + * Copyright 2023 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 + +#include +#include + +namespace bluetooth { + +// flatbuffers uses structs over class definition +struct DumpsysDataBuilder; +using DumpsysDataFinisher = std::function; + +extern bluetooth::DumpsysDataFinisher EmptyDumpsysDataFinisher; + +class ModuleStateDumper { + public: + virtual ~ModuleStateDumper() = default; + + // Get relevant state data from the module + virtual DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const; + virtual void GetDumpsysData() const; + virtual void GetDumpsysData(int fd) const; + virtual void GetDumpsysData(std::ostringstream& oss) const; +}; + +} // namespace bluetooth diff --git a/system/gd/module_state_dumper_unittest.cc b/system/gd/module_state_dumper_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..b5c020d6fbbfd5b896ca5ffe4637f66b6a2dcc46 --- /dev/null +++ b/system/gd/module_state_dumper_unittest.cc @@ -0,0 +1,177 @@ +/* + * Copyright 2023 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 "module_state_dumper_unittest.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include "gtest/gtest.h" +#include "module_dumper.h" +#include "module_state_dumper.h" +#include "os/handler.h" +#include "os/thread.h" +#include "stack/include/main_thread.h" + +using namespace bluetooth; + +namespace { + +constexpr int sync_timeout_in_ms = 3000; +constexpr char title[] = "module_state_dumper_test"; + +} // namespace + +// Module private implementation that is inaccessible externally +struct StateDumperTestModule::PrivateImpl : public ModuleMainloop {}; + +bool StateDumperTestModule::IsStarted() const { + return pimpl_ != nullptr; +} + +void StateDumperTestModule::Start() { + ASSERT_FALSE(IsStarted()); + pimpl_ = std::make_shared(); +} + +void StateDumperTestModule::Stop() { + ASSERT_TRUE(IsStarted()); + pimpl_.reset(); +} + +std::string StateDumperTestModule::ToString() const { + return std::string(__func__); +} + +const bluetooth::ModuleFactory StateDumperTestModule::Factory = + bluetooth::ModuleFactory([]() { return new StateDumperTestModule(); }); + +DumpsysDataFinisher StateDumperTestModule::GetDumpsysData( + flatbuffers::FlatBufferBuilder* /* builder */) const { + LOG_INFO("flatbuffers"); + return EmptyDumpsysDataFinisher; +} + +void StateDumperTestModule::GetDumpsysData() const { + LOG_INFO("void"); +} + +void StateDumperTestModule::GetDumpsysData(int fd) const { + LOG_INFO("fd"); + dprintf(fd, "GetDumpsysData(int fd)"); +} + +void StateDumperTestModule::GetDumpsysData(std::ostringstream& oss) const { + LOG_INFO("oss"); + oss << "GetDumpsysData(std::ostringstream& oss)"; +} + +// +// Module GDx Testing Below +// +class ModuleStateDumperTest : public ::testing::Test { + protected: + void SetUp() override { + test_framework_tid_ = base::PlatformThread::CurrentId(); + module_ = new StateDumperTestModule(); + main_thread_start_up(); + mainloop_tid_ = get_mainloop_tid(); + } + + void TearDown() override { + sync_main_handler(); + main_thread_shut_down(); + delete module_; + } + + void sync_main_handler() { + std::promise promise = std::promise(); + std::future future = promise.get_future(); + post_on_bt_main([&promise]() { promise.set_value(); }); + future.wait_for(std::chrono::milliseconds(sync_timeout_in_ms)); + }; + + static pid_t get_mainloop_tid() { + std::promise pid_promise = std::promise(); + auto future = pid_promise.get_future(); + post_on_bt_main([&pid_promise]() { pid_promise.set_value(base::PlatformThread::CurrentId()); }); + return future.get(); + } + + pid_t test_framework_tid_{-1}; + pid_t mainloop_tid_{-1}; + TestModuleRegistry module_registry_; + StateDumperTestModule* module_; +}; + +class ModuleStateDumperWithStackTest : public ModuleStateDumperTest { + protected: + void SetUp() override { + ModuleStateDumperTest::SetUp(); + module_registry_.InjectTestModule( + &StateDumperTestModule::Factory, module_ /* pass ownership */); + module_ = nullptr; // ownership is passed + } + + static pid_t get_handler_tid(os::Handler* handler) { + std::promise handler_tid_promise = std::promise(); + std::future future = handler_tid_promise.get_future(); + handler->Post(common::BindOnce( + [](std::promise promise) { promise.set_value(base::PlatformThread::CurrentId()); }, + std::move(handler_tid_promise))); + return future.get(); + } + + void TearDown() override { + module_registry_.StopAll(); + ModuleStateDumperTest::TearDown(); + } + + StateDumperTestModule* Mod() { + return module_registry_.GetModuleUnderTest(); + } + + pid_t handler_tid_{-1}; +}; + +TEST_F(ModuleStateDumperTest, lifecycle) { + ::bluetooth::os::Thread* thread = + new bluetooth::os::Thread("Name", bluetooth::os::Thread::Priority::REAL_TIME); + ASSERT_FALSE(module_registry_.IsStarted()); + module_registry_.Start(thread); + ASSERT_TRUE(module_registry_.IsStarted()); + module_registry_.StopAll(); + ASSERT_FALSE(module_registry_.IsStarted()); + delete thread; +} + +TEST_F(ModuleStateDumperWithStackTest, dump_state) { + ModuleDumper dumper(STDOUT_FILENO, module_registry_, title); + + std::string output; + std::ostringstream oss; + dumper.DumpState(&output, oss); + + LOG_INFO("DUMP STATE"); + LOG_INFO("%s", oss.str().c_str()); + LOG_INFO("%s", output.c_str()); +} diff --git a/system/gd/module_state_dumper_unittest.h b/system/gd/module_state_dumper_unittest.h new file mode 100644 index 0000000000000000000000000000000000000000..4600c9398d9593875373e3df15f971ed19e64760 --- /dev/null +++ b/system/gd/module_state_dumper_unittest.h @@ -0,0 +1,49 @@ +/* + * Copyright 2023 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 +#include + +#include "module.h" +#include "module_mainloop.h" + +using namespace bluetooth; + +class StateDumperTestModule : public Module, public ModuleMainloop { + public: + static const bluetooth::ModuleFactory Factory; + + protected: + bool IsStarted() const; + + void ListDependencies(bluetooth::ModuleList* /* list */) const override {} + void Start() override; + void Stop() override; + std::string ToString() const override; + + DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override; + void GetDumpsysData() const override; + void GetDumpsysData(int fd) const override; + void GetDumpsysData(std::ostringstream& oss) const override; + + private: + struct PrivateImpl; + std::shared_ptr pimpl_; + + bool started_ = false; + + friend bluetooth::ModuleRegistry; +}; diff --git a/system/gd/module_unittest.cc b/system/gd/module_unittest.cc index ab5d52d0f7a563398679dd12f95e30aa04daa90c..f8cdd30b6fc44b8d03219ad42647e4e84bb6e0a4 100644 --- a/system/gd/module_unittest.cc +++ b/system/gd/module_unittest.cc @@ -16,7 +16,10 @@ #include "module.h" +#include + #include +#include #include #include "dumpsys_data_generated.h" @@ -291,10 +294,11 @@ TEST_F(ModuleTest, dump_state) { list.add(); registry_->Start(&list, thread_); - ModuleDumper dumper(*registry_, title); + ModuleDumper dumper(STDOUT_FILENO, *registry_, title); std::string output; - dumper.DumpState(&output); + std::ostringstream oss; + dumper.DumpState(&output, oss); auto data = flatbuffers::GetRoot(output.data()); EXPECT_STREQ(title, data->title()->c_str()); @@ -306,7 +310,9 @@ TEST_F(ModuleTest, dump_state) { static_cast(registry_->Start(&TestModuleDumpState::Factory, nullptr)); test_module->test_string_ = "A Second Test String"; - dumper.DumpState(&output); + oss.clear(); + output.clear(); + dumper.DumpState(&output, oss); data = flatbuffers::GetRoot(output.data()); test_data = data->module_unittest_data(); diff --git a/system/gd/neighbor/Android.bp b/system/gd/neighbor/Android.bp index 267a3f3a02d1af8782d6818ac722b18dcc6bc0fe..7a94145aa6f734ea062ef102fbcd7b38f4a330cc 100644 --- a/system/gd/neighbor/Android.bp +++ b/system/gd/neighbor/Android.bp @@ -19,13 +19,6 @@ filegroup { ], } -filegroup { - name: "BluetoothNeighborTestSources", - srcs: [ - "inquiry_test.cc", - ], -} - filegroup { name: "BluetoothFacade_neighbor", srcs: [ diff --git a/system/gd/neighbor/BUILD.gn b/system/gd/neighbor/BUILD.gn index 21571263b7b9a2af36871e227a9e18d6d7308e7d..d3ec55d490afae0ab0b6b05ba8ca9c7d521edc73 100644 --- a/system/gd/neighbor/BUILD.gn +++ b/system/gd/neighbor/BUILD.gn @@ -25,5 +25,8 @@ source_set("BluetoothNeighborSources") { deps = [ "//bt/system/gd:gd_default_deps" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } diff --git a/system/gd/neighbor/inquiry_test.cc b/system/gd/neighbor/inquiry_test.cc deleted file mode 100644 index b072c66ef488e51a570a66e888504e57a8111bf1..0000000000000000000000000000000000000000 --- a/system/gd/neighbor/inquiry_test.cc +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "neighbor/inquiry.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "common/bind.h" -#include "common/callback.h" -#include "hci/address.h" -#include "hci/class_of_device.h" -#include "hci/hci_layer.h" -#include "hci/hci_packets.h" -#include "os/thread.h" -#include "packet/raw_builder.h" - -namespace bluetooth { -namespace neighbor { -namespace { - -static const uint8_t kNumberPacketsReadyToReceive = 1; - -/** - * This structure reflects the current state of the bluetooth chip - * at any given time. - */ -static const int8_t kInitialInquiryResponseTransmitPowerLevel = 123; -static const uint16_t kInitialInquiryScanInterval = 1111; -static const uint16_t kInitialInquiryScanWindow = 2222; - -struct HciRegister { - bool one_shot_inquiry_active; - bool periodic_inquiry_active; - int8_t inquiry_response_transmit_power_level; - uint16_t inquiry_scan_interval; - uint16_t inquiry_scan_window; - hci::InquiryScanType inquiry_scan_type; - hci::InquiryMode inquiry_mode; - uint8_t inquiry_length; - uint8_t num_responses; - uint16_t min_period_length; - uint16_t max_period_length; -} hci_register_{ - .one_shot_inquiry_active = false, - .periodic_inquiry_active = false, - .inquiry_response_transmit_power_level = kInitialInquiryResponseTransmitPowerLevel, - .inquiry_scan_interval = kInitialInquiryScanInterval, - .inquiry_scan_window = kInitialInquiryScanWindow, - .inquiry_scan_type = hci::InquiryScanType::STANDARD, - .inquiry_mode = hci::InquiryMode::STANDARD, - .inquiry_length = 0, - .num_responses = 0, - .min_period_length = 0, - .max_period_length = 0, -}; - -hci::PacketView GetPacketView(std::unique_ptr packet) { - auto bytes = std::make_shared>(); - hci::BitInserter i(*bytes); - bytes->reserve(packet->size()); - packet->Serialize(i); - return packet::PacketView(bytes); -} - -class TestHciLayer : public hci::HciLayer { - public: - void EnqueueCommand( - std::unique_ptr command, - common::ContextualOnceCallback on_complete) override { - GetHandler()->Post(common::BindOnce( - &TestHciLayer::HandleCommand, common::Unretained(this), std::move(command), std::move(on_complete))); - } - - void EnqueueCommand( - std::unique_ptr command, - common::ContextualOnceCallback on_status) override { - GetHandler()->Post(common::BindOnce( - &TestHciLayer::HandleStatus, common::Unretained(this), std::move(command), std::move(on_status))); - } - - void HandleCommand( - std::unique_ptr command_builder, - common::ContextualOnceCallback on_complete) { - hci::CommandView command = hci::CommandView::Create(GetPacketView(std::move(command_builder))); - ASSERT_TRUE(command.IsValid()); - - std::unique_ptr event_builder; - switch (command.GetOpCode()) { - case hci::OpCode::INQUIRY_CANCEL: - event_builder = - hci::InquiryCancelCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS); - hci_register_.one_shot_inquiry_active = false; - break; - - case hci::OpCode::PERIODIC_INQUIRY_MODE: { - auto inquiry = hci::PeriodicInquiryModeView::Create(hci::DiscoveryCommandView::Create(command)); - ASSERT_TRUE(inquiry.IsValid()); - event_builder = - hci::PeriodicInquiryModeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS); - hci_register_.periodic_inquiry_active = true; - hci_register_.inquiry_length = inquiry.GetInquiryLength(); - hci_register_.num_responses = inquiry.GetNumResponses(); - hci_register_.max_period_length = inquiry.GetMaxPeriodLength(); - hci_register_.min_period_length = inquiry.GetMinPeriodLength(); - } break; - - case hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE: - event_builder = - hci::ExitPeriodicInquiryModeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS); - hci_register_.periodic_inquiry_active = false; - break; - - case hci::OpCode::WRITE_INQUIRY_MODE: - event_builder = - hci::WriteInquiryModeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS); - { - auto view = hci::WriteInquiryModeView::Create(hci::DiscoveryCommandView::Create(command)); - ASSERT_TRUE(view.IsValid()); - hci_register_.inquiry_mode = view.GetInquiryMode(); - } - break; - - case hci::OpCode::READ_INQUIRY_MODE: - event_builder = hci::ReadInquiryModeCompleteBuilder::Create( - kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS, hci_register_.inquiry_mode); - break; - - case hci::OpCode::WRITE_INQUIRY_SCAN_ACTIVITY: - event_builder = - hci::WriteInquiryScanActivityCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS); - { - auto view = hci::WriteInquiryScanActivityView::Create(hci::DiscoveryCommandView::Create(command)); - ASSERT_TRUE(view.IsValid()); - hci_register_.inquiry_scan_interval = view.GetInquiryScanInterval(); - hci_register_.inquiry_scan_window = view.GetInquiryScanWindow(); - } - break; - - case hci::OpCode::READ_INQUIRY_SCAN_ACTIVITY: - event_builder = hci::ReadInquiryScanActivityCompleteBuilder::Create( - kNumberPacketsReadyToReceive, - hci::ErrorCode::SUCCESS, - hci_register_.inquiry_scan_interval, - hci_register_.inquiry_scan_window); - break; - - case hci::OpCode::WRITE_INQUIRY_SCAN_TYPE: - event_builder = - hci::WriteInquiryScanTypeCompleteBuilder::Create(kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS); - { - auto view = hci::WriteInquiryScanTypeView::Create(hci::DiscoveryCommandView::Create(command)); - ASSERT_TRUE(view.IsValid()); - hci_register_.inquiry_scan_type = view.GetInquiryScanType(); - } - break; - - case hci::OpCode::READ_INQUIRY_SCAN_TYPE: - event_builder = hci::ReadInquiryScanTypeCompleteBuilder::Create( - kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS, hci_register_.inquiry_scan_type); - break; - - case hci::OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL: - event_builder = hci::ReadInquiryResponseTransmitPowerLevelCompleteBuilder::Create( - kNumberPacketsReadyToReceive, hci::ErrorCode::SUCCESS, hci_register_.inquiry_response_transmit_power_level); - break; - - default: - LOG_INFO("Dropping unhandled command:%s", hci::OpCodeText(command.GetOpCode()).c_str()); - return; - } - hci::EventView event = hci::EventView::Create(GetPacketView(std::move(event_builder))); - ASSERT_TRUE(event.IsValid()); - hci::CommandCompleteView command_complete = hci::CommandCompleteView::Create(event); - ASSERT_TRUE(command_complete.IsValid()); - on_complete.Invoke(std::move(command_complete)); - - if (promise_sync_complete_ != nullptr) { - promise_sync_complete_->set_value(command.GetOpCode()); - } - } - - void HandleStatus( - std::unique_ptr command_builder, - common::ContextualOnceCallback on_status) { - hci::CommandView command = hci::CommandView::Create(GetPacketView(std::move(command_builder))); - ASSERT_TRUE(command.IsValid()); - - std::unique_ptr event_builder; - switch (command.GetOpCode()) { - case hci::OpCode::INQUIRY: { - auto inquiry = hci::InquiryView::Create(hci::DiscoveryCommandView::Create(command)); - ASSERT_TRUE(inquiry.IsValid()); - event_builder = hci::InquiryStatusBuilder::Create(hci::ErrorCode::SUCCESS, kNumberPacketsReadyToReceive); - hci_register_.one_shot_inquiry_active = true; - hci_register_.num_responses = inquiry.GetNumResponses(); - hci_register_.inquiry_length = inquiry.GetInquiryLength(); - } break; - default: - LOG_INFO("Dropping unhandled status expecting command:%s", hci::OpCodeText(command.GetOpCode()).c_str()); - return; - } - hci::EventView event = hci::EventView::Create(GetPacketView(std::move(event_builder))); - ASSERT_TRUE(event.IsValid()); - hci::CommandStatusView command_status = hci::CommandStatusView::Create(event); - ASSERT_TRUE(command_status.IsValid()); - on_status.Invoke(std::move(command_status)); - - if (promise_sync_complete_ != nullptr) { - promise_sync_complete_->set_value(command.GetOpCode()); - } - } - - void RegisterEventHandler( - hci::EventCode event_code, common::ContextualCallback event_handler) override { - switch (event_code) { - case hci::EventCode::INQUIRY_RESULT: - inquiry_result_callback_ = event_handler; - break; - case hci::EventCode::INQUIRY_RESULT_WITH_RSSI: - inquiry_result_with_rssi_callback_ = event_handler; - break; - case hci::EventCode::EXTENDED_INQUIRY_RESULT: - extended_inquiry_result_callback_ = event_handler; - break; - case hci::EventCode::INQUIRY_COMPLETE: - inquiry_complete_callback_ = event_handler; - break; - default: - ASSERT_TRUE(false) << "Unexpected event handler being registered"; - break; - } - } - - void UnregisterEventHandler(hci::EventCode event_code) override { - if (hci_register_.one_shot_inquiry_active || hci_register_.periodic_inquiry_active) { - LOG_ERROR("Event handlers may not be unregistered until inquiry is stopped"); - return; - } - - switch (event_code) { - case hci::EventCode::INQUIRY_RESULT: - inquiry_result_callback_ = {}; - break; - case hci::EventCode::INQUIRY_RESULT_WITH_RSSI: - inquiry_result_with_rssi_callback_ = {}; - break; - case hci::EventCode::EXTENDED_INQUIRY_RESULT: - extended_inquiry_result_callback_ = {}; - break; - case hci::EventCode::INQUIRY_COMPLETE: - inquiry_complete_callback_ = {}; - break; - default: - ASSERT_TRUE(false) << "Unexpected event handler being unregistered"; - break; - } - } - - void Synchronize(std::function func, hci::OpCode op_code) { - ASSERT_EQ(promise_sync_complete_, nullptr); - promise_sync_complete_ = new std::promise(); - auto future = promise_sync_complete_->get_future(); - func(); - auto result = future.wait_for(std::chrono::milliseconds(100)); - ASSERT_EQ(std::future_status::ready, result); - ASSERT_EQ(op_code, future.get()); - delete promise_sync_complete_; - promise_sync_complete_ = nullptr; - } - - void InjectInquiryResult(std::unique_ptr result) { - hci::EventView view = hci::EventView::Create(GetPacketView(std::move(result))); - ASSERT_TRUE(view.IsValid()); - inquiry_result_callback_.Invoke(std::move(view)); - } - - void ListDependencies(ModuleList* /* list */) const {} - void Start() override {} - void Stop() override {} - - private: - std::promise* promise_sync_complete_{nullptr}; - - common::ContextualCallback inquiry_result_callback_; - common::ContextualCallback inquiry_result_with_rssi_callback_; - common::ContextualCallback extended_inquiry_result_callback_; - common::ContextualCallback inquiry_complete_callback_; -}; - -class InquiryTest : public ::testing::Test { - public: - void Result(hci::InquiryResultView view) { - ASSERT_TRUE(view.size() >= sizeof(uint16_t)); - promise_result_complete_->set_value(true); - } - - void WaitForInquiryResult(std::function func) { - ASSERT_EQ(promise_result_complete_, nullptr); - promise_result_complete_ = new std::promise(); - auto future = promise_result_complete_->get_future(); - func(); - future.wait(); - delete promise_result_complete_; - promise_result_complete_ = nullptr; - } - - void ResultWithRssi(hci::InquiryResultWithRssiView view) { - ASSERT_TRUE(view.size() >= sizeof(uint16_t)); - } - - void ExtendedResult(hci::ExtendedInquiryResultView view) { - ASSERT_TRUE(view.size() >= sizeof(uint16_t)); - } - - void Complete(hci::ErrorCode status) {} - - protected: - void SetUp() override { - test_hci_layer_ = new TestHciLayer; - fake_registry_.InjectTestModule(&hci::HciLayer::Factory, test_hci_layer_); - client_handler_ = fake_registry_.GetTestModuleHandler(&hci::HciLayer::Factory); - fake_registry_.Start(&thread_); - - inquiry_module_ = static_cast(fake_registry_.GetModuleUnderTest(&InquiryModule::Factory)); - - InquiryCallbacks inquiry_callbacks; - inquiry_callbacks.result = std::bind(&InquiryTest::Result, this, std::placeholders::_1); - inquiry_callbacks.result_with_rssi = std::bind(&InquiryTest::ResultWithRssi, this, std::placeholders::_1); - inquiry_callbacks.extended_result = std::bind(&InquiryTest::ExtendedResult, this, std::placeholders::_1); - inquiry_callbacks.complete = std::bind(&InquiryTest::Complete, this, std::placeholders::_1); - inquiry_module_->RegisterCallbacks(inquiry_callbacks); - } - - void TearDown() override { - inquiry_module_->UnregisterCallbacks(); - fake_registry_.StopAll(); - } - - TestModuleRegistry fake_registry_; - TestHciLayer* test_hci_layer_ = nullptr; - os::Thread& thread_ = fake_registry_.GetTestThread(); - InquiryModule* inquiry_module_ = nullptr; - os::Handler* client_handler_ = nullptr; - - std::promise* promise_result_complete_{nullptr}; -}; - -TEST_F(InquiryTest, Module) {} - -TEST_F(InquiryTest, SetInquiryModes) { - test_hci_layer_->Synchronize( - [this] { inquiry_module_->SetInquiryWithRssiResultMode(); }, hci::OpCode::WRITE_INQUIRY_MODE); - ASSERT_EQ(hci_register_.inquiry_mode, hci::InquiryMode::RSSI); - - test_hci_layer_->Synchronize( - [this] { inquiry_module_->SetExtendedInquiryResultMode(); }, hci::OpCode::WRITE_INQUIRY_MODE); - ASSERT_EQ(hci_register_.inquiry_mode, hci::InquiryMode::RSSI_OR_EXTENDED); - - test_hci_layer_->Synchronize( - [this] { inquiry_module_->SetStandardInquiryResultMode(); }, hci::OpCode::WRITE_INQUIRY_MODE); - ASSERT_EQ(hci_register_.inquiry_mode, hci::InquiryMode::STANDARD); -} - -TEST_F(InquiryTest, SetScanType) { - test_hci_layer_->Synchronize([this] { inquiry_module_->SetInterlacedScan(); }, hci::OpCode::WRITE_INQUIRY_SCAN_TYPE); - ASSERT_EQ(hci_register_.inquiry_scan_type, hci::InquiryScanType::INTERLACED); - - test_hci_layer_->Synchronize([this] { inquiry_module_->SetStandardScan(); }, hci::OpCode::WRITE_INQUIRY_SCAN_TYPE); - ASSERT_EQ(hci_register_.inquiry_scan_type, hci::InquiryScanType::STANDARD); -} - -TEST_F(InquiryTest, ScanActivity) { - ScanParameters params{ - .interval = 0x1234, - .window = 0x5678, - }; - - test_hci_layer_->Synchronize( - [this, params] { inquiry_module_->SetScanActivity(params); }, hci::OpCode::WRITE_INQUIRY_SCAN_ACTIVITY); - ASSERT_EQ(params.interval, hci_register_.inquiry_scan_interval); - ASSERT_EQ(params.window, hci_register_.inquiry_scan_window); -} - -TEST_F(InquiryTest, OneShotGeneralInquiry) { - uint8_t inquiry_length = 128; - uint8_t num_responses = 100; - test_hci_layer_->Synchronize( - [this, inquiry_length, num_responses] { inquiry_module_->StartGeneralInquiry(inquiry_length, num_responses); }, - hci::OpCode::INQUIRY); - ASSERT_EQ(inquiry_length, hci_register_.inquiry_length); - ASSERT_EQ(num_responses, hci_register_.num_responses); - - test_hci_layer_->Synchronize([this] { inquiry_module_->StopInquiry(); }, hci::OpCode::INQUIRY_CANCEL); -} - -TEST_F(InquiryTest, OneShotLimitedInquiry) { - test_hci_layer_->Synchronize([this] { inquiry_module_->StartLimitedInquiry(128, 100); }, hci::OpCode::INQUIRY); - - test_hci_layer_->Synchronize([this] { inquiry_module_->StopInquiry(); }, hci::OpCode::INQUIRY_CANCEL); -} - -TEST_F(InquiryTest, GeneralPeriodicInquiry) { - uint8_t inquiry_length = 128; - uint8_t num_responses = 100; - uint16_t max_delay = 1100; - uint16_t min_delay = 200; - test_hci_layer_->Synchronize( - [this, inquiry_length, num_responses, max_delay, min_delay] { - inquiry_module_->StartGeneralPeriodicInquiry(inquiry_length, num_responses, max_delay, min_delay); - }, - hci::OpCode::PERIODIC_INQUIRY_MODE); - ASSERT_EQ(inquiry_length, hci_register_.inquiry_length); - ASSERT_EQ(num_responses, hci_register_.num_responses); - ASSERT_EQ(max_delay, hci_register_.max_period_length); - ASSERT_EQ(min_delay, hci_register_.min_period_length); - - test_hci_layer_->Synchronize( - [this] { inquiry_module_->StopPeriodicInquiry(); }, hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE); -} - -TEST_F(InquiryTest, LimitedPeriodicInquiry) { - test_hci_layer_->Synchronize( - [this] { inquiry_module_->StartLimitedPeriodicInquiry(128, 100, 1100, 200); }, - hci::OpCode::PERIODIC_INQUIRY_MODE); - - test_hci_layer_->Synchronize( - [this] { inquiry_module_->StopPeriodicInquiry(); }, hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE); -} - -TEST_F(InquiryTest, InjectInquiryResult) { - test_hci_layer_->Synchronize([this] { inquiry_module_->StartGeneralInquiry(128, 100); }, hci::OpCode::INQUIRY); - - WaitForInquiryResult([this] { - const std::vector inquiry_results; - auto packet = hci::InquiryResultBuilder::Create(inquiry_results); - test_hci_layer_->InjectInquiryResult(std::move(packet)); - }); - test_hci_layer_->Synchronize([this] { inquiry_module_->StopInquiry(); }, hci::OpCode::INQUIRY_CANCEL); -} - -} // namespace -} // namespace neighbor -} // namespace bluetooth diff --git a/system/gd/os/BUILD.gn b/system/gd/os/BUILD.gn index 7842583a42e639e090b174d10293f305a8930feb..b463430a9f04a1f281953d961697e2ba062dee17 100644 --- a/system/gd/os/BUILD.gn +++ b/system/gd/os/BUILD.gn @@ -22,7 +22,10 @@ source_set("BluetoothOsSources_chromeos") { "syslog.cc", ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system:libbt-platform-protos-lite", "//bt/system/gd/rust/shim:init_flags_bridge_header", @@ -39,7 +42,10 @@ source_set("BluetoothOsSources_linux") { "syslog.cc", ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system:libbt-platform-protos-lite", "//bt/system/gd/rust/shim:init_flags_bridge_header", @@ -59,7 +65,10 @@ source_set("BluetoothOsSources_linux_generic") { "linux_generic/wakelock_manager.cc", ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] if (target_os == "chromeos") { diff --git a/system/gd/os/android/metrics.cc b/system/gd/os/android/metrics.cc index a64f3319350b1254660b026e5548f3df565794c6..61cd78b79008f9c13e28509b5bf1e64d9b2fed65 100644 --- a/system/gd/os/android/metrics.cc +++ b/system/gd/os/android/metrics.cc @@ -176,6 +176,20 @@ void LogMetricA2dpPlaybackEvent(const Address& address, int playback_state, int } } +void LogMetricA2dpSessionMetricsEvent( + const hci::Address& /* address */, + int64_t /* audio_duration_ms */, + int /* media_timer_min_ms */, + int /* media_timer_max_ms */, + int /* media_timer_avg_ms */, + int /* total_scheduling_count */, + int /* buffer_overruns_max_count */, + int /* buffer_overruns_total */, + float /* buffer_underruns_average */, + int /* buffer_underruns_count */, + int64_t /* codec_index */, + bool /* is_a2dp_offload */) {} + void LogMetricHfpPacketLossStats( const Address& /* address */, int /* num_decoded_frames */, diff --git a/system/gd/os/chromeos/metrics.cc b/system/gd/os/chromeos/metrics.cc index 76023230ead7117e564f2a8a8b4d58ef12ffd7f6..758cfe66ab3e128ef0a131269137b27eb0362143 100644 --- a/system/gd/os/chromeos/metrics.cc +++ b/system/gd/os/chromeos/metrics.cc @@ -20,7 +20,7 @@ #include -#include "gd/metrics/utils.h" +#include "metrics/utils.h" #include "os/log.h" namespace bluetooth { @@ -187,6 +187,59 @@ void LogMetricSmpPairingEvent( void LogMetricA2dpPlaybackEvent(const Address& address, int playback_state, int audio_coding_mode) { } +void LogMetricA2dpSessionMetricsEvent( + const hci::Address& address, + int64_t audio_duration_ms, + int media_timer_min_ms, + int media_timer_max_ms, + int media_timer_avg_ms, + int total_scheduling_count, + int buffer_overruns_max_count, + int buffer_overruns_total, + float buffer_underruns_average, + int buffer_underruns_count, + int64_t codec_index, + bool is_a2dp_offload) { + std::string boot_id; + std::string addr_string; + + if (!metrics::GetBootId(&boot_id)) return; + + addr_string = address.ToString(); + + LOG_DEBUG( + "A2dpSessionMetrics: %s, %s, %lld, %d, %d, %d, %d, %d, %d, %f, %d, %lld, %d", + boot_id.c_str(), + addr_string.c_str(), + (long long int)audio_duration_ms, + media_timer_min_ms, + media_timer_max_ms, + media_timer_avg_ms, + total_scheduling_count, + buffer_overruns_max_count, + buffer_overruns_total, + buffer_underruns_average, + buffer_underruns_count, + codec_index, + is_a2dp_offload); + + ::metrics::structured::events::bluetooth::BluetoothA2dpSession() + .SetBootId(boot_id) + .SetDeviceId(addr_string) + .SetAudioDuration(audio_duration_ms) + .SetMediaTimerMin(media_timer_min_ms) + .SetMediaTimerMax(media_timer_max_ms) + .SetMediaTimerAvg(media_timer_avg_ms) + .SetTotalSchedulingCount(total_scheduling_count) + .SetBufferOverrunsMaxCount(buffer_overruns_max_count) + .SetBufferOverrunsTotal(buffer_overruns_total) + .SetBufferUnderrunsAvg(buffer_underruns_average) + .SetBufferUnderrunsCount(buffer_underruns_count) + .SetCodecIndex(codec_index) + .SetIsA2dpOffload(is_a2dp_offload) + .Record(); +} + void LogMetricBluetoothHalCrashReason( const Address& address, uint32_t error_code, uint32_t vendor_error_code) {} @@ -214,5 +267,6 @@ void LogMetricBluetoothLEConnectionMetricEvent( android::bluetooth::le::LeConnectionState transaction_state, std::vector>& argument_list) {} +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions /* session_options */) {} } // namespace os } // namespace bluetooth diff --git a/system/gd/os/handler.h b/system/gd/os/handler.h index 1dabbde7ffb8b5779ee4ca9859a7c6a7ef800e23..2609ea8486afdb1442bfe7480f66277f814c9562 100644 --- a/system/gd/os/handler.h +++ b/system/gd/os/handler.h @@ -64,29 +64,26 @@ class Handler : public common::IPostableContext { } template - common::ContextualOnceCallback> BindOnce( - Functor&& functor, Args&&... args) { - return common::ContextualOnceCallback>( + auto BindOnce(Functor&& functor, Args&&... args) { + return common::ContextualOnceCallback( common::BindOnce(std::forward(functor), std::forward(args)...), this); } template - common::ContextualOnceCallback> BindOnceOn( - T* obj, Functor&& functor, Args&&... args) { - return common::ContextualOnceCallback>( + auto BindOnceOn(T* obj, Functor&& functor, Args&&... args) { + return common::ContextualOnceCallback( common::BindOnce(std::forward(functor), common::Unretained(obj), std::forward(args)...), this); } template - common::ContextualCallback> Bind(Functor&& functor, Args&&... args) { - return common::ContextualCallback>( + auto Bind(Functor&& functor, Args&&... args) { + return common::ContextualCallback( common::Bind(std::forward(functor), std::forward(args)...), this); } template - common::ContextualCallback> BindOn( - T* obj, Functor&& functor, Args&&... args) { - return common::ContextualCallback>( + auto BindOn(T* obj, Functor&& functor, Args&&... args) { + return common::ContextualCallback( common::Bind(std::forward(functor), common::Unretained(obj), std::forward(args)...), this); } diff --git a/system/gd/os/host/metrics.cc b/system/gd/os/host/metrics.cc index d2c3b900d39bf2f551abfbf87a2930a3a5f04760..29caef103d88585ea9d5332e805d098e57173adb 100644 --- a/system/gd/os/host/metrics.cc +++ b/system/gd/os/host/metrics.cc @@ -129,6 +129,20 @@ void LogMetricSmpPairingEvent( void LogMetricA2dpPlaybackEvent( const Address& /* address */, int /* playback_state */, int /* audio_coding_mode */) {} +void LogMetricA2dpSessionMetricsEvent( + const Address& /* address */, + int64_t /* audio_duration_ms */, + int /* media_timer_min_ms */, + int /* media_timer_max_ms */, + int /* media_timer_avg_ms */, + int /* total_scheduling_count */, + int /* buffer_overruns_max_count */, + int /* buffer_overruns_total */, + float /* buffer_underruns_average */, + int /* buffer_underruns_count */, + int64_t /* codec_index */, + bool /* is_a2dp_offload */) {} + void LogMetricBluetoothHalCrashReason( const Address& /* address */, uint32_t /* error_code */, uint32_t /* vendor_error_code */) {} diff --git a/system/gd/os/linux/metrics.cc b/system/gd/os/linux/metrics.cc index ed653d9812a0f8165fb52a319ea1761395f2ab09..62f7b9392d7f1ae86cb48bfa017e40fa1a33f071 100644 --- a/system/gd/os/linux/metrics.cc +++ b/system/gd/os/linux/metrics.cc @@ -100,6 +100,20 @@ void LogMetricSmpPairingEvent( void LogMetricA2dpPlaybackEvent(const Address& address, int playback_state, int audio_coding_mode) {} +void LogMetricA2dpSessionMetricsEvent( + const Address& address, + int64_t audio_duration_ms, + int media_timer_min_ms, + int media_timer_max_ms, + int media_timer_avg_ms, + int total_scheduling_count, + int buffer_overruns_max_count, + int buffer_overruns_total, + float buffer_underruns_average, + int buffer_underruns_count, + int64_t codec_index, + bool is_a2dp_offload) {} + void LogMetricHfpPacketLossStats( const Address& address, int num_decoded_frames, double packet_loss_ratio, uint16_t codec_type) { } @@ -134,5 +148,6 @@ void LogMetricBluetoothLEConnectionMetricEvent( android::bluetooth::le::LeConnectionState transaction_state, std::vector>& argument_list) {} +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions /* session_options */) {} } // namespace os } // namespace bluetooth diff --git a/system/gd/os/log.h b/system/gd/os/log.h index 468261e86f927f1dd916e1aa1d8f2dd10b6d534b..437cba5af525c6da7c8c90f6ad8c5713f2c04348 100644 --- a/system/gd/os/log.h +++ b/system/gd/os/log.h @@ -57,24 +57,21 @@ static_assert(LOG_TAG != nullptr, "LOG_TAG should never be NULL"); #include #include -#if __has_include("src/init_flags.rs.h") - -#include "common/init_flags.h" - -#define LOG_VERBOSE_INT(fmt, args...) \ - do { \ - if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_VERBOSE) { \ - ALOGV(fmt, ##args); \ - } \ +#define LOG_VERBOSE_INT(fmt, args...) \ + do { \ + if (!__android_log_is_loggable(ANDROID_LOG_VERBOSE, LOG_TAG, ANDROID_LOG_INFO) && \ + !__android_log_is_loggable(ANDROID_LOG_VERBOSE, "bluetooth", ANDROID_LOG_INFO)) { \ + ALOGV(fmt, ##args); \ + } \ } while (false) -#define LOG_DEBUG_INT(fmt, args...) \ - do { \ - if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_DEBUG) { \ - ALOGD(fmt, ##args); \ - } \ +#define LOG_DEBUG_INT(fmt, args...) \ + do { \ + if (!__android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO) && \ + !__android_log_is_loggable(ANDROID_LOG_DEBUG, "bluetooth", ANDROID_LOG_INFO)) { \ + ALOGD(fmt, ##args); \ + } \ } while (false) -#endif /* __has_include("src/init_flags.rs.h") */ #define LOG_INFO_INT(fmt, args...) ALOGI(fmt, ##args) #define LOG_WARN_INT(fmt, args...) ALOGW(fmt, ##args) @@ -102,25 +99,13 @@ static_assert(LOG_TAG != nullptr, "LOG_TAG should never be NULL"); abort(); \ } while (false) #elif defined(TARGET_FLOSS) /* end of defined (ANDROID_EMULATOR) */ -#include "gd/common/init_flags.h" -#include "gd/os/syslog.h" +#include "os/syslog.h" // Prefix the log with tag, file, line and function -#define LOGWRAPPER(tag, fmt, args...) \ - write_syslog(tag, "%s: " fmt, LOG_TAG, ##args) - -#define LOG_VERBOSE_INT(...) \ - do { \ - if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_VERBOSE) { \ - LOGWRAPPER(LOG_TAG_VERBOSE, __VA_ARGS__); \ - } \ - } while (false) -#define LOG_DEBUG_INT(...) \ - do { \ - if (bluetooth::common::InitFlags::GetLogLevelForTag(LOG_TAG) >= LOG_TAG_DEBUG) { \ - LOGWRAPPER(LOG_TAG_DEBUG, __VA_ARGS__); \ - } \ - } while (false) +#define LOGWRAPPER(tag, fmt, args...) write_syslog(tag, LOG_TAG, "%s: " fmt, LOG_TAG, ##args) + +#define LOG_VERBOSE_INT(...) LOGWRAPPER(LOG_TAG_VERBOSE, __VA_ARGS__) +#define LOG_DEBUG_INT(...) LOGWRAPPER(LOG_TAG_DEBUG, __VA_ARGS__) #define LOG_INFO_INT(...) LOGWRAPPER(LOG_TAG_INFO, __VA_ARGS__) #define LOG_WARN_INT(...) LOGWRAPPER(LOG_TAG_WARN, __VA_ARGS__) #define LOG_ERROR_INT(...) LOGWRAPPER(LOG_TAG_ERROR, __VA_ARGS__) diff --git a/system/gd/os/log_tags.h b/system/gd/os/log_tags.h index ac94a7f8402178c0bfe2ce8d87e848925d1f34e3..437fb120f25efe31df81d22da6e9ee42a5089451 100644 --- a/system/gd/os/log_tags.h +++ b/system/gd/os/log_tags.h @@ -15,14 +15,15 @@ */ #pragma once +// TODO(b/305066880) - Deprecate once replaced with fmtlib implementation. // These log levels may need to be mapped to system values. These values are -// used to control the log level via init flags. +// used to control the log level and should match +// `bluetooth::log_internal::Level`. enum LogLevels { - LOG_TAG_FATAL = 0, - LOG_TAG_ERROR, - LOG_TAG_WARN, - LOG_TAG_NOTICE, - LOG_TAG_INFO, - LOG_TAG_DEBUG, - LOG_TAG_VERBOSE + LOG_TAG_VERBOSE = 2, + LOG_TAG_DEBUG = 3, + LOG_TAG_INFO = 4, + LOG_TAG_WARN = 5, + LOG_TAG_ERROR = 6, + LOG_TAG_FATAL = 7, }; diff --git a/system/gd/os/metrics.h b/system/gd/os/metrics.h index c1703b6935609a2d0396f732f82a78995e4d0356..2b6883d4fed294869983aeb5ff49e43162123b5b 100644 --- a/system/gd/os/metrics.h +++ b/system/gd/os/metrics.h @@ -22,6 +22,8 @@ #include #include +#include + #include "hci/address.h" namespace bluetooth { @@ -119,7 +121,41 @@ void LogMetricA2dpAudioOverrunEvent( * @param playback_state A2DP audio playback state, on/off * @param audio_coding_mode A2DP audio codec encoding mode, hw/sw */ -void LogMetricA2dpPlaybackEvent(const hci::Address& address, int playback_state, int audio_coding_mode); +void LogMetricA2dpPlaybackEvent( + const hci::Address& address, int playback_state, int audio_coding_mode); + +/** + * Log A2DP audio session metrics + * + * @param address A2DP device associated with this session + * @param audio_duration_ms duration of the A2DP session + * @param media_timer_min_ms min time interval for the media timer + * @param media_timer_max_ms max time interval for the media timer + * @param media_timer_avg_ms avg time interval for the media timer + * @param total_scheduling_count total scheduling count + * @param buffer_overruns_max_count max count of Tx queue messages dropped + caused by buffer overruns + * @param buffer_overruns_total total count of Tx queue messages dropped + caused by buffer overruns + * @param buffer_underruns_average avg number of bytes short in buffer + underruns + * @param buffer_underruns_count count of buffer underruns + * @param codec_index A2DP codec index (SBC=0, AAC=1, etc...) + * @param is_a2dp_offload if A2DP is offload + */ +void LogMetricA2dpSessionMetricsEvent( + const hci::Address& address, + int64_t audio_duration_ms, + int media_timer_min_ms, + int media_timer_max_ms, + int media_timer_avg_ms, + int total_scheduling_count, + int buffer_overruns_max_count, + int buffer_overruns_total, + float buffer_underruns_average, + int buffer_underruns_count, + int64_t codec_index, + bool is_a2dp_offload); /** * Log HFP audio capture packet loss statistics diff --git a/system/gd/os/syslog.cc b/system/gd/os/syslog.cc index f117f64ffcc7b3f463e37398ee5f38701497a92b..1f223dd2ec21737f0a502911280788a51adbb99f 100644 --- a/system/gd/os/syslog.cc +++ b/system/gd/os/syslog.cc @@ -14,14 +14,23 @@ * limitations under the License. */ -#include "gd/os/syslog.h" +#include "os/syslog.h" #include #include #include -#include "gd/os/log_tags.h" +#include "os/log_tags.h" + +// TODO(b/305066880) - This implementation will replace this syslog +// implementation. Remove this file once everything is moved over to the new +// logging macros. +#include "bluetooth/log.h" + +namespace bluetooth::log_internal { +extern Level GetLogLevelForTag(char const* tag); +} namespace { #define SYSLOG_IDENT "btadapterd" @@ -29,17 +38,16 @@ namespace { const char kSyslogIdent[] = SYSLOG_IDENT; // Map LOG_TAG_* to syslog mappings -const int kTagMap[] = { - /*LOG_TAG_FATAL=*/LOG_CRIT, - /*LOG_TAG_ERROR=*/LOG_ERR, - /*LOG_TAG_WARN=*/LOG_WARNING, - /*LOG_TAG_NOTICE=*/LOG_NOTICE, - /*LOG_TAG_INFO=*/LOG_INFO, - /*LOG_TAG_DEBUG=*/LOG_DEBUG, +const int kLevelMap[] = { /*LOG_TAG_VERBOSE=*/LOG_DEBUG, + /*LOG_TAG_DEBUG=*/LOG_DEBUG, + /*LOG_TAG_INFO=*/LOG_INFO, + /*LOG_TAG_WARN=*/LOG_WARNING, + /*LOG_TAG_ERROR=*/LOG_ERR, + /*LOG_TAG_FATAL=*/LOG_CRIT, }; -static_assert(sizeof(kTagMap) / sizeof(kTagMap[0]) == LOG_TAG_VERBOSE + 1); +static_assert(sizeof(kLevelMap) / sizeof(kLevelMap[0]) == (LOG_TAG_FATAL - LOG_TAG_VERBOSE) + 1); class SyslogWrapper { public: @@ -55,18 +63,28 @@ class SyslogWrapper { std::unique_ptr gSyslog; } // namespace -void write_syslog(int tag, const char* format, ...) { +void write_syslog(int level, const char* tag, const char* format, ...) { if (!gSyslog) { gSyslog = std::make_unique(); } - // I don't expect to see incorrect tags but making the check anyway so we + // Filter out logs that don't meet level requirement. + bluetooth::log_internal::Level current_level = bluetooth::log_internal::GetLogLevelForTag(tag); + if (static_cast(level) < current_level) { + return; + } + + // I don't expect to see incorrect levels but making the check anyway so we // don't go out of bounds in the array above. - tag = tag <= LOG_TAG_VERBOSE ? tag : LOG_TAG_ERROR; - int level = kTagMap[tag]; + if (level > LOG_TAG_FATAL) { + level = LOG_TAG_ERROR; + } else if (level < LOG_TAG_VERBOSE) { + level = LOG_TAG_VERBOSE; + } + int syslog_level = kLevelMap[level - LOG_TAG_VERBOSE]; va_list args; va_start(args, format); - vsyslog(level, format, args); + vsyslog(syslog_level, format, args); va_end(args); } diff --git a/system/gd/os/syslog.h b/system/gd/os/syslog.h index 63411a26200a4c026e460d4e06fe23b7404dc088..aed9bc60e772079b8b19e025abe18b1a95d0ce3b 100644 --- a/system/gd/os/syslog.h +++ b/system/gd/os/syslog.h @@ -26,4 +26,4 @@ /** * Write log to syslog. */ -void write_syslog(int tag, const char* format, ...); +void write_syslog(int level, const char* tag, const char* format, ...); diff --git a/system/gd/os/system_properties.h b/system/gd/os/system_properties.h index 194c93f8bf2a4e5847279ca6e38a68ba666590ff..cbad2dc9568d5b6571702281039e91a2ed1cd69d 100644 --- a/system/gd/os/system_properties.h +++ b/system/gd/os/system_properties.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include diff --git a/system/gd/packet/iterator.cc b/system/gd/packet/iterator.cc index 27db6e7b1f040fdfeb10fa1e903db7f6fce02b26..c5088adc45d827bb830f5f63b9179e502999b2f9 100644 --- a/system/gd/packet/iterator.cc +++ b/system/gd/packet/iterator.cc @@ -32,6 +32,14 @@ Iterator::Iterator(const std::forward_list& data, size_t of } } +template +Iterator::Iterator(std::shared_ptr> data) { + data_.emplace_front(data, 0, data->size()); + index_ = 0; + begin_ = 0; + end_ = data_.front().size(); +} + template Iterator Iterator::operator+(int offset) const { auto itr(*this); diff --git a/system/gd/packet/iterator.h b/system/gd/packet/iterator.h index 0afdcd795d4deac33b3fd548c5bf1433680f56c8..52ab47f43aca1b6920aa5783a8cec3d092ea1be2 100644 --- a/system/gd/packet/iterator.h +++ b/system/gd/packet/iterator.h @@ -46,6 +46,7 @@ template class Iterator : public IteratorTraits { public: Iterator(const std::forward_list& data, size_t offset); + Iterator(std::shared_ptr> data); Iterator(const Iterator& itr) = default; virtual ~Iterator() = default; diff --git a/system/gd/packet/packet_view.h b/system/gd/packet/packet_view.h index 7b69730ee7f1ef0d1573a1518b331d725be87f43..b822fdfbfbb30ee2fea2009e542f58769927babc 100644 --- a/system/gd/packet/packet_view.h +++ b/system/gd/packet/packet_view.h @@ -18,6 +18,7 @@ #include #include +#include #include "packet/iterator.h" #include "packet/view.h" diff --git a/system/gd/packet/packet_view_unittest.cc b/system/gd/packet/packet_view_unittest.cc index c0d7a0e1bb48544d048eba543c7f74dc9a219802..1e1fd8a28291707e922f9aa1aa05f55aeb672bf3 100644 --- a/system/gd/packet/packet_view_unittest.cc +++ b/system/gd/packet/packet_view_unittest.cc @@ -17,10 +17,12 @@ #include "packet/packet_view.h" #include + #include #include #include "hci/address.h" +#include "packet/iterator.h" using bluetooth::hci::Address; using bluetooth::packet::PacketView; @@ -399,6 +401,15 @@ TYPED_TEST(IteratorTest, subrangeTest) { ASSERT_EQ(*(subrange), this->packet->size() - 1); } +TYPED_TEST(IteratorTest, constructor_from_shared_vector_test) { + auto iterator = this->packet->begin(); + Iterator another(std::make_shared>(count_all)); + ASSERT_EQ(iterator.NumBytesRemaining(), another.NumBytesRemaining()); + for (size_t i = 0; i < count_all.size(); i++) { + ASSERT_EQ(iterator.template extract(), another.extract()); + } +} + using SubviewTestParam = std::pair; class SubviewBaseTest : public ::testing::TestWithParam { public: diff --git a/system/gd/packet/parser/fields/array_field.cc b/system/gd/packet/parser/fields/array_field.cc index 33cfb1be6b4e1bf800ad95b550bb2c9363fdd30f..27719d0864c24066d2d09eccfd1a0c187f97c462 100644 --- a/system/gd/packet/parser/fields/array_field.cc +++ b/system/gd/packet/parser/fields/array_field.cc @@ -113,7 +113,7 @@ std::string ArrayField::GetGetterFunctionName() const { } void ArrayField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const { - s << GetDataType() << " " << GetGetterFunctionName() << "() {"; + s << GetDataType() << " " << GetGetterFunctionName() << "() const {"; s << "ASSERT(was_validated_);"; s << "size_t end_index = size();"; s << "auto to_bound = begin();"; diff --git a/system/gd/packet/parser/fields/vector_field.cc b/system/gd/packet/parser/fields/vector_field.cc index a13ac3259a03c1c378bbcaf0a44bc1c068ee0976..5fbde3e3d6f90ba7a89b4bb7dd8ec4fc61800509 100644 --- a/system/gd/packet/parser/fields/vector_field.cc +++ b/system/gd/packet/parser/fields/vector_field.cc @@ -151,7 +151,7 @@ std::string VectorField::GetGetterFunctionName() const { } void VectorField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const { - s << GetDataType() << " " << GetGetterFunctionName() << "() {"; + s << GetDataType() << " " << GetGetterFunctionName() << "() const {"; s << "ASSERT(was_validated_);"; s << "size_t end_index = size();"; s << "auto to_bound = begin();"; diff --git a/system/gd/packet/parser/packet_def.cc b/system/gd/packet/parser/packet_def.cc index eaf195925ae583df80ed53efb2b79f9a2654295d..eaf7c855b2734fca7201be3ce78bd70fbb3902d3 100644 --- a/system/gd/packet/parser/packet_def.cc +++ b/system/gd/packet/parser/packet_def.cc @@ -347,7 +347,7 @@ void PacketDef::GenValidator(std::ostream& s) const { } void PacketDef::GenParserToString(std::ostream& s) const { - s << "virtual std::string ToString() " << (parent_ != nullptr ? " override" : "") << " {"; + s << "virtual std::string ToString() const " << (parent_ != nullptr ? " override" : "") << " {"; s << "std::stringstream ss;"; s << "ss << std::showbase << std::hex << \"" << name_ << " { \";"; diff --git a/system/gd/packet/parser/packet_dependency.h b/system/gd/packet/parser/packet_dependency.h index 3b12d1d48d7f0f0b56aeb1cf6b844047d5d1de4d..e550775c3503be857c46ba4b811c441b8283983f 100644 --- a/system/gd/packet/parser/packet_dependency.h +++ b/system/gd/packet/parser/packet_dependency.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include "parent_def.h" diff --git a/system/gd/packet/parser/parent_def.h b/system/gd/packet/parser/parent_def.h index bf316cf5008ede197c6596e7846b63b0666a682d..f9e29dbd5c56c51c3d29669f468f5a771cbc0dcc 100644 --- a/system/gd/packet/parser/parent_def.h +++ b/system/gd/packet/parser/parent_def.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "enum_def.h" #include "field_list.h" diff --git a/system/gd/packet/parser/struct_def.cc b/system/gd/packet/parser/struct_def.cc index 82a4766de403859590556d3ad5dad02d09492828..a7867912b8baae294747bb78d1e52c2a655bccf8 100644 --- a/system/gd/packet/parser/struct_def.cc +++ b/system/gd/packet/parser/struct_def.cc @@ -46,7 +46,7 @@ void StructDef::GenSpecialize(std::ostream& s) const { } void StructDef::GenToString(std::ostream& s) const { - s << "std::string ToString() {"; + s << "std::string ToString() const {"; s << "std::stringstream ss;"; s << "ss << std::hex << std::showbase << \"" << name_ << " { \";"; diff --git a/system/gd/packet/parser/util.h b/system/gd/packet/parser/util.h index f252ac6e5de141a3deb774786031d38016778957..918c0d43ca45aa03f8c35563fa4d6e170f69169b 100644 --- a/system/gd/packet/parser/util.h +++ b/system/gd/packet/parser/util.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "logging.h" diff --git a/system/gd/rust/common/BUILD.gn b/system/gd/rust/common/BUILD.gn index 9a6e8ca5ac0d42dd6d3a45ebd4a6d031c122ab1f..dd1e7c33c008dcd834294ac92593a7545ec143d5 100644 --- a/system/gd/rust/common/BUILD.gn +++ b/system/gd/rust/common/BUILD.gn @@ -22,7 +22,10 @@ static_library("libbt_keystore_cc") { ":libbt_common_bridge_code" ] - configs += ["//bt/system/gd:gd_defaults"] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } config("rust_common_config") { @@ -38,7 +41,10 @@ cxxbridge_header("libbt_common_bridge_header") { cxxbridge_cc("libbt_common_bridge_code") { sources = [ "src/bridge.rs" ] deps = [ ":libbt_common_bridge_header" ] - configs = [ "//bt/system/gd:gd_defaults" ] + configs = [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } cxxbridge_libheader("cxxlibheader") { diff --git a/system/gd/rust/common/Cargo.toml b/system/gd/rust/common/Cargo.toml index eb593779478bed19a52453b6979749275493c80b..410f11e2ce7c8d2823bc61908b035de7b5439991 100644 --- a/system/gd/rust/common/Cargo.toml +++ b/system/gd/rust/common/Cargo.toml @@ -22,7 +22,7 @@ edition = "2018" cxx = "1.0" env_logger = "0.8" futures = "0.3.13" -grpcio = "0.9" +grpcio = { version = "0.13.0", default-features = false, features = ["protobufv3-codec", "openssl"] } lazy_static = "1.4" log = "0.4" nix = { version = "0.27.1", features = ["time", "user"] } diff --git a/system/gd/rust/common/src/init_flags.rs b/system/gd/rust/common/src/init_flags.rs index 6a41c0f306b5138018e3727e6270e9a0e9db5c69..e1376a4a186c5d98f003d7e18f76e5883822761c 100644 --- a/system/gd/rust/common/src/init_flags.rs +++ b/system/gd/rust/common/src/init_flags.rs @@ -2,7 +2,6 @@ use lazy_static::lazy_static; use log::{error, info}; use paste::paste; use std::collections::{BTreeMap, HashMap}; -use std::convert::TryFrom; use std::fmt; use std::sync::Mutex; @@ -70,25 +69,6 @@ macro_rules! create_getter_fn { }; } -macro_rules! create_setter_fn { - ($flag:ident) => { - paste! { - #[doc = concat!(" Update value of ", stringify!($flag), " at runtime")] - pub fn [](value: bool) { - FLAGS.lock().unwrap().$flag = value; - } - } - }; - ($flag:ident $type:ty) => { - paste! { - #[doc = concat!(" Update value of ", stringify!($flag), " at runtime")] - pub fn [](value: $type) { - FLAGS.lock().unwrap().$flag = value; - } - } - }; -} - macro_rules! init_flags { ( name: $name:ident @@ -116,23 +96,17 @@ macro_rules! init_flags_struct { ( name: $name:ident flags: { $($flag:ident $(: $type:ty)? $(= $default:tt)?,)* } - dynamic_flags: { $($dy_flag:ident $(: $dy_type:ty)? $(= $dy_default:tt)?,)* } - extra_fields: { $($extra_field:ident : $extra_field_type:ty $(= $extra_default:tt)?,)* } extra_parsed_flags: { $($extra_flag:tt => $extra_flag_fn:ident(_, _ $(,$extra_args:tt)*),)*} dependencies: { $($parent:ident => $child:ident),* }) => { struct $name { $($flag : type_expand!($($type)?),)* - $($dy_flag : type_expand!($($dy_type)?),)* - $($extra_field : $extra_field_type,)* } impl Default for $name { fn default() -> Self { Self { $($flag : default_value!($($type)? $(= $default)?),)* - $($dy_flag : default_value!($($dy_type)? $(= $dy_default)?),)* - $($extra_field : default_value!($extra_field_type $(= $extra_default)?),)* } } } @@ -141,16 +115,12 @@ macro_rules! init_flags_struct { fn get_defaults_for_test() -> Self { Self { $($flag: test_value!($($type)?),)* - $($dy_flag: test_value!($($dy_type)?),)* - $($extra_field: test_value!($extra_field_type),)* } } fn dump(&self) -> BTreeMap<&'static str, String> { [ $((stringify!($flag), format!("{}", self.$flag)),)* - $((stringify!($dy_flag), format!("{}", self.$dy_flag)),)* - $((stringify!($extra_field), format!("{}", self.$extra_field)),)* ].into() } @@ -169,10 +139,6 @@ macro_rules! init_flags_struct { init_flags.$flag = values[1].parse().unwrap_or_else(|e| { error!("Parse failure on '{}': {}", flag, e); default_value!($($type)? $(= $default)?)}),)* - $(concat!("INIT_", stringify!($dy_flag)) => - init_flags.$dy_flag = values[1].parse().unwrap_or_else(|e| { - error!("Parse failure on '{}': {}", flag, e); - default_value!($($dy_type)? $(= $dy_default)?)}),)* $($extra_flag => $extra_flag_fn(&mut init_flags, values $(, $extra_args)*),)* _ => error!("Unsaved flag: {} = {}", values[0], values[1]) } @@ -197,13 +163,9 @@ macro_rules! init_flags_struct { impl fmt::Display for $name { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, concat!( + write!(f, concat!($(concat!(stringify!($flag), "={}")),*), - concat!($(concat!(stringify!($dy_flag), "={}")),*), - $(concat!(stringify!($extra_field), "={}")),*), - $(self.$flag),*, - $(self.$dy_flag),*, - $(self.$extra_field),*) + $(self.$flag),*) } } @@ -213,16 +175,11 @@ macro_rules! init_flags_struct { macro_rules! init_flags_getters { ( flags: { $($flag:ident $(: $type:ty)? $(= $default:tt)?,)* } - dynamic_flags: { $($dy_flag:ident $(: $dy_type:ty)? $(= $dy_default:tt)?,)* } - extra_fields: { $($extra_field:ident : $extra_field_type:ty $(= $extra_default:tt)?,)* } extra_parsed_flags: { $($extra_flag:tt => $extra_flag_fn:ident(_, _ $(,$extra_args:tt)*),)*} dependencies: { $($parent:ident => $child:ident),* }) => { $(create_getter_fn!($flag $($type)?);)* - $(create_getter_fn!($dy_flag $($dy_type)?);)* - $(create_setter_fn!($dy_flag $($dy_type)?);)* - #[cfg(test)] mod tests_autogenerated { use super::*; @@ -238,19 +195,6 @@ macro_rules! init_flags_getters { assert_eq!(get_value, test_value!($($type)?)); } })* - - $(paste! { - #[test] - pub fn []() { - let _guard = tests::ASYNC_LOCK.lock().unwrap(); - tests::test_load(vec![ - &*format!(concat!(concat!("INIT_", stringify!($dy_flag)), "={}"), test_value!($($dy_type)?)) - ]); - let get_value = call_getter_fn!($dy_flag $($dy_type)?); - drop(_guard); // Prevent poisonning other tests if a panic occurs - assert_eq!(get_value, test_value!($($dy_type)?)); - } - })* } } } @@ -266,95 +210,16 @@ impl fmt::Display for ExplicitTagSettings { } } -struct LogLevel(i32); - -impl TryFrom<&str> for LogLevel { - type Error = &'static str; - - fn try_from(tag_value: &str) -> Result { - match tag_value { - "LOG_FATAL" => Ok(LogLevel(LOG_TAG_FATAL)), - "LOG_ERROR" => Ok(LogLevel(LOG_TAG_ERROR)), - "LOG_WARN" => Ok(LogLevel(LOG_TAG_WARN)), - "LOG_NOTICE" => Ok(LogLevel(LOG_TAG_NOTICE)), - "LOG_INFO" => Ok(LogLevel(LOG_TAG_INFO)), - "LOG_DEBUG" => Ok(LogLevel(LOG_TAG_DEBUG)), - "LOG_VERBOSE" => Ok(LogLevel(LOG_TAG_VERBOSE)), - _ => Err("Invalid tag value"), - } - } -} - -fn deprecated_set_debug_logging_enabled_for_all(flags: &mut InitFlags, values: Vec<&str>) { - let truthy: bool = values[1].parse().unwrap_or(false); - flags.default_log_level = if truthy { LOG_TAG_VERBOSE } else { LOG_TAG_INFO }; - - // Leave a note that this flag is deprecated in the logs. - log::error!( - "DEPRECATED flag used: INIT_logging_debug_enabled_for_all. Use INIT_default_log_level_str=LOG_VERBOSE instead.", - ); -} - -fn parse_log_level(flags: &mut InitFlags, values: Vec<&str>) { - if let Ok(v) = LogLevel::try_from(values[1]) { - flags.default_log_level = v.0; - } -} - -fn parse_logging_tag(flags: &mut InitFlags, values: Vec<&str>) { - for tag in values[1].split(',') { - let tagstr = tag.to_string(); - let pair = tagstr.split(':').collect::>(); - if pair.len() == 2 { - if let Ok(v) = LogLevel::try_from(pair[1]) { - flags.logging_explicit_tag_settings.map.insert(pair[0].into(), v.0); - } - } - } -} - -fn parse_debug_logging_tag(flags: &mut InitFlags, values: Vec<&str>, enabled: bool) { - let log_level: i32 = if enabled { LOG_TAG_VERBOSE } else { LOG_TAG_INFO }; - - for tag in values[1].split(',') { - flags.logging_explicit_tag_settings.map.insert(tag.to_string(), log_level); - } -} - fn parse_hci_adapter(flags: &mut InitFlags, values: Vec<&str>) { flags.hci_adapter = values[1].parse().unwrap_or(0); } -/// Returns the log level for given flag. -pub fn get_log_level_for_tag(tag: &str) -> i32 { - let guard = FLAGS.lock().unwrap(); - *guard.logging_explicit_tag_settings.map.get(tag).unwrap_or(&guard.default_log_level) -} - /// Sets all bool flags to true /// Set all other flags and extra fields to their default type value pub fn set_all_for_testing() { *FLAGS.lock().unwrap() = InitFlags::get_defaults_for_test(); } -// Keep these values in sync with the values in gd/os/log_tags.h -// They are used to control the log level for each tag. - -/// Fatal log level. -pub const LOG_TAG_FATAL: i32 = 0; -/// Error log level. -pub const LOG_TAG_ERROR: i32 = 1; -/// Warning log level. -pub const LOG_TAG_WARN: i32 = 2; -/// Notice log level. -pub const LOG_TAG_NOTICE: i32 = 3; -/// Info log level. This is usually the default log level on most systems. -pub const LOG_TAG_INFO: i32 = 4; -/// Debug log level. -pub const LOG_TAG_DEBUG: i32 = 5; -/// Verbose log level. -pub const LOG_TAG_VERBOSE: i32 = 6; - init_flags!( name: InitFlags flags: { @@ -378,7 +243,6 @@ init_flags!( irk_rotation, leaudio_targeted_announcement_reconnection_mode = true, pbap_pse_dynamic_version_upgrade = false, - periodic_advertising_adi = true, private_gatt = true, redact_log = true, rust_event_loop = true, @@ -389,28 +253,13 @@ init_flags!( bluetooth_quality_report_callback = true, set_min_encryption = true, subrating = true, - trigger_advertising_callbacks_on_first_resume_after_pause = true, use_unified_connection_manager, sdp_return_classic_services_when_le_discovery_fails = true, use_rsi_from_cached_inqiry_results = false, att_mtu_default: i32 = 517, encryption_in_busy_state = true, } - // dynamic flags can be updated at runtime and should be accessed directly - // to check. - dynamic_flags: { - default_log_level : i32 = LOG_TAG_INFO, - } - // extra_fields are not a 1 to 1 match with "INIT_*" flags - extra_fields: { - logging_explicit_tag_settings: ExplicitTagSettings, - } extra_parsed_flags: { - "INIT_default_log_level_str" => parse_log_level(_, _), - "INIT_log_level_for_tags" => parse_logging_tag(_, _), - "INIT_logging_debug_enabled_for_all" => deprecated_set_debug_logging_enabled_for_all(_, _), - "INIT_logging_debug_enabled_for_tags" => parse_debug_logging_tag(_, _, true), - "INIT_logging_debug_disabled_for_tags" => parse_debug_logging_tag(_, _, false), "--hci" => parse_hci_adapter(_, _), } dependencies: { @@ -435,9 +284,6 @@ pub fn load(raw_flags: Vec) { let flags = InitFlags::parse(raw_flags); info!("Flags loaded: {}", flags); *FLAGS.lock().unwrap() = flags; - - // re-init to respect log levels set by flags - crate::init_logging(); } /// Dumps all flag K-V pairs, storing values as strings @@ -488,29 +334,6 @@ mod tests { assert_eq!(get_hci_adapter(), 2); } #[test] - fn explicit_flag() { - let _guard = ASYNC_LOCK.lock().unwrap(); - test_load(vec![ - "INIT_default_log_level_str=LOG_VERBOSE", - "INIT_logging_debug_enabled_for_tags=foo,bar", - "INIT_logging_debug_disabled_for_tags=foo,bar2,fizz", - "INIT_logging_debug_enabled_for_tags=bar2", - "INIT_log_level_for_tags=fizz:LOG_WARN,buzz:LOG_NOTICE", - ]); - - assert!(get_log_level_for_tag("foo") == LOG_TAG_INFO); - assert!(get_log_level_for_tag("bar") == LOG_TAG_VERBOSE); - assert!(get_log_level_for_tag("bar2") == LOG_TAG_VERBOSE); - assert!(get_log_level_for_tag("unknown_flag") == LOG_TAG_VERBOSE); - assert!(get_default_log_level() == LOG_TAG_VERBOSE); - FLAGS.lock().unwrap().default_log_level = LOG_TAG_INFO; - assert!(get_log_level_for_tag("foo") == LOG_TAG_INFO); - assert!(get_log_level_for_tag("bar") == LOG_TAG_VERBOSE); - assert!(get_log_level_for_tag("bar2") == LOG_TAG_VERBOSE); - assert!(get_log_level_for_tag("unknown_flag") == LOG_TAG_INFO); - assert!(get_default_log_level() == LOG_TAG_INFO); - } - #[test] fn test_redact_logging() { let _guard = ASYNC_LOCK.lock().unwrap(); assert!(redact_log_is_enabled()); // default is true @@ -521,63 +344,23 @@ mod tests { test_load(vec!["INIT_redact_log=true"]); assert!(redact_log_is_enabled()); // turned on } - #[test] - fn test_runtime_update() { - let _guard = ASYNC_LOCK.lock().unwrap(); - test_load(vec!["INIT_private_gatt=true", "INIT_default_log_level_str=LOG_WARN"]); - assert!(private_gatt_is_enabled()); - assert!(get_default_log_level() == LOG_TAG_WARN); - - update_default_log_level(LOG_TAG_DEBUG); - assert!(get_default_log_level() == LOG_TAG_DEBUG); - update_default_log_level(LOG_TAG_ERROR); - assert!(get_default_log_level() == LOG_TAG_ERROR); - } - #[test] - fn test_default_log_level() { - // Default log level can be provided via int value or string. - // The string version is just for ease-of-use. - let _guard = ASYNC_LOCK.lock().unwrap(); - test_load(vec!["INIT_default_log_level=1"]); - assert!(get_default_log_level() == LOG_TAG_ERROR); - test_load(vec!["INIT_default_log_level_str=LOG_VERBOSE"]); - assert!(get_default_log_level() == LOG_TAG_VERBOSE); - test_load(vec!["INIT_default_log_level_str=LOG_VERBOSE", "INIT_default_log_level=0"]); - assert!(get_default_log_level() == LOG_TAG_FATAL); - } - #[test] - fn test_deprecated_logging_flag() { - let _guard = ASYNC_LOCK.lock().unwrap(); - test_load(vec!["INIT_default_log_level_str=1", "INIT_logging_debug_enabled_for_all=true"]); - assert!(get_default_log_level() == LOG_TAG_VERBOSE); - test_load(vec!["INIT_logging_debug_enabled_for_all=false"]); - assert!(get_default_log_level() == LOG_TAG_INFO); - } init_flags_struct!( name: InitFlagsForTest flags: { cat, } - dynamic_flags: { - dog: i32 = 8, - } - extra_fields: { - elephant: String, - } extra_parsed_flags: {} dependencies: {} ); #[test] fn test_dumpsys() { - let flags = InitFlagsForTest { dog: 3, elephant: "Go bears!".into(), ..Default::default() }; + let flags = InitFlagsForTest { ..Default::default() }; let out = flags.dump(); - assert_eq!(out.len(), 3); + assert_eq!(out.len(), 1); assert_eq!(out["cat"], "false"); - assert_eq!(out["dog"], "3"); - assert_eq!(out["elephant"], "Go bears!"); } } diff --git a/system/gd/rust/common/src/logging.rs b/system/gd/rust/common/src/logging.rs index d51e5b3b66bf87d156568c2f30db9ea75da8da9f..4207114d92ac37fdf1f49928b853dda6c09b2377 100644 --- a/system/gd/rust/common/src/logging.rs +++ b/system/gd/rust/common/src/logging.rs @@ -1,37 +1,11 @@ -use crate::init_flags::{ - get_log_level_for_tag, LOG_TAG_DEBUG, LOG_TAG_ERROR, LOG_TAG_FATAL, LOG_TAG_INFO, - LOG_TAG_NOTICE, LOG_TAG_VERBOSE, LOG_TAG_WARN, -}; - -fn get_log_level() -> log::Level { - match get_log_level_for_tag("bluetooth_core") { - LOG_TAG_FATAL => log::Level::Error, - LOG_TAG_ERROR => log::Level::Error, - LOG_TAG_WARN => log::Level::Warn, - LOG_TAG_NOTICE => log::Level::Info, - LOG_TAG_INFO => log::Level::Info, - LOG_TAG_DEBUG => log::Level::Debug, - LOG_TAG_VERBOSE => log::Level::Trace, - _ => log::Level::Info, // default level - } -} - /// Inits logging for Android #[cfg(target_os = "android")] pub fn init_logging() { - android_logger::init_once( - android_logger::Config::default().with_tag("bt").with_min_level(get_log_level()), - ); - log::set_max_level(get_log_level().to_level_filter()) + android_logger::init_once(android_logger::Config::default().with_tag("bt")); } /// Inits logging for host #[cfg(not(target_os = "android"))] pub fn init_logging() { - env_logger::Builder::new() - .filter(None, get_log_level().to_level_filter()) - .parse_default_env() - .try_init() - .ok(); - log::set_max_level(get_log_level().to_level_filter()) + env_logger::Builder::new().parse_default_env().try_init().ok(); } diff --git a/system/gd/rust/facade/Cargo.toml b/system/gd/rust/facade/Cargo.toml index 9055002293c4cdd6c0954632aa7d3ac49bd03032..d806e12f0e18445d2e6004836bc60d41a753e18e 100644 --- a/system/gd/rust/facade/Cargo.toml +++ b/system/gd/rust/facade/Cargo.toml @@ -27,9 +27,9 @@ bt_packets = { path = "../packets" } bytes = "1.0" cxx = "1.0" futures = "0.3" -grpcio = "0.9" +grpcio = { version = "0.13.0", default-features = false, features = ["protobufv3-codec", "openssl"] } log = "0.4" -protobuf = "2.0" +protobuf = "3.2" tokio = "1.0" # Binary-only deps diff --git a/system/gd/rust/facade/helpers/Cargo.toml b/system/gd/rust/facade/helpers/Cargo.toml index 6d0de0562cc74fe7824d85c19f24e5511e25bef3..bd66f599566172e4d6eca317282941c3b92ece11 100644 --- a/system/gd/rust/facade/helpers/Cargo.toml +++ b/system/gd/rust/facade/helpers/Cargo.toml @@ -26,9 +26,9 @@ bt_facade_proto = { path = "../../facade_proto" } bytes = "1.0" cxx = "1.0" futures = "0.3" -grpcio = "0.9" +grpcio = { version = "0.13.0", default-features = false, features = ["protobufv3-codec", "openssl"] } log = "0.4" -protobuf = "2.0" +protobuf = "3.2" tokio = "1.0" [lib] diff --git a/system/gd/rust/facade_proto/Cargo.toml b/system/gd/rust/facade_proto/Cargo.toml index bac110f3935f03761a6f16cc76ec6938333eb4ee..f43206af1d8278e5dd0a6e3c6a5d5db9ad3f2ea5 100644 --- a/system/gd/rust/facade_proto/Cargo.toml +++ b/system/gd/rust/facade_proto/Cargo.toml @@ -21,13 +21,13 @@ build = "build.rs" [dependencies] futures = "0.3" -grpcio = "0.9" -protobuf = "2.0" +grpcio = { version = "0.13.0", default-features = false, features = ["protobufv3-codec", "openssl"] } +protobuf = "3.2" [build-dependencies] -protoc-rust = "2.0" -protoc-grpcio = "2.0" -protobuf-codegen = "2.0" +anyhow = "1" +grpcio-compiler = "0.13" +protobuf-codegen = "3.2" [lib] crate-types = ["rlib"] diff --git a/system/gd/rust/facade_proto/build.rs b/system/gd/rust/facade_proto/build.rs index 87b9fe6d63e47737189476ba5089616d597a266a..eeac4af56070e777ef66a3e352201b1dd3107da6 100644 --- a/system/gd/rust/facade_proto/build.rs +++ b/system/gd/rust/facade_proto/build.rs @@ -17,6 +17,10 @@ use std::env; use std::fs; use std::io::Write; use std::path::{Path, PathBuf}; +use std::process; +use std::process::Command; + +extern crate grpcio_compiler; fn paths_to_strs>(paths: &[P]) -> Vec<&str> { paths.iter().map(|p| p.as_ref().as_os_str().to_str().unwrap()).collect() @@ -38,6 +42,20 @@ fn gen_mod_rs>(out_dir: PathBuf, inputs: &[P], grpc: bool) { } } +fn exec(c: &mut Command) { + match c.status() { + Err(e) => { + eprintln!("failed to execute {:?}: {}", c, e); + process::exit(-1); + } + Ok(s) => { + if !s.success() { + process::exit(s.code().unwrap_or(-1)); + } + } + } +} + fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let proto_out_dir = out_dir.join("proto_out"); @@ -70,13 +88,14 @@ fn main() { let proto_input_files = [facade_dir.join("common.proto")]; let proto_include_dirs = [facade_dir.clone()]; - protoc_rust::Codegen::new() + protobuf_codegen::Codegen::new() + .protoc() .out_dir(proto_out_dir.as_os_str().to_str().unwrap()) .inputs(&paths_to_strs(&proto_input_files)) .includes(&paths_to_strs(&proto_include_dirs)) .customize(Default::default()) .run() - .expect("protoc"); + .expect("Common protos failed to generate"); // // Generate grpc output @@ -90,13 +109,33 @@ fn main() { 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, - &grpc_proto_include_dirs, - &grpc_out_dir, - None, - ) - .expect("Failed to compile gRPC definitions"); + // Generate protobuf files first + protobuf_codegen::Codegen::new() + .protoc() + .out_dir(&grpc_out_dir.as_os_str().to_str().unwrap()) + .inputs(&paths_to_strs(&grpc_proto_input_files)) + .includes(&paths_to_strs(&grpc_proto_include_dirs)) + .customize(Default::default()) + .run() + .expect("Facade protos failed to generate"); + + // Invoke protoc directly to generate grpcio. + let mut c = Command::new("protoc"); + // Include dirs + for inc in &grpc_proto_include_dirs { + c.arg(format!("-I{}", &inc.as_os_str().to_str().unwrap())); + } + // Output dir + c.arg(format!("--grpc_out={}", &grpc_out_dir.as_os_str().to_str().unwrap())); + // Plugin location + let grpc_rust_plugin_path = std::env::var_os("GRPC_RUST_PLUGIN_PATH").unwrap(); + c.arg(format!("--plugin=protoc-gen-grpc={}", grpc_rust_plugin_path.into_string().unwrap())); + // Input files + for input in &grpc_proto_input_files { + c.arg(input); + } + + exec(&mut c); gen_mod_rs(proto_out_dir, &proto_input_files, false); gen_mod_rs(grpc_out_dir, &grpc_proto_input_files, true); diff --git a/system/gd/rust/linux/client/src/bt_gatt.rs b/system/gd/rust/linux/client/src/bt_gatt.rs index f90216381d354d6ab707cd8ac2416922e8a0ad8f..a8ac8df1c93a7ee82c7d9872fae8e854b066189c 100644 --- a/system/gd/rust/linux/client/src/bt_gatt.rs +++ b/system/gd/rust/linux/client/src/bt_gatt.rs @@ -50,3 +50,17 @@ impl GattClientContext { self.auth_req } } + +/// User preference of GATT server operations +pub(crate) struct GattServerContext { + /// Is connection going to be directed? + pub(crate) is_connect_direct: bool, + /// Transport of connection + pub(crate) connect_transport: BtTransport, +} + +impl GattServerContext { + pub(crate) fn new() -> Self { + GattServerContext { is_connect_direct: false, connect_transport: BtTransport::Le } + } +} diff --git a/system/gd/rust/linux/client/src/callbacks.rs b/system/gd/rust/linux/client/src/callbacks.rs index ca73daa1882b21dc34e4b8c3faf9ab032e6ad372..749aba4302368ed652fa192f02d0507e81c6e09f 100644 --- a/system/gd/rust/linux/client/src/callbacks.rs +++ b/system/gd/rust/linux/client/src/callbacks.rs @@ -1,12 +1,12 @@ use crate::command_handler::SocketSchedule; use crate::dbus_iface::{ export_admin_policy_callback_dbus_intf, export_advertising_set_callback_dbus_intf, - export_bluetooth_callback_dbus_intf, export_bluetooth_connection_callback_dbus_intf, - export_bluetooth_gatt_callback_dbus_intf, export_bluetooth_manager_callback_dbus_intf, - export_bluetooth_media_callback_dbus_intf, export_bluetooth_telephony_callback_dbus_intf, - export_gatt_server_callback_dbus_intf, export_qa_callback_dbus_intf, - export_scanner_callback_dbus_intf, export_socket_callback_dbus_intf, - export_suspend_callback_dbus_intf, + export_battery_manager_callback_dbus_intf, export_bluetooth_callback_dbus_intf, + export_bluetooth_connection_callback_dbus_intf, export_bluetooth_gatt_callback_dbus_intf, + export_bluetooth_manager_callback_dbus_intf, export_bluetooth_media_callback_dbus_intf, + export_bluetooth_telephony_callback_dbus_intf, export_gatt_server_callback_dbus_intf, + export_qa_callback_dbus_intf, export_scanner_callback_dbus_intf, + export_socket_callback_dbus_intf, export_suspend_callback_dbus_intf, }; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; @@ -14,6 +14,7 @@ use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant, BtStatus, Uuid use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy}; use bt_topshim::profiles::hfp::HfpCodecId; use bt_topshim::profiles::sdp::BtSdpRecord; +use btstack::battery_manager::{BatterySet, IBatteryManagerCallback}; use btstack::bluetooth::{ BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, }; @@ -1468,3 +1469,63 @@ impl RPCProxy for TelephonyCallback { cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self))); } } + +pub(crate) struct BatteryManagerCallback { + objpath: String, + context: Arc>, + + dbus_connection: Arc, + dbus_crossroads: Arc>, +} + +impl BatteryManagerCallback { + pub(crate) fn new( + objpath: String, + context: Arc>, + dbus_connection: Arc, + dbus_crossroads: Arc>, + ) -> Self { + Self { objpath, context, dbus_connection, dbus_crossroads } + } +} + +impl IBatteryManagerCallback for BatteryManagerCallback { + fn on_battery_info_updated(&mut self, remote_address: String, battery_set: BatterySet) { + let address = remote_address.to_uppercase(); + if self.context.lock().unwrap().battery_address_filter.contains(&address) { + if battery_set.batteries.len() == 0 { + print_info!( + "Battery info for address '{}' updated with empty battery set. \ + The batteries for this device may have been removed.", + address.clone() + ); + return; + } + print_info!( + "Battery data for '{}' from source '{}' and uuid '{}' changed to:", + address.clone(), + battery_set.source_uuid.clone(), + battery_set.source_info.clone() + ); + for battery in battery_set.batteries { + print_info!(" {}%, variant: '{}'", battery.percentage, battery.variant); + } + } + } +} + +impl RPCProxy for BatteryManagerCallback { + fn get_object_id(&self) -> String { + self.objpath.clone() + } + + fn export_for_rpc(self: Box) { + let cr = self.dbus_crossroads.clone(); + let iface = export_battery_manager_callback_dbus_intf( + self.dbus_connection.clone(), + &mut cr.lock().unwrap(), + Arc::new(Mutex::new(DisconnectWatcher::new())), + ); + cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self))); + } +} diff --git a/system/gd/rust/linux/client/src/command_handler.rs b/system/gd/rust/linux/client/src/command_handler.rs index 262ee4a604f831427c39bb539e2e00a548112670..1a959752e3d69588301c8f1820f74c0871454f2b 100644 --- a/system/gd/rust/linux/client/src/command_handler.rs +++ b/system/gd/rust/linux/client/src/command_handler.rs @@ -9,12 +9,15 @@ use crate::bt_gatt::AuthReq; use crate::callbacks::{BtGattCallback, BtGattServerCallback}; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; -use bt_topshim::btif::{BtConnectionState, BtDiscMode, BtStatus, BtTransport, INVALID_RSSI}; +use bt_topshim::btif::{BtConnectionState, BtDiscMode, BtStatus, BtTransport, Uuid, INVALID_RSSI}; use bt_topshim::profiles::hid_host::BthhReportType; use bt_topshim::profiles::sdp::{BtSdpMpsRecord, BtSdpRecord}; use bt_topshim::profiles::{gatt::LePhy, ProfileConnectionState}; +use btstack::battery_manager::IBatteryManager; use btstack::bluetooth::{BluetoothDevice, IBluetooth}; -use btstack::bluetooth_gatt::{GattWriteType, IBluetoothGatt}; +use btstack::bluetooth_gatt::{ + BluetoothGattService, GattDbElementType, GattWriteType, IBluetoothGatt, +}; use btstack::bluetooth_media::{IBluetoothMedia, IBluetoothTelephony}; use btstack::bluetooth_qa::IBluetoothQA; use btstack::socket_manager::{IBluetoothSocketManager, SocketResult}; @@ -27,6 +30,7 @@ const BAR2_CHAR: &str = "-"; const MAX_MENU_CHAR_WIDTH: usize = 72; const GATT_CLIENT_APP_UUID: &str = "12345678123456781234567812345678"; const GATT_SERVER_APP_UUID: &str = "12345678123456781234567812345679"; +const HEART_RATE_SERVICE_UUID: &str = "0000180D-0000-1000-8000-00805F9B34FB"; enum CommandError { // Command not handled due to invalid arguments. @@ -138,6 +142,24 @@ fn build_commands() -> HashMap { function_pointer: CommandHandler::cmd_adapter, }, ); + command_options.insert( + String::from("battery"), + CommandOption { + rules: vec![ + String::from("battery status
"), + String::from("battery track
"), + String::from("battery untrack
"), + ], + description: String::from( + " + status: Current battery status of a given device.\n + track: Track a given device to monitor battery updates.\n + untrack: Stop tracking a device for battery updates. + ", + ), + function_pointer: CommandHandler::cmd_battery, + }, + ); command_options.insert( String::from("bond"), CommandOption { @@ -202,6 +224,14 @@ fn build_commands() -> HashMap { ), String::from("gatt register-notification
"), String::from("gatt register-server"), + String::from("gatt unregister-server "), + String::from("gatt server-connect "), + String::from("gatt server-disconnect "), + String::from("gatt server-add-heartrate-service "), + String::from("gatt server-remove-service "), + String::from("gatt server-clear-all-services "), + String::from("gatt server-set-direct-connect "), + String::from("gatt server-set-connect-transport "), ], description: String::from("GATT tools"), function_pointer: CommandHandler::cmd_gatt, @@ -641,6 +671,79 @@ impl CommandHandler { Ok(()) } + fn cmd_battery(&mut self, args: &Vec) -> CommandResult { + if !self.lock_context().adapter_ready { + return Err(self.adapter_not_ready()); + } + + let command = get_arg(args, 0)?; + let address = get_arg(args, 1)?.to_uppercase(); + + match &command[..] { + "status" => { + match self + .lock_context() + .battery_manager_dbus + .as_ref() + .unwrap() + .get_battery_information(address.clone()) + { + None => println!( + "Battery status for device {} could not be fetched", + address.clone() + ), + Some(set) => { + if set.batteries.len() == 0 { + println!("Battery set for device {} is empty", set.address.clone()); + return Ok(()); + } + + println!( + "Battery data for '{}' from source '{}' and uuid '{}':", + set.address.clone(), + set.source_uuid.clone(), + set.source_info.clone() + ); + for battery in set.batteries { + println!(" {}%, variant: '{}'", battery.percentage, battery.variant); + } + } + } + } + "track" => { + if self.lock_context().battery_address_filter.contains(&address) { + println!("Already tracking {}", address.clone()); + return Ok(()); + } + self.lock_context().battery_address_filter.insert(address.clone()); + + println!("Currently tracking:"); + for addr in self.lock_context().battery_address_filter.iter() { + println!("{}", addr); + } + } + "untrack" => { + if !self.lock_context().battery_address_filter.remove(&address) { + println!("Not tracking {}", address.clone()); + return Ok(()); + } + println!("Stopped tracking {}", address.clone()); + + if self.lock_context().battery_address_filter.len() == 0 { + println!("No longer tracking any addresses for battery status updates"); + return Ok(()); + } + + println!("Currently tracking:"); + for addr in self.lock_context().battery_address_filter.iter() { + println!("{}", addr); + } + } + _ => return Err(CommandError::InvalidArgs), + } + Ok(()) + } + fn cmd_bond(&mut self, args: &Vec) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); @@ -1223,6 +1326,98 @@ impl CommandHandler { false, ); } + "unregister-server" => { + let server_id = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed parsing server id"))?; + + self.lock_context().gatt_dbus.as_mut().unwrap().unregister_server(server_id); + } + "server-connect" => { + let server_id = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed to parse server_id"))?; + let client_addr = String::from(get_arg(args, 2)?); + let is_direct = self.lock_context().gatt_server_context.is_connect_direct; + let transport = self.lock_context().gatt_server_context.connect_transport; + + if !self.lock_context().gatt_dbus.as_mut().unwrap().server_connect( + server_id, + client_addr.clone(), + is_direct, + transport, + ) { + return Err("Connection was unsuccessful".into()); + } + } + "server-disconnect" => { + let server_id = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed to parse server_id"))?; + let client_addr = String::from(get_arg(args, 2)?); + + if !self + .lock_context() + .gatt_dbus + .as_mut() + .unwrap() + .server_disconnect(server_id, client_addr.clone()) + { + return Err("Disconnection was unsuccessful".into()); + } + } + "server-add-heartrate-service" => { + let uuid = Uuid::from(UuidHelper::from_string(HEART_RATE_SERVICE_UUID).unwrap()); + + let server_id = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed to parse server_id"))?; + let service = BluetoothGattService::new( + uuid.into(), + 0, // libbluetooth assigns this handle once the service is added + GattDbElementType::PrimaryService.into(), + ); + + self.lock_context().gatt_dbus.as_mut().unwrap().add_service(server_id, service); + } + "server-remove-service" => { + let server_id = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed to parse server_id"))?; + let service_handle = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed to parse service handle"))?; + + self.lock_context() + .gatt_dbus + .as_mut() + .unwrap() + .remove_service(server_id, service_handle); + } + "server-clear-all-services" => { + let server_id = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed to parse server_id"))?; + self.lock_context().gatt_dbus.as_mut().unwrap().clear_services(server_id); + } + "server-set-direct-connect" => { + let is_direct = String::from(get_arg(args, 1)?) + .parse::() + .or(Err("Failed to parse is_direct"))?; + + self.lock_context().gatt_server_context.is_connect_direct = is_direct; + } + "server-set-connect-transport" => { + let transport = match &get_arg(args, 1)?[..] { + "Bredr" => BtTransport::Bredr, + "LE" => BtTransport::Le, + "Auto" => BtTransport::Auto, + _ => { + return Err("Failed to parse transport".into()); + } + }; + self.lock_context().gatt_server_context.connect_transport = transport; + } _ => return Err(CommandError::InvalidArgs), } Ok(()) diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index ebee9c011ccd93aef9468110e2bef2e1b0d53e86..fb392a3795952b79ac27398373a04b7259bd9da2 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -10,7 +10,7 @@ use bt_topshim::profiles::a2dp::{ }; use bt_topshim::profiles::avrcp::PlayerMetadata; use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy}; -use bt_topshim::profiles::hfp::HfpCodecCapability; +use bt_topshim::profiles::hfp::{EscoCodingFormat, HfpCodecBitId, HfpCodecFormat}; use bt_topshim::profiles::hid_host::BthhReportType; use bt_topshim::profiles::sdp::{ BtSdpDipRecord, BtSdpHeaderOverlay, BtSdpMasRecord, BtSdpMnsRecord, BtSdpMpsRecord, @@ -20,8 +20,9 @@ use bt_topshim::profiles::sdp::{ use bt_topshim::profiles::socket::SocketType; use bt_topshim::profiles::ProfileConnectionState; +use btstack::battery_manager::{Battery, BatterySet, IBatteryManager, IBatteryManagerCallback}; use btstack::bluetooth::{ - BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, + BluetoothDevice, BtAdapterRole, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, IBluetoothQALegacy, }; use btstack::bluetooth_admin::{IBluetoothAdmin, IBluetoothAdminPolicyCallback, PolicyEffect}; @@ -95,6 +96,7 @@ impl_dbus_arg_enum!(SuspendMode); impl_dbus_arg_enum!(SuspendType); impl_dbus_arg_from_into!(Uuid, Vec); impl_dbus_arg_enum!(BthhReportType); +impl_dbus_arg_enum!(BtAdapterRole); impl RefArgToRust for Uuid { type RustType = Vec; @@ -433,13 +435,16 @@ impl_dbus_arg_from_into!(A2dpCodecSampleRate, i32); impl_dbus_arg_from_into!(A2dpCodecBitsPerSample, i32); impl_dbus_arg_from_into!(A2dpCodecChannelMode, i32); -impl_dbus_arg_from_into!(HfpCodecCapability, i32); +impl_dbus_arg_from_into!(EscoCodingFormat, u8); +impl_dbus_arg_from_into!(HfpCodecBitId, i32); +impl_dbus_arg_from_into!(HfpCodecFormat, i32); + #[dbus_propmap(BluetoothAudioDevice)] pub struct BluetoothAudioDeviceDBus { address: String, name: String, a2dp_caps: Vec, - hfp_cap: HfpCodecCapability, + hfp_cap: HfpCodecFormat, absolute_volume: bool, } @@ -994,6 +999,16 @@ impl IBluetooth for BluetoothDBus { fn is_swb_supported(&self) -> bool { dbus_generated!() } + + #[dbus_method("GetSupportedRoles")] + fn get_supported_roles(&self) -> Vec { + dbus_generated!() + } + + #[dbus_method("IsCodingFormatSupported")] + fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool { + dbus_generated!() + } } pub(crate) struct BluetoothQALegacyDBus { @@ -2649,7 +2664,7 @@ impl IBluetoothMedia for BluetoothMediaDBus { &mut self, address: String, sco_offload: bool, - disabled_codecs: HfpCodecCapability, + disabled_codecs: HfpCodecBitId, ) -> bool { dbus_generated!() } @@ -2734,3 +2749,80 @@ impl IBluetoothMediaCallback for IBluetoothMediaCallbackDBus { ) { } } + +pub(crate) struct BatteryManagerDBusRPC { + client_proxy: ClientDBusProxy, +} + +pub(crate) struct BatteryManagerDBus { + client_proxy: ClientDBusProxy, + pub rpc: BatteryManagerDBusRPC, +} + +impl BatteryManagerDBus { + fn make_client_proxy(conn: Arc, index: i32) -> ClientDBusProxy { + ClientDBusProxy::new( + conn.clone(), + String::from("org.chromium.bluetooth"), + make_object_path(index, "battery_manager"), + String::from("org.chromium.bluetooth.BatteryManager"), + ) + } + + pub(crate) fn new(conn: Arc, index: i32) -> BatteryManagerDBus { + BatteryManagerDBus { + client_proxy: Self::make_client_proxy(conn.clone(), index), + rpc: BatteryManagerDBusRPC { + client_proxy: Self::make_client_proxy(conn.clone(), index), + }, + } + } +} + +#[generate_dbus_interface_client(BatteryManagerDBusRPC)] +impl IBatteryManager for BatteryManagerDBus { + #[dbus_method("RegisterBatteryCallback")] + fn register_battery_callback( + &mut self, + battery_manager_callback: Box, + ) -> u32 { + dbus_generated!() + } + + #[dbus_method("UnregisterBatteryCallback")] + fn unregister_battery_callback(&mut self, callback_id: u32) -> bool { + dbus_generated!() + } + + #[dbus_method("GetBatteryInformation")] + fn get_battery_information(&self, remote_address: String) -> Option { + dbus_generated!() + } +} + +#[dbus_propmap(BatterySet)] +pub struct BatterySetDBus { + address: String, + source_uuid: String, + source_info: String, + batteries: Vec, +} + +#[dbus_propmap(Battery)] +pub struct BatteryDBus { + percentage: u32, + variant: String, +} + +struct IBatteryManagerCallbackDBus {} + +impl RPCProxy for IBatteryManagerCallbackDBus {} + +#[generate_dbus_exporter( + export_battery_manager_callback_dbus_intf, + "org.chromium.bluetooth.BatteryManagerCallback" +)] +impl IBatteryManagerCallback for IBatteryManagerCallbackDBus { + #[dbus_method("OnBatteryInfoUpdated")] + fn on_battery_info_updated(&mut self, remote_address: String, battery_set: BatterySet) {} +} diff --git a/system/gd/rust/linux/client/src/main.rs b/system/gd/rust/linux/client/src/main.rs index 5793cc16f1d56df5b28a7d1ea521d60d7eb99a30..eafaa8ae1d1137bf467973354b53c89e4cc2567d 100644 --- a/system/gd/rust/linux/client/src/main.rs +++ b/system/gd/rust/linux/client/src/main.rs @@ -12,17 +12,17 @@ use tokio::sync::mpsc; use tokio::time::{sleep, timeout}; use crate::bt_adv::AdvSet; -use crate::bt_gatt::GattClientContext; +use crate::bt_gatt::{GattClientContext, GattServerContext}; use crate::callbacks::{ - AdminCallback, AdvertisingSetCallback, BtCallback, BtConnectionCallback, BtManagerCallback, - BtSocketManagerCallback, MediaCallback, QACallback, ScannerCallback, SuspendCallback, - TelephonyCallback, + AdminCallback, AdvertisingSetCallback, BatteryManagerCallback, BtCallback, + BtConnectionCallback, BtManagerCallback, BtSocketManagerCallback, MediaCallback, QACallback, + ScannerCallback, SuspendCallback, TelephonyCallback, }; use crate::command_handler::{CommandHandler, SocketSchedule}; use crate::dbus_iface::{ - BluetoothAdminDBus, BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, BluetoothMediaDBus, - BluetoothQADBus, BluetoothQALegacyDBus, BluetoothSocketManagerDBus, BluetoothTelephonyDBus, - SuspendDBus, + BatteryManagerDBus, BluetoothAdminDBus, BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, + BluetoothMediaDBus, BluetoothQADBus, BluetoothQALegacyDBus, BluetoothSocketManagerDBus, + BluetoothTelephonyDBus, SuspendDBus, }; use crate::editor::AsyncEditor; use bt_topshim::topstack; @@ -102,6 +102,9 @@ pub(crate) struct ClientContext { /// Proxy for Media interface. pub(crate) media_dbus: Option, + /// Proxy for battery manager interface. + pub(crate) battery_manager_dbus: Option, + /// Channel to send actions to take in the foreground fg: mpsc::Sender, @@ -138,6 +141,9 @@ pub(crate) struct ClientContext { /// Data of GATT client preference. gatt_client_context: GattClientContext, + /// Data of GATT server preference. + gatt_server_context: GattServerContext, + /// The schedule when a socket is connected. socket_test_schedule: Option, @@ -146,6 +152,9 @@ pub(crate) struct ClientContext { /// The set of client commands that need to wait for callbacks. client_commands_with_callbacks: Vec, + + /// A set of addresses whose battery changes are being tracked. + pub(crate) battery_address_filter: HashSet, } impl ClientContext { @@ -180,6 +189,7 @@ impl ClientContext { socket_manager_dbus: None, telephony_dbus: None, media_dbus: None, + battery_manager_dbus: None, fg: tx, dbus_connection, dbus_crossroads, @@ -192,9 +202,11 @@ impl ClientContext { qa_callback_id: None, is_restricted, gatt_client_context: GattClientContext::new(), + gatt_server_context: GattServerContext::new(), socket_test_schedule: None, mps_sdp_handle: None, client_commands_with_callbacks, + battery_address_filter: HashSet::new(), } } @@ -243,6 +255,8 @@ impl ClientContext { self.media_dbus = Some(BluetoothMediaDBus::new(conn.clone(), idx)); + self.battery_manager_dbus = Some(BatteryManagerDBus::new(conn.clone(), idx)); + // Trigger callback registration in the foreground let fg = self.fg.clone(); tokio::spawn(async move { @@ -548,6 +562,8 @@ async fn handle_client_command( "/org/chromium/bluetooth/client/{}/bluetooth_telephony_callback", adapter ); + let battery_cb_objpath: String = + format!("/org/chromium/bluetooth/client/{}/battery_manager_callback", adapter); let dbus_connection = context.lock().unwrap().dbus_connection.clone(); let dbus_crossroads = context.lock().unwrap().dbus_crossroads.clone(); @@ -711,6 +727,22 @@ async fn handle_client_command( .await .expect("D-Bus error on IBluetoothMedia::RegisterTelephonyCallback"); + context + .lock() + .unwrap() + .battery_manager_dbus + .as_mut() + .unwrap() + .rpc + .register_battery_callback(Box::new(BatteryManagerCallback::new( + battery_cb_objpath, + context.clone(), + dbus_connection.clone(), + dbus_crossroads.clone(), + ))) + .await + .expect("D-Bus error on IBatteryManagerDBus::RegisterBatteryCallback"); + context.lock().unwrap().adapter_ready = true; let adapter_address = context.lock().unwrap().update_adapter_address(); context.lock().unwrap().update_bonded_devices(); diff --git a/system/gd/rust/linux/mgmt/Cargo.toml b/system/gd/rust/linux/mgmt/Cargo.toml index 042b25b00177e91392908e2d1464d20ec92798c6..ca38dd178ff88a49c14da84c8321f49f5da5da60 100644 --- a/system/gd/rust/linux/mgmt/Cargo.toml +++ b/system/gd/rust/linux/mgmt/Cargo.toml @@ -32,6 +32,7 @@ regex = "1.5" serde_json = "1.0" syslog = "6" tokio = { version = "1.0", features = ["fs", "macros", "rt-multi-thread", "sync"] } +libc = "0.2" [build-dependencies] pkg-config = "0.3.19" diff --git a/system/gd/rust/linux/mgmt/src/migrate.rs b/system/gd/rust/linux/mgmt/src/migrate.rs index efecc7c24ce7e99fea89c4258447f443d7c778e9..d37fe56a3bdbec094b01aa2e0a1388d9e619d4c1 100644 --- a/system/gd/rust/linux/mgmt/src/migrate.rs +++ b/system/gd/rust/linux/mgmt/src/migrate.rs @@ -11,7 +11,6 @@ //! all others use std::collections::HashMap; -use std::convert::{TryFrom, TryInto}; use std::fs; use std::path::Path; @@ -29,14 +28,15 @@ const LINKKEY_SECTION_NAME: &str = "LinkKey"; const DEVICEID_SECTION_NAME: &str = "DeviceID"; const IRK_SECTION_NAME: &str = "IdentityResolvingKey"; const LTK_SECTION_NAME: &str = "LongTermKey"; +const BLUEZ_PERIPHERAL_LTK_SECTION_NAME: &str = "PeripheralLongTermKey"; +const BLUEZ_LOCAL_LTK_SECTION_NAME: &str = "SlaveLongTermKey"; const REPORT_MAP_SECTION_NAME: &str = "ReportMap"; const CLASSIC_TYPE: &str = "BR/EDR;"; const LE_TYPE: &str = "LE;"; const DUAL_TYPE: &str = "BR/EDR;LE;"; -/// Represents LTK info since in Floss, -/// LE_KEY_PENC = LTK + RAND (64) + EDIV (16) + Security Level (8) + Key Length (8) +/// Represents LTK info #[derive(Debug, Default)] struct LtkInfo { key: u128, @@ -46,12 +46,38 @@ struct LtkInfo { len: u8, } -impl TryFrom for LtkInfo { - type Error = &'static str; +impl LtkInfo { + fn new_from_bluez(bluez_conf: &Ini, sec: &str) -> Self { + LtkInfo { + key: u128::from_str_radix(bluez_conf.get(sec, "Key").unwrap_or_default().as_str(), 16) + .unwrap_or_default(), + rand: bluez_conf + .get(sec, "Rand") + .unwrap_or_default() + .parse::() + .unwrap_or_default(), + ediv: bluez_conf + .get(sec, "EDiv") + .unwrap_or_default() + .parse::() + .unwrap_or_default(), + auth: bluez_conf + .get(sec, "Authenticated") + .unwrap_or_default() + .parse::() + .unwrap_or_default(), + len: bluez_conf + .get(sec, "EncSize") + .unwrap_or_default() + .parse::() + .unwrap_or_default(), + } + } - fn try_from(val: String) -> Result { + // LE_KEY_PENC = LTK + RAND (64) + EDIV (16) + Security Level (8) + Key Length (8) + fn try_from_penc(val: String) -> Result { if val.len() != 56 { - return Err("String provided to LtkInfo is not the right size"); + return Err("PENC String provided to LtkInfo is not the right size"); } Ok(LtkInfo { @@ -62,12 +88,8 @@ impl TryFrom for LtkInfo { len: u8::from_str_radix(&val[54..56], 16).unwrap_or_default(), }) } -} - -impl TryInto for LtkInfo { - type Error = &'static str; - fn try_into(self) -> Result { + fn try_into_penc(self) -> Result { Ok(format!( "{:032x}{:016x}{:04x}{:02x}{:02x}", self.key, @@ -77,6 +99,31 @@ impl TryInto for LtkInfo { self.len )) } + + // LE_KEY_LENC = LTK + EDIV (16) + Key Size (8) + Security Level (8) + fn try_from_lenc(val: String) -> Result { + if val.len() != 40 { + return Err("LENC String provided to LtkInfo is not the right size"); + } + + Ok(LtkInfo { + key: u128::from_str_radix(&val[0..32], 16).unwrap_or_default(), + ediv: u16::from_str_radix(&val[32..36], 16).unwrap_or_default().swap_bytes(), + len: u8::from_str_radix(&val[36..38], 16).unwrap_or_default(), + auth: u8::from_str_radix(&val[38..40], 16).unwrap_or_default(), + rand: 0, + }) + } + + fn try_into_lenc(self) -> Result { + Ok(format!( + "{:032x}{:04x}{:02x}{:02x}", + self.key, + self.ediv.swap_bytes(), + self.len, + self.auth, + )) + } } /// Represents the different conversions that can be done on keys @@ -233,17 +280,7 @@ fn floss_to_bluez_addr_type(str: String) -> Result { // BlueZ stores link keys as little endian and Floss as big endian fn reverse_endianness(str: String, uppercase: bool) -> Result { - // Handling for LE_KEY_PID - // In Floss, LE_KEY_PID = IRK + Identity Address Type (8) + Identity Address - let mut len = 32; - if str.len() < len { - // Logging to observe crash behavior, can clean up and remove if not an error - warn!("Link key too small: {}", str); - len = str.len(); - } - let s = String::from(&str[0..len]); - - match u128::from_str_radix(&s, 16) { + match u128::from_str_radix(str.as_str(), 16) { Ok(x) => { if uppercase { Ok(format!("{:0>32X}", x.swap_bytes())) @@ -317,39 +354,23 @@ fn convert_from_bluez_device( ); true } - "PeripheralLongTermKey" | LTK_SECTION_NAME => { + BLUEZ_PERIPHERAL_LTK_SECTION_NAME | LTK_SECTION_NAME => { // Special handling since in Floss LE_KEY_PENC is a combination of values in BlueZ - let ltk = LtkInfo { - key: u128::from_str_radix( - bluez_conf.get(sec.as_str(), "Key").unwrap_or_default().as_str(), - 16, - ) - .unwrap_or_default(), - rand: bluez_conf - .get(sec.as_str(), "Rand") - .unwrap_or_default() - .parse::() - .unwrap_or_default(), - ediv: bluez_conf - .get(sec.as_str(), "EDiv") - .unwrap_or_default() - .parse::() - .unwrap_or_default(), - auth: bluez_conf - .get(sec.as_str(), "Authenticated") - .unwrap_or_default() - .parse::() - .unwrap_or_default(), - len: bluez_conf - .get(sec.as_str(), "EncSize") - .unwrap_or_default() - .parse::() - .unwrap_or_default(), - }; + let ltk: LtkInfo = LtkInfo::new_from_bluez(&bluez_conf, sec.as_str()); floss_conf.set( addr_lower.as_str(), "LE_KEY_PENC", - Some(ltk.try_into().unwrap_or_default()), + Some(ltk.try_into_penc().unwrap_or_default()), + ); + true + } + BLUEZ_LOCAL_LTK_SECTION_NAME => { + // Special handling since in Floss LE_KEY_LENC is a combination of values in BlueZ + let lltk: LtkInfo = LtkInfo::new_from_bluez(&bluez_conf, sec.as_str()); + floss_conf.set( + addr_lower.as_str(), + "LE_KEY_LENC", + Some(lltk.try_into_lenc().unwrap_or_default()), ); true } @@ -468,7 +489,7 @@ fn convert_from_bluez_device( return false; } }; - floss_conf.set(addr_lower.as_str(), key.key.clone(), Some(new_val)); + floss_conf.set(addr_lower.as_str(), key.key, Some(new_val)); } } None => { @@ -681,13 +702,6 @@ fn convert_floss_conf(filename: &str) { ("VendorId", DeviceKey::new("Vendor", KeyAction::ToSection(DEVICEID_SECTION_NAME))), ("ProductId", DeviceKey::new("Product", KeyAction::ToSection(DEVICEID_SECTION_NAME))), ("ProductVersion", DeviceKey::new("Version", KeyAction::ToSection(DEVICEID_SECTION_NAME))), - ( - "LE_KEY_PID", - DeviceKey::new( - "Key", - KeyAction::ApplyToSection(Converter::ReverseEndianUppercase, IRK_SECTION_NAME), - ), - ), ] .into(); @@ -718,19 +732,72 @@ fn convert_floss_conf(filename: &str) { } // Keep track of Floss devices we've seen so we can remove BlueZ devices that don't exist on Floss devices.push(sec.clone()); - let device_addr = sec.to_uppercase(); + let mut device_addr = sec.to_uppercase(); let mut bluez_info = Ini::new_cs(); let mut bluez_hid = Ini::new_cs(); let mut is_hid: bool = false; + let has_local_keys: bool = props.contains_key("LE_KEY_LENC"); for (k, v) in props { - // Special handling since in Floss LE_KEY_PENC is a combination of values in BlueZ - if k == "LE_KEY_PENC" { - let ltk = LtkInfo::try_from(v.unwrap_or_default()).unwrap_or_default(); - bluez_info.set(LTK_SECTION_NAME, "Key", Some(format!("{:032X}", ltk.key))); - bluez_info.set(LTK_SECTION_NAME, "Rand", Some(format!("{}", ltk.rand))); - bluez_info.set(LTK_SECTION_NAME, "EDiv", Some(format!("{}", ltk.ediv))); - bluez_info.set(LTK_SECTION_NAME, "Authenticated", Some(format!("{}", ltk.auth))); - bluez_info.set(LTK_SECTION_NAME, "EncSize", Some(format!("{}", ltk.len))); + // Special handling since in Floss LE_KEY_* are a combination of values in BlueZ + if k == "LE_KEY_PID" { + // In Floss, LE_KEY_PID = IRK (128) + Identity Address Type (8) + Identity Address (48) + // Identity Address Type is also found as "AddrType" key so no need to parse it here. + let val = v.unwrap_or_default(); + if val.len() != 46 { + warn!("LE_KEY_PID is not the correct size: {}", val); + continue; + } + bluez_info.set( + IRK_SECTION_NAME, + "Key", + Some(reverse_endianness(val[0..32].to_string(), true).unwrap_or_default()), + ); + // BlueZ uses the identity address as the device path + devices.retain(|d| *d != device_addr); + device_addr = format!( + "{}:{}:{}:{}:{}:{}", + &val[34..36], + &val[36..38], + &val[38..40], + &val[40..42], + &val[42..44], + &val[44..46] + ) + .to_uppercase(); + devices.push(device_addr.clone().to_lowercase()); + continue; + } else if k == "LE_KEY_PENC" { + let ltk = LtkInfo::try_from_penc(v.unwrap_or_default()).unwrap_or_default(); + let section_name = if has_local_keys { + BLUEZ_PERIPHERAL_LTK_SECTION_NAME + } else { + LTK_SECTION_NAME + }; + bluez_info.set(section_name, "Key", Some(format!("{:032X}", ltk.key))); + bluez_info.set(section_name, "Rand", Some(format!("{}", ltk.rand))); + bluez_info.set(section_name, "EDiv", Some(format!("{}", ltk.ediv))); + bluez_info.set(section_name, "Authenticated", Some(format!("{}", ltk.auth))); + bluez_info.set(section_name, "EncSize", Some(format!("{}", ltk.len))); + continue; + } else if k == "LE_KEY_LENC" { + let ltk = LtkInfo::try_from_lenc(v.unwrap_or_default()).unwrap_or_default(); + bluez_info.set( + BLUEZ_LOCAL_LTK_SECTION_NAME, + "Key", + Some(format!("{:032X}", ltk.key)), + ); + bluez_info.set(BLUEZ_LOCAL_LTK_SECTION_NAME, "Rand", Some(format!("{}", ltk.rand))); + bluez_info.set(BLUEZ_LOCAL_LTK_SECTION_NAME, "EDiv", Some(format!("{}", ltk.ediv))); + bluez_info.set( + BLUEZ_LOCAL_LTK_SECTION_NAME, + "Authenticated", + Some(format!("{}", ltk.auth)), + ); + bluez_info.set( + BLUEZ_LOCAL_LTK_SECTION_NAME, + "EncSize", + Some(format!("{}", ltk.len)), + ); continue; } // Convert matching info file keys @@ -743,7 +810,7 @@ fn convert_floss_conf(filename: &str) { continue; } }; - bluez_info.set(key.section, key.key.clone(), Some(new_val)); + bluez_info.set(key.section, key.key, Some(new_val)); continue; } None => { @@ -761,7 +828,7 @@ fn convert_floss_conf(filename: &str) { continue; } }; - bluez_hid.set(key.section, key.key.clone(), Some(new_val)); + bluez_hid.set(key.section, key.key, Some(new_val)); } None => { debug!("No key match: {}", k) @@ -1000,30 +1067,44 @@ mod tests { fn test_irk_conversion() { let mut key = DeviceKey::new("", KeyAction::Apply(Converter::ReverseEndianUppercase)); assert_eq!( - key.apply_action("d584da72ceccfdf462405b558441ed4401e260f9ee9fb8".to_string()), + key.apply_action("d584da72ceccfdf462405b558441ed44".to_string()), Ok("44ED4184555B4062F4FDCCCE72DA84D5".to_string()) ); assert_eq!( - key.apply_action("td584da72ceccfdf462405b558441ed4401e260f9ee9fb8".to_string()), + key.apply_action("td584da72ceccfdf462405b558441ed44".to_string()), Err("Error converting link key: invalid digit found in string".to_string()) ); } #[test] fn test_ltk_conversion() { - let floss_key = String::from("48fdc93d776cd8cc918f31e422ece00d2322924fa9a09fb30eb20110"); - let ltk = LtkInfo::try_from(floss_key).unwrap_or_default(); - assert_eq!(ltk.key, 0x48FDC93D776CD8CC918F31E422ECE00D); - assert_eq!(ltk.rand, 12943240503130989091); - assert_eq!(ltk.ediv, 45582); - assert_eq!(ltk.auth, 1); - assert_eq!(ltk.len, 16); + let floss_penc_key = + String::from("48fdc93d776cd8cc918f31e422ece00d2322924fa9a09fb30eb20110"); + let pltk = LtkInfo::try_from_penc(floss_penc_key).unwrap_or_default(); + assert_eq!(pltk.key, 0x48FDC93D776CD8CC918F31E422ECE00D); + assert_eq!(pltk.rand, 12943240503130989091); + assert_eq!(pltk.ediv, 45582); + assert_eq!(pltk.auth, 1); + assert_eq!(pltk.len, 16); assert_eq!( - LtkInfo::try_from( + LtkInfo::try_from_penc( "48fdc93d776cd8cc918f31e422ece00d2322924fa9a09fb30eb2011".to_string() ) .unwrap_err(), - "String provided to LtkInfo is not the right size" + "PENC String provided to LtkInfo is not the right size" + ); + + let floss_lenc_key = String::from("07a104a6d2b464d74ff7e2e80b20295600001001"); + let lltk = LtkInfo::try_from_lenc(floss_lenc_key).unwrap_or_default(); + assert_eq!(lltk.key, 0x07A104A6D2B464D74FF7E2E80B202956); + assert_eq!(lltk.rand, 0); + assert_eq!(lltk.ediv, 0); + assert_eq!(lltk.auth, 1); + assert_eq!(lltk.len, 16); + assert_eq!( + LtkInfo::try_from_lenc("07a104a6d2b464d74ff7e2e80b2029560000100".to_string()) + .unwrap_err(), + "LENC String provided to LtkInfo is not the right size" ); } diff --git a/system/gd/rust/linux/mgmt/src/state_machine.rs b/system/gd/rust/linux/mgmt/src/state_machine.rs index 8647c68e8df66c5fa94e43298931454083cf1086..e9de581723a16e6562a348a31a0704b271136e4f 100644 --- a/system/gd/rust/linux/mgmt/src/state_machine.rs +++ b/system/gd/rust/linux/mgmt/src/state_machine.rs @@ -5,6 +5,7 @@ use bt_utils::socket::{ BtSocket, HciChannels, MgmtCommand, MgmtCommandResponse, MgmtEvent, HCI_DEV_NONE, }; +use libc; use log::{debug, error, info, warn}; use nix::sys::signal::{self, Signal}; use nix::unistd::Pid; @@ -36,6 +37,10 @@ pub const INDEX_REMOVED_DEBOUNCE_TIME: Duration = Duration::from_millis(150); /// to avoid dead process + PID not cleaned up from happening. pub const PID_RUNNING_CHECK_PERIOD: Duration = Duration::from_secs(60); +const HCI_BIND_MAX_RETRY: i32 = 2; + +const HCI_BIND_RETRY_INTERVAL: Duration = Duration::from_millis(10); + #[derive(Debug, PartialEq, Copy, Clone)] #[repr(u32)] pub enum ProcessState { @@ -362,19 +367,37 @@ fn configure_hci(hci_tx: mpsc::Sender) { x => debug!("Socket open at fd: {}", x), } - // Bind to control channel (which is used for mgmt commands). We provide - // HCI_DEV_NONE because we don't actually need a valid HCI dev for some MGMT commands. - match btsock.bind_channel(HciChannels::Control, HCI_DEV_NONE) { - -1 => { - panic!( - "Failed to bind control channel with errno={}", - std::io::Error::last_os_error().raw_os_error().unwrap_or(0) - ); + tokio::spawn(async move { + // Bind to control channel (which is used for mgmt commands). We provide + // HCI_DEV_NONE because we don't actually need a valid HCI dev for some MGMT commands. + let mut bind_succ = false; + for _i in 0..HCI_BIND_MAX_RETRY { + match btsock.bind_channel(HciChannels::Control, HCI_DEV_NONE) { + -1 => { + match std::io::Error::last_os_error().raw_os_error().unwrap_or(0) { + libc::EINVAL => { + // If MGMT hasn't been initialized EINVAL will be returned. + // Just wait for a short time and try again. + debug!("Got EINVAL in bind. Wait and try again"); + tokio::time::sleep(HCI_BIND_RETRY_INTERVAL).await; + continue; + } + others => { + panic!("Failed to bind control channel with errno={}", others); + } + } + } + _ => { + bind_succ = true; + break; + } + }; + } + + if !bind_succ { + panic!("bind failed too many times!!"); } - _ => (), - }; - tokio::spawn(async move { debug!("Spawned hci notify task"); // Make this into an AsyncFD and start using it for IO diff --git a/system/gd/rust/linux/service/build.rs b/system/gd/rust/linux/service/build.rs index 1585a230befd490e2df093039979625a7197d6f3..8223fd341c9d70daca6d700f01ac665e8afc79b4 100644 --- a/system/gd/rust/linux/service/build.rs +++ b/system/gd/rust/linux/service/build.rs @@ -26,6 +26,7 @@ fn main() { Config::new().probe("libmodp_b64").unwrap(); Config::new().probe("tinyxml2").unwrap(); Config::new().probe("lc3").unwrap(); + Config::new().probe("fmt").unwrap(); // Include ChromeOS-specific dependencies. if option_env!("TARGET_OS_VARIANT").unwrap_or("None").to_string() == "chromeos" { diff --git a/system/gd/rust/linux/service/src/iface_bluetooth.rs b/system/gd/rust/linux/service/src/iface_bluetooth.rs index 6ed6ae99090ab337ffe00c5f77f282e279e974a3..d1783e38cd6f92470712c7ed6c779f021ed07011 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth.rs @@ -5,6 +5,8 @@ use bt_topshim::btif::{ use bt_topshim::profiles::socket::SocketType; use bt_topshim::profiles::ProfileConnectionState; +use bt_topshim::profiles::hfp::EscoCodingFormat; + use bt_topshim::profiles::hid_host::BthhReportType; use bt_topshim::profiles::sdp::{ @@ -14,8 +16,8 @@ use bt_topshim::profiles::sdp::{ }; use btstack::bluetooth::{ - Bluetooth, BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, - IBluetoothQALegacy, + Bluetooth, BluetoothDevice, BtAdapterRole, IBluetooth, IBluetoothCallback, + IBluetoothConnectionCallback, IBluetoothQALegacy, }; use btstack::socket_manager::{ BluetoothServerSocket, BluetoothSocket, BluetoothSocketManager, CallbackId, @@ -162,6 +164,7 @@ impl_dbus_arg_enum!(BtPropertyType); impl_dbus_arg_enum!(BtSspVariant); impl_dbus_arg_enum!(BtTransport); impl_dbus_arg_enum!(ProfileConnectionState); +impl_dbus_arg_enum!(BtAdapterRole); #[allow(dead_code)] struct BluetoothConnectionCallbackDBus {} @@ -423,6 +426,7 @@ impl DBusArg for BtSdpRecord { } impl_dbus_arg_enum!(BtDiscMode); +impl_dbus_arg_from_into!(EscoCodingFormat, u8); #[allow(dead_code)] struct IBluetoothDBus {} @@ -706,6 +710,16 @@ impl IBluetooth for IBluetoothDBus { fn is_swb_supported(&self) -> bool { dbus_generated!() } + + #[dbus_method("GetSupportedRoles", DBusLog::Disable)] + fn get_supported_roles(&self) -> Vec { + dbus_generated!() + } + + #[dbus_method("IsCodingFormatSupported", DBusLog::Disable)] + fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool { + dbus_generated!() + } } impl_dbus_arg_enum!(SocketType); diff --git a/system/gd/rust/linux/service/src/iface_bluetooth_media.rs b/system/gd/rust/linux/service/src/iface_bluetooth_media.rs index cb575bd22afc958fa40c84bb6c610cc97d1de153..0dc4b47c4364448339f426e456b3a569cbe35973 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth_media.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth_media.rs @@ -3,7 +3,7 @@ use bt_topshim::profiles::a2dp::{ A2dpCodecSampleRate, PresentationPosition, }; use bt_topshim::profiles::avrcp::PlayerMetadata; -use bt_topshim::profiles::hfp::HfpCodecCapability; +use bt_topshim::profiles::hfp::{HfpCodecBitId, HfpCodecFormat}; use btstack::bluetooth_media::{BluetoothAudioDevice, IBluetoothMedia, IBluetoothMediaCallback}; use btstack::RPCProxy; @@ -43,11 +43,12 @@ pub struct BluetoothAudioDeviceDBus { address: String, name: String, a2dp_caps: Vec, - hfp_cap: HfpCodecCapability, + hfp_cap: HfpCodecFormat, absolute_volume: bool, } -impl_dbus_arg_from_into!(HfpCodecCapability, i32); +impl_dbus_arg_from_into!(HfpCodecBitId, i32); +impl_dbus_arg_from_into!(HfpCodecFormat, i32); impl_dbus_arg_enum!(A2dpCodecIndex); impl_dbus_arg_from_into!(A2dpCodecSampleRate, i32); impl_dbus_arg_from_into!(A2dpCodecBitsPerSample, i32); @@ -254,7 +255,7 @@ impl IBluetoothMedia for IBluetoothMediaDBus { &mut self, address: String, sco_offload: bool, - disabled_codecs: HfpCodecCapability, + disabled_codecs: HfpCodecBitId, ) -> bool { dbus_generated!() } diff --git a/system/gd/rust/linux/service/src/interface_manager.rs b/system/gd/rust/linux/service/src/interface_manager.rs index b12b38be292d922b6bfd91992601a298c7f1e382..f18b153325d0f64992e21a0cf039560927120a79 100644 --- a/system/gd/rust/linux/service/src/interface_manager.rs +++ b/system/gd/rust/linux/service/src/interface_manager.rs @@ -7,10 +7,11 @@ use tokio::sync::mpsc::{channel, Receiver, Sender}; use btstack::{ battery_manager::BatteryManager, battery_provider_manager::BatteryProviderManager, - battery_service::BatteryService, bluetooth::Bluetooth, bluetooth_admin::BluetoothAdmin, - bluetooth_gatt::BluetoothGatt, bluetooth_logging::BluetoothLogging, - bluetooth_media::BluetoothMedia, bluetooth_qa::BluetoothQA, - socket_manager::BluetoothSocketManager, suspend::Suspend, APIMessage, BluetoothAPI, + battery_service::BatteryService, bluetooth::Bluetooth, bluetooth::IBluetooth, + bluetooth_admin::BluetoothAdmin, bluetooth_gatt::BluetoothGatt, + bluetooth_logging::BluetoothLogging, bluetooth_media::BluetoothMedia, + bluetooth_qa::BluetoothQA, socket_manager::BluetoothSocketManager, suspend::Suspend, + APIMessage, BluetoothAPI, Message, }; use crate::iface_battery_manager; @@ -35,10 +36,25 @@ impl InterfaceManager { channel::(1) } + /// Runs the dispatch loop for APIMessage + /// + /// # Arguments + /// + /// * `rx` - The receiver channel for APIMessage + /// * `tx` - The sender channel for Message + /// * `virt_index` - The virtual index of the adapter + /// * `conn` - The DBus connection + /// * `conn_join_handle` - The thread handle that's maintaining the DBus resource + /// * `disconnect_watcher` - DisconnectWatcher to monitor client disconnects + /// * `bluetooth` - Implementation of the Bluetooth API + /// other implementations follow. + /// pub async fn dispatch( mut rx: Receiver, + tx: Sender, virt_index: i32, conn: Arc, + conn_join_handle: tokio::task::JoinHandle<()>, disconnect_watcher: Arc>, bluetooth: Arc>>, bluetooth_admin: Arc>>, @@ -191,6 +207,19 @@ impl InterfaceManager { &[qa_iface], bluetooth_qa.clone(), ); + + // AdvertiseManager selects the stack per is_le_ext_adv_supported. + // Initialize it after Adapter is ready. + let bt_clone = bluetooth.clone(); + let gatt_clone = bluetooth_gatt.clone(); + tokio::spawn(async move { + let is_le_ext_adv_supported = + bt_clone.lock().unwrap().is_le_extended_advertising_supported(); + gatt_clone + .lock() + .unwrap() + .init_adv_manager(bt_clone, is_le_ext_adv_supported); + }); } BluetoothAPI::Gatt => { cr.lock().unwrap().insert( @@ -233,6 +262,18 @@ impl InterfaceManager { ); } }, + + APIMessage::ShutDown => { + // To shut down the connection, call _handle.abort() and drop the connection. + conn_join_handle.abort(); + drop(conn); + + let tx = tx.clone(); + tokio::spawn(async move { + let _ = tx.send(Message::AdapterShutdown).await; + }); + break; + } } } } diff --git a/system/gd/rust/linux/service/src/main.rs b/system/gd/rust/linux/service/src/main.rs index 3861df37c1a6cf8b0d8f66ea5599e57e670c49f9..22a49044ece5d24e2cba0fd33bb461efa22f573f 100644 --- a/system/gd/rust/linux/service/src/main.rs +++ b/system/gd/rust/linux/service/src/main.rs @@ -50,15 +50,6 @@ const STACK_TURN_OFF_TIMEOUT_MS: Duration = Duration::from_millis(4000); // Time bt_stack_manager waits for cleanup const STACK_CLEANUP_TIMEOUT_MS: Duration = Duration::from_millis(1000); -const VERBOSE_ONLY_LOG_TAGS: &[&str] = &[ - "bt_bta_av", // AV apis - "btm_sco", // SCO data path logs - "l2c_csm", // L2CAP state machine - "l2c_link", // L2CAP link layer logs - "sco_hci", // SCO over HCI - "uipc", // Userspace IPC implementation -]; - const INIT_LOGGING_MAX_RETRY: u8 = 3; /// Runs the Bluetooth daemon serving D-Bus IPC. @@ -111,24 +102,14 @@ fn main() -> Result<(), Box> { None => vec![], }; - // Set GD debug flag if debug is enabled. - if is_debug { - // Limit tags if verbose debug logging isn't enabled. - if !is_verbose_debug { - init_flags.push(format!( - "INIT_logging_debug_disabled_for_tags={}", - VERBOSE_ONLY_LOG_TAGS.join(",") - )); - init_flags.push(String::from("INIT_default_log_level_str=LOG_DEBUG")); - } else { - init_flags.push(String::from("INIT_default_log_level_str=LOG_VERBOSE")); - } - } - // Forward --hci to Fluoride. init_flags.push(format!("--hci={}", hci_index)); - let logging = Arc::new(Mutex::new(Box::new(BluetoothLogging::new(is_debug, log_output)))); + let logging = Arc::new(Mutex::new(Box::new(BluetoothLogging::new( + is_debug, + is_verbose_debug, + log_output, + )))); // TODO(b/307171804): Investigate why connecting to unix syslog might fail. // Retry it a few times. Ignore the failure if fails too many times. for _ in 0..INIT_LOGGING_MAX_RETRY { @@ -207,7 +188,7 @@ fn main() -> Result<(), Box> { // The `resource` is a task that should be spawned onto a tokio compatible // reactor ASAP. If the resource ever finishes, we lost connection to D-Bus. - tokio::spawn(async { + let conn_join_handle = tokio::spawn(async { let err = resource.await; panic!("Lost connection to D-Bus: {}", err); }); @@ -218,6 +199,7 @@ fn main() -> Result<(), Box> { // Run the stack main dispatch loop. topstack::get_runtime().spawn(Stack::dispatch( rx, + api_tx.clone(), bluetooth.clone(), bluetooth_gatt.clone(), battery_service.clone(), @@ -237,8 +219,10 @@ fn main() -> Result<(), Box> { tokio::spawn(interface_manager::InterfaceManager::dispatch( api_rx, + tx.clone(), virt_index, - conn.clone(), + conn, + conn_join_handle, disconnect_watcher.clone(), bluetooth.clone(), bluetooth_admin.clone(), @@ -264,11 +248,7 @@ fn main() -> Result<(), Box> { bluetooth.init(init_flags); bluetooth.enable(); - bluetooth_gatt.lock().unwrap().init_profiles( - tx.clone(), - api_tx.clone(), - adapter.clone(), - ); + bluetooth_gatt.lock().unwrap().init_profiles(tx.clone(), api_tx.clone()); bt_sock_mgr.lock().unwrap().initialize(intf.clone()); // Install SIGTERM handler so that we can properly shutdown @@ -310,7 +290,7 @@ extern "C" fn handle_sigterm(_signum: i32) { let txl = tx.clone(); tokio::spawn(async move { // Send the shutdown message here. - let _ = txl.send(Message::Shutdown).await; + let _ = txl.send(Message::InterfaceShutdown).await; }); let guard = notifier.enabled.lock().unwrap(); diff --git a/system/gd/rust/linux/stack/build.rs b/system/gd/rust/linux/stack/build.rs index 1ecdfad91705c77b73c8016d2ddba84ae623099d..9baf3e221119e8cac0e9e2fa637d7e7bda9b745a 100644 --- a/system/gd/rust/linux/stack/build.rs +++ b/system/gd/rust/linux/stack/build.rs @@ -12,6 +12,7 @@ fn main() { println!("cargo:rustc-link-lib=dylib=protobuf"); println!("cargo:rustc-link-lib=dylib=resolv"); println!("cargo:rustc-link-lib=dylib=lc3"); + println!("cargo:rustc-link-lib=dylib=fmt"); println!("cargo:rerun-if-changed=build.rs"); } diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index 6514edf49bdc316c36e55e804ae27133b87c1b67..2e0cf877c40670809cc7040b59be7ccc686618ba 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -8,8 +8,9 @@ use bt_topshim::btif::{ ToggleableProfile, Uuid, Uuid128Bit, INVALID_RSSI, }; use bt_topshim::{ - metrics, + controller, metrics, profiles::gatt::GattStatus, + profiles::hfp::EscoCodingFormat, profiles::hid_host::{ BthhConnectionState, BthhHidInfo, BthhProtocolMode, BthhReportType, BthhStatus, HHCallbacks, HHCallbacksDispatcher, HidHost, @@ -25,6 +26,7 @@ use bt_utils::uhid::{UHid, BD_ADDR_DEFAULT}; use btif_macros::{btif_callback, btif_callbacks_dispatcher}; use log::{debug, warn}; +use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::cast::ToPrimitive; use num_traits::pow; use std::collections::{HashMap, HashSet}; @@ -66,6 +68,14 @@ const BTM_SUCCESS: i32 = 0; const PID_DIR: &str = "/var/run/bluetooth"; +/// Represents various roles the adapter supports. +#[derive(Debug, FromPrimitive, ToPrimitive)] +#[repr(u32)] +pub enum BtAdapterRole { + Central = 0, + Peripheral, + CentralPeripheral, +} /// Defines the adapter API. pub trait IBluetooth { /// Adds a callback from a client who wishes to observe adapter events. @@ -239,6 +249,12 @@ pub trait IBluetooth { /// Returns whether SWB is supported. fn is_swb_supported(&self) -> bool; + + /// Returns a list of all the roles that are supported. + fn get_supported_roles(&self) -> Vec; + + /// Returns whether the coding format is supported. + fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool; } /// Adapter API for Bluetooth qualification and verification. @@ -521,6 +537,8 @@ pub struct Bluetooth { // Internal API members discoverable_timeout: Option>, cancelling_devices: HashSet, + active_pairing_address: Option, + le_supported_states: u64, /// Used to notify signal handler that we have turned off the stack. sig_notifier: Arc, @@ -577,6 +595,8 @@ impl Bluetooth { // Internal API members discoverable_timeout: None, cancelling_devices: HashSet::new(), + active_pairing_address: None, + le_supported_states: 0u64, sig_notifier, uhid_wakeup_source: UHid::new(), } @@ -1004,6 +1024,9 @@ impl Bluetooth { )); } props.push(BluetoothProperty::RemoteRssi(result.rssi)); + props.push(BluetoothProperty::RemoteAddrType( + (result.addr_type as u32).into(), + )); props } @@ -1307,6 +1330,7 @@ impl BtifBluetoothCallbacks for Bluetooth { // Also need to manually request some properties self.intf.lock().unwrap().get_adapter_property(BtPropertyType::ClassOfDevice); + self.le_supported_states = controller::Controller::new().get_ble_supported_states(); // Initialize the BLE scanner for discovery. let callback_id = self.bluetooth_gatt.lock().unwrap().register_scanner_callback( @@ -1490,6 +1514,16 @@ impl BtifBluetoothCallbacks for Bluetooth { variant: BtSspVariant, passkey: u32, ) { + // Accept the Just-Works pairing that we initiated, reject otherwise. + if variant == BtSspVariant::Consent { + let initiated_by_us = Some(remote_addr.clone()) == self.active_pairing_address; + self.set_pairing_confirmation( + BluetoothDevice::new(remote_addr.to_string(), remote_name.clone()), + initiated_by_us, + ); + return; + } + // Currently this supports many agent because we accept many callbacks. // TODO(b/274706838): We need a way to select the default agent. self.callbacks.for_all_callbacks(|callback| { @@ -1558,6 +1592,12 @@ impl BtifBluetoothCallbacks for Bluetooth { let device_type = self.get_remote_type(BluetoothDevice::new(address.clone(), "".to_string())); + // Clear the pairing lock if this call corresponds to the + // active pairing device. + if &bond_state != &BtBondState::Bonding && self.active_pairing_address == Some(addr) { + self.active_pairing_address = None; + } + // Easy case of not bonded -- we remove the device from the bonded list and change the bond // state in the found list (in case it was previously bonding). if &bond_state == &BtBondState::NotBonded { @@ -2136,6 +2176,15 @@ impl IBluetooth for Bluetooth { _ => self.get_remote_type(device.clone()), }; + if let Some(active_address) = self.active_pairing_address { + warn!( + "Bonding requested for {} while already bonding {}, rejecting", + DisplayAddress(&address), + DisplayAddress(&active_address) + ); + return false; + } + // There could be a race between bond complete and bond cancel, which makes // |cancelling_devices| in a wrong state. Remove the device just in case. if self.cancelling_devices.remove(&address) { @@ -2148,6 +2197,8 @@ impl IBluetooth for Bluetooth { // BREDR connection won't work when Inquiry is in progress. self.pause_discovery(); + + self.active_pairing_address = Some(address.clone()); let status = self.intf.lock().unwrap().create_bond(&address, transport); if status != 0 { @@ -2733,6 +2784,27 @@ impl IBluetooth for Bluetooth { fn is_swb_supported(&self) -> bool { self.intf.lock().unwrap().get_swb_supported() } + + fn get_supported_roles(&self) -> Vec { + let mut roles: Vec = vec![]; + + // See Core 5.3, Vol 4, Part E, 7.8.27 for detailed state information + if self.le_supported_states >> 35 & 1 == 1u64 { + roles.push(BtAdapterRole::Central); + } + if self.le_supported_states >> 38 & 1 == 1u64 { + roles.push(BtAdapterRole::Peripheral); + } + if self.le_supported_states >> 28 & 1 == 1u64 { + roles.push(BtAdapterRole::CentralPeripheral); + } + + roles + } + + fn is_coding_format_supported(&self, coding_format: EscoCodingFormat) -> bool { + self.intf.lock().unwrap().is_coding_format_supported(coding_format as u8) + } } impl BtifSdpCallbacks for Bluetooth { diff --git a/system/gd/rust/linux/stack/src/bluetooth_adv.rs b/system/gd/rust/linux/stack/src/bluetooth_adv.rs index 6dee294a2ab5800b59b10467b2851686d0211313..0c331889ff6c160f5f7793d086410c2805222ddf 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_adv.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_adv.rs @@ -1,14 +1,21 @@ //! BLE Advertising types and utilities -use bt_topshim::btif::Uuid; -use bt_topshim::profiles::gatt::{AdvertisingStatus, Gatt, LePhy}; +use btif_macros::{btif_callback, btif_callbacks_dispatcher}; + +use bt_topshim::btif::{RawAddress, Uuid}; +use bt_topshim::profiles::gatt::{AdvertisingStatus, Gatt, GattAdvCallbacks, LePhy}; use itertools::Itertools; -use log::warn; +use log::{debug, error, info, warn}; use num_traits::clamp; -use std::collections::HashMap; +use std::collections::{HashMap, VecDeque}; +use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; use tokio::sync::mpsc::Sender; +use tokio::task::JoinHandle; +use tokio::time; +use crate::bluetooth::{Bluetooth, IBluetooth}; use crate::callbacks::Callbacks; use crate::uuid::UuidHelper; use crate::{Message, RPCProxy, SuspendMode}; @@ -350,16 +357,9 @@ impl AdvertiseData { } /// Checks if the advertisement can be upgraded to extended. - pub fn can_upgrade( - parameters: &mut AdvertisingSetParameters, - adv_bytes: &Vec, - is_le_extended_advertising_supported: bool, - ) -> bool { - if parameters.is_legacy - && is_le_extended_advertising_supported - && !AdvertiseData::validate_raw_data(true, adv_bytes) - { - log::info!("Auto upgrading advertisement to extended"); + pub fn can_upgrade(parameters: &mut AdvertisingSetParameters, adv_bytes: &Vec) -> bool { + if parameters.is_legacy && !AdvertiseData::validate_raw_data(true, adv_bytes) { + info!("Auto upgrading advertisement to extended"); parameters.is_legacy = false; return true; } @@ -394,7 +394,7 @@ impl Into // Keeps information of an advertising set. #[derive(Debug, PartialEq, Copy, Clone)] -pub(crate) struct AdvertisingSetInfo { +struct AdvertisingSetInfo { /// Identifies the advertising set when it's started successfully. adv_id: Option, @@ -411,8 +411,11 @@ pub(crate) struct AdvertisingSetInfo { paused: bool, /// Whether the stop of advertising set is held. - /// This happens when an advertising set is stopped when the system is suspending. - /// The advertising set will be stopped on system resumed. + /// This flag is set when an advertising set is stopped while we're not able to do it, such as: + /// - The system is suspending / suspended + /// - The advertising set is not yet valid (started) + /// + /// The advertising set will be stopped on system resumed / advertising set becomes ready. stopped: bool, /// Advertising duration, in 10 ms unit. @@ -427,7 +430,7 @@ pub(crate) struct AdvertisingSetInfo { } impl AdvertisingSetInfo { - pub(crate) fn new( + fn new( callback_id: CallbackId, adv_timeout: u16, adv_events: u8, @@ -448,129 +451,163 @@ impl AdvertisingSetInfo { } /// Gets advertising set registration ID. - pub(crate) fn reg_id(&self) -> RegId { + fn reg_id(&self) -> RegId { self.reg_id } /// Gets associated callback ID. - pub(crate) fn callback_id(&self) -> CallbackId { + fn callback_id(&self) -> CallbackId { self.callback_id } /// Updates advertiser ID. - pub(crate) fn set_adv_id(&mut self, id: Option) { + fn set_adv_id(&mut self, id: Option) { self.adv_id = id; } /// Gets advertiser ID, which is required for advertising |BleAdvertiserInterface|. - pub(crate) fn adv_id(&self) -> u8 { + fn adv_id(&self) -> u8 { // As advertiser ID was from topshim originally, type casting is safe. self.adv_id.unwrap_or(INVALID_ADV_ID) as u8 } /// Updates advertising set status. - pub(crate) fn set_enabled(&mut self, enabled: bool) { + fn set_enabled(&mut self, enabled: bool) { self.enabled = enabled; } /// Returns true if the advertising set has been enabled, false otherwise. - pub(crate) fn is_enabled(&self) -> bool { + fn is_enabled(&self) -> bool { self.enabled } /// Marks the advertising set as paused or not. - pub(crate) fn set_paused(&mut self, paused: bool) { + fn set_paused(&mut self, paused: bool) { self.paused = paused; } /// Returns true if the advertising set has been paused, false otherwise. - pub(crate) fn is_paused(&self) -> bool { + fn is_paused(&self) -> bool { self.paused } /// Marks the advertising set as stopped. - pub(crate) fn set_stopped(&mut self) { + fn set_stopped(&mut self) { self.stopped = true; } /// Returns true if the advertising set has been stopped, false otherwise. - pub(crate) fn is_stopped(&self) -> bool { + fn is_stopped(&self) -> bool { self.stopped } /// Gets adv_timeout. - pub(crate) fn adv_timeout(&self) -> u16 { + fn adv_timeout(&self) -> u16 { self.adv_timeout } /// Gets adv_events. - pub(crate) fn adv_events(&self) -> u8 { + fn adv_events(&self) -> u8 { self.adv_events } /// Returns whether the legacy advertisement will be used. - pub(crate) fn is_legacy(&self) -> bool { + fn is_legacy(&self) -> bool { self.legacy } + + /// Returns whether the advertising set is valid. + fn is_valid(&self) -> bool { + self.adv_id.is_some() + } } // Manages advertising sets and the callbacks. -pub(crate) struct Advertisers { +pub(crate) struct AdvertiseManager { + tx: Sender, + adv_manager_impl: Option>, +} + +impl AdvertiseManager { + pub(crate) fn new(tx: Sender) -> Self { + AdvertiseManager { tx, adv_manager_impl: None } + } + + /// Initializes the AdvertiseManager + /// This needs to be called after Bluetooth is ready because we need to query LE features. + pub(crate) fn initialize( + &mut self, + gatt: Arc>, + adapter: Arc>>, + is_le_ext_adv_supported: bool, + ) { + self.adv_manager_impl = if is_le_ext_adv_supported { + info!("AdvertiseManager: Selected extended advertising stack"); + Some(Box::new(AdvertiseManagerImpl::new(self.tx.clone(), gatt, adapter))) + } else { + info!("AdvertiseManager: Selected software rotation stack"); + Some(Box::new(SoftwareRotationAdvertiseManagerImpl::new( + self.tx.clone(), + gatt, + adapter, + ))) + } + } + + pub fn get_impl(&mut self) -> &mut Box { + self.adv_manager_impl.as_mut().unwrap() + } +} + +struct AdvertiseManagerImpl { callbacks: Callbacks, sets: HashMap, suspend_mode: SuspendMode, + gatt: Arc>, + adapter: Arc>>, } -impl Advertisers { - pub(crate) fn new(tx: Sender) -> Self { - Advertisers { +impl AdvertiseManagerImpl { + fn new( + tx: Sender, + gatt: Arc>, + adapter: Arc>>, + ) -> Self { + AdvertiseManagerImpl { callbacks: Callbacks::new(tx, Message::AdvertiserCallbackDisconnected), sets: HashMap::new(), suspend_mode: SuspendMode::Normal, + gatt, + adapter, } } // Returns the minimum unoccupied register ID from 0. - pub(crate) fn new_reg_id(&mut self) -> RegId { + fn new_reg_id(&mut self) -> RegId { (0..) .find(|id| !self.sets.contains_key(id)) .expect("There must be an unoccupied register ID") } /// Adds an advertising set. - pub(crate) fn add(&mut self, s: AdvertisingSetInfo) { + fn add(&mut self, s: AdvertisingSetInfo) { if let Some(old) = self.sets.insert(s.reg_id(), s) { warn!("An advertising set with the same reg_id ({}) exists. Drop it!", old.reg_id); } } /// Returns an iterator of valid advertising sets. - pub(crate) fn valid_sets(&self) -> impl Iterator { + fn valid_sets(&self) -> impl Iterator { self.sets.iter().filter_map(|(_, s)| s.adv_id.map(|_| s)) } - /// Returns a mutable iterator of valid advertising sets. - pub(crate) fn valid_sets_mut(&mut self) -> impl Iterator { - self.sets.iter_mut().filter_map(|(_, s)| s.adv_id.map(|_| s)) - } - /// Returns an iterator of enabled advertising sets. - pub(crate) fn enabled_sets(&self) -> impl Iterator { + fn enabled_sets(&self) -> impl Iterator { self.valid_sets().filter(|s| s.is_enabled()) } - /// Returns a mutable iterator of enabled advertising sets. - pub(crate) fn enabled_sets_mut(&mut self) -> impl Iterator { - self.valid_sets_mut().filter(|s| s.is_enabled()) - } - - /// Returns a mutable iterator of paused advertising sets. - pub(crate) fn paused_sets_mut(&mut self) -> impl Iterator { - self.valid_sets_mut().filter(|s| s.is_paused()) - } - /// Returns an iterator of stopped advertising sets. - pub(crate) fn stopped_sets(&self) -> impl Iterator { + fn stopped_sets(&self) -> impl Iterator { self.valid_sets().filter(|s| s.is_stopped()) } @@ -584,17 +621,17 @@ impl Advertisers { } /// Returns a mutable reference to the advertising set with the reg_id specified. - pub(crate) fn get_mut_by_reg_id(&mut self, reg_id: RegId) -> Option<&mut AdvertisingSetInfo> { + fn get_mut_by_reg_id(&mut self, reg_id: RegId) -> Option<&mut AdvertisingSetInfo> { self.sets.get_mut(®_id) } /// Returns a shared reference to the advertising set with the reg_id specified. - pub(crate) fn get_by_reg_id(&self, reg_id: RegId) -> Option<&AdvertisingSetInfo> { + fn get_by_reg_id(&self, reg_id: RegId) -> Option<&AdvertisingSetInfo> { self.sets.get(®_id) } /// Returns a mutable reference to the advertising set with the advertiser ID specified. - pub(crate) fn get_mut_by_advertiser_id( + fn get_mut_by_advertiser_id( &mut self, adv_id: AdvertiserId, ) -> Option<&mut AdvertisingSetInfo> { @@ -605,7 +642,7 @@ impl Advertisers { } /// Returns a shared reference to the advertising set with the advertiser ID specified. - pub(crate) fn get_by_advertiser_id(&self, adv_id: AdvertiserId) -> Option<&AdvertisingSetInfo> { + fn get_by_advertiser_id(&self, adv_id: AdvertiserId) -> Option<&AdvertisingSetInfo> { if let Some(reg_id) = self.find_reg_id(adv_id) { return self.get_by_reg_id(reg_id); } @@ -615,53 +652,30 @@ impl Advertisers { /// Removes the advertising set with the reg_id specified. /// /// Returns the advertising set if found, None otherwise. - pub(crate) fn remove_by_reg_id(&mut self, reg_id: RegId) -> Option { + fn remove_by_reg_id(&mut self, reg_id: RegId) -> Option { self.sets.remove(®_id) } /// Removes the advertising set with the specified advertiser ID. /// /// Returns the advertising set if found, None otherwise. - pub(crate) fn remove_by_advertiser_id( - &mut self, - adv_id: AdvertiserId, - ) -> Option { + fn remove_by_advertiser_id(&mut self, adv_id: AdvertiserId) -> Option { if let Some(reg_id) = self.find_reg_id(adv_id) { return self.remove_by_reg_id(reg_id); } None } - /// Adds an advertiser callback. - pub(crate) fn add_callback( - &mut self, - callback: Box, - ) -> CallbackId { - self.callbacks.add_callback(callback) - } - /// Returns callback of the advertising set. - pub(crate) fn get_callback( + fn get_callback( &mut self, s: &AdvertisingSetInfo, ) -> Option<&mut Box> { self.callbacks.get_by_id_mut(s.callback_id()) } - /// Removes an advertiser callback and unregisters all advertising sets associated with that callback. - pub(crate) fn remove_callback(&mut self, callback_id: CallbackId, gatt: &mut Gatt) -> bool { - for (_, s) in - self.sets.iter().filter(|(_, s)| s.callback_id() == callback_id && s.adv_id.is_some()) - { - gatt.advertiser.unregister(s.adv_id()); - } - self.sets.retain(|_, s| s.callback_id() != callback_id); - - self.callbacks.remove_callback(callback_id) - } - /// Update suspend mode. - pub(crate) fn set_suspend_mode(&mut self, suspend_mode: SuspendMode) { + fn set_suspend_mode(&mut self, suspend_mode: SuspendMode) { if suspend_mode != self.suspend_mode { self.suspend_mode = suspend_mode; self.notify_suspend_mode(); @@ -669,7 +683,7 @@ impl Advertisers { } /// Gets current suspend mode. - pub(crate) fn suspend_mode(&mut self) -> SuspendMode { + fn suspend_mode(&mut self) -> SuspendMode { self.suspend_mode.clone() } @@ -680,84 +694,1404 @@ impl Advertisers { callback.on_suspend_mode_change(suspend_mode.clone()); }); } + + fn get_adapter_name(&self) -> String { + self.adapter.lock().unwrap().get_name() + } } -#[cfg(test)] -mod tests { - use super::*; - use std::iter::FromIterator; +pub enum AdvertiserActions { + /// Triggers the rotation of the advertising set. + /// Should only be used in the software rotation stack. + RunRotate, +} - #[test] - fn test_append_ad_data_clamped() { - let mut bytes = Vec::::new(); - let mut ans = Vec::::new(); - ans.push(255); - ans.push(102); - ans.extend(Vec::::from_iter(0..254)); +/// Defines all required ops for an AdvertiseManager to communicate with the upper/lower layers. +pub(crate) trait AdvertiseManagerOps: + IBluetoothAdvertiseManager + BtifGattAdvCallbacks +{ + /// Prepares for suspend + fn enter_suspend(&mut self); - let payload = Vec::::from_iter(0..255); - AdvertiseData::append_adv_data(&mut bytes, 102, &payload); - assert_eq!(bytes, ans); + /// Undoes previous suspend preparation + fn exit_suspend(&mut self); + + /// Handles advertise manager actions + fn handle_action(&mut self, action: AdvertiserActions); +} + +impl AdvertiseManagerOps for AdvertiseManagerImpl { + fn enter_suspend(&mut self) { + self.set_suspend_mode(SuspendMode::Suspending); + + let mut pausing_cnt = 0; + for s in self.sets.values_mut().filter(|s| s.is_valid() && s.is_enabled()) { + s.set_paused(true); + self.gatt.lock().unwrap().advertiser.enable( + s.adv_id(), + false, + s.adv_timeout(), + s.adv_events(), + ); + pausing_cnt += 1; + } + + if pausing_cnt == 0 { + self.set_suspend_mode(SuspendMode::Suspended); + } } - #[test] - fn test_append_ad_data_multiple() { - let mut bytes = Vec::::new(); + fn exit_suspend(&mut self) { + for id in self.stopped_sets().map(|s| s.adv_id()).collect::>() { + self.gatt.lock().unwrap().advertiser.unregister(id); + self.remove_by_advertiser_id(id as AdvertiserId); + } + for s in self.sets.values_mut().filter(|s| s.is_valid() && s.is_paused()) { + s.set_paused(false); + self.gatt.lock().unwrap().advertiser.enable( + s.adv_id(), + true, + s.adv_timeout(), + s.adv_events(), + ); + } - let payload = vec![0 as u8, 1, 2, 3, 4]; - AdvertiseData::append_adv_data(&mut bytes, 100, &payload); - AdvertiseData::append_adv_data(&mut bytes, 101, &[0]); - assert_eq!(bytes, vec![6 as u8, 100, 0, 1, 2, 3, 4, 2, 101, 0]); + self.set_suspend_mode(SuspendMode::Normal); } - #[test] - fn test_add_remove_advising_set_info() { - let (tx, _rx) = crate::Stack::create_channel(); - let mut advertisers = Advertisers::new(tx.clone()); - for i in 0..35 { - let reg_id = i * 2 as RegId; - let s = AdvertisingSetInfo::new(0 as CallbackId, 0, 0, false, reg_id); - advertisers.add(s); - } - for i in 0..35 { - let expected_reg_id = i * 2 + 1 as RegId; - let reg_id = advertisers.new_reg_id(); - assert_eq!(reg_id, expected_reg_id); - let s = AdvertisingSetInfo::new(0 as CallbackId, 0, 0, false, reg_id); - advertisers.add(s); - } - for i in 0..35 { - let reg_id = i * 2 as RegId; - assert!(advertisers.remove_by_reg_id(reg_id).is_some()); - } - for i in 0..35 { - let expected_reg_id = i * 2 as RegId; - let reg_id = advertisers.new_reg_id(); - assert_eq!(reg_id, expected_reg_id); - let s = AdvertisingSetInfo::new(0 as CallbackId, 0, 0, false, reg_id); - advertisers.add(s); + fn handle_action(&mut self, action: AdvertiserActions) { + match action { + AdvertiserActions::RunRotate => { + error!("Unexpected RunRotate call in hardware offloaded stack"); + } } } +} - #[test] - fn test_iterate_adving_set_info() { - let (tx, _rx) = crate::Stack::create_channel(); - let mut advertisers = Advertisers::new(tx.clone()); +pub trait IBluetoothAdvertiseManager { + /// Registers callback for BLE advertising. + fn register_callback(&mut self, callback: Box) -> u32; + + /// Unregisters callback for BLE advertising. + fn unregister_callback(&mut self, callback_id: u32) -> bool; + + /// Creates a new BLE advertising set and start advertising. + /// + /// Returns the reg_id for the advertising set, which is used in the callback + /// `on_advertising_set_started` to identify the advertising set started. + /// + /// * `parameters` - Advertising set parameters. + /// * `advertise_data` - Advertisement data to be broadcasted. + /// * `scan_response` - Scan response. + /// * `periodic_parameters` - Periodic advertising parameters. If None, periodic advertising + /// will not be started. + /// * `periodic_data` - Periodic advertising data. + /// * `duration` - Advertising duration, in 10 ms unit. Valid range is from 1 (10 ms) to + /// 65535 (655.35 sec). 0 means no advertising timeout. + /// * `max_ext_adv_events` - Maximum number of extended advertising events the controller + /// shall attempt to send before terminating the extended advertising, even if the + /// duration has not expired. Valid range is from 1 to 255. 0 means event count limitation. + /// * `callback_id` - Identifies callback registered in register_advertiser_callback. + fn start_advertising_set( + &mut self, + parameters: AdvertisingSetParameters, + advertise_data: AdvertiseData, + scan_response: Option, + periodic_parameters: Option, + periodic_data: Option, + duration: i32, + max_ext_adv_events: i32, + callback_id: u32, + ) -> i32; + + /// Disposes a BLE advertising set. + fn stop_advertising_set(&mut self, advertiser_id: i32); + + /// Queries address associated with the advertising set. + fn get_own_address(&mut self, advertiser_id: i32); + + /// Enables or disables an advertising set. + fn enable_advertising_set( + &mut self, + advertiser_id: i32, + enable: bool, + duration: i32, + max_ext_adv_events: i32, + ); + + /// Updates advertisement data of the advertising set. + fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData); + + /// Set the advertisement data of the advertising set. + fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec); + + /// Updates scan response of the advertising set. + fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData); + + /// Updates advertising parameters of the advertising set. + /// + /// It must be called when advertising is not active. + fn set_advertising_parameters( + &mut self, + advertiser_id: i32, + parameters: AdvertisingSetParameters, + ); + + /// Updates periodic advertising parameters. + fn set_periodic_advertising_parameters( + &mut self, + advertiser_id: i32, + parameters: PeriodicAdvertisingParameters, + ); + + /// Updates periodic advertisement data. + /// + /// It must be called after `set_periodic_advertising_parameters`, or after + /// advertising was started with periodic advertising data set. + fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData); + + /// Enables or disables periodic advertising. + fn set_periodic_advertising_enable( + &mut self, + advertiser_id: i32, + enable: bool, + include_adi: bool, + ); +} + +impl IBluetoothAdvertiseManager for AdvertiseManagerImpl { + fn register_callback(&mut self, callback: Box) -> u32 { + self.callbacks.add_callback(callback) + } + + fn unregister_callback(&mut self, callback_id: u32) -> bool { + for s in self.sets.values_mut().filter(|s| s.callback_id() == callback_id) { + if s.is_valid() { + self.gatt.lock().unwrap().advertiser.unregister(s.adv_id()); + } else { + s.set_stopped(); + } + } + self.sets.retain(|_, s| s.callback_id() != callback_id || !s.is_valid()); + + self.callbacks.remove_callback(callback_id) + } + + fn start_advertising_set( + &mut self, + mut parameters: AdvertisingSetParameters, + advertise_data: AdvertiseData, + scan_response: Option, + periodic_parameters: Option, + periodic_data: Option, + duration: i32, + max_ext_adv_events: i32, + callback_id: u32, + ) -> i32 { + if self.suspend_mode() != SuspendMode::Normal { + return INVALID_REG_ID; + } + + let device_name = self.get_adapter_name(); + let adv_bytes = advertise_data.make_with(&device_name); + // TODO(b/311417973): Remove this once we have more robust /device/bluetooth APIs to control extended advertising + let is_legacy = + parameters.is_legacy && !AdvertiseData::can_upgrade(&mut parameters, &adv_bytes); + let params = parameters.into(); + if !AdvertiseData::validate_raw_data(is_legacy, &adv_bytes) { + warn!("Failed to start advertising set with invalid advertise data"); + return INVALID_REG_ID; + } + let scan_bytes = + if let Some(d) = scan_response { d.make_with(&device_name) } else { Vec::::new() }; + if !AdvertiseData::validate_raw_data(is_legacy, &scan_bytes) { + warn!("Failed to start advertising set with invalid scan response"); + return INVALID_REG_ID; + } + let periodic_params = if let Some(p) = periodic_parameters { + p.into() + } else { + bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default() + }; + let periodic_bytes = + if let Some(d) = periodic_data { d.make_with(&device_name) } else { Vec::::new() }; + if !AdvertiseData::validate_raw_data(false, &periodic_bytes) { + warn!("Failed to start advertising set with invalid periodic data"); + return INVALID_REG_ID; + } + let adv_timeout = clamp(duration, 0, 0xffff) as u16; + let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8; + + let reg_id = self.new_reg_id(); + let s = AdvertisingSetInfo::new(callback_id, adv_timeout, adv_events, is_legacy, reg_id); + self.add(s); + + self.gatt.lock().unwrap().advertiser.start_advertising_set( + reg_id, + params, + adv_bytes, + scan_bytes, + periodic_params, + periodic_bytes, + adv_timeout, + adv_events, + ); + reg_id + } + + fn stop_advertising_set(&mut self, advertiser_id: i32) { + let s = if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + s.clone() + } else { + return; + }; + + if self.suspend_mode() != SuspendMode::Normal { + if !s.is_stopped() { + warn!("Deferred advertisement unregistering due to suspending"); + self.get_mut_by_advertiser_id(advertiser_id).unwrap().set_stopped(); + if let Some(cb) = self.get_callback(&s) { + cb.on_advertising_set_stopped(advertiser_id); + } + } + return; + } + + self.gatt.lock().unwrap().advertiser.unregister(s.adv_id()); + if let Some(cb) = self.get_callback(&s) { + cb.on_advertising_set_stopped(advertiser_id); + } + self.remove_by_advertiser_id(advertiser_id); + } + + fn get_own_address(&mut self, advertiser_id: i32) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + self.gatt.lock().unwrap().advertiser.get_own_address(s.adv_id()); + } + } + + fn enable_advertising_set( + &mut self, + advertiser_id: i32, + enable: bool, + duration: i32, + max_ext_adv_events: i32, + ) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + let adv_timeout = clamp(duration, 0, 0xffff) as u16; + let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8; + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + self.gatt.lock().unwrap().advertiser.enable( + s.adv_id(), + enable, + adv_timeout, + adv_events, + ); + } + } + + fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + let device_name = self.get_adapter_name(); + let bytes = data.make_with(&device_name); + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) { + warn!("AdvertiseManagerImpl {}: invalid advertise data to update", advertiser_id); + return; + } + self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), false, bytes); + } + } + + fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + if !AdvertiseData::validate_raw_data(s.is_legacy(), &data) { + warn!( + "AdvertiseManagerImpl {}: invalid raw advertise data to update", + advertiser_id + ); + return; + } + self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), false, data); + } + } + + fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + let device_name = self.get_adapter_name(); + let bytes = data.make_with(&device_name); + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) { + warn!("AdvertiseManagerImpl {}: invalid scan response to update", advertiser_id); + return; + } + self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), true, bytes); + } + } + + fn set_advertising_parameters( + &mut self, + advertiser_id: i32, + parameters: AdvertisingSetParameters, + ) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + let params = parameters.into(); + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + let was_enabled = s.is_enabled(); + if was_enabled { + self.gatt.lock().unwrap().advertiser.enable( + s.adv_id(), + false, + s.adv_timeout(), + s.adv_events(), + ); + } + self.gatt.lock().unwrap().advertiser.set_parameters(s.adv_id(), params); + if was_enabled { + self.gatt.lock().unwrap().advertiser.enable( + s.adv_id(), + true, + s.adv_timeout(), + s.adv_events(), + ); + } + } + } - let size = 256; - for i in 0..size { - let callback_id: CallbackId = i as CallbackId; - let adv_id: AdvertiserId = i as AdvertiserId; - let reg_id = advertisers.new_reg_id(); - let mut s = AdvertisingSetInfo::new(callback_id, 0, 0, false, reg_id); - s.set_adv_id(Some(adv_id)); - advertisers.add(s); + fn set_periodic_advertising_parameters( + &mut self, + advertiser_id: i32, + parameters: PeriodicAdvertisingParameters, + ) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + let params = parameters.into(); + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + self.gatt + .lock() + .unwrap() + .advertiser + .set_periodic_advertising_parameters(s.adv_id(), params); + } + } + + fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + + let device_name = self.get_adapter_name(); + let bytes = data.make_with(&device_name); + + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + if !AdvertiseData::validate_raw_data(false, &bytes) { + warn!("AdvertiseManagerImpl {}: invalid periodic data to update", advertiser_id); + return; + } + self.gatt.lock().unwrap().advertiser.set_periodic_advertising_data(s.adv_id(), bytes); + } + } + + fn set_periodic_advertising_enable( + &mut self, + advertiser_id: i32, + enable: bool, + include_adi: bool, + ) { + if self.suspend_mode() != SuspendMode::Normal { + return; + } + if let Some(s) = self.get_by_advertiser_id(advertiser_id) { + self.gatt.lock().unwrap().advertiser.set_periodic_advertising_enable( + s.adv_id(), + enable, + include_adi, + ); + } + } +} + +#[btif_callbacks_dispatcher(dispatch_le_adv_callbacks, GattAdvCallbacks)] +pub(crate) trait BtifGattAdvCallbacks { + #[btif_callback(OnAdvertisingSetStarted)] + fn on_advertising_set_started( + &mut self, + reg_id: i32, + advertiser_id: u8, + tx_power: i8, + status: AdvertisingStatus, + ); + + #[btif_callback(OnAdvertisingEnabled)] + fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus); + + #[btif_callback(OnAdvertisingDataSet)] + fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); + + #[btif_callback(OnScanResponseDataSet)] + fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); + + #[btif_callback(OnAdvertisingParametersUpdated)] + fn on_advertising_parameters_updated( + &mut self, + adv_id: u8, + tx_power: i8, + status: AdvertisingStatus, + ); + + #[btif_callback(OnPeriodicAdvertisingParametersUpdated)] + fn on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus); + + #[btif_callback(OnPeriodicAdvertisingDataSet)] + fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); + + #[btif_callback(OnPeriodicAdvertisingEnabled)] + fn on_periodic_advertising_enabled( + &mut self, + adv_id: u8, + enabled: bool, + status: AdvertisingStatus, + ); + + #[btif_callback(OnOwnAddressRead)] + fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress); +} + +impl BtifGattAdvCallbacks for AdvertiseManagerImpl { + fn on_advertising_set_started( + &mut self, + reg_id: i32, + advertiser_id: u8, + tx_power: i8, + status: AdvertisingStatus, + ) { + debug!( + "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}", + reg_id, advertiser_id, tx_power, status + ); + + let s = if let Some(s) = self.sets.get_mut(®_id) { + s + } else { + error!("AdvertisingSetInfo not found"); + // An unknown advertising set has started. Unregister it anyway. + self.gatt.lock().unwrap().advertiser.unregister(advertiser_id); + return; + }; + + if s.is_stopped() { + // The advertising set needs to be stopped. This could happen when |unregister_callback| + // is called before an advertising becomes ready. + self.gatt.lock().unwrap().advertiser.unregister(advertiser_id); + self.sets.remove(®_id); + return; } - assert_eq!(advertisers.valid_sets().count(), size); - for s in advertisers.valid_sets() { - assert_eq!(s.callback_id() as u32, s.adv_id() as u32); + s.set_adv_id(Some(advertiser_id.into())); + s.set_enabled(status == AdvertisingStatus::Success); + + if let Some(cb) = self.callbacks.get_by_id_mut(s.callback_id()) { + cb.on_advertising_set_started(reg_id, advertiser_id.into(), tx_power.into(), status); } + + if status != AdvertisingStatus::Success { + warn!( + "on_advertising_set_started(): failed! reg_id = {}, status = {:?}", + reg_id, status + ); + self.sets.remove(®_id); + } + } + + fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus) { + debug!( + "on_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}", + adv_id, enabled, status + ); + + let advertiser_id: i32 = adv_id.into(); + + if let Some(s) = self.get_mut_by_advertiser_id(advertiser_id) { + s.set_enabled(enabled); + } else { + return; + } + + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + if let Some(cb) = self.get_callback(&s) { + cb.on_advertising_enabled(advertiser_id, enabled, status); + } + + if self.suspend_mode() == SuspendMode::Suspending { + if self.enabled_sets().count() == 0 { + self.set_suspend_mode(SuspendMode::Suspended); + } + } + } + + fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { + debug!("on_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); + + let advertiser_id: i32 = adv_id.into(); + if None == self.get_by_advertiser_id(advertiser_id) { + return; + } + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + + if let Some(cb) = self.get_callback(&s) { + cb.on_advertising_data_set(advertiser_id, status); + } + } + + fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { + debug!("on_scan_response_data_set(): adv_id = {}, status = {:?}", adv_id, status); + + let advertiser_id: i32 = adv_id.into(); + if None == self.get_by_advertiser_id(advertiser_id) { + return; + } + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + + if let Some(cb) = self.get_callback(&s) { + cb.on_scan_response_data_set(advertiser_id, status); + } + } + + fn on_advertising_parameters_updated( + &mut self, + adv_id: u8, + tx_power: i8, + status: AdvertisingStatus, + ) { + debug!( + "on_advertising_parameters_updated(): adv_id = {}, tx_power = {}, status = {:?}", + adv_id, tx_power, status + ); + + let advertiser_id: i32 = adv_id.into(); + if None == self.get_by_advertiser_id(advertiser_id) { + return; + } + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + + if let Some(cb) = self.get_callback(&s) { + cb.on_advertising_parameters_updated(advertiser_id, tx_power.into(), status); + } + } + + fn on_periodic_advertising_parameters_updated( + &mut self, + adv_id: u8, + status: AdvertisingStatus, + ) { + debug!( + "on_periodic_advertising_parameters_updated(): adv_id = {}, status = {:?}", + adv_id, status + ); + + let advertiser_id: i32 = adv_id.into(); + if None == self.get_by_advertiser_id(advertiser_id) { + return; + } + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + + if let Some(cb) = self.get_callback(&s) { + cb.on_periodic_advertising_parameters_updated(advertiser_id, status); + } + } + + fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { + debug!("on_periodic_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); + + let advertiser_id: i32 = adv_id.into(); + if None == self.get_by_advertiser_id(advertiser_id) { + return; + } + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + + if let Some(cb) = self.get_callback(&s) { + cb.on_periodic_advertising_data_set(advertiser_id, status); + } + } + + fn on_periodic_advertising_enabled( + &mut self, + adv_id: u8, + enabled: bool, + status: AdvertisingStatus, + ) { + debug!( + "on_periodic_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}", + adv_id, enabled, status + ); + + let advertiser_id: i32 = adv_id.into(); + if None == self.get_by_advertiser_id(advertiser_id) { + return; + } + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + + if let Some(cb) = self.get_callback(&s) { + cb.on_periodic_advertising_enabled(advertiser_id, enabled, status); + } + } + + fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress) { + debug!( + "on_own_address_read(): adv_id = {}, addr_type = {}, address = {:?}", + adv_id, addr_type, address + ); + + let advertiser_id: i32 = adv_id.into(); + if None == self.get_by_advertiser_id(advertiser_id) { + return; + } + let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + + if let Some(cb) = self.get_callback(&s) { + cb.on_own_address_read(advertiser_id, addr_type.into(), address.to_string()); + } + } +} + +/// The underlying legacy advertising rotates every SOFTWARE_ROTATION_INTERVAL seconds. +const SOFTWARE_ROTATION_INTERVAL: Duration = Duration::from_secs(2); + +/// The ID of a software rotation advertising. +/// +/// From DBus API's perspective this is used as both Advertiser ID and Register ID. +/// Unlike the extended advertising stack we can't propagate the LibBluetooth Advertiser ID to +/// DBus clients because there can be at most 1 advertiser in LibBluetooth layer at the same time. +pub type SoftwareRotationAdvertierId = i32; + +struct SoftwareRotationAdvertiseInfo { + id: SoftwareRotationAdvertierId, + callback_id: u32, + + advertising_params: AdvertisingSetParameters, + advertising_data: Vec, + scan_response_data: Vec, + + /// Filled in on the first time the advertiser started. + tx_power: Option, + + /// True if it's advertising (from DBus client's perspective), false otherwise. + enabled: bool, + duration: i32, + /// None means no timeout + expire_time: Option, +} + +enum SoftwareRotationAdvertiseState { + /// No advertiser is running in LibBluetooth. + Stopped, + /// A StartAdvertisingSet call to LibBluetooth is pending. + Pending(SoftwareRotationAdvertierId), + /// An advertiser is running in LibBluetooth, i.e., an OnAdvertisingSetStarted is received. + /// Parameters: ID, LibBluetooth BLE Advertiser ID, rotation timer handle + Advertising(SoftwareRotationAdvertierId, u8, JoinHandle<()>), +} + +struct SoftwareRotationAdvertiseManagerImpl { + callbacks: Callbacks, + suspend_mode: SuspendMode, + gatt: Arc>, + adapter: Arc>>, + tx: Sender, + + state: SoftwareRotationAdvertiseState, + adv_info: HashMap, + /// The enabled advertising sets to be rotate. + /// When they are removed from the queue, OnAdvertisingEnabled needs to be sent. + /// Note that the current advertiser running in LibBluetooth must *NOT* be in the queue. + adv_queue: VecDeque, +} + +impl SoftwareRotationAdvertiseManagerImpl { + fn new( + tx: Sender, + gatt: Arc>, + adapter: Arc>>, + ) -> Self { + Self { + callbacks: Callbacks::new(tx.clone(), Message::AdvertiserCallbackDisconnected), + suspend_mode: SuspendMode::Normal, + gatt, + adapter, + tx, + state: SoftwareRotationAdvertiseState::Stopped, + adv_info: HashMap::new(), + adv_queue: VecDeque::new(), + } + } +} + +impl SoftwareRotationAdvertiseManagerImpl { + /// Updates suspend mode. + fn set_suspend_mode(&mut self, suspend_mode: SuspendMode) { + if suspend_mode != self.suspend_mode { + self.suspend_mode = suspend_mode.clone(); + self.callbacks.for_all_callbacks(|cb| { + cb.on_suspend_mode_change(suspend_mode.clone()); + }); + } + } + + fn get_adapter_name(&self) -> String { + self.adapter.lock().unwrap().get_name() + } + + /// Returns the ID of the advertiser running in LibBluetooth. + fn current_id(&self) -> Option { + match &self.state { + SoftwareRotationAdvertiseState::Pending(id) => Some(*id), + SoftwareRotationAdvertiseState::Advertising(id, _, _) => Some(*id), + SoftwareRotationAdvertiseState::Stopped => None, + } + } + + /// Returns the minimum unoccupied ID from 0. + fn new_id(&mut self) -> SoftwareRotationAdvertierId { + // The advertiser running in LibBluetooth may have been removed in this layer. + // Avoid conflicting with it. + let current_id = self.current_id(); + (0..) + .find(|id| !self.adv_info.contains_key(id) && Some(*id) != current_id) + .expect("There must be an unoccupied register ID") + } + + fn is_pending(&self) -> bool { + matches!(&self.state, SoftwareRotationAdvertiseState::Pending(_)) + } + + fn is_stopped(&self) -> bool { + matches!(&self.state, SoftwareRotationAdvertiseState::Stopped) + } + + /// Clears the removed or disabled advertisers from the queue and invokes callback. + fn refresh_queue(&mut self) { + let now = Instant::now(); + let adv_info = &mut self.adv_info; + let callbacks = &mut self.callbacks; + self.adv_queue.retain(|id| { + let Some(info) = adv_info.get_mut(id) else { + // This advertiser has been removed. + return false; + }; + if info.expire_time.map_or(false, |t| t < now) { + // This advertiser has expired. + info.enabled = false; + callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success); + }); + } + info.enabled + }); + } + + fn stop_current_advertising(&mut self) { + match &self.state { + SoftwareRotationAdvertiseState::Advertising(id, adv_id, handle) => { + handle.abort(); + self.gatt.lock().unwrap().advertiser.unregister(*adv_id); + self.adv_queue.push_back(*id); + self.state = SoftwareRotationAdvertiseState::Stopped; + } + SoftwareRotationAdvertiseState::Pending(_) => { + error!("stop_current_advertising: Unexpected Pending state"); + } + SoftwareRotationAdvertiseState::Stopped => {} + }; + } + + fn start_next_advertising(&mut self) { + match &self.state { + SoftwareRotationAdvertiseState::Stopped => { + self.state = loop { + let Some(id) = self.adv_queue.pop_front() else { + break SoftwareRotationAdvertiseState::Stopped; + }; + let Some(info) = self.adv_info.get(&id) else { + error!("start_next_advertising: Unknown ID, which means queue is not refreshed!"); + continue; + }; + self.gatt.lock().unwrap().advertiser.start_advertising_set( + id, + info.advertising_params.clone().into(), + info.advertising_data.clone(), + info.scan_response_data.clone(), + Default::default(), // Unsupported periodic_parameters + vec![], // Unsupported periodic_data + 0, // Set no timeout. Timeout is controlled in this layer. + 0, // Unsupported max_ext_adv_events + ); + break SoftwareRotationAdvertiseState::Pending(id); + } + } + SoftwareRotationAdvertiseState::Pending(_) => { + error!("start_next_advertising: Unexpected Pending state"); + } + SoftwareRotationAdvertiseState::Advertising(_, _, _) => { + error!("start_next_advertising: Unexpected Advertising state"); + } + }; + } + + fn run_rotate(&mut self) { + if self.is_pending() { + return; + } + let Some(current_id) = self.current_id() else { + // State is Stopped. Try to start next one. + self.refresh_queue(); + self.start_next_advertising(); + return; + }; + // We are Advertising. Checks if the current advertiser is still allowed + // to advertise, or if we should schedule the next one in the queue. + let current_is_enabled = { + let now = Instant::now(); + if let Some(info) = self.adv_info.get(¤t_id) { + if info.enabled { + info.expire_time.map_or(true, |t| t >= now) + } else { + false + } + } else { + false + } + }; + if !current_is_enabled { + // If current advertiser is not allowed to advertise, + // stop it and then let |refresh_queue| handle the callback. + self.stop_current_advertising(); + self.refresh_queue(); + self.start_next_advertising(); + } else { + // Current advertiser is still enabled, refresh the other advertisers in the queue. + self.refresh_queue(); + if self.adv_queue.is_empty() { + // No need to rotate. + } else { + self.stop_current_advertising(); + self.start_next_advertising(); + } + } + } +} + +impl AdvertiseManagerOps for SoftwareRotationAdvertiseManagerImpl { + fn enter_suspend(&mut self) { + if self.suspend_mode != SuspendMode::Normal { + return; + } + + self.set_suspend_mode(SuspendMode::Suspending); + if self.is_pending() { + // We will unregister it on_advertising_set_started and then set mode to suspended. + return; + } + self.stop_current_advertising(); + self.set_suspend_mode(SuspendMode::Suspended); + } + + fn exit_suspend(&mut self) { + if self.suspend_mode != SuspendMode::Suspended { + return; + } + self.refresh_queue(); + self.start_next_advertising(); + self.set_suspend_mode(SuspendMode::Normal); + } + + fn handle_action(&mut self, action: AdvertiserActions) { + match action { + AdvertiserActions::RunRotate => { + if self.suspend_mode == SuspendMode::Normal { + self.run_rotate(); + } + } + } + } +} + +/// Generates expire time from now per the definition in IBluetoothAdvertiseManager +/// +/// None means never timeout. +fn gen_expire_time_from_now(duration: i32) -> Option { + let duration = clamp(duration, 0, 0xffff) as u64; + if duration != 0 { + Some(Instant::now() + Duration::from_millis(duration * 10)) + } else { + None + } +} + +impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl { + fn register_callback(&mut self, callback: Box) -> u32 { + self.callbacks.add_callback(callback) + } + + fn unregister_callback(&mut self, callback_id: u32) -> bool { + self.adv_info.retain(|_, info| info.callback_id != callback_id); + let ret = self.callbacks.remove_callback(callback_id); + if let Some(current_id) = self.current_id() { + if !self.adv_info.contains_key(¤t_id) { + self.run_rotate(); + } + } + ret + } + + fn start_advertising_set( + &mut self, + advertising_params: AdvertisingSetParameters, + advertising_data: AdvertiseData, + scan_response_data: Option, + periodic_parameters: Option, + periodic_data: Option, + duration: i32, + max_ext_adv_events: i32, + callback_id: u32, + ) -> i32 { + if self.suspend_mode != SuspendMode::Normal { + return INVALID_REG_ID; + } + + let is_legacy = advertising_params.is_legacy; + let device_name = self.get_adapter_name(); + + let advertising_data = advertising_data.make_with(&device_name); + if !AdvertiseData::validate_raw_data(is_legacy, &advertising_data) { + warn!("Failed to start advertising set with invalid advertising data"); + return INVALID_REG_ID; + } + + let scan_response_data = + scan_response_data.map_or(vec![], |data| data.make_with(&device_name)); + if !AdvertiseData::validate_raw_data(is_legacy, &scan_response_data) { + warn!("Failed to start advertising set with invalid scan response data"); + return INVALID_REG_ID; + } + + if periodic_parameters.is_some() { + warn!("Periodic parameters is not supported in software rotation stack, ignored"); + } + if periodic_data.is_some() { + warn!("Periodic data is not supported in software rotation stack, ignored"); + } + if max_ext_adv_events != 0 { + warn!("max_ext_adv_events is not supported in software rotation stack, ignored"); + } + + let id = self.new_id(); + + // expire_time will be determined on this advertiser is started at the first time. + self.adv_info.insert( + id, + SoftwareRotationAdvertiseInfo { + id, + callback_id, + advertising_params, + advertising_data, + scan_response_data, + tx_power: None, + enabled: true, + duration, + expire_time: None, + }, + ); + // Schedule it as the next one and rotate. + self.adv_queue.push_front(id); + self.run_rotate(); + + id + } + + fn stop_advertising_set(&mut self, adv_id: i32) { + let current_id = self.current_id(); + let Some(info) = self.adv_info.remove(&adv_id) else { + warn!("stop_advertising_set: Unknown adv_id {}", adv_id); + return; + }; + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_set_stopped(info.id); + }); + if current_id == Some(info.id) { + self.run_rotate(); + } + } + + fn get_own_address(&mut self, _adv_id: i32) { + error!("get_own_address is not supported in software rotation stack"); + } + + fn enable_advertising_set( + &mut self, + adv_id: i32, + enable: bool, + duration: i32, + max_ext_adv_events: i32, + ) { + if self.suspend_mode != SuspendMode::Normal { + return; + } + + let current_id = self.current_id(); + let Some(info) = self.adv_info.get_mut(&adv_id) else { + warn!("enable_advertising_set: Unknown adv_id {}", adv_id); + return; + }; + + if max_ext_adv_events != 0 { + warn!("max_ext_adv_events is not supported in software rotation stack, ignored"); + } + + info.enabled = enable; + // We won't really call enable() to LibBluetooth so calculate the expire time right now. + info.expire_time = gen_expire_time_from_now(duration); + // This actually won't be used as the expire_time is already determined. + // Still fill it in to keep the data updated. + info.duration = duration; + + if enable && !self.adv_queue.contains(&info.id) && current_id != Some(info.id) { + // The adv was not enabled and not in the queue. Invoke callback and queue it. + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success); + }); + self.adv_queue.push_back(info.id); + if self.is_stopped() { + self.start_next_advertising(); + } + } else if !enable && current_id == Some(info.id) { + self.run_rotate(); + } + } + + fn set_advertising_data(&mut self, adv_id: i32, data: AdvertiseData) { + if self.suspend_mode != SuspendMode::Normal { + return; + } + + let current_id = self.current_id(); + let device_name = self.get_adapter_name(); + let Some(info) = self.adv_info.get_mut(&adv_id) else { + warn!("set_advertising_data: Unknown adv_id {}", adv_id); + return; + }; + let data = data.make_with(&device_name); + if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) { + warn!("set_advertising_data {}: invalid advertise data to update", adv_id); + return; + } + info.advertising_data = data; + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_data_set(info.id, AdvertisingStatus::Success); + }); + + if current_id == Some(info.id) { + self.run_rotate(); + } + } + + fn set_raw_adv_data(&mut self, adv_id: i32, data: Vec) { + if self.suspend_mode != SuspendMode::Normal { + return; + } + + let current_id = self.current_id(); + let Some(info) = self.adv_info.get_mut(&adv_id) else { + warn!("set_raw_adv_data: Unknown adv_id {}", adv_id); + return; + }; + if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) { + warn!("set_raw_adv_data {}: invalid raw advertise data to update", adv_id); + return; + } + info.advertising_data = data; + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_data_set(info.id, AdvertisingStatus::Success); + }); + + if current_id == Some(info.id) { + self.run_rotate(); + } + } + + fn set_scan_response_data(&mut self, adv_id: i32, data: AdvertiseData) { + if self.suspend_mode != SuspendMode::Normal { + return; + } + + let current_id = self.current_id(); + let device_name = self.get_adapter_name(); + let Some(info) = self.adv_info.get_mut(&adv_id) else { + warn!("set_scan_response_data: Unknown adv_id {}", adv_id); + return; + }; + let data = data.make_with(&device_name); + if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) { + warn!("set_scan_response_data {}: invalid scan response to update", adv_id); + return; + } + info.scan_response_data = data; + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_scan_response_data_set(info.id, AdvertisingStatus::Success); + }); + + if current_id == Some(info.id) { + self.run_rotate(); + } + } + + fn set_advertising_parameters(&mut self, adv_id: i32, params: AdvertisingSetParameters) { + if self.suspend_mode != SuspendMode::Normal { + return; + } + + let current_id = self.current_id(); + let Some(info) = self.adv_info.get_mut(&adv_id) else { + warn!("set_advertising_parameters: Unknown adv_id {}", adv_id); + return; + }; + info.advertising_params = params; + let Some(tx_power) = info.tx_power else { + error!("set_advertising_parameters: tx_power is None! Is this called before adv has started?"); + return; + }; + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_parameters_updated(info.id, tx_power, AdvertisingStatus::Success); + }); + + if current_id == Some(info.id) { + self.run_rotate(); + } + } + + fn set_periodic_advertising_parameters( + &mut self, + _adv_id: i32, + _parameters: PeriodicAdvertisingParameters, + ) { + error!("set_periodic_advertising_parameters is not supported in software rotation stack"); + } + + fn set_periodic_advertising_data(&mut self, _adv_id: i32, _data: AdvertiseData) { + error!("set_periodic_advertising_data is not supported in software rotation stack"); + } + + fn set_periodic_advertising_enable(&mut self, _adv_id: i32, _enable: bool, _include_adi: bool) { + error!("set_periodic_advertising_enable is not supported in software rotation stack"); + } +} + +impl BtifGattAdvCallbacks for SoftwareRotationAdvertiseManagerImpl { + fn on_advertising_set_started( + &mut self, + reg_id: i32, + adv_id: u8, + tx_power: i8, + status: AdvertisingStatus, + ) { + debug!( + "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}", + reg_id, adv_id, tx_power, status + ); + + // Unregister if it's unexpected. + match &self.state { + SoftwareRotationAdvertiseState::Pending(pending_id) if pending_id == ®_id => {} + _ => { + error!( + "Unexpected on_advertising_set_started reg_id = {}, adv_id = {}, status = {:?}", + reg_id, adv_id, status + ); + if status == AdvertisingStatus::Success { + self.gatt.lock().unwrap().advertiser.unregister(adv_id); + } + return; + } + } + // Switch out from the pending state. + self.state = if status != AdvertisingStatus::Success { + warn!("on_advertising_set_started failed: reg_id = {}, status = {:?}", reg_id, status); + SoftwareRotationAdvertiseState::Stopped + } else { + let txl = self.tx.clone(); + SoftwareRotationAdvertiseState::Advertising( + reg_id, + adv_id, + tokio::spawn(async move { + loop { + time::sleep(SOFTWARE_ROTATION_INTERVAL).await; + let _ = txl + .send(Message::AdvertiserActions(AdvertiserActions::RunRotate)) + .await; + } + }), + ) + }; + + // 1. Handle on_advertising_set_started callback if it's the first time it started + // 2. Stop advertising if it's removed or disabled + // 3. Disable or remove the advertiser if it failed + if let Some(info) = self.adv_info.get_mut(®_id) { + if info.tx_power.is_none() { + // tx_power is none means it's the first time this advertiser started. + if status != AdvertisingStatus::Success { + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_set_started(info.id, INVALID_ADV_ID, 0, status); + }); + self.adv_info.remove(®_id); + } else { + info.tx_power = Some(tx_power.into()); + info.expire_time = gen_expire_time_from_now(info.duration); + self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + cb.on_advertising_set_started(info.id, info.id, tx_power.into(), status); + }); + } + } else { + // Not the first time. This means we are not able to report the failure through + // on_advertising_set_started if it failed. Disable it instead in that case. + if status != AdvertisingStatus::Success { + info.enabled = false; + // Push to the queue and let refresh_queue handle the disabled callback. + self.adv_queue.push_back(reg_id); + } else { + if !info.enabled { + self.stop_current_advertising(); + } + } + } + } else { + self.stop_current_advertising(); + } + + // Rotate again if the next advertiser is new. We need to consume all + // "first time" advertiser before suspended to make sure callbacks are sent. + if let Some(id) = self.adv_queue.front() { + if let Some(info) = self.adv_info.get(id) { + if info.tx_power.is_none() { + self.run_rotate(); + return; + } + } + } + + // We're fine to suspend since there is no advertiser pending callback. + if self.suspend_mode != SuspendMode::Normal { + self.stop_current_advertising(); + self.set_suspend_mode(SuspendMode::Suspended); + return; + } + + // If the current advertiser is stopped for some reason, schedule the next one. + if self.is_stopped() { + self.refresh_queue(); + self.start_next_advertising(); + } + } + + fn on_advertising_enabled(&mut self, _adv_id: u8, _enabled: bool, _status: AdvertisingStatus) { + error!("Unexpected on_advertising_enabled in software rotation stack"); + } + + fn on_advertising_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus) { + error!("Unexpected on_advertising_data_set in software rotation stack"); + } + + fn on_scan_response_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus) { + error!("Unexpected on_scan_response_data_set in software rotation stack"); + } + + fn on_advertising_parameters_updated( + &mut self, + _adv_id: u8, + _tx_power: i8, + _status: AdvertisingStatus, + ) { + error!("Unexpected on_advertising_parameters_updated in software rotation stack"); + } + + fn on_periodic_advertising_parameters_updated( + &mut self, + _adv_id: u8, + _status: AdvertisingStatus, + ) { + error!("Unexpected on_periodic_advertising_parameters_updated in software rotation stack"); + } + + fn on_periodic_advertising_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus) { + error!("Unexpected on_periodic_advertising_data_set in software rotation stack"); + } + + fn on_periodic_advertising_enabled( + &mut self, + _adv_id: u8, + _enabled: bool, + _status: AdvertisingStatus, + ) { + error!("Unexpected on_periodic_advertising_enabled in software rotation stack"); + } + + fn on_own_address_read(&mut self, _adv_id: u8, _addr_type: u8, _address: RawAddress) { + error!("Unexpected on_own_address_read in software rotation stack"); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::iter::FromIterator; + + #[test] + fn test_append_ad_data_clamped() { + let mut bytes = Vec::::new(); + let mut ans = Vec::::new(); + ans.push(255); + ans.push(102); + ans.extend(Vec::::from_iter(0..254)); + + let payload = Vec::::from_iter(0..255); + AdvertiseData::append_adv_data(&mut bytes, 102, &payload); + assert_eq!(bytes, ans); + } + + #[test] + fn test_append_ad_data_multiple() { + let mut bytes = Vec::::new(); + + let payload = vec![0 as u8, 1, 2, 3, 4]; + AdvertiseData::append_adv_data(&mut bytes, 100, &payload); + AdvertiseData::append_adv_data(&mut bytes, 101, &[0]); + assert_eq!(bytes, vec![6 as u8, 100, 0, 1, 2, 3, 4, 2, 101, 0]); } #[test] diff --git a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs index 0ee191f4ae44359606a3e9fd9d776d9fa62aa5c1..4e02cfb52d83249d9ebf7cdf547db3c9d376c43a 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs @@ -6,11 +6,11 @@ use bt_topshim::bindings::root::bluetooth::Uuid; use bt_topshim::btif::{BluetoothInterface, BtStatus, BtTransport, RawAddress, Uuid128Bit}; use bt_topshim::profiles::gatt::{ ffi::RustAdvertisingTrackInfo, AdvertisingStatus, BtGattDbElement, BtGattNotifyParams, - BtGattReadParams, BtGattResponse, BtGattValue, Gatt, GattAdvCallbacks, - GattAdvCallbacksDispatcher, GattAdvInbandCallbacksDispatcher, GattClientCallbacks, - GattClientCallbacksDispatcher, GattScannerCallbacks, GattScannerCallbacksDispatcher, - GattScannerInbandCallbacks, GattScannerInbandCallbacksDispatcher, GattServerCallbacks, - GattServerCallbacksDispatcher, GattStatus, LePhy, MsftAdvMonitor, MsftAdvMonitorPattern, + BtGattReadParams, BtGattResponse, BtGattValue, Gatt, GattAdvCallbacksDispatcher, + GattAdvInbandCallbacksDispatcher, GattClientCallbacks, GattClientCallbacksDispatcher, + GattScannerCallbacks, GattScannerCallbacksDispatcher, GattScannerInbandCallbacks, + GattScannerInbandCallbacksDispatcher, GattServerCallbacks, GattServerCallbacksDispatcher, + GattStatus, LePhy, MsftAdvMonitor, MsftAdvMonitorPattern, }; use bt_topshim::sysprop; use bt_topshim::topstack; @@ -18,18 +18,17 @@ use bt_utils::adv_parser; use bt_utils::array_utils; use crate::async_helper::{AsyncHelper, CallbackSender}; -use crate::bluetooth::{Bluetooth, BluetoothDevice, IBluetooth}; +use crate::bluetooth::{Bluetooth, BluetoothDevice}; use crate::bluetooth_adv::{ - AdvertiseData, AdvertiserId, Advertisers, AdvertisingSetInfo, AdvertisingSetParameters, - IAdvertisingSetCallback, PeriodicAdvertisingParameters, INVALID_REG_ID, + AdvertiseData, AdvertiseManager, AdvertiserActions, AdvertisingSetParameters, + BtifGattAdvCallbacks, IAdvertisingSetCallback, PeriodicAdvertisingParameters, }; use crate::callbacks::Callbacks; use crate::uuid::UuidHelper; use crate::{APIMessage, BluetoothAPI, Message, RPCProxy, SuspendMode}; -use log::{debug, warn}; +use log::warn; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::cast::{FromPrimitive, ToPrimitive}; -use num_traits::clamp; use rand::rngs::SmallRng; use rand::{RngCore, SeedableRng}; use std::collections::{HashMap, HashSet}; @@ -782,11 +781,7 @@ pub struct BluetoothGattService { } impl BluetoothGattService { - pub(crate) fn new( - uuid: Uuid128Bit, - instance_id: i32, - service_type: i32, - ) -> BluetoothGattService { + pub fn new(uuid: Uuid128Bit, instance_id: i32, service_type: i32) -> BluetoothGattService { BluetoothGattService { uuid, instance_id, @@ -1133,7 +1128,7 @@ pub trait IScannerCallback: RPCProxy { #[derive(Debug, FromPrimitive, ToPrimitive)] #[repr(u8)] /// GATT write type. -pub(crate) enum GattDbElementType { +pub enum GattDbElementType { PrimaryService = 0, SecondaryService = 1, IncludedService = 2, @@ -1163,7 +1158,7 @@ impl Default for GattWriteType { } } -#[derive(Debug, FromPrimitive, ToPrimitive, Clone)] +#[derive(Debug, FromPrimitive, ToPrimitive, Clone, PartialEq)] #[repr(u32)] /// Scan type configuration. pub enum ScanType { @@ -1173,7 +1168,7 @@ pub enum ScanType { impl Default for ScanType { fn default() -> Self { - ScanType::Active + ScanType::Passive } } @@ -1189,20 +1184,26 @@ pub struct ScanSettings { } impl ScanSettings { - fn extract_scan_parameters(self) -> Option<(u16, u16)> { - let interval = u16::try_from(self.interval); - if interval.is_err() { - println!("Invalid scan interval {}", self.interval); - return None; - } - - let window = u16::try_from(self.window); - if window.is_err() { - println!("Invalid scan window {}", self.window); - return None; - } - - return Some((interval.unwrap(), window.unwrap())); + fn extract_scan_parameters(&self) -> Option<(u8, u16, u16)> { + let scan_type = match self.scan_type { + ScanType::Passive => 0x00, + ScanType::Active => 0x01, + }; + let interval = match u16::try_from(self.interval) { + Ok(i) => i, + Err(e) => { + println!("Invalid scan interval {}: {}", self.interval, e); + return None; + } + }; + let window = match u16::try_from(self.window) { + Ok(w) => w, + Err(e) => { + println!("Invalid scan window {}: {}", self.window, e); + return None; + } + }; + return Some((scan_type, interval, window)); } } @@ -1344,31 +1345,52 @@ impl GattAsyncIntf { .await } - /// Updates the topshim's scan state depending on the states of registered scanners. Scan is - /// enabled if there is at least 1 active registered scanner. + /// Updates the scan state depending on the states of registered scanners: + /// 1. Scan is started if there is at least 1 enabled scanner. + /// 2. Always toggle the scan off and on so that we reset the scan parameters based on whether + /// we have enabled scanners using hardware filtering. + /// TODO(b/266752123): We can do more bookkeeping to optimize when we really need to + /// toggle. Also improve toggling API into 1 operation that guarantees correct ordering. + /// 3. If there is an enabled ScanType::Active scanner, prefer its scan settings. Otherwise, + /// adopt the settings from any of the enabled scanners. We shouldn't just use the settings + /// from |scanner_id| because it may refer to a disabled scan. /// /// Note: this does not need to be async, but declared as async for consistency in this struct. /// May be converted into real async in the future if btif supports it. - async fn update_scan(&mut self, scanner_id: u8, scan_settings: Option) { - if self.scanners.lock().unwrap().values().find(|scanner| scanner.is_active).is_some() { - // Toggle the scan off and on so that we reset the scan parameters based on whether - // we have active scanners using hardware filtering. - // TODO(b/266752123): We can do more bookkeeping to optimize when we really need to - // toggle. Also improve toggling API into 1 operation that guarantees correct ordering. - self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); - if let Some(settings) = scan_settings { - if let Some((scan_interval, scan_window)) = settings.extract_scan_parameters() { - self.gatt.as_ref().unwrap().lock().unwrap().scanner.set_scan_parameters( - scanner_id, - scan_interval, - scan_window, - ); + async fn update_scan(&mut self, scanner_id: u8) { + let mut has_enabled_scan = false; + let mut enabled_scan_param = None; + let mut enabled_active_scan_param = None; + for scanner in self.scanners.lock().unwrap().values() { + if !scanner.is_enabled { + continue; + } + has_enabled_scan = true; + if let Some(ss) = &scanner.scan_settings { + enabled_scan_param = ss.extract_scan_parameters(); + if ss.scan_type == ScanType::Active { + enabled_active_scan_param = ss.extract_scan_parameters(); + break; } } - self.gatt.as_ref().unwrap().lock().unwrap().scanner.start_scan(); - } else { - self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); } + + self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan(); + if !has_enabled_scan { + return; + } + + if let Some((scan_type, scan_interval, scan_window)) = + enabled_active_scan_param.or(enabled_scan_param) + { + self.gatt.as_ref().unwrap().lock().unwrap().scanner.set_scan_parameters( + scanner_id, + scan_type, + scan_interval, + scan_window, + ); + } + self.gatt.as_ref().unwrap().lock().unwrap().scanner.start_scan(); } } @@ -1385,7 +1407,6 @@ pub struct BluetoothGatt { // to not wrap this in `Option` since we know that we can't function without `gatt` being // initialized anyway. gatt: Option>>, - adapter: Option>>>, context_map: ContextMap, server_context_map: ServerContextMap, @@ -1394,7 +1415,7 @@ pub struct BluetoothGatt { scanners: Arc>, scan_suspend_mode: SuspendMode, paused_scanner_ids: Vec, - advertisers: Advertisers, + adv_manager: AdvertiseManager, adv_mon_add_cb_sender: CallbackSender<(u8, u8)>, adv_mon_remove_cb_sender: CallbackSender, @@ -1419,7 +1440,6 @@ impl BluetoothGatt { BluetoothGatt { intf, gatt: None, - adapter: None, context_map: ContextMap::new(tx.clone()), server_context_map: ServerContextMap::new(tx.clone()), reliable_queue: HashSet::new(), @@ -1428,7 +1448,7 @@ impl BluetoothGatt { scan_suspend_mode: SuspendMode::Normal, paused_scanner_ids: Vec::new(), small_rng: SmallRng::from_entropy(), - advertisers: Advertisers::new(tx.clone()), + adv_manager: AdvertiseManager::new(tx.clone()), adv_mon_add_cb_sender: async_helper_msft_adv_monitor_add.get_callback_sender(), adv_mon_remove_cb_sender: async_helper_msft_adv_monitor_remove.get_callback_sender(), adv_mon_enable_cb_sender: async_helper_msft_adv_monitor_enable.get_callback_sender(), @@ -1443,14 +1463,8 @@ impl BluetoothGatt { } } - pub fn init_profiles( - &mut self, - tx: Sender, - api_tx: Sender, - adapter: Arc>>, - ) { + pub fn init_profiles(&mut self, tx: Sender, api_tx: Sender) { self.gatt = Gatt::new(&self.intf.lock().unwrap()).map(|gatt| Arc::new(Mutex::new(gatt))); - self.adapter = Some(adapter); let tx_clone = tx.clone(); let gatt_client_callbacks_dispatcher = GattClientCallbacksDispatcher { @@ -1534,6 +1548,26 @@ impl BluetoothGatt { }); } + /// Initializes AdvertiseManager. + /// + /// Query |is_le_ext_adv_supported| outside this function (before locking BluetoothGatt) to + /// avoid deadlock. |is_le_ext_adv_supported| can only be queried after Bluetooth is ready. + /// + /// TODO(b/242083290): Correctly fire IsReady message for Adv API in this function after the + /// API is fully split out. For now Gatt is delayed for 500ms (see + /// |BluetoothGatt::init_profiles|) which shall be enough for Bluetooth to become ready. + pub fn init_adv_manager( + &mut self, + adapter: Arc>>, + is_le_ext_adv_supported: bool, + ) { + self.adv_manager.initialize( + self.gatt.as_ref().unwrap().clone(), + adapter, + is_le_ext_adv_supported, + ); + } + pub fn enable(&mut self, enabled: bool) { self.enabled = enabled; } @@ -1593,7 +1627,7 @@ impl BluetoothGatt { .unwrap() .iter() .filter_map(|(_uuid, scanner)| { - if let (true, Some(scanner_id)) = (scanner.is_active, scanner.scanner_id) { + if let (true, Some(scanner_id)) = (scanner.is_enabled, scanner.scanner_id) { Some(scanner_id) } else { None @@ -1663,7 +1697,7 @@ impl BluetoothGatt { if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { if scanner.is_suspended { scanner.is_suspended = false; - scanner.is_active = true; + scanner.is_enabled = true; // When a scanner resumes from a suspended state, the // scanner.filter has already had the filter data. scanner.filter.clone() @@ -1723,14 +1757,14 @@ impl BluetoothGatt { log::debug!("Added adv monitor handle = {}", monitor_handle); } - let has_active_unfiltered_scanner = scanners + let has_enabled_unfiltered_scanner = scanners .lock() .unwrap() .iter() - .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none()); + .any(|(_uuid, scanner)| scanner.is_enabled && scanner.filter.is_none()); if !gatt_async - .msft_adv_monitor_enable(!has_active_unfiltered_scanner) + .msft_adv_monitor_enable(!has_enabled_unfiltered_scanner) .await .map_or(false, |status| status == 0) { @@ -1742,27 +1776,15 @@ impl BluetoothGatt { } } - let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) - .map_or(None, |s| s.scan_settings.clone()); - - gatt_async.update_scan(scanner_id, scan_settings).await; + gatt_async.update_scan(scanner_id).await; }); BtStatus::Success } - /// Remove an advertiser callback and unregisters all advertising sets associated with that callback. + /// Remove an adv_manager callback and unregisters all advertising sets associated with that callback. pub fn remove_adv_callback(&mut self, callback_id: u32) -> bool { - self.advertisers - .remove_callback(callback_id, &mut self.gatt.as_ref().unwrap().lock().unwrap()) - } - - fn get_adapter_name(&self) -> String { - if let Some(adapter) = &self.adapter { - adapter.lock().unwrap().get_name() - } else { - String::new() - } + self.adv_manager.get_impl().unregister_callback(callback_id) } pub fn remove_client_callback(&mut self, callback_id: u32) { @@ -1791,42 +1813,12 @@ impl BluetoothGatt { /// Enters suspend mode for LE advertising. pub fn advertising_enter_suspend(&mut self) { - self.advertisers.set_suspend_mode(SuspendMode::Suspending); - - let mut pausing_cnt = 0; - for s in self.advertisers.enabled_sets_mut() { - s.set_paused(true); - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( - s.adv_id(), - false, - s.adv_timeout(), - s.adv_events(), - ); - pausing_cnt += 1; - } - - if pausing_cnt == 0 { - self.advertisers.set_suspend_mode(SuspendMode::Suspended); - } + self.adv_manager.get_impl().enter_suspend() } /// Exits suspend mode for LE advertising. pub fn advertising_exit_suspend(&mut self) { - for id in self.advertisers.stopped_sets().map(|s| s.adv_id()).collect::>() { - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.unregister(id); - self.advertisers.remove_by_advertiser_id(id as AdvertiserId); - } - for s in self.advertisers.paused_sets_mut() { - s.set_paused(false); - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( - s.adv_id(), - true, - s.adv_timeout(), - s.adv_events(), - ); - } - - self.advertisers.set_suspend_mode(SuspendMode::Normal); + self.adv_manager.get_impl().exit_suspend() } /// Start an active scan on given scanner id. This will look up and assign @@ -1889,6 +1881,10 @@ impl BluetoothGatt { } } } + + pub fn handle_adv_action(&mut self, action: AdvertiserActions) { + self.adv_manager.get_impl().handle_action(action); + } } #[derive(Debug, FromPrimitive, ToPrimitive)] @@ -1909,8 +1905,8 @@ struct ScannerInfo { callback_id: u32, // If the scanner is registered successfully, this contains the scanner id, otherwise None. scanner_id: Option, - // If one of scanners is active, we scan. - is_active: bool, + // If one of scanners is enabled, we scan. + is_enabled: bool, // Scan filter. filter: Option, // Adv monitor handle, if exists. @@ -1926,7 +1922,7 @@ impl ScannerInfo { Self { callback_id, scanner_id: None, - is_active: false, + is_enabled: false, filter: None, monitor_handle: None, is_suspended: false, @@ -1982,6 +1978,10 @@ impl IBluetoothGatt for BluetoothGatt { } fn register_scanner(&mut self, callback_id: u32) -> Uuid128Bit { + if !self.enabled { + return Uuid::empty().uu; + } + let mut bytes: [u8; 16] = [0; 16]; self.small_rng.fill_bytes(&mut bytes); let uuid = Uuid::from(bytes); @@ -2029,7 +2029,7 @@ impl IBluetoothGatt for BluetoothGatt { let settings = settings.unwrap_or_else(|| ScanSettings { interval: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval), window: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow), - scan_type: ScanType::Active, + scan_type: ScanType::default(), }); // Multiplexing scanners happens at this layer. The implementations of start_scan @@ -2039,7 +2039,7 @@ impl IBluetoothGatt for BluetoothGatt { let mut scanners_lock = self.scanners.lock().unwrap(); if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { - scanner.is_active = true; + scanner.is_enabled = true; scanner.filter = filter.clone(); scanner.scan_settings = Some(settings); } else { @@ -2066,7 +2066,7 @@ impl IBluetoothGatt for BluetoothGatt { let mut scanners_lock = self.scanners.lock().unwrap(); if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) { - scanner.is_active = false; + scanner.is_enabled = false; scanner.monitor_handle } else { log::warn!("Scanner {} not found", scanner_id); @@ -2091,14 +2091,14 @@ impl IBluetoothGatt for BluetoothGatt { let _res = gatt_async.msft_adv_monitor_remove(handle).await; } - let has_active_unfiltered_scanner = scanners + let has_enabled_unfiltered_scanner = scanners .lock() .unwrap() .iter() - .any(|(_uuid, scanner)| scanner.is_active && scanner.filter.is_none()); + .any(|(_uuid, scanner)| scanner.is_enabled && scanner.filter.is_none()); if !gatt_async - .msft_adv_monitor_enable(!has_active_unfiltered_scanner) + .msft_adv_monitor_enable(!has_enabled_unfiltered_scanner) .await .map_or(false, |status| status == 0) { @@ -2106,10 +2106,7 @@ impl IBluetoothGatt for BluetoothGatt { } } - let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id) - .map_or(None, |s| s.scan_settings.clone()); - - gatt_async.update_scan(scanner_id, scan_settings).await; + gatt_async.update_scan(scanner_id).await; }); BtStatus::Success @@ -2125,17 +2122,16 @@ impl IBluetoothGatt for BluetoothGatt { &mut self, callback: Box, ) -> u32 { - self.advertisers.add_callback(callback) + self.adv_manager.get_impl().register_callback(callback) } fn unregister_advertiser_callback(&mut self, callback_id: u32) -> bool { - self.advertisers - .remove_callback(callback_id, &mut self.gatt.as_ref().unwrap().lock().unwrap()) + self.adv_manager.get_impl().unregister_callback(callback_id) } fn start_advertising_set( &mut self, - mut parameters: AdvertisingSetParameters, + parameters: AdvertisingSetParameters, advertise_data: AdvertiseData, scan_response: Option, periodic_parameters: Option, @@ -2144,98 +2140,24 @@ impl IBluetoothGatt for BluetoothGatt { max_ext_adv_events: i32, callback_id: u32, ) -> i32 { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return INVALID_REG_ID; - } - - let device_name = self.get_adapter_name(); - let adv_bytes = advertise_data.make_with(&device_name); - let is_le_extended_advertising_supported = match &self.adapter { - Some(adapter) => adapter.lock().unwrap().is_le_extended_advertising_supported(), - _ => false, - }; - // TODO(b/311417973): Remove this once we have more robust /device/bluetooth APIs to control extended advertising - let is_legacy = parameters.is_legacy - && !AdvertiseData::can_upgrade( - &mut parameters, - &adv_bytes, - is_le_extended_advertising_supported, - ); - let params = parameters.into(); - if !AdvertiseData::validate_raw_data(is_legacy, &adv_bytes) { - log::warn!("Failed to start advertising set with invalid advertise data"); - return INVALID_REG_ID; - } - let scan_bytes = - if let Some(d) = scan_response { d.make_with(&device_name) } else { Vec::::new() }; - if !AdvertiseData::validate_raw_data(is_legacy, &scan_bytes) { - log::warn!("Failed to start advertising set with invalid scan response"); - return INVALID_REG_ID; - } - let periodic_params = if let Some(p) = periodic_parameters { - p.into() - } else { - bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default() - }; - let periodic_bytes = - if let Some(d) = periodic_data { d.make_with(&device_name) } else { Vec::::new() }; - if !AdvertiseData::validate_raw_data(false, &periodic_bytes) { - log::warn!("Failed to start advertising set with invalid periodic data"); - return INVALID_REG_ID; - } - let adv_timeout = clamp(duration, 0, 0xffff) as u16; - let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8; - - let reg_id = self.advertisers.new_reg_id(); - let s = AdvertisingSetInfo::new(callback_id, adv_timeout, adv_events, is_legacy, reg_id); - self.advertisers.add(s); - - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.start_advertising_set( - reg_id, - params, - adv_bytes, - scan_bytes, - periodic_params, - periodic_bytes, - adv_timeout, - adv_events, - ); - reg_id + self.adv_manager.get_impl().start_advertising_set( + parameters, + advertise_data, + scan_response, + periodic_parameters, + periodic_data, + duration, + max_ext_adv_events, + callback_id, + ) } fn stop_advertising_set(&mut self, advertiser_id: i32) { - let s = if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - s.clone() - } else { - return; - }; - - if self.advertisers.suspend_mode() != SuspendMode::Normal { - if !s.is_stopped() { - warn!("Deferred advertisement unregistering due to suspending"); - self.advertisers.get_mut_by_advertiser_id(advertiser_id).unwrap().set_stopped(); - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_advertising_set_stopped(advertiser_id); - } - } - return; - } - - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.unregister(s.adv_id()); - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_advertising_set_stopped(advertiser_id); - } - self.advertisers.remove_by_advertiser_id(advertiser_id); + self.adv_manager.get_impl().stop_advertising_set(advertiser_id) } fn get_own_address(&mut self, advertiser_id: i32) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.get_own_address(s.adv_id()); - } + self.adv_manager.get_impl().get_own_address(advertiser_id); } fn enable_advertising_set( @@ -2245,81 +2167,24 @@ impl IBluetoothGatt for BluetoothGatt { duration: i32, max_ext_adv_events: i32, ) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - let adv_timeout = clamp(duration, 0, 0xffff) as u16; - let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8; - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( - s.adv_id(), - enable, - adv_timeout, - adv_events, - ); - } + self.adv_manager.get_impl().enable_advertising_set( + advertiser_id, + enable, + duration, + max_ext_adv_events, + ); } fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - let device_name = self.get_adapter_name(); - let bytes = data.make_with(&device_name); - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) { - log::warn!("Advertiser {}: invalid advertise data to update", advertiser_id); - return; - } - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_data( - s.adv_id(), - false, - bytes, - ); - } + self.adv_manager.get_impl().set_advertising_data(advertiser_id, data); } fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - if !AdvertiseData::validate_raw_data(s.is_legacy(), &data) { - log::warn!("Advertiser {}: invalid raw advertise data to update", advertiser_id); - return; - } - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_data( - s.adv_id(), - false, - data, - ); - } + self.adv_manager.get_impl().set_raw_adv_data(advertiser_id, data); } fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - let device_name = self.get_adapter_name(); - let bytes = data.make_with(&device_name); - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) { - log::warn!("Advertiser {}: invalid scan response to update", advertiser_id); - return; - } - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_data( - s.adv_id(), - true, - bytes, - ); - } + self.adv_manager.get_impl().set_scan_response_data(advertiser_id, data); } fn set_advertising_parameters( @@ -2327,38 +2192,7 @@ impl IBluetoothGatt for BluetoothGatt { advertiser_id: i32, parameters: AdvertisingSetParameters, ) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - let params = parameters.into(); - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - let was_enabled = s.is_enabled(); - if was_enabled { - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( - s.adv_id(), - false, - s.adv_timeout(), - s.adv_events(), - ); - } - self.gatt - .as_ref() - .unwrap() - .lock() - .unwrap() - .advertiser - .set_parameters(s.adv_id(), params); - if was_enabled { - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.enable( - s.adv_id(), - true, - s.adv_timeout(), - s.adv_events(), - ); - } - } + self.adv_manager.get_impl().set_advertising_parameters(advertiser_id, parameters); } fn set_periodic_advertising_parameters( @@ -2366,44 +2200,11 @@ impl IBluetoothGatt for BluetoothGatt { advertiser_id: i32, parameters: PeriodicAdvertisingParameters, ) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - let params = parameters.into(); - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - self.gatt - .as_ref() - .unwrap() - .lock() - .unwrap() - .advertiser - .set_periodic_advertising_parameters(s.adv_id(), params); - } + self.adv_manager.get_impl().set_periodic_advertising_parameters(advertiser_id, parameters); } fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - - let device_name = self.get_adapter_name(); - let bytes = data.make_with(&device_name); - - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - if !AdvertiseData::validate_raw_data(false, &bytes) { - log::warn!("Advertiser {}: invalid periodic data to update", advertiser_id); - return; - } - self.gatt - .as_ref() - .unwrap() - .lock() - .unwrap() - .advertiser - .set_periodic_advertising_data(s.adv_id(), bytes); - } + self.adv_manager.get_impl().set_periodic_advertising_data(advertiser_id, data); } fn set_periodic_advertising_enable( @@ -2412,16 +2213,11 @@ impl IBluetoothGatt for BluetoothGatt { enable: bool, include_adi: bool, ) { - if self.advertisers.suspend_mode() != SuspendMode::Normal { - return; - } - if let Some(s) = self.advertisers.get_by_advertiser_id(advertiser_id) { - self.gatt.as_ref().unwrap().lock().unwrap().advertiser.set_periodic_advertising_enable( - s.adv_id(), - enable, - include_adi, - ); - } + self.adv_manager.get_impl().set_periodic_advertising_enable( + advertiser_id, + enable, + include_adi, + ); } // GATT Client @@ -4342,52 +4138,6 @@ impl BtifGattScannerCallbacks for BluetoothGatt { } } -#[btif_callbacks_dispatcher(dispatch_le_adv_callbacks, GattAdvCallbacks)] -pub(crate) trait BtifGattAdvCallbacks { - #[btif_callback(OnAdvertisingSetStarted)] - fn on_advertising_set_started( - &mut self, - reg_id: i32, - advertiser_id: u8, - tx_power: i8, - status: AdvertisingStatus, - ); - - #[btif_callback(OnAdvertisingEnabled)] - fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus); - - #[btif_callback(OnAdvertisingDataSet)] - fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); - - #[btif_callback(OnScanResponseDataSet)] - fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); - - #[btif_callback(OnAdvertisingParametersUpdated)] - fn on_advertising_parameters_updated( - &mut self, - adv_id: u8, - tx_power: i8, - status: AdvertisingStatus, - ); - - #[btif_callback(OnPeriodicAdvertisingParametersUpdated)] - fn on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus); - - #[btif_callback(OnPeriodicAdvertisingDataSet)] - fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus); - - #[btif_callback(OnPeriodicAdvertisingEnabled)] - fn on_periodic_advertising_enabled( - &mut self, - adv_id: u8, - enabled: bool, - status: AdvertisingStatus, - ); - - #[btif_callback(OnOwnAddressRead)] - fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress); -} - impl BtifGattAdvCallbacks for BluetoothGatt { fn on_advertising_set_started( &mut self, @@ -4396,84 +4146,24 @@ impl BtifGattAdvCallbacks for BluetoothGatt { tx_power: i8, status: AdvertisingStatus, ) { - debug!( - "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}", - reg_id, advertiser_id, tx_power, status + self.adv_manager.get_impl().on_advertising_set_started( + reg_id, + advertiser_id, + tx_power, + status, ); - - if let Some(s) = self.advertisers.get_mut_by_reg_id(reg_id) { - s.set_adv_id(Some(advertiser_id.into())); - s.set_enabled(status == AdvertisingStatus::Success); - } else { - return; - } - let s = self.advertisers.get_mut_by_reg_id(reg_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_advertising_set_started(reg_id, advertiser_id.into(), tx_power.into(), status); - } - - if status != AdvertisingStatus::Success { - warn!( - "on_advertising_set_started(): failed! reg_id = {}, status = {:?}", - reg_id, status - ); - self.advertisers.remove_by_reg_id(reg_id); - } } fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus) { - debug!( - "on_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}", - adv_id, enabled, status - ); - - let advertiser_id: i32 = adv_id.into(); - - if let Some(s) = self.advertisers.get_mut_by_advertiser_id(advertiser_id) { - s.set_enabled(enabled); - } else { - return; - } - - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_advertising_enabled(advertiser_id, enabled, status); - } - - if self.advertisers.suspend_mode() == SuspendMode::Suspending { - if self.advertisers.enabled_sets().count() == 0 { - self.advertisers.set_suspend_mode(SuspendMode::Suspended); - } - } + self.adv_manager.get_impl().on_advertising_enabled(adv_id, enabled, status); } fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { - debug!("on_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); - - let advertiser_id: i32 = adv_id.into(); - if None == self.advertisers.get_by_advertiser_id(advertiser_id) { - return; - } - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_advertising_data_set(advertiser_id, status); - } + self.adv_manager.get_impl().on_advertising_data_set(adv_id, status); } fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { - debug!("on_scan_response_data_set(): adv_id = {}, status = {:?}", adv_id, status); - - let advertiser_id: i32 = adv_id.into(); - if None == self.advertisers.get_by_advertiser_id(advertiser_id) { - return; - } - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_scan_response_data_set(advertiser_id, status); - } + self.adv_manager.get_impl().on_scan_response_data_set(adv_id, status); } fn on_advertising_parameters_updated( @@ -4482,20 +4172,7 @@ impl BtifGattAdvCallbacks for BluetoothGatt { tx_power: i8, status: AdvertisingStatus, ) { - debug!( - "on_advertising_parameters_updated(): adv_id = {}, tx_power = {}, status = {:?}", - adv_id, tx_power, status - ); - - let advertiser_id: i32 = adv_id.into(); - if None == self.advertisers.get_by_advertiser_id(advertiser_id) { - return; - } - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_advertising_parameters_updated(advertiser_id, tx_power.into(), status); - } + self.adv_manager.get_impl().on_advertising_parameters_updated(adv_id, tx_power, status); } fn on_periodic_advertising_parameters_updated( @@ -4503,34 +4180,11 @@ impl BtifGattAdvCallbacks for BluetoothGatt { adv_id: u8, status: AdvertisingStatus, ) { - debug!( - "on_periodic_advertising_parameters_updated(): adv_id = {}, status = {:?}", - adv_id, status - ); - - let advertiser_id: i32 = adv_id.into(); - if None == self.advertisers.get_by_advertiser_id(advertiser_id) { - return; - } - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_periodic_advertising_parameters_updated(advertiser_id, status); - } + self.adv_manager.get_impl().on_periodic_advertising_parameters_updated(adv_id, status); } fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) { - debug!("on_periodic_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); - - let advertiser_id: i32 = adv_id.into(); - if None == self.advertisers.get_by_advertiser_id(advertiser_id) { - return; - } - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_periodic_advertising_data_set(advertiser_id, status); - } + self.adv_manager.get_impl().on_periodic_advertising_data_set(adv_id, status); } fn on_periodic_advertising_enabled( @@ -4539,37 +4193,11 @@ impl BtifGattAdvCallbacks for BluetoothGatt { enabled: bool, status: AdvertisingStatus, ) { - debug!( - "on_periodic_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}", - adv_id, enabled, status - ); - - let advertiser_id: i32 = adv_id.into(); - if None == self.advertisers.get_by_advertiser_id(advertiser_id) { - return; - } - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_periodic_advertising_enabled(advertiser_id, enabled, status); - } + self.adv_manager.get_impl().on_periodic_advertising_enabled(adv_id, enabled, status); } fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress) { - debug!( - "on_own_address_read(): adv_id = {}, addr_type = {}, address = {:?}", - adv_id, addr_type, address - ); - - let advertiser_id: i32 = adv_id.into(); - if None == self.advertisers.get_by_advertiser_id(advertiser_id) { - return; - } - let s = self.advertisers.get_by_advertiser_id(advertiser_id).unwrap().clone(); - - if let Some(cb) = self.advertisers.get_callback(&s) { - cb.on_own_address_read(advertiser_id, addr_type.into(), address.to_string()); - } + self.adv_manager.get_impl().on_own_address_read(adv_id, addr_type, address); } } diff --git a/system/gd/rust/linux/stack/src/bluetooth_logging.rs b/system/gd/rust/linux/stack/src/bluetooth_logging.rs index 2fbd181d5e1c83361820f4afdfc314fee235c8f8..aa2a0c0e189b832ca933ff742c9be142f4969a78 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_logging.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_logging.rs @@ -1,10 +1,16 @@ -use bt_common::init_flags; +//! Modify the Bluetooth logging configuration to enable debug logging. +//! +//! There are two logging implementations depending on whether the log is +//! emitted from Rust or C/C++. In order to keep log levels in sync between the +//! two, the |BluetoothLogging| struct will configure both the Rust logging and +//! the C/C++ logging (via topshim). +use bt_topshim::syslog::{set_default_log_level, set_log_level_for_tag, Level}; use log::LevelFilter; use syslog::{BasicLogger, Error, Facility, Formatter3164}; use log_panics; -/// API to modify log levels. +/// API to modify log levels that is exposed via RPC. pub trait IBluetoothLogging { /// Check whether debug logging is enabled. fn is_debug_enabled(&self) -> bool; @@ -15,15 +21,34 @@ pub trait IBluetoothLogging { /// Logging related implementation. pub struct BluetoothLogging { + /// Should debug logs be emitted? is_debug: bool, + + /// If this flag is not set, we will not emit debug logs for all tags. + /// `VERBOSE_ONLY_LOG_TAGS` will be set to emit up to `INFO` only. This + /// can only be configured in the constructor (not modifiable at runtime). + is_verbose_debug: bool, + + /// Log to stderr? is_stderr: bool, + + /// Is logging already initialized? is_initialized: bool, } +const VERBOSE_ONLY_LOG_TAGS: &[&str] = &[ + "bt_bta_av", // AV apis + "btm_sco", // SCO data path logs + "l2c_csm", // L2CAP state machine + "l2c_link", // L2CAP link layer logs + "sco_hci", // SCO over HCI + "uipc", // Userspace IPC implementation +]; + impl BluetoothLogging { - pub fn new(is_debug: bool, log_output: &str) -> Self { + pub fn new(is_debug: bool, is_verbose_debug: bool, log_output: &str) -> Self { let is_stderr = log_output == "stderr"; - Self { is_debug, is_stderr, is_initialized: false } + Self { is_debug, is_verbose_debug, is_stderr, is_initialized: false } } pub fn initialize(&mut self) -> Result<(), Error> { @@ -44,9 +69,31 @@ impl BluetoothLogging { .map(|()| log::set_max_level(level)); log_panics::init(); } + + // Set initial log levels and filter out tags if not verbose debug. + set_default_log_level(self.get_libbluetooth_level()); + if self.is_debug && !self.is_verbose_debug { + for tag in VERBOSE_ONLY_LOG_TAGS { + set_log_level_for_tag(tag, Level::Info); + } + } + + // Initialize the underlying system as well. self.is_initialized = true; Ok(()) } + + fn get_libbluetooth_level(&self) -> Level { + if self.is_debug { + if self.is_verbose_debug { + Level::Verbose + } else { + Level::Debug + } + } else { + Level::Info + } + } } impl IBluetoothLogging for BluetoothLogging { @@ -66,9 +113,8 @@ impl IBluetoothLogging for BluetoothLogging { log::set_max_level(level); // Update log level in libbluetooth. - let level = - if self.is_debug { init_flags::LOG_TAG_DEBUG } else { init_flags::LOG_TAG_INFO }; - init_flags::update_default_log_level(level); + let level = self.get_libbluetooth_level(); + set_default_log_level(level); // Mark the start of debug logging with a debug print. if self.is_debug { diff --git a/system/gd/rust/linux/stack/src/bluetooth_media.rs b/system/gd/rust/linux/stack/src/bluetooth_media.rs index e96c882f0612b339d8711f4b54f8d759ff455d3a..4c93aa4dc67c2daf161f765999b47e3c68cd5a27 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_media.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_media.rs @@ -14,9 +14,9 @@ use bt_topshim::profiles::avrcp::{ }; use bt_topshim::profiles::hfp::interop_insert_call_when_sco_start; use bt_topshim::profiles::hfp::{ - BthfAudioState, BthfConnectionState, CallHoldCommand, CallInfo, CallSource, CallState, Hfp, - HfpCallbacks, HfpCallbacksDispatcher, HfpCodecCapability, HfpCodecId, PhoneState, - TelephonyDeviceStatus, + BthfAudioState, BthfConnectionState, CallHoldCommand, CallInfo, CallSource, CallState, + EscoCodingFormat, Hfp, HfpCallbacks, HfpCallbacksDispatcher, HfpCodecBitId, HfpCodecFormat, + HfpCodecId, PhoneState, TelephonyDeviceStatus, }; use bt_topshim::profiles::ProfileConnectionState; use bt_topshim::{metrics, topstack}; @@ -129,7 +129,7 @@ pub trait IBluetoothMedia { &mut self, address: String, sco_offload: bool, - disabled_codecs: HfpCodecCapability, + disabled_codecs: HfpCodecBitId, ) -> bool; fn stop_sco_call(&mut self, address: String); @@ -247,7 +247,7 @@ pub struct BluetoothAudioDevice { pub address: String, pub name: String, pub a2dp_caps: Vec, - pub hfp_cap: HfpCodecCapability, + pub hfp_cap: HfpCodecFormat, pub absolute_volume: bool, } @@ -256,7 +256,7 @@ impl BluetoothAudioDevice { address: String, name: String, a2dp_caps: Vec, - hfp_cap: HfpCodecCapability, + hfp_cap: HfpCodecFormat, absolute_volume: bool, ) -> BluetoothAudioDevice { BluetoothAudioDevice { address, name, a2dp_caps, hfp_cap, absolute_volume } @@ -304,7 +304,7 @@ pub struct BluetoothMedia { hfp_states: HashMap, hfp_audio_state: HashMap, a2dp_caps: HashMap>, - hfp_cap: HashMap, + hfp_cap: HashMap, fallback_tasks: Arc, Instant)>>>>, absolute_volume: bool, uinput: UInput, @@ -711,7 +711,7 @@ impl BluetoothMedia { // The device may not support codec-negotiation, // in which case we shall assume it supports CVSD at this point. if !self.hfp_cap.contains_key(&addr) { - self.hfp_cap.insert(addr, HfpCodecCapability::CVSD); + self.hfp_cap.insert(addr, HfpCodecFormat::CVSD); } self.add_connected_profile(addr, uuid::Profile::Hfp); @@ -719,11 +719,7 @@ impl BluetoothMedia { // This is only used for Bluetooth HFP qualification. if self.mps_qualification_enabled && self.phone_state.num_active > 0 { debug!("[{}]: Connect SCO due to active call.", DisplayAddress(&addr)); - self.start_sco_call_impl( - addr.to_string(), - false, - HfpCodecCapability::NONE, - ); + self.start_sco_call_impl(addr.to_string(), false, HfpCodecBitId::NONE); } self.uhid_create(addr); @@ -910,32 +906,55 @@ impl BluetoothMedia { .set_battery_info(self.battery_provider_id, battery_set); } HfpCallbacks::WbsCapsUpdate(wbs_supported, addr) => { + let is_transparent_coding_format_supported = match &self.adapter { + Some(adapter) => adapter + .lock() + .unwrap() + .is_coding_format_supported(EscoCodingFormat::TRANSPARENT), + _ => false, + }; + + let is_msbc_coding_format_supported = match &self.adapter { + Some(adapter) => { + adapter.lock().unwrap().is_coding_format_supported(EscoCodingFormat::MSBC) + } + _ => false, + }; + + let mut codec_diff = HfpCodecFormat::NONE; + if is_transparent_coding_format_supported { + codec_diff |= HfpCodecFormat::MSBC_TRANSPARENT; + } + if is_msbc_coding_format_supported { + codec_diff |= HfpCodecFormat::MSBC; + } + if let Some(cur_hfp_cap) = self.hfp_cap.get_mut(&addr) { if wbs_supported { - *cur_hfp_cap |= HfpCodecCapability::MSBC; - } else if (*cur_hfp_cap & HfpCodecCapability::MSBC) == HfpCodecCapability::MSBC - { - *cur_hfp_cap ^= HfpCodecCapability::MSBC; + *cur_hfp_cap |= codec_diff; + } else { + *cur_hfp_cap &= !codec_diff; } } else { let new_hfp_cap = match wbs_supported { - true => HfpCodecCapability::CVSD | HfpCodecCapability::MSBC, - false => HfpCodecCapability::CVSD, + true => HfpCodecFormat::CVSD | codec_diff, + false => HfpCodecFormat::CVSD, }; self.hfp_cap.insert(addr, new_hfp_cap); } } HfpCallbacks::SwbCapsUpdate(swb_supported, addr) => { + // LC3 can be propagated to this point only if adapter supports transparent mode. if let Some(cur_hfp_cap) = self.hfp_cap.get_mut(&addr) { if swb_supported { - *cur_hfp_cap |= HfpCodecCapability::LC3; - } else if (*cur_hfp_cap & HfpCodecCapability::LC3) == HfpCodecCapability::LC3 { - *cur_hfp_cap ^= HfpCodecCapability::LC3; + *cur_hfp_cap |= HfpCodecFormat::LC3_TRANSPARENT; + } else { + *cur_hfp_cap &= !HfpCodecFormat::LC3_TRANSPARENT; } } else { let new_hfp_cap = match swb_supported { - true => HfpCodecCapability::CVSD | HfpCodecCapability::LC3, - false => HfpCodecCapability::CVSD, + true => HfpCodecFormat::CVSD | HfpCodecFormat::LC3_TRANSPARENT, + false => HfpCodecFormat::CVSD, }; self.hfp_cap.insert(addr, new_hfp_cap); } @@ -994,7 +1013,7 @@ impl BluetoothMedia { if self.mps_qualification_enabled { debug!("[{}]: Start SCO call due to ATA", DisplayAddress(&addr)); - self.start_sco_call_impl(addr.to_string(), false, HfpCodecCapability::NONE); + self.start_sco_call_impl(addr.to_string(), false, HfpCodecBitId::NONE); } self.uhid_send_input_report(&addr); } @@ -1599,7 +1618,7 @@ impl BluetoothMedia { addr.to_string(), name.clone(), cur_a2dp_caps.unwrap_or(&Vec::new()).to_vec(), - *cur_hfp_cap.unwrap_or(&HfpCodecCapability::NONE), + *cur_hfp_cap.unwrap_or(&HfpCodecFormat::NONE), absolute_volume, ); @@ -1799,7 +1818,7 @@ impl BluetoothMedia { &mut self, address: String, sco_offload: bool, - disabled_codecs: HfpCodecCapability, + disabled_codecs: HfpCodecBitId, ) -> bool { match (|| -> Result<(), &str> { let addr = RawAddress::from_string(address.clone()) @@ -2756,7 +2775,7 @@ impl IBluetoothMedia for BluetoothMedia { &mut self, address: String, sco_offload: bool, - disabled_codecs: HfpCodecCapability, + disabled_codecs: HfpCodecBitId, ) -> bool { self.start_sco_call_impl(address, sco_offload, disabled_codecs) } @@ -2791,16 +2810,33 @@ impl IBluetoothMedia for BluetoothMedia { match self.hfp_audio_state.get(&addr) { Some(BthfAudioState::Connected) => match self.hfp_cap.get(&addr) { - Some(caps) if (*caps & HfpCodecCapability::LC3) == HfpCodecCapability::LC3 => 4, - Some(caps) if (*caps & HfpCodecCapability::MSBC) == HfpCodecCapability::MSBC => 2, - Some(caps) if (*caps & HfpCodecCapability::CVSD) == HfpCodecCapability::CVSD => 1, + Some(caps) + if (*caps & HfpCodecFormat::LC3_TRANSPARENT) + == HfpCodecFormat::LC3_TRANSPARENT => + { + HfpCodecBitId::LC3 + } + Some(caps) if (*caps & HfpCodecFormat::MSBC) == HfpCodecFormat::MSBC => { + HfpCodecBitId::MSBC + } + Some(caps) + if (*caps & HfpCodecFormat::MSBC_TRANSPARENT) + == HfpCodecFormat::MSBC_TRANSPARENT => + { + HfpCodecBitId::MSBC + } + Some(caps) if (*caps & HfpCodecFormat::CVSD) == HfpCodecFormat::CVSD => { + HfpCodecBitId::CVSD + } _ => { warn!("hfp_cap not found, fallback to CVSD."); - 1 + HfpCodecBitId::CVSD } }, - _ => 0, + _ => HfpCodecBitId::NONE, } + .try_into() + .unwrap() } fn get_presentation_position(&mut self) -> PresentationPosition { @@ -3029,7 +3065,7 @@ impl IBluetoothTelephony for BluetoothMedia { } }) { info!("Start SCO call due to call answered"); - self.start_sco_call_impl(addr.to_string(), false, HfpCodecCapability::NONE); + self.start_sco_call_impl(addr.to_string(), false, HfpCodecBitId::NONE); } } @@ -3090,7 +3126,7 @@ impl IBluetoothTelephony for BluetoothMedia { } fn audio_connect(&mut self, address: String) -> bool { - self.start_sco_call_impl(address, false, HfpCodecCapability::NONE) + self.start_sco_call_impl(address, false, HfpCodecBitId::NONE) } fn audio_disconnect(&mut self, address: String) { diff --git a/system/gd/rust/linux/stack/src/lib.rs b/system/gd/rust/linux/stack/src/lib.rs index 12810d23ea50d485788490e1e425357246b4837e..6616b2d9df6a025525f4d46d1c821e75ccfbdb54 100644 --- a/system/gd/rust/linux/stack/src/lib.rs +++ b/system/gd/rust/linux/stack/src/lib.rs @@ -35,10 +35,10 @@ use crate::bluetooth::{ BluetoothDevice, DelayedActions, IBluetooth, }; use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin}; +use crate::bluetooth_adv::{dispatch_le_adv_callbacks, AdvertiserActions}; use crate::bluetooth_gatt::{ - dispatch_gatt_client_callbacks, dispatch_gatt_server_callbacks, dispatch_le_adv_callbacks, - dispatch_le_scanner_callbacks, dispatch_le_scanner_inband_callbacks, BluetoothGatt, - GattActions, + dispatch_gatt_client_callbacks, dispatch_gatt_server_callbacks, dispatch_le_scanner_callbacks, + dispatch_le_scanner_inband_callbacks, BluetoothGatt, GattActions, }; use crate::bluetooth_media::{BluetoothMedia, MediaActions}; use crate::dis::{DeviceInformation, ServiceCallbacks}; @@ -63,8 +63,11 @@ use bt_topshim::{ /// Message types that are sent to the stack main dispatch loop. pub enum Message { - // Shuts down the stack. - Shutdown, + /// Remove the DBus API. Call it before other AdapterShutdown. + InterfaceShutdown, + /// Disable the adapter by calling btif disable. + AdapterShutdown, + /// Clean up the adapter by calling btif cleanup. Cleanup, // Adapter is enabled and ready. @@ -113,6 +116,7 @@ pub enum Message { // Advertising related AdvertiserCallbackDisconnected(u32), + AdvertiserActions(AdvertiserActions), SocketManagerActions(SocketActions), SocketManagerCallbackDisconnected(u32), @@ -164,8 +168,12 @@ pub enum BluetoothAPI { Gatt, } +/// Message types that are sent to the InterfaceManager's dispatch loop. pub enum APIMessage { + /// Indicates a subcomponent is ready to receive DBus messages. IsReady(BluetoothAPI), + /// Indicates bluetooth is shutting down, so we remove all DBus endpoints. + ShutDown, } /// Represents suspend mode of a module. @@ -192,6 +200,7 @@ impl Stack { /// Runs the main dispatch loop. pub async fn dispatch( mut rx: Receiver, + api_tx: Sender, bluetooth: Arc>>, bluetooth_gatt: Arc>>, battery_service: Arc>>, @@ -213,7 +222,14 @@ impl Stack { } match m.unwrap() { - Message::Shutdown => { + Message::InterfaceShutdown => { + let tx = api_tx.clone(); + tokio::spawn(async move { + let _ = tx.send(APIMessage::ShutDown).await; + }); + } + + Message::AdapterShutdown => { bluetooth.lock().unwrap().disable(); } @@ -352,6 +368,10 @@ impl Stack { bluetooth_gatt.lock().unwrap().remove_adv_callback(id); } + Message::AdvertiserActions(action) => { + bluetooth_gatt.lock().unwrap().handle_adv_action(action); + } + Message::SocketManagerActions(action) => { bluetooth_socketmgr.lock().unwrap().handle_actions(action); } diff --git a/system/gd/rust/linux/stack/src/suspend.rs b/system/gd/rust/linux/stack/src/suspend.rs index 221ae2ae226d4a6394f945e1a5924c32215a0b7f..99971ebc32d7d9f4f9154f15a6021da7d685bc31 100644 --- a/system/gd/rust/linux/stack/src/suspend.rs +++ b/system/gd/rust/linux/stack/src/suspend.rs @@ -7,6 +7,7 @@ use crate::bluetooth_media::BluetoothMedia; use crate::callbacks::Callbacks; use crate::{BluetoothGatt, Message, RPCProxy}; use bt_topshim::btif::{BluetoothInterface, BtDiscMode}; +use bt_topshim::metrics; use log::warn; use num_derive::{FromPrimitive, ToPrimitive}; use std::sync::{Arc, Mutex}; @@ -292,6 +293,22 @@ impl ISuspend for Suspend { } fn resume(&mut self) -> bool { + // Suspend ID state 0: NoRecord, 1: Recorded + let suspend_id_state = match self.suspend_state.lock().unwrap().suspend_id { + None => { + log::error!("No suspend id saved at resume."); + 0 + } + Some(_) => 1, + }; + metrics::suspend_complete_state(suspend_id_state); + // If no suspend id is saved here, it means floss did not receive the SuspendImminent + // signal and as a result, the suspend flow was not run. + // Skip the resume flow and return after logging the metrics. + if suspend_id_state == 0 { + return true; + } + let hci_index = self.bt.lock().unwrap().get_hci_index(); notify_suspend_state(hci_index, false); diff --git a/system/gd/rust/shim/Cargo.toml b/system/gd/rust/shim/Cargo.toml index 01d508907bc2ddbbf00e4748c880ae1b32d133ee..00cee221a750bb8854b04c12c8df00bbef44f0c7 100644 --- a/system/gd/rust/shim/Cargo.toml +++ b/system/gd/rust/shim/Cargo.toml @@ -31,8 +31,8 @@ bytes = "1.0" cxx = { version = "1.0.42", features = ["c++17"] } env_logger = "0.8" futures = "0.3" -grpcio = { version = "0.9", features = ["protobuf", "protobuf-codec", "openssl"] } -grpcio-sys = { version = "0.9", features = ["openssl"] } +grpcio = { version = "0.13.0", default-features = false, features = ["protobufv3-codec", "openssl"] } +grpcio-sys = { version = "0.13.0", features = ["openssl"] } lazy_static = "1.4" log = "0.4" nix = "0.23" @@ -41,9 +41,8 @@ num-traits = "0.2" pdl-runtime = "0.2.2" paste = "1.0" proc-macro2 = "1.0.24" -protobuf = "2.0" -protoc-grpcio = "2.0" -protoc-rust = "2.0" +protobuf = "3.2" +protoc-grpcio = "3.0" quote = "1.0.8" thiserror = "1.0" syn = { version = "2.0.1", features = ['default', 'full'] } diff --git a/system/gd/rust/shim/src/init_flags.rs b/system/gd/rust/shim/src/init_flags.rs index d2275cfaa8bfc45702ffdf58149bbd3f9e25c3fc..4017057fb164c9cd8e9940737e5c229bef0fe026 100644 --- a/system/gd/rust/shim/src/init_flags.rs +++ b/system/gd/rust/shim/src/init_flags.rs @@ -25,16 +25,13 @@ mod ffi { fn dynamic_avrcp_version_enhancement_is_enabled() -> bool; fn gatt_robust_caching_client_is_enabled() -> bool; fn gatt_robust_caching_server_is_enabled() -> bool; - fn get_default_log_level() -> i32; fn get_hci_adapter() -> i32; - fn get_log_level_for_tag(tag: &str) -> i32; fn get_asha_packet_drop_frequency_threshold() -> i32; fn get_asha_phy_update_retry_limit() -> i32; fn hfp_dynamic_version_is_enabled() -> bool; fn irk_rotation_is_enabled() -> bool; fn leaudio_targeted_announcement_reconnection_mode_is_enabled() -> bool; fn pbap_pse_dynamic_version_upgrade_is_enabled() -> bool; - fn periodic_advertising_adi_is_enabled() -> bool; fn private_gatt_is_enabled() -> bool; fn redact_log_is_enabled() -> bool; fn rust_event_loop_is_enabled() -> bool; @@ -45,7 +42,6 @@ mod ffi { fn bluetooth_quality_report_callback_is_enabled() -> bool; fn set_min_encryption_is_enabled() -> bool; fn subrating_is_enabled() -> bool; - fn trigger_advertising_callbacks_on_first_resume_after_pause_is_enabled() -> bool; fn use_unified_connection_manager_is_enabled() -> bool; fn sdp_return_classic_services_when_le_discovery_fails_is_enabled() -> bool; fn use_rsi_from_cached_inqiry_results_is_enabled() -> bool; diff --git a/system/gd/rust/stack/Cargo.toml b/system/gd/rust/stack/Cargo.toml index 13c3c3209baf7c9cb260a61686e20ce30b6e3007..d1dda7058974f9ae27e10616ee93446e66913820 100644 --- a/system/gd/rust/stack/Cargo.toml +++ b/system/gd/rust/stack/Cargo.toml @@ -30,13 +30,13 @@ gddi = { path = "../gddi" } bytes = "1.0" cxx = "1.0" futures = "0.3" -grpcio = "0.9" +grpcio = { version = "0.13.0", default-features = false, features = ["protobufv3-codec", "openssl"] } lazy_static = "1.4" log = "0.4" nix = "0.23" num-traits = "0.2" pdl-runtime = "0.2.2" -protobuf = "2.0" +protobuf = "3.2" thiserror = "1.0" tokio = "1.0" tokio-stream = "0.1" diff --git a/system/gd/rust/stack/src/hal/ffi/hidl.cc b/system/gd/rust/stack/src/hal/ffi/hidl.cc index fd8e1710092dc628cdf9667256b6d8045859b942..60c7dbf62bca379a4a3909a3fe5a1c4081d8053e 100644 --- a/system/gd/rust/stack/src/hal/ffi/hidl.cc +++ b/system/gd/rust/stack/src/hal/ffi/hidl.cc @@ -5,7 +5,7 @@ #include #include -#include "gd/os/log.h" +#include "os/log.h" using ::android::hardware::hidl_vec; using ::android::hardware::Return; diff --git a/system/gd/rust/topshim/Android.bp b/system/gd/rust/topshim/Android.bp index 5f3e6e8f7960f9fddabc9e2c015d3652f66dc4c8..17b551844595bbe33d8b36932c981fd32ccaf9b8 100644 --- a/system/gd/rust/topshim/Android.bp +++ b/system/gd/rust/topshim/Android.bp @@ -70,7 +70,10 @@ cc_library_static { "packages/modules/Bluetooth/system/types", ], host_supported: true, - static_libs: ["libchrome"], + static_libs: [ + "libbluetooth_log", + "libchrome", + ], } gensrcs { @@ -138,6 +141,9 @@ rust_bindgen { shared_libs: [ "libc++", ], + static_libs: [ + "libbluetooth_log", + ], // The bindgen rule can only include headers via header_libs and does not // support include_dirs. Make sure newly added headers have the correct // header export target listed here. diff --git a/system/gd/rust/topshim/BUILD.gn b/system/gd/rust/topshim/BUILD.gn index cde636eff0b0ccbdfa3e66a2b83edd10c3e6831a..f9c5aea3dc43d0f7db83bb14e50d4290cbd09961 100644 --- a/system/gd/rust/topshim/BUILD.gn +++ b/system/gd/rust/topshim/BUILD.gn @@ -48,7 +48,10 @@ cxxbridge_cc("btif_bridge_code") { ":btif_bridge_header", "//bt/system/pdl:BluetoothGeneratedPackets_h", ] - configs = [ "//bt/system/gd:gd_defaults" ] + configs = [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } source_set("btif_cxx_bridge_code") { @@ -69,7 +72,10 @@ source_set("btif_cxx_bridge_code") { "//bt/system/gd/metrics:BluetoothMetricsSources", "//bt/system/pdl:BluetoothGeneratedPackets_h", ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } cxxbridge_libheader("cxxlibheader") { diff --git a/system/gd/rust/topshim/btav/btav_shim.cc b/system/gd/rust/topshim/btav/btav_shim.cc index 14a88b38caeb67a6f7ba3b24eb09db60a2831a62..2ebed73deb60a3db0aa41b412f7d581570e7838b 100644 --- a/system/gd/rust/topshim/btav/btav_shim.cc +++ b/system/gd/rust/topshim/btav/btav_shim.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "gd/rust/topshim/btav/btav_shim.h" +#include "rust/topshim/btav/btav_shim.h" #include #include @@ -276,7 +276,8 @@ std::unique_ptr GetA2dpProfile(const unsigned char* btif) { int A2dpIntf::init() const { std::vector a; std::vector b; - return intf_->init(&internal::g_callbacks, 1, a, b); + std::vector c; + return intf_->init(&internal::g_callbacks, 1, a, b, &c); } uint32_t A2dpIntf::connect(RawAddress addr) const { diff --git a/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc b/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc index d2a42a8056e314cc169d18be8e440f1362831fe6..9bcb3389365e6d3a23a7f66a1f9aee58ec798082 100644 --- a/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc +++ b/system/gd/rust/topshim/btav_sink/btav_sink_shim.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "gd/rust/topshim/btav_sink/btav_sink_shim.h" +#include "rust/topshim/btav_sink/btav_sink_shim.h" #include diff --git a/system/gd/rust/topshim/btav_sink/btav_sink_shim.h b/system/gd/rust/topshim/btav_sink/btav_sink_shim.h index 1aa2f53d892c7963bc7a1d3beb18e1e67c0eb669..900fdf0b36aacaffeb9548e2b4f5c505c55a6d55 100644 --- a/system/gd/rust/topshim/btav_sink/btav_sink_shim.h +++ b/system/gd/rust/topshim/btav_sink/btav_sink_shim.h @@ -18,9 +18,9 @@ #include -#include "gd/rust/topshim/btav_sink/btav_sink_shim.h" #include "include/hardware/bt_av.h" #include "rust/cxx.h" +#include "rust/topshim/btav_sink/btav_sink_shim.h" #include "types/raw_address.h" namespace bluetooth { diff --git a/system/gd/rust/topshim/btif/btif_shim.cc b/system/gd/rust/topshim/btif/btif_shim.cc index 8529605bac0b085ce5eb375c4261b6cdf4b8a607..82cb32ea1993380bf6e0a81171de30778eedc046 100644 --- a/system/gd/rust/topshim/btif/btif_shim.cc +++ b/system/gd/rust/topshim/btif/btif_shim.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "gd/rust/topshim/btif/btif_shim.h" +#include "rust/topshim/btif/btif_shim.h" #include #include diff --git a/system/gd/rust/topshim/build.rs b/system/gd/rust/topshim/build.rs index c7cacdf3a8d2e6a1cdb6c55ff3580382930f2f71..ad646e085e61dcc1c4c6efde9aa2cb489b15428f 100644 --- a/system/gd/rust/topshim/build.rs +++ b/system/gd/rust/topshim/build.rs @@ -21,6 +21,7 @@ fn main() { "/system/btcore", "/system/include", "/system/include/hardware", + "/system/log/include", "/system/types", ]; diff --git a/system/gd/rust/topshim/controller/controller_shim.cc b/system/gd/rust/topshim/controller/controller_shim.cc index b20d97c0e8d0b50c49961cb7205b12e5e42cd3e7..3ee9086c3268ccb322851dd096548d96680474c8 100644 --- a/system/gd/rust/topshim/controller/controller_shim.cc +++ b/system/gd/rust/topshim/controller/controller_shim.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "gd/rust/topshim/controller/controller_shim.h" +#include "rust/topshim/controller/controller_shim.h" #include @@ -43,6 +43,13 @@ RawAddress ControllerIntf::read_local_addr() const { return *controller_->get_address(); } +uint64_t ControllerIntf::get_ble_supported_states() const { + if (!controller_) std::abort(); + uint64_t states; + memcpy(&states, controller_->get_ble_supported_states(), sizeof(uint64_t)); + return states; +} + } // namespace rust } // namespace topshim } // namespace bluetooth diff --git a/system/gd/rust/topshim/controller/controller_shim.h b/system/gd/rust/topshim/controller/controller_shim.h index 35fcf24749123ad0321927c231bb26819bd56e8e..275824ad669465b037ef1f73720a69614988e158 100644 --- a/system/gd/rust/topshim/controller/controller_shim.h +++ b/system/gd/rust/topshim/controller/controller_shim.h @@ -32,6 +32,7 @@ class ControllerIntf { ~ControllerIntf(); RawAddress read_local_addr() const; + uint64_t get_ble_supported_states() const; private: const controller_t* controller_; diff --git a/system/gd/rust/topshim/facade/Android.bp b/system/gd/rust/topshim/facade/Android.bp index 09748982de5d4f5ee44fc1ec0ac6b6ed1823055e..bdbe1275b49f3795e2544165c8723e7e4f34dfc9 100644 --- a/system/gd/rust/topshim/facade/Android.bp +++ b/system/gd/rust/topshim/facade/Android.bp @@ -44,16 +44,20 @@ rust_defaults { "libFraunhoferAAC", "libaudio-a2dp-hw-utils", "libbluetooth-dumpsys", + "libbluetooth-gdx", "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_crypto_toolbox", "libbluetooth_gd", // Gabeldorsche + "libbluetooth_log", + "libbt-audio-asrc", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", "libbt-btu-main-thread", "libbt-common", "libbt-hci", + "libbt-jni-thread", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", diff --git a/system/gd/rust/topshim/facade/src/gatt_service.rs b/system/gd/rust/topshim/facade/src/gatt_service.rs index 081fb9833a7f8d25d61f8e88eca1d0d5dca1a6ca..73a5bc29c8bc01639295e6dcb4ab295052c2893b 100644 --- a/system/gd/rust/topshim/facade/src/gatt_service.rs +++ b/system/gd/rust/topshim/facade/src/gatt_service.rs @@ -364,7 +364,7 @@ impl GattService for GattServiceImpl { fn set_scan_parameters(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink) { let scanner = &mut self.gatt.lock().unwrap().scanner; - scanner.set_scan_parameters(0, 0, 0); + scanner.set_scan_parameters(0, 0, 0, 0); ctx.spawn(async move { sink.success(Empty::default()).await.unwrap(); }) diff --git a/system/gd/rust/topshim/gatt/gatt_ble_advertiser_shim.cc b/system/gd/rust/topshim/gatt/gatt_ble_advertiser_shim.cc index cb5b6d58493b5c6c1a84f3e138b876855406583c..73649a74ec3f7a125cc6ce985d97e5e89d20b6dd 100644 --- a/system/gd/rust/topshim/gatt/gatt_ble_advertiser_shim.cc +++ b/system/gd/rust/topshim/gatt/gatt_ble_advertiser_shim.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "gd/rust/topshim/gatt/gatt_ble_advertiser_shim.h" +#include "rust/topshim/gatt/gatt_ble_advertiser_shim.h" #include #include 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 bc4f311fb408bb3ad77714447326391632a813e5..e8f5019a1e37e68e1f962d9fe786f357e95f7725 100644 --- a/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc +++ b/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "gd/rust/topshim/gatt/gatt_ble_scanner_shim.h" +#include "rust/topshim/gatt/gatt_ble_scanner_shim.h" #include #include @@ -272,9 +272,11 @@ void BleScannerIntf::MsftAdvMonitorEnable(uint32_t call_id, bool enable) { enable, base::Bind(&BleScannerIntf::OnMsftAdvMonitorEnableCallback, base::Unretained(this), call_id)); } -void BleScannerIntf::SetScanParameters(uint8_t scanner_id, uint16_t scan_interval, uint16_t scan_window) { +void BleScannerIntf::SetScanParameters( + uint8_t scanner_id, uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window) { scanner_intf_->SetScanParameters( scanner_id, + scan_type, scan_interval, scan_window, base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id)); 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 7011ae32b59380fd683d100ab857282e09828466..75bb38fc6efc7ce6337d3833b23a3ddfe6fe2f77 100644 --- a/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.h +++ b/system/gd/rust/topshim/gatt/gatt_ble_scanner_shim.h @@ -117,7 +117,8 @@ class BleScannerIntf : public ScanningCallbacks { // 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); + void SetScanParameters( + uint8_t scanner_id, uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window); // Configure the batchscan storage and get a response via |OnStatusCallback|. void BatchscanConfigStorage( diff --git a/system/gd/rust/topshim/gatt/gatt_shim.cc b/system/gd/rust/topshim/gatt/gatt_shim.cc index 1439e8241d77acf1cf27b1c2bba99160ceeb7c1a..1fcf175c5caae95656e4f7965476f27c06dac00c 100644 --- a/system/gd/rust/topshim/gatt/gatt_shim.cc +++ b/system/gd/rust/topshim/gatt/gatt_shim.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "gd/rust/topshim/gatt/gatt_shim.h" +#include "rust/topshim/gatt/gatt_shim.h" #include "base/functional/bind.h" #include "base/functional/callback.h" diff --git a/system/gd/rust/topshim/hfp/hfp_shim.cc b/system/gd/rust/topshim/hfp/hfp_shim.cc index a98d7949627dfa680fc93e381f5c106a1293dbc1..30cb6232da57ac68f057e99a12959d88f4a846cf 100644 --- a/system/gd/rust/topshim/hfp/hfp_shim.cc +++ b/system/gd/rust/topshim/hfp/hfp_shim.cc @@ -14,13 +14,13 @@ * limitations under the License. */ -#include "gd/rust/topshim/hfp/hfp_shim.h" +#include "rust/topshim/hfp/hfp_shim.h" #include "btif/include/btif_hf.h" +#include "common/strings.h" #include "device/include/interop.h" -#include "gd/common/strings.h" -#include "gd/os/log.h" #include "include/hardware/bt_hf.h" +#include "os/log.h" #include "src/profiles/hfp.rs.h" #include "types/raw_address.h" diff --git a/system/gd/rust/topshim/metrics/metrics_shim.cc b/system/gd/rust/topshim/metrics/metrics_shim.cc index ffc746a17177a92d0cb4125bc8ee00bb213a3432..2e9b01944e8f951d2713339dce70c540262fdb7d 100644 --- a/system/gd/rust/topshim/metrics/metrics_shim.cc +++ b/system/gd/rust/topshim/metrics/metrics_shim.cc @@ -14,9 +14,9 @@ * limitations under the License. */ -#include "gd/rust/topshim/metrics/metrics_shim.h" +#include "rust/topshim/metrics/metrics_shim.h" -#include "gd/metrics/metrics.h" +#include "metrics/metrics.h" #include "src/metrics.rs.h" #include "types/raw_address.h" @@ -65,6 +65,10 @@ void acl_connection_state_changed( metrics::LogMetricsAclConnectionStateChanged(&addr, transport, status, acl_state, direction, hci_reason); } +void suspend_complete_state(uint32_t state) { + metrics::LogMetricsSuspendIdState(state); +} + } // namespace rust } // namespace topshim } // namespace bluetooth diff --git a/system/gd/rust/topshim/metrics/metrics_shim.h b/system/gd/rust/topshim/metrics/metrics_shim.h index ed8fa2b994d893385ff1b65424448cf92e9619f9..d2e8fb9e557a008d1485bf99eaa03f0abcb38359 100644 --- a/system/gd/rust/topshim/metrics/metrics_shim.h +++ b/system/gd/rust/topshim/metrics/metrics_shim.h @@ -42,6 +42,7 @@ void profile_connection_state_changed(RawAddress addr, uint32_t profile, uint32_ void acl_connect_attempt(RawAddress addr, uint32_t acl_state); void acl_connection_state_changed( RawAddress addr, uint32_t transport, uint32_t status, uint32_t acl_state, uint32_t direction, uint32_t hci_reason); +void suspend_complete_state(uint32_t state); } // namespace rust } // namespace topshim diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs index 012539284dbc78fa8df41af3f005221c66633af5..5620932cda112fee58a1bf77afce4a9b5e100ce5 100644 --- a/system/gd/rust/topshim/src/btif.rs +++ b/system/gd/rust/topshim/src/btif.rs @@ -466,6 +466,10 @@ impl Uuid { uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]) } + + pub fn empty() -> Uuid { + unsafe { bindings::bluetooth::Uuid_kEmpty } + } } impl Display for Uuid { @@ -953,6 +957,7 @@ pub enum BaseCallbacks { // switch_codec_cb GenerateLocalOobData(u8, OobData), LeRandCallback(u64), + // key_missing_cb } pub struct BaseCallbacksDispatcher { @@ -1143,6 +1148,7 @@ impl BluetoothInterface { switch_buffer_size_cb: None, switch_codec_cb: None, le_rand_cb: Some(le_rand_cb), + key_missing_cb: None, }); let cb_ptr = LTCheckedPtrMut::from(&mut callbacks); @@ -1321,6 +1327,10 @@ impl BluetoothInterface { ccall!(self, get_swb_supported) } + pub fn is_coding_format_supported(&self, coding_format: u8) -> bool { + ccall!(self, is_coding_format_supported, coding_format) + } + pub fn le_rand(&self) -> i32 { ccall!(self, le_rand) } diff --git a/system/gd/rust/topshim/src/controller.rs b/system/gd/rust/topshim/src/controller.rs index 36df8a2187638e5b33cbc41d8354f2227453772a..3247935349eddd49713605281a24620e6f86ff56 100644 --- a/system/gd/rust/topshim/src/controller.rs +++ b/system/gd/rust/topshim/src/controller.rs @@ -12,6 +12,7 @@ mod ffi { fn GetControllerInterface() -> UniquePtr; fn read_local_addr(self: &ControllerIntf) -> RawAddress; + fn get_ble_supported_states(self: &ControllerIntf) -> u64; } } @@ -30,4 +31,8 @@ impl Controller { pub fn read_local_addr(&mut self) -> [u8; 6] { self.internal.read_local_addr().address } + + pub fn get_ble_supported_states(&mut self) -> u64 { + self.internal.get_ble_supported_states() + } } diff --git a/system/gd/rust/topshim/src/lib.rs b/system/gd/rust/topshim/src/lib.rs index 27772b3eb1e6ab6846c0ca7390e91f9ac142dad4..6d7bb3b5b4b56399367f0077abb19326fed16743 100644 --- a/system/gd/rust/topshim/src/lib.rs +++ b/system/gd/rust/topshim/src/lib.rs @@ -20,6 +20,7 @@ pub mod btif; pub mod controller; pub mod metrics; pub mod profiles; +pub mod syslog; pub mod sysprop; pub mod topstack; diff --git a/system/gd/rust/topshim/src/metrics.rs b/system/gd/rust/topshim/src/metrics.rs index edca7d1ab4fbfee1ca3367691f2c488f300b57ad..9c1aa7cdf00f98df80ad80599de9cb40b5ef859e 100644 --- a/system/gd/rust/topshim/src/metrics.rs +++ b/system/gd/rust/topshim/src/metrics.rs @@ -47,6 +47,7 @@ mod ffi { direction: u32, hci_reason: u32, ); + fn suspend_complete_state(state: u32); } } @@ -126,3 +127,7 @@ pub fn acl_connection_state_changed( hci_reason as u32, ); } + +pub fn suspend_complete_state(state: u32) { + ffi::suspend_complete_state(state); +} diff --git a/system/gd/rust/topshim/src/profiles/gatt.rs b/system/gd/rust/topshim/src/profiles/gatt.rs index 01691a40a99bd5cce8cd2a8b99d7396a413b77fe..d2b0e458a59d637e482e76a5eadf93a77a4bb355 100644 --- a/system/gd/rust/topshim/src/profiles/gatt.rs +++ b/system/gd/rust/topshim/src/profiles/gatt.rs @@ -199,6 +199,7 @@ pub mod ffi { fn SetScanParameters( self: Pin<&mut BleScannerIntf>, scanner_id: u8, + scan_type: u8, scan_interval: u16, scan_window: u16, ); @@ -1540,8 +1541,14 @@ impl BleScanner { mutcxxcall!(self, MsftAdvMonitorEnable, call_id, enable); } - pub fn set_scan_parameters(&mut self, scanner_id: u8, scan_interval: u16, scan_window: u16) { - mutcxxcall!(self, SetScanParameters, scanner_id, scan_interval, scan_window); + pub fn set_scan_parameters( + &mut self, + scanner_id: u8, + scan_type: u8, + scan_interval: u16, + scan_window: u16, + ) { + mutcxxcall!(self, SetScanParameters, scanner_id, scan_type, scan_interval, scan_window); } pub fn batchscan_config_storage( diff --git a/system/gd/rust/topshim/src/profiles/hfp.rs b/system/gd/rust/topshim/src/profiles/hfp.rs index 3017986aa125cba6092954b0c6834ea0f024bebb..4ea72e959e7fc4ce0c1122f6a3e0164b400e3786 100644 --- a/system/gd/rust/topshim/src/profiles/hfp.rs +++ b/system/gd/rust/topshim/src/profiles/hfp.rs @@ -11,6 +11,7 @@ use topshim_macros::{cb_variant, profile_enabled_or}; use log::warn; #[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd, Clone)] +#[repr(u8)] pub enum HfpCodecId { NONE = 0x00, CVSD = 0x01, @@ -18,6 +19,32 @@ pub enum HfpCodecId { LC3 = 0x03, } +#[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd, Clone)] +#[repr(u8)] +pub enum EscoCodingFormat { + ULAW = 0x00, + ALAW = 0x01, + CVSD = 0x02, + TRANSPARENT = 0x03, + LINEAR = 0x04, + MSBC = 0x05, + LC3 = 0x06, + G729A = 0x07, + VENDOR = 0xff, +} + +impl From for EscoCodingFormat { + fn from(item: u8) -> Self { + EscoCodingFormat::from_u8(item).unwrap() + } +} + +impl From for u8 { + fn from(item: EscoCodingFormat) -> Self { + item as u8 + } +} + #[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd, Clone)] #[repr(u32)] pub enum BthfConnectionState { @@ -49,24 +76,58 @@ impl From for BthfAudioState { } } +// This is used for codec-negotiation related methods that do not +// concern with the coding format. Do not confuse this with |HfpCodecFormat|. +bitflags! { + #[derive(Default)] + pub struct HfpCodecBitId: i32 { + const NONE = 0b000; + const CVSD = 0b001; + const MSBC = 0b010; + const LC3 = 0b100; + } +} + +impl TryInto for HfpCodecBitId { + type Error = (); + fn try_into(self) -> Result { + Ok(self.bits().try_into().unwrap()) + } +} + +impl TryInto for HfpCodecBitId { + type Error = (); + fn try_into(self) -> Result { + Ok(self.bits()) + } +} + +impl TryFrom for HfpCodecBitId { + type Error = (); + fn try_from(val: i32) -> Result { + Self::from_bits(val).ok_or(()) + } +} + bitflags! { #[derive(Default)] - pub struct HfpCodecCapability: i32 { - const NONE = 0b00; - const CVSD = 0b01; - const MSBC = 0b10; - const LC3 = 0b100; + pub struct HfpCodecFormat: i32 { + const NONE = 0b0000; + const CVSD = 0b0001; + const MSBC_TRANSPARENT = 0b0010; + const MSBC = 0b0100; + const LC3_TRANSPARENT = 0b1000; } } -impl TryInto for HfpCodecCapability { +impl TryInto for HfpCodecFormat { type Error = (); fn try_into(self) -> Result { Ok(self.bits()) } } -impl TryFrom for HfpCodecCapability { +impl TryFrom for HfpCodecFormat { type Error = (); fn try_from(val: i32) -> Result { Self::from_bits(val).ok_or(()) diff --git a/system/gd/rust/topshim/src/syslog.rs b/system/gd/rust/topshim/src/syslog.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd575ba485614fd6f1e5da3224901b7cc20bae06 --- /dev/null +++ b/system/gd/rust/topshim/src/syslog.rs @@ -0,0 +1,56 @@ +//! Expose some internal methods to set the log level for system syslog. +//! +//! On systems that use syslog (i.e. `vlog_syslog.cc`), there is support +//! to filter out logs before they go to syslog. This module provides Rust apis +//! to tune log levels for syslog. + +use num_derive::ToPrimitive; +use num_traits::cast::ToPrimitive; +use std::ffi::CString; +use std::os::raw::c_char; + +#[derive(ToPrimitive)] +#[repr(u8)] +/// Android framework log priority levels. +/// They are defined in system/logging/liblog/include/android/log.h by +/// the Android Framework code. +pub enum Level { + Verbose = 2, + Debug = 3, + Info = 4, + Warn = 5, + Error = 6, + Fatal = 7, +} + +// Defined in syslog linkage. See |vlog_syslog.cc|. +extern "C" { + fn SetLogLevelForTag(tag: *const c_char, level: u8); + fn SetDefaultLogLevel(level: u8); +} + +/// Set a default level value for failed |level.to_u8()| of |Level::Info|. +const DEFAULT_LEVEL: u8 = 4; + +/// Set the level of logs which will get printed for the given tag. +/// +/// Args: +/// tag - LOG_TAG for the system module that's logging. +/// level - Minimum log level that will be sent to syslog. +pub fn set_log_level_for_tag(tag: &str, level: Level) { + let cstr: CString = CString::new(tag).expect("CString::new failed on log tag"); + + unsafe { + SetLogLevelForTag(cstr.as_ptr(), level.to_u8().unwrap_or(DEFAULT_LEVEL)); + } +} + +/// Set the default log level for log tags. Will be overridden by any tag specific levels. +/// +/// Args: +/// level - Minimum log level that will be sent to syslog. +pub fn set_default_log_level(level: Level) { + unsafe { + SetDefaultLogLevel(level.to_u8().unwrap_or(DEFAULT_LEVEL)); + } +} diff --git a/system/gd/security/BUILD.gn b/system/gd/security/BUILD.gn index 02e04bed5572b67e33212a29943b666fb648e68b..de17a0a316671f2d146a834c6a8e9afc7d11c635 100644 --- a/system/gd/security/BUILD.gn +++ b/system/gd/security/BUILD.gn @@ -15,19 +15,28 @@ source_set("BluetoothSecurityChannelSources") { sources = [ "channel/security_manager_channel.cc" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] } source_set("BluetoothSecurityPairingSources") { sources = [ "pairing/classic_pairing_handler.cc" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] } source_set("BluetoothSecurityRecordSources") { sources = [ "record/security_record_storage.cc" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] } @@ -53,5 +62,8 @@ source_set("BluetoothSecuritySources") { "//bt/system/gd:gd_default_deps", ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] } diff --git a/system/gd/security/channel/security_manager_channel.cc b/system/gd/security/channel/security_manager_channel.cc index a6a2c198cce4d17cf9083ea1f7a6172502600237..72bfa96f02afabb44234799932a2e5f228ce76a1 100644 --- a/system/gd/security/channel/security_manager_channel.cc +++ b/system/gd/security/channel/security_manager_channel.cc @@ -18,7 +18,6 @@ #include "security/channel/security_manager_channel.h" #include "hci/address.h" -#include "security/smp_packets.h" namespace bluetooth { namespace security { diff --git a/system/gd/security/channel/security_manager_channel.h b/system/gd/security/channel/security_manager_channel.h index 9e23604695e4190cf471376eb1c8b86ac376cd1a..f1b0a8ebdc4a340b63ba6cfc86c484201e00120b 100644 --- a/system/gd/security/channel/security_manager_channel.h +++ b/system/gd/security/channel/security_manager_channel.h @@ -19,14 +19,11 @@ #include #include -#include #include "common/contextual_callback.h" -#include "hci/address_with_type.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" #include "hci/security_interface.h" -#include "l2cap/classic/l2cap_classic_module.h" #include "l2cap/classic/link_security_interface.h" namespace bluetooth { diff --git a/system/gd/security/channel/security_manager_channel_unittest.cc b/system/gd/security/channel/security_manager_channel_unittest.cc index 22b16d8512d15e288d72ed202d75e1f591c09596..07a9e02a0f34bc7ca9415c0d97cb539cf1a3804c 100644 --- a/system/gd/security/channel/security_manager_channel_unittest.cc +++ b/system/gd/security/channel/security_manager_channel_unittest.cc @@ -22,7 +22,6 @@ #include "hci/address.h" #include "hci/hci_packets.h" #include "packet/raw_builder.h" -#include "security/smp_packets.h" #include "security/test/fake_hci_layer.h" #include "security/test/fake_security_interface.h" diff --git a/system/gd/security/ecc/multprecision.cc b/system/gd/security/ecc/multprecision.cc index c2583ed1d3becdc0db0294968f2311ff98c31058..86ef0d80024d0fd9f32b0a2f423c6e7c6464fd54 100644 --- a/system/gd/security/ecc/multprecision.cc +++ b/system/gd/security/ecc/multprecision.cc @@ -23,7 +23,6 @@ ******************************************************************************/ #include "security/ecc/multprecision.h" -#include namespace bluetooth { namespace security { @@ -501,4 +500,4 @@ void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u, const uint32_t* modp) } // namespace ecc } // namespace security -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/gd/security/ecdh_keys.cc b/system/gd/security/ecdh_keys.cc index 9a4214b8482a9512d84f20560fa46a5512ed023f..1a7a7aaa0b7c9747bc094810f6edd8ceb394e7a4 100644 --- a/system/gd/security/ecdh_keys.cc +++ b/system/gd/security/ecdh_keys.cc @@ -23,8 +23,9 @@ should honour all the random number requirements from the spec!! **********************************************************************************************************************/ #include -#include + #include +#include #include "security/ecc/p_256_ecc_pp.h" diff --git a/system/gd/security/facade_configuration_api.h b/system/gd/security/facade_configuration_api.h index 9feb8a46003fce4bdadf60572f45f43e57114fc7..660b8178e66ff4ab72c575f855a65aab463a4225 100644 --- a/system/gd/security/facade_configuration_api.h +++ b/system/gd/security/facade_configuration_api.h @@ -18,9 +18,6 @@ #pragma once -#include -#include - #include "hci/address_with_type.h" #include "hci/hci_packets.h" #include "security/internal/security_manager_impl.h" diff --git a/system/gd/security/internal/security_manager_impl.cc b/system/gd/security/internal/security_manager_impl.cc index 74bd54d1c4541af552291abbdf47546252b521b2..4b6d69fec8466cf27038752f8987757b3bf210b0 100644 --- a/system/gd/security/internal/security_manager_impl.cc +++ b/system/gd/security/internal/security_manager_impl.cc @@ -17,6 +17,8 @@ */ #include "security_manager_impl.h" +#include + #include "common/bind.h" #include "hci/address_with_type.h" #include "hci/octets.h" @@ -25,7 +27,9 @@ #include "security/initial_informations.h" #include "security/internal/security_manager_impl.h" #include "security/pairing_handler_le.h" +#include "security/security_manager_listener.h" #include "security/ui.h" +#include "storage/config_keys.h" namespace bluetooth { namespace security { @@ -77,23 +81,29 @@ void SecurityManagerImpl::Init() { ASSERT_LOG(storage_module_ != nullptr, "Storage module must not be null!"); security_database_.LoadRecordsFromStorage(); - auto irk_prop = storage_module_->GetBin("Adapter", "LE_LOCAL_KEY_IRK"); + auto irk_prop = + storage_module_->GetBin(BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK); if (!irk_prop.has_value()) { auto rand16 = bluetooth::os::GenerateRandom<16>(); std::vector new_irk{rand16.begin(), rand16.end()}; - storage_module_->SetBin("Adapter", "LE_LOCAL_KEY_IRK", new_irk); - irk_prop = storage_module_->GetBin("Adapter", "LE_LOCAL_KEY_IRK"); + storage_module_->SetBin( + BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK, new_irk); + irk_prop = + storage_module_->GetBin(BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK); } Address controllerAddress = controller_->GetMacAddress(); - auto address_prop = storage_module_->GetProperty("Adapter", "Address"); + auto address_prop = + storage_module_->GetProperty(BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_ADDRESS); if (!address_prop || address_prop.value() != controllerAddress.ToString()) { - storage_module_->SetProperty("Adapter", "Address", controllerAddress.ToString()); + storage_module_->SetProperty( + BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_ADDRESS, controllerAddress.ToString()); } local_identity_address_ = hci::AddressWithType(controllerAddress, hci::AddressType::PUBLIC_DEVICE_ADDRESS); - irk_prop = storage_module_->GetBin("Adapter", "LE_LOCAL_KEY_IRK"); + irk_prop = + storage_module_->GetBin(BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK); ASSERT_LOG(irk_prop.has_value(), "Irk not found in storage"); ASSERT_LOG(irk_prop->size() == 16, "Irk corrupted in storage"); std::copy(irk_prop->begin(), irk_prop->end(), local_identity_resolving_key_.data()); @@ -101,9 +111,12 @@ void SecurityManagerImpl::Init() { hci::LeAddressManager::AddressPolicy address_policy = hci::LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS; hci::AddressWithType address_with_type(hci::Address{}, hci::AddressType::RANDOM_DEVICE_ADDRESS); - /* 7 minutes minimum, 15 minutes maximum for random address refreshing */ - auto minimum_rotation_time = std::chrono::minutes(7); - auto maximum_rotation_time = std::chrono::minutes(15); + /* Default to 7 minutes minimum, 15 minutes maximum for random address refreshing; + * device can override. */ + auto minimum_rotation_time = std::chrono::minutes( + GET_SYSPROP(Ble, random_address_rotation_interval_min, 7)); + auto maximum_rotation_time = std::chrono::minutes( + GET_SYSPROP(Ble, random_address_rotation_interval_max, 15)); acl_manager_->SetPrivacyPolicyForInitiatorAddress( address_policy, address_with_type, minimum_rotation_time, maximum_rotation_time); diff --git a/system/gd/security/internal/security_manager_impl.h b/system/gd/security/internal/security_manager_impl.h index cf9f7759ea310c66e568e732e9a97a857c75d5c7..97e5957bfa69797d4c05ac71f1f4d47bd246d6c0 100644 --- a/system/gd/security/internal/security_manager_impl.h +++ b/system/gd/security/internal/security_manager_impl.h @@ -20,6 +20,7 @@ #include #include +#include #include "hci/acl_manager.h" #include "hci/controller.h" diff --git a/system/gd/security/pairing/classic_pairing_handler.h b/system/gd/security/pairing/classic_pairing_handler.h index 190395df54329ff1fe9d24d543b0ab8f926cee0e..0df839d25724903ffa86b840c8b1bc66606d4130 100644 --- a/system/gd/security/pairing/classic_pairing_handler.h +++ b/system/gd/security/pairing/classic_pairing_handler.h @@ -17,14 +17,11 @@ */ #pragma once -#include "security/pairing/pairing_handler.h" - #include #include "common/callback.h" -#include "l2cap/classic/l2cap_classic_module.h" #include "security/initial_informations.h" -#include "security/security_manager_listener.h" +#include "security/pairing/pairing_handler.h" namespace bluetooth { namespace security { diff --git a/system/gd/security/pairing/classic_pairing_handler_unittest.cc b/system/gd/security/pairing/classic_pairing_handler_unittest.cc index dde08ccb8d4a54dc2fea62dfe32d3032c8a7d3aa..0db1de0fbb6e294469edac7f5c0423ef30ec4e84 100644 --- a/system/gd/security/pairing/classic_pairing_handler_unittest.cc +++ b/system/gd/security/pairing/classic_pairing_handler_unittest.cc @@ -18,6 +18,7 @@ #include "security/pairing/classic_pairing_handler.h" #include + #include #include @@ -25,7 +26,6 @@ #include "packet/raw_builder.h" #include "security/channel/security_manager_channel.h" #include "security/initial_informations.h" -#include "security/smp_packets.h" #include "security/test/fake_hci_layer.h" #include "security/test/fake_name_db.h" #include "security/test/fake_security_interface.h" diff --git a/system/gd/security/pairing/oob_data.h b/system/gd/security/pairing/oob_data.h index 79430a2d7189df87e10dee193f116286b057dcee..3d75196d8067edda9ff4dc277719c83209d38a5a 100644 --- a/system/gd/security/pairing/oob_data.h +++ b/system/gd/security/pairing/oob_data.h @@ -17,6 +17,9 @@ */ #pragma once +#include +#include + namespace bluetooth { namespace security { namespace pairing { diff --git a/system/gd/security/pairing/pairing_handler.h b/system/gd/security/pairing/pairing_handler.h index 3ad8883879fc08eaf67bba84510b27d4fba3519b..b3e4eb6c0361a4fe2f90f290365efc1c4f141e77 100644 --- a/system/gd/security/pairing/pairing_handler.h +++ b/system/gd/security/pairing/pairing_handler.h @@ -18,7 +18,9 @@ #pragma once #include + #include +#include #include "hci/address_with_type.h" #include "hci/hci_packets.h" @@ -26,7 +28,6 @@ #include "security/channel/security_manager_channel.h" #include "security/pairing/oob_data.h" #include "security/record/security_record.h" -#include "security/smp_packets.h" #include "security/ui.h" namespace bluetooth { diff --git a/system/gd/security/pairing_handler_le_unittest.cc b/system/gd/security/pairing_handler_le_unittest.cc index 690c080c0a5c9ba00d0721508ffe606324258ae8..a91aa4843d9edd2da9c598f13c81769c56ede02a 100644 --- a/system/gd/security/pairing_handler_le_unittest.cc +++ b/system/gd/security/pairing_handler_le_unittest.cc @@ -16,13 +16,14 @@ * ******************************************************************************/ +#include "security/pairing_handler_le.h" + #include #include + #include -#include "os/log.h" #include "os/rand.h" -#include "security/pairing_handler_le.h" #include "security/test/mocks.h" using ::testing::_; diff --git a/system/gd/security/record/security_record.h b/system/gd/security/record/security_record.h index 7b1783eda251971f9fb60ce9e408c134aa9b2bd0..6a4a5a77960e374ef8b8ffb5a0eaddf520c20b21 100644 --- a/system/gd/security/record/security_record.h +++ b/system/gd/security/record/security_record.h @@ -20,7 +20,6 @@ #include "hci/address_with_type.h" #include "hci/octets.h" -#include "storage/device.h" namespace bluetooth { namespace security { diff --git a/system/gd/security/record/security_record_storage.cc b/system/gd/security/record/security_record_storage.cc index 8b452e4724699bbd55eb064f45f49ac0e347b90a..a572b80a89a8e26a52f1d293e9835664e97744aa 100644 --- a/system/gd/security/record/security_record_storage.cc +++ b/system/gd/security/record/security_record_storage.cc @@ -17,6 +17,8 @@ */ #include "security/record/security_record_storage.h" +#include "storage/classic_device.h" +#include "storage/le_device.h" #include "storage/mutation.h" namespace bluetooth { diff --git a/system/gd/security/record/security_record_storage.h b/system/gd/security/record/security_record_storage.h index e244d6698c1a3d4066865aed70b5cf97643ce56c..a3ed24b785b281ec74b8dbfb3f428ddfeea725c5 100644 --- a/system/gd/security/record/security_record_storage.h +++ b/system/gd/security/record/security_record_storage.h @@ -17,14 +17,10 @@ */ #pragma once -#include +#include -#include "hci/hci_packets.h" #include "os/handler.h" -#include "os/utils.h" #include "security/record/security_record.h" -#include "storage/classic_device.h" -#include "storage/le_device.h" #include "storage/storage_module.h" namespace bluetooth { diff --git a/system/gd/security/security_manager.cc b/system/gd/security/security_manager.cc index cb857608411bb34aba81e15b86f49faa923ba931..ed3b91fa208005a6ecb43bb21a738c76f3deff31 100644 --- a/system/gd/security/security_manager.cc +++ b/system/gd/security/security_manager.cc @@ -18,7 +18,6 @@ #include "security_manager.h" #include "hci/octets.h" -#include "os/log.h" namespace bluetooth { namespace security { diff --git a/system/gd/security/security_manager.h b/system/gd/security/security_manager.h index 1c7b49a9e58a5f4084463e971e44f091768f30f2..469bff0ca8ae67a4178f3b59a9cebf83cd5a6a47 100644 --- a/system/gd/security/security_manager.h +++ b/system/gd/security/security_manager.h @@ -18,7 +18,6 @@ #pragma once -#include #include #include "hci/address_with_type.h" diff --git a/system/gd/security/security_manager_listener.h b/system/gd/security/security_manager_listener.h index 206b2d77de2386d735696dcdcd44a22d62f75afb..c854575f13c91c483c4623fecc0dbcec9e75b55e 100644 --- a/system/gd/security/security_manager_listener.h +++ b/system/gd/security/security_manager_listener.h @@ -18,8 +18,6 @@ #pragma once -#include "common/callback.h" -#include "hci/acl_manager.h" #include "security/pairing_failure.h" namespace bluetooth { diff --git a/system/gd/security/security_module.cc b/system/gd/security/security_module.cc index a8617b87d56203a53172ca5ae211b979a56a3ebd..b95d9e4794900991dcf86ef8e5c9b86f807d946f 100644 --- a/system/gd/security/security_module.cc +++ b/system/gd/security/security_module.cc @@ -16,20 +16,21 @@ #define LOG_TAG "security" +#include "security/security_module.h" + #include -#include "module.h" -#include "os/handler.h" -#include "os/log.h" #include "hci/acl_manager.h" #include "hci/hci_layer.h" +#include "l2cap/classic/l2cap_classic_module.h" #include "l2cap/le/l2cap_le_module.h" +#include "module.h" #include "neighbor/name_db.h" +#include "os/handler.h" #include "security/channel/security_manager_channel.h" #include "security/facade_configuration_api.h" #include "security/internal/security_manager_impl.h" #include "security/l2cap_security_module_interface.h" -#include "security/security_module.h" #include "storage/storage_module.h" namespace bluetooth { diff --git a/system/gd/security/test/fake_hci_layer.h b/system/gd/security/test/fake_hci_layer.h index 8d16e80db78ca0a19da7a3f9bb36e02feaa19b58..4c0b11a75895ac18b55b770f523a2509f81eb70a 100644 --- a/system/gd/security/test/fake_hci_layer.h +++ b/system/gd/security/test/fake_hci_layer.h @@ -16,19 +16,23 @@ * */ -#include "common/bind.h" +#include + #include "hci/hci_layer.h" namespace bluetooth { namespace security { using common::ContextualOnceCallback; +using hci::BitInserter; using hci::CommandCompleteView; using hci::CommandStatusView; using hci::EventBuilder; using hci::EventCode; using hci::EventView; using hci::HciLayer; +using hci::kLittleEndian; +using hci::PacketView; namespace { @@ -100,7 +104,7 @@ class FakeHciLayer : public HciLayer { registered_events_[event_code].Invoke(event); } - void ListDependencies(ModuleList* list) const override {} + void ListDependencies(ModuleList* /* list */) const override {} void Start() override {} void Stop() override {} diff --git a/system/gd/security/test/fake_name_db.h b/system/gd/security/test/fake_name_db.h index 91a319596ea60d42a5a1d0cd50efe29268e97b54..704dc4083d63604d9d9e93b0db9494e66c767d75 100644 --- a/system/gd/security/test/fake_name_db.h +++ b/system/gd/security/test/fake_name_db.h @@ -25,7 +25,7 @@ class FakeNameDbModule : public neighbor::NameDbModule { public: FakeNameDbModule() {} - void ListDependencies(ModuleList* list) const override {} + void ListDependencies(ModuleList* /* list */) const override {} void Start() override {} void Stop() override {} std::string ToString() const override { @@ -37,11 +37,11 @@ class FakeNameDbModule : public neighbor::NameDbModule { handler->Call(std::move(callback), address, true); } - bool IsNameCached(hci::Address address) const { + bool IsNameCached(hci::Address /* address */) const { return true; } - neighbor::RemoteName ReadCachedRemoteName(hci::Address address) const { + neighbor::RemoteName ReadCachedRemoteName(hci::Address /* address */) const { neighbor::RemoteName name = {'t', 'e', 's', 't'}; return name; } diff --git a/system/gd/security/test/fake_security_interface.h b/system/gd/security/test/fake_security_interface.h index 822f15ea672cca066e2c1744cf62eb4152ce6c55..2066abf0001def0892b001fd6cb124fe1dcb42a5 100644 --- a/system/gd/security/test/fake_security_interface.h +++ b/system/gd/security/test/fake_security_interface.h @@ -15,7 +15,7 @@ * limitations under the License. * */ -#include "common/bind.h" +#include "l2cap/classic/link_security_interface.h" #include "os/handler.h" namespace bluetooth { diff --git a/system/gd/security/test/mocks.h b/system/gd/security/test/mocks.h index dc8d3254dbf9fc7705ad0be01509e5559c4a749e..324cb6abea95990a76e39d19cffe4b80d8340df1 100644 --- a/system/gd/security/test/mocks.h +++ b/system/gd/security/test/mocks.h @@ -20,7 +20,7 @@ #include -#include "hci/address.h" +#include "hci/address_with_type.h" #include "hci/le_security_interface.h" #include "security/ui.h" diff --git a/system/gd/security/ui.h b/system/gd/security/ui.h index d4ead9a36cb3811137186ebc0ddc23ba1f50fd22..a9519b6ed8b0eab1c5d99f36557ba12bbae8969c 100644 --- a/system/gd/security/ui.h +++ b/system/gd/security/ui.h @@ -18,6 +18,9 @@ #pragma once +#include +#include + #include "hci/address_with_type.h" namespace bluetooth { diff --git a/system/gd/shim/dumpsys.cc b/system/gd/shim/dumpsys.cc index 4813a7545790275024b979ae529ce6dc8c4ee8e6..f1283615e3d3809190bc1be0d078b6104acce2a7 100644 --- a/system/gd/shim/dumpsys.cc +++ b/system/gd/shim/dumpsys.cc @@ -17,7 +17,11 @@ #include "dumpsys/dumpsys.h" +#include +#include + #include +#include #include #include "dumpsys/filter.h" @@ -135,9 +139,14 @@ void Dumpsys::impl::DumpWithArgsAsync(int fd, const char** args) { ParsedDumpsysArgs parsed_dumpsys_args(args); const auto registry = dumpsys_module_.GetModuleRegistry(); - ModuleDumper dumper(*registry, kDumpsysTitle); + int dumper_fd = STDOUT_FILENO; + if (IS_FLAG_ENABLED(dumpsys_use_passed_in_fd)) { + dumper_fd = fd; + } + ModuleDumper dumper(dumper_fd, *registry, kDumpsysTitle); std::string dumpsys_data; - dumper.DumpState(&dumpsys_data); + std::ostringstream oss; + dumper.DumpState(&dumpsys_data, oss); dprintf(fd, " ----- Filtering as Developer -----\n"); FilterAsDeveloper(&dumpsys_data); diff --git a/system/gd/storage/BUILD.gn b/system/gd/storage/BUILD.gn index 167293caa48941215605f370a8a3002b810fbfdd..2c9d4bd109cad16c375d155b68cd9914403efe34 100644 --- a/system/gd/storage/BUILD.gn +++ b/system/gd/storage/BUILD.gn @@ -26,6 +26,9 @@ source_set("BluetoothStorageSources") { "storage_module.cc", ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] } diff --git a/system/gd/storage/config_cache_test.cc b/system/gd/storage/config_cache_test.cc index 29773dbe445021e2f749d0c237ead99d6fcab6f0..d4fde9144a77a1fcf0f442cdc8445746b86e6bef 100644 --- a/system/gd/storage/config_cache_test.cc +++ b/system/gd/storage/config_cache_test.cc @@ -22,6 +22,7 @@ #include #include "hci/enum_helper.h" +#include "storage/config_keys.h" #include "storage/device.h" namespace testing { @@ -61,42 +62,42 @@ TEST(ConfigCacheTest, empty_values_test) { TEST(ConfigCacheTest, insert_boundary_device_with_linkkey_test) { ConfigCache config(2, Device::kLinkKeyProperties); config.SetProperty("A", "B", "C"); - config.SetProperty("CC:DD:EE:FF:00:10", "Name", "Hello"); - config.SetProperty("CC:DD:EE:FF:00:09", "Name", "Hello 2"); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); - ASSERT_TRUE(config.GetProperty("CC:DD:EE:FF:00:10", "Name")); + config.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello"); + config.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2"); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); + ASSERT_TRUE(config.GetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME)); } TEST(ConfigCacheTest, comparison_test) { ConfigCache config_1(2, Device::kLinkKeyProperties); config_1.SetProperty("A", "B", "C"); - config_1.SetProperty("CC:DD:EE:FF:00:10", "Name", "Hello"); - config_1.SetProperty("CC:DD:EE:FF:00:09", "Name", "Hello 2"); - config_1.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); + config_1.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello"); + config_1.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2"); + config_1.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); ConfigCache config_2(2, Device::kLinkKeyProperties); config_2.SetProperty("A", "B", "C"); - config_2.SetProperty("CC:DD:EE:FF:00:10", "Name", "Hello"); - config_2.SetProperty("CC:DD:EE:FF:00:09", "Name", "Hello 2"); - config_2.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); + config_2.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello"); + config_2.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2"); + config_2.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); ASSERT_EQ(config_1, config_2); // Config with different temp device order should not be equal - ASSERT_TRUE(config_2.GetProperty("CC:DD:EE:FF:00:10", "Name")); + ASSERT_TRUE(config_2.GetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME)); ASSERT_NE(config_1, config_2); - ASSERT_TRUE(config_1.GetProperty("CC:DD:EE:FF:00:10", "Name")); + ASSERT_TRUE(config_1.GetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME)); ASSERT_EQ(config_1, config_2); // Config with different persistent device order should not be equal - config_1.SetProperty("CC:DD:EE:FF:00:12", "LinkKey", "AABBAABBCCDDEE"); + config_1.SetProperty("CC:DD:EE:FF:00:12", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); config_2.RemoveSection("CC:DD:EE:FF:00:11"); - config_2.SetProperty("CC:DD:EE:FF:00:12", "LinkKey", "AABBAABBCCDDEE"); - config_2.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); + config_2.SetProperty("CC:DD:EE:FF:00:12", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); + config_2.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); ASSERT_NE(config_1, config_2); // Config with different capacity should not be equal ConfigCache config_3(3, Device::kLinkKeyProperties); config_3.SetProperty("A", "B", "C"); - config_3.SetProperty("CC:DD:EE:FF:00:10", "Name", "Hello"); - config_3.SetProperty("CC:DD:EE:FF:00:09", "Name", "Hello 2"); - config_3.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); - config_3.SetProperty("CC:DD:EE:FF:00:12", "LinkKey", "AABBAABBCCDDEE"); + config_3.SetProperty("CC:DD:EE:FF:00:10", BTIF_STORAGE_KEY_NAME, "Hello"); + config_3.SetProperty("CC:DD:EE:FF:00:09", BTIF_STORAGE_KEY_NAME, "Hello 2"); + config_3.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); + config_3.SetProperty("CC:DD:EE:FF:00:12", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); ASSERT_NE(config_1, config_3); // Empty config should not be equal to non-empty ones ConfigCache config_4(2, Device::kLinkKeyProperties); @@ -208,31 +209,35 @@ TEST(ConfigCacheTest, get_persistent_devices_test) { config.SetProperty("A", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D"); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); - ASSERT_TRUE(config.HasProperty("CC:DD:EE:FF:00:11", "LinkKey")); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); + ASSERT_TRUE(config.HasProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY)); ASSERT_THAT(config.GetPersistentSections(), ElementsAre("CC:DD:EE:FF:00:11")); - config.SetProperty("AA:BB:CC:DD:EE:FF", "LinkKey", "DEERDEERDEER"); + config.SetProperty("AA:BB:CC:DD:EE:FF", BTIF_STORAGE_KEY_LINK_KEY, "DEERDEERDEER"); ASSERT_THAT(config.GetPersistentSections(), ElementsAre("CC:DD:EE:FF:00:11", "AA:BB:CC:DD:EE:FF")); - ASSERT_TRUE(config.RemoveProperty("CC:DD:EE:FF:00:11", "LinkKey")); + ASSERT_TRUE(config.RemoveProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY)); ASSERT_THAT(config.GetPersistentSections(), ElementsAre("AA:BB:CC:DD:EE:FF")); } TEST(ConfigCacheTest, appoaching_temporary_config_limit_test) { ConfigCache config(2, Device::kLinkKeyProperties); for (int i = 0; i < 10; ++i) { - config.SetProperty(GetTestAddress(i), "Name", "Hello" + std::to_string(i)); + config.SetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_NAME, "Hello" + std::to_string(i)); if (i % 2 == 0) { - config.SetProperty(GetTestAddress(i), "LinkKey", "Key" + std::to_string(i)); + config.SetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_LINK_KEY, "Key" + std::to_string(i)); } } for (int i = 0; i < 10; ++i) { if (i % 2 == 0) { ASSERT_TRUE(config.HasSection(GetTestAddress(i))); - ASSERT_TRUE(config.HasProperty(GetTestAddress(i), "LinkKey")); - ASSERT_THAT(config.GetProperty(GetTestAddress(i), "Name"), Optional(StrEq("Hello" + std::to_string(i)))); + ASSERT_TRUE(config.HasProperty(GetTestAddress(i), BTIF_STORAGE_KEY_LINK_KEY)); + ASSERT_THAT( + config.GetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_NAME), + Optional(StrEq("Hello" + std::to_string(i)))); } else if (i >= 7) { ASSERT_TRUE(config.HasSection(GetTestAddress(i))); - ASSERT_THAT(config.GetProperty(GetTestAddress(i), "Name"), Optional(StrEq("Hello" + std::to_string(i)))); + ASSERT_THAT( + config.GetProperty(GetTestAddress(i), BTIF_STORAGE_KEY_NAME), + Optional(StrEq("Hello" + std::to_string(i)))); } else { ASSERT_FALSE(config.HasSection(GetTestAddress(i))); } @@ -248,7 +253,7 @@ TEST(ConfigCacheTest, remove_section_with_property_test) { config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D"); config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE"); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); config.RemoveSectionWithProperty("B"); ASSERT_FALSE(config.HasSection("A")); ASSERT_FALSE(config.HasSection("AA:BB:CC:DD:EE:FF")); @@ -267,9 +272,9 @@ TEST(ConfigCacheTest, persistent_config_changed_callback_test) { ASSERT_EQ(num_change, 1); config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE"); ASSERT_EQ(num_change, 1); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); ASSERT_EQ(num_change, 2); - config.RemoveProperty("CC:DD:EE:FF:00:11", "LinkKey"); + config.RemoveProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY); ASSERT_EQ(num_change, 3); config.RemoveSectionWithProperty("B"); ASSERT_EQ(num_change, 4); @@ -285,7 +290,7 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_missing_devtype_no_keys_test ASSERT_TRUE(hadInconsistencies); ASSERT_THAT( - config.GetProperty("AA:BB:CC:DD:EE:FF", "DevType"), + config.GetProperty("AA:BB:CC:DD:EE:FF", BTIF_STORAGE_KEY_DEV_TYPE), Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::BR_EDR)))); } @@ -295,11 +300,17 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_consistent_devtype_test) { config.SetProperty("A", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D"); - config.SetProperty("AA:BB:CC:DD:EE:FF", "DevType", std::to_string(bluetooth::hci::DeviceType::BR_EDR)); + config.SetProperty( + "AA:BB:CC:DD:EE:FF", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::BR_EDR)); config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE"); - config.SetProperty("CC:DD:EE:FF:00:11", "DevType", std::to_string(bluetooth::hci::DeviceType::BR_EDR)); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); + config.SetProperty( + "CC:DD:EE:FF:00:11", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::BR_EDR)); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); // act auto hadInconsistencies = config.FixDeviceTypeInconsistencies(); @@ -307,7 +318,7 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_consistent_devtype_test) { // assert ASSERT_FALSE(hadInconsistencies); ASSERT_THAT( - config.GetProperty("CC:DD:EE:FF:00:11", "DevType"), + config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE), Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::BR_EDR)))); } @@ -317,12 +328,18 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_should_be_dual_test) config.SetProperty("A", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D"); - config.SetProperty("AA:BB:CC:DD:EE:FF", "DevType", std::to_string(bluetooth::hci::DeviceType::BR_EDR)); + config.SetProperty( + "AA:BB:CC:DD:EE:FF", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::BR_EDR)); config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE"); - config.SetProperty("CC:DD:EE:FF:00:11", "DevType", std::to_string(bluetooth::hci::DeviceType::BR_EDR)); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); - config.SetProperty("CC:DD:EE:FF:00:11", "LE_KEY_PENC", "AABBAABBCCDDEE"); + config.SetProperty( + "CC:DD:EE:FF:00:11", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::BR_EDR)); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LE_KEY_PENC, "AABBAABBCCDDEE"); // act auto hadInconsistencies = config.FixDeviceTypeInconsistencies(); @@ -330,7 +347,7 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_should_be_dual_test) // assert ASSERT_TRUE(hadInconsistencies); ASSERT_THAT( - config.GetProperty("CC:DD:EE:FF:00:11", "DevType"), + config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE), Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::DUAL)))); } @@ -340,11 +357,17 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_should_be_le_not_cla config.SetProperty("A", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D"); - config.SetProperty("AA:BB:CC:DD:EE:FF", "DevType", std::to_string(bluetooth::hci::DeviceType::BR_EDR)); + config.SetProperty( + "AA:BB:CC:DD:EE:FF", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::BR_EDR)); config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE"); - config.SetProperty("CC:DD:EE:FF:00:11", "DevType", std::to_string(bluetooth::hci::DeviceType::BR_EDR)); - config.SetProperty("CC:DD:EE:FF:00:11", "LE_KEY_PENC", "AABBAABBCCDDEE"); + config.SetProperty( + "CC:DD:EE:FF:00:11", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::BR_EDR)); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LE_KEY_PENC, "AABBAABBCCDDEE"); // act auto hadInconsistencies = config.FixDeviceTypeInconsistencies(); @@ -352,7 +375,7 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_should_be_le_not_cla // assert ASSERT_TRUE(hadInconsistencies); ASSERT_THAT( - config.GetProperty("CC:DD:EE:FF:00:11", "DevType"), + config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE), Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::LE)))); } @@ -362,12 +385,18 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_dont_override_dual_t config.SetProperty("A", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D"); - config.SetProperty("AA:BB:CC:DD:EE:FF", "DevType", std::to_string(bluetooth::hci::DeviceType::BR_EDR)); + config.SetProperty( + "AA:BB:CC:DD:EE:FF", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::BR_EDR)); config.SetProperty("CC:DD:EE:FF:00:11", "B", "AABBAABBCCDDEE"); - config.SetProperty("CC:DD:EE:FF:00:11", "DevType", std::to_string(bluetooth::hci::DeviceType::DUAL)); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); - config.SetProperty("CC:DD:EE:FF:00:11", "LE_KEY_PENC", "AABBAABBCCDDEE"); + config.SetProperty( + "CC:DD:EE:FF:00:11", + BTIF_STORAGE_KEY_DEV_TYPE, + std::to_string(bluetooth::hci::DeviceType::DUAL)); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LE_KEY_PENC, "AABBAABBCCDDEE"); // act auto hadInconsistencies = config.FixDeviceTypeInconsistencies(); @@ -375,7 +404,7 @@ TEST(ConfigCacheTest, fix_device_type_inconsistency_devtype_dont_override_dual_t // assert ASSERT_FALSE(hadInconsistencies); ASSERT_THAT( - config.GetProperty("CC:DD:EE:FF:00:11", "DevType"), + config.GetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_DEV_TYPE), Optional(StrEq(std::to_string(bluetooth::hci::DeviceType::DUAL)))); } @@ -406,7 +435,7 @@ TEST(ConfigCacheTest, test_empty_persistent_properties) { config.SetProperty("A", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:EF", "C", "D"); - config.SetProperty("AA:BB:CC:DD:EE:EF", "LinkKey", "D"); + config.SetProperty("AA:BB:CC:DD:EE:EF", BTIF_STORAGE_KEY_LINK_KEY, "D"); ASSERT_TRUE(config.HasAtLeastOneMatchingPropertiesInSection("AA:BB:CC:DD:EE:FF", {"B", "C", "D"})); ASSERT_TRUE(config.HasAtLeastOneMatchingPropertiesInSection("A", {"B", "C", "D"})); ASSERT_FALSE(config.HasAtLeastOneMatchingPropertiesInSection("AA:BB:CC:DD:EE:FF", {"BC", "D"})); diff --git a/system/gd/storage/config_keys.h b/system/gd/storage/config_keys.h new file mode 100644 index 0000000000000000000000000000000000000000..d5e19d8794a749c0358b103adaaee5fbc4794f04 --- /dev/null +++ b/system/gd/storage/config_keys.h @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define BTIF_STORAGE_SECTION_ADAPTER "Adapter" +#define BTIF_STORAGE_SECTION_INFO "Info" +#define BTIF_STORAGE_SECTION_METRICS "Metrics" + +#define BTIF_STORAGE_KEY_ADDR_TYPE "AddrType" +#define BTIF_STORAGE_KEY_ADDRESS "Address" +#define BTIF_STORAGE_KEY_ALIAS "Aliase" +#define BTIF_STORAGE_KEY_APPEARANCE "Appearance" +#define BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES "AvrcpPeerFeatures" +#define BTIF_STORAGE_KEY_AVDTP_VERSION "AvdtpVersion" +#define BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION "AvrcpControllerVersion" +#define BTIF_STORAGE_KEY_CLOCK_OFFSET "ClockOffset" +#define BTIF_STORAGE_KEY_CSIS_AUTOCONNECT "CsisAutoconnect" +#define BTIF_STORAGE_KEY_CSIS_SET_INFO_BIN "CsisSetInfoBin" +#define BTIF_STORAGE_KEY_DEV_CLASS "DevClass" +#define BTIF_STORAGE_KEY_DEV_TYPE "DevType" +#define BTIF_STORAGE_KEY_DEVICE_GROUP_BIN "DeviceGroupBin" +#define BTIF_STORAGE_KEY_DIS_MODEL_NUM "ModelName" +#define BTIF_STORAGE_KEY_DISC_TIMEOUT "DiscoveryTimeout" +#define BTIF_STORAGE_KEY_GATT_CLIENT_DB_HASH "GattClientDatabaseHash" +#define BTIF_STORAGE_KEY_GATT_CLIENT_SUPPORTED "GattClientSupportedFeatures" +#define BTIF_STORAGE_KEY_GATT_SERVER_SUPPORTED "GattServerSupportedFeatures" +#define BTIF_STORAGE_KEY_HEARING_AID_AUDIO_CONTROL_POINT "HearingAidAudioControlPoint" +#define BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_CCC_HANDLE "HearingAidAudioStatusCccHandle" +#define BTIF_STORAGE_KEY_HEARING_AID_AUDIO_STATUS_HANDLE "HearingAidAudioStatusHandle" +#define BTIF_STORAGE_KEY_HEARING_AID_CAPABILITIES "HearingAidCapabilities" +#define BTIF_STORAGE_KEY_HEARING_AID_CODECS "HearingAidCodecs" +#define BTIF_STORAGE_KEY_HEARING_AID_IS_ACCEPTLISTED "HearingAidIsAcceptlisted" +#define BTIF_STORAGE_KEY_HEARING_AID_PREPARATION_DELAY "HearingAidPreparationDelay" +#define BTIF_STORAGE_KEY_HEARING_AID_READ_PSM_HANDLE "HearingAidReadPsmHandle" +#define BTIF_STORAGE_KEY_HEARING_AID_RENDER_DELAY "HearingAidRenderDelay" +#define BTIF_STORAGE_KEY_HEARING_AID_SERVICE_CHANGED_CCC_HANDLE "HearingAidServiceChangedCccHandle" +#define BTIF_STORAGE_KEY_HEARING_AID_SYNC_ID "HearingAidSyncId" +#define BTIF_STORAGE_KEY_HEARING_AID_VOLUME_HANDLE "HearingAidVolumeHandle" +#define BTIF_STORAGE_KEY_HFP_SDP_FEATURES "HfpSdpFeatures" +#define BTIF_STORAGE_KEY_HFP_VERSION "HfpVersion" +#define BTIF_STORAGE_KEY_HID_APP_ID "HidAppId" +#define BTIF_STORAGE_KEY_HID_ATTR_MASK "HidAttrMask" +#define BTIF_STORAGE_KEY_HID_COUNTRY_CODE "HidCountryCode" +#define BTIF_STORAGE_KEY_HID_DESCRIPTOR "HidDescriptor" +#define BTIF_STORAGE_KEY_HID_DEVICE_CABLED "HidDeviceCabled" +#define BTIF_STORAGE_KEY_HID_PRODUCT_ID "HidProductId" +#define BTIF_STORAGE_KEY_HID_REPORT "HidReport" +#define BTIF_STORAGE_KEY_HID_REPORT_VERSION "HidReportVersion" +#define BTIF_STORAGE_KEY_HID_SSR_MAX_LATENCY "HidSSRMaxLatency" +#define BTIF_STORAGE_KEY_HID_SSR_MIN_TIMEOUT "HidSSRMinTimeout" +#define BTIF_STORAGE_KEY_HID_SUB_CLASS "HidSubClass" +#define BTIF_STORAGE_KEY_HID_VENDOR_ID "HidVendorId" +#define BTIF_STORAGE_KEY_HID_VERSION "HidVersion" +#define BTIF_STORAGE_KEY_LE_KEY_LCSRK "LE_KEY_LCSRK" +#define BTIF_STORAGE_KEY_LE_KEY_LENC "LE_KEY_LENC" +#define BTIF_STORAGE_KEY_LE_KEY_LID "LE_KEY_LID" +#define BTIF_STORAGE_KEY_LE_KEY_PCSRK "LE_KEY_PCSRK" +#define BTIF_STORAGE_KEY_LE_KEY_PENC "LE_KEY_PENC" +#define BTIF_STORAGE_KEY_LE_KEY_PID "LE_KEY_PID" +#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_DHK "LE_LOCAL_KEY_DHK" +#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_ER "LE_LOCAL_KEY_ER" +#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_IR "LE_LOCAL_KEY_IR" +#define BTIF_STORAGE_KEY_LE_LOCAL_KEY_IRK "LE_LOCAL_KEY_IRK" +#define BTIF_STORAGE_KEY_LEAUDIO_ASES_BIN "AsesBin" +#define BTIF_STORAGE_KEY_LEAUDIO_AUTOCONNECT "LeAudioAutoconnect" +#define BTIF_STORAGE_KEY_LEAUDIO_HANDLES_BIN "LeAudioHandlesBin" +#define BTIF_STORAGE_KEY_LEAUDIO_HAS_ACTIVE_PRESET "LeAudioHasActivePreset" +#define BTIF_STORAGE_KEY_LEAUDIO_HAS_FLAGS "LeAudioHasFlags" +#define BTIF_STORAGE_KEY_LEAUDIO_HAS_IS_ACCEPTLISTED "LeAudioHasIsAcceptlisted" +#define BTIF_STORAGE_KEY_LEAUDIO_HAS_SERIALIZED_PRESETS "LeAudioHasSerializedPresets" +#define BTIF_STORAGE_KEY_LEAUDIO_SINK_AUDIOLOCATION "SinkAudioLocation" +#define BTIF_STORAGE_KEY_LEAUDIO_SINK_PACS_BIN "SinkPacsBin" +#define BTIF_STORAGE_KEY_LEAUDIO_SINK_SUPPORTED_CONTEXT_TYPE "SinkSupportedContextType" +#define BTIF_STORAGE_KEY_LEAUDIO_SOURCE_AUDIOLOCATION "SourceAudioLocation" +#define BTIF_STORAGE_KEY_LEAUDIO_SOURCE_PACS_BIN "SourcePacsBin" +#define BTIF_STORAGE_KEY_LEAUDIO_SOURCE_SUPPORTED_CONTEXT_TYPE "SourceSupportedContextType" +#define BTIF_STORAGE_KEY_LINK_KEY "LinkKey" +#define BTIF_STORAGE_KEY_LINK_KEY_TYPE "LinkKeyType" +#define BTIF_STORAGE_KEY_LOCAL_IO_CAPS "LocalIOCaps" +#define BTIF_STORAGE_KEY_MAX_SESSION_KEY_SIZE "MaxSessionKeySize" +#define BTIF_STORAGE_KEY_METRICS_ID_KEY "MetricsId" +#define BTIF_STORAGE_KEY_METRICS_SALT_256BIT "Salt256Bit" +#define BTIF_STORAGE_KEY_NAME "Name" +#define BTIF_STORAGE_KEY_PBAP_PCE_VERSION "PbapPceVersion" +#define BTIF_STORAGE_KEY_PIN_LENGTH "PinLength" +#define BTIF_STORAGE_KEY_PRODUCT_ID "ProductId" +#define BTIF_STORAGE_KEY_REMOTE_SERVICE "Service" +#define BTIF_STORAGE_KEY_REMOTE_VER_MFCT "Manufacturer" +#define BTIF_STORAGE_KEY_REMOTE_VER_SUBVER "LmpSubVer" +#define BTIF_STORAGE_KEY_REMOTE_VER_VER "LmpVer" +#define BTIF_STORAGE_KEY_RESTRICTED "Restricted" +#define BTIF_STORAGE_KEY_SCANMODE "ScanMode" +#define BTIF_STORAGE_KEY_SDP_DI_HW_VERSION "SdpDiHardwareVersion" +#define BTIF_STORAGE_KEY_SDP_DI_MANUFACTURER "SdpDiManufacturer" +#define BTIF_STORAGE_KEY_SDP_DI_MODEL "SdpDiModel" +#define BTIF_STORAGE_KEY_SDP_DI_VENDOR_ID_SRC "SdpDiVendorIdSource" +#define BTIF_STORAGE_KEY_SECURE_CONNECTIONS_SUPPORTED "SecureConnectionsSupported" +#define BTIF_STORAGE_KEY_TIMESTAMP "Timestamp" +#define BTIF_STORAGE_KEY_VENDOR_ID "VendorId" +#define BTIF_STORAGE_KEY_VENDOR_ID_SOURCE "VendorIdSource" +#define BTIF_STORAGE_KEY_VERSION "ProductVersion" diff --git a/system/gd/storage/device.h b/system/gd/storage/device.h index e1b5fd97b717d75b3843d4cd9ae544aabe2f8e31..ffccefdf8628969b96f087133901e2fc12d4dd6f 100644 --- a/system/gd/storage/device.h +++ b/system/gd/storage/device.h @@ -29,6 +29,7 @@ #include "hci/enum_helper.h" #include "storage/config_cache.h" #include "storage/config_cache_helper.h" +#include "storage/config_keys.h" #include "storage/mutation_entry.h" #include "storage/serializable.h" @@ -183,11 +184,14 @@ class Device { public: // Macro generate getters, setters and removers - GENERATE_PROPERTY_GETTER_SETTER_REMOVER(Name, std::string, "Name"); - GENERATE_PROPERTY_GETTER_SETTER_REMOVER(ClassOfDevice, hci::ClassOfDevice, "DevClass"); - GENERATE_PROPERTY_GETTER_SETTER_REMOVER_WITH_CUSTOM_SETTER(DeviceType, hci::DeviceType, "DevType", { - return static_cast(value | GetDeviceType().value_or(hci::DeviceType::UNKNOWN)); - }); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER(Name, std::string, BTIF_STORAGE_KEY_NAME); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER( + ClassOfDevice, hci::ClassOfDevice, BTIF_STORAGE_KEY_DEV_CLASS); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER_WITH_CUSTOM_SETTER( + DeviceType, hci::DeviceType, BTIF_STORAGE_KEY_DEV_TYPE, { + return static_cast( + value | GetDeviceType().value_or(hci::DeviceType::UNKNOWN)); + }); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(ManufacturerCode, uint16_t, "Manufacturer"); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(LmpVersion, uint8_t, "LmpVer"); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(LmpSubVersion, uint16_t, "LmpSubVer"); @@ -199,7 +203,7 @@ class Device { GENERATE_PROPERTY_GETTER_SETTER_REMOVER(MetricsId, int, "MetricsId"); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(PinLength, int, "PinLength"); // unix timestamp in seconds from epoch - GENERATE_PROPERTY_GETTER_SETTER_REMOVER(CreationUnixTimestamp, int, "DevClass"); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER(CreationUnixTimestamp, int, BTIF_STORAGE_KEY_DEV_CLASS); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(IsAuthenticated, int, "IsAuthenticated"); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(RequiresMitmProtection, int, "RequiresMitmProtection"); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(IsEncryptionRequired, int, "IsEncryptionRequired"); diff --git a/system/gd/storage/le_device.h b/system/gd/storage/le_device.h index d87225f2ba4e2cdc4bac175a508b0cf96007ebb8..e855e37e04f17184efefca7ba09a6641724dd63f 100644 --- a/system/gd/storage/le_device.h +++ b/system/gd/storage/le_device.h @@ -20,6 +20,7 @@ #include "hci/hci_packets.h" #include "storage/config_cache.h" +#include "storage/config_keys.h" #include "storage/device.h" namespace bluetooth { @@ -83,13 +84,16 @@ class LeDevice { public: // Get LE address type of the key address - GENERATE_PROPERTY_GETTER_SETTER_REMOVER(AddressType, hci::AddressType, "AddrType"); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER( + AddressType, hci::AddressType, BTIF_STORAGE_KEY_ADDR_TYPE); // IRK + Identity Address Type + Identity Address - GENERATE_PROPERTY_GETTER_SETTER_REMOVER(PeerId, std::string, "LE_KEY_PID"); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER(PeerId, std::string, BTIF_STORAGE_KEY_LE_KEY_PID); // LTK + RAND + EDIV + Security Level + Key Length - GENERATE_PROPERTY_GETTER_SETTER_REMOVER(PeerEncryptionKeys, std::string, "LE_KEY_PENC"); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER( + PeerEncryptionKeys, std::string, BTIF_STORAGE_KEY_LE_KEY_PENC); // counter + CSRK (connection signature resolving key) + security level - GENERATE_PROPERTY_GETTER_SETTER_REMOVER(PeerSignatureResolvingKeys, std::string, "LE_KEY_PCSRK"); + GENERATE_PROPERTY_GETTER_SETTER_REMOVER( + PeerSignatureResolvingKeys, std::string, BTIF_STORAGE_KEY_LE_KEY_PCSRK); GENERATE_PROPERTY_GETTER_SETTER_REMOVER(LegacyPseudoAddress, hci::Address, "LeLegacyPseudoAddr"); }; diff --git a/system/gd/storage/legacy_config_file_test.cc b/system/gd/storage/legacy_config_file_test.cc index 6b82b747290d80fa31fe0905ce3f8db8742224b3..430dbd403d933464e1654609e7a9657c8c049694 100644 --- a/system/gd/storage/legacy_config_file_test.cc +++ b/system/gd/storage/legacy_config_file_test.cc @@ -22,6 +22,7 @@ #include #include "os/files.h" +#include "storage/config_keys.h" #include "storage/device.h" namespace testing { @@ -40,8 +41,8 @@ TEST(LegacyConfigFileTest, write_and_read_loop_back_test) { config.SetProperty("A", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "B", "C"); config.SetProperty("AA:BB:CC:DD:EE:FF", "C", "D"); - config.SetProperty("CC:DD:EE:FF:00:11", "LinkKey", "AABBAABBCCDDEE"); - EXPECT_TRUE(config.HasProperty("CC:DD:EE:FF:00:11", "LinkKey")); + config.SetProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY, "AABBAABBCCDDEE"); + EXPECT_TRUE(config.HasProperty("CC:DD:EE:FF:00:11", BTIF_STORAGE_KEY_LINK_KEY)); EXPECT_THAT(config.GetPersistentSections(), ElementsAre("CC:DD:EE:FF:00:11")); EXPECT_TRUE(LegacyConfigFile::FromPath(temp_config.string()).Write(config)); @@ -103,7 +104,7 @@ static const std::string kWriteTestConfig = "Address = 01:02:03:ab:cd:ef\n" "\n" "[01:02:03:ab:cd:ea]\n" - "name = hello world\n" + "Name = hello world\n" "LinkKey = fedcba0987654321fedcba0987654328\n" "\n"; @@ -114,9 +115,10 @@ TEST(LegacyConfigFileTest, write_test) { ConfigCache config(100, Device::kLinkKeyProperties); config.SetProperty("Info", "FileSource", "Empty"); config.SetProperty("Info", "TimeCreated", ""); - config.SetProperty("Adapter", "Address", "01:02:03:ab:cd:ef"); - config.SetProperty("01:02:03:ab:cd:ea", "name", "hello world"); - config.SetProperty("01:02:03:ab:cd:ea", "LinkKey", "fedcba0987654321fedcba0987654328"); + config.SetProperty(BTIF_STORAGE_SECTION_ADAPTER, BTIF_STORAGE_KEY_ADDRESS, "01:02:03:ab:cd:ef"); + config.SetProperty("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME, "hello world"); + config.SetProperty( + "01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_LINK_KEY, "fedcba0987654321fedcba0987654328"); EXPECT_TRUE(LegacyConfigFile::FromPath(temp_config.string()).Write(config)); EXPECT_THAT(ReadSmallFile(temp_config.string()), Optional(StrEq(kWriteTestConfig))); diff --git a/system/gd/storage/storage_module.cc b/system/gd/storage/storage_module.cc index 691436035c753cc1fd8bd26e3c57939771be8c4e..febcf95a613cc129ced157928945c4e32fa0b535 100644 --- a/system/gd/storage/storage_module.cc +++ b/system/gd/storage/storage_module.cc @@ -30,6 +30,7 @@ #include "os/parameter_provider.h" #include "os/system_properties.h" #include "storage/config_cache.h" +#include "storage/config_keys.h" #include "storage/legacy_config_file.h" #include "storage/mutation.h" @@ -53,12 +54,12 @@ const int kConfigBackupComparePass = 2; const std::string kConfigFilePrefix = "bt_config-origin"; const std::string kConfigFileHash = "hash"; -const std::string StorageModule::kInfoSection = "Info"; +const std::string StorageModule::kInfoSection = BTIF_STORAGE_SECTION_INFO; const std::string StorageModule::kFileSourceProperty = "FileSource"; const std::string StorageModule::kTimeCreatedProperty = "TimeCreated"; const std::string StorageModule::kTimeCreatedFormat = "%Y-%m-%d %H:%M:%S"; -const std::string StorageModule::kAdapterSection = "Adapter"; +const std::string StorageModule::kAdapterSection = BTIF_STORAGE_SECTION_ADAPTER; StorageModule::StorageModule( std::string config_file_path, @@ -127,7 +128,9 @@ void StorageModule::SaveImmediately() { // 2. write in-memory config to disk, if failed, backup can still be used ASSERT(LegacyConfigFile::FromPath(config_file_path_).Write(pimpl_->cache_)); // 3. now write back up to disk as well - ASSERT(LegacyConfigFile::FromPath(config_backup_path_).Write(pimpl_->cache_)); + if (!LegacyConfigFile::FromPath(config_backup_path_).Write(pimpl_->cache_)) { + LOG_ERROR("Unable to write backup config file"); + } // 4. save checksum if it is running in common criteria mode if (bluetooth::os::ParameterProvider::GetBtKeystoreInterface() != nullptr && bluetooth::os::ParameterProvider::IsCommonCriteriaMode()) { diff --git a/system/gd/storage/storage_module.h b/system/gd/storage/storage_module.h index ef873e00318b8e65022efdb5d1171db68fcb48f9..7ad976bf59d263bb33d4f2c44797c916e934ed74 100644 --- a/system/gd/storage/storage_module.h +++ b/system/gd/storage/storage_module.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "hci/address.h" #include "module.h" diff --git a/system/gd/storage/storage_module_test.cc b/system/gd/storage/storage_module_test.cc index 6f645482a062e5ed9ff5712df7eb620d6e98782f..88ec4f6a212c98c0538f05d51a73cb90e8d47a52 100644 --- a/system/gd/storage/storage_module_test.cc +++ b/system/gd/storage/storage_module_test.cc @@ -31,6 +31,7 @@ #include "os/fake_timer/fake_timerfd.h" #include "os/files.h" #include "storage/config_cache.h" +#include "storage/config_keys.h" #include "storage/device.h" #include "storage/legacy_config_file.h" @@ -187,7 +188,7 @@ static const std::string kReadTestConfig = "DiscoveryTimeout = 120\n" "\n" "[01:02:03:ab:cd:ea]\n" - "name = hello world\n" + "Name = hello world\n" "LinkKey = fedcba0987654321fedcba0987654328\n" "\n"; @@ -203,7 +204,7 @@ TEST_F(StorageModuleTest, read_existing_config_test) { ASSERT_TRUE(storage->HasSectionPublic("Metrics")); ASSERT_THAT(storage->GetPersistentSectionsPublic(), ElementsAre("01:02:03:ab:cd:ea")); ASSERT_THAT( - storage->GetPropertyPublic(StorageModule::kAdapterSection, "Address"), + storage->GetPropertyPublic(StorageModule::kAdapterSection, BTIF_STORAGE_KEY_ADDRESS), Optional(StrEq("01:02:03:ab:cd:ef"))); // Tear down @@ -229,22 +230,26 @@ TEST_F(StorageModuleTest, save_config_test) { // Test // Change a property ASSERT_THAT( - storage->GetPropertyPublic("01:02:03:ab:cd:ea", "name"), Optional(StrEq("hello world"))); - storage->SetPropertyPublic("01:02:03:ab:cd:ea", "name", "foo"); - ASSERT_THAT(storage->GetPropertyPublic("01:02:03:ab:cd:ea", "name"), Optional(StrEq("foo"))); + storage->GetPropertyPublic("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME), + Optional(StrEq("hello world"))); + storage->SetPropertyPublic("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME, "foo"); + ASSERT_THAT( + storage->GetPropertyPublic("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME), + Optional(StrEq("foo"))); ASSERT_TRUE(WaitForReactorIdle(kTestConfigSaveDelay)); auto config = LegacyConfigFile::FromPath(temp_config_.string()).Read(kTestTempDevicesCapacity); ASSERT_TRUE(config); - ASSERT_THAT(config->GetProperty("01:02:03:ab:cd:ea", "name"), Optional(StrEq("foo"))); + ASSERT_THAT( + config->GetProperty("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME), Optional(StrEq("foo"))); // Remove a property - storage->RemovePropertyPublic("01:02:03:ab:cd:ea", "name"); + storage->RemovePropertyPublic("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME); ASSERT_TRUE(WaitForReactorIdle(kTestConfigSaveDelay)); LOG_INFO("After waiting 2"); config = LegacyConfigFile::FromPath(temp_config_.string()).Read(kTestTempDevicesCapacity); ASSERT_TRUE(config); - ASSERT_FALSE(config->HasProperty("01:02:03:ab:cd:ea", "name")); + ASSERT_FALSE(config->HasProperty("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME)); // Remove a section storage->RemoveSectionPublic("01:02:03:ab:cd:ea"); @@ -310,7 +315,7 @@ TEST_F(StorageModuleTest, changed_config_causes_a_write) { DeleteConfigFiles(); // Change a property - storage->SetPropertyPublic("01:02:03:ab:cd:ea", "name", "foo"); + storage->SetPropertyPublic("01:02:03:ab:cd:ea", BTIF_STORAGE_KEY_NAME, "foo"); ASSERT_TRUE(WaitForReactorIdle(std::chrono::milliseconds(1))); diff --git a/system/gd/sysprops/BUILD.gn b/system/gd/sysprops/BUILD.gn index c6401a0b292b34ee49bb0298b43886739aa219cf..fb3204c6c9a3abb7ca273da0c9f86c312f96d5f5 100644 --- a/system/gd/sysprops/BUILD.gn +++ b/system/gd/sysprops/BUILD.gn @@ -17,6 +17,9 @@ source_set("BluetoothSyspropsSources") { sources = [ "sysprops_module.cc" ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ + "//bt/system/gd:gd_defaults", + "//bt/system/log:log_defaults", + ] deps = [ "//bt/system/gd:gd_default_deps" ] } diff --git a/system/gd/sysprops/sysprops_module.cc b/system/gd/sysprops/sysprops_module.cc index 5b15d43e45b611187fd1f0b124d69ff34276b565..57181b4648cdb83a0332b0724e0914bf136ab6e8 100644 --- a/system/gd/sysprops/sysprops_module.cc +++ b/system/gd/sysprops/sysprops_module.cc @@ -83,6 +83,7 @@ void SyspropsModule::parse_config(std::string file_path) { "bluetooth.core.classic.inq_scan_type", "bluetooth.core.classic.inq_scan_interval", "bluetooth.core.classic.inq_scan_window", + "bluetooth.core.classic.inq_length", "bluetooth.core.acl.link_supervision_timeout", "bluetooth.core.classic.page_timeout", "bluetooth.core.classic.sniff_max_intervals", diff --git a/system/hci/Android.bp b/system/hci/Android.bp index 8137d261be189bbf25c82f4ee4f97143b987e6c5..b0773d34c16bdb3e8a5f21aaf95fe3f9477fc99d 100644 --- a/system/hci/Android.bp +++ b/system/hci/Android.bp @@ -15,9 +15,6 @@ cc_library_static { "src/buffer_allocator.cc", "src/packet_fragmenter.cc", ], - generated_headers: [ - "BluetoothGeneratedDumpsysDataSchema_h", - ], local_include_dirs: [ "include", ], @@ -26,7 +23,6 @@ cc_library_static { "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", "system/libhwbinder/include", ], @@ -36,7 +32,10 @@ cc_library_static { host_supported: true, min_sdk_version: "Tiramisu", header_libs: ["libbluetooth_headers"], - static_libs: ["libbt_shim_bridge"], + static_libs: [ + "libbluetooth_log", + "libbt_shim_bridge", + ], } // HCI unit tests for target @@ -54,26 +53,19 @@ cc_test { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/include", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/osi/test", - "packages/modules/Bluetooth/system/stack/include", - "system/libhwbinder/include", ], srcs: [ "test/packet_fragmenter_test.cc", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libbase", - "libdl", "liblog", ], static_libs: [ - "libbluetooth-for-tests", "libbluetooth-types", + "libbluetooth_log", "libbt-hci", - "libbtcore", "libchrome", "libosi", ], @@ -82,5 +74,4 @@ cc_test { cfi: true, misc_undefined: ["bounds"], }, - cflags: ["-Wno-unused-parameter"], } diff --git a/system/hci/BUILD.gn b/system/hci/BUILD.gn index ebea9e65072760511c6f510537e5c5d9f02bc9d6..430954996515c03604db21a1521c4b20d89731d5 100644 --- a/system/hci/BUILD.gn +++ b/system/hci/BUILD.gn @@ -23,7 +23,6 @@ static_library("hci") { include_dirs = [ "include", "//bt/system/", - "//bt/system/internal_include", "//bt/system/bta/include", "//bt/system/stack/include", ] @@ -45,7 +44,6 @@ if (use.test) { include_dirs = [ "//bt/system/", - "//bt/system/internal_include", "//bt/system/osi/test", "//bt/system/stack/include", ] diff --git a/system/hci/include/hci_layer.h b/system/hci/include/hci_layer.h index edfda11f57ebe3e87cfb51e4247b77513aaee6d8..2d07a5fca0aa09fe0b324877b984ce170b499b2b 100644 --- a/system/hci/include/hci_layer.h +++ b/system/hci/include/hci_layer.h @@ -22,8 +22,6 @@ #include #include "hci/include/hci_layer_legacy.h" -#include "osi/include/future.h" -#include "osi/include/osi.h" // INVALID_FD #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" @@ -45,7 +43,7 @@ typedef struct hci_t { command_status_cb status_cb, void* context); // Send some data downward through the HCI layer - void (*transmit_downward)(uint16_t type, void* data); + void (*transmit_downward)(void* data, uint16_t iso_buffer_size); } hci_t; const hci_t* hci_layer_get_interface(); diff --git a/system/hci/include/packet_fragmenter.h b/system/hci/include/packet_fragmenter.h index 65eefb1a98fcbbdb348fae4988897d91e0185cab..e3b5f3f253469571f36dd6db9416b3ca153a5990 100644 --- a/system/hci/include/packet_fragmenter.h +++ b/system/hci/include/packet_fragmenter.h @@ -18,7 +18,6 @@ #pragma once -#include "device/include/controller.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" @@ -43,7 +42,7 @@ typedef struct packet_fragmenter_t { // Fragments |packet| if necessary and hands off everything to the fragmented // callback. - void (*fragment_and_dispatch)(BT_HDR* packet); + void (*fragment_and_dispatch)(BT_HDR* packet, uint16_t iso_buffer_size); // If |packet| is a complete packet, forwards to the reassembled callback. // Otherwise holds onto it until all fragments arrive, at which point the // reassembled callback is called with the reassembled data. @@ -51,7 +50,3 @@ typedef struct packet_fragmenter_t { } packet_fragmenter_t; const packet_fragmenter_t* packet_fragmenter_get_interface(); - -const packet_fragmenter_t* packet_fragmenter_get_test_interface( - const controller_t* controller_interface, - const allocator_t* buffer_allocator_interface); diff --git a/system/hci/src/buffer_allocator.cc b/system/hci/src/buffer_allocator.cc index bd008dffeee83ebd1755ca9217e5e9d64d73dfa8..6dcfa34ea6b7a8be8e28b2def97f099f34f220ef 100644 --- a/system/hci/src/buffer_allocator.cc +++ b/system/hci/src/buffer_allocator.cc @@ -20,6 +20,7 @@ #include +#include "include/check.h" #include "internal_include/bt_target.h" #include "osi/include/allocator.h" diff --git a/system/hci/src/packet_fragmenter.cc b/system/hci/src/packet_fragmenter.cc index fc32f84994b0c7b4f9024b92bdf445a4e26a539a..950402f19c252bce3da25e5ad970ee309790a23d 100644 --- a/system/hci/src/packet_fragmenter.cc +++ b/system/hci/src/packet_fragmenter.cc @@ -25,9 +25,9 @@ #include -#include "device/include/controller.h" #include "hci/include/buffer_allocator.h" #include "hci/include/hci_layer.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "stack/include/bt_hdr.h" @@ -78,7 +78,6 @@ // Our interface and callbacks static const allocator_t* buffer_allocator; -static const controller_t* controller; static const packet_fragmenter_callbacks_t* callbacks; static std::unordered_map partial_iso_packets; @@ -89,7 +88,7 @@ static void init(const packet_fragmenter_callbacks_t* result_callbacks) { static void cleanup() { partial_iso_packets.clear(); } -static void fragment_and_dispatch(BT_HDR* packet) { +static void fragment_and_dispatch(BT_HDR* packet, uint16_t max_data_size) { CHECK(packet != NULL); uint16_t event = packet->event & MSG_EVT_MASK; @@ -97,7 +96,6 @@ static void fragment_and_dispatch(BT_HDR* packet) { CHECK(event == MSG_STACK_TO_HC_HCI_ISO); uint8_t* stream = packet->data + packet->offset; - uint16_t max_data_size = controller->get_iso_data_size(); uint16_t max_packet_size = max_data_size + HCI_ISO_PREAMBLE_SIZE; uint16_t remaining_length = packet->len; @@ -141,7 +139,7 @@ static void fragment_and_dispatch(BT_HDR* packet) { callbacks->fragmented(packet, true); } -static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR* packet) { +static void reassemble_and_dispatch(BT_HDR* packet) { uint8_t* stream = packet->data; uint16_t handle; uint16_t iso_length; @@ -331,15 +329,6 @@ static const packet_fragmenter_t interface = {init, cleanup, reassemble_and_dispatch}; const packet_fragmenter_t* packet_fragmenter_get_interface() { - controller = controller_get_interface(); buffer_allocator = buffer_allocator_get_interface(); return &interface; } - -const packet_fragmenter_t* packet_fragmenter_get_test_interface( - const controller_t* controller_interface, - const allocator_t* buffer_allocator_interface) { - controller = controller_interface; - buffer_allocator = buffer_allocator_interface; - return &interface; -} diff --git a/system/hci/test/packet_fragmenter_test.cc b/system/hci/test/packet_fragmenter_test.cc index 2696b0b727e80ade0655542f9f40a4210b9c124a..f85450f271318f329c9cc64ada2e67a016a0f19c 100644 --- a/system/hci/test/packet_fragmenter_test.cc +++ b/system/hci/test/packet_fragmenter_test.cc @@ -21,7 +21,6 @@ #include #include -#include "device/include/controller.h" #include "hci/include/hci_layer.h" #include "internal_include/bt_target.h" #include "osi/include/allocator.h" @@ -33,11 +32,8 @@ #define HCI_ISO_PREAMBLE_SIZE 4 #endif -DECLARE_TEST_MODES(init, set_data_sizes, no_fragmentation, fragmentation, - ble_no_fragmentation, ble_fragmentation, - non_acl_passthrough_fragmentation, no_reassembly, reassembly, - non_acl_passthrough_reassembly, iso_no_reassembly, - iso_reassembly, iso_fragmentation, iso_no_fragmentation); +DECLARE_TEST_MODES(init, iso_no_reassembly, iso_reassembly, iso_fragmentation, + iso_no_fragmentation); #define LOCAL_BLE_CONTROLLER_ID 1 @@ -284,19 +280,6 @@ static void manufacture_packet_and_then_reassemble(uint16_t event, } } -static void expect_packet_reassembled(uint16_t event, BT_HDR* packet, - const char* expected_data) { - uint16_t expected_data_length = strlen(expected_data); - uint8_t* data = packet->data + packet->offset; - - for (int i = 0; i < expected_data_length; i++) { - EXPECT_EQ(expected_data[i], data[i]); - data_size_sum++; - } - - osi_free(packet); -} - static void expect_packet_reassembled_iso(uint16_t event, BT_HDR* packet, const char* expected_data, uint32_t expected_timestamp, @@ -359,12 +342,6 @@ DURING(iso_no_fragmentation) { return; } -DURING(non_acl_passthrough_fragmentation) AT_CALL(0) { - expect_packet_fragmented(MSG_STACK_TO_HC_HCI_CMD, 10, packet, sample_data, - send_complete); - return; -} - UNEXPECTED_CALL; } @@ -382,30 +359,7 @@ DURING(iso_no_reassembly) AT_CALL(0) { return; } -DURING(non_acl_passthrough_reassembly) AT_CALL(0) { - expect_packet_reassembled(MSG_HC_TO_STACK_HCI_EVT, packet, sample_data); - return; -} - -UNEXPECTED_CALL; -} - -STUB_FUNCTION(uint16_t, get_acl_data_size_classic, (void)) -DURING(no_fragmentation, non_acl_passthrough_fragmentation, no_reassembly) -return 42; -DURING(fragmentation) return 10; -DURING(no_reassembly) return 1337; - UNEXPECTED_CALL; -return 0; -} - -STUB_FUNCTION(uint16_t, get_acl_data_size_ble, (void)) -DURING(ble_no_fragmentation) return 42; -DURING(ble_fragmentation) return 10; - -UNEXPECTED_CALL; -return 0; } STUB_FUNCTION(uint16_t, get_iso_data_size, (void)) @@ -419,34 +373,25 @@ return 0; static void reset_for(TEST_MODES_T next) { RESET_CALL_COUNT(fragmented_callback); RESET_CALL_COUNT(reassembled_callback); - RESET_CALL_COUNT(get_acl_data_size_classic); - RESET_CALL_COUNT(get_acl_data_size_ble); - RESET_CALL_COUNT(get_iso_data_size); CURRENT_TEST_MODE = next; } class PacketFragmenterTest : public ::testing::Test { protected: void SetUp() override { - fragmenter = - packet_fragmenter_get_test_interface(&controller, &allocator_malloc); + fragmenter = packet_fragmenter_get_interface(); packet_index = 0; data_size_sum = 0; callbacks.fragmented = fragmented_callback; callbacks.reassembled = reassembled_callback; - controller.get_acl_data_size_classic = get_acl_data_size_classic; - controller.get_acl_data_size_ble = get_acl_data_size_ble; - controller.get_iso_data_size = get_iso_data_size; - reset_for(init); fragmenter->init(&callbacks); } void TearDown() override { fragmenter->cleanup(); } - controller_t controller; packet_fragmenter_callbacks_t callbacks; }; @@ -457,7 +402,7 @@ TEST_F(PacketFragmenterTest, test_iso_fragment_necessary) { BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, sample_data); packet->event |= LOCAL_BLE_CONTROLLER_ID; - fragmenter->fragment_and_dispatch(packet); + fragmenter->fragment_and_dispatch(packet, get_iso_data_size()); ASSERT_EQ(strlen(sample_data), data_size_sum); } @@ -469,7 +414,7 @@ TEST_F(PacketFragmenterTest, test_iso_no_fragment_necessary) { BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, small_sample_data); packet->event |= LOCAL_BLE_CONTROLLER_ID; - fragmenter->fragment_and_dispatch(packet); + fragmenter->fragment_and_dispatch(packet, get_iso_data_size()); ASSERT_EQ(strlen(small_sample_data), data_size_sum); } @@ -480,7 +425,7 @@ TEST_F(PacketFragmenterTest, test_iso_fragment_necessary_no_ts) { BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, sample_data); packet->event |= LOCAL_BLE_CONTROLLER_ID; - fragmenter->fragment_and_dispatch(packet); + fragmenter->fragment_and_dispatch(packet, get_iso_data_size()); ASSERT_EQ(strlen(sample_data), data_size_sum); } @@ -491,7 +436,7 @@ TEST_F(PacketFragmenterTest, test_iso_no_fragment_necessary_no_ts) { BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, small_sample_data); packet->event |= LOCAL_BLE_CONTROLLER_ID; - fragmenter->fragment_and_dispatch(packet); + fragmenter->fragment_and_dispatch(packet, get_iso_data_size()); ASSERT_EQ(strlen(small_sample_data), data_size_sum); } diff --git a/system/include/hardware/avrcp/avrcp.h b/system/include/hardware/avrcp/avrcp.h index cfd9388dc51672985cf9f908800e953d17e46945..9ba033ad0e1b14265b0fe4f02b62183f3a44c8c5 100644 --- a/system/include/hardware/avrcp/avrcp.h +++ b/system/include/hardware/avrcp/avrcp.h @@ -16,12 +16,12 @@ #pragma once +#include + #include #include #include -#include - #include "avrcp_common.h" #include "raw_address.h" diff --git a/system/include/hardware/avrcp/avrcp_logging_helper.h b/system/include/hardware/avrcp/avrcp_logging_helper.h index dc2d52354f816b059886aceb35c29b2ae195ce38..79792eafc5733f41d54d7ff4b5e1a9ad0ec88573 100644 --- a/system/include/hardware/avrcp/avrcp_logging_helper.h +++ b/system/include/hardware/avrcp/avrcp_logging_helper.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include #include @@ -284,3 +286,36 @@ inline std::ostream& operator<<(std::ostream& os, } // namespace avrcp } // namespace bluetooth + +namespace fmt { +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +} // namespace fmt diff --git a/system/include/hardware/ble_scanner.h b/system/include/hardware/ble_scanner.h index af5b71098e839998d9b5aff2a5805a55c2830cec..a899526d5337708d57acc510c10150cb981eaa09 100644 --- a/system/include/hardware/ble_scanner.h +++ b/system/include/hardware/ble_scanner.h @@ -183,8 +183,9 @@ class BleScannerInterface { MsftAdvMonitorEnableCallback cb) = 0; /** Sets the LE scan interval and window in units of N*0.625 msec */ - virtual void SetScanParameters(int scanner_id, int scan_interval, - int scan_window, Callback cb) = 0; + virtual void SetScanParameters(int scanner_id, uint8_t scan_type, + int scan_interval, int scan_window, + Callback cb) = 0; /* Configure the batchscan storage */ virtual void BatchscanConfigStorage(int client_if, int batch_scan_full_max, diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h index a9e804fc9d6dc1a66ba3504ef1f8e14917cc5362..bf0bc05013ebec0a26a2bfa1370030cd271863d6 100644 --- a/system/include/hardware/bluetooth.h +++ b/system/include/hardware/bluetooth.h @@ -23,6 +23,8 @@ #include #include +#include + #include "avrcp/avrcp.h" #include "base/functional/callback.h" #include "bluetooth/uuid.h" @@ -129,11 +131,11 @@ inline std::string bt_status_text(const bt_status_t& status) { case BT_STATUS_UNHANDLED: return std::string("unhandled"); case BT_STATUS_AUTH_FAILURE: - return std::string("failure"); + return std::string("auth_failure"); case BT_STATUS_RMT_DEV_DOWN: return std::string("remote_device_down"); case BT_STATUS_AUTH_REJECTED: - return std::string("rejected"); + return std::string("auth_rejected"); case BT_STATUS_JNI_ENVIRONMENT_ERROR: return std::string("jni_env_error"); case BT_STATUS_JNI_THREAD_ATTACH_ERROR: @@ -156,7 +158,7 @@ typedef struct { uint8_t pin[16]; } __attribute__((packed)) bt_pin_code_t; typedef struct { uint8_t status; - uint8_t ctrl_state; /* stack reported state */ + uint32_t ctrl_state; /* stack reported state */ uint64_t tx_time; /* in ms */ uint64_t rx_time; /* in ms */ uint64_t idle_time; /* in ms */ @@ -401,6 +403,20 @@ typedef enum { */ BT_PROPERTY_REMOTE_ADDR_TYPE, + /** + * Description - Whether remote device supports Secure Connections mode + * Access mode - GET and SET. + * Data Type - uint8_t. + */ + BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED, + + /** + * Description - Maximum observed session key for remote device + * Access mode - GET and SET. + * Data Type - uint8_t. + */ + BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE, + BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF, } bt_property_type_t; @@ -593,6 +609,8 @@ typedef void (*energy_info_callback)(bt_activity_energy_info* energy_info, typedef void (*generate_local_oob_data_callback)(tBT_TRANSPORT transport, bt_oob_data_t oob_data); +typedef void (*key_missing_callback)(const RawAddress bd_addr); + /** TODO: Add callbacks for Link Up/Down and other generic * notifications/callbacks */ @@ -620,6 +638,7 @@ typedef struct { switch_buffer_size_callback switch_buffer_size_cb; switch_codec_callback switch_codec_cb; le_rand_callback le_rand_cb; + key_missing_callback key_missing_cb; } bt_callbacks_t; typedef int (*acquire_wake_lock_callout)(const char* lock_name); @@ -739,6 +758,8 @@ typedef struct { /** Cancel Bond */ int (*cancel_bond)(const RawAddress* bd_addr); + bool (*pairing_is_busy)(); + /** * Get the connection status for a given remote device. * return value of 0 means the device is not connected, @@ -935,6 +956,13 @@ typedef struct { */ bool (*get_swb_supported)(); + /** + * + * Is the specified coding format supported by the adapter + * + */ + bool (*is_coding_format_supported)(uint8_t coding_format); + /** * Data passed from BluetoothDevice.metadata_changed * @@ -975,4 +1003,20 @@ typedef struct { #define BLUETOOTH_INTERFACE_STRING "bluetoothInterface" +#if __has_include() +#include + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + +#endif // __has_include() + #endif /* ANDROID_INCLUDE_BLUETOOTH_H */ diff --git a/system/include/hardware/bt_av.h b/system/include/hardware/bt_av.h index 8f42b3a07f8acb98e8819e44bb4ba789ea535986..80512e34ede88423f346462213f9789bc2b217dd 100644 --- a/system/include/hardware/bt_av.h +++ b/system/include/hardware/bt_av.h @@ -17,6 +17,7 @@ #ifndef ANDROID_INCLUDE_BT_AV_H #define ANDROID_INCLUDE_BT_AV_H +#include #include #include @@ -61,7 +62,14 @@ typedef enum { BTAV_A2DP_CODEC_INDEX_SOURCE_MAX, - BTAV_A2DP_CODEC_INDEX_SINK_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MAX, + // Range of codec indexes reserved for Offload codec extensibility. + // Indexes in this range will be allocated for offloaded codecs + // that the stack does not recognize. + BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MAX, + BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX = + BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN + 4, + + BTAV_A2DP_CODEC_INDEX_SINK_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX, // Add an entry for each sink codec here BTAV_A2DP_CODEC_INDEX_SINK_SBC = BTAV_A2DP_CODEC_INDEX_SINK_MIN, @@ -71,10 +79,22 @@ typedef enum { BTAV_A2DP_CODEC_INDEX_SINK_MAX, + // Range of codec indexes reserved for Offload codec extensibility. + // Indexes in this range will be allocated for offloaded codecs + // that the stack does not recognize. + BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN = BTAV_A2DP_CODEC_INDEX_SINK_MAX, + BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX = BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN + 4, + BTAV_A2DP_CODEC_INDEX_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MIN, - BTAV_A2DP_CODEC_INDEX_MAX = BTAV_A2DP_CODEC_INDEX_SINK_MAX + BTAV_A2DP_CODEC_INDEX_MAX = BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX } btav_a2dp_codec_index_t; +typedef struct { + btav_a2dp_codec_index_t codec_type; + uint64_t codec_id; + std::string codec_name; +} btav_a2dp_codec_info_t; + typedef enum { // Disable the codec. // NOTE: This value can be used only during initialization when @@ -188,6 +208,10 @@ struct btav_a2dp_codec_config_t { case BTAV_A2DP_CODEC_INDEX_MAX: codec_name_str = "Unknown(CODEC_INDEX_MAX)"; break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN: + case BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN: + codec_name_str = "Unknown(CODEC_EXT)"; + break; } std::string sample_rate_str; @@ -353,7 +377,8 @@ typedef struct { bt_status_t (*init)( btav_source_callbacks_t* callbacks, int max_connected_audio_devices, const std::vector& codec_priorities, - const std::vector& offloading_preference); + const std::vector& offloading_preference, + std::vector* supported_codecs); /** connect to headset */ bt_status_t (*connect)(const RawAddress& bd_addr); @@ -409,4 +434,30 @@ typedef struct { __END_DECLS +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt + #endif /* ANDROID_INCLUDE_BT_AV_H */ diff --git a/system/include/hardware/bt_common_types.h b/system/include/hardware/bt_common_types.h index ad3c7de136147a75e2230529e49557ec6ba6e46d..601b64b0eabcea7e12ab4d761f1986931ce6fb66 100644 --- a/system/include/hardware/bt_common_types.h +++ b/system/include/hardware/bt_common_types.h @@ -128,4 +128,14 @@ struct MsftAdvMonitor { std::vector patterns; }; +#if __has_include() +#include + +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt +#endif // __has_include() + #endif /* ANDROID_INCLUDE_BT_COMMON_TYPES_H */ diff --git a/system/include/hardware/bt_hd.h b/system/include/hardware/bt_hd.h index 0566e89455d952d2d1fb1e10973886d1ff1544e5..732dc6168b3a6f71ab36361b6aa7023046306df3 100644 --- a/system/include/hardware/bt_hd.h +++ b/system/include/hardware/bt_hd.h @@ -126,4 +126,14 @@ typedef struct { __END_DECLS +#if __has_include() +#include + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + +#endif // __has_include() + #endif /* ANDROID_INCLUDE_BT_HD_H */ diff --git a/system/include/hardware/bt_hf.h b/system/include/hardware/bt_hf.h index 671e564084229ceb17179216b5e34625819fb8a1..074c896fec9b43f3477d46b201bafeb9512ea994 100644 --- a/system/include/hardware/bt_hf.h +++ b/system/include/hardware/bt_hf.h @@ -16,6 +16,8 @@ #pragma once +#include + namespace bluetooth { namespace headset { @@ -137,3 +139,24 @@ typedef enum { } // namespace headset } // namespace bluetooth + +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt diff --git a/system/include/hardware/bt_hf_client.h b/system/include/hardware/bt_hf_client.h index 9e64dbb48193a56368b2556041b27e6fccfafed6..83d005b8df37ef89e6dda8b322c78dd755bf1fb8 100644 --- a/system/include/hardware/bt_hf_client.h +++ b/system/include/hardware/bt_hf_client.h @@ -14,11 +14,10 @@ * limitations under the License. */ -#ifndef ANDROID_INCLUDE_BT_HF_CLIENT_H -#define ANDROID_INCLUDE_BT_HF_CLIENT_H -#include +#pragma once -__BEGIN_DECLS +#include +#include typedef enum { BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED = 0, @@ -398,6 +397,8 @@ typedef struct { bt_status_t (*send_android_at)(const RawAddress* bd_addr, const char* arg); } bthf_client_interface_t; -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HF_CLIENT_H */ +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt diff --git a/system/include/hardware/bt_hh.h b/system/include/hardware/bt_hh.h index 1be58aa0c0355410357a631295b9b426a16d1497..c9ee0a95f1fbc2cd86bcc7d39ea6ecd610882a16 100644 --- a/system/include/hardware/bt_hh.h +++ b/system/include/hardware/bt_hh.h @@ -224,4 +224,20 @@ typedef struct { } bthh_interface_t; __END_DECLS +#if __has_include() +#include + +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter : enum_formatter { +}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + +#endif // __has_include() + #endif /* ANDROID_INCLUDE_BT_HH_H */ diff --git a/system/include/hardware/bt_le_audio.h b/system/include/hardware/bt_le_audio.h index c7d3130d918ad05d190d7d5f7ee3aca8fe5e6dcf..b149fec9e069429a45c0f8fcd7014f0981825e08 100644 --- a/system/include/hardware/bt_le_audio.h +++ b/system/include/hardware/bt_le_audio.h @@ -17,6 +17,8 @@ #pragma once +#include + #include #include #include @@ -102,11 +104,18 @@ typedef enum { QUALITY_STANDARD = 0, QUALITY_HIGH } btle_audio_quality_t; typedef enum { LE_AUDIO_SAMPLE_RATE_INDEX_NONE = 0, LE_AUDIO_SAMPLE_RATE_INDEX_8000HZ = 0x01 << 0, + LE_AUDIO_SAMPLE_RATE_INDEX_11025HZ = 0x01 << 1, LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ = 0x01 << 2, + LE_AUDIO_SAMPLE_RATE_INDEX_22050HZ = 0x01 << 3, LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ = 0x01 << 4, LE_AUDIO_SAMPLE_RATE_INDEX_32000HZ = 0x01 << 5, LE_AUDIO_SAMPLE_RATE_INDEX_44100HZ = 0x01 << 6, - LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ = 0x01 << 7 + LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ = 0x01 << 7, + LE_AUDIO_SAMPLE_RATE_INDEX_88200HZ = 0x01 << 8, + LE_AUDIO_SAMPLE_RATE_INDEX_96000HZ = 0x01 << 9, + LE_AUDIO_SAMPLE_RATE_INDEX_176400HZ = 0x01 << 10, + LE_AUDIO_SAMPLE_RATE_INDEX_192000HZ = 0x01 << 11, + LE_AUDIO_SAMPLE_RATE_INDEX_384000HZ = 0x01 << 12 } btle_audio_sample_rate_index_t; typedef enum { @@ -162,9 +171,15 @@ typedef struct { case LE_AUDIO_SAMPLE_RATE_INDEX_8000HZ: sample_rate_str = "8000 hz"; break; + case LE_AUDIO_SAMPLE_RATE_INDEX_11025HZ: + sample_rate_str = "11025 hz"; + break; case LE_AUDIO_SAMPLE_RATE_INDEX_16000HZ: sample_rate_str = "16000 hz"; break; + case LE_AUDIO_SAMPLE_RATE_INDEX_22050HZ: + sample_rate_str = "22050 hz"; + break; case LE_AUDIO_SAMPLE_RATE_INDEX_24000HZ: sample_rate_str = "24000 hz"; break; @@ -177,6 +192,21 @@ typedef struct { case LE_AUDIO_SAMPLE_RATE_INDEX_48000HZ: sample_rate_str = "48000 hz"; break; + case LE_AUDIO_SAMPLE_RATE_INDEX_88200HZ: + sample_rate_str = "88200 hz"; + break; + case LE_AUDIO_SAMPLE_RATE_INDEX_96000HZ: + sample_rate_str = "96000 hz"; + break; + case LE_AUDIO_SAMPLE_RATE_INDEX_176400HZ: + sample_rate_str = "176400 hz"; + break; + case LE_AUDIO_SAMPLE_RATE_INDEX_192000HZ: + sample_rate_str = "192000 hz"; + break; + case LE_AUDIO_SAMPLE_RATE_INDEX_384000HZ: + sample_rate_str = "384000 hz"; + break; default: sample_rate_str = "Unknown LE sample rate " + std::to_string(sample_rate); @@ -305,6 +335,10 @@ class LeAudioClientCallbacks { virtual void OnUnicastMonitorModeStatus(uint8_t direction, UnicastMonitorModeStatus status) = 0; + + /* Callback with group stream status update */ + virtual void OnGroupStreamStatus(int group_id, + GroupStreamStatus group_stream_status) = 0; }; class LeAudioClientInterface { @@ -501,3 +535,22 @@ class LeAudioBroadcasterInterface { } /* namespace le_audio */ } /* namespace bluetooth */ + +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter { +}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt diff --git a/system/include/hardware/bt_pan.h b/system/include/hardware/bt_pan.h index 439edf8592434a661c6ceeecfe428247908381f9..25261baf9391845a2821937c868b795e41e7c814 100644 --- a/system/include/hardware/bt_pan.h +++ b/system/include/hardware/bt_pan.h @@ -14,11 +14,10 @@ * limitations under the License. */ -#ifndef ANDROID_INCLUDE_BT_PAN_H -#define ANDROID_INCLUDE_BT_PAN_H -#include +#pragma once -__BEGIN_DECLS +#include +#include #define BTPAN_ROLE_NONE 0 #define BTPAN_ROLE_PANNAP 1 @@ -90,6 +89,12 @@ typedef struct { } btpan_interface_t; -__END_DECLS +namespace fmt { +template <> +struct formatter + : enum_formatter {}; -#endif /* ANDROID_INCLUDE_BT_PAN_H */ +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt diff --git a/system/include/hardware/bt_rc.h b/system/include/hardware/bt_rc.h index dc3179a292d6f6cc1a4c2405938c64cf4244950b..849793944175692fdbbcbacd5ebceeca4f7fd04b 100644 --- a/system/include/hardware/bt_rc.h +++ b/system/include/hardware/bt_rc.h @@ -727,4 +727,22 @@ typedef struct { __END_DECLS +#if __has_include() +#include + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt + +#endif // __has_include() + #endif /* ANDROID_INCLUDE_BT_RC_H */ diff --git a/system/include/hardware/bt_sdp.h b/system/include/hardware/bt_sdp.h index 77d00bd43dd0f578b18d57f90d57154dd5e42b36..fd4a970e0572b2cba8a060ca635e3cbbf6d0fd06 100644 --- a/system/include/hardware/bt_sdp.h +++ b/system/include/hardware/bt_sdp.h @@ -178,3 +178,13 @@ typedef struct { } btsdp_interface_t; __END_DECLS + +#if __has_include() +#include + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + +#endif // __has_include() diff --git a/system/include/hardware/bt_sock.h b/system/include/hardware/bt_sock.h index 7d5060e00593fc9ac835b6c2d90671aaf84d0c91..47e53ca0da9779dc00c34c0f42c68be3db128371 100644 --- a/system/include/hardware/bt_sock.h +++ b/system/include/hardware/bt_sock.h @@ -110,3 +110,13 @@ typedef struct { } btsock_interface_t; __END_DECLS + +#if __has_include() +#include + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + +#endif // __has_include() diff --git a/system/include/hardware/distance_measurement_interface.h b/system/include/hardware/distance_measurement_interface.h index f5febb1f9bdbd6b2dca012748a313fdc4ebbe796..99aa7c2f2c716325785d30bc711a50aeb4d9aaa0 100644 --- a/system/include/hardware/distance_measurement_interface.h +++ b/system/include/hardware/distance_measurement_interface.h @@ -45,7 +45,7 @@ class DistanceMeasurementInterface { virtual void RegisterDistanceMeasurementCallbacks( DistanceMeasurementCallbacks* callbacks) = 0; virtual void StartDistanceMeasurement(RawAddress raw_address, - uint16_t frequency, uint8_t method) = 0; + uint16_t interval, uint8_t method) = 0; virtual void StopDistanceMeasurement(RawAddress raw_address, uint8_t method) = 0; }; diff --git a/system/internal_include/bt_target.h b/system/internal_include/bt_target.h index 87bb256d369d622764efd19f5b9039d9664e6aa7..be8ddc35758395c363c933ac91f6d6fb4675d88c 100644 --- a/system/internal_include/bt_target.h +++ b/system/internal_include/bt_target.h @@ -20,12 +20,6 @@ #ifndef BT_TARGET_H #define BT_TARGET_H -#ifndef BUILDCFG -#define BUILDCFG -#endif - -#include "stack/include/bt_types.h" /* This must be defined AFTER buildcfg.h */ - #ifndef FALSE #define FALSE false #endif @@ -74,13 +68,6 @@ #define BTA_AG_AT_MAX_LEN 512 #endif -#ifndef BTA_AG_SCO_PKT_TYPES -#define BTA_AG_SCO_PKT_TYPES \ - (BTM_SCO_LINK_ONLY_MASK | ESCO_PKT_TYPES_MASK_EV3 | \ - ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 | \ - ESCO_PKT_TYPES_MASK_NO_3_EV5) -#endif - #ifndef BTA_AV_RET_TOUT #define BTA_AV_RET_TOUT 15 #endif @@ -89,18 +76,10 @@ #define BTA_DM_SDP_DB_SIZE 20000 #endif -#ifndef HL_INCLUDED -#define HL_INCLUDED TRUE -#endif - #ifndef AG_VOICE_SETTINGS #define AG_VOICE_SETTINGS HCI_DEFAULT_VOICE_SETTINGS #endif -#ifndef BTIF_DM_OOB_TEST -#define BTIF_DM_OOB_TEST TRUE -#endif - // How long to wait before activating sniff mode after entering the // idle state for server FT/RFCOMM, OPS connections #ifndef BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS @@ -154,10 +133,6 @@ #define L2CAP_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE #endif -#ifndef L2CAP_FCR_ERTM_BUF_SIZE -#define L2CAP_FCR_ERTM_BUF_SIZE (10240 + 24) -#endif - /* Number of ACL buffers to assign to LE */ /* * TODO: Do we need this? @@ -172,10 +147,6 @@ #define BTM_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE #endif -#ifndef OBX_LRG_DATA_BUF_SIZE -#define OBX_LRG_DATA_BUF_SIZE (8080 + 26) -#endif - /* BNEP data and protocol messages. */ #ifndef BNEP_BUF_SIZE #define BNEP_BUF_SIZE BT_DEFAULT_BUFFER_SIZE @@ -210,10 +181,6 @@ #define AVRC_META_CMD_BUF_SIZE BT_SMALL_BUFFER_SIZE #endif -#ifndef BTA_HL_LRG_DATA_BUF_SIZE -#define BTA_HL_LRG_DATA_BUF_SIZE (10240 + 24) -#endif - /* GATT Data sending buffer size */ #ifndef GATT_DATA_BUF_SIZE #define GATT_DATA_BUF_SIZE BT_DEFAULT_BUFFER_SIZE @@ -234,13 +201,6 @@ #define DISABLE_WBS FALSE #endif -/* This is used to work around a controller bug that doesn't like Disconnect - * issued while there is a role switch in progress -*/ -#ifndef BTM_DISC_DURING_RS -#define BTM_DISC_DURING_RS TRUE -#endif - /************************** * Initial SCO TX credit ************************/ @@ -350,24 +310,10 @@ #define BTM_LOCAL_IO_CAPS BTM_IO_CAP_IO #endif -#ifndef BTM_LOCAL_IO_CAPS_BLE -#define BTM_LOCAL_IO_CAPS_BLE BTM_IO_CAP_KBDISP -#endif - -/* TRUE to include Sniff Subrating */ -#ifndef BTM_SSR_INCLUDED -#define BTM_SSR_INCLUDED TRUE -#endif - /************************* * End of Lisbon Features *************************/ -/* 4.1/4.2 secure connections feature */ -#ifndef SC_MODE_INCLUDED -#define SC_MODE_INCLUDED TRUE -#endif - /****************************************************************************** * * L2CAP @@ -412,36 +358,11 @@ #define L2CAP_MTU_SIZE 1691 #endif -/* - * The L2CAP MPS over Bluetooth; must be in accord with the FCR tx buffer size - * and ACL down buffer size. - */ -#ifndef L2CAP_MPS_OVER_BR_EDR -#define L2CAP_MPS_OVER_BR_EDR 1010 -#endif - -/* If host flow control enabled, this is the number of buffers the controller - * can have unacknowledged. */ -#ifndef L2CAP_HOST_FC_ACL_BUFS -#define L2CAP_HOST_FC_ACL_BUFS 20 -#endif - -/* This is set to enable L2CAP to take the ACL link out of park mode when ACL - * data is to be sent. */ -#ifndef L2CAP_WAKE_PARKED_LINK -#define L2CAP_WAKE_PARKED_LINK TRUE -#endif - /* Minimum number of ACL credit for high priority link */ #ifndef L2CAP_HIGH_PRI_MIN_XMIT_QUOTA #define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA 5 #endif -/* used for monitoring HCI ACL credit management */ -#ifndef L2CAP_HCI_FLOW_CONTROL_DEBUG -#define L2CAP_HCI_FLOW_CONTROL_DEBUG TRUE -#endif - /* Used for features using fixed channels; set to zero if no fixed channels * supported (BLE, etc.) */ /* Excluding L2CAP signaling channel and UCD */ @@ -459,11 +380,6 @@ (L2CAP_FIRST_FIXED_CHNL + L2CAP_NUM_FIXED_CHNLS - 1) #endif -/* Round Robin service channels in link */ -#ifndef L2CAP_ROUND_ROBIN_CHANNEL_SERVICE -#define L2CAP_ROUND_ROBIN_CHANNEL_SERVICE TRUE -#endif - /* Used for conformance testing ONLY: When TRUE lets scriptwrapper overwrite * info response */ #ifndef L2CAP_CONFORMANCE_TESTING @@ -547,10 +463,6 @@ * SMP * *****************************************************************************/ -#ifndef SMP_DEBUG -#define SMP_DEBUG FALSE -#endif - #ifndef SMP_DEFAULT_AUTH_REQ #define SMP_DEFAULT_AUTH_REQ SMP_AUTH_NB_ENC_ONLY #endif @@ -631,11 +543,6 @@ #define SDP_MTU_SIZE 1024 #endif -/* The name for security authorization. */ -#ifndef SDP_SERVICE_NAME -#define SDP_SERVICE_NAME "Service Discovery" -#endif - /****************************************************************************** * * RFCOMM @@ -717,11 +624,6 @@ #define BNEP_INCLUDED TRUE #endif -/* BNEP status API call is used mainly to get the L2CAP handle */ -#ifndef BNEP_SUPPORTS_STATUS_API -#define BNEP_SUPPORTS_STATUS_API TRUE -#endif - /* Maximum number of protocol filters supported. */ #ifndef BNEP_MAX_PROT_FILTERS #define BNEP_MAX_PROT_FILTERS 5 @@ -947,6 +849,4 @@ * *****************************************************************************/ -#include "internal_include/bt_trace.h" - #endif /* BT_TARGET_H */ diff --git a/system/log/Android.bp b/system/log/Android.bp new file mode 100644 index 0000000000000000000000000000000000000000..10c7e730db8f4908a4ab20cbb3a7a4706d7ea2f7 --- /dev/null +++ b/system/log/Android.bp @@ -0,0 +1,31 @@ +cc_library { + name: "libbluetooth_log", + host_supported: true, + min_sdk_version: "33", + apex_available: [ + "com.android.btservices", + ], + export_include_dirs: [ + "include", + ], + shared_libs: [ + "libbase", + "liblog", + ], + srcs: [ + "src/vlog_android.cc", + ], +} + +cc_test { + name: "libbluetooth_log_test", + host_supported: true, + srcs: [ + "src/truncating_buffer_test.cc", + "src/vlog_test.cc", + ], + shared_libs: [ + "libbase", + "libbluetooth_log", + ], +} diff --git a/system/log/BUILD.gn b/system/log/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b7b94e7deedd4bd479b071132ca2943b9b1d91e5 --- /dev/null +++ b/system/log/BUILD.gn @@ -0,0 +1,36 @@ +# +# Copyright 2024 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. +# + +config("log_defaults") { + include_dirs = [ + "//bt/system/log/include", + ] +} + +static_library("libbluetooth_log") { + cflags = [ + "-fvisibility=default", + ] + sources = [ + "include/bluetooth/log.h", + "src/truncating_buffer.h", + "src/vlog_syslog.cc", + ] + configs += [ + "//bt/system:target_defaults", + ":log_defaults", + ] +} diff --git a/system/log/include/bluetooth/log.h b/system/log/include/bluetooth/log.h new file mode 100644 index 0000000000000000000000000000000000000000..81106fcdfa93fad8ab8d1b15d6f6d6d508bcbe14 --- /dev/null +++ b/system/log/include/bluetooth/log.h @@ -0,0 +1,187 @@ +/* + * Copyright 2023 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 +#include +#include + +#ifndef LOG_TAG +#define LOG_TAG "bluetooth" +#endif // LOG_TAG + +namespace bluetooth::log_internal { + +/// Android framework log priority levels. +/// They are defined in system/logging/liblog/include/android/log.h by +/// the Android Framework code. +enum Level { + kVerbose = 2, + kDebug = 3, + kInfo = 4, + kWarn = 5, + kError = 6, + kFatal = 7, +}; + +/// Write a single log line. +/// The implementation of this function is dependent on the backend. +void vlog(Level level, char const* tag, char const* file_name, int line, + char const* function_name, fmt::string_view fmt, + fmt::format_args vargs); + +/// Capture invalid parameter values that would cause runtime +/// formatting errors. +template +[[maybe_unused]] static inline T& format_replace(T& arg) { + return arg; +} + +/// Specialization of format_replace for nullptr string parameters. +template <> +char const*& format_replace(char const*& arg) { + static char const* nullptr_str = "(nullptr)"; + if (arg) return arg; + return nullptr_str; +} + +/// Specialization of format_replace for nullptr string parameters. +template <> +char*& format_replace(char*& arg) { + static char* nullptr_str = (char*)"(nullptr)"; + if (arg) return arg; + return nullptr_str; +} + +template +struct log { + log(fmt::format_string fmt, T&&... args, + char const* file_name = __builtin_FILE(), int line = __builtin_LINE(), + char const* function_name = __builtin_FUNCTION()) { + vlog(level, LOG_TAG, file_name, line, function_name, + static_cast(fmt), + fmt::make_format_args(format_replace(args)...)); + } +}; + +#if (__cplusplus >= 202002L && defined(__GNUC__) && !defined(__clang__)) + +template +log(fmt::format_string, T&&...) -> log; + +#endif + +} // namespace bluetooth::log_internal + +namespace bluetooth::log { + +#if (__cplusplus >= 202002L && defined(__GNUC__) && !defined(__clang__)) + +template +using fatal = log_internal::log; +template +using error = log_internal::log; +template +using warning = log_internal::log; +template +using info = log_internal::log; +template +using debug = log_internal::log; +template +using verbose = log_internal::log; + +#else + +template +struct fatal : log_internal::log { + using log_internal::log::log; +}; +template +struct error : log_internal::log { + using log_internal::log::log; +}; +template +struct warn : log_internal::log { + using log_internal::log::log; +}; +template +struct info : log_internal::log { + using log_internal::log::log; +}; +template +struct debug : log_internal::log { + using log_internal::log::log; +}; +template +struct verbose : log_internal::log { + using log_internal::log::log; +}; + +template +fatal(fmt::format_string, T&&...) -> fatal; +template +error(fmt::format_string, T&&...) -> error; +template +warn(fmt::format_string, T&&...) -> warn; +template +info(fmt::format_string, T&&...) -> info; +template +debug(fmt::format_string, T&&...) -> debug; +template +verbose(fmt::format_string, T&&...) -> verbose; + +#endif // GCC / C++20 + +} // namespace bluetooth::log + +namespace fmt { + +/// Default formatter implementation for formatting +/// enum class values to the underlying type. +/// +/// Enable this formatter in the code by declaring: +/// ``` +/// template<> +/// struct fmt::formatter : enum_formatter {}; +/// ``` +template +struct enum_formatter : fmt::formatter, CharT> { + template + typename Context::iterator format(EnumT value, Context& ctx) const { + return fmt::formatter, CharT>::format( + static_cast>(value), ctx); + } +}; + +/// Default formatter implementation for formatting +/// values of type T for which a string conversion function +/// T_to_str is implemented. +/// +/// Enable this formatter in the code by declaring: +/// ``` +/// template<> +/// struct fmt::formatter : string_formatter {}; +/// ``` +template +struct string_formatter : fmt::formatter { + template + typename Context::iterator format(const T& value, Context& ctx) const { + return fmt::formatter::format(F(value), ctx); + } +}; + +} // namespace fmt diff --git a/system/log/src/truncating_buffer.h b/system/log/src/truncating_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..c2ad0014a958c9200cceab4e2f396bc71448e3de --- /dev/null +++ b/system/log/src/truncating_buffer.h @@ -0,0 +1,69 @@ +/* + * Copyright 2023 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 + +namespace bluetooth::log_internal { + +/// Truncating write buffer. +/// +/// This buffer can be used with `std::back_insert_iterator` to create +/// an output iterator. All write actions beyond the maximum length of +/// the buffer are silently ignored. +template +struct truncating_buffer { + using value_type = char; + + void push_back(char c) { + if (len < buffer_size - 1) { + buffer[len++] = c; + } + } + + char const* c_str() { + if (len == buffer_size - 1) { + // Inspect the last 4 bytes of the buffer to check if + // the last character was truncated. Remove the character + // entirely if that's the case. + for (size_t n = 0; n < 4; n++) { + char c = buffer[len - n - 1]; + if ((c & 0b11000000) == 0b10000000) { + continue; + } + size_t char_len = (c & 0b10000000) == 0b00000000 ? 1 + : (c & 0b11100000) == 0b11000000 ? 2 + : (c & 0b11110000) == 0b11100000 ? 3 + : (c & 0b11111000) == 0b11110000 ? 4 + : 0; + if ((n + 1) < char_len) { + len -= n + 1; + } + break; + } + } + + buffer[len] = '\0'; + return buffer; + } + + private: + char buffer[buffer_size]; + size_t len{0}; +}; + +} // namespace bluetooth::log_internal diff --git a/system/log/src/truncating_buffer_test.cc b/system/log/src/truncating_buffer_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..5790270cdc68a86a1b8623158d8c46c7e52755e4 --- /dev/null +++ b/system/log/src/truncating_buffer_test.cc @@ -0,0 +1,83 @@ +/* + * Copyright 2023 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 "test" + +#include "truncating_buffer.h" + +#include +#include +#include + +using namespace bluetooth::log_internal; + +TEST(TruncatingBufferTest, 1byte) { + EXPECT_EQ(sizeof("ab"), 3); + truncating_buffer<2> buffer_1; + truncating_buffer<3> buffer_2; + fmt::format_to(std::back_insert_iterator(buffer_1), "ab"); + fmt::format_to(std::back_insert_iterator(buffer_2), "ab"); + EXPECT_STREQ(buffer_1.c_str(), "a"); + EXPECT_STREQ(buffer_2.c_str(), "ab"); +} + +TEST(TruncatingBufferTest, 2bytes) { + EXPECT_EQ(sizeof("αβ"), 5); + truncating_buffer<3> buffer_1; + truncating_buffer<4> buffer_2; + truncating_buffer<5> buffer_3; + fmt::format_to(std::back_insert_iterator(buffer_1), "αβ"); + fmt::format_to(std::back_insert_iterator(buffer_2), "αβ"); + fmt::format_to(std::back_insert_iterator(buffer_3), "αβ"); + EXPECT_STREQ(buffer_1.c_str(), "α"); + EXPECT_STREQ(buffer_2.c_str(), "α"); + EXPECT_STREQ(buffer_3.c_str(), "αβ"); +} + +TEST(TruncatingBufferTest, 3bytes) { + EXPECT_EQ(sizeof("ພຮ"), 7); + truncating_buffer<4> buffer_1; + truncating_buffer<5> buffer_2; + truncating_buffer<6> buffer_3; + truncating_buffer<7> buffer_4; + fmt::format_to(std::back_insert_iterator(buffer_1), "ພຮ"); + fmt::format_to(std::back_insert_iterator(buffer_2), "ພຮ"); + fmt::format_to(std::back_insert_iterator(buffer_3), "ພຮ"); + fmt::format_to(std::back_insert_iterator(buffer_4), "ພຮ"); + EXPECT_STREQ(buffer_1.c_str(), "ພ"); + EXPECT_STREQ(buffer_2.c_str(), "ພ"); + EXPECT_STREQ(buffer_3.c_str(), "ພ"); + EXPECT_STREQ(buffer_4.c_str(), "ພຮ"); +} + +TEST(TruncatingBufferTest, 4bytes) { + EXPECT_EQ(sizeof("𐎡𐎪"), 9); + truncating_buffer<5> buffer_1; + truncating_buffer<6> buffer_2; + truncating_buffer<7> buffer_3; + truncating_buffer<8> buffer_4; + truncating_buffer<9> buffer_5; + fmt::format_to(std::back_insert_iterator(buffer_1), "𐎡𐎪"); + fmt::format_to(std::back_insert_iterator(buffer_2), "𐎡𐎪"); + fmt::format_to(std::back_insert_iterator(buffer_3), "𐎡𐎪"); + fmt::format_to(std::back_insert_iterator(buffer_4), "𐎡𐎪"); + fmt::format_to(std::back_insert_iterator(buffer_5), "𐎡𐎪"); + EXPECT_STREQ(buffer_1.c_str(), "𐎡"); + EXPECT_STREQ(buffer_2.c_str(), "𐎡"); + EXPECT_STREQ(buffer_3.c_str(), "𐎡"); + EXPECT_STREQ(buffer_4.c_str(), "𐎡"); + EXPECT_STREQ(buffer_5.c_str(), "𐎡𐎪"); +} diff --git a/system/log/src/vlog_android.cc b/system/log/src/vlog_android.cc new file mode 100644 index 0000000000000000000000000000000000000000..e5ca8f1fc84553724ddb89f994ab296b967a266c --- /dev/null +++ b/system/log/src/vlog_android.cc @@ -0,0 +1,62 @@ +/* + * Copyright 2023 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 + +#include "bluetooth/log.h" +#include "truncating_buffer.h" + +namespace bluetooth::log_internal { + +static constexpr size_t kBufferSize = 1024; + +void vlog(Level level, char const* tag, char const* file_name, int line, + char const* function_name, fmt::string_view fmt, + fmt::format_args vargs) { + // Check if log is enabled. + if (!__android_log_is_loggable(level, tag, ANDROID_LOG_INFO) && + !__android_log_is_loggable(level, "bluetooth", ANDROID_LOG_INFO)) { + return; + } + + // Format to stack buffer. + truncating_buffer buffer; + fmt::format_to(std::back_insert_iterator(buffer), "{}: ", function_name); + fmt::vformat_to(std::back_insert_iterator(buffer), fmt, vargs); + + // Send message to liblog. + struct __android_log_message message = { + .struct_size = sizeof(__android_log_message), + .buffer_id = LOG_ID_MAIN, + .priority = static_cast(level), + .tag = tag, + .file = file_name, + .line = static_cast(line), + .message = buffer.c_str(), + }; + __android_log_write_log_message(&message); + + if (level == Level::kFatal) { + // Log assertion failures to stderr for the benefit of "adb shell" users + // and gtests (http://b/23675822). + char const* buf = buffer.c_str(); + TEMP_FAILURE_RETRY(write(2, buf, strlen(buf))); + TEMP_FAILURE_RETRY(write(2, "\n", 1)); + __android_log_call_aborter(buf); + } +} + +} // namespace bluetooth::log_internal diff --git a/system/log/src/vlog_syslog.cc b/system/log/src/vlog_syslog.cc new file mode 100644 index 0000000000000000000000000000000000000000..d119ca13396d5f12ebf3cae21baed73451d4b4a7 --- /dev/null +++ b/system/log/src/vlog_syslog.cc @@ -0,0 +1,119 @@ +/* + * Copyright 2023 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 + +#include +#include + +#include "bluetooth/log.h" +#include "truncating_buffer.h" + +namespace bluetooth::log_internal { + +// Map of tags with custom levels. +std::unordered_map& GetTagMap() { + static std::unordered_map tag_level_map; + return tag_level_map; +} + +// Default log level. +Level gDefaultLogLevel = Level::kInfo; + +Level GetLogLevelForTag(char const* tag) { + auto tag_map = GetTagMap(); + auto find = tag_map.find(tag); + if (find != tag_map.end()) { + return find->second; + } else { + return gDefaultLogLevel; + } +} + +Level GetDefaultLogLevel() { return gDefaultLogLevel; } + +// Default value for $MaxMessageSize for rsyslog. +static constexpr size_t kBufferSize = 8192; + +void vlog(Level level, char const* tag, char const* file_name, int line, + char const* function_name, fmt::string_view fmt, + fmt::format_args vargs) { + // Filter out logs that don't meet level requirement. + Level current_level = GetLogLevelForTag(tag); + if (level < current_level) { + return; + } + + // Convert the level to syslog severity. + int severity = LOG_DEBUG; + switch (level) { + case Level::kVerbose: + case Level::kDebug: + default: + severity = LOG_DEBUG; + break; + case Level::kInfo: + severity = LOG_INFO; + break; + case Level::kWarn: + severity = LOG_WARNING; + break; + case Level::kError: + severity = LOG_ERR; + break; + case Level::kFatal: + severity = LOG_CRIT; + break; + } + + // Prepare bounded stack buffer. + truncating_buffer buffer; + + // Format file, line. + fmt::format_to(std::back_insert_iterator(buffer), "{} {}:{} {}: ", tag, + file_name, line, function_name); + + // Format message. + fmt::vformat_to(std::back_insert_iterator(buffer), fmt, vargs); + + // Print to vsyslog. + syslog(LOG_USER | severity, "%s", buffer.c_str()); +} + +} // namespace bluetooth::log_internal + +// These apis will be exposed in topshim to allow control of syslog log levels. +extern "C" { +void SetLogLevelForTag(char const* tag, uint8_t level) { + if (level < bluetooth::log_internal::Level::kVerbose || + level > bluetooth::log_internal::Level::kFatal) { + level = bluetooth::log_internal::GetDefaultLogLevel(); + } + + bluetooth::log_internal::GetTagMap().emplace( + tag, static_cast(level)); +} + +void SetDefaultLogLevel(uint8_t level) { + if (level < bluetooth::log_internal::Level::kVerbose || + level > bluetooth::log_internal::Level::kFatal) { + return; + } + + bluetooth::log_internal::gDefaultLogLevel = + static_cast(level); +} +} diff --git a/system/log/src/vlog_test.cc b/system/log/src/vlog_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..f5f41b6c5dfb19355f94f22851c4e8dcdb1b3760 --- /dev/null +++ b/system/log/src/vlog_test.cc @@ -0,0 +1,134 @@ +/* + * Copyright 2023 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 "test" + +#include +#include + +#include "bluetooth/log.h" +#include "truncating_buffer.h" + +/// Captures the latest message generated by the android vlog +/// implementation. +static std::optional<__android_log_message> androidLogMessage; + +/// Mask the implementation from liblog. +int __android_log_is_loggable(int /*prio*/, const char* /*tag*/, + int /*default_prio*/) { + return true; +} + +/// Mask the implementation from liblog. +void __android_log_write_log_message( + struct __android_log_message* log_message) { + if (log_message != nullptr) { + log_message->message = strdup(log_message->message); + androidLogMessage.emplace(*log_message); + } +} + +using namespace bluetooth; + +TEST(BluetoothLoggerTest, verbose) { + androidLogMessage.reset(); + + log::verbose("verbose test"); + + ASSERT_TRUE(androidLogMessage.has_value()); + EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_VERBOSE); + EXPECT_STREQ(androidLogMessage->tag, LOG_TAG); + EXPECT_STREQ(androidLogMessage->file, + "packages/modules/Bluetooth/system/log/src/vlog_test.cc"); + EXPECT_EQ(androidLogMessage->line, 49); + EXPECT_STREQ(androidLogMessage->message, "TestBody: verbose test"); +} + +TEST(BluetoothLoggerTest, debug) { + androidLogMessage.reset(); + + log::debug("debug test"); + + ASSERT_TRUE(androidLogMessage.has_value()); + EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_DEBUG); + EXPECT_STREQ(androidLogMessage->tag, LOG_TAG); + EXPECT_STREQ(androidLogMessage->file, + "packages/modules/Bluetooth/system/log/src/vlog_test.cc"); + EXPECT_EQ(androidLogMessage->line, 63); + EXPECT_STREQ(androidLogMessage->message, "TestBody: debug test"); +} + +TEST(BluetoothLoggerTest, info) { + androidLogMessage.reset(); + + log::info("info test"); + + ASSERT_TRUE(androidLogMessage.has_value()); + EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_INFO); + EXPECT_STREQ(androidLogMessage->tag, LOG_TAG); + EXPECT_STREQ(androidLogMessage->file, + "packages/modules/Bluetooth/system/log/src/vlog_test.cc"); + EXPECT_EQ(androidLogMessage->line, 77); + EXPECT_STREQ(androidLogMessage->message, "TestBody: info test"); +} + +TEST(BluetoothLoggerTest, warn) { + androidLogMessage.reset(); + + log::warn("warn test"); + + ASSERT_TRUE(androidLogMessage.has_value()); + EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_WARN); + EXPECT_STREQ(androidLogMessage->tag, LOG_TAG); + EXPECT_STREQ(androidLogMessage->file, + "packages/modules/Bluetooth/system/log/src/vlog_test.cc"); + EXPECT_EQ(androidLogMessage->line, 91); + EXPECT_STREQ(androidLogMessage->message, "TestBody: warn test"); +} + +TEST(BluetoothLoggerTest, error) { + androidLogMessage.reset(); + + log::error("error test"); + + ASSERT_TRUE(androidLogMessage.has_value()); + EXPECT_EQ(androidLogMessage->priority, ANDROID_LOG_ERROR); + EXPECT_STREQ(androidLogMessage->tag, LOG_TAG); + EXPECT_STREQ(androidLogMessage->file, + "packages/modules/Bluetooth/system/log/src/vlog_test.cc"); + EXPECT_EQ(androidLogMessage->line, 105); + EXPECT_STREQ(androidLogMessage->message, "TestBody: error test"); +} + +TEST(BluetoothLoggerTest, null_string_parameter) { + androidLogMessage.reset(); + + char const* const_null_str = nullptr; + log::info("input: {}", const_null_str); + EXPECT_STREQ(androidLogMessage->message, "TestBody: input: (nullptr)"); + + androidLogMessage.reset(); + + char* null_str = nullptr; + log::info("input: {}", null_str); + EXPECT_STREQ(androidLogMessage->message, "TestBody: input: (nullptr)"); + + androidLogMessage.reset(); + + char const* nonnull_str = "hello world"; + log::info("input: {}", nonnull_str); + EXPECT_STREQ(androidLogMessage->message, "TestBody: input: hello world"); +} diff --git a/system/main/Android.bp b/system/main/Android.bp index 3242b155074a30059a9267e6e447a8d1f103ff3c..97288a3dd201964b77fcfa5ac92c0045e46bf18d 100644 --- a/system/main/Android.bp +++ b/system/main/Android.bp @@ -22,6 +22,7 @@ cc_library_static { name: "libbte", defaults: ["fluoride_defaults"], srcs: [ + ":BluetoothStackManagerSources", ":LibBluetoothShimSources", ":LibBluetoothSources", ], @@ -32,11 +33,9 @@ cc_library_static { "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/sys", "packages/modules/Bluetooth/system/btif/co", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/embdrv/sbc/decoder/include", "packages/modules/Bluetooth/system/embdrv/sbc/encoder/include", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/a2dp", "packages/modules/Bluetooth/system/stack/avdt", "packages/modules/Bluetooth/system/stack/btm", @@ -56,8 +55,10 @@ cc_library_static { min_sdk_version: "Tiramisu", static_libs: [ "libbluetooth_gd", + "libbluetooth_log", "libbt-platform-protos-lite", "libbt_shim_bridge", + "libcom.android.sysprop.bluetooth.wrapped", ], header_libs: ["libbluetooth_headers"], cflags: ["-Wno-unused-parameter"], @@ -80,10 +81,8 @@ cc_library { "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/sys", "packages/modules/Bluetooth/system/btif/co", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/embdrv/sbc/decoder/include", "packages/modules/Bluetooth/system/embdrv/sbc/encoder/include", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/a2dp", "packages/modules/Bluetooth/system/stack/avdt", "packages/modules/Bluetooth/system/stack/btm", @@ -109,9 +108,6 @@ cc_library { // that might link statically with some of the code in the library, and // also dlopen(3) the shared library. ldflags: ["-Wl,-Bsymbolic,-Bsymbolic-functions"], - cflags: [ - "-DBUILDCFG", - ], sanitize: { scs: true, }, @@ -127,6 +123,7 @@ cc_library_static { defaults: ["fluoride_defaults"], srcs: [ + ":BluetoothStackManagerSources", ":LibBluetoothShimSources", ":LibBluetoothSources", ], @@ -134,9 +131,7 @@ cc_library_static { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ], generated_headers: [ @@ -144,7 +139,6 @@ cc_library_static { "BluetoothGeneratedDumpsysDataSchema_h", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: [ @@ -154,8 +148,10 @@ cc_library_static { ], header_libs: ["libbluetooth_headers"], static_libs: [ + "libbluetooth_log", "libbt-platform-protos-lite", "libbt_shim_bridge", + "libcom.android.sysprop.bluetooth.wrapped", ], } @@ -183,6 +179,7 @@ cc_test { ":TestMockBta", ":TestMockBtif", ":TestMockBtu", + ":TestMockJni", ":TestMockLegacyHciCommands", ":TestMockLegacyHciInterface", ":TestMockMainShimEntry", @@ -207,20 +204,25 @@ cc_test { "shim/utils.cc", "test/common_stack_test.cc", "test/main_shim_dumpsys_test.cc", + "test/main_shim_stack_lifecycle_test.cc", "test/main_shim_test.cc", ], static_libs: [ + "libbase", "libbluetooth-dumpsys", + "libbluetooth-gdx", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", "libbtdevice", "libchrome", + "libcom.android.sysprop.bluetooth.wrapped", "libevent", "libflatbuffers-cpp", "libgmock", @@ -228,6 +230,7 @@ cc_test { "libosi", ], shared_libs: [ + "libPlatformProperties", "libcrypto", "server_configurable_flags", ], diff --git a/system/main/BUILD.gn b/system/main/BUILD.gn index b71e538c1dcf8fb718fa527d783d903909d1ed73..08456b7f45e4e8e8dfe3ebaa8135ce1560e07269 100644 --- a/system/main/BUILD.gn +++ b/system/main/BUILD.gn @@ -58,7 +58,6 @@ target(lib_type, "bluetooth") { "//bt/system/bta/include", "//bt/system/bta/sys", "//bt/system/bta/dm", - "//bt/system/internal_include", "//bt/system/stack/include", "//bt/system/stack/l2cap", "//bt/system/stack/a2dp", @@ -84,7 +83,9 @@ target(lib_type, "bluetooth") { "//bt/system/embdrv/g722", "//bt/system/embdrv/sbc", "//bt/system/gd:libbluetooth_gd", + "//bt/system/log:libbluetooth_log", "//bt/system/hci", + "//bt/system/main/shim:BluetoothStackManagerSources", "//bt/system/main/shim:LibBluetoothShimSources", "//bt/system/osi", "//bt/system/packet", @@ -95,6 +96,7 @@ target(lib_type, "bluetooth") { configs += [ "//bt/system:target_defaults", + "//bt/system/log:log_defaults", "//bt/system:external_tinyxml2", "//bt/system:external_flatbuffers", ] @@ -106,6 +108,7 @@ target(lib_type, "bluetooth") { libs = [ "dl", + "fmt", "pthread", "resolv", "rt", diff --git a/system/main/bte_conf.cc b/system/main/bte_conf.cc index 603ea70294460f4d3bc2a5cdd84a590144bddd87..b08f0799fa979afe93174a9ad8e64b4bd60c0608 100644 --- a/system/main/bte_conf.cc +++ b/system/main/bte_conf.cc @@ -23,9 +23,10 @@ #include #include "bta/include/bta_api.h" +#include "include/check.h" +#include "os/log.h" #include "osi/include/compat.h" // strlcpy #include "osi/include/config.h" -#include "osi/include/log.h" // Parses the specified Device ID configuration file and registers the // Device ID records with SDP. diff --git a/system/main/bte_init_cpp_logging.cc b/system/main/bte_init_cpp_logging.cc index 520d14db84909963274518f4906b75faa911db3f..367cce1fb97df3b4a33568d1b5deb35e7ea34ea9 100644 --- a/system/main/bte_init_cpp_logging.cc +++ b/system/main/bte_init_cpp_logging.cc @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include "main_int.h" diff --git a/system/main/shim/Android.bp b/system/main/shim/Android.bp index ae14e4fc99a4445ecf85ceeb2d87a6ad071db2fa..b896720583b075b8268a2edee108e5bc85f66ace 100644 --- a/system/main/shim/Android.bp +++ b/system/main/shim/Android.bp @@ -7,6 +7,14 @@ package { default_applicable_licenses: ["system_bt_license"], } +filegroup { + name: "BluetoothStackManagerSources", + srcs: [ + "entry.cc", + "stack.cc", + ], +} + filegroup { name: "LibBluetoothShimSources", srcs: [ @@ -19,7 +27,6 @@ filegroup { "controller.cc", "distance_measurement_manager.cc", "dumpsys.cc", - "entry.cc", "hci_layer.cc", "l2c_api.cc", "le_advertising_manager.cc", @@ -27,7 +34,6 @@ filegroup { "metric_id_api.cc", "metrics_api.cc", "shim.cc", - "stack.cc", "utils.cc", ], } diff --git a/system/main/shim/BUILD.gn b/system/main/shim/BUILD.gn index fb6ba62a01217905b8404be1a80ec1c22b7fb85d..33ffeb953fbfc1e1f966469e1369abd5b8d9155b 100644 --- a/system/main/shim/BUILD.gn +++ b/system/main/shim/BUILD.gn @@ -13,7 +13,42 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# +source_set("BluetoothStackManagerSources") { + sources = [ + "entry.cc", + "stack.cc", + ] + + include_dirs = [ + "//bt/system", + "//bt/system/btif/include", + "//bt/system/gd", + "//bt/system/gd/rust/shim", + "//bt/system/stack/include", + "//bt/system/types", + ] + + deps = [ + "//bt/system/gd:BluetoothGeneratedDumpsysDataSchema_h", + "//bt/system/gd/common:BluetoothCommonSources", + "//bt/system/gd/dumpsys/bundler:BluetoothGeneratedBundlerSchema_h_bfbs", + "//bt/system/gd/hci:BluetoothHciSources", + "//bt/system/gd/os:BluetoothOsSources_linux_generic", + "//bt/system/gd/packet:BluetoothPacketSources", + "//bt/system/gd/rust/shim:libbluetooth_rust_interop", + "//bt/system/gd/rust/topshim:libbluetooth_topshim", + "//bt/system/osi", + "//bt/system/pdl:BluetoothGeneratedPackets_h", + "//bt/system/stack", + "//bt/system/types", + ] + configs += [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] +} source_set("LibBluetoothShimSources") { sources = [ "acl.cc", @@ -25,7 +60,6 @@ source_set("LibBluetoothShimSources") { "controller.cc", "distance_measurement_manager.cc", "dumpsys.cc", - "entry.cc", "hci_layer.cc", "l2c_api.cc", "le_advertising_manager.cc", @@ -33,7 +67,6 @@ source_set("LibBluetoothShimSources") { "metric_id_api.cc", "metrics_api.cc", "shim.cc", - "stack.cc", "utils.cc", ] @@ -42,7 +75,6 @@ source_set("LibBluetoothShimSources") { "//bt/system/btif/include", "//bt/system/gd", "//bt/system/gd/rust/shim", - "//bt/system/internal_include", "//bt/system/stack/include", "//bt/system/types", ] @@ -62,5 +94,8 @@ source_set("LibBluetoothShimSources") { "//bt/system/types", ] - configs += [ "//bt/system:target_defaults" ] + configs += [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] } diff --git a/system/main/shim/acl.cc b/system/main/shim/acl.cc index 04977b8e8732e8a67f2c43e8d29971d5c7b464ea..cd6339b12c78a2a1ffc8a12864df1b26847eb0ce 100644 --- a/system/main/shim/acl.cc +++ b/system/main/shim/acl.cc @@ -30,27 +30,27 @@ #include #include +#include "common/bind.h" #include "common/interfaces/ILoggable.h" +#include "common/strings.h" +#include "common/sync_map_count.h" #include "device/include/controller.h" -#include "gd/common/bind.h" -#include "gd/common/strings.h" -#include "gd/common/sync_map_count.h" -#include "gd/hci/acl_manager.h" -#include "gd/hci/acl_manager/acl_connection.h" -#include "gd/hci/acl_manager/classic_acl_connection.h" -#include "gd/hci/acl_manager/connection_management_callbacks.h" -#include "gd/hci/acl_manager/le_acl_connection.h" -#include "gd/hci/acl_manager/le_connection_management_callbacks.h" -#include "gd/hci/address.h" -#include "gd/hci/address_with_type.h" -#include "gd/hci/class_of_device.h" -#include "gd/hci/controller.h" -#include "gd/os/handler.h" +#include "hci/acl_manager.h" +#include "hci/acl_manager/acl_connection.h" +#include "hci/acl_manager/classic_acl_connection.h" +#include "hci/acl_manager/connection_management_callbacks.h" +#include "hci/acl_manager/le_acl_connection.h" +#include "hci/acl_manager/le_connection_management_callbacks.h" +#include "hci/address.h" +#include "hci/address_with_type.h" +#include "hci/class_of_device.h" +#include "hci/controller_interface.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" #include "main/shim/stack.h" +#include "os/handler.h" #include "osi/include/allocator.h" #include "stack/acl/acl.h" #include "stack/btm/btm_int_types.h" @@ -542,7 +542,7 @@ class ClassicShimAclConnection TRY_POSTING_ON_MAIN(interface_.on_change_connection_link_key_complete); } - void OnReadClockOffsetComplete(uint16_t clock_offset) override { + void OnReadClockOffsetComplete(uint16_t /* clock_offset */) override { LOG_INFO("UNIMPLEMENTED"); } @@ -563,66 +563,73 @@ class ClassicShimAclConnection minimum_remote_timeout, minimum_local_timeout); } - void OnQosSetupComplete(hci::ServiceType service_type, uint32_t token_rate, - uint32_t peak_bandwidth, uint32_t latency, - uint32_t delay_variation) override { + void OnQosSetupComplete(hci::ServiceType /* service_type */, + uint32_t /* token_rate */, + uint32_t /* peak_bandwidth */, uint32_t /* latency */, + uint32_t /* delay_variation */) override { LOG_INFO("UNIMPLEMENTED"); } - void OnFlowSpecificationComplete(hci::FlowDirection flow_direction, - hci::ServiceType service_type, - uint32_t token_rate, - uint32_t token_bucket_size, - uint32_t peak_bandwidth, - uint32_t access_latency) override { + void OnFlowSpecificationComplete(hci::FlowDirection /* flow_direction */, + hci::ServiceType /* service_type */, + uint32_t /* token_rate */, + uint32_t /* token_bucket_size */, + uint32_t /* peak_bandwidth */, + uint32_t /* access_latency */) override { LOG_INFO("UNIMPLEMENTED"); } void OnFlushOccurred() override { LOG_INFO("UNIMPLEMENTED"); } - void OnRoleDiscoveryComplete(hci::Role current_role) override { + void OnRoleDiscoveryComplete(hci::Role /* current_role */) override { LOG_INFO("UNIMPLEMENTED"); } void OnReadLinkPolicySettingsComplete( - uint16_t link_policy_settings) override { + uint16_t /* link_policy_settings */) override { LOG_INFO("UNIMPLEMENTED"); } - void OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) override { + void OnReadAutomaticFlushTimeoutComplete( + uint16_t /* flush_timeout */) override { LOG_INFO("UNIMPLEMENTED"); } - void OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) override { + void OnReadTransmitPowerLevelComplete( + uint8_t /* transmit_power_level */) override { LOG_INFO("UNIMPLEMENTED"); } void OnReadLinkSupervisionTimeoutComplete( - uint16_t link_supervision_timeout) override { + uint16_t /* link_supervision_timeout */) override { LOG_INFO("UNIMPLEMENTED"); } void OnReadFailedContactCounterComplete( - uint16_t failed_contact_counter) override { + uint16_t /* failed_contact_counter */) override { LOG_INFO("UNIMPLEMENTED"); } - void OnReadLinkQualityComplete(uint8_t link_quality) override { + void OnReadLinkQualityComplete(uint8_t /* link_quality */) override { LOG_INFO("UNIMPLEMENTED"); } void OnReadAfhChannelMapComplete( - hci::AfhMode afh_mode, std::array afh_channel_map) override { + hci::AfhMode /* afh_mode */, + std::array /* afh_channel_map */) override { LOG_INFO("UNIMPLEMENTED"); } - void OnReadRssiComplete(uint8_t rssi) override { LOG_INFO("UNIMPLEMENTED"); } + void OnReadRssiComplete(uint8_t /* rssi */) override { + LOG_INFO("UNIMPLEMENTED"); + } - void OnReadClockComplete(uint32_t clock, uint16_t accuracy) override { + void OnReadClockComplete(uint32_t /* clock */, + uint16_t /* accuracy */) override { LOG_INFO("UNIMPLEMENTED"); } - void OnCentralLinkKeyComplete(hci::KeyFlag key_flag) override { + void OnCentralLinkKeyComplete(hci::KeyFlag /* key_flag */) override { LOG_INFO("%s UNIMPLEMENTED", __func__); } @@ -807,8 +814,8 @@ class LeShimAclConnection manufacturer_name, sub_version); } - void OnLeReadRemoteFeaturesComplete(hci::ErrorCode hci_status, - uint64_t features) { + void OnLeReadRemoteFeaturesComplete(hci::ErrorCode /* hci_status */, + uint64_t /* features */) { // TODO } @@ -1384,17 +1391,6 @@ shim::legacy::Acl::Acl(os::Handler* handler, handler->BindOn(this, &Acl::on_incoming_acl_credits)); shim::RegisterDumpsysFunction(static_cast(this), [this](int fd) { Dump(fd); }); - - GetAclManager()->HACK_SetNonAclDisconnectCallback( - [this](uint16_t handle, uint8_t reason) { - TRY_POSTING_ON_MAIN(acl_interface_.connection.sco.on_disconnected, - handle, static_cast(reason)); - - // HACKCEPTION! LE ISO connections, just like SCO are not registered in - // GD, so ISO can use same hack to get notified about disconnections - TRY_POSTING_ON_MAIN(acl_interface_.connection.le.on_iso_disconnected, - handle, static_cast(reason)); - }); } shim::legacy::Acl::~Acl() { @@ -1630,11 +1626,8 @@ void shim::legacy::Acl::OnConnectRequest(hci::Address address, hci::ClassOfDevice cod) { const RawAddress bd_addr = ToRawAddress(address); - types::ClassOfDevice legacy_cod; - legacy_cod.FromOctets(cod.data()); - TRY_POSTING_ON_MAIN(acl_interface_.connection.classic.on_connect_request, - bd_addr, legacy_cod); + bd_addr, cod); LOG_DEBUG("Received connect request remote:%s", ADDRESS_TO_LOGGABLE_CSTR(address)); BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "Connection request"); @@ -1653,31 +1646,6 @@ void shim::legacy::Acl::OnConnectFail(hci::Address address, hci::ErrorCodeText(reason).c_str())); } -void shim::legacy::Acl::HACK_OnEscoConnectRequest(hci::Address address, - hci::ClassOfDevice cod) { - const RawAddress bd_addr = ToRawAddress(address); - types::ClassOfDevice legacy_cod; - types::ClassOfDevice::FromString(cod.ToLegacyConfigString(), legacy_cod); - - TRY_POSTING_ON_MAIN(acl_interface_.connection.sco.on_esco_connect_request, - bd_addr, legacy_cod); - LOG_DEBUG("Received ESCO connect request remote:%s", - ADDRESS_TO_LOGGABLE_CSTR(address)); - BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "ESCO Connection request"); -} - -void shim::legacy::Acl::HACK_OnScoConnectRequest(hci::Address address, - hci::ClassOfDevice cod) { - const RawAddress bd_addr = ToRawAddress(address); - types::ClassOfDevice legacy_cod; - types::ClassOfDevice::FromString(cod.ToLegacyConfigString(), legacy_cod); - - TRY_POSTING_ON_MAIN(acl_interface_.connection.sco.on_sco_connect_request, - bd_addr, legacy_cod); - LOG_DEBUG("Received SCO connect request remote:%s", ADDRESS_TO_LOGGABLE_CSTR(address)); - BTM_LogHistory(kBtmLogTag, ToRawAddress(address), "SCO Connection request"); -} - void shim::legacy::Acl::OnLeConnectSuccess( hci::AddressWithType address_with_type, std::unique_ptr connection) { diff --git a/system/main/shim/acl.h b/system/main/shim/acl.h index eadb465bd67a50ae22749e89133efd9f3b533d9f..749c012e1df19809c33bc799bbd4429a41693f17 100644 --- a/system/main/shim/acl.h +++ b/system/main/shim/acl.h @@ -19,16 +19,16 @@ #include #include -#include "gd/hci/acl_manager/connection_callbacks.h" -#include "gd/hci/acl_manager/le_connection_callbacks.h" -#include "gd/hci/address.h" -#include "gd/hci/address_with_type.h" -#include "gd/hci/class_of_device.h" -#include "gd/os/handler.h" -#include "gd/packet/raw_builder.h" +#include "hci/acl_manager/connection_callbacks.h" +#include "hci/acl_manager/le_connection_callbacks.h" +#include "hci/address.h" +#include "hci/address_with_type.h" +#include "hci/class_of_device.h" #include "main/shim/acl_legacy_interface.h" #include "main/shim/link_connection_interface.h" #include "main/shim/link_policy_interface.h" +#include "os/handler.h" +#include "packet/raw_builder.h" #include "types/raw_address.h" using LeRandCallback = base::OnceCallback; @@ -57,9 +57,6 @@ class Acl : public hci::acl_manager::ConnectionCallbacks, void OnConnectFail(hci::Address, hci::ErrorCode reason, bool locally_initiated) override; - void HACK_OnEscoConnectRequest(hci::Address, hci::ClassOfDevice) override; - void HACK_OnScoConnectRequest(hci::Address, hci::ClassOfDevice) override; - void OnClassicLinkDisconnected(uint16_t handle, hci::ErrorCode reason); // hci::acl_manager::LeConnectionCallbacks diff --git a/system/main/shim/acl_api.cc b/system/main/shim/acl_api.cc index e2db8dd4633e5c6e5d1dbb719b98062c341c2d01..6194e4a4c9c2ed86f04fff5b58a94a538acf0760 100644 --- a/system/main/shim/acl_api.cc +++ b/system/main/shim/acl_api.cc @@ -16,14 +16,14 @@ #include "main/shim/acl_api.h" +#include #include - #include #include #include -#include "gd/hci/acl_manager.h" -#include "gd/hci/remote_name_request.h" +#include "hci/acl_manager.h" +#include "hci/remote_name_request.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" #include "main/shim/stack.h" @@ -79,9 +79,13 @@ void bluetooth::shim::ACL_ConfigureLePrivacy(bool is_le_privacy_enabled) { : hci::LeAddressManager::AddressPolicy::USE_PUBLIC_ADDRESS; hci::AddressWithType empty_address_with_type( hci::Address{}, hci::AddressType::RANDOM_DEVICE_ADDRESS); - /* 7 minutes minimum, 15 minutes maximum for random address refreshing */ - auto minimum_rotation_time = std::chrono::minutes(7); - auto maximum_rotation_time = std::chrono::minutes(15); + + /* Default to 7 minutes minimum, 15 minutes maximum for random address refreshing; + * device can override. */ + auto minimum_rotation_time = std::chrono::minutes( + GET_SYSPROP(Ble, random_address_rotation_interval_min, 7)); + auto maximum_rotation_time = std::chrono::minutes( + GET_SYSPROP(Ble, random_address_rotation_interval_max, 15)); Stack::GetInstance() ->GetStackManager() @@ -177,7 +181,7 @@ void bluetooth::shim::ACL_LeSubrateRequest( void bluetooth::shim::ACL_RemoteNameRequest(const RawAddress& addr, uint8_t page_scan_rep_mode, - uint8_t page_scan_mode, + uint8_t /* page_scan_mode */, uint16_t clock_offset) { bluetooth::shim::GetRemoteNameRequest()->StartRemoteNameRequest( ToGdAddress(addr), diff --git a/system/main/shim/acl_legacy_interface.cc b/system/main/shim/acl_legacy_interface.cc index 08454812b9a1c74978e037f38c939e326f5ddfdd..48539230279caede80b58cfb33ecbddbda47a812 100644 --- a/system/main/shim/acl_legacy_interface.cc +++ b/system/main/shim/acl_legacy_interface.cc @@ -18,7 +18,6 @@ #include "stack/include/acl_hci_link_interface.h" #include "stack/include/ble_acl_interface.h" -#include "stack/include/sco_hci_link_interface.h" #include "stack/include/sec_hci_link_interface.h" struct tBTM_ESCO_DATA; @@ -59,11 +58,6 @@ const acl_interface_t& GetAclInterface() { acl_ble_enhanced_connection_complete_from_shim, .connection.le.on_failed = acl_ble_connection_fail, .connection.le.on_disconnected = btm_acl_disconnected, - .connection.le.on_iso_disconnected = btm_acl_iso_disconnected, - - .connection.sco.on_esco_connect_request = btm_sco_on_esco_connect_request, - .connection.sco.on_sco_connect_request = btm_sco_on_sco_connect_request, - .connection.sco.on_disconnected = btm_sco_on_disconnected, .link.classic.on_authentication_complete = btm_sec_auth_complete, .link.classic.on_central_link_key_complete = nullptr, diff --git a/system/main/shim/acl_legacy_interface.h b/system/main/shim/acl_legacy_interface.h index 2cd3ce0ec132985be464cfdbfd96045d52951008..c08edc1a93232cc5dd7c55bec8212d85346ca05a 100644 --- a/system/main/shim/acl_legacy_interface.h +++ b/system/main/shim/acl_legacy_interface.h @@ -18,11 +18,11 @@ #include +#include "hci/class_of_device.h" #include "stack/include/bt_hdr.h" #include "stack/include/hci_error_code.h" #include "stack/include/hci_mode.h" #include "types/ble_address_with_type.h" -#include "types/class_of_device.h" #include "types/hci_role.h" #include "types/raw_address.h" @@ -33,8 +33,7 @@ namespace legacy { typedef struct { void (*on_connected)(const RawAddress& bda, uint16_t handle, uint8_t enc_mode, bool locally_initiated); - void (*on_connect_request)(const RawAddress& bda, - const types::ClassOfDevice&); + void (*on_connect_request)(const RawAddress& bda, const hci::ClassOfDevice&); void (*on_failed)(const RawAddress& bda, tHCI_STATUS status, bool locally_initiated); void (*on_disconnected)(tHCI_STATUS status, uint16_t handle, @@ -52,17 +51,8 @@ typedef struct { bool enhanced, tHCI_STATUS status); void (*on_disconnected)(tHCI_STATUS status, uint16_t handle, tHCI_STATUS reason); - void (*on_iso_disconnected)(uint16_t handle, tHCI_STATUS reason); } acl_le_connection_interface_t; -typedef struct { - void (*on_esco_connect_request)(const RawAddress&, - const types::ClassOfDevice&); - void (*on_sco_connect_request)(const RawAddress&, - const types::ClassOfDevice&); - void (*on_disconnected)(uint16_t handle, tHCI_REASON reason); -} acl_sco_connection_interface_t; - typedef struct { void (*on_authentication_complete)(uint16_t handle, tHCI_STATUS status); void (*on_change_connection_link_key_complete)(); @@ -135,7 +125,6 @@ typedef struct { typedef struct { acl_classic_connection_interface_t classic; acl_le_connection_interface_t le; - acl_sco_connection_interface_t sco; } acl_connection_interface_t; typedef struct { diff --git a/system/main/shim/ble_scanner_interface_impl.h b/system/main/shim/ble_scanner_interface_impl.h index c39bb66f409a6410faa374fb3c8439910868bc5f..8a952405c48246306ffb7e02dec5770a63f07be9 100644 --- a/system/main/shim/ble_scanner_interface_impl.h +++ b/system/main/shim/ble_scanner_interface_impl.h @@ -21,6 +21,7 @@ #include #include +#include #include "hci/le_scanning_callback.h" #include "include/hardware/ble_scanner.h" @@ -73,8 +74,8 @@ class BleScannerInterfaceImpl : public ::BleScannerInterface, MsftAdvMonitorRemoveCallback cb) override; void MsftAdvMonitorEnable(bool enable, MsftAdvMonitorEnableCallback cb) override; - void SetScanParameters(int scanner_id, int scan_interval, int scan_window, - Callback cb) override; + void SetScanParameters(int scanner_id, uint8_t scan_type, int scan_interval, + int scan_window, Callback cb) override; void BatchscanConfigStorage(int client_if, int batch_scan_full_max, int batch_scan_trunc_max, int batch_scan_notify_threshold, diff --git a/system/main/shim/btm.cc b/system/main/shim/btm.cc index 0274d4bba607cfc779fa60f1d2b926bf63604bff..526983298c5cc0b09d68947db5ea940e3573a17a 100644 --- a/system/main/shim/btm.cc +++ b/system/main/shim/btm.cc @@ -26,16 +26,16 @@ #include #include -#include "gd/hci/le_advertising_manager.h" -#include "gd/hci/le_scanning_manager.h" -#include "gd/neighbor/connectability.h" -#include "gd/neighbor/discoverability.h" -#include "gd/neighbor/inquiry.h" -#include "gd/neighbor/page.h" -#include "gd/security/security_module.h" -#include "main/shim/controller.h" +#include "hci/acl_manager.h" +#include "hci/controller_interface.h" +#include "hci/le_advertising_manager.h" +#include "hci/le_scanning_manager.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" +#include "neighbor/connectability.h" +#include "neighbor/discoverability.h" +#include "neighbor/inquiry.h" +#include "neighbor/page.h" #include "stack/btm/btm_dev.h" #include "stack/btm/btm_int_types.h" #include "types/ble_address_with_type.h" @@ -49,8 +49,6 @@ static constexpr bool kPassiveScanning = false; using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME; -void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode); -void btm_process_inq_complete(tHCI_STATUS status, uint8_t result_type); void btm_ble_process_adv_addr(RawAddress& raw_address, tBLE_ADDR_TYPE* address_type); void btm_ble_process_adv_pkt_cont(uint16_t event_type, @@ -62,24 +60,6 @@ void btm_ble_process_adv_pkt_cont(uint16_t event_type, uint8_t data_len, const uint8_t* data, const RawAddress& original_bda); -void btm_api_process_inquiry_result(const RawAddress& raw_address, - uint8_t page_scan_rep_mode, - DEV_CLASS device_class, - uint16_t clock_offset); - -void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address, - uint8_t page_scan_rep_mode, - DEV_CLASS device_class, - uint16_t clock_offset, - int8_t rssi); - -void btm_api_process_extended_inquiry_result(RawAddress raw_address, - uint8_t page_scan_rep_mode, - DEV_CLASS device_class, - uint16_t clock_offset, int8_t rssi, - const uint8_t* eir_data, - size_t eir_len); - namespace bluetooth { namespace shim { @@ -106,16 +86,17 @@ std::string Btm::ReadRemoteName::AddressString() const { } void Btm::ScanningCallbacks::OnScannerRegistered( - const bluetooth::hci::Uuid app_uuid, bluetooth::hci::ScannerId scanner_id, - ScanningStatus status){}; + const bluetooth::hci::Uuid /* app_uuid */, + bluetooth::hci::ScannerId /* scanner_id */, ScanningStatus /* status */){}; void Btm::ScanningCallbacks::OnSetScannerParameterComplete( - bluetooth::hci::ScannerId scanner_id, ScanningStatus status){}; + bluetooth::hci::ScannerId /* scanner_id */, ScanningStatus /* status */){}; void Btm::ScanningCallbacks::OnScanResult( - uint16_t event_type, uint8_t address_type, bluetooth::hci::Address address, - uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid, - int8_t tx_power, int8_t rssi, uint16_t periodic_advertising_interval, + uint16_t /* event_type */, uint8_t address_type, + bluetooth::hci::Address address, uint8_t primary_phy, uint8_t secondary_phy, + uint8_t advertising_sid, int8_t tx_power, int8_t rssi, + uint16_t periodic_advertising_interval, std::vector advertising_data) { tBLE_ADDR_TYPE ble_address_type = to_ble_addr_type(address_type); uint16_t extended_event_type = 0; @@ -138,34 +119,37 @@ void Btm::ScanningCallbacks::OnScanResult( } void Btm::ScanningCallbacks::OnTrackAdvFoundLost( - bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info){}; -void Btm::ScanningCallbacks::OnBatchScanReports(int client_if, int status, - int report_format, - int num_records, - std::vector data){}; + bluetooth::hci:: + AdvertisingFilterOnFoundOnLostInfo /* on_found_on_lost_info */){}; +void Btm::ScanningCallbacks::OnBatchScanReports( + int /* client_if */, int /* status */, int /* report_format */, + int /* num_records */, std::vector /* data */){}; -void Btm::ScanningCallbacks::OnBatchScanThresholdCrossed(int client_if){}; +void Btm::ScanningCallbacks::OnBatchScanThresholdCrossed(int /* client_if */){}; void Btm::ScanningCallbacks::OnTimeout(){}; -void Btm::ScanningCallbacks::OnFilterEnable(bluetooth::hci::Enable enable, - uint8_t status){}; +void Btm::ScanningCallbacks::OnFilterEnable(bluetooth::hci::Enable /* enable */, + uint8_t /* status */){}; void Btm::ScanningCallbacks::OnFilterParamSetup( - uint8_t available_spaces, bluetooth::hci::ApcfAction action, - uint8_t status){}; + uint8_t /* available_spaces */, bluetooth::hci::ApcfAction /* action */, + uint8_t /* status */){}; void Btm::ScanningCallbacks::OnFilterConfigCallback( - bluetooth::hci::ApcfFilterType filter_type, uint8_t available_spaces, - bluetooth::hci::ApcfAction action, uint8_t status){}; + bluetooth::hci::ApcfFilterType /* filter_type */, + uint8_t /* available_spaces */, bluetooth::hci::ApcfAction /* action */, + uint8_t /* status */){}; void Btm::ScanningCallbacks::OnPeriodicSyncStarted( - int reg_id, uint8_t status, uint16_t sync_handle, uint8_t advertising_sid, - bluetooth::hci::AddressWithType address_with_type, uint8_t phy, - uint16_t interval) {} -void Btm::ScanningCallbacks::OnPeriodicSyncReport(uint16_t sync_handle, - int8_t tx_power, int8_t rssi, - uint8_t status, - std::vector data) {} -void Btm::ScanningCallbacks::OnPeriodicSyncLost(uint16_t sync_handle) {} + int /* reg_id */, uint8_t /* status */, uint16_t /* sync_handle */, + uint8_t /* advertising_sid */, + bluetooth::hci::AddressWithType /* address_with_type */, uint8_t /* phy */, + uint16_t /* interval */) {} +void Btm::ScanningCallbacks::OnPeriodicSyncReport( + uint16_t /* sync_handle */, int8_t /* tx_power */, int8_t /* rssi */, + uint8_t /* status */, std::vector /* data */) {} +void Btm::ScanningCallbacks::OnPeriodicSyncLost(uint16_t /* sync_handle */) {} void Btm::ScanningCallbacks::OnPeriodicSyncTransferred( - int pa_source, uint8_t status, bluetooth::hci::Address address) {} -void Btm::ScanningCallbacks::OnBigInfoReport(uint16_t sync_handle, bool encrypted) {} + int /* pa_source */, uint8_t /* status */, + bluetooth::hci::Address /* address */) {} +void Btm::ScanningCallbacks::OnBigInfoReport(uint16_t /* sync_handle */, + bool /* encrypted */) {} Btm::Btm(os::Handler* handler, neighbor::InquiryModule* inquiry) : scanning_timer_(handler), observing_timer_(handler) { @@ -190,7 +174,7 @@ void Btm::SetInterlacedInquiryScan() { GetInquiry()->SetInterlacedScan(); } void Btm::SetStandardInquiryScan() { GetInquiry()->SetStandardScan(); } bool Btm::IsInterlacedScanSupported() const { - return controller_get_interface()->supports_interlaced_inquiry_scan(); + return bluetooth::shim::GetController()->SupportsInterlacedInquiryScan(); } /** @@ -261,7 +245,7 @@ bool Btm::IsLimitedInquiryActive() const { return limited_inquiry_active_; } bool Btm::StartPeriodicInquiry(uint8_t mode, uint8_t duration, uint8_t max_responses, uint16_t max_delay, uint16_t min_delay, - tBTM_INQ_RESULTS_CB* p_results_cb) { + tBTM_INQ_RESULTS_CB* /* p_results_cb */) { switch (mode) { case kInquiryModeOff: limited_periodic_inquiry_active_ = false; @@ -413,26 +397,12 @@ bool Btm::UseLeLink(const RawAddress& raw_address) const { return true; } -BtmStatus Btm::ReadClassicRemoteDeviceName(const RawAddress& raw_address, - tBTM_NAME_CMPL_CB* callback) { +BtmStatus Btm::ReadClassicRemoteDeviceName(const RawAddress& /* raw_address */, + tBTM_NAME_CMPL_CB* /* callback */) { LOG_ALWAYS_FATAL("unreachable"); return BTM_UNDEFINED; } -BtmStatus Btm::ReadLeRemoteDeviceName(const RawAddress& raw_address, - tBTM_NAME_CMPL_CB* callback) { - if (!CheckLeAclLink(raw_address)) { - return BTM_UNKNOWN_ADDR; - } - - if (!le_read_remote_name_.Start(raw_address)) { - return BTM_BUSY; - } - - LOG_INFO("UNIMPLEMENTED %s need access to GATT module", __func__); - return BTM_UNKNOWN_ADDR; -} - BtmStatus Btm::CancelAllReadRemoteDeviceName() { LOG_ALWAYS_FATAL("unreachable"); return BTM_UNDEFINED; @@ -478,7 +448,7 @@ void Btm::SetObservingTimer(uint64_t duration_ms, void Btm::CancelObservingTimer() { observing_timer_.Cancel(); } -void Btm::StartScanning(bool use_active_scanning) { +void Btm::StartScanning(bool /* use_active_scanning */) { GetScanning()->RegisterScanningCallback(&scanning_callbacks_); GetScanning()->Scan(true); } @@ -487,42 +457,8 @@ size_t Btm::GetNumberOfAdvertisingInstances() const { return GetAdvertising()->GetNumberOfAdvertisingInstances(); } -tBTM_STATUS Btm::CreateBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, - tBT_TRANSPORT transport, int device_type) { - if (transport == BT_TRANSPORT_AUTO) { - if (device_type & BT_DEVICE_TYPE_BLE) { - transport = BT_TRANSPORT_LE; - } else if (device_type & BT_DEVICE_TYPE_BREDR) { - transport = BT_TRANSPORT_BR_EDR; - } - LOG_INFO("%s guessing transport as %02x ", __func__, transport); - } - - auto security_manager = GetSecurityModule()->GetSecurityManager(); - switch (transport) { - case BT_TRANSPORT_BR_EDR: - security_manager->CreateBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC)); - break; - case BT_TRANSPORT_LE: - security_manager->CreateBondLe(ToAddressWithType(bd_addr, addr_type)); - break; - default: - return BTM_ILLEGAL_VALUE; - } - return BTM_CMD_STARTED; -} - -bool Btm::CancelBond(const RawAddress& bd_addr) { - auto security_manager = GetSecurityModule()->GetSecurityManager(); - security_manager->CancelBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC)); - return true; -} - -bool Btm::RemoveBond(const RawAddress& bd_addr) { - // TODO(cmanton) Check if acl is connected - auto security_manager = GetSecurityModule()->GetSecurityManager(); - security_manager->RemoveBond(ToAddressWithType(bd_addr, BLE_ADDR_PUBLIC)); - return true; +size_t Btm::GetNumberOfAdvertisingInstancesInUse() const { + return GetAdvertising()->GetNumberOfAdvertisingInstancesInUse(); } uint16_t Btm::GetAclHandle(const RawAddress& remote_bda, diff --git a/system/main/shim/btm.h b/system/main/shim/btm.h index 6083ae038d77e729fe91435d82d6c9f9e36d28c1..695724fa86cc3709c6888bf47d58ebcfe9de73e7 100644 --- a/system/main/shim/btm.h +++ b/system/main/shim/btm.h @@ -23,12 +23,12 @@ #include #include "bt_transport.h" -#include "gd/common/callback.h" -#include "gd/hci/le_advertising_manager.h" -#include "gd/hci/le_scanning_callback.h" -#include "gd/neighbor/inquiry.h" -#include "gd/os/alarm.h" +#include "common/callback.h" #include "hci/hci_packets.h" +#include "hci/le_advertising_manager.h" +#include "hci/le_scanning_callback.h" +#include "neighbor/inquiry.h" +#include "os/alarm.h" #include "stack/btm/neighbor_inquiry.h" #include "types/raw_address.h" @@ -74,8 +74,6 @@ using DiscoverabilityState = struct { }; using ConnectabilityState = DiscoverabilityState; -using HACK_NonAclDisconnectCallback = std::function; - using BtmStatus = tBTM_STATUS; namespace bluetooth { @@ -140,8 +138,6 @@ class Btm { // Remote device name API BtmStatus ReadClassicRemoteDeviceName(const RawAddress& raw_address, tBTM_NAME_CMPL_CB* callback); - BtmStatus ReadLeRemoteDeviceName(const RawAddress& raw_address, - tBTM_NAME_CMPL_CB* callback); BtmStatus CancelAllReadRemoteDeviceName(); // Le neighbor interaction API @@ -159,6 +155,7 @@ class Btm { void StopObserving(); size_t GetNumberOfAdvertisingInstances() const; + size_t GetNumberOfAdvertisingInstancesInUse() const; void SetObservingTimer(uint64_t duration_ms, common::OnceCallback callback); @@ -240,11 +237,7 @@ class Btm { void OnBigInfoReport(uint16_t sync_handle, bool encrypted) override; }; ScanningCallbacks scanning_callbacks_; - - // TODO(cmanton) abort if there is no classic acl link up - bool CheckClassicAclLink(const RawAddress& raw_address) { return true; } - bool CheckLeAclLink(const RawAddress& raw_address) { return true; } - void StartScanning(bool use_active_scanning); + void StartScanning(bool /* use_active_scanning */); }; } // namespace shim diff --git a/system/main/shim/btm_api.cc b/system/main/shim/btm_api.cc index e92dea60d2a8cab6474a397c341a80b4e0aea1d5..f28198640f3b512b87f732721c23a81dfaefbbcc 100644 --- a/system/main/shim/btm_api.cc +++ b/system/main/shim/btm_api.cc @@ -26,6 +26,7 @@ #include "main/shim/helpers.h" #include "main/shim/stack.h" #include "stack/btm/btm_ble_sec.h" +#include "stack/btm/btm_dev.h" #include "types/raw_address.h" uint16_t bluetooth::shim::BTM_GetHCIConnHandle(const RawAddress& remote_bda, @@ -80,8 +81,9 @@ tBTM_STATUS bluetooth::shim::BTM_AllowWakeByHid( std::promise accept_promise; auto accept_future = accept_promise.get_future(); + tBLE_BD_ADDR bdadr = BTM_Sec_GetAddressWithType(hid_address.first); Stack::GetInstance()->GetAcl()->AcceptLeConnectionFrom( - ToAddressWithType(hid_address.first, hid_address.second), + ToAddressWithType(bdadr.bda, bdadr.type), /*is_direct=*/false, std::move(accept_promise)); accept_future.wait(); @@ -101,8 +103,9 @@ tBTM_STATUS bluetooth::shim::BTM_RestoreFilterAcceptList( std::promise accept_promise; auto accept_future = accept_promise.get_future(); + tBLE_BD_ADDR bdadr = BTM_Sec_GetAddressWithType(address_pair.first); Stack::GetInstance()->GetAcl()->AcceptLeConnectionFrom( - ToAddressWithType(address_pair.first, address_pair.second), + ToAddressWithType(bdadr.bda, bdadr.type), /*is_direct=*/false, std::move(accept_promise)); accept_future.wait(); @@ -128,3 +131,7 @@ tBTM_STATUS bluetooth::shim::BTM_BleResetId() { btm_ble_reset_id(); return BTM_SUCCESS; } + +size_t bluetooth::shim::BTM_BleGetNumberOfAdvertisingInstancesInUse(void) { + return Stack::GetInstance()->GetBtm()->GetNumberOfAdvertisingInstancesInUse(); +} diff --git a/system/main/shim/btm_api.h b/system/main/shim/btm_api.h index a54dd6188eae02a4e428ecb87fa88ef730b0e27d..b296ecf6758ce4776e79d498e895c07c78ea8ef0 100644 --- a/system/main/shim/btm_api.h +++ b/system/main/shim/btm_api.h @@ -16,6 +16,8 @@ #pragma once +#include + #include "base/functional/callback.h" #include "device/include/esco_parameters.h" #include "stack/btm/neighbor_inquiry.h" @@ -27,43 +29,6 @@ namespace bluetooth { namespace shim { -/******************************************************************************* - * - * Function BTM_StartInquiry - * - * Description This function is called to start an inquiry. - * - * Parameters: p_inqparms - pointer to the inquiry information - * mode - GENERAL or LIMITED inquiry - * duration - length in 1.28 sec intervals (If '0', the - * inquiry is CANCELLED) - * filter_cond_type - BTM_CLR_INQUIRY_FILTER, - * BTM_FILTER_COND_DEVICE_CLASS, or - * BTM_FILTER_COND_BD_ADDR - * filter_cond - value for the filter (based on - * filter_cond_type) - * - * p_results_cb - Pointer to the callback routine which gets - * called upon receipt of an inquiry result. If - * this field is NULL, the application is not - * notified. - * - * p_cmpl_cb - Pointer to the callback routine which gets - * called upon completion. If this field is - * NULL, the application is not notified when - * completed. - * Returns tBTM_STATUS - * BTM_CMD_STARTED if successfully initiated - * BTM_BUSY if already in progress - * BTM_ILLEGAL_VALUE if parameter(s) are out of range - * BTM_NO_RESOURCES if could not allocate resources to start - * the command - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); - /******************************************************************************* * * Function BTM_SetDiscoverability @@ -175,27 +140,6 @@ tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); tBTM_STATUS BTM_SetConnectability(uint16_t page_mode, uint16_t window, uint16_t interval); -/******************************************************************************* - * - * Function BTM_IsInquiryActive - * - * Description Return a bit mask of the current inquiry state - * - * Returns BTM_INQUIRY_INACTIVE if inactive (0) - * BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active - * - ******************************************************************************/ -uint16_t BTM_IsInquiryActive(void); - -/******************************************************************************* - * - * Function BTM_CancelInquiry - * - * Description This function cancels an inquiry if active - * - ******************************************************************************/ -void BTM_CancelInquiry(void); - /******************************************************************************* * * Function BTM_ReadRemoteDeviceName @@ -518,10 +462,10 @@ tBTM_STATUS BTM_ReadLocalDeviceNameFromController( * * Description This function is called to read the local device class * - * Returns pointer to the device class + * Returns the device class * ******************************************************************************/ -uint8_t* BTM_ReadDeviceClass(void); +DEV_CLASS BTM_ReadDeviceClass(void); /******************************************************************************* * @@ -1174,6 +1118,16 @@ tBTM_STATUS BTM_SetEventFilterInquiryResultAllDevices(void); *******************************************************************************/ tBTM_STATUS BTM_BleResetId(void); +/******************************************************************************* + * + * Function BTM_BleGetNumberOfAdvertisingInstancesInUse + * + * Description Obtains the number of BLE advertising instances in use + * + * Returns Return the number of BLE advertising instances in use + *******************************************************************************/ +size_t BTM_BleGetNumberOfAdvertisingInstancesInUse(void); + /** * Send remote name request to GD shim Name module */ diff --git a/system/main/shim/config.cc b/system/main/shim/config.cc index bc16ef84a4fd0fa38e866950de9ad58ac6fe1401..97efb9325af3e645e3484f56b5e6f635d5eee11d 100644 --- a/system/main/shim/config.cc +++ b/system/main/shim/config.cc @@ -22,9 +22,9 @@ #include #include -#include "gd/os/log.h" -#include "gd/storage/storage_module.h" #include "main/shim/entry.h" +#include "os/log.h" +#include "storage/storage_module.h" using ::bluetooth::shim::GetStorage; using ::bluetooth::storage::ConfigCacheHelper; diff --git a/system/main/shim/config.h b/system/main/shim/config.h index 2ee022c45ba8c5fb8ac2771f7ce2595619d10852..7b12cf75c355cdb2aa65fd8a7ae6a88e39fa0009 100644 --- a/system/main/shim/config.h +++ b/system/main/shim/config.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include #include diff --git a/system/main/shim/controller.cc b/system/main/shim/controller.cc index 10d130c80528e778d0535860d211acbda2aaa640..183b2424720d4a542ae662ffe7c6ec9514fef285 100644 --- a/system/main/shim/controller.cc +++ b/system/main/shim/controller.cc @@ -19,8 +19,9 @@ #include "main/shim/controller.h" #include "btcore/include/module.h" -#include "gd/hci/controller.h" #include "hci/controller.h" +#include "hci/controller_interface.h" +#include "include/check.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" #include "main/shim/shim.h" @@ -116,35 +117,6 @@ static const uint8_t* get_ble_supported_states(void) { #define MAP_TO_GD(legacy, gd) \ static bool legacy(void) { return GetController()->gd(); } -MAP_TO_GD(supports_simple_pairing, SupportsSimplePairing) -MAP_TO_GD(supports_secure_connections, SupportsSecureConnections) -MAP_TO_GD(supports_simultaneous_le_bredr, SupportsSimultaneousLeBrEdr) -MAP_TO_GD(supports_interlaced_inquiry_scan, SupportsInterlacedInquiryScan) -MAP_TO_GD(supports_rssi_with_inquiry_results, SupportsRssiWithInquiryResults) -MAP_TO_GD(supports_extended_inquiry_response, SupportsExtendedInquiryResponse) -MAP_TO_GD(supports_three_slot_packets, Supports3SlotPackets) -MAP_TO_GD(supports_five_slot_packets, Supports5SlotPackets) -MAP_TO_GD(supports_classic_2m_phy, SupportsClassic2mPhy) -MAP_TO_GD(supports_classic_3m_phy, SupportsClassic3mPhy) -MAP_TO_GD(supports_three_slot_edr_packets, Supports3SlotEdrPackets) -MAP_TO_GD(supports_five_slot_edr_packets, Supports5SlotEdrPackets) -MAP_TO_GD(supports_sco, SupportsSco) -MAP_TO_GD(supports_hv2_packets, SupportsHv2Packets) -MAP_TO_GD(supports_hv3_packets, SupportsHv3Packets) -MAP_TO_GD(supports_ev3_packets, SupportsEv3Packets) -MAP_TO_GD(supports_ev4_packets, SupportsEv4Packets) -MAP_TO_GD(supports_ev5_packets, SupportsEv5Packets) -MAP_TO_GD(supports_esco_2m_phy, SupportsEsco2mPhy) -MAP_TO_GD(supports_esco_3m_phy, SupportsEsco3mPhy) -MAP_TO_GD(supports_three_slot_esco_edr_packets, Supports3SlotEscoEdrPackets) -MAP_TO_GD(supports_role_switch, SupportsRoleSwitch) -MAP_TO_GD(supports_hold_mode, SupportsHoldMode) -MAP_TO_GD(supports_sniff_mode, SupportsSniffMode) -MAP_TO_GD(supports_park_mode, SupportsParkMode) -MAP_TO_GD(supports_non_flushable_pb, SupportsNonFlushablePb) -MAP_TO_GD(supports_sniff_subrating, SupportsSniffSubrating) -MAP_TO_GD(supports_encryption_pause, SupportsEncryptionPause) - MAP_TO_GD(supports_ble, SupportsBle) MAP_TO_GD(supports_privacy, SupportsBlePrivacy) MAP_TO_GD(supports_packet_extension, SupportsBleDataPacketLengthExtension) @@ -156,8 +128,6 @@ MAP_TO_GD(supports_extended_advertising, SupportsBleExtendedAdvertising) MAP_TO_GD(supports_periodic_advertising, SupportsBlePeriodicAdvertising) MAP_TO_GD(supports_peripheral_initiated_feature_exchange, SupportsBlePeripheralInitiatedFeaturesExchange) -MAP_TO_GD(supports_connection_parameter_request, - SupportsBleConnectionParametersRequest) MAP_TO_GD(supports_periodic_advertising_sync_transfer_sender, SupportsBlePeriodicAdvertisingSyncTransferSender) @@ -188,10 +158,6 @@ FORWARD(supports_read_encryption_key_size, GetController()->IsSupported( bluetooth::hci::OpCode::READ_ENCRYPTION_KEY_SIZE)) -FORWARD(supports_reading_remote_extended_features, - GetController()->IsSupported( - bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES)) - FORWARD(supports_enhanced_setup_synchronous_connection, GetController()->IsSupported( bluetooth::hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION)) @@ -255,10 +221,10 @@ FORWARD_GETTER(uint8_t, get_le_buffers, FORWARD_GETTER( uint8_t, get_iso_buffers, GetController()->GetControllerIsoBufferSize().total_num_le_packets_) -FORWARD_GETTER(uint8_t, get_le_connect_list_size, +FORWARD_GETTER(uint8_t, get_le_accept_list_size, GetController()->GetLeFilterAcceptListSize()) -static void set_ble_resolving_list_max_size(int resolving_list_max_size) { +static void set_ble_resolving_list_max_size(int /* resolving_list_max_size */) { LOG_DEBUG("UNSUPPORTED"); } @@ -328,72 +294,39 @@ static const controller_t interface = { .get_ble_supported_states = get_ble_supported_states, - .supports_simple_pairing = supports_simple_pairing, - .supports_secure_connections = supports_secure_connections, - .supports_simultaneous_le_bredr = supports_simultaneous_le_bredr, - .supports_reading_remote_extended_features = - supports_reading_remote_extended_features, - .supports_interlaced_inquiry_scan = supports_interlaced_inquiry_scan, - .supports_rssi_with_inquiry_results = supports_rssi_with_inquiry_results, - .supports_extended_inquiry_response = supports_extended_inquiry_response, - .supports_central_peripheral_role_switch = supports_role_switch, .supports_enhanced_setup_synchronous_connection = supports_enhanced_setup_synchronous_connection, .supports_enhanced_accept_synchronous_connection = supports_enhanced_accept_synchronous_connection, - .supports_3_slot_packets = supports_three_slot_packets, - .supports_5_slot_packets = supports_five_slot_packets, - .supports_classic_2m_phy = supports_classic_2m_phy, - .supports_classic_3m_phy = supports_classic_3m_phy, - .supports_3_slot_edr_packets = supports_three_slot_edr_packets, - .supports_5_slot_edr_packets = supports_five_slot_edr_packets, - .supports_sco = supports_sco, - .supports_hv2_packets = supports_hv2_packets, - .supports_hv3_packets = supports_hv3_packets, - .supports_ev3_packets = supports_ev3_packets, - .supports_ev4_packets = supports_ev4_packets, - .supports_ev5_packets = supports_ev5_packets, - .supports_esco_2m_phy = supports_esco_2m_phy, - .supports_esco_3m_phy = supports_esco_3m_phy, - .supports_3_slot_esco_edr_packets = supports_three_slot_esco_edr_packets, - .supports_role_switch = supports_role_switch, - .supports_hold_mode = supports_hold_mode, - .supports_sniff_mode = supports_sniff_mode, - .supports_park_mode = supports_park_mode, - .supports_non_flushable_pb = supports_non_flushable_pb, - .supports_sniff_subrating = supports_sniff_subrating, - .supports_encryption_pause = supports_encryption_pause, .supports_configure_data_path = supports_configure_data_path, .supports_set_min_encryption_key_size = supports_set_min_encryption_key_size, .supports_read_encryption_key_size = supports_read_encryption_key_size, - .supports_ble = supports_ble, - .supports_ble_packet_extension = supports_packet_extension, - .supports_ble_connection_parameters_request = + .SupportsBle = supports_ble, + .SupportsBleDataPacketLengthExtension = supports_packet_extension, + .SupportsBleConnectionParametersRequest = supports_connection_parameters_request, - .supports_ble_privacy = supports_privacy, + .SupportsBlePrivacy = supports_privacy, .supports_ble_set_privacy_mode = supports_ble_set_privacy_mode, - .supports_ble_2m_phy = supports_ble_2m_phy, - .supports_ble_coded_phy = supports_ble_coded_phy, - .supports_ble_extended_advertising = supports_extended_advertising, - .supports_ble_periodic_advertising = supports_periodic_advertising, - .supports_ble_peripheral_initiated_feature_exchange = + .SupportsBle2mPhy = supports_ble_2m_phy, + .SupportsBleCodedPhy = supports_ble_coded_phy, + .SupportsBleExtendedAdvertising = supports_extended_advertising, + .SupportsBlePeriodicAdvertising = supports_periodic_advertising, + .SupportsBlePeripheralInitiatedFeaturesExchange = supports_peripheral_initiated_feature_exchange, - .supports_ble_connection_parameter_request = - supports_connection_parameter_request, - .supports_ble_periodic_advertising_sync_transfer_sender = + .SupportsBlePeriodicAdvertisingSyncTransferSender = supports_periodic_advertising_sync_transfer_sender, - .supports_ble_periodic_advertising_sync_transfer_recipient = + .SupportsBlePeriodicAdvertisingSyncTransferRecipient = supports_periodic_advertising_sync_transfer_recipient, - .supports_ble_connected_isochronous_stream_central = + .SupportsBleConnectedIsochronousStreamCentral = supports_connected_iso_stream_central, - .supports_ble_connected_isochronous_stream_peripheral = + .SupportsBleConnectedIsochronousStreamPeripheral = supports_connected_iso_stream_peripheral, - .supports_ble_isochronous_broadcaster = supports_iso_broadcaster, - .supports_ble_synchronized_receiver = supports_synchronized_receiver, - .supports_ble_connection_subrating = supports_ble_connection_subrating, - .supports_ble_connection_subrating_host = + .SupportsBleIsochronousBroadcaster = supports_iso_broadcaster, + .SupportsBleSynchronizedReceiver = supports_synchronized_receiver, + .SupportsBleConnectionSubrating = supports_ble_connection_subrating, + .SupportsBleConnectionSubratingHost = supports_ble_connection_subrating_host, .get_acl_data_size_classic = get_acl_buffer_length, @@ -418,7 +351,7 @@ static const controller_t interface = { .get_acl_buffer_count_ble = get_le_buffers, .get_iso_buffer_count = get_iso_buffers, - .get_ble_acceptlist_size = get_le_connect_list_size, + .get_ble_acceptlist_size = get_le_accept_list_size, .get_ble_resolving_list_max_size = get_le_resolving_list_size, .set_ble_resolving_list_max_size = set_ble_resolving_list_max_size, diff --git a/system/main/shim/distance_measurement_manager.cc b/system/main/shim/distance_measurement_manager.cc index 3f333a0f43ffa6686b3a6282aac34412425090f5..31e835ede734f825f3a5429a506b5f949dd6fe2d 100644 --- a/system/main/shim/distance_measurement_manager.cc +++ b/system/main/shim/distance_measurement_manager.cc @@ -17,7 +17,7 @@ #include "distance_measurement_manager.h" #include "btif/include/btif_common.h" -#include "gd/hci/distance_measurement_manager.h" +#include "hci/distance_measurement_manager.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" @@ -41,10 +41,10 @@ class DistanceMeasurementInterfaceImpl distance_measurement_callbacks_ = callbacks; } - void StartDistanceMeasurement(RawAddress raw_address, uint16_t frequency, + void StartDistanceMeasurement(RawAddress raw_address, uint16_t interval, uint8_t method) { bluetooth::shim::GetDistanceMeasurementManager()->StartDistanceMeasurement( - bluetooth::ToGdAddress(raw_address), frequency, + bluetooth::ToGdAddress(raw_address), interval, static_cast(method)); } diff --git a/system/main/shim/dumpsys.cc b/system/main/shim/dumpsys.cc index 51c7d3818cf600d8a9ac14572b8187ff55e89887..7c80cb27db7c1b177e1d3cb8530ce1e1bc529a77 100644 --- a/system/main/shim/dumpsys.cc +++ b/system/main/shim/dumpsys.cc @@ -20,6 +20,7 @@ #include +#include "include/check.h" #include "main/shim/entry.h" #include "main/shim/shim.h" #include "main/shim/stack.h" diff --git a/system/main/shim/entry.cc b/system/main/shim/entry.cc index 032c7a5ccee1cfbf13a5e3a2f9df5c5f0e6c59b6..9e1bd77684d65c575905bf46b2aa1c4414ab2b27 100644 --- a/system/main/shim/entry.cc +++ b/system/main/shim/entry.cc @@ -16,26 +16,26 @@ #include "main/shim/entry.h" -#include "gd/hal/snoop_logger.h" -#include "gd/hci/controller.h" -#include "gd/hci/distance_measurement_manager.h" -#include "gd/hci/hci_layer.h" -#include "gd/hci/le_advertising_manager.h" -#include "gd/hci/le_scanning_manager.h" -#include "gd/hci/msft.h" -#include "gd/hci/remote_name_request.h" -#include "gd/hci/vendor_specific_event_manager.h" -#include "gd/metrics/counter_metrics.h" -#include "gd/neighbor/connectability.h" -#include "gd/neighbor/discoverability.h" -#include "gd/neighbor/inquiry.h" -#include "gd/neighbor/page.h" -#include "gd/os/handler.h" -#include "gd/security/security_module.h" -#include "gd/shim/dumpsys.h" -#include "gd/storage/storage_module.h" +#include "hal/snoop_logger.h" #include "hci/acl_manager.h" +#include "hci/controller.h" +#include "hci/controller_interface.h" +#include "hci/distance_measurement_manager.h" +#include "hci/hci_layer.h" +#include "hci/le_advertising_manager.h" +#include "hci/le_scanning_manager.h" +#include "hci/msft.h" +#include "hci/remote_name_request.h" +#include "hci/vendor_specific_event_manager.h" #include "main/shim/stack.h" +#include "metrics/counter_metrics.h" +#include "neighbor/connectability.h" +#include "neighbor/discoverability.h" +#include "neighbor/inquiry.h" +#include "neighbor/page.h" +#include "os/handler.h" +#include "shim/dumpsys.h" +#include "storage/storage_module.h" namespace bluetooth { namespace shim { @@ -48,7 +48,7 @@ hci::LeAdvertisingManager* GetAdvertising() { ->GetInstance(); } -hci::Controller* GetController() { +hci::ControllerInterface* GetController() { return Stack::GetInstance() ->GetStackManager() ->GetInstance(); @@ -80,18 +80,6 @@ hci::HciLayer* GetHciLayer() { return Stack::GetInstance()->GetStackManager()->GetInstance(); } -l2cap::classic::L2capClassicModule* GetL2capClassicModule() { - return Stack::GetInstance() - ->GetStackManager() - ->GetInstance(); -} - -bluetooth::l2cap::le::L2capLeModule* GetL2capLeModule() { - return Stack::GetInstance() - ->GetStackManager() - ->GetInstance(); -} - neighbor::PageModule* GetPage() { return Stack::GetInstance() ->GetStackManager() @@ -116,12 +104,6 @@ hci::DistanceMeasurementManager* GetDistanceMeasurementManager() { ->GetInstance(); } -security::SecurityModule* GetSecurityModule() { - return Stack::GetInstance() - ->GetStackManager() - ->GetInstance(); -} - hal::SnoopLogger* GetSnoopLogger() { return Stack::GetInstance() ->GetStackManager() diff --git a/system/main/shim/entry.h b/system/main/shim/entry.h index 560b9218ea7218511b0b743d43d3947fbcddf15c..9be71ec6da41130584aa061b63deff07b0907582 100644 --- a/system/main/shim/entry.h +++ b/system/main/shim/entry.h @@ -44,7 +44,7 @@ class SnoopLogger; } namespace hci { -class Controller; +class ControllerInterface; class HciLayer; class AclManager; class RemoteNameRequestModule; @@ -55,22 +55,10 @@ class VendorSpecificEventManager; class MsftExtensionManager; } -namespace l2cap { -namespace classic { -class L2capClassicModule; -} // namespace classic -namespace le { -class L2capLeModule; -} // namespace le -} // namespace l2cap - namespace metrics { class CounterMetrics; } -namespace security { -class SecurityModule; -} namespace storage { class StorageModule; } @@ -82,19 +70,16 @@ class Dumpsys; * within the stack. */ os::Handler* GetGdShimHandler(); hci::LeAdvertisingManager* GetAdvertising(); -bluetooth::hci::Controller* GetController(); +bluetooth::hci::ControllerInterface* GetController(); neighbor::DiscoverabilityModule* GetDiscoverability(); neighbor::ConnectabilityModule* GetConnectability(); Dumpsys* GetDumpsys(); neighbor::InquiryModule* GetInquiry(); hci::HciLayer* GetHciLayer(); -l2cap::classic::L2capClassicModule* GetL2capClassicModule(); -l2cap::le::L2capLeModule* GetL2capLeModule(); neighbor::PageModule* GetPage(); hci::RemoteNameRequestModule* GetRemoteNameRequest(); hci::DistanceMeasurementManager* GetDistanceMeasurementManager(); hci::LeScanningManager* GetScanning(); -bluetooth::security::SecurityModule* GetSecurityModule(); hal::SnoopLogger* GetSnoopLogger(); storage::StorageModule* GetStorage(); hci::AclManager* GetAclManager(); diff --git a/system/main/shim/hci_layer.cc b/system/main/shim/hci_layer.cc index 0b44f8773878f360e4c34c11f54feb3b50371874..e14e106efadd901a1f5baa6f15f75378100ee51b 100644 --- a/system/main/shim/hci_layer.cc +++ b/system/main/shim/hci_layer.cc @@ -25,18 +25,21 @@ #include "common/bidi_queue.h" #include "common/init_flags.h" -#include "hci/acl_connection_interface.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" #include "hci/include/packet_fragmenter.h" #include "hci/vendor_specific_event_manager.h" +#include "include/check.h" #include "main/shim/entry.h" #include "os/log.h" #include "osi/include/allocator.h" #include "packet/raw_builder.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" +#include "stack/include/btm_iso_api.h" +#include "stack/include/dev_hci_link_interface.h" #include "stack/include/hcimsgs.h" +#include "stack/include/main_thread.h" /** * Callback data wrapped as opaque token bundled with the command @@ -57,173 +60,35 @@ static base::Callback send_data_upwards; static const packet_fragmenter_t* packet_fragmenter; namespace { -bool is_valid_event_code(bluetooth::hci::EventCode event_code) { +bool register_event_code(bluetooth::hci::EventCode event_code) { switch (event_code) { - case bluetooth::hci::EventCode::INQUIRY_COMPLETE: - case bluetooth::hci::EventCode::INQUIRY_RESULT: - case bluetooth::hci::EventCode::CONNECTION_COMPLETE: - case bluetooth::hci::EventCode::CONNECTION_REQUEST: - case bluetooth::hci::EventCode::DISCONNECTION_COMPLETE: - case bluetooth::hci::EventCode::AUTHENTICATION_COMPLETE: - case bluetooth::hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE: + // SCO + case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_COMPLETE: + case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_CHANGED: + + // SecurityEvents case bluetooth::hci::EventCode::ENCRYPTION_CHANGE: - case bluetooth::hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE: - case bluetooth::hci::EventCode::CENTRAL_LINK_KEY_COMPLETE: - case bluetooth::hci::EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE: - case bluetooth::hci::EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE: - case bluetooth::hci::EventCode::QOS_SETUP_COMPLETE: - case bluetooth::hci::EventCode::COMMAND_COMPLETE: - case bluetooth::hci::EventCode::COMMAND_STATUS: - case bluetooth::hci::EventCode::HARDWARE_ERROR: - case bluetooth::hci::EventCode::FLUSH_OCCURRED: - case bluetooth::hci::EventCode::ROLE_CHANGE: - case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS: - case bluetooth::hci::EventCode::MODE_CHANGE: - case bluetooth::hci::EventCode::RETURN_LINK_KEYS: case bluetooth::hci::EventCode::PIN_CODE_REQUEST: case bluetooth::hci::EventCode::LINK_KEY_REQUEST: case bluetooth::hci::EventCode::LINK_KEY_NOTIFICATION: - case bluetooth::hci::EventCode::LOOPBACK_COMMAND: - case bluetooth::hci::EventCode::DATA_BUFFER_OVERFLOW: - case bluetooth::hci::EventCode::MAX_SLOTS_CHANGE: - case bluetooth::hci::EventCode::READ_CLOCK_OFFSET_COMPLETE: - case bluetooth::hci::EventCode::CONNECTION_PACKET_TYPE_CHANGED: - case bluetooth::hci::EventCode::QOS_VIOLATION: - case bluetooth::hci::EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE: - case bluetooth::hci::EventCode::FLOW_SPECIFICATION_COMPLETE: - case bluetooth::hci::EventCode::INQUIRY_RESULT_WITH_RSSI: - case bluetooth::hci::EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE: - case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_COMPLETE: - case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_CHANGED: - case bluetooth::hci::EventCode::SNIFF_SUBRATING: - case bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT: case bluetooth::hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE: case bluetooth::hci::EventCode::IO_CAPABILITY_REQUEST: case bluetooth::hci::EventCode::IO_CAPABILITY_RESPONSE: - case bluetooth::hci::EventCode::USER_CONFIRMATION_REQUEST: - case bluetooth::hci::EventCode::USER_PASSKEY_REQUEST: case bluetooth::hci::EventCode::REMOTE_OOB_DATA_REQUEST: case bluetooth::hci::EventCode::SIMPLE_PAIRING_COMPLETE: - case bluetooth::hci::EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED: - case bluetooth::hci::EventCode::ENHANCED_FLUSH_COMPLETE: case bluetooth::hci::EventCode::USER_PASSKEY_NOTIFICATION: - case bluetooth::hci::EventCode::KEYPRESS_NOTIFICATION: - case bluetooth::hci::EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION: - case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_DATA_BLOCKS: + case bluetooth::hci::EventCode::USER_CONFIRMATION_REQUEST: + case bluetooth::hci::EventCode::USER_PASSKEY_REQUEST: return true; - case bluetooth::hci::EventCode::VENDOR_SPECIFIC: - case bluetooth::hci::EventCode::LE_META_EVENT: // Private to hci - case bluetooth::hci::EventCode::AUTHENTICATED_PAYLOAD_TIMEOUT_EXPIRED: + default: return false; } - return false; }; -bool is_valid_subevent_code(bluetooth::hci::SubeventCode subevent_code) { +static bool register_subevent_code(bluetooth::hci::SubeventCode subevent_code) { switch (subevent_code) { - case bluetooth::hci::SubeventCode::CONNECTION_COMPLETE: - case bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE: - case bluetooth::hci::SubeventCode::DATA_LENGTH_CHANGE: - case bluetooth::hci::SubeventCode::ENHANCED_CONNECTION_COMPLETE: - case bluetooth::hci::SubeventCode::PHY_UPDATE_COMPLETE: case bluetooth::hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE: - case bluetooth::hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST: - case bluetooth::hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE: - case bluetooth::hci::SubeventCode::GENERATE_DHKEY_COMPLETE: - case bluetooth::hci::SubeventCode::DIRECTED_ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::EXTENDED_ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED: - case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST: - case bluetooth::hci::SubeventCode::SCAN_TIMEOUT: - case bluetooth::hci::SubeventCode::ADVERTISING_SET_TERMINATED: - case bluetooth::hci::SubeventCode::SCAN_REQUEST_RECEIVED: - case bluetooth::hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM: - case bluetooth::hci::SubeventCode::CONNECTIONLESS_IQ_REPORT: - case bluetooth::hci::SubeventCode::CONNECTION_IQ_REPORT: - case bluetooth::hci::SubeventCode::CTE_REQUEST_FAILED: - case bluetooth::hci::SubeventCode:: - PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED: - case bluetooth::hci::SubeventCode::CIS_ESTABLISHED: - case bluetooth::hci::SubeventCode::CIS_REQUEST: - case bluetooth::hci::SubeventCode::CREATE_BIG_COMPLETE: - case bluetooth::hci::SubeventCode::TERMINATE_BIG_COMPLETE: - case bluetooth::hci::SubeventCode::BIG_SYNC_ESTABLISHED: - case bluetooth::hci::SubeventCode::BIG_SYNC_LOST: - case bluetooth::hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE: - case bluetooth::hci::SubeventCode::PATH_LOSS_THRESHOLD: - case bluetooth::hci::SubeventCode::TRANSMIT_POWER_REPORTING: - case bluetooth::hci::SubeventCode::BIG_INFO_ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::ADVERTISING_REPORT: case bluetooth::hci::SubeventCode::LONG_TERM_KEY_REQUEST: - return true; - default: - return false; - } -} - -static bool event_already_registered_in_hci_layer( - bluetooth::hci::EventCode event_code) { - switch (event_code) { - case bluetooth::hci::EventCode::COMMAND_COMPLETE: - case bluetooth::hci::EventCode::COMMAND_STATUS: - case bluetooth::hci::EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE: - case bluetooth::hci::EventCode::MAX_SLOTS_CHANGE: - case bluetooth::hci::EventCode::LE_META_EVENT: - case bluetooth::hci::EventCode::DISCONNECTION_COMPLETE: - case bluetooth::hci::EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE: - case bluetooth::hci::EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION: - case bluetooth::hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE: - return true; - default: - return false; - } -} - -static bool event_already_registered_in_controller_layer( - bluetooth::hci::EventCode event_code) { - switch (event_code) { - case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS: - return true; - default: - return false; - } -} - -static bool event_already_registered_in_acl_layer( - bluetooth::hci::EventCode event_code) { - for (auto event : bluetooth::hci::AclConnectionEvents) { - if (event == event_code) { - return true; - } - } - return false; -} - -static bool subevent_already_registered_in_le_hci_layer( - bluetooth::hci::SubeventCode subevent_code) { - switch (subevent_code) { - case bluetooth::hci::SubeventCode::CONNECTION_COMPLETE: - case bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE: - case bluetooth::hci::SubeventCode::DATA_LENGTH_CHANGE: - case bluetooth::hci::SubeventCode::ENHANCED_CONNECTION_COMPLETE: - case bluetooth::hci::SubeventCode::PHY_UPDATE_COMPLETE: - case bluetooth::hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST: - case bluetooth::hci::SubeventCode::ADVERTISING_SET_TERMINATED: - case bluetooth::hci::SubeventCode::SCAN_REQUEST_RECEIVED: - case bluetooth::hci::SubeventCode::SCAN_TIMEOUT: - case bluetooth::hci::SubeventCode::ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::DIRECTED_ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::EXTENDED_ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_REPORT: - case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED: - case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST: - case bluetooth::hci::SubeventCode:: - PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED: - case bluetooth::hci::SubeventCode::TRANSMIT_POWER_REPORTING: - case bluetooth::hci::SubeventCode::BIG_INFO_ADVERTISING_REPORT: - return true; - case bluetooth::hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE: case bluetooth::hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE: case bluetooth::hci::SubeventCode::GENERATE_DHKEY_COMPLETE: case bluetooth::hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM: @@ -238,32 +103,12 @@ static bool subevent_already_registered_in_le_hci_layer( case bluetooth::hci::SubeventCode::BIG_SYNC_LOST: case bluetooth::hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE: case bluetooth::hci::SubeventCode::PATH_LOSS_THRESHOLD: - case bluetooth::hci::SubeventCode::LONG_TERM_KEY_REQUEST: + return true; default: return false; } } -static bool event_already_registered_in_le_advertising_manager( - bluetooth::hci::EventCode event_code) { - for (auto event : bluetooth::hci::AclConnectionEvents) { - if (event == event_code) { - return true; - } - } - return false; -} - -static bool event_already_registered_in_le_scanning_manager( - bluetooth::hci::EventCode event_code) { - for (auto event : bluetooth::hci::AclConnectionEvents) { - if (event == event_code) { - return true; - } - } - return false; -} - } // namespace namespace cpp { @@ -316,12 +161,15 @@ static void subevent_callback( static void vendor_specific_event_callback( bluetooth::hci::VendorSpecificEventView vendor_specific_event_view) { - if (!send_data_upwards) { + auto bqr = + bluetooth::hci::BqrEventView::CreateOptional(vendor_specific_event_view); + if (!bqr) { return; } - send_data_upwards.Run( - FROM_HERE, - WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT, &vendor_specific_event_view)); + + auto payload = vendor_specific_event_view.GetPayload(); + std::vector bytes{payload.begin(), payload.end()}; + btm_vendor_specific_evt(bytes.data(), bytes.size()); } void OnTransmitPacketCommandComplete(command_complete_cb complete_callback, @@ -440,6 +288,18 @@ static void register_for_iso() { pending_iso_data = new bluetooth::os::EnqueueBuffer( hci_iso_queue_end); + // Register ISO for disconnect notifications + bluetooth::shim::GetHciLayer()->RegisterForDisconnects( + get_main_thread()->Bind([](uint16_t handle, + bluetooth::hci::ErrorCode error_code) { + auto iso = bluetooth::hci::IsoManager::GetInstance(); + if (iso) { + auto reason = static_cast(error_code); + LOG_INFO("ISO disconnection from GD, handle: 0x%02x, reason: 0x%02x", + handle, reason); + iso->HandleDisconnect(handle, reason); + } + })); } static void on_shutting_down() { @@ -499,9 +359,10 @@ static void dispatch_reassembled(BT_HDR* packet) { static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = { transmit_fragment, dispatch_reassembled}; -static void transmit_downward(uint16_t type, void* raw_data) { +static void transmit_downward(void* raw_data, uint16_t iso_buffer_size) { bluetooth::shim::GetGdShimHandler()->Call( - packet_fragmenter->fragment_and_dispatch, static_cast(raw_data)); + packet_fragmenter->fragment_and_dispatch, static_cast(raw_data), + iso_buffer_size); } static hci_t interface = {.set_data_cb = set_data_cb, @@ -519,21 +380,9 @@ void bluetooth::shim::hci_on_reset_complete() { for (uint16_t event_code_raw = 0; event_code_raw < 0x100; event_code_raw++) { auto event_code = static_cast(event_code_raw); - if (!is_valid_event_code(event_code)) { + if (!register_event_code(event_code)) { continue; } - if (event_already_registered_in_acl_layer(event_code)) { - continue; - } else if (event_already_registered_in_controller_layer(event_code)) { - continue; - } else if (event_already_registered_in_hci_layer(event_code)) { - continue; - } else if (event_already_registered_in_le_advertising_manager(event_code)) { - continue; - } else if (event_already_registered_in_le_scanning_manager(event_code)) { - continue; - } - cpp::register_event(event_code); } @@ -541,21 +390,16 @@ void bluetooth::shim::hci_on_reset_complete() { subevent_code_raw++) { auto subevent_code = static_cast(subevent_code_raw); - if (!is_valid_subevent_code(subevent_code)) { + if (!register_subevent_code(subevent_code)) { continue; } - if (subevent_already_registered_in_le_hci_layer(subevent_code)) { - continue; - } - cpp::register_le_event(subevent_code); } // TODO handle BQR event in GD - auto handler = bluetooth::shim::GetGdShimHandler(); bluetooth::shim::GetVendorSpecificEventManager()->RegisterEventHandler( bluetooth::hci::VseSubeventCode::BQR_EVENT, - handler->Bind(cpp::vendor_specific_event_callback)); + get_main_thread()->Bind(cpp::vendor_specific_event_callback)); cpp::register_for_iso(); } diff --git a/system/main/shim/helpers.h b/system/main/shim/helpers.h index bd1dd93204e2bc1b04e9e8b168b17020d4be3ab3..63bb85f9876b086ffb9e65575143e5c130b18942 100644 --- a/system/main/shim/helpers.h +++ b/system/main/shim/helpers.h @@ -15,10 +15,12 @@ */ #pragma once -#include "gd/common/init_flags.h" -#include "gd/packet/raw_builder.h" +#include + +#include "common/init_flags.h" #include "hci/address_with_type.h" #include "osi/include/allocator.h" +#include "packet/raw_builder.h" #include "stack/include/bt_hdr.h" #include "stack/include/hci_error_code.h" #include "stack/include/hci_mode.h" diff --git a/system/main/shim/l2c_api.cc b/system/main/shim/l2c_api.cc index 1afa5976c02ff1116cc4a493a7ddc4bd39e8d3f5..8093eb5e8e57571c7e0aef9d777818e77bbafd37 100644 --- a/system/main/shim/l2c_api.cc +++ b/system/main/shim/l2c_api.cc @@ -15,1480 +15,3 @@ */ #define LOG_TAG "bt_shim_l2cap" - -#include "main/shim/l2c_api.h" - -#include - -#include - -#include "bta/include/bta_dm_acl.h" -#include "gd/l2cap/classic/l2cap_classic_module.h" -#include "gd/l2cap/le/l2cap_le_module.h" -#include "gd/os/log.h" -#include "gd/os/queue.h" -#include "main/shim/btm.h" -#include "main/shim/entry.h" -#include "main/shim/helpers.h" -#include "osi/include/allocator.h" -#include "stack/btm/btm_ble_int.h" -#include "stack/btm/btm_sec.h" -#include "stack/btm/power_mode.h" -#include "stack/include/ble_acl_interface.h" -#include "stack/include/bt_hdr.h" -#include "stack/include/btu_hcif.h" -#include "stack/include/gatt_api.h" -#include "stack/include/main_thread.h" -#include "types/ble_address_with_type.h" -#include "types/raw_address.h" - -void gatt_notify_phy_updated(tHCI_STATUS status, uint16_t handle, - uint8_t tx_phy, uint8_t rx_phy); - -namespace bluetooth { -namespace shim { - -using bluetooth::hci::AddressWithType; -using namespace bluetooth::l2cap; - -// Classic Dynamic Channel Shim Helper - -namespace { -uint16_t classic_cid_token_counter_ = 0x41; - -std::unordered_map - classic_cid_token_to_channel_map_; - -uint16_t add_classic_cid_token_entry(uint16_t psm) { - uint16_t new_token = classic_cid_token_counter_; - classic_cid_token_to_channel_map_[new_token] = psm; - classic_cid_token_counter_++; - if (classic_cid_token_counter_ == 0) classic_cid_token_counter_ = 0x41; - return new_token; -} - -void remove_classic_cid_token_entry(uint16_t cid_token) { - classic_cid_token_to_channel_map_.erase(cid_token); -} - -void remove_classic_dynamic_channel_helper(uint16_t psm); - -struct ClassicDynamicChannelHelper { - ClassicDynamicChannelHelper(uint16_t psm, tL2CAP_APPL_INFO appl_info, - classic::DynamicChannelConfigurationOption config, - classic::SecurityPolicy policy) - : psm_(psm), appl_info_(appl_info), config_(config), policy_(policy) {} - - uint16_t psm_; - tL2CAP_APPL_INFO appl_info_; - classic::DynamicChannelConfigurationOption config_; - classic::SecurityPolicy policy_; - - void Register() { - GetL2capClassicModule()->GetDynamicChannelManager()->RegisterService( - psm_, config_, policy_, - GetGdShimHandler()->BindOnceOn( - this, &ClassicDynamicChannelHelper::on_registration_complete), - GetGdShimHandler()->BindOn( - this, &ClassicDynamicChannelHelper::on_channel_open, 0)); - } - - void on_registration_complete( - classic::DynamicChannelManager::RegistrationResult result, - std::unique_ptr service) { - if (result != classic::DynamicChannelManager::RegistrationResult::SUCCESS) { - LOG(ERROR) << "Channel is not registered. psm=" << +psm_ << (int)result; - return; - } - channel_service_ = std::move(service); - } - - std::unique_ptr channel_service_ = nullptr; - - void Connect(uint16_t cid_token, bluetooth::hci::AddressWithType device) { - if (channel_service_ == nullptr) { - return; - } - initiated_by_us_[cid_token] = true; - GetL2capClassicModule()->GetDynamicChannelManager()->ConnectChannel( - device.GetAddress(), config_, psm_, - GetGdShimHandler()->BindOn( - this, &ClassicDynamicChannelHelper::on_channel_open, cid_token), - GetGdShimHandler()->BindOnceOn( - this, &ClassicDynamicChannelHelper::on_outgoing_connection_fail)); - } - - void Disconnect(uint16_t cid_token) { - if (channel_service_ == nullptr) { - return; - } - if (channels_.count(cid_token) == 0) { - return; - } - channels_[cid_token]->Close(); - } - - void Unregister() { - if (channel_service_ != nullptr) { - channel_service_->Unregister(GetGdShimHandler()->BindOnceOn( - this, &ClassicDynamicChannelHelper::on_unregistered)); - channel_service_ = nullptr; - } - } - - void on_unregistered() { - for (const auto& device : channels_) { - device.second->Close(); - } - remove_classic_dynamic_channel_helper(psm_); - } - - void on_channel_close(uint16_t cid_token, - bluetooth::hci::ErrorCode error_code) { - channel_enqueue_buffer_[cid_token] = nullptr; - channel_enqueue_buffer_.erase(cid_token); - channels_[cid_token]->GetQueueUpEnd()->UnregisterDequeue(); - channels_.erase(cid_token); - do_in_main_thread( - FROM_HERE, - base::BindOnce(appl_info_.pL2CA_DisconnectInd_Cb, cid_token, false)); - - remove_classic_cid_token_entry(cid_token); - initiated_by_us_.erase(cid_token); - - if (channel_service_ == nullptr && channels_.empty()) { - // Try again - L2CA_Deregister(psm_); - } - } - - void on_channel_open(uint16_t cid_token, - std::unique_ptr channel) { - auto device = channel->GetDevice(); - auto address = bluetooth::ToRawAddress(device.GetAddress()); - bool initiator_local = (cid_token != 0); - if (cid_token == 0) { - cid_token = add_classic_cid_token_entry(psm_); - } - - channel->RegisterOnCloseCallback(GetGdShimHandler()->BindOnceOn( - this, &ClassicDynamicChannelHelper::on_channel_close, cid_token)); - - channel_enqueue_buffer_[cid_token] = std::make_unique< - bluetooth::os::EnqueueBuffer>( - channel->GetQueueUpEnd()); - - if (initiator_local) { - do_in_main_thread( - FROM_HERE, - base::BindOnce(appl_info_.pL2CA_ConnectCfm_Cb, cid_token, 0)); - - tL2CAP_CFG_INFO cfg_info{}; - do_in_main_thread( - FROM_HERE, - base::BindOnce(appl_info_.pL2CA_ConfigCfm_Cb, cid_token, - L2CAP_INITIATOR_LOCAL, base::Unretained(&cfg_info))); - } else { - if (appl_info_.pL2CA_ConnectInd_Cb == nullptr) { - Disconnect(cid_token); - return; - } - do_in_main_thread(FROM_HERE, - base::BindOnce(appl_info_.pL2CA_ConnectInd_Cb, address, - cid_token, psm_, 0)); - - tL2CAP_CFG_INFO cfg_info{}; - do_in_main_thread( - FROM_HERE, - base::BindOnce(appl_info_.pL2CA_ConfigCfm_Cb, cid_token, - L2CAP_INITIATOR_LOCAL, base::Unretained(&cfg_info))); - } - - channel->GetQueueUpEnd()->RegisterDequeue( - GetGdShimHandler(), - bluetooth::common::Bind(&ClassicDynamicChannelHelper::on_incoming_data, - bluetooth::common::Unretained(this), - cid_token)); - - channels_[cid_token] = std::move(channel); - } - - void on_incoming_data(uint16_t cid_token) { - auto channel = channels_.find(cid_token); - if (channel == channels_.end()) { - LOG_ERROR("Channel is not open"); - return; - } - auto packet = channel->second->GetQueueUpEnd()->TryDequeue(); - std::vector packet_vector(packet->begin(), packet->end()); - BT_HDR* buffer = - static_cast(osi_calloc(packet_vector.size() + sizeof(BT_HDR))); - std::copy(packet_vector.begin(), packet_vector.end(), buffer->data); - buffer->len = packet_vector.size(); - if (do_in_main_thread(FROM_HERE, - base::BindOnce(appl_info_.pL2CA_DataInd_Cb, cid_token, - base::Unretained(buffer))) != - BT_STATUS_SUCCESS) { - osi_free(buffer); - } - } - - void on_outgoing_connection_fail( - classic::DynamicChannelManager::ConnectionResult result) { - LOG(ERROR) << "Outgoing connection failed: " - << static_cast(result.connection_result_code); - } - - bool send(uint16_t cid, - std::unique_ptr packet) { - auto buffer = channel_enqueue_buffer_.find(cid); - if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) { - LOG(ERROR) << "Channel is not open"; - return false; - } - buffer->second->Enqueue(std::move(packet), GetGdShimHandler()); - return true; - } - - uint16_t GetRemoteCid(uint16_t cid) { - auto channel = channels_.find(cid); - if (channel == channels_.end()) { - LOG_ERROR("Channel is not open"); - return 0; - } - return channel->second->HACK_GetRemoteCid(); - } - - bool SetChannelTxPriority(uint16_t cid, bool high_priority) { - auto channel = channels_.find(cid); - if (channel == channels_.end()) { - LOG_ERROR("Channel is not open"); - return false; - } - channel->second->HACK_SetChannelTxPriority(high_priority); - return true; - } - - void FlushChannel(uint16_t cid) { - auto buffer = channel_enqueue_buffer_.find(cid); - if (buffer == channel_enqueue_buffer_.end()) { - LOG_ERROR("Channel is not open"); - return; - } - buffer->second->Clear(); - } - - uint16_t GetNumBufferedPackets(uint16_t cid) { - auto buffer = channel_enqueue_buffer_.find(cid); - if (buffer == channel_enqueue_buffer_.end()) { - LOG_ERROR("Channel is not open"); - return 0; - } - return buffer->second->Size(); - } - - std::unordered_map> - channels_; - std::unordered_map>> - channel_enqueue_buffer_; - std::unordered_map initiated_by_us_; -}; - -std::unordered_map> - classic_dynamic_channel_helper_map_; - -void remove_classic_dynamic_channel_helper(uint16_t psm) { - if (classic_dynamic_channel_helper_map_.count(psm) != 0 && - classic_dynamic_channel_helper_map_[psm]->channels_.empty()) { - classic_dynamic_channel_helper_map_.erase(psm); - } -} - -// Helper: L2cap security enforcement shim - -std::unordered_map> - security_enforce_callback_map = {}; - -class ClassicSecurityEnforcementShim - : public bluetooth::l2cap::classic::SecurityEnforcementInterface { - public: - static void security_enforce_result_callback(const RawAddress* bd_addr, - tBT_TRANSPORT trasnport, - void* p_ref_data, - tBTM_STATUS result) { - intptr_t counter = (intptr_t)p_ref_data; - if (security_enforce_callback_map.count(counter) == 0) { - LOG_ERROR("Received unexpected callback"); - return; - } - - auto& callback = security_enforce_callback_map[counter]; - std::move(callback).Invoke(result == BTM_SUCCESS); - security_enforce_callback_map.erase(counter); - } - - void Enforce(bluetooth::hci::AddressWithType remote, - bluetooth::l2cap::classic::SecurityPolicy policy, - ResultCallback result_callback) override { - uint16_t sec_mask = 0; - switch (policy) { - case bluetooth::l2cap::classic::SecurityPolicy:: - _SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK: - result_callback.Invoke(true); - return; - case bluetooth::l2cap::classic::SecurityPolicy::ENCRYPTED_TRANSPORT: - sec_mask = BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT | - BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT; - break; - case bluetooth::l2cap::classic::SecurityPolicy::BEST: - case bluetooth::l2cap::classic::SecurityPolicy:: - AUTHENTICATED_ENCRYPTED_TRANSPORT: - sec_mask = BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT | - BTM_SEC_IN_MITM | BTM_SEC_OUT_AUTHENTICATE | - BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_MITM; - break; - } - auto bd_addr = bluetooth::ToRawAddress(remote.GetAddress()); - security_enforce_callback_map[security_enforce_callback_counter_] = - std::move(result_callback); - btm_sec_l2cap_access_req_by_requirement( - bd_addr, sec_mask, true, security_enforce_result_callback, - (void*)security_enforce_callback_counter_); - security_enforce_callback_counter_++; - } - - intptr_t security_enforce_callback_counter_ = 100; -} security_enforcement_shim_; - -struct RemoteFeature { - uint8_t lmp_version = 0; - uint16_t manufacturer_name = 0; - uint16_t sub_version = 0; - uint8_t raw_remote_features[8]; - bool version_info_received = false; - bool role_switch_supported = false; - bool br_edr_supported = false; - bool le_supported_controller = false; - bool le_supported_host = false; - bool ssp_supported = false; - bool sc_supported = false; - bool received_page_0 = false; - bool received_page_1 = false; -}; - -std::unordered_map remote_feature_map_; - -class SecurityListenerShim - : public bluetooth::l2cap::classic::LinkSecurityInterfaceListener { - public: - void OnLinkConnected( - std::unique_ptr - interface) override { - auto bda = bluetooth::ToRawAddress(interface->GetRemoteAddress()); - - uint16_t handle = interface->GetAclHandle(); - address_to_handle_[bda] = handle; - btm_sec_connected(bda, handle, HCI_SUCCESS, 0); - BTM_PM_OnConnected(handle, bda); - BTA_dm_acl_up(bda, BT_TRANSPORT_BR_EDR, handle); - address_to_interface_[bda] = std::move(interface); - } - - void OnAuthenticationComplete(hci::ErrorCode hci_status, - bluetooth::hci::Address remote) override { - // Note: if gd security is not enabled, we should use btu_hcif.cc path - auto bda = bluetooth::ToRawAddress(remote); - uint16_t handle = address_to_handle_[bda]; - btm_sec_auth_complete(handle, ToLegacyHciErrorCode(hci_status)); - } - - void OnLinkDisconnected(bluetooth::hci::Address remote) override { - auto bda = bluetooth::ToRawAddress(remote); - uint16_t handle = address_to_handle_[bda]; - address_to_handle_.erase(bda); - address_to_interface_.erase(bda); - btm_sec_disconnected(handle, HCI_ERR_PEER_USER, - "main::shim::l2c_api::OnLinkDisconnected"); - BTA_dm_acl_down(bda, BT_TRANSPORT_BR_EDR); - BTM_PM_OnDisconnected(handle); - } - - void OnEncryptionChange(bluetooth::hci::Address remote, - bool encrypted) override { - // Note: if gd security is not enabled, we should use btu_hcif.cc path - auto bda = bluetooth::ToRawAddress(remote); - uint16_t handle = address_to_handle_[bda]; - btm_sec_encrypt_change(handle, HCI_SUCCESS, encrypted); - } - - void UpdateLinkHoldForSecurity(RawAddress remote, bool is_bonding) { - if (address_to_interface_.count(remote) == 0) { - return; - } - if (is_bonding) { - address_to_interface_[remote]->Hold(); - } else { - address_to_interface_[remote]->Release(); - } - } - - bool IsRoleCentral(RawAddress remote) { - if (address_to_interface_.count(remote) == 0) { - return false; - } - return address_to_interface_[remote]->GetRole() == - bluetooth::hci::Role::CENTRAL; - } - - void Disconnect(RawAddress remote) { - if (address_to_interface_.count(remote) == 0) { - return; - } - return address_to_interface_[remote]->Disconnect(); - } - - uint16_t GetNumAclLinks() { return address_to_handle_.size(); } - - bool IsLinkUp(RawAddress remote) { - return address_to_interface_.count(remote) != 0; - } - - std::unordered_map address_to_handle_; - std::unordered_map< - RawAddress, - std::unique_ptr> - address_to_interface_; -} security_listener_shim_; - -bluetooth::l2cap::classic::SecurityInterface* security_interface_ = nullptr; - -struct LeLinkPropertyListenerShim - : public bluetooth::l2cap::le::LinkPropertyListener { - struct ConnectionInfo { - uint16_t handle; - hci::Role role; - AddressWithType address_with_type; - }; - std::unordered_map info_; - - void OnLinkConnected(AddressWithType remote, uint16_t handle, - hci::Role role) override { - info_[remote.GetAddress()] = {handle, role, remote}; - LOG_ALWAYS_FATAL("discoverable bit needs to be determined properly"); - btm_ble_connected(ToRawAddress(remote.GetAddress()), handle, - HCI_ENCRYPT_MODE_DISABLED, static_cast(role), - static_cast(remote.GetAddressType()), - false, true); - } - - void OnLinkDisconnected(hci::AddressWithType remote) override { - info_.erase(remote.GetAddress()); - } - - void OnReadRemoteVersionInformation(hci::ErrorCode hci_status, - hci::AddressWithType remote, - uint8_t lmp_version, - uint16_t manufacturer_name, - uint16_t sub_version) override { - auto bda = bluetooth::ToRawAddress(remote.GetAddress()); - auto& entry = remote_feature_map_[bda]; - entry.lmp_version = lmp_version; - entry.manufacturer_name = manufacturer_name; - entry.sub_version = sub_version; - entry.version_info_received = true; - } - - void OnConnectionUpdate(hci::AddressWithType remote, - uint16_t connection_interval, - uint16_t connection_latency, - uint16_t supervision_timeout) override { - acl_ble_update_event_received( - HCI_SUCCESS, info_[remote.GetAddress()].handle, connection_interval, - connection_latency, supervision_timeout); - } - - void OnPhyUpdate(hci::AddressWithType remote, uint8_t tx_phy, - uint8_t rx_phy) override { - gatt_notify_phy_updated(HCI_SUCCESS, info_[remote.GetAddress()].handle, - tx_phy, rx_phy); - } - - void OnDataLengthChange(hci::AddressWithType remote, uint16_t tx_octets, - uint16_t tx_time, uint16_t rx_octets, - uint16_t rx_time) override { - // Used by L2cap internal only. - } -} le_link_property_listener_shim_; - -std::unordered_map> - le_security_enforce_callback_map = {}; - -class LeSecurityEnforcementShim - : public bluetooth::l2cap::le::SecurityEnforcementInterface { - public: - static void le_security_enforce_result_callback(const RawAddress* bd_addr, - tBT_TRANSPORT trasnport, - void* p_ref_data, - tBTM_STATUS result) { - intptr_t counter = (intptr_t)p_ref_data; - if (le_security_enforce_callback_map.count(counter) == 0) { - LOG_ERROR("Received unexpected callback"); - return; - } - auto& callback = le_security_enforce_callback_map[counter]; - std::move(callback).Invoke(result == BTM_SUCCESS); - le_security_enforce_callback_map.erase(counter); - } - - void Enforce(bluetooth::hci::AddressWithType remote, - bluetooth::l2cap::le::SecurityPolicy policy, - ResultCallback result_callback) override { - tBTM_BLE_SEC_ACT sec_act = BTM_BLE_SEC_NONE; - switch (policy) { - case bluetooth::l2cap::le::SecurityPolicy:: - NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK: - result_callback.Invoke(true); - return; - case bluetooth::l2cap::le::SecurityPolicy::ENCRYPTED_TRANSPORT: - sec_act = BTM_BLE_SEC_ENCRYPT; - break; - case bluetooth::l2cap::le::SecurityPolicy::BEST: - case bluetooth::l2cap::le::SecurityPolicy:: - AUTHENTICATED_ENCRYPTED_TRANSPORT: - sec_act = BTM_BLE_SEC_ENCRYPT_MITM; - break; - default: - result_callback.Invoke(false); - } - auto bd_addr = bluetooth::ToRawAddress(remote.GetAddress()); - le_security_enforce_callback_map[security_enforce_callback_counter_] = - std::move(result_callback); - BTM_SetEncryption(bd_addr, BT_TRANSPORT_LE, - le_security_enforce_result_callback, - (void*)security_enforce_callback_counter_, sec_act); - security_enforce_callback_counter_++; - } - - intptr_t security_enforce_callback_counter_ = 100; -} le_security_enforcement_shim_; -} // namespace - -bool L2CA_ReadRemoteVersion(const RawAddress& addr, uint8_t* lmp_version, - uint16_t* manufacturer, uint16_t* lmp_sub_version) { - auto& entry = remote_feature_map_[addr]; - if (!entry.version_info_received) { - return false; - } - if (lmp_version != nullptr) *lmp_version = entry.lmp_version; - if (manufacturer != nullptr) *manufacturer = entry.manufacturer_name; - if (lmp_sub_version != nullptr) *lmp_sub_version = entry.sub_version; - return true; -} - -uint8_t* L2CA_ReadRemoteFeatures(const RawAddress& addr) { - auto& entry = remote_feature_map_[addr]; - if (!entry.received_page_0) { - return nullptr; - } - return entry.raw_remote_features; -} - -/** - * Classic Service Registration APIs - */ -uint16_t L2CA_Register(uint16_t client_psm, const tL2CAP_APPL_INFO& callbacks, - bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info, - uint16_t my_mtu, uint16_t required_remote_mtu, - uint16_t sec_level) { - if (classic_dynamic_channel_helper_map_.count(client_psm) != 0) { - LOG(ERROR) << __func__ << "Already registered psm: " << client_psm; - return 0; - } - - classic::DynamicChannelConfigurationOption config; - config.minimal_remote_mtu = std::max(required_remote_mtu, 48); - config.incoming_mtu = my_mtu; - config.channel_mode = - (p_ertm_info != nullptr && - p_ertm_info->preferred_mode == L2CAP_FCR_ERTM_MODE - ? classic::DynamicChannelConfigurationOption:: - RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION - : classic::DynamicChannelConfigurationOption:: - RetransmissionAndFlowControlMode::L2CAP_BASIC); - - classic::SecurityPolicy policy = - (client_psm == 1 - ? classic::SecurityPolicy:: - _SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK - : classic::SecurityPolicy::ENCRYPTED_TRANSPORT); - if (sec_level & (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE)) { - policy = classic::SecurityPolicy::BEST; - } - - classic_dynamic_channel_helper_map_[client_psm] = - std::make_unique(client_psm, callbacks, - config, policy); - - classic_dynamic_channel_helper_map_[client_psm]->Register(); - return client_psm; -} - -void L2CA_Deregister(uint16_t psm) { - if (classic_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return; - } - classic_dynamic_channel_helper_map_[psm]->Unregister(); -} - -/** - * Classic Connection Oriented Channel APIS - */ -uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& raw_address) { - if (classic_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return 0; - } - uint16_t cid_token = add_classic_cid_token_entry(psm); - classic_dynamic_channel_helper_map_[psm]->Connect( - cid_token, ToAddressWithType(raw_address, BLE_ADDR_PUBLIC)); - return cid_token; -} - -bool L2CA_DisconnectReq(uint16_t cid) { - auto psm = classic_cid_token_to_channel_map_[cid]; - if (classic_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return false; - } - classic_dynamic_channel_helper_map_[psm]->Disconnect(cid); - return true; -} - -uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { - if (classic_cid_token_to_channel_map_.count(cid) == 0) { - LOG(ERROR) << __func__ << "Invalid cid: " << cid; - osi_free(p_data); - return 0; - } - auto psm = classic_cid_token_to_channel_map_[cid]; - if (classic_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - osi_free(p_data); - return 0; - } - auto len = p_data->len; - auto* data = p_data->data + p_data->offset; - uint8_t sent_length = - classic_dynamic_channel_helper_map_[psm]->send( - cid, MakeUniquePacket(data, len, IsPacketFlushable(p_data))) * - len; - osi_free(p_data); - return sent_length; -} - -bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bd_addr, - std::vector& lcids, - tL2CAP_LE_CFG_INFO* p_cfg) { - LOG_INFO("UNIMPLEMENTED %s addr: %s cfg:%p", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p_cfg); - return false; -} - -std::vector L2CA_ConnectCreditBasedReq(uint16_t psm, - const RawAddress& p_bd_addr, - tL2CAP_LE_CFG_INFO* p_cfg) { - LOG_INFO("UNIMPLEMENTED %s addr:%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr)); - std::vector result; - return result; -} - -bool L2CA_ConnectCreditBasedRsp(const RawAddress& bd_addr, uint8_t id, - std::vector& accepted_lcids, - uint16_t result, tL2CAP_LE_CFG_INFO* p_cfg) { - LOG_INFO("UNIMPLEMENTED %s addr:%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); - return false; -} - -/** - * Link APIs - */ -bool L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, uint16_t timeout, - tBT_TRANSPORT transport) { - if (transport == BT_TRANSPORT_BR_EDR) { - LOG_INFO("UNIMPLEMENTED %s", __func__); - return false; - } - if (timeout == 0 || timeout == GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP) { - bluetooth::shim::L2CA_RemoveFixedChnl(kLeAttributeCid, bd_addr); - return true; - } else { - LOG_INFO("UNIMPLEMENTED %s", __func__); - return false; - } -} - -bool L2CA_SetAclPriority(uint16_t handle, bool high_priority) { - GetAclManager()->HACK_SetAclTxPriority(handle, high_priority); - return true; -} - -bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) { - uint16_t handle = security_listener_shim_.address_to_handle_[bd_addr]; - return L2CA_SetAclPriority(handle, priority == L2CAP_PRIORITY_HIGH); -} - -bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat, - uint8_t* p_chnl_mask) { - LOG_INFO("UNIMPLEMENTED %s", __func__); - return false; -} - -static constexpr uint16_t kAttCid = 4; - -struct LeFixedChannelHelper { - LeFixedChannelHelper(uint16_t cid) : cid_(cid) {} - - uint16_t cid_; - - void on_registration_complete( - le::FixedChannelManager::RegistrationResult result, - std::unique_ptr service) { - if (result != le::FixedChannelManager::RegistrationResult::SUCCESS) { - LOG(ERROR) << "Channel is not registered. cid=" << +cid_; - return; - } - channel_service_ = std::move(service); - } - - std::unique_ptr channel_service_ = nullptr; - - void on_channel_close(bluetooth::hci::Address device, - bluetooth::hci::ErrorCode error_code) { - auto address = bluetooth::ToRawAddress(device); - channel_enqueue_buffer_[device] = nullptr; - channels_[device]->GetQueueUpEnd()->UnregisterDequeue(); - channels_[device] = nullptr; - conn_parameters_.erase(device); - uint8_t error = static_cast(error_code); - (freg_.pL2CA_FixedConn_Cb)(cid_, address, false, error, BT_TRANSPORT_LE); - } - - void on_channel_open(std::unique_ptr channel) { - auto remote = channel->GetDevice(); - auto device = remote.GetAddress(); - channel->RegisterOnCloseCallback( - GetGdShimHandler(), bluetooth::common::BindOnce( - &LeFixedChannelHelper::on_channel_close, - bluetooth::common::Unretained(this), device)); - if (cid_ == kAttCid) { - channel->Acquire(); - } - channel_enqueue_buffer_[device] = std::make_unique< - bluetooth::os::EnqueueBuffer>( - channel->GetQueueUpEnd()); - channel->GetQueueUpEnd()->RegisterDequeue( - GetGdShimHandler(), - bluetooth::common::Bind(&LeFixedChannelHelper::on_incoming_data, - bluetooth::common::Unretained(this), device)); - channels_[device] = std::move(channel); - conn_parameters_[device] = {}; - - auto address = bluetooth::ToRawAddress(device); - - (freg_.pL2CA_FixedConn_Cb)(cid_, address, true, 0, BT_TRANSPORT_LE); - } - - void on_incoming_data(bluetooth::hci::Address device) { - auto channel = channels_.find(device); - if (channel == channels_.end()) { - LOG_ERROR("Channel is not open"); - return; - } - auto packet = channel->second->GetQueueUpEnd()->TryDequeue(); - std::vector packet_vector(packet->begin(), packet->end()); - BT_HDR* buffer = - static_cast(osi_calloc(packet_vector.size() + sizeof(BT_HDR))); - std::copy(packet_vector.begin(), packet_vector.end(), buffer->data); - buffer->len = packet_vector.size(); - auto address = bluetooth::ToRawAddress(device); - freg_.pL2CA_FixedData_Cb(cid_, address, buffer); - } - - void on_outgoing_connection_fail( - RawAddress remote, le::FixedChannelManager::ConnectionResult result) { - LOG(ERROR) << "Outgoing connection failed"; - freg_.pL2CA_FixedConn_Cb(cid_, remote, true, 0, BT_TRANSPORT_LE); - } - - bool send(hci::Address remote, - std::unique_ptr packet) { - auto buffer = channel_enqueue_buffer_.find(remote); - if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) { - LOG(ERROR) << "Channel is not open for cid " << cid_; - return false; - } - buffer->second->Enqueue(std::move(packet), GetGdShimHandler()); - return true; - } - - std::unordered_map> channels_; - std::unordered_map>> - channel_enqueue_buffer_; - - struct ConnectionParameter { - // Default values are from GD HCI_ACL le_impl. - uint16_t min_int = 0x0018; - uint16_t max_int = 0x0028; - uint16_t latency = 0x0000; - uint16_t timeout = 0x001f4; - uint16_t min_ce_len = 0x0000; - uint16_t max_ce_len = 0x0000; - bool update_allowed = true; - }; - std::unordered_map conn_parameters_; - tL2CAP_FIXED_CHNL_REG freg_; -}; - -static LeFixedChannelHelper att_helper{4}; -static LeFixedChannelHelper smp_helper{6}; -static std::unordered_map - le_fixed_channel_helper_{ - {4, att_helper}, - {6, smp_helper}, - }; - -/** - * Fixed Channel APIs. Note: Classic fixed channel (connectionless and BR SMP) - * is not supported - */ -bool L2CA_RegisterFixedChannel(uint16_t cid, tL2CAP_FIXED_CHNL_REG* p_freg) { - if (cid != kAttCid && cid != kSmpCid) { - LOG(ERROR) << "Invalid cid: " << cid; - return false; - } - auto* helper = &le_fixed_channel_helper_.find(cid)->second; - if (helper == nullptr) { - LOG(ERROR) << "Can't register cid " << cid; - return false; - } - GetL2capLeModule()->GetFixedChannelManager()->RegisterService( - cid, - common::BindOnce(&LeFixedChannelHelper::on_registration_complete, - common::Unretained(helper)), - common::Bind(&LeFixedChannelHelper::on_channel_open, - common::Unretained(helper)), - GetGdShimHandler()); - helper->freg_ = *p_freg; - return true; -} - -bool L2CA_ConnectFixedChnl(uint16_t cid, const RawAddress& rem_bda) { - if (cid != kAttCid && cid != kSmpCid) { - LOG(ERROR) << "Invalid cid " << cid; - return false; - } - - auto* helper = &le_fixed_channel_helper_.find(cid)->second; - auto remote = Btm::GetAddressAndType(rem_bda); - auto record = - le_link_property_listener_shim_.info_.find(ToGdAddress(rem_bda)); - if (record != le_link_property_listener_shim_.info_.end()) { - remote = record->second.address_with_type; - } - LOG(ERROR) << __func__ << ADDRESS_TO_LOGGABLE_STR(remote); - auto manager = GetL2capLeModule()->GetFixedChannelManager(); - manager->ConnectServices( - remote, - common::BindOnce(&LeFixedChannelHelper::on_outgoing_connection_fail, - common::Unretained(helper), rem_bda), - GetGdShimHandler()); - return true; -} - -uint16_t L2CA_SendFixedChnlData(uint16_t cid, const RawAddress& rem_bda, - BT_HDR* p_buf) { - if (cid != kAttCid && cid != kSmpCid) { - LOG(ERROR) << "Invalid cid " << cid; - osi_free(p_buf); - return L2CAP_DW_FAILED; - } - auto* helper = &le_fixed_channel_helper_.find(cid)->second; - auto len = p_buf->len; - auto* data = p_buf->data + p_buf->offset; - bool sent = - helper->send(ToGdAddress(rem_bda), - MakeUniquePacket(data, len, IsPacketFlushable(p_buf))); - osi_free(p_buf); - return sent ? L2CAP_DW_SUCCESS : L2CAP_DW_FAILED; -} - -bool L2CA_RemoveFixedChnl(uint16_t cid, const RawAddress& rem_bda) { - if (cid != kAttCid && cid != kSmpCid) { - LOG(ERROR) << "Invalid cid " << cid; - return false; - } - auto* helper = &le_fixed_channel_helper_.find(cid)->second; - auto channel = helper->channels_.find(ToGdAddress(rem_bda)); - if (channel == helper->channels_.end() || channel->second == nullptr) { - LOG(ERROR) << "Channel is not open"; - return false; - } - channel->second->Release(); - return true; -} - -uint16_t L2CA_GetLeHandle(const RawAddress& rem_bda) { - auto addr = ToGdAddress(rem_bda); - if (le_link_property_listener_shim_.info_.count(addr) == 0) { - return 0; - } - return le_link_property_listener_shim_.info_[addr].handle; -} - -void L2CA_LeConnectionUpdate(const RawAddress& rem_bda, uint16_t min_int, - uint16_t max_int, uint16_t latency, - uint16_t timeout, uint16_t min_ce_len, - uint16_t max_ce_len) { - auto* helper = &le_fixed_channel_helper_.find(kAttCid)->second; - auto channel = helper->channels_.find(ToGdAddress(rem_bda)); - if (channel == helper->channels_.end() || channel->second == nullptr) { - LOG(ERROR) << "Channel is not open"; - return; - } - - auto& parameter = helper->conn_parameters_[ToGdAddress(rem_bda)]; - - parameter.min_int = min_int; - parameter.max_int = max_int; - parameter.latency = latency; - parameter.timeout = timeout; - parameter.min_ce_len = min_ce_len; - parameter.max_ce_len = max_ce_len; - - if (parameter.update_allowed) { - channel->second->GetLinkOptions()->UpdateConnectionParameter( - min_int, max_int, latency, timeout, min_ce_len, max_ce_len); - } - // If update not allowed, don't update; instead cache the value, and update - // when update is allowed. -} - -bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable) { - // When enable is false, we disallow remote connection update request, and - // we use default parameters temporarily. - auto* helper = &le_fixed_channel_helper_.find(kAttCid)->second; - auto channel = helper->channels_.find(ToGdAddress(rem_bda)); - if (channel == helper->channels_.end() || channel->second == nullptr) { - LOG(ERROR) << "Channel is not open"; - return false; - } - - auto& parameter = helper->conn_parameters_[ToGdAddress(rem_bda)]; - parameter.update_allowed = enable; - // TODO(hsz): Notify HCI_ACL LE to allow/disallow remote request. - - if (parameter.update_allowed) { - // Use cached values - uint16_t min_int = parameter.min_int; - uint16_t max_int = parameter.max_int; - uint16_t latency = parameter.latency; - uint16_t timeout = parameter.timeout; - uint16_t min_ce_len = parameter.min_ce_len; - uint16_t max_ce_len = parameter.max_ce_len; - channel->second->GetLinkOptions()->UpdateConnectionParameter( - min_int, max_int, latency, timeout, min_ce_len, max_ce_len); - } else { - // Use the value from legacy l2cble_start_conn_update - uint16_t min_int = BTM_BLE_CONN_INT_MIN; - uint16_t max_int = BTM_BLE_CONN_INT_MIN; - L2CA_AdjustConnectionIntervals(&min_int, &max_int, BTM_BLE_CONN_INT_MIN); - uint16_t latency = BTM_BLE_CONN_PERIPHERAL_LATENCY_DEF; - uint16_t timeout = BTM_BLE_CONN_TIMEOUT_DEF; - uint16_t min_ce_len = 0x0000; - uint16_t max_ce_len = 0x0000; - channel->second->GetLinkOptions()->UpdateConnectionParameter( - min_int, max_int, latency, timeout, min_ce_len, max_ce_len); - } - return true; -} - -/** - * Channel hygiene APIs - */ -bool L2CA_GetRemoteCid(uint16_t lcid, uint16_t* rcid) { - auto psm = classic_cid_token_to_channel_map_[lcid]; - if (classic_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return false; - } - *rcid = classic_dynamic_channel_helper_map_[psm]->GetRemoteCid(lcid); - return *rcid != 0; -} - -bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) { - auto psm = classic_cid_token_to_channel_map_[cid]; - if (classic_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return false; - } - bool high_priority = priority == L2CAP_CHNL_PRIORITY_HIGH; - return classic_dynamic_channel_helper_map_[psm]->SetChannelTxPriority( - cid, high_priority); -} - -bool L2CA_SetLeGattTimeout(const RawAddress& rem_bda, uint16_t idle_tout) { - if (idle_tout == 0xffff) { - bluetooth::shim::L2CA_ConnectFixedChnl(kLeAttributeCid, rem_bda); - } else { - bluetooth::shim::L2CA_RemoveFixedChnl(kLeAttributeCid, rem_bda); - } - return true; -} - -bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) { - LOG_INFO("UNIMPLEMENTED %s", __func__); - return false; -} - -uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) { - auto psm = classic_cid_token_to_channel_map_[lcid]; - if (classic_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return 0; - } - if (num_to_flush == L2CAP_FLUSH_CHANS_GET) { - return classic_dynamic_channel_helper_map_[psm]->GetNumBufferedPackets( - lcid); - } else { - classic_dynamic_channel_helper_map_[psm]->FlushChannel(lcid); - return 1; // Client doesn't care - } - // TODO: Implement LE part -} - -bool L2CA_IsLinkEstablished(const RawAddress& bd_addr, - tBT_TRANSPORT transport) { - if (transport == BT_TRANSPORT_BR_EDR) { - return security_listener_shim_.IsLinkUp(bd_addr); - } else { - return bluetooth::shim::L2CA_GetLeHandle(bd_addr) != 0; - } -} - -bool L2CA_IsLeLink(uint16_t acl_handle) { - for (const auto& entry : le_link_property_listener_shim_.info_) { - if (entry.second.handle == acl_handle) return true; - } - return false; -} - -void L2CA_ReadConnectionAddr(const RawAddress& pseudo_addr, - RawAddress& conn_addr, - tBLE_ADDR_TYPE* p_addr_type) { - auto* helper = &le_fixed_channel_helper_.find(kSmpCid)->second; - auto channel = helper->channels_.find(ToGdAddress(pseudo_addr)); - if (channel == helper->channels_.end() || channel->second == nullptr) { - LOG(ERROR) << "Channel is not open!"; - return; - } - auto local = channel->second->GetLinkOptions()->GetLocalAddress(); - conn_addr = ToRawAddress(local.GetAddress()); - *p_addr_type = to_ble_addr_type(static_cast(local.GetAddressType())); -} - -bool L2CA_ReadRemoteConnectionAddr(const RawAddress& pseudo_addr, - RawAddress& conn_addr, - tBLE_ADDR_TYPE* p_addr_type) { - auto remote = ToGdAddress(pseudo_addr); - if (le_link_property_listener_shim_.info_.count(remote) == 0) { - LOG(ERROR) << __func__ << ": Unknown address"; - return false; - } - auto info = le_link_property_listener_shim_.info_[remote].address_with_type; - conn_addr = ToRawAddress(info.GetAddress()); - *p_addr_type = to_ble_addr_type(static_cast(info.GetAddressType())); - return true; -} - -hci_role_t L2CA_GetBleConnRole(const RawAddress& bd_addr) { - auto remote = ToGdAddress(bd_addr); - if (le_link_property_listener_shim_.info_.count(remote) == 0) { - return HCI_ROLE_UNKNOWN; - } - return static_cast( - le_link_property_listener_shim_.info_[remote].role); -} - -void L2CA_ConnectForSecurity(const RawAddress& bd_addr) { - security_interface_->InitiateConnectionForSecurity( - bluetooth::ToGdAddress(bd_addr)); -} - -void L2CA_SetBondingState(const RawAddress& bd_addr, bool is_bonding) { - security_listener_shim_.UpdateLinkHoldForSecurity(bd_addr, is_bonding); -} - -void L2CA_DisconnectLink(const RawAddress& remote) { - security_listener_shim_.Disconnect(remote); -} - -uint16_t L2CA_GetNumLinks() { return security_listener_shim_.GetNumAclLinks(); } - -// LE COC Shim Helper - -namespace { - -uint16_t le_cid_token_counter_ = 0x41; - -std::unordered_map - le_cid_token_to_channel_map_; - -uint16_t add_le_cid_token_entry(uint16_t psm) { - uint16_t new_token = le_cid_token_counter_; - le_cid_token_to_channel_map_[new_token] = psm; - le_cid_token_counter_++; - if (le_cid_token_counter_ == 0) le_cid_token_counter_ = 0x41; - return new_token; -} - -void remove_le_cid_token_entry(uint16_t cid_token) { - le_cid_token_to_channel_map_.erase(cid_token); -} - -void remove_le_dynamic_channel_helper(uint16_t psm); - -struct LeDynamicChannelHelper { - LeDynamicChannelHelper(uint16_t psm, tL2CAP_APPL_INFO appl_info, - le::DynamicChannelConfigurationOption config, - le::SecurityPolicy policy) - : psm_(psm), appl_info_(appl_info), config_(config), policy_(policy) {} - - uint16_t psm_; - tL2CAP_APPL_INFO appl_info_; - le::DynamicChannelConfigurationOption config_; - le::SecurityPolicy policy_; - - void Register() { - std::promise promise; - auto future = promise.get_future(); - GetL2capLeModule()->GetDynamicChannelManager()->RegisterService( - psm_, config_, policy_, - base::BindOnce(&LeDynamicChannelHelper::on_registration_complete, - base::Unretained(this), std::move(promise)), - base::Bind(&LeDynamicChannelHelper::on_channel_open, - base::Unretained(this), 0), - GetGdShimHandler()); - future.wait_for(std::chrono::milliseconds(300)); - } - - void on_registration_complete( - std::promise promise, - le::DynamicChannelManager::RegistrationResult result, - std::unique_ptr service) { - if (result != le::DynamicChannelManager::RegistrationResult::SUCCESS) { - LOG(ERROR) << "Channel is not registered. psm=" << +psm_ << (int)result; - promise.set_value(); - return; - } - channel_service_ = std::move(service); - promise.set_value(); - } - - std::unique_ptr channel_service_ = nullptr; - - void Connect(uint16_t cid_token, bluetooth::hci::AddressWithType device) { - if (channel_service_ == nullptr) { - LOG(ERROR) << __func__ << "Not registered"; - return; - } - initiated_by_us_[cid_token] = true; - GetL2capLeModule()->GetDynamicChannelManager()->ConnectChannel( - device, config_, psm_, - base::Bind(&LeDynamicChannelHelper::on_channel_open, - base::Unretained(this), cid_token), - base::BindOnce(&LeDynamicChannelHelper::on_outgoing_connection_fail, - base::Unretained(this)), - GetGdShimHandler()); - } - - void Disconnect(uint16_t cid_token) { - if (channel_service_ == nullptr) { - return; - } - if (channels_.count(cid_token) == 0) { - return; - } - channels_[cid_token]->Close(); - } - - void Unregister() { - if (channel_service_ != nullptr) { - channel_service_->Unregister( - base::BindOnce(&LeDynamicChannelHelper::on_unregistered, - base::Unretained(this)), - GetGdShimHandler()); - channel_service_ = nullptr; - } - } - - void on_unregistered() { - for (const auto& device : channels_) { - device.second->Close(); - } - remove_le_dynamic_channel_helper(psm_); - } - - void on_channel_close(uint16_t cid_token, - bluetooth::hci::ErrorCode error_code) { - channel_enqueue_buffer_[cid_token] = nullptr; - channel_enqueue_buffer_.erase(cid_token); - channels_[cid_token]->GetQueueUpEnd()->UnregisterDequeue(); - channels_.erase(cid_token); - do_in_main_thread( - FROM_HERE, - base::BindOnce(appl_info_.pL2CA_DisconnectInd_Cb, cid_token, false)); - - remove_le_cid_token_entry(cid_token); - initiated_by_us_.erase(cid_token); - - if (channel_service_ == nullptr && channels_.empty()) { - // Try again - L2CA_Deregister(psm_); - } - } - - void on_channel_open(uint16_t cid_token, - std::unique_ptr channel) { - auto device = channel->GetDevice(); - auto address = bluetooth::ToRawAddress(device.GetAddress()); - bool initiator_local = (cid_token != 0); - if (cid_token == 0) { - cid_token = add_le_cid_token_entry(psm_); - } - - channel->RegisterOnCloseCallback(GetGdShimHandler()->BindOnceOn( - this, &LeDynamicChannelHelper::on_channel_close, cid_token)); - - channel->GetQueueUpEnd()->RegisterDequeue( - GetGdShimHandler(), - bluetooth::common::Bind(&LeDynamicChannelHelper::on_incoming_data, - bluetooth::common::Unretained(this), - cid_token)); - - channel_enqueue_buffer_[cid_token] = std::make_unique< - bluetooth::os::EnqueueBuffer>( - channel->GetQueueUpEnd()); - - channels_[cid_token] = std::move(channel); - - if (initiator_local) { - do_in_main_thread( - FROM_HERE, - base::BindOnce(appl_info_.pL2CA_ConnectCfm_Cb, cid_token, 0)); - - } else { - if (appl_info_.pL2CA_ConnectInd_Cb == nullptr) { - Disconnect(cid_token); - return; - } - do_in_main_thread(FROM_HERE, - base::BindOnce(appl_info_.pL2CA_ConnectInd_Cb, address, - cid_token, psm_, 0)); - } - } - - void on_incoming_data(uint16_t cid_token) { - auto channel = channels_.find(cid_token); - if (channel == channels_.end()) { - LOG_ERROR("Channel is not open"); - return; - } - auto packet = channel->second->GetQueueUpEnd()->TryDequeue(); - std::vector packet_vector(packet->begin(), packet->end()); - BT_HDR* buffer = - static_cast(osi_calloc(packet_vector.size() + sizeof(BT_HDR))); - std::copy(packet_vector.begin(), packet_vector.end(), buffer->data); - buffer->len = packet_vector.size(); - if (do_in_main_thread(FROM_HERE, - base::BindOnce(appl_info_.pL2CA_DataInd_Cb, cid_token, - base::Unretained(buffer))) != - BT_STATUS_SUCCESS) { - osi_free(buffer); - } - } - - void on_outgoing_connection_fail( - le::DynamicChannelManager::ConnectionResult result) { - LOG(ERROR) << "Outgoing connection failed"; - } - - bool send(uint16_t cid, - std::unique_ptr packet) { - auto buffer = channel_enqueue_buffer_.find(cid); - if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) { - LOG(ERROR) << "Channel is not open"; - return false; - } - buffer->second->Enqueue(std::move(packet), GetGdShimHandler()); - return true; - } - - uint16_t GetMtu(uint16_t cid_token) { - if (channels_.count(cid_token) == 0) { - return 0; - } - return static_cast(channels_[cid_token]->GetMtu()); - } - - std::unordered_map> channels_; - std::unordered_map>> - channel_enqueue_buffer_; - std::unordered_map initiated_by_us_; -}; - -std::unordered_map> - le_dynamic_channel_helper_map_; - -void remove_le_dynamic_channel_helper(uint16_t psm) { - if (le_dynamic_channel_helper_map_.count(psm) != 0 && - le_dynamic_channel_helper_map_[psm]->channels_.empty()) { - le_dynamic_channel_helper_map_.erase(psm); - } -} - -std::unordered_set assigned_dynamic_le_psm_; -uint16_t next_assigned_dynamic_le_psm_ = 0x80; -} // namespace - -/** - * Le Connection Oriented Channel APIs - */ - -uint16_t L2CA_AllocateLePSM() { - if (le_dynamic_channel_helper_map_.size() > 100) { - LOG_ERROR("Why do we need more than 100 dynamic channel PSMs?"); - return 0; - } - while (le_dynamic_channel_helper_map_.count(next_assigned_dynamic_le_psm_)) { - next_assigned_dynamic_le_psm_++; - if (next_assigned_dynamic_le_psm_ > 0xff) { - next_assigned_dynamic_le_psm_ = 0x80; - } - } - assigned_dynamic_le_psm_.emplace(next_assigned_dynamic_le_psm_); - return next_assigned_dynamic_le_psm_; -} - -void L2CA_FreeLePSM(uint16_t psm) { assigned_dynamic_le_psm_.erase(psm); } - -uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& callbacks, - uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg) { - if (le_dynamic_channel_helper_map_.count(psm) != 0) { - LOG(ERROR) << __func__ << "Already registered psm: " << psm; - return 0; - } - - le::DynamicChannelConfigurationOption config; - config.mtu = cfg.mtu; - le::SecurityPolicy policy = - le::SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK; - if (sec_level & (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE)) { - policy = le::SecurityPolicy::AUTHENTICATED_ENCRYPTED_TRANSPORT; - } - - le_dynamic_channel_helper_map_[psm] = - std::make_unique(psm, callbacks, config, policy); - le_dynamic_channel_helper_map_[psm]->Register(); - return psm; -} - -void L2CA_DeregisterLECoc(uint16_t psm) { - if (le_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return; - } - le_dynamic_channel_helper_map_[psm]->Unregister(); -} - -uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, - tL2CAP_LE_CFG_INFO* p_cfg) { - if (le_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return 0; - } - uint16_t cid_token = add_le_cid_token_entry(psm); - auto remote = Btm::GetAddressAndType(p_bd_addr); - auto record = - le_link_property_listener_shim_.info_.find(ToGdAddress(p_bd_addr)); - if (record != le_link_property_listener_shim_.info_.end()) { - remote = record->second.address_with_type; - } - le_dynamic_channel_helper_map_[psm]->Connect(cid_token, remote); - return cid_token; -} - -bool L2CA_GetPeerLECocConfig(uint16_t cid, tL2CAP_LE_CFG_INFO* peer_cfg) { - if (le_cid_token_to_channel_map_.count(cid) == 0) { - LOG(ERROR) << __func__ << "Invalid cid: " << cid; - return false; - } - auto psm = le_cid_token_to_channel_map_[cid]; - if (le_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return false; - } - auto mtu = le_dynamic_channel_helper_map_[psm]->GetMtu(cid); - peer_cfg->mtu = mtu; - return mtu; -} - -bool L2CA_DisconnectLECocReq(uint16_t cid) { - if (le_cid_token_to_channel_map_.count(cid) == 0) { - LOG(ERROR) << __func__ << "Invalid cid: " << cid; - return false; - } - auto psm = le_cid_token_to_channel_map_[cid]; - if (le_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - return false; - } - le_dynamic_channel_helper_map_[psm]->Disconnect(cid); - return true; -} - -uint8_t L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) { - if (le_cid_token_to_channel_map_.count(cid) == 0) { - LOG(ERROR) << __func__ << "Invalid cid: " << cid; - osi_free(p_data); - return 0; - } - auto psm = le_cid_token_to_channel_map_[cid]; - if (le_dynamic_channel_helper_map_.count(psm) == 0) { - LOG(ERROR) << __func__ << "Not registered psm: " << psm; - osi_free(p_data); - return 0; - } - auto len = p_data->len; - auto* data = p_data->data + p_data->offset; - uint8_t sent_length = - le_dynamic_channel_helper_map_[psm]->send( - cid, MakeUniquePacket(data, len, IsPacketFlushable(p_data))) * - len; - osi_free(p_data); - return sent_length; -} - -void L2CA_SwitchRoleToCentral(const RawAddress& addr) { - GetAclManager()->SwitchRole(ToGdAddress(addr), bluetooth::hci::Role::CENTRAL); -} - -} // namespace shim -} // namespace bluetooth diff --git a/system/main/shim/l2c_api.h b/system/main/shim/l2c_api.h index 9f12916ca00bef04e72c95d95293d510283ddd25..07d27718e6e24256312cb4eb0c4835cd4196e313 100644 --- a/system/main/shim/l2c_api.h +++ b/system/main/shim/l2c_api.h @@ -390,10 +390,6 @@ void L2CA_LeConnectionUpdate(const RawAddress& rem_bda, uint16_t min_int, uint16_t timeout, uint16_t min_ce_len, uint16_t max_ce_len); -// When GATT discovery is in progress, use the minimal connection interval, and -// reject remote connection updates, until done. -bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable); - /******************************************************************************* * * Function L2CA_SetLeGattTimeout @@ -419,20 +415,19 @@ bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int, uint16_t max_int, uint16_t latency, uint16_t timeout, uint16_t min_ce_len, uint16_t max_ce_len); +/* When called with lock=true, LE connection parameters will be locked on + * fastest value, and we won't accept request to change it from remote. When + * called with lock=false, parameters are relaxed. + */ +void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& rem_bda, + bool lock); -/******************************************************************************* - * - * Function L2CA_EnableUpdateBleConnParams - * - * Description Update BLE connection parameters. - * - * Parameters: BD Address of remote - * enable flag - * - * Return value: true if update started - * - ******************************************************************************/ -bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable); +/* When called with lock=true, LE connection parameters will be locked on + * fastest value, and we won't accept request to change it from remote. When + * called with lock=false, parameters are relaxed. + */ +void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& rem_bda, + bool lock); /******************************************************************************* * diff --git a/system/main/shim/le_advertising_manager.cc b/system/main/shim/le_advertising_manager.cc index d04862ecedf7fd47d57512332b3b0faa83f32456..a1ec02f05e7feb3dc893e53512b7fff40204a7e6 100644 --- a/system/main/shim/le_advertising_manager.cc +++ b/system/main/shim/le_advertising_manager.cc @@ -25,8 +25,8 @@ #include #include "btif/include/btif_common.h" -#include "gd/common/init_flags.h" -#include "gd/hci/le_advertising_manager.h" +#include "common/init_flags.h" +#include "hci/le_advertising_manager.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" #include "stack/include/btm_log_history.h" @@ -93,7 +93,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, } void SetParameters(uint8_t advertiser_id, AdvertiseParameters params, - ParametersCallback cb) override { + ParametersCallback /* cb */) override { LOG(INFO) << __func__ << " in shim layer"; bluetooth::hci::AdvertisingConfig config{}; parse_parameter(config, params); @@ -101,7 +101,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, } void SetData(int advertiser_id, bool set_scan_rsp, vector data, - StatusCallback cb) override { + StatusCallback /* cb */) override { LOG(INFO) << __func__ << " in shim layer"; std::vector advertising_data = {}; parse_gap_data(data, advertising_data); @@ -109,9 +109,9 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, advertising_data); } - void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb, + void Enable(uint8_t advertiser_id, bool enable, StatusCallback /* cb */, uint16_t duration, uint8_t maxExtAdvEvents, - StatusCallback timeout_cb) override { + StatusCallback /* timeout_cb */) override { LOG(INFO) << __func__ << " in shim layer"; bluetooth::shim::GetAdvertising()->EnableAdvertiser( advertiser_id, enable, duration, maxExtAdvEvents); @@ -137,14 +137,14 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, } void StartAdvertisingSet(uint8_t client_id, int reg_id, - IdTxPowerStatusCallback register_cb, + IdTxPowerStatusCallback /* register_cb */, AdvertiseParameters params, std::vector advertise_data, std::vector scan_response_data, PeriodicAdvertisingParameters periodic_params, std::vector periodic_data, uint16_t duration, uint8_t maxExtAdvEvents, - IdStatusCallback timeout_cb) { + IdStatusCallback /* timeout_cb */) { LOG(INFO) << __func__ << " in shim layer"; bluetooth::hci::AdvertisingConfig config{}; @@ -175,7 +175,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, void SetPeriodicAdvertisingParameters( int advertiser_id, PeriodicAdvertisingParameters periodic_params, - StatusCallback cb) override { + StatusCallback /* cb */) override { LOG(INFO) << __func__ << " in shim layer"; bluetooth::hci::PeriodicAdvertisingParameters parameters; parameters.max_interval = periodic_params.max_interval; @@ -186,7 +186,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, } void SetPeriodicAdvertisingData(int advertiser_id, std::vector data, - StatusCallback cb) override { + StatusCallback /* cb */) override { LOG(INFO) << __func__ << " in shim layer"; std::vector advertising_data = {}; parse_gap_data(data, advertising_data); @@ -196,7 +196,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable, bool include_adi, - StatusCallback cb) override { + StatusCallback /* cb */) override { LOG(INFO) << __func__ << " in shim layer"; bluetooth::shim::GetAdvertising()->EnablePeriodicAdvertising( advertiser_id, enable, include_adi); @@ -211,11 +211,11 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface, native_adv_callbacks_map_[client_id] = callbacks; } - void on_scan(Address address, AddressType address_type) { + void on_scan(Address /* address */, AddressType /* address_type */) { LOG(INFO) << __func__ << " in shim layer"; } - void on_set_terminated(ErrorCode error_code, uint8_t, uint8_t) { + void on_set_terminated(ErrorCode /* error_code */, uint8_t, uint8_t) { LOG(INFO) << __func__ << " in shim layer"; } diff --git a/system/main/shim/le_scanning_manager.cc b/system/main/shim/le_scanning_manager.cc index 6fe1525649e7d02007c5d96e44e7882ab0096cfe..806d51788bad9f5c2cfb62f5a079a2c15b36bb06 100644 --- a/system/main/shim/le_scanning_manager.cc +++ b/system/main/shim/le_scanning_manager.cc @@ -37,6 +37,7 @@ #include "main/shim/shim.h" #include "os/log.h" #include "stack/btm/btm_int_types.h" +#include "stack/include/bt_dev_class.h" #include "stack/include/btm_log_history.h" #include "storage/device.h" #include "storage/le_device.h" @@ -62,48 +63,58 @@ constexpr uint16_t kAllowAllFilter = 0x00; constexpr uint16_t kListLogicOr = 0x01; class DefaultScanningCallback : public ::ScanningCallbacks { - void OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scanner_id, - uint8_t status) override { + void OnScannerRegistered(const bluetooth::Uuid /* app_uuid */, + uint8_t /* scanner_id */, + uint8_t /* status */) override { LogUnused(); } - void OnSetScannerParameterComplete(uint8_t scanner_id, - uint8_t status) override { + void OnSetScannerParameterComplete(uint8_t /* scanner_id */, + uint8_t /* status */) override { LogUnused(); } - void OnScanResult(uint16_t event_type, uint8_t address_type, RawAddress bda, - uint8_t primary_phy, uint8_t secondary_phy, - uint8_t advertising_sid, int8_t tx_power, int8_t rssi, - uint16_t periodic_advertising_interval, - std::vector advertising_data) override { + void OnScanResult(uint16_t /* event_type */, uint8_t /* address_type */, + RawAddress /* bda */, uint8_t /* primary_phy */, + uint8_t /* secondary_phy */, uint8_t /* advertising_sid */, + int8_t /* tx_power */, int8_t /* rssi */, + uint16_t /* periodic_advertising_interval */, + std::vector /* advertising_data */) override { LogUnused(); } void OnTrackAdvFoundLost( - AdvertisingTrackInfo advertising_track_info) override { + AdvertisingTrackInfo /* advertising_track_info */) override { LogUnused(); } - void OnBatchScanReports(int client_if, int status, int report_format, - int num_records, std::vector data) override { + void OnBatchScanReports(int /* client_if */, int /* status */, + int /* report_format */, int /* num_records */, + std::vector /* data */) override { LogUnused(); } - void OnBatchScanThresholdCrossed(int client_if) override { LogUnused(); } - void OnPeriodicSyncStarted(int reg_id, uint8_t status, uint16_t sync_handle, - uint8_t advertising_sid, uint8_t address_type, - RawAddress address, uint8_t phy, - uint16_t interval) override { + void OnBatchScanThresholdCrossed(int /* client_if */) override { + LogUnused(); + } + void OnPeriodicSyncStarted(int /* reg_id */, uint8_t /* status */, + uint16_t /* sync_handle */, + uint8_t /* advertising_sid */, + uint8_t /* address_type */, + RawAddress /* address */, uint8_t /* phy */, + uint16_t /* interval */) override { LogUnused(); }; - void OnPeriodicSyncReport(uint16_t sync_handle, int8_t tx_power, int8_t rssi, - uint8_t status, - std::vector data) override { + void OnPeriodicSyncReport(uint16_t /* sync_handle */, int8_t /* tx_power */, + int8_t /* rssi */, uint8_t /* status */, + std::vector /* data */) override { LogUnused(); }; - void OnPeriodicSyncLost(uint16_t sync_handle) override { LogUnused(); }; - void OnPeriodicSyncTransferred(int pa_source, uint8_t status, - RawAddress address) override { + void OnPeriodicSyncLost(uint16_t /* sync_handle */) override { LogUnused(); }; + void OnPeriodicSyncTransferred(int /* pa_source */, uint8_t /* status */, + RawAddress /* address */) override { LogUnused(); }; - void OnBigInfoReport(uint16_t sync_handle, bool encrypted) override {LogUnused(); }; + void OnBigInfoReport(uint16_t /* sync_handle */, + bool /* encrypted */) override { + LogUnused(); + }; private: static void LogUnused() { @@ -133,8 +144,8 @@ extern void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr, void btm_ble_process_adv_addr(RawAddress& raw_address, tBLE_ADDR_TYPE* address_type); -extern bool btm_ble_get_appearance_as_cod(std::vector const& data, - DEV_CLASS dev_class); +extern DEV_CLASS btm_ble_get_appearance_as_cod( + std::vector const& data); using bluetooth::shim::BleScannerInterfaceImpl; @@ -255,8 +266,8 @@ void BleScannerInterfaceImpl::ScanFilterAdd(int filter_index, } /** Clear all scan filter conditions for specific filter index*/ -void BleScannerInterfaceImpl::ScanFilterClear(int filter_index, - FilterConfigCallback cb) { +void BleScannerInterfaceImpl::ScanFilterClear(int /* filter_index */, + FilterConfigCallback /* cb */) { LOG(INFO) << __func__ << " in shim layer"; // This function doesn't used in java layer } @@ -339,23 +350,23 @@ void BleScannerInterfaceImpl::OnMsftAdvMonitorEnable( /** Sets the LE scan interval and window in units of N*0.625 msec */ void BleScannerInterfaceImpl::SetScanParameters(int scanner_id, + uint8_t scan_type, int scan_interval, - int scan_window, Callback cb) { + int scan_window, + Callback /* cb */) { LOG(INFO) << __func__ << " in shim layer"; - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; if (BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_EXT_SCAN_INT_MAX) && BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_EXT_SCAN_WIN_MAX)) { - p_cb->scan_type = BTM_BLE_SCAN_MODE_ACTI; - p_cb->scan_interval = scan_interval; - p_cb->scan_window = scan_window; + btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_ACTI; + btm_cb.ble_ctr_cb.inq_var.scan_interval = scan_interval; + btm_cb.ble_ctr_cb.inq_var.scan_window = scan_window; } - // use active scan - auto scan_type = static_cast(0x01); - bluetooth::shim::GetScanning()->SetScanParameters(scanner_id, scan_type, - scan_interval, scan_window); + bluetooth::shim::GetScanning()->SetScanParameters( + scanner_id, static_cast(scan_type), + scan_interval, scan_window); } /* Configure the batchscan storage */ @@ -372,7 +383,8 @@ void BleScannerInterfaceImpl::BatchscanConfigStorage( /* Enable batchscan */ void BleScannerInterfaceImpl::BatchscanEnable(int scan_mode, int scan_interval, - int scan_window, int addr_type, + int scan_window, + int /* addr_type */, int discard_rule, Callback cb) { LOG(INFO) << __func__ << " in shim layer"; auto batch_scan_mode = static_cast(scan_mode); @@ -654,14 +666,15 @@ void BleScannerInterfaceImpl::OnBigInfoReport(uint16_t sync_handle, bool encrypt } void BleScannerInterfaceImpl::OnTimeout() {} -void BleScannerInterfaceImpl::OnFilterEnable(bluetooth::hci::Enable enable, - uint8_t status) {} +void BleScannerInterfaceImpl::OnFilterEnable( + bluetooth::hci::Enable /* enable */, uint8_t /* status */) {} void BleScannerInterfaceImpl::OnFilterParamSetup( - uint8_t available_spaces, bluetooth::hci::ApcfAction action, - uint8_t status) {} + uint8_t /* available_spaces */, bluetooth::hci::ApcfAction /* action */, + uint8_t /* status */) {} void BleScannerInterfaceImpl::OnFilterConfigCallback( - bluetooth::hci::ApcfFilterType filter_type, uint8_t available_spaces, - bluetooth::hci::ApcfAction action, uint8_t status) {} + bluetooth::hci::ApcfFilterType /* filter_type */, + uint8_t /* available_spaces */, bluetooth::hci::ApcfAction /* action */, + uint8_t /* status */) {} bool BleScannerInterfaceImpl::parse_filter_command( bluetooth::hci::AdvertisingPacketContentFilterCommand& @@ -792,13 +805,13 @@ void BleScannerInterfaceImpl::handle_remote_properties( memcpy(bdname.name, p_eir_remote_name, remote_name_len); if (remote_name_len < BD_NAME_LEN + 1) bdname.name[remote_name_len] = '\0'; - btif_dm_update_ble_remote_properties(bd_addr, bdname.name, NULL, + btif_dm_update_ble_remote_properties(bd_addr, bdname.name, kDevClassEmpty, device_type); } } - DEV_CLASS dev_class; - if (btm_ble_get_appearance_as_cod(advertising_data, dev_class)) { + DEV_CLASS dev_class = btm_ble_get_appearance_as_cod(advertising_data); + if (dev_class != kDevClassUnclassified) { btif_dm_update_ble_remote_properties(bd_addr, bdname.name, dev_class, device_type); } diff --git a/system/main/shim/link_connection_interface.h b/system/main/shim/link_connection_interface.h index 2fc88a17690a006fc997213d1dec1b970f45791a..7788ae4cbe2da102ca38c5ba44973d768f866e31 100644 --- a/system/main/shim/link_connection_interface.h +++ b/system/main/shim/link_connection_interface.h @@ -19,8 +19,8 @@ #include #include -#include "gd/hci/address.h" -#include "gd/hci/address_with_type.h" +#include "hci/address.h" +#include "hci/address_with_type.h" #include "stack/include/hci_error_code.h" namespace bluetooth { diff --git a/system/main/shim/metric_id_api.cc b/system/main/shim/metric_id_api.cc index 0573e6e1dadeff661e7a33c326d969b679fda4d8..cce6b050033479e4cad77d8ee2aa9ba607026ccf 100644 --- a/system/main/shim/metric_id_api.cc +++ b/system/main/shim/metric_id_api.cc @@ -15,8 +15,8 @@ */ #include "main/shim/metric_id_api.h" -#include "gd/common/metric_id_manager.h" -#include "gd/hci/address.h" +#include "common/metric_id_manager.h" +#include "hci/address.h" #include "main/shim/helpers.h" #include "types/raw_address.h" diff --git a/system/main/shim/metrics_api.cc b/system/main/shim/metrics_api.cc index 296ecc3f8684eb320c0f50dfbf7521f9fe1eaa54..279697601066c0516fc0cfb27be9886ffac945e3 100644 --- a/system/main/shim/metrics_api.cc +++ b/system/main/shim/metrics_api.cc @@ -16,11 +16,11 @@ #include "main/shim/metrics_api.h" -#include "gd/hci/address.h" -#include "gd/metrics/counter_metrics.h" -#include "gd/os/metrics.h" +#include "hci/address.h" #include "main/shim/entry.h" #include "main/shim/helpers.h" +#include "metrics/counter_metrics.h" +#include "os/metrics.h" #include "types/raw_address.h" using bluetooth::hci::Address; @@ -67,6 +67,20 @@ void LogMetricA2dpPlaybackEvent(const RawAddress& raw_address, audio_coding_mode); } +void LogMetricA2dpSessionMetricsEvent( + const RawAddress& raw_address, int64_t audio_duration_ms, + int media_timer_min_ms, int media_timer_max_ms, int media_timer_avg_ms, + int total_scheduling_count, int buffer_overruns_max_count, + int buffer_overruns_total, float buffer_underruns_average, + int buffer_underruns_count, int64_t codec_index, bool is_a2dp_offload) { + Address address = bluetooth::ToGdAddress(raw_address); + bluetooth::os::LogMetricA2dpSessionMetricsEvent( + address, audio_duration_ms, media_timer_min_ms, media_timer_max_ms, + media_timer_avg_ms, total_scheduling_count, buffer_overruns_max_count, + buffer_overruns_total, buffer_underruns_average, buffer_underruns_count, + codec_index, is_a2dp_offload); +} + void LogMetricHfpPacketLossStats(const RawAddress& raw_address, int num_decoded_frames, double packet_loss_ratio, diff --git a/system/main/shim/metrics_api.h b/system/main/shim/metrics_api.h index 04d6e985ce25c90f431292de6c90e2b047eee620..f36ac4e0a7511f3db334fb60aa309937e256bbfa 100644 --- a/system/main/shim/metrics_api.h +++ b/system/main/shim/metrics_api.h @@ -86,6 +86,31 @@ void LogMetricA2dpAudioOverrunEvent(const RawAddress& address, void LogMetricA2dpPlaybackEvent(const RawAddress& raw_address, int playback_state, int audio_coding_mode); +/** + * Log A2DP audio session metrics event + * + * @param address A2DP device associated with this session + * @param audio_duration_ms duration of the A2DP session + * @param media_timer_min_ms min time interval for the media timer + * @param media_timer_max_ms max time interval for the media timer + * @param media_timer_avg_ms avg time interval for the media timer + * @param total_scheduling_count total scheduling count + * @param buffer_overruns_max_count max count of Tx queue messages dropped + caused by buffer overruns + * @param buffer_overruns_total total count of Tx queue messages dropped + caused by buffer overruns + * @param buffer_underruns_average avg number of bytes short in buffer + underruns + * @param buffer_underruns_count count of buffer underruns + * @param codec_index A2DP codec index (SBC=0, AAC=1, etc...) + * @param is_a2dp_offload if A2DP is offload + */ +void LogMetricA2dpSessionMetricsEvent( + const RawAddress& address, int64_t audio_duration_ms, + int media_timer_min_ms, int media_timer_max_ms, int media_timer_avg_ms, + int total_scheduling_count, int buffer_overruns_max_count, + int buffer_overruns_total, float buffer_underruns_average, + int buffer_underruns_count, int64_t codec_index, bool is_a2dp_offload); /** * Log HFP audio capture packet loss statistics * diff --git a/system/main/shim/shim.cc b/system/main/shim/shim.cc index 990fbe5fb4eda8901cf6c6ef3841908a7ac049bc..51de0afdda05546097b12e3998840f3a48d0cd56 100644 --- a/system/main/shim/shim.cc +++ b/system/main/shim/shim.cc @@ -18,11 +18,11 @@ #include "main/shim/shim.h" -#include "gd/common/init_flags.h" -#include "gd/os/log.h" +#include "common/init_flags.h" #include "main/shim/entry.h" #include "main/shim/hci_layer.h" #include "main/shim/stack.h" +#include "os/log.h" #include "stack/include/main_thread.h" static const hci_t* hci; @@ -38,7 +38,7 @@ static void post_to_main_message_loop(const base::Location& from_here, } } -future_t* ShimModuleStartUp() { +static future_t* ShimModuleStartUp() { hci = bluetooth::shim::hci_layer_get_interface(); ASSERT_LOG(hci, "%s could not get hci layer interface.", __func__); @@ -48,7 +48,7 @@ future_t* ShimModuleStartUp() { return kReturnImmediate; } -future_t* GeneralShutDown() { +static future_t* GeneralShutDown() { bluetooth::shim::Stack::GetInstance()->Stop(); return kReturnImmediate; } diff --git a/system/main/shim/stack.cc b/system/main/shim/stack.cc index bffeb27915d1bceee4868e490c4a64f964f0f5b9..615119e9474add413e6a46b186b164e19d3c565d 100644 --- a/system/main/shim/stack.cc +++ b/system/main/shim/stack.cc @@ -24,30 +24,30 @@ #include +#include "common/init_flags.h" +#include "common/strings.h" #include "device/include/controller.h" -#include "gd/common/init_flags.h" -#include "gd/common/strings.h" -#include "gd/hal/hci_hal.h" -#include "gd/hci/acl_manager.h" -#include "gd/hci/acl_manager/acl_scheduler.h" -#include "gd/hci/controller.h" -#include "gd/hci/distance_measurement_manager.h" -#include "gd/hci/hci_layer.h" -#include "gd/hci/le_advertising_manager.h" -#include "gd/hci/le_scanning_manager.h" -#include "gd/hci/msft.h" -#include "gd/hci/remote_name_request.h" -#include "gd/hci/vendor_specific_event_manager.h" -#include "gd/metrics/counter_metrics.h" -#include "gd/os/log.h" -#include "gd/shim/dumpsys.h" -#include "gd/storage/storage_module.h" -#include "gd/sysprops/sysprops_module.h" +#include "hal/hci_hal.h" +#include "hci/acl_manager.h" +#include "hci/acl_manager/acl_scheduler.h" +#include "hci/controller.h" +#include "hci/distance_measurement_manager.h" +#include "hci/hci_layer.h" +#include "hci/le_advertising_manager.h" +#include "hci/le_scanning_manager.h" +#include "hci/msft.h" +#include "hci/remote_name_request.h" +#include "hci/vendor_specific_event_manager.h" #include "main/shim/acl_legacy_interface.h" #include "main/shim/distance_measurement_manager.h" #include "main/shim/hci_layer.h" #include "main/shim/le_advertising_manager.h" #include "main/shim/le_scanning_manager.h" +#include "metrics/counter_metrics.h" +#include "os/log.h" +#include "shim/dumpsys.h" +#include "storage/storage_module.h" +#include "sysprops/sysprops_module.h" namespace bluetooth { namespace shim { @@ -102,6 +102,20 @@ void Stack::StartEverything() { bluetooth::shim::init_distance_measurement_manager(); } +void Stack::StartModuleStack(const ModuleList* modules, + const os::Thread* thread) { + std::lock_guard lock(mutex_); + ASSERT_LOG(!is_running_, "%s Gd stack already running", __func__); + stack_thread_ = const_cast(thread); + LOG_INFO("Starting Gd stack"); + + stack_manager_.StartUp(const_cast(modules), stack_thread_); + stack_handler_ = new os::Handler(stack_thread_); + + num_modules_ = modules->NumModules(); + is_running_ = true; +} + void Stack::Start(ModuleList* modules) { ASSERT_LOG(!is_running_, "%s Gd stack already running", __func__); LOG_INFO("%s Starting Gd stack", __func__); diff --git a/system/main/shim/stack.h b/system/main/shim/stack.h index 8b04d84c6ef31cabb078fcf82938521ef8f929b4..d4a18f3ca01aea4049f606d3f4dbddbe30eab8e3 100644 --- a/system/main/shim/stack.h +++ b/system/main/shim/stack.h @@ -19,13 +19,13 @@ #include #include -#include "gd/module.h" -#include "gd/os/handler.h" -#include "gd/os/thread.h" -#include "gd/stack_manager.h" #include "main/shim/acl.h" #include "main/shim/btm.h" #include "main/shim/link_policy_interface.h" +#include "module.h" +#include "os/handler.h" +#include "os/thread.h" +#include "stack_manager.h" // The shim layer implementation on the Gd stack side. namespace bluetooth { @@ -60,6 +60,22 @@ class Stack { void LockForDumpsys(std::function dumpsys_callback); + // Start the list of modules with the given stack manager thread + void StartModuleStack(const ModuleList* modules, const os::Thread* thread); + + // Run the callable object on the module instance + template + bool CallOnModule(std::function run) { + std::lock_guard lock(Stack::GetInstance()->mutex_); + if (Stack::GetInstance()->is_running_) { + run(Stack::GetInstance()->GetStackManager()->GetInstance()); + return true; + } + return false; + } + + size_t NumModules() const { return num_modules_; } + private: mutable std::recursive_mutex mutex_; StackManager stack_manager_; @@ -68,7 +84,7 @@ class Stack { os::Handler* stack_handler_ = nullptr; legacy::Acl* acl_ = nullptr; Btm* btm_ = nullptr; - + size_t num_modules_{0}; void Start(ModuleList* modules); }; diff --git a/system/main/shim/utils.cc b/system/main/shim/utils.cc index 9f18ddc4f76ee49b2c50f9fd5e5b1f7c828cebea..c660ecd7142226100ac711acc85b66807384d8b0 100644 --- a/system/main/shim/utils.cc +++ b/system/main/shim/utils.cc @@ -14,8 +14,12 @@ * limitations under the License. */ +#define LOG_TAG "shim" + #include "utils.h" +#include "os/log.h" + namespace bluetooth { namespace shim { void parse_gap_data(const std::vector &raw_data, @@ -26,6 +30,7 @@ void parse_gap_data(const std::vector &raw_data, uint8_t len = raw_data[offset]; if (offset + len + 1 > raw_data.size()) { + LOG_WARN("GAP data out of bound"); break; } diff --git a/system/main/stack_config.cc b/system/main/stack_config.cc index 8c69d1348c7379364b5f6905bca9596c5943e9b1..4f0e86c6c5f0938b003eae73d847374bdeada9a4 100644 --- a/system/main/stack_config.cc +++ b/system/main/stack_config.cc @@ -22,8 +22,9 @@ #include +#include "include/check.h" +#include "os/log.h" #include "osi/include/future.h" -#include "osi/include/log.h" namespace { const char* PTS_AVRCP_TEST = "PTS_AvrcpTest"; diff --git a/system/main/test/main_shim_stack_lifecycle_test.cc b/system/main/test/main_shim_stack_lifecycle_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..39c9636a4ecab6ab66062709c8bb9efb4321261a --- /dev/null +++ b/system/main/test/main_shim_stack_lifecycle_test.cc @@ -0,0 +1,655 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "common/strings.h" +#include "gd/module_jniloop.h" +#include "gd/module_mainloop.h" +#include "main/shim/stack.h" +#include "module.h" +#include "os/thread.h" +#include "stack/include/main_thread.h" +#include "test/mock/mock_main_shim_entry.h" + +using ::testing::_; + +using namespace bluetooth; +using namespace testing; + +namespace { +constexpr int kSyncMainLoopTimeoutMs = 3000; +constexpr int kWaitUntilHandlerStoppedMs = 2000; +constexpr size_t kNumTestClients = 3; +constexpr size_t kNumTestModules = 3; +constexpr int kNumIters = 100; +constexpr int kAbruptStackShutdownIter = kNumIters * 3 / 4; +constexpr char kTestStackThreadName[] = "test_stack_thread"; +constexpr char kTestDataTag[] = "This is a test"; + +inline void maybe_yield() { + if (std::rand() & 1) std::this_thread::yield(); +} + +constexpr size_t kTagLength = 48 + sizeof(' ') + sizeof(' '); +inline void log_tag(std::string tag) { + std::string prepend(kTagLength / 2 - tag.size() / 2, '='); + std::string append(kTagLength / 2 - tag.size() / 2, '='); + log::info("{} {} {}", prepend, tag, append); +} + +class MainThread { + public: + MainThread() { main_thread_start_up(); } + + ~MainThread() { + sync_main_handler(); + main_thread_shut_down(); + } + + private: + void sync_main_handler() { + std::promise promise = std::promise(); + std::future future = promise.get_future(); + post_on_bt_main([&promise]() { promise.set_value(); }); + future.wait_for(std::chrono::milliseconds(kSyncMainLoopTimeoutMs)); + } +}; + +class TestStackManager { + public: + TestStackManager() { + // Start is executed by the test after each test adds the default + // or their own modules + } + + ~TestStackManager() { + log::debug("Deleting stack manager"); + Stop(); + } + + TestStackManager(const TestStackManager&) = delete; + + template + void AddModule() { + modules_.add(); + } + + void Start() { + if (stack_started_) return; + log::info("Started stack manager"); + stack_started_ = true; + bluetooth::os::Thread* stack_thread = new bluetooth::os::Thread( + kTestStackThreadName, bluetooth::os::Thread::Priority::NORMAL); + bluetooth::shim::Stack::GetInstance()->StartModuleStack(&modules_, + stack_thread); + } + + void Stop() { + if (!stack_started_) return; + stack_started_ = false; + bluetooth::shim::Stack::GetInstance()->Stop(); + } + + // NOTE: Stack manager *must* be active else method returns nullptr + // if stack manager has not started or shutdown + template + static T* GetUnsafeModule() { + return bluetooth::shim::Stack::GetInstance() + ->GetStackManager() + ->GetInstance(); + } + + size_t NumModules() const { return modules_.NumModules(); } + + private: + bluetooth::ModuleList modules_; + bool stack_started_{false}; +}; + +// Data returned via callback from a stack managed module +struct TestCallbackData { + int iter; + std::string tag; +}; + +// Data sent to a stack managed module via a module API +struct TestData { + int iter; + std::string tag; + std::function callback; +}; + +class TestStackModuleBase : public bluetooth::Module, + public ModuleMainloop, + public ModuleJniloop { + public: + TestStackModuleBase(const TestStackModuleBase&) = delete; + TestStackModuleBase& operator=(const TestStackModuleBase&) = delete; + + virtual ~TestStackModuleBase(){}; + static const ModuleFactory Factory; + + virtual void TestMethod(TestData test_data) const { + log::info("Test base class iter:{} tag:{}", test_data.iter, + test_data.tag.c_str()); + } + + protected: + void ListDependencies(ModuleList* list) const override{}; + void Start() override { log::error("Started TestStackModuleBase"); }; + void Stop() override { log::error("Stopped TestStackModuleBase"); }; + std::string ToString() const override { return std::string("TestFunction"); } + + TestStackModuleBase() = default; +}; + +class TestStackModule1 : public TestStackModuleBase { + public: + TestStackModule1(const TestStackModule1&) = delete; + TestStackModule1& operator=(const TestStackModule1&) = delete; + virtual ~TestStackModule1() = default; + + static const ModuleFactory Factory; + + void TestMethod(TestData test_data) const override; + + private: + struct impl; + std::shared_ptr impl_; + TestStackModule1(); +}; + +struct TestStackModule1::impl : public ModuleMainloop, public ModuleJniloop { + void test(TestData test_data) { + TestCallbackData callback_data{ + .iter = test_data.iter, + .tag = std::string(__func__), + }; + PostFunctionOnMain( + [](std::function callback, + TestCallbackData data) { callback(data); }, + test_data.callback, callback_data); + } +}; + +TestStackModule1::TestStackModule1() : TestStackModuleBase() { + impl_ = std::make_shared(); +} + +void TestStackModule1::TestMethod(TestData test_data) const { + PostMethodOnMain(impl_, &impl::test, test_data); +} + +class TestStackModule2 : public TestStackModuleBase { + public: + TestStackModule2(const TestStackModule2&) = delete; + TestStackModule2& operator=(const TestStackModule2&) = delete; + virtual ~TestStackModule2() = default; + + static const ModuleFactory Factory; + + void TestMethod(TestData test_data) const override; + + private: + struct impl; + std::shared_ptr impl_; + TestStackModule2(); +}; + +struct TestStackModule2::impl : public ModuleMainloop, public ModuleJniloop { + void test(TestData test_data) { + TestCallbackData callback_data{ + .iter = test_data.iter, + .tag = std::string(__func__), + }; + PostFunctionOnMain( + [](std::function callback, + TestCallbackData data) { callback(data); }, + test_data.callback, callback_data); + } +}; + +TestStackModule2::TestStackModule2() : TestStackModuleBase() { + impl_ = std::make_shared(); +} + +void TestStackModule2::TestMethod(TestData test_data) const { + PostMethodOnMain(impl_, &impl::test, test_data); +} + +class TestStackModule3 : public TestStackModuleBase { + public: + TestStackModule3(const TestStackModule3&) = delete; + TestStackModule3& operator=(const TestStackModule3&) = delete; + virtual ~TestStackModule3() = default; + + static const ModuleFactory Factory; + + void TestMethod(TestData test_data) const override; + + private: + struct impl; + std::shared_ptr impl_; + TestStackModule3(); +}; + +struct TestStackModule3::impl : public ModuleMainloop, public ModuleJniloop { + void test(TestData test_data) { + TestCallbackData callback_data{ + .iter = test_data.iter, + .tag = std::string(__func__), + }; + PostFunctionOnMain( + [](std::function callback, + TestCallbackData data) { callback(data); }, + test_data.callback, callback_data); + } +}; + +TestStackModule3::TestStackModule3() : TestStackModuleBase() { + impl_ = std::make_shared(); +} + +void TestStackModule3::TestMethod(TestData test_data) const { + PostMethodOnMain(impl_, &impl::test, test_data); +} + +class TestStackModule4 : public TestStackModuleBase { + public: + TestStackModule4(const TestStackModule4&) = delete; + TestStackModule4& operator=(const TestStackModule3&) = delete; + virtual ~TestStackModule4() = default; + + static const ModuleFactory Factory; + + void TestMethod(TestData test_data) const override { + log::info("mod:{} iter:{} tag:{}", __func__, test_data.iter, + test_data.tag.c_str()); + } + + private: + struct impl; + std::shared_ptr impl_; + TestStackModule4() : TestStackModuleBase() {} +}; + +struct TestStackModule4::impl : public ModuleMainloop, public ModuleJniloop {}; + +} // namespace + +const ModuleFactory TestStackModuleBase::Factory = + ModuleFactory([]() { return new TestStackModuleBase(); }); + +const ModuleFactory TestStackModule1::Factory = + ModuleFactory([]() { return new TestStackModule1(); }); +const ModuleFactory TestStackModule2::Factory = + ModuleFactory([]() { return new TestStackModule2(); }); +const ModuleFactory TestStackModule3::Factory = + ModuleFactory([]() { return new TestStackModule3(); }); +const ModuleFactory TestStackModule4::Factory = + ModuleFactory([]() { return new TestStackModule4(); }); + +class StackWithMainThreadUnitTest : public ::testing::Test { + protected: + void SetUp() override { main_thread_ = std::make_unique(); } + void TearDown() override { main_thread_.reset(); } + + private: + std::unique_ptr main_thread_; +}; + +class StackLifecycleUnitTest : public StackWithMainThreadUnitTest { + public: + std::shared_ptr StackManager() const { + return stack_manager_; + } + + protected: + void SetUp() override { + StackWithMainThreadUnitTest::SetUp(); + stack_manager_ = std::make_shared(); + } + + void TearDown() override { + stack_manager_.reset(); + StackWithMainThreadUnitTest::TearDown(); + } + + private: + std::shared_ptr stack_manager_; +}; + +TEST_F(StackLifecycleUnitTest, no_modules_in_stack) { + ASSERT_EQ(0U, StackManager()->NumModules()); +} + +class StackLifecycleWithDefaultModulesUnitTest : public StackLifecycleUnitTest { + protected: + void SetUp() override { + StackLifecycleUnitTest::SetUp(); + StackManager()->AddModule(); + StackManager()->AddModule(); + StackManager()->AddModule(); + StackManager()->Start(); + ASSERT_EQ(3U, StackManager()->NumModules()); + } + + void TearDown() override { StackLifecycleUnitTest::TearDown(); } +}; + +struct CallablePostCnt { + size_t success{0}; + size_t misses{0}; + CallablePostCnt operator+=(const CallablePostCnt& post_cnt) { + return CallablePostCnt( + {success += post_cnt.success, misses += post_cnt.misses}); + } +}; + +// Provide a client user of the stack manager module services +class Client { + public: + Client(int id) : id_(id) {} + Client(const Client&) = default; + virtual ~Client() = default; + + // Start up the client a thread and handler + void Start() { + log::info("Started client {}", id_); + thread_ = new os::Thread(common::StringFormat("ClientThread%d", id_), + os::Thread::Priority::NORMAL); + handler_ = new os::Handler(thread_); + handler_->Post(common::BindOnce( + [](int id) { log::info("Started client {}", id); }, id_)); + } + + // Ensure all the client handlers are running + void Await() { + std::promise promise; + std::future future = promise.get_future(); + handler_->Post( + base::BindOnce([](std::promise promise) { promise.set_value(); }, + std::move(promise))); + future.wait(); + } + + // Post a work task on behalf of this client + void Post(common::OnceClosure closure) { + if (quiesced_) { + post_cnt_.misses++; + maybe_yield(); + } else { + post_cnt_.success++; + handler_->Post(std::move(closure)); + maybe_yield(); + } + } + + // Safely prevent new work tasks from being posted + void Quiesce() { + if (quiesced_) return; + quiesced_ = true; + std::promise promise = std::promise(); + std::future future = promise.get_future(); + handler_->Post(common::BindOnce( + [](std::promise promise) { promise.set_value(); }, + std::move(promise))); + future.wait_for(std::chrono::milliseconds(kSyncMainLoopTimeoutMs)); + } + + // Stops the client and associated resources + void Stop() { + if (!quiesced_) { + Quiesce(); + } + handler_->Clear(); + handler_->WaitUntilStopped( + std::chrono::milliseconds(kWaitUntilHandlerStoppedMs)); + delete handler_; + delete thread_; + } + + int Id() const { return id_; } + + CallablePostCnt GetCallablePostCnt() const { return post_cnt_; } + + std::string Name() const { + return common::StringFormat("%s%d", __func__, id_); + } + + private: + int id_{0}; + CallablePostCnt post_cnt_{}; + bool quiesced_{false}; + os::Handler* handler_{nullptr}; + os::Thread* thread_{nullptr}; +}; + +// Convenience object to handle multiple clients with logging +class ClientGroup { + public: + ClientGroup(){}; + + void Start() { + for (auto& c : clients_) { + c->Start(); + } + log_tag("STARTING"); + } + + void Await() { + for (auto& c : clients_) { + c->Await(); + } + log_tag("STARTED"); + } + + void Quiesce() { + log_tag("QUIESCING"); + for (auto& c : clients_) { + c->Quiesce(); + } + log_tag("QUIESCED"); + } + + void Stop() { + for (auto& c : clients_) { + c->Stop(); + } + log_tag("STOPPED"); + } + + void Dump() const { + for (auto& c : clients_) { + log::info("Callable post cnt client_id:{} success:{} misses:{}", c->Id(), + c->GetCallablePostCnt().success, + c->GetCallablePostCnt().misses); + } + } + + CallablePostCnt GetCallablePostCnt() const { + CallablePostCnt post_cnt{}; + for (auto& c : clients_) { + post_cnt += c->GetCallablePostCnt(); + } + return post_cnt; + } + + size_t NumClients() const { return kNumTestClients; } + + std::unique_ptr clients_[kNumTestClients] = { + std::make_unique(1), std::make_unique(2), + std::make_unique(3)}; +}; + +TEST_F(StackLifecycleWithDefaultModulesUnitTest, clients_start) { + ClientGroup client_group; + + client_group.Start(); + client_group.Await(); + + // Clients are operational + + client_group.Quiesce(); + client_group.Stop(); +} + +TEST_F(StackLifecycleWithDefaultModulesUnitTest, client_using_stack_manager) { + ClientGroup client_group; + client_group.Start(); + client_group.Await(); + + for (int i = 0; i < kNumIters; i++) { + for (auto& c : client_group.clients_) { + c->Post(base::BindOnce( + [](int id, int iter, + std::shared_ptr stack_manager) { + stack_manager->GetUnsafeModule()->TestMethod({ + .iter = iter, + .tag = std::string(kTestDataTag), + .callback = [](TestCallbackData data) {}, + }); + }, + c->Id(), i, StackManager())); + c->Post(base::BindOnce( + [](int id, int iter, + std::shared_ptr stack_manager) { + stack_manager->GetUnsafeModule()->TestMethod({ + .iter = iter, + .tag = std::string(kTestDataTag), + .callback = [](TestCallbackData data) {}, + }); + }, + c->Id(), i, StackManager())); + c->Post(base::BindOnce( + [](int id, int iter, + std::shared_ptr stack_manager) { + stack_manager->GetUnsafeModule()->TestMethod({ + .iter = iter, + .tag = std::string(kTestDataTag), + .callback = [](TestCallbackData data) {}, + }); + }, + c->Id(), i, StackManager())); + } + } + + client_group.Quiesce(); + client_group.Stop(); + client_group.Dump(); + + ASSERT_EQ(client_group.NumClients() * kNumIters * kNumTestModules, + client_group.GetCallablePostCnt().success + + client_group.GetCallablePostCnt().misses); +} + +TEST_F(StackLifecycleWithDefaultModulesUnitTest, + client_using_stack_manager_when_shutdown) { + struct Counters { + struct { + std::atomic_size_t cnt{0}; + } up, down; + } counters; + + ClientGroup client_group; + client_group.Start(); + client_group.Await(); + + for (int i = 0; i < kNumIters; i++) { + for (auto& c : client_group.clients_) { + c->Post(base::BindOnce( + [](int id, int iter, Counters* counters, + std::shared_ptr stack_manager) { + TestData test_data = { + .iter = iter, + .tag = std::string(kTestDataTag), + .callback = [](TestCallbackData data) {}, + }; + if (bluetooth::shim::Stack::GetInstance() + ->CallOnModule( + [test_data](TestStackModule1* mod) { + mod->TestMethod(test_data); + })) { + counters->up.cnt++; + } else { + counters->down.cnt++; + } + }, + c->Id(), i, &counters, StackManager())); + c->Post(base::BindOnce( + [](int id, int iter, Counters* counters, + std::shared_ptr stack_manager) { + TestData test_data = { + .iter = iter, + .tag = std::string(kTestDataTag), + .callback = [](TestCallbackData data) {}, + }; + if (bluetooth::shim::Stack::GetInstance() + ->CallOnModule( + [test_data](TestStackModule2* mod) { + mod->TestMethod(test_data); + })) { + counters->up.cnt++; + } else { + counters->down.cnt++; + } + }, + c->Id(), i, &counters, StackManager())); + c->Post(base::BindOnce( + [](int id, int iter, Counters* counters, + std::shared_ptr stack_manager) { + TestData test_data = { + .iter = iter, + .tag = std::string(kTestDataTag), + .callback = [](TestCallbackData data) {}, + }; + if (bluetooth::shim::Stack::GetInstance() + ->CallOnModule( + [test_data](TestStackModule3* mod) { + mod->TestMethod(test_data); + })) { + counters->up.cnt++; + } else { + counters->down.cnt++; + } + }, + c->Id(), i, &counters, StackManager())); + } + // Abruptly shutdown stack at some point through the iterations + if (i == kAbruptStackShutdownIter) { + log_tag("SHUTTING DOWN STACK"); + StackManager()->Stop(); + } + } + + client_group.Quiesce(); + client_group.Stop(); + log::info("Execution stack availability counters up:{} down:{}", + counters.up.cnt, counters.down.cnt); + + ASSERT_EQ(client_group.NumClients() * kNumIters * kNumTestModules, + client_group.GetCallablePostCnt().success + + client_group.GetCallablePostCnt().misses); +} diff --git a/system/main/test/main_shim_test.cc b/system/main/test/main_shim_test.cc index a0bcbc3a150be055a39e9a24af4ef2d946aafbaf..9122d1ace8ab632a362a70fe4dbd7e6fd5c24f36 100644 --- a/system/main/test/main_shim_test.cc +++ b/system/main/test/main_shim_test.cc @@ -40,7 +40,7 @@ #include "hci/acl_manager_mock.h" #include "hci/address.h" #include "hci/address_with_type.h" -#include "hci/controller_mock.h" +#include "hci/controller_interface_mock.h" #include "hci/distance_measurement_manager_mock.h" #include "hci/le_advertising_manager_mock.h" #include "hci/le_scanning_manager_mock.h" @@ -65,7 +65,6 @@ #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" #include "stack/include/hci_error_code.h" -#include "stack/include/sco_hci_link_interface.h" #include "stack/include/sec_hci_link_interface.h" #include "stack/l2cap/l2c_int.h" #include "test/common/jni_thread.h" @@ -184,10 +183,6 @@ const shim::legacy::acl_interface_t GetMockAclInterface() { .connection.le.on_failed = mock_connection_le_on_failed, .connection.le.on_disconnected = mock_connection_le_on_disconnected, - .connection.sco.on_esco_connect_request = nullptr, - .connection.sco.on_sco_connect_request = nullptr, - .connection.sco.on_disconnected = nullptr, - .link.classic.on_authentication_complete = nullptr, .link.classic.on_central_link_key_complete = nullptr, .link.classic.on_change_connection_link_key_complete = nullptr, @@ -224,7 +219,6 @@ const shim::legacy::acl_interface_t GetMockAclInterface() { struct hci_packet_parser_t; const hci_packet_parser_t* hci_packet_parser_get_interface() { return nullptr; } struct hci_t; -const hci_t* hci_layer_get_interface() { return nullptr; } struct packet_fragmenter_t; const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; } @@ -373,7 +367,7 @@ class MainShimTest : public testing::Test { handler_ = new os::Handler(thread_); /* extern */ test::mock_controller_ = - new bluetooth::hci::testing::MockController(); + new bluetooth::hci::testing::MockControllerInterface(); /* extern */ test::mock_acl_manager_ = new bluetooth::hci::testing::MockAclManager(); /* extern */ test::mock_le_scanning_manager_ = @@ -413,8 +407,6 @@ class MainShimTest : public testing::Test { EXPECT_CALL(*test::mock_controller_, RegisterCompletedMonitorAclPacketsCallback(_)) .Times(1); - EXPECT_CALL(*test::mock_acl_manager_, HACK_SetNonAclDisconnectCallback(_)) - .Times(1); EXPECT_CALL(*test::mock_controller_, UnregisterCompletedMonitorAclPacketsCallback) .Times(1); diff --git a/system/osi/Android.bp b/system/osi/Android.bp index 01ff6c3bb6f889bb4d2b75962d7e0fd65637d524..beef0f61aae70b09aa5f899da8e47d44a3967bea 100644 --- a/system/osi/Android.bp +++ b/system/osi/Android.bp @@ -14,7 +14,6 @@ cc_defaults { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ], } @@ -93,6 +92,7 @@ cc_library_static { ], header_libs: ["libbluetooth_headers"], static_libs: [ + "libbluetooth_log", "libbt-platform-protos-lite", "libbt_shim_bridge", ], @@ -140,6 +140,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", diff --git a/system/osi/BUILD.gn b/system/osi/BUILD.gn index 730c1edca253119f1b56d52660591adaeb3dd880..0fc06716706a504a60479a5c48c11215ed7dabb7 100644 --- a/system/osi/BUILD.gn +++ b/system/osi/BUILD.gn @@ -45,7 +45,6 @@ static_library("osi") { include_dirs = [ "//bt/system/", - "//bt/system/internal_include", "//bt/system/linux_include", "//bt/system/osi/include_internal", "//bt/system/stack/include", @@ -62,6 +61,7 @@ static_library("osi") { configs += [ "//bt/system:target_defaults", + "//bt/system/log:log_defaults", ] } diff --git a/system/osi/include/log.h b/system/osi/include/log.h deleted file mode 100644 index 5aeb316f45296674b9f969cc0c9630d3ad7191fa..0000000000000000000000000000000000000000 --- a/system/osi/include/log.h +++ /dev/null @@ -1,29 +0,0 @@ -/****************************************************************************** - * - * Copyright 2014 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. - * - ******************************************************************************/ - -#pragma once - -#include "gd/common/init_flags.h" - -#ifndef OSI_INCLUDE_LOG_H -#define OSI_INCLUDE_LOG_H -#endif - -#include "gd/os/log.h" - -#undef OSI_INCLUDE_LOG_H \ No newline at end of file diff --git a/system/osi/src/future.cc b/system/osi/src/future.cc index fe97b9c393f8346229992bd80d9feec79fb7a724..ece49c7a054f3c27c0e12aaa999c27425dba9193 100644 --- a/system/osi/src/future.cc +++ b/system/osi/src/future.cc @@ -23,8 +23,8 @@ #include #include "check.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "osi/include/osi.h" #include "osi/semaphore.h" diff --git a/system/osi/src/properties.cc b/system/osi/src/properties.cc index 5bdddf9743d777cf610d4e9a3836168756a287ea..000cccd0c644592fabffba84127b63a035168076 100644 --- a/system/osi/src/properties.cc +++ b/system/osi/src/properties.cc @@ -24,7 +24,7 @@ #include #include -#include "gd/os/system_properties.h" +#include "os/system_properties.h" #ifdef __ANDROID__ #undef PROPERTY_VALUE_MAX diff --git a/system/osi/src/reactor.cc b/system/osi/src/reactor.cc index e16334e1520d4eacc6f5bc3bdb38330ab6eefc48..d6f5784642c718649d5c9231516b70d8e4b34ba0 100644 --- a/system/osi/src/reactor.cc +++ b/system/osi/src/reactor.cc @@ -115,6 +115,7 @@ void reactor_free(reactor_t* reactor) { list_free(reactor->invalidation_list); close(reactor->event_fd); close(reactor->epoll_fd); + delete reactor->list_mutex; osi_free(reactor); } diff --git a/system/osi/test/alarm_test.cc b/system/osi/test/alarm_test.cc index f0e4d71da71ec360e86987ddfa4632185445c3ea..f6ec1454722a111c935621d27ff4edbbcb47be12 100644 --- a/system/osi/test/alarm_test.cc +++ b/system/osi/test/alarm_test.cc @@ -29,7 +29,6 @@ #include "osi/semaphore.h" using base::Closure; -using base::TimeDelta; using bluetooth::common::MessageLoopThread; static semaphore_t* semaphore; diff --git a/system/osi/test/future_test.cc b/system/osi/test/future_test.cc index 8babd591b967126135016f3659cc2723b4b54df4..be17511b8d472c92b25201212d3da0daff7e6993 100644 --- a/system/osi/test/future_test.cc +++ b/system/osi/test/future_test.cc @@ -41,7 +41,7 @@ TEST_F(FutureTest, test_future_non_immediate) { MessageLoopThread worker_thread("worker_thread"); worker_thread.StartUp(); - worker_thread.DoInThread(FROM_HERE, base::Bind(post_to_future, future)); + worker_thread.DoInThread(FROM_HERE, base::BindOnce(post_to_future, future)); EXPECT_EQ(pass_back_data0, future_await(future)); diff --git a/system/osi/test/fuzzers/alarm/fuzz_alarm.cc b/system/osi/test/fuzzers/alarm/fuzz_alarm.cc index de3054e6f527d580f3e14a00142e355abd2c6404..99ddd768ed98deddde27a6fa648a73eb1400ade0 100644 --- a/system/osi/test/fuzzers/alarm/fuzz_alarm.cc +++ b/system/osi/test/fuzzers/alarm/fuzz_alarm.cc @@ -21,7 +21,6 @@ #include "common/message_loop_thread.h" using base::Closure; -using base::TimeDelta; using bluetooth::common::MessageLoopThread; #define MAX_CONCURRENT_ALARMS 25 diff --git a/system/osi/test/internal/semaphore_test.cc b/system/osi/test/internal/semaphore_test.cc index a54d1e22f688665d32f96fd32fdeac280272b982..e2e031bccb24e8386cf36e37d1dc32753fa14efb 100644 --- a/system/osi/test/internal/semaphore_test.cc +++ b/system/osi/test/internal/semaphore_test.cc @@ -6,6 +6,7 @@ #include #include "common/message_loop_thread.h" +#include "include/check.h" #include "osi/include/osi.h" #include "osi/include/reactor.h" @@ -77,8 +78,8 @@ TEST_F(SemaphoreTest, test_ensure_wait) { EXPECT_FALSE(semaphore_try_wait(semaphore)); SemaphoreTestSequenceHelper sequence_helper = {semaphore, 0}; - thread.DoInThread(FROM_HERE, - base::Bind(sleep_then_increment_counter, &sequence_helper)); + thread.DoInThread(FROM_HERE, base::BindOnce(sleep_then_increment_counter, + &sequence_helper)); semaphore_wait(semaphore); EXPECT_EQ(sequence_helper.counter, 1) << "semaphore_wait() did not wait for counter to increment"; diff --git a/system/packet/Android.bp b/system/packet/Android.bp index 6fa932d7b74ce2773cc4123901b0eb423c87cb8e..1e3f9c44b9ef5b43e6525edfb0f967adc2507c36 100644 --- a/system/packet/Android.bp +++ b/system/packet/Android.bp @@ -78,11 +78,11 @@ cc_test { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], target: { diff --git a/system/packet/BUILD.gn b/system/packet/BUILD.gn index 5a1145656f284f8a9e6dbc1310e5ee45577d2410..a6f8f2560c4b92902fe714799064db5e59b2f250 100644 --- a/system/packet/BUILD.gn +++ b/system/packet/BUILD.gn @@ -18,12 +18,14 @@ config("packet_config") { include_dirs = [ "//bt/system/", "//bt/system/include", - "//bt/system/internal_include", "//bt/system/stack/include", "//bt/system/profile/avrcp", ] - configs = [ "//bt/system:target_defaults" ] + configs = [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] } static_library("packet") { diff --git a/system/packet/avrcp/Android.bp b/system/packet/avrcp/Android.bp index 4e3190811ea64e0fc6ab220777789f28e2f50a36..180811207265126a9967ecdd56a3a214c2392a11 100644 --- a/system/packet/avrcp/Android.bp +++ b/system/packet/avrcp/Android.bp @@ -45,6 +45,7 @@ cc_library_static { ], static_libs: [ "lib-bt-packets-base", + "libbluetooth_log", "libchrome", ], apex_available: [ diff --git a/system/packet/avrcp/avrcp_browse_packet.cc b/system/packet/avrcp/avrcp_browse_packet.cc index 07b5485997174f09b35f796d8f9246d0b197f930..fedd52a3aab0ff8ad5b362194ac127fbbc210a27 100644 --- a/system/packet/avrcp/avrcp_browse_packet.cc +++ b/system/packet/avrcp/avrcp_browse_packet.cc @@ -18,6 +18,8 @@ #include +#include "internal_include/bt_trace.h" + namespace bluetooth { namespace avrcp { diff --git a/system/packet/avrcp/capabilities_packet.cc b/system/packet/avrcp/capabilities_packet.cc index 459b47d7b5bcb59f38668d4c5b57069ae706ac84..6c5c675655e8c871fce44b090d00fb68db1f61f3 100644 --- a/system/packet/avrcp/capabilities_packet.cc +++ b/system/packet/avrcp/capabilities_packet.cc @@ -16,6 +16,8 @@ #include "capabilities_packet.h" +#include "internal_include/bt_trace.h" + namespace bluetooth { namespace avrcp { @@ -149,4 +151,4 @@ bool GetCapabilitiesResponseBuilder::Serialize( } } // namespace avrcp -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/packet/avrcp/get_element_attributes_packet.h b/system/packet/avrcp/get_element_attributes_packet.h index b1d4c61d59a6256004a8e79111d06a671c02b36f..9d816732528f1ab3f06cb9397562b80cf1bee5e1 100644 --- a/system/packet/avrcp/get_element_attributes_packet.h +++ b/system/packet/avrcp/get_element_attributes_packet.h @@ -17,6 +17,8 @@ #pragma once #include +#include + #include "vendor_packet.h" namespace bluetooth { diff --git a/system/packet/avrcp/get_folder_items.cc b/system/packet/avrcp/get_folder_items.cc index 4e6e3a17237949d6cf6e5c6e3163c0ed043cbe15..af0c6b3b6dd3d176cfbec1ae89b149f244b3e38b 100644 --- a/system/packet/avrcp/get_folder_items.cc +++ b/system/packet/avrcp/get_folder_items.cc @@ -16,6 +16,9 @@ #include "get_folder_items.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" + namespace bluetooth { namespace avrcp { diff --git a/system/packet/avrcp/get_item_attributes.cc b/system/packet/avrcp/get_item_attributes.cc index 0c7afe4f8a7ffe74beee555df6549532b5e3355f..7401a24b9f49788a904cfdd63eecdeb9f40a6995 100644 --- a/system/packet/avrcp/get_item_attributes.cc +++ b/system/packet/avrcp/get_item_attributes.cc @@ -16,6 +16,8 @@ #include "get_item_attributes.h" +#include "include/check.h" + namespace bluetooth { namespace avrcp { diff --git a/system/packet/avrcp/get_item_attributes.h b/system/packet/avrcp/get_item_attributes.h index 781190911bd682cd57ca6266f59070a6411a8e30..70aac1e88650070f501676ed976f9c99d1a623ac 100644 --- a/system/packet/avrcp/get_item_attributes.h +++ b/system/packet/avrcp/get_item_attributes.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include "avrcp_browse_packet.h" diff --git a/system/packet/avrcp/register_notification_packet.cc b/system/packet/avrcp/register_notification_packet.cc index 94194d5f3e1f96374c246f74fd4289fe47a29587..0ba8374d954d7abe21ec9f7ae45779b88d37bba1 100644 --- a/system/packet/avrcp/register_notification_packet.cc +++ b/system/packet/avrcp/register_notification_packet.cc @@ -14,9 +14,12 @@ * limitations under the License. */ +#include "register_notification_packet.h" + #include -#include "register_notification_packet.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" namespace bluetooth { namespace avrcp { diff --git a/system/packet/avrcp/set_browsed_player.cc b/system/packet/avrcp/set_browsed_player.cc index fa0c76842887be6dea997d1f2f87f0ce6992126c..85795a2fa94d567d2586899212bdeb1906f59439 100644 --- a/system/packet/avrcp/set_browsed_player.cc +++ b/system/packet/avrcp/set_browsed_player.cc @@ -16,6 +16,8 @@ #include "set_browsed_player.h" +#include "internal_include/bt_trace.h" + namespace bluetooth { namespace avrcp { diff --git a/system/packet/avrcp/vendor_packet.cc b/system/packet/avrcp/vendor_packet.cc index 4525cfbd9ac586d49d2c26f4ae3802254a60d6fd..83ccd1fdc5669016313a84c0ea980cb05b76be95 100644 --- a/system/packet/avrcp/vendor_packet.cc +++ b/system/packet/avrcp/vendor_packet.cc @@ -16,6 +16,8 @@ #include "vendor_packet.h" +#include "internal_include/bt_trace.h" + namespace bluetooth { namespace avrcp { diff --git a/system/packet/tests/base/packet_test_common.h b/system/packet/tests/base/packet_test_common.h index 26302effa7928996f745e6263c026dbce734ba0e..a74735d7fb28f57981b863dc0d09ea4eb9baf9ce 100644 --- a/system/packet/tests/base/packet_test_common.h +++ b/system/packet/tests/base/packet_test_common.h @@ -16,7 +16,9 @@ #pragma once -#include "packet.h" +#include +#include + #include "packet_test_helper.h" // We have our own definition of loghex to avoid dependencies @@ -93,4 +95,4 @@ class TestPacketBuilder : public PacketBuilder { std::vector data_; }; -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/packet/tests/fuzzers/Android.bp b/system/packet/tests/fuzzers/Android.bp index ed273405415b5d4bd3803cc3de4910234991913c..a617b4875194ca63a841ac80289d9b7a843f7d85 100644 --- a/system/packet/tests/fuzzers/Android.bp +++ b/system/packet/tests/fuzzers/Android.bp @@ -32,11 +32,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -68,11 +68,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -104,11 +104,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -140,11 +140,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -176,11 +176,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -212,11 +212,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -248,11 +248,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -284,11 +284,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -320,11 +320,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -356,11 +356,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -392,11 +392,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -428,11 +428,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -464,11 +464,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -500,11 +500,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -536,11 +536,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -572,11 +572,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -608,11 +608,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -644,11 +644,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -680,11 +680,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -716,11 +716,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -752,11 +752,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -788,11 +788,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -824,11 +824,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -860,11 +860,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], @@ -896,11 +896,11 @@ cc_fuzz { "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", + "libbluetooth_log", "libchrome", "libgmock", ], cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], shared_libs: ["liblog"], diff --git a/system/packet/tests/test_packets.h b/system/packet/tests/test_packets.h index 0e0db42167ee1127f441f125ace3f76edb4e1aa9..c7628cfa21bc522ad20719049f79fc87ef0aa43d 100644 --- a/system/packet/tests/test_packets.h +++ b/system/packet/tests/test_packets.h @@ -1,5 +1,23 @@ +/* + * Copyright 2023 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 + namespace { // L2CAP packet pulled from Wireshark @@ -47,4 +65,4 @@ std::vector test_avrcp_data = { 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6a, 0x00, 0x06, 0x34, 0x37, 0x33, 0x30, 0x30, 0x30}; -} // namespace \ No newline at end of file +} // namespace diff --git a/system/pdl/hci/hci_packets.pdl b/system/pdl/hci/hci_packets.pdl index 53193d45d09274d5dcb65a95e81c0bf3455fafd5..212cd2910b0f3e6723e73025eea22d4ebbc4e4cd 100644 --- a/system/pdl/hci/hci_packets.pdl +++ b/system/pdl/hci/hci_packets.pdl @@ -456,6 +456,7 @@ enum OpCode : 16 { CONTROLLER_DEBUG_INFO = 0xFD5B, CONTROLLER_A2DP_OPCODE = 0xFD5D, CONTROLLER_BQR = 0xFD5E, + DYNAMIC_AUDIO_BUFFER = 0xFD5F, // MSFT_OPCODE_xxxx below are needed for the tests. MSFT_OPCODE_MEDIATEK = 0xFD30, MSFT_OPCODE_QUALCOMM = 0xFD70, @@ -5311,7 +5312,22 @@ packet LeGetVendorCapabilitiesComplete096 : LeGetVendorCapabilitiesComplete095 { packet LeGetVendorCapabilitiesComplete098 : LeGetVendorCapabilitiesComplete096 { a2dp_source_offload_capability_mask: 32, - bluetooth_quality_report_support: 8 + bluetooth_quality_report_support: 8, + _payload_, +} + +packet LeGetVendorCapabilitiesComplete103 : LeGetVendorCapabilitiesComplete098 { + dynamic_audio_buffer_support : 32, + _payload_, +} + +test LeGetVendorCapabilitiesComplete103 { + "\x0e\x1c\x01\x53\xfd\x00\x10\x01\x00\x28\x00\x01\x3e\x01\x03\x01\x14\x00\x01\x01\x00\x23\x00\x00\x00\x01\x23\x00\x00\x00", +} + +packet LeGetVendorCapabilitiesComplete104 : LeGetVendorCapabilitiesComplete103 { + a2dp_offload_v2_support : 8, + _payload_, } enum SubOcf : 8 { @@ -5761,7 +5777,7 @@ enum BqrReportAction : 8 { CLEAR = 0x02, } -packet ControllerBqr : VendorCommand(op_code = CONTROLLER_BQR) { +packet ControllerBqr : VendorCommand (op_code = CONTROLLER_BQR) { bqr_report_action : BqrReportAction, bqr_quality_event_mask : 32, bqr_minimum_report_interval : 16, @@ -5780,6 +5796,60 @@ test ControllerBqrComplete { "\x0e\x08\x01\x5e\xfd\x00\x1f\x00\x07\x00", } +enum DabCommand : 8 { + GET_AUDIO_BUFFER_TIME_CAPABILITY = 0x01, + SET_AUDIO_BUFFER_TIME = 0x02, +} + +packet DynamicAudioBuffer : VendorCommand (op_code = DYNAMIC_AUDIO_BUFFER) { + dab_command : DabCommand, + _body_, +} + +packet DynamicAudioBufferComplete : CommandComplete (command_op_code = DYNAMIC_AUDIO_BUFFER) { + status : ErrorCode, + dab_command : DabCommand, + _body_, +} + +packet DabGetAudioBufferTimeCapability : DynamicAudioBuffer (dab_command = GET_AUDIO_BUFFER_TIME_CAPABILITY) { +} + +test DabGetAudioBufferTimeCapability { + "\x5f\xfd\x01\x01", +} + +struct DynamicAudioBufferCodecCapability { + default_time_ms : 16, + maximum_time_ms : 16, + minimum_time_ms : 16, +} + +packet DabGetAudioBufferTimeCapabilityComplete : DynamicAudioBufferComplete (dab_command = GET_AUDIO_BUFFER_TIME_CAPABILITY) { + audio_codec_type_supported : 32, + audio_codec_capabilities : DynamicAudioBufferCodecCapability[32], +} + +test DabGetAudioBufferTimeCapabilityComplete { + "\x0e\xc9\x01\x5f\xfd\x00\x01\x03\x00\x00\x00\xf4\x01\xf4\x01\x64\x00\xf4\x01\xf4\x01\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", +} + +packet DabSetAudioBufferTime : DynamicAudioBuffer(dab_command = SET_AUDIO_BUFFER_TIME) { + buffer_time_ms : 16, // Requested audio buffer time for the currently used codec. +} + +test DabSetAudioBufferTime { + "\x5f\xfd\x03\x02\x23\x01", +} + +packet DabSetAudioBufferTimeComplete : DynamicAudioBufferComplete (dab_command = SET_AUDIO_BUFFER_TIME) { + current_buffer_time_ms : 16, +} + +test DabSetAudioBufferTimeComplete { + "\x0e\x07\x01\x5f\xfd\x00\x02\x23\x01", +} + // HCI Event Packets packet InquiryComplete : Event (event_code = INQUIRY_COMPLETE) { @@ -6778,6 +6848,32 @@ packet LeCsProcedureEnableComplete : LeMetaEvent (subevent_code = LE_CS_PROCEDUR procedure_count : 16, } +struct LeCsMode0InitatorData { + packet_quality : 8, + packet_rssi : 8, + packet_antenna : 8, + measured_freq_offset : 15, + _reserved_ : 1, +} + +struct LeCsMode0ReflectorData { + packet_quality : 8, + packet_rssi : 8, + packet_antenna : 8, +} + +struct LeCsToneDataWithQuality { + i_sample : 12, + q_sample : 12, + tone_quality_indicator : 8, +} + +struct LeCsMode2Data { + _count_(tone_data) : 8, + antenna_permutation_index : 8, + tone_data : LeCsToneDataWithQuality[], +} + enum CsProcedureDoneStatus : 4 { ALL_RESULTS_COMPLETE = 0x0, PARTIAL_RESULTS = 0x1, diff --git a/system/profile/avrcp/Android.bp b/system/profile/avrcp/Android.bp index 34e3d1df48f5a267fb0bcc6bb54e9bd5cf4ca0a3..fa7012701e51b35494e0e5120f142f2d45b1f1b0 100644 --- a/system/profile/avrcp/Android.bp +++ b/system/profile/avrcp/Android.bp @@ -16,7 +16,6 @@ cc_library_static { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ], export_include_dirs: ["./"], @@ -27,6 +26,7 @@ cc_library_static { static_libs: [ "lib-bt-packets", "libbluetooth-types", + "libbluetooth_log", "libbt_shim_bridge", "libosi", ], @@ -58,7 +58,6 @@ cc_test { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ], srcs: [ @@ -73,6 +72,7 @@ cc_test { "libbase", "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt_shim_bridge", "libbt_shim_ffi", "libbtdevice", @@ -88,7 +88,6 @@ cc_test { }, cflags: [ - "-DBUILDCFG", "-Wno-unused-parameter", ], header_libs: ["libbluetooth_headers"], @@ -106,7 +105,6 @@ cc_fuzz { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/packet/tests", "packages/modules/Bluetooth/system/stack/include", ], @@ -118,6 +116,7 @@ cc_fuzz { "libbase", "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", diff --git a/system/profile/avrcp/BUILD.gn b/system/profile/avrcp/BUILD.gn index 4341af7d388329372065b0598c3bd204afe1f6f8..788c60e003f72643189b0e9e288f429ef8d5fe5e 100644 --- a/system/profile/avrcp/BUILD.gn +++ b/system/profile/avrcp/BUILD.gn @@ -17,7 +17,6 @@ config("avrcp_config") { include_dirs = [ "//bt/system/", - "//bt/system/internal_include", "//bt/system/stack/include", "//bt/system/profile/avrcp", "//bt/system/packet", @@ -25,7 +24,10 @@ config("avrcp_config") { "//bt/system/include/hardware/avrcp", ] - configs = ["//bt/system:target_defaults"] + configs = [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] } static_library("profile_avrcp") { diff --git a/system/profile/avrcp/avrcp_message_converter.h b/system/profile/avrcp/avrcp_message_converter.h index 0b47f9610fe022be64b121f331485d1bc8f2f4ac..db6dd4946c97a25681ca3ed5b220eaf729da1f28 100644 --- a/system/profile/avrcp/avrcp_message_converter.h +++ b/system/profile/avrcp/avrcp_message_converter.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include @@ -98,7 +100,7 @@ class AvrcpMessageConverter { } } break; default: - LOG(ERROR) << "Unknown opcode for AVRCP message"; + bluetooth::log::error("Unknown opcode for AVRCP message"); break; } diff --git a/system/profile/avrcp/connection_handler.cc b/system/profile/avrcp/connection_handler.cc index 4f2e4a97a2cca1c89bb83907a82bb305230f8954..9881e9e6e404d3e813db70caaa08d9e3ffe56754 100644 --- a/system/profile/avrcp/connection_handler.cc +++ b/system/profile/avrcp/connection_handler.cc @@ -14,24 +14,25 @@ * limitations under the License. */ +#define LOG_TAG "avrcp" + #include "connection_handler.h" #include -#include +#include #include #include #include "avrc_defs.h" #include "avrcp_message_converter.h" -#include "internal_include/bt_target.h" -#include "packet/avrcp/avrcp_packet.h" -// TODO (apanicke): Remove dependency on this header once we cleanup feature -// handling. #include "bta/include/bta_av_api.h" #include "device/include/interop.h" +#include "include/check.h" +#include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "osi/include/properties.h" +#include "packet/avrcp/avrcp_packet.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_uuid16.h" #include "types/raw_address.h" @@ -62,11 +63,11 @@ bool IsAbsoluteVolumeEnabled(const RawAddress* bdaddr) { char volume_disabled[PROPERTY_VALUE_MAX] = {0}; osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false"); if (strncmp(volume_disabled, "true", 4) == 0) { - LOG(INFO) << "Absolute volume disabled by property"; + log::info("Absolute volume disabled by property"); return false; } if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, bdaddr)) { - LOG(INFO) << "Absolute volume disabled by IOP table"; + log::info("Absolute volume disabled by IOP table"); return false; } return true; @@ -125,13 +126,13 @@ void ConnectionHandler::InitForTesting(ConnectionHandler* handler) { } bool ConnectionHandler::ConnectDevice(const RawAddress& bdaddr) { - LOG(INFO) << "Attempting to connect to device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr); + log::info("Attempting to connect to device {}", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); for (const auto& pair : device_map_) { if (bdaddr == pair.second->GetAddress()) { - LOG(WARNING) << "Already connected to device with address " - << ADDRESS_TO_LOGGABLE_STR(bdaddr); + log::warn("Already connected to device with address {}", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); return false; } } @@ -139,12 +140,11 @@ bool ConnectionHandler::ConnectDevice(const RawAddress& bdaddr) { auto connection_lambda = [](ConnectionHandler* instance_, const RawAddress& bdaddr, uint16_t status, uint16_t version, uint16_t features) { - LOG(INFO) << __PRETTY_FUNCTION__ - << " SDP Completed features=" << loghex(features); + log::info("SDP Completed features={}", loghex(features)); if (status != AVRC_SUCCESS || !(features & BTA_AV_FEAT_RCCT)) { - LOG(ERROR) << "Failed to do SDP: status=" << loghex(status) - << " features=" << loghex(features) - << " supports controller: " << (features & BTA_AV_FEAT_RCCT); + log::error( + "Failed to do SDP: status={} features={} supports controller: {}", + loghex(status), loghex(features), (features & BTA_AV_FEAT_RCCT)); instance_->connection_cb_.Run(std::shared_ptr()); } @@ -189,7 +189,7 @@ std::vector> ConnectionHandler::GetListOfDevices() bool ConnectionHandler::SdpLookup(const RawAddress& bdaddr, SdpCallback cb, bool retry) { - LOG(INFO) << __PRETTY_FUNCTION__; + log::info(""); tAVRC_SDP_DB_PARAMS db_params; // TODO (apanicke): This needs to be replaced with smarter memory management. @@ -213,7 +213,7 @@ bool ConnectionHandler::SdpLookup(const RawAddress& bdaddr, SdpCallback cb, } bool ConnectionHandler::AvrcpConnect(bool initiator, const RawAddress& bdaddr) { - LOG(INFO) << "Connect to device " << ADDRESS_TO_LOGGABLE_STR(bdaddr); + log::info("Connect to device {}", ADDRESS_TO_LOGGABLE_STR(bdaddr)); tAVRC_CONN_CB open_cb; if (initiator) { @@ -235,8 +235,7 @@ bool ConnectionHandler::AvrcpConnect(bool initiator, const RawAddress& bdaddr) { uint8_t handle = 0; uint16_t status = avrc_->Open(&handle, &open_cb, bdaddr); - LOG(INFO) << __PRETTY_FUNCTION__ << ": handle=" << loghex(handle) - << " status= " << loghex(status); + log::info("handle={} status= {}", loghex(handle), loghex(status)); return status == AVRC_SUCCESS; } @@ -245,18 +244,18 @@ void ConnectionHandler::InitiatorControlCb(uint8_t handle, uint8_t event, const RawAddress* peer_addr) { DCHECK(!connection_cb_.is_null()); - LOG(INFO) << __PRETTY_FUNCTION__ << ": handle=" << loghex(handle) - << " result=" << loghex(result) << " addr=" - << (peer_addr ? ADDRESS_TO_LOGGABLE_STR(*peer_addr) : "none"); + log::info("handle={} result={} addr={}", loghex(handle), loghex(result), + (peer_addr ? ADDRESS_TO_LOGGABLE_STR(*peer_addr) : "none")); switch (event) { case AVRC_OPEN_IND_EVT: { - LOG(INFO) << __PRETTY_FUNCTION__ << ": Connection Opened Event"; + log::info("Connection Opened Event"); const auto& feature_iter = feature_map_.find(*peer_addr); if (feature_iter == feature_map_.end()) { - LOG(ERROR) << "Features do not exist even though SDP should have been " - "done first"; + log::error( + "Features do not exist even though SDP should have been " + "done first"); return; } @@ -296,11 +295,10 @@ void ConnectionHandler::InitiatorControlCb(uint8_t handle, uint8_t event, } break; case AVRC_CLOSE_IND_EVT: { - LOG(INFO) << __PRETTY_FUNCTION__ << ": Connection Closed Event"; + log::info("Connection Closed Event"); if (device_map_.find(handle) == device_map_.end()) { - LOG(WARNING) - << "Connection Close received from device that doesn't exist"; + log::warn("Connection Close received from device that doesn't exist"); return; } std::lock_guard lock(device_map_lock); @@ -311,13 +309,13 @@ void ConnectionHandler::InitiatorControlCb(uint8_t handle, uint8_t event, } break; case AVRC_BROWSE_OPEN_IND_EVT: { - LOG(INFO) << __PRETTY_FUNCTION__ << ": Browse Open Event"; + log::info("Browse Open Event"); // NOTE (apanicke): We don't need to explicitly handle this message // since the AVCTP Layer will still send us browsing messages // regardless. It would be useful to note this though for future // compatibility issues. if (device_map_.find(handle) == device_map_.end()) { - LOG(WARNING) << "Browse Opened received from device that doesn't exist"; + log::warn("Browse Opened received from device that doesn't exist"); return; } @@ -325,10 +323,10 @@ void ConnectionHandler::InitiatorControlCb(uint8_t handle, uint8_t event, device_map_[handle]->SetBrowseMtu(browse_mtu); } break; case AVRC_BROWSE_CLOSE_IND_EVT: - LOG(INFO) << __PRETTY_FUNCTION__ << ": Browse Close Event"; + log::info("Browse Close Event"); break; default: - LOG(ERROR) << "Unknown AVRCP Control event"; + log::error("Unknown AVRCP Control event"); break; } } @@ -338,19 +336,18 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, const RawAddress* peer_addr) { DCHECK(!connection_cb_.is_null()); - LOG(INFO) << __PRETTY_FUNCTION__ << ": handle=" << loghex(handle) - << " result=" << loghex(result) << " addr=" - << (peer_addr ? ADDRESS_TO_LOGGABLE_STR(*peer_addr) : "none"); + log::info("handle={} result={} addr={}", loghex(handle), loghex(result), + (peer_addr ? ADDRESS_TO_LOGGABLE_STR(*peer_addr) : "none")); switch (event) { case AVRC_OPEN_IND_EVT: { - LOG(INFO) << __PRETTY_FUNCTION__ << ": Connection Opened Event"; + log::info("Connection Opened Event"); if (peer_addr == NULL) { return; } if (btif_av_src_sink_coexist_enabled() && btif_av_peer_is_connected_source(*peer_addr)) { - LOG(WARNING) << "peer is src, close new avrcp cback"; + log::warn("peer is src, close new avrcp cback"); if (device_map_.find(handle) != device_map_.end()) { std::lock_guard lock(device_map_lock); feature_map_.erase(device_map_[handle]->GetAddress()); @@ -372,16 +369,14 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, device_map_[handle] = newDevice; connection_cb_.Run(newDevice); - LOG(INFO) << __PRETTY_FUNCTION__ - << ": Performing SDP on connected device. address=" - << ADDRESS_TO_LOGGABLE_STR(*peer_addr); + log::info("Performing SDP on connected device. address={}", + ADDRESS_TO_LOGGABLE_STR(*peer_addr)); auto sdp_lambda = [](ConnectionHandler* instance_, uint8_t handle, uint16_t status, uint16_t version, uint16_t features) { if (instance_->device_map_.find(handle) == instance_->device_map_.end()) { - LOG(WARNING) << __PRETTY_FUNCTION__ - << ": No device found for handle: " << loghex(handle); + log::warn("No device found for handle: {}", loghex(handle)); return; } @@ -407,9 +402,8 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, // SDP search failed, this could be due to a collision between outgoing // and incoming connection. In any case, we need to reject the current // connection. - LOG(ERROR) << __PRETTY_FUNCTION__ - << ": SDP search failed for handle: " << loghex(handle) - << ", closing connection"; + log::error("SDP search failed for handle: {}, closing connection", + loghex(handle)); DisconnectDevice(*peer_addr); } // Open for the next incoming connection. The handle will not be the same @@ -418,11 +412,10 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, } break; case AVRC_CLOSE_IND_EVT: { - LOG(INFO) << __PRETTY_FUNCTION__ << ": Connection Closed Event"; + log::info("Connection Closed Event"); if (device_map_.find(handle) == device_map_.end()) { - LOG(WARNING) - << "Connection Close received from device that doesn't exist"; + log::warn("Connection Close received from device that doesn't exist"); return; } { @@ -435,13 +428,13 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, } break; case AVRC_BROWSE_OPEN_IND_EVT: { - LOG(INFO) << __PRETTY_FUNCTION__ << ": Browse Open Event"; + log::info("Browse Open Event"); // NOTE (apanicke): We don't need to explicitly handle this message // since the AVCTP Layer will still send us browsing messages // regardless. It would be useful to note this though for future // compatibility issues. if (device_map_.find(handle) == device_map_.end()) { - LOG(WARNING) << "Browse Opened received from device that doesn't exist"; + log::warn("Browse Opened received from device that doesn't exist"); return; } @@ -449,10 +442,10 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, device_map_[handle]->SetBrowseMtu(browse_mtu); } break; case AVRC_BROWSE_CLOSE_IND_EVT: - LOG(INFO) << __PRETTY_FUNCTION__ << ": Browse Close Event"; + log::info("Browse Close Event"); break; default: - LOG(ERROR) << "Unknown AVRCP Control event"; + log::error("Unknown AVRCP Control event"); break; } } @@ -460,8 +453,8 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, void ConnectionHandler::MessageCb(uint8_t handle, uint8_t label, uint8_t opcode, tAVRC_MSG* p_msg) { if (device_map_.find(handle) == device_map_.end()) { - LOG(ERROR) << "Message received for unconnected device: handle=" - << loghex(handle); + log::error("Message received for unconnected device: handle={}", + loghex(handle)); return; } @@ -470,31 +463,30 @@ void ConnectionHandler::MessageCb(uint8_t handle, uint8_t label, uint8_t opcode, if (opcode == AVRC_OP_BROWSE) { if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) { if (p_msg->browse.hdr.ctype == AVCT_RSP) { - VLOG(2) << "ignore response handle " << (unsigned int)handle; + log::verbose("ignore response handle {}", (unsigned int)handle); return; } } - VLOG(4) << "Browse Message received on handle " << (unsigned int)handle; + log::verbose("Browse Message received on handle {}", (unsigned int)handle); device_map_[handle]->BrowseMessageReceived(label, BrowsePacket::Parse(pkt)); return; } - VLOG(4) << "Message received on handle " << (unsigned int)handle; + log::verbose("Message received on handle {}", (unsigned int)handle); device_map_[handle]->MessageReceived(label, Packet::Parse(pkt)); } void ConnectionHandler::SdpCb(RawAddress bdaddr, SdpCallback cb, tSDP_DISCOVERY_DB* disc_db, bool retry, uint16_t status) { - VLOG(1) << __PRETTY_FUNCTION__ << ": SDP lookup callback received"; + log::verbose("SDP lookup callback received"); if (status == SDP_CONN_FAILED && !retry) { - LOG(WARNING) << __PRETTY_FUNCTION__ << ": SDP Failure retry again"; + log::warn("SDP Failure retry again"); SdpLookup(bdaddr, cb, true); return; } else if (status != AVRC_SUCCESS) { - LOG(ERROR) << __PRETTY_FUNCTION__ - << ": SDP Failure: status = " << (unsigned int)status; + log::error("SDP Failure: status = {}", (unsigned int)status); cb.Run(status, 0, 0); osi_free(disc_db); return; @@ -509,8 +501,8 @@ void ConnectionHandler::SdpCb(RawAddress bdaddr, SdpCallback cb, sdp_record = sdp_->FindServiceInDb(disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, nullptr); if (sdp_record != nullptr) { - LOG(INFO) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) << " supports remote control"; + log::info("Device {} supports remote control", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); peer_features |= BTA_AV_FEAT_RCCT; if ((sdp_->FindAttributeInRec(sdp_record, ATTR_ID_BT_PROFILE_DESC_LIST)) != @@ -518,39 +510,36 @@ void ConnectionHandler::SdpCb(RawAddress bdaddr, SdpCallback cb, /* get profile version (if failure, version parameter is not updated) */ sdp_->FindProfileVersionInRec( sdp_record, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_avrcp_version); - VLOG(1) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) - << " peer avrcp version=" << loghex(peer_avrcp_version); + log::verbose("Device {} peer avrcp version={}", + ADDRESS_TO_LOGGABLE_STR(bdaddr), loghex(peer_avrcp_version)); if (peer_avrcp_version >= AVRC_REV_1_3) { // These are the standard features, another way to check this is to // search for CAT1 on the remote device - VLOG(1) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) << " supports metadata"; + log::verbose("Device {} supports metadata", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA); } if (peer_avrcp_version >= AVRC_REV_1_4) { /* get supported categories */ - VLOG(1) << __PRETTY_FUNCTION__ << " Get Supported categories"; + log::verbose("Get Supported categories"); tSDP_DISC_ATTR* sdp_attribute = sdp_->FindAttributeInRec(sdp_record, ATTR_ID_SUPPORTED_FEATURES); if (sdp_attribute != NULL && SDP_DISC_ATTR_TYPE(sdp_attribute->attr_len_type) == UINT_DESC_TYPE && SDP_DISC_ATTR_LEN(sdp_attribute->attr_len_type) >= 2) { - VLOG(1) << __PRETTY_FUNCTION__ - << "Get Supported categories SDP ATTRIBUTES != null"; + log::verbose("Get Supported categories SDP ATTRIBUTES != null"); uint16_t categories = sdp_attribute->attr_value.v.u16; if (categories & AVRC_SUPF_CT_CAT2) { - VLOG(1) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) - << " supports advanced control"; + log::verbose("Device {} supports advanced control", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); if (IsAbsoluteVolumeEnabled(&bdaddr)) { peer_features |= (BTA_AV_FEAT_ADV_CTRL); } } if (categories & AVRC_SUPF_CT_BROWSE) { - VLOG(1) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) << " supports browsing"; + log::verbose("Device {} supports browsing", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); peer_features |= (BTA_AV_FEAT_BROWSE); } } @@ -565,34 +554,31 @@ void ConnectionHandler::SdpCb(RawAddress bdaddr, SdpCallback cb, sdp_record = sdp_->FindServiceInDb(disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, nullptr); if (sdp_record != nullptr) { - VLOG(1) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) - << " supports remote control target"; + log::verbose("Device {} supports remote control target", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); uint16_t peer_avrcp_target_version = 0; sdp_->FindProfileVersionInRec(sdp_record, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_avrcp_target_version); - VLOG(1) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) << " peer avrcp target version=" - << loghex(peer_avrcp_target_version); + log::verbose("Device {} peer avrcp target version={}", + ADDRESS_TO_LOGGABLE_STR(bdaddr), + loghex(peer_avrcp_target_version)); if ((sdp_->FindAttributeInRec(sdp_record, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) { if (peer_avrcp_target_version >= AVRC_REV_1_4) { /* get supported categories */ - VLOG(1) << __PRETTY_FUNCTION__ << " Get Supported categories"; + log::verbose("Get Supported categories"); tSDP_DISC_ATTR* sdp_attribute = sdp_->FindAttributeInRec(sdp_record, ATTR_ID_SUPPORTED_FEATURES); if (sdp_attribute != NULL && SDP_DISC_ATTR_TYPE(sdp_attribute->attr_len_type) == UINT_DESC_TYPE && SDP_DISC_ATTR_LEN(sdp_attribute->attr_len_type) >= 2) { - VLOG(1) << __PRETTY_FUNCTION__ - << "Get Supported categories SDP ATTRIBUTES != null"; + log::verbose("Get Supported categories SDP ATTRIBUTES != null"); uint16_t categories = sdp_attribute->attr_value.v.u16; if (categories & AVRC_SUPF_CT_CAT2) { - VLOG(1) << __PRETTY_FUNCTION__ << ": Device " - << ADDRESS_TO_LOGGABLE_STR(bdaddr) - << " supports advanced control"; + log::verbose("Device {} supports advanced control", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); if (IsAbsoluteVolumeEnabled(&bdaddr)) { peer_features |= (BTA_AV_FEAT_ADV_CTRL); } @@ -619,7 +605,7 @@ void ConnectionHandler::SendMessage( (uint8_t)(::bluetooth::Packet::Specialize(packet)->GetCType()); } - DLOG(INFO) << "SendMessage to handle=" << loghex(handle); + log::info("SendMessage to handle={}", loghex(handle)); BT_HDR* pkt = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); @@ -653,7 +639,8 @@ void ConnectionHandler::SendMessage( } void ConnectionHandler::RegisterVolChanged(const RawAddress& bdaddr) { - LOG(INFO) << "Attempting to RegisterVolChanged device " << bdaddr; + log::info("Attempting to RegisterVolChanged device {}", + ADDRESS_TO_LOGGABLE_STR(bdaddr)); for (auto it = device_map_.begin(); it != device_map_.end(); it++) { if (bdaddr == it->second->GetAddress()) { const auto& feature_iter = feature_map_.find(bdaddr); diff --git a/system/profile/avrcp/connection_handler.h b/system/profile/avrcp/connection_handler.h index 961ed4a768fe98de7ec4a6ec35b68acbe18c0efb..897541d31d3bcc7d0d4ce3ebdf72bdb2e485291b 100644 --- a/system/profile/avrcp/connection_handler.h +++ b/system/profile/avrcp/connection_handler.h @@ -18,8 +18,10 @@ #include #include + #include #include +#include #include "avrcp_internal.h" #include "packet/avrcp/avrcp_packet.h" @@ -50,7 +52,8 @@ class ConnectionHandler { * A reference to the new Avrcp device is located in the shared_ptr. * If there was an issue during connection the pointer value will be null. */ - using ConnectionCallback = base::Callback)>; + using ConnectionCallback = + base::RepeatingCallback)>; /** * Initializes the singleton instance and sets up SDP. Also Opens the diff --git a/system/profile/avrcp/device.cc b/system/profile/avrcp/device.cc index 2a4cd96c147cd1338b2f3bb6386627bebca3f09a..ece0d640f43bce31ec25726507d866b48dbbd831 100644 --- a/system/profile/avrcp/device.cc +++ b/system/profile/avrcp/device.cc @@ -13,13 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#define LOG_TAG "avrcp" + #include "device.h" -#include +#include #include "abstract_message_loop.h" #include "avrcp_common.h" -#include "connection_handler.h" +#include "include/check.h" #include "internal_include/stack_config.h" #include "packet/avrcp/avrcp_reject_packet.h" #include "packet/avrcp/general_reject_packet.h" @@ -37,14 +40,13 @@ extern bool btif_av_peer_is_connected_sink(const RawAddress& peer_address); extern bool btif_av_both_enable(void); extern bool btif_av_src_sink_coexist_enabled(void); +template <> +struct fmt::formatter + : enum_formatter {}; + namespace bluetooth { namespace avrcp { -#define DEVICE_LOG(LEVEL) \ - LOG(LEVEL) << ADDRESS_TO_LOGGABLE_STR(address_) << " : " -#define DEVICE_VLOG(LEVEL) \ - VLOG(LEVEL) << ADDRESS_TO_LOGGABLE_STR(address_) << " : " - #define VOL_NOT_SUPPORTED -1 #define VOL_REGISTRATION_FAILED -2 @@ -77,12 +79,13 @@ void Device::RegisterInterfaces( base::WeakPtr Device::Get() { return weak_ptr_factory_.GetWeakPtr(); } void Device::SetBrowseMtu(uint16_t browse_mtu) { - DEVICE_LOG(INFO) << __PRETTY_FUNCTION__ << ": browse_mtu = " << browse_mtu; + log::info("{}: browse_mtu = {}", ADDRESS_TO_LOGGABLE_STR(address_), + browse_mtu); browse_mtu_ = browse_mtu; } void Device::SetBipClientStatus(bool connected) { - DEVICE_LOG(INFO) << __PRETTY_FUNCTION__ << ": connected = " << connected; + log::info("{}: connected = {}", ADDRESS_TO_LOGGABLE_STR(address_), connected); has_bip_client_ = connected; } @@ -108,10 +111,11 @@ bool Device::IsInSilenceMode() const { void Device::VendorPacketHandler(uint8_t label, std::shared_ptr pkt) { CHECK(media_interface_); - DEVICE_VLOG(3) << __func__ << ": pdu=" << pkt->GetCommandPdu(); + log::verbose("pdu={}", pkt->GetCommandPdu()); if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(static_cast(0), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -134,7 +138,8 @@ void Device::VendorPacketHandler(uint8_t label, (btif_av_src_sink_coexist_enabled() && register_notification->GetEvent() == Event::VOLUME_CHANGED)) && !register_notification->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -145,9 +150,9 @@ void Device::VendorPacketHandler(uint8_t label, } if (register_notification->GetEvent() != Event::VOLUME_CHANGED) { - DEVICE_LOG(WARNING) - << __func__ << ": Unhandled register notification received: " - << register_notification->GetEvent(); + log::warn("{}: Unhandled register notification received: {}", + ADDRESS_TO_LOGGABLE_STR(address_), + register_notification->GetEvent()); return; } HandleVolumeChanged(label, register_notification); @@ -159,8 +164,8 @@ void Device::VendorPacketHandler(uint8_t label, // about the response to this message. break; default: - DEVICE_LOG(WARNING) - << __func__ << ": Unhandled Response: pdu=" << pkt->GetCommandPdu(); + log::warn("{}: Unhandled Response: pdu={}", + ADDRESS_TO_LOGGABLE_STR(address_), pkt->GetCommandPdu()); break; } return; @@ -182,7 +187,8 @@ void Device::VendorPacketHandler(uint8_t label, Packet::Specialize(pkt); if (!get_element_attributes_request_pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -212,7 +218,8 @@ void Device::VendorPacketHandler(uint8_t label, Packet::Specialize(pkt); if (!set_addressed_player_request->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -226,8 +233,7 @@ void Device::VendorPacketHandler(uint8_t label, case CommandPdu::LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES: { if (player_settings_interface_ == nullptr) { - LOG(ERROR) << __func__ - << ": Player Settings Interface not initialized."; + log::error("Player Settings Interface not initialized."); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -241,8 +247,7 @@ void Device::VendorPacketHandler(uint8_t label, case CommandPdu::LIST_PLAYER_APPLICATION_SETTING_VALUES: { if (player_settings_interface_ == nullptr) { - LOG(ERROR) << __func__ - << ": Player Settings Interface not initialized."; + log::error("Player Settings Interface not initialized."); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -252,7 +257,8 @@ void Device::VendorPacketHandler(uint8_t label, Packet::Specialize(pkt); if (!list_player_setting_values_request->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -263,8 +269,8 @@ void Device::VendorPacketHandler(uint8_t label, list_player_setting_values_request->GetRequestedAttribute(); if (attribute < PlayerAttribute::EQUALIZER || attribute > PlayerAttribute::SCAN) { - DEVICE_LOG(WARNING) - << __func__ << ": Player Setting Attribute is not valid"; + log::warn("{}: Player Setting Attribute is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -279,8 +285,7 @@ void Device::VendorPacketHandler(uint8_t label, case CommandPdu::GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE: { if (player_settings_interface_ == nullptr) { - LOG(ERROR) << __func__ - << ": Player Settings Interface not initialized."; + log::error("Player Settings Interface not initialized."); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -291,7 +296,8 @@ void Device::VendorPacketHandler(uint8_t label, pkt); if (!get_current_player_setting_value_request->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -303,8 +309,8 @@ void Device::VendorPacketHandler(uint8_t label, for (auto attribute : attributes) { if (attribute < PlayerAttribute::EQUALIZER || attribute > PlayerAttribute::SCAN) { - DEVICE_LOG(WARNING) - << __func__ << ": Player Setting Attribute is not valid"; + log::warn("{}: Player Setting Attribute is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -320,8 +326,7 @@ void Device::VendorPacketHandler(uint8_t label, case CommandPdu::SET_PLAYER_APPLICATION_SETTING_VALUE: { if (player_settings_interface_ == nullptr) { - LOG(ERROR) << __func__ - << ": Player Settings Interface not initialized."; + log::error("Player Settings Interface not initialized."); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -331,7 +336,8 @@ void Device::VendorPacketHandler(uint8_t label, Packet::Specialize(pkt); if (!set_player_setting_value_request->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{} : Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -347,8 +353,8 @@ void Device::VendorPacketHandler(uint8_t label, for (size_t i = 0; i < attributes.size(); i++) { if (attributes[i] < PlayerAttribute::EQUALIZER || attributes[i] > PlayerAttribute::SCAN) { - DEVICE_LOG(WARNING) - << __func__ << ": Player Setting Attribute is not valid"; + log::warn("{}: Player Setting Attribute is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); invalid_request = true; break; } @@ -357,8 +363,8 @@ void Device::VendorPacketHandler(uint8_t label, PlayerRepeatValue value = static_cast(values[i]); if (value < PlayerRepeatValue::OFF || value > PlayerRepeatValue::GROUP) { - DEVICE_LOG(WARNING) - << __func__ << ": Player Repeat Value is not valid"; + log::warn("{}: Player Repeat Value is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); invalid_request = true; break; } @@ -366,8 +372,8 @@ void Device::VendorPacketHandler(uint8_t label, PlayerShuffleValue value = static_cast(values[i]); if (value < PlayerShuffleValue::OFF || value > PlayerShuffleValue::GROUP) { - DEVICE_LOG(WARNING) - << __func__ << ": Player Shuffle Value is not valid"; + log::warn("{}: Player Shuffle Value is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); invalid_request = true; break; } @@ -389,7 +395,8 @@ void Device::VendorPacketHandler(uint8_t label, } break; default: { - DEVICE_LOG(ERROR) << "Unhandled Vendor Packet: " << pkt->ToString(); + log::error("{}: Unhandled Vendor Packet: {}", + ADDRESS_TO_LOGGABLE_STR(address_), pkt->ToString()); auto response = RejectBuilder::MakeBuilder( (CommandPdu)pkt->GetCommandPdu(), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -399,17 +406,17 @@ void Device::VendorPacketHandler(uint8_t label, void Device::HandleGetCapabilities( uint8_t label, const std::shared_ptr& pkt) { - DEVICE_VLOG(4) << __func__ - << ": capability=" << pkt->GetCapabilityRequested(); - if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); return; } + log::verbose("capability={}", pkt->GetCapabilityRequested()); + switch (pkt->GetCapabilityRequested()) { case Capability::COMPANY_ID: { auto response = @@ -439,8 +446,9 @@ void Device::HandleGetCapabilities( } break; default: { - DEVICE_LOG(WARNING) << "Unhandled Capability: " - << pkt->GetCapabilityRequested(); + log::warn("{}: Unhandled Capability: {}", + ADDRESS_TO_LOGGABLE_STR(address_), + pkt->GetCapabilityRequested()); auto response = RejectBuilder::MakeBuilder(CommandPdu::GET_CAPABILITIES, Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -451,14 +459,15 @@ void Device::HandleGetCapabilities( void Device::HandleNotification( uint8_t label, const std::shared_ptr& pkt) { if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); return; } - DEVICE_VLOG(4) << __func__ << ": event=" << pkt->GetEventRegistered(); + log::verbose("event={}", pkt->GetEventRegistered()); switch (pkt->GetEventRegistered()) { case Event::TRACK_CHANGED: { @@ -482,8 +491,7 @@ void Device::HandleNotification( case Event::PLAYER_APPLICATION_SETTING_CHANGED: { if (player_settings_interface_ == nullptr) { - LOG(ERROR) << __func__ - << ": Player Settings Interface not initialized."; + log::error("Player Settings Interface not initialized."); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -534,8 +542,8 @@ void Device::HandleNotification( } break; default: { - DEVICE_LOG(ERROR) << __func__ << " : Unknown event registered. Event ID=" - << pkt->GetEventRegistered(); + log::error("{}: Unknown event registered. Event ID={}", + ADDRESS_TO_LOGGABLE_STR(address_), pkt->GetEventRegistered()); auto response = RejectBuilder::MakeBuilder( (CommandPdu)pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); @@ -544,7 +552,7 @@ void Device::HandleNotification( } void Device::RegisterVolumeChanged() { - DEVICE_VLOG(2) << __func__; + log::verbose(""); if (volume_interface_ == nullptr) return; auto request = @@ -563,9 +571,8 @@ void Device::RegisterVolumeChanged() { } if (label == MAX_TRANSACTION_LABEL) { - DEVICE_LOG(FATAL) - << __func__ - << ": Abandon all hope, something went catastrophically wrong"; + log::fatal("{}: Abandon all hope, something went catastrophically wrong", + ADDRESS_TO_LOGGABLE_STR(address_)); } send_message_cb_.Run(label, false, std::move(request)); @@ -573,7 +580,7 @@ void Device::RegisterVolumeChanged() { void Device::HandleVolumeChanged( uint8_t label, const std::shared_ptr& pkt) { - DEVICE_VLOG(1) << __func__ << ": interim=" << pkt->IsInterim(); + log::verbose("interim={}", pkt->IsInterim()); if (volume_interface_ == nullptr) return; @@ -606,23 +613,22 @@ void Device::HandleVolumeChanged( } if (!IsActive()) { - DEVICE_VLOG(3) << __func__ - << ": Ignoring volume changes from non active device"; + log::verbose("Ignoring volume changes from non active device"); return; } volume_ = pkt->GetVolume(); volume_ &= ~0x80; // remove RFA bit - DEVICE_VLOG(1) << __func__ << ": Volume has changed to " << (uint32_t)volume_; + log::verbose("Volume has changed to {}", (uint32_t)volume_); volume_interface_->SetVolume(volume_); } void Device::SetVolume(int8_t volume) { // TODO (apanicke): Implement logic for Multi-AVRCP - DEVICE_VLOG(1) << __func__ << ": volume=" << (int)volume; + log::verbose("volume={}", (int)volume); if (volume == volume_) { - DEVICE_LOG(WARNING) - << __func__ << ": Ignoring volume change same as current volume level"; + log::warn("{}: Ignoring volume change same as current volume level", + ADDRESS_TO_LOGGABLE_STR(address_)); return; } auto request = SetAbsoluteVolumeRequestBuilder::MakeBuilder(volume); @@ -643,12 +649,12 @@ void Device::SetVolume(int8_t volume) { void Device::TrackChangedNotificationResponse(uint8_t label, bool interim, std::string curr_song_id, std::vector song_list) { - DEVICE_VLOG(1) << __func__; + log::verbose(""); if (interim) { track_changed_ = Notification(true, label); } else if (!track_changed_.first) { - DEVICE_VLOG(0) << __func__ << ": Device not registered for update"; + log::verbose("Device not registered for update"); return; } @@ -665,7 +671,7 @@ void Device::TrackChangedNotificationResponse(uint8_t label, bool interim, // Case for browsing not supported; // PTS BV-04-C and BV-5-C assume browsing not supported if (stack_config_get_interface()->get_pts_avrcp_test()) { - DEVICE_LOG(WARNING) << __func__ << ": pts test mode"; + log::warn("{}: pts test mode", ADDRESS_TO_LOGGABLE_STR(address_)); uint64_t uid = curr_song_id.empty() ? 0xffffffffffffffff : 0; auto response = RegisterNotificationResponseBuilder::MakeTrackChangedBuilder(interim, @@ -681,15 +687,15 @@ void Device::TrackChangedNotificationResponse(uint8_t label, bool interim, for (const SongInfo& song : song_list) { now_playing_ids_.insert(song.media_id); if (curr_song_id == song.media_id) { - DEVICE_VLOG(3) << __func__ << ": Found media ID match for " - << song.media_id; + log::verbose("Found media ID match for {}", song.media_id); uid = now_playing_ids_.get_uid(curr_song_id); } } if (uid == 0) { // uid 0 is not valid here when browsing is supported - DEVICE_LOG(ERROR) << "No match for media ID found"; + log::error("{}: No match for media ID found", + ADDRESS_TO_LOGGABLE_STR(address_)); } auto response = RegisterNotificationResponseBuilder::MakeTrackChangedBuilder( @@ -699,22 +705,21 @@ void Device::TrackChangedNotificationResponse(uint8_t label, bool interim, void Device::PlaybackStatusNotificationResponse(uint8_t label, bool interim, PlayStatus status) { - DEVICE_VLOG(1) << __func__; + log::verbose(""); if (status.state == PlayState::PAUSED) play_pos_update_cb_.Cancel(); if (interim) { play_status_changed_ = Notification(true, label); } else if (!play_status_changed_.first) { - DEVICE_VLOG(0) << __func__ << ": Device not registered for update"; + log::verbose("Device not registered for update"); return; } auto state_to_send = status.state; if (!IsActive()) state_to_send = PlayState::PAUSED; if (!interim && state_to_send == last_play_status_.state) { - DEVICE_VLOG(0) << __func__ - << ": Not sending notification due to no state update " - << ADDRESS_TO_LOGGABLE_STR(address_); + log::verbose("Not sending notification due to no state update {}", + ADDRESS_TO_LOGGABLE_STR(address_)); return; } @@ -733,18 +738,18 @@ void Device::PlaybackStatusNotificationResponse(uint8_t label, bool interim, void Device::PlaybackPosNotificationResponse(uint8_t label, bool interim, PlayStatus status) { - DEVICE_VLOG(4) << __func__; + log::verbose(""); if (interim) { play_pos_changed_ = Notification(true, label); } else if (!play_pos_changed_.first) { - DEVICE_VLOG(3) << __func__ << ": Device not registered for update"; + log::verbose("Device not registered for update"); return; } if (!interim && last_play_status_.position == status.position) { - DEVICE_LOG(WARNING) << ADDRESS_TO_LOGGABLE_STR(address_) - << ": No update to play position"; + log::warn("{}: No update to play position", + ADDRESS_TO_LOGGABLE_STR(address_)); return; } @@ -764,7 +769,7 @@ void Device::PlaybackPosNotificationResponse(uint8_t label, bool interim, // device even though the device thinks the music is paused. This makes // the status bar on the remote device move. if (status.state == PlayState::PLAYING && !IsInSilenceMode()) { - DEVICE_VLOG(0) << __func__ << ": Queue next play position update"; + log::verbose("Queue next play position update"); play_pos_update_cb_.Reset(base::Bind(&Device::HandlePlayPosUpdate, weak_ptr_factory_.GetWeakPtr())); btbase::AbstractMessageLoop::current_task_runner()->PostDelayedTask( @@ -782,13 +787,12 @@ void Device::PlaybackPosNotificationResponse(uint8_t label, bool interim, void Device::AddressedPlayerNotificationResponse( uint8_t label, bool interim, uint16_t curr_player, std::vector /* unused */) { - DEVICE_VLOG(1) << __func__ - << ": curr_player_id=" << (unsigned int)curr_player; + log::verbose("curr_player_id={}", (unsigned int)curr_player); if (interim) { addr_player_changed_ = Notification(true, label); } else if (!addr_player_changed_.first) { - DEVICE_VLOG(3) << __func__ << ": Device not registered for update"; + log::verbose("Device not registered for update"); return; } @@ -811,7 +815,7 @@ void Device::AddressedPlayerNotificationResponse( } void Device::RejectNotification() { - DEVICE_VLOG(1) << __func__; + log::verbose(""); Notification* rejectNotification[] = {&play_status_changed_, &track_changed_, &play_pos_changed_, &now_playing_changed_}; @@ -826,9 +830,8 @@ void Device::RejectNotification() { } void Device::GetPlayStatusResponse(uint8_t label, PlayStatus status) { - DEVICE_VLOG(2) << __func__ << ": position=" << status.position - << " duration=" << status.duration - << " state=" << status.state; + log::verbose("position={} duration={} state={}", status.position, + status.duration, status.state); auto response = GetPlayStatusResponseBuilder::MakeBuilder( status.duration, status.position, IsActive() ? status.state : PlayState::PAUSED); @@ -868,14 +871,15 @@ void Device::GetElementAttributesResponse( void Device::MessageReceived(uint8_t label, std::shared_ptr pkt) { if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(static_cast(0), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); return; } - DEVICE_VLOG(4) << __func__ << ": opcode=" << pkt->GetOpcode(); + log::verbose("opcode={}", pkt->GetOpcode()); active_labels_.insert(label); switch (pkt->GetOpcode()) { // TODO (apanicke): Remove handling of UNIT_INFO and SUBUNIT_INFO from @@ -894,7 +898,8 @@ void Device::MessageReceived(uint8_t label, std::shared_ptr pkt) { auto pass_through_packet = Packet::Specialize(pkt); if (!pass_through_packet->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(static_cast(0), Status::INVALID_COMMAND); send_message(label, false, std::move(response)); @@ -917,13 +922,13 @@ void Device::MessageReceived(uint8_t label, std::shared_ptr pkt) { if (!d) return; if (!d->IsActive()) { - LOG(INFO) << "Setting " << ADDRESS_TO_LOGGABLE_STR(d->address_) - << " to be the active device"; + log::info("Setting {} to be the active device", + ADDRESS_TO_LOGGABLE_STR(d->address_)); d->media_interface_->SetActiveDevice(d->address_); if (s.state == PlayState::PLAYING) { - LOG(INFO) - << "Skipping sendKeyEvent since music is already playing"; + log::info( + "Skipping sendKeyEvent since music is already playing"); return; } } @@ -948,17 +953,17 @@ void Device::MessageReceived(uint8_t label, std::shared_ptr pkt) { void Device::HandlePlayItem(uint8_t label, std::shared_ptr pkt) { - DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope() - << " uid=" << pkt->GetUid(); - if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pkt->GetCommandPdu(), Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); return; } + log::verbose("scope={} uid={}", pkt->GetScope(), pkt->GetUid()); + std::string media_id = ""; switch (pkt->GetScope()) { case Scope::NOW_PLAYING: @@ -968,11 +973,12 @@ void Device::HandlePlayItem(uint8_t label, media_id = vfs_ids_.get_media_id(pkt->GetUid()); break; default: - DEVICE_LOG(WARNING) << __func__ << ": Unknown scope for play item"; + log::warn("{}: Unknown scope for play item", + ADDRESS_TO_LOGGABLE_STR(address_)); } if (media_id == "") { - DEVICE_VLOG(2) << "Could not find item"; + log::verbose("Could not find item"); auto response = RejectBuilder::MakeBuilder(CommandPdu::PLAY_ITEM, Status::DOES_NOT_EXIST); send_message(label, false, std::move(response)); @@ -989,10 +995,10 @@ void Device::HandlePlayItem(uint8_t label, void Device::HandleSetAddressedPlayer( uint8_t label, std::shared_ptr pkt, uint16_t curr_player, std::vector players) { - DEVICE_VLOG(2) << __func__ << ": PlayerId=" << pkt->GetPlayerId(); + log::verbose("PlayerId={}", pkt->GetPlayerId()); if (curr_player != pkt->GetPlayerId()) { - DEVICE_VLOG(2) << "Reject invalid addressed player ID"; + log::verbose("Reject invalid addressed player ID"); auto response = RejectBuilder::MakeBuilder(CommandPdu::SET_ADDRESSED_PLAYER, Status::INVALID_PLAYER_ID); send_message(label, false, std::move(response)); @@ -1007,11 +1013,10 @@ void Device::HandleSetAddressedPlayer( void Device::ListPlayerApplicationSettingAttributesResponse( uint8_t label, std::vector attributes) { uint8_t num_of_attributes = attributes.size(); - DEVICE_VLOG(2) << __func__ - << ": num_of_attributes=" << std::to_string(num_of_attributes); + log::verbose("num_of_attributes={}", num_of_attributes); if (num_of_attributes > 0) { for (auto attribute : attributes) { - DEVICE_VLOG(2) << __func__ << ": attribute=" << attribute; + log::verbose("attribute={}", attribute); } } auto response = @@ -1023,22 +1028,20 @@ void Device::ListPlayerApplicationSettingAttributesResponse( void Device::ListPlayerApplicationSettingValuesResponse( uint8_t label, PlayerAttribute attribute, std::vector values) { uint8_t number_of_values = values.size(); - DEVICE_VLOG(2) << __func__ << ": attribute=" << attribute - << ", number_of_values=" << std::to_string(number_of_values); + log::verbose("attribute={}, number_of_values={}", attribute, + number_of_values); if (number_of_values > 0) { if (attribute == PlayerAttribute::REPEAT) { for (auto value : values) { - DEVICE_VLOG(2) << __func__ - << ": value=" << static_cast(value); + log::verbose("value={}", static_cast(value)); } } else if (attribute == PlayerAttribute::SHUFFLE) { for (auto value : values) { - DEVICE_VLOG(2) << __func__ - << ": value=" << static_cast(value); + log::verbose("value={}", static_cast(value)); } } else { - DEVICE_VLOG(2) << __func__ << ": value=" << loghex(values.at(0)); + log::verbose("value={}", loghex(values.at(0))); } } @@ -1052,16 +1055,13 @@ void Device::GetPlayerApplicationSettingValueResponse( uint8_t label, std::vector attributes, std::vector values) { for (size_t i = 0; i < attributes.size(); i++) { - DEVICE_VLOG(2) << __func__ << ": attribute=" - << static_cast(attributes[i]); + log::verbose("attribute={}", static_cast(attributes[i])); if (attributes[i] == PlayerAttribute::REPEAT) { - DEVICE_VLOG(2) << __func__ - << ": value=" << static_cast(values[i]); + log::verbose("value={}", static_cast(values[i])); } else if (attributes[i] == PlayerAttribute::SHUFFLE) { - DEVICE_VLOG(2) << __func__ << ": value=" - << static_cast(values[i]); + log::verbose("value={}", static_cast(values[i])); } else { - DEVICE_VLOG(2) << __func__ << ": value=" << loghex(values.at(0)); + log::verbose("value={}", loghex(values.at(0))); } } @@ -1075,8 +1075,8 @@ void Device::SetPlayerApplicationSettingValueResponse(uint8_t label, CommandPdu pdu, bool success) { if (!success) { - DEVICE_LOG(ERROR) << __func__ - << ": Set Player Application Setting Value failed"; + log::error("{}: Set Player Application Setting Value failed", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = RejectBuilder::MakeBuilder(pdu, Status::INVALID_PARAMETER); send_message(label, false, std::move(response)); return; @@ -1090,13 +1090,14 @@ void Device::SetPlayerApplicationSettingValueResponse(uint8_t label, void Device::BrowseMessageReceived(uint8_t label, std::shared_ptr pkt) { if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND); send_message(label, false, std::move(response)); return; } - DEVICE_VLOG(1) << __func__ << ": pdu=" << pkt->GetPdu(); + log::verbose("pdu={}", pkt->GetPdu()); switch (pkt->GetPdu()) { case BrowsePdu::SET_BROWSED_PLAYER: @@ -1119,7 +1120,7 @@ void Device::BrowseMessageReceived(uint8_t label, label, Packet::Specialize(pkt)); break; default: - DEVICE_LOG(WARNING) << __func__ << ": " << pkt->GetPdu(); + log::warn("{}: pdu={}", ADDRESS_TO_LOGGABLE_STR(address_), pkt->GetPdu()); auto response = GeneralRejectBuilder::MakeBuilder(Status::INVALID_COMMAND); send_message(label, true, std::move(response)); @@ -1132,15 +1133,15 @@ void Device::HandleGetFolderItems(uint8_t label, std::shared_ptr pkt) { if (!pkt->IsValid()) { // The specific get folder items builder is unimportant on failure. - DEVICE_LOG(WARNING) << __func__ - << ": Get folder items request packet is not valid"; + log::warn("{}: Get folder items request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = GetFolderItemsResponseBuilder::MakePlayerListBuilder( Status::INVALID_PARAMETER, 0x0000, browse_mtu_); send_message(label, true, std::move(response)); return; } - DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope(); + log::verbose("scope={}", pkt->GetScope()); switch (pkt->GetScope()) { case Scope::MEDIA_PLAYER_LIST: @@ -1160,7 +1161,8 @@ void Device::HandleGetFolderItems(uint8_t label, weak_ptr_factory_.GetWeakPtr(), label, pkt)); break; default: - DEVICE_LOG(ERROR) << __func__ << ": " << pkt->GetScope(); + log::error("{}: scope={}", ADDRESS_TO_LOGGABLE_STR(address_), + pkt->GetScope()); auto response = GetFolderItemsResponseBuilder::MakePlayerListBuilder( Status::INVALID_PARAMETER, 0, browse_mtu_); send_message(label, true, std::move(response)); @@ -1171,14 +1173,15 @@ void Device::HandleGetFolderItems(uint8_t label, void Device::HandleGetTotalNumberOfItems( uint8_t label, std::shared_ptr pkt) { if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = GetTotalNumberOfItemsResponseBuilder::MakeBuilder( Status::INVALID_PARAMETER, 0x0000, 0); send_message(label, true, std::move(response)); return; } - DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope(); + log::verbose("scope={}", pkt->GetScope()); switch (pkt->GetScope()) { case Scope::MEDIA_PLAYER_LIST: { @@ -1199,14 +1202,15 @@ void Device::HandleGetTotalNumberOfItems( weak_ptr_factory_.GetWeakPtr(), label)); break; default: - DEVICE_LOG(ERROR) << __func__ << ": " << pkt->GetScope(); + log::error("{}: scope={}", ADDRESS_TO_LOGGABLE_STR(address_), + pkt->GetScope()); break; } } void Device::GetTotalNumberOfItemsMediaPlayersResponse( uint8_t label, uint16_t curr_player, std::vector list) { - DEVICE_VLOG(2) << __func__ << ": num_items=" << list.size(); + log::verbose("num_items={}", list.size()); auto builder = GetTotalNumberOfItemsResponseBuilder::MakeBuilder( Status::NO_ERROR, 0x0000, list.size()); @@ -1215,7 +1219,7 @@ void Device::GetTotalNumberOfItemsMediaPlayersResponse( void Device::GetTotalNumberOfItemsVFSResponse(uint8_t label, std::vector list) { - DEVICE_VLOG(2) << __func__ << ": num_items=" << list.size(); + log::verbose("num_items={}", list.size()); auto builder = GetTotalNumberOfItemsResponseBuilder::MakeBuilder( Status::NO_ERROR, 0x0000, list.size()); @@ -1224,7 +1228,7 @@ void Device::GetTotalNumberOfItemsVFSResponse(uint8_t label, void Device::GetTotalNumberOfItemsNowPlayingResponse( uint8_t label, std::string curr_song_id, std::vector list) { - DEVICE_VLOG(2) << __func__ << ": num_items=" << list.size(); + log::verbose("num_items={}", list.size()); auto builder = GetTotalNumberOfItemsResponseBuilder::MakeBuilder( Status::NO_ERROR, 0x0000, list.size()); @@ -1234,20 +1238,21 @@ void Device::GetTotalNumberOfItemsNowPlayingResponse( void Device::HandleChangePath(uint8_t label, std::shared_ptr pkt) { if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = ChangePathResponseBuilder::MakeBuilder(Status::INVALID_PARAMETER, 0); send_message(label, true, std::move(response)); return; } - DEVICE_VLOG(2) << __func__ << ": direction=" << pkt->GetDirection() - << " uid=" << loghex(pkt->GetUid()); + log::verbose("direction={} uid={}", pkt->GetDirection(), + loghex(pkt->GetUid())); if (pkt->GetDirection() == Direction::DOWN && vfs_ids_.get_media_id(pkt->GetUid()) == "") { - DEVICE_LOG(ERROR) << __func__ - << ": No item found for UID=" << pkt->GetUid(); + log::error("{}: No item found for UID={}", + ADDRESS_TO_LOGGABLE_STR(address_), pkt->GetUid()); auto builder = ChangePathResponseBuilder::MakeBuilder(Status::DOES_NOT_EXIST, 0); send_message(label, true, std::move(builder)); @@ -1256,21 +1261,21 @@ void Device::HandleChangePath(uint8_t label, if (pkt->GetDirection() == Direction::DOWN) { current_path_.push(vfs_ids_.get_media_id(pkt->GetUid())); - DEVICE_VLOG(2) << "Pushing Path to stack: \"" << CurrentFolder() << "\""; + log::verbose("Pushing Path to stack: \"{}\"", CurrentFolder()); } else { // Don't pop the root id off the stack if (current_path_.size() > 1) { current_path_.pop(); } else { - DEVICE_LOG(ERROR) << "Trying to change directory up past root."; + log::error("{}: Trying to change directory up past root.", + ADDRESS_TO_LOGGABLE_STR(address_)); auto builder = ChangePathResponseBuilder::MakeBuilder(Status::DOES_NOT_EXIST, 0); send_message(label, true, std::move(builder)); return; } - DEVICE_VLOG(2) << "Popping Path from stack: new path=\"" << CurrentFolder() - << "\""; + log::verbose("Popping Path from stack: new path=\"{}\"", CurrentFolder()); } media_interface_->GetFolderItems( @@ -1292,18 +1297,18 @@ void Device::ChangePathResponse(uint8_t label, void Device::HandleGetItemAttributes( uint8_t label, std::shared_ptr pkt) { if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto builder = GetItemAttributesResponseBuilder::MakeBuilder( Status::INVALID_PARAMETER, browse_mtu_); send_message(label, true, std::move(builder)); return; } - DEVICE_VLOG(2) << __func__ << ": scope=" << pkt->GetScope() - << " uid=" << loghex(pkt->GetUid()) - << " uid counter=" << loghex(pkt->GetUidCounter()); + log::verbose("scope={} uid={} uid counter={}", pkt->GetScope(), + loghex(pkt->GetUid()), loghex(pkt->GetUidCounter())); if (pkt->GetUidCounter() != 0x0000) { // For database unaware player, use 0 - DEVICE_LOG(WARNING) << "UidCounter is invalid"; + log::warn("{}: UidCounter is invalid", ADDRESS_TO_LOGGABLE_STR(address_)); auto builder = GetItemAttributesResponseBuilder::MakeBuilder( Status::UIDS_CHANGED, browse_mtu_); send_message(label, true, std::move(builder)); @@ -1327,7 +1332,8 @@ void Device::HandleGetItemAttributes( weak_ptr_factory_.GetWeakPtr(), label, pkt)); break; default: - DEVICE_LOG(ERROR) << "UNKNOWN SCOPE FOR HANDLE GET ITEM ATTRIBUTES"; + log::error("{}: UNKNOWN SCOPE FOR HANDLE GET ITEM ATTRIBUTES", + ADDRESS_TO_LOGGABLE_STR(address_)); break; } } @@ -1335,7 +1341,7 @@ void Device::HandleGetItemAttributes( void Device::GetItemAttributesNowPlayingResponse( uint8_t label, std::shared_ptr pkt, std::string curr_media_id, std::vector song_list) { - DEVICE_VLOG(2) << __func__ << ": uid=" << loghex(pkt->GetUid()); + log::verbose("uid={}", loghex(pkt->GetUid())); auto builder = GetItemAttributesResponseBuilder::MakeBuilder(Status::NO_ERROR, browse_mtu_); @@ -1344,13 +1350,11 @@ void Device::GetItemAttributesNowPlayingResponse( media_id = curr_media_id; } - DEVICE_VLOG(2) << __func__ << ": media_id=\"" << media_id << "\""; + log::verbose("media_id=\"{}\"", media_id); SongInfo info; if (song_list.size() == 1) { - DEVICE_VLOG(2) - << __func__ - << " Send out the only song in the queue as now playing song."; + log::verbose("Send out the only song in the queue as now playing song."); info = song_list.front(); } else { for (const auto& temp : song_list) { @@ -1386,11 +1390,11 @@ void Device::GetItemAttributesNowPlayingResponse( void Device::GetItemAttributesVFSResponse( uint8_t label, std::shared_ptr pkt, std::vector item_list) { - DEVICE_VLOG(2) << __func__ << ": uid=" << loghex(pkt->GetUid()); + log::verbose("uid={}", loghex(pkt->GetUid())); auto media_id = vfs_ids_.get_media_id(pkt->GetUid()); if (media_id == "") { - LOG(WARNING) << __func__ << ": Item not found"; + log::warn("Item not found"); auto builder = GetItemAttributesResponseBuilder::MakeBuilder( Status::DOES_NOT_EXIST, browse_mtu_); send_message(label, true, std::move(builder)); @@ -1453,7 +1457,7 @@ void Device::GetItemAttributesVFSResponse( void Device::GetMediaPlayerListResponse( uint8_t label, std::shared_ptr pkt, uint16_t curr_player, std::vector players) { - DEVICE_VLOG(2) << __func__; + log::verbose(""); if (players.size() == 0) { auto no_items_rsp = GetFolderItemsResponseBuilder::MakePlayerListBuilder( @@ -1469,7 +1473,7 @@ void Device::GetMediaPlayerListResponse( // returned by Addressed Player Changed for (auto it = players.begin(); it != players.end(); it++) { if (it->id == curr_player) { - DEVICE_VLOG(1) << " Adding player to first spot: " << it->name; + log::verbose(" Adding player to first spot: {}", it->name); auto temp_player = *it; players.erase(it); players.insert(players.begin(), temp_player); @@ -1502,8 +1506,8 @@ std::set filter_attributes_requested( void Device::GetVFSListResponse(uint8_t label, std::shared_ptr pkt, std::vector items) { - DEVICE_VLOG(2) << __func__ << ": start_item=" << pkt->GetStartItem() - << " end_item=" << pkt->GetEndItem(); + log::verbose("start_item={} end_item={}", pkt->GetStartItem(), + pkt->GetEndItem()); // The builder will automatically correct the status if there are zero items auto builder = GetFolderItemsResponseBuilder::MakeVFSBuilder( @@ -1566,7 +1570,7 @@ void Device::GetVFSListResponse(uint8_t label, void Device::GetNowPlayingListResponse( uint8_t label, std::shared_ptr pkt, std::string /* unused curr_song_id */, std::vector song_list) { - DEVICE_VLOG(2) << __func__; + log::verbose(""); auto builder = GetFolderItemsResponseBuilder::MakeNowPlayingBuilder( Status::NO_ERROR, 0x0000, browse_mtu_); @@ -1607,14 +1611,15 @@ void Device::GetNowPlayingListResponse( void Device::HandleSetBrowsedPlayer( uint8_t label, std::shared_ptr pkt) { if (!pkt->IsValid()) { - DEVICE_LOG(WARNING) << __func__ << ": Request packet is not valid"; + log::warn("{}: Request packet is not valid", + ADDRESS_TO_LOGGABLE_STR(address_)); auto response = SetBrowsedPlayerResponseBuilder::MakeBuilder( Status::INVALID_PARAMETER, 0x0000, 0, 0, ""); send_message(label, true, std::move(response)); return; } - DEVICE_VLOG(2) << __func__ << ": player_id=" << pkt->GetPlayerId(); + log::verbose("player_id={}", pkt->GetPlayerId()); media_interface_->SetBrowsedPlayer( pkt->GetPlayerId(), base::Bind(&Device::SetBrowsedPlayerResponse, @@ -1624,8 +1629,8 @@ void Device::HandleSetBrowsedPlayer( void Device::SetBrowsedPlayerResponse( uint8_t label, std::shared_ptr pkt, bool success, std::string root_id, uint32_t num_items) { - DEVICE_VLOG(2) << __func__ << ": success=" << success << " root_id=\"" - << root_id << "\" num_items=" << num_items; + log::verbose("success={} root_id=\"{}\" num_items={}", success, root_id, + num_items); if (!success) { auto response = SetBrowsedPlayerResponseBuilder::MakeBuilder( @@ -1657,9 +1662,8 @@ void Device::SendMediaUpdate(bool metadata, bool play_status, bool queue) { bool is_silence = IsInSilenceMode(); CHECK(media_interface_); - DEVICE_VLOG(4) << __func__ << ": Metadata=" << metadata - << " : play_status= " << play_status << " : queue=" << queue - << " ; is_silence=" << is_silence; + log::verbose("Metadata={} : play_status= {} : queue={} : is_silence={}", + metadata, play_status, queue, is_silence); if (queue) { HandleNowPlayingUpdate(); @@ -1678,7 +1682,7 @@ void Device::SendMediaUpdate(bool metadata, bool play_status, bool queue) { void Device::SendFolderUpdate(bool available_players, bool addressed_player, bool uids) { CHECK(media_interface_); - DEVICE_VLOG(4) << __func__; + log::verbose(""); if (available_players) { HandleAvailablePlayerUpdate(); @@ -1690,9 +1694,9 @@ void Device::SendFolderUpdate(bool available_players, bool addressed_player, } void Device::HandleTrackUpdate() { - DEVICE_VLOG(2) << __func__; + log::verbose(""); if (!track_changed_.first) { - LOG(WARNING) << "Device is not registered for track changed updates"; + log::warn("Device is not registered for track changed updates"); return; } @@ -1702,9 +1706,9 @@ void Device::HandleTrackUpdate() { } void Device::HandlePlayStatusUpdate() { - DEVICE_VLOG(2) << __func__; + log::verbose(""); if (!play_status_changed_.first) { - LOG(WARNING) << "Device is not registered for play status updates"; + log::warn("Device is not registered for play status updates"); return; } @@ -1714,10 +1718,10 @@ void Device::HandlePlayStatusUpdate() { } void Device::HandleNowPlayingUpdate() { - DEVICE_VLOG(2) << __func__; + log::verbose(""); if (!now_playing_changed_.first) { - LOG(WARNING) << "Device is not registered for now playing updates"; + log::warn("Device is not registered for now playing updates"); return; } @@ -1728,21 +1732,20 @@ void Device::HandleNowPlayingUpdate() { void Device::HandlePlayerSettingChanged(std::vector attributes, std::vector values) { - DEVICE_VLOG(2) << __func__; + log::verbose(""); if (!player_setting_changed_.first) { - LOG(WARNING) << "Device is not registered for player settings updates"; + log::warn("Device is not registered for player settings updates"); return; } for (size_t i = 0; i < attributes.size(); i++) { - DEVICE_VLOG(2) << " attribute: " << attributes[i] << std::endl; + log::verbose(" attribute: {}", attributes[i]); if (attributes[i] == PlayerAttribute::SHUFFLE) { - DEVICE_VLOG(2) << " value: " << (PlayerShuffleValue)values[i] - << std::endl; + log::verbose(" value: {}", (PlayerShuffleValue)values[i]); } else if (attributes[i] == PlayerAttribute::REPEAT) { - DEVICE_VLOG(2) << " value: " << (PlayerRepeatValue)values[i] << std::endl; + log::verbose(" value: {}", (PlayerRepeatValue)values[i]); } else { - DEVICE_VLOG(2) << " value: " << std::to_string(values[i]) << std::endl; + log::verbose(" value: {}", values[i]); } } @@ -1755,23 +1758,22 @@ void Device::HandlePlayerSettingChanged(std::vector attributes, void Device::PlayerSettingChangedNotificationResponse( uint8_t label, bool interim, std::vector attributes, std::vector values) { - DEVICE_VLOG(2) << __func__ << " interim: " << interim << std::endl; + log::verbose("interim: {}", interim); for (size_t i = 0; i < attributes.size(); i++) { - DEVICE_VLOG(2) << " attribute: " << attributes[i] << std::endl; + log::verbose(" attribute: {}", attributes[i]); if (attributes[i] == PlayerAttribute::SHUFFLE) { - DEVICE_VLOG(2) << " value: " << (PlayerShuffleValue)values[i] - << std::endl; + log::verbose(" value: {}", (PlayerShuffleValue)values[i]); } else if (attributes[i] == PlayerAttribute::REPEAT) { - DEVICE_VLOG(2) << " value: " << (PlayerRepeatValue)values[i] << std::endl; + log::verbose(" value: {}", (PlayerRepeatValue)values[i]); } else { - DEVICE_VLOG(2) << " value: " << std::to_string(values[i]) << std::endl; + log::verbose(" value: {}", values[i]); } } if (interim) { player_setting_changed_ = Notification(true, label); } else if (!player_setting_changed_.first) { - LOG(WARNING) << "Device is not registered for now playing updates"; + log::warn("Device is not registered for now playing updates"); return; } @@ -1792,7 +1794,7 @@ void Device::HandleNowPlayingNotificationResponse( if (interim) { now_playing_changed_ = Notification(true, label); } else if (!now_playing_changed_.first) { - LOG(WARNING) << "Device is not registered for now playing updates"; + log::warn("Device is not registered for now playing updates"); return; } @@ -1812,9 +1814,9 @@ void Device::HandleNowPlayingNotificationResponse( } void Device::HandlePlayPosUpdate() { - DEVICE_VLOG(0) << __func__; + log::verbose(""); if (!play_pos_changed_.first) { - LOG(WARNING) << "Device is not registered for play position updates"; + log::warn("Device is not registered for play position updates"); return; } @@ -1824,10 +1826,10 @@ void Device::HandlePlayPosUpdate() { } void Device::HandleAvailablePlayerUpdate() { - DEVICE_VLOG(1) << __func__; + log::verbose(""); if (!avail_players_changed_.first) { - LOG(WARNING) << "Device is not registered for available player updates"; + log::warn("Device is not registered for available player updates"); return; } @@ -1843,10 +1845,10 @@ void Device::HandleAvailablePlayerUpdate() { } void Device::HandleAddressedPlayerUpdate() { - DEVICE_VLOG(1) << __func__; + log::verbose(""); if (!addr_player_changed_.first) { - DEVICE_LOG(WARNING) - << "Device is not registered for addressed player updates"; + log::warn("{}: Device is not registered for addressed player updates", + ADDRESS_TO_LOGGABLE_STR(address_)); return; } media_interface_->GetMediaPlayerList(base::Bind( @@ -1855,7 +1857,7 @@ void Device::HandleAddressedPlayerUpdate() { } void Device::DeviceDisconnected() { - DEVICE_LOG(INFO) << "Device was disconnected"; + log::info("{} : Device was disconnected", ADDRESS_TO_LOGGABLE_STR(address_)); play_pos_update_cb_.Cancel(); // TODO (apanicke): Once the interfaces are set in the Device construction, diff --git a/system/profile/avrcp/device.h b/system/profile/avrcp/device.h index e056d021ad6081f44abed870eef6bfb3badd5eef..1b4288941b6ab05809a68fb00da288fc60867f79 100644 --- a/system/profile/avrcp/device.h +++ b/system/profile/avrcp/device.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "avrcp_internal.h" #include "hardware/avrcp/avrcp.h" diff --git a/system/profile/avrcp/tests/avrcp_connection_handler_test.cc b/system/profile/avrcp/tests/avrcp_connection_handler_test.cc index 4dbc79338b7d76d3769e23925a37fd97f0252e3f..7b3ea7bd22698bd5994e1cc765f2b43360936c5c 100644 --- a/system/profile/avrcp/tests/avrcp_connection_handler_test.cc +++ b/system/profile/avrcp/tests/avrcp_connection_handler_test.cc @@ -15,14 +15,13 @@ */ #include -#include #include #include -#include "sdpdefs.h" #include "avrcp_internal.h" #include "avrcp_test_helper.h" #include "connection_handler.h" +#include "sdpdefs.h" #include "types/raw_address.h" using ::testing::_; @@ -106,8 +105,8 @@ TEST_F(AvrcpConnectionHandlerTest, initializeTest) { .WillOnce( DoAll(SetArgPointee<0>(1), SaveArgPointee<1>(&conn_cb), Return(0))); - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -130,8 +129,8 @@ TEST_F(AvrcpConnectionHandlerTest, notConnectedDisconnectTest) { DoAll(SetArgPointee<0>(1), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -154,8 +153,8 @@ TEST_F(AvrcpConnectionHandlerTest, disconnectAfterCleanupTest) { DoAll(SetArgPointee<0>(1), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -183,8 +182,8 @@ TEST_F(AvrcpConnectionHandlerTest, remoteDeviceConnectionTest) { DoAll(SetArgPointee<0>(2), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -229,8 +228,8 @@ TEST_F(AvrcpConnectionHandlerTest, noAbsoluteVolumeTest) { DoAll(SetArgPointee<0>(2), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -267,8 +266,8 @@ TEST_F(AvrcpConnectionHandlerTest, absoluteVolumeTest) { DoAll(SetArgPointee<0>(2), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); StrictMock strict_volume; ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, @@ -301,8 +300,8 @@ TEST_F(AvrcpConnectionHandlerTest, disconnectTest) { .WillOnce(DoAll(SetArgPointee<0>(2), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -339,8 +338,8 @@ TEST_F(AvrcpConnectionHandlerTest, multipleRemoteDeviceConnectionTest) { DoAll(SetArgPointee<0>(3), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -398,8 +397,8 @@ TEST_F(AvrcpConnectionHandlerTest, cleanupTest) { DoAll(SetArgPointee<0>(3), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -420,8 +419,8 @@ TEST_F(AvrcpConnectionHandlerTest, cleanupTest) { TEST_F(AvrcpConnectionHandlerTest, connectToRemoteDeviceTest) { // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -465,8 +464,8 @@ TEST_F(AvrcpConnectionHandlerTest, connectToRemoteDeviceTest) { TEST_F(AvrcpConnectionHandlerTest, connectToBrowsableRemoteDeviceTest) { // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -519,8 +518,8 @@ TEST_F(AvrcpConnectionHandlerTest, disconnectWhileDoingSdpTest) { .WillOnce(DoAll(SetArgPointee<0>(2), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -557,8 +556,8 @@ TEST_F(AvrcpConnectionHandlerTest, connectionCollisionTest) { DoAll(SetArgPointee<0>(2), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); @@ -612,8 +611,8 @@ TEST_F(AvrcpConnectionHandlerTest, acceptorSdpSearchFailTest) { DoAll(SetArgPointee<0>(2), SaveArgPointee<1>(&conn_cb), Return(0))); // Initialize the interface - auto bound_callback = base::Bind(&MockFunction::Call, - base::Unretained(&device_cb)); + auto bound_callback = base::BindRepeating( + &MockFunction::Call, base::Unretained(&device_cb)); ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_, &mock_sdp_, &mock_volume_)); connection_handler_ = ConnectionHandler::Get(); diff --git a/system/profile/avrcp/tests/avrcp_device_test.cc b/system/profile/avrcp/tests/avrcp_device_test.cc index 7216a5dbf025919175b59bc37954984db99e133f..52672baa59c9e8fe2c53080bf18ecb4b0e457003 100644 --- a/system/profile/avrcp/tests/avrcp_device_test.cc +++ b/system/profile/avrcp/tests/avrcp_device_test.cc @@ -15,7 +15,6 @@ */ #include -#include #include #include #include diff --git a/system/profile/sdp/Android.bp b/system/profile/sdp/Android.bp index a076f462f9ebdf50137efa817eb9b426b9020594..88e491644f45026ccf50c466cf81b227186bea8c 100644 --- a/system/profile/sdp/Android.bp +++ b/system/profile/sdp/Android.bp @@ -23,6 +23,7 @@ cc_library_static { static_libs: [ "lib-bt-packets", "libbluetooth-types", + "libbluetooth_log", ], header_libs: ["libbluetooth_headers"], } @@ -37,6 +38,7 @@ cc_test { host_supported: true, include_dirs: [ "packages/modules/Bluetooth/system/", + "packages/modules/Bluetooth/system/gd", ], srcs: [ "common/test/data_element_reader_test.cc", @@ -46,9 +48,13 @@ cc_test { "lib-bt-packets-avrcp", "lib-bt-packets-base", "libbluetooth-types", + "libbluetooth_log", "libchrome", "libgmock", "sdp_service", ], - shared_libs: ["liblog"], + shared_libs: [ + "libbase", + "liblog", + ], } diff --git a/system/profile/sdp/common/data_element_reader.cc b/system/profile/sdp/common/data_element_reader.cc index 992e7c8b87397219ee7d01ae5403cb99719caa3b..5bba1905768b021c9386d6697d4b9320440cbc57 100644 --- a/system/profile/sdp/common/data_element_reader.cc +++ b/system/profile/sdp/common/data_element_reader.cc @@ -16,7 +16,7 @@ #include "data_element_reader.h" -#include +#include #include @@ -27,19 +27,19 @@ // reader to extract without overflowing. end_ - it_ should never be negative // so casting it to a size_t is always safe. If it does fail, set it_ to end_ // so that all additional readings fail. -#define CHECK_REMAINING_LEN(x) \ - do { \ - if ((size_t)(end_ - it_) < x) { \ - LOG(WARNING) << __func__ << ": Extract would read past end of data."; \ - return ParseFail(); \ - } \ +#define CHECK_REMAINING_LEN(x) \ + do { \ + if ((size_t)(end_ - it_) < x) { \ + log::warn("Extract would read past end of data."); \ + return ParseFail(); \ + } \ } while (0) namespace bluetooth { namespace sdp { DataElementReader::DataElement DataElementReader::ReadNext() { - if (it_ > end_) LOG(FATAL) << "Beginning of buffer is past end of buffer."; + if (it_ > end_) log::fatal("Beginning of buffer is past end of buffer."); if (it_ == end_) return std::monostate(); uint8_t descriptor = *it_++; @@ -48,14 +48,14 @@ DataElementReader::DataElement DataElementReader::ReadNext() { // All types with a value greater than URL are currently reserved. if (type > DataElementType::MAX_VALUE) { - LOG(WARNING) << __func__ << ": Trying to use a reserved data element type"; + log::warn("Trying to use a reserved data element type"); return ParseFail(); } switch (type) { case DataElementType::BOOLEAN: if (size != DataElementSize::BYTE1) { - LOG(WARNING) << __func__ << ": Invalid size for bool: " << size; + log::warn("Invalid size for bool: {}", size); return ParseFail(); } @@ -75,7 +75,7 @@ DataElementReader::DataElement DataElementReader::ReadNext() { // TODO: The other data element types are never used in the previous SDP // implementation. We should properly handle them in the future though // for completeness. - LOG(ERROR) << __func__ << ": Unhandled Data Element Type: " << type; + log::error("Unhandled Data Element Type: {}", type); } return ParseFail(); @@ -120,7 +120,7 @@ DataElementReader::DataElement DataElementReader::ReadSignedInt( case DataElementSize::BYTE16: return ReadLargeInt(); default: - LOG(WARNING) << __func__ << ": Invalid size for int: " << size; + log::warn("Invalid size for int: {}", size); } return ParseFail(); @@ -140,7 +140,7 @@ DataElementReader::DataElement DataElementReader::ReadUnsignedInt( case DataElementSize::BYTE16: return ReadLargeInt(); default: - LOG(WARNING) << __func__ << ": Invalid size for uint: " << size; + log::warn("Invalid size for uint: {}", size); } return ParseFail(); @@ -169,7 +169,7 @@ DataElementReader::DataElement DataElementReader::ReadUuid( return Uuid::From128BitBE(uuid_array); } - LOG(WARNING) << __func__ << ": Invalid size for UUID: " << size; + log::warn("Invalid size for UUID: {}", size); return ParseFail(); } @@ -191,7 +191,7 @@ DataElementReader::DataElement DataElementReader::ReadString( num_bytes = it_.extractBE(); break; default: - LOG(WARNING) << __func__ << ": Invalid size for string: " << size; + log::warn("Invalid size for string: {}", size); return ParseFail(); } @@ -223,7 +223,7 @@ DataElementReader::DataElement DataElementReader::ReadSequence( num_bytes = it_.extractBE(); break; default: - LOG(WARNING) << __func__ << ": Invalid size for string: " << size; + log::warn("Invalid size for string: {}", size); return ParseFail(); } diff --git a/system/profile/sdp/common/test/data_element_reader_test.cc b/system/profile/sdp/common/test/data_element_reader_test.cc index 167f7d191f9f72d932487deeaff1673bf6c96da3..429eaba80522fbf1eebe3b3b2a19b993f6ed2da8 100644 --- a/system/profile/sdp/common/test/data_element_reader_test.cc +++ b/system/profile/sdp/common/test/data_element_reader_test.cc @@ -16,7 +16,6 @@ #include "common/data_element_reader.h" -#include #include #include "types/bluetooth/uuid.h" diff --git a/system/profile/sdp/sdp_logging_helper.h b/system/profile/sdp/sdp_logging_helper.h index 253ce925c3c86b2b6904586ee8bf1619428eecef..d556b6e5367a4c03d043993234d7e0244b1d8f9a 100644 --- a/system/profile/sdp/sdp_logging_helper.h +++ b/system/profile/sdp/sdp_logging_helper.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include #include @@ -116,3 +118,14 @@ inline std::ostream& operator<<(std::ostream& os, const DataElementSize& size) { } // namespace sdp } // namespace bluetooth + +namespace fmt { +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +template <> +struct formatter : ostream_formatter {}; +} // namespace fmt diff --git a/system/rust/Android.bp b/system/rust/Android.bp index 925ec1bd3ecec3286f01d3a0237110b0a5fa95b0..d2cc3ae9e86a655dd006720bc6128e9f0af59dbf 100644 --- a/system/rust/Android.bp +++ b/system/rust/Android.bp @@ -119,13 +119,13 @@ cc_library_static { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/include", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", "packages/modules/Bluetooth/system/types", ], export_include_dirs: ["."], static_libs: [ "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt_shim_bridge", "libbt_shim_ffi", "libchrome", @@ -145,6 +145,11 @@ cc_library_static { generated_sources: ["libbluetooth_core_rs_bridge_codegen"], apex_available: ["com.android.btservices"], min_sdk_version: "Tiramisu", + // Bug: 286537287 this library gets linked with Rust objects but cross-language LTO + // isn't supported yet. + lto: { + never: true, + }, } /// FFI codegen diff --git a/system/rust/BUILD.gn b/system/rust/BUILD.gn index bc6e7912a5be5c70d44db1625b2c038cd880bf37..202e9dff76014dbf22041146c44a35ba6eee21fb 100644 --- a/system/rust/BUILD.gn +++ b/system/rust/BUILD.gn @@ -32,12 +32,14 @@ static_library("core_rs") { "//bt/system/rust", "//bt/system/include", "//bt/system/stack/include", - "//bt/system/internal_include", "//bt/system/gd", "//bt/system/types", ] - configs += [ "//bt/system:target_defaults" ] + configs += [ + "//bt/system:target_defaults", + "//bt/system/log:log_defaults", + ] deps = [ ":cxxlibheader", diff --git a/system/rust/src/core/ffi/module.cc b/system/rust/src/core/ffi/module.cc index b2c77c433a4072d39c630068530b1a9873217211..ace30e9289472847d645bb5687f996f7208549d2 100644 --- a/system/rust/src/core/ffi/module.cc +++ b/system/rust/src/core/ffi/module.cc @@ -19,7 +19,7 @@ #include #include "btcore/include/module.h" -#include "osi/include/log.h" +#include "os/log.h" #ifndef TARGET_FLOSS #include "src/connection/ffi/connection_shim.h" #include "src/core/ffi.rs.h" diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 06e7c2f28319e0470cd495d094eaa8c7891285b7..afca1445f95702a6265e05067b20ada02c908794 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -16,11 +16,11 @@ cc_library_static { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/include", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", "packages/modules/Bluetooth/system/types", ], static_libs: [ + "libbluetooth_log", "libbt_shim_bridge", ], shared_libs: [ @@ -68,11 +68,9 @@ cc_library_static { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/sys", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/device/include", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/gd/hal", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/udrv/include", ], generated_headers: [ @@ -84,6 +82,7 @@ cc_library_static { "a2dp/a2dp_aac_encoder.cc", "a2dp/a2dp_api.cc", "a2dp/a2dp_codec_config.cc", + "a2dp/a2dp_ext.cc", "a2dp/a2dp_sbc.cc", "a2dp/a2dp_sbc_decoder.cc", "a2dp/a2dp_sbc_encoder.cc", @@ -140,6 +139,7 @@ cc_library_static { static_libs: [ "libbluetooth_crypto_toolbox", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-btu-main-thread", "libbt-hci", "libbt-platform-protos-lite", @@ -202,9 +202,7 @@ cc_library_static { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/bta/include", "packages/modules/Bluetooth/system/bta/sys", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/udrv/include", ], srcs: [ @@ -212,14 +210,12 @@ cc_library_static { "acl/acl.cc", "acl/ble_acl.cc", "acl/btm_acl.cc", - "acl/btm_ble_connection_establishment.cc", "acl/btm_pm.cc", "arbiter/acl_arbiter.cc", "btm/ble_scanner_hci_interface.cc", "btm/btm_ble.cc", "btm/btm_ble_addr.cc", "btm/btm_ble_adv_filter.cc", - "btm/btm_ble_batchscan.cc", "btm/btm_ble_bgconn.cc", "btm/btm_ble_cont_energy.cc", "btm/btm_ble_gap.cc", @@ -239,6 +235,7 @@ cc_library_static { "btm/btm_sec.cc", "btm/btm_sec_cb.cc", "btm/btm_security_client_interface.cc", + "btm/security_event_parser.cc", "btu/btu_event.cc", "btu/btu_hcif.cc", "eatt/eatt.cc", @@ -259,6 +256,7 @@ cc_library_static { "hcic/hcicmds.cc", "l2cap/l2c_api.cc", "l2cap/l2c_ble.cc", + "l2cap/l2c_ble_conn_params.cc", "l2cap/l2c_csm.cc", "l2cap/l2c_fcr.cc", "l2cap/l2c_link.cc", @@ -300,10 +298,12 @@ cc_library_static { "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-hci", "libbt-platform-protos-lite", "libbt_shim_bridge", "libcom.android.sysprop.bluetooth.wrapped", + "server_configurable_flags", ], shared_libs: [ "libPlatformProperties", @@ -320,7 +320,6 @@ cc_defaults { name: "btstack_fuzzer_default", host_supported: true, cflags: [ - "-DHAS_NO_BDROID_BUILDCFG", "-Wall", "-Werror", "-Wextra", @@ -331,15 +330,17 @@ cc_defaults { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/include", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", "packages/modules/Bluetooth/system/test/common", "packages/modules/Bluetooth/system/types", ], static_libs: [ "libchrome", + "libgmock", + "libgtest", ], shared_libs: [ + "libbase", "liblog", ], target: { @@ -408,6 +409,7 @@ cc_fuzz { ], static_libs: [ "libbluetooth-types", + "libbluetooth_log", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", @@ -429,6 +431,7 @@ cc_fuzz { "BluetoothGeneratedDumpsysDataSchema_h", ], srcs: [ + ":BluetoothPacketSources", ":TestCommonMockFunctions", ":TestCommonStackConfig", ":TestFakeOsi", @@ -436,6 +439,7 @@ cc_fuzz { ":TestMockDevice", ":TestMockGdOsLoggingLogRedaction", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockRustFfi", ":TestMockSrvcDis", ":TestMockStackAcl", @@ -449,16 +453,20 @@ cc_fuzz { "fuzzers/gatt_fuzzer.cc", "gatt/*.cc", ], + shared_libs: [ + "server_configurable_flags", + ], static_libs: [ + "bluetooth_flags_c_lib", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_smp_pdl", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", - "libgmock", ], } @@ -477,6 +485,7 @@ cc_fuzz { "BluetoothGeneratedDumpsysDataSchema_h", ], srcs: [ + ":BluetoothPacketSources", ":TestCommonMockFunctions", ":TestCommonStackConfig", ":TestFakeOsi", @@ -484,6 +493,7 @@ cc_fuzz { ":TestMockDevice", ":TestMockGdOsLoggingLogRedaction", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackAcl", ":TestMockStackBtm", ":TestMockStackHcic", @@ -492,16 +502,20 @@ cc_fuzz { "fuzzers/smp_fuzzer.cc", "smp/*.cc", // add other sources files (p256 related) under smp into this test ], + shared_libs: [ + "server_configurable_flags", + ], static_libs: [ + "bluetooth_flags_c_lib", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_smp_pdl", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", - "libgmock", ], } @@ -520,6 +534,7 @@ cc_fuzz { "BluetoothGeneratedDumpsysDataSchema_h", ], srcs: [ + ":BluetoothPacketSources", ":TestCommonMockFunctions", ":TestCommonStackConfig", ":TestFakeOsi", @@ -527,6 +542,7 @@ cc_fuzz { ":TestMockDevice", ":TestMockGdOsLoggingLogRedaction", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackAcl", ":TestMockStackBtm", ":TestMockStackHcic", @@ -539,11 +555,11 @@ cc_fuzz { "libbluetooth-types", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_smp_pdl", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", - "libgmock", ], } @@ -562,6 +578,7 @@ cc_fuzz { "BluetoothGeneratedDumpsysDataSchema_h", ], srcs: [ + ":BluetoothPacketSources", ":TestCommonMockFunctions", ":TestCommonStackConfig", ":TestFakeOsi", @@ -569,6 +586,7 @@ cc_fuzz { ":TestMockDevice", ":TestMockGdOsLoggingLogRedaction", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackAcl", ":TestMockStackBtm", ":TestMockStackHcic", @@ -584,12 +602,12 @@ cc_fuzz { "libbluetooth-types", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_smp_pdl", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", "libcom.android.sysprop.bluetooth.wrapped", - "libgmock", ], } @@ -608,6 +626,7 @@ cc_fuzz { "BluetoothGeneratedDumpsysDataSchema_h", ], srcs: [ + ":BluetoothPacketSources", ":TestCommonMockFunctions", ":TestCommonStackConfig", ":TestFakeOsi", @@ -615,6 +634,7 @@ cc_fuzz { ":TestMockDevice", ":TestMockGdOsLoggingLogRedaction", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackAcl", ":TestMockStackBtm", ":TestMockStackHcic", @@ -626,12 +646,11 @@ cc_fuzz { "libbluetooth-types", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_smp_pdl", "libbt-platform-protos-lite", "libbt_shim_bridge", "libbt_shim_ffi", - "libgmock", - "libosi", ], target: { android: { @@ -648,7 +667,7 @@ cc_test { defaults: [ "fluoride_defaults", "latest_android_hardware_audio_common_ndk_static", - "latest_android_hardware_bluetooth_audio_ndk_shared", + "latest_android_hardware_bluetooth_audio_ndk_static", "latest_android_media_audio_common_types_ndk_static", "mts_defaults", ], @@ -659,7 +678,6 @@ cc_test { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", ], srcs: [ "test/gatt/gatt_api_test.cc", @@ -667,15 +685,12 @@ cc_test { "test/stack_avrcp_test.cc", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", "libPlatformProperties", "libaaudio", - "libbinder_ndk", "libcrypto", "libcutils", "libdl", - "libfmq", + "libevent", "libhidlbase", "liblog", "libstatssocket", @@ -684,23 +699,31 @@ cc_test { "server_configurable_flags", ], static_libs: [ + "android.hardware.audio.common@5.0", "android.hardware.bluetooth.a2dp@1.0", - "android.hardware.bluetooth@1.0", - "android.hardware.bluetooth@1.1", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", "android.hardware.common-V2-ndk", "android.hardware.common.fmq-V1-ndk", + "android.system.suspend-V1-ndk", "android.system.suspend.control-V1-ndk", "libFraunhoferAAC", + "libaudio-a2dp-hw-utils", + "libbase", "libbluetooth-dumpsys", + "libbluetooth-for-tests", + "libbluetooth-gdx", "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", "libbt-btu-main-thread", "libbt-common", "libbt-hci", + "libbt-jni-thread", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", @@ -711,6 +734,7 @@ cc_test { "libbtif", "libbtif-core", "libchrome", + "libfmq", "libg722codec", "liblc3", "libopus", @@ -719,9 +743,22 @@ cc_test { "libstatslog_bt", "libudrv-uipc", ], - whole_static_libs: [ - "libbluetooth-for-tests", - ], + target: { + android: { + shared_libs: [ + "libbinder_ndk", + ], + static_libs: [ + "android.hardware.bluetooth@1.0", + "android.hardware.bluetooth@1.1", + ], + }, + host: { + static_libs: [ + "libbinder_ndk", + ], + }, + }, header_libs: ["libbluetooth_headers"], } @@ -745,12 +782,12 @@ cc_test { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/gd/hal", - "packages/modules/Bluetooth/system/internal_include", ], srcs: [ ":TestCommonMockFunctions", ":TestMockHci", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackMetrics", "rfcomm/port_api.cc", "rfcomm/port_rfc.cc", @@ -778,11 +815,13 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_smp_pdl", "libbt-btu-main-thread", "libbt-common", @@ -815,6 +854,7 @@ cc_test { cc_test { name: "net_test_stack_smp", defaults: [ + "bluetooth_flatbuffer_bundler_defaults", "fluoride_defaults", "mts_defaults", ], @@ -830,7 +870,6 @@ cc_test { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/include", - "packages/modules/Bluetooth/system/internal_include", ], srcs: [ ":TestCommonMainHandler", @@ -838,6 +877,7 @@ cc_test { ":TestMockBtif", ":TestMockDevice", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackAcl", ":TestMockStackBtm", ":TestMockStackHcic", @@ -861,13 +901,16 @@ cc_test { shared_libs: [ "libcrypto", "libcutils", + "server_configurable_flags", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", "libbluetooth_hci_pdl", "libbluetooth_l2cap_pdl", + "libbluetooth_log", "libbluetooth_smp_pdl", "libbt-btu-main-thread", "libbt-common", @@ -913,6 +956,7 @@ cc_test { static_libs: [ "android.system.suspend.control-V1-ndk", "libbluetooth-types", + "libbluetooth_log", "libgmock", "liblog", ], @@ -935,7 +979,6 @@ cc_test { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", ], srcs: [ ":TestCommonMainHandler", @@ -947,8 +990,10 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -992,7 +1037,6 @@ cc_test { "gatt/gatt_utils.cc", "test/common/mock_eatt.cc", "test/common/mock_gatt_layer.cc", - "test/common/mock_main_shim.cc", "test/gatt/gatt_sr_test.cc", ], shared_libs: [ @@ -1000,9 +1044,11 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -1069,9 +1115,11 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -1119,7 +1167,6 @@ cc_test { "external/libldac/inc", "external/libopus/include", "packages/modules/Bluetooth/system", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/embdrv/encoder_for_aptxhd/include", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/stack/include", @@ -1145,12 +1192,14 @@ cc_test { ], srcs: [ ":TestCommonMockFunctions", + ":TestMockAudioHalInterface", ":TestMockBta", ":TestMockStackA2dpApi", "a2dp/a2dp_aac.cc", "a2dp/a2dp_aac_decoder.cc", "a2dp/a2dp_aac_encoder.cc", "a2dp/a2dp_codec_config.cc", + "a2dp/a2dp_ext.cc", "a2dp/a2dp_sbc.cc", "a2dp/a2dp_sbc_decoder.cc", "a2dp/a2dp_sbc_encoder.cc", @@ -1184,9 +1233,11 @@ cc_test { ], static_libs: [ "libFraunhoferAAC", + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-sbc-decoder", "libbt-sbc-encoder", @@ -1239,7 +1290,9 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libchrome", @@ -1286,7 +1339,6 @@ cc_test { "gatt/gatt_utils.cc", "test/common/mock_eatt.cc", "test/common/mock_gatt_layer.cc", - "test/common/mock_main_shim.cc", "test/gatt/mock_gatt_utils_ref.cc", "test/stack_gatt_sr_hash_test.cc", ], @@ -1295,9 +1347,11 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -1335,12 +1389,19 @@ cc_test { "include", "test/common", ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + ], include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", ], srcs: [ + ":BluetoothPacketSources", + ":TestCommonMockFunctions", ":TestCommonStackConfig", + ":TestMockMainShim", + ":TestMockMainShimEntry", "btm/btm_iso.cc", "test/btm_iso_test.cc", "test/common/mock_controller.cc", @@ -1348,10 +1409,15 @@ cc_test { "test/common/mock_hcic_layer.cc", ], static_libs: [ + "libbase", "libbluetooth-types", + "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-common", + "libbt-platform-protos-lite", "libbt_shim_bridge", "libchrome", + "libflatbuffers-cpp", "libgmock", "liblog", "libosi", @@ -1393,7 +1459,6 @@ cc_test { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", ], srcs: [ ":TestCommonMainHandler", @@ -1412,8 +1477,10 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbt_shim_ffi", @@ -1445,6 +1512,7 @@ cc_test { unit_test: true, }, defaults: [ + "bluetooth_flatbuffer_bundler_defaults", "fluoride_defaults", "mts_defaults", ], @@ -1476,6 +1544,7 @@ cc_test { ":TestMockLegacyHciInterface", ":TestMockMainBte", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockRustFfi", ":TestMockStackBtu", ":TestMockStackGap", @@ -1487,13 +1556,11 @@ cc_test { "acl/acl.cc", "acl/ble_acl.cc", "acl/btm_acl.cc", - "acl/btm_ble_connection_establishment.cc", "acl/btm_pm.cc", "btm/ble_scanner_hci_interface.cc", "btm/btm_ble.cc", "btm/btm_ble_addr.cc", "btm/btm_ble_adv_filter.cc", - "btm/btm_ble_batchscan.cc", "btm/btm_ble_bgconn.cc", "btm/btm_ble_cont_energy.cc", "btm/btm_ble_gap.cc", @@ -1517,10 +1584,12 @@ cc_test { "btm/hfp_lc3_encoder.cc", "btm/hfp_msbc_decoder.cc", "btm/hfp_msbc_encoder.cc", + "btm/security_event_parser.cc", "metrics/stack_metrics_logging.cc", "test/btm/peer_packet_types_test.cc", "test/btm/sco_hci_test.cc", "test/btm/sco_pkt_status_test.cc", + "test/btm/stack_btm_dev_test.cc", "test/btm/stack_btm_power_mode_test.cc", "test/btm/stack_btm_regression_tests.cc", "test/btm/stack_btm_sec_test.cc", @@ -1533,6 +1602,7 @@ cc_test { "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt-sbc-decoder", @@ -1591,6 +1661,7 @@ cc_test { ], static_libs: [ "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbt-common", "libbt_shim_bridge", "libbtdevice", @@ -1646,8 +1717,10 @@ cc_test { "test/hid/stack_hid_test.cc", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -1710,6 +1783,7 @@ cc_test { ":TestMockHci", ":TestMockLegacyHciCommands", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackAcl", ":TestMockStackBtm", ":TestMockStackHcic", @@ -1722,8 +1796,10 @@ cc_test { "test/stack_btu_test.cc", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -1783,6 +1859,7 @@ cc_test { ":TestMockHci", ":TestMockLegacyHciCommands", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockRustFfi", ":TestMockSrvcDis", ":TestMockStackAcl", @@ -1806,9 +1883,12 @@ cc_test { "test/gatt/stack_gatt_test.cc", ], static_libs: [ + "bluetooth_flags_c_lib", + "libbase", "libbluetooth-types", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -1816,6 +1896,7 @@ cc_test { "libbtdevice", "libchrome", "libevent", + "libflagtest", "libgmock", "liblog", "libosi", @@ -1823,9 +1904,11 @@ cc_test { "libstatslog_bt", ], shared_libs: [ + "libbase", "libbinder_ndk", "libcrypto", "libcutils", + "server_configurable_flags", ], target: { android: { @@ -1874,8 +1957,10 @@ cc_test { ":TestMockBta", ":TestMockBtif", ":TestMockHci", + ":TestMockJni", ":TestMockLegacyHciCommands", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockStackAcl", ":TestMockStackBtm", ":TestMockStackHcic", @@ -1883,6 +1968,7 @@ cc_test { ":TestMockStackSmp", "l2cap/l2c_api.cc", "l2cap/l2c_ble.cc", + "l2cap/l2c_ble_conn_params.cc", "l2cap/l2c_csm.cc", "l2cap/l2c_fcr.cc", "l2cap/l2c_link.cc", @@ -1893,6 +1979,7 @@ cc_test { static_libs: [ "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -1940,6 +2027,7 @@ cc_test { test_suites: ["general-tests"], host_supported: true, defaults: [ + "bluetooth_flatbuffer_bundler_defaults", "fluoride_defaults", "mts_defaults", ], @@ -1967,6 +2055,7 @@ cc_test { ":TestMockLegacyHciCommands", ":TestMockLegacyHciInterface", ":TestMockMainShim", + ":TestMockMainShimEntry", ":TestMockRustFfi", ":TestMockStackBtm", ":TestMockStackBtu", @@ -1983,6 +2072,7 @@ cc_test { static_libs: [ "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", @@ -2038,7 +2128,6 @@ cc_test { "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/device/include/", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/btm", ], srcs: [ @@ -2056,8 +2145,10 @@ cc_test { "libcutils", ], static_libs: [ + "libbase", "libbluetooth-types", "libbluetooth_gd", + "libbluetooth_log", "libbt-common", "libbt-platform-protos-lite", "libbt_shim_bridge", diff --git a/system/stack/BUILD.gn b/system/stack/BUILD.gn index 4592e3629ee8d6692a97ada98784197158c887a4..07999bc27f7d4b46a1d5f22ed5e2aae7ec8e36bb 100644 --- a/system/stack/BUILD.gn +++ b/system/stack/BUILD.gn @@ -34,7 +34,6 @@ source_set("nonstandard_codecs") { "//bt/system/bta/include", "//bt/system/btif/include", "//bt/system/include", - "//bt/system/internal_include", "//bt/system/stack", "//bt/system/stack/include", "//bt/system/utils/include", @@ -47,6 +46,7 @@ source_set("nonstandard_codecs") { configs += [ "//bt/system:target_defaults", + "//bt/system/log:log_defaults", ] } } @@ -55,6 +55,7 @@ source_set("stack") { sources = [ "a2dp/a2dp_api.cc", "a2dp/a2dp_codec_config.cc", + "a2dp/a2dp_ext.cc", "a2dp/a2dp_sbc.cc", "a2dp/a2dp_sbc_decoder.cc", "a2dp/a2dp_sbc_encoder.cc", @@ -62,7 +63,6 @@ source_set("stack") { "acl/acl.cc", "acl/ble_acl.cc", "acl/btm_acl.cc", - "acl/btm_ble_connection_establishment.cc", "acl/btm_pm.cc", "arbiter/acl_arbiter.cc", "avct/avct_api.cc", @@ -95,7 +95,6 @@ source_set("stack") { "btm/btm_ble.cc", "btm/btm_ble_addr.cc", "btm/btm_ble_adv_filter.cc", - "btm/btm_ble_batchscan.cc", "btm/btm_ble_bgconn.cc", "btm/btm_ble_cont_energy.cc", "btm/btm_ble_gap.cc", @@ -115,6 +114,7 @@ source_set("stack") { "btm/btm_sec.cc", "btm/btm_sec_cb.cc", "btm/btm_security_client_interface.cc", + "btm/security_event_parser.cc", "btm/hfp_lc3_encoder_linux.cc", "btm/hfp_lc3_decoder_linux.cc", "btm/hfp_msbc_encoder.cc", @@ -144,6 +144,7 @@ source_set("stack") { "hid/hidh_conn.cc", "l2cap/l2c_api.cc", "l2cap/l2c_ble.cc", + "l2cap/l2c_ble_conn_params.cc", "l2cap/l2c_csm.cc", "l2cap/l2c_fcr.cc", "l2cap/l2c_link.cc", @@ -207,7 +208,6 @@ source_set("stack") { "//bt/system/ctrlr/include", "//bt/system/gd", "//bt/system/hcis", - "//bt/system/internal_include", "//bt/system/linux_include", "//bt/system/rpc/include", "//bt/system/types", @@ -223,11 +223,11 @@ source_set("stack") { "//bt/system/gd/rust/shim:init_flags_bridge_header", "//bt/system/stack/mmc", "//bt/system/types", - "//bt/system/types", ] configs += [ "//bt/system:target_defaults", + "//bt/system/log:log_defaults", ] } @@ -245,7 +245,6 @@ if (use.test) { "btm", "include", "test/common", - "//bt/system/internal_include", "//bt/system/packet/tests", ] @@ -275,7 +274,6 @@ if (defined(use.android) && use.android) { "//bt/system/bta/include", "//bt/system/bta/sys", "//bt/system/embdrv/sbc/encoder/include", - "//bt/system/internal_include", "//bt/system/stack/a2dp", "//bt/system/stack/btm", "//bt/system/stack/include", @@ -285,6 +283,7 @@ if (defined(use.android) && use.android) { libs = [ "dl", + "fmt", "pthread", "resolv", "rt", @@ -325,11 +324,9 @@ if (defined(use.android) && use.android) { include_dirs = [ "//bt/system/", "//bt/system/linux_include", - "//bt/system/internal_include", "//bt/system/bta/include", "//bt/system/bta/sys", "//bt/system/embdrv/sbc/encoder/include", - "//bt/system/internal_include", "//bt/system/stack/a2dp", "//bt/system/stack/l2cap", "//bt/system/stack/btm", @@ -340,6 +337,7 @@ if (defined(use.android) && use.android) { libs = [ "dl", + "fmt", "pthread", "resolv", "rt", diff --git a/system/stack/a2dp/a2dp_aac.cc b/system/stack/a2dp/a2dp_aac.cc index 4cb21dec8dafd9a6106871ac7962432600f6f3a8..05b7412aef255f6b133858b7607a66d5faadece9 100644 --- a/system/stack/a2dp/a2dp_aac.cc +++ b/system/stack/a2dp/a2dp_aac.cc @@ -25,11 +25,13 @@ #include "a2dp_aac.h" -#include +#include #include #include "a2dp_aac_decoder.h" #include "a2dp_aac_encoder.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/osi.h" #include "osi/include/properties.h" @@ -38,6 +40,8 @@ #define A2DP_AAC_DEFAULT_BITRATE 320000 // 320 kbps #define A2DP_AAC_MIN_BITRATE 64000 // 64 kbps +using namespace bluetooth; + // data type for the AAC Codec Information Element */ // NOTE: bits_per_sample is needed only for AAC encoder initialization. typedef struct { @@ -294,23 +298,22 @@ static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAac( /* parse configuration */ status = A2DP_ParseInfoAac(&cfg_cie, p_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: parsing failed %d", __func__, status); + log::error("parsing failed {}", status); return status; } /* verify that each parameter is in range */ - LOG_VERBOSE("%s: Object Type peer: 0x%x, capability 0x%x", __func__, - cfg_cie.objectType, p_cap->objectType); - LOG_VERBOSE("%s: Sample Rate peer: %u, capability %u", __func__, - cfg_cie.sampleRate, p_cap->sampleRate); - LOG_VERBOSE("%s: Channel Mode peer: 0x%x, capability 0x%x", __func__, - cfg_cie.channelMode, p_cap->channelMode); - LOG_VERBOSE("%s: Variable Bit Rate Support peer: 0x%x, capability 0x%x", - __func__, cfg_cie.variableBitRateSupport, - p_cap->variableBitRateSupport); - LOG_VERBOSE("%s: Bit Rate peer: %u, capability %u", __func__, cfg_cie.bitRate, - p_cap->bitRate); + log::verbose("Object Type peer: 0x{:x}, capability 0x{:x}", + cfg_cie.objectType, p_cap->objectType); + log::verbose("Sample Rate peer: {}, capability {}", cfg_cie.sampleRate, + p_cap->sampleRate); + log::verbose("Channel Mode peer: 0x{:x}, capability 0x{:x}", + cfg_cie.channelMode, p_cap->channelMode); + log::verbose("Variable Bit Rate Support peer: 0x{:x}, capability 0x{:x}", + cfg_cie.variableBitRateSupport, p_cap->variableBitRateSupport); + log::verbose("Bit Rate peer: {}, capability {}", cfg_cie.bitRate, + p_cap->bitRate); /* Object Type */ if ((cfg_cie.objectType & p_cap->objectType) == 0) return A2DP_BAD_OBJ_TYPE; @@ -342,12 +345,12 @@ bool A2DP_CodecTypeEqualsAac(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoAac(&aac_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -363,12 +366,12 @@ bool A2DP_CodecEqualsAac(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoAac(&aac_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -386,7 +389,7 @@ int A2DP_GetTrackSampleRateAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -426,7 +429,7 @@ int A2DP_GetTrackBitsPerSampleAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -440,7 +443,7 @@ int A2DP_GetTrackChannelCountAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -460,7 +463,7 @@ int A2DP_GetSinkTrackChannelTypeAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -480,7 +483,7 @@ int A2DP_GetObjectTypeCodeAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -503,7 +506,7 @@ int A2DP_GetChannelModeCodeAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -524,7 +527,7 @@ int A2DP_GetVariableBitRateSupportAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -545,7 +548,7 @@ int A2DP_GetBitRateAac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -558,7 +561,7 @@ int A2DP_ComputeMaxBitRateAac(const uint8_t* p_codec_info, uint16_t mtu) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAac(&aac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -795,7 +798,7 @@ bool A2dpCodecConfigAacSource::init() { // Load the encoder if (!A2DP_LoadEncoderAac()) { - LOG_ERROR("%s: cannot load the encoder", __func__); + log::error("cannot load the encoder"); return false; } @@ -1031,8 +1034,7 @@ bool A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_info, tA2DP_STATUS status = A2DP_ParseInfoAac(&peer_info_cie, p_peer_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -1169,10 +1171,10 @@ bool A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) { - LOG_ERROR( - "%s: cannot match sample frequency: source caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_aac_caps->sampleRate, peer_info_cie.sampleRate); + log::error( + "cannot match sample frequency: source caps = 0x{:x} peer info = " + "0x{:x}", + p_a2dp_aac_caps->sampleRate, peer_info_cie.sampleRate); goto fail; } @@ -1244,10 +1246,10 @@ bool A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) { - LOG_ERROR( - "%s: cannot match bits per sample: default = 0x%x " - "user preference = 0x%x", - __func__, a2dp_aac_default_config.bits_per_sample, + log::error( + "cannot match bits per sample: default = 0x{:x} user preference = " + "0x{:x}", + a2dp_aac_default_config.bits_per_sample, codec_user_config_.bits_per_sample); goto fail; } @@ -1319,10 +1321,9 @@ bool A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) { - LOG_ERROR( - "%s: cannot match channel mode: source caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_aac_caps->channelMode, peer_info_cie.channelMode); + log::error( + "cannot match channel mode: source caps = 0x{:x} peer info = 0x{:x}", + p_a2dp_aac_caps->channelMode, peer_info_cie.channelMode); goto fail; } @@ -1423,8 +1424,7 @@ bool A2dpCodecConfigAacBase::setPeerCodecCapabilities( tA2DP_STATUS status = A2DP_ParseInfoAac(&peer_info_cie, p_peer_codec_capabilities, true); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -1499,7 +1499,7 @@ bool A2dpCodecConfigAacSink::init() { // Load the decoder if (!A2DP_LoadDecoderAac()) { - LOG_ERROR("%s: cannot load the decoder", __func__); + log::error("cannot load the decoder"); return false; } diff --git a/system/stack/a2dp/a2dp_aac_decoder.cc b/system/stack/a2dp/a2dp_aac_decoder.cc index 639512b0c1b38ff3ee6c78997000a618e09066f5..b45bdce8e43c62a2206adc1a91a2791f9f6ea1a0 100644 --- a/system/stack/a2dp/a2dp_aac_decoder.cc +++ b/system/stack/a2dp/a2dp_aac_decoder.cc @@ -19,7 +19,7 @@ #include "a2dp_aac_decoder.h" #include -#include +#include #include "os/log.h" #include "osi/include/allocator.h" @@ -27,6 +27,8 @@ #define DECODE_BUF_LEN (8 * 2 * 1024) +using namespace bluetooth; + typedef struct { HANDLE_AACDECODER aac_handle; bool has_aac_handle; // True if aac_handle is valid @@ -70,8 +72,7 @@ bool a2dp_aac_decoder_decode_packet(BT_HDR* p_buf) { AAC_DECODER_ERROR err = aacDecoder_Fill(a2dp_aac_decoder_cb.aac_handle, &pBuffer, &bufferSize, &bytesValid); if (err != AAC_DEC_OK) { - LOG_ERROR("%s: aacDecoder_Fill failed: 0x%x", __func__, - static_cast(err)); + log::error("aacDecoder_Fill failed: 0x{:x}", static_cast(err)); return false; } @@ -83,15 +84,15 @@ bool a2dp_aac_decoder_decode_packet(BT_HDR* p_buf) { break; } if (err != AAC_DEC_OK) { - LOG_ERROR("%s: aacDecoder_DecodeFrame failed: 0x%x", __func__, - static_cast(err)); + log::error("aacDecoder_DecodeFrame failed: 0x{:x}", + static_cast(err)); break; } CStreamInfo* info = aacDecoder_GetStreamInfo(a2dp_aac_decoder_cb.aac_handle); if (!info || info->sampleRate <= 0) { - LOG_ERROR("%s: Invalid stream info", __func__); + log::error("Invalid stream info"); break; } diff --git a/system/stack/a2dp/a2dp_aac_encoder.cc b/system/stack/a2dp/a2dp_aac_encoder.cc index 1dd893e6a7b2c7a4b5d797af48b6bf05f5e1f411..7cee8590648c6ca682aab5ccaadad6567cc3c8c3 100644 --- a/system/stack/a2dp/a2dp_aac_encoder.cc +++ b/system/stack/a2dp/a2dp_aac_encoder.cc @@ -19,13 +19,14 @@ #include "a2dp_aac_encoder.h" #include -#include +#include #include #include #include #include "a2dp_aac.h" #include "common/time_util.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -41,6 +42,13 @@ // offset #define A2DP_AAC_OFFSET AVDT_MEDIA_OFFSET +using namespace bluetooth; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + typedef struct { uint32_t sample_rate; uint8_t channel_mode; @@ -162,18 +170,15 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, AACENC_ERROR aac_error = aacEncOpen(&a2dp_aac_encoder_cb.aac_handle, 0, 2 /* max 2 channels: stereo */); if (aac_error != AACENC_OK) { - LOG_ERROR("%s: Cannot open AAC encoder handle: AAC error 0x%x", __func__, - aac_error); + log::error("Cannot open AAC encoder handle: AAC error 0x{:x}", aac_error); return; // TODO: Return an error? } a2dp_aac_encoder_cb.has_aac_handle = true; } if (!a2dp_codec_config->copyOutOtaCodecConfig(codec_info)) { - LOG_ERROR( - "%s: Cannot update the codec encoder for %s: " - "invalid codec config", - __func__, a2dp_codec_config->name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid codec config", + a2dp_codec_config->name().c_str()); return; } const uint8_t* p_codec_info = codec_info; @@ -184,9 +189,9 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, p_feeding_params->bits_per_sample = a2dp_codec_config->getAudioBitsPerSample(); p_feeding_params->channel_count = A2DP_GetTrackChannelCountAac(p_codec_info); - LOG_INFO("%s: sample_rate=%u bits_per_sample=%u channel_count=%u", __func__, - p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, - p_feeding_params->channel_count); + log::info("sample_rate={} bits_per_sample={} channel_count={}", + p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, + p_feeding_params->channel_count); // The codec parameters p_encoder_params->sample_rate = @@ -196,10 +201,10 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, const tA2DP_ENCODER_INIT_PEER_PARAMS& peer_params = a2dp_aac_encoder_cb.peer_params; a2dp_aac_encoder_cb.TxAaMtuSize = adjust_effective_mtu(peer_params); - LOG_INFO("%s: MTU=%d, peer_mtu=%d", __func__, a2dp_aac_encoder_cb.TxAaMtuSize, - peer_params.peer_mtu); - LOG_INFO("%s: sample_rate: %d channel_mode: %d ", __func__, - p_encoder_params->sample_rate, p_encoder_params->channel_mode); + log::info("MTU={}, peer_mtu={}", a2dp_aac_encoder_cb.TxAaMtuSize, + peer_params.peer_mtu); + log::info("sample_rate: {} channel_mode: {} ", p_encoder_params->sample_rate, + p_encoder_params->channel_mode); // Set the encoder's parameters: Audio Object Type - MANDATORY // A2DP_AAC_OBJECT_TYPE_MPEG2_LC -> AOT_AAC_LC @@ -222,19 +227,15 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_param_value = AOT_AAC_SCAL; break; default: - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_AOT: " - "invalid object type %d", - __func__, object_type); + log::error("Cannot set AAC parameter AACENC_AOT: invalid object type {}", + object_type); return; // TODO: Return an error? } aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_AOT, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_AOT to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error("Cannot set AAC parameter AACENC_AOT to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } @@ -243,10 +244,9 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_AUDIOMUXVER, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_AUDIOMUXVER to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_AUDIOMUXVER to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } @@ -255,10 +255,10 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_SIGNALING_MODE, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_SIGNALING_MODE to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_SIGNALING_MODE to {}: AAC error " + "0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } @@ -267,10 +267,9 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_SAMPLERATE, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_SAMPLERATE to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_SAMPLERATE to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } aac_sampling_freq = aac_param_value; // Save for extra usage below @@ -281,22 +280,20 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_peak_bit_rate = A2DP_ComputeMaxBitRateAac(p_codec_info, a2dp_aac_encoder_cb.TxAaMtuSize); aac_param_value = std::min(aac_param_value, aac_peak_bit_rate); - LOG_INFO("%s: MTU = %d Sampling Frequency = %d Bit Rate = %d", __func__, - a2dp_aac_encoder_cb.TxAaMtuSize, aac_sampling_freq, aac_param_value); + log::info("MTU = {} Sampling Frequency = {} Bit Rate = {}", + a2dp_aac_encoder_cb.TxAaMtuSize, aac_sampling_freq, + aac_param_value); if (aac_param_value == -1) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_BITRATE: " - "invalid codec bit rate", - __func__); + log::error( + "Cannot set AAC parameter AACENC_BITRATE: invalid codec bit rate"); return; // TODO: Return an error? } aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_BITRATE, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_BITRATE to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_BITRATE to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } @@ -304,10 +301,9 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_PEAK_BITRATE, aac_peak_bit_rate); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_PEAK_BITRATE to %d: " - "AAC error 0x%x", - __func__, aac_peak_bit_rate, aac_error); + log::error( + "Cannot set AAC parameter AACENC_PEAK_BITRATE to {}: AAC error 0x{:x}", + aac_peak_bit_rate, aac_error); return; // TODO: Return an error? } @@ -320,10 +316,9 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_CHANNELMODE, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_CHANNELMODE to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_CHANNELMODE to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } @@ -332,10 +327,9 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_TRANSMUX, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_TRANSMUX to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_TRANSMUX to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } @@ -344,20 +338,18 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_HEADER_PERIOD, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_HEADER_PERIOD to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_HEADER_PERIOD to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } // Set the encoder's parameters: Variable Bit Rate Support aac_param_value = A2DP_GetVariableBitRateSupportAac(p_codec_info); if (aac_param_value == -1) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_BITRATEMODE: " - "invalid codec bit rate mode", - __func__); + log::error( + "Cannot set AAC parameter AACENC_BITRATEMODE: invalid codec bit rate " + "mode"); return; // TODO: Return an error? } else if (aac_param_value == A2DP_AAC_VARIABLE_BIT_RATE_ENABLED) { // VBR has 5 modes defined in external/aac/libAACenc/src/aacenc.h @@ -381,14 +373,13 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_param_value = static_cast(bitrate_mode) & ~A2DP_AAC_VARIABLE_BIT_RATE_MASK; } - LOG_INFO("%s: AACENC_BITRATEMODE: %d", __func__, aac_param_value); + log::info("AACENC_BITRATEMODE: {}", aac_param_value); aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle, AACENC_BITRATEMODE, aac_param_value); if (aac_error != AACENC_OK) { - LOG_ERROR( - "%s: Cannot set AAC parameter AACENC_BITRATEMODE to %d: " - "AAC error 0x%x", - __func__, aac_param_value, aac_error); + log::error( + "Cannot set AAC parameter AACENC_BITRATEMODE to {}: AAC error 0x{:x}", + aac_param_value, aac_error); return; // TODO: Return an error? } @@ -396,8 +387,8 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, aac_error = aacEncEncode(a2dp_aac_encoder_cb.aac_handle, NULL, NULL, NULL, NULL); if (aac_error != AACENC_OK) { - LOG_ERROR("%s: Cannot complete setting the AAC parameters: AAC error 0x%x", - __func__, aac_error); + log::error("Cannot complete setting the AAC parameters: AAC error 0x{:x}", + aac_error); return; // TODO: Return an error? } @@ -405,18 +396,17 @@ static void a2dp_aac_encoder_update(A2dpCodecConfig* a2dp_codec_config, AACENC_InfoStruct aac_info; aac_error = aacEncInfo(a2dp_aac_encoder_cb.aac_handle, &aac_info); if (aac_error != AACENC_OK) { - LOG_ERROR("%s: Cannot retrieve the AAC encoder info: AAC error 0x%x", - __func__, aac_error); + log::error("Cannot retrieve the AAC encoder info: AAC error 0x{:x}", + aac_error); return; // TODO: Return an error? } p_encoder_params->frame_length = aac_info.frameLength; p_encoder_params->input_channels_n = aac_info.inputChannels; p_encoder_params->max_encoded_buffer_bytes = aac_info.maxOutBufBytes; - LOG_INFO( - "%s: AAC frame_length = %u input_channels_n = %u " - "max_encoded_buffer_bytes = %d", - __func__, p_encoder_params->frame_length, - p_encoder_params->input_channels_n, + log::info( + "AAC frame_length = {} input_channels_n = {} max_encoded_buffer_bytes = " + "{}", + p_encoder_params->frame_length, p_encoder_params->input_channels_n, p_encoder_params->max_encoded_buffer_bytes); // After encoder params ready, reset the feeding state and its interval. @@ -433,7 +423,7 @@ void a2dp_aac_feeding_reset(void) { auto frame_length = a2dp_aac_encoder_cb.aac_encoder_params.frame_length; auto sample_rate = a2dp_aac_encoder_cb.feeding_params.sample_rate; if (frame_length == 0 || sample_rate == 0) { - LOG_WARN("%s: AAC encoder is not configured", __func__); + log::warn("AAC encoder is not configured"); a2dp_aac_encoder_interval_ms = A2DP_AAC_ENCODER_INTERVAL_MS; } else { // PCM data size per AAC frame (bits) @@ -458,9 +448,9 @@ void a2dp_aac_feeding_reset(void) { a2dp_aac_encoder_interval_ms) / 1000; - LOG_INFO("%s: PCM bytes %u per tick %u ms", __func__, - a2dp_aac_encoder_cb.aac_feeding_state.bytes_per_tick, - a2dp_aac_encoder_interval_ms); + log::info("PCM bytes {} per tick {} ms", + a2dp_aac_encoder_cb.aac_feeding_state.bytes_per_tick, + a2dp_aac_encoder_interval_ms); } void a2dp_aac_feeding_flush(void) { @@ -480,8 +470,8 @@ void a2dp_aac_send_frames(uint64_t timestamp_us) { uint8_t nb_iterations = 0; a2dp_aac_get_num_frame_iteration(&nb_iterations, &nb_frame, timestamp_us); - LOG_VERBOSE("%s: Sending %d frames per iteration, %d iterations", __func__, - nb_frame, nb_iterations); + log::verbose("Sending {} frames per iteration, {} iterations", nb_frame, + nb_iterations); if (nb_frame == 0) return; for (uint8_t counter = 0; counter < nb_iterations; counter++) { @@ -504,7 +494,7 @@ static void a2dp_aac_get_num_frame_iteration(uint8_t* num_of_iterations, a2dp_aac_encoder_cb.aac_encoder_params.frame_length * a2dp_aac_encoder_cb.feeding_params.channel_count * a2dp_aac_encoder_cb.feeding_params.bits_per_sample / 8; - LOG_VERBOSE("%s: pcm_bytes_per_frame %u", __func__, pcm_bytes_per_frame); + log::verbose("pcm_bytes_per_frame {}", pcm_bytes_per_frame); uint32_t us_this_tick = a2dp_aac_encoder_interval_ms * 1000; uint64_t now_us = timestamp_us; @@ -521,8 +511,7 @@ static void a2dp_aac_get_num_frame_iteration(uint8_t* num_of_iterations, a2dp_aac_encoder_cb.aac_feeding_state.counter -= result * pcm_bytes_per_frame; nof = result; - LOG_VERBOSE("%s: effective num of frames %u, iterations %u", __func__, nof, - noi); + log::verbose("effective num of frames {}, iterations {}", nof, noi); *num_of_frames = nof; *num_of_iterations = noi; @@ -594,7 +583,7 @@ static void a2dp_aac_encode_frames(uint8_t nb_frame) { if (a2dp_aac_read_feeding(read_buffer, &bytes_read)) { uint8_t* packet = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len; if (!a2dp_aac_encoder_cb.has_aac_handle) { - LOG_ERROR("%s: invalid AAC handle", __func__); + log::error("invalid AAC handle"); a2dp_aac_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -605,7 +594,7 @@ static void a2dp_aac_encode_frames(uint8_t nb_frame) { aacEncEncode(a2dp_aac_encoder_cb.aac_handle, &in_buf_desc, &out_buf_desc, &aac_in_args, &aac_out_args); if (aac_error != AACENC_OK) { - LOG_ERROR("%s: AAC encoding error: 0x%x", __func__, aac_error); + log::error("AAC encoding error: 0x{:x}", aac_error); a2dp_aac_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -616,7 +605,7 @@ static void a2dp_aac_encode_frames(uint8_t nb_frame) { nb_frame--; p_buf->layer_specific++; // added a frame to the buffer } else { - LOG_WARN("%s: underflow %d", __func__, nb_frame); + log::warn("underflow {}", nb_frame); a2dp_aac_encoder_cb.aac_feeding_state.counter += nb_frame * p_encoder_params->frame_length * p_feeding_params->channel_count * @@ -686,16 +675,15 @@ static uint16_t adjust_effective_mtu( if (mtu_size > peer_params.peer_mtu) { mtu_size = peer_params.peer_mtu; } - LOG_VERBOSE("%s: original AVDTP MTU size: %d", __func__, mtu_size); + log::verbose("original AVDTP MTU size: {}", mtu_size); if (peer_params.is_peer_edr && !peer_params.peer_supports_3mbps) { // This condition would be satisfied only if the remote device is // EDR and supports only 2 Mbps, but the effective AVDTP MTU size // exceeds the 2DH5 packet size. - LOG_VERBOSE("%s: The remote device is EDR but does not support 3 Mbps", - __func__); + log::verbose("The remote device is EDR but does not support 3 Mbps"); if (mtu_size > MAX_2MBPS_AVDTP_MTU) { - LOG_WARN("%s: Restricting AVDTP MTU size from %d to %d", __func__, - mtu_size, MAX_2MBPS_AVDTP_MTU); + log::warn("Restricting AVDTP MTU size from {} to {}", mtu_size, + MAX_2MBPS_AVDTP_MTU); mtu_size = MAX_2MBPS_AVDTP_MTU; } } diff --git a/system/stack/a2dp/a2dp_aac_encoder_linux.cc b/system/stack/a2dp/a2dp_aac_encoder_linux.cc index 8c1b9c2729bfba69d8f9e9182263232a269a2b0e..f374bcf18d242978dfad62259e3d4f4fc344dba7 100644 --- a/system/stack/a2dp/a2dp_aac_encoder_linux.cc +++ b/system/stack/a2dp/a2dp_aac_encoder_linux.cc @@ -16,6 +16,7 @@ #define LOG_TAG "a2dp_aac_encoder" +#include #include #include #include @@ -25,10 +26,10 @@ #include "a2dp_aac.h" #include "a2dp_aac_encoder.h" #include "common/time_util.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "mmc/codec_client/codec_client.h" #include "mmc/proto/mmc_config.pb.h" -#include "os/log.h" #include "os/rand.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" @@ -62,8 +63,7 @@ class FFmpegInterface { int rc = client->init(config); if (rc < 0) { - LOG_ERROR("%s: Init failed with error message, %s", __func__, - strerror(-rc)); + log::error("Init failed with error message, {}", strerror(-rc)); } return rc; } @@ -80,20 +80,19 @@ class FFmpegInterface { // Otherwise returns the length of the encoded frame stored in `o_buf`. int encode_pcm(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) { if (i_buf == nullptr || o_buf == nullptr) { - LOG_ERROR("%s: Buffer is null", __func__); + log::error("Buffer is null"); return -EINVAL; } if (!client) { - LOG_ERROR("%s: CodecClient does not init", __func__); + log::error("CodecClient does not init"); return -ENOENT; } int rc = client->transcode(i_buf, i_len, o_buf, o_len); if (rc < 0) { - LOG_ERROR("%s: Encode failed with error message, %s", __func__, - strerror(-rc)); + log::error("Encode failed with error message, {}", strerror(-rc)); } return rc; } @@ -157,10 +156,8 @@ void a2dp_aac_encoder_init(const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, a2dp_source_enqueue_callback_t enqueue_callback) { uint8_t codec_info[AVDT_CODEC_SIZE]; if (!a2dp_codec_config->copyOutOtaCodecConfig(codec_info)) { - LOG_ERROR( - "%s: Cannot update the codec encoder for %s: " - "invalid codec config", - __func__, a2dp_codec_config->name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid codec config", + a2dp_codec_config->name().c_str()); return; } @@ -180,8 +177,7 @@ void a2dp_aac_encoder_init(const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, sample_rate, channel_count, bit_rate, bits_per_sample, mtu); if (pcm_samples_per_frame < 0) { - LOG_ERROR("%s: Failed to prepare context: %d", __func__, - pcm_samples_per_frame); + log::error("Failed to prepare context: {}", pcm_samples_per_frame); codec_intf.clear_context(); return; // TODO(b/294165759): need to return an error } @@ -224,7 +220,7 @@ void a2dp_aac_feeding_reset() { auto frame_length = a2dp_aac_encoder_cb.pcm_samples_per_frame; auto sample_rate = a2dp_aac_encoder_cb.feeding_params.sample_rate; if (sample_rate == 0) { - LOG_WARN("%s: Sample rate is not configured", __func__); + log::warn("Sample rate is not configured"); return; } @@ -238,9 +234,9 @@ void a2dp_aac_feeding_reset() { 1000, }; - LOG_WARN("%s: PCM bytes %d per tick (%dms)", __func__, - a2dp_aac_encoder_cb.aac_feeding_state.bytes_per_tick, - a2dp_aac_encoder_cb.encoder_interval_ms); + log::warn("PCM bytes {} per tick ({}ms)", + a2dp_aac_encoder_cb.aac_feeding_state.bytes_per_tick, + a2dp_aac_encoder_cb.encoder_interval_ms); } void a2dp_aac_feeding_flush() { @@ -281,7 +277,7 @@ static void a2dp_aac_get_num_frame_iteration(uint8_t* num_of_iterations, a2dp_aac_encoder_cb.pcm_samples_per_frame * a2dp_aac_encoder_cb.feeding_params.channel_count * a2dp_aac_encoder_cb.feeding_params.bits_per_sample / 8; - LOG_VERBOSE("%s: pcm_bytes_per_frame %u", __func__, pcm_bytes_per_frame); + log::verbose("pcm_bytes_per_frame {}", pcm_bytes_per_frame); uint32_t us_this_tick = a2dp_aac_encoder_cb.encoder_interval_ms * 1000; uint64_t now_us = timestamp_us; @@ -298,8 +294,7 @@ static void a2dp_aac_get_num_frame_iteration(uint8_t* num_of_iterations, a2dp_aac_encoder_cb.aac_feeding_state.counter -= result * pcm_bytes_per_frame; nof = result; - LOG_VERBOSE("%s: effective num of frames %u, iterations %u", __func__, nof, - noi); + log::verbose("effective num of frames {}, iterations {}", nof, noi); *num_of_frames = nof; *num_of_iterations = noi; @@ -318,7 +313,7 @@ static void a2dp_aac_encode_frames(uint8_t nb_frame) { uint32_t bytes_read = 0; if (!a2dp_aac_read_feeding(read_buffer, &bytes_read)) { - LOG_WARN("%s: Underflow %u", __func__, nb_frame); + log::warn("Underflow {}", nb_frame); a2dp_aac_encoder_cb.aac_feeding_state.counter += nb_frame * a2dp_aac_encoder_cb.pcm_samples_per_frame * a2dp_aac_encoder_cb.feeding_params.channel_count * @@ -342,7 +337,7 @@ static void a2dp_aac_encode_frames(uint8_t nb_frame) { } if (written == 0) { - LOG_INFO("%s: Dropped a frame, likely due to buffering", __func__); + log::info("Dropped a frame, likely due to buffering"); a2dp_aac_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); continue; @@ -395,16 +390,15 @@ static uint16_t adjust_effective_mtu( if (mtu_size > peer_params.peer_mtu) { mtu_size = peer_params.peer_mtu; } - LOG_VERBOSE("%s: original AVDTP MTU size: %d", __func__, mtu_size); + log::verbose("original AVDTP MTU size: {}", mtu_size); if (peer_params.is_peer_edr && !peer_params.peer_supports_3mbps) { // This condition would be satisfied only if the remote device is // EDR and supports only 2 Mbps, but the effective AVDTP MTU size // exceeds the 2DH5 packet size. - LOG_VERBOSE("%s: The remote device is EDR but does not support 3 Mbps", - __func__); + log::verbose("The remote device is EDR but does not support 3 Mbps"); if (mtu_size > MAX_2MBPS_AVDTP_MTU) { - LOG_WARN("%s: Restricting AVDTP MTU size from %d to %d", __func__, - mtu_size, MAX_2MBPS_AVDTP_MTU); + log::warn("Restricting AVDTP MTU size from {} to {}", mtu_size, + MAX_2MBPS_AVDTP_MTU); mtu_size = MAX_2MBPS_AVDTP_MTU; } } diff --git a/system/stack/a2dp/a2dp_api.cc b/system/stack/a2dp/a2dp_api.cc index 13bda9fded61e7ebf8327ca915e2dc7e226c9a00..bdee82b2552ca857d5dd371dde4bb26731173a17 100644 --- a/system/stack/a2dp/a2dp_api.cc +++ b/system/stack/a2dp/a2dp_api.cc @@ -26,12 +26,12 @@ #include "a2dp_api.h" +#include #include #include "a2dp_int.h" #include "avdt_api.h" #include "internal_include/bt_target.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "sdpdefs.h" @@ -41,6 +41,7 @@ #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +using namespace bluetooth; using namespace bluetooth::legacy::stack::sdp; using bluetooth::Uuid; @@ -79,7 +80,7 @@ static void a2dp_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, tSDP_PROTOCOL_ELEM elem; RawAddress peer_address = RawAddress::kEmpty; - LOG_INFO("%s: status: %d", __func__, status); + log::info("status: {}", status); if (status == SDP_SUCCESS) { /* loop through all records we found */ @@ -99,10 +100,10 @@ static void a2dp_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, a2dp_svc.p_service_name = (char*)p_attr->attr_value.v.array; a2dp_svc.service_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type); } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr type not STR!!"); + log::error("ATTR_ID_SERVICE_NAME attr type not STR!!"); } } else { - LOG_ERROR("ATTR_ID_SERVICE_NAME attr not found!!"); + log::error("ATTR_ID_SERVICE_NAME attr not found!!"); } /* get provider name */ @@ -112,10 +113,10 @@ static void a2dp_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, a2dp_svc.p_provider_name = (char*)p_attr->attr_value.v.array; a2dp_svc.provider_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type); } else { - LOG_ERROR("ATTR_ID_PROVIDER_NAME attr type not STR!!"); + log::error("ATTR_ID_PROVIDER_NAME attr type not STR!!"); } } else { - LOG_ERROR("ATTR_ID_PROVIDER_NAME attr not found!!"); + log::error("ATTR_ID_PROVIDER_NAME attr not found!!"); } /* get supported features */ @@ -125,17 +126,17 @@ static void a2dp_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { a2dp_svc.features = p_attr->attr_value.v.u16; } else { - LOG_ERROR("ATTR_ID_SUPPORTED_FEATURES attr type not STR!!"); + log::error("ATTR_ID_SUPPORTED_FEATURES attr type not STR!!"); } } else { - LOG_ERROR("ATTR_ID_SUPPORTED_FEATURES attr not found!!"); + log::error("ATTR_ID_SUPPORTED_FEATURES attr not found!!"); } /* get AVDTP version */ if (get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec( p_rec, UUID_PROTOCOL_AVDTP, &elem)) { a2dp_svc.avdt_version = elem.params[0]; - LOG_VERBOSE("avdt_version: 0x%x", a2dp_svc.avdt_version); + log::verbose("avdt_version: 0x{:x}", a2dp_svc.avdt_version); } /* we've got everything, we're done */ @@ -208,7 +209,7 @@ tA2DP_STATUS A2DP_AddRecord(uint16_t service_uuid, char* p_service_name, uint8_t* p; tSDP_PROTOCOL_ELEM proto_list[A2DP_NUM_PROTO_ELEMS]; - LOG_VERBOSE("%s: uuid: 0x%x", __func__, service_uuid); + log::verbose("uuid: 0x{:x}", service_uuid); if ((sdp_handle == 0) || (service_uuid != UUID_SERVCLASS_AUDIO_SOURCE && service_uuid != UUID_SERVCLASS_AUDIO_SINK)) @@ -308,16 +309,17 @@ tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, const RawAddress& bd_addr, if ((service_uuid != UUID_SERVCLASS_AUDIO_SOURCE && service_uuid != UUID_SERVCLASS_AUDIO_SINK) || p_db == NULL || p_cback == NULL) { - LOG_ERROR("Cannot find service for peer %s UUID 0x%04x: invalid parameters", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); + log::error( + "Cannot find service for peer {} UUID 0x{:04x}: invalid parameters", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); return A2DP_INVALID_PARAMS; } if (a2dp_cb.find.service_uuid == UUID_SERVCLASS_AUDIO_SOURCE || a2dp_cb.find.service_uuid == UUID_SERVCLASS_AUDIO_SINK || a2dp_cb.find.p_db != NULL) { - LOG_ERROR("Cannot find service for peer %s UUID 0x%04x: busy", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); + log::error("Cannot find service for peer {} UUID 0x{:04x}: busy", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); return A2DP_BUSY; } @@ -333,8 +335,8 @@ tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, const RawAddress& bd_addr, a2dp_cb.find.p_db, p_db->db_len, 1, &uuid_list, p_db->num_attr, p_db->p_attrs)) { osi_free_and_reset((void**)&a2dp_cb.find.p_db); - LOG_ERROR("Unable to initialize SDP discovery for peer %s UUID 0x%04X", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); + log::error("Unable to initialize SDP discovery for peer {} UUID 0x{:04X}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); return A2DP_FAIL; } @@ -348,12 +350,13 @@ tA2DP_STATUS A2DP_FindService(uint16_t service_uuid, const RawAddress& bd_addr, a2dp_cb.find.service_uuid = 0; a2dp_cb.find.p_cback = NULL; osi_free_and_reset((void**)&a2dp_cb.find.p_db); - LOG_ERROR("Cannot find service for peer %s UUID 0x%04x: SDP error", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); + log::error("Cannot find service for peer {} UUID 0x{:04x}: SDP error", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); return A2DP_FAIL; } - LOG_INFO("A2DP service discovery for peer %s UUID 0x%04x: SDP search started", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); + log::info( + "A2DP service discovery for peer {} UUID 0x{:04x}: SDP search started", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), service_uuid); return A2DP_SUCCESS; } diff --git a/system/stack/a2dp/a2dp_codec_config.cc b/system/stack/a2dp/a2dp_codec_config.cc index 8cd18594879bfa20e9e310c4f7f3ddc403259b5f..da537fbe33420dc998399892ca2261e8bc36790f 100644 --- a/system/stack/a2dp/a2dp_codec_config.cc +++ b/system/stack/a2dp/a2dp_codec_config.cc @@ -20,12 +20,14 @@ #define LOG_TAG "a2dp_codec" -#include +#include #include "a2dp_aac.h" #include "a2dp_codec_api.h" +#include "a2dp_ext.h" #include "a2dp_sbc.h" #include "a2dp_vendor.h" +#include "include/check.h" #if !defined(EXCLUDE_NONSTANDARD_CODECS) #include "a2dp_vendor_aptx.h" @@ -34,12 +36,10 @@ #include "a2dp_vendor_opus.h" #endif -#if !defined(UNIT_TESTS) #include "audio_hal_interface/a2dp_encoding.h" -#endif #include "bta/av/bta_av_int.h" #include "device/include/device_iot_config.h" -#include "osi/include/log.h" +#include "internal_include/bt_trace.h" #include "osi/include/properties.h" #include "stack/include/bt_hdr.h" @@ -51,6 +51,8 @@ // |codec_index| and |codec_priority| are the codec type and priority to use // for the initialization. +using namespace bluetooth; + static void init_btav_a2dp_codec_config( btav_a2dp_codec_config_t* codec_config, btav_a2dp_codec_index_t codec_index, btav_a2dp_codec_priority_t codec_priority) { @@ -60,9 +62,10 @@ static void init_btav_a2dp_codec_config( } A2dpCodecConfig::A2dpCodecConfig(btav_a2dp_codec_index_t codec_index, - const std::string& name, + uint64_t codec_id, const std::string& name, btav_a2dp_codec_priority_t codec_priority) : codec_index_(codec_index), + codec_id_(codec_id), name_(name), default_codec_priority_(codec_priority) { setCodecPriority(codec_priority); @@ -111,7 +114,14 @@ void A2dpCodecConfig::setDefaultCodecPriority() { A2dpCodecConfig* A2dpCodecConfig::createCodec( btav_a2dp_codec_index_t codec_index, btav_a2dp_codec_priority_t codec_priority) { - LOG_INFO("%s", A2DP_CodecIndexStr(codec_index)); + log::info("{}", A2DP_CodecIndexStr(codec_index)); + + // Hardware offload codec extensibility: + // management of the codec is moved under the ProviderInfo + // class of the aidl audio HAL client. + if (::bluetooth::audio::a2dp::provider::supports_codec(codec_index)) { + return new A2dpCodecConfigExt(codec_index, true); + } A2dpCodecConfig* codec_config = nullptr; switch (codec_index) { @@ -167,7 +177,7 @@ int A2dpCodecConfig::getTrackBitRate() const { memcpy(p_codec_info, ota_codec_config_, sizeof(ota_codec_config_)); tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -182,7 +192,7 @@ int A2dpCodecConfig::getTrackBitRate() const { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return -1; } @@ -252,8 +262,8 @@ bool A2dpCodecConfig::getCodecSpecificConfig(tBT_A2DP_OFFLOAD* p_a2dp_offload) { } p_a2dp_offload->codec_info[7] = codec_config[10]; // LDAC specific channel mode - LOG_VERBOSE("%s: Ldac specific channelmode =%d", __func__, - p_a2dp_offload->codec_info[7]); + log::verbose("Ldac specific channelmode ={}", + p_a2dp_offload->codec_info[7]); } break; #endif @@ -527,7 +537,7 @@ void A2dpCodecConfig::debug_codec_dump(int fd) { int A2DP_IotGetPeerSinkCodecType(const uint8_t* p_codec_info) { int peer_codec_type = 0; tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_SBC; @@ -537,8 +547,8 @@ int A2DP_IotGetPeerSinkCodecType(const uint8_t* p_codec_info) { uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info); uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info); - LOG_VERBOSE("%s codec_id = %d", __func__, codec_id); - LOG_VERBOSE("%s vendor_id = %x", __func__, vendor_id); + log::verbose("codec_id = {}", codec_id); + log::verbose("vendor_id = {:x}", vendor_id); if (codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH && vendor_id == A2DP_APTX_VENDOR_ID) { @@ -596,7 +606,7 @@ A2dpCodecs::~A2dpCodecs() { } bool A2dpCodecs::init() { - LOG_INFO("%s", __func__); + log::info(""); std::lock_guard lock(codec_mutex_); bool opus_enabled = @@ -627,8 +637,7 @@ bool A2dpCodecs::init() { // If OPUS is not supported it is disabled if (codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS && !opus_enabled) { codec_priority = BTAV_A2DP_CODEC_PRIORITY_DISABLED; - LOG_INFO("%s: OPUS codec disabled, updated priority to %d", __func__, - codec_priority); + log::info("OPUS codec disabled, updated priority to {}", codec_priority); } A2dpCodecConfig* codec_config = @@ -636,8 +645,8 @@ bool A2dpCodecs::init() { if (codec_config == nullptr) continue; if (codec_priority != BTAV_A2DP_CODEC_PRIORITY_DEFAULT) { - LOG_INFO("%s: updated %s codec priority to %d", __func__, - codec_config->name().c_str(), codec_priority); + log::info("updated {} codec priority to {}", codec_config->name().c_str(), + codec_priority); } // Test if the codec is disabled @@ -658,18 +667,19 @@ bool A2dpCodecs::init() { } if (ordered_source_codecs_.empty()) { - LOG_ERROR("%s: no Source codecs were initialized", __func__); + log::error("no Source codecs were initialized"); } else { for (auto iter : ordered_source_codecs_) { - LOG_INFO("%s: initialized Source codec %s", __func__, - iter->name().c_str()); + log::info("initialized Source codec {}, idx {}", iter->name().c_str(), + iter->codecIndex()); } } if (ordered_sink_codecs_.empty()) { - LOG_ERROR("%s: no Sink codecs were initialized", __func__); + log::error("no Sink codecs were initialized"); } else { for (auto iter : ordered_sink_codecs_) { - LOG_INFO("%s: initialized Sink codec %s", __func__, iter->name().c_str()); + log::info("initialized Sink codec {}, idx {}", iter->name().c_str(), + iter->codecIndex()); } } @@ -687,6 +697,15 @@ A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig( return iter->second; } +A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig( + btav_a2dp_codec_index_t codec_index) { + std::lock_guard lock(codec_mutex_); + + auto iter = indexed_codecs_.find(codec_index); + if (iter == indexed_codecs_.end()) return nullptr; + return iter->second; +} + A2dpCodecConfig* A2dpCodecs::findSinkCodecConfig(const uint8_t* p_codec_info) { std::lock_guard lock(codec_mutex_); btav_a2dp_codec_index_t codec_index = A2DP_SinkCodecIndex(p_codec_info); @@ -749,8 +768,7 @@ bool A2dpCodecs::setCodecUserConfig( *p_restart_output = false; *p_config_updated = false; - LOG_INFO("%s: Configuring: %s", __func__, - codec_user_config.ToString().c_str()); + log::info("Configuring: {}", codec_user_config.ToString().c_str()); if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) { auto iter = indexed_codecs_.find(codec_user_config.codec_type); @@ -829,10 +847,9 @@ bool A2dpCodecs::setCodecUserConfig( if (*p_restart_input || *p_restart_output) *p_config_updated = true; - LOG_INFO( - "%s: Configured: restart_input = %d restart_output = %d " - "config_updated = %d", - __func__, *p_restart_input, *p_restart_output, *p_config_updated); + log::info( + "Configured: restart_input = {} restart_output = {} config_updated = {}", + *p_restart_input, *p_restart_output, *p_config_updated); return true; @@ -887,10 +904,10 @@ bool A2dpCodecs::setCodecOtaConfig( if (current_codec_config_ != nullptr) { codec_user_config = current_codec_config_->getCodecUserConfig(); if (!A2dpCodecConfig::isCodecConfigEmpty(codec_user_config)) { - LOG_WARN( - "%s: ignoring peer OTA configuration for codec %s: " - "existing user configuration for current codec %s", - __func__, A2DP_CodecName(p_ota_codec_config), + log::warn( + "ignoring peer OTA configuration for codec {}: existing user " + "configuration for current codec {}", + A2DP_CodecName(p_ota_codec_config), current_codec_config_->name().c_str()); goto fail; } @@ -901,16 +918,13 @@ bool A2dpCodecs::setCodecOtaConfig( // ignored. codec_type = A2DP_SourceCodecIndex(p_ota_codec_config); if (codec_type == BTAV_A2DP_CODEC_INDEX_MAX) { - LOG_WARN( - "%s: ignoring peer OTA codec configuration: " - "invalid codec", - __func__); + log::warn("ignoring peer OTA codec configuration: invalid codec"); goto fail; // Invalid codec } else { auto iter = indexed_codecs_.find(codec_type); if (iter == indexed_codecs_.end()) { - LOG_WARN("%s: cannot find codec configuration for peer OTA codec %s", - __func__, A2DP_CodecName(p_ota_codec_config)); + log::warn("cannot find codec configuration for peer OTA codec {}", + A2DP_CodecName(p_ota_codec_config)); goto fail; } a2dp_codec_config = iter->second; @@ -918,10 +932,10 @@ bool A2dpCodecs::setCodecOtaConfig( if (a2dp_codec_config == nullptr) goto fail; codec_user_config = a2dp_codec_config->getCodecUserConfig(); if (!A2dpCodecConfig::isCodecConfigEmpty(codec_user_config)) { - LOG_WARN( - "%s: ignoring peer OTA configuration for codec %s: " - "existing user configuration for same codec", - __func__, A2DP_CodecName(p_ota_codec_config)); + log::warn( + "ignoring peer OTA configuration for codec {}: existing user " + "configuration for same codec", + A2DP_CodecName(p_ota_codec_config)); goto fail; } current_codec_config_ = a2dp_codec_config; @@ -932,8 +946,8 @@ bool A2dpCodecs::setCodecOtaConfig( codec_user_config, codec_audio_config, p_peer_params, p_ota_codec_config, false, p_result_codec_config, p_restart_input, p_restart_output, p_config_updated)) { - LOG_WARN("%s: cannot set codec configuration for peer OTA codec %s", - __func__, A2DP_CodecName(p_ota_codec_config)); + log::warn("cannot set codec configuration for peer OTA codec {}", + A2DP_CodecName(p_ota_codec_config)); goto fail; } CHECK(current_codec_config_ != nullptr); @@ -951,10 +965,19 @@ bool A2dpCodecs::setPeerSinkCodecCapabilities( const uint8_t* p_peer_codec_capabilities) { std::lock_guard lock(codec_mutex_); - if (!A2DP_IsPeerSinkCodecValid(p_peer_codec_capabilities)) return false; A2dpCodecConfig* a2dp_codec_config = findSourceCodecConfig(p_peer_codec_capabilities); if (a2dp_codec_config == nullptr) return false; + + // Bypass the validation for codecs that are offloaded: + // the stack does not need to know about the peer capabilities, + // since the validation and selection will be performed by the + // bluetooth audio HAL for offloaded codecs. + if (!::bluetooth::audio::a2dp::provider::supports_codec( + a2dp_codec_config->codecIndex()) && + !A2DP_IsPeerSinkCodecValid(p_peer_codec_capabilities)) + return false; + return a2dp_codec_config->setPeerCodecCapabilities(p_peer_codec_capabilities); } @@ -1031,7 +1054,7 @@ tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info) { bool A2DP_IsSourceCodecValid(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1052,7 +1075,7 @@ bool A2DP_IsSourceCodecValid(const uint8_t* p_codec_info) { bool A2DP_IsSinkCodecValid(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1073,7 +1096,7 @@ bool A2DP_IsSinkCodecValid(const uint8_t* p_codec_info) { bool A2DP_IsPeerSourceCodecValid(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1094,7 +1117,7 @@ bool A2DP_IsPeerSourceCodecValid(const uint8_t* p_codec_info) { bool A2DP_IsPeerSinkCodecValid(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1115,7 +1138,7 @@ bool A2DP_IsPeerSinkCodecValid(const uint8_t* p_codec_info) { bool A2DP_IsSinkCodecSupported(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1130,14 +1153,14 @@ bool A2DP_IsSinkCodecSupported(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return false; } bool A2DP_IsPeerSourceCodecSupported(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1152,7 +1175,7 @@ bool A2DP_IsPeerSourceCodecSupported(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return false; } @@ -1181,7 +1204,7 @@ uint8_t A2DP_GetMediaType(const uint8_t* p_codec_info) { const char* A2DP_CodecName(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1196,7 +1219,7 @@ const char* A2DP_CodecName(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return "UNKNOWN CODEC"; } @@ -1220,7 +1243,7 @@ bool A2DP_CodecTypeEquals(const uint8_t* p_codec_info_a, break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type_a); + log::error("unsupported codec type 0x{:x}", codec_type_a); return false; } @@ -1244,14 +1267,14 @@ bool A2DP_CodecEquals(const uint8_t* p_codec_info_a, break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type_a); + log::error("unsupported codec type 0x{:x}", codec_type_a); return false; } int A2DP_GetTrackSampleRate(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1266,14 +1289,14 @@ int A2DP_GetTrackSampleRate(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return -1; } int A2DP_GetTrackBitsPerSample(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1288,14 +1311,14 @@ int A2DP_GetTrackBitsPerSample(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return -1; } int A2DP_GetTrackChannelCount(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1310,14 +1333,14 @@ int A2DP_GetTrackChannelCount(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return -1; } int A2DP_GetSinkTrackChannelType(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1332,7 +1355,7 @@ int A2DP_GetSinkTrackChannelType(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return -1; } @@ -1353,7 +1376,7 @@ bool A2DP_GetPacketTimestamp(const uint8_t* p_codec_info, const uint8_t* p_data, break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return false; } @@ -1375,7 +1398,7 @@ bool A2DP_BuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf, break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return false; } @@ -1383,7 +1406,12 @@ const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterface( const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); + + if (::bluetooth::audio::a2dp::provider::supports_codec( + A2DP_SourceCodecIndex(p_codec_info))) { + return A2DP_GetEncoderInterfaceExt(p_codec_info); + } switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1398,7 +1426,7 @@ const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterface( break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return NULL; } @@ -1406,7 +1434,7 @@ const tA2DP_DECODER_INTERFACE* A2DP_GetDecoderInterface( const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1421,7 +1449,7 @@ const tA2DP_DECODER_INTERFACE* A2DP_GetDecoderInterface( break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return NULL; } @@ -1441,14 +1469,20 @@ bool A2DP_AdjustCodec(uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return false; } btav_a2dp_codec_index_t A2DP_SourceCodecIndex(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); + + auto ext_codec_index = + bluetooth::audio::a2dp::provider::source_codec_index(p_codec_info); + if (ext_codec_index.has_value()) { + return ext_codec_index.value(); + } switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1463,14 +1497,20 @@ btav_a2dp_codec_index_t A2DP_SourceCodecIndex(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return BTAV_A2DP_CODEC_INDEX_MAX; } btav_a2dp_codec_index_t A2DP_SinkCodecIndex(const uint8_t* p_codec_info) { tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - LOG_VERBOSE("%s: codec_type = 0x%x", __func__, codec_type); + log::verbose("codec_type = 0x{:x}", codec_type); + + auto ext_codec_index = + bluetooth::audio::a2dp::provider::sink_codec_index(p_codec_info); + if (ext_codec_index.has_value()) { + return ext_codec_index.value(); + } switch (codec_type) { case A2DP_MEDIA_CT_SBC: @@ -1485,11 +1525,22 @@ btav_a2dp_codec_index_t A2DP_SinkCodecIndex(const uint8_t* p_codec_info) { break; } - LOG_ERROR("%s: unsupported codec type 0x%x", __func__, codec_type); + log::error("unsupported codec type 0x{:x}", codec_type); return BTAV_A2DP_CODEC_INDEX_MAX; } const char* A2DP_CodecIndexStr(btav_a2dp_codec_index_t codec_index) { + if ((codec_index >= BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN && + codec_index < BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX) || + (codec_index >= BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN && + codec_index < BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX)) { + auto codec_index_str = + bluetooth::audio::a2dp::provider::codec_index_str(codec_index); + if (codec_index_str.has_value()) { + return codec_index_str.value(); + } + } + switch (codec_index) { case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: return A2DP_CodecIndexStrSbc(); @@ -1515,12 +1566,17 @@ const char* A2DP_CodecIndexStr(btav_a2dp_codec_index_t codec_index) { bool A2DP_InitCodecConfig(btav_a2dp_codec_index_t codec_index, AvdtpSepConfig* p_cfg) { - LOG_VERBOSE("%s: codec %s", __func__, A2DP_CodecIndexStr(codec_index)); + log::verbose("codec {}", A2DP_CodecIndexStr(codec_index)); /* Default: no content protection info */ p_cfg->num_protect = 0; p_cfg->protect_info[0] = 0; + if (::bluetooth::audio::a2dp::provider::supports_codec(codec_index)) { + return ::bluetooth::audio::a2dp::provider::codec_info( + codec_index, nullptr, p_cfg->codec_info, nullptr); + } + switch (codec_index) { case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: return A2DP_InitCodecConfigSbc(p_cfg); @@ -1564,26 +1620,9 @@ std::string A2DP_CodecInfoString(const uint8_t* p_codec_info) { } int A2DP_GetEecoderEffectiveFrameSize(const uint8_t* p_codec_info) { - tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info); - - const tA2DP_ENCODER_INTERFACE* a2dp_encoder_interface = nullptr; - switch (codec_type) { - case A2DP_MEDIA_CT_SBC: - a2dp_encoder_interface = A2DP_GetEncoderInterfaceSbc(p_codec_info); - break; -#if !defined(EXCLUDE_NONSTANDARD_CODECS) - case A2DP_MEDIA_CT_AAC: - a2dp_encoder_interface = A2DP_GetEncoderInterfaceAac(p_codec_info); - break; - case A2DP_MEDIA_CT_NON_A2DP: - a2dp_encoder_interface = A2DP_VendorGetEncoderInterface(p_codec_info); - break; -#endif - default: - break; - } - if (a2dp_encoder_interface == nullptr) { - return 0; - } - return a2dp_encoder_interface->get_effective_frame_size(); + const tA2DP_ENCODER_INTERFACE* a2dp_encoder_interface = + A2DP_GetEncoderInterface(p_codec_info); + return a2dp_encoder_interface + ? a2dp_encoder_interface->get_effective_frame_size() + : 0; } diff --git a/system/stack/a2dp/a2dp_ext.cc b/system/stack/a2dp/a2dp_ext.cc new file mode 100644 index 0000000000000000000000000000000000000000..a0bb2eb51e3b75e6581948ae29859cb88c98dafa --- /dev/null +++ b/system/stack/a2dp/a2dp_ext.cc @@ -0,0 +1,103 @@ +/** + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "a2dp_ext.h" + +#include +#include + +#include "a2dp_codec_api.h" +#include "audio_hal_interface/a2dp_encoding.h" + +using namespace bluetooth; + +static uint64_t codec_id(btav_a2dp_codec_index_t codec_index) { + uint64_t id = 0; + auto result = ::bluetooth::audio::a2dp::provider::codec_info( + codec_index, &id, nullptr, nullptr); + LOG_ASSERT(result) << "provider::codec_info unexpectdly failed"; + return id; +} + +A2dpCodecConfigExt::A2dpCodecConfigExt(btav_a2dp_codec_index_t codec_index, + bool is_source) + : A2dpCodecConfig( + codec_index, codec_id(codec_index), + bluetooth::audio::a2dp::provider::codec_index_str(codec_index) + .value(), + BTAV_A2DP_CODEC_PRIORITY_DEFAULT), + is_source_(is_source) { + // Load the local capabilities from the provider info. + auto result = ::bluetooth::audio::a2dp::provider::codec_info( + codec_index, nullptr, ota_codec_config_, &codec_capability_); + LOG_ASSERT(result) << "provider::codec_info unexpectdly failed"; + codec_selectable_capability_ = codec_capability_; +} + +bool A2dpCodecConfigExt::setCodecConfig(const uint8_t* p_peer_codec_info, + bool is_capability, + uint8_t* p_result_codec_config) { + // Call get_a2dp_config to recompute best capabilities. + // This method need to update codec_capability_, codec_config_, + // and ota_codec_config_ using the local codec_user_config_, and input + // peer_codec_info. + using namespace bluetooth::audio::a2dp; + provider::a2dp_remote_capabilities capabilities = { + .seid = 0, // the SEID does not matter here. + .capabilities = p_peer_codec_info, + }; + + auto result = provider::get_a2dp_configuration( + RawAddress::kEmpty, + std::vector{capabilities}, + codec_user_config_); + if (!result.has_value()) { + log::error("Failed to set a configuration for {}", name_); + return false; + } + + memcpy(ota_codec_config_, result->codec_config, sizeof(ota_codec_config_)); + codec_config_ = result->codec_parameters; + codec_capability_ = result->codec_parameters; + vendor_specific_parameters_ = result->vendor_specific_parameters; + return true; +} + +bool A2dpCodecConfigExt::setPeerCodecCapabilities( + const uint8_t* p_peer_codec_capabilities) { + // setPeerCodecCapabilities updates the selectable + // capabilities in the codec config. It can be safely + // ignored as providing a superset of the selectable + // capabilities is safe. + return true; +} + +tA2DP_ENCODER_INTERFACE const a2dp_encoder_interface_ext = { + .encoder_init = [](const tA2DP_ENCODER_INIT_PEER_PARAMS*, A2dpCodecConfig*, + a2dp_source_read_callback_t, + a2dp_source_enqueue_callback_t) {}, + .encoder_cleanup = []() {}, + .feeding_reset = []() {}, + .feeding_flush = []() {}, + .get_encoder_interval_ms = []() { return (uint64_t)20; }, + .get_effective_frame_size = []() { return 0; }, + .send_frames = [](uint64_t) {}, + .set_transmit_queue_length = [](size_t) {}, +}; + +const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterfaceExt(const uint8_t*) { + return &a2dp_encoder_interface_ext; +} diff --git a/system/stack/a2dp/a2dp_sbc.cc b/system/stack/a2dp/a2dp_sbc.cc index e05ab913009d7c13960ce6a4f1e49199215d0471..d50fd5324d8ebca6d3912bc29c3f32f7afd2a932 100644 --- a/system/stack/a2dp/a2dp_sbc.cc +++ b/system/stack/a2dp/a2dp_sbc.cc @@ -27,18 +27,21 @@ #include "a2dp_sbc.h" -#include +#include #include #include "a2dp_sbc_decoder.h" #include "a2dp_sbc_encoder.h" #include "embdrv/sbc/encoder/include/sbc_encoder.h" -#include "os/log.h" +#include "include/check.h" +#include "internal_include/bt_trace.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" #define A2DP_SBC_MAX_BITPOOL 53 +using namespace bluetooth; + /* data type for the SBC Codec Information Element */ typedef struct { uint8_t samp_freq; /* Sampling frequency */ @@ -333,7 +336,7 @@ bool A2DP_IsPeerSourceCodecSupportedSbc(const uint8_t* p_codec_info) { void A2DP_InitDefaultCodecSbc(uint8_t* p_codec_info) { if (A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &a2dp_sbc_default_config, p_codec_info) != A2DP_SUCCESS) { - LOG_ERROR("%s: A2DP_BuildInfoSbc failed", __func__); + log::error("A2DP_BuildInfoSbc failed"); } } @@ -352,26 +355,26 @@ static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc( /* parse configuration */ status = A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: parsing failed %d", __func__, status); + log::error("parsing failed {}", status); return status; } /* verify that each parameter is in range */ - LOG_VERBOSE("%s: FREQ peer: 0x%x, capability 0x%x", __func__, - cfg_cie.samp_freq, p_cap->samp_freq); - LOG_VERBOSE("%s: CH_MODE peer: 0x%x, capability 0x%x", __func__, - cfg_cie.ch_mode, p_cap->ch_mode); - LOG_VERBOSE("%s: BLOCK_LEN peer: 0x%x, capability 0x%x", __func__, - cfg_cie.block_len, p_cap->block_len); - LOG_VERBOSE("%s: SUB_BAND peer: 0x%x, capability 0x%x", __func__, - cfg_cie.num_subbands, p_cap->num_subbands); - LOG_VERBOSE("%s: ALLOC_METHOD peer: 0x%x, capability 0x%x", __func__, - cfg_cie.alloc_method, p_cap->alloc_method); - LOG_VERBOSE("%s: MIN_BitPool peer: 0x%x, capability 0x%x", __func__, - cfg_cie.min_bitpool, p_cap->min_bitpool); - LOG_VERBOSE("%s: MAX_BitPool peer: 0x%x, capability 0x%x", __func__, - cfg_cie.max_bitpool, p_cap->max_bitpool); + log::verbose("FREQ peer: 0x{:x}, capability 0x{:x}", cfg_cie.samp_freq, + p_cap->samp_freq); + log::verbose("CH_MODE peer: 0x{:x}, capability 0x{:x}", cfg_cie.ch_mode, + p_cap->ch_mode); + log::verbose("BLOCK_LEN peer: 0x{:x}, capability 0x{:x}", cfg_cie.block_len, + p_cap->block_len); + log::verbose("SUB_BAND peer: 0x{:x}, capability 0x{:x}", cfg_cie.num_subbands, + p_cap->num_subbands); + log::verbose("ALLOC_METHOD peer: 0x{:x}, capability 0x{:x}", + cfg_cie.alloc_method, p_cap->alloc_method); + log::verbose("MIN_BitPool peer: 0x{:x}, capability 0x{:x}", + cfg_cie.min_bitpool, p_cap->min_bitpool); + log::verbose("MAX_BitPool peer: 0x{:x}, capability 0x{:x}", + cfg_cie.max_bitpool, p_cap->max_bitpool); /* sampling frequency */ if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) return A2DP_NS_SAMP_FREQ; @@ -408,12 +411,12 @@ bool A2DP_CodecTypeEqualsSbc(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoSbc(&sbc_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -432,12 +435,12 @@ bool A2DP_CodecEqualsSbc(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoSbc(&sbc_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -461,7 +464,7 @@ int A2DP_GetTrackSampleRateSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -486,7 +489,7 @@ int A2DP_GetTrackBitsPerSampleSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -499,7 +502,7 @@ int A2DP_GetTrackChannelCountSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -522,7 +525,7 @@ int A2DP_GetNumberOfSubbandsSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -543,7 +546,7 @@ int A2DP_GetNumberOfBlocksSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -568,7 +571,7 @@ int A2DP_GetAllocationMethodCodeSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -589,7 +592,7 @@ int A2DP_GetChannelModeCodeSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -614,7 +617,7 @@ int A2DP_GetSamplingFrequencyCodeSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -639,7 +642,7 @@ int A2DP_GetMinBitpoolSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -651,7 +654,7 @@ int A2DP_GetMaxBitpoolSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -664,7 +667,7 @@ int A2DP_GetSinkTrackChannelTypeSbc(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -796,8 +799,8 @@ bool A2DP_AdjustCodecSbc(uint8_t* p_codec_info) { // Updated the max bitpool if (cfg_cie.max_bitpool > A2DP_SBC_MAX_BITPOOL) { - LOG_WARN("%s: Updated the SBC codec max bitpool from %d to %d", __func__, - cfg_cie.max_bitpool, A2DP_SBC_MAX_BITPOOL); + log::warn("Updated the SBC codec max bitpool from {} to {}", + cfg_cie.max_bitpool, A2DP_SBC_MAX_BITPOOL); cfg_cie.max_bitpool = A2DP_SBC_MAX_BITPOOL; } @@ -889,7 +892,7 @@ bool A2dpCodecConfigSbcSource::init() { // Load the encoder if (!A2DP_LoadEncoderSbc()) { - LOG_ERROR("%s: cannot load the encoder", __func__); + log::error("cannot load the encoder"); return false; } @@ -1090,8 +1093,7 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, tA2DP_STATUS status = A2DP_ParseInfoSbc(&peer_info_cie, p_peer_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } // Try using the prefered peer codec config (if valid), instead of the peer @@ -1193,10 +1195,9 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) { - LOG_ERROR( - "%s: cannot match sample frequency: local caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_sbc_caps->samp_freq, peer_info_cie.samp_freq); + log::error( + "cannot match sample frequency: local caps = 0x{:x} peer info = 0x{:x}", + p_a2dp_sbc_caps->samp_freq, peer_info_cie.samp_freq); goto fail; } @@ -1248,8 +1249,8 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) { - LOG_ERROR("%s: cannot match bits per sample: user preference = 0x%x", - __func__, codec_user_config_.bits_per_sample); + log::error("cannot match bits per sample: user preference = 0x{:x}", + codec_user_config_.bits_per_sample); goto fail; } @@ -1341,10 +1342,9 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) { - LOG_ERROR( - "%s: cannot match channel mode: local caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_sbc_caps->ch_mode, peer_info_cie.ch_mode); + log::error( + "cannot match channel mode: local caps = 0x{:x} peer info = 0x{:x}", + p_a2dp_sbc_caps->ch_mode, peer_info_cie.ch_mode); goto fail; } @@ -1361,10 +1361,9 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, } else if (block_len & A2DP_SBC_IE_BLOCKS_4) { result_config_cie.block_len = A2DP_SBC_IE_BLOCKS_4; } else { - LOG_ERROR( - "%s: cannot match block length: local caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_sbc_caps->block_len, peer_info_cie.block_len); + log::error( + "cannot match block length: local caps = 0x{:x} peer info = 0x{:x}", + p_a2dp_sbc_caps->block_len, peer_info_cie.block_len); goto fail; } @@ -1377,10 +1376,10 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, } else if (num_subbands & A2DP_SBC_IE_SUBBAND_4) { result_config_cie.num_subbands = A2DP_SBC_IE_SUBBAND_4; } else { - LOG_ERROR( - "%s: cannot match number of sub-bands: local caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_sbc_caps->num_subbands, peer_info_cie.num_subbands); + log::error( + "cannot match number of sub-bands: local caps = 0x{:x} peer info = " + "0x{:x}", + p_a2dp_sbc_caps->num_subbands, peer_info_cie.num_subbands); goto fail; } @@ -1393,10 +1392,10 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, } else if (alloc_method & A2DP_SBC_IE_ALLOC_MD_S) { result_config_cie.alloc_method = A2DP_SBC_IE_ALLOC_MD_S; } else { - LOG_ERROR( - "%s: cannot match allocation method: local caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_sbc_caps->alloc_method, peer_info_cie.alloc_method); + log::error( + "cannot match allocation method: local caps = 0x{:x} peer info = " + "0x{:x}", + p_a2dp_sbc_caps->alloc_method, peer_info_cie.alloc_method); goto fail; } @@ -1410,10 +1409,10 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info, if (result_config_cie.max_bitpool > peer_info_cie.max_bitpool) result_config_cie.max_bitpool = peer_info_cie.max_bitpool; if (result_config_cie.min_bitpool > result_config_cie.max_bitpool) { - LOG_ERROR( - "%s: cannot match min/max bitpool: " - "local caps min/max = 0x%x/0x%x peer info min/max = 0x%x/0x%x", - __func__, p_a2dp_sbc_caps->min_bitpool, p_a2dp_sbc_caps->max_bitpool, + log::error( + "cannot match min/max bitpool: local caps min/max = 0x{:x}/0x{:x} peer " + "info min/max = 0x{:x}/0x{:x}", + p_a2dp_sbc_caps->min_bitpool, p_a2dp_sbc_caps->max_bitpool, peer_info_cie.min_bitpool, peer_info_cie.max_bitpool); goto fail; } @@ -1484,8 +1483,7 @@ bool A2dpCodecConfigSbcBase::setPeerCodecCapabilities( tA2DP_STATUS status = A2DP_ParseInfoSbc(&peer_info_cie, p_peer_codec_capabilities, true); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -1549,7 +1547,7 @@ bool A2dpCodecConfigSbcSink::init() { // Load the decoder if (!A2DP_LoadDecoderSbc()) { - LOG_ERROR("%s: cannot load the decoder", __func__); + log::error("cannot load the decoder"); return false; } diff --git a/system/stack/a2dp/a2dp_sbc_decoder.cc b/system/stack/a2dp/a2dp_sbc_decoder.cc index da28cacc48607baed90aea3c18e2de50c7f9ded8..ed3324a3de44ebbdccbdd02cdf1d636d52b26dbd 100644 --- a/system/stack/a2dp/a2dp_sbc_decoder.cc +++ b/system/stack/a2dp/a2dp_sbc_decoder.cc @@ -18,13 +18,19 @@ #include "a2dp_sbc_decoder.h" -#include +#include #include "embdrv/sbc/decoder/include/oi_codec_sbc.h" #include "embdrv/sbc/decoder/include/oi_status.h" -#include "os/log.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + typedef struct { OI_CODEC_SBC_DECODER_CONTEXT decoder_context; uint32_t context_data[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)]; @@ -46,8 +52,7 @@ bool a2dp_sbc_decoder_init(decoded_data_callback_t decode_callback) { &a2dp_sbc_decoder_cb.decoder_context, a2dp_sbc_decoder_cb.context_data, sizeof(a2dp_sbc_decoder_cb.context_data), 2, 2, false); if (!OI_SUCCESS(status)) { - LOG_ERROR("%s: OI_CODEC_SBC_DecoderReset failed with error code %d", - __func__, status); + log::error("OI_CODEC_SBC_DecoderReset failed with error code {}", status); return false; } @@ -64,7 +69,7 @@ bool a2dp_sbc_decoder_decode_packet(BT_HDR* p_buf) { size_t data_size = p_buf->len; if (data_size == 0) { - LOG_ERROR("%s: Empty packet", __func__); + log::error("Empty packet"); return false; } size_t num_frames = data[0] & 0xf; @@ -82,7 +87,7 @@ bool a2dp_sbc_decoder_decode_packet(BT_HDR* p_buf) { OI_CODEC_SBC_DecodeFrame(&a2dp_sbc_decoder_cb.decoder_context, &oi_data, &oi_size, out_ptr, &out_size); if (!OI_SUCCESS(status)) { - LOG_ERROR("%s: Decoding failure: %d", __func__, status); + log::error("Decoding failure: {}", status); return false; } out_avail -= out_size; diff --git a/system/stack/a2dp/a2dp_sbc_encoder.cc b/system/stack/a2dp/a2dp_sbc_encoder.cc index 977198425332366b30a6d43926ff9cda2abccce0..fab6f23bd0c4ade50d5894b2b3805bebef7eec82 100644 --- a/system/stack/a2dp/a2dp_sbc_encoder.cc +++ b/system/stack/a2dp/a2dp_sbc_encoder.cc @@ -21,6 +21,7 @@ #include "a2dp_sbc_encoder.h" +#include #include #include #include @@ -30,7 +31,6 @@ #include "common/time_util.h" #include "embdrv/sbc/encoder/include/sbc_encoder.h" #include "internal_include/bt_target.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" @@ -61,6 +61,8 @@ #define A2DP_HDR_SIZE 1 #define A2DP_SBC_OFFSET (AVDT_MEDIA_OFFSET + A2DP_SBC_MPL_HDR_LEN) +using namespace bluetooth; + typedef struct { uint32_t aa_frame_counter; int32_t aa_feed_counter; @@ -169,10 +171,8 @@ static void a2dp_sbc_encoder_update(A2dpCodecConfig* a2dp_codec_config, *p_restart_output = false; *p_config_updated = false; if (!a2dp_codec_config->copyOutOtaCodecConfig(codec_info)) { - LOG_ERROR( - "%s: Cannot update the codec encoder for %s: " - "invalid codec config", - __func__, a2dp_codec_config->name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid codec config", + a2dp_codec_config->name().c_str()); return; } const uint8_t* p_codec_info = codec_info; @@ -185,9 +185,9 @@ static void a2dp_sbc_encoder_update(A2dpCodecConfig* a2dp_codec_config, p_feeding_params->bits_per_sample = a2dp_codec_config->getAudioBitsPerSample(); p_feeding_params->channel_count = A2DP_GetTrackChannelCountSbc(p_codec_info); - LOG_INFO("%s: sample_rate=%u bits_per_sample=%u channel_count=%u", __func__, - p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, - p_feeding_params->channel_count); + log::info("sample_rate={} bits_per_sample={} channel_count={}", + p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, + p_feeding_params->channel_count); a2dp_sbc_feeding_reset(); // The codec parameters @@ -204,18 +204,18 @@ static void a2dp_sbc_encoder_update(A2dpCodecConfig* a2dp_codec_config, // Reset invalid parameters if (!p_encoder_params->s16NumOfSubBands) { - LOG_WARN("%s: SubBands are set to 0, resetting to max (%d)", __func__, - SBC_MAX_NUM_OF_SUBBANDS); + log::warn("SubBands are set to 0, resetting to max ({})", + SBC_MAX_NUM_OF_SUBBANDS); p_encoder_params->s16NumOfSubBands = SBC_MAX_NUM_OF_SUBBANDS; } if (!p_encoder_params->s16NumOfBlocks) { - LOG_WARN("%s: Blocks are set to 0, resetting to max (%d)", __func__, - SBC_MAX_NUM_OF_BLOCKS); + log::warn("Blocks are set to 0, resetting to max ({})", + SBC_MAX_NUM_OF_BLOCKS); p_encoder_params->s16NumOfBlocks = SBC_MAX_NUM_OF_BLOCKS; } if (!p_encoder_params->s16NumOfChannels) { - LOG_WARN("%s: Channels are set to 0, resetting to max (%d)", __func__, - SBC_MAX_NUM_OF_CHANNELS); + log::warn("Channels are set to 0, resetting to max ({})", + SBC_MAX_NUM_OF_CHANNELS); p_encoder_params->s16NumOfChannels = SBC_MAX_NUM_OF_CHANNELS; } @@ -234,16 +234,16 @@ static void a2dp_sbc_encoder_update(A2dpCodecConfig* a2dp_codec_config, p_encoder_params->u16BitRate = a2dp_sbc_source_rate(peer_params.is_peer_edr); a2dp_sbc_encoder_cb.TxAaMtuSize = adjust_effective_mtu(peer_params); - LOG_INFO("%s: MTU=%d, peer_mtu=%d min_bitpool=%d max_bitpool=%d", __func__, - a2dp_sbc_encoder_cb.TxAaMtuSize, peer_params.peer_mtu, min_bitpool, - max_bitpool); - LOG_INFO( - "%s: ChannelMode=%d, NumOfSubBands=%d, NumOfBlocks=%d, " - "AllocationMethod=%d, BitRate=%d, SamplingFreq=%d BitPool=%d", - __func__, p_encoder_params->s16ChannelMode, - p_encoder_params->s16NumOfSubBands, p_encoder_params->s16NumOfBlocks, - p_encoder_params->s16AllocationMethod, p_encoder_params->u16BitRate, - s16SamplingFreq, p_encoder_params->s16BitPool); + log::info("MTU={}, peer_mtu={} min_bitpool={} max_bitpool={}", + a2dp_sbc_encoder_cb.TxAaMtuSize, peer_params.peer_mtu, min_bitpool, + max_bitpool); + log::info( + "ChannelMode={}, NumOfSubBands={}, NumOfBlocks={}, AllocationMethod={}, " + "BitRate={}, SamplingFreq={} BitPool={}", + p_encoder_params->s16ChannelMode, p_encoder_params->s16NumOfSubBands, + p_encoder_params->s16NumOfBlocks, p_encoder_params->s16AllocationMethod, + p_encoder_params->u16BitRate, s16SamplingFreq, + p_encoder_params->s16BitPool); do { if ((p_encoder_params->s16ChannelMode == SBC_JOINT_STEREO) || @@ -293,17 +293,17 @@ static void a2dp_sbc_encoder_update(A2dpCodecConfig* a2dp_codec_config, if (s16BitPool < 0) s16BitPool = 0; - LOG_VERBOSE("%s: bitpool candidate: %d (%d kbps)", __func__, s16BitPool, - p_encoder_params->u16BitRate); + log::verbose("bitpool candidate: {} ({} kbps)", s16BitPool, + p_encoder_params->u16BitRate); if (s16BitPool > max_bitpool) { - LOG_VERBOSE("%s: computed bitpool too large (%d)", __func__, s16BitPool); + log::verbose("computed bitpool too large ({})", s16BitPool); /* Decrease bitrate */ p_encoder_params->u16BitRate -= A2DP_SBC_BITRATE_STEP; /* Record that we have decreased the bitrate */ protect |= 1; } else if (s16BitPool < min_bitpool) { - LOG_WARN("%s: computed bitpool too small (%d)", __func__, s16BitPool); + log::warn("computed bitpool too small ({})", s16BitPool); /* Increase bitrate */ uint16_t previous_u16BitRate = p_encoder_params->u16BitRate; @@ -317,7 +317,7 @@ static void a2dp_sbc_encoder_update(A2dpCodecConfig* a2dp_codec_config, } /* In case we have already increased and decreased the bitrate, just stop */ if (protect == 3) { - LOG_ERROR("%s: could not find bitpool in range", __func__); + log::error("could not find bitpool in range"); break; } } while (true); @@ -325,8 +325,8 @@ static void a2dp_sbc_encoder_update(A2dpCodecConfig* a2dp_codec_config, /* Finally update the bitpool in the encoder structure */ p_encoder_params->s16BitPool = s16BitPool; - LOG_INFO("%s: final bit rate %d, final bit pool %d", __func__, - p_encoder_params->u16BitRate, p_encoder_params->s16BitPool); + log::info("final bit rate {}, final bit pool {}", + p_encoder_params->u16BitRate, p_encoder_params->s16BitPool); /* Reset the SBC encoder */ SBC_Encoder_Init(&a2dp_sbc_encoder_cb.sbc_encoder_params); @@ -349,8 +349,8 @@ void a2dp_sbc_feeding_reset(void) { A2DP_SBC_ENCODER_INTERVAL_MS) / 1000; - LOG_INFO("%s: PCM bytes per tick %u", __func__, - a2dp_sbc_encoder_cb.feeding_state.bytes_per_tick); + log::info("PCM bytes per tick {}", + a2dp_sbc_encoder_cb.feeding_state.bytes_per_tick); } void a2dp_sbc_feeding_flush(void) { @@ -371,8 +371,8 @@ void a2dp_sbc_send_frames(uint64_t timestamp_us) { uint8_t nb_iterations = 0; a2dp_sbc_get_num_frame_iteration(&nb_iterations, &nb_frame, timestamp_us); - LOG_VERBOSE("%s: Sending %d frames per iteration, %d iterations", __func__, - nb_frame, nb_iterations); + log::verbose("Sending {} frames per iteration, {} iterations", nb_frame, + nb_iterations); if (nb_frame == 0) return; for (uint8_t counter = 0; counter < nb_iterations; counter++) { @@ -396,7 +396,7 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, a2dp_sbc_encoder_cb.sbc_encoder_params.s16NumOfBlocks * a2dp_sbc_encoder_cb.feeding_params.channel_count * a2dp_sbc_encoder_cb.feeding_params.bits_per_sample / 8; - LOG_VERBOSE("%s: pcm_bytes_per_frame %u", __func__, pcm_bytes_per_frame); + log::verbose("pcm_bytes_per_frame {}", pcm_bytes_per_frame); uint32_t us_this_tick = A2DP_SBC_ENCODER_INTERVAL_MS * 1000; uint64_t now_us = timestamp_us; @@ -415,8 +415,8 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, a2dp_sbc_encoder_cb.stats.media_read_total_expected_frames += projected_nof; if (projected_nof > MAX_PCM_FRAME_NUM_PER_TICK) { - LOG_WARN("%s: limiting frames to be sent from %d to %d", __func__, - projected_nof, MAX_PCM_FRAME_NUM_PER_TICK); + log::warn("limiting frames to be sent from {} to {}", projected_nof, + MAX_PCM_FRAME_NUM_PER_TICK); // Update the stats size_t delta = projected_nof - MAX_PCM_FRAME_NUM_PER_TICK; @@ -425,26 +425,25 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, projected_nof = MAX_PCM_FRAME_NUM_PER_TICK; } - LOG_VERBOSE("%s: frames for available PCM data %u", __func__, projected_nof); + log::verbose("frames for available PCM data {}", projected_nof); if (a2dp_sbc_encoder_cb.peer_params.is_peer_edr) { if (!a2dp_sbc_encoder_cb.tx_sbc_frames) { - LOG_ERROR("%s: tx_sbc_frames not updated, update from here", __func__); + log::error("tx_sbc_frames not updated, update from here"); a2dp_sbc_encoder_cb.tx_sbc_frames = calculate_max_frames_per_packet(); } nof = a2dp_sbc_encoder_cb.tx_sbc_frames; if (!nof) { - LOG_ERROR("%s: number of frames not updated, set calculated values", - __func__); + log::error("number of frames not updated, set calculated values"); nof = projected_nof; noi = 1; } else { if (nof < projected_nof) { noi = projected_nof / nof; // number of iterations would vary if (noi > A2DP_SBC_MAX_PCM_ITER_NUM_PER_TICK) { - LOG_ERROR("%s: Audio Congestion (iterations:%d > max (%d))", __func__, - noi, A2DP_SBC_MAX_PCM_ITER_NUM_PER_TICK); + log::error("Audio Congestion (iterations:{} > max ({}))", noi, + A2DP_SBC_MAX_PCM_ITER_NUM_PER_TICK); noi = A2DP_SBC_MAX_PCM_ITER_NUM_PER_TICK; a2dp_sbc_encoder_cb.feeding_state.counter = noi * nof * (float)pcm_bytes_per_frame; @@ -452,16 +451,16 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, projected_nof = nof; } else { noi = 1; // number of iterations is 1 - LOG_VERBOSE("%s: reducing frames for available PCM data", __func__); + log::verbose("reducing frames for available PCM data"); nof = projected_nof; } } } else { // For BR cases nof will be same as the value retrieved at projected_nof - LOG_VERBOSE("%s: headset BR, number of frames %u", __func__, nof); + log::verbose("headset BR, number of frames {}", nof); if (projected_nof > MAX_PCM_FRAME_NUM_PER_TICK) { - LOG_ERROR("%s: Audio Congestion (frames: %d > max (%d))", __func__, - projected_nof, MAX_PCM_FRAME_NUM_PER_TICK); + log::error("Audio Congestion (frames: {} > max ({}))", projected_nof, + MAX_PCM_FRAME_NUM_PER_TICK); // Update the stats size_t delta = projected_nof - MAX_PCM_FRAME_NUM_PER_TICK; @@ -475,8 +474,7 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, } a2dp_sbc_encoder_cb.feeding_state.counter -= noi * nof * (float)pcm_bytes_per_frame; - LOG_VERBOSE("%s: effective num of frames %u, iterations %u", __func__, nof, - noi); + log::verbose("effective num of frames {}, iterations {}", nof, noi); *num_of_frames = nof; *num_of_iterations = noi; @@ -520,8 +518,8 @@ static void a2dp_sbc_encode_frames(uint8_t nb_frame) { bytes_read += num_bytes; } else { - LOG_WARN("%s: underflow %d, %d", __func__, nb_frame, - a2dp_sbc_encoder_cb.feeding_state.aa_feed_residue); + log::warn("underflow {}, {}", nb_frame, + a2dp_sbc_encoder_cb.feeding_state.aa_feed_residue); a2dp_sbc_encoder_cb.feeding_state.counter += nb_frame * p_encoder_params->s16NumOfSubBands * p_encoder_params->s16NumOfBlocks * @@ -719,16 +717,15 @@ static uint16_t adjust_effective_mtu( if (mtu_size > peer_params.peer_mtu) { mtu_size = peer_params.peer_mtu; } - LOG_VERBOSE("%s: original AVDTP MTU size: %d", __func__, mtu_size); + log::verbose("original AVDTP MTU size: {}", mtu_size); if (peer_params.is_peer_edr && !peer_params.peer_supports_3mbps) { // This condition would be satisfied only if the remote device is // EDR and supports only 2 Mbps, but the effective AVDTP MTU size // exceeds the 2DH5 packet size. - LOG_VERBOSE("%s: The remote device is EDR but does not support 3 Mbps", - __func__); + log::verbose("The remote device is EDR but does not support 3 Mbps"); if (mtu_size > MAX_2MBPS_AVDTP_MTU) { - LOG_WARN("%s: Restricting AVDTP MTU size from %d to %d", __func__, - mtu_size, MAX_2MBPS_AVDTP_MTU); + log::warn("Restricting AVDTP MTU size from {} to {}", mtu_size, + MAX_2MBPS_AVDTP_MTU); mtu_size = MAX_2MBPS_AVDTP_MTU; } } @@ -745,49 +742,47 @@ static uint8_t calculate_max_frames_per_packet(void) { const uint16_t& effective_mtu_size = a2dp_sbc_encoder_cb.TxAaMtuSize; if (!p_encoder_params->s16NumOfSubBands) { - LOG_ERROR("%s: SubBands are set to 0, resetting to %d", __func__, - SBC_MAX_NUM_OF_SUBBANDS); + log::error("SubBands are set to 0, resetting to {}", + SBC_MAX_NUM_OF_SUBBANDS); p_encoder_params->s16NumOfSubBands = SBC_MAX_NUM_OF_SUBBANDS; } if (!p_encoder_params->s16NumOfBlocks) { - LOG_ERROR("%s: Blocks are set to 0, resetting to %d", __func__, - SBC_MAX_NUM_OF_BLOCKS); + log::error("Blocks are set to 0, resetting to {}", SBC_MAX_NUM_OF_BLOCKS); p_encoder_params->s16NumOfBlocks = SBC_MAX_NUM_OF_BLOCKS; } if (!p_encoder_params->s16NumOfChannels) { - LOG_ERROR("%s: Channels are set to 0, resetting to %d", __func__, - SBC_MAX_NUM_OF_CHANNELS); + log::error("Channels are set to 0, resetting to {}", + SBC_MAX_NUM_OF_CHANNELS); p_encoder_params->s16NumOfChannels = SBC_MAX_NUM_OF_CHANNELS; } frame_len = a2dp_sbc_frame_length(); - LOG_VERBOSE("%s: Effective Tx MTU to be considered: %d", __func__, - effective_mtu_size); + log::verbose("Effective Tx MTU to be considered: {}", effective_mtu_size); switch (p_encoder_params->s16SamplingFreq) { case SBC_sf44100: if (frame_len == 0) { - LOG_ERROR("%s: Calculating frame length, resetting it to default %d", - __func__, A2DP_SBC_MAX_HQ_FRAME_SIZE_44_1); + log::error("Calculating frame length, resetting it to default {}", + A2DP_SBC_MAX_HQ_FRAME_SIZE_44_1); frame_len = A2DP_SBC_MAX_HQ_FRAME_SIZE_44_1; } result = (effective_mtu_size - A2DP_HDR_SIZE) / frame_len; - LOG_VERBOSE("%s: Max number of SBC frames: %d", __func__, result); + log::verbose("Max number of SBC frames: {}", result); break; case SBC_sf48000: if (frame_len == 0) { - LOG_ERROR("%s: Calculating frame length, resetting it to default %d", - __func__, A2DP_SBC_MAX_HQ_FRAME_SIZE_48); + log::error("Calculating frame length, resetting it to default {}", + A2DP_SBC_MAX_HQ_FRAME_SIZE_48); frame_len = A2DP_SBC_MAX_HQ_FRAME_SIZE_48; } result = (effective_mtu_size - A2DP_HDR_SIZE) / frame_len; - LOG_VERBOSE("%s: Max number of SBC frames: %d", __func__, result); + log::verbose("Max number of SBC frames: {}", result); break; default: - LOG_ERROR("%s: Max number of SBC frames: %d", __func__, result); + log::error("Max number of SBC frames: {}", result); break; } return result; @@ -799,8 +794,7 @@ static uint16_t a2dp_sbc_source_rate(bool is_peer_edr) { /* restrict bitrate if a2dp link is non-edr */ if (!is_peer_edr) { rate = A2DP_SBC_NON_EDR_MAX_RATE; - LOG_VERBOSE("%s: non-edr a2dp sink detected, restrict rate to %d", __func__, - rate); + log::verbose("non-edr a2dp sink detected, restrict rate to {}", rate); } return rate; @@ -810,13 +804,12 @@ static uint32_t a2dp_sbc_frame_length(void) { SBC_ENC_PARAMS* p_encoder_params = &a2dp_sbc_encoder_cb.sbc_encoder_params; uint32_t frame_len = 0; - LOG_VERBOSE( - "%s: channel mode: %d, sub-band: %d, number of block: %d, " - "bitpool: %d, sampling frequency: %d, num channels: %d", - __func__, p_encoder_params->s16ChannelMode, - p_encoder_params->s16NumOfSubBands, p_encoder_params->s16NumOfBlocks, - p_encoder_params->s16BitPool, p_encoder_params->s16SamplingFreq, - p_encoder_params->s16NumOfChannels); + log::verbose( + "channel mode: {}, sub-band: {}, number of block: {}, bitpool: {}, " + "sampling frequency: {}, num channels: {}", + p_encoder_params->s16ChannelMode, p_encoder_params->s16NumOfSubBands, + p_encoder_params->s16NumOfBlocks, p_encoder_params->s16BitPool, + p_encoder_params->s16SamplingFreq, p_encoder_params->s16NumOfChannels); switch (p_encoder_params->s16ChannelMode) { case SBC_MONO: @@ -854,17 +847,17 @@ static uint32_t a2dp_sbc_frame_length(void) { CHAR_BIT); break; default: - LOG_VERBOSE("%s: Invalid channel number: %d", __func__, - p_encoder_params->s16ChannelMode); + log::verbose("Invalid channel number: {}", + p_encoder_params->s16ChannelMode); break; } - LOG_VERBOSE("%s: calculated frame length: %d", __func__, frame_len); + log::verbose("calculated frame length: {}", frame_len); return frame_len; } uint32_t a2dp_sbc_get_bitrate() { SBC_ENC_PARAMS* p_encoder_params = &a2dp_sbc_encoder_cb.sbc_encoder_params; - LOG_INFO("%s: bit rate %d ", __func__, p_encoder_params->u16BitRate); + log::info("bit rate {} ", p_encoder_params->u16BitRate); return p_encoder_params->u16BitRate * 1000; } diff --git a/system/stack/a2dp/a2dp_vendor.cc b/system/stack/a2dp/a2dp_vendor.cc index 8cb171c9e0869ffd72e216d0daf651cdad1f593c..95093dfb515d711d85d1bc36fd3dd5bf099e0841 100644 --- a/system/stack/a2dp/a2dp_vendor.cc +++ b/system/stack/a2dp/a2dp_vendor.cc @@ -26,6 +26,7 @@ #include "a2dp_vendor_aptx_hd.h" #include "a2dp_vendor_ldac.h" #include "a2dp_vendor_opus.h" +#include "internal_include/bt_trace.h" #include "stack/include/bt_hdr.h" bool A2DP_IsVendorSourceCodecValid(const uint8_t* p_codec_info) { @@ -720,6 +721,9 @@ const char* A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index) { // Add a switch statement for each vendor-specific codec case BTAV_A2DP_CODEC_INDEX_MAX: break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN: + case BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN: + break; } return "UNKNOWN CODEC INDEX"; @@ -751,6 +755,9 @@ bool A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index, // Add a switch statement for each vendor-specific codec case BTAV_A2DP_CODEC_INDEX_MAX: break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN: + case BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN: + break; } return false; diff --git a/system/stack/a2dp/a2dp_vendor_aptx.cc b/system/stack/a2dp/a2dp_vendor_aptx.cc index 4d6ec80def7e2eafb678ba92161bc746da7e8085..7700043d2c49cb58e3a85d7de3ae58f019f00802 100644 --- a/system/stack/a2dp/a2dp_vendor_aptx.cc +++ b/system/stack/a2dp/a2dp_vendor_aptx.cc @@ -25,17 +25,19 @@ #include "a2dp_vendor_aptx.h" -#include +#include #include #include "a2dp_vendor.h" #include "a2dp_vendor_aptx_encoder.h" -#include "btif_av_co.h" +#include "btif/include/btif_av_co.h" +#include "include/check.h" #include "internal_include/bt_trace.h" -#include "os/log.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + // data type for the aptX Codec Information Element */ typedef struct { uint32_t vendorId; @@ -208,16 +210,16 @@ static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAptx( /* parse configuration */ status = A2DP_ParseInfoAptx(&cfg_cie, p_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: parsing failed %d", __func__, status); + log::error("parsing failed {}", status); return status; } /* verify that each parameter is in range */ - LOG_VERBOSE("%s: FREQ peer: 0x%x, capability 0x%x", __func__, - cfg_cie.sampleRate, p_cap->sampleRate); - LOG_VERBOSE("%s: CH_MODE peer: 0x%x, capability 0x%x", __func__, - cfg_cie.channelMode, p_cap->channelMode); + log::verbose("FREQ peer: 0x{:x}, capability 0x{:x}", cfg_cie.sampleRate, + p_cap->sampleRate); + log::verbose("CH_MODE peer: 0x{:x}, capability 0x{:x}", cfg_cie.channelMode, + p_cap->channelMode); /* sampling frequency */ if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ; @@ -247,12 +249,12 @@ bool A2DP_VendorCodecTypeEqualsAptx(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptx(&aptx_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoAptx(&aptx_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -268,12 +270,12 @@ bool A2DP_VendorCodecEqualsAptx(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptx(&aptx_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoAptx(&aptx_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -294,7 +296,7 @@ int A2DP_VendorGetTrackSampleRateAptx(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptx(&aptx_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -310,7 +312,7 @@ int A2DP_VendorGetTrackBitsPerSampleAptx(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptx(&aptx_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -324,7 +326,7 @@ int A2DP_VendorGetTrackChannelCountAptx(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptx(&aptx_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -424,7 +426,7 @@ bool A2DP_VendorInitCodecConfigAptx(AvdtpSepConfig* p_cfg) { A2dpCodecConfigAptx::A2dpCodecConfigAptx( btav_a2dp_codec_priority_t codec_priority) - : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, + : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, A2DP_CODEC_ID_APTX, A2DP_VendorCodecIndexStrAptx(), codec_priority) { // Compute the local capability if (a2dp_aptx_source_caps.sampleRate & A2DP_APTX_SAMPLERATE_44100) { @@ -450,7 +452,7 @@ bool A2dpCodecConfigAptx::init() { // Load the encoder if (A2DP_VendorLoadEncoderAptx() != LOAD_SUCCESS) { - LOG_ERROR("%s: cannot load the encoder", __func__); + log::error("cannot load the encoder"); return false; } @@ -630,8 +632,7 @@ bool A2dpCodecConfigAptx::setCodecConfig(const uint8_t* p_peer_codec_info, tA2DP_STATUS status = A2DP_ParseInfoAptx(&peer_info_cie, p_peer_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -714,10 +715,9 @@ bool A2dpCodecConfigAptx::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) { - LOG_ERROR( - "%s: cannot match sample frequency: local caps = 0x%x " - "peer info = 0x%x", - __func__, a2dp_aptx_source_caps.sampleRate, peer_info_cie.sampleRate); + log::error( + "cannot match sample frequency: local caps = 0x{:x} peer info = 0x{:x}", + a2dp_aptx_source_caps.sampleRate, peer_info_cie.sampleRate); goto fail; } @@ -769,8 +769,8 @@ bool A2dpCodecConfigAptx::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) { - LOG_ERROR("%s: cannot match bits per sample: user preference = 0x%x", - __func__, codec_user_config_.bits_per_sample); + log::error("cannot match bits per sample: user preference = 0x{:x}", + codec_user_config_.bits_per_sample); goto fail; } @@ -840,10 +840,9 @@ bool A2dpCodecConfigAptx::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) { - LOG_ERROR( - "%s: cannot match channel mode: local caps = 0x%x " - "peer info = 0x%x", - __func__, a2dp_aptx_source_caps.channelMode, peer_info_cie.channelMode); + log::error( + "cannot match channel mode: local caps = 0x{:x} peer info = 0x{:x}", + a2dp_aptx_source_caps.channelMode, peer_info_cie.channelMode); goto fail; } @@ -920,8 +919,7 @@ bool A2dpCodecConfigAptx::setPeerCodecCapabilities( tA2DP_STATUS status = A2DP_ParseInfoAptx(&peer_info_cie, p_peer_codec_capabilities, true); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } diff --git a/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc b/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc index 3568492f0a35c606bb898c4fb196203aa4c5dea3..f39b205a0492b742fe859d16c093f5f6a0e7c967 100644 --- a/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc +++ b/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc @@ -18,6 +18,7 @@ #include "a2dp_vendor_aptx_encoder.h" +#include #include #include #include @@ -32,6 +33,8 @@ #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + // // Encoder for aptX Source Codec // @@ -142,7 +145,7 @@ void a2dp_vendor_aptx_encoder_init( if (a2dp_aptx_encoder_cb.aptx_encoder_state != NULL) { aptx_api.init_func(a2dp_aptx_encoder_cb.aptx_encoder_state, 0); } else { - LOG_ERROR("%s: Cannot allocate aptX encoder state", __func__); + log::error("Cannot allocate aptX encoder state"); // TODO: Return an error? } @@ -167,10 +170,8 @@ static void a2dp_vendor_aptx_encoder_update(A2dpCodecConfig* a2dp_codec_config, *p_restart_output = false; *p_config_updated = false; if (!a2dp_codec_config->copyOutOtaCodecConfig(codec_info)) { - LOG_ERROR( - "%s: Cannot update the codec encoder for %s: " - "invalid codec config", - __func__, a2dp_codec_config->name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid codec config", + a2dp_codec_config->name().c_str()); return; } const uint8_t* p_codec_info = codec_info; @@ -183,9 +184,9 @@ static void a2dp_vendor_aptx_encoder_update(A2dpCodecConfig* a2dp_codec_config, a2dp_codec_config->getAudioBitsPerSample(); p_feeding_params->channel_count = A2DP_VendorGetTrackChannelCountAptx(p_codec_info); - LOG_INFO("%s: sample_rate=%u bits_per_sample=%u channel_count=%u", __func__, - p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, - p_feeding_params->channel_count); + log::info("sample_rate={} bits_per_sample={} channel_count={}", + p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, + p_feeding_params->channel_count); a2dp_vendor_aptx_feeding_reset(); } @@ -220,8 +221,7 @@ static void aptx_init_framing_params(tAPTX_FRAMING_PARAMS* framing_params) { } } - LOG_INFO("%s: sleep_time_ns = %" PRIu64, __func__, - framing_params->sleep_time_ns); + log::info("{}: sleep_time_ns = %", PRIu64); } // @@ -275,12 +275,10 @@ static void aptx_update_framing_params(tAPTX_FRAMING_PARAMS* framing_params) { } } - LOG_VERBOSE("%s: sleep_time_ns = %" PRIu64 - " aptx_bytes = %u " - "pcm_bytes_per_read = %u pcm_reads = %u frame_size_counter = %u", - __func__, framing_params->sleep_time_ns, - framing_params->aptx_bytes, framing_params->pcm_bytes_per_read, - framing_params->pcm_reads, framing_params->frame_size_counter); + log::verbose( + "{}: sleep_time_ns = %", PRIu64 + " aptx_bytes = %u " + "pcm_bytes_per_read = %u pcm_reads = %u frame_size_counter = %u"); } void a2dp_vendor_aptx_feeding_reset(void) { @@ -328,13 +326,13 @@ void a2dp_vendor_aptx_send_frames(uint64_t timestamp_us) { a2dp_aptx_encoder_cb.stats.media_read_total_expected_read_bytes += expected_read_bytes; - LOG_VERBOSE("%s: PCM read of size %u", __func__, expected_read_bytes); + log::verbose("PCM read of size {}", expected_read_bytes); bytes_read = a2dp_aptx_encoder_cb.read_callback((uint8_t*)read_buffer16, expected_read_bytes); a2dp_aptx_encoder_cb.stats.media_read_total_actual_read_bytes += bytes_read; if (bytes_read < expected_read_bytes) { - LOG_WARN("%s: underflow at PCM reading: read %u bytes instead of %u", - __func__, bytes_read, expected_read_bytes); + log::warn("underflow at PCM reading: read {} bytes instead of {}", + bytes_read, expected_read_bytes); a2dp_aptx_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -352,8 +350,7 @@ void a2dp_vendor_aptx_send_frames(uint64_t timestamp_us) { const int COMPRESSION_RATIO = 4; size_t encoded_bytes = pcm_bytes_encoded / COMPRESSION_RATIO; p_buf->len += encoded_bytes; - LOG_VERBOSE("%s: encoded %zu PCM bytes to %zu", __func__, pcm_bytes_encoded, - encoded_bytes); + log::verbose("encoded {} PCM bytes to {}", pcm_bytes_encoded, encoded_bytes); // Update the RTP timestamp *((uint32_t*)(p_buf + 1)) = a2dp_aptx_encoder_cb.timestamp; diff --git a/system/stack/a2dp/a2dp_vendor_aptx_hd.cc b/system/stack/a2dp/a2dp_vendor_aptx_hd.cc index 78c3cf8c4fb3d2cb656bb23385427e7f9f9d73e3..965704cc071aa2e188e9d1c24961f631d8b83e3c 100644 --- a/system/stack/a2dp/a2dp_vendor_aptx_hd.cc +++ b/system/stack/a2dp/a2dp_vendor_aptx_hd.cc @@ -26,16 +26,20 @@ #include "a2dp_vendor_aptx_hd.h" #include +#include #include #include "a2dp_vendor.h" #include "a2dp_vendor_aptx_hd_encoder.h" -#include "btif_av_co.h" +#include "btif/include/btif_av_co.h" +#include "include/check.h" #include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + // data type for the aptX-HD Codec Information Element */ typedef struct { uint32_t vendorId; @@ -226,16 +230,16 @@ static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAptxHd( /* parse configuration */ status = A2DP_ParseInfoAptxHd(&cfg_cie, p_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: parsing failed %d", __func__, status); + log::error("parsing failed {}", status); return status; } /* verify that each parameter is in range */ - LOG_VERBOSE("%s: FREQ peer: 0x%x, capability 0x%x", __func__, - cfg_cie.sampleRate, p_cap->sampleRate); - LOG_VERBOSE("%s: CH_MODE peer: 0x%x, capability 0x%x", __func__, - cfg_cie.channelMode, p_cap->channelMode); + log::verbose("FREQ peer: 0x{:x}, capability 0x{:x}", cfg_cie.sampleRate, + p_cap->sampleRate); + log::verbose("CH_MODE peer: 0x{:x}, capability 0x{:x}", cfg_cie.channelMode, + p_cap->channelMode); /* sampling frequency */ if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ; @@ -265,12 +269,12 @@ bool A2DP_VendorCodecTypeEqualsAptxHd(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -286,12 +290,12 @@ bool A2DP_VendorCodecEqualsAptxHd(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -313,7 +317,7 @@ int A2DP_VendorGetTrackSampleRateAptxHd(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -330,7 +334,7 @@ int A2DP_VendorGetTrackBitsPerSampleAptxHd(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -345,7 +349,7 @@ int A2DP_VendorGetTrackChannelCountAptxHd(const uint8_t* p_codec_info) { tA2DP_STATUS a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -447,7 +451,8 @@ bool A2DP_VendorInitCodecConfigAptxHd(AvdtpSepConfig* p_cfg) { A2dpCodecConfigAptxHd::A2dpCodecConfigAptxHd( btav_a2dp_codec_priority_t codec_priority) : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD, - A2DP_VendorCodecIndexStrAptxHd(), codec_priority) { + A2DP_CODEC_ID_APTX_HD, A2DP_VendorCodecIndexStrAptxHd(), + codec_priority) { // Compute the local capability if (a2dp_aptx_hd_source_caps.sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) { codec_local_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100; @@ -472,7 +477,7 @@ bool A2dpCodecConfigAptxHd::init() { // Load the encoder if (A2DP_VendorLoadEncoderAptxHd() != LOAD_SUCCESS) { - LOG_ERROR("%s: cannot load the encoder", __func__); + log::error("cannot load the encoder"); return false; } @@ -649,8 +654,7 @@ bool A2dpCodecConfigAptxHd::setCodecConfig(const uint8_t* p_peer_codec_info, tA2DP_STATUS status = A2DP_ParseInfoAptxHd(&peer_info_cie, p_peer_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -733,11 +737,9 @@ bool A2dpCodecConfigAptxHd::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) { - LOG_ERROR( - "%s: cannot match sample frequency: local caps = 0x%x " - "peer info = 0x%x", - __func__, a2dp_aptx_hd_source_caps.sampleRate, - peer_info_cie.sampleRate); + log::error( + "cannot match sample frequency: local caps = 0x{:x} peer info = 0x{:x}", + a2dp_aptx_hd_source_caps.sampleRate, peer_info_cie.sampleRate); goto fail; } @@ -789,8 +791,8 @@ bool A2dpCodecConfigAptxHd::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) { - LOG_ERROR("%s: cannot match bits per sample: user preference = 0x%x", - __func__, codec_user_config_.bits_per_sample); + log::error("cannot match bits per sample: user preference = 0x{:x}", + codec_user_config_.bits_per_sample); goto fail; } @@ -861,11 +863,9 @@ bool A2dpCodecConfigAptxHd::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) { - LOG_ERROR( - "%s: cannot match channel mode: local caps = 0x%x " - "peer info = 0x%x", - __func__, a2dp_aptx_hd_source_caps.channelMode, - peer_info_cie.channelMode); + log::error( + "cannot match channel mode: local caps = 0x{:x} peer info = 0x{:x}", + a2dp_aptx_hd_source_caps.channelMode, peer_info_cie.channelMode); goto fail; } @@ -949,8 +949,7 @@ bool A2dpCodecConfigAptxHd::setPeerCodecCapabilities( tA2DP_STATUS status = A2DP_ParseInfoAptxHd(&peer_info_cie, p_peer_codec_capabilities, true); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } diff --git a/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc b/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc index bfef8c2b5ff92eea458ad172c31129466bec6e10..a399c2461f89dc92dfcc14e86f1040ffc4434ec6 100644 --- a/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc +++ b/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc @@ -18,6 +18,7 @@ #include "a2dp_vendor_aptx_hd_encoder.h" +#include #include #include #include @@ -32,6 +33,8 @@ #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + // // Encoder for aptX-HD Source Codec // @@ -142,7 +145,7 @@ void a2dp_vendor_aptx_hd_encoder_init( if (a2dp_aptx_hd_encoder_cb.aptx_hd_encoder_state != NULL) { aptx_hd_api.init_func(a2dp_aptx_hd_encoder_cb.aptx_hd_encoder_state, 0); } else { - LOG_ERROR("%s: Cannot allocate aptX-HD encoder state", __func__); + log::error("Cannot allocate aptX-HD encoder state"); // TODO: Return an error? } @@ -166,10 +169,8 @@ static void a2dp_vendor_aptx_hd_encoder_update( *p_restart_output = false; *p_config_updated = false; if (!a2dp_codec_config->copyOutOtaCodecConfig(codec_info)) { - LOG_ERROR( - "%s: Cannot update the codec encoder for %s: " - "invalid codec config", - __func__, a2dp_codec_config->name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid codec config", + a2dp_codec_config->name().c_str()); return; } const uint8_t* p_codec_info = codec_info; @@ -183,9 +184,9 @@ static void a2dp_vendor_aptx_hd_encoder_update( a2dp_codec_config->getAudioBitsPerSample(); p_feeding_params->channel_count = A2DP_VendorGetTrackChannelCountAptxHd(p_codec_info); - LOG_INFO("%s: sample_rate=%u bits_per_sample=%u channel_count=%u", __func__, - p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, - p_feeding_params->channel_count); + log::info("sample_rate={} bits_per_sample={} channel_count={}", + p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, + p_feeding_params->channel_count); a2dp_vendor_aptx_hd_feeding_reset(); } @@ -208,8 +209,7 @@ static void aptx_hd_init_framing_params( framing_params->sleep_time_ns = 9000000; - LOG_INFO("%s: sleep_time_ns = %" PRIu64, __func__, - framing_params->sleep_time_ns); + log::info("{}: sleep_time_ns = %", PRIu64); } // @@ -258,12 +258,10 @@ static void aptx_hd_update_framing_params( framing_params->frame_size_counter = 0; } - LOG_VERBOSE("%s: sleep_time_ns = %" PRIu64 - " aptx_hd_bytes = %u " - "pcm_bytes_per_read = %u pcm_reads = %u frame_size_counter = %u", - __func__, framing_params->sleep_time_ns, - framing_params->aptx_hd_bytes, framing_params->pcm_bytes_per_read, - framing_params->pcm_reads, framing_params->frame_size_counter); + log::verbose( + "{}: sleep_time_ns = %", PRIu64 + " aptx_hd_bytes = %u " + "pcm_bytes_per_read = %u pcm_reads = %u frame_size_counter = %u"); } void a2dp_vendor_aptx_hd_feeding_reset(void) { @@ -313,14 +311,14 @@ void a2dp_vendor_aptx_hd_send_frames(uint64_t timestamp_us) { a2dp_aptx_hd_encoder_cb.stats.media_read_total_expected_read_bytes += expected_read_bytes; - LOG_VERBOSE("%s: PCM read of size %u", __func__, expected_read_bytes); + log::verbose("PCM read of size {}", expected_read_bytes); bytes_read = a2dp_aptx_hd_encoder_cb.read_callback((uint8_t*)read_buffer32, expected_read_bytes); a2dp_aptx_hd_encoder_cb.stats.media_read_total_actual_read_bytes += bytes_read; if (bytes_read < expected_read_bytes) { - LOG_WARN("%s: underflow at PCM reading: read %u bytes instead of %u", - __func__, bytes_read, expected_read_bytes); + log::warn("underflow at PCM reading: read {} bytes instead of {}", + bytes_read, expected_read_bytes); a2dp_aptx_hd_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -339,8 +337,7 @@ void a2dp_vendor_aptx_hd_send_frames(uint64_t timestamp_us) { const int COMPRESSION_RATIO = 4; size_t encoded_bytes = pcm_bytes_encoded / COMPRESSION_RATIO; p_buf->len += encoded_bytes; - LOG_VERBOSE("%s: encoded %zu PCM bytes to %zu", __func__, pcm_bytes_encoded, - encoded_bytes); + log::verbose("encoded {} PCM bytes to {}", pcm_bytes_encoded, encoded_bytes); // Update the RTP timestamp *((uint32_t*)(p_buf + 1)) = a2dp_aptx_hd_encoder_cb.timestamp; diff --git a/system/stack/a2dp/a2dp_vendor_aptx_hd_linux.cc b/system/stack/a2dp/a2dp_vendor_aptx_hd_linux.cc index 923d40035db997329a147ef8eb34e25efe65b908..25731516c7b11626c1da81197f27789270c564b7 100644 --- a/system/stack/a2dp/a2dp_vendor_aptx_hd_linux.cc +++ b/system/stack/a2dp/a2dp_vendor_aptx_hd_linux.cc @@ -116,7 +116,8 @@ bool A2DP_VendorInitCodecConfigAptxHd(AvdtpSepConfig* p_cfg) { return false; } A2dpCodecConfigAptxHd::A2dpCodecConfigAptxHd( btav_a2dp_codec_priority_t codec_priority) : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD, - A2DP_VendorCodecIndexStrAptxHd(), codec_priority) {} + A2DP_CODEC_ID_APTX_HD, A2DP_VendorCodecIndexStrAptxHd(), + codec_priority) {} A2dpCodecConfigAptxHd::~A2dpCodecConfigAptxHd() {} diff --git a/system/stack/a2dp/a2dp_vendor_aptx_linux.cc b/system/stack/a2dp/a2dp_vendor_aptx_linux.cc index 24a68229ee02130989b57b604207bde2d205c297..0b8b81ed0543a81c8ab6de3a74ff97f03ede3e1e 100644 --- a/system/stack/a2dp/a2dp_vendor_aptx_linux.cc +++ b/system/stack/a2dp/a2dp_vendor_aptx_linux.cc @@ -114,7 +114,7 @@ bool A2DP_VendorInitCodecConfigAptx(AvdtpSepConfig* p_cfg) { return false; } A2dpCodecConfigAptx::A2dpCodecConfigAptx( btav_a2dp_codec_priority_t codec_priority) - : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, + : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, A2DP_CODEC_ID_APTX, A2DP_VendorCodecIndexStrAptx(), codec_priority) {} A2dpCodecConfigAptx::~A2dpCodecConfigAptx() {} diff --git a/system/stack/a2dp/a2dp_vendor_ldac.cc b/system/stack/a2dp/a2dp_vendor_ldac.cc index 65e899177829337345174fe7c0e5be1ce63977d0..356f5284ae7426b28b285bb6ae291c223e03d35e 100644 --- a/system/stack/a2dp/a2dp_vendor_ldac.cc +++ b/system/stack/a2dp/a2dp_vendor_ldac.cc @@ -26,16 +26,19 @@ #include "a2dp_vendor_ldac.h" #include +#include #include #include "a2dp_vendor_ldac_decoder.h" #include "a2dp_vendor_ldac_encoder.h" -#include "btif_av_co.h" +#include "btif/include/btif_av_co.h" #include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + // data type for the LDAC Codec Information Element */ // NOTE: bits_per_sample is needed only for LDAC encoder initialization. typedef struct { @@ -279,16 +282,16 @@ static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityLdac( /* parse configuration */ status = A2DP_ParseInfoLdac(&cfg_cie, p_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: parsing failed %d", __func__, status); + log::error("parsing failed {}", status); return status; } /* verify that each parameter is in range */ - LOG_VERBOSE("%s: FREQ peer: 0x%x, capability 0x%x", __func__, - cfg_cie.sampleRate, p_cap->sampleRate); - LOG_VERBOSE("%s: CH_MODE peer: 0x%x, capability 0x%x", __func__, - cfg_cie.channelMode, p_cap->channelMode); + log::verbose("FREQ peer: 0x{:x}, capability 0x{:x}", cfg_cie.sampleRate, + p_cap->sampleRate); + log::verbose("CH_MODE peer: 0x{:x}, capability 0x{:x}", cfg_cie.channelMode, + p_cap->channelMode); /* sampling frequency */ if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ; @@ -318,12 +321,12 @@ bool A2DP_VendorCodecTypeEqualsLdac(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoLdac(&ldac_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoLdac(&ldac_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -339,12 +342,12 @@ bool A2DP_VendorCodecEqualsLdac(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoLdac(&ldac_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoLdac(&ldac_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -388,7 +391,7 @@ int A2DP_VendorGetTrackSampleRateLdac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoLdac(&ldac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -416,7 +419,7 @@ int A2DP_VendorGetTrackBitsPerSampleLdac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoLdac(&ldac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -444,7 +447,7 @@ int A2DP_VendorGetTrackChannelCountLdac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoLdac(&ldac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -466,7 +469,7 @@ int A2DP_VendorGetSinkTrackChannelTypeLdac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoLdac(&ldac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -488,7 +491,7 @@ int A2DP_VendorGetChannelModeCodeLdac(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoLdac(&ldac_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("%s: cannot decode codec information: %d", __func__, a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -699,7 +702,7 @@ bool A2dpCodecConfigLdacSource::init() { // Load the encoder if (!A2DP_VendorLoadEncoderLdac()) { - LOG_ERROR("%s: cannot load the encoder", __func__); + log::error("cannot load the encoder"); return false; } @@ -967,8 +970,7 @@ bool A2dpCodecConfigLdacBase::setCodecConfig(const uint8_t* p_peer_codec_info, tA2DP_STATUS status = A2DP_ParseInfoLdac(&peer_info_cie, p_peer_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -1099,10 +1101,9 @@ bool A2dpCodecConfigLdacBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) { - LOG_ERROR( - "%s: cannot match sample frequency: local caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_ldac_caps->sampleRate, peer_info_cie.sampleRate); + log::error( + "cannot match sample frequency: local caps = 0x{:x} peer info = 0x{:x}", + p_a2dp_ldac_caps->sampleRate, peer_info_cie.sampleRate); goto fail; } @@ -1174,10 +1175,10 @@ bool A2dpCodecConfigLdacBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) { - LOG_ERROR( - "%s: cannot match bits per sample: default = 0x%x " - "user preference = 0x%x", - __func__, a2dp_ldac_default_config.bits_per_sample, + log::error( + "cannot match bits per sample: default = 0x{:x} user preference = " + "0x{:x}", + a2dp_ldac_default_config.bits_per_sample, codec_user_config_.bits_per_sample); goto fail; } @@ -1261,10 +1262,9 @@ bool A2dpCodecConfigLdacBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) { - LOG_ERROR( - "%s: cannot match channel mode: local caps = 0x%x " - "peer info = 0x%x", - __func__, p_a2dp_ldac_caps->channelMode, peer_info_cie.channelMode); + log::error( + "cannot match channel mode: local caps = 0x{:x} peer info = 0x{:x}", + p_a2dp_ldac_caps->channelMode, peer_info_cie.channelMode); goto fail; } @@ -1334,8 +1334,7 @@ bool A2dpCodecConfigLdacBase::setPeerCodecCapabilities( tA2DP_STATUS status = A2DP_ParseInfoLdac(&peer_info_cie, p_peer_codec_capabilities, true); if (status != A2DP_SUCCESS) { - LOG_ERROR("%s: can't parse peer's capabilities: error = %d", __func__, - status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -1411,7 +1410,7 @@ bool A2dpCodecConfigLdacSink::init() { // Load the decoder if (!A2DP_VendorLoadDecoderLdac()) { - LOG_ERROR("%s: cannot load the decoder", __func__); + log::error("cannot load the decoder"); return false; } diff --git a/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc b/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc index 3b734520a5c03bbaae7b0f24c12537bfd5fb3cfa..6327ff42be8aea43ef056a00c1b471f8221fe6ef 100644 --- a/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc +++ b/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc @@ -19,6 +19,7 @@ #include "a2dp_vendor_ldac_decoder.h" #include +#include #include #include #include @@ -30,6 +31,13 @@ #include "os/log.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + // // Decoder for LDAC Source Codec // @@ -100,8 +108,8 @@ static tA2DP_LDAC_DECODER_CB a2dp_ldac_decoder_cb; static void* load_func(const char* func_name) { void* func_ptr = dlsym(ldac_bco_lib_handle, func_name); if (func_ptr == NULL) { - LOG_ERROR("%s: cannot find function '%s' in the decoder library: %s", - __func__, func_name, dlerror()); + log::error("cannot find function '{}' in the decoder library: {}", + func_name, dlerror()); A2DP_VendorUnloadDecoderLdac(); return NULL; } @@ -119,8 +127,8 @@ bool A2DP_VendorLoadDecoderLdac(void) { // Open the decoder library ldac_bco_lib_handle = dlopen(LDAC_BCO_LIB_NAME, RTLD_NOW); if (ldac_bco_lib_handle == NULL) { - LOG_INFO("%s: cannot open LDAC decoder library %s: %s", __func__, - LDAC_BCO_LIB_NAME, dlerror()); + log::info("cannot open LDAC decoder library {}: {}", LDAC_BCO_LIB_NAME, + dlerror()); return false; } @@ -192,7 +200,7 @@ void a2dp_vendor_ldac_decoder_cleanup(void) { bool a2dp_vendor_ldac_decoder_decode_packet(BT_HDR* p_buf) { if (p_buf == nullptr) { - LOG_ERROR("%s Dropping packet with nullptr", __func__); + log::error("Dropping packet with nullptr"); return false; } pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex)); @@ -202,7 +210,7 @@ bool a2dp_vendor_ldac_decoder_decode_packet(BT_HDR* p_buf) { unsigned int bytesValid = p_buf->len; if (bytesValid == 0) { pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex)); - LOG_WARN("%s Dropping packet with zero length", __func__); + log::warn("Dropping packet with zero length"); return false; } @@ -211,7 +219,7 @@ bool a2dp_vendor_ldac_decoder_decode_packet(BT_HDR* p_buf) { frame_number = (int)pBuffer[0]; bs_bytes = (int)bytesValid; bytesValid -= 1; - LOG_INFO("%s:INPUT size : %d, frame : %d", __func__, bs_bytes, frame_number); + log::info("INPUT size : {}, frame : {}", bs_bytes, frame_number); if (a2dp_ldac_decoder_cb.has_ldac_handle) ldac_BCO_decode_packet_func(a2dp_ldac_decoder_cb.ldac_handle_bco, pBuffer, @@ -223,7 +231,7 @@ bool a2dp_vendor_ldac_decoder_decode_packet(BT_HDR* p_buf) { void a2dp_vendor_ldac_decoder_start(void) { pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex)); - LOG_INFO("%s", __func__); + log::info(""); if (a2dp_ldac_decoder_cb.has_ldac_handle) ldac_BCO_start_func(a2dp_ldac_decoder_cb.ldac_handle_bco); pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex)); @@ -231,7 +239,7 @@ void a2dp_vendor_ldac_decoder_start(void) { void a2dp_vendor_ldac_decoder_suspend(void) { pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex)); - LOG_INFO("%s", __func__); + log::info(""); if (a2dp_ldac_decoder_cb.has_ldac_handle) ldac_BCO_suspend_func(a2dp_ldac_decoder_cb.ldac_handle_bco); pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex)); @@ -243,7 +251,7 @@ void a2dp_vendor_ldac_decoder_configure(const uint8_t* p_codec_info) { int32_t channel_mode; if (p_codec_info == NULL) { - LOG_ERROR("%s: p_codec_info is NULL", __func__); + log::error("p_codec_info is NULL"); return; } @@ -252,8 +260,8 @@ void a2dp_vendor_ldac_decoder_configure(const uint8_t* p_codec_info) { bits_per_sample = A2DP_VendorGetTrackBitsPerSampleLdac(p_codec_info); channel_mode = A2DP_VendorGetChannelModeCodeLdac(p_codec_info); - LOG_INFO("%s , sample_rate=%d, bits_per_sample=%d, channel_mode=%d", __func__, - sample_rate, bits_per_sample, channel_mode); + log::info(", sample_rate={}, bits_per_sample={}, channel_mode={}", + sample_rate, bits_per_sample, channel_mode); if (a2dp_ldac_decoder_cb.has_ldac_handle) ldac_BCO_configure_func(a2dp_ldac_decoder_cb.ldac_handle_bco, sample_rate, diff --git a/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc b/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc index d7f1ce8af64305af465f06b731b2a9edaf08865d..8a88a2d15b4658a4d7bfb3b9e1e3e176068404d8 100644 --- a/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc +++ b/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc @@ -22,6 +22,7 @@ #ifdef __ANDROID__ #include #endif +#include #include #include #include @@ -30,6 +31,7 @@ #include "a2dp_vendor_ldac.h" #include "common/time_util.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -49,6 +51,13 @@ // offset #define A2DP_LDAC_OFFSET (AVDT_MEDIA_OFFSET + A2DP_LDAC_MPL_HDR_LEN) +using namespace bluetooth; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + typedef struct { uint32_t sample_rate; uint8_t channel_mode; @@ -175,7 +184,7 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, if (!a2dp_ldac_encoder_cb.has_ldac_handle) { a2dp_ldac_encoder_cb.ldac_handle = ldacBT_get_handle(); if (a2dp_ldac_encoder_cb.ldac_handle == NULL) { - LOG_ERROR("%s: Cannot get LDAC encoder handle", __func__); + log::error("Cannot get LDAC encoder handle"); return; // TODO: Return an error? } a2dp_ldac_encoder_cb.has_ldac_handle = true; @@ -183,10 +192,8 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, CHECK(a2dp_ldac_encoder_cb.ldac_handle != nullptr); if (!a2dp_codec_config->copyOutOtaCodecConfig(codec_info)) { - LOG_ERROR( - "%s: Cannot update the codec encoder for %s: " - "invalid codec config", - __func__, a2dp_codec_config->name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid codec config", + a2dp_codec_config->name().c_str()); return; } const uint8_t* p_codec_info = codec_info; @@ -200,9 +207,9 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, a2dp_codec_config->getAudioBitsPerSample(); p_feeding_params->channel_count = A2DP_VendorGetTrackChannelCountLdac(p_codec_info); - LOG_INFO("%s: sample_rate=%u bits_per_sample=%u channel_count=%u", __func__, - p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, - p_feeding_params->channel_count); + log::info("sample_rate={} bits_per_sample={} channel_count={}", + p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, + p_feeding_params->channel_count); a2dp_vendor_ldac_feeding_reset(); // The codec parameters @@ -215,35 +222,32 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, int old_quality_mode_index = p_encoder_params->quality_mode_index; if (codec_config.codec_specific_1 != 0) { p_encoder_params->quality_mode_index = codec_config.codec_specific_1 % 10; - LOG_INFO("%s: setting quality mode to %s", __func__, - quality_mode_index_to_name(p_encoder_params->quality_mode_index) - .c_str()); + log::info("setting quality mode to {}", + quality_mode_index_to_name(p_encoder_params->quality_mode_index) + .c_str()); } else { p_encoder_params->quality_mode_index = A2DP_LDAC_QUALITY_ABR; - LOG_INFO("%s: setting quality mode to default %s", __func__, - quality_mode_index_to_name(p_encoder_params->quality_mode_index) - .c_str()); + log::info("setting quality mode to default {}", + quality_mode_index_to_name(p_encoder_params->quality_mode_index) + .c_str()); } int ldac_eqmid = LDAC_ABR_MODE_EQMID; if (p_encoder_params->quality_mode_index == A2DP_LDAC_QUALITY_ABR) { if (!ldac_abr_loaded) { p_encoder_params->quality_mode_index = A2DP_LDAC_QUALITY_MID; - LOG_WARN( - - "%s: LDAC ABR library is not loaded, resetting quality mode to %s", - __func__, - quality_mode_index_to_name(p_encoder_params->quality_mode_index) - .c_str()); + log::warn("LDAC ABR library is not loaded, resetting quality mode to {}", + quality_mode_index_to_name(p_encoder_params->quality_mode_index) + .c_str()); } else { - LOG_INFO("%s: changing mode from %s to %s", __func__, - quality_mode_index_to_name(old_quality_mode_index).c_str(), - quality_mode_index_to_name(p_encoder_params->quality_mode_index) - .c_str()); + log::info("changing mode from {} to {}", + quality_mode_index_to_name(old_quality_mode_index).c_str(), + quality_mode_index_to_name(p_encoder_params->quality_mode_index) + .c_str()); if (a2dp_ldac_encoder_cb.ldac_abr_handle != NULL) { - LOG_INFO("%s: already in LDAC ABR mode, do nothing.", __func__); + log::info("already in LDAC ABR mode, do nothing."); } else { - LOG_INFO("%s: get and init LDAC ABR handle.", __func__); + log::info("get and init LDAC ABR handle."); a2dp_ldac_encoder_cb.ldac_abr_handle = ldac_ABR_get_handle(); if (a2dp_ldac_encoder_cb.ldac_abr_handle != NULL) { a2dp_ldac_encoder_cb.has_ldac_abr_handle = true; @@ -253,10 +257,8 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, A2DP_LDAC_ENCODER_INTERVAL_MS); } else { p_encoder_params->quality_mode_index = A2DP_LDAC_QUALITY_MID; - LOG_INFO( - - "%s: get LDAC ABR handle failed, resetting quality mode to %s.", - __func__, + log::info( + "get LDAC ABR handle failed, resetting quality mode to {}.", quality_mode_index_to_name(p_encoder_params->quality_mode_index) .c_str()); } @@ -264,8 +266,8 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, } } else { ldac_eqmid = p_encoder_params->quality_mode_index; - LOG_INFO("%s: in %s mode, free LDAC ABR handle.", __func__, - quality_mode_index_to_name(ldac_eqmid).c_str()); + log::info("in {} mode, free LDAC ABR handle.", + quality_mode_index_to_name(ldac_eqmid).c_str()); if (a2dp_ldac_encoder_cb.has_ldac_abr_handle) { ldac_ABR_free_handle(a2dp_ldac_encoder_cb.ldac_abr_handle); a2dp_ldac_encoder_cb.ldac_abr_handle = NULL; @@ -292,12 +294,12 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, const tA2DP_ENCODER_INIT_PEER_PARAMS& peer_params = a2dp_ldac_encoder_cb.peer_params; a2dp_ldac_encoder_cb.TxAaMtuSize = adjust_effective_mtu(peer_params); - LOG_INFO("%s: MTU=%d, peer_mtu=%d", __func__, - a2dp_ldac_encoder_cb.TxAaMtuSize, peer_params.peer_mtu); - LOG_INFO( - "%s: sample_rate: %d channel_mode: %d " - "quality_mode_index: %d pcm_wlength: %d pcm_fmt: %d", - __func__, p_encoder_params->sample_rate, p_encoder_params->channel_mode, + log::info("MTU={}, peer_mtu={}", a2dp_ldac_encoder_cb.TxAaMtuSize, + peer_params.peer_mtu); + log::info( + "sample_rate: {} channel_mode: {} quality_mode_index: {} pcm_wlength: {} " + "pcm_fmt: {}", + p_encoder_params->sample_rate, p_encoder_params->channel_mode, p_encoder_params->quality_mode_index, p_encoder_params->pcm_wlength, p_encoder_params->pcm_fmt); @@ -310,10 +312,10 @@ static void a2dp_vendor_ldac_encoder_update(A2dpCodecConfig* a2dp_codec_config, p_encoder_params->sample_rate); if (result != 0) { int err_code = ldacBT_get_error_code(a2dp_ldac_encoder_cb.ldac_handle); - LOG_ERROR( - "%s: error initializing the LDAC encoder: %d api_error = %d " - "handle_error = %d block_error = %d error_code = 0x%x", - __func__, result, LDACBT_API_ERR(err_code), LDACBT_HANDLE_ERR(err_code), + log::error( + "error initializing the LDAC encoder: {} api_error = {} handle_error = " + "{} block_error = {} error_code = 0x{:x}", + result, LDACBT_API_ERR(err_code), LDACBT_HANDLE_ERR(err_code), LDACBT_BLOCK_ERR(err_code), err_code); } } @@ -340,8 +342,8 @@ void a2dp_vendor_ldac_feeding_reset(void) { A2DP_LDAC_ENCODER_INTERVAL_MS) / 1000; - LOG_INFO("%s: PCM bytes per tick %u", __func__, - a2dp_ldac_encoder_cb.ldac_feeding_state.bytes_per_tick); + log::info("PCM bytes per tick {}", + a2dp_ldac_encoder_cb.ldac_feeding_state.bytes_per_tick); } void a2dp_vendor_ldac_feeding_flush(void) { @@ -361,8 +363,8 @@ void a2dp_vendor_ldac_send_frames(uint64_t timestamp_us) { uint8_t nb_iterations = 0; a2dp_ldac_get_num_frame_iteration(&nb_iterations, &nb_frame, timestamp_us); - LOG_VERBOSE("%s: Sending %d frames per iteration, %d iterations", __func__, - nb_frame, nb_iterations); + log::verbose("Sending {} frames per iteration, {} iterations", nb_frame, + nb_iterations); if (nb_frame == 0) return; for (uint8_t counter = 0; counter < nb_iterations; counter++) { @@ -398,7 +400,7 @@ static void a2dp_ldac_get_num_frame_iteration(uint8_t* num_of_iterations, A2DP_LDAC_MEDIA_BYTES_PER_FRAME * a2dp_ldac_encoder_cb.feeding_params.channel_count * a2dp_ldac_encoder_cb.feeding_params.bits_per_sample / 8; - LOG_VERBOSE("%s: pcm_bytes_per_frame %u", __func__, pcm_bytes_per_frame); + log::verbose("pcm_bytes_per_frame {}", pcm_bytes_per_frame); uint32_t us_this_tick = A2DP_LDAC_ENCODER_INTERVAL_MS * 1000; uint64_t now_us = timestamp_us; @@ -417,8 +419,7 @@ static void a2dp_ldac_get_num_frame_iteration(uint8_t* num_of_iterations, result * pcm_bytes_per_frame; nof = result; - LOG_VERBOSE("%s: effective num of frames %u, iterations %u", __func__, nof, - noi); + log::verbose("effective num of frames {}, iterations {}", nof, noi); *num_of_frames = nof; *num_of_iterations = noi; @@ -470,7 +471,7 @@ static void a2dp_ldac_encode_frames(uint8_t nb_frame) { bytes_read += temp_bytes_read; uint8_t* packet = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len; if (a2dp_ldac_encoder_cb.ldac_handle == NULL) { - LOG_ERROR("%s: invalid LDAC handle", __func__); + log::error("invalid LDAC handle"); a2dp_ldac_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -481,12 +482,11 @@ static void a2dp_ldac_encode_frames(uint8_t nb_frame) { if (result != 0) { int err_code = ldacBT_get_error_code(a2dp_ldac_encoder_cb.ldac_handle); - LOG_ERROR( - "%s: LDAC encoding error: %d api_error = %d " - "handle_error = %d block_error = %d error_code = 0x%x", - __func__, result, LDACBT_API_ERR(err_code), - LDACBT_HANDLE_ERR(err_code), LDACBT_BLOCK_ERR(err_code), - err_code); + log::error( + "LDAC encoding error: {} api_error = {} handle_error = {} " + "block_error = {} error_code = 0x{:x}", + result, LDACBT_API_ERR(err_code), LDACBT_HANDLE_ERR(err_code), + LDACBT_BLOCK_ERR(err_code), err_code); a2dp_ldac_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -496,7 +496,7 @@ static void a2dp_ldac_encode_frames(uint8_t nb_frame) { nb_frame--; p_buf->layer_specific += out_frames; // added a frame to the buffer } else { - LOG_WARN("%s: underflow %d", __func__, nb_frame); + log::warn("underflow {}", nb_frame); a2dp_ldac_encoder_cb.ldac_feeding_state.counter += nb_frame * LDACBT_ENC_LSU * a2dp_ldac_encoder_cb.feeding_params.channel_count * @@ -565,7 +565,7 @@ static uint16_t adjust_effective_mtu( if (mtu_size > peer_params.peer_mtu) { mtu_size = peer_params.peer_mtu; } - LOG_VERBOSE("%s: original AVDTP MTU size: %d", __func__, mtu_size); + log::verbose("original AVDTP MTU size: {}", mtu_size); return mtu_size; } diff --git a/system/stack/a2dp/a2dp_vendor_opus.cc b/system/stack/a2dp/a2dp_vendor_opus.cc index 0ce0e7ac401f54190495d1a730e6302d24255868..5b9c8b895ab065bc2e474b321e33da738631f36a 100644 --- a/system/stack/a2dp/a2dp_vendor_opus.cc +++ b/system/stack/a2dp/a2dp_vendor_opus.cc @@ -26,14 +26,18 @@ #include "a2dp_vendor_opus.h" #include +#include #include #include "a2dp_vendor_opus_decoder.h" #include "a2dp_vendor_opus_encoder.h" +#include "include/check.h" #include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/osi.h" +using namespace bluetooth; + // data type for the Opus Codec Information Element */ // NOTE: bits_per_sample and frameSize for Opus encoder initialization. typedef struct { @@ -128,7 +132,7 @@ static tA2DP_STATUS A2DP_BuildInfoOpus(uint8_t media_type, const tA2DP_OPUS_CIE* p_ie, uint8_t* p_result) { if (p_ie == NULL || p_result == NULL) { - LOG_ERROR("invalid information element"); + log::error("invalid information element"); return A2DP_INVALID_PARAMS; } @@ -147,19 +151,19 @@ static tA2DP_STATUS A2DP_BuildInfoOpus(uint8_t media_type, *p_result = 0; *p_result |= (uint8_t)(p_ie->channelMode) & A2DP_OPUS_CHANNEL_MODE_MASK; if ((*p_result & A2DP_OPUS_CHANNEL_MODE_MASK) == 0) { - LOG_ERROR("channelmode 0x%X setting failed", (p_ie->channelMode)); + log::error("channelmode 0x{:X} setting failed", (p_ie->channelMode)); return A2DP_INVALID_PARAMS; } *p_result |= ((uint8_t)(p_ie->future1) & A2DP_OPUS_FRAMESIZE_MASK); if ((*p_result & A2DP_OPUS_FRAMESIZE_MASK) == 0) { - LOG_ERROR("frameSize 0x%X setting failed", (p_ie->future1)); + log::error("frameSize 0x{:X} setting failed", (p_ie->future1)); return A2DP_INVALID_PARAMS; } *p_result |= ((uint8_t)(p_ie->sampleRate) & A2DP_OPUS_SAMPLING_FREQ_MASK); if ((*p_result & A2DP_OPUS_SAMPLING_FREQ_MASK) == 0) { - LOG_ERROR("samplerate 0x%X setting failed", (p_ie->sampleRate)); + log::error("samplerate 0x{:X} setting failed", (p_ie->sampleRate)); return A2DP_INVALID_PARAMS; } @@ -182,14 +186,14 @@ static tA2DP_STATUS A2DP_ParseInfoOpus(tA2DP_OPUS_CIE* p_ie, tA2DP_CODEC_TYPE codec_type; if (p_ie == NULL || p_codec_info == NULL) { - LOG_ERROR("unable to parse information element"); + log::error("unable to parse information element"); return A2DP_INVALID_PARAMS; } // Check the codec capability length losc = *p_codec_info++; if (losc != A2DP_OPUS_CODEC_LEN) { - LOG_ERROR("invalid codec ie length %d", losc); + log::error("invalid codec ie length {}", losc); return A2DP_WRONG_CODEC; } @@ -198,7 +202,7 @@ static tA2DP_STATUS A2DP_ParseInfoOpus(tA2DP_OPUS_CIE* p_ie, /* Check the Media Type and Media Codec Type */ if (media_type != AVDT_MEDIA_TYPE_AUDIO || codec_type != A2DP_MEDIA_CT_NON_A2DP) { - LOG_ERROR("invalid codec"); + log::error("invalid codec"); return A2DP_WRONG_CODEC; } @@ -213,7 +217,7 @@ static tA2DP_STATUS A2DP_ParseInfoOpus(tA2DP_OPUS_CIE* p_ie, p_codec_info += 2; if (p_ie->vendorId != A2DP_OPUS_VENDOR_ID || p_ie->codecId != A2DP_OPUS_CODEC_ID) { - LOG_ERROR("wrong vendor or codec id"); + log::error("wrong vendor or codec id"); return A2DP_WRONG_CODEC; } @@ -226,11 +230,11 @@ static tA2DP_STATUS A2DP_ParseInfoOpus(tA2DP_OPUS_CIE* p_ie, // NOTE: The checks here are very liberal. We should be using more // pedantic checks specific to the SRC or SNK as specified in the spec. if (A2DP_BitsSet(p_ie->sampleRate) == A2DP_SET_ZERO_BIT) { - LOG_ERROR("invalid sample rate 0x%X", p_ie->sampleRate); + log::error("invalid sample rate 0x{:X}", p_ie->sampleRate); return A2DP_BAD_SAMP_FREQ; } if (A2DP_BitsSet(p_ie->channelMode) == A2DP_SET_ZERO_BIT) { - LOG_ERROR("invalid channel mode"); + log::error("invalid channel mode"); return A2DP_BAD_CH_MODE; } @@ -238,11 +242,11 @@ static tA2DP_STATUS A2DP_ParseInfoOpus(tA2DP_OPUS_CIE* p_ie, } if (A2DP_BitsSet(p_ie->sampleRate) != A2DP_SET_ONE_BIT) { - LOG_ERROR("invalid sampling frequency 0x%X", p_ie->sampleRate); + log::error("invalid sampling frequency 0x{:X}", p_ie->sampleRate); return A2DP_BAD_SAMP_FREQ; } if (A2DP_BitsSet(p_ie->channelMode) != A2DP_SET_ONE_BIT) { - LOG_ERROR("invalid channel mode."); + log::error("invalid channel mode."); return A2DP_BAD_CH_MODE; } @@ -327,18 +331,18 @@ static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityOpus( /* parse configuration */ status = A2DP_ParseInfoOpus(&cfg_cie, p_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("parsing failed %d", status); + log::error("parsing failed {}", status); return status; } /* verify that each parameter is in range */ - LOG_VERBOSE("SAMPLING FREQ peer: 0x%x, capability 0x%x", cfg_cie.sampleRate, - p_cap->sampleRate); - LOG_VERBOSE("CH_MODE peer: 0x%x, capability 0x%x", cfg_cie.channelMode, - p_cap->channelMode); - LOG_VERBOSE("FRAMESIZE peer: 0x%x, capability 0x%x", cfg_cie.future1, - p_cap->future1); + log::verbose("SAMPLING FREQ peer: 0x{:x}, capability 0x{:x}", + cfg_cie.sampleRate, p_cap->sampleRate); + log::verbose("CH_MODE peer: 0x{:x}, capability 0x{:x}", cfg_cie.channelMode, + p_cap->channelMode); + log::verbose("FRAMESIZE peer: 0x{:x}, capability 0x{:x}", cfg_cie.future1, + p_cap->future1); /* sampling frequency */ if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ; @@ -370,12 +374,12 @@ bool A2DP_VendorCodecTypeEqualsOpus(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoOpus(&Opus_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -391,12 +395,12 @@ bool A2DP_VendorCodecEqualsOpus(const uint8_t* p_codec_info_a, tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie_a, p_codec_info_a, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } a2dp_status = A2DP_ParseInfoOpus(&Opus_cie_b, p_codec_info_b, true); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return false; } @@ -430,7 +434,7 @@ int A2DP_VendorGetTrackSampleRateOpus(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -448,7 +452,7 @@ int A2DP_VendorGetTrackBitsPerSampleOpus(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -461,7 +465,7 @@ int A2DP_VendorGetTrackBitsPerSampleOpus(const uint8_t* p_codec_info) { return 32; case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE: default: - LOG_ERROR("Invalid bit depth setting"); + log::error("Invalid bit depth setting"); return -1; } } @@ -472,7 +476,7 @@ int A2DP_VendorGetTrackChannelCountOpus(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -483,7 +487,7 @@ int A2DP_VendorGetTrackChannelCountOpus(const uint8_t* p_codec_info) { case A2DP_OPUS_CHANNEL_MODE_DUAL_MONO: return 2; default: - LOG_ERROR("Invalid channel setting"); + log::error("Invalid channel setting"); } return -1; @@ -495,7 +499,7 @@ int A2DP_VendorGetSinkTrackChannelTypeOpus(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -515,7 +519,7 @@ int A2DP_VendorGetChannelModeCodeOpus(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } @@ -536,7 +540,7 @@ int A2DP_VendorGetFrameSizeOpus(const uint8_t* p_codec_info) { // Check whether the codec info contains valid data tA2DP_STATUS a2dp_status = A2DP_ParseInfoOpus(&Opus_cie, p_codec_info, false); if (a2dp_status != A2DP_SUCCESS) { - LOG_ERROR("cannot decode codec information: %d", a2dp_status); + log::error("cannot decode codec information: {}", a2dp_status); return -1; } int samplerate = A2DP_VendorGetTrackSampleRateOpus(p_codec_info); @@ -898,9 +902,8 @@ bool A2dpCodecConfigOpusBase::setCodecConfig(const uint8_t* p_peer_codec_info, btav_a2dp_codec_config_t device_codec_config_ = getCodecConfig(); - LOG_INFO( - "AudioManager stream config %d sample rate %d bit depth %d channel " - "mode", + log::info( + "AudioManager stream config {} sample rate {} bit depth {} channel mode", device_codec_config_.sample_rate, device_codec_config_.bits_per_sample, device_codec_config_.channel_mode); @@ -923,7 +926,7 @@ bool A2dpCodecConfigOpusBase::setCodecConfig(const uint8_t* p_peer_codec_info, tA2DP_STATUS status = A2DP_ParseInfoOpus(&peer_info_cie, p_peer_codec_info, is_capability); if (status != A2DP_SUCCESS) { - LOG_ERROR("can't parse peer's capabilities: error = %d", status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -995,9 +998,8 @@ bool A2dpCodecConfigOpusBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) { - LOG_ERROR( - "cannot match sample frequency: local caps = 0x%x " - "peer info = 0x%x", + log::error( + "cannot match sample frequency: local caps = 0x{:x} peer info = 0x{:x}", p_a2dp_opus_caps->sampleRate, peer_info_cie.sampleRate); goto fail; } @@ -1070,9 +1072,9 @@ bool A2dpCodecConfigOpusBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) { - LOG_ERROR( - "cannot match bits per sample: default = 0x%x " - "user preference = 0x%x", + log::error( + "cannot match bits per sample: default = 0x{:x} user preference = " + "0x{:x}", a2dp_opus_default_config.bits_per_sample, codec_user_config_.bits_per_sample); goto fail; @@ -1145,9 +1147,8 @@ bool A2dpCodecConfigOpusBase::setCodecConfig(const uint8_t* p_peer_codec_info, } } while (false); if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) { - LOG_ERROR( - "cannot match channel mode: local caps = 0x%x " - "peer info = 0x%x", + log::error( + "cannot match channel mode: local caps = 0x{:x} peer info = 0x{:x}", p_a2dp_opus_caps->channelMode, peer_info_cie.channelMode); goto fail; } @@ -1186,16 +1187,15 @@ bool A2dpCodecConfigOpusBase::setCodecConfig(const uint8_t* p_peer_codec_info, result_config_cie.future3 = 0x00; if (codec_config_.codec_specific_1 == BTAV_A2DP_CODEC_FRAME_SIZE_NONE) { - LOG_ERROR( - "cannot match frame size: local caps = 0x%x " - "peer info = 0x%x", + log::error( + "cannot match frame size: local caps = 0x{:x} peer info = 0x{:x}", p_a2dp_opus_caps->future1, peer_info_cie.future1); goto fail; } if (A2DP_BuildInfoOpus(AVDT_MEDIA_TYPE_AUDIO, &result_config_cie, p_result_codec_config) != A2DP_SUCCESS) { - LOG_ERROR("failed to BuildInfoOpus for result_config_cie"); + log::error("failed to BuildInfoOpus for result_config_cie"); goto fail; } @@ -1261,7 +1261,7 @@ bool A2dpCodecConfigOpusBase::setPeerCodecCapabilities( tA2DP_STATUS status = A2DP_ParseInfoOpus(&peer_info_cie, p_peer_codec_capabilities, true); if (status != A2DP_SUCCESS) { - LOG_ERROR("can't parse peer's capabilities: error = %d", status); + log::error("can't parse peer's capabilities: error = {}", status); goto fail; } @@ -1287,7 +1287,7 @@ bool A2dpCodecConfigOpusBase::setPeerCodecCapabilities( BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO; } - LOG_INFO("BuildInfoOpus for peer info cie for ota caps"); + log::info("BuildInfoOpus for peer info cie for ota caps"); status = A2DP_BuildInfoOpus(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie, ota_codec_peer_capability_); CHECK(status == A2DP_SUCCESS); diff --git a/system/stack/a2dp/a2dp_vendor_opus_decoder.cc b/system/stack/a2dp/a2dp_vendor_opus_decoder.cc index d36112bf0f1261cd02955ac83df27d9cfa7cf743..ad3fbe14433d37da5002d2977cc78f9152b3728f 100644 --- a/system/stack/a2dp/a2dp_vendor_opus_decoder.cc +++ b/system/stack/a2dp/a2dp_vendor_opus_decoder.cc @@ -19,11 +19,14 @@ #include "a2dp_vendor_opus_decoder.h" #include +#include #include #include "a2dp_vendor_opus.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" + +using namespace bluetooth; typedef struct { OpusDecoder* opus_handle = nullptr; @@ -60,7 +63,7 @@ bool a2dp_vendor_opus_decoder_init(decoded_data_callback_t decode_callback) { a2dp_opus_decoder_cb.opus_handle = static_cast(osi_malloc(size)); if (a2dp_opus_decoder_cb.opus_handle == nullptr) { - LOG_ERROR("failed to allocate opus decoder handle"); + log::error("failed to allocate opus decoder handle"); return false; } err_val = opus_decoder_init(a2dp_opus_decoder_cb.opus_handle, @@ -75,10 +78,10 @@ bool a2dp_vendor_opus_decoder_init(decoded_data_callback_t decode_callback) { memset(a2dp_opus_decoder_cb.decode_buf, 0, A2DP_OPUS_DECODE_BUFFER_LENGTH); a2dp_opus_decoder_cb.decode_callback = decode_callback; - LOG_INFO("decoder init success"); + log::info("decoder init success"); return true; } else { - LOG_ERROR("failed to initialize Opus Decoder"); + log::error("failed to initialize Opus Decoder"); a2dp_opus_decoder_cb.has_opus_handle = false; return false; } @@ -96,12 +99,12 @@ bool a2dp_vendor_opus_decoder_decode_packet(BT_HDR* p_buf) { uint32_t frameLen = 0; if (p_buf == nullptr) { - LOG_ERROR("Dropping packet with nullptr"); + log::error("Dropping packet with nullptr"); return false; } if (p_buf->len == 0) { - LOG_ERROR("Empty packet"); + log::error("Empty packet"); return false; } @@ -117,10 +120,10 @@ bool a2dp_vendor_opus_decoder_decode_packet(BT_HDR* p_buf) { A2DP_OPUS_CODEC_DEFAULT_SAMPLERATE); uint32_t num_frames = pBuffer[0] & 0xf; - LOG_ERROR("numframes %d framesize %d framelen %d bufferSize %d", num_frames, - frameSize, frameLen, bufferSize); - LOG_ERROR("numChannels %d numFrames %d offset %d", numChannels, numFrames, - p_buf->offset); + log::error("numframes {} framesize {} framelen {} bufferSize {}", num_frames, + frameSize, frameLen, bufferSize); + log::error("numChannels {} numFrames {} offset {}", numChannels, numFrames, + p_buf->offset); for (uint32_t frame = 0; frame < numFrames; ++frame) { { @@ -132,15 +135,15 @@ bool a2dp_vendor_opus_decoder_decode_packet(BT_HDR* p_buf) { A2DP_OPUS_DECODE_BUFFER_LENGTH, 0 /* flags */); if (ret_val < OPUS_OK) { - LOG_ERROR("Opus DecodeFrame failed %d, applying concealment", ret_val); + log::error("Opus DecodeFrame failed {}, applying concealment", ret_val); ret_val = opus_decode(a2dp_opus_decoder_cb.opus_handle, NULL, 0, a2dp_opus_decoder_cb.decode_buf, A2DP_OPUS_DECODE_BUFFER_LENGTH, 0 /* flags */); } if (ret_val < OPUS_OK) { - LOG_ERROR("Opus DecodeFrame retry failed with %d, dropping packet", - ret_val); + log::error("Opus DecodeFrame retry failed with {}, dropping packet", + ret_val); return false; } @@ -163,7 +166,7 @@ void a2dp_vendor_opus_decoder_suspend(void) { err_val = opus_decoder_ctl(a2dp_opus_decoder_cb.opus_handle, OPUS_RESET_STATE); if (err_val != OPUS_OK) { - LOG_ERROR("failed to reset decoder"); + log::error("failed to reset decoder"); } } return; diff --git a/system/stack/a2dp/a2dp_vendor_opus_encoder.cc b/system/stack/a2dp/a2dp_vendor_opus_encoder.cc index 7c85b9005c1e7592bccf265bfee5af2eae762230..e8b59d0f848cc951c5d7aad8f4d8e64b790555d3 100644 --- a/system/stack/a2dp/a2dp_vendor_opus_encoder.cc +++ b/system/stack/a2dp/a2dp_vendor_opus_encoder.cc @@ -18,8 +18,8 @@ #include "a2dp_vendor_opus_encoder.h" +#include #include -#include #include #include #include @@ -27,11 +27,14 @@ #include "a2dp_vendor.h" #include "a2dp_vendor_opus.h" #include "common/time_util.h" +#include "include/check.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + typedef struct { uint32_t sample_rate; uint16_t bitrate; @@ -138,7 +141,7 @@ void a2dp_vendor_opus_encoder_init( a2dp_opus_encoder_cb.opus_handle = static_cast(osi_malloc(size)); if (a2dp_opus_encoder_cb.opus_handle == nullptr) { - LOG_ERROR("failed to allocate opus encoder handle"); + log::error("failed to allocate opus encoder handle"); return; } @@ -147,9 +150,9 @@ void a2dp_vendor_opus_encoder_init( A2DP_OPUS_CODEC_OUTPUT_CHS, OPUS_APPLICATION_AUDIO); if (error_val != OPUS_OK) { - LOG_ERROR( - "failed to init opus encoder (handle size %d, sampling rate %d, " - "output chs %d, error %d)", + log::error( + "failed to init opus encoder (handle size {}, sampling rate {}, output " + "chs {}, error {})", size, A2DP_OPUS_CODEC_DEFAULT_SAMPLERATE, A2DP_OPUS_CODEC_OUTPUT_CHS, error_val); osi_free(a2dp_opus_encoder_cb.opus_handle); @@ -169,10 +172,8 @@ bool A2dpCodecConfigOpusSource::updateEncoderUserConfig( const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, bool* p_restart_input, bool* p_restart_output, bool* p_config_updated) { if (a2dp_opus_encoder_cb.peer_mtu == 0) { - LOG_ERROR( - "Cannot update the codec encoder for %s: " - "invalid peer MTU", - name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid peer MTU", + name().c_str()); return false; } @@ -197,16 +198,14 @@ static bool a2dp_vendor_opus_encoder_update(uint16_t peer_mtu, if (!a2dp_opus_encoder_cb.has_opus_handle || a2dp_opus_encoder_cb.opus_handle == NULL) { - LOG_ERROR("Cannot get Opus encoder handle"); + log::error("Cannot get Opus encoder handle"); return false; } CHECK(a2dp_opus_encoder_cb.opus_handle != nullptr); if (!a2dp_codec_config->copyOutOtaCodecConfig(codec_info)) { - LOG_ERROR( - "Cannot update the codec encoder for %s: " - "invalid codec config", - a2dp_codec_config->name().c_str()); + log::error("Cannot update the codec encoder for {}: invalid codec config", + a2dp_codec_config->name().c_str()); return false; } const uint8_t* p_codec_info = codec_info; @@ -220,9 +219,9 @@ static bool a2dp_vendor_opus_encoder_update(uint16_t peer_mtu, a2dp_codec_config->getAudioBitsPerSample(); p_feeding_params->channel_count = A2DP_VendorGetTrackChannelCountOpus(p_codec_info); - LOG_INFO("sample_rate=%u bits_per_sample=%u channel_count=%u", - p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, - p_feeding_params->channel_count); + log::info("sample_rate={} bits_per_sample={} channel_count={}", + p_feeding_params->sample_rate, p_feeding_params->bits_per_sample, + p_feeding_params->channel_count); // The codec parameters p_encoder_params->sample_rate = @@ -245,12 +244,12 @@ static bool a2dp_vendor_opus_encoder_update(uint16_t peer_mtu, // Set the bitrate quality mode index if (codec_config.codec_specific_3 != 0) { p_encoder_params->quality_mode_index = codec_config.codec_specific_3 % 10; - LOG_INFO("setting bitrate quality mode to %d", - p_encoder_params->quality_mode_index); + log::info("setting bitrate quality mode to {}", + p_encoder_params->quality_mode_index); } else { p_encoder_params->quality_mode_index = 5; - LOG_INFO("setting bitrate quality mode to default %d", - p_encoder_params->quality_mode_index); + log::info("setting bitrate quality mode to default {}", + p_encoder_params->quality_mode_index); } error = opus_encoder_ctl( @@ -258,19 +257,19 @@ static bool a2dp_vendor_opus_encoder_update(uint16_t peer_mtu, OPUS_SET_COMPLEXITY(p_encoder_params->quality_mode_index)); if (error != OPUS_OK) { - LOG_ERROR("failed to set encoder bitrate quality setting"); + log::error("failed to set encoder bitrate quality setting"); return false; } p_encoder_params->pcm_wlength = a2dp_opus_encoder_cb.feeding_params.bits_per_sample >> 3; - LOG_INFO("setting bitrate to %d", p_encoder_params->bitrate); + log::info("setting bitrate to {}", p_encoder_params->bitrate); error = opus_encoder_ctl(a2dp_opus_encoder_cb.opus_handle, OPUS_SET_BITRATE(p_encoder_params->bitrate)); if (error != OPUS_OK) { - LOG_ERROR("failed to set encoder bitrate"); + log::error("failed to set encoder bitrate"); return false; } @@ -392,7 +391,7 @@ static void a2dp_opus_encode_frames(uint8_t nb_frame) { packet = (unsigned char*)(p_buf + 1) + p_buf->offset + p_buf->len; if (a2dp_opus_encoder_cb.opus_handle == NULL) { - LOG_ERROR("invalid OPUS handle"); + log::error("invalid OPUS handle"); a2dp_opus_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -404,7 +403,7 @@ static void a2dp_opus_encode_frames(uint8_t nb_frame) { packet, (BT_DEFAULT_BUFFER_SIZE - p_buf->offset)); if (written <= 0) { - LOG_ERROR("OPUS encoding error"); + log::error("OPUS encoding error"); a2dp_opus_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); return; @@ -415,7 +414,7 @@ static void a2dp_opus_encode_frames(uint8_t nb_frame) { nb_frame--; p_buf->layer_specific += out_frames; // added a frame to the buffer } else { - LOG_WARN("Opus src buffer underflow %d", nb_frame); + log::warn("Opus src buffer underflow {}", nb_frame); a2dp_opus_encoder_cb.opus_feeding_state.counter += nb_frame * opus_frame_size * a2dp_opus_encoder_cb.feeding_params.channel_count * diff --git a/system/stack/acl/acl.h b/system/stack/acl/acl.h index 5fbc10c9fec0e914a4fe78acfdafaddeebe40ef4..818c27ad4a61b06fd4d732a7fb730a229de1c816 100644 --- a/system/stack/acl/acl.h +++ b/system/stack/acl/acl.h @@ -18,6 +18,7 @@ #include #include +#include #include "internal_include/bt_target.h" #include "internal_include/bt_trace.h" @@ -303,8 +304,6 @@ struct tACL_CONN { return is_switch_role_switching() || is_switch_role_in_progress(); } - friend void DumpsysL2cap(int fd); - public: uint8_t sca; /* Sleep clock accuracy */ @@ -325,7 +324,6 @@ struct tACL_CB { friend void btm_acl_encrypt_change(uint16_t handle, uint8_t status, uint8_t encr_enable); - friend void DumpsysL2cap(int fd); friend void DumpsysAcl(int fd); friend struct StackAclBtmAcl; @@ -362,3 +360,6 @@ struct tACL_CB { }; tACL_CONN* btm_acl_for_bda(const RawAddress& bd_addr, tBT_TRANSPORT transport); + +void btm_acl_encrypt_change(uint16_t handle, uint8_t status, + uint8_t encr_enable); \ No newline at end of file diff --git a/system/stack/acl/ble_acl.cc b/system/stack/acl/ble_acl.cc index 1d42c7af1ccfda3e9c26925bbc7ed56434990129..051526e7b9ecd49f9bc9a2bf1620f51281a2b0bf 100644 --- a/system/stack/acl/ble_acl.cc +++ b/system/stack/acl/ble_acl.cc @@ -16,9 +16,11 @@ #define LOG_TAG "acl" +#include + #include -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "os/log.h" #include "stack/btm/btm_ble_int.h" #include "stack/btm/btm_dev.h" @@ -31,6 +33,8 @@ #include "stack/include/l2cap_hci_link_interface.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; void btm_ble_increment_link_topology_mask(uint8_t link_role); @@ -63,7 +67,7 @@ static bool acl_ble_common_connection( address_with_type.type, conn_interval, conn_latency, conn_timeout)) { btm_sec_disconnect(handle, HCI_ERR_PEER_USER, "stack::acl::ble_acl fail"); - LOG_WARN("Unable to complete l2cap connection"); + log::warn("Unable to complete l2cap connection"); return false; } @@ -82,7 +86,7 @@ void acl_ble_enhanced_connection_complete( if (!acl_ble_common_connection(address_with_type, handle, role, match, conn_interval, conn_latency, conn_timeout, can_read_discoverable_characteristics)) { - LOG_WARN("Unable to create enhanced ble acl connection"); + log::warn("Unable to create enhanced ble acl connection"); return; } @@ -145,10 +149,10 @@ void acl_ble_connection_fail(const tBLE_BD_ADDR& address_with_type, connection_manager::on_connection_timed_out_from_shim( resolved_address_with_type.bda); } - LOG_WARN("LE connection fail peer:%s bd_addr:%s hci_status:%s", - ADDRESS_TO_LOGGABLE_CSTR(address_with_type), - ADDRESS_TO_LOGGABLE_CSTR(resolved_address_with_type.bda), - hci_status_code_text(status).c_str()); + log::warn("LE connection fail peer:{} bd_addr:{} hci_status:{}", + ADDRESS_TO_LOGGABLE_CSTR(address_with_type), + ADDRESS_TO_LOGGABLE_CSTR(resolved_address_with_type.bda), + hci_status_code_text(status).c_str()); } else { btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; } @@ -176,9 +180,9 @@ void acl_ble_data_length_change_event(uint16_t handle, uint16_t max_tx_octets, uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time) { - LOG_DEBUG( - "Data length change event received handle:0x%04x max_tx_octets:%hu " - "max_tx_time:%hu max_rx_octets:%hu max_rx_time:%hu", + log::debug( + "Data length change event received handle:0x{:04x} max_tx_octets:{} " + "max_tx_time:{} max_rx_octets:{} max_rx_time:{}", handle, max_tx_octets, max_tx_time, max_rx_octets, max_rx_time); l2cble_process_data_length_change_event(handle, max_tx_octets, max_rx_octets); } diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc index 1f0631880f75773265e6ea6c7ed625d63d5ac05e..f86484de23d3bb64d0e28f97ded4a3d180d1b8d1 100644 --- a/system/stack/acl/btm_acl.cc +++ b/system/stack/acl/btm_acl.cc @@ -31,20 +31,22 @@ * *****************************************************************************/ +#include "main/shim/entry.h" #define LOG_TAG "btm_acl" -#include +#include #include #include "bta/include/bta_dm_acl.h" #include "bta/sys/bta_sys.h" -#include "btif/include/btif_acl.h" #include "common/init_flags.h" #include "common/metrics.h" #include "device/include/controller.h" #include "device/include/device_iot_config.h" #include "device/include/interop.h" +#include "hci/controller_interface.h" +#include "include/check.h" #include "include/l2cap_hci_link_interface.h" #include "internal_include/bt_target.h" #include "main/shim/acl_api.h" @@ -62,6 +64,7 @@ #include "stack/acl/peer_packet_types.h" #include "stack/btm/btm_dev.h" #include "stack/btm/btm_int_types.h" +#include "stack/btm/btm_sco.h" #include "stack/btm/btm_sec.h" #include "stack/btm/security_device_record.h" #include "stack/include/acl_api.h" @@ -77,7 +80,6 @@ #include "stack/include/l2cap_acl_interface.h" #include "stack/include/l2cdefs.h" #include "stack/include/main_thread.h" -#include "stack/include/sco_hci_link_interface.h" #include "types/hci_role.h" #include "types/raw_address.h" @@ -86,6 +88,7 @@ "bluetooth.core.acl.link_supervision_timeout" #endif +using namespace bluetooth; using bluetooth::legacy::hci::GetInterface; void BTM_update_version_info(const RawAddress& bd_addr, @@ -150,11 +153,11 @@ constexpr uint16_t BTM_ACL_EXCEPTION_PKTS_MASK = static bool IsEprAvailable(const tACL_CONN& p_acl) { if (!p_acl.peer_lmp_feature_valid[0]) { - LOG_WARN("Checking incomplete feature page read"); + log::warn("Checking incomplete feature page read"); return false; } return HCI_ATOMIC_ENCRYPT_SUPPORTED(p_acl.peer_lmp_feature_pages[0]) && - controller_get_interface()->supports_encryption_pause(); + bluetooth::shim::GetController()->SupportsEncryptionPause(); } static void btm_process_remote_ext_features(tACL_CONN* p_acl_cb, @@ -169,7 +172,7 @@ void btm_set_link_policy(tACL_CONN* conn, tLINK_POLICY policy); namespace { void NotifyAclLinkUp(tACL_CONN& p_acl) { if (p_acl.link_up_issued) { - LOG_INFO("Already notified BTA layer that the link is up"); + log::info("Already notified BTA layer that the link is up"); return; } p_acl.link_up_issued = true; @@ -200,9 +203,9 @@ void NotifyAclFeaturesReadComplete(tACL_CONN& p_acl, static void disconnect_acl(tACL_CONN& p_acl, tHCI_STATUS reason, std::string comment) { - LOG_INFO("Disconnecting peer:%s reason:%s comment:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_acl.remote_addr), - hci_error_code_text(reason).c_str(), comment.c_str()); + log::info("Disconnecting peer:{} reason:{} comment:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_acl.remote_addr), + hci_error_code_text(reason).c_str(), comment.c_str()); p_acl.disconnect_reason = reason; return bluetooth::shim::ACL_Disconnect( @@ -219,22 +222,23 @@ void StackAclBtmAcl::hci_start_role_switch_to_central(tACL_CONN& p_acl) { void hci_btm_set_link_supervision_timeout(tACL_CONN& link, uint16_t timeout) { if (link.link_role != HCI_ROLE_CENTRAL) { /* Only send if current role is Central; 2.0 spec requires this */ - LOG_WARN("Can only set link supervision timeout if central role:%s", - RoleText(link.link_role).c_str()); + log::warn("Can only set link supervision timeout if central role:{}", + RoleText(link.link_role).c_str()); return; } if (!bluetooth::shim:: controller_is_write_link_supervision_timeout_supported()) { - LOG_WARN( - "UNSUPPORTED by controller write link supervision timeout:%.2fms " - "bd_addr:%s", + log::warn( + "UNSUPPORTED by controller write link supervision timeout:{:.2f}ms " + "bd_addr:{}", supervision_timeout_to_seconds(timeout), ADDRESS_TO_LOGGABLE_CSTR(link.RemoteAddress())); return; } - LOG_DEBUG("Setting link supervision timeout:%.2fs peer:%s", - double(timeout) * 0.01, ADDRESS_TO_LOGGABLE_CSTR(link.RemoteAddress())); + log::debug("Setting link supervision timeout:{:.2f}s peer:{}", + double(timeout) * 0.01, + ADDRESS_TO_LOGGABLE_CSTR(link.RemoteAddress())); link.link_super_tout = timeout; btsnd_hcic_write_link_super_tout(link.Handle(), timeout); } @@ -251,35 +255,35 @@ void BTM_acl_after_controller_started(const controller_t* controller) { uint16_t btm_acl_pkt_types_supported = (HCI_PKT_TYPES_MASK_DH1 + HCI_PKT_TYPES_MASK_DM1); - if (controller->supports_3_slot_packets()) + if (bluetooth::shim::GetController()->Supports3SlotPackets()) btm_acl_pkt_types_supported |= (HCI_PKT_TYPES_MASK_DH3 + HCI_PKT_TYPES_MASK_DM3); - if (controller->supports_5_slot_packets()) + if (bluetooth::shim::GetController()->Supports5SlotPackets()) btm_acl_pkt_types_supported |= (HCI_PKT_TYPES_MASK_DH5 + HCI_PKT_TYPES_MASK_DM5); /* Add in EDR related ACL types */ - if (!controller->supports_classic_2m_phy()) { + if (!bluetooth::shim::GetController()->SupportsClassic2mPhy()) { btm_acl_pkt_types_supported |= (HCI_PKT_TYPES_MASK_NO_2_DH1 + HCI_PKT_TYPES_MASK_NO_2_DH3 + HCI_PKT_TYPES_MASK_NO_2_DH5); } - if (!controller->supports_classic_3m_phy()) { + if (!bluetooth::shim::GetController()->SupportsClassic3mPhy()) { btm_acl_pkt_types_supported |= (HCI_PKT_TYPES_MASK_NO_3_DH1 + HCI_PKT_TYPES_MASK_NO_3_DH3 + HCI_PKT_TYPES_MASK_NO_3_DH5); } /* Check to see if 3 and 5 slot packets are available */ - if (controller->supports_classic_2m_phy() || - controller->supports_classic_3m_phy()) { - if (!controller->supports_3_slot_edr_packets()) + if (bluetooth::shim::GetController()->SupportsClassic2mPhy() || + bluetooth::shim::GetController()->SupportsClassic3mPhy()) { + if (!bluetooth::shim::GetController()->Supports3SlotEdrPackets()) btm_acl_pkt_types_supported |= (HCI_PKT_TYPES_MASK_NO_2_DH3 + HCI_PKT_TYPES_MASK_NO_3_DH3); - if (!controller->supports_5_slot_edr_packets()) + if (!bluetooth::shim::GetController()->Supports5SlotEdrPackets()) btm_acl_pkt_types_supported |= (HCI_PKT_TYPES_MASK_NO_2_DH5 + HCI_PKT_TYPES_MASK_NO_3_DH5); } @@ -325,8 +329,8 @@ void StackAclBtmAcl::btm_acl_consolidate(const RawAddress& identity_addr, if (!p_acl->in_use) continue; if (p_acl->remote_addr == rpa) { - LOG_INFO("consolidate %s -> %s", ADDRESS_TO_LOGGABLE_CSTR(rpa), - ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); + log::info("consolidate {} -> {}", ADDRESS_TO_LOGGABLE_CSTR(rpa), + ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); p_acl->remote_addr = identity_addr; return; } @@ -377,15 +381,15 @@ void btm_acl_process_sca_cmpl_pkt(uint8_t len, uint8_t* data) { uint8_t status; if (len < 4) { - LOG_WARN("Malformatted packet, not containing enough data"); + log::warn("Malformatted packet, not containing enough data"); return; } STREAM_TO_UINT8(status, data); if (status != HCI_SUCCESS) { - LOG_WARN("Peer SCA Command complete failed:%s", - hci_error_code_text(static_cast(status)).c_str()); + log::warn("Peer SCA Command complete failed:{}", + hci_error_code_text(static_cast(status)).c_str()); return; } @@ -394,7 +398,7 @@ void btm_acl_process_sca_cmpl_pkt(uint8_t len, uint8_t* data) { tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(handle); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } p_acl->sca = sca; @@ -420,9 +424,9 @@ void btm_acl_created(const RawAddress& bda, uint16_t hci_handle, if (transport == BT_TRANSPORT_BR_EDR) { btm_set_link_policy(p_acl, btm_cb.acl_cb_.DefaultLinkPolicy()); } - LOG_WARN( - "Unable to create duplicate acl when one already exists handle:%hu" - " role:%s transport:%s", + log::warn( + "Unable to create duplicate acl when one already exists handle:{} " + "role:{} transport:{}", hci_handle, RoleText(link_role).c_str(), bt_transport_text(transport).c_str()); return; @@ -430,7 +434,7 @@ void btm_acl_created(const RawAddress& bda, uint16_t hci_handle, p_acl = internal_.acl_allocate_connection(); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } @@ -444,10 +448,10 @@ void btm_acl_created(const RawAddress& bda, uint16_t hci_handle, p_acl->switch_role_failed_attempts = 0; p_acl->reset_switch_role(); - LOG_DEBUG( - "Created new ACL connection peer:%s role:%s handle:0x%04x transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda), RoleText(p_acl->link_role).c_str(), hci_handle, - bt_transport_text(transport).c_str()); + log::debug( + "Created new ACL connection peer:{} role:{} handle:0x{:04x} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda), RoleText(p_acl->link_role).c_str(), + hci_handle, bt_transport_text(transport).c_str()); if (p_acl->is_transport_br_edr()) { BTM_PM_OnConnected(hci_handle, bda); @@ -467,7 +471,7 @@ void btm_acl_created(const RawAddress& bda, uint16_t hci_handle, &p_acl->active_remote_addr_type); if (controller_get_interface() - ->supports_ble_peripheral_initiated_feature_exchange() || + ->SupportsBlePeripheralInitiatedFeaturesExchange() || link_role == HCI_ROLE_CENTRAL) { btsnd_hcic_ble_read_remote_feat(p_acl->hci_handle); } else { @@ -495,7 +499,7 @@ void btm_acl_create_failed(const RawAddress& bda, tBT_TRANSPORT transport, void btm_acl_removed(uint16_t handle) { tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(handle); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } p_acl->in_use = false; @@ -527,11 +531,6 @@ void btm_acl_device_down(void) { BTM_db_reset(); } -void btm_acl_update_inquiry_status(uint8_t status) { - btm_cb.is_inquiry = status == BTM_INQUIRY_STARTED; - BTIF_dm_report_inquiry_status_change(status); -} - tBTM_STATUS BTM_GetRole(const RawAddress& remote_bd_addr, tHCI_ROLE* p_role) { if (p_role == nullptr) { return BTM_ILLEGAL_VALUE; @@ -541,7 +540,7 @@ tBTM_STATUS BTM_GetRole(const RawAddress& remote_bd_addr, tHCI_ROLE* p_role) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return BTM_UNKNOWN_ADDR; } *p_role = p_acl->link_role; @@ -566,46 +565,46 @@ tBTM_STATUS BTM_GetRole(const RawAddress& remote_bd_addr, tHCI_ROLE* p_role) { * ******************************************************************************/ tBTM_STATUS BTM_SwitchRoleToCentral(const RawAddress& remote_bd_addr) { - if (!controller_get_interface()->supports_central_peripheral_role_switch()) { - LOG_INFO("Local controller does not support role switching"); + if (!bluetooth::shim::GetController()->SupportsRoleSwitch()) { + log::info("Local controller does not support role switching"); return BTM_MODE_UNSUPPORTED; } tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return BTM_UNKNOWN_ADDR; } if (p_acl->link_role == HCI_ROLE_CENTRAL) { - LOG_INFO("Requested role is already in effect"); + log::info("Requested role is already in effect"); return BTM_SUCCESS; } if (interop_match_addr(INTEROP_DISABLE_ROLE_SWITCH, &remote_bd_addr)) { - LOG_INFO("Remote device is on list preventing role switch"); + log::info("Remote device is on list preventing role switch"); return BTM_DEV_RESTRICT_LISTED; } if (BTM_IsScoActiveByBdaddr(remote_bd_addr)) { - LOG_INFO("An active SCO to device prevents role switch at this time"); + log::info("An active SCO to device prevents role switch at this time"); return BTM_NO_RESOURCES; } if (!p_acl->is_switch_role_idle()) { - LOG_INFO("Role switch is already progress"); + log::info("Role switch is already progress"); return BTM_BUSY; } if (interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &remote_bd_addr)) { - LOG_DEBUG("Device restrict listed under INTEROP_DYNAMIC_ROLE_SWITCH"); + log::debug("Device restrict listed under INTEROP_DYNAMIC_ROLE_SWITCH"); return BTM_DEV_RESTRICT_LISTED; } tBTM_PM_MODE pwr_mode; if (!BTM_ReadPowerMode(p_acl->remote_addr, &pwr_mode)) { - LOG_WARN( + log::warn( "Unable to find device to read current power mode prior to role " "switch"); return BTM_UNKNOWN_ADDR; @@ -613,7 +612,7 @@ tBTM_STATUS BTM_SwitchRoleToCentral(const RawAddress& remote_bd_addr) { if (pwr_mode == BTM_PM_MD_PARK || pwr_mode == BTM_PM_MD_SNIFF) { if (!BTM_SetLinkPolicyActiveMode(p_acl->remote_addr)) { - LOG_WARN("Unable to set link policy active before attempting switch"); + log::warn("Unable to set link policy active before attempting switch"); return BTM_WRONG_MODE; } p_acl->set_switch_role_changing(); @@ -648,7 +647,7 @@ void btm_acl_encrypt_change(uint16_t handle, uint8_t status, uint8_t encr_enable) { tACL_CONN* p = internal_.acl_get_connection_from_handle(handle); if (p == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } @@ -656,11 +655,10 @@ void btm_acl_encrypt_change(uint16_t handle, uint8_t status, * encrypted connection, drop the connection */ if (bluetooth::os::ParameterProvider::IsCommonCriteriaMode()) { if (p->is_encrypted && !encr_enable) { - LOG(ERROR) - << __func__ - << " attempting to decrypt encrypted connection, disconnecting. " - "handle: " - << loghex(handle); + log::error( + "attempting to decrypt encrypted connection, disconnecting. " + "handle: {}", + loghex(handle)); acl_disconnect_from_handle(handle, HCI_ERR_HOST_REJECT_SECURITY, "stack::btu::btu_hcif::read_drop_encryption " @@ -703,27 +701,25 @@ void btm_acl_encrypt_change(uint16_t handle, uint8_t status, } static void check_link_policy(tLINK_POLICY* settings) { - const controller_t* controller = controller_get_interface(); - if ((*settings & HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH) && - (!controller->supports_role_switch())) { + (!bluetooth::shim::GetController()->SupportsRoleSwitch())) { *settings &= (~HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH); - LOG_INFO("Role switch not supported (settings: 0x%04x)", *settings); + log::info("Role switch not supported (settings: 0x{:04x})", *settings); } if ((*settings & HCI_ENABLE_HOLD_MODE) && - (!controller->supports_hold_mode())) { + (!bluetooth::shim::GetController()->SupportsHoldMode())) { *settings &= (~HCI_ENABLE_HOLD_MODE); - LOG_INFO("hold not supported (settings: 0x%04x)", *settings); + log::info("hold not supported (settings: 0x{:04x})", *settings); } if ((*settings & HCI_ENABLE_SNIFF_MODE) && - (!controller->supports_sniff_mode())) { + (!bluetooth::shim::GetController()->SupportsSniffMode())) { *settings &= (~HCI_ENABLE_SNIFF_MODE); - LOG_INFO("sniff not supported (settings: 0x%04x)", *settings); + log::info("sniff not supported (settings: 0x{:04x})", *settings); } if ((*settings & HCI_ENABLE_PARK_MODE) && - (!controller->supports_park_mode())) { + (!bluetooth::shim::GetController()->SupportsParkMode())) { *settings &= (~HCI_ENABLE_PARK_MODE); - LOG_INFO("park not supported (settings: 0x%04x)", *settings); + log::info("park not supported (settings: 0x{:04x})", *settings); } } @@ -742,7 +738,7 @@ static void btm_toggle_policy_on_for(const RawAddress& peer_addr, uint16_t flag) { auto conn = internal_.btm_bda_to_acl(peer_addr, BT_TRANSPORT_BR_EDR); if (!conn) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } btm_set_link_policy(conn, conn->link_policy | flag); @@ -752,7 +748,7 @@ static void btm_toggle_policy_off_for(const RawAddress& peer_addr, uint16_t flag) { auto conn = internal_.btm_bda_to_acl(peer_addr, BT_TRANSPORT_BR_EDR); if (!conn) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } btm_set_link_policy(conn, conn->link_policy & ~flag); @@ -761,7 +757,7 @@ static void btm_toggle_policy_off_for(const RawAddress& peer_addr, bool BTM_is_sniff_allowed_for(const RawAddress& peer_addr) { auto conn = internal_.btm_bda_to_acl(peer_addr, BT_TRANSPORT_BR_EDR); if (!conn) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } return conn->link_policy & HCI_ENABLE_SNIFF_MODE; @@ -826,7 +822,7 @@ static void maybe_chain_more_commands_after_read_remote_version_complete( uint8_t status, uint16_t handle) { tACL_CONN* p_acl_cb = internal_.acl_get_connection_from_handle(handle); if (p_acl_cb == nullptr) { - LOG_WARN("Received remote version complete for unknown device"); + log::warn("Received remote version complete for unknown device"); return; } @@ -845,9 +841,9 @@ static void maybe_chain_more_commands_after_read_remote_version_complete( */ break; default: - LOG_ERROR("Unable to determine transport:%s device:%s", - bt_transport_text(p_acl_cb->transport).c_str(), - ADDRESS_TO_LOGGABLE_CSTR(p_acl_cb->remote_addr)); + log::error("Unable to determine transport:{} device:{}", + bt_transport_text(p_acl_cb->transport).c_str(), + ADDRESS_TO_LOGGABLE_CSTR(p_acl_cb->remote_addr)); } // save remote versions to iot conf file @@ -860,7 +856,7 @@ void btm_process_remote_version_complete(uint8_t status, uint16_t handle, uint16_t lmp_subversion) { tACL_CONN* p_acl_cb = internal_.acl_get_connection_from_handle(handle); if (p_acl_cb == nullptr) { - LOG_WARN("Received remote version complete for unknown acl"); + log::warn("Received remote version complete for unknown acl"); return; } p_acl_cb->remote_version_received = true; @@ -903,9 +899,7 @@ void btm_process_remote_ext_features(tACL_CONN* p_acl_cb, uint8_t max_page_number) { CHECK(p_acl_cb != nullptr); if (!p_acl_cb->peer_lmp_feature_valid[max_page_number]) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } bool ssp_supported = @@ -953,7 +947,7 @@ void btm_read_remote_ext_features_complete_raw(uint8_t* p, uint8_t evt_len) { uint16_t handle; if (evt_len < HCI_EXT_FEATURES_SUCCESS_EVT_LEN) { - LOG_WARN("Remote extended feature length too short. length=%d", evt_len); + log::warn("Remote extended feature length too short. length={}", evt_len); return; } @@ -963,17 +957,17 @@ void btm_read_remote_ext_features_complete_raw(uint8_t* p, uint8_t evt_len) { STREAM_TO_UINT8(max_page, p); if (max_page > HCI_EXT_FEATURES_PAGE_MAX) { - LOG_WARN("Too many max pages read page=%d unknown", max_page); + log::warn("Too many max pages read page={} unknown", max_page); return; } if (page_num > HCI_EXT_FEATURES_PAGE_MAX) { - LOG_WARN("Too many received pages num_page=%d invalid", page_num); + log::warn("Too many received pages num_page={} invalid", page_num); return; } if (page_num > max_page) { - LOG_WARN("num_page=%d, max_page=%d invalid", page_num, max_page); + log::warn("num_page={}, max_page={} invalid", page_num, max_page); } btm_read_remote_ext_features_complete(handle, page_num, max_page, p); @@ -985,7 +979,7 @@ void btm_read_remote_ext_features_complete(uint16_t handle, uint8_t page_num, /* Validate parameters */ auto* p_acl_cb = internal_.acl_get_connection_from_handle(handle); if (p_acl_cb == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } @@ -1005,13 +999,13 @@ void btm_read_remote_ext_features_complete(uint16_t handle, uint8_t page_num, * we have space to keep this page data - read this page */ if ((page_num < max_page) && (page_num < HCI_EXT_FEATURES_PAGE_MAX)) { page_num++; - LOG_DEBUG("BTM reads next remote extended features page (%d)", page_num); + log::debug("BTM reads next remote extended features page ({})", page_num); btm_read_remote_ext_features(handle, page_num); return; } /* Reading of remote feature pages is complete */ - LOG_DEBUG("BTM reached last remote extended features page (%d)", page_num); + log::debug("BTM reached last remote extended features page ({})", page_num); /* Process the pages */ btm_process_remote_ext_features(p_acl_cb, max_page); @@ -1031,11 +1025,11 @@ void btm_read_remote_ext_features_complete(uint16_t handle, uint8_t page_num, * ******************************************************************************/ void btm_read_remote_ext_features_failed(uint8_t status, uint16_t handle) { - LOG_WARN("status 0x%02x for handle %d", status, handle); + log::warn("status 0x{:02x} for handle {}", status, handle); tACL_CONN* p_acl_cb = internal_.acl_get_connection_from_handle(handle); if (p_acl_cb == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } @@ -1068,9 +1062,10 @@ void StackAclBtmAcl::btm_establish_continue(tACL_CONN* p_acl) { btm_cb.acl_cb_.DefaultPacketTypes(); if (!internal_.change_connection_packet_types(*p_acl, default_packet_type_mask)) { - LOG_ERROR("Unable to change connection packet type types:%04x address:%s", - default_packet_type_mask, - ADDRESS_TO_LOGGABLE_CSTR(p_acl->RemoteAddress())); + log::error( + "Unable to change connection packet type types:{:04x} address:{}", + default_packet_type_mask, + ADDRESS_TO_LOGGABLE_CSTR(p_acl->RemoteAddress())); } btm_set_link_policy(p_acl, btm_cb.acl_cb_.DefaultLinkPolicy()); } @@ -1081,7 +1076,7 @@ void btm_establish_continue_from_address(const RawAddress& bda, tBT_TRANSPORT transport) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bda, transport); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } internal_.btm_establish_continue(p_acl); @@ -1102,7 +1097,7 @@ tBTM_STATUS BTM_GetLinkSuperTout(const RawAddress& remote_bda, const tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return BTM_UNKNOWN_ADDR; } *p_timeout = p_acl->link_super_tout; @@ -1122,7 +1117,7 @@ tBTM_STATUS BTM_SetLinkSuperTout(const RawAddress& remote_bda, uint16_t timeout) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return BTM_UNKNOWN_ADDR; } @@ -1130,23 +1125,25 @@ tBTM_STATUS BTM_SetLinkSuperTout(const RawAddress& remote_bda, if (p_acl->link_role == HCI_ROLE_CENTRAL) { if (!bluetooth::shim:: controller_is_write_link_supervision_timeout_supported()) { - LOG_WARN( - "UNSUPPORTED by controller write link supervision timeout:%.2fms " - "bd_addr:%s", - supervision_timeout_to_seconds(timeout), ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn( + "UNSUPPORTED by controller write link supervision timeout:{:.2f}ms " + "bd_addr:{}", + supervision_timeout_to_seconds(timeout), + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return BTM_MODE_UNSUPPORTED; } p_acl->link_super_tout = timeout; btsnd_hcic_write_link_super_tout(p_acl->hci_handle, timeout); - LOG_DEBUG("Set supervision timeout:%.2fms bd_addr:%s", - supervision_timeout_to_seconds(timeout), - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::debug("Set supervision timeout:{:.2f}ms bd_addr:{}", + supervision_timeout_to_seconds(timeout), + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return BTM_CMD_STARTED; } else { - LOG_WARN( - "Role is peripheral so unable to set supervision timeout:%.2fms " - "bd_addr:%s", - supervision_timeout_to_seconds(timeout), ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn( + "Role is peripheral so unable to set supervision timeout:{:.2f}ms " + "bd_addr:{}", + supervision_timeout_to_seconds(timeout), + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return BTM_SUCCESS; } } @@ -1160,7 +1157,7 @@ bool BTM_IsAclConnectionUpAndHandleValid(const RawAddress& remote_bda, tBT_TRANSPORT transport) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, transport); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } return p_acl->hci_handle != HCI_INVALID_HANDLE; @@ -1245,17 +1242,15 @@ uint16_t BTM_GetHCIConnHandle(const RawAddress& remote_bda, ******************************************************************************/ bool BTM_IsPhy2mSupported(const RawAddress& remote_bda, tBT_TRANSPORT transport) { tACL_CONN* p; - LOG_VERBOSE("BTM_IsPhy2mSupported"); + log::verbose("BTM_IsPhy2mSupported"); p = internal_.btm_bda_to_acl(remote_bda, transport); if (p == (tACL_CONN*)NULL) { - LOG_VERBOSE("BTM_IsPhy2mSupported: no connection"); + log::verbose("BTM_IsPhy2mSupported: no connection"); return false; } if (!p->peer_le_features_valid) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } return HCI_LE_2M_PHY_SUPPORTED(p->peer_le_features); } @@ -1272,7 +1267,7 @@ void BTM_RequestPeerSCA(const RawAddress& remote_bda, tBT_TRANSPORT transport) { tACL_CONN* p; p = internal_.btm_bda_to_acl(remote_bda, transport); if (p == (tACL_CONN*)NULL) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } @@ -1295,7 +1290,7 @@ uint8_t BTM_GetPeerSCA(const RawAddress& remote_bda, tBT_TRANSPORT transport) { if (p != (tACL_CONN*)NULL) { return (p->sca); } - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); /* If here, no BD Addr found */ return (0xFF); @@ -1320,7 +1315,7 @@ void btm_rejectlist_role_change_device(const RawAddress& bd_addr, tACL_CONN* p = internal_.btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR); if (!p) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } if (hci_status == HCI_SUCCESS) { @@ -1331,8 +1326,8 @@ void btm_rejectlist_role_change_device(const RawAddress& bd_addr, /* check for carkits */ const uint32_t cod_audio_device = (BTM_COD_SERVICE_AUDIO | BTM_COD_MAJOR_AUDIO) << 8; - const uint8_t* dev_class = btm_get_dev_class(bd_addr); - if (dev_class == nullptr) return; + DEV_CLASS dev_class = btm_get_dev_class(bd_addr); + if (dev_class == kDevClassEmpty) return; const uint32_t cod = ((dev_class[0] << 16) | (dev_class[1] << 8) | dev_class[2]) & 0xffffff; if ((hci_status != HCI_SUCCESS) && @@ -1341,9 +1336,9 @@ void btm_rejectlist_role_change_device(const RawAddress& bd_addr, (!interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr))) { p->switch_role_failed_attempts++; if (p->switch_role_failed_attempts == BTM_MAX_SW_ROLE_FAILED_ATTEMPTS) { - LOG_WARN( - "Device %s rejectlisted for role switching - " - "multiple role switch failed attempts: %u", + log::warn( + "Device {} rejectlisted for role switching - multiple role switch " + "failed attempts: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), p->switch_role_failed_attempts); interop_database_add(INTEROP_DYNAMIC_ROLE_SWITCH, &bd_addr, 3); } @@ -1394,14 +1389,15 @@ void StackAclBtmAcl::btm_acl_role_changed(tHCI_STATUS hci_status, // If we get a role change before connection complete, we cache the new // role here and then propagate it when ACL Link is created. acl_cache_role(bd_addr, new_role, /*overwrite_cache=*/true); - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } tBTM_ROLE_SWITCH_CMPL* p_switch_role = &btm_cb.acl_cb_.switch_role_ref_data; - LOG_DEBUG("Role change event received peer:%s hci_status:%s new_role:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), hci_error_code_text(hci_status).c_str(), - RoleText(new_role).c_str()); + log::debug("Role change event received peer:{} hci_status:{} new_role:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + hci_error_code_text(hci_status).c_str(), + RoleText(new_role).c_str()); p_switch_role->hci_status = hci_status; if (hci_status == HCI_SUCCESS) { @@ -1495,22 +1491,23 @@ bool StackAclBtmAcl::change_connection_packet_types( packet_type_mask &= peer_packet_types.acl.supported; packet_type_mask |= peer_packet_types.acl.unsupported; } else { - LOG_INFO( + log::info( "Unable to include remote supported packet types as read feature " "incomplete"); - LOG_INFO("TIP: Maybe wait until read feature complete beforehand"); + log::info("TIP: Maybe wait until read feature complete beforehand"); } if (packet_type_mask == 0) { - LOG_WARN("Unable to send controller illegal change packet mask:0x%04x", - packet_type_mask); + log::warn("Unable to send controller illegal change packet mask:0x{:04x}", + packet_type_mask); return false; } link.pkt_types_mask = packet_type_mask; GetInterface().ChangeConnectionPacketType(link.Handle(), link.pkt_types_mask); - LOG_DEBUG("Started change connection packet type:0x%04x address:%s", - link.pkt_types_mask, ADDRESS_TO_LOGGABLE_CSTR(link.RemoteAddress())); + log::debug("Started change connection packet type:0x{:04x} address:{}", + link.pkt_types_mask, + ADDRESS_TO_LOGGABLE_CSTR(link.RemoteAddress())); return true; } @@ -1518,13 +1515,14 @@ void btm_set_packet_types_from_address(const RawAddress& bd_addr, uint16_t pkt_types) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } if (!internal_.change_connection_packet_types(*p_acl, pkt_types)) { - LOG_ERROR("Unable to change connection packet type types:%04x address:%s", - pkt_types, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error( + "Unable to change connection packet type types:{:04x} address:{}", + pkt_types, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } @@ -1609,13 +1607,13 @@ bool BTM_ReadRemoteVersion(const RawAddress& addr, uint8_t* lmp_version, if (p_acl == nullptr) { p_acl = internal_.btm_bda_to_acl(addr, BT_TRANSPORT_LE); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } } if (!p_acl->remote_version_info.valid) { - LOG_WARN("Remote version information is invalid"); + log::warn("Remote version information is invalid"); return false; } @@ -1639,7 +1637,7 @@ bool BTM_ReadRemoteVersion(const RawAddress& addr, uint8_t* lmp_version, uint8_t* BTM_ReadRemoteFeatures(const RawAddress& addr) { tACL_CONN* p = internal_.btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR); if (p == NULL) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return (NULL); } @@ -1684,7 +1682,7 @@ tBTM_STATUS BTM_ReadRSSI(const RawAddress& remote_bda, tBTM_CMPL_CB* p_cb) { btsnd_hcic_read_rssi(p->hci_handle); return (BTM_CMD_STARTED); } - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); /* If here, no BD Addr found */ return (BTM_UNKNOWN_ADDR); @@ -1724,7 +1722,7 @@ tBTM_STATUS BTM_ReadFailedContactCounter(const RawAddress& remote_bda, btsnd_hcic_read_failed_contact_counter(p->hci_handle); return (BTM_CMD_STARTED); } - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); /* If here, no BD Addr found */ return (BTM_UNKNOWN_ADDR); @@ -1748,7 +1746,7 @@ tBTM_STATUS BTM_ReadTxPower(const RawAddress& remote_bda, #define BTM_READ_RSSI_TYPE_CUR 0x00 #define BTM_READ_RSSI_TYPE_MAX 0X01 - VLOG(2) << __func__ << ": RemBdAddr: " << ADDRESS_TO_LOGGABLE_STR(remote_bda); + log::verbose("RemBdAddr: {}", ADDRESS_TO_LOGGABLE_STR(remote_bda)); /* If someone already waiting on the version, do not allow another */ if (btm_cb.devcb.p_tx_power_cmpl_cb) return (BTM_BUSY); @@ -1770,7 +1768,7 @@ tBTM_STATUS BTM_ReadTxPower(const RawAddress& remote_bda, return (BTM_CMD_STARTED); } - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); /* If here, no BD Addr found */ return (BTM_UNKNOWN_ADDR); @@ -1841,10 +1839,10 @@ void btm_read_tx_power_complete(uint8_t* p, uint16_t evt_len, bool is_ble) { STREAM_TO_UINT8(result.tx_power, p); result.rem_bda = btm_cb.devcb.read_tx_pwr_addr; } - LOG_DEBUG("Transmit power complete: tx_power:%d hci status:%s", - result.tx_power, - hci_error_code_text(static_cast(result.hci_status)) - .c_str()); + log::debug( + "Transmit power complete: tx_power:{} hci status:{}", result.tx_power, + hci_error_code_text(static_cast(result.hci_status)) + .c_str()); } else { result.status = BTM_ERR_PROCESSING; } @@ -1855,7 +1853,7 @@ void btm_read_tx_power_complete(uint8_t* p, uint16_t evt_len, bool is_ble) { return; err_out: - LOG_ERROR("Bogus event packet, too short"); + log::error("Bogus event packet, too short"); } /******************************************************************************* @@ -1910,9 +1908,7 @@ void btm_read_rssi_complete(uint8_t* p, uint16_t evt_len) { STREAM_TO_UINT16(handle, p); STREAM_TO_UINT8(result.rssi, p); - LOG_DEBUG("Read rrsi complete rssi:%hhd hci status:%s", result.rssi, - hci_error_code_text(static_cast(result.hci_status)) - .c_str()); + log::debug("Read rrsi complete rssi:%hhd hci status:{}", result.rssi); tACL_CONN* p_acl_cb = internal_.acl_get_connection_from_handle(handle); if (p_acl_cb != nullptr) { @@ -1926,7 +1922,7 @@ void btm_read_rssi_complete(uint8_t* p, uint16_t evt_len) { return; err_out: - LOG_ERROR("Bogus event packet, too short"); + log::error("Bogus event packet, too short"); } /******************************************************************************* @@ -1975,8 +1971,8 @@ void btm_read_failed_contact_counter_complete(uint8_t* p) { STREAM_TO_UINT16(handle, p); STREAM_TO_UINT16(result.failed_contact_counter, p); - LOG_DEBUG( - "Failed contact counter complete: counter %u, hci status:%s", + log::debug( + "Failed contact counter complete: counter {}, hci status:{}", result.failed_contact_counter, hci_status_code_text(to_hci_status_code(result.hci_status)).c_str()); @@ -2021,8 +2017,8 @@ void btm_read_automatic_flush_timeout_complete(uint8_t* p) { STREAM_TO_UINT16(handle, p); STREAM_TO_UINT16(result.automatic_flush_timeout, p); - LOG_DEBUG( - "Read automatic flush timeout complete timeout:%hu hci_status:%s", + log::debug( + "Read automatic flush timeout complete timeout:{} hci_status:{}", result.automatic_flush_timeout, hci_error_code_text(static_cast(result.hci_status)) .c_str()); @@ -2087,10 +2083,11 @@ void btm_read_link_quality_complete(uint8_t* p, uint16_t evt_len) { STREAM_TO_UINT16(handle, p); STREAM_TO_UINT8(result.link_quality, p); - LOG_DEBUG("BTM Link Quality Complete: Link Quality %d, hci status:%s", - result.link_quality, - hci_error_code_text(static_cast(result.hci_status)) - .c_str()); + log::debug( + "BTM Link Quality Complete: Link Quality {}, hci status:{}", + result.link_quality, + hci_error_code_text(static_cast(result.hci_status)) + .c_str()); tACL_CONN* p_acl_cb = internal_.acl_get_connection_from_handle(handle); if (p_acl_cb != nullptr) { @@ -2106,7 +2103,7 @@ void btm_read_link_quality_complete(uint8_t* p, uint16_t evt_len) { return; err_out: - LOG_ERROR("Bogus Link Quality event packet, size: %d", evt_len); + log::error("Bogus Link Quality event packet, size: {}", evt_len); } /******************************************************************************* @@ -2122,21 +2119,23 @@ err_out: tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr, tBT_TRANSPORT transport) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, transport); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return BTM_UNKNOWN_ADDR; } if (p_acl->Handle() == HCI_INVALID_HANDLE) { - LOG_WARN("Cannot remove unknown acl bd_addr:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport).c_str()); + log::warn("Cannot remove unknown acl bd_addr:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport).c_str()); return BTM_UNKNOWN_ADDR; } if (p_acl->rs_disc_pending == BTM_SEC_RS_PENDING) { - LOG_DEBUG( - "Delay disconnect until role switch is complete bd_addr:%s " - "transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport).c_str()); + log::debug( + "Delay disconnect until role switch is complete bd_addr:{} " + "transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport).c_str()); p_acl->rs_disc_pending = BTM_SEC_DISC_PENDING; return BTM_SUCCESS; } @@ -2149,7 +2148,7 @@ tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr, tBT_TRANSPORT transport) { void btm_cont_rswitch_from_handle(uint16_t hci_handle) { tACL_CONN* p = internal_.acl_get_connection_from_handle(hci_handle); if (p == nullptr) { - LOG_WARN("Role switch received but with no active ACL"); + log::warn("Role switch received but with no active ACL"); return; } @@ -2197,7 +2196,7 @@ bool acl_refresh_remote_address(const RawAddress& identity_address, const RawAddress& rpa) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bda, BT_TRANSPORT_LE); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } @@ -2215,7 +2214,7 @@ bool acl_refresh_remote_address(const RawAddress& identity_address, p_acl->active_remote_addr = rpa; } - LOG_DEBUG("active_remote_addr_type: %d ", p_acl->active_remote_addr_type); + log::debug("active_remote_addr_type: {} ", p_acl->active_remote_addr_type); return true; } @@ -2223,13 +2222,11 @@ bool acl_peer_supports_ble_connection_parameters_request( const RawAddress& remote_bda) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } if (!p_acl->peer_le_features_valid) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } return HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl->peer_le_features); } @@ -2237,13 +2234,11 @@ bool acl_peer_supports_ble_connection_parameters_request( bool acl_peer_supports_sniff_subrating(const RawAddress& remote_bda) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } if (!p_acl->peer_lmp_feature_valid[0]) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } return HCI_SNIFF_SUB_RATE_SUPPORTED(p_acl->peer_lmp_feature_pages[0]); } @@ -2251,13 +2246,11 @@ bool acl_peer_supports_sniff_subrating(const RawAddress& remote_bda) { bool acl_peer_supports_ble_connection_subrating(const RawAddress& remote_bda) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } if (!p_acl->peer_le_features_valid) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } return HCI_LE_CONN_SUBRATING_SUPPORT(p_acl->peer_le_features); } @@ -2266,13 +2259,11 @@ bool acl_peer_supports_ble_connection_subrating_host( const RawAddress& remote_bda) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } if (!p_acl->peer_le_features_valid) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } return HCI_LE_CONN_SUBRATING_HOST_SUPPORT(p_acl->peer_le_features); } @@ -2292,8 +2283,8 @@ void BTM_ReadConnectionAddr(const RawAddress& remote_bda, tBLE_ADDR_TYPE* p_addr_type, bool ota_address) { tBTM_SEC_DEV_REC* p_sec_rec = btm_find_dev(remote_bda); if (p_sec_rec == nullptr) { - LOG_WARN("No matching known device %s in record", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn("No matching known device {} in record", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return; } @@ -2329,7 +2320,7 @@ bool acl_is_switch_role_idle(const RawAddress& bd_addr, tBT_TRANSPORT transport) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, transport); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return false; } return p_acl->is_switch_role_idle(); @@ -2358,8 +2349,8 @@ bool BTM_ReadRemoteConnectionAddr(const RawAddress& pseudo_addr, bool ota_address) { tBTM_SEC_DEV_REC* p_sec_rec = btm_find_dev(pseudo_addr); if (p_sec_rec == nullptr) { - LOG_WARN("No matching known device %s in record", - ADDRESS_TO_LOGGABLE_CSTR(pseudo_addr)); + log::warn("No matching known device {} in record", + ADDRESS_TO_LOGGABLE_CSTR(pseudo_addr)); return false; } @@ -2382,9 +2373,7 @@ bool acl_peer_supports_ble_packet_extension(uint16_t hci_handle) { return false; } if (!p_acl->peer_le_features_valid) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } return HCI_LE_DATA_LEN_EXT_SUPPORTED(p_acl->peer_le_features); } @@ -2395,9 +2384,7 @@ bool acl_peer_supports_ble_2m_phy(uint16_t hci_handle) { return false; } if (!p_acl->peer_le_features_valid) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); } return HCI_LE_2M_PHY_SUPPORTED(p_acl->peer_le_features); } @@ -2408,9 +2395,7 @@ bool acl_peer_supports_ble_coded_phy(uint16_t hci_handle) { return false; } if (!p_acl->peer_le_features_valid) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); return false; } return HCI_LE_CODED_PHY_SUPPORTED(p_acl->peer_le_features); @@ -2441,7 +2426,7 @@ bool acl_set_peer_le_features_from_handle(uint16_t hci_handle, } STREAM_TO_ARRAY(p_acl->peer_le_features, p, BD_FEATURES_LEN); p_acl->peer_le_features_valid = true; - LOG_DEBUG("Completed le feature read request"); + log::debug("Completed le feature read request"); /* save LE remote supported features to iot conf file */ std::string key = IOT_CONF_KEY_RT_SUPP_FEATURES "_" + std::to_string(0); @@ -2468,7 +2453,7 @@ void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle, tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(handle); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } @@ -2512,17 +2497,11 @@ void btm_acl_connected(const RawAddress& bda, uint16_t handle, } } -void btm_acl_iso_disconnected(uint16_t handle, tHCI_REASON reason) { - LOG_INFO("ISO disconnection from GD, handle: 0x%02x, reason: 0x%02x", handle, - reason); - bluetooth::hci::IsoManager::GetInstance()->HandleDisconnect(handle, reason); -} - void btm_acl_disconnected(tHCI_STATUS status, uint16_t handle, tHCI_REASON reason) { if (status != HCI_SUCCESS) { - LOG_WARN("Received disconnect with error:%s", - hci_error_code_text(status).c_str()); + log::warn("Received disconnect with error:{}", + hci_error_code_text(status).c_str()); } power_telemetry::GetInstance().LogLinkDetails(handle, RawAddress::kEmpty, false, true); @@ -2532,11 +2511,8 @@ void btm_acl_disconnected(tHCI_STATUS status, uint16_t handle, acl_set_disconnect_reason(static_cast(reason)); } - /* If L2CAP or SCO doesn't know about it, send it to ISO */ - if (!l2c_link_hci_disc_comp(handle, reason) && - !btm_sco_removed(handle, reason)) { - bluetooth::hci::IsoManager::GetInstance()->HandleDisconnect(handle, reason); - } + /* Let L2CAP know about it */ + l2c_link_hci_disc_comp(handle, reason); /* Notify security manager */ btm_sec_disconnected(handle, reason, @@ -2550,14 +2526,14 @@ void acl_create_classic_connection(const RawAddress& bd_addr, } void btm_connection_request(const RawAddress& bda, - const bluetooth::types::ClassOfDevice& cod) { + const bluetooth::hci::ClassOfDevice& cod) { // Copy Cod information DEV_CLASS dc; /* Some device may request a connection before we are done with the HCI_Reset * sequence */ if (!controller_get_interface()->get_is_ready()) { - LOG_VERBOSE("Security Manager: connect request when device not ready"); + log::verbose("Security Manager: connect request when device not ready"); btsnd_hcic_reject_conn(bda, HCI_ERR_HOST_REJECT_DEVICE); return; } @@ -2595,9 +2571,9 @@ bool is_disconnect_reason_valid(const tHCI_REASON& reason) { void acl_disconnect_after_role_switch(uint16_t conn_handle, tHCI_STATUS reason, std::string comment) { if (!is_disconnect_reason_valid(reason)) { - LOG_WARN( - "Controller will not accept invalid reason parameter:%s" - " instead sending:%s", + log::warn( + "Controller will not accept invalid reason parameter:{} instead " + "sending:{}", hci_error_code_text(reason).c_str(), hci_error_code_text(HCI_ERR_PEER_USER).c_str()); reason = HCI_ERR_PEER_USER; @@ -2605,7 +2581,7 @@ void acl_disconnect_after_role_switch(uint16_t conn_handle, tHCI_STATUS reason, tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(conn_handle); if (p_acl == nullptr) { - LOG_ERROR("Sending disconnect for unknown acl:%hu PLEASE FIX", conn_handle); + log::error("Sending disconnect for unknown acl:{} PLEASE FIX", conn_handle); GetInterface().Disconnect(conn_handle, reason); return; } @@ -2613,14 +2589,13 @@ void acl_disconnect_after_role_switch(uint16_t conn_handle, tHCI_STATUS reason, /* If a role switch is in progress, delay the HCI Disconnect to avoid * controller problem */ if (p_acl->rs_disc_pending == BTM_SEC_RS_PENDING) { - LOG_DEBUG( + log::debug( "Role switch in progress - Set DISC Pending flag in " - "btm_sec_send_hci_disconnect " - "to delay disconnect"); + "btm_sec_send_hci_disconnect to delay disconnect"); p_acl->rs_disc_pending = BTM_SEC_DISC_PENDING; } else { - LOG_DEBUG("Sending acl disconnect reason:%s [%hu]", - hci_error_code_text(reason).c_str(), reason); + log::debug("Sending acl disconnect reason:{} [{}]", + hci_error_code_text(reason).c_str(), reason); disconnect_acl(*p_acl, reason, comment); } } @@ -2628,8 +2603,8 @@ void acl_disconnect_after_role_switch(uint16_t conn_handle, tHCI_STATUS reason, void acl_send_data_packet_br_edr(const RawAddress& bd_addr, BT_HDR* p_buf) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Acl br_edr data write for unknown device:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Acl br_edr data write for unknown device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); osi_free(p_buf); return; } @@ -2640,8 +2615,8 @@ void acl_send_data_packet_br_edr(const RawAddress& bd_addr, BT_HDR* p_buf) { void acl_send_data_packet_ble(const RawAddress& bd_addr, BT_HDR* p_buf) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE); if (p_acl == nullptr) { - LOG_WARN("Acl le data write for unknown device:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Acl le data write for unknown device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); osi_free(p_buf); return; } @@ -2653,12 +2628,12 @@ void acl_write_automatic_flush_timeout(const RawAddress& bd_addr, uint16_t flush_timeout_in_ticks) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } if (p_acl->flush_timeout_in_ticks == flush_timeout_in_ticks) { - LOG_INFO( - "Ignoring since cached value is same as requested flush_timeout:%hd", + log::info( + "Ignoring since cached value is same as requested flush_timeout:{}", flush_timeout_in_ticks); return; } @@ -2676,14 +2651,14 @@ bool acl_create_le_connection_with_id(uint8_t id, const RawAddress& bd_addr, find_in_device_record(bd_addr, &address_with_type); - LOG_DEBUG("Creating le direct connection to:%s type:%s (initial type: %s)", - ADDRESS_TO_LOGGABLE_CSTR(address_with_type), - AddressTypeText(address_with_type.type).c_str(), - AddressTypeText(addr_type).c_str()); + log::debug("Creating le direct connection to:{} type:{} (initial type: {})", + ADDRESS_TO_LOGGABLE_CSTR(address_with_type), + AddressTypeText(address_with_type.type).c_str(), + AddressTypeText(addr_type).c_str()); if (address_with_type.type == BLE_ADDR_ANONYMOUS) { - LOG_WARN( - "Creating le direct connection to:%s, address type 'anonymous' is " + log::warn( + "Creating le direct connection to:{}, address type 'anonymous' is " "invalid", ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); return false; @@ -2722,8 +2697,8 @@ void acl_rcv_acl_data(BT_HDR* p_msg) { STREAM_TO_UINT16(acl_header.hci_len, p); if (acl_header.hci_len < L2CAP_PKT_OVERHEAD || acl_header.hci_len != p_msg->len - sizeof(acl_header)) { - LOG_WARN("Received mismatched hci header length:%u data_len:%zu", - acl_header.hci_len, p_msg->len - sizeof(acl_header)); + log::warn("Received mismatched hci header length:{} data_len:{}", + acl_header.hci_len, p_msg->len - sizeof(acl_header)); osi_free(p_msg); return; } @@ -2739,7 +2714,7 @@ void acl_packets_completed(uint16_t handle, uint16_t credits) { void acl_process_supported_features(uint16_t handle, uint64_t features) { tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(handle); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } const uint8_t current_page_number = 0; @@ -2748,19 +2723,19 @@ void acl_process_supported_features(uint16_t handle, uint64_t features) { (uint8_t*)&features, sizeof(uint64_t)); p_acl->peer_lmp_feature_valid[current_page_number] = true; - LOG_DEBUG( - "Copied supported feature pages handle:%hu current_page_number:%hhu " - "features:%s", + log::debug( + "Copied supported feature pages handle:{} current_page_number:{} " + "features:{}", handle, current_page_number, bd_features_text(p_acl->peer_lmp_feature_pages[current_page_number]) .c_str()); if ((HCI_LMP_EXTENDED_SUPPORTED(p_acl->peer_lmp_feature_pages[0])) && - (controller_get_interface() - ->supports_reading_remote_extended_features())) { - LOG_DEBUG("Waiting for remote extended feature response to arrive"); + (bluetooth::shim::GetController()->IsSupported( + bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES))) { + log::debug("Waiting for remote extended feature response to arrive"); } else { - LOG_DEBUG("No more remote features outstanding so notify upper layer"); + log::debug("No more remote features outstanding so notify upper layer"); NotifyAclFeaturesReadComplete(*p_acl, current_page_number); } } @@ -2768,21 +2743,21 @@ void acl_process_supported_features(uint16_t handle, uint64_t features) { void acl_process_extended_features(uint16_t handle, uint8_t current_page_number, uint8_t max_page_number, uint64_t features) { if (current_page_number > HCI_EXT_FEATURES_PAGE_MAX) { - LOG_WARN("Unable to process current_page_number:%hhu", current_page_number); + log::warn("Unable to process current_page_number:{}", current_page_number); return; } tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(handle); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return; } memcpy(p_acl->peer_lmp_feature_pages[current_page_number], (uint8_t*)&features, sizeof(uint64_t)); p_acl->peer_lmp_feature_valid[current_page_number] = true; - LOG_DEBUG( - "Copied extended feature pages handle:%hu current_page_number:%hhu " - "max_page_number:%hhu features:%s", + log::debug( + "Copied extended feature pages handle:{} current_page_number:{} " + "max_page_number:{} features:{}", handle, current_page_number, max_page_number, bd_features_text(p_acl->peer_lmp_feature_pages[current_page_number]) .c_str()); @@ -2793,28 +2768,17 @@ void acl_process_extended_features(uint16_t handle, uint8_t current_page_number, } void ACL_RegisterClient(struct acl_client_callback_s* callbacks) { - LOG_DEBUG("UNIMPLEMENTED"); + log::debug("UNIMPLEMENTED"); } void ACL_UnregisterClient(struct acl_client_callback_s* callbacks) { - LOG_DEBUG("UNIMPLEMENTED"); -} - -bool ACL_SupportTransparentSynchronousData(const RawAddress& bd_addr) { - const tACL_CONN* p_acl = - internal_.btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR); - if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); - return false; - } - - return HCI_LMP_TRANSPNT_SUPPORTED(p_acl->peer_lmp_feature_pages[0]); + log::debug("UNIMPLEMENTED"); } tACL_CONN* btm_acl_for_bda(const RawAddress& bd_addr, tBT_TRANSPORT transport) { tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, transport); if (p_acl == nullptr) { - LOG_WARN("Unable to find active acl"); + log::warn("Unable to find active acl"); return nullptr; } return p_acl; diff --git a/system/stack/acl/btm_ble_connection_establishment.cc b/system/stack/acl/btm_ble_connection_establishment.cc deleted file mode 100644 index b339e92c573f05abd89373e5fdbc768b36f7e84b..0000000000000000000000000000000000000000 --- a/system/stack/acl/btm_ble_connection_establishment.cc +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************** - * - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#include -#include -#include - -#include "stack/btm/btm_ble_int.h" -#include "stack/btm/btm_int_types.h" -#include "stack/include/ble_hci_link_interface.h" - -extern tBTM_CB btm_cb; - -/** LE connection complete. */ -void btm_ble_create_ll_conn_complete(tHCI_STATUS status) { - if (status == HCI_SUCCESS) return; - - LOG(WARNING) << "LE Create Connection attempt failed, status=" - << hci_error_code_text(status); - - if (status == HCI_ERR_COMMAND_DISALLOWED) { - btm_cb.ble_ctr_cb.set_connection_state_connecting(); - btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT); - LOG(ERROR) << "LE Create Connection - command disallowed"; - } else { - btm_cb.ble_ctr_cb.set_connection_state_idle(); - btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT); - btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status); - } -} diff --git a/system/stack/acl/btm_pm.cc b/system/stack/acl/btm_pm.cc index d80d73cbb33131512a81b26a9e68f5b2f2a544ab..afaf2205ca6c02b668318c709a922216ed122802 100644 --- a/system/stack/acl/btm_pm.cc +++ b/system/stack/acl/btm_pm.cc @@ -28,17 +28,20 @@ * *****************************************************************************/ +#include "main/shim/entry.h" #define LOG_TAG "bt_btm_pm" #include +#include #include #include -#include "device/include/controller.h" #include "device/include/interop.h" +#include "hci/controller_interface.h" #include "internal_include/bt_target.h" #include "main/shim/dumpsys.h" +#include "main/shim/entry.h" #include "os/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "osi/include/stack_power_telemetry.h" @@ -48,6 +51,8 @@ #include "stack/include/btm_status.h" #include "types/raw_address.h" +using namespace bluetooth; + void l2c_OnHciModeChangeSendPendingPackets(RawAddress remote); void btm_sco_chk_pend_unpark(tHCI_STATUS status, uint16_t handle); void btm_cont_rswitch_from_handle(uint16_t hci_handle); @@ -149,8 +154,8 @@ tBTM_STATUS BTM_PmRegister(uint8_t mask, uint8_t* p_pm_id, void BTM_PM_OnConnected(uint16_t handle, const RawAddress& remote_bda) { if (pm_mode_db.find(handle) != pm_mode_db.end()) { - LOG_ERROR("Overwriting power mode db entry handle:%hu peer:%s", handle, - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::error("Overwriting power mode db entry handle:{} peer:{}", handle, + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); } pm_mode_db[handle] = {}; pm_mode_db[handle].Init(remote_bda, handle); @@ -158,7 +163,7 @@ void BTM_PM_OnConnected(uint16_t handle, const RawAddress& remote_bda) { void BTM_PM_OnDisconnected(uint16_t handle) { if (pm_mode_db.find(handle) == pm_mode_db.end()) { - LOG_ERROR("Erasing unknown power mode db entry handle:%hu", handle); + log::error("Erasing unknown power mode db entry handle:{}", handle); } pm_mode_db.erase(handle); if (handle == pm_pend_link) { @@ -184,40 +189,40 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, } if (!p_mode) { - LOG_ERROR("pm_id: %u, p_mode is null for %s", unsigned(pm_id), - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::error("pm_id: {}, p_mode is null for {}", unsigned(pm_id), + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return BTM_ILLEGAL_VALUE; } // per ACL link auto* p_cb = btm_pm_get_power_manager_from_address(remote_bda); if (p_cb == nullptr) { - LOG_WARN("Unable to find power manager for peer: %s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn("Unable to find power manager for peer: {}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return BTM_UNKNOWN_ADDR; } uint16_t handle = p_cb->handle_; tBTM_PM_MODE mode = p_mode->mode; if (!is_legal_power_mode(mode)) { - LOG_ERROR("Unable to set illegal power mode value:0x%02x", mode); + log::error("Unable to set illegal power mode value:0x{:02x}", mode); return BTM_ILLEGAL_VALUE; } if (p_mode->mode & BTM_PM_MD_FORCE) { - LOG_INFO("Attempting to force into this power mode"); + log::info("Attempting to force into this power mode"); /* take out the force bit */ mode &= (~BTM_PM_MD_FORCE); } if (mode != BTM_PM_MD_ACTIVE) { - const controller_t* controller = controller_get_interface(); - if ((mode == BTM_PM_MD_HOLD && !controller->supports_hold_mode()) || - (mode == BTM_PM_MD_SNIFF && !controller->supports_sniff_mode()) || - (mode == BTM_PM_MD_PARK && !controller->supports_park_mode()) || + auto controller = bluetooth::shim::GetController(); + if ((mode == BTM_PM_MD_HOLD && !controller->SupportsHoldMode()) || + (mode == BTM_PM_MD_SNIFF && !controller->SupportsSniffMode()) || + (mode == BTM_PM_MD_PARK && !controller->SupportsParkMode()) || interop_match_addr(INTEROP_DISABLE_SNIFF, &remote_bda)) { - LOG_ERROR("pm_id %u mode %u is not supported for %s", pm_id, mode, - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::error("pm_id {} mode {} is not supported for {}", pm_id, mode, + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return BTM_MODE_UNSUPPORTED; } } @@ -230,9 +235,9 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, (p_mode->min <= p_cb->interval)) || ((p_mode->mode & BTM_PM_MD_FORCE) == 0 && (p_mode->max >= p_cb->interval))) { - LOG_DEBUG( - "Device is already in requested mode %d, interval: %d, max: %d, min: " - "%d", + log::debug( + "Device is already in requested mode {}, interval: {}, max: {}, min: " + "{}", p_mode->mode, p_cb->interval, p_mode->max, p_mode->min); return BTM_SUCCESS; } @@ -250,23 +255,24 @@ tBTM_STATUS BTM_SetPowerMode(uint8_t pm_id, const RawAddress& remote_bda, /* if mode == hold or pending, return */ if ((p_cb->state == BTM_PM_STS_HOLD) || (p_cb->state == BTM_PM_STS_PENDING) || (pm_pend_link != 0)) { - LOG_INFO( - "Current power mode is hold or pending status or pending links" - " state:%s[%hhu] pm_pending_link:%hu", + log::info( + "Current power mode is hold or pending status or pending links " + "state:{}[{}] pm_pending_link:{}", power_mode_state_text(p_cb->state).c_str(), p_cb->state, pm_pend_link); /* command pending */ if (handle != pm_pend_link) { p_cb->state |= BTM_PM_STORED_MASK; - LOG_INFO("Setting stored bitmask for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::info("Setting stored bitmask for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); } return BTM_CMD_STORED; } - LOG_INFO( - "Setting power mode for peer:%s current_mode:%s[%hhu] new_mode:%s[%hhu]", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda), power_mode_state_text(p_cb->state).c_str(), - p_cb->state, power_mode_text(p_mode->mode).c_str(), p_mode->mode); + log::info( + "Setting power mode for peer:{} current_mode:{}[{}] new_mode:{}[{}]", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda), + power_mode_state_text(p_cb->state).c_str(), p_cb->state, + power_mode_text(p_mode->mode).c_str(), p_mode->mode); return btm_pm_snd_md_req(p_cb->handle_, pm_id, p_cb->handle_, p_mode); } @@ -287,12 +293,12 @@ bool BTM_SetLinkPolicyActiveMode(const RawAddress& remote_bda) { bool BTM_ReadPowerMode(const RawAddress& remote_bda, tBTM_PM_MODE* p_mode) { if (p_mode == nullptr) { - LOG_ERROR("power mode is nullptr"); + log::error("power mode is nullptr"); return false; } tBTM_PM_MCB* p_mcb = btm_pm_get_power_manager_from_address(remote_bda); if (p_mcb == nullptr) { - LOG_WARN("Unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn("Unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return false; } *p_mode = static_cast(p_mcb->state); @@ -321,29 +327,27 @@ tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda, uint16_t max_lat, uint16_t min_rmt_to, uint16_t min_loc_to) { tBTM_PM_MCB* p_cb = btm_pm_get_power_manager_from_address(remote_bda); if (p_cb == nullptr) { - LOG_WARN("Unable to find power manager for peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::warn("Unable to find power manager for peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return BTM_UNKNOWN_ADDR; } - const controller_t* controller = controller_get_interface(); - if (!controller->supports_sniff_subrating()) { - LOG_INFO("No controller support for sniff subrating"); + if (!bluetooth::shim::GetController()->SupportsSniffSubrating()) { + log::info("No controller support for sniff subrating"); return BTM_SUCCESS; } if (p_cb->state == BTM_PM_ST_ACTIVE || p_cb->state == BTM_PM_ST_SNIFF) { - LOG_INFO( - "Set sniff subrating state:%s[%d] max_latency:0x%04x " - "min_remote_timeout:0x%04x" - " min_local_timeout:0x%04x", + log::info( + "Set sniff subrating state:{}[{}] max_latency:0x{:04x} " + "min_remote_timeout:0x{:04x} min_local_timeout:0x{:04x}", power_mode_state_text(p_cb->state).c_str(), p_cb->state, max_lat, min_rmt_to, min_loc_to); send_sniff_subrating(p_cb->handle_, remote_bda, max_lat, min_rmt_to, min_loc_to); return BTM_SUCCESS; } - LOG_INFO("pm_mode_db state: %d", p_cb->state); + log::info("pm_mode_db state: {}", p_cb->state); p_cb->max_lat = max_lat; p_cb->min_rmt_to = min_rmt_to; p_cb->min_loc_to = min_loc_to; @@ -378,7 +382,7 @@ void btm_pm_reset(void) { pm_mode_db.clear(); pm_pend_id = 0; memset(&pm_reg_db, 0, sizeof(pm_reg_db)); - LOG_INFO("reset pm"); + log::info("reset pm"); } /******************************************************************************* @@ -523,37 +527,35 @@ static tBTM_STATUS btm_pm_snd_md_req(uint16_t handle, uint8_t pm_id, mode = btm_pm_get_set_mode(pm_id, p_cb, p_mode, &md_res); md_res.mode = mode; - LOG_DEBUG("Found controller in mode:%s", power_mode_text(mode).c_str()); + log::debug("Found controller in mode:{}", power_mode_text(mode).c_str()); if (p_cb->state == mode) { - LOG_INFO( - "Link already in requested mode pm_id:%hhu link_ind:%d mode:%s[%hhu]", - pm_id, link_ind, power_mode_text(mode).c_str(), mode); + log::info("Link already in requested mode pm_id:{} link_ind:{} mode:{}[{}]", + pm_id, link_ind, power_mode_text(mode).c_str(), mode); /* already in the resulting mode */ if ((mode == BTM_PM_MD_ACTIVE) || ((md_res.max >= p_cb->interval) && (md_res.min <= p_cb->interval))) { - LOG_DEBUG("Storing command"); + log::debug("Storing command"); return BTM_CMD_STORED; } - LOG_DEBUG("Need to wake then sleep"); + log::debug("Need to wake then sleep"); chg_ind = true; } p_cb->chg_ind = chg_ind; /* cannot go directly from current mode to resulting mode. */ if (mode != BTM_PM_MD_ACTIVE && p_cb->state != BTM_PM_MD_ACTIVE) { - LOG_DEBUG("Power mode change delay required"); + log::debug("Power mode change delay required"); p_cb->chg_ind = true; /* needs to wake, then sleep */ } if (p_cb->chg_ind) { - LOG_DEBUG("Need to wake first"); + log::debug("Need to wake first"); md_res.mode = BTM_PM_MD_ACTIVE; } else if (BTM_PM_MD_SNIFF == md_res.mode && p_cb->max_lat) { - const controller_t* controller = controller_get_interface(); - if (controller->supports_sniff_subrating()) { - LOG_DEBUG("Sending sniff subrating to controller"); + if (bluetooth::shim::GetController()->SupportsSniffSubrating()) { + log::debug("Sending sniff subrating to controller"); send_sniff_subrating(handle, p_cb->bda_, p_cb->max_lat, p_cb->min_rmt_to, p_cb->min_loc_to); } @@ -565,9 +567,9 @@ static tBTM_STATUS btm_pm_snd_md_req(uint16_t handle, uint8_t pm_id, /* send the appropriate HCI command */ pm_pend_id = pm_id; - LOG_INFO("Switching from %s[0x%02x] to %s[0x%02x]", - power_mode_state_text(p_cb->state).c_str(), p_cb->state, - power_mode_state_text(md_res.mode).c_str(), md_res.mode); + log::info("Switching from {}[0x{:02x}] to {}[0x{:02x}]", + power_mode_state_text(p_cb->state).c_str(), p_cb->state, + power_mode_state_text(md_res.mode).c_str(), md_res.mode); BTM_LogHistory(kBtmLogTag, p_cb->bda_, "Power mode change", base::StringPrintf( "%s[0x%02x] ==> %s[0x%02x]", @@ -613,7 +615,7 @@ static tBTM_STATUS btm_pm_snd_md_req(uint16_t handle, uint8_t pm_id, if (pm_pend_link == 0) { /* the command was not sent */ - LOG_ERROR("pm_pending_link maxed out"); + log::error("pm_pending_link maxed out"); return (BTM_NO_RESOURCES); } @@ -624,8 +626,8 @@ static void btm_pm_continue_pending_mode_changes() { for (auto& entry : pm_mode_db) { if (entry.second.state & BTM_PM_STORED_MASK) { entry.second.state &= ~BTM_PM_STORED_MASK; - LOG_INFO("Found another link requiring power mode change:%s", - ADDRESS_TO_LOGGABLE_CSTR(entry.second.bda_)); + log::info("Found another link requiring power mode change:{}", + ADDRESS_TO_LOGGABLE_CSTR(entry.second.bda_)); btm_pm_snd_md_req(entry.second.handle_, BTM_PM_SET_ONLY_ID, entry.second.handle_, NULL); return; @@ -647,15 +649,15 @@ static void btm_pm_continue_pending_mode_changes() { ******************************************************************************/ void btm_pm_proc_cmd_status(tHCI_STATUS status) { if (pm_pend_link == 0) { - LOG_ERROR( + log::error( "There are no links pending power mode changes; try to find other " "pending changes"); btm_pm_continue_pending_mode_changes(); return; } if (pm_mode_db.count(pm_pend_link) == 0) { - LOG_ERROR( - "Got PM change status for disconnected link %d; forgot to clean up " + log::error( + "Got PM change status for disconnected link {}; forgot to clean up " "pm_pend_link?", pm_pend_link); btm_pm_continue_pending_mode_changes(); @@ -675,13 +677,13 @@ void btm_pm_proc_cmd_status(tHCI_STATUS status) { /* notify the caller is appropriate */ if ((pm_pend_id != BTM_PM_SET_ONLY_ID) && (pm_reg_db.mask & BTM_PM_REG_SET)) { const RawAddress bd_addr = pm_mode_db[pm_pend_link].bda_; - LOG_DEBUG("Notifying callback that link power mode is complete peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Notifying callback that link power mode is complete peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); (*pm_reg_db.cback)(bd_addr, pm_status, 0, status); } - LOG_INFO("Clearing pending power mode link state:%s", - power_mode_state_text(p_cb->state).c_str()); + log::info("Clearing pending power mode link state:{}", + power_mode_state_text(p_cb->state).c_str()); pm_pend_link = 0; btm_pm_continue_pending_mode_changes(); @@ -710,7 +712,7 @@ void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle, /* update control block */ if (pm_mode_db.count(hci_handle) == 0) { - LOG_WARN("Unable to find active acl for handle %d", hci_handle); + log::warn("Unable to find active acl for handle {}", hci_handle); return; } tBTM_PM_MCB* p_cb = &pm_mode_db[hci_handle]; @@ -719,9 +721,9 @@ void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle, p_cb->state = mode; p_cb->interval = interval; - LOG_INFO("Power mode switched from %s[%hhu] to %s[%hhu]", - power_mode_state_text(old_state).c_str(), old_state, - power_mode_state_text(p_cb->state).c_str(), p_cb->state); + log::info("Power mode switched from {}[{}] to {}[{}]", + power_mode_state_text(old_state).c_str(), old_state, + power_mode_state_text(p_cb->state).c_str(), p_cb->state); if ((p_cb->state == BTM_PM_ST_ACTIVE) || (p_cb->state == BTM_PM_ST_SNIFF)) { l2c_OnHciModeChangeSendPendingPackets(p_cb->bda_); @@ -772,7 +774,7 @@ void btm_pm_proc_mode_change(tHCI_STATUS hci_status, uint16_t hci_handle, void process_ssr_event(tHCI_STATUS status, uint16_t handle, UNUSED_ATTR uint16_t max_tx_lat, uint16_t max_rx_lat) { if (pm_mode_db.count(handle) == 0) { - LOG_WARN("Received sniff subrating event with no active ACL"); + log::warn("Received sniff subrating event with no active ACL"); return; } tBTM_PM_MCB* p_cb = &pm_mode_db[handle]; @@ -780,10 +782,10 @@ void process_ssr_event(tHCI_STATUS status, uint16_t handle, bool use_ssr = true; if (p_cb->interval == max_rx_lat) { - LOG_DEBUG("Sniff subrating unsupported so dropping to legacy sniff mode"); + log::debug("Sniff subrating unsupported so dropping to legacy sniff mode"); use_ssr = false; } else { - LOG_DEBUG("Sniff subrating enabled"); + log::debug("Sniff subrating enabled"); } int cnt = 0; @@ -791,9 +793,9 @@ void process_ssr_event(tHCI_STATUS status, uint16_t handle, (*pm_reg_db.cback)(bd_addr, BTM_PM_STS_SSR, (use_ssr) ? 1 : 0, status); cnt++; } - LOG_DEBUG( - "Notified sniff subrating registered clients cnt:%d peer:%s use_ssr:%s " - "status:%s", + log::debug( + "Notified sniff subrating registered clients cnt:{} peer:{} use_ssr:{} " + "status:{}", cnt, ADDRESS_TO_LOGGABLE_CSTR(bd_addr), logbool(use_ssr).c_str(), hci_error_code_text(status).c_str()); } @@ -842,7 +844,7 @@ static bool btm_pm_device_in_active_or_sniff_mode(void) { /* Check BLE states */ if (!btm_cb.ble_ctr_cb.is_connection_state_idle()) { - LOG_VERBOSE("%s - BLE state is not idle", __func__); + log::verbose("- BLE state is not idle"); return true; } @@ -851,24 +853,18 @@ static bool btm_pm_device_in_active_or_sniff_mode(void) { /******************************************************************************* * - * Function btm_pm_device_in_scan_state + * Function BTM_PM_DeviceInScanState * - * Description This function is called to check if in paging, inquiry or - * connecting mode + * Description This function is called to check if in inquiry * - * Returns true, if in paging, inquiry or connecting mode + * Returns true, if in inquiry * ******************************************************************************/ -static bool btm_pm_device_in_scan_state(void) { - /* Scan state-paging, inquiry, and trying to connect */ - - /* Check for paging */ - // TODO: Get this information from connection manager? - +bool BTM_PM_DeviceInScanState(void) { /* Check for inquiry */ if ((btm_cb.btm_inq_vars.inq_active & (BTM_BR_INQ_ACTIVE_MASK | BTM_BLE_INQ_ACTIVE_MASK)) != 0) { - LOG_VERBOSE("btm_pm_device_in_scan_state- Inq active"); + log::verbose("BTM_PM_DeviceInScanState- Inq active"); return true; } @@ -888,12 +884,65 @@ static bool btm_pm_device_in_scan_state(void) { tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void) { if (btm_pm_device_in_active_or_sniff_mode()) return BTM_CONTRL_ACTIVE; - else if (btm_pm_device_in_scan_state()) + else if (BTM_PM_DeviceInScanState()) return BTM_CONTRL_SCAN; else return BTM_CONTRL_IDLE; } +/******************************************************************************* + * + * Function BTM_PM_ReadSniffLinkCount + * + * Description Return the number of BT connection in sniff mode + * + * Returns Number of BT connection in sniff mode + * + ******************************************************************************/ +uint8_t BTM_PM_ReadSniffLinkCount(void) { + uint8_t count = 0; + for (auto& entry : pm_mode_db) { + if (entry.second.state == HCI_MODE_SNIFF) { + ++count; + } + } + return count; +} + +/******************************************************************************* + * + * Function BTM_PM_ReadBleLinkCount + * + * Description Return the number of BLE connection + * + * Returns Number of BLE connection + * + ******************************************************************************/ +uint8_t BTM_PM_ReadBleLinkCount(void) { + return btm_cb.ble_ctr_cb.link_count[HCI_ROLE_CENTRAL] + + btm_cb.ble_ctr_cb.link_count[HCI_ROLE_PERIPHERAL]; +} + +/******************************************************************************* + * + * Function BTM_PM_ReadBleScanDutyCycle + * + * Description Returns BLE scan duty cycle which is (window * 100) / + *interval + * + * Returns BLE scan duty cycle + * + ******************************************************************************/ +uint32_t BTM_PM_ReadBleScanDutyCycle(void) { + if (!btm_cb.ble_ctr_cb.is_ble_scan_active()) { + return 0; + } + uint32_t scan_window = btm_cb.ble_ctr_cb.inq_var.scan_window; + uint32_t scan_interval = btm_cb.ble_ctr_cb.inq_var.scan_interval; + log::debug("LE scan_window:{} scan interval:{}", scan_window, scan_interval); + return (scan_window * 100) / scan_interval; +} + void btm_pm_on_mode_change(tHCI_STATUS status, uint16_t handle, tHCI_MODE current_mode, uint16_t interval) { btm_sco_chk_pend_unpark(status, handle); diff --git a/system/stack/arbiter/acl_arbiter.cc b/system/stack/arbiter/acl_arbiter.cc index f1321c127d8b61ecb871423cf6421855c32d7c61..c80f98a74ad7374514e7bfb21601b1a9fa4e011c 100644 --- a/system/stack/arbiter/acl_arbiter.cc +++ b/system/stack/arbiter/acl_arbiter.cc @@ -17,10 +17,10 @@ #include "stack/arbiter/acl_arbiter.h" #include +#include #include -#include "os/log.h" #include "osi/include/allocator.h" #include "stack/gatt/gatt_int.h" #include "stack/include/l2c_api.h" @@ -80,18 +80,18 @@ RustArbiterCallbacks callbacks_{}; class RustGattAclArbiter : public AclArbiter { public: virtual void OnLeConnect(uint8_t tcb_idx, uint16_t advertiser_id) override { - LOG_INFO("Notifying Rust of LE connection"); + log::info("Notifying Rust of LE connection"); callbacks_.on_le_connect(tcb_idx, advertiser_id); } virtual void OnLeDisconnect(uint8_t tcb_idx) override { - LOG_INFO("Notifying Rust of LE disconnection"); + log::info("Notifying Rust of LE disconnection"); callbacks_.on_le_disconnect(tcb_idx); } virtual InterceptAction InterceptAttPacket(uint8_t tcb_idx, const BT_HDR* packet) override { - LOG_DEBUG("Intercepting ATT packet and forwarding to Rust"); + log::debug("Intercepting ATT packet and forwarding to Rust"); uint8_t* packet_start = (uint8_t*)(packet + 1) + packet->offset; uint8_t* packet_end = packet_start + packet->len; @@ -102,17 +102,17 @@ class RustGattAclArbiter : public AclArbiter { } virtual void OnOutgoingMtuReq(uint8_t tcb_idx) override { - LOG_DEBUG("Notifying Rust of outgoing MTU request"); + log::debug("Notifying Rust of outgoing MTU request"); callbacks_.on_outgoing_mtu_req(tcb_idx); } virtual void OnIncomingMtuResp(uint8_t tcb_idx, size_t mtu) { - LOG_DEBUG("Notifying Rust of incoming MTU response %zu", mtu); + log::debug("Notifying Rust of incoming MTU response {}", mtu); callbacks_.on_incoming_mtu_resp(tcb_idx, mtu); } virtual void OnIncomingMtuReq(uint8_t tcb_idx, size_t mtu) { - LOG_DEBUG("Notifying Rust of incoming MTU request %zu", mtu); + log::debug("Notifying Rust of incoming MTU request {}", mtu); callbacks_.on_incoming_mtu_req(tcb_idx, mtu); } @@ -122,7 +122,7 @@ class RustGattAclArbiter : public AclArbiter { BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + buffer.size() + L2CAP_MIN_OFFSET); if (p_buf == nullptr) { - LOG_ALWAYS_FATAL("OOM when sending packet"); + log::fatal("OOM when sending packet"); } auto p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; std::copy(buffer.begin(), buffer.end(), p); @@ -130,7 +130,7 @@ class RustGattAclArbiter : public AclArbiter { p_buf->len = buffer.size(); L2CA_SendFixedChnlData(L2CAP_ATT_CID, p_tcb->peer_bda, p_buf); } else { - LOG_ERROR("Dropping packet since connection no longer exists"); + log::error("Dropping packet since connection no longer exists"); } } @@ -148,7 +148,7 @@ void StoreCallbacksFromRust( ::rust::Fn on_outgoing_mtu_req, ::rust::Fn on_incoming_mtu_resp, ::rust::Fn on_incoming_mtu_req) { - LOG_INFO("Received callbacks from Rust, registering in Arbiter"); + log::info("Received callbacks from Rust, registering in Arbiter"); callbacks_ = {on_le_connect, on_le_disconnect, intercept_packet, on_outgoing_mtu_req, on_incoming_mtu_resp, on_incoming_mtu_req}; } diff --git a/system/stack/avct/avct_api.cc b/system/stack/avct/avct_api.cc index 8be7cc88dc25e06b232097f3b378eaf7ff7a51f8..f50f592b19187875e51b63a07189cdb7d8f711a4 100644 --- a/system/stack/avct/avct_api.cc +++ b/system/stack/avct/avct_api.cc @@ -24,6 +24,7 @@ #include "avct_api.h" +#include #include #include "avct_int.h" @@ -31,11 +32,12 @@ #include "internal_include/bt_target.h" #include "l2c_api.h" #include "l2cdefs.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /* Control block for AVCT */ tAVCT_CB avct_cb; @@ -54,7 +56,7 @@ tAVCT_CB avct_cb; * ******************************************************************************/ void AVCT_Register() { - LOG_VERBOSE("AVCT_Register"); + log::verbose("AVCT_Register"); /* initialize AVCTP data structures */ memset(&avct_cb, 0, sizeof(tAVCT_CB)); @@ -87,7 +89,7 @@ void AVCT_Register() { * ******************************************************************************/ void AVCT_Deregister(void) { - LOG_VERBOSE("AVCT_Deregister"); + log::verbose("AVCT_Deregister"); /* deregister PSM with L2CAP */ L2CA_Deregister(AVCT_PSM); @@ -116,7 +118,7 @@ uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, tAVCT_CCB* p_ccb; tAVCT_LCB* p_lcb; - LOG_VERBOSE("AVCT_CreateConn: %d, control:%d", p_cc->role, p_cc->control); + log::verbose("AVCT_CreateConn: {}, control:{}", p_cc->role, p_cc->control); /* Allocate ccb; if no ccbs, return failure */ p_ccb = avct_ccb_alloc(p_cc); @@ -147,7 +149,7 @@ uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, if (result == AVCT_SUCCESS) { /* bind lcb to ccb */ p_ccb->p_lcb = p_lcb; - LOG_VERBOSE("ch_state: %d", p_lcb->ch_state); + log::verbose("ch_state: {}", p_lcb->ch_state); tAVCT_LCB_EVT avct_lcb_evt; avct_lcb_evt.p_ccb = p_ccb; avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt); @@ -174,7 +176,7 @@ uint16_t AVCT_RemoveConn(uint8_t handle) { uint16_t result = AVCT_SUCCESS; tAVCT_CCB* p_ccb; - LOG_VERBOSE("AVCT_RemoveConn"); + log::verbose("AVCT_RemoveConn"); /* map handle to ccb */ p_ccb = avct_ccb_by_idx(handle); @@ -217,7 +219,7 @@ uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) { tAVCT_BCB* p_bcb; int index; - LOG_VERBOSE("AVCT_CreateBrowse: %d", role); + log::verbose("AVCT_CreateBrowse: {}", role); /* map handle to ccb */ p_ccb = avct_ccb_by_idx(handle); @@ -251,7 +253,7 @@ uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) { /* bind bcb to ccb */ p_ccb->p_bcb = p_bcb; p_bcb->peer_addr = p_ccb->p_lcb->peer_addr; - LOG_VERBOSE("ch_state: %d", p_bcb->ch_state); + log::verbose("ch_state: {}", p_bcb->ch_state); tAVCT_LCB_EVT avct_lcb_evt; avct_lcb_evt.p_ccb = p_ccb; avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt); @@ -278,7 +280,7 @@ uint16_t AVCT_RemoveBrowse(uint8_t handle) { uint16_t result = AVCT_SUCCESS; tAVCT_CCB* p_ccb; - LOG_VERBOSE("AVCT_RemoveBrowse"); + log::verbose("AVCT_RemoveBrowse"); /* map handle to ccb */ p_ccb = avct_ccb_by_idx(handle); @@ -369,14 +371,13 @@ uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) { tAVCT_CCB* p_ccb; tAVCT_UL_MSG ul_msg; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* verify p_msg parameter */ if (p_msg == NULL) { return AVCT_NO_RESOURCES; } - LOG_VERBOSE("%s len: %d layer_specific: %d", __func__, p_msg->len, - p_msg->layer_specific); + log::verbose("len: {} layer_specific: {}", p_msg->len, p_msg->layer_specific); /* map handle to ccb */ p_ccb = avct_ccb_by_idx(handle); diff --git a/system/stack/avct/avct_bcb_act.cc b/system/stack/avct/avct_bcb_act.cc index 6a27097e9c675bdd61d4786de57081d94f688fa9..a2264b8f9afb00d72219f55d997de3ee2053993c 100644 --- a/system/stack/avct/avct_bcb_act.cc +++ b/system/stack/avct/avct_bcb_act.cc @@ -28,19 +28,21 @@ #define LOG_TAG "bluetooth" #include +#include #include #include "avct_api.h" #include "avct_int.h" #include "bta/include/bta_sec_api.h" #include "internal_include/bt_target.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "stack/avct/avct_defs.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /* action function list */ const tAVCT_BCB_ACTION avct_bcb_action[] = { avct_bcb_chnl_open, /* AVCT_LCB_CHNL_OPEN */ @@ -88,7 +90,7 @@ static BT_HDR* avct_bcb_msg_asmbl(UNUSED_ATTR tAVCT_BCB* p_bcb, BT_HDR* p_buf) { /* must be single packet - can not fragment */ if (pkt_type != AVCT_PKT_TYPE_SINGLE) { osi_free_and_reset((void**)&p_buf); - LOG_WARN("Pkt type=%d - fragmentation not allowed. drop it", pkt_type); + log::warn("Pkt type={} - fragmentation not allowed. drop it", pkt_type); } return p_buf; } @@ -422,8 +424,8 @@ void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { (p_data->ul_msg.cr << 8) + p_data->ul_msg.label; /* the channel is closed, opening or closing - open it again */ - LOG_VERBOSE("ch_state: %d, allocated:%d->%d", p_bcb->ch_state, - p_bcb->allocated, p_data->ul_msg.p_ccb->p_lcb->allocated); + log::verbose("ch_state: {}, allocated:{}->{}", p_bcb->ch_state, + p_bcb->allocated, p_data->ul_msg.p_ccb->p_lcb->allocated); p_bcb->allocated = p_data->ul_msg.p_ccb->p_lcb->allocated; avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT*)p_data->ul_msg.p_ccb); @@ -452,8 +454,8 @@ void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { /* initialize packet type and other stuff */ if (curr_msg_len > (p_bcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) { - LOG_ERROR("%s msg len (%d) exceeds peer mtu(%d-%d)!!", __func__, - curr_msg_len, p_bcb->peer_mtu, AVCT_HDR_LEN_SINGLE); + log::error("msg len ({}) exceeds peer mtu({}-{})!!", curr_msg_len, + p_bcb->peer_mtu, AVCT_HDR_LEN_SINGLE); osi_free_and_reset((void**)&p_data->ul_msg.p_buf); return; } @@ -510,7 +512,7 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb); if ((p_data == NULL) || (p_data->p_buf == NULL)) { - LOG_WARN("%s p_data is NULL, returning!", __func__); + log::warn("p_data is NULL, returning!"); return; } @@ -527,8 +529,8 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { } if (p_data->p_buf->len < AVCT_HDR_LEN_SINGLE) { - LOG_WARN("Invalid AVCTP packet length %d: must be at least %d", - p_data->p_buf->len, AVCT_HDR_LEN_SINGLE); + log::warn("Invalid AVCTP packet length {}: must be at least {}", + p_data->p_buf->len, AVCT_HDR_LEN_SINGLE); osi_free_and_reset((void**)&p_data->p_buf); return; } @@ -542,7 +544,7 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { /* check for invalid cr_ipid */ if (cr_ipid == AVCT_CR_IPID_INVALID) { - LOG_WARN("Invalid cr_ipid %d", cr_ipid); + log::warn("Invalid cr_ipid {}", cr_ipid); osi_free_and_reset((void**)&p_data->p_buf); return; } @@ -566,7 +568,7 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { } /* PID not found; drop message */ - LOG_WARN("No ccb for PID=%x", pid); + log::warn("No ccb for PID={:x}", pid); osi_free_and_reset((void**)&p_data->p_buf); /* if command send reject */ @@ -595,13 +597,13 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { void avct_bcb_dealloc(tAVCT_BCB* p_bcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; - LOG_VERBOSE("%s %d", __func__, p_bcb->allocated); + log::verbose("{}", p_bcb->allocated); for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) { /* if ccb allocated and */ if ((p_ccb->allocated) && (p_ccb->p_bcb == p_bcb)) { p_ccb->p_bcb = NULL; - LOG_VERBOSE("%s used by ccb: %d", __func__, idx); + log::verbose("used by ccb: {}", idx); break; } } @@ -699,6 +701,6 @@ tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid) { } /* out of lcbs */ - LOG_WARN("No bcb for lcid %x", lcid); + log::warn("No bcb for lcid {:x}", lcid); return NULL; } diff --git a/system/stack/avct/avct_ccb.cc b/system/stack/avct/avct_ccb.cc index 7f916c694f89ab390041080ae5ee51b432017521..c31df28d80271fe3a67aec52fafc2a62bf157c04 100644 --- a/system/stack/avct/avct_ccb.cc +++ b/system/stack/avct/avct_ccb.cc @@ -25,14 +25,16 @@ #define LOG_TAG "avctp" +#include #include #include "avct_api.h" #include "avct_int.h" #include "internal_include/bt_target.h" -#include "os/log.h" #include "types/raw_address.h" +using namespace bluetooth; + /******************************************************************************* * * Function avct_ccb_alloc @@ -51,7 +53,7 @@ tAVCT_CCB* avct_ccb_alloc(tAVCT_CC* p_cc) { if (!p_ccb->allocated) { p_ccb->allocated = AVCT_ALOC_LCB; memcpy(&p_ccb->cc, p_cc, sizeof(tAVCT_CC)); - LOG_VERBOSE("avct_ccb_alloc %d", i); + log::verbose("avct_ccb_alloc {}", i); break; } } @@ -59,7 +61,7 @@ tAVCT_CCB* avct_ccb_alloc(tAVCT_CC* p_cc) { if (i == AVCT_NUM_CONN) { /* out of ccbs */ p_ccb = NULL; - LOG_WARN("Out of ccbs"); + log::warn("Out of ccbs"); } return p_ccb; } @@ -79,7 +81,7 @@ void avct_ccb_dealloc(tAVCT_CCB* p_ccb, uint8_t event, uint16_t result, const RawAddress* bd_addr) { tAVCT_CTRL_CBACK* p_cback = p_ccb->cc.p_ctrl_cback; - LOG_VERBOSE("avct_ccb_dealloc %d", avct_ccb_to_idx(p_ccb)); + log::verbose("avct_ccb_dealloc {}", avct_ccb_to_idx(p_ccb)); if (p_ccb->p_bcb == NULL) { memset(p_ccb, 0, sizeof(tAVCT_CCB)); @@ -131,11 +133,11 @@ tAVCT_CCB* avct_ccb_by_idx(uint8_t idx) { /* verify ccb is allocated */ if (!p_ccb->allocated) { p_ccb = NULL; - LOG_WARN("ccb %d not allocated", idx); + log::warn("ccb {} not allocated", idx); } } else { p_ccb = NULL; - LOG_WARN("No ccb for idx %d", idx); + log::warn("No ccb for idx {}", idx); } return p_ccb; } diff --git a/system/stack/avct/avct_l2c.cc b/system/stack/avct/avct_l2c.cc index b8b65fe93461b9dca64c455d6188f8ca0a2b50dd..328778503b5f1e11cfed0720710074c8060124b7 100644 --- a/system/stack/avct/avct_l2c.cc +++ b/system/stack/avct/avct_l2c.cc @@ -24,19 +24,20 @@ #define LOG_TAG "avctp" #include -#include +#include #include "avct_api.h" #include "avct_int.h" #include "internal_include/bt_target.h" #include "l2c_api.h" #include "l2cdefs.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /* callback function declarations */ void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t psm, uint8_t id); @@ -84,7 +85,7 @@ static bool avct_l2c_is_passive(tAVCT_LCB* p_lcb) { for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { - LOG_VERBOSE("avct_l2c_is_ct control:x%x", p_ccb->cc.control); + log::verbose("avct_l2c_is_ct control:x{:x}", p_ccb->cc.control); if (p_ccb->cc.control & AVCT_PASSIVE) { is_passive = true; break; @@ -128,14 +129,14 @@ void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, /* TG role only - accept the connection from CT. move the channel ID to * the conflict list */ p_lcb->conflict_lcid = p_lcb->ch_lcid; - LOG_VERBOSE("avct_l2c_connect_ind_cback conflict_lcid:0x%x", - p_lcb->conflict_lcid); + log::verbose("avct_l2c_connect_ind_cback conflict_lcid:0x{:x}", + p_lcb->conflict_lcid); } } if (p_lcb) { - LOG_VERBOSE("avct_l2c_connect_ind_cback: 0x%x, res: %d, ch_state: %d", lcid, - result, p_lcb->ch_state); + log::verbose("avct_l2c_connect_ind_cback: 0x{:x}, res: {}, ch_state: {}", + lcid, result, p_lcb->ch_state); } /* If we reject the connection, send DisconnectReq */ @@ -151,9 +152,10 @@ void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, if (p_ccb && p_ccb->allocated && (p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP)) { p_ccb->p_lcb = p_lcb; - LOG_VERBOSE( - "ACP bind %d ccb to lcb, alloc %d, lcb %p, role %d, pid 0x%x", i, - p_ccb->allocated, p_ccb->p_lcb, p_ccb->cc.role, p_ccb->cc.pid); + log::verbose( + "ACP bind {} ccb to lcb, alloc {}, lcb {}, role {}, pid 0x{:x}", + i, p_ccb->allocated, fmt::ptr(p_ccb->p_lcb), p_ccb->cc.role, + p_ccb->cc.pid); } } } @@ -164,15 +166,15 @@ void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, p_lcb->ch_state = AVCT_CH_CFG; } - if (p_lcb) LOG_VERBOSE("ch_state cni: %d ", p_lcb->ch_state); + if (p_lcb) log::verbose("ch_state cni: {} ", p_lcb->ch_state); } static void avct_on_l2cap_error(uint16_t lcid, uint16_t result) { tAVCT_LCB* p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb == nullptr) return; if (p_lcb->ch_state == AVCT_CH_CONN) { - LOG_VERBOSE("avct_l2c_connect_cfm_cback conflict_lcid:0x%x", - p_lcb->conflict_lcid); + log::verbose("avct_l2c_connect_cfm_cback conflict_lcid:0x{:x}", + p_lcb->conflict_lcid); if (p_lcb->conflict_lcid == lcid) { p_lcb->conflict_lcid = 0; } else { @@ -181,8 +183,8 @@ static void avct_on_l2cap_error(uint16_t lcid, uint16_t result) { avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt); } } else if (p_lcb->ch_state == AVCT_CH_CFG) { - LOG_VERBOSE("ERROR avct_l2c_config_cfm_cback L2CA_DisconnectReq %d ", - p_lcb->ch_state); + log::verbose("ERROR avct_l2c_config_cfm_cback L2CA_DisconnectReq {} ", + p_lcb->ch_state); /* store result value */ p_lcb->ch_result = result; @@ -207,9 +209,9 @@ void avct_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result) { /* look up lcb for this channel */ p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb != NULL) { - LOG_VERBOSE( - "avct_l2c_connect_cfm_cback lcid:0x%x result: %d ch_state: %d, " - "conflict_lcid:0x%x", + log::verbose( + "avct_l2c_connect_cfm_cback lcid:0x{:x} result: {} ch_state: {}, " + "conflict_lcid:0x{:x}", lcid, result, p_lcb->ch_state, p_lcb->conflict_lcid); /* if in correct state */ if (p_lcb->ch_state == AVCT_CH_CONN) { @@ -220,12 +222,13 @@ void avct_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result) { } /* else failure */ else { - LOG(ERROR) << __func__ << ": invoked with non OK status"; + log::error("invoked with non OK status"); } } else if (p_lcb->conflict_lcid == lcid) { /* we must be in AVCT_CH_CFG state for the ch_lcid channel */ - LOG_VERBOSE("avct_l2c_connect_cfm_cback ch_state: %d, conflict_lcid:0x%x", - p_lcb->ch_state, p_lcb->conflict_lcid); + log::verbose( + "avct_l2c_connect_cfm_cback ch_state: {}, conflict_lcid:0x{:x}", + p_lcb->ch_state, p_lcb->conflict_lcid); if (result == L2CAP_CONN_OK) { /* just in case the peer also accepts our connection - Send L2CAP * disconnect req */ @@ -233,7 +236,7 @@ void avct_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result) { } p_lcb->conflict_lcid = 0; } - LOG_VERBOSE("ch_state cnc: %d ", p_lcb->ch_state); + log::verbose("ch_state cnc: {} ", p_lcb->ch_state); } } @@ -256,14 +259,14 @@ void avct_l2c_config_cfm_cback(uint16_t lcid, uint16_t initiator, /* look up lcb for this channel */ p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb != NULL) { - LOG_VERBOSE("avct_l2c_config_cfm_cback: 0x%x, ch_state: %d,", lcid, - p_lcb->ch_state); + log::verbose("avct_l2c_config_cfm_cback: 0x{:x}, ch_state: {},", lcid, + p_lcb->ch_state); /* if in correct state */ if (p_lcb->ch_state == AVCT_CH_CFG) { p_lcb->ch_state = AVCT_CH_OPEN; avct_lcb_event(p_lcb, AVCT_LCB_LL_OPEN_EVT, NULL); } - LOG_VERBOSE("ch_state cfc: %d ", p_lcb->ch_state); + log::verbose("ch_state cfc: {} ", p_lcb->ch_state); } } @@ -283,8 +286,8 @@ void avct_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) { /* look up lcb for this channel */ p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb != NULL) { - LOG_VERBOSE("avct_l2c_config_ind_cback: 0x%x, ch_state: %d", lcid, - p_lcb->ch_state); + log::verbose("avct_l2c_config_ind_cback: 0x{:x}, ch_state: {}", lcid, + p_lcb->ch_state); /* store the mtu in tbl */ if (p_cfg->mtu_present) { p_lcb->peer_mtu = p_cfg->mtu; @@ -311,12 +314,12 @@ void avct_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed) { /* look up lcb for this channel */ p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb != NULL) { - LOG_VERBOSE("avct_l2c_disconnect_ind_cback: 0x%x, ch_state: %d", lcid, - p_lcb->ch_state); + log::verbose("avct_l2c_disconnect_ind_cback: 0x{:x}, ch_state: {}", lcid, + p_lcb->ch_state); tAVCT_LCB_EVT avct_lcb_evt; avct_lcb_evt.result = result; avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt); - LOG_VERBOSE("ch_state di: %d ", p_lcb->ch_state); + log::verbose("ch_state di: {} ", p_lcb->ch_state); } } @@ -329,8 +332,8 @@ void avct_l2c_disconnect(uint16_t lcid, uint16_t result) { /* look up lcb for this channel */ p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb != NULL) { - LOG_VERBOSE("avct_l2c_disconnect_cfm_cback: 0x%x, ch_state: %d, res: %d", - lcid, p_lcb->ch_state, result); + log::verbose("avct_l2c_disconnect_cfm_cback: 0x{:x}, ch_state: {}, res: {}", + lcid, p_lcb->ch_state, result); /* result value may be previously stored */ res = (p_lcb->ch_result != 0) ? p_lcb->ch_result : result; p_lcb->ch_result = 0; @@ -338,7 +341,7 @@ void avct_l2c_disconnect(uint16_t lcid, uint16_t result) { tAVCT_LCB_EVT avct_lcb_evt; avct_lcb_evt.result = res; avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt); - LOG_VERBOSE("ch_state dc: %d ", p_lcb->ch_state); + log::verbose("ch_state dc: {} ", p_lcb->ch_state); } } @@ -355,7 +358,7 @@ void avct_l2c_disconnect(uint16_t lcid, uint16_t result) { void avct_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested) { tAVCT_LCB* p_lcb; - LOG_VERBOSE("avct_l2c_congestion_ind_cback: 0x%x", lcid); + log::verbose("avct_l2c_congestion_ind_cback: 0x{:x}", lcid); /* look up lcb for this channel */ p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb != NULL) { @@ -378,14 +381,14 @@ void avct_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested) { void avct_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf) { tAVCT_LCB* p_lcb; - LOG_VERBOSE("avct_l2c_data_ind_cback: 0x%x", lcid); + log::verbose("avct_l2c_data_ind_cback: 0x{:x}", lcid); /* look up lcb for this channel */ p_lcb = avct_lcb_by_lcid(lcid); if (p_lcb != NULL) { avct_lcb_event(p_lcb, AVCT_LCB_LL_MSG_EVT, (tAVCT_LCB_EVT*)&p_buf); } else /* prevent buffer leak */ { - LOG_WARN("ERROR -> avct_l2c_data_ind_cback drop buffer"); + log::warn("ERROR -> avct_l2c_data_ind_cback drop buffer"); osi_free(p_buf); } } diff --git a/system/stack/avct/avct_l2c_br.cc b/system/stack/avct/avct_l2c_br.cc index 70b4b5e0f294a2136e6732b97de40ca491338942..86bb97f39452d877863e1e268775155846e53157 100644 --- a/system/stack/avct/avct_l2c_br.cc +++ b/system/stack/avct/avct_l2c_br.cc @@ -26,20 +26,20 @@ #define LOG_TAG "avctp" -#include +#include #include "avct_api.h" #include "avct_int.h" -#include "bt_target.h" #include "internal_include/bt_target.h" #include "l2c_api.h" #include "l2cdefs.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /* callback function declarations */ void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t psm, uint8_t id); @@ -87,8 +87,8 @@ static bool avct_l2c_br_is_passive(tAVCT_BCB* p_bcb) { for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { - LOG_VERBOSE("Is bcb associated ccb control passive :0x%x", - p_ccb->cc.control); + log::verbose("Is bcb associated ccb control passive :0x{:x}", + p_ccb->cc.control); if (p_ccb->cc.control & AVCT_PASSIVE) { is_passive = true; break; @@ -136,7 +136,7 @@ void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, /* add channel ID to conflict ID */ p_bcb->conflict_lcid = p_bcb->ch_lcid; result = L2CAP_CONN_OK; - LOG_VERBOSE("Detected conflict_lcid:0x%x", p_bcb->conflict_lcid); + log::verbose("Detected conflict_lcid:0x{:x}", p_bcb->conflict_lcid); } } } @@ -147,7 +147,7 @@ void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, /* If we reject the connection, send DisconnectReq */ if (result != L2CAP_CONN_OK) { - LOG_VERBOSE("Connection rejected to lcid:0x%x", lcid); + log::verbose("Connection rejected to lcid:0x{:x}", lcid); L2CA_DisconnectReq(lcid); } @@ -166,7 +166,7 @@ void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result) { if (p_bcb == nullptr) return; if (p_bcb->ch_state == AVCT_CH_CONN && p_bcb->conflict_lcid == lcid) { - LOG_VERBOSE("Reset conflict_lcid:0x%x", p_bcb->conflict_lcid); + log::verbose("Reset conflict_lcid:0x{:x}", p_bcb->conflict_lcid); p_bcb->conflict_lcid = 0; return; } @@ -205,14 +205,14 @@ void avct_l2c_br_connect_cfm_cback(uint16_t lcid, uint16_t result) { } /* else failure */ else { - LOG_ERROR("Invoked with non OK status"); + log::error("Invoked with non OK status"); } } else if (p_bcb->conflict_lcid == lcid) { /* we must be in AVCT_CH_CFG state for the ch_lcid channel */ if (result == L2CAP_CONN_OK) { /* just in case the peer also accepts our connection - Send L2CAP * disconnect req */ - LOG_VERBOSE("Disconnect conflict_lcid:0x%x", p_bcb->conflict_lcid); + log::verbose("Disconnect conflict_lcid:0x{:x}", p_bcb->conflict_lcid); L2CA_DisconnectReq(lcid); } p_bcb->conflict_lcid = 0; @@ -271,7 +271,7 @@ void avct_l2c_br_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) { p_lcb->peer_mtu = max_mtu; } - LOG_VERBOSE("%s peer_mtu:%d use:%d", __func__, p_lcb->peer_mtu, max_mtu); + log::verbose("peer_mtu:{} use:{}", p_lcb->peer_mtu, max_mtu); } /******************************************************************************* diff --git a/system/stack/avct/avct_lcb.cc b/system/stack/avct/avct_lcb.cc index 6a3aebd3bb94b726f03840d1228fde0548d52c76..f7d4c58a5b16f5a300d9ba62f5ffce8de9fe78db 100644 --- a/system/stack/avct/avct_lcb.cc +++ b/system/stack/avct/avct_lcb.cc @@ -25,7 +25,7 @@ #define LOG_TAG "avctp" -#include +#include #include #include "avct_api.h" @@ -37,6 +37,8 @@ #include "osi/include/osi.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * state machine constants and types ****************************************************************************/ @@ -170,8 +172,8 @@ void avct_lcb_event(tAVCT_LCB* p_lcb, uint8_t event, tAVCT_LCB_EVT* p_data) { uint8_t action; int i; - LOG_VERBOSE("LCB lcb=%d event=%s state=%s", p_lcb->allocated, - avct_lcb_evt_str[event], avct_lcb_st_str[p_lcb->state]); + log::verbose("LCB lcb={} event={} state={}", p_lcb->allocated, + avct_lcb_evt_str[event], avct_lcb_st_str[p_lcb->state]); /* look up the state table for the current state */ state_table = avct_lcb_st_tbl[p_lcb->state]; @@ -209,8 +211,8 @@ void avct_bcb_event(tAVCT_BCB* p_bcb, uint8_t event, tAVCT_LCB_EVT* p_data) { uint8_t action; int i; - LOG_VERBOSE("BCB lcb=%d event=%s state=%s", p_bcb->allocated, - avct_lcb_evt_str[event], avct_lcb_st_str[p_bcb->state]); + log::verbose("BCB lcb={} event={} state={}", p_bcb->allocated, + avct_lcb_evt_str[event], avct_lcb_st_str[p_bcb->state]); /* look up the state table for the current state */ state_table = avct_lcb_st_tbl[p_bcb->state]; @@ -254,7 +256,7 @@ tAVCT_LCB* avct_lcb_by_bd(const RawAddress& bd_addr) { /* if no lcb found */ p_lcb = NULL; - VLOG(1) << "No lcb for addr " << ADDRESS_TO_LOGGABLE_STR(bd_addr); + log::verbose("No lcb for addr {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); } return p_lcb; } @@ -277,7 +279,7 @@ tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr) { if (!p_lcb->allocated) { p_lcb->allocated = (uint8_t)(i + 1); p_lcb->peer_addr = bd_addr; - LOG_VERBOSE("avct_lcb_alloc %d", p_lcb->allocated); + log::verbose("avct_lcb_alloc {}", p_lcb->allocated); p_lcb->tx_q = fixed_queue_new(SIZE_MAX); p_lcb->peer_mtu = L2CAP_LE_MIN_MTU; break; @@ -287,7 +289,7 @@ tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr) { if (i == AVCT_NUM_LINKS) { /* out of lcbs */ p_lcb = NULL; - LOG_WARN("Out of lcbs"); + log::warn("Out of lcbs"); } return p_lcb; } @@ -303,21 +305,21 @@ tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr) { * ******************************************************************************/ void avct_lcb_dealloc(tAVCT_LCB* p_lcb, UNUSED_ATTR tAVCT_LCB_EVT* p_data) { - LOG_VERBOSE("%s allocated: %d", __func__, p_lcb->allocated); + log::verbose("allocated: {}", p_lcb->allocated); // Check if the LCB is still referenced tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; for (size_t i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { if (p_ccb->allocated && p_ccb->p_lcb == p_lcb) { - LOG_VERBOSE("%s LCB in use; lcb index: %zu", __func__, i); + log::verbose("LCB in use; lcb index: {}", i); return; } } // If not, de-allocate now... - LOG_VERBOSE("%s Freeing LCB", __func__); + log::verbose("Freeing LCB"); osi_free(p_lcb->p_rx_msg); fixed_queue_free(p_lcb->tx_q, NULL); memset(p_lcb, 0, sizeof(tAVCT_LCB)); @@ -347,7 +349,7 @@ tAVCT_LCB* avct_lcb_by_lcid(uint16_t lcid) { if (i == AVCT_NUM_LINKS) { /* out of lcbs */ p_lcb = NULL; - LOG_WARN("No lcb for lcid %x", lcid); + log::warn("No lcb for lcid {:x}", lcid); } return p_lcb; @@ -389,10 +391,11 @@ bool avct_lcb_last_ccb(tAVCT_LCB* p_lcb, tAVCT_CCB* p_ccb_last) { tAVCT_CCB* p_ccb = &avct_cb.ccb[0]; int i; - LOG_WARN("avct_lcb_last_ccb"); + log::warn("avct_lcb_last_ccb"); for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { - LOG_WARN("%x: aloc:%d, lcb:0x%p/0x%p, ccb:0x%p/0x%p", i, p_ccb->allocated, - p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last); + log::warn("{:x}: aloc:{}, lcb:0x{}/0x{}, ccb:0x{}/0x{}", i, + p_ccb->allocated, fmt::ptr(p_ccb->p_lcb), fmt::ptr(p_lcb), + fmt::ptr(p_ccb), fmt::ptr(p_ccb_last)); if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last)) { return false; } diff --git a/system/stack/avct/avct_lcb_act.cc b/system/stack/avct/avct_lcb_act.cc index 32cdb1ede1c2807ce8668ecbaf83be6042aeeb26..2aa38d56f8c98482f8b86832781bb81619d95b03 100644 --- a/system/stack/avct/avct_lcb_act.cc +++ b/system/stack/avct/avct_lcb_act.cc @@ -22,21 +22,22 @@ * ******************************************************************************/ #include +#include #include #include "avct_api.h" #include "avct_int.h" -#include "bt_target.h" #include "bta/include/bta_sec_api.h" #include "device/include/device_iot_config.h" #include "internal_include/bt_target.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "stack/avct/avct_defs.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /* packet header length lookup table */ const uint8_t avct_lcb_pkt_type_len[] = {AVCT_HDR_LEN_SINGLE, AVCT_HDR_LEN_START, AVCT_HDR_LEN_CONT, @@ -72,13 +73,13 @@ static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) { if (p_buf->len < avct_lcb_pkt_type_len[pkt_type] || (sizeof(BT_HDR) + p_buf->offset + p_buf->len) > BT_DEFAULT_BUFFER_SIZE) { osi_free(p_buf); - LOG_WARN("Bad length during reassembly"); + log::warn("Bad length during reassembly"); p_ret = NULL; } /* single packet */ else if (pkt_type == AVCT_PKT_TYPE_SINGLE) { /* if reassembly in progress drop message and process new single */ - if (p_lcb->p_rx_msg != NULL) LOG_WARN("Got single during reassembly"); + if (p_lcb->p_rx_msg != NULL) log::warn("Got single during reassembly"); osi_free_and_reset((void**)&p_lcb->p_rx_msg); @@ -87,7 +88,7 @@ static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) { /* start packet */ else if (pkt_type == AVCT_PKT_TYPE_START) { /* if reassembly in progress drop message and process new start */ - if (p_lcb->p_rx_msg != NULL) LOG_WARN("Got start during reassembly"); + if (p_lcb->p_rx_msg != NULL) log::warn("Got start during reassembly"); osi_free_and_reset((void**)&p_lcb->p_rx_msg); @@ -126,7 +127,7 @@ static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) { /* if no reassembly in progress drop message */ if (p_lcb->p_rx_msg == NULL) { osi_free(p_buf); - LOG_WARN("Pkt type=%d out of order", pkt_type); + log::warn("Pkt type={} out of order", pkt_type); p_ret = NULL; } else { /* get size of buffer holding assembled message */ @@ -143,7 +144,7 @@ static BT_HDR* avct_lcb_msg_asmbl(tAVCT_LCB* p_lcb, BT_HDR* p_buf) { /* verify length */ if ((p_lcb->p_rx_msg->offset + p_buf->len) > buf_len) { /* won't fit; free everything */ - LOG_WARN("%s: Fragmented message too big!", __func__); + log::warn("Fragmented message too big!"); osi_free_and_reset((void**)&p_lcb->p_rx_msg); osi_free(p_buf); p_ret = NULL; @@ -231,7 +232,7 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) { if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && p_ccb->cc.role == AVCT_INT) { - LOG_VERBOSE("%s, find int handle %d", __func__, i); + log::verbose("find int handle {}", i); is_originater = true; } } @@ -241,9 +242,9 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { /* if ccb allocated and */ /** M: to avoid avctp collision, make sure the collision can be checked @{ */ - LOG_VERBOSE("%s, %d ccb to lcb, alloc %d, lcb %p, role %d, pid 0x%x", - __func__, i, p_ccb->allocated, p_ccb->p_lcb, p_ccb->cc.role, - p_ccb->cc.pid); + log::verbose("{} ccb to lcb, alloc {}, lcb {}, role {}, pid 0x{:x}", i, + p_ccb->allocated, fmt::ptr(p_ccb->p_lcb), p_ccb->cc.role, + p_ccb->cc.pid); if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) { /* if bound to this lcb send connect confirm event */ if (p_ccb->cc.role == AVCT_INT) { @@ -261,7 +262,7 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { avct_lcb_has_pid(p_lcb, p_ccb->cc.pid)) { /* bind ccb to lcb and send connect ind event */ if (is_originater) { - LOG_ERROR("%s, int exist, unbind acp handle:%d", __func__, i); + log::error("int exist, unbind acp handle:{}", i); p_ccb->p_lcb = NULL; } else { bind = true; @@ -428,11 +429,11 @@ void avct_lcb_bind_conn(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { void avct_lcb_chk_disc(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { avct_close_bcb(p_lcb, p_data); if (avct_lcb_last_ccb(p_lcb, p_data->p_ccb)) { - LOG_INFO("Closing last avct channel to device"); + log::info("Closing last avct channel to device"); p_data->p_ccb->ch_close = true; avct_lcb_event(p_lcb, AVCT_LCB_INT_CLOSE_EVT, p_data); } else { - LOG_INFO("Closing avct channel with active remaining channels"); + log::info("Closing avct channel with active remaining channels"); avct_lcb_unbind_disc(p_lcb, p_data); } } @@ -516,7 +517,7 @@ void avct_lcb_cong_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { * ******************************************************************************/ void avct_lcb_discard_msg(UNUSED_ATTR tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { - LOG_WARN("%s Dropping message", __func__); + log::warn("Dropping message"); osi_free_and_reset((void**)&p_data->ul_msg.p_buf); } @@ -614,7 +615,7 @@ void avct_lcb_send_msg(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { pkt_type = AVCT_PKT_TYPE_END; } } - LOG_VERBOSE("%s tx_q_count:%zu", __func__, fixed_queue_length(p_lcb->tx_q)); + log::verbose("tx_q_count:{}", fixed_queue_length(p_lcb->tx_q)); return; } @@ -672,7 +673,7 @@ void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { /* check for invalid cr_ipid */ if (cr_ipid == AVCT_CR_IPID_INVALID) { - LOG_WARN("Invalid cr_ipid %d", cr_ipid); + log::warn("Invalid cr_ipid {}", cr_ipid); osi_free_and_reset((void**)&p_data->p_buf); return; } @@ -696,7 +697,7 @@ void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { } /* PID not found; drop message */ - LOG_WARN("No ccb for PID=%x", pid); + log::warn("No ccb for PID={:x}", pid); osi_free_and_reset((void**)&p_data->p_buf); /* if command send reject */ diff --git a/system/stack/avdt/avdt_ad.cc b/system/stack/avdt/avdt_ad.cc index 5d72382b80c26efe8cd9474045d20ab53cefd873..378d6d4c59a87043b07eb167c66d05405e33fc79 100644 --- a/system/stack/avdt/avdt_ad.cc +++ b/system/stack/avdt/avdt_ad.cc @@ -22,11 +22,12 @@ * ******************************************************************************/ -#include +#include #include #include "avdt_api.h" #include "avdt_int.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "l2c_api.h" #include "l2cdefs.h" @@ -34,21 +35,21 @@ #include "stack/include/bt_hdr.h" #include "stack/include/btm_sec_api_types.h" +using namespace bluetooth; + AvdtpScb* AvdtpAdaptationLayer::LookupAvdtpScb( const AvdtpTransportChannel& tc) { if (tc.ccb_idx >= AVDT_NUM_LINKS) { - LOG_ERROR("%s: AvdtpScb entry not found: invalid ccb_idx:%d", __func__, - tc.ccb_idx); + log::error("AvdtpScb entry not found: invalid ccb_idx:{}", tc.ccb_idx); return nullptr; } if (tc.tcid >= AVDT_NUM_RT_TBL) { - LOG_ERROR("%s: AvdtpScb entry not found: invalid tcid:%d", __func__, - tc.tcid); + log::error("AvdtpScb entry not found: invalid tcid:{}", tc.tcid); return nullptr; } const AvdtpRoutingEntry& re = rt_tbl[tc.ccb_idx][tc.tcid]; - LOG_VERBOSE("%s: ccb_idx:%d tcid:%d scb_hdl:%d", __func__, tc.ccb_idx, - tc.tcid, re.scb_hdl); + log::verbose("ccb_idx:{} tcid:{} scb_hdl:{}", tc.ccb_idx, tc.tcid, + re.scb_hdl); return avdt_scb_by_hdl(re.scb_hdl); } @@ -73,7 +74,7 @@ uint8_t avdt_ad_type_to_tcid(uint8_t type, AvdtpScb* p_scb) { // There are AVDT_CHAN_NUM_TYPES channel types per SEP. Here we compute // the type index (TCID) from the SEP index and the type itself. uint8_t tcid = (scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type; - LOG_VERBOSE("%s: type:%d, tcid: %d", __func__, type, tcid); + log::verbose("type:{}, tcid: {}", type, tcid); return tcid; } @@ -100,7 +101,7 @@ static uint8_t avdt_ad_tcid_to_type(uint8_t tcid) { */ type = ((tcid + AVDT_CHAN_NUM_TYPES - 2) % (AVDT_CHAN_NUM_TYPES - 1)) + 1; } - LOG_VERBOSE("tcid: %d, type: %d", tcid, type); + log::verbose("tcid: {}, type: {}", tcid, type); return type; } @@ -274,7 +275,7 @@ AvdtpTransportChannel* avdt_ad_tc_tbl_alloc(AvdtpCcb* p_ccb) { * ******************************************************************************/ uint8_t avdt_ad_tc_tbl_to_idx(AvdtpTransportChannel* p_tbl) { - LOG_VERBOSE("avdt_ad_tc_tbl_to_idx: %ld", (long)(p_tbl - avdtp_cb.ad.tc_tbl)); + log::verbose("avdt_ad_tc_tbl_to_idx: {}", (long)(p_tbl - avdtp_cb.ad.tc_tbl)); /* use array arithmetic to determine index */ return (uint8_t)(p_tbl - avdtp_cb.ad.tc_tbl); } @@ -304,8 +305,7 @@ void avdt_ad_tc_close_ind(AvdtpTransportChannel* p_tbl) { p_tbl->cfg_flags = 0; p_tbl->peer_mtu = L2CAP_DEFAULT_MTU; - LOG_VERBOSE("%s: tcid: %d, old: %d", __func__, p_tbl->tcid, - close.old_tc_state); + log::verbose("tcid: {}, old: {}", p_tbl->tcid, close.old_tc_state); /* if signaling channel, notify ccb that channel open */ if (p_tbl->tcid == 0) { p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx); @@ -316,8 +316,8 @@ void avdt_ad_tc_close_ind(AvdtpTransportChannel* p_tbl) { /* look up scb in stream routing table by ccb, tcid */ p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl); if (p_scb == nullptr) { - LOG_ERROR("%s: Cannot find AvdtScb entry: ccb_idx:%d tcid:%d", __func__, - p_tbl->ccb_idx, p_tbl->tcid); + log::error("Cannot find AvdtScb entry: ccb_idx:{} tcid:{}", p_tbl->ccb_idx, + p_tbl->tcid); return; } close.tcid = p_tbl->tcid; @@ -345,9 +345,9 @@ void avdt_ad_tc_open_ind(AvdtpTransportChannel* p_tbl) { tAVDT_OPEN open; tAVDT_EVT_HDR evt; - LOG_VERBOSE("%s: p_tbl:%p state:%d ccb_idx:%d tcid:%d scb_hdl:%d", __func__, - p_tbl, p_tbl->state, p_tbl->ccb_idx, p_tbl->tcid, - avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl); + log::verbose("p_tbl:{} state:{} ccb_idx:{} tcid:{} scb_hdl:{}", + fmt::ptr(p_tbl), p_tbl->state, p_tbl->ccb_idx, p_tbl->tcid, + avdtp_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl); p_tbl->state = AVDT_AD_ST_OPEN; @@ -373,8 +373,8 @@ void avdt_ad_tc_open_ind(AvdtpTransportChannel* p_tbl) { /* look up scb in stream routing table by ccb, tcid */ p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl); if (p_scb == nullptr) { - LOG_ERROR("%s: Cannot find AvdtScb entry: ccb_idx:%d tcid:%d", __func__, - p_tbl->ccb_idx, p_tbl->tcid); + log::error("Cannot find AvdtScb entry: ccb_idx:{} tcid:{}", p_tbl->ccb_idx, + p_tbl->tcid); return; } /* put lcid in event data */ @@ -416,8 +416,8 @@ void avdt_ad_tc_cong_ind(AvdtpTransportChannel* p_tbl, bool is_congested) { /* look up scb in stream routing table by ccb, tcid */ p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl); if (p_scb == nullptr) { - LOG_ERROR("%s: Cannot find AvdtScb entry: ccb_idx:%d tcid:%d", __func__, - p_tbl->ccb_idx, p_tbl->tcid); + log::error("Cannot find AvdtScb entry: ccb_idx:{} tcid:{}", p_tbl->ccb_idx, + p_tbl->tcid); return; } tAVDT_SCB_EVT avdt_scb_evt; @@ -453,10 +453,10 @@ void avdt_ad_tc_data_ind(AvdtpTransportChannel* p_tbl, BT_HDR* p_buf) { /* if media or other channel, send event to scb */ p_scb = avdtp_cb.ad.LookupAvdtpScb(*p_tbl); if (p_scb == nullptr) { - LOG_ERROR("%s: Cannot find AvdtScb entry: ccb_idx:%d tcid:%d", __func__, - p_tbl->ccb_idx, p_tbl->tcid); + log::error("Cannot find AvdtScb entry: ccb_idx:{} tcid:{}", p_tbl->ccb_idx, + p_tbl->tcid); osi_free(p_buf); - LOG_ERROR("%s: buffer freed", __func__); + log::error("buffer freed"); return; } avdt_scb_event(p_scb, AVDT_SCB_TC_DATA_EVT, (tAVDT_SCB_EVT*)&p_buf); @@ -512,13 +512,13 @@ void avdt_ad_open_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, p_tbl = avdt_ad_tc_tbl_alloc(p_ccb); if (p_tbl == NULL) { - LOG_ERROR("avdt_ad_open_req: Cannot allocate p_tbl"); + log::error("avdt_ad_open_req: Cannot allocate p_tbl"); return; } p_tbl->tcid = avdt_ad_type_to_tcid(type, p_scb); - LOG_VERBOSE("avdt_ad_open_req: type: %d, role: %d, tcid:%d", type, role, - p_tbl->tcid); + log::verbose("avdt_ad_open_req: type: {}, role: {}, tcid:{}", type, role, + p_tbl->tcid); if (type == AVDT_CHAN_SIG) { /* if signaling, get mtu from registration control block */ @@ -530,8 +530,8 @@ void avdt_ad_open_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, /* also set scb_hdl in rt_tbl */ avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].scb_hdl = avdt_scb_to_hdl(p_scb); - LOG_VERBOSE("avdtp_cb.ad.rt_tbl[%d][%d].scb_hdl = %d", - avdt_ccb_to_idx(p_ccb), p_tbl->tcid, avdt_scb_to_hdl(p_scb)); + log::verbose("avdtp_cb.ad.rt_tbl[{}][{}].scb_hdl = {}", + avdt_ccb_to_idx(p_ccb), p_tbl->tcid, avdt_scb_to_hdl(p_scb)); } /* if we're acceptor, we're done; just sit back and listen */ @@ -548,12 +548,12 @@ void avdt_ad_open_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, if (lcid != 0) { /* if connect req ok, store tcid in lcid table */ avdtp_cb.ad.lcid_tbl[lcid] = avdt_ad_tc_tbl_to_idx(p_tbl); - LOG_VERBOSE("avdtp_cb.ad.lcid_tbl[%d] = %d", (lcid), - avdt_ad_tc_tbl_to_idx(p_tbl)); + log::verbose("avdtp_cb.ad.lcid_tbl[{}] = {}", (lcid), + avdt_ad_tc_tbl_to_idx(p_tbl)); avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid; - LOG_VERBOSE("avdtp_cb.ad.rt_tbl[%d][%d].lcid = 0x%x", - avdt_ccb_to_idx(p_ccb), p_tbl->tcid, lcid); + log::verbose("avdtp_cb.ad.rt_tbl[{}][{}].lcid = 0x{:x}", + avdt_ccb_to_idx(p_ccb), p_tbl->tcid, lcid); } else { /* if connect req failed, call avdt_ad_tc_close_ind() */ avdt_ad_tc_close_ind(p_tbl); @@ -578,7 +578,7 @@ void avdt_ad_close_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb) { AvdtpTransportChannel* p_tbl; p_tbl = avdt_ad_tc_tbl_by_type(type, p_ccb, p_scb); - LOG_VERBOSE("avdt_ad_close_req state: %d", p_tbl->state); + log::verbose("avdt_ad_close_req state: {}", p_tbl->state); switch (p_tbl->state) { case AVDT_AD_ST_UNUSED: diff --git a/system/stack/avdt/avdt_api.cc b/system/stack/avdt/avdt_api.cc index 60518de3c7b35aae1aa781a7696447229fc1f48a..923641ebac3afa4c3def4152c9ee00c09ead8e67 100644 --- a/system/stack/avdt/avdt_api.cc +++ b/system/stack/avdt/avdt_api.cc @@ -25,6 +25,7 @@ #include "avdt_api.h" +#include #include #include "avdt_int.h" @@ -37,6 +38,8 @@ #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /* Control block for AVDTP */ AvdtpCb avdtp_cb; @@ -126,14 +129,13 @@ void AVDT_Deregister(void) { } void AVDT_AbortReq(uint8_t handle) { - LOG_WARN("%s: avdt_handle=%d", __func__, handle); + log::warn("avdt_handle={}", handle); AvdtpScb* p_scb = avdt_scb_by_hdl(handle); if (p_scb != NULL) { avdt_scb_event(p_scb, AVDT_SCB_API_ABORT_REQ_EVT, NULL); } else { - LOG_ERROR("%s Improper avdp_handle=%d, can not abort the stream", __func__, - handle); + log::error("Improper avdp_handle={}, can not abort the stream", handle); } } @@ -160,21 +162,23 @@ uint16_t AVDT_CreateStream(uint8_t peer_id, uint8_t* p_handle, if (((avdtp_stream_config.cfg.psc_mask & (~AVDT_PSC)) != 0) || (avdtp_stream_config.p_avdt_ctrl_cback == NULL)) { result = AVDT_BAD_PARAMS; - LOG_ERROR("Invalid AVDT stream endpoint parameters peer_id=%d scb_index=%d", - peer_id, avdtp_stream_config.scb_index); + log::error( + "Invalid AVDT stream endpoint parameters peer_id={} scb_index={}", + peer_id, avdtp_stream_config.scb_index); } /* Allocate scb; if no scbs, return failure */ else { p_scb = avdt_scb_alloc(peer_id, avdtp_stream_config); if (p_scb == NULL) { - LOG_ERROR("Unable to create AVDT stream endpoint peer_id=%d scb_index=%d", - peer_id, avdtp_stream_config.scb_index); + log::error( + "Unable to create AVDT stream endpoint peer_id={} scb_index={}", + peer_id, avdtp_stream_config.scb_index); result = AVDT_NO_RESOURCES; } else { *p_handle = avdt_scb_to_hdl(p_scb); - LOG_DEBUG("Created stream endpoint peer_id=%d handle=%hhu", peer_id, - *p_handle); + log::debug("Created stream endpoint peer_id={} handle={}", peer_id, + *p_handle); } } return static_cast(result); @@ -198,7 +202,7 @@ uint16_t AVDT_RemoveStream(uint8_t handle) { uint16_t result = AVDT_SUCCESS; AvdtpScb* p_scb; - LOG_VERBOSE("%s: avdt_handle=%d", __func__, handle); + log::verbose("avdt_handle={}", handle); /* look up scb */ p_scb = avdt_scb_by_hdl(handle); @@ -210,7 +214,7 @@ uint16_t AVDT_RemoveStream(uint8_t handle) { } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle); + log::error("result={} avdt_handle={}", result, handle); } return result; @@ -249,7 +253,7 @@ uint16_t AVDT_DiscoverReq(const RawAddress& bd_addr, uint8_t channel_index, uint16_t result = AVDT_SUCCESS; tAVDT_CCB_EVT evt; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* find channel control block for this bd addr; if none, allocate one */ p_ccb = avdt_ccb_by_bd(bd_addr); @@ -276,8 +280,8 @@ uint16_t AVDT_DiscoverReq(const RawAddress& bd_addr, uint8_t channel_index, } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d address=%s", __func__, result, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("result={} address={}", result, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } return result; } @@ -297,12 +301,12 @@ static uint16_t avdt_get_cap_req(const RawAddress& bd_addr, AvdtpCcb* p_ccb = NULL; uint16_t result = AVDT_SUCCESS; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* verify SEID */ if ((p_evt->single.seid < AVDT_SEID_MIN) || (p_evt->single.seid > AVDT_SEID_MAX)) { - LOG_ERROR("seid: %d", p_evt->single.seid); + log::error("seid: {}", p_evt->single.seid); result = AVDT_BAD_PARAMS; } /* find channel control block for this bd addr; if none, allocate one */ @@ -329,8 +333,8 @@ static uint16_t avdt_get_cap_req(const RawAddress& bd_addr, } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d address=%s", __func__, result, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("result={} address={}", result, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } return result; } @@ -365,7 +369,7 @@ uint16_t AVDT_GetCapReq(const RawAddress& bd_addr, uint8_t channel_index, tAVDT_CCB_API_GETCAP getcap; uint16_t result = AVDT_SUCCESS; - LOG_VERBOSE("%s", __func__); + log::verbose(""); getcap.single.seid = seid; if (get_all_cap) { @@ -378,8 +382,8 @@ uint16_t AVDT_GetCapReq(const RawAddress& bd_addr, uint8_t channel_index, result = avdt_get_cap_req(bd_addr, channel_index, &getcap); if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d address=%s", __func__, result, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("result={} address={}", result, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } return result; } @@ -400,8 +404,7 @@ uint16_t AVDT_DelayReport(uint8_t handle, uint8_t seid, uint16_t delay) { uint16_t result = AVDT_SUCCESS; tAVDT_SCB_EVT evt; - LOG_VERBOSE("%s: avdt_handle=%d seid=%d delay=%d", __func__, handle, seid, - delay); + log::verbose("avdt_handle={} seid={} delay={}", handle, seid, delay); /* map handle to scb */ p_scb = avdt_scb_by_hdl(handle); @@ -416,8 +419,7 @@ uint16_t AVDT_DelayReport(uint8_t handle, uint8_t seid, uint16_t delay) { } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d avdt_handle=%d seid=%d", __func__, result, handle, - seid); + log::error("result={} avdt_handle={} seid={}", result, handle, seid); } return result; } @@ -444,8 +446,8 @@ uint16_t AVDT_OpenReq(uint8_t handle, const RawAddress& bd_addr, uint16_t result = AVDT_SUCCESS; tAVDT_SCB_EVT evt; - LOG_VERBOSE("%s: address=%s avdt_handle=%d seid=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle, seid); + log::verbose("address={} avdt_handle={} seid={}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle, seid); /* verify SEID */ if ((seid < AVDT_SEID_MIN) || (seid > AVDT_SEID_MAX)) { @@ -472,8 +474,7 @@ uint16_t AVDT_OpenReq(uint8_t handle, const RawAddress& bd_addr, /* send event to scb */ if (result == AVDT_SUCCESS) { - LOG_VERBOSE("%s: codec: %s", __func__, - A2DP_CodecInfoString(p_cfg->codec_info).c_str()); + log::verbose("codec: {}", A2DP_CodecInfoString(p_cfg->codec_info).c_str()); evt.msg.config_cmd.hdr.seid = seid; evt.msg.config_cmd.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb); @@ -481,8 +482,8 @@ uint16_t AVDT_OpenReq(uint8_t handle, const RawAddress& bd_addr, evt.msg.config_cmd.p_cfg = p_cfg; avdt_scb_event(p_scb, AVDT_SCB_API_SETCONFIG_REQ_EVT, &evt); } else { - LOG_ERROR("%s: result=%d address=%s avdt_handle=%d", __func__, result, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle); + log::error("result={} address={} avdt_handle={}", result, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), handle); } return result; @@ -507,8 +508,8 @@ uint16_t AVDT_ConfigRsp(uint8_t handle, uint8_t label, uint8_t error_code, uint16_t result = AVDT_SUCCESS; uint8_t event_code; - LOG_VERBOSE("%s: avdt_handle=%d label=%d error_code=0x%x category=%d", - __func__, handle, label, error_code, category); + log::verbose("avdt_handle={} label={} error_code=0x{:x} category={}", handle, + label, error_code, category); /* map handle to scb */ p_scb = avdt_scb_by_hdl(handle); @@ -535,7 +536,7 @@ uint16_t AVDT_ConfigRsp(uint8_t handle, uint8_t label, uint8_t error_code, } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle); + log::error("result={} avdt_handle={}", result, handle); } return result; } @@ -561,7 +562,7 @@ uint16_t AVDT_StartReq(uint8_t* p_handles, uint8_t num_handles) { uint16_t result = AVDT_SUCCESS; int i; - LOG_VERBOSE("%s: num_handles=%d", __func__, num_handles); + log::verbose("num_handles={}", num_handles); if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) { result = AVDT_BAD_PARAMS; @@ -589,11 +590,10 @@ uint16_t AVDT_StartReq(uint8_t* p_handles, uint8_t num_handles) { if (result != AVDT_SUCCESS) { if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) { - LOG_ERROR("%s: result=%d num_handles=%d invalid", __func__, result, - num_handles); + log::error("result={} num_handles={} invalid", result, num_handles); } else { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, - (i < num_handles ? p_handles[i] : p_handles[num_handles - 1])); + log::error("result={} avdt_handle={}", result, + (i < num_handles ? p_handles[i] : p_handles[num_handles - 1])); } } return result; @@ -620,7 +620,7 @@ uint16_t AVDT_SuspendReq(uint8_t* p_handles, uint8_t num_handles) { uint16_t result = AVDT_SUCCESS; int i; - LOG_VERBOSE("%s: num_handles=%d", __func__, num_handles); + log::verbose("num_handles={}", num_handles); if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) { result = AVDT_BAD_PARAMS; @@ -648,11 +648,10 @@ uint16_t AVDT_SuspendReq(uint8_t* p_handles, uint8_t num_handles) { if (result != AVDT_SUCCESS) { if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) { - LOG_ERROR("%s: result=%d num_handles=%d invalid", __func__, result, - num_handles); + log::error("result={} num_handles={} invalid", result, num_handles); } else { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, - (i < num_handles ? p_handles[i] : p_handles[num_handles - 1])); + log::error("result={} avdt_handle={}", result, + (i < num_handles ? p_handles[i] : p_handles[num_handles - 1])); } } return result; @@ -676,7 +675,7 @@ uint16_t AVDT_CloseReq(uint8_t handle) { AvdtpScb* p_scb; uint16_t result = AVDT_SUCCESS; - LOG_VERBOSE("%s: avdt_handle=%d", __func__, handle); + log::verbose("avdt_handle={}", handle); /* map handle to scb */ p_scb = avdt_scb_by_hdl(handle); @@ -689,7 +688,7 @@ uint16_t AVDT_CloseReq(uint8_t handle) { } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle); + log::error("result={} avdt_handle={}", result, handle); } return result; } @@ -716,7 +715,7 @@ uint16_t AVDT_ReconfigReq(uint8_t handle, AvdtpSepConfig* p_cfg) { uint16_t result = AVDT_SUCCESS; tAVDT_SCB_EVT evt; - LOG_VERBOSE("%s: avdt_handle=%d", __func__, handle); + log::verbose("avdt_handle={}", handle); /* map handle to scb */ p_scb = avdt_scb_by_hdl(handle); @@ -732,7 +731,7 @@ uint16_t AVDT_ReconfigReq(uint8_t handle, AvdtpSepConfig* p_cfg) { } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle); + log::error("result={} avdt_handle={}", result, handle); } return result; } @@ -756,7 +755,7 @@ uint16_t AVDT_SecurityReq(uint8_t handle, uint8_t* p_data, uint16_t len) { uint16_t result = AVDT_SUCCESS; tAVDT_SCB_EVT evt; - LOG_VERBOSE("%s: avdt_handle=%d len=%d", __func__, handle, len); + log::verbose("avdt_handle={} len={}", handle, len); /* map handle to scb */ p_scb = avdt_scb_by_hdl(handle); @@ -771,7 +770,7 @@ uint16_t AVDT_SecurityReq(uint8_t handle, uint8_t* p_data, uint16_t len) { } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle); + log::error("result={} avdt_handle={}", result, handle); } return result; } @@ -796,8 +795,8 @@ uint16_t AVDT_SecurityRsp(uint8_t handle, uint8_t label, uint8_t error_code, uint16_t result = AVDT_SUCCESS; tAVDT_SCB_EVT evt; - LOG_VERBOSE("%s: avdt_handle=%d label=%d error_code=0x%x len=%d", __func__, - handle, label, error_code, len); + log::verbose("avdt_handle={} label={} error_code=0x{:x} len={}", handle, + label, error_code, len); /* map handle to scb */ p_scb = avdt_scb_by_hdl(handle); @@ -814,7 +813,7 @@ uint16_t AVDT_SecurityRsp(uint8_t handle, uint8_t label, uint8_t error_code, } if (result != AVDT_SUCCESS) { - LOG_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle); + log::error("result={} avdt_handle={}", result, handle); } return result; } @@ -862,8 +861,8 @@ uint16_t AVDT_WriteReqOpt(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp, tAVDT_SCB_EVT evt; uint16_t result = AVDT_SUCCESS; - LOG_VERBOSE("%s: avdt_handle=%d timestamp=%d m_pt=0x%x opt=0x%x", __func__, - handle, time_stamp, m_pt, opt); + log::verbose("avdt_handle={} timestamp={} m_pt=0x{:x} opt=0x{:x}", handle, + time_stamp, m_pt, opt); /* map handle to scb */ p_scb = avdt_scb_by_hdl(handle); @@ -877,7 +876,7 @@ uint16_t AVDT_WriteReqOpt(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp, avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt); } - LOG_VERBOSE("%s: result=%d avdt_handle=%d", __func__, result, handle); + log::verbose("result={} avdt_handle={}", result, handle); return result; } @@ -902,8 +901,8 @@ uint16_t AVDT_ConnectReq(const RawAddress& bd_addr, uint8_t channel_index, uint16_t result = AVDT_SUCCESS; tAVDT_CCB_EVT evt; - LOG_WARN("%s: address=%s channel_index=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), channel_index); + log::warn("address={} channel_index={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + channel_index); /* find channel control block for this bd addr; if none, allocate one */ p_ccb = avdt_ccb_by_bd(bd_addr); @@ -914,7 +913,7 @@ uint16_t AVDT_ConnectReq(const RawAddress& bd_addr, uint8_t channel_index, result = AVDT_NO_RESOURCES; } } else if (!p_ccb->ll_opened) { - LOG_WARN("AVDT_ConnectReq: CCB LL is in the middle of opening"); + log::warn("AVDT_ConnectReq: CCB LL is in the middle of opening"); /* ccb was already allocated for the incoming signalling. */ result = AVDT_BUSY; @@ -926,8 +925,7 @@ uint16_t AVDT_ConnectReq(const RawAddress& bd_addr, uint8_t channel_index, avdt_ccb_event(p_ccb, AVDT_CCB_API_CONNECT_REQ_EVT, &evt); } - LOG_WARN("%s: address=%s result=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), result); + log::warn("address={} result={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), result); return result; } @@ -953,12 +951,12 @@ uint16_t AVDT_DisconnectReq(const RawAddress& bd_addr, /* find channel control block for this bd addr; if none, error */ p_ccb = avdt_ccb_by_bd(bd_addr); if (p_ccb == NULL) { - LOG_ERROR("Unable to find AVDT stream endpoint peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Unable to find AVDT stream endpoint peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); result = AVDT_BAD_PARAMS; } else { - LOG_DEBUG("Sending disconnect request to ccb peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Sending disconnect request to ccb peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); evt.disconnect.p_cback = p_cback; avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCONNECT_REQ_EVT, &evt); } diff --git a/system/stack/avdt/avdt_ccb.cc b/system/stack/avdt/avdt_ccb.cc index 2083b3888f9a15b171d0b73ae10cf073b689d6a8..ca4d1c0cc3792a6b3bb1841aa84e982742aedac2 100644 --- a/system/stack/avdt/avdt_ccb.cc +++ b/system/stack/avdt/avdt_ccb.cc @@ -23,7 +23,7 @@ * ******************************************************************************/ -#include // VLOG +#include #include #include "avdt_int.h" @@ -31,6 +31,8 @@ #include "osi/include/osi.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * state machine constants and types ****************************************************************************/ @@ -367,9 +369,9 @@ void avdt_ccb_event(AvdtpCcb* p_ccb, uint8_t event, tAVDT_CCB_EVT* p_data) { int i; #if (AVDT_DEBUG == TRUE) - LOG_VERBOSE("%s: CCB ccb=%d event=%s state=%s p_ccb=%p", __func__, - avdt_ccb_to_idx(p_ccb), avdt_ccb_evt_str[event], - avdt_ccb_st_str[p_ccb->state], p_ccb); + log::verbose("CCB ccb={} event={} state={} p_ccb={}", avdt_ccb_to_idx(p_ccb), + avdt_ccb_evt_str[event], avdt_ccb_st_str[p_ccb->state], + fmt::ptr(p_ccb)); #endif /* look up the state table for the current state */ @@ -383,8 +385,8 @@ void avdt_ccb_event(AvdtpCcb* p_ccb, uint8_t event, tAVDT_CCB_EVT* p_data) { /* execute action functions */ for (i = 0; i < AVDT_CCB_ACTIONS; i++) { action = state_table[event][i]; - LOG_VERBOSE("%s: event=%s state=%s action=%d", __func__, - avdt_ccb_evt_str[event], avdt_ccb_st_str[p_ccb->state], action); + log::verbose("event={} state={} action={}", avdt_ccb_evt_str[event], + avdt_ccb_st_str[p_ccb->state], action); if (action != AVDT_CCB_IGNORE) { (*avdtp_cb.p_ccb_act[action])(p_ccb, p_data); } else { @@ -418,7 +420,7 @@ AvdtpCcb* avdt_ccb_by_bd(const RawAddress& bd_addr) { /* if no ccb found */ p_ccb = NULL; - VLOG(1) << "No ccb for addr " << bd_addr; + log::verbose("No ccb for addr {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); } return p_ccb; } @@ -439,13 +441,13 @@ AvdtpCcb* avdt_ccb_alloc(const RawAddress& bd_addr) { for (int i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) { if (!p_ccb->allocated) { p_ccb->Allocate(bd_addr); - LOG_VERBOSE("%s: allocated (index %d) for peer %s", __func__, i, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("allocated (index {}) for peer {}", i, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return p_ccb; } } - LOG_WARN("%s: out of AvdtpCcb entries", __func__); + log::warn("out of AvdtpCcb entries"); return nullptr; } @@ -453,19 +455,20 @@ AvdtpCcb* avdt_ccb_alloc_by_channel_index(const RawAddress& bd_addr, uint8_t channel_index) { // Allocate the entry for the specified channel index if (channel_index >= AVDT_NUM_LINKS) { - LOG_ERROR("%s: peer %s invalid channel index %d (max %d)", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), channel_index, AVDT_NUM_LINKS); + log::error("peer {} invalid channel index {} (max {})", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), channel_index, + AVDT_NUM_LINKS); return nullptr; } AvdtpCcb* p_ccb = &avdtp_cb.ccb[channel_index]; if (p_ccb->allocated) { - LOG_ERROR("%s: peer %s channel index %d already allocated", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), channel_index); + log::error("peer {} channel index {} already allocated", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), channel_index); return nullptr; } p_ccb->Allocate(bd_addr); - LOG_VERBOSE("%s: allocated (index %d) peer=%s p_ccb=%p", __func__, - channel_index, ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr), p_ccb); + log::verbose("allocated (index {}) peer={} p_ccb={}", channel_index, + ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr), fmt::ptr(p_ccb)); return p_ccb; } @@ -491,9 +494,9 @@ void AvdtpCcb::Allocate(const RawAddress& peer_address) { * ******************************************************************************/ void avdt_ccb_dealloc(AvdtpCcb* p_ccb, UNUSED_ATTR tAVDT_CCB_EVT* p_data) { - LOG_VERBOSE("%s: deallocated (index %d) peer=%s p_ccb=%p", __func__, - avdt_ccb_to_idx(p_ccb), - ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr), p_ccb); + log::verbose("deallocated (index {}) peer={} p_ccb={}", + avdt_ccb_to_idx(p_ccb), + ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr), fmt::ptr(p_ccb)); p_ccb->ResetCcb(); } @@ -530,7 +533,7 @@ AvdtpCcb* avdt_ccb_by_idx(uint8_t idx) { p_ccb = &avdtp_cb.ccb[idx]; } else { p_ccb = NULL; - LOG_WARN("No ccb for idx %d", idx); + log::warn("No ccb for idx {}", idx); } return p_ccb; } diff --git a/system/stack/avdt/avdt_ccb_act.cc b/system/stack/avdt/avdt_ccb_act.cc index e1cbeba33399993128da84827d316959aa5be834..85f25eb6b675ec63ac359162e8bf9260daa46906 100644 --- a/system/stack/avdt/avdt_ccb_act.cc +++ b/system/stack/avdt/avdt_ccb_act.cc @@ -23,19 +23,20 @@ * ******************************************************************************/ +#include #include #include "avdt_api.h" #include "avdt_int.h" #include "avdtc_api.h" -#include "bt_target.h" -#include "btm_api.h" +#include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" -#include "stack/btm/btm_sec.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" +using namespace bluetooth; + /******************************************************************************* * * Function avdt_ccb_clear_ccb @@ -145,7 +146,7 @@ void avdt_ccb_hdl_discover_cmd(AvdtpCcb* p_ccb, tAVDT_CCB_EVT* p_data) { tAVDT_SEP_INFO sep_info[AVDT_NUM_SEPS]; AvdtpScb* p_scb = &(p_ccb->scb[0]); - LOG_VERBOSE("%s: p_ccb index=%d", __func__, avdt_ccb_to_idx(p_ccb)); + log::verbose("p_ccb index={}", avdt_ccb_to_idx(p_ccb)); p_data->msg.discover_rsp.p_sep_info = sep_info; p_data->msg.discover_rsp.num_seps = 0; @@ -493,7 +494,7 @@ void avdt_ccb_snd_start_cmd(AvdtpCcb* p_ccb, tAVDT_CCB_EVT* p_data) { tAVDT_MSG avdt_msg; uint8_t seid_list[AVDT_NUM_SEPS]; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* make copy of our seid list */ memcpy(seid_list, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps); @@ -503,7 +504,7 @@ void avdt_ccb_snd_start_cmd(AvdtpCcb* p_ccb, tAVDT_CCB_EVT* p_data) { avdt_scb_verify(p_ccb, AVDT_VERIFY_OPEN, p_data->msg.multi.seid_list, p_data->msg.multi.num_seps, &avdt_msg.hdr.err_code); if (avdt_msg.hdr.err_param == 0) { - LOG_VERBOSE("%s: AVDT_SIG_START", __func__); + log::verbose("AVDT_SIG_START"); /* set peer seid list in messsage */ avdt_scb_peer_seid_list(&p_data->msg.multi); @@ -515,7 +516,7 @@ void avdt_ccb_snd_start_cmd(AvdtpCcb* p_ccb, tAVDT_CCB_EVT* p_data) { for (i = 0; i < p_data->msg.multi.num_seps; i++) { p_scb = avdt_scb_by_hdl(seid_list[i]); if (p_scb != NULL) { - LOG_VERBOSE("%s: AVDT_SCB_MSG_START_REJ_EVT: i=%d", __func__, i); + log::verbose("AVDT_SCB_MSG_START_REJ_EVT: i={}", i); tAVDT_SCB_EVT avdt_scb_evt; avdt_scb_evt.msg.hdr = avdt_msg.hdr; avdt_scb_event(p_scb, AVDT_SCB_MSG_START_REJ_EVT, &avdt_scb_evt); @@ -960,8 +961,8 @@ void avdt_ccb_set_conn(AvdtpCcb* p_ccb, tAVDT_CCB_EVT* p_data) { ******************************************************************************/ void avdt_ccb_set_disconn(AvdtpCcb* p_ccb, tAVDT_CCB_EVT* p_data) { /* - LOG_VERBOSE("avdt_ccb_set_disconn:conn:x%x, api:x%x", - p_ccb->p_conn_cback, p_data->disconnect.p_cback); + log::verbose("avdt_ccb_set_disconn:conn:x{:x}, api:x{:x}", + p_ccb->p_conn_cback, p_data->disconnect.p_cback); */ /* save callback */ if (p_data->disconnect.p_cback) @@ -1000,8 +1001,7 @@ void avdt_ccb_ll_closed(AvdtpCcb* p_ccb, UNUSED_ATTR tAVDT_CCB_EVT* p_data) { tAVDT_CTRL_CBACK* p_cback; tAVDT_CTRL avdt_ctrl; - LOG_VERBOSE("%s peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr)); + log::verbose("peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr)); /* clear any pending commands */ avdt_ccb_clear_cmds(p_ccb, NULL); @@ -1036,9 +1036,9 @@ void avdt_ccb_ll_closed(AvdtpCcb* p_ccb, UNUSED_ATTR tAVDT_CCB_EVT* p_data) { void avdt_ccb_ll_opened(AvdtpCcb* p_ccb, tAVDT_CCB_EVT* p_data) { tAVDT_CTRL avdt_ctrl; - LOG_VERBOSE("%s peer %s BtaAvScbIndex=%d p_ccb=%p", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr), - p_ccb->BtaAvScbIndex(), p_ccb); + log::verbose("peer {} BtaAvScbIndex={} p_ccb={}", + ADDRESS_TO_LOGGABLE_CSTR(p_ccb->peer_addr), + p_ccb->BtaAvScbIndex(), fmt::ptr(p_ccb)); p_ccb->ll_opened = true; if (!p_ccb->p_conn_cback) p_ccb->p_conn_cback = avdtp_cb.p_conn_cback; diff --git a/system/stack/avdt/avdt_l2c.cc b/system/stack/avdt/avdt_l2c.cc index 1d50681109067dc0e105f7d15b953f68baeb9a09..06aadbf3cac88c3b1c40b2f27ad92130ed87671a 100644 --- a/system/stack/avdt/avdt_l2c.cc +++ b/system/stack/avdt/avdt_l2c.cc @@ -22,10 +22,10 @@ * ******************************************************************************/ +#include + #include "avdt_int.h" -#include "bt_target.h" #include "bta/include/bta_av_api.h" -#include "btm_api.h" #include "device/include/interop.h" #include "l2c_api.h" #include "l2cdefs.h" @@ -35,7 +35,7 @@ #include "stack/include/bt_hdr.h" #include "types/raw_address.h" -#include +using namespace bluetooth; /* callback function declarations */ void avdt_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, @@ -111,7 +111,7 @@ static void avdt_sec_check_complete_orig(const RawAddress* bd_addr, AvdtpCcb* p_ccb = NULL; AvdtpTransportChannel* p_tbl; - LOG_VERBOSE("avdt_sec_check_complete_orig res: %d", res); + log::verbose("avdt_sec_check_complete_orig res: {}", res); if (bd_addr) p_ccb = avdt_ccb_by_bd(*bd_addr); p_tbl = avdt_ad_tc_tbl_by_st(AVDT_CHAN_SIG, p_ccb, AVDT_AD_ST_SEC_INT); if (p_tbl == NULL) return; @@ -238,7 +238,7 @@ void avdt_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result) { AvdtpTransportChannel* p_tbl; AvdtpCcb* p_ccb; - LOG_VERBOSE("avdt_l2c_connect_cfm_cback lcid: %d, result: %d", lcid, result); + log::verbose("avdt_l2c_connect_cfm_cback lcid: {}, result: {}", lcid, result); /* look up info for this channel */ p_tbl = avdt_ad_tc_tbl_by_lcid(lcid); if (p_tbl != NULL) { @@ -278,7 +278,7 @@ void avdt_l2c_connect_cfm_cback(uint16_t lcid, uint16_t result) { /* failure; notify adaption that channel closed */ if (result != L2CAP_CONN_OK) { - LOG(ERROR) << __func__ << ": invoked with non OK status"; + log::error("invoked with non OK status"); } } } @@ -300,7 +300,7 @@ void avdt_l2c_config_cfm_cback(uint16_t lcid, uint16_t initiator, AvdtpTransportChannel* p_tbl; - LOG_VERBOSE("%s: lcid: %d", __func__, lcid); + log::verbose("lcid: {}", lcid); /* look up info for this channel */ p_tbl = avdt_ad_tc_tbl_by_lcid(lcid); @@ -327,7 +327,7 @@ void avdt_l2c_config_cfm_cback(uint16_t lcid, uint16_t initiator, void avdt_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) { AvdtpTransportChannel* p_tbl; - LOG_VERBOSE("%s: lcid: %d", __func__, lcid); + log::verbose("lcid: {}", lcid); /* look up info for this channel */ p_tbl = avdt_ad_tc_tbl_by_lcid(lcid); @@ -338,7 +338,7 @@ void avdt_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) { } else { p_tbl->peer_mtu = L2CAP_DEFAULT_MTU; } - LOG_VERBOSE("%s: peer_mtu: %d, lcid: %d", __func__, p_tbl->peer_mtu, lcid); + log::verbose("peer_mtu: {}, lcid: {}", p_tbl->peer_mtu, lcid); } } @@ -355,8 +355,8 @@ void avdt_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) { void avdt_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed) { AvdtpTransportChannel* p_tbl; - LOG_VERBOSE("avdt_l2c_disconnect_ind_cback lcid: %d, ack_needed: %d", lcid, - ack_needed); + log::verbose("avdt_l2c_disconnect_ind_cback lcid: {}, ack_needed: {}", lcid, + ack_needed); /* look up info for this channel */ p_tbl = avdt_ad_tc_tbl_by_lcid(lcid); if (p_tbl != NULL) { @@ -368,7 +368,7 @@ void avdt_l2c_disconnect(uint16_t lcid) { L2CA_DisconnectReq(lcid); AvdtpTransportChannel* p_tbl; - LOG_VERBOSE("avdt_l2c_disconnect_cfm_cback lcid: %d", lcid); + log::verbose("avdt_l2c_disconnect_cfm_cback lcid: {}", lcid); /* look up info for this channel */ p_tbl = avdt_ad_tc_tbl_by_lcid(lcid); if (p_tbl != NULL) { diff --git a/system/stack/avdt/avdt_msg.cc b/system/stack/avdt/avdt_msg.cc index 29e566234b459aeb975abe40bad0e08e77821d7c..b99819295aba0d230430c67753cd13ab9082a25d 100644 --- a/system/stack/avdt/avdt_msg.cc +++ b/system/stack/avdt/avdt_msg.cc @@ -28,6 +28,7 @@ #define LOG_TAG "bluetooth" +#include #include #include "avdt_api.h" @@ -40,6 +41,8 @@ #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /***************************************************************************** * constants ****************************************************************************/ @@ -531,7 +534,7 @@ static uint8_t avdt_msg_prs_cfg(AvdtpSepConfig* p_cfg, uint8_t* p, uint16_t len, uint8_t protect_offset = 0; if (!p_cfg) { - LOG_ERROR("not expecting this cfg"); + log::error("not expecting this cfg"); return AVDT_ERR_BAD_STATE; } @@ -568,8 +571,8 @@ static uint8_t avdt_msg_prs_cfg(AvdtpSepConfig* p_cfg, uint8_t* p, uint16_t len, { /* Skip unknown categories. */ p += elem_len; - LOG_VERBOSE("skipping unknown service category=%d len: %d", elem, - elem_len); + log::verbose("skipping unknown service category={} len: {}", elem, + elem_len); continue; } } @@ -582,8 +585,8 @@ static uint8_t avdt_msg_prs_cfg(AvdtpSepConfig* p_cfg, uint8_t* p, uint16_t len, /* add element to psc mask, but mask out codec or protect */ p_cfg->psc_mask |= (1 << elem); - LOG_VERBOSE("elem=%d elem_len: %d psc_mask=0x%x", elem, elem_len, - p_cfg->psc_mask); + log::verbose("elem={} elem_len: {} psc_mask=0x{:x}", elem, elem_len, + p_cfg->psc_mask); /* parse individual information elements with additional parameters */ switch (elem) { @@ -646,7 +649,7 @@ static uint8_t avdt_msg_prs_cfg(AvdtpSepConfig* p_cfg, uint8_t* p, uint16_t len, break; case AVDT_CAT_DELAY_RPT: - LOG_VERBOSE("%s: Remote device supports delay reporting", __func__); + log::verbose("Remote device supports delay reporting"); break; default: @@ -655,7 +658,8 @@ static uint8_t avdt_msg_prs_cfg(AvdtpSepConfig* p_cfg, uint8_t* p, uint16_t len, } /* switch */ } /* while ! err, !end*/ *p_elem = elem; - LOG_VERBOSE("err=0x%x, elem:0x%x psc_mask=0x%x", err, elem, p_cfg->psc_mask); + log::verbose("err=0x{:x}, elem:0x{:x} psc_mask=0x{:x}", err, elem, + p_cfg->psc_mask); return err; } @@ -789,8 +793,8 @@ static uint8_t avdt_msg_prs_reconfig_cmd(tAVDT_MSG* p_msg, uint8_t* p, /* verify no protocol service capabilities in parameters */ if (!err) { - LOG_VERBOSE("avdt_msg_prs_reconfig_cmd psc_mask=0x%x/0x%x", - p_msg->config_cmd.p_cfg->psc_mask, AVDT_MSG_PSC_MASK); + log::verbose("avdt_msg_prs_reconfig_cmd psc_mask=0x{:x}/0x{:x}", + p_msg->config_cmd.p_cfg->psc_mask, AVDT_MSG_PSC_MASK); if ((p_msg->config_cmd.p_cfg->psc_mask != 0) || (p_msg->config_cmd.p_cfg->num_codec == 0 && p_msg->config_cmd.p_cfg->num_protect == 0)) { @@ -1023,8 +1027,8 @@ static uint8_t avdt_msg_prs_delay_rpt(tAVDT_MSG* p_msg, uint8_t* p, /* verify len */ if (len != AVDT_LEN_DELAY_RPT) { - LOG_WARN("avdt_msg_prs_delay_rpt expected len: %u got: %u", - AVDT_LEN_DELAY_RPT, len); + log::warn("avdt_msg_prs_delay_rpt expected len: {} got: {}", + AVDT_LEN_DELAY_RPT, len); err = AVDT_ERR_LENGTH; } else { /* get seid */ @@ -1034,8 +1038,8 @@ static uint8_t avdt_msg_prs_delay_rpt(tAVDT_MSG* p_msg, uint8_t* p, err = AVDT_ERR_SEID; } else { BE_STREAM_TO_UINT16(p_msg->delay_rpt_cmd.delay, p); - LOG_VERBOSE("avdt_msg_prs_delay_rpt delay: %u", - p_msg->delay_rpt_cmd.delay); + log::verbose("avdt_msg_prs_delay_rpt delay: {}", + p_msg->delay_rpt_cmd.delay); } } return err; @@ -1135,7 +1139,7 @@ bool avdt_msg_send(AvdtpCcb* p_ccb, BT_HDR* p_msg) { label = AVDT_LAYERSPEC_LABEL(p_ccb->p_curr_msg->layer_specific); msg = AVDT_LAYERSPEC_MSG(p_ccb->p_curr_msg->layer_specific); sig = (uint8_t)p_ccb->p_curr_msg->event; - LOG_VERBOSE("avdt_msg_send label:%d, msg:%d, sig:%d", label, msg, sig); + log::verbose("avdt_msg_send label:{}, msg:{}, sig:{}", label, msg, sig); /* keep track of how much of msg we've sent */ curr_msg_len -= p_buf->len; @@ -1218,13 +1222,13 @@ BT_HDR* avdt_msg_asmbl(AvdtpCcb* p_ccb, BT_HDR* p_buf) { /* quick sanity check on length */ if (p_buf->len < avdt_msg_pkt_type_len[pkt_type]) { osi_free(p_buf); - LOG_WARN("Bad length during reassembly"); + log::warn("Bad length during reassembly"); p_ret = NULL; } /* single packet */ else if (pkt_type == AVDT_PKT_TYPE_SINGLE) { /* if reassembly in progress drop message and process new single */ - if (p_ccb->p_rx_msg != NULL) LOG_WARN("Got single during reassembly"); + if (p_ccb->p_rx_msg != NULL) log::warn("Got single during reassembly"); osi_free_and_reset((void**)&p_ccb->p_rx_msg); @@ -1233,7 +1237,7 @@ BT_HDR* avdt_msg_asmbl(AvdtpCcb* p_ccb, BT_HDR* p_buf) { /* start packet */ else if (pkt_type == AVDT_PKT_TYPE_START) { /* if reassembly in progress drop message and process new single */ - if (p_ccb->p_rx_msg != NULL) LOG_WARN("Got start during reassembly"); + if (p_ccb->p_rx_msg != NULL) log::warn("Got start during reassembly"); osi_free_and_reset((void**)&p_ccb->p_rx_msg); @@ -1272,7 +1276,7 @@ BT_HDR* avdt_msg_asmbl(AvdtpCcb* p_ccb, BT_HDR* p_buf) { /* if no reassembly in progress drop message */ if (p_ccb->p_rx_msg == NULL) { osi_free(p_buf); - LOG_WARN("Pkt type=%d out of order", pkt_type); + log::warn("Pkt type={} out of order", pkt_type); p_ret = NULL; } else { /* get size of buffer holding assembled message */ @@ -1289,7 +1293,7 @@ BT_HDR* avdt_msg_asmbl(AvdtpCcb* p_ccb, BT_HDR* p_buf) { /* verify length */ if (((size_t) p_ccb->p_rx_msg->offset + (size_t) p_buf->len) > buf_len) { /* won't fit; free everything */ - LOG_WARN("%s: Fragmented message too big!", __func__); + log::warn("Fragmented message too big!"); osi_free_and_reset((void**)&p_ccb->p_rx_msg); osi_free(p_buf); p_ret = NULL; @@ -1448,7 +1452,7 @@ void avdt_msg_send_rej(AvdtpCcb* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) { /* add the error code */ AVDT_MSG_BLD_ERR(p, p_params->hdr.err_code); } - LOG_VERBOSE("avdt_msg_send_rej"); + log::verbose("avdt_msg_send_rej"); /* calculate length */ p_buf->len = (uint16_t)(p - p_start); @@ -1494,7 +1498,7 @@ void avdt_msg_send_grej(AvdtpCcb* p_ccb, uint8_t sig_id, tAVDT_MSG* p_params) { p_buf->event = sig_id; AVDT_BLD_LAYERSPEC(p_buf->layer_specific, AVDT_MSG_TYPE_GRJ, p_params->hdr.label); - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* queue message and trigger ccb to send it */ fixed_queue_enqueue(p_ccb->rsp_q, p_buf); @@ -1542,14 +1546,14 @@ void avdt_msg_ind(AvdtpCcb* p_ccb, BT_HDR* p_buf) { /* parse the message header */ AVDT_MSG_PRS_HDR(p, label, pkt_type, msg_type); - LOG_VERBOSE("msg_type=%d, sig=%d", msg_type, sig); + log::verbose("msg_type={}, sig={}", msg_type, sig); /* set up label and ccb_idx in message hdr */ msg.hdr.label = label; msg.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb); /* verify msg type */ if (msg_type == AVDT_MSG_TYPE_GRJ) { - LOG_WARN("Dropping msg msg_type=%d", msg_type); + log::warn("Dropping msg msg_type={}", msg_type); ok = false; } /* check for general reject */ @@ -1568,7 +1572,7 @@ void avdt_msg_ind(AvdtpCcb* p_ccb, BT_HDR* p_buf) { AVDT_MSG_PRS_SIG(p, sig); msg.hdr.sig_id = sig; if ((sig == 0) || (sig > AVDT_SIG_MAX)) { - LOG_WARN("Dropping msg sig=%d msg_type:%d", sig, msg_type); + log::warn("Dropping msg sig={} msg_type:{}", sig, msg_type); ok = false; /* send a general reject */ @@ -1619,7 +1623,7 @@ void avdt_msg_ind(AvdtpCcb* p_ccb, BT_HDR* p_buf) { /* if parsing failed */ if (err != 0) { - LOG_WARN("Parsing failed sig=%d err=0x%x", sig, err); + log::warn("Parsing failed sig={} err=0x{:x}", sig, err); /* if its a rsp or rej, drop it; if its a cmd, send a rej; ** note special case for abort; never send abort reject @@ -1651,7 +1655,7 @@ void avdt_msg_ind(AvdtpCcb* p_ccb, BT_HDR* p_buf) { handle_rsp = true; } else { ok = false; - LOG_WARN("Cmd not found for rsp sig=%d label=%d", sig, label); + log::warn("Cmd not found for rsp sig={} label={}", sig, label); } } } diff --git a/system/stack/avdt/avdt_scb.cc b/system/stack/avdt/avdt_scb.cc index bd0b682295c59666f8ba7c038157d9a954227fe6..c15d13aac6d6e36b5a2579d9828781c875695ea6 100644 --- a/system/stack/avdt/avdt_scb.cc +++ b/system/stack/avdt/avdt_scb.cc @@ -23,14 +23,18 @@ * ******************************************************************************/ +#include #include #include "avdt_api.h" #include "avdt_int.h" #include "avdtc_api.h" +#include "check.h" #include "internal_include/bt_target.h" #include "osi/include/osi.h" +using namespace bluetooth; + /***************************************************************************** * state machine constants and types ****************************************************************************/ @@ -758,10 +762,10 @@ void avdt_scb_event(AvdtpScb* p_scb, uint8_t event, tAVDT_SCB_EVT* p_data) { uint8_t action; #if (AVDT_DEBUG == TRUE) - LOG_VERBOSE("%s: SCB hdl=%d event=%d/%s state=%s p_avdt_scb=%p scb_index=%d", - __func__, avdt_scb_to_hdl(p_scb), event, avdt_scb_evt_str[event], - avdt_scb_st_str[p_scb->state], p_scb, - p_scb->stream_config.scb_index); + log::verbose("SCB hdl={} event={}/{} state={} p_avdt_scb={} scb_index={}", + avdt_scb_to_hdl(p_scb), event, avdt_scb_evt_str[event], + avdt_scb_st_str[p_scb->state], fmt::ptr(p_scb), + p_scb->stream_config.scb_index); #endif /* Check that we only send AVDT_SCB_API_WRITE_REQ_EVT to the active stream @@ -788,7 +792,7 @@ void avdt_scb_event(AvdtpScb* p_scb, uint8_t event, tAVDT_SCB_EVT* p_data) { avdtp_cb.ccb[ccb_index].scb[scb_index].curr_stream = true; } else if (num_st_streams > 1 && !p_scb->curr_stream && event == AVDT_SCB_API_WRITE_REQ_EVT) { - LOG_ERROR("%s: ignore AVDT_SCB_API_WRITE_REQ_EVT", __func__); + log::error("ignore AVDT_SCB_API_WRITE_REQ_EVT"); avdt_scb_free_pkt(p_scb, p_data); return; } @@ -854,13 +858,13 @@ AvdtpScb* avdt_scb_alloc(uint8_t peer_id, for (int i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) { if (!p_scb->allocated) { p_scb->Allocate(&avdtp_cb.ccb[peer_id], avdtp_stream_config); - LOG_VERBOSE("%s: allocated (handle=%d, psc_mask:0x%x)", __func__, - p_scb->ScbHandle(), avdtp_stream_config.cfg.psc_mask); + log::verbose("allocated (handle={}, psc_mask:0x{:x})", p_scb->ScbHandle(), + avdtp_stream_config.cfg.psc_mask); return p_scb; } } - LOG_WARN("%s: out of AvdtScb entries for peer_id %d", __func__, peer_id); + log::warn("out of AvdtScb entries for peer_id {}", peer_id); return nullptr; } @@ -885,7 +889,7 @@ void AvdtpScb::Allocate(AvdtpCcb* p_avdtp_ccb, * ******************************************************************************/ void avdt_scb_dealloc(AvdtpScb* p_scb, UNUSED_ATTR tAVDT_SCB_EVT* p_data) { - LOG_VERBOSE("%s: hdl=%d", __func__, avdt_scb_to_hdl(p_scb)); + log::verbose("hdl={}", avdt_scb_to_hdl(p_scb)); p_scb->Recycle(); } @@ -915,7 +919,7 @@ uint8_t avdt_scb_to_hdl(AvdtpScb* p_scb) { return p_scb->ScbHandle(); } AvdtpScb* avdt_scb_by_hdl(uint8_t hdl) { // Verify the index if ((hdl < 1) || (hdl > AVDT_NUM_LINKS * AVDT_NUM_SEPS)) { - LOG_WARN("%s: SCB handle %d out of range", __func__, hdl); + log::warn("SCB handle {} out of range", hdl); return nullptr; } @@ -926,12 +930,12 @@ AvdtpScb* avdt_scb_by_hdl(uint8_t hdl) { AvdtpScb* p_scb = &avdtp_cb.ccb[i].scb[j]; // Verify the whether the scb is allocated if (!p_scb->allocated) { - LOG_WARN("%s: SCB handle %d not allocated", __func__, hdl); + log::warn("SCB handle {} not allocated", hdl); return nullptr; } - LOG_VERBOSE("%s: SCB for handle %d found: p_scb=%p scb_index=%d", __func__, - hdl, p_scb, p_scb->stream_config.scb_index); + log::verbose("SCB for handle {} found: p_scb={} scb_index={}", hdl, + fmt::ptr(p_scb), p_scb->stream_config.scb_index); return p_scb; } @@ -947,7 +951,7 @@ AvdtpScb* avdt_scb_by_hdl(uint8_t hdl) { ******************************************************************************/ uint8_t avdt_scb_verify(AvdtpCcb* p_ccb, uint8_t state, uint8_t* p_seid, uint16_t num_seid, uint8_t* p_err_code) { - LOG_VERBOSE("avdt_scb_verify state %d", state); + log::verbose("avdt_scb_verify state {}", state); /* set nonsupported command mask */ /* translate public state into private state */ uint8_t nsc_mask = 0; diff --git a/system/stack/avdt/avdt_scb_act.cc b/system/stack/avdt/avdt_scb_act.cc index 9920f016d42f279cf6e26f14f2f12c15bf71ed02..58b651a2b277aabd4119ca274d9a8d94e19d9cd6 100644 --- a/system/stack/avdt/avdt_scb_act.cc +++ b/system/stack/avdt/avdt_scb_act.cc @@ -25,6 +25,7 @@ #define LOG_TAG "bluetooth" +#include #include #include "a2dp_codec_api.h" @@ -38,6 +39,8 @@ #include "stack/include/bt_types.h" #include "types/raw_address.h" +using namespace bluetooth; + /* This table is used to lookup the callback event that matches a particular * state machine API request event. Note that state machine API request * events are at the beginning of the event list starting at zero, thus @@ -274,7 +277,7 @@ void avdt_scb_hdl_pkt_no_frag(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { /* do sanity check */ if (pad_len >= (len - offset)) { - LOG_WARN("Got bad media packet"); + log::warn("Got bad media packet"); osi_free_and_reset((void**)&p_data->p_pkt); } /* adjust offset and length and send it up */ @@ -294,8 +297,7 @@ void avdt_scb_hdl_pkt_no_frag(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { } return; length_error: - LOG_WARN("%s: hdl packet length %d too short: must be at least %d", __func__, - len, offset); + log::warn("hdl packet length {} too short: must be at least {}", len, offset); osi_free_and_reset((void**)&p_data->p_pkt); } @@ -317,13 +319,13 @@ uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) { AVDT_REPORT_TYPE pt; tAVDT_REPORT_DATA report; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (p_scb->stream_config.p_report_cback) { /* parse report packet header */ min_len += 8; if (min_len > len) { - LOG_WARN("%s: hdl packet length %d too short: must be at least %d", - __func__, len, min_len); + log::warn("hdl packet length {} too short: must be at least {}", len, + min_len); goto avdt_scb_hdl_report_exit; } AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc); @@ -335,8 +337,8 @@ uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) { case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */ min_len += 20; if (min_len > len) { - LOG_WARN("%s: hdl packet length %d too short: must be at least %d", - __func__, len, min_len); + log::warn("hdl packet length {} too short: must be at least {}", len, + min_len); goto avdt_scb_hdl_report_exit; } BE_STREAM_TO_UINT32(report.sr.ntp_sec, p); @@ -349,8 +351,8 @@ uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) { case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */ min_len += 20; if (min_len > len) { - LOG_WARN("%s: hdl packet length %d too short: must be at least %d", - __func__, len, min_len); + log::warn("hdl packet length {} too short: must be at least {}", len, + min_len); goto avdt_scb_hdl_report_exit; } report.rr.frag_lost = *p; @@ -366,8 +368,8 @@ uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) { uint8_t sdes_type; min_len += 1; if (min_len > len) { - LOG_WARN("%s: hdl packet length %d too short: must be at least %d", - __func__, len, min_len); + log::warn("hdl packet length {} too short: must be at least {}", len, + min_len); goto avdt_scb_hdl_report_exit; } BE_STREAM_TO_UINT8(sdes_type, p); @@ -375,8 +377,8 @@ uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) { uint8_t name_length; min_len += 1; if (min_len > len) { - LOG_WARN("%s: hdl packet length %d too short: must be at least %d", - __func__, len, min_len); + log::warn("hdl packet length {} too short: must be at least {}", + len, min_len); goto avdt_scb_hdl_report_exit; } BE_STREAM_TO_UINT8(name_length, p); @@ -388,18 +390,18 @@ uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) { } } else { if (min_len + 1 > len) { - LOG_WARN("%s: hdl packet length %d too short: must be at least %d", - __func__, len, min_len); + log::warn("hdl packet length {} too short: must be at least {}", + len, min_len); goto avdt_scb_hdl_report_exit; } - LOG_WARN("%s: SDES SSRC=0x%08x sc=%d %d len=%d", __func__, ssrc, o_cc, - sdes_type, *p); + log::warn("SDES SSRC=0x{:08x} sc={} {} len={}", ssrc, o_cc, sdes_type, + *p); result = AVDT_BUSY; } break; default: - LOG_ERROR("Bad Report pkt - packet type: %d", pt); + log::error("Bad Report pkt - packet type: {}", pt); result = AVDT_BAD_PARAMS; } @@ -442,7 +444,7 @@ void avdt_scb_hdl_pkt(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { * ******************************************************************************/ void avdt_scb_drop_pkt(UNUSED_ATTR AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { - LOG_ERROR("%s dropped incoming media packet", __func__); + log::error("dropped incoming media packet"); osi_free_and_reset((void**)&p_data->p_pkt); } @@ -560,15 +562,15 @@ void avdt_scb_hdl_security_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { * ******************************************************************************/ void avdt_scb_hdl_setconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { - LOG_VERBOSE("%s: p_scb->in_use=%d p_avdt_scb=%p scb_index=%d", __func__, - p_scb->in_use, p_scb, p_scb->stream_config.scb_index); + log::verbose("p_scb->in_use={} p_avdt_scb={} scb_index={}", p_scb->in_use, + fmt::ptr(p_scb), p_scb->stream_config.scb_index); if (!p_scb->in_use) { - LOG_VERBOSE( - "%s: codec: %s", __func__, + log::verbose( + "codec: {}", A2DP_CodecInfoString(p_scb->stream_config.cfg.codec_info).c_str()); - LOG_VERBOSE( - "%s: codec: %s", __func__, + log::verbose( + "codec: {}", A2DP_CodecInfoString(p_data->msg.config_cmd.p_cfg->codec_info).c_str()); AvdtpSepConfig* p_cfg = p_data->msg.config_cmd.p_cfg; if (A2DP_GetCodecType(p_scb->stream_config.cfg.codec_info) == @@ -576,12 +578,11 @@ void avdt_scb_hdl_setconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { /* copy info to scb */ AvdtpCcb* p_ccb = avdt_ccb_by_idx(p_data->msg.config_cmd.hdr.ccb_idx); if (p_scb->p_ccb != p_ccb) { - LOG_ERROR( - "%s: mismatch in AVDTP SCB/CCB state: (p_scb->p_ccb=%p != " - "p_ccb=%p): " - "p_scb=%p scb_handle=%d ccb_idx=%d", - __func__, p_scb->p_ccb, p_ccb, p_scb, p_scb->ScbHandle(), - p_data->msg.config_cmd.hdr.ccb_idx); + log::error( + "mismatch in AVDTP SCB/CCB state: (p_scb->p_ccb={} != p_ccb={}): " + "p_scb={} scb_handle={} ccb_idx={}", + fmt::ptr(p_scb->p_ccb), fmt::ptr(p_ccb), fmt::ptr(p_scb), + p_scb->ScbHandle(), p_data->msg.config_cmd.hdr.ccb_idx); avdt_scb_rej_not_in_use(p_scb, p_data); return; } @@ -604,7 +605,7 @@ void avdt_scb_hdl_setconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { p_data->msg.hdr.sig_id, &p_data->msg); } } else { - LOG_VERBOSE("%s: calling avdt_scb_rej_in_use()", __func__); + log::verbose("calling avdt_scb_rej_in_use()"); avdt_scb_rej_in_use(p_scb, p_data); } } @@ -932,9 +933,9 @@ void avdt_scb_hdl_tc_open(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { (p_scb->role == AVDT_OPEN_INT) ? AVDT_OPEN_CFM_EVT : AVDT_OPEN_IND_EVT; p_data->open.hdr.err_code = 0; - LOG_VERBOSE("%s: psc_mask: cfg: 0x%x, req:0x%x, cur: 0x%x", __func__, - p_scb->stream_config.cfg.psc_mask, p_scb->req_cfg.psc_mask, - p_scb->curr_cfg.psc_mask); + log::verbose("psc_mask: cfg: 0x{:x}, req:0x{:x}, cur: 0x{:x}", + p_scb->stream_config.cfg.psc_mask, p_scb->req_cfg.psc_mask, + p_scb->curr_cfg.psc_mask); if (p_scb->curr_cfg.psc_mask & AVDT_PSC_REPORT) { /* open the reporting channel, if both devices support it */ role = (p_scb->role == AVDT_OPEN_INT) ? AVDT_INT : AVDT_ACP; @@ -994,7 +995,7 @@ void avdt_scb_hdl_write_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { /* free packet we're holding, if any; to be replaced with new */ if (p_scb->p_pkt != NULL) { /* this shouldn't be happening */ - LOG_WARN("Dropped media packet; congested"); + log::warn("Dropped media packet; congested"); } osi_free_and_reset((void**)&p_scb->p_pkt); @@ -1042,7 +1043,7 @@ void avdt_scb_snd_abort_req(AvdtpScb* p_scb, UNUSED_ATTR tAVDT_SCB_EVT* p_data) { tAVDT_EVT_HDR hdr; - LOG_VERBOSE("%s: p_scb->p_ccb=%p", __func__, p_scb->p_ccb); + log::verbose("p_scb->p_ccb={}", fmt::ptr(p_scb->p_ccb)); if (p_scb->p_ccb != NULL) { p_scb->role = AVDT_CLOSE_INT; @@ -1206,10 +1207,10 @@ void avdt_scb_snd_open_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { * ******************************************************************************/ void avdt_scb_snd_reconfig_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { - LOG_VERBOSE("%s: p_scb->peer_seid=%d p_data->msg.hdr.seid=%d", __func__, - p_scb->peer_seid, p_data->msg.hdr.seid); - LOG_VERBOSE( - "%s: codec: %s", __func__, + log::verbose("p_scb->peer_seid={} p_data->msg.hdr.seid={}", p_scb->peer_seid, + p_data->msg.hdr.seid); + log::verbose( + "codec: {}", A2DP_CodecInfoString(p_data->msg.config_cmd.p_cfg->codec_info).c_str()); p_scb->req_cfg = *p_data->msg.config_cmd.p_cfg; @@ -1312,19 +1313,19 @@ void avdt_scb_snd_setconfig_rej(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { * ******************************************************************************/ void avdt_scb_snd_setconfig_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { - LOG_VERBOSE( - "%s: codec: %s", __func__, + log::verbose( + "codec: {}", A2DP_CodecInfoString(p_data->msg.config_cmd.p_cfg->codec_info).c_str()); /* copy API parameters to scb, set scb as in use */ AvdtpCcb* p_ccb = avdt_ccb_by_idx(p_data->msg.config_cmd.hdr.ccb_idx); if (p_scb->p_ccb != p_ccb) { - LOG_ERROR( - "%s: mismatch in AVDTP SCB/CCB state: (p_scb->p_ccb=%p != p_ccb=%p): " - "p_scb=%p scb_handle=%d ccb_idx=%d", - __func__, p_scb->p_ccb, p_ccb, p_scb, p_scb->ScbHandle(), - p_data->msg.config_cmd.hdr.ccb_idx); + log::error( + "mismatch in AVDTP SCB/CCB state: (p_scb->p_ccb={} != p_ccb={}): " + "p_scb={} scb_handle={} ccb_idx={}", + fmt::ptr(p_scb->p_ccb), fmt::ptr(p_ccb), fmt::ptr(p_scb), + p_scb->ScbHandle(), p_data->msg.config_cmd.hdr.ccb_idx); avdt_scb_rej_not_in_use(p_scb, p_data); return; } @@ -1494,7 +1495,7 @@ void avdt_scb_free_pkt(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) { osi_free_and_reset((void**)&p_data->apiwrite.p_buf); - LOG_WARN("Dropped media packet"); + log::warn("Dropped media packet"); /* we need to call callback to keep data flow going */ (*p_scb->stream_config.p_avdt_ctrl_cback)( @@ -1533,7 +1534,7 @@ void avdt_scb_clr_pkt(AvdtpScb* p_scb, UNUSED_ATTR tAVDT_SCB_EVT* p_data) { if (p_scb->p_pkt != NULL) { osi_free_and_reset((void**)&p_scb->p_pkt); - LOG_VERBOSE("Dropped stored media packet"); + log::verbose("Dropped stored media packet"); /* we need to call callback to keep data flow going */ (*p_scb->stream_config.p_avdt_ctrl_cback)( diff --git a/system/stack/avrc/avrc_api.cc b/system/stack/avrc/avrc_api.cc index 1f71c31b3f395e40910856cac0d196d86d2a5cb5..e1a7643c1ddd01cc4c4bafe160ef6c48277c4fae 100644 --- a/system/stack/avrc/avrc_api.cc +++ b/system/stack/avrc/avrc_api.cc @@ -24,11 +24,12 @@ #include "avrc_api.h" #include -#include +#include #include #include "avrc_int.h" #include "btif/include/btif_config.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -38,8 +39,11 @@ #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" +#include "storage/config_keys.h" #include "types/raw_address.h" +using namespace bluetooth; + /***************************************************************************** * Global data ****************************************************************************/ @@ -133,7 +137,7 @@ static void avrc_ctrl_cback(uint8_t handle, uint8_t event, uint16_t result, * *****************************************************************************/ void avrc_flush_cmd_q(uint8_t handle) { - LOG_VERBOSE("AVRC: Flushing command queue for handle=0x%02x", handle); + log::verbose("AVRC: Flushing command queue for handle=0x{:02x}", handle); avrc_cb.ccb_int[handle].flags &= ~AVRC_CB_FLAGS_RSP_PENDING; alarm_cancel(avrc_cb.ccb_int[handle].tle); @@ -153,8 +157,8 @@ void avrc_flush_cmd_q(uint8_t handle) { void avrc_process_timeout(void* data) { tAVRC_PARAM* param = (tAVRC_PARAM*)data; - LOG_VERBOSE("AVRC: command timeout (handle=0x%02x, label=0x%02x)", - param->handle, param->label); + log::verbose("AVRC: command timeout (handle=0x{:02x}, label=0x{:02x})", + param->handle, param->label); /* Notify app */ if (avrc_cb.ccb[param->handle].ctrl_cback) { @@ -188,8 +192,9 @@ void avrc_send_next_vendor_cmd(uint8_t handle) { next_label = (p_next_cmd->layer_specific) >> 8; /* extract label */ p_next_cmd->layer_specific &= 0xFF; /* AVCT_DATA_CTRL or AVCT_DATA_BROWSE */ - LOG_VERBOSE("AVRC: Dequeuing command 0x%p (handle=0x%02x, label=0x%02x)", - p_next_cmd, handle, next_label); + log::verbose( + "AVRC: Dequeuing command 0x{} (handle=0x{:02x}, label=0x{:02x})", + fmt::ptr(p_next_cmd), handle, next_label); /* Send the message */ if ((AVCT_MsgReq(handle, next_label, AVCT_CMD, p_next_cmd)) == @@ -222,8 +227,8 @@ void avrc_start_cmd_timer(uint8_t handle, uint8_t label, uint8_t msg_mask) { param->label = label; param->msg_mask = msg_mask; - LOG_VERBOSE("AVRC: starting timer (handle=0x%02x, label=0x%02x)", handle, - label); + log::verbose("AVRC: starting timer (handle=0x{:02x}, label=0x{:02x})", handle, + label); alarm_set_on_mloop(avrc_cb.ccb_int[handle].tle, AVRC_CMD_TOUT_MS, avrc_process_timeout, param); @@ -282,7 +287,7 @@ static void avrc_prep_end_frag(uint8_t handle) { uint8_t *p_data, *p_orig_data; uint8_t rsp_type; - LOG_VERBOSE("%s", __func__); + log::verbose(""); p_fcb = &avrc_cb.fcb[handle]; /* The response type of the end fragment should be the same as the the PDU of @@ -329,8 +334,7 @@ static uint16_t avrc_send_continue_frag(uint8_t handle, uint8_t label) { p_fcb = &avrc_cb.fcb[handle]; p_pkt = p_fcb->p_fmsg; - LOG_VERBOSE("%s handle = %u label = %u len = %d", __func__, handle, label, - p_pkt->len); + log::verbose("handle = {} label = {} len = {}", handle, label, p_pkt->len); if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) { int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset); p_pkt_old = p_fcb->p_fmsg; @@ -386,7 +390,7 @@ static BT_HDR* avrc_proc_vendor_command(uint8_t handle, uint8_t label, if (pkt_type != AVRC_PKT_SINGLE) { /* reject - commands can only be in single packets at AVRCP level */ - LOG_ERROR("commands must be in single packet pdu:0x%x", *p_data); + log::error("commands must be in single packet pdu:0x{:x}", *p_data); /* use the current GKI buffer to send the reject */ status = AVRC_STS_BAD_CMD; } @@ -420,9 +424,9 @@ static BT_HDR* avrc_proc_vendor_command(uint8_t handle, uint8_t label, } else { /* the pdu id does not match - reject the command using the current * GKI buffer */ - LOG_ERROR( - "%s continue pdu: 0x%x does not match the current pdu: 0x%x", - __func__, *(p_data + 4), p_fcb->frag_pdu); + log::error( + "continue pdu: 0x{:x} does not match the current pdu: 0x{:x}", + *(p_data + 4), p_fcb->frag_pdu); status = AVRC_STS_BAD_PARAM; abort_frag = true; } @@ -489,7 +493,7 @@ static uint8_t avrc_proc_far_msg(uint8_t handle, uint8_t label, uint8_t cr, p_data += AVRC_VENDOR_HDR_SIZE; pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK; - LOG_VERBOSE("pkt_type %d", pkt_type); + log::verbose("pkt_type {}", pkt_type); p_rcb = &avrc_cb.rcb[handle]; /* check if the message needs to be re-assembled */ @@ -532,9 +536,9 @@ static uint8_t avrc_proc_far_msg(uint8_t handle, uint8_t label, uint8_t cr, } else if (p_rcb->p_rmsg == NULL) { /* Received a CONTINUE/END, but no corresponding START (or previous fragmented response was dropped) */ - LOG_VERBOSE( - "Received a CONTINUE/END without no corresponding START" - " (or previous fragmented response was dropped)"); + log::verbose( + "Received a CONTINUE/END without no corresponding START (or previous " + "fragmented response was dropped)"); drop_code = 5; osi_free(p_pkt); *pp_pkt = NULL; @@ -550,7 +554,7 @@ static uint8_t avrc_proc_far_msg(uint8_t handle, uint8_t label, uint8_t cr, p_pkt->len -= (AVRC_VENDOR_HDR_SIZE + AVRC_MIN_META_HDR_SIZE); /* verify length */ if ((p_rcb->p_rmsg->offset + p_pkt->len) > buf_len) { - LOG_WARN("Fragmented message too big! - report the partial message"); + log::warn("Fragmented message too big! - report the partial message"); p_pkt->len = buf_len - p_rcb->p_rmsg->offset; pkt_type = AVRC_PKT_END; buf_overflow = true; @@ -575,8 +579,8 @@ static uint8_t avrc_proc_far_msg(uint8_t handle, uint8_t label, uint8_t cr, *p_data++ = AVRC_PKT_SINGLE; UINT16_TO_BE_STREAM(p_data, (p_msg->vendor_len - AVRC_MIN_META_HDR_SIZE)); - LOG_VERBOSE("end frag:%d, total len:%d, offset:%d", p_pkt->len, - p_pkt_new->len, p_pkt_new->offset); + log::verbose("end frag:{}, total len:{}, offset:{}", p_pkt->len, + p_pkt_new->len, p_pkt_new->offset); } else { p_rcb->p_rmsg->offset += p_pkt->len; p_rcb->p_rmsg->len += p_pkt->len; @@ -653,8 +657,8 @@ static void avrc_msg_cback(uint8_t handle, uint8_t label, uint8_t cr, if (cr == AVCT_CMD && (p_pkt->layer_specific & AVCT_DATA_CTRL && p_pkt->len > AVRC_PACKET_LEN)) { - LOG_WARN("%s: Command length %d too long: must be at most %d", __func__, - p_pkt->len, AVRC_PACKET_LEN); + log::warn("Command length {} too long: must be at most {}", p_pkt->len, + AVRC_PACKET_LEN); osi_free(p_pkt); return; } @@ -667,7 +671,7 @@ static void avrc_msg_cback(uint8_t handle, uint8_t label, uint8_t cr, return; } else if (cr == AVCT_RSP) { /* Received response. Stop command timeout timer */ - LOG_VERBOSE("AVRC: stopping timer (handle=0x%02x)", handle); + log::verbose("AVRC: stopping timer (handle=0x{:02x})", handle); alarm_cancel(avrc_cb.ccb_int[handle].tle); } @@ -682,14 +686,14 @@ static void avrc_msg_cback(uint8_t handle, uint8_t label, uint8_t cr, msg.browse.p_browse_pkt = p_pkt; } else { if (p_pkt->len < AVRC_AVC_HDR_SIZE) { - LOG_WARN("%s: message length %d too short: must be at least %d", __func__, - p_pkt->len, AVRC_AVC_HDR_SIZE); + log::warn("message length {} too short: must be at least {}", p_pkt->len, + AVRC_AVC_HDR_SIZE); osi_free(p_pkt); return; } msg.hdr.ctype = p_data[0] & AVRC_CTYPE_MASK; - LOG_VERBOSE("%s handle:%d, ctype:%d, offset:%d, len: %d", __func__, handle, - msg.hdr.ctype, p_pkt->offset, p_pkt->len); + log::verbose("handle:{}, ctype:{}, offset:{}, len: {}", handle, + msg.hdr.ctype, p_pkt->offset, p_pkt->len); msg.hdr.subunit_type = (p_data[1] & AVRC_SUBTYPE_MASK) >> AVRC_SUBTYPE_SHIFT; msg.hdr.subunit_id = p_data[1] & AVRC_SUBID_MASK; @@ -721,8 +725,8 @@ static void avrc_msg_cback(uint8_t handle, uint8_t label, uint8_t cr, } else { /* parse response */ if (p_pkt->len < AVRC_OP_UNIT_INFO_RSP_LEN) { - LOG_WARN("%s: message length %d too short: must be at least %d", - __func__, p_pkt->len, AVRC_OP_UNIT_INFO_RSP_LEN); + log::warn("message length {} too short: must be at least {}", + p_pkt->len, AVRC_OP_UNIT_INFO_RSP_LEN); drop = true; p_drop_msg = "UNIT_INFO_RSP too short"; break; @@ -757,8 +761,8 @@ static void avrc_msg_cback(uint8_t handle, uint8_t label, uint8_t cr, } else { /* parse response */ if (p_pkt->len < AVRC_OP_SUB_UNIT_INFO_RSP_LEN) { - LOG_WARN("%s: message length %d too short: must be at least %d", - __func__, p_pkt->len, AVRC_OP_SUB_UNIT_INFO_RSP_LEN); + log::warn("message length {} too short: must be at least {}", + p_pkt->len, AVRC_OP_SUB_UNIT_INFO_RSP_LEN); drop = true; p_drop_msg = "SUB_UNIT_INFO_RSP too short"; break; @@ -903,8 +907,8 @@ static void avrc_msg_cback(uint8_t handle, uint8_t label, uint8_t cr, msg.hdr.opcode = opcode; avrc_cb.ccb[handle].msg_cback.Run(handle, label, opcode, &msg); } else { - LOG_WARN("%s %s msg handle:%d, control:%d, cr:%d, opcode:x%x", __func__, - p_drop_msg, handle, avrc_cb.ccb[handle].control, cr, opcode); + log::warn("{} msg handle:{}, control:{}, cr:{}, opcode:x{:x}", p_drop_msg, + handle, avrc_cb.ccb[handle].control, cr, opcode); } if (opcode == AVRC_OP_BROWSE && msg.browse.p_browse_pkt == NULL) { @@ -1088,8 +1092,8 @@ uint16_t AVRC_Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb, avrc_cb.ccb_int[*p_handle].tle = alarm_new("avrcp.commandTimer"); avrc_cb.ccb_int[*p_handle].cmd_q = fixed_queue_new(SIZE_MAX); } - LOG_VERBOSE("%s role: %d, control:%d status:%d, handle:%d", __func__, cc.role, - cc.control, status, *p_handle); + log::verbose("role: {}, control:{} status:{}, handle:{}", cc.role, cc.control, + status, *p_handle); return status; } @@ -1113,7 +1117,7 @@ uint16_t AVRC_Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb, * *****************************************************************************/ uint16_t AVRC_Close(uint8_t handle) { - LOG_VERBOSE("%s handle:%d", __func__, handle); + log::verbose("handle:{}", handle); avrc_flush_cmd_q(handle); return AVCT_RemoveConn(handle); } @@ -1184,8 +1188,8 @@ uint16_t AVRC_MsgReq(uint8_t handle, uint8_t label, uint8_t ctype, if (!p_pkt) return AVRC_BAD_PARAM; - LOG_VERBOSE("%s handle = %u label = %u ctype = %u len = %d", __func__, handle, - label, ctype, p_pkt->len); + log::verbose("handle = {} label = {} ctype = {} len = {}", handle, label, + ctype, p_pkt->len); /* Handle for AVRCP fragment */ if (!GET_SYSPROP(A2dp, src_sink_coexist, false)) is_new_avrcp = @@ -1236,8 +1240,8 @@ uint16_t AVRC_MsgReq(uint8_t handle, uint8_t label, uint8_t ctype, peer_mtu = AVCT_GetPeerMtu(handle); } if (p_pkt->len > (peer_mtu - AVCT_HDR_LEN_SINGLE)) { - LOG_ERROR("%s bigger than peer mtu (p_pkt->len(%d) > peer_mtu(%d-%d))", - __func__, p_pkt->len, peer_mtu, AVCT_HDR_LEN_SINGLE); + log::error("bigger than peer mtu (p_pkt->len({}) > peer_mtu({}-{}))", + p_pkt->len, peer_mtu, AVCT_HDR_LEN_SINGLE); osi_free(p_pkt); return AVRC_MSG_TOO_BIG; } @@ -1247,7 +1251,7 @@ uint16_t AVRC_MsgReq(uint8_t handle, uint8_t label, uint8_t ctype, p_fcb = &avrc_cb.fcb[handle]; if (p_fcb == NULL) { - LOG_ERROR("%s p_fcb is NULL", __func__); + log::error("p_fcb is NULL"); osi_free(p_pkt); return AVRC_NOT_OPEN; } @@ -1289,11 +1293,11 @@ uint16_t AVRC_MsgReq(uint8_t handle, uint8_t label, uint8_t ctype, /* prepare the left over for as an end fragment */ avrc_prep_end_frag(handle); - LOG_VERBOSE("%s p_pkt len:%d/%d, next len:%d", __func__, p_pkt->len, - len, p_fcb->p_fmsg->len); + log::verbose("p_pkt len:{}/{}, next len:{}", p_pkt->len, len, + p_fcb->p_fmsg->len); } else { /* TODO: Is this "else" block valid? Remove it? */ - LOG_ERROR("%s no buffers for fragmentation", __func__); + log::error("no buffers for fragmentation"); osi_free(p_pkt); return AVRC_NO_RESOURCES; } @@ -1307,8 +1311,9 @@ uint16_t AVRC_MsgReq(uint8_t handle, uint8_t label, uint8_t ctype, * command * is received (exception is continuation request command * must sent that to get additional response frags) */ - LOG_VERBOSE("AVRC: Enqueuing command 0x%p (handle=0x%02x, label=0x%02x)", - p_pkt, handle, label); + log::verbose( + "AVRC: Enqueuing command 0x{} (handle=0x{:02x}, label=0x{:02x})", + fmt::ptr(p_pkt), handle, label); /* label in BT_HDR (will need this later when the command is dequeued) */ p_pkt->layer_specific = (label << 8) | (p_pkt->layer_specific & 0xFF); @@ -1432,24 +1437,24 @@ void AVRC_SaveControllerVersion(const RawAddress& bdaddr, uint16_t old_version = 0; size_t version_value_size = sizeof(old_version); if (btif_config_get_bin(bdaddr.ToString(), - AVRCP_CONTROLLER_VERSION_CONFIG_KEY, + BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION, (uint8_t*)&old_version, &version_value_size) && new_version == old_version) { - LOG_INFO("AVRC controller version same as cached config"); + log::info("AVRC controller version same as cached config"); } else if (btif_config_set_bin( - bdaddr.ToString(), AVRCP_CONTROLLER_VERSION_CONFIG_KEY, + bdaddr.ToString(), BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION, (const uint8_t*)&new_version, sizeof(new_version))) { - LOG_INFO("store AVRC controller version %x for %s into config.", - new_version, ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); + log::info("store AVRC controller version {:x} for {} into config.", + new_version, ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); } else { - LOG_WARN("Failed to store AVRC controller version for %s", - ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); + log::warn("Failed to store AVRC controller version for {}", + ADDRESS_TO_LOGGABLE_CSTR(bdaddr)); } } void AVRC_UpdateCcb(RawAddress* addr, uint32_t company_id) { for (uint8_t i = 0; i < AVCT_NUM_CONN; i++) { - LOG_INFO("%s: handle:%d, update cback:0x%0x", __func__, i, company_id); + log::info("handle:{}, update cback:0x{:0x}", i, company_id); if (avrc_cb.ccb[i].company_id == company_id) { avrc_cb.ccb[i].ctrl_cback.Run(i, AVRC_CLOSE_IND_EVT, 0, addr); } diff --git a/system/stack/avrc/avrc_bld_ct.cc b/system/stack/avrc/avrc_bld_ct.cc index 8ac25692cfb018acbb1d0ba4c16d8d678d23fff1..b619bf09abe0e20eececc6de988acf6c0f759509 100644 --- a/system/stack/avrc/avrc_bld_ct.cc +++ b/system/stack/avrc/avrc_bld_ct.cc @@ -18,6 +18,7 @@ #define LOG_TAG "avrcp" +#include #include #include "avrc_api.h" @@ -29,6 +30,8 @@ #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /***************************************************************************** * Global data ****************************************************************************/ @@ -46,7 +49,7 @@ static tAVRC_STS avrc_bld_next_cmd(tAVRC_NEXT_CMD* p_cmd, BT_HDR* p_pkt) { uint8_t *p_data, *p_start; - LOG_VERBOSE("avrc_bld_next_cmd"); + log::verbose("avrc_bld_next_cmd"); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; @@ -78,7 +81,7 @@ static tAVRC_STS avrc_bld_set_abs_volume_cmd(tAVRC_SET_VOLUME_CMD* p_cmd, BT_HDR* p_pkt) { uint8_t *p_data, *p_start; - LOG_VERBOSE("avrc_bld_set_abs_volume_cmd"); + log::verbose("avrc_bld_set_abs_volume_cmd"); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_start + 2; /* pdu + rsvd */ @@ -103,7 +106,7 @@ static tAVRC_STS avrc_bld_register_notifn(BT_HDR* p_pkt, uint8_t event_id, uint32_t event_param) { uint8_t *p_data, *p_start; - LOG_VERBOSE("avrc_bld_register_notifn"); + log::verbose("avrc_bld_register_notifn"); /* get the existing length, if any, and also the num attributes */ // Set the notify value p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; @@ -127,7 +130,7 @@ static tAVRC_STS avrc_bld_register_notifn(BT_HDR* p_pkt, uint8_t event_id, * ******************************************************************************/ static tAVRC_STS avrc_bld_get_capability_cmd(BT_HDR* p_pkt, uint8_t cap_id) { - LOG_VERBOSE("avrc_bld_get_capability_cmd"); + log::verbose("avrc_bld_get_capability_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ /* add fixed length 1 -*/ @@ -148,7 +151,7 @@ static tAVRC_STS avrc_bld_get_capability_cmd(BT_HDR* p_pkt, uint8_t cap_id) { * ******************************************************************************/ static tAVRC_STS avrc_bld_list_player_app_attr_cmd(BT_HDR* p_pkt) { - LOG_VERBOSE("avrc_bld_list_player_app_attr_cmd"); + log::verbose("avrc_bld_list_player_app_attr_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ /* add fixed length 1 -*/ @@ -169,7 +172,7 @@ static tAVRC_STS avrc_bld_list_player_app_attr_cmd(BT_HDR* p_pkt) { ******************************************************************************/ static tAVRC_STS avrc_bld_list_player_app_values_cmd(BT_HDR* p_pkt, uint8_t attrib_id) { - LOG_VERBOSE("avrc_bld_list_player_app_values_cmd"); + log::verbose("avrc_bld_list_player_app_values_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ /* add fixed length 1 -*/ @@ -192,7 +195,7 @@ static tAVRC_STS avrc_bld_list_player_app_values_cmd(BT_HDR* p_pkt, ******************************************************************************/ static tAVRC_STS avrc_bld_get_current_player_app_values_cmd( BT_HDR* p_pkt, uint8_t num_attrib_id, uint8_t* attrib_ids) { - LOG_VERBOSE("avrc_bld_get_current_player_app_values_cmd"); + log::verbose("avrc_bld_get_current_player_app_values_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ uint8_t param_len = @@ -220,7 +223,7 @@ static tAVRC_STS avrc_bld_get_current_player_app_values_cmd( ******************************************************************************/ static tAVRC_STS avrc_bld_set_current_player_app_values_cmd( BT_HDR* p_pkt, uint8_t num_attrib_id, tAVRC_APP_SETTING* p_val) { - LOG_VERBOSE("avrc_bld_set_current_player_app_values_cmd"); + log::verbose("avrc_bld_set_current_player_app_values_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ /* we have to store attrib- value pair @@ -251,7 +254,7 @@ static tAVRC_STS avrc_bld_set_current_player_app_values_cmd( ******************************************************************************/ static tAVRC_STS avrc_bld_get_player_app_setting_attr_text_cmd( BT_HDR* p_pkt, tAVRC_GET_APP_ATTR_TXT_CMD* p_cmd) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ @@ -280,7 +283,7 @@ static tAVRC_STS avrc_bld_get_player_app_setting_attr_text_cmd( ******************************************************************************/ static tAVRC_STS avrc_bld_get_player_app_setting_value_text_cmd( BT_HDR* p_pkt, tAVRC_GET_APP_VAL_TXT_CMD* p_cmd) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ @@ -309,7 +312,7 @@ static tAVRC_STS avrc_bld_get_player_app_setting_value_text_cmd( static tAVRC_STS avrc_bld_get_element_attr_cmd(BT_HDR* p_pkt, uint8_t num_attrib, uint32_t* attrib_ids) { - LOG_VERBOSE("avrc_bld_get_element_attr_cmd"); + log::verbose("avrc_bld_get_element_attr_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ /* we have to store attrib- value pair @@ -341,7 +344,7 @@ static tAVRC_STS avrc_bld_get_element_attr_cmd(BT_HDR* p_pkt, ******************************************************************************/ static tAVRC_STS avrc_bld_play_item_cmd(BT_HDR* p_pkt, uint8_t scope, uint8_t* uid, uint16_t uid_counter) { - LOG_VERBOSE("avrc_bld_get_element_attr_cmd"); + log::verbose("avrc_bld_get_element_attr_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ /* add fixed length 11 */ @@ -367,7 +370,7 @@ static tAVRC_STS avrc_bld_play_item_cmd(BT_HDR* p_pkt, uint8_t scope, * ******************************************************************************/ static tAVRC_STS avrc_bld_get_play_status_cmd(BT_HDR* p_pkt) { - LOG_VERBOSE("avrc_bld_list_player_app_attr_cmd"); + log::verbose("avrc_bld_list_player_app_attr_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ /* add fixed length 0 -*/ @@ -388,8 +391,8 @@ static tAVRC_STS avrc_bld_get_play_status_cmd(BT_HDR* p_pkt) { ******************************************************************************/ static tAVRC_STS avrc_bld_get_folder_items_cmd(BT_HDR* p_pkt, const tAVRC_GET_ITEMS_CMD* cmd) { - LOG_VERBOSE( - "avrc_bld_get_folder_items_cmd scope %d, start_item %d, end_item %d", + log::verbose( + "avrc_bld_get_folder_items_cmd scope {}, start_item {}, end_item {}", cmd->scope, cmd->start_item, cmd->end_item); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; /* This is where the PDU specific for AVRC starts @@ -420,7 +423,7 @@ static tAVRC_STS avrc_bld_get_folder_items_cmd(BT_HDR* p_pkt, ******************************************************************************/ static tAVRC_STS avrc_bld_change_folder_cmd(BT_HDR* p_pkt, const tAVRC_CHG_PATH_CMD* cmd) { - LOG_VERBOSE("avrc_bld_change_folder_cmd"); + log::verbose("avrc_bld_change_folder_cmd"); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; /* This is where the PDU specific for AVRC starts * AVRCP Spec 1.4 section 22.19 */ @@ -438,7 +441,7 @@ static tAVRC_STS avrc_bld_change_folder_cmd(BT_HDR* p_pkt, } static tAVRC_STS avrc_bld_get_item_attributes_cmd( BT_HDR* p_pkt, const tAVRC_GET_ATTRS_CMD* cmd) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; /* This is where the PDU specific for AVRC starts * AVRCP Spec 1.4 section 22.19 */ @@ -466,7 +469,7 @@ static tAVRC_STS avrc_bld_get_item_attributes_cmd( ******************************************************************************/ static tAVRC_STS avrc_bld_set_browsed_player_cmd( BT_HDR* p_pkt, const tAVRC_SET_BR_PLAYER_CMD* cmd) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; /* This is where the PDU specific for AVRC starts * AVRCP Spec 1.4 section 22.19 */ @@ -493,7 +496,7 @@ static tAVRC_STS avrc_bld_set_browsed_player_cmd( ******************************************************************************/ static tAVRC_STS avrc_bld_set_addressed_player_cmd( BT_HDR* p_pkt, const tAVRC_SET_ADDR_PLAYER_CMD* cmd) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* get the existing length, if any, and also the num attributes */ uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; uint8_t* p_data = p_start + 2; /* pdu + rsvd */ @@ -521,8 +524,8 @@ static tAVRC_STS avrc_bld_set_addressed_player_cmd( static BT_HDR* avrc_bld_init_cmd_buffer(tAVRC_COMMAND* p_cmd) { uint16_t chnl = AVCT_DATA_CTRL; uint8_t opcode = avrc_opcode_from_pdu(p_cmd->pdu); - LOG_VERBOSE("avrc_bld_init_cmd_buffer: pdu=%x, opcode=%x", p_cmd->pdu, - opcode); + log::verbose("avrc_bld_init_cmd_buffer: pdu={:x}, opcode={:x}", p_cmd->pdu, + opcode); uint16_t offset = 0; switch (opcode) { @@ -583,19 +586,19 @@ static BT_HDR* avrc_bld_init_cmd_buffer(tAVRC_COMMAND* p_cmd) { tAVRC_STS AVRC_BldCommand(tAVRC_COMMAND* p_cmd, BT_HDR** pp_pkt) { tAVRC_STS status = AVRC_STS_BAD_PARAM; bool alloc = false; - LOG_VERBOSE("AVRC_BldCommand: pdu=%x status=%x", p_cmd->cmd.pdu, - p_cmd->cmd.status); + log::verbose("AVRC_BldCommand: pdu={:x} status={:x}", p_cmd->cmd.pdu, + p_cmd->cmd.status); if (!p_cmd || !pp_pkt) { - LOG_VERBOSE( - "AVRC_BldCommand. Invalid parameters passed. p_cmd=%p, pp_pkt=%p", - p_cmd, pp_pkt); + log::verbose( + "AVRC_BldCommand. Invalid parameters passed. p_cmd={}, pp_pkt={}", + fmt::ptr(p_cmd), fmt::ptr(pp_pkt)); return AVRC_STS_BAD_PARAM; } if (*pp_pkt == NULL) { *pp_pkt = avrc_bld_init_cmd_buffer(p_cmd); if (*pp_pkt == NULL) { - LOG_VERBOSE("AVRC_BldCommand: Failed to initialize command buffer"); + log::verbose("AVRC_BldCommand: Failed to initialize command buffer"); return AVRC_STS_INTERNAL_ERR; } alloc = true; @@ -684,6 +687,6 @@ tAVRC_STS AVRC_BldCommand(tAVRC_COMMAND* p_cmd, BT_HDR** pp_pkt) { osi_free(p_pkt); *pp_pkt = NULL; } - LOG_VERBOSE("AVRC_BldCommand: returning %d", status); + log::verbose("AVRC_BldCommand: returning {}", status); return status; } diff --git a/system/stack/avrc/avrc_bld_tg.cc b/system/stack/avrc/avrc_bld_tg.cc index 6ce63765974656b4e8d36534232a923a9bbab3de..0fa9cf2424754b575cb5ccc0e99b30209e67344f 100644 --- a/system/stack/avrc/avrc_bld_tg.cc +++ b/system/stack/avrc/avrc_bld_tg.cc @@ -17,12 +17,13 @@ ******************************************************************************/ #define LOG_TAG "avrcp" -#include +#include #include #include "avrc_api.h" #include "avrc_defs.h" #include "avrc_int.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -31,6 +32,8 @@ #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /***************************************************************************** * Global data ****************************************************************************/ @@ -64,12 +67,12 @@ static tAVRC_STS avrc_bld_get_capability_rsp(tAVRC_GET_CAPS_RSP* p_rsp, tAVRC_STS status = AVRC_STS_NO_ERROR; if (!(AVRC_IS_VALID_CAP_ID(p_rsp->capability_id))) { - LOG_ERROR("%s bad parameter. p_rsp: %p", __func__, p_rsp); + log::error("bad parameter. p_rsp: {}", fmt::ptr(p_rsp)); status = AVRC_STS_BAD_PARAM; return status; } - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 2; /* pdu + rsvd */ @@ -128,7 +131,7 @@ static tAVRC_STS avrc_bld_list_app_settings_attr_rsp( uint16_t len = 0; uint8_t xx; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 2; /* pdu + rsvd */ @@ -174,7 +177,7 @@ static tAVRC_STS avrc_bld_list_app_settings_values_rsp( uint8_t xx; uint16_t len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 2; /* pdu + rsvd */ @@ -219,11 +222,11 @@ static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp( uint8_t xx; if (!p_rsp->p_vals) { - LOG_ERROR("%s NULL parameter", __func__); + log::error("NULL parameter"); return AVRC_STS_BAD_PARAM; } - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 2; /* pdu + rsvd */ @@ -267,7 +270,7 @@ static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp( static tAVRC_STS avrc_bld_set_app_setting_value_rsp( UNUSED_ATTR tAVRC_RSP* p_rsp, UNUSED_ATTR BT_HDR* p_pkt) { /* nothing to be added. */ - LOG_VERBOSE("%s", __func__); + log::verbose(""); return AVRC_STS_NO_ERROR; } @@ -291,7 +294,7 @@ static tAVRC_STS avrc_bld_app_setting_text_rsp( uint8_t num_added = 0; if (!p_rsp->p_attrs) { - LOG_ERROR("%s NULL parameter", __func__); + log::error("NULL parameter"); return AVRC_STS_BAD_PARAM; } /* get the existing length, if any, and also the num attributes */ @@ -316,14 +319,14 @@ static tAVRC_STS avrc_bld_app_setting_text_rsp( for (xx = 0; xx < p_rsp->num_attr; xx++) { if (len_left < (p_rsp->p_attrs[xx].str_len + 4)) { - LOG_ERROR("%s out of room (str_len:%d, left:%d)", __func__, - p_rsp->p_attrs[xx].str_len, len_left); + log::error("out of room (str_len:{}, left:{})", + p_rsp->p_attrs[xx].str_len, len_left); p_rsp->num_attr = num_added; sts = AVRC_STS_INTERNAL_ERR; break; } if (!p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str) { - LOG_ERROR("%s NULL attr text[%d]", __func__, xx); + log::error("NULL attr text[{}]", xx); continue; } UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id); @@ -354,7 +357,7 @@ static tAVRC_STS avrc_bld_app_setting_text_rsp( ******************************************************************************/ static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp( tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt); } @@ -371,7 +374,7 @@ static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp( ******************************************************************************/ static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp( tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt); } @@ -389,7 +392,7 @@ static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp( static tAVRC_STS avrc_bld_inform_charset_rsp(UNUSED_ATTR tAVRC_RSP* p_rsp, UNUSED_ATTR BT_HDR* p_pkt) { /* nothing to be added. */ - LOG_VERBOSE("%s", __func__); + log::verbose(""); return AVRC_STS_NO_ERROR; } @@ -407,7 +410,7 @@ static tAVRC_STS avrc_bld_inform_charset_rsp(UNUSED_ATTR tAVRC_RSP* p_rsp, static tAVRC_STS avrc_bld_inform_battery_status_rsp( UNUSED_ATTR tAVRC_RSP* p_rsp, UNUSED_ATTR BT_HDR* p_pkt) { /* nothing to be added. */ - LOG_VERBOSE("%s", __func__); + log::verbose(""); return AVRC_STS_NO_ERROR; } @@ -416,12 +419,12 @@ static void avrc_build_attribute_entries(int num_attrs, int remaining_buffer_capacity, uint8_t** pp_data, uint8_t* p_attribute_count) { - LOG_VERBOSE("%s num_attrs: %d, remaining_buffer_capacity: %d", __func__, - num_attrs, remaining_buffer_capacity); + log::verbose("num_attrs: {}, remaining_buffer_capacity: {}", num_attrs, + remaining_buffer_capacity); uint8_t* p_data = *pp_data; /* Fill in the Attribute ID, Character Set, Length and Values */ for (int index = 0; index < num_attrs; index++) { - LOG_VERBOSE("%s attr id[%d]: %d", __func__, index, p_attrs[index].attr_id); + log::verbose("attr id[{}]: {}", index, p_attrs[index].attr_id); CHECK(AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_attrs[index].attr_id)); if (!p_attrs[index].name.p_str) { p_attrs[index].name.str_len = 0; @@ -429,17 +432,15 @@ static void avrc_build_attribute_entries(int num_attrs, /* 8 is the size of attr_id, char set and str_len */ remaining_buffer_capacity -= 8; if (remaining_buffer_capacity < 0) { - LOG_WARN( - "%s not enough buffer space for attr_id[%d]: %d," - " skipping %d attributes", - __func__, index, p_attrs[index].attr_id, num_attrs - index); + log::warn( + "not enough buffer space for attr_id[{}]: {}, skipping {} attributes", + index, p_attrs[index].attr_id, num_attrs - index); break; } if (remaining_buffer_capacity < p_attrs[index].name.str_len) { - LOG_WARN( - "%s not enough buffer space for attr_id[%d]: %d," - " truncating attribute", - __func__, index, p_attrs[index].attr_id); + log::warn( + "not enough buffer space for attr_id[{}]: {}, truncating attribute", + index, p_attrs[index].attr_id); p_attrs[index].name.str_len = remaining_buffer_capacity; remaining_buffer_capacity = 0; } @@ -452,8 +453,8 @@ static void avrc_build_attribute_entries(int num_attrs, (*p_attribute_count)++; } *pp_data = p_data; - LOG_VERBOSE("%s filled attributes, remaining_buffer_capacity: %d", __func__, - remaining_buffer_capacity); + log::verbose("filled attributes, remaining_buffer_capacity: {}", + remaining_buffer_capacity); } /******************************************************************************* @@ -469,17 +470,17 @@ static void avrc_build_attribute_entries(int num_attrs, ******************************************************************************/ static tAVRC_STS avrc_bld_get_elem_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!p_rsp->p_attrs) { - LOG_ERROR("%s NULL p_attrs", __func__); + log::error("NULL p_attrs"); return AVRC_STS_BAD_PARAM; } /* Figure out how much we have left in current buffer */ int remaining_buffer_capacity = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset; if (remaining_buffer_capacity < 5) { - LOG_ERROR("%d not enough buffer for packet header", - remaining_buffer_capacity); + log::error("{} not enough buffer for packet header", + remaining_buffer_capacity); return AVRC_STS_INTERNAL_ERR; } /* Get to the beginning of PDU */ @@ -503,7 +504,7 @@ static tAVRC_STS avrc_bld_get_elem_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp, remaining_buffer_capacity -= p_data - p_pdu_start; ; if (remaining_buffer_capacity < 0) { - LOG_ERROR("%s not enough buffer capacity for response", __func__); + log::error("not enough buffer capacity for response"); return AVRC_STS_BAD_PARAM; } /* Fill in the Attribute ID, Character Set, Length and Values */ @@ -531,7 +532,7 @@ static tAVRC_STS avrc_bld_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP* p_rsp, BT_HDR* p_pkt) { uint8_t *p_data, *p_start; - LOG_VERBOSE("%s", __func__); + log::verbose(""); p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_start + 2; @@ -563,7 +564,7 @@ static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp, uint8_t xx; tAVRC_STS status = AVRC_STS_NO_ERROR; - LOG_VERBOSE("%s event_id %d", __func__, p_rsp->event_id); + log::verbose("event_id {}", p_rsp->event_id); p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 2; /* pdu + rsvd */ @@ -578,7 +579,7 @@ static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp, UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status); len = 2; } else { - LOG_ERROR("%s bad play state", __func__); + log::error("bad play state"); status = AVRC_STS_BAD_PARAM; } break; @@ -605,7 +606,7 @@ static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp, UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status); len = 2; } else { - LOG_ERROR("%s bad battery status", __func__); + log::error("bad battery status"); status = AVRC_STS_BAD_PARAM; } break; @@ -615,7 +616,7 @@ static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp, UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status); len = 2; } else { - LOG_ERROR("%s bad system status", __func__); + log::error("bad system status"); status = AVRC_STS_BAD_PARAM; } break; @@ -635,7 +636,7 @@ static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp, UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]); } else { - LOG_ERROR("%s bad player app seeting attribute or value", __func__); + log::error("bad player app seeting attribute or value"); status = AVRC_STS_BAD_PARAM; break; } @@ -663,7 +664,7 @@ static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp, default: status = AVRC_STS_BAD_PARAM; - LOG_ERROR("%s unknown event_id", __func__); + log::error("unknown event_id"); } UINT16_TO_BE_STREAM(p_len, len); @@ -690,7 +691,7 @@ static tAVRC_STS avrc_bld_next_rsp(tAVRC_NEXT_RSP* p_rsp, BT_HDR* p_pkt) { UINT16_TO_BE_STREAM(p_data, 0x0001); /* only one attribute to be sent */ UINT8_TO_BE_STREAM(p_data, p_rsp->target_pdu); - LOG_VERBOSE("%s: target_pdu: 0x%02x", __func__, p_rsp->target_pdu); + log::verbose("target_pdu: 0x{:02x}", p_rsp->target_pdu); return AVRC_STS_NO_ERROR; } @@ -705,7 +706,7 @@ static tAVRC_STS avrc_bld_next_rsp(tAVRC_NEXT_RSP* p_rsp, BT_HDR* p_pkt) { *****************************************************************************/ static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; /* To calculate length */ uint8_t* p_data = p_start + 2; @@ -729,10 +730,10 @@ static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol, ******************************************************************************/ tAVRC_STS avrc_bld_group_navigation_rsp(uint16_t navi_id, BT_HDR* p_pkt) { if (!AVRC_IS_VALID_GROUP(navi_id)) { - LOG_ERROR("%s bad navigation op id: %d", __func__, navi_id); + log::error("bad navigation op id: {}", navi_id); return AVRC_STS_BAD_PARAM; } - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t* p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset; UINT16_TO_BE_STREAM(p_data, navi_id); p_pkt->len = 2; @@ -753,8 +754,8 @@ static tAVRC_STS avrc_bld_rejected_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { uint8_t* p_data; uint8_t opcode = p_rsp->opcode; - LOG_VERBOSE("%s: status=%d, pdu:x%x, opcode=%x", __func__, p_rsp->status, - p_rsp->pdu, opcode); + log::verbose("status={}, pdu:x{:x}, opcode={:x}", p_rsp->status, p_rsp->pdu, + opcode); if (opcode == AVRC_OP_BROWSE) { p_data = p_start + 1; @@ -768,7 +769,7 @@ static tAVRC_STS avrc_bld_rejected_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { } else { p_data = p_start + 2; } - LOG_VERBOSE("%s pdu:x%x, Opcode:%x", __func__, *p_start, opcode); + log::verbose("pdu:x{:x}, Opcode:{:x}", *p_start, opcode); UINT16_TO_BE_STREAM(p_data, 1); UINT8_TO_BE_STREAM(p_data, p_rsp->status); p_pkt->len = p_data - p_start; @@ -791,7 +792,7 @@ static tAVRC_STS avrc_bld_rejected_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { ******************************************************************************/ static tAVRC_STS avrc_bld_ctrl_status_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; - LOG_VERBOSE("pdu:x%x", *p_start); + log::verbose("pdu:x{:x}", *p_start); /* To calculate length */ uint8_t* p_data = p_start + 2; /* pdu + rsvd */ @@ -814,7 +815,7 @@ static tAVRC_STS avrc_bld_ctrl_status_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { * ******************************************************************************/ static tAVRC_STS avrc_bld_set_addr_player_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt); } @@ -848,7 +849,7 @@ static tAVRC_STS avrc_bld_set_browsed_player_rsp(tAVRC_SET_BR_PLAYER_RSP* p_rsp, len_left = mtu; } len_left = len_left - p_pkt->offset - p_pkt->len; - LOG_VERBOSE("len_left:%d, mtu:%d ", len_left, mtu); + log::verbose("len_left:{}, mtu:{} ", len_left, mtu); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; @@ -924,7 +925,7 @@ static tAVRC_STS avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP* p_rsp, uint16_t item_count; uint16_t mtu; bool multi_items_add_fail = false; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* make sure the given buffer can accomodate this response */ len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE; @@ -936,7 +937,7 @@ static tAVRC_STS avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP* p_rsp, // Version 5.3 | Vol 3, Part A, Chapter 5 // MTU may be controlled by the peer if (len_left < p_pkt->offset + p_pkt->len) { - LOG_ERROR("memory not enough (len_left=%d)", len_left); + log::error("memory not enough (len_left={})", len_left); return AVRC_STS_INTERNAL_ERR; } @@ -958,7 +959,7 @@ static tAVRC_STS avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP* p_rsp, len = 5; if (len_left < 5) { - LOG_ERROR("memory not enough (len_left=%d)", len_left); + log::error("memory not enough (len_left={})", len_left); return AVRC_STS_INTERNAL_ERR; } @@ -968,7 +969,7 @@ static tAVRC_STS avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP* p_rsp, p = p_num; BE_STREAM_TO_UINT16(item_count, p); } - LOG_VERBOSE("len:%d, len_left:%d, num:%d", len, len_left, item_count); + log::verbose("len:{}, len_left:{}, num:{}", len, len_left, item_count); /* min len required = item_type(1) + item len(2) + min item (14) = 17 */ for (xx = 0; @@ -1091,8 +1092,8 @@ static tAVRC_STS avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP* p_rsp, status = AVRC_STS_BAD_PARAM; break; } - LOG_VERBOSE("len:%d, len_left:%d, num:%d, item_len:%zu", len, len_left, - item_count, item_len); + log::verbose("len:{}, len_left:{}, num:{}, item_len:{}", len, len_left, + item_count, item_len); } /* for item_count */ UINT16_TO_BE_STREAM(p_num, item_count); @@ -1146,9 +1147,9 @@ static tAVRC_STS avrc_bld_change_path_rsp(tAVRC_CHG_PATH_RSP* p_rsp, ******************************************************************************/ static tAVRC_STS avrc_bld_get_item_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!p_rsp->p_attrs) { - LOG_ERROR("%s NULL p_attrs", __func__); + log::error("NULL p_attrs"); return AVRC_STS_BAD_PARAM; } /* Figure out how much we have left in current buffer */ @@ -1162,11 +1163,11 @@ static tAVRC_STS avrc_bld_get_item_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp, if (remaining_buffer_capacity > mtu) { remaining_buffer_capacity = mtu; } - LOG_VERBOSE("%s: remaining_buffer_capacity:%d, mtu:%d", __func__, - remaining_buffer_capacity, mtu); + log::verbose("remaining_buffer_capacity:{}, mtu:{}", + remaining_buffer_capacity, mtu); if (remaining_buffer_capacity < 5) { - LOG_ERROR("%s: not enough space for packet header, remaining:%d < 5", - __func__, remaining_buffer_capacity); + log::error("not enough space for packet header, remaining:{} < 5", + remaining_buffer_capacity); return AVRC_STS_INTERNAL_ERR; } /* Get to the beginning of PDU */ @@ -1224,7 +1225,7 @@ static tAVRC_STS avrc_bld_get_num_of_item_rsp(tAVRC_GET_NUM_OF_ITEMS_RSP* p_rsp, BT_HDR* p_pkt) { uint8_t *p_data, *p_start, *p_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 1; /* pdu */ @@ -1261,7 +1262,7 @@ static tAVRC_STS avrc_bld_get_num_of_item_rsp(tAVRC_GET_NUM_OF_ITEMS_RSP* p_rsp, static tAVRC_STS avrc_bld_search_rsp(tAVRC_SEARCH_RSP* p_rsp, BT_HDR* p_pkt) { uint8_t *p_data, *p_start, *p_len; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* get the existing length, if any, and also the num attributes */ p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 1; /* pdu */ @@ -1286,7 +1287,7 @@ static tAVRC_STS avrc_bld_search_rsp(tAVRC_SEARCH_RSP* p_rsp, BT_HDR* p_pkt) { * ******************************************************************************/ static tAVRC_STS avrc_bld_play_item_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt); } @@ -1302,7 +1303,7 @@ static tAVRC_STS avrc_bld_play_item_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { ******************************************************************************/ static tAVRC_STS avrc_bld_add_to_now_playing_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt); } @@ -1321,12 +1322,12 @@ static BT_HDR* avrc_bld_init_rsp_buffer(tAVRC_RESPONSE* p_rsp) { uint16_t chnl = AVCT_DATA_CTRL; uint8_t opcode = avrc_opcode_from_pdu(p_rsp->pdu); - LOG_VERBOSE("%s: pdu=%x, opcode=%x/%x", __func__, p_rsp->pdu, opcode, - p_rsp->rsp.opcode); + log::verbose("pdu={:x}, opcode={:x}/{:x}", p_rsp->pdu, opcode, + p_rsp->rsp.opcode); if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR && avrc_is_valid_opcode(p_rsp->rsp.opcode)) { opcode = p_rsp->rsp.opcode; - LOG_VERBOSE("%s opcode=%x", __func__, opcode); + log::verbose("opcode={:x}", opcode); } switch (opcode) { @@ -1394,15 +1395,15 @@ tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp, uint16_t peer_mtu; if (!p_rsp || !pp_pkt) { - LOG_VERBOSE("%s Invalid parameters passed. p_rsp=%p, pp_pkt=%p", __func__, - p_rsp, pp_pkt); + log::verbose("Invalid parameters passed. p_rsp={}, pp_pkt={}", + fmt::ptr(p_rsp), fmt::ptr(pp_pkt)); return AVRC_STS_BAD_PARAM; } if (*pp_pkt == NULL) { *pp_pkt = avrc_bld_init_rsp_buffer(p_rsp); if (*pp_pkt == NULL) { - LOG_VERBOSE("%s Failed to initialize response buffer", __func__); + log::verbose("Failed to initialize response buffer"); return AVRC_STS_INTERNAL_ERR; } @@ -1417,8 +1418,7 @@ tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp, status = AVRC_STS_NO_ERROR; p_pkt = *pp_pkt; - LOG_VERBOSE("%s pdu=%x status=%x", __func__, p_rsp->rsp.pdu, - p_rsp->rsp.status); + log::verbose("pdu={:x} status={:x}", p_rsp->rsp.pdu, p_rsp->rsp.status); if (p_rsp->rsp.status != AVRC_STS_NO_ERROR) { return (avrc_bld_rejected_rsp(&p_rsp->rsp, p_pkt)); } @@ -1536,6 +1536,6 @@ tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp, osi_free(p_pkt); *pp_pkt = NULL; } - LOG_VERBOSE("%s returning %d", __func__, status); + log::verbose("returning {}", status); return status; } diff --git a/system/stack/avrc/avrc_opt.cc b/system/stack/avrc/avrc_opt.cc index ec097bf17ccd409b026948478ee3aacba8c4fb96..09e623bf8d4cd11f53659360a3626c311c595fd8 100644 --- a/system/stack/avrc/avrc_opt.cc +++ b/system/stack/avrc/avrc_opt.cc @@ -21,7 +21,7 @@ * Interface to AVRCP optional commands * ******************************************************************************/ -#include +#include #include #include "avrc_api.h" @@ -30,6 +30,8 @@ #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" +using namespace bluetooth; + /****************************************************************************** * * Function avrc_vendor_msg @@ -40,7 +42,7 @@ * p_msg: Pointer to VENDOR DEPENDENT message structure. * * Output Parameters: -* None. + * None. * * Returns pointer to a valid GKI buffer if successful. * NULL if p_msg is NULL. diff --git a/system/stack/avrc/avrc_pars_ct.cc b/system/stack/avrc/avrc_pars_ct.cc index aa4f3fcba508014512d02c612707e9033f5d43b7..3179204ba2a24ec3b3186072439d1c350d8094c2 100644 --- a/system/stack/avrc/avrc_pars_ct.cc +++ b/system/stack/avrc/avrc_pars_ct.cc @@ -15,6 +15,7 @@ * limitations under the License. * ******************************************************************************/ +#include #include #include "avrc_api.h" @@ -25,6 +26,8 @@ #include "osi/include/osi.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /***************************************************************************** * Global data ****************************************************************************/ @@ -55,26 +58,25 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, if (p_msg->p_vendor_data == NULL) return AVRC_STS_INTERNAL_ERR; if (p_msg->vendor_len < 4) { - LOG_WARN("%s: message length %d too short: must be at least 4", __func__, - p_msg->vendor_len); + log::warn("message length {} too short: must be at least 4", + p_msg->vendor_len); return AVRC_STS_INTERNAL_ERR; } p = p_msg->p_vendor_data; BE_STREAM_TO_UINT8(p_result->pdu, p); p++; /* skip the reserved/packe_type byte */ BE_STREAM_TO_UINT16(len, p); - LOG_VERBOSE("%s ctype:0x%x pdu:0x%x, len:%d/0x%x vendor_len=0x%x", __func__, - p_msg->hdr.ctype, p_result->pdu, len, len, p_msg->vendor_len); + log::verbose("ctype:0x{:x} pdu:0x{:x}, len:{}/0x{:x} vendor_len=0x{:x}", + p_msg->hdr.ctype, p_result->pdu, len, len, p_msg->vendor_len); if (p_msg->vendor_len < len + 4) { - LOG_WARN("%s: message length %d too short: must be at least %d", __func__, - p_msg->vendor_len, len + 4); + log::warn("message length {} too short: must be at least {}", + p_msg->vendor_len, len + 4); return AVRC_STS_INTERNAL_ERR; } if (p_msg->hdr.ctype == AVRC_RSP_REJ) { if (len < 1) { - LOG_WARN("%s: invalid parameter length %d: must be at least 1", __func__, - len); + log::warn("invalid parameter length {}: must be at least 1", len); return AVRC_STS_INTERNAL_ERR; } p_result->rsp.status = *p; @@ -101,8 +103,7 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, break; } if (len < 1) { - LOG_WARN("%s: invalid parameter length %d: must be at least 1", - __func__, len); + log::warn("invalid parameter length {}: must be at least 1", len); return AVRC_STS_INTERNAL_ERR; } BE_STREAM_TO_UINT8(eventid, p); @@ -112,16 +113,15 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, AVRC_RSP_REJ == p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) { if (len < 2) { - LOG_WARN("%s: invalid parameter length %d: must be at least 2", - __func__, len); + log::warn("invalid parameter length {}: must be at least 2", len); return AVRC_STS_INTERNAL_ERR; } p_result->reg_notif.status = p_msg->hdr.ctype; p_result->reg_notif.event_id = eventid; BE_STREAM_TO_UINT8(p_result->reg_notif.param.volume, p); } - LOG_VERBOSE("%s PDU reg notif response:event %x, volume %x", __func__, - eventid, p_result->reg_notif.param.volume); + log::verbose("PDU reg notif response:event {:x}, volume {:x}", eventid, + p_result->reg_notif.param.volume); break; default: status = AVRC_STS_BAD_CMD; @@ -201,8 +201,7 @@ tAVRC_STS avrc_parse_notification_rsp(uint8_t* p_stream, uint16_t len, return AVRC_STS_NO_ERROR; length_error: - LOG_WARN("%s: invalid parameter length %d: must be at least %d", __func__, - len, min_len); + log::warn("invalid parameter length {}: must be at least {}", len, min_len); return AVRC_STS_INTERNAL_ERR; } @@ -212,7 +211,7 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, uint8_t pdu; if (p_msg->browse_len == 0) { - LOG_ERROR("%s length %d", __func__, p_msg->browse_len); + log::error("length {}", p_msg->browse_len); return AVRC_STS_BAD_PARAM; } @@ -220,8 +219,8 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, /* read the pdu */ if (p_msg->browse_len < 3) { - LOG_WARN("%s: message length %d too short: must be at least 3", __func__, - p_msg->browse_len); + log::warn("message length {} too short: must be at least 3", + p_msg->browse_len); return AVRC_STS_BAD_PARAM; } BE_STREAM_TO_UINT8(pdu, p); @@ -230,11 +229,11 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, /* read the entire packet len */ BE_STREAM_TO_UINT16(pkt_len, p); - LOG_VERBOSE("%s pdu:%d, pkt_len:%d", __func__, pdu, pkt_len); + log::verbose("pdu:{}, pkt_len:{}", pdu, pkt_len); if (p_msg->browse_len < (pkt_len + 3)) { - LOG_WARN("%s: message length %d too short: must be at least %d", __func__, - p_msg->browse_len, pkt_len + 3); + log::warn("message length {} too short: must be at least {}", + p_msg->browse_len, pkt_len + 3); return AVRC_STS_INTERNAL_ERR; } @@ -249,7 +248,7 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, /* read the status */ BE_STREAM_TO_UINT8(get_item_rsp->status, p); if (get_item_rsp->status != AVRC_STS_NO_ERROR) { - LOG_WARN("%s returning error %d", __func__, get_item_rsp->status); + log::warn("returning error {}", get_item_rsp->status); return get_item_rsp->status; } @@ -260,9 +259,9 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, /* read the number of items */ BE_STREAM_TO_UINT16(get_item_rsp->item_count, p); - LOG_VERBOSE("%s pdu %d status %d pkt_len %d uid counter %d item count %d", - __func__, get_item_rsp->pdu, get_item_rsp->status, pkt_len, - get_item_rsp->uid_counter, get_item_rsp->item_count); + log::verbose("pdu {} status {} pkt_len {} uid counter {} item count {}", + get_item_rsp->pdu, get_item_rsp->status, pkt_len, + get_item_rsp->uid_counter, get_item_rsp->item_count); /* get each of the items */ get_item_rsp->p_item_list = (tAVRC_ITEM*)osi_calloc( @@ -272,7 +271,7 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, min_len += 1; if (pkt_len < min_len) goto browse_length_error; BE_STREAM_TO_UINT8(curr_item->item_type, p); - LOG_VERBOSE("%s item type %d", __func__, curr_item->item_type); + log::verbose("item type {}", curr_item->item_type); switch (curr_item->item_type) { case AVRC_ITEM_PLAYER: { /* Handle player */ @@ -297,11 +296,11 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, player->name.p_str = (uint8_t*)osi_calloc( (player->name.str_len + 1) * sizeof(uint8_t)); BE_STREAM_TO_ARRAY(p, player->name.p_str, player->name.str_len); - LOG_VERBOSE( - "%s type %d id %d mtype %d stype %d ps %d cs %d name len %d", - __func__, curr_item->item_type, player->player_id, - player->major_type, player->sub_type, player->play_status, - player->name.charset_id, player->name.str_len); + log::verbose( + "type {} id {} mtype {} stype {} ps {} cs {} name len {}", + curr_item->item_type, player->player_id, player->major_type, + player->sub_type, player->play_status, player->name.charset_id, + player->name.str_len); } break; case AVRC_ITEM_FOLDER: { @@ -325,9 +324,9 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, folder->name.p_str = (uint8_t*)osi_calloc( (folder->name.str_len + 1) * sizeof(uint8_t)); BE_STREAM_TO_ARRAY(p, folder->name.p_str, folder->name.str_len); - LOG_VERBOSE("%s type %d playable %d cs %d name len %d", __func__, - folder->type, folder->playable, folder->name.charset_id, - folder->name.str_len); + log::verbose("type {} playable {} cs {} name len {}", folder->type, + folder->playable, folder->name.charset_id, + folder->name.str_len); } break; case AVRC_ITEM_MEDIA: { @@ -351,9 +350,9 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, BE_STREAM_TO_ARRAY(p, media->name.p_str, media->name.str_len); BE_STREAM_TO_UINT8(media->attr_count, p); - LOG_VERBOSE("%s media type %d charset id %d len %d attr ct %d", - __func__, media->type, media->name.charset_id, - media->name.str_len, media->attr_count); + log::verbose("media type {} charset id {} len {} attr ct {}", + media->type, media->name.charset_id, + media->name.str_len, media->attr_count); media->p_attr_list = (tAVRC_ATTR_ENTRY*)osi_calloc( media->attr_count * sizeof(tAVRC_ATTR_ENTRY)); @@ -372,19 +371,18 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, attr_entry->name.str_len * sizeof(uint8_t)); BE_STREAM_TO_ARRAY(p, attr_entry->name.p_str, attr_entry->name.str_len); - LOG_VERBOSE("%s media attr id %d cs %d name len %d", __func__, - attr_entry->attr_id, attr_entry->name.charset_id, - attr_entry->name.str_len); + log::verbose("media attr id {} cs {} name len {}", + attr_entry->attr_id, attr_entry->name.charset_id, + attr_entry->name.str_len); } } break; default: - LOG_ERROR("%s item type not handled %d", __func__, - curr_item->item_type); + log::error("item type not handled {}", curr_item->item_type); return AVRC_STS_INTERNAL_ERR; } - LOG_VERBOSE("%s pkt_len %d min_len %d", __func__, pkt_len, min_len); + log::verbose("pkt_len {} min_len {}", pkt_len, min_len); /* advance to populate the next item */ curr_item++; @@ -403,9 +401,8 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, /* Read the number of items in folder */ BE_STREAM_TO_UINT32(change_path_rsp->num_items, p); - LOG_VERBOSE("%s pdu %d status %d item count %d", __func__, - change_path_rsp->pdu, change_path_rsp->status, - change_path_rsp->num_items); + log::verbose("pdu {} status {} item count {}", change_path_rsp->pdu, + change_path_rsp->status, change_path_rsp->num_items); break; } @@ -432,9 +429,8 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, attr_entry->name.p_str = (uint8_t*)osi_malloc(attr_entry->name.str_len * sizeof(uint8_t)); BE_STREAM_TO_ARRAY(p, attr_entry->name.p_str, attr_entry->name.str_len); - LOG_VERBOSE("%s media attr id %d cs %d name len %d", __func__, - attr_entry->attr_id, attr_entry->name.charset_id, - attr_entry->name.str_len); + log::verbose("media attr id {} cs {} name len {}", attr_entry->attr_id, + attr_entry->name.charset_id, attr_entry->name.str_len); } break; @@ -450,18 +446,18 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, BE_STREAM_TO_UINT8(set_br_pl_rsp->status, p); if (set_br_pl_rsp->status != AVRC_STS_NO_ERROR) { - LOG_ERROR( - "%s Stopping further parsing because player not browsable sts %d", - __func__, set_br_pl_rsp->status); + log::error( + "Stopping further parsing because player not browsable sts {}", + set_br_pl_rsp->status); break; } BE_STREAM_TO_UINT16(set_br_pl_rsp->uid_counter, p); BE_STREAM_TO_UINT32(set_br_pl_rsp->num_items, p); BE_STREAM_TO_UINT16(set_br_pl_rsp->charset_id, p); BE_STREAM_TO_UINT8(set_br_pl_rsp->folder_depth, p); - LOG_VERBOSE( - "%s AVRC_PDU_SET_BROWSED_PLAYER status %d items %d cs %d depth %d", - __func__, set_br_pl_rsp->status, set_br_pl_rsp->num_items, + log::verbose( + "AVRC_PDU_SET_BROWSED_PLAYER status {} items {} cs {} depth {}", + set_br_pl_rsp->status, set_br_pl_rsp->num_items, set_br_pl_rsp->charset_id, set_br_pl_rsp->folder_depth); set_br_pl_rsp->p_folders = (tAVRC_NAME*)osi_calloc( @@ -475,8 +471,8 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, BE_STREAM_TO_UINT16(folder_name->str_len, p); min_len += folder_name->str_len; if (pkt_len < min_len) goto browse_length_error; - LOG_VERBOSE("%s AVRC_PDU_SET_BROWSED_PLAYER item: %d len: %d", __func__, - i, folder_name->str_len); + log::verbose("AVRC_PDU_SET_BROWSED_PLAYER item: {} len: {}", i, + folder_name->str_len); folder_name->p_str = (uint8_t*)osi_calloc((folder_name->str_len + 1) * sizeof(uint8_t)); BE_STREAM_TO_ARRAY(p, folder_name->p_str, folder_name->str_len); @@ -485,14 +481,14 @@ static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg, } default: - LOG_ERROR("%s pdu %d not handled", __func__, pdu); + log::error("pdu {} not handled", pdu); } return status; browse_length_error: - LOG_WARN("%s: invalid parameter length %d: must be at least %d", __func__, - pkt_len, min_len); + log::warn("invalid parameter length {}: must be at least {}", pkt_len, + min_len); return AVRC_STS_BAD_CMD; } @@ -512,8 +508,8 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, tAVRC_RESPONSE* p_result, uint8_t* p_buf, uint16_t* buf_len) { if (p_msg->vendor_len < 4) { - LOG_WARN("%s: message length %d too short: must be at least 4", __func__, - p_msg->vendor_len); + log::warn("message length {} too short: must be at least 4", + p_msg->vendor_len); return AVRC_STS_INTERNAL_ERR; } @@ -524,11 +520,11 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, uint16_t len; uint32_t min_len = 0; BE_STREAM_TO_UINT16(len, p); - LOG_VERBOSE("%s ctype:0x%x pdu:0x%x, len:%d vendor_len=0x%x", __func__, - p_msg->hdr.ctype, p_result->pdu, len, p_msg->vendor_len); + log::verbose("ctype:0x{:x} pdu:0x{:x}, len:{} vendor_len=0x{:x}", + p_msg->hdr.ctype, p_result->pdu, len, p_msg->vendor_len); if (p_msg->vendor_len < len + 4) { - LOG_WARN("%s: message length %d too short: must be at least %d", __func__, - p_msg->vendor_len, len + 4); + log::warn("message length {} too short: must be at least {}", + p_msg->vendor_len, len + 4); return AVRC_STS_INTERNAL_ERR; } /* Todo: Issue in handling reject, check */ @@ -557,8 +553,8 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, if (len < min_len) goto length_error; BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p); BE_STREAM_TO_UINT8(p_result->get_caps.count, p); - LOG_VERBOSE("%s cap id = %d, cap_count = %d ", __func__, - p_result->get_caps.capability_id, p_result->get_caps.count); + log::verbose("cap id = {}, cap_count = {} ", + 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) { return AVRC_STS_INTERNAL_ERR; @@ -592,8 +588,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, } min_len += 1; BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p); - LOG_VERBOSE("%s attr count = %d ", __func__, - p_result->list_app_attr.num_attr); + log::verbose("attr count = {} ", p_result->list_app_attr.num_attr); if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) { p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE; @@ -617,8 +612,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, p_result->list_app_values.num_val = AVRC_MAX_APP_ATTR_SIZE; } - LOG_VERBOSE("%s value count = %d ", __func__, - p_result->list_app_values.num_val); + log::verbose("value count = {} ", p_result->list_app_values.num_val); min_len += p_result->list_app_values.num_val; if (len < min_len) goto length_error; for (int xx = 0; xx < p_result->list_app_values.num_val; xx++) { @@ -633,8 +627,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, } min_len += 1; BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p); - LOG_VERBOSE("%s attr count = %d ", __func__, - p_result->get_cur_app_val.num_val); + log::verbose("attr count = {} ", p_result->get_cur_app_val.num_val); if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) { p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE; @@ -666,8 +659,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) { num_attrs = AVRC_MAX_APP_ATTR_SIZE; } - LOG_VERBOSE("%s attr count = %d ", __func__, - p_result->get_app_attr_txt.num_attr); + log::verbose("attr count = {} ", p_result->get_app_attr_txt.num_attr); p_result->get_app_attr_txt.num_attr = num_attrs; p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc( @@ -720,8 +712,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, num_vals = AVRC_MAX_APP_ATTR_SIZE; } p_result->get_app_val_txt.num_attr = num_vals; - LOG_VERBOSE("%s value count = %d ", __func__, - p_result->get_app_val_txt.num_attr); + log::verbose("value count = {} ", p_result->get_app_val_txt.num_attr); p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc( num_vals * sizeof(tAVRC_APP_SETTING_TEXT)); @@ -824,7 +815,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, case AVRC_PDU_SET_ADDRESSED_PLAYER: if (len != 1) { - LOG_ERROR("%s pdu: %d len %d", __func__, p_result->pdu, len); + log::error("pdu: {} len {}", p_result->pdu, len); return AVRC_STS_BAD_CMD; } BE_STREAM_TO_UINT8(p_result->rsp.status, p); @@ -836,8 +827,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, return AVRC_STS_NO_ERROR; length_error: - LOG_WARN("%s: invalid parameter length %d: must be at least %d", __func__, - len, min_len); + log::warn("invalid parameter length {}: must be at least {}", len, min_len); return AVRC_STS_INTERNAL_ERR; } @@ -867,7 +857,7 @@ tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result, break; default: - LOG_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode); + log::error("unknown opcode:0x{:x}", p_msg->hdr.opcode); break; } p_result->rsp.opcode = p_msg->hdr.opcode; @@ -908,7 +898,7 @@ tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result, break; default: - LOG_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode); + log::error("unknown opcode:0x{:x}", p_msg->hdr.opcode); break; } p_result->rsp.opcode = p_msg->hdr.opcode; diff --git a/system/stack/avrc/avrc_pars_tg.cc b/system/stack/avrc/avrc_pars_tg.cc index a6ae9a62d03ccaa0e056775e7bf98d81600e1a46..4a053c64f9ce49cec0558595e07b1a403104df16 100644 --- a/system/stack/avrc/avrc_pars_tg.cc +++ b/system/stack/avrc/avrc_pars_tg.cc @@ -15,6 +15,7 @@ * limitations under the License. * ******************************************************************************/ +#include #include #include "avrc_api.h" @@ -23,6 +24,8 @@ #include "os/log.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /***************************************************************************** * Global data ****************************************************************************/ @@ -44,15 +47,15 @@ static tAVRC_STS avrc_ctrl_pars_vendor_cmd(tAVRC_MSG_VENDOR* p_msg, tAVRC_STS status = AVRC_STS_NO_ERROR; if (p_msg->vendor_len < 4) { // 4 == pdu + reserved byte + len as uint16 - LOG_WARN("%s: message length %d too short: must be at least 4", __func__, - p_msg->vendor_len); + log::warn("message length {} too short: must be at least 4", + p_msg->vendor_len); return AVRC_STS_INTERNAL_ERR; } uint8_t* p = p_msg->p_vendor_data; p_result->pdu = *p++; - LOG_VERBOSE("%s pdu:0x%x", __func__, p_result->pdu); + log::verbose("pdu:0x{:x}", p_result->pdu); if (!AVRC_IsValidAvcType(p_result->pdu, p_msg->hdr.ctype)) { - LOG_VERBOSE("%s detects wrong AV/C type!", __func__); + log::verbose("detects wrong AV/C type!"); status = AVRC_STS_BAD_CMD; } @@ -123,24 +126,23 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR* p_msg, if (p_msg->p_vendor_data == NULL) return AVRC_STS_INTERNAL_ERR; if (p_msg->vendor_len < 4) { - LOG_WARN("%s: message length %d too short: must be at least 4", __func__, - p_msg->vendor_len); + log::warn("message length {} too short: must be at least 4", + p_msg->vendor_len); return AVRC_STS_INTERNAL_ERR; } p = p_msg->p_vendor_data; p_result->pdu = *p++; - LOG_VERBOSE("%s pdu:0x%x", __func__, p_result->pdu); + log::verbose("pdu:0x{:x}", p_result->pdu); if (!AVRC_IsValidAvcType(p_result->pdu, p_msg->hdr.ctype)) { - LOG_VERBOSE("%s detects wrong AV/C type(0x%x)!", __func__, - p_msg->hdr.ctype); + log::verbose("detects wrong AV/C type(0x{:x})!", p_msg->hdr.ctype); status = AVRC_STS_BAD_CMD; } p++; /* skip the reserved byte */ BE_STREAM_TO_UINT16(len, p); if ((len + 4) != (p_msg->vendor_len)) { - LOG_ERROR("%s incorrect length :%d, %d", __func__, len, p_msg->vendor_len); + log::error("incorrect length :{}, {}", len, p_msg->vendor_len); status = AVRC_STS_INTERNAL_ERR; } @@ -211,16 +213,15 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR* p_msg, status = AVRC_STS_BAD_PARAM; } if (xx != p_result->set_app_val.num_val) { - LOG_ERROR( - "%s AVRC_PDU_SET_PLAYER_APP_VALUE not enough room:%d orig " - "num_val:%d", - __func__, xx, p_result->set_app_val.num_val); + log::error( + "AVRC_PDU_SET_PLAYER_APP_VALUE not enough room:{} orig " + "num_val:{}", + xx, p_result->set_app_val.num_val); p_result->set_app_val.num_val = xx; } } else { - LOG_ERROR( - "%s AVRC_PDU_SET_PLAYER_APP_VALUE NULL decode buffer or bad len", - __func__); + log::error( + "AVRC_PDU_SET_PLAYER_APP_VALUE NULL decode buffer or bad len"); status = AVRC_STS_INTERNAL_ERR; } break; @@ -320,8 +321,7 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR* p_msg, else { BE_STREAM_TO_UINT8(p_result->reg_notif.event_id, p); if (!AVRC_IS_VALID_EVENT_ID(p_result->reg_notif.event_id)) { - LOG_ERROR("%s: Invalid event id: %d", __func__, - p_result->reg_notif.event_id); + log::error("Invalid event id: {}", p_result->reg_notif.event_id); return AVRC_STS_BAD_PARAM; } @@ -352,7 +352,7 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR* p_msg, case AVRC_PDU_SET_ADDRESSED_PLAYER: /* 0x60 */ if (len != 2) { - LOG_ERROR("AVRC_PDU_SET_ADDRESSED_PLAYER length is incorrect:%d", len); + log::error("AVRC_PDU_SET_ADDRESSED_PLAYER length is incorrect:{}", len); return AVRC_STS_INTERNAL_ERR; } BE_STREAM_TO_UINT16(p_result->addr_player.player_id, p); @@ -400,13 +400,13 @@ tAVRC_STS AVRC_Ctrl_ParsCommand(tAVRC_MSG* p_msg, tAVRC_COMMAND* p_result) { break; default: - LOG_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode); + log::error("unknown opcode:0x{:x}", p_msg->hdr.opcode); break; } p_result->cmd.opcode = p_msg->hdr.opcode; p_result->cmd.status = status; } - LOG_VERBOSE("%s return status:0x%x", __func__, status); + log::verbose("return status:0x{:x}", status); return status; } @@ -440,7 +440,7 @@ static tAVRC_STS avrc_pars_browsing_cmd(tAVRC_MSG_BROWSE* p_msg, "msg too short"); p_result->pdu = *p++; - LOG_VERBOSE("avrc_pars_browsing_cmd() pdu:0x%x", p_result->pdu); + log::verbose("avrc_pars_browsing_cmd() pdu:0x{:x}", p_result->pdu); /* skip over len */ p += 2; @@ -621,12 +621,12 @@ tAVRC_STS AVRC_ParsCommand(tAVRC_MSG* p_msg, tAVRC_COMMAND* p_result, break; default: - LOG_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode); + log::error("unknown opcode:0x{:x}", p_msg->hdr.opcode); break; } p_result->cmd.opcode = p_msg->hdr.opcode; p_result->cmd.status = status; } - LOG_VERBOSE("%s return status:0x%x", __func__, status); + log::verbose("return status:0x{:x}", status); return status; } diff --git a/system/stack/avrc/avrc_sdp.cc b/system/stack/avrc/avrc_sdp.cc index e6f46717c008d297860f50d848498769d4fd5c0f..5944a10a8e72e1073e979d8c8979510f0397df5e 100644 --- a/system/stack/avrc/avrc_sdp.cc +++ b/system/stack/avrc/avrc_sdp.cc @@ -23,6 +23,7 @@ ******************************************************************************/ #define LOG_TAG "avrcp" +#include #include #include "avrc_api.h" @@ -36,6 +37,7 @@ #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +using namespace bluetooth; using namespace bluetooth::legacy::stack::sdp; using bluetooth::Uuid; @@ -67,7 +69,7 @@ static uint16_t a2dp_attr_list_sdp[] = { *****************************************************************************/ static void avrc_sdp_cback(UNUSED_ATTR const RawAddress& bd_addr, tSDP_STATUS status) { - LOG_VERBOSE("%s status: %d", __func__, status); + log::verbose("status: {}", status); /* reset service_uuid, so can start another find service */ avrc_cb.service_uuid = 0; @@ -122,7 +124,7 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, const tAVRC_FIND_CBACK& find_cback) { bool result = true; - LOG_VERBOSE("%s uuid: %x", __func__, service_uuid); + log::verbose("uuid: {:x}", service_uuid); if ((service_uuid != UUID_SERVCLASS_AV_REM_CTRL_TARGET && service_uuid != UUID_SERVCLASS_AV_REMOTE_CONTROL) || p_db == NULL || p_db->p_db == NULL || find_cback.is_null()) @@ -155,8 +157,8 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, bd_addr, p_db->p_db, avrc_sdp_cback); if (!result) { - LOG_ERROR("%s: Failed to init SDP for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Failed to init SDP for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); avrc_sdp_cback(bd_addr, SDP_GENERIC_ERROR); } } @@ -218,10 +220,10 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, uint8_t index = 0; uint16_t class_list[2]; - LOG_VERBOSE( - "%s: Add AVRCP SDP record, uuid: %x, profile_version: 0x%x, " - "supported_features: 0x%x, psm: 0x%x", - __func__, service_uuid, profile_version, categories, cover_art_psm); + log::verbose( + "Add AVRCP SDP record, uuid: {:x}, profile_version: 0x{:x}, " + "supported_features: 0x{:x}, psm: 0x{:x}", + service_uuid, profile_version, categories, cover_art_psm); if (service_uuid != UUID_SERVCLASS_AV_REM_CTRL_TARGET && service_uuid != UUID_SERVCLASS_AV_REMOTE_CONTROL) @@ -270,10 +272,7 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, /* If we support browsing then add the list */ if (browse_supported) { - LOG_VERBOSE( - "%s: Add Browsing PSM to additional protocol descriptor" - " lists", - __func__); + log::verbose("Add Browsing PSM to additional protocol descriptor lists"); num_additional_protocols++; avrc_add_proto_desc_lists[i].num_elems = 2; avrc_add_proto_desc_lists[i].list_elem[0].num_params = 1; @@ -294,10 +293,10 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, if (profile_version >= AVRC_REV_1_6 && service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET && cover_art_psm > 0) { - LOG_VERBOSE( - "%s: Add AVRCP BIP PSM to additional protocol descriptor" - " lists, psm: 0x%x", - __func__, cover_art_psm); + log::verbose( + "Add AVRCP BIP PSM to additional protocol descriptor lists, psm: " + "0x{:x}", + cover_art_psm); num_additional_protocols++; avrc_add_proto_desc_lists[i].num_elems = 2; avrc_add_proto_desc_lists[i].list_elem[0].num_params = 1; @@ -314,8 +313,8 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, /* Add the additional lists if we support any */ if (num_additional_protocols > 0) { - LOG_VERBOSE("%s: Add %d additional protocol descriptor lists", __func__, - num_additional_protocols); + log::verbose("Add {} additional protocol descriptor lists", + num_additional_protocols); result &= get_legacy_stack_sdp_api()->handle.SDP_AddAdditionProtoLists( sdp_handle, num_additional_protocols, avrc_add_proto_desc_lists); } @@ -367,7 +366,7 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, * *******************************************************************************/ uint16_t AVRC_RemoveRecord(uint32_t sdp_handle) { - LOG_VERBOSE("%s: remove AVRCP SDP record", __func__); + log::verbose("remove AVRCP SDP record"); bool result = get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(sdp_handle); return (result ? AVRC_SUCCESS : AVRC_FAIL); } diff --git a/system/stack/avrc/avrc_utils.cc b/system/stack/avrc/avrc_utils.cc index 1d0247eb997296e707960290807a4526253ee9c1..968cd50daf409a8c3806425eb27bb739730b285b 100644 --- a/system/stack/avrc/avrc_utils.cc +++ b/system/stack/avrc/avrc_utils.cc @@ -18,11 +18,15 @@ #define LOG_TAG "avrcp" +#include + #include "avrc_api.h" #include "avrc_int.h" #include "os/log.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + /************************************************************************** * * Function AVRC_IsValidAvcType @@ -113,8 +117,8 @@ bool avrc_is_valid_player_attrib_value(uint8_t attrib, uint8_t value) { if (attrib >= AVRC_PLAYER_SETTING_LOW_MENU_EXT) result = true; if (!result) { - LOG_ERROR(" %s found not matching attrib(x%x)-value(x%x) pair!", __func__, - attrib, value); + log::error(" found not matching attrib(x{:x})-value(x{:x}) pair!", attrib, + value); } return result; } diff --git a/system/stack/bnep/bnep_api.cc b/system/stack/bnep/bnep_api.cc index 96d1ad770051b87ab198a3ab235b7edbf19df6b9..c41d7863593dc564a35137785262abebf2b49844 100644 --- a/system/stack/bnep/bnep_api.cc +++ b/system/stack/bnep/bnep_api.cc @@ -24,7 +24,7 @@ #include "bnep_api.h" -#include +#include #include #include "bnep_int.h" @@ -37,6 +37,7 @@ #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +using namespace bluetooth; using bluetooth::Uuid; /******************************************************************************* @@ -136,7 +137,7 @@ tBNEP_RESULT BNEP_Connect(const RawAddress& p_rem_bda, const Uuid& src_uuid, uint16_t cid; tBNEP_CONN* p_bcb = bnepu_find_bcb_by_bd_addr(p_rem_bda); - VLOG(0) << __func__ << " BDA:" << p_rem_bda; + log::verbose("BDA:{}", ADDRESS_TO_LOGGABLE_STR(p_rem_bda)); if (!bnep_cb.profile_registered) return BNEP_WRONG_STATE; @@ -162,8 +163,8 @@ tBNEP_RESULT BNEP_Connect(const RawAddress& p_rem_bda, const Uuid& src_uuid, */ p_bcb->con_state = BNEP_STATE_SEC_CHECKING; - LOG_VERBOSE("BNEP initiating security procedures for src uuid %s", - p_bcb->src_uuid.ToString().c_str()); + log::verbose("BNEP initiating security procedures for src uuid {}", + p_bcb->src_uuid.ToString().c_str()); bnep_sec_check_complete(&p_bcb->rem_bda, BT_TRANSPORT_BR_EDR, p_bcb); } else { @@ -177,7 +178,7 @@ tBNEP_RESULT BNEP_Connect(const RawAddress& p_rem_bda, const Uuid& src_uuid, p_bcb->l2cap_cid = cid; } else { - LOG_ERROR("BNEP - Originate failed"); + log::error("BNEP - Originate failed"); if (bnep_cb.p_conn_state_cb) (*bnep_cb.p_conn_state_cb)(p_bcb->handle, p_bcb->rem_bda, BNEP_CONN_FAILED, false); @@ -221,7 +222,7 @@ tBNEP_RESULT BNEP_ConnectResp(uint16_t handle, tBNEP_RESULT resp) { (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD))) return (BNEP_WRONG_STATE); - LOG_DEBUG("handle %d, responce %d", handle, resp); + log::debug("handle {}, responce {}", handle, resp); /* Form appropriate responce based on profile responce */ if (resp == BNEP_CONN_FAILED_SRC_UUID) @@ -294,7 +295,7 @@ tBNEP_RESULT BNEP_Disconnect(uint16_t handle) { if (p_bcb->con_state == BNEP_STATE_IDLE) return (BNEP_WRONG_HANDLE); - LOG_VERBOSE("BNEP_Disconnect() for handle %d", handle); + log::verbose("BNEP_Disconnect() for handle {}", handle); L2CA_DisconnectReq(p_bcb->l2cap_cid); @@ -326,9 +327,9 @@ tBNEP_RESULT BNEP_Disconnect(uint16_t handle) { * BNEP_SUCCESS - If written successfully * ******************************************************************************/ -tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, +tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& dest_addr, BT_HDR* p_buf, uint16_t protocol, - const RawAddress* p_src_addr, bool fw_ext_present) { + const RawAddress& src_addr, bool fw_ext_present) { tBNEP_CONN* p_bcb; uint8_t* p_data; @@ -340,16 +341,15 @@ tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, p_bcb = &(bnep_cb.bcb[handle - 1]); /* Check MTU size */ if (p_buf->len > BNEP_MTU_SIZE) { - LOG_ERROR("%s length %d exceeded MTU %d", __func__, p_buf->len, - BNEP_MTU_SIZE); + log::error("length {} exceeded MTU {}", p_buf->len, BNEP_MTU_SIZE); osi_free(p_buf); return (BNEP_MTU_EXCEDED); } /* Check if the packet should be filtered out */ p_data = (uint8_t*)(p_buf + 1) + p_buf->offset; - if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present, - p_data, p_buf->len) != BNEP_SUCCESS) { + if (bnep_is_packet_allowed(p_bcb, dest_addr, protocol, fw_ext_present, p_data, + p_buf->len) != BNEP_SUCCESS) { /* ** If packet is filtered and ext headers are present ** drop the data and forward the ext headers @@ -404,7 +404,7 @@ tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, } /* Build the BNEP header */ - bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr, + bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, src_addr, dest_addr, fw_ext_present); /* Send the data or queue it up */ @@ -420,12 +420,12 @@ tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, * Description This function sends data over a BNEP connection * * Parameters: handle - handle of the connection to write - * p_dest_addr - BD_ADDR/Ethernet addr of the destination + * dest_addr - BD_ADDR/Ethernet addr of the destination * p_data - pointer to data start * protocol - protocol type of the packet - * p_src_addr - (optional) BD_ADDR/ethernet address of the + * src_addr - (optional) BD_ADDR/ethernet address of the * source - * (should be NULL if it is local BD Addr) + * (should be kEmpty if it is local BD Addr) * fw_ext_present - forwarded extensions present * * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid @@ -437,15 +437,15 @@ tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, * BNEP_SUCCESS - If written successfully * ******************************************************************************/ -tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr, +tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& dest_addr, uint8_t* p_data, uint16_t len, uint16_t protocol, - const RawAddress* p_src_addr, bool fw_ext_present) { + const RawAddress& src_addr, bool fw_ext_present) { tBNEP_CONN* p_bcb; uint8_t* p; /* Check MTU size. Consider the possibility of having extension headers */ if (len > BNEP_MTU_SIZE) { - LOG_ERROR("%s length %d exceeded MTU %d", __func__, len, BNEP_MTU_SIZE); + log::error("length {} exceeded MTU {}", len, BNEP_MTU_SIZE); return (BNEP_MTU_EXCEDED); } @@ -454,8 +454,8 @@ tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr, p_bcb = &(bnep_cb.bcb[handle - 1]); /* Check if the packet should be filtered out */ - if (bnep_is_packet_allowed(p_bcb, p_dest_addr, protocol, fw_ext_present, - p_data, len) != BNEP_SUCCESS) { + if (bnep_is_packet_allowed(p_bcb, dest_addr, protocol, fw_ext_present, p_data, + len) != BNEP_SUCCESS) { /* ** If packet is filtered and ext headers are present ** drop the data and forward the ext headers @@ -510,7 +510,7 @@ tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr, memcpy(p, p_data, len); /* Build the BNEP header */ - bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, p_src_addr, &p_dest_addr, + bnepu_build_bnep_hdr(p_bcb, p_buf, protocol, src_addr, dest_addr, fw_ext_present); /* Send the data or queue it up */ diff --git a/system/stack/bnep/bnep_int.h b/system/stack/bnep/bnep_int.h index b932c48a6563cbf904292aa4e5a12d209e55bd11..e553251952ba5bd2b642cb2bdd904ef801bc46da 100644 --- a/system/stack/bnep/bnep_int.h +++ b/system/stack/bnep/bnep_int.h @@ -179,8 +179,8 @@ void bnepu_send_peer_our_filters(tBNEP_CONN* p_bcb); void bnepu_send_peer_our_multi_filters(tBNEP_CONN* p_bcb); bool bnepu_does_dest_support_prot(tBNEP_CONN* p_bcb, uint16_t protocol); void bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol, - const RawAddress* p_src_addr, - const RawAddress* p_dest_addr, bool ext_bit); + const RawAddress& src_addr, + const RawAddress& dest_addr, bool ext_bit); void test_bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol, uint8_t* p_src_addr, uint8_t* p_dest_addr, uint8_t type); @@ -202,7 +202,7 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, void bnep_sec_check_complete(const RawAddress* bd_addr, tBT_TRANSPORT trasnport, void* p_ref_data); tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, - const RawAddress& p_dest_addr, + const RawAddress& dest_addr, uint16_t protocol, bool fw_ext_present, uint8_t* p_data, uint16_t org_len); diff --git a/system/stack/bnep/bnep_main.cc b/system/stack/bnep/bnep_main.cc index 65bea68e32d99d138bd998eab28b41602721bf40..6f6ed8f6dfa7a3c0e4135837633ac70ed6515661 100644 --- a/system/stack/bnep/bnep_main.cc +++ b/system/stack/bnep/bnep_main.cc @@ -24,7 +24,7 @@ #define LOG_TAG "bluetooth" -#include +#include #include #include "bnep_api.h" @@ -42,6 +42,8 @@ #include "stack/include/bt_types.h" #include "types/raw_address.h" +using namespace bluetooth; + /******************************************************************************/ /* G L O B A L B N E P D A T A */ /******************************************************************************/ @@ -90,7 +92,7 @@ tBNEP_RESULT bnep_register_with_l2cap(void) { if (!L2CA_Register2(BT_PSM_BNEP, bnep_cb.reg_info, false /* enable_snoop */, nullptr, BNEP_MTU_SIZE, BNEP_MTU_SIZE, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) { - LOG_ERROR("BNEP - Registration failed"); + log::error("BNEP - Registration failed"); return BNEP_SECURITY_FAIL; } @@ -130,7 +132,7 @@ static void bnep_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid, alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS, bnep_conn_timer_timeout, p_bcb); - LOG_DEBUG("BNEP - Rcvd L2CAP conn ind, CID: 0x%x", p_bcb->l2cap_cid); + log::debug("BNEP - Rcvd L2CAP conn ind, CID: 0x{:x}", p_bcb->l2cap_cid); } static void bnep_on_l2cap_error(uint16_t l2cap_cid, uint16_t result) { @@ -165,7 +167,7 @@ static void bnep_connect_cfm(uint16_t l2cap_cid, uint16_t result) { /* Find CCB based on CID */ p_bcb = bnepu_find_bcb_by_cid(l2cap_cid); if (p_bcb == NULL) { - LOG_WARN("BNEP - Rcvd conn cnf for unknown CID 0x%x", l2cap_cid); + log::warn("BNEP - Rcvd conn cnf for unknown CID 0x{:x}", l2cap_cid); return; } @@ -179,9 +181,10 @@ static void bnep_connect_cfm(uint16_t l2cap_cid, uint16_t result) { alarm_set_on_mloop(p_bcb->conn_timer, BNEP_CONN_TIMEOUT_MS, bnep_conn_timer_timeout, p_bcb); - LOG_DEBUG("BNEP - got conn cnf, sent cfg req, CID: 0x%x", p_bcb->l2cap_cid); + log::debug("BNEP - got conn cnf, sent cfg req, CID: 0x{:x}", + p_bcb->l2cap_cid); } else { - LOG(ERROR) << __func__ << ": invoked with non OK status"; + log::error("invoked with non OK status"); } } @@ -199,12 +202,12 @@ static void bnep_config_cfm(uint16_t l2cap_cid, uint16_t initiator, tL2CAP_CFG_INFO* p_cfg) { tBNEP_CONN* p_bcb; - LOG_DEBUG("BNEP - Rcvd cfg cfm, CID: 0x%x", l2cap_cid); + log::debug("BNEP - Rcvd cfg cfm, CID: 0x{:x}", l2cap_cid); /* Find CCB based on CID */ p_bcb = bnepu_find_bcb_by_cid(l2cap_cid); if (p_bcb == NULL) { - LOG_WARN("BNEP - Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); + log::warn("BNEP - Rcvd L2CAP cfg ind, unknown CID: 0x{:x}", l2cap_cid); return; } @@ -236,11 +239,11 @@ static void bnep_disconnect_ind(uint16_t l2cap_cid, bool ack_needed) { /* Find CCB based on CID */ p_bcb = bnepu_find_bcb_by_cid(l2cap_cid); if (p_bcb == NULL) { - LOG_WARN("BNEP - Rcvd L2CAP disc, unknown CID: 0x%x", l2cap_cid); + log::warn("BNEP - Rcvd L2CAP disc, unknown CID: 0x{:x}", l2cap_cid); return; } - LOG_DEBUG("BNEP - Rcvd L2CAP disc, CID: 0x%x", l2cap_cid); + log::debug("BNEP - Rcvd L2CAP disc, CID: 0x{:x}", l2cap_cid); /* Tell the user if there is a callback */ if (p_bcb->con_state == BNEP_STATE_CONNECTED) { @@ -272,7 +275,7 @@ static void bnep_congestion_ind(uint16_t l2cap_cid, bool is_congested) { /* Find BCB based on CID */ p_bcb = bnepu_find_bcb_by_cid(l2cap_cid); if (p_bcb == NULL) { - LOG_WARN("BNEP - Rcvd L2CAP cong, unknown CID: 0x%x", l2cap_cid); + log::warn("BNEP - Rcvd L2CAP cong, unknown CID: 0x{:x}", l2cap_cid); return; } @@ -329,7 +332,7 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { /* Find CCB based on CID */ p_bcb = bnepu_find_bcb_by_cid(l2cap_cid); if (p_bcb == NULL) { - LOG_WARN("BNEP - Rcvd L2CAP data, unknown CID: 0x%x", l2cap_cid); + log::warn("BNEP - Rcvd L2CAP data, unknown CID: 0x{:x}", l2cap_cid); osi_free(p_buf); return; } @@ -339,12 +342,13 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { extension_present = type >> 7; type &= 0x7f; if (type >= sizeof(bnep_frame_hdr_sizes) / sizeof(bnep_frame_hdr_sizes[0])) { - LOG_INFO("BNEP - rcvd frame, bad type: 0x%02x", type); + log::info("BNEP - rcvd frame, bad type: 0x{:02x}", type); osi_free(p_buf); return; } if ((rem_len <= bnep_frame_hdr_sizes[type]) || (rem_len > BNEP_MTU_SIZE)) { - LOG_DEBUG("BNEP - rcvd frame, bad len: %d type: 0x%02x", p_buf->len, type); + log::debug("BNEP - rcvd frame, bad len: {} type: 0x{:02x}", p_buf->len, + type); osi_free(p_buf); return; } @@ -354,8 +358,8 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)) && (type != BNEP_FRAME_CONTROL)) { - LOG_WARN("BNEP - Ignored L2CAP data while in state: %d, CID: 0x%x", - p_bcb->con_state, l2cap_cid); + log::warn("BNEP - Ignored L2CAP data while in state: {}, CID: 0x{:x}", + p_bcb->con_state, l2cap_cid); if (extension_present) { /* @@ -398,23 +402,23 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { } if (type > BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY) { - LOG_DEBUG("BNEP - rcvd frame, unknown type: 0x%02x", type); + log::debug("BNEP - rcvd frame, unknown type: 0x{:02x}", type); osi_free(p_buf); return; } - LOG_DEBUG("BNEP - rcv frame, type: %d len: %d Ext: %d", type, p_buf->len, - extension_present); + log::debug("BNEP - rcv frame, type: {} len: {} Ext: {}", type, p_buf->len, + extension_present); /* Initialize addresses to 'not supplied' */ - const RawAddress *p_src_addr, *p_dst_addr; - p_src_addr = p_dst_addr = NULL; + RawAddress src_addr = RawAddress::kEmpty; + RawAddress dst_addr = RawAddress::kEmpty; switch (type) { case BNEP_FRAME_GENERAL_ETHERNET: - p_dst_addr = (RawAddress*)p; + dst_addr = *(RawAddress*)p; p += BD_ADDR_LEN; - p_src_addr = (RawAddress*)p; + src_addr = *(RawAddress*)p; p += BD_ADDR_LEN; BE_STREAM_TO_UINT16(protocol, p); rem_len -= 14; @@ -454,14 +458,14 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { break; case BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY: - p_src_addr = (RawAddress*)p; + src_addr = *(RawAddress*)p; p += BD_ADDR_LEN; BE_STREAM_TO_UINT16(protocol, p); rem_len -= 8; break; case BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY: - p_dst_addr = (RawAddress*)p; + dst_addr = *(RawAddress*)p; p += BD_ADDR_LEN; BE_STREAM_TO_UINT16(protocol, p); rem_len -= 8; @@ -476,7 +480,7 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { /* if unknown extension present stop processing */ if (ext_type) { - LOG_DEBUG("Data extension type 0x%x found", ext_type); + log::debug("Data extension type 0x{:x} found", ext_type); break; } @@ -489,9 +493,10 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { p_buf->len = rem_len; /* Always give the upper layer MAC addresses */ - if (!p_src_addr) p_src_addr = &p_bcb->rem_bda; + if (src_addr == RawAddress::kEmpty) src_addr = p_bcb->rem_bda; - if (!p_dst_addr) p_dst_addr = controller_get_interface()->get_address(); + if (dst_addr == RawAddress::kEmpty) + dst_addr = *controller_get_interface()->get_address(); /* check whether there are any extensions to be forwarded */ if (ext_type) @@ -500,11 +505,11 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { fw_ext_present = false; if (bnep_cb.p_data_buf_cb) { - (*bnep_cb.p_data_buf_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol, - p_buf, fw_ext_present); + (*bnep_cb.p_data_buf_cb)(p_bcb->handle, src_addr, dst_addr, protocol, p_buf, + fw_ext_present); } else if (bnep_cb.p_data_ind_cb) { - (*bnep_cb.p_data_ind_cb)(p_bcb->handle, *p_src_addr, *p_dst_addr, protocol, - p, rem_len, fw_ext_present); + (*bnep_cb.p_data_ind_cb)(p_bcb->handle, src_addr, dst_addr, protocol, p, + rem_len, fw_ext_present); osi_free(p_buf); } } @@ -523,14 +528,14 @@ static void bnep_data_ind(uint16_t l2cap_cid, BT_HDR* p_buf) { void bnep_conn_timer_timeout(void* data) { tBNEP_CONN* p_bcb = (tBNEP_CONN*)data; - LOG_DEBUG( - "BNEP - CCB timeout in state: %d CID: 0x%x flags %x, re_transmit %d", + log::debug( + "BNEP - CCB timeout in state: {} CID: 0x{:x} flags {:x}, re_transmit {}", p_bcb->con_state, p_bcb->l2cap_cid, p_bcb->con_flags, p_bcb->re_transmits); if (p_bcb->con_state == BNEP_STATE_CONN_SETUP) { - LOG_DEBUG("BNEP - CCB timeout in state: %d CID: 0x%x", p_bcb->con_state, - p_bcb->l2cap_cid); + log::debug("BNEP - CCB timeout in state: {} CID: 0x{:x}", p_bcb->con_state, + p_bcb->l2cap_cid); if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) { L2CA_DisconnectReq(p_bcb->l2cap_cid); @@ -554,8 +559,8 @@ void bnep_conn_timer_timeout(void* data) { return; } } else if (p_bcb->con_state != BNEP_STATE_CONNECTED) { - LOG_DEBUG("BNEP - CCB timeout in state: %d CID: 0x%x", p_bcb->con_state, - p_bcb->l2cap_cid); + log::debug("BNEP - CCB timeout in state: {} CID: 0x{:x}", p_bcb->con_state, + p_bcb->l2cap_cid); L2CA_DisconnectReq(p_bcb->l2cap_cid); diff --git a/system/stack/bnep/bnep_utils.cc b/system/stack/bnep/bnep_utils.cc index aeff8e236077c29cead88f8d1c20ddfd7d7888c6..51e5059f296b24a82784263bf8562b0de844d9fb 100644 --- a/system/stack/bnep/bnep_utils.cc +++ b/system/stack/bnep/bnep_utils.cc @@ -22,7 +22,7 @@ * ******************************************************************************/ -#include +#include #include #include @@ -36,6 +36,7 @@ #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +using namespace bluetooth; using bluetooth::Uuid; /******************************************************************************/ @@ -169,8 +170,8 @@ void bnep_send_conn_req(tBNEP_CONN* p_bcb) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE); uint8_t *p, *p_start; - LOG_VERBOSE("%s: sending setup req with dst uuid %s", __func__, - p_bcb->dst_uuid.ToString().c_str()); + log::verbose("sending setup req with dst uuid {}", + p_bcb->dst_uuid.ToString().c_str()); p_buf->offset = L2CAP_MIN_OFFSET; p = p_start = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -198,9 +199,9 @@ void bnep_send_conn_req(tBNEP_CONN* p_bcb) { memcpy(p, p_bcb->src_uuid.To128BitBE().data(), Uuid::kNumBytes128); p += Uuid::kNumBytes128; } else { - LOG_ERROR("%s: uuid: %s, invalid length: %zu", __func__, - p_bcb->dst_uuid.ToString().c_str(), - p_bcb->dst_uuid.GetShortestRepresentationSize()); + log::error("uuid: {}, invalid length: {}", + p_bcb->dst_uuid.ToString().c_str(), + p_bcb->dst_uuid.GetShortestRepresentationSize()); } p_buf->len = (uint16_t)(p - p_start); @@ -221,7 +222,8 @@ void bnep_send_conn_response(tBNEP_CONN* p_bcb, uint16_t resp_code) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE); uint8_t* p; - LOG_DEBUG("BNEP - bnep_send_conn_response for CID: 0x%x", p_bcb->l2cap_cid); + log::debug("BNEP - bnep_send_conn_response for CID: 0x{:x}", + p_bcb->l2cap_cid); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -253,7 +255,7 @@ void bnepu_send_peer_our_filters(tBNEP_CONN* p_bcb) { uint8_t* p; uint16_t xx; - LOG_VERBOSE("BNEP sending peer our filters"); + log::verbose("BNEP sending peer our filters"); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -295,7 +297,7 @@ void bnepu_send_peer_our_multi_filters(tBNEP_CONN* p_bcb) { uint8_t* p; uint16_t xx; - LOG_VERBOSE("BNEP sending peer our multicast filters"); + log::verbose("BNEP sending peer our multicast filters"); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -338,7 +340,7 @@ void bnepu_send_peer_filter_rsp(tBNEP_CONN* p_bcb, uint16_t response_code) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE); uint8_t* p; - LOG_VERBOSE("BNEP sending filter response"); + log::verbose("BNEP sending filter response"); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -369,8 +371,9 @@ void bnep_send_command_not_understood(tBNEP_CONN* p_bcb, uint8_t cmd_code) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE); uint8_t* p; - LOG_VERBOSE("BNEP - bnep_send_command_not_understood for CID: 0x%x, cmd 0x%x", - p_bcb->l2cap_cid, cmd_code); + log::verbose( + "BNEP - bnep_send_command_not_understood for CID: 0x{:x}, cmd 0x{:x}", + p_bcb->l2cap_cid, cmd_code); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -400,10 +403,12 @@ void bnep_send_command_not_understood(tBNEP_CONN* p_bcb, uint8_t cmd_code) { * ******************************************************************************/ void bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) { - LOG_DEBUG("BNEP - bnepu_check_send_packet for CID: 0x%x", p_bcb->l2cap_cid); + log::debug("BNEP - bnepu_check_send_packet for CID: 0x{:x}", + p_bcb->l2cap_cid); if (p_bcb->con_flags & BNEP_FLAGS_L2CAP_CONGESTED) { if (fixed_queue_length(p_bcb->xmit_q) >= BNEP_MAX_XMITQ_DEPTH) { - LOG_WARN("BNEP - congested, dropping buf, CID: 0x%x", p_bcb->l2cap_cid); + log::warn("BNEP - congested, dropping buf, CID: 0x{:x}", + p_bcb->l2cap_cid); osi_free(p_buf); } else { @@ -426,33 +431,36 @@ void bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) { * ******************************************************************************/ void bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol, - const RawAddress* p_src_addr, - const RawAddress* p_dest_addr, bool fw_ext_present) { + const RawAddress& src_addr, + const RawAddress& dest_addr, bool fw_ext_present) { const controller_t* controller = controller_get_interface(); uint8_t ext_bit, *p = (uint8_t*)NULL; uint8_t type = BNEP_FRAME_COMPRESSED_ETHERNET; + RawAddress source_addr = src_addr; ext_bit = fw_ext_present ? 0x80 : 0x00; - if (p_src_addr && *p_src_addr != *controller->get_address()) + if (source_addr != RawAddress::kEmpty && + source_addr != *controller->get_address()) type = BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY; - if (*p_dest_addr != p_bcb->rem_bda) + if (dest_addr != p_bcb->rem_bda) type = (type == BNEP_FRAME_COMPRESSED_ETHERNET) ? BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY : BNEP_FRAME_GENERAL_ETHERNET; - if (!p_src_addr) p_src_addr = controller->get_address(); + if (source_addr == RawAddress::kEmpty) + source_addr = *controller->get_address(); switch (type) { case BNEP_FRAME_GENERAL_ETHERNET: p = bnepu_init_hdr(p_buf, 15, (uint8_t)(ext_bit | BNEP_FRAME_GENERAL_ETHERNET)); - memcpy(p, p_dest_addr->address, BD_ADDR_LEN); + memcpy(p, dest_addr.address, BD_ADDR_LEN); p += BD_ADDR_LEN; - memcpy(p, p_src_addr->address, BD_ADDR_LEN); + memcpy(p, source_addr.address, BD_ADDR_LEN); p += BD_ADDR_LEN; break; @@ -466,7 +474,7 @@ void bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol, p_buf, 9, (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_SRC_ONLY)); - memcpy(p, p_src_addr->address, BD_ADDR_LEN); + memcpy(p, source_addr.address, BD_ADDR_LEN); p += BD_ADDR_LEN; break; @@ -475,7 +483,7 @@ void bnepu_build_bnep_hdr(tBNEP_CONN* p_bcb, BT_HDR* p_buf, uint16_t protocol, p_buf, 9, (uint8_t)(ext_bit | BNEP_FRAME_COMPRESSED_ETHERNET_DEST_ONLY)); - memcpy(p, p_dest_addr->address, BD_ADDR_LEN); + memcpy(p, dest_addr.address, BD_ADDR_LEN); p += BD_ADDR_LEN; break; } @@ -528,12 +536,12 @@ static uint8_t* bnepu_init_hdr(BT_HDR* p_buf, uint16_t hdr_len, ******************************************************************************/ void bnep_process_setup_conn_req(tBNEP_CONN* p_bcb, uint8_t* p_setup, uint8_t len) { - LOG_DEBUG("BNEP - for CID: 0x%x", p_bcb->l2cap_cid); + log::debug("BNEP - for CID: 0x{:x}", p_bcb->l2cap_cid); if (p_bcb->con_state != BNEP_STATE_CONN_SETUP && p_bcb->con_state != BNEP_STATE_SEC_CHECKING && p_bcb->con_state != BNEP_STATE_CONNECTED) { - LOG_ERROR("BNEP - setup request in bad state %d", p_bcb->con_state); + log::error("BNEP - setup request in bad state {}", p_bcb->con_state); bnep_send_conn_response(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED); return; } @@ -541,7 +549,7 @@ void bnep_process_setup_conn_req(tBNEP_CONN* p_bcb, uint8_t* p_setup, /* Check if we already initiated security check or if waiting for user * responce */ if (p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD) { - LOG_WARN( + log::warn( "BNEP - Duplicate Setup message received while doing security check"); return; } @@ -550,8 +558,8 @@ void bnep_process_setup_conn_req(tBNEP_CONN* p_bcb, uint8_t* p_setup, if (p_bcb->con_state != BNEP_STATE_CONNECTED && (!(p_bcb->con_flags & BNEP_FLAGS_SETUP_RCVD)) && (p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) { - LOG_ERROR("BNEP - setup request when we are originator state:%hu", - p_bcb->con_state); + log::error("BNEP - setup request when we are originator state:{}", + p_bcb->con_state); bnep_send_conn_response(p_bcb, BNEP_SETUP_CONN_NOT_ALLOWED); return; } @@ -593,7 +601,7 @@ void bnep_process_setup_conn_req(tBNEP_CONN* p_bcb, uint8_t* p_setup, p_bcb->dst_uuid = Uuid::From128BitBE(p_setup); p_setup += len; } else { - LOG_ERROR("BNEP - Bad UID len %d in ConnReq", len); + log::error("BNEP - Bad UID len {} in ConnReq", len); bnep_send_conn_response(p_bcb, BNEP_SETUP_INVALID_UUID_SIZE); return; } @@ -601,8 +609,8 @@ void bnep_process_setup_conn_req(tBNEP_CONN* p_bcb, uint8_t* p_setup, p_bcb->con_state = BNEP_STATE_SEC_CHECKING; p_bcb->con_flags |= BNEP_FLAGS_SETUP_RCVD; - LOG_DEBUG("BNEP initiating security check for incoming call for uuid %s", - p_bcb->src_uuid.ToString().c_str()); + log::debug("BNEP initiating security check for incoming call for uuid {}", + p_bcb->src_uuid.ToString().c_str()); bnep_sec_check_complete(&p_bcb->rem_bda, BT_TRANSPORT_BR_EDR, p_bcb); } @@ -621,17 +629,17 @@ void bnep_process_setup_conn_responce(tBNEP_CONN* p_bcb, uint8_t* p_setup) { tBNEP_RESULT resp; uint16_t resp_code; - LOG_VERBOSE("BNEP received setup responce"); + log::verbose("BNEP received setup responce"); /* The state should be either SETUP or CONNECTED */ if (p_bcb->con_state != BNEP_STATE_CONN_SETUP) { /* Should we disconnect ? */ - LOG_ERROR("BNEP - setup response in bad state %d", p_bcb->con_state); + log::error("BNEP - setup response in bad state {}", p_bcb->con_state); return; } /* Check if we are the originator */ if (!(p_bcb->con_flags & BNEP_FLAGS_IS_ORIG)) { - LOG_ERROR("BNEP - setup response when we are not originator"); + log::error("BNEP - setup response when we are not originator"); return; } @@ -659,7 +667,7 @@ void bnep_process_setup_conn_responce(tBNEP_CONN* p_bcb, uint8_t* p_setup) { /* Check the responce code */ if (resp_code != BNEP_SETUP_CONN_OK) { if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED) { - LOG_VERBOSE("BNEP - role change response is %d", resp_code); + log::verbose("BNEP - role change response is {}", resp_code); /* Restore the earlier BNEP status */ p_bcb->con_state = BNEP_STATE_CONNECTED; @@ -677,7 +685,7 @@ void bnep_process_setup_conn_responce(tBNEP_CONN* p_bcb, uint8_t* p_setup) { return; } else { - LOG_ERROR("BNEP - setup response %d is not OK", resp_code); + log::error("BNEP - setup response {} is not OK", resp_code); L2CA_DisconnectReq(p_bcb->l2cap_cid); @@ -712,8 +720,8 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, if (p == NULL || rem_len == NULL) { if (rem_len != NULL) *rem_len = 0; - LOG_VERBOSE("%s: invalid packet: p = %p rem_len = %p", __func__, p, - rem_len); + log::verbose("invalid packet: p = {} rem_len = {}", fmt::ptr(p), + fmt::ptr(rem_len)); return NULL; } uint16_t rem_len_orig = *rem_len; @@ -728,37 +736,33 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, control_type = *p++; *rem_len = *rem_len - 1; - LOG_VERBOSE( - "%s: BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d", - __func__, *rem_len, is_ext, control_type); + log::verbose( + "BNEP processing control packet rem_len {}, is_ext {}, ctrl_type {}", + *rem_len, is_ext, control_type); switch (control_type) { case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD: if (*rem_len < 1) { - LOG_ERROR( - "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD with bad length", - __func__); + log::error( + "Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD with bad length"); goto bad_packet_length; } - LOG_ERROR( - "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD for pkt type: %d", - __func__, *p); + log::error( + "Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD for pkt type: {}", *p); p++; *rem_len = *rem_len - 1; break; case BNEP_SETUP_CONNECTION_REQUEST_MSG: if (*rem_len < 1) { - LOG_ERROR( - "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length", - __func__); + log::error( + "Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length"); goto bad_packet_length; } len = *p++; if (*rem_len < ((2 * len) + 1)) { - LOG_ERROR( - "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length", - __func__); + log::error( + "Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length"); goto bad_packet_length; } if (!is_ext) bnep_process_setup_conn_req(p_bcb, p, (uint8_t)len); @@ -768,9 +772,8 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, case BNEP_SETUP_CONNECTION_RESPONSE_MSG: if (*rem_len < 2) { - LOG_ERROR( - "%s: Received BNEP_SETUP_CONNECTION_RESPONSE_MSG with bad length", - __func__); + log::error( + "Received BNEP_SETUP_CONNECTION_RESPONSE_MSG with bad length"); goto bad_packet_length; } if (!is_ext) bnep_process_setup_conn_responce(p_bcb, p); @@ -780,14 +783,12 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, case BNEP_FILTER_NET_TYPE_SET_MSG: if (*rem_len < 2) { - LOG_ERROR("%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length", - __func__); + log::error("Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length"); goto bad_packet_length; } BE_STREAM_TO_UINT16(len, p); if (*rem_len < (len + 2)) { - LOG_ERROR("%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length", - __func__); + log::error("Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length"); goto bad_packet_length; } bnepu_process_peer_filter_set(p_bcb, p, len); @@ -797,9 +798,8 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, case BNEP_FILTER_NET_TYPE_RESPONSE_MSG: if (*rem_len < 2) { - LOG_ERROR( - "%s: Received BNEP_FILTER_NET_TYPE_RESPONSE_MSG with bad length", - __func__); + log::error( + "Received BNEP_FILTER_NET_TYPE_RESPONSE_MSG with bad length"); goto bad_packet_length; } bnepu_process_peer_filter_rsp(p_bcb, p); @@ -809,14 +809,12 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, case BNEP_FILTER_MULTI_ADDR_SET_MSG: if (*rem_len < 2) { - LOG_ERROR("%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length", - __func__); + log::error("Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length"); goto bad_packet_length; } BE_STREAM_TO_UINT16(len, p); if (*rem_len < (len + 2)) { - LOG_ERROR("%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length", - __func__); + log::error("Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length"); goto bad_packet_length; } bnepu_process_peer_multicast_filter_set(p_bcb, p, len); @@ -826,9 +824,8 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG: if (*rem_len < 2) { - LOG_ERROR( - "%s: Received BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG with bad length", - __func__); + log::error( + "Received BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG with bad length"); goto bad_packet_length; } bnepu_process_multicast_filter_rsp(p_bcb, p); @@ -837,7 +834,7 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, break; default: - LOG_ERROR("%s: BNEP - bad ctl pkt type: %d", __func__, control_type); + log::error("BNEP - bad ctl pkt type: {}", control_type); bnep_send_command_not_understood(p_bcb, control_type); if (is_ext && (ext_len > 0)) { if (*rem_len < (ext_len - 1)) { @@ -851,8 +848,8 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p, return p; bad_packet_length: - LOG_ERROR("%s: bad control packet length: original=%d remaining=%d", __func__, - rem_len_orig, *rem_len); + log::error("bad control packet length: original={} remaining={}", + rem_len_orig, *rem_len); *rem_len = 0; return NULL; } @@ -877,15 +874,15 @@ void bnepu_process_peer_filter_set(tBNEP_CONN* p_bcb, uint8_t* p_filters, if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) { - LOG_VERBOSE( + log::verbose( "BNEP received filter set from peer when there is no connection"); return; } - LOG_VERBOSE("BNEP received filter set from peer"); + log::verbose("BNEP received filter set from peer"); /* Check for length not a multiple of 4 */ if (len & 3) { - LOG_VERBOSE("BNEP - bad filter len: %d", len); + log::verbose("BNEP - bad filter len: {}", len); bnepu_send_peer_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE); return; } @@ -941,17 +938,17 @@ void bnepu_process_peer_filter_rsp(tBNEP_CONN* p_bcb, uint8_t* p_data) { uint16_t resp_code; tBNEP_RESULT result; - LOG_VERBOSE("BNEP received filter responce"); + log::verbose("BNEP received filter responce"); /* The state should be CONNECTED */ if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) { - LOG_ERROR("BNEP - filter response in bad state %d", p_bcb->con_state); + log::error("BNEP - filter response in bad state {}", p_bcb->con_state); return; } /* Check if we are the originator */ if (!(p_bcb->con_flags & BNEP_FLAGS_FILTER_RESP_PEND)) { - LOG_ERROR("BNEP - filter response when not expecting"); + log::error("BNEP - filter response when not expecting"); return; } @@ -983,18 +980,18 @@ void bnepu_process_multicast_filter_rsp(tBNEP_CONN* p_bcb, uint8_t* p_data) { uint16_t resp_code; tBNEP_RESULT result; - LOG_VERBOSE("BNEP received multicast filter responce"); + log::verbose("BNEP received multicast filter responce"); /* The state should be CONNECTED */ if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) { - LOG_ERROR("BNEP - multicast filter response in bad state %d", - p_bcb->con_state); + log::error("BNEP - multicast filter response in bad state {}", + p_bcb->con_state); return; } /* Check if we are the originator */ if (!(p_bcb->con_flags & BNEP_FLAGS_MULTI_RESP_PEND)) { - LOG_ERROR("BNEP - multicast filter response when not expecting"); + log::error("BNEP - multicast filter response when not expecting"); return; } @@ -1031,20 +1028,20 @@ void bnepu_process_peer_multicast_filter_set(tBNEP_CONN* p_bcb, if ((p_bcb->con_state != BNEP_STATE_CONNECTED) && (!(p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED))) { - LOG_VERBOSE( + log::verbose( "BNEP received multicast filter set from peer when there is no " "connection"); return; } if (len % 12) { - LOG_VERBOSE("BNEP - bad filter len: %d", len); + log::verbose("BNEP - bad filter len: {}", len); bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_BAD_RANGE); return; } if (len > (BNEP_MAX_MULTI_FILTERS * 2 * BD_ADDR_LEN)) { - LOG_VERBOSE("BNEP - Too many filters"); + log::verbose("BNEP - Too many filters"); bnepu_send_peer_multicast_filter_rsp(p_bcb, BNEP_FILTER_CRL_MAX_REACHED); return; } @@ -1085,7 +1082,7 @@ void bnepu_process_peer_multicast_filter_set(tBNEP_CONN* p_bcb, } } - LOG_VERBOSE("BNEP multicast filters %d", p_bcb->rcvd_mcast_filters); + log::verbose("BNEP multicast filters {}", p_bcb->rcvd_mcast_filters); bnepu_send_peer_multicast_filter_rsp(p_bcb, resp_code); if (bnep_cb.p_mfilter_ind_cb) @@ -1106,7 +1103,7 @@ void bnepu_send_peer_multicast_filter_rsp(tBNEP_CONN* p_bcb, BT_HDR* p_buf = (BT_HDR*)osi_malloc(BNEP_BUF_SIZE); uint8_t* p; - LOG_VERBOSE("BNEP sending multicast filter response %d", response_code); + log::verbose("BNEP sending multicast filter response {}", response_code); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -1147,8 +1144,8 @@ void bnep_sec_check_complete(const RawAddress* bd_addr, tBT_TRANSPORT trasnport, /* check if the port is still waiting for security to complete */ if (p_bcb->con_state != BNEP_STATE_SEC_CHECKING) { - LOG_ERROR("BNEP Connection in wrong state %d when security is completed", - p_bcb->con_state); + log::error("BNEP Connection in wrong state {} when security is completed", + p_bcb->con_state); return; } @@ -1187,7 +1184,7 @@ void bnep_sec_check_complete(const RawAddress* bd_addr, tBT_TRANSPORT trasnport, * ******************************************************************************/ tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, - const RawAddress& p_dest_addr, + const RawAddress& dest_addr, uint16_t protocol, bool fw_ext_present, uint8_t* p_data, uint16_t org_len) { if (p_bcb->rcvd_num_filters) { @@ -1227,13 +1224,13 @@ tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, } if (i == p_bcb->rcvd_num_filters) { - LOG_VERBOSE("Ignoring protocol 0x%x in BNEP data write", proto); + log::verbose("Ignoring protocol 0x{:x} in BNEP data write", proto); return BNEP_IGNORE_CMD; } } /* Ckeck for multicast address filtering */ - if ((p_dest_addr.address[0] & 0x01) && p_bcb->rcvd_mcast_filters) { + if ((dest_addr.address[0] & 0x01) && p_bcb->rcvd_mcast_filters) { uint16_t i; /* Check if every multicast should be filtered */ @@ -1241,9 +1238,9 @@ tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, /* Check if the address is mentioned in the filter range */ for (i = 0; i < p_bcb->rcvd_mcast_filters; i++) { if ((memcmp(p_bcb->rcvd_mcast_filter_start[i].address, - p_dest_addr.address, BD_ADDR_LEN) <= 0) && - (memcmp(p_bcb->rcvd_mcast_filter_end[i].address, - p_dest_addr.address, BD_ADDR_LEN) >= 0)) + dest_addr.address, BD_ADDR_LEN) <= 0) && + (memcmp(p_bcb->rcvd_mcast_filter_end[i].address, dest_addr.address, + BD_ADDR_LEN) >= 0)) break; } } @@ -1255,8 +1252,8 @@ tBNEP_RESULT bnep_is_packet_allowed(tBNEP_CONN* p_bcb, */ if ((p_bcb->rcvd_mcast_filters == 0xFFFF) || (i == p_bcb->rcvd_mcast_filters)) { - VLOG(1) << "Ignoring multicast address " << p_dest_addr - << " in BNEP data write"; + log::verbose("Ignoring multicast address {} in BNEP data write", + ADDRESS_TO_LOGGABLE_STR(dest_addr)); return BNEP_IGNORE_CMD; } } diff --git a/system/stack/btm/ble_scanner_hci_interface.cc b/system/stack/btm/ble_scanner_hci_interface.cc index 79842d9a0357b5a67739feed753a9e532cd05825..9f59be05149c5802bfe7909dacfdf074a3e4de51 100644 --- a/system/stack/btm/ble_scanner_hci_interface.cc +++ b/system/stack/btm/ble_scanner_hci_interface.cc @@ -19,6 +19,7 @@ #include #include +#include #include "btm_api.h" #include "device/include/controller.h" @@ -26,6 +27,8 @@ #include "stack/include/hcimsgs.h" #include "types/raw_address.h" +using namespace bluetooth; + namespace { BleScannerHciInterface* instance = nullptr; @@ -55,7 +58,7 @@ static void status_handle_callback(base::Callback cb, handle = handle & 0x0EFF; } else { - VLOG(1) << __func__ << " hci response error code: " << int{status}; + log::verbose("hci response error code: {}", int{status}); } cb.Run(status, handle); } @@ -135,8 +138,7 @@ class BleScannerImplBase : public BleScannerHciInterface { uint16_t acl_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); if (acl_handle == HCI_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": Wrong mode: no LE link exist or LE not supported"; + log::error("Wrong mode: no LE link exist or LE not supported"); return; } @@ -151,8 +153,7 @@ class BleScannerImplBase : public BleScannerHciInterface { uint16_t acl_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); if (acl_handle == HCI_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": Wrong mode: no LE link exist or LE not supported"; + log::error("Wrong mode: no LE link exist or LE not supported"); return; } @@ -168,8 +169,7 @@ class BleScannerImplBase : public BleScannerHciInterface { uint16_t acl_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); if (acl_handle == HCI_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": Wrong mode: no LE link exist or LE not supported"; + log::error("Wrong mode: no LE link exist or LE not supported"); return; } @@ -246,8 +246,7 @@ class BleScannerSyncTransferImpl : public virtual BleScannerImplBase { uint16_t acl_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); if (acl_handle == HCI_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": Wrong mode: no LE link exist or LE not supported"; + log::error("Wrong mode: no LE link exist or LE not supported"); return; } @@ -262,8 +261,7 @@ class BleScannerSyncTransferImpl : public virtual BleScannerImplBase { uint16_t acl_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); if (acl_handle == HCI_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": Wrong mode: no LE link exist or LE not supported"; + log::error("Wrong mode: no LE link exist or LE not supported"); return; } @@ -279,8 +277,7 @@ class BleScannerSyncTransferImpl : public virtual BleScannerImplBase { uint16_t acl_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); if (acl_handle == HCI_INVALID_HANDLE) { - LOG(ERROR) << __func__ - << ": Wrong mode: no LE link exist or LE not supported"; + log::error("Wrong mode: no LE link exist or LE not supported"); return; } @@ -307,17 +304,17 @@ void BleScannerHciInterface::Initialize() { if ((controller_get_interface()->get_ble_periodic_advertiser_list_size()) && (controller_get_interface() - ->supports_ble_periodic_advertising_sync_transfer_sender())) { - LOG(INFO) << "Advertiser list in controller can be used"; - LOG(INFO) << "Periodic Adv Sync Transfer Sender role is supported"; + ->SupportsBlePeriodicAdvertisingSyncTransferSender())) { + log::info("Advertiser list in controller can be used"); + log::info("Periodic Adv Sync Transfer Sender role is supported"); instance = new BleScannerCompleteImpl(); } else if (controller_get_interface() - ->supports_ble_periodic_advertising_sync_transfer_sender()) { - LOG(INFO) << "Periodic Adv Sync Transfer Sender role is supported"; + ->SupportsBlePeriodicAdvertisingSyncTransferSender()) { + log::info("Periodic Adv Sync Transfer Sender role is supported"); instance = new BleScannerSyncTransferImpl(); } else if (controller_get_interface() ->get_ble_periodic_advertiser_list_size()) { - LOG(INFO) << "Periodic Adv Sync Transfer Recipient role is supported"; + log::info("Periodic Adv Sync Transfer Recipient role is supported"); instance = new BleScannerListImpl(); } // TODO: Implement periodic adv. sync. recipient role if ever needed. diff --git a/system/stack/btm/btm_ble.cc b/system/stack/btm/btm_ble.cc index 7fba96985ace838f5b8814ec49864a449d0acc3f..36d6ddec4624475fb557dc9aa6608acf756c2ad4 100644 --- a/system/stack/btm/btm_ble.cc +++ b/system/stack/btm/btm_ble.cc @@ -25,6 +25,8 @@ #define LOG_TAG "ble" +#include + #include #include "base/functional/bind.h" @@ -38,6 +40,8 @@ #include "stack/include/gatt_api.h" #include "stack/include/hcimsgs.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; /******************************************************************************* @@ -134,7 +138,7 @@ void read_phy_cb( uint8_t status, tx_phy, rx_phy; uint16_t handle; - LOG_ASSERT(len == 5) << "Received bad response length: " << len; + ASSERT_LOG(len == 5, "Received bad response length:%d", len); uint8_t* pp = data; STREAM_TO_UINT8(status, pp); STREAM_TO_UINT16(handle, pp); @@ -161,19 +165,16 @@ void read_phy_cb( void BTM_BleReadPhy( const RawAddress& bd_addr, base::Callback cb) { - LOG_VERBOSE("%s", __func__); - if (!BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { - LOG_ERROR("%s: Wrong mode: no LE link exist or LE not supported", __func__); + log::error("Wrong mode: no LE link exist or LE not supported"); cb.Run(0, 0, HCI_ERR_NO_CONNECTION); return; } // checking if local controller supports it! - if (!controller_get_interface()->supports_ble_2m_phy() && - !controller_get_interface()->supports_ble_coded_phy()) { - LOG_ERROR("%s failed, request not supported in local controller!", - __func__); + if (!controller_get_interface()->SupportsBle2mPhy() && + !controller_get_interface()->SupportsBleCodedPhy()) { + log::error("request not supported in local controller!"); cb.Run(0, 0, GATT_REQ_NOT_SUPPORTED); return; } @@ -186,7 +187,6 @@ void BTM_BleReadPhy( UINT16_TO_STREAM(pp, handle); btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_READ_PHY, data, len, base::Bind(&read_phy_cb, std::move(cb))); - return; } void doNothing(uint8_t* data, uint16_t len) {} @@ -194,7 +194,7 @@ void doNothing(uint8_t* data, uint16_t len) {} void BTM_BleSetPhy(const RawAddress& bd_addr, uint8_t tx_phys, uint8_t rx_phys, uint16_t phy_options) { if (!BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { - LOG_INFO( + log::info( "Unable to set phy preferences because no le acl is connected to " "device"); return; @@ -207,9 +207,10 @@ void BTM_BleSetPhy(const RawAddress& bd_addr, uint8_t tx_phys, uint8_t rx_phys, uint16_t handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); // checking if local controller supports it! - if (!controller_get_interface()->supports_ble_2m_phy() && - !controller_get_interface()->supports_ble_coded_phy()) { - LOG_INFO("Local controller unable to support setting of le phy parameters"); + if (!controller_get_interface()->SupportsBle2mPhy() && + !controller_get_interface()->SupportsBleCodedPhy()) { + log::info( + "Local controller unable to support setting of le phy parameters"); gatt_notify_phy_updated(static_cast(GATT_REQ_NOT_SUPPORTED), handle, tx_phys, rx_phys); return; @@ -217,7 +218,7 @@ void BTM_BleSetPhy(const RawAddress& bd_addr, uint8_t tx_phys, uint8_t rx_phys, if (!acl_peer_supports_ble_2m_phy(handle) && !acl_peer_supports_ble_coded_phy(handle)) { - LOG_INFO("Remote device unable to support setting of le phy parameter"); + log::info("Remote device unable to support setting of le phy parameter"); gatt_notify_phy_updated(static_cast(GATT_REQ_NOT_SUPPORTED), handle, tx_phys, rx_phys); return; diff --git a/system/stack/btm/btm_ble_addr.cc b/system/stack/btm/btm_ble_addr.cc index 8234ecdfc6a7d53d4381a1958f2cca8f34b2ee04..988a3c98316fdce361d7092a399726fc53d76bd3 100644 --- a/system/stack/btm/btm_ble_addr.cc +++ b/system/stack/btm/btm_ble_addr.cc @@ -27,6 +27,7 @@ #include "stack/include/btm_ble_addr.h" #include +#include #include #include "btm_ble_int.h" @@ -43,6 +44,8 @@ #include "types/ble_address_with_type.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; /* This function generates Resolvable Private Address (RPA) from Identity @@ -76,7 +79,7 @@ static RawAddress generate_rpa_from_irk_and_rand(const Octet16& irk, void btm_gen_resolve_paddr_low(const RawAddress& address) { /* when GD advertising and scanning modules are enabled, set random address * via address manager in GD */ - LOG_INFO("GD advertising and scanning modules are enabled, skip"); + log::info("GD advertising and scanning modules are enabled, skip"); } /** This function generate a resolvable private address using local IRK */ @@ -205,9 +208,8 @@ static tBTM_SEC_DEV_REC* btm_find_dev_by_identity_addr( if (p_dev_rec->ble.identity_address_with_type.bda == bd_addr) { if ((p_dev_rec->ble.identity_address_with_type.type & (~BLE_ADDR_TYPE_ID_BIT)) != (addr_type & (~BLE_ADDR_TYPE_ID_BIT))) - LOG_WARN("%s find pseudo->random match with diff addr type: %d vs %d", - __func__, p_dev_rec->ble.identity_address_with_type.type, - addr_type); + log::warn("pseudo->random match with diff addr type: {} vs {}", + p_dev_rec->ble.identity_address_with_type.type, addr_type); /* found the match */ return p_dev_rec; @@ -272,7 +274,7 @@ bool btm_random_pseudo_to_identity_addr(RawAddress* random_pseudo, if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) { *p_identity_addr_type = p_dev_rec->ble.identity_address_with_type.type; *random_pseudo = p_dev_rec->ble.identity_address_with_type.bda; - if (controller_get_interface()->supports_ble_privacy()) + if (controller_get_interface()->SupportsBlePrivacy()) *p_identity_addr_type |= BLE_ADDR_TYPE_ID_BIT; return true; } @@ -294,7 +296,7 @@ void btm_ble_refresh_peer_resolvable_private_addr( tBLE_RAND_ADDR_TYPE rra_type) { tBTM_SEC_DEV_REC* p_sec_rec = btm_find_dev(pseudo_bda); if (p_sec_rec == nullptr) { - LOG_WARN("%s No matching known device in record", __func__); + log::warn("No matching known device in record"); return; } @@ -317,7 +319,7 @@ void btm_ble_refresh_peer_resolvable_private_addr( if (!acl_refresh_remote_address(identity_address, identity_address_type, p_sec_rec->ble.pseudo_addr, rra_type, rpa)) { - LOG_ERROR("%s Unknown device to refresh remote device", __func__); + log::error("Unknown device to refresh remote device"); } } } @@ -342,7 +344,8 @@ bool maybe_resolve_address(RawAddress* bda, tBLE_ADDR_TYPE* bda_type) { if (!is_in_security_db && addr_is_rpa) { tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(*bda); if (match_rec) { - LOG(INFO) << __func__ << ": matched and resolved random address"; + log::info("matched/resolved random address:{}", + ADDRESS_TO_LOGGABLE_CSTR(*bda)); is_in_security_db = true; match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA; match_rec->ble.cur_rand_addr = *bda; @@ -354,7 +357,8 @@ bool maybe_resolve_address(RawAddress* bda, tBLE_ADDR_TYPE* bda_type) { *bda = match_rec->bd_addr; } } else { - LOG(INFO) << __func__ << ": unable to match and resolve random address"; + log::info("unable to match/resolve random address:{}", + ADDRESS_TO_LOGGABLE_CSTR(*bda)); } } return is_in_security_db; diff --git a/system/stack/btm/btm_ble_adv_filter.cc b/system/stack/btm/btm_ble_adv_filter.cc index 1c0cfe7226479fdba4193d5d4de45d076f8cd940..f345c4c2b103baea5212201e9eb64e762cc23020 100644 --- a/system/stack/btm/btm_ble_adv_filter.cc +++ b/system/stack/btm/btm_ble_adv_filter.cc @@ -19,6 +19,7 @@ #define LOG_TAG "bt_btm_ble" #include +#include #include "btm_ble_api.h" #include "os/log.h" @@ -32,6 +33,7 @@ extern tBTM_CB btm_cb; +using namespace bluetooth; using base::Bind; using bluetooth::Uuid; @@ -125,7 +127,7 @@ static uint8_t btm_ble_ocf_to_condtype(uint8_t ocf) { static void btm_flt_update_cb(uint8_t expected_ocf, tBTM_BLE_PF_CFG_CBACK cb, uint8_t* p, uint16_t evt_len) { if (evt_len != 4) { - LOG_ERROR("%s: bad length: %d", __func__, evt_len); + log::error("bad length: {}", evt_len); return; } @@ -136,8 +138,8 @@ static void btm_flt_update_cb(uint8_t expected_ocf, tBTM_BLE_PF_CFG_CBACK cb, STREAM_TO_UINT8(num_avail, p); if (expected_ocf != op_subcode) { - LOG_ERROR("%s: Incorrect opcode: 0x%02x, expected: 0x%02x", __func__, - expected_ocf, op_subcode); + log::error("Incorrect opcode: 0x{:02x}, expected: 0x{:02x}", expected_ocf, + op_subcode); return; } @@ -149,8 +151,8 @@ static void btm_flt_update_cb(uint8_t expected_ocf, tBTM_BLE_PF_CFG_CBACK cb, } uint8_t cond_type = btm_ble_ocf_to_condtype(expected_ocf); - LOG_VERBOSE("%s: Recd: %d, %d, %d, %d, %d", __func__, op_subcode, - expected_ocf, action, status, num_avail); + log::verbose("Recd: {}, {}, {}, {}, {}", op_subcode, expected_ocf, action, + status, num_avail); if (HCI_SUCCESS == status) { if (btm_ble_adv_filt_cb.cur_filter_target.bda.IsEmpty()) btm_ble_cs_update_pf_counter(static_cast(action), @@ -269,7 +271,7 @@ static uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, uint8_t* p_counter = NULL; if (cond_type > BTM_BLE_PF_TYPE_ALL) { - LOG_ERROR("unknown PF filter condition type %d", cond_type); + log::error("unknown PF filter condition type {}", cond_type); return BTM_BLE_INVALID_COUNTER; } @@ -300,13 +302,13 @@ static uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, p_counter = p_addr_filter->pf_counter; if (num_available > 0) p_counter[cond_type] += 1; - LOG_VERBOSE("counter = %d, maxfilt = %d, num_avbl=%d", - p_counter[cond_type], cmn_ble_vsc_cb.max_filter, - num_available); + log::verbose("counter = {}, maxfilt = {}, num_avbl={}", + p_counter[cond_type], cmn_ble_vsc_cb.max_filter, + num_available); return p_counter[cond_type]; } } else { - LOG_ERROR("no matching filter counter found"); + log::error("no matching filter counter found"); } /* no matching filter located and updated */ return BTM_BLE_INVALID_COUNTER; @@ -341,17 +343,17 @@ void BTM_BleAdvFilterParamSetup( p = param; memset(param, 0, len); - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (BTM_BLE_SCAN_COND_ADD == action) { p_bda_filter = btm_ble_find_addr_filter_counter(nullptr); if (NULL == p_bda_filter) { - LOG_ERROR("BD Address not found!"); + log::error("BD Address not found!"); cb.Run(0, BTM_BLE_PF_ENABLE, btm_status_value(BTM_UNKNOWN_ADDR)); return; } - LOG_VERBOSE("%s : Feat mask:%d", __func__, p_filt_params->feat_seln); + log::verbose("Feat mask:{}", p_filt_params->feat_seln); /* select feature based on control block settings */ UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD); diff --git a/system/stack/btm/btm_ble_batchscan.cc b/system/stack/btm/btm_ble_batchscan.cc deleted file mode 100644 index bccdcc4b5b87437ae1dda598294f8272e0a23ecc..0000000000000000000000000000000000000000 --- a/system/stack/btm/btm_ble_batchscan.cc +++ /dev/null @@ -1,589 +0,0 @@ -/****************************************************************************** - * - * Copyright 2014 Broadcom Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ -#define LOG_TAG "ble_batchscan" - -#include -#include -#include -#include - -#include - -#include "btm_ble_api.h" -#include "device/include/controller.h" -#include "os/log.h" -#include "osi/include/allocator.h" -#include "stack/btm/btm_int_types.h" -#include "stack/include/bt_types.h" -#include "stack/include/btm_client_interface.h" -#include "stack/include/btu_hcif.h" - -extern tBTM_CB btm_cb; - -using base::Bind; -using base::Callback; -using hci_cmd_cb = base::Callback; - -tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb; -tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb; - -/* length of each batch scan command */ -#define BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN 4 -#define BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN 12 -#define BTM_BLE_BATCH_SCAN_ENB_DISB_LEN 2 -#define BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN 2 - -namespace { - -bool can_do_batch_scan() { - if (!controller_get_interface()->supports_ble()) return false; - - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - - if (cmn_ble_vsc_cb.tot_scan_results_strg == 0) return false; - - return true; -} - -/* VSE callback for batch scan, filter, and tracking events */ -void btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, - const uint8_t* p) { - tBTM_BLE_TRACK_ADV_DATA adv_data{}; - uint8_t sub_event = 0; - tBTM_BLE_VSC_CB cmn_ble_vsc_cb; - - if (len < 1) - goto err_out; - - STREAM_TO_UINT8(sub_event, p); - len -= 1; - - LOG_VERBOSE( - "btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x", - sub_event); - if (HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT == sub_event && - NULL != ble_batchscan_cb.p_thres_cback) { - ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value); - return; - } - - if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event && - NULL != ble_advtrack_cb.p_track_cback) { - - BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - adv_data.client_if = (uint8_t)ble_advtrack_cb.ref_value; - if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) { - if (len < 10) { - goto err_out; - } - - STREAM_TO_UINT8(adv_data.filt_index, p); - STREAM_TO_UINT8(adv_data.advertiser_state, p); - STREAM_TO_UINT8(adv_data.advertiser_info_present, p); - STREAM_TO_BDADDR(adv_data.bd_addr, p); - STREAM_TO_UINT8(adv_data.addr_type, p); - - len -= 10; - - /* Extract the adv info details */ - if (ADV_INFO_PRESENT == adv_data.advertiser_info_present) { - - if (len < 5) { - goto err_out; - } - - STREAM_TO_UINT8(adv_data.tx_power, p); - STREAM_TO_UINT8(adv_data.rssi_value, p); - STREAM_TO_UINT16(adv_data.time_stamp, p); - STREAM_TO_UINT8(adv_data.adv_pkt_len, p); - - len -= 5; - - if (adv_data.adv_pkt_len > 0) { - adv_data.p_adv_pkt_data = - static_cast(osi_malloc(adv_data.adv_pkt_len)); - if (adv_data.p_adv_pkt_data == nullptr || \ - len < adv_data.adv_pkt_len) { - goto err_out; - } - memcpy(adv_data.p_adv_pkt_data, p, adv_data.adv_pkt_len); - len -= adv_data.adv_pkt_len; - p += adv_data.adv_pkt_len; - } - - STREAM_TO_UINT8(adv_data.scan_rsp_len, p); - if (adv_data.scan_rsp_len > 0) { - adv_data.p_scan_rsp_data = - static_cast(osi_malloc(adv_data.scan_rsp_len)); - - if (adv_data.p_scan_rsp_data == nullptr || len < adv_data.scan_rsp_len) { - goto err_out; - } - memcpy(adv_data.p_scan_rsp_data, p, adv_data.scan_rsp_len); - } - } - } else { - /* Based on L-release version */ - if (len < 9) { - goto err_out; - } - - STREAM_TO_UINT8(adv_data.filt_index, p); - STREAM_TO_UINT8(adv_data.addr_type, p); - STREAM_TO_BDADDR(adv_data.bd_addr, p); - STREAM_TO_UINT8(adv_data.advertiser_state, p); - } - - LOG_VERBOSE("track_adv_vse_cback called: %d, %d, %d", adv_data.filt_index, - adv_data.addr_type, adv_data.advertiser_state); - - // Make sure the device is known - get_btm_client_interface().security.BTM_SecAddBleDevice( - adv_data.bd_addr, BT_DEVICE_TYPE_BLE, - to_ble_addr_type(adv_data.addr_type)); - - ble_advtrack_cb.p_track_cback(&adv_data); - } - - return; - -err_out: - LOG_ERROR("malformatted packet detected"); - - osi_free_and_reset((void **) &adv_data.p_adv_pkt_data); - osi_free_and_reset((void **) &adv_data.p_scan_rsp_data); -} - -void feat_enable_cb(uint8_t* p, uint16_t len) { - if (len < 2) { - LOG_ERROR("%s: wrong length", __func__); - return; - } - - uint8_t status, subcode; - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(subcode, p); - - uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE; - if (subcode != expected_opcode) { - LOG_ERROR("%s: bad subcode, expected: %d got: %d", __func__, - expected_opcode, subcode); - return; - } - - if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_ENABLE_CALLED) - LOG_ERROR("%s: state should be ENABLE_CALLED", __func__); - - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLED_STATE; -} - -void storage_config_cb(Callback cb, uint8_t* p, - uint16_t len) { - if (len < 2) { - LOG_ERROR("%s: wrong length", __func__); - return; - } - - uint8_t status, subcode; - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(subcode, p); - - uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM; - if (subcode != expected_opcode) { - LOG_ERROR("%s: bad subcode, expected: %d got: %d", __func__, - expected_opcode, subcode); - return; - } - - cb.Run(status); -} - -void param_enable_cb(Callback cb, uint8_t* p, - uint16_t len) { - if (len < 2) { - LOG_ERROR("%s: wrong length", __func__); - return; - } - - uint8_t status, subcode; - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(subcode, p); - - uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS; - if (subcode != expected_opcode) { - LOG_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode, - subcode); - return; - } - - cb.Run(status); -} - -void disable_cb(base::Callback cb, uint8_t* p, - uint16_t len) { - if (len < 2) { - LOG_ERROR("%s: wrong length", __func__); - return; - } - - uint8_t status, subcode; - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(subcode, p); - - uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS; - if (subcode != expected_opcode) { - LOG_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode, - subcode); - return; - } - - if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_DISABLE_CALLED) { - LOG_ERROR("%s: state should be DISABLE_CALLED", __func__); - } - - if (BTM_SUCCESS == status) { - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLED_STATE; - } else { - LOG_ERROR("%s: Invalid state after disabled", __func__); - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE; - } - - cb.Run(status); -} - -/** - * This function reads the reports from controller. |scan_mode| is the mode for - * which the reports are to be read - */ -void btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - hci_cmd_cb cb) { - uint8_t len = BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN; - uint8_t param[len]; - memset(param, 0, len); - - uint8_t* pp = param; - UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_READ_RESULTS); - UINT8_TO_STREAM(pp, scan_mode); - - btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb); -} - -/* read reports. data is accumulated in |data_all|, number of records is - * accumulated in |num_records_all| */ -void read_reports_cb(std::vector data_all, uint8_t num_records_all, - tBTM_BLE_SCAN_REP_CBACK cb, uint8_t* p, uint16_t len) { - if (len < 2) { - LOG_ERROR("%s: wrong length", __func__); - return; - } - - uint8_t status, subcode; - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT8(subcode, p); - - uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_READ_RESULTS; - if (subcode != expected_opcode) { - LOG_ERROR("%s: bad subcode, expected: %d got: %d", __func__, - expected_opcode, subcode); - return; - } - - if (len < 4) { - LOG_ERROR("%s: wrong length", __func__); - return; - } - - uint8_t report_format, num_records; - STREAM_TO_UINT8(report_format, p); - STREAM_TO_UINT8(num_records, p); - - LOG_VERBOSE("%s: status=%d,len=%d,rec=%d", __func__, status, len - 4, - num_records); - - if (num_records == 0) { - cb.Run(BTM_SUCCESS, report_format, num_records_all, data_all); - return; - } - - if (len > 4) { - data_all.insert(data_all.end(), p, p + len - 4); - num_records_all += num_records; - - /* More records could be in the buffer and needs to be pulled out */ - btm_ble_read_batchscan_reports( - report_format, base::Bind(&read_reports_cb, std::move(data_all), - num_records_all, std::move(cb))); - } -} - -/** - * This function writes the storage configuration in controller - * - * Parameters batch_scan_full_max - Max storage space (in %) allocated to - * full scanning - * batch_scan_trunc_max - Max storage space (in %) allocated to - * truncated scanning - * batch_scan_notify_threshold - Set up notification level - * based on total space - * - **/ -void btm_ble_set_storage_config(uint8_t batch_scan_full_max, - uint8_t batch_scan_trunc_max, - uint8_t batch_scan_notify_threshold, - hci_cmd_cb cb) { - uint8_t len = BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN; - uint8_t param[len]; - memset(param, 0, len); - - uint8_t* pp = param; - UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM); - UINT8_TO_STREAM(pp, batch_scan_full_max); - UINT8_TO_STREAM(pp, batch_scan_trunc_max); - UINT8_TO_STREAM(pp, batch_scan_notify_threshold); - - btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb); -} - -/* This function writes the batch scan params in controller */ -void btm_ble_set_batchscan_param(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - uint32_t scan_interval, uint32_t scan_window, - tBLE_ADDR_TYPE addr_type, - tBTM_BLE_DISCARD_RULE discard_rule, - hci_cmd_cb cb) { - // Override param and decide addr_type based on own addr type - // TODO: Remove upper layer parameter? - addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type; - - uint8_t len = BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN; - uint8_t param[len]; - memset(param, 0, len); - - uint8_t* p = param; - UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_SET_PARAMS); - UINT8_TO_STREAM(p, scan_mode); - UINT32_TO_STREAM(p, scan_window); - UINT32_TO_STREAM(p, scan_interval); - UINT8_TO_STREAM(p, addr_type); - UINT8_TO_STREAM(p, discard_rule); - - btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb); -} - -/* This function enables the customer specific feature in controller */ -void btm_ble_enable_batchscan(hci_cmd_cb cb) { - uint8_t len = BTM_BLE_BATCH_SCAN_ENB_DISB_LEN; - uint8_t param[len]; - memset(param, 0, len); - - uint8_t* p = param; - UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE); - UINT8_TO_STREAM(p, 0x01 /* enable */); - - btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN, param, len, cb); -} - -} // namespace - -/******************************************************************************* - * - * Description This function is called to write storage config params. - * - * Parameters: batch_scan_full_max - Max storage space (in %) allocated to - * full style - * batch_scan_trunc_max - Max storage space (in %) allocated to - * trunc style - * batch_scan_notify_threshold - Setup notification level based - * on total space - * cb - Setup callback pointer - * p_thres_cback - Threshold callback pointer - * ref_value - Reference value - * - ******************************************************************************/ -void BTM_BleSetStorageConfig(uint8_t batch_scan_full_max, - uint8_t batch_scan_trunc_max, - uint8_t batch_scan_notify_threshold, - Callback cb, - tBTM_BLE_SCAN_THRESHOLD_CBACK* p_thres_cback, - tBTM_BLE_REF_VALUE ref_value) { - if (!can_do_batch_scan()) { - cb.Run(BTM_ERR_PROCESSING); - return; - } - - LOG_VERBOSE("%s: %d, %d, %d, %d, %d", __func__, ble_batchscan_cb.cur_state, - ref_value, batch_scan_full_max, batch_scan_trunc_max, - batch_scan_notify_threshold); - - ble_batchscan_cb.p_thres_cback = p_thres_cback; - ble_batchscan_cb.ref_value = ref_value; - - if (batch_scan_full_max > BTM_BLE_ADV_SCAN_FULL_MAX || - batch_scan_trunc_max > BTM_BLE_ADV_SCAN_TRUNC_MAX || - batch_scan_notify_threshold > BTM_BLE_ADV_SCAN_THR_MAX) { - LOG_ERROR("Illegal set storage config params"); - cb.Run(BTM_ILLEGAL_VALUE); - return; - } - - if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) { - btm_ble_enable_batchscan(Bind(&feat_enable_cb)); - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED; - } - - btm_ble_set_storage_config(batch_scan_full_max, batch_scan_trunc_max, - batch_scan_notify_threshold, - Bind(&storage_config_cb, cb)); - return; -} - -/* This function is called to configure and enable batch scanning */ -void BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - uint32_t scan_interval, uint32_t scan_window, - tBLE_ADDR_TYPE addr_type, - tBTM_BLE_DISCARD_RULE discard_rule, - Callback cb) { - LOG_VERBOSE("%s: %d, %d, %d, %d, %d", __func__, scan_mode, scan_interval, - scan_window, addr_type, discard_rule); - - if (!can_do_batch_scan()) { - cb.Run(BTM_ERR_PROCESSING); - return; - } - - LOG_VERBOSE("%s: %d, %x, %x, %d, %d", __func__, scan_mode, scan_interval, - scan_window, discard_rule, ble_batchscan_cb.cur_state); - - /* Only 16 bits will be used for scan interval and scan window as per - * agreement with Google */ - /* So the standard LE range would suffice for scan interval and scan window */ - if ((BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN, - BTM_BLE_SCAN_INT_MAX) || - BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN, - BTM_BLE_SCAN_WIN_MAX)) && - (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode || - BTM_BLE_BATCH_SCAN_MODE_ACTI == scan_mode || - BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI == scan_mode) && - (BTM_BLE_DISCARD_OLD_ITEMS == discard_rule || - BTM_BLE_DISCARD_LOWER_RSSI_ITEMS == discard_rule)) { - } else { - LOG_ERROR("%s: Illegal enable scan params", __func__); - cb.Run(BTM_ILLEGAL_VALUE); - return; - } - - if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state || - BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) { - btm_ble_enable_batchscan(Bind(&feat_enable_cb)); - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED; - } - - ble_batchscan_cb.scan_mode = scan_mode; - ble_batchscan_cb.scan_interval = scan_interval; - ble_batchscan_cb.scan_window = scan_window; - ble_batchscan_cb.addr_type = addr_type; - ble_batchscan_cb.discard_rule = discard_rule; - /* This command starts batch scanning, if enabled */ - btm_ble_set_batchscan_param(scan_mode, scan_interval, scan_window, addr_type, - discard_rule, Bind(¶m_enable_cb, cb)); -} - -/* This function is called to disable batch scanning */ -void BTM_BleDisableBatchScan(base::Callback cb) { - LOG_VERBOSE(" BTM_BleDisableBatchScan"); - - if (!can_do_batch_scan()) { - cb.Run(BTM_ERR_PROCESSING); - return; - } - - btm_ble_set_batchscan_param( - BTM_BLE_BATCH_SCAN_MODE_DISABLE, ble_batchscan_cb.scan_interval, - ble_batchscan_cb.scan_window, ble_batchscan_cb.addr_type, - ble_batchscan_cb.discard_rule, Bind(&disable_cb, cb)); - ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLE_CALLED; -} - -/* This function is called to start reading batch scan reports */ -void BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - tBTM_BLE_SCAN_REP_CBACK cb) { - uint8_t read_scan_mode = 0; - - LOG_VERBOSE("%s; %d", __func__, scan_mode); - - if (!can_do_batch_scan()) { - LOG_ERROR("Controller does not support batch scan"); - cb.Run(BTM_ERR_PROCESSING, 0, 0, {}); - return; - } - - /* Check if the requested scan mode has already been setup by the user */ - read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_ACTI; - if (0 == read_scan_mode) - read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_PASS; - - /* Check only for modes, as scan reports can be called after disabling batch - * scan */ - if (scan_mode != BTM_BLE_BATCH_SCAN_MODE_PASS && - scan_mode != BTM_BLE_BATCH_SCAN_MODE_ACTI) { - LOG_ERROR("Illegal read scan params: %d, %d, %d", read_scan_mode, scan_mode, - ble_batchscan_cb.cur_state); - cb.Run(BTM_ILLEGAL_VALUE, 0, 0, {}); - return; - } - - btm_ble_read_batchscan_reports( - scan_mode, base::Bind(&read_reports_cb, std::vector(), 0, cb)); - return; -} - -/* This function is called to setup the callback for tracking */ -void BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK* p_track_cback, - tBTM_BLE_REF_VALUE ref_value) { - LOG_VERBOSE("%s:", __func__); - - if (!can_do_batch_scan()) { - LOG_ERROR("Controller does not support batch scan"); - - tBTM_BLE_TRACK_ADV_DATA track_adv_data; - memset(&track_adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA)); - track_adv_data.advertiser_info_present = - NO_ADV_INFO_PRESENT; /* Indicates failure */ - track_adv_data.client_if = (uint8_t)ref_value; - p_track_cback(&track_adv_data); - return; - } - - ble_advtrack_cb.p_track_cback = p_track_cback; - ble_advtrack_cb.ref_value = ref_value; - return; -} - -/** - * This function initialize the batch scan control block. - **/ -void btm_ble_batchscan_init(void) { - LOG_VERBOSE(" btm_ble_batchscan_init"); - memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB)); - memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB)); - BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, true); -} diff --git a/system/stack/btm/btm_ble_bgconn.cc b/system/stack/btm/btm_ble_bgconn.cc index d1c70db45a7db082d0ffd05ffd8140d0adedcaaa..487359adf8f81c89ee3cc3e56fe1972c11a50ef0 100644 --- a/system/stack/btm/btm_ble_bgconn.cc +++ b/system/stack/btm/btm_ble_bgconn.cc @@ -26,6 +26,8 @@ #include "stack/btm/btm_ble_bgconn.h" +#include + #include #include @@ -37,6 +39,8 @@ #include "stack/btm/btm_int_types.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; // Unfortunately (for now?) we have to maintain a copy of the device acceptlist @@ -70,57 +74,25 @@ static std::unordered_map * Description This function updates the filter policy of scanner ******************************************************************************/ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) { - tBTM_BLE_INQ_CB* p_inq = &btm_cb.ble_ctr_cb.inq_var; - - uint32_t scan_interval = - !p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval; - uint32_t scan_window = - !p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window; - - LOG_VERBOSE("%s", __func__); - - p_inq->sfp = scan_policy; - p_inq->scan_type = p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE - ? BTM_BLE_SCAN_MODE_ACTI - : p_inq->scan_type; - - btm_send_hci_set_scan_params( - p_inq->scan_type, (uint16_t)scan_interval, (uint16_t)scan_window, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, scan_policy); -} - -/******************************************************************************* - * - * Function btm_ble_suspend_bg_conn - * - * Description This function is to suspend an active background connection - * procedure. - * - * Parameters none. - * - * Returns none. - * - ******************************************************************************/ -bool btm_ble_suspend_bg_conn(void) { - LOG_DEBUG("Gd acl_manager handles sync of background connections"); - return true; -} - -/******************************************************************************* - * - * Function btm_ble_resume_bg_conn - * - * Description This function is to resume a background auto connection - * procedure. - * - * Parameters none. - * - * Returns none. - * - ******************************************************************************/ -bool btm_ble_resume_bg_conn(void) { - LOG_DEBUG("Gd acl_manager handles sync of background connections"); - return true; + uint32_t scan_interval = !btm_cb.ble_ctr_cb.inq_var.scan_interval + ? BTM_BLE_GAP_DISC_SCAN_INT + : btm_cb.ble_ctr_cb.inq_var.scan_interval; + uint32_t scan_window = !btm_cb.ble_ctr_cb.inq_var.scan_window + ? BTM_BLE_GAP_DISC_SCAN_WIN + : btm_cb.ble_ctr_cb.inq_var.scan_window; + + log::verbose(""); + + btm_cb.ble_ctr_cb.inq_var.sfp = scan_policy; + btm_cb.ble_ctr_cb.inq_var.scan_type = + btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_NONE + ? BTM_BLE_SCAN_MODE_ACTI + : btm_cb.ble_ctr_cb.inq_var.scan_type; + + btm_send_hci_set_scan_params(btm_cb.ble_ctr_cb.inq_var.scan_type, + (uint16_t)scan_interval, (uint16_t)scan_window, + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, + scan_policy); } /** Adds the device into acceptlist. Returns false if acceptlist is full and @@ -133,8 +105,8 @@ bool BTM_AcceptlistAdd(const RawAddress& address) { * connect parameters. Returns false if acceptlist is full and device can't * be added, true otherwise. */ bool BTM_AcceptlistAdd(const RawAddress& address, bool is_direct) { - if (!controller_get_interface()->supports_ble()) { - LOG_WARN("Controller does not support Le"); + if (!controller_get_interface()->SupportsBle()) { + log::warn("Controller does not support Le"); return false; } @@ -144,8 +116,8 @@ bool BTM_AcceptlistAdd(const RawAddress& address, bool is_direct) { /** Removes the device from acceptlist */ void BTM_AcceptlistRemove(const RawAddress& address) { - if (!controller_get_interface()->supports_ble()) { - LOG_WARN("Controller does not support Le"); + if (!controller_get_interface()->SupportsBle()) { + log::warn("Controller does not support Le"); return; } @@ -156,8 +128,8 @@ void BTM_AcceptlistRemove(const RawAddress& address) { /** Clear the acceptlist, end any pending acceptlist connections */ void BTM_AcceptlistClear() { - if (!controller_get_interface()->supports_ble()) { - LOG_WARN("Controller does not support Le"); + if (!controller_get_interface()->SupportsBle()) { + log::warn("Controller does not support Le"); return; } bluetooth::shim::ACL_IgnoreAllLeConnections(); diff --git a/system/stack/btm/btm_ble_cont_energy.cc b/system/stack/btm/btm_ble_cont_energy.cc index ef7600382e4520a8754550448fcec333dc29d262..c61918f8b01a08d111de0f0dd3777afa59d56100 100644 --- a/system/stack/btm/btm_ble_cont_energy.cc +++ b/system/stack/btm/btm_ble_cont_energy.cc @@ -18,15 +18,18 @@ #define LOG_TAG "btm_ble_cont_energy" +#include #include #include -#include "bt_target.h" #include "btm_ble_api.h" +#include "internal_include/bt_target.h" #include "os/log.h" #include "stack/btm/btm_int_types.h" #include "stack/include/bt_types.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; tBTM_BLE_ENERGY_INFO_CB ble_energy_info_cb; @@ -49,7 +52,7 @@ static void btm_ble_cont_energy_cmpl_cback(tBTM_VSC_CMPL* p_params) { total_energy_used = 0; if (len < 17) { - LOG_ERROR("wrong length for btm_ble_cont_energy_cmpl_cback"); + log::error("wrong length for btm_ble_cont_energy_cmpl_cback"); return; } @@ -61,10 +64,9 @@ static void btm_ble_cont_energy_cmpl_cback(tBTM_VSC_CMPL* p_params) { STREAM_TO_UINT32(total_idle_time, p); STREAM_TO_UINT32(total_energy_used, p); - LOG_VERBOSE("energy_info status=%d,tx_t=%" PRId32 ", rx_t=%" PRId32 - ", ener_used=%" PRId32 ", idle_t=%" PRId32, - status, total_tx_time, total_rx_time, total_energy_used, - total_idle_time); + log::verbose( + "energy_info status={},tx_t={}, rx_t={}, ener_used={}, idle_t={}", status, + total_tx_time, total_rx_time, total_energy_used, total_idle_time); if (NULL != ble_energy_info_cb.p_ener_cback) ble_energy_info_cb.p_ener_cback(total_tx_time, total_rx_time, @@ -90,10 +92,10 @@ tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK* p_ener_cback) { BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); - LOG_VERBOSE("BTM_BleGetEnergyInfo"); + log::verbose("BTM_BleGetEnergyInfo"); if (0 == cmn_ble_vsc_cb.energy_support) { - LOG_ERROR("Controller does not support get energy info"); + log::error("Controller does not support get energy info"); return BTM_ERR_PROCESSING; } diff --git a/system/stack/btm/btm_ble_gap.cc b/system/stack/btm/btm_ble_gap.cc index ac24e99a216c50be92756829453f5d10f1758380..577e5b3433cc05ba0b0e6ffa5f5ecfd006b158cb 100644 --- a/system/stack/btm/btm_ble_gap.cc +++ b/system/stack/btm/btm_ble_gap.cc @@ -24,10 +24,11 @@ #define LOG_TAG "bt_btm_ble" +#include #include #include -#include #include +#include #include #include @@ -39,7 +40,11 @@ #include "bta/include/bta_api.h" #include "common/time_util.h" #include "device/include/controller.h" +#include "hci/controller.h" +#include "hci/controller_interface.h" +#include "include/check.h" #include "main/shim/acl_api.h" +#include "main/shim/entry.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "osi/include/properties.h" @@ -55,6 +60,7 @@ #include "stack/include/acl_api.h" #include "stack/include/advertise_data_parser.h" #include "stack/include/ble_scanner.h" +#include "stack/include/bt_dev_class.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "stack/include/btm_api_types.h" @@ -67,10 +73,11 @@ #include "types/ble_address_with_type.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; void btm_inq_remote_name_timer_timeout(void* data); -void btm_ble_batchscan_init(void); void btm_ble_adv_filter_init(void); #define BTM_EXT_BLE_RMT_NAME_TIMEOUT_MS (30 * 1000) @@ -96,6 +103,8 @@ static void btm_ble_stop_scan(); static tBTM_STATUS btm_ble_stop_adv(void); static tBTM_STATUS btm_ble_start_adv(void); +using bluetooth::shim::GetController; + namespace { constexpr char kBtmLogTag[] = "SCAN"; @@ -489,6 +498,16 @@ void BTM_BleTargetAnnouncementObserve(bool enable, } } +std::pair +get_low_latency_scan_params() { + uint16_t scan_interval = osi_property_get_int32(kPropertyInquiryScanInterval, + BTM_BLE_LOW_LATENCY_SCAN_INT); + uint16_t scan_window = osi_property_get_int32(kPropertyInquiryScanWindow, + BTM_BLE_LOW_LATENCY_SCAN_WIN); + + return std::make_pair(scan_interval, scan_window); +} + /******************************************************************************* * * Function BTM_BleObserve @@ -509,24 +528,27 @@ void BTM_BleTargetAnnouncementObserve(bool enable, tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, tBTM_INQ_RESULTS_CB* p_results_cb, tBTM_CMPL_CB* p_cmpl_cb, bool low_latency_scan) { - tBTM_BLE_INQ_CB* p_inq = &btm_cb.ble_ctr_cb.inq_var; tBTM_STATUS status = BTM_WRONG_MODE; - uint32_t scan_interval = - !p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval; - uint32_t scan_window = - !p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window; + uint16_t scan_interval = !btm_cb.ble_ctr_cb.inq_var.scan_interval + ? BTM_BLE_GAP_DISC_SCAN_INT + : btm_cb.ble_ctr_cb.inq_var.scan_interval; + uint16_t scan_window = !btm_cb.ble_ctr_cb.inq_var.scan_window + ? BTM_BLE_GAP_DISC_SCAN_WIN + : btm_cb.ble_ctr_cb.inq_var.scan_window; // use low latency scanning if the scanning is active + uint16_t ll_scan_interval, ll_scan_window; + std::tie(ll_scan_interval, ll_scan_window) = get_low_latency_scan_params(); if (low_latency_scan) { - scan_interval = BTM_BLE_LOW_LATENCY_SCAN_INT; - scan_window = BTM_BLE_LOW_LATENCY_SCAN_WIN; + std::tie(scan_interval, scan_window) = + std::tie(ll_scan_interval, ll_scan_window); } - LOG_VERBOSE("%s : scan_type:%d, %d, %d", __func__, p_inq->scan_type, - scan_interval, scan_window); + log::verbose("scan_type:{}, {}, {}", btm_cb.ble_ctr_cb.inq_var.scan_type, + scan_interval, scan_window); - if (!controller_get_interface()->supports_ble()) return BTM_ILLEGAL_VALUE; + if (!controller_get_interface()->SupportsBle()) return BTM_ILLEGAL_VALUE; if (start) { /* shared inquiry database, do not allow observe if any inquiry is active. @@ -537,12 +559,12 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, if (alarm_is_scheduled(btm_cb.ble_ctr_cb.observer_timer)) { alarm_cancel(btm_cb.ble_ctr_cb.observer_timer); } else { - LOG_ERROR("%s Scan with no duration started twice!", __func__); + log::error("Scan with no duration started twice!"); } } else { if (!low_latency_scan && alarm_is_scheduled(btm_cb.ble_ctr_cb.observer_timer)) { - LOG_ERROR("%s Scan with duration started twice!", __func__); + log::error("Scan with duration started twice!"); } } /* @@ -551,11 +573,11 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, * 2. current ongoing scanning is low latency */ bool is_ongoing_low_latency = - p_inq->scan_interval == BTM_BLE_GAP_DISC_SCAN_INT && - p_inq->scan_window == BTM_BLE_LOW_LATENCY_SCAN_WIN; + btm_cb.ble_ctr_cb.inq_var.scan_interval == ll_scan_interval && + btm_cb.ble_ctr_cb.inq_var.scan_window == ll_scan_window; if (!low_latency_scan || is_ongoing_low_latency) { - LOG_WARN("%s Observer was already active, is_low_latency: %d", __func__, - is_ongoing_low_latency); + log::warn("Observer was already active, is_low_latency: {}", + is_ongoing_low_latency); return BTM_CMD_STARTED; } // stop any scan without low latency config @@ -570,12 +592,14 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, if (!btm_cb.ble_ctr_cb.is_ble_scan_active()) { /* allow config of scan type */ cache.ClearAll(); - p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) - ? BTM_BLE_SCAN_MODE_ACTI - : p_inq->scan_type; + btm_cb.ble_ctr_cb.inq_var.scan_type = + (btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_NONE) + ? BTM_BLE_SCAN_MODE_ACTI + : btm_cb.ble_ctr_cb.inq_var.scan_type; btm_send_hci_set_scan_params( - p_inq->scan_type, (uint16_t)scan_interval, (uint16_t)scan_window, - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, BTM_BLE_DEFAULT_SFP); + btm_cb.ble_ctr_cb.inq_var.scan_type, (uint16_t)scan_interval, + (uint16_t)scan_window, btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, + BTM_BLE_DEFAULT_SFP); btm_ble_start_scan(); } @@ -609,7 +633,7 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, status = BTM_CMD_STARTED; btm_ble_stop_observe(); } else { - LOG_ERROR("%s Observe not active", __func__); + log::error("Observe not active"); } return status; @@ -617,11 +641,10 @@ tBTM_STATUS BTM_BleObserve(bool start, uint8_t duration, static void btm_get_dynamic_audio_buffer_vsc_cmpl_cback( tBTM_VSC_CMPL* p_vsc_cmpl_params) { - LOG(INFO) << __func__; + log::info(""); if (p_vsc_cmpl_params->param_len < 1) { - LOG(ERROR) << __func__ - << ": The length of returned parameters is less than 1"; + log::error("The length of returned parameters is less than 1"); return; } uint8_t* p_event_param_buf = p_vsc_cmpl_params->p_param_buf; @@ -636,24 +659,22 @@ static void btm_get_dynamic_audio_buffer_vsc_cmpl_cback( // Audio_Codec_Buffer_Time | 192 octet| Default/Max/Min buffer time STREAM_TO_UINT8(status, p_event_param_buf); if (status != HCI_SUCCESS) { - LOG(ERROR) << __func__ - << ": Fail to configure DFTB. status: " << loghex(status); + log::error("Fail to configure DFTB. status: {}", loghex(status)); return; } if (p_vsc_cmpl_params->param_len != 198) { - LOG(FATAL) << __func__ - << ": The length of returned parameters is not equal to 198: " - << std::to_string(p_vsc_cmpl_params->param_len); + log::fatal("The length of returned parameters is not equal to 198: {}", + p_vsc_cmpl_params->param_len); return; } STREAM_TO_UINT8(opcode, p_event_param_buf); - LOG(INFO) << __func__ << ": opcode = " << loghex(opcode); + log::info("opcode = {}", loghex(opcode)); if (opcode == 0x01) { STREAM_TO_UINT32(codec_mask, p_event_param_buf); - LOG(INFO) << __func__ << ": codec_mask = " << loghex(codec_mask); + log::info("codec_mask = {}", loghex(codec_mask)); for (int i = 0; i < BTM_CODEC_TYPE_MAX_RECORDS; i++) { STREAM_TO_UINT16(btm_cb.dynamic_audio_buffer_cb[i].default_buffer_time, @@ -664,7 +685,7 @@ static void btm_get_dynamic_audio_buffer_vsc_cmpl_cback( p_event_param_buf); } - LOG(INFO) << __func__ << ": Succeed to receive Media Tx Buffer."; + log::info("Succeed to receive Media Tx Buffer."); } } @@ -679,7 +700,7 @@ static void btm_get_dynamic_audio_buffer_vsc_cmpl_cback( ******************************************************************************/ static void btm_ble_vendor_capability_vsc_cmpl_cback( tBTM_VSC_CMPL* p_vcs_cplt_params) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* Check status of command complete event */ CHECK(p_vcs_cplt_params->opcode == HCI_BLE_VENDOR_CAP); @@ -691,7 +712,7 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback( tHCI_STATUS status = to_hci_status_code(raw_status); if (status != HCI_SUCCESS) { - LOG_VERBOSE("%s: Status = 0x%02x (0 is success)", __func__, status); + log::verbose("Status = 0x{:02x} (0 is success)", status); return; } CHECK(p_vcs_cplt_params->param_len >= BTM_VSC_CHIP_CAPABILITY_RSP_LEN); @@ -717,10 +738,10 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback( * If the device has a BT firmware that advertises compliance with Marshmallow * LE capabilities but fails to pass the minimum expected response length, skip * checking its reported response length against the minimum expected by M_RELEASE - * if said device is known to have Bluetooth working again by simply skipping past + * if said device is known to have Bluetooth working again by simply skipping past * this, and has the respective system property set. */ - if(!property_get_bool("bluetooth.device.m_rsplen_workaround", false)) { + if (!property_get_bool("bluetooth.device.m_rsplen_workaround", false)) { CHECK(p_vcs_cplt_params->param_len >= BTM_VSC_CHIP_CAPABILITY_RSP_LEN_M_RELEASE); } @@ -764,24 +785,22 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback( btm_cb.cmn_ble_vsc_cb.values_read = true; - LOG_VERBOSE("%s: stat=%d, irk=%d, ADV ins:%d, rpa=%d, ener=%d, ext_scan=%d", - __func__, status, btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, - btm_cb.cmn_ble_vsc_cb.adv_inst_max, - btm_cb.cmn_ble_vsc_cb.rpa_offloading, - btm_cb.cmn_ble_vsc_cb.energy_support, - btm_cb.cmn_ble_vsc_cb.extended_scan_support); + log::verbose("stat={}, irk={}, ADV ins:{}, rpa={}, ener={}, ext_scan={}", + status, btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, + btm_cb.cmn_ble_vsc_cb.adv_inst_max, + btm_cb.cmn_ble_vsc_cb.rpa_offloading, + btm_cb.cmn_ble_vsc_cb.energy_support, + btm_cb.cmn_ble_vsc_cb.extended_scan_support); if (btm_cb.cmn_ble_vsc_cb.max_filter > 0) btm_ble_adv_filter_init(); /* VS capability included and non-4.2 device */ - if (controller_get_interface()->supports_ble() && - controller_get_interface()->supports_ble_privacy() && + if (controller_get_interface()->SupportsBle() && + controller_get_interface()->SupportsBlePrivacy() && btm_cb.cmn_ble_vsc_cb.max_irk_list_sz > 0 && controller_get_interface()->get_ble_resolving_list_max_size() == 0) btm_ble_resolving_list_init(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz); - if (btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg > 0) btm_ble_batchscan_init(); - if (p_ctrl_le_feature_rd_cmpl_cback != NULL) p_ctrl_le_feature_rd_cmpl_cback(static_cast(status)); } @@ -805,7 +824,7 @@ void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB* p_cmn_vsc_cb) { void BTM_BleGetDynamicAudioBuffer( tBTM_BT_DYNAMIC_AUDIO_BUFFER_CB p_dynamic_audio_buffer_cb[]) { - LOG_VERBOSE("BTM_BleGetDynamicAudioBuffer"); + log::verbose("BTM_BleGetDynamicAudioBuffer"); if (NULL != p_dynamic_audio_buffer_cb) { for (int i = 0; i < 32; i++) { @@ -831,11 +850,96 @@ void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK* p_vsc_cback) { if (btm_cb.cmn_ble_vsc_cb.values_read) return; - LOG_VERBOSE("BTM_BleReadControllerFeatures"); + log::verbose("BTM_BleReadControllerFeatures"); + + if (IS_FLAG_ENABLED(report_vsc_data_from_the_gd_controller)) { + btm_cb.cmn_ble_vsc_cb.values_read = true; + bluetooth::hci::Controller::VendorCapabilities vendor_capabilities = + GetController()->GetVendorCapabilities(); + + btm_cb.cmn_ble_vsc_cb.adv_inst_max = + vendor_capabilities.max_advt_instances_; + btm_cb.cmn_ble_vsc_cb.rpa_offloading = + vendor_capabilities.offloaded_resolution_of_private_address_; + btm_cb.cmn_ble_vsc_cb.tot_scan_results_strg = + vendor_capabilities.total_scan_results_storage_; + btm_cb.cmn_ble_vsc_cb.max_irk_list_sz = + vendor_capabilities.max_irk_list_sz_; + btm_cb.cmn_ble_vsc_cb.filter_support = + vendor_capabilities.filtering_support_; + btm_cb.cmn_ble_vsc_cb.max_filter = vendor_capabilities.max_filter_; + btm_cb.cmn_ble_vsc_cb.energy_support = + vendor_capabilities.activity_energy_info_support_; + + btm_cb.cmn_ble_vsc_cb.version_supported = + vendor_capabilities.version_supported_; + btm_cb.cmn_ble_vsc_cb.total_trackable_advertisers = + vendor_capabilities.total_num_of_advt_tracked_; + btm_cb.cmn_ble_vsc_cb.extended_scan_support = + vendor_capabilities.extended_scan_support_; + btm_cb.cmn_ble_vsc_cb.debug_logging_supported = + vendor_capabilities.debug_logging_supported_; + + btm_cb.cmn_ble_vsc_cb.le_address_generation_offloading_support = + vendor_capabilities.le_address_generation_offloading_support_; + btm_cb.cmn_ble_vsc_cb.a2dp_source_offload_capability_mask = + vendor_capabilities.a2dp_source_offload_capability_mask_; + btm_cb.cmn_ble_vsc_cb.quality_report_support = + vendor_capabilities.bluetooth_quality_report_support_; + btm_cb.cmn_ble_vsc_cb.dynamic_audio_buffer_support = + vendor_capabilities.dynamic_audio_buffer_support_; + btm_cb.cmn_ble_vsc_cb.a2dp_offload_v2_support = + vendor_capabilities.a2dp_offload_v2_support_; + + if (vendor_capabilities.dynamic_audio_buffer_support_) { + std::array + capabilities = GetController()->GetDabCodecCapabilities(); + + for (size_t i = 0; i < capabilities.size(); i++) { + btm_cb.dynamic_audio_buffer_cb[i].default_buffer_time = + capabilities[i].default_time_ms_; + btm_cb.dynamic_audio_buffer_cb[i].maximum_buffer_time = + capabilities[i].maximum_time_ms_; + btm_cb.dynamic_audio_buffer_cb[i].minimum_buffer_time = + capabilities[i].minimum_time_ms_; + } + } + + if (btm_cb.cmn_ble_vsc_cb.filter_support == 1 && + GetController()->GetLocalVersionInformation().manufacturer_name_ == + LMP_COMPID_QTI) { + // QTI controller, TDS data filter are supported by default. + btm_cb.cmn_ble_vsc_cb.adv_filter_extended_features_mask = 0x01; + } else { + btm_cb.cmn_ble_vsc_cb.adv_filter_extended_features_mask = 0x00; + } + + log::verbose("irk={}, ADV ins:{}, rpa={}, ener={}, ext_scan={}", + btm_cb.cmn_ble_vsc_cb.max_irk_list_sz, + btm_cb.cmn_ble_vsc_cb.adv_inst_max, + btm_cb.cmn_ble_vsc_cb.rpa_offloading, + btm_cb.cmn_ble_vsc_cb.energy_support, + btm_cb.cmn_ble_vsc_cb.extended_scan_support); + + if (btm_cb.cmn_ble_vsc_cb.max_filter > 0) btm_ble_adv_filter_init(); + + /* VS capability included and non-4.2 device */ + if (GetController()->SupportsBle() && + GetController()->SupportsBlePrivacy() && + btm_cb.cmn_ble_vsc_cb.max_irk_list_sz > 0 && + GetController()->GetLeResolvingListSize() == 0) { + btm_ble_resolving_list_init(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz); + } - p_ctrl_le_feature_rd_cmpl_cback = p_vsc_cback; - BTM_VendorSpecificCommand(HCI_BLE_VENDOR_CAP, 0, NULL, - btm_ble_vendor_capability_vsc_cmpl_cback); + if (p_vsc_cback != NULL) { + p_vsc_cback(tHCI_STATUS::HCI_SUCCESS); + } + } else { + p_ctrl_le_feature_rd_cmpl_cback = p_vsc_cback; + BTM_VendorSpecificCommand(HCI_BLE_VENDOR_CAP, 0, NULL, + btm_ble_vendor_capability_vsc_cmpl_cback); + } } /******************************************************************************* @@ -851,36 +955,35 @@ void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK* p_vsc_cback) { * ******************************************************************************/ bool BTM_BleConfigPrivacy(bool privacy_mode) { - tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb; - - LOG_WARN("%s %d", __func__, (int)privacy_mode); + log::warn("{}", (int)privacy_mode); /* if LE is not supported, return error */ - if (!controller_get_interface()->supports_ble()) return false; + if (!controller_get_interface()->SupportsBle()) return false; tGAP_BLE_ATTR_VALUE gap_ble_attr_value; gap_ble_attr_value.addr_resolution = 0; if (!privacy_mode) /* if privacy disabled, always use public address */ { - p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC; - p_cb->privacy_mode = BTM_PRIVACY_NONE; + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC; + btm_cb.ble_ctr_cb.privacy_mode = BTM_PRIVACY_NONE; } else /* privacy is turned on*/ { /* always set host random address, used when privacy 1.1 or priavcy 1.2 is * disabled */ - p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM; + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM; btm_gen_resolvable_private_addr(base::Bind(&btm_gen_resolve_paddr_low)); /* 4.2 controller only allow privacy 1.2 or mixed mode, resolvable private * address in controller */ - if (controller_get_interface()->supports_ble_privacy()) { + if (controller_get_interface()->SupportsBlePrivacy()) { gap_ble_attr_value.addr_resolution = 1; - p_cb->privacy_mode = BTM_PRIVACY_1_2; + btm_cb.ble_ctr_cb.privacy_mode = BTM_PRIVACY_1_2; } else /* 4.1/4.0 controller */ - p_cb->privacy_mode = BTM_PRIVACY_1_1; + btm_cb.ble_ctr_cb.privacy_mode = BTM_PRIVACY_1_1; } - VLOG(2) << __func__ << " privacy_mode: " << p_cb->privacy_mode - << " own_addr_type: " << p_cb->addr_mgnt_cb.own_addr_type; + log::verbose("privacy_mode: {} own_addr_type: {}", + btm_cb.ble_ctr_cb.privacy_mode, + btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type); GAP_BleAttrDBUpdate(GATT_UUID_GAP_CENTRAL_ADDR_RESOL, &gap_ble_attr_value); @@ -933,7 +1036,7 @@ static bool is_resolving_list_bit_set(void* data, void* context) { static void sync_queue_add(sync_node_t* p_param) { std::unique_lock guard(sync_queue_mutex_); if (!sync_queue) { - LOG_INFO("%s: allocating sync queue", __func__); + log::info("allocating sync queue"); sync_queue = list_new(osi_free); CHECK(sync_queue != NULL); } @@ -946,12 +1049,12 @@ static void sync_queue_add(sync_node_t* p_param) { } static void sync_queue_advance() { - LOG_DEBUG("%s", ""); + log::debug(""); std::unique_lock guard(sync_queue_mutex_); if (sync_queue && !list_is_empty(sync_queue)) { sync_node_t* p_head = (sync_node_t*)list_front(sync_queue); - LOG_INFO("queue_advance"); + log::info("queue_advance"); list_remove(sync_queue, p_head); } } @@ -969,10 +1072,10 @@ static void sync_queue_cleanup(remove_sync_node_t* p_param) { node = list_next(node); if (sync_request->sid == p_param->sid && sync_request->address == p_param->address) { - LOG_INFO("%s: removing connection request SID=%04X, bd_addr=%s, busy=%d", - __func__, sync_request->sid, - ADDRESS_TO_LOGGABLE_CSTR(sync_request->address), - sync_request->busy); + log::info("removing connection request SID={:04X}, bd_addr={}, busy={}", + sync_request->sid, + ADDRESS_TO_LOGGABLE_CSTR(sync_request->address), + sync_request->busy); list_remove(sync_queue, sync_request); } } @@ -992,7 +1095,7 @@ void btm_ble_start_sync_request(uint8_t sid, RawAddress addr, uint16_t skip, int index = btm_ble_get_psync_index(sid, addr); if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("Failed to get sync transfer index"); + log::error("Failed to get sync transfer index"); return; } @@ -1009,16 +1112,16 @@ void btm_ble_start_sync_request(uint8_t sid, RawAddress addr, uint16_t skip, static void btm_queue_sync_next() { if (!sync_queue || list_is_empty(sync_queue)) { - LOG_DEBUG("sync_queue empty"); + log::debug("sync_queue empty"); return; } sync_node_t* p_head = (sync_node_t*)list_front(sync_queue); - LOG_INFO("%s: executing sync request SID=%04X, bd_addr=%s", __func__, - p_head->sid, ADDRESS_TO_LOGGABLE_CSTR(p_head->address)); + log::info("executing sync request SID={:04X}, bd_addr={}", p_head->sid, + ADDRESS_TO_LOGGABLE_CSTR(p_head->address)); if (p_head->busy) { - LOG_DEBUG("BUSY"); + log::debug("BUSY"); return; } @@ -1031,11 +1134,11 @@ static void btm_queue_sync_next() { static void btm_ble_sync_queue_handle(uint16_t event, char* param) { switch (event) { case BTM_QUEUE_SYNC_REQ_EVT: - LOG_DEBUG("BTIF_QUEUE_SYNC_REQ_EVT"); + log::debug("BTIF_QUEUE_SYNC_REQ_EVT"); sync_queue_add((sync_node_t*)param); break; case BTM_QUEUE_SYNC_ADVANCE_EVT: - LOG_DEBUG("BTIF_QUEUE_ADVANCE_EVT"); + log::debug("BTIF_QUEUE_ADVANCE_EVT"); sync_queue_advance(); break; case BTM_QUEUE_SYNC_CLEANUP_EVT: @@ -1047,7 +1150,7 @@ static void btm_ble_sync_queue_handle(uint16_t event, char* param) { void btm_queue_start_sync_req(uint8_t sid, RawAddress address, uint16_t skip, uint16_t timeout) { - LOG_DEBUG("address = %s, sid = %d", ADDRESS_TO_LOGGABLE_CSTR(address), sid); + log::debug("address = {}, sid = {}", ADDRESS_TO_LOGGABLE_CSTR(address), sid); sync_node_t node = {}; node.sid = sid; node.address = address; @@ -1057,12 +1160,12 @@ void btm_queue_start_sync_req(uint8_t sid, RawAddress address, uint16_t skip, } static void btm_sync_queue_advance() { - LOG_DEBUG("%s", ""); + log::debug(""); btm_ble_sync_queue_handle(BTM_QUEUE_SYNC_ADVANCE_EVT, nullptr); } static void btm_ble_start_sync_timeout(void* data) { - LOG_DEBUG("%s", ""); + log::debug(""); sync_node_t* p_head = (sync_node_t*)list_front(sync_queue); uint8_t adv_sid = p_head->sid; RawAddress address = p_head->address; @@ -1070,7 +1173,7 @@ static void btm_ble_start_sync_timeout(void* data) { int index = btm_ble_get_psync_index(adv_sid, address); if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("Failed to get sync transfer index"); + log::error("Failed to get sync transfer index"); return; } @@ -1089,23 +1192,12 @@ static void btm_ble_start_sync_timeout(void* data) { p->in_use = false; } -static int btm_ble_get_free_psync_index() { - int i; - for (i = 0; i < MAX_SYNC_TRANSACTION; i++) { - if (btm_ble_pa_sync_cb.p_sync[i].in_use == false) { - LOG_DEBUG("found index at %d", i); - return i; - } - } - return i; -} - static int btm_ble_get_psync_index_from_handle(uint16_t handle) { int i; for (i = 0; i < MAX_SYNC_TRANSACTION; i++) { if (btm_ble_pa_sync_cb.p_sync[i].sync_handle == handle && btm_ble_pa_sync_cb.p_sync[i].sync_state == PERIODIC_SYNC_ESTABLISHED) { - LOG_DEBUG("found index at %d", i); + log::debug("found index at {}", i); return i; } } @@ -1117,18 +1209,7 @@ static int btm_ble_get_psync_index(uint8_t adv_sid, RawAddress addr) { for (i = 0; i < MAX_SYNC_TRANSACTION; i++) { if (btm_ble_pa_sync_cb.p_sync[i].sid == adv_sid && btm_ble_pa_sync_cb.p_sync[i].remote_bda == addr) { - LOG_DEBUG("found index at %d", i); - return i; - } - } - return i; -} - -static int btm_ble_get_free_sync_transfer_index() { - int i; - for (i = 0; i < MAX_SYNC_TRANSACTION; i++) { - if (!btm_ble_pa_sync_cb.sync_transfer[i].in_use) { - LOG_DEBUG("found index at %d", i); + log::debug("found index at {}", i); return i; } } @@ -1139,7 +1220,7 @@ static int btm_ble_get_sync_transfer_index(uint16_t conn_handle) { int i; for (i = 0; i < MAX_SYNC_TRANSACTION; i++) { if (btm_ble_pa_sync_cb.sync_transfer[i].conn_handle == conn_handle) { - LOG_DEBUG("found index at %d", i); + log::debug("found index at {}", i); return i; } } @@ -1161,14 +1242,14 @@ void btm_ble_periodic_adv_sync_established(uint8_t status, uint16_t sync_handle, const RawAddress& addr, uint8_t phy, uint16_t interval, uint8_t adv_clock_accuracy) { - LOG_DEBUG( - "[PSync]: status=%d, sync_handle=%d, s_id=%d, " - "addr_type=%d, adv_phy=%d,adv_interval=%d, clock_acc=%d", + log::debug( + "[PSync]: status={}, sync_handle={}, s_id={}, addr_type={}, " + "adv_phy={},adv_interval={}, clock_acc={}", status, sync_handle, adv_sid, address_type, phy, interval, adv_clock_accuracy); /*if (param_len != ADV_SYNC_ESTB_EVT_LEN) { - LOG_ERROR("[PSync]%s: Invalid event length",__func__); + log::error("[PSync]Invalid event length"); STREAM_TO_UINT8(status, param); if (status == BTM_SUCCESS) { STREAM_TO_UINT16(sync_handle, param); @@ -1189,9 +1270,9 @@ void btm_ble_periodic_adv_sync_established(uint8_t status, uint16_t sync_handle, } int index = btm_ble_get_psync_index(adv_sid, bda); if (index == MAX_SYNC_TRANSACTION) { - LOG_WARN("[PSync]%s: Invalid index for sync established", __func__); + log::warn("[PSync]: Invalid index for sync established"); if (status == BTM_SUCCESS) { - LOG_WARN("%s: Terminate sync", __func__); + log::warn("Terminate sync"); if (BleScanningManager::IsInitialized()) { BleScanningManager::Get()->PeriodicScanTerminate(sync_handle); } @@ -1219,9 +1300,9 @@ void btm_ble_periodic_adv_report(uint16_t sync_handle, uint8_t tx_power, int8_t rssi, uint8_t cte_type, uint8_t data_status, uint8_t data_len, const uint8_t* periodic_data) { - LOG_DEBUG( - "[PSync]: sync_handle = %u, tx_power = %d, rssi = %d," - "cte_type = %u, data_status = %u, data_len = %u", + log::debug( + "[PSync]: sync_handle = {}, tx_power = {}, rssi = {},cte_type = {}, " + "data_status = {}, data_len = {}", sync_handle, tx_power, rssi, cte_type, data_status, data_len); std::vector data; @@ -1230,11 +1311,11 @@ void btm_ble_periodic_adv_report(uint16_t sync_handle, uint8_t tx_power, } int index = btm_ble_get_psync_index_from_handle(sync_handle); if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("[PSync]: index not found for handle %u", sync_handle); + log::error("[PSync]: index not found for handle {}", sync_handle); return; } tBTM_BLE_PERIODIC_SYNC* ps = &btm_ble_pa_sync_cb.p_sync[index]; - LOG_DEBUG("%s", "[PSync]: invoking callback"); + log::debug("[PSync]: invoking callback"); ps->sync_report_cb.Run(sync_handle, tx_power, rssi, data_status, data); } @@ -1246,11 +1327,11 @@ void btm_ble_periodic_adv_report(uint16_t sync_handle, uint8_t tx_power, * ******************************************************************************/ void btm_ble_periodic_adv_sync_lost(uint16_t sync_handle) { - LOG_DEBUG("[PSync]: sync_handle = %d", sync_handle); + log::debug("[PSync]: sync_handle = {}", sync_handle); int index = btm_ble_get_psync_index_from_handle(sync_handle); if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("[PSync]: index not found for handle %u", sync_handle); + log::error("[PSync]: index not found for handle {}", sync_handle); return; } tBTM_BLE_PERIODIC_SYNC* ps = &btm_ble_pa_sync_cb.p_sync[index]; @@ -1263,102 +1344,6 @@ void btm_ble_periodic_adv_sync_lost(uint16_t sync_handle) { ps->remote_bda = RawAddress::kEmpty; } -/******************************************************************************* - * - * Function BTM_BleStartPeriodicSync - * - * Description Create sync request to PA associated with address and sid - * - ******************************************************************************/ -void BTM_BleStartPeriodicSync(uint8_t adv_sid, RawAddress address, - uint16_t skip, uint16_t timeout, - StartSyncCb syncCb, SyncReportCb reportCb, - SyncLostCb lostCb, BigInfoReportCb biginfo_reportCb) { - LOG_DEBUG("%s", "[PSync]"); - int index = btm_ble_get_free_psync_index(); - - if (index == MAX_SYNC_TRANSACTION) { - syncCb.Run(BTM_NO_RESOURCES, 0, adv_sid, BLE_ADDR_RANDOM, address, 0, 0); - return; - } - - tBTM_BLE_PERIODIC_SYNC* p = &btm_ble_pa_sync_cb.p_sync[index]; - - p->in_use = true; - p->remote_bda = address; - p->sid = adv_sid; - p->sync_start_cb = syncCb; - p->sync_report_cb = reportCb; - p->sync_lost_cb = lostCb; - p->biginfo_report_cb = biginfo_reportCb; - btm_queue_start_sync_req(adv_sid, address, skip, timeout); -} - -/******************************************************************************* - * - * Function BTM_BleStopPeriodicSync - * - * Description Terminate sync request to PA associated with sync handle - * - ******************************************************************************/ -void BTM_BleStopPeriodicSync(uint16_t handle) { - LOG_DEBUG("[PSync]: handle = %u", handle); - int index = btm_ble_get_psync_index_from_handle(handle); - if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("[PSync]: invalid index for handle %u", handle); - if (BleScanningManager::IsInitialized()) { - BleScanningManager::Get()->PeriodicScanTerminate(handle); - } - return; - } - tBTM_BLE_PERIODIC_SYNC* p = &btm_ble_pa_sync_cb.p_sync[index]; - p->sync_state = PERIODIC_SYNC_IDLE; - p->in_use = false; - p->remote_bda = RawAddress::kEmpty; - p->sid = 0; - p->sync_handle = 0; - p->in_use = false; - if (BleScanningManager::IsInitialized()) { - BleScanningManager::Get()->PeriodicScanTerminate(handle); - } -} - -/******************************************************************************* - * - * Function BTM_BleCancelPeriodicSync - * - * Description Cancel create sync request to PA associated with sid and - * address - * - ******************************************************************************/ -void BTM_BleCancelPeriodicSync(uint8_t adv_sid, RawAddress address) { - LOG_DEBUG("%s", "[PSync]"); - int index = btm_ble_get_psync_index(adv_sid, address); - if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("[PSync]:Invalid index for sid=%u", adv_sid); - return; - } - tBTM_BLE_PERIODIC_SYNC* p = &btm_ble_pa_sync_cb.p_sync[index]; - if (p->sync_state == PERIODIC_SYNC_PENDING) { - LOG_WARN("[PSync]: Sync state is pending for index %d", index); - if (BleScanningManager::IsInitialized()) { - BleScanningManager::Get()->PeriodicScanCancelStart(); - } - } else if (p->sync_state == PERIODIC_SYNC_IDLE) { - LOG_DEBUG("[PSync]: Removing Sync request from queue for index %d", index); - remove_sync_node_t remove_node; - remove_node.sid = adv_sid; - remove_node.address = address; - btm_ble_sync_queue_handle(BTM_QUEUE_SYNC_CLEANUP_EVT, (char*)&remove_node); - } - p->sync_state = PERIODIC_SYNC_IDLE; - p->in_use = false; - p->remote_bda = RawAddress::kEmpty; - p->sid = 0; - p->sync_handle = 0; - p->in_use = false; -} - /******************************************************************************* * * Function btm_ble_periodic_syc_transfer_cmd_cmpl @@ -1368,11 +1353,11 @@ void BTM_BleCancelPeriodicSync(uint8_t adv_sid, RawAddress address) { ******************************************************************************/ void btm_ble_periodic_syc_transfer_cmd_cmpl(uint8_t status, uint16_t conn_handle) { - LOG_DEBUG("[PAST]: status = %d, conn_handle =%d", status, conn_handle); + log::debug("[PAST]: status = {}, conn_handle ={}", status, conn_handle); int index = btm_ble_get_sync_transfer_index(conn_handle); if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("[PAST]:Invalid, conn_handle %u not found in DB", conn_handle); + log::error("[PAST]:Invalid, conn_handle {} not found in DB", conn_handle); return; } @@ -1386,97 +1371,7 @@ void btm_ble_periodic_syc_transfer_cmd_cmpl(uint8_t status, } void btm_ble_periodic_syc_transfer_param_cmpl(uint8_t status) { - LOG_DEBUG("[PAST]: status = %d", status); -} - -/******************************************************************************* - * - * Function BTM_BlePeriodicSyncTransfer - * - * Description Initiate PAST to connected remote device with sync handle - * - ******************************************************************************/ -void BTM_BlePeriodicSyncTransfer(RawAddress addr, uint16_t service_data, - uint16_t sync_handle, SyncTransferCb cb) { - uint16_t conn_handle = BTM_GetHCIConnHandle(addr, BT_TRANSPORT_LE); - tACL_CONN* p_acl = btm_acl_for_bda(addr, BT_TRANSPORT_LE); - LOG_VERBOSE("[PAST]%s for connection_handle = %x", __func__, conn_handle); - if (conn_handle == 0xFFFF || p_acl == NULL) { - LOG_ERROR("[PAST]%s:Invalid connection handle or no LE ACL link", __func__); - cb.Run(BTM_UNKNOWN_ADDR, addr); - return; - } - - if (!HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT( - p_acl->peer_le_features)) { - LOG_ERROR("[PAST]%s:Remote doesn't support PAST", __func__); - cb.Run(BTM_MODE_UNSUPPORTED, addr); - return; - } - - int index = btm_ble_get_free_sync_transfer_index(); - if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("Failed to get sync transfer index"); - cb.Run(BTM_ILLEGAL_VALUE, addr); - return; - } - - tBTM_BLE_PERIODIC_SYNC_TRANSFER* p_sync_transfer = - &btm_ble_pa_sync_cb.sync_transfer[index]; - p_sync_transfer->in_use = true; - p_sync_transfer->conn_handle = conn_handle; - p_sync_transfer->addr = addr; - p_sync_transfer->cb = cb; - if (BleScanningManager::IsInitialized()) { - BleScanningManager::Get()->PeriodicAdvSyncTransfer( - addr, service_data, sync_handle, - base::Bind(&btm_ble_periodic_syc_transfer_cmd_cmpl)); - } -} - -/******************************************************************************* - * - * Function BTM_BlePeriodicSyncSetInfo - * - * Description Initiate PAST to connected remote device with adv handle - * - ******************************************************************************/ -void BTM_BlePeriodicSyncSetInfo(RawAddress addr, uint16_t service_data, - uint8_t adv_handle, SyncTransferCb cb) { - uint16_t conn_handle = BTM_GetHCIConnHandle(addr, BT_TRANSPORT_LE); - tACL_CONN* p_acl = btm_acl_for_bda(addr, BT_TRANSPORT_LE); - LOG_DEBUG("[PAST] for connection_handle = %u", conn_handle); - if (conn_handle == 0xFFFF || p_acl == nullptr) { - LOG_ERROR("[PAST]:Invalid connection handle %u or no LE ACL link", - conn_handle); - cb.Run(BTM_UNKNOWN_ADDR, addr); - return; - } - if (!HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT( - p_acl->peer_le_features)) { - LOG_ERROR("%s", "[PAST]:Remote doesn't support PAST"); - cb.Run(BTM_MODE_UNSUPPORTED, addr); - return; - } - - int index = btm_ble_get_free_sync_transfer_index(); - if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("Failed to get sync transfer index"); - cb.Run(BTM_ILLEGAL_VALUE, addr); - return; - } - - tBTM_BLE_PERIODIC_SYNC_TRANSFER* p_sync_transfer = - &btm_ble_pa_sync_cb.sync_transfer[index]; - p_sync_transfer->in_use = true; - p_sync_transfer->conn_handle = conn_handle; - p_sync_transfer->addr = addr; - p_sync_transfer->cb = cb; - if (BleScanningManager::IsInitialized()) { - BleScanningManager::Get()->PeriodicAdvSetInfoTransfer( - addr, service_data, adv_handle, - base::Bind(&btm_ble_periodic_syc_transfer_cmd_cmpl)); - } + log::debug("[PAST]: status = {}", status); } /******************************************************************************* @@ -1487,7 +1382,7 @@ void BTM_BlePeriodicSyncSetInfo(RawAddress addr, uint16_t service_data, * ******************************************************************************/ void btm_ble_biginfo_adv_report_rcvd(const uint8_t* p, uint16_t param_len) { - LOG_DEBUG("[PAST]: BIGINFO report received, len=%u", param_len); + log::debug("[PAST]: BIGINFO report received, len={}", param_len); uint16_t sync_handle, iso_interval, max_pdu, max_sdu; uint8_t num_bises, nse, bn, pto, irc, phy, framing, encryption; uint32_t sdu_interval; @@ -1497,7 +1392,7 @@ void btm_ble_biginfo_adv_report_rcvd(const uint8_t* p, uint16_t param_len) { // for sdu_interval, 2 bytes for max_sdu, 1 byte each for phy, framing, // encryption if (param_len < 19) { - LOG_ERROR("Insufficient data"); + log::error("Insufficient data"); return; } @@ -1514,21 +1409,20 @@ void btm_ble_biginfo_adv_report_rcvd(const uint8_t* p, uint16_t param_len) { STREAM_TO_UINT8(phy, p); STREAM_TO_UINT8(framing, p); STREAM_TO_UINT8(encryption, p); - LOG_DEBUG( - "[PAST]:sync_handle %u, num_bises = %u, nse = %u," - "iso_interval = %d, bn = %u, pto = %u, irc = %u, max_pdu = %u " - "sdu_interval = %d, max_sdu = %u, phy = %u, framing = %u, encryption = " - "%u", + log::debug( + "[PAST]:sync_handle {}, num_bises = {}, nse = {},iso_interval = {}, bn = " + "{}, pto = {}, irc = {}, max_pdu = {} sdu_interval = {}, max_sdu = {}, " + "phy = {}, framing = {}, encryption = {}", sync_handle, num_bises, nse, iso_interval, bn, pto, irc, max_pdu, sdu_interval, max_sdu, phy, framing, encryption); int index = btm_ble_get_psync_index_from_handle(sync_handle); if (index == MAX_SYNC_TRANSACTION) { - LOG_ERROR("[PSync]: index not found for handle %u", sync_handle); + log::error("[PSync]: index not found for handle {}", sync_handle); return; } tBTM_BLE_PERIODIC_SYNC* ps = &btm_ble_pa_sync_cb.p_sync[index]; - LOG_DEBUG("%s", "[PSync]: invoking callback"); + log::debug("[PSync]: invoking callback"); ps->biginfo_report_cb.Run(sync_handle, encryption ? true : false); } @@ -1542,9 +1436,9 @@ void btm_ble_biginfo_adv_report_rcvd(const uint8_t* p, uint16_t param_len) { * ******************************************************************************/ void btm_ble_periodic_adv_sync_tx_rcvd(const uint8_t* p, uint16_t param_len) { - LOG_DEBUG("[PAST]: PAST received, param_len=%u", param_len); + log::debug("[PAST]: PAST received, param_len={}", param_len); if (param_len < 19) { - LOG_ERROR("%s", "Insufficient data"); + log::error("Insufficient data"); return; } uint8_t status, adv_sid, address_type, adv_phy, clk_acc; @@ -1560,10 +1454,10 @@ void btm_ble_periodic_adv_sync_tx_rcvd(const uint8_t* p, uint16_t param_len) { STREAM_TO_UINT8(adv_phy, p); STREAM_TO_UINT16(pa_int, p); STREAM_TO_UINT8(clk_acc, p); - LOG_VERBOSE( - "[PAST]: status = %u, conn_handle = %u, service_data = %u," - " sync_handle = %u, adv_sid = %u, address_type = %u, addr = %s," - " adv_phy = %u, pa_int = %u, clk_acc = %u", + log::verbose( + "[PAST]: status = {}, conn_handle = {}, service_data = {}, sync_handle = " + "{}, adv_sid = {}, address_type = {}, addr = {}, adv_phy = {}, pa_int = " + "{}, clk_acc = {}", status, conn_handle, service_data, sync_handle, adv_sid, address_type, ADDRESS_TO_LOGGABLE_CSTR(addr), adv_phy, pa_int, clk_acc); if (syncRcvdCbRegistered) { @@ -1572,29 +1466,6 @@ void btm_ble_periodic_adv_sync_tx_rcvd(const uint8_t* p, uint16_t param_len) { } } -/******************************************************************************* - * - * Function BTM_BlePeriodicSyncTxParameters - * - * Description On receiver side this command is used to specify how BT SoC - * will process PA sync info received from the remote device - * identified by the addr. - * - ******************************************************************************/ -void BTM_BlePeriodicSyncTxParameters(RawAddress addr, uint8_t mode, - uint16_t skip, uint16_t timeout, - StartSyncCb syncCb) { - LOG_DEBUG("[PAST]: mode=%u, skip=%u, timeout=%u", mode, skip, timeout); - uint8_t cte_type = 7; - sync_rcvd_cb = syncCb; - syncRcvdCbRegistered = true; - if (BleScanningManager::IsInitialized()) { - BleScanningManager::Get()->SetPeriodicAdvSyncTransferParams( - addr, mode, skip, timeout, cte_type, true, - base::Bind(&btm_ble_periodic_syc_transfer_param_cmpl)); - } -} - /******************************************************************************* * * Function btm_set_conn_mode_adv_init_addr @@ -1607,12 +1478,11 @@ void BTM_BlePeriodicSyncTxParameters(RawAddress addr, uint8_t mode, static uint8_t btm_set_conn_mode_adv_init_addr( RawAddress& p_peer_addr_ptr, tBLE_ADDR_TYPE* p_peer_addr_type, tBLE_ADDR_TYPE* p_own_addr_type) { - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; uint8_t evt_type; tBTM_SEC_DEV_REC* p_dev_rec; - if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) { - if (p_cb->scan_rsp) { + if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_NON_CONNECTABLE) { + if (btm_cb.ble_ctr_cb.inq_var.scan_rsp) { evt_type = BTM_BLE_DISCOVER_EVT; } else { evt_type = BTM_BLE_NON_CONNECT_EVT; @@ -1627,20 +1497,24 @@ static uint8_t btm_set_conn_mode_adv_init_addr( .type = *p_peer_addr_type, .bda = p_peer_addr_ptr, }; - LOG_DEBUG("Received BLE connect event %s", ADDRESS_TO_LOGGABLE_CSTR(ble_bd_addr)); + log::debug("Received BLE connect event {}", + ADDRESS_TO_LOGGABLE_CSTR(ble_bd_addr)); - evt_type = p_cb->directed_conn; + evt_type = btm_cb.ble_ctr_cb.inq_var.directed_conn; if (static_cast>( - p_cb->directed_conn) == BTM_BLE_CONNECT_DIR_EVT || + btm_cb.ble_ctr_cb.inq_var.directed_conn) == + BTM_BLE_CONNECT_DIR_EVT || static_cast>( - p_cb->directed_conn) == BTM_BLE_CONNECT_LO_DUTY_DIR_EVT) { + btm_cb.ble_ctr_cb.inq_var.directed_conn) == + BTM_BLE_CONNECT_LO_DUTY_DIR_EVT) { /* for privacy 1.2, convert peer address as static, own address set as ID * addr */ if (btm_cb.ble_ctr_cb.privacy_mode == BTM_PRIVACY_1_2 || btm_cb.ble_ctr_cb.privacy_mode == BTM_PRIVACY_MIXED) { /* only do so for bonded device */ - if ((p_dev_rec = btm_find_or_alloc_dev(p_cb->direct_bda.bda)) != NULL && + if ((p_dev_rec = btm_find_or_alloc_dev( + btm_cb.ble_ctr_cb.inq_var.direct_bda.bda)) != NULL && p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) { p_peer_addr_ptr = p_dev_rec->ble.identity_address_with_type.bda; *p_peer_addr_type = p_dev_rec->ble.identity_address_with_type.type; @@ -1650,8 +1524,8 @@ static uint8_t btm_set_conn_mode_adv_init_addr( /* otherwise fall though as normal directed adv */ } /* direct adv mode does not have privacy, if privacy is not enabled */ - *p_peer_addr_type = p_cb->direct_bda.type; - p_peer_addr_ptr = p_cb->direct_bda.bda; + *p_peer_addr_type = btm_cb.ble_ctr_cb.inq_var.direct_bda.type; + p_peer_addr_ptr = btm_cb.ble_ctr_cb.inq_var.direct_bda.bda; return evt_type; } } @@ -1659,7 +1533,7 @@ static uint8_t btm_set_conn_mode_adv_init_addr( /* undirect adv mode or non-connectable mode*/ /* when privacy 1.2 privacy only mode is used, or mixed mode */ if ((btm_cb.ble_ctr_cb.privacy_mode == BTM_PRIVACY_1_2 && - p_cb->afp != AP_SCAN_CONN_ALL) || + btm_cb.ble_ctr_cb.inq_var.afp != AP_SCAN_CONN_ALL) || btm_cb.ble_ctr_cb.privacy_mode == BTM_PRIVACY_MIXED) { list_node_t* n = list_foreach(btm_sec_cb.sec_dev_rec, is_resolving_list_bit_set, NULL); @@ -1701,7 +1575,7 @@ static uint8_t btm_set_conn_mode_adv_init_addr( * ******************************************************************************/ uint16_t BTM_BleReadDiscoverability() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return (btm_cb.ble_ctr_cb.inq_var.discoverable_mode); } @@ -1717,7 +1591,7 @@ uint16_t BTM_BleReadDiscoverability() { * ******************************************************************************/ uint16_t BTM_BleReadConnectability() { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return (btm_cb.ble_ctr_cb.inq_var.connectable_mode); } @@ -1785,7 +1659,7 @@ void btm_ble_update_dmt_flag_bits(uint8_t* adv_flag_value, /* if local controller support, mark both controller and host support in flag */ - if (controller_get_interface()->supports_simultaneous_le_bredr()) + if (bluetooth::shim::GetController()->SupportsSimultaneousLeBrEdr()) *adv_flag_value |= (BTM_BLE_DMT_CONTROLLER_SPT | BTM_BLE_DMT_HOST_SPT); else *adv_flag_value &= ~(BTM_BLE_DMT_CONTROLLER_SPT | BTM_BLE_DMT_HOST_SPT); @@ -1811,7 +1685,7 @@ void btm_ble_set_adv_flag(uint16_t connect_mode, uint16_t disc_mode) { btm_ble_update_dmt_flag_bits(&flag, connect_mode, disc_mode); - LOG_INFO("disc_mode %04x", disc_mode); + log::info("disc_mode {:04x}", disc_mode); /* update discoverable flag */ if (disc_mode & BTM_BLE_LIMITED_DISCOVERABLE) { flag &= ~BTM_BLE_GEN_DISC_FLAG; @@ -1841,7 +1715,6 @@ void btm_ble_set_adv_flag(uint16_t connect_mode, uint16_t disc_mode) { ******************************************************************************/ tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode) { tBTM_LE_RANDOM_CB* p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; uint16_t mode = (combined_mode & BTM_BLE_DISCOVERABLE_MASK); uint8_t new_mode = BTM_BLE_ADV_ENABLE; uint8_t evt_type; @@ -1851,66 +1724,69 @@ tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode) { own_addr_type = p_addr_cb->own_addr_type; uint16_t adv_int_min, adv_int_max; - LOG_VERBOSE("%s mode=0x%0x combined_mode=0x%x", __func__, mode, - combined_mode); + log::verbose("mode=0x{:0x} combined_mode=0x{:x}", mode, combined_mode); /*** Check mode parameter ***/ if (mode > BTM_BLE_MAX_DISCOVERABLE) return (BTM_ILLEGAL_VALUE); - p_cb->discoverable_mode = mode; + btm_cb.ble_ctr_cb.inq_var.discoverable_mode = mode; evt_type = btm_set_conn_mode_adv_init_addr(address, &init_addr_type, &own_addr_type); - if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE && + if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_NON_CONNECTABLE && mode == BTM_BLE_NON_DISCOVERABLE) new_mode = BTM_BLE_ADV_DISABLE; btm_ble_select_adv_interval(evt_type, &adv_int_min, &adv_int_max); - alarm_cancel(p_cb->fast_adv_timer); + alarm_cancel(btm_cb.ble_ctr_cb.inq_var.fast_adv_timer); /* update adv params if start advertising */ - LOG_VERBOSE("evt_type=0x%x p-cb->evt_type=0x%x ", evt_type, p_cb->evt_type); + log::verbose("evt_type=0x{:x} p-cb->evt_type=0x{:x} ", evt_type, + btm_cb.ble_ctr_cb.inq_var.evt_type); if (new_mode == BTM_BLE_ADV_ENABLE) { btm_ble_set_adv_flag(btm_cb.btm_inq_vars.connectable_mode, combined_mode); - if (evt_type != p_cb->evt_type || p_cb->adv_addr_type != own_addr_type || - !p_cb->fast_adv_on) { + if (evt_type != btm_cb.ble_ctr_cb.inq_var.evt_type || + btm_cb.ble_ctr_cb.inq_var.adv_addr_type != own_addr_type || + !btm_cb.ble_ctr_cb.inq_var.fast_adv_on) { btm_ble_stop_adv(); /* update adv params */ btsnd_hcic_ble_write_adv_params(adv_int_min, adv_int_max, evt_type, own_addr_type, init_addr_type, address, - p_cb->adv_chnl_map, p_cb->afp); - p_cb->evt_type = evt_type; - p_cb->adv_addr_type = own_addr_type; + btm_cb.ble_ctr_cb.inq_var.adv_chnl_map, + btm_cb.ble_ctr_cb.inq_var.afp); + btm_cb.ble_ctr_cb.inq_var.evt_type = evt_type; + btm_cb.ble_ctr_cb.inq_var.adv_addr_type = own_addr_type; } } - if (status == BTM_SUCCESS && p_cb->adv_mode != new_mode) { + if (status == BTM_SUCCESS && btm_cb.ble_ctr_cb.inq_var.adv_mode != new_mode) { if (new_mode == BTM_BLE_ADV_ENABLE) status = btm_ble_start_adv(); else status = btm_ble_stop_adv(); } - if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { - p_cb->fast_adv_on = true; + if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { + btm_cb.ble_ctr_cb.inq_var.fast_adv_on = true; /* start initial GAP mode adv timer */ - alarm_set_on_mloop(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS, + alarm_set_on_mloop(btm_cb.ble_ctr_cb.inq_var.fast_adv_timer, + BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS, btm_ble_fast_adv_timer_timeout, NULL); } /* set up stop advertising timer */ if (status == BTM_SUCCESS && mode == BTM_BLE_LIMITED_DISCOVERABLE) { - LOG_VERBOSE("start timer for limited disc mode duration=%d ms", - BTM_BLE_GAP_LIM_TIMEOUT_MS); + log::verbose("start timer for limited disc mode duration={} ms", + BTM_BLE_GAP_LIM_TIMEOUT_MS); /* start Tgap(lim_timeout) */ - alarm_set_on_mloop(p_cb->inquiry_timer, BTM_BLE_GAP_LIM_TIMEOUT_MS, - btm_ble_inquiry_timer_gap_limited_discovery_timeout, - NULL); + alarm_set_on_mloop( + btm_cb.ble_ctr_cb.inq_var.inquiry_timer, BTM_BLE_GAP_LIM_TIMEOUT_MS, + btm_ble_inquiry_timer_gap_limited_discovery_timeout, NULL); } return status; } @@ -1928,7 +1804,6 @@ tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode) { ******************************************************************************/ tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode) { tBTM_LE_RANDOM_CB* p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; uint16_t mode = (combined_mode & BTM_BLE_CONNECTABLE_MASK); uint8_t new_mode = BTM_BLE_ADV_ENABLE; uint8_t evt_type; @@ -1938,51 +1813,53 @@ tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode) { own_addr_type = p_addr_cb->own_addr_type; uint16_t adv_int_min, adv_int_max; - LOG_VERBOSE("%s mode=0x%0x combined_mode=0x%x", __func__, mode, - combined_mode); + log::verbose("mode=0x{:0x} combined_mode=0x{:x}", mode, combined_mode); /*** Check mode parameter ***/ if (mode > BTM_BLE_MAX_CONNECTABLE) return (BTM_ILLEGAL_VALUE); - p_cb->connectable_mode = mode; + btm_cb.ble_ctr_cb.inq_var.connectable_mode = mode; evt_type = btm_set_conn_mode_adv_init_addr(address, &peer_addr_type, &own_addr_type); if (mode == BTM_BLE_NON_CONNECTABLE && - p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE) + btm_cb.ble_ctr_cb.inq_var.discoverable_mode == BTM_BLE_NON_DISCOVERABLE) new_mode = BTM_BLE_ADV_DISABLE; btm_ble_select_adv_interval(evt_type, &adv_int_min, &adv_int_max); - alarm_cancel(p_cb->fast_adv_timer); + alarm_cancel(btm_cb.ble_ctr_cb.inq_var.fast_adv_timer); /* update adv params if needed */ if (new_mode == BTM_BLE_ADV_ENABLE) { btm_ble_set_adv_flag(combined_mode, btm_cb.btm_inq_vars.discoverable_mode); - if (p_cb->evt_type != evt_type || - p_cb->adv_addr_type != p_addr_cb->own_addr_type || !p_cb->fast_adv_on) { + if (btm_cb.ble_ctr_cb.inq_var.evt_type != evt_type || + btm_cb.ble_ctr_cb.inq_var.adv_addr_type != p_addr_cb->own_addr_type || + !btm_cb.ble_ctr_cb.inq_var.fast_adv_on) { btm_ble_stop_adv(); btsnd_hcic_ble_write_adv_params(adv_int_min, adv_int_max, evt_type, own_addr_type, peer_addr_type, address, - p_cb->adv_chnl_map, p_cb->afp); - p_cb->evt_type = evt_type; - p_cb->adv_addr_type = own_addr_type; + btm_cb.ble_ctr_cb.inq_var.adv_chnl_map, + btm_cb.ble_ctr_cb.inq_var.afp); + btm_cb.ble_ctr_cb.inq_var.evt_type = evt_type; + btm_cb.ble_ctr_cb.inq_var.adv_addr_type = own_addr_type; } } /* update advertising mode */ - if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode) { + if (status == BTM_SUCCESS && new_mode != btm_cb.ble_ctr_cb.inq_var.adv_mode) { if (new_mode == BTM_BLE_ADV_ENABLE) status = btm_ble_start_adv(); else status = btm_ble_stop_adv(); } - if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { - p_cb->fast_adv_on = true; + if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { + btm_cb.ble_ctr_cb.inq_var.fast_adv_on = true; /* start initial GAP mode adv timer */ - alarm_set_on_mloop(p_cb->fast_adv_timer, BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS, + alarm_set_on_mloop(btm_cb.ble_ctr_cb.inq_var.fast_adv_timer, + BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS, btm_ble_fast_adv_timer_timeout, NULL); } return status; @@ -1990,7 +1867,7 @@ tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode) { static void btm_send_hci_scan_enable(uint8_t enable, uint8_t filter_duplicates) { - if (controller_get_interface()->supports_ble_extended_advertising()) { + if (controller_get_interface()->SupportsBleExtendedAdvertising()) { btsnd_hcic_ble_set_extended_scan_enable(enable, filter_duplicates, 0x0000, 0x0000); } else { @@ -2002,7 +1879,7 @@ void btm_send_hci_set_scan_params(uint8_t scan_type, uint16_t scan_int, uint16_t scan_win, tBLE_ADDR_TYPE addr_type_own, uint8_t scan_filter_policy) { - if (controller_get_interface()->supports_ble_extended_advertising()) { + if (controller_get_interface()->SupportsBleExtendedAdvertising()) { scanning_phy_cfg phy_cfg; phy_cfg.scan_type = scan_type; phy_cfg.scan_int = scan_int; @@ -2021,9 +1898,9 @@ static void btm_ble_scan_filt_param_cfg_evt(uint8_t avbl_space, tBTM_BLE_SCAN_COND_OP action_type, tBTM_STATUS btm_status) { if (btm_status != btm_status_value(BTM_SUCCESS)) { - LOG_ERROR("%s, %d", __func__, btm_status); + log::error("{}", btm_status); } else { - LOG_VERBOSE("%s", __func__); + log::verbose(""); } } @@ -2042,16 +1919,13 @@ static void btm_ble_scan_filt_param_cfg_evt(uint8_t avbl_space, * ******************************************************************************/ tBTM_STATUS btm_ble_start_inquiry(uint8_t duration) { - tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb; - tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; - - LOG_VERBOSE("btm_ble_start_inquiry: inq_active = 0x%02x", - btm_cb.btm_inq_vars.inq_active); + log::verbose("btm_ble_start_inquiry: inq_active = 0x{:02x}", + btm_cb.btm_inq_vars.inq_active); /* if selective connection is active, or inquiry is already active, reject it */ - if (p_ble_cb->is_ble_inquiry_active()) { - LOG_ERROR("LE Inquiry is active, can not start inquiry"); + if (btm_cb.ble_ctr_cb.is_ble_inquiry_active()) { + log::error("LE Inquiry is active, can not start inquiry"); return (BTM_BUSY); } @@ -2071,21 +1945,23 @@ tBTM_STATUS btm_ble_start_inquiry(uint8_t duration) { BTM_BleAdvFilterParamSetup(BTM_BLE_SCAN_COND_ADD, static_cast(0), std::move(adv_filt_param), base::Bind(btm_ble_scan_filt_param_cfg_evt)); - uint16_t scan_interval = osi_property_get_int32(kPropertyInquiryScanInterval, - BTM_BLE_LOW_LATENCY_SCAN_INT); - uint16_t scan_window = osi_property_get_int32(kPropertyInquiryScanWindow, - BTM_BLE_LOW_LATENCY_SCAN_WIN); + uint16_t scan_interval, scan_window; + std::tie(scan_interval, scan_window) = get_low_latency_scan_params(); - if (!p_ble_cb->is_ble_scan_active()) { + if (!btm_cb.ble_ctr_cb.is_ble_scan_active()) { cache.ClearAll(); btm_send_hci_set_scan_params( BTM_BLE_SCAN_MODE_ACTI, scan_interval, scan_window, btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, SP_ADV_ALL); - p_ble_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_ACTI; + btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_ACTI; btm_ble_start_scan(); - } else if ((p_ble_cb->inq_var.scan_interval != scan_interval) || - (p_ble_cb->inq_var.scan_window != scan_window)) { - LOG_VERBOSE("%s, restart LE scan with low latency scan params", __func__); + } else if ((btm_cb.ble_ctr_cb.inq_var.scan_interval != scan_interval) || + (btm_cb.ble_ctr_cb.inq_var.scan_window != scan_window)) { + log::verbose("restart LE scan with low latency scan params"); + if (IS_FLAG_ENABLED(le_scan_parameters_fix)) { + btm_cb.ble_ctr_cb.inq_var.scan_interval = scan_interval; + btm_cb.ble_ctr_cb.inq_var.scan_window = scan_window; + } btm_send_hci_scan_enable(BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); btm_send_hci_set_scan_params( BTM_BLE_SCAN_MODE_ACTI, scan_interval, scan_window, @@ -2093,15 +1969,16 @@ tBTM_STATUS btm_ble_start_inquiry(uint8_t duration) { btm_send_hci_scan_enable(BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE); } - p_inq->inq_active |= BTM_BLE_GENERAL_INQUIRY; - p_ble_cb->set_ble_inquiry_active(); + btm_cb.btm_inq_vars.inq_active |= BTM_BLE_GENERAL_INQUIRY; + btm_cb.ble_ctr_cb.set_ble_inquiry_active(); - LOG_VERBOSE("btm_ble_start_inquiry inq_active = 0x%02x", p_inq->inq_active); + log::verbose("btm_ble_start_inquiry inq_active = 0x{:02x}", + btm_cb.btm_inq_vars.inq_active); if (duration != 0) { /* start inquiry timer */ uint64_t duration_ms = duration * 1000; - alarm_set_on_mloop(p_ble_cb->inq_var.inquiry_timer, duration_ms, + alarm_set_on_mloop(btm_cb.ble_ctr_cb.inq_var.inquiry_timer, duration_ms, btm_ble_inquiry_timer_timeout, NULL); } @@ -2156,27 +2033,26 @@ void btm_ble_read_remote_name_cmpl(bool status, const RawAddress& bda, ******************************************************************************/ tBTM_STATUS btm_ble_read_remote_name(const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb) { - tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; - - if (!controller_get_interface()->supports_ble()) return BTM_ERR_PROCESSING; + if (!controller_get_interface()->SupportsBle()) return BTM_ERR_PROCESSING; tINQ_DB_ENT* p_i = btm_inq_db_find(remote_bda); if (p_i && !ble_evt_type_is_connectable(p_i->inq_info.results.ble_evt_type)) { - LOG_VERBOSE("name request to non-connectable device failed."); + log::verbose("name request to non-connectable device failed."); return BTM_ERR_PROCESSING; } /* read remote device name using GATT procedure */ - if (p_inq->remname_active) return BTM_BUSY; + if (btm_cb.btm_inq_vars.remname_active) return BTM_BUSY; if (!GAP_BleReadPeerDevName(remote_bda, btm_ble_read_remote_name_cmpl)) return BTM_BUSY; - p_inq->p_remname_cmpl_cb = p_cb; - p_inq->remname_active = true; - p_inq->remname_bda = remote_bda; + btm_cb.btm_inq_vars.p_remname_cmpl_cb = p_cb; + btm_cb.btm_inq_vars.remname_active = true; + btm_cb.btm_inq_vars.remname_bda = remote_bda; - alarm_set_on_mloop(p_inq->remote_name_timer, BTM_EXT_BLE_RMT_NAME_TIMEOUT_MS, + alarm_set_on_mloop(btm_cb.btm_inq_vars.remote_name_timer, + BTM_EXT_BLE_RMT_NAME_TIMEOUT_MS, btm_inq_remote_name_timer_timeout, NULL); return BTM_CMD_STARTED; @@ -2194,14 +2070,13 @@ tBTM_STATUS btm_ble_read_remote_name(const RawAddress& remote_bda, * ******************************************************************************/ bool btm_ble_cancel_remote_name(const RawAddress& remote_bda) { - tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; bool status; status = GAP_BleCancelReadPeerDevName(remote_bda); - p_inq->remname_active = false; - p_inq->remname_bda = RawAddress::kEmpty; - alarm_cancel(p_inq->remote_name_timer); + btm_cb.btm_inq_vars.remname_active = false; + btm_cb.btm_inq_vars.remname_bda = RawAddress::kEmpty; + alarm_cancel(btm_cb.btm_inq_vars.remote_name_timer); return status; } @@ -2222,10 +2097,10 @@ static void btm_ble_update_adv_flag(uint8_t flag) { tBTM_BLE_LOCAL_ADV_DATA* p_adv_data = &btm_cb.ble_ctr_cb.inq_var.adv_data; uint8_t* p; - LOG_VERBOSE("btm_ble_update_adv_flag new=0x%x", flag); + log::verbose("btm_ble_update_adv_flag new=0x{:x}", flag); if (p_adv_data->p_flags != NULL) { - LOG_VERBOSE("btm_ble_update_adv_flag old=0x%x", *p_adv_data->p_flags); + log::verbose("btm_ble_update_adv_flag old=0x{:x}", *p_adv_data->p_flags); *p_adv_data->p_flags = flag; } else /* no FLAGS in ADV data*/ { @@ -2278,8 +2153,8 @@ static uint8_t btm_ble_is_discoverable(const RawAddress& bda, return scan_state; } -static void btm_ble_appearance_to_cod(uint16_t appearance, uint8_t* dev_class) { - dev_class[0] = 0; +static DEV_CLASS btm_ble_appearance_to_cod(uint16_t appearance) { + DEV_CLASS dev_class = kDevClassEmpty; switch (appearance) { case BTM_BLE_APPEARANCE_GENERIC_PHONE: @@ -2410,10 +2285,10 @@ static void btm_ble_appearance_to_cod(uint16_t appearance, uint8_t* dev_class) { dev_class[1] = BTM_COD_MAJOR_UNCLASSIFIED; dev_class[2] = BTM_COD_MINOR_UNCLASSIFIED; }; + return dev_class; } -bool btm_ble_get_appearance_as_cod(std::vector const& data, - DEV_CLASS dev_class) { +DEV_CLASS btm_ble_get_appearance_as_cod(std::vector const& data) { /* Check to see the BLE device has the Appearance UUID in the advertising * data. If it does then try to convert the appearance value to a class of * device value Fluoride can use. Otherwise fall back to trying to infer if @@ -2423,46 +2298,46 @@ bool btm_ble_get_appearance_as_cod(std::vector const& data, const uint8_t* p_uuid16 = AdvertiseDataParser::GetFieldByType( data, BTM_BLE_AD_TYPE_APPEARANCE, &len); if (p_uuid16 && len == 2) { - btm_ble_appearance_to_cod((uint16_t)p_uuid16[0] | (p_uuid16[1] << 8), - dev_class); - return true; + return btm_ble_appearance_to_cod((uint16_t)p_uuid16[0] | + (p_uuid16[1] << 8)); } p_uuid16 = AdvertiseDataParser::GetFieldByType( data, BTM_BLE_AD_TYPE_16SRV_CMPL, &len); if (p_uuid16 == NULL) { - return false; + return kDevClassUnclassified; } for (uint8_t i = 0; i + 2 <= len; i = i + 2) { /* if this BLE device supports HID over LE, set HID Major in class of * device */ if ((p_uuid16[i] | (p_uuid16[i + 1] << 8)) == UUID_SERVCLASS_LE_HID) { + DEV_CLASS dev_class; dev_class[0] = 0; dev_class[1] = BTM_COD_MAJOR_PERIPHERAL; dev_class[2] = 0; - return true; + return dev_class; } } - return false; + return kDevClassUnclassified; } /** * Update adv packet information into inquiry result. */ -void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type, - const RawAddress& bda, uint16_t evt_type, - uint8_t primary_phy, uint8_t secondary_phy, - uint8_t advertising_sid, int8_t tx_power, - int8_t rssi, uint16_t periodic_adv_int, - std::vector const& data) { +static void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type, + const RawAddress& bda, uint16_t evt_type, + uint8_t primary_phy, + uint8_t secondary_phy, + uint8_t advertising_sid, int8_t tx_power, + int8_t rssi, uint16_t periodic_adv_int, + std::vector const& data) { tBTM_INQ_RESULTS* p_cur = &p_i->inq_info.results; uint8_t len; - tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; /* Save the info */ - p_cur->inq_result_type |= BTM_INQ_RESULT_BLE; + p_cur->inq_result_type |= BT_DEVICE_TYPE_BLE; p_cur->ble_addr_type = static_cast(addr_type); p_cur->rssi = rssi; p_cur->ble_primary_phy = primary_phy; @@ -2478,14 +2353,15 @@ void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type, } else p_i->scan_rsp = true; - if (p_i->inq_count != p_inq->inq_counter) + if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) p_cur->device_type = BT_DEVICE_TYPE_BLE; else p_cur->device_type |= BT_DEVICE_TYPE_BLE; if (evt_type != BTM_BLE_SCAN_RSP_EVT) p_cur->ble_evt_type = evt_type; - p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */ + p_i->inq_count = + btm_cb.btm_inq_vars.inq_counter; /* Mark entry for current inquiry */ bool has_advertising_flags = false; if (!data.empty()) { @@ -2496,7 +2372,7 @@ void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type, p_cur->flag = *p_flag; } - btm_ble_get_appearance_as_cod(data, p_cur->dev_class); + p_cur->dev_class = btm_ble_get_appearance_as_cod(data); const uint8_t* p_rsi = AdvertiseDataParser::GetFieldByType(data, BTM_BLE_AD_TYPE_RSI, &len); @@ -2537,13 +2413,13 @@ void btm_ble_update_inq_result(tINQ_DB_ENT* p_i, uint8_t addr_type, if (should_process_flags && (p_cur->flag & BTM_BLE_BREDR_NOT_SPT) == 0 && !ble_evt_type_is_directed(evt_type)) { if (p_cur->ble_addr_type != BLE_ADDR_RANDOM) { - LOG_VERBOSE("NOT_BR_EDR support bit not set, treat device as DUMO"); + log::verbose("NOT_BR_EDR support bit not set, treat device as DUMO"); p_cur->device_type |= BT_DEVICE_TYPE_DUMO; } else { - LOG_VERBOSE("Random address, treat device as LE only"); + log::verbose("Random address, treat device as LE only"); } } else { - LOG_VERBOSE("NOT_BR/EDR support bit set, treat device as LE only"); + log::verbose("NOT_BR/EDR support bit set, treat device as LE only"); } } @@ -2551,7 +2427,7 @@ void btm_ble_process_adv_addr(RawAddress& bda, tBLE_ADDR_TYPE* addr_type) { /* map address to security record */ bool match = btm_identity_addr_to_random_pseudo(&bda, addr_type, false); - VLOG(1) << __func__ << ": bda=" << bda; + log::verbose("bda={}", ADDRESS_TO_LOGGABLE_STR(bda)); /* always do RRA resolution on host */ if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) { tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(bda); @@ -2570,181 +2446,6 @@ void btm_ble_process_adv_addr(RawAddress& bda, tBLE_ADDR_TYPE* addr_type) { } } -/** - * This function is called when extended advertising report event is received . - * It updates the inquiry database. If the inquiry database is full, the oldest - * entry is discarded. - */ -void btm_ble_process_ext_adv_pkt(uint8_t data_len, const uint8_t* data) { - RawAddress bda, direct_address; - const uint8_t* p = data; - uint8_t addr_type, num_reports, pkt_data_len, primary_phy, secondary_phy, - advertising_sid; - int8_t rssi, tx_power; - uint16_t event_type, periodic_adv_int, direct_address_type; - size_t bytes_to_process; - - /* Only process the results if the inquiry is still active */ - if (!btm_cb.ble_ctr_cb.is_ble_scan_active()) return; - - bytes_to_process = 1; - - if (data_len < bytes_to_process) { - LOG(ERROR) << "Malformed LE extended advertising packet: not enough room " - "for num reports"; - return; - } - - /* Extract the number of reports in this event. */ - STREAM_TO_UINT8(num_reports, p); - - while (num_reports--) { - bytes_to_process += 24; - if (data_len < bytes_to_process) { - LOG(ERROR) << "Malformed LE extended advertising packet: not enough room " - "for metadata"; - return; - } - - /* Extract inquiry results */ - STREAM_TO_UINT16(event_type, p); - STREAM_TO_UINT8(addr_type, p); - STREAM_TO_BDADDR(bda, p); - STREAM_TO_UINT8(primary_phy, p); - STREAM_TO_UINT8(secondary_phy, p); - STREAM_TO_UINT8(advertising_sid, p); - STREAM_TO_INT8(tx_power, p); - STREAM_TO_INT8(rssi, p); - STREAM_TO_UINT16(periodic_adv_int, p); - STREAM_TO_UINT8(direct_address_type, p); - STREAM_TO_BDADDR(direct_address, p); - STREAM_TO_UINT8(pkt_data_len, p); - - const uint8_t* pkt_data = p; - p += pkt_data_len; /* Advance to the the next packet*/ - - bytes_to_process += pkt_data_len; - if (data_len < bytes_to_process) { - LOG(ERROR) << "Malformed LE extended advertising packet: not enough room " - "for packet data"; - return; - } - - if (rssi >= 21 && rssi <= 126) { - LOG_ERROR("%s: bad rssi value in advertising report: %d", __func__, rssi); - } - - // Store this to pass up the callback chain to GattService#onScanResult for - // the check in ScanFilter#matches - RawAddress original_bda = bda; - - if (addr_type != BLE_ADDR_ANONYMOUS) { - btm_ble_process_adv_addr(bda, &addr_type); - } - - btm_ble_process_adv_pkt_cont( - event_type, addr_type, bda, primary_phy, secondary_phy, advertising_sid, - tx_power, rssi, periodic_adv_int, pkt_data_len, pkt_data, original_bda); - } -} - -/** - * This function is called when advertising report event is received. It updates - * the inquiry database. If the inquiry database is full, the oldest entry is - * discarded. - */ -void btm_ble_process_adv_pkt(uint8_t data_len, const uint8_t* data) { - RawAddress bda; - const uint8_t* p = data; - uint8_t legacy_evt_type, addr_type, num_reports, pkt_data_len; - int8_t rssi; - size_t bytes_to_process; - - /* Only process the results if the inquiry is still active */ - if (!btm_cb.ble_ctr_cb.is_ble_scan_active()) return; - - bytes_to_process = 1; - - if (data_len < bytes_to_process) { - LOG(ERROR) - << "Malformed LE advertising packet: not enough room for num reports"; - return; - } - - /* Extract the number of reports in this event. */ - STREAM_TO_UINT8(num_reports, p); - - while (num_reports--) { - bytes_to_process += 9; - - if (data_len < bytes_to_process) { - LOG(ERROR) - << "Malformed LE advertising packet: not enough room for metadata"; - return; - } - - /* Extract inquiry results */ - STREAM_TO_UINT8(legacy_evt_type, p); - STREAM_TO_UINT8(addr_type, p); - STREAM_TO_BDADDR(bda, p); - STREAM_TO_UINT8(pkt_data_len, p); - - const uint8_t* pkt_data = p; - p += pkt_data_len; /* Advance to the the rssi byte */ - - // include rssi for this check - bytes_to_process += pkt_data_len + 1; - if (data_len < bytes_to_process) { - LOG(ERROR) << "Malformed LE advertising packet: not enough room for " - "packet data and/or RSSI"; - return; - } - - STREAM_TO_INT8(rssi, p); - - if (rssi >= 21 && rssi <= 126) { - LOG_ERROR("%s: bad rssi value in advertising report: %d", __func__, rssi); - } - - // Pass up the address to GattService#onScanResult to use in - // ScanFilter#matches - RawAddress original_bda = bda; - - btm_ble_process_adv_addr(bda, &addr_type); - - uint16_t event_type; - event_type = 1 << BLE_EVT_LEGACY_BIT; - if (legacy_evt_type == BTM_BLE_ADV_IND_EVT) { - event_type |= - (1 << BLE_EVT_CONNECTABLE_BIT) | (1 << BLE_EVT_SCANNABLE_BIT); - } else if (legacy_evt_type == BTM_BLE_ADV_DIRECT_IND_EVT) { - event_type |= - (1 << BLE_EVT_CONNECTABLE_BIT) | (1 << BLE_EVT_DIRECTED_BIT); - } else if (legacy_evt_type == BTM_BLE_ADV_SCAN_IND_EVT) { - event_type |= (1 << BLE_EVT_SCANNABLE_BIT); - } else if (legacy_evt_type == BTM_BLE_ADV_NONCONN_IND_EVT) { - event_type = (1 << BLE_EVT_LEGACY_BIT); // 0x0010; - } else if (legacy_evt_type == BTM_BLE_SCAN_RSP_EVT) { // SCAN_RSP; - // We can't distinguish between "SCAN_RSP to an ADV_IND", and "SCAN_RSP to - // an ADV_SCAN_IND", so always return "SCAN_RSP to an ADV_IND" - event_type |= (1 << BLE_EVT_CONNECTABLE_BIT) | - (1 << BLE_EVT_SCANNABLE_BIT) | - (1 << BLE_EVT_SCAN_RESPONSE_BIT); - } else { - LOG_ERROR( - "Malformed LE Advertising Report Event - unsupported " - "legacy_event_type 0x%02x", - legacy_evt_type); - return; - } - - btm_ble_process_adv_pkt_cont( - event_type, addr_type, bda, PHY_LE_1M, PHY_LE_NO_PACKET, NO_ADI_PRESENT, - TX_POWER_NOT_PRESENT, rssi, 0x00 /* no periodic adv */, pkt_data_len, - pkt_data, original_bda); - } -} - /** * This function is called after random address resolution is done, and proceed * to process adv packet. @@ -2756,7 +2457,6 @@ void btm_ble_process_adv_pkt_cont(uint16_t evt_type, tBLE_ADDR_TYPE addr_type, int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len, const uint8_t* data, const RawAddress& original_bda) { - tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; bool update = true; std::vector tmp; @@ -2788,7 +2488,8 @@ void btm_ble_process_adv_pkt_cont(uint16_t evt_type, tBLE_ADDR_TYPE addr_type, if (!data_complete) { // If we didn't receive whole adv data yet, don't report the device. - VLOG(1) << "Data not complete yet, waiting for more " << bda; + log::verbose("Data not complete yet, waiting for more {}", + ADDRESS_TO_LOGGABLE_STR(bda)); return; } @@ -2796,13 +2497,13 @@ void btm_ble_process_adv_pkt_cont(uint16_t evt_type, tBLE_ADDR_TYPE addr_type, btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_ACTI; if (is_active_scan && is_scannable && !is_scan_resp) { // If we didn't receive scan response yet, don't report the device. - VLOG(1) << " Waiting for scan response " << bda; + log::verbose(" Waiting for scan response {}", ADDRESS_TO_LOGGABLE_STR(bda)); return; } if (!AdvertiseDataParser::IsValid(adv_data)) { - VLOG(1) << __func__ << "Dropping bad advertisement packet: " - << base::HexEncode(adv_data.data(), adv_data.size()); + log::verbose("Dropping bad advertisement packet: {}", + base::HexEncode(adv_data.data(), adv_data.size())); cache.Clear(addr_type, bda); return; } @@ -2837,15 +2538,16 @@ void btm_ble_process_adv_pkt_cont(uint16_t evt_type, tBLE_ADDR_TYPE addr_type, if (p_i == NULL) { p_i = btm_inq_db_new(bda, true); if (p_i != NULL) { - p_inq->inq_cmpl_info.num_resp++; + btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); } else return; } else if (p_i->inq_count != - p_inq->inq_counter) /* first time seen in this inquiry */ + btm_cb.btm_inq_vars + .inq_counter) /* first time seen in this inquiry */ { p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); - p_inq->inq_cmpl_info.num_resp++; + btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; } /* update the LE device information in inquiry database */ @@ -2882,7 +2584,7 @@ void btm_ble_process_adv_pkt_cont(uint16_t evt_type, tBLE_ADDR_TYPE addr_type, if (!update) result &= ~BTM_BLE_INQ_RESULT; - tBTM_INQ_RESULTS_CB* p_inq_results_cb = p_inq->p_inq_results_cb; + tBTM_INQ_RESULTS_CB* p_inq_results_cb = btm_cb.btm_inq_vars.p_inq_results_cb; if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) { (p_inq_results_cb)((tBTM_INQ_RESULTS*)&p_i->inq_info.results, const_cast(adv_data.data()), adv_data.size()); @@ -2909,7 +2611,6 @@ void btm_ble_process_adv_pkt_cont_for_inquiry( uint8_t primary_phy, uint8_t secondary_phy, uint8_t advertising_sid, int8_t tx_power, int8_t rssi, uint16_t periodic_adv_int, std::vector advertising_data) { - tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; bool update = true; bool include_rsi = false; @@ -2943,19 +2644,20 @@ void btm_ble_process_adv_pkt_cont_for_inquiry( if (p_i == NULL) { p_i = btm_inq_db_new(bda, true); if (p_i != NULL) { - p_inq->inq_cmpl_info.num_resp++; + btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); btm_cb.neighbor.le_inquiry.results++; btm_cb.neighbor.le_legacy_scan.results++; } else { - LOG_WARN("Unable to allocate entry for inquiry result"); + log::warn("Unable to allocate entry for inquiry result"); return; } } else if (p_i->inq_count != - p_inq->inq_counter) /* first time seen in this inquiry */ + btm_cb.btm_inq_vars + .inq_counter) /* first time seen in this inquiry */ { p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); - p_inq->inq_cmpl_info.num_resp++; + btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; } /* update the LE device information in inquiry database */ @@ -2990,7 +2692,7 @@ void btm_ble_process_adv_pkt_cont_for_inquiry( if (!update) result &= ~BTM_BLE_INQ_RESULT; - tBTM_INQ_RESULTS_CB* p_inq_results_cb = p_inq->p_inq_results_cb; + tBTM_INQ_RESULTS_CB* p_inq_results_cb = btm_cb.btm_inq_vars.p_inq_results_cb; if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT)) { (p_inq_results_cb)((tBTM_INQ_RESULTS*)&p_i->inq_info.results, const_cast(advertising_data.data()), @@ -2998,22 +2700,6 @@ void btm_ble_process_adv_pkt_cont_for_inquiry( } } -void btm_ble_process_phy_update_pkt(uint8_t len, uint8_t* data) { - uint8_t status, tx_phy, rx_phy; - uint16_t handle; - - LOG_ASSERT(len == 5); - uint8_t* p = data; - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT16(handle, p); - handle = handle & 0x0FFF; - STREAM_TO_UINT8(tx_phy, p); - STREAM_TO_UINT8(rx_phy, p); - - gatt_notify_phy_updated(static_cast(status), handle, tx_phy, - rx_phy); -} - /******************************************************************************* * * Function btm_ble_start_scan @@ -3080,10 +2766,7 @@ static void btm_ble_stop_scan(void) { * ******************************************************************************/ void btm_ble_stop_inquiry(void) { - tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars; - tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb; - - alarm_cancel(p_ble_cb->inq_var.inquiry_timer); + alarm_cancel(btm_cb.ble_ctr_cb.inq_var.inquiry_timer); const unsigned long long duration_timestamp = timestamper_in_milliseconds.GetTimestamp() - @@ -3092,7 +2775,7 @@ void btm_ble_stop_inquiry(void) { base::StringPrintf("duration_s:%6.3f results:%-3lu", (double)duration_timestamp / 1000.0, btm_cb.neighbor.le_inquiry.results)); - p_ble_cb->reset_ble_inquiry(); + btm_cb.ble_ctr_cb.reset_ble_inquiry(); /* Cleanup anything remaining on index 0 */ BTM_BleAdvFilterParamSetup(BTM_BLE_SCAN_COND_DELETE, @@ -3100,22 +2783,25 @@ void btm_ble_stop_inquiry(void) { base::Bind(btm_ble_scan_filt_param_cfg_evt)); /* If no more scan activity, stop LE scan now */ - if (!p_ble_cb->is_ble_scan_active()) { + if (!btm_cb.ble_ctr_cb.is_ble_scan_active()) { btm_ble_stop_scan(); - } else if ((p_ble_cb->inq_var.scan_interval != - BTM_BLE_LOW_LATENCY_SCAN_INT) || - (p_ble_cb->inq_var.scan_window != BTM_BLE_LOW_LATENCY_SCAN_WIN)) { - LOG_VERBOSE("%s: setting default params for ongoing observe", __func__); + } else if (get_low_latency_scan_params() != + std::pair(btm_cb.ble_ctr_cb.inq_var.scan_interval, + btm_cb.ble_ctr_cb.inq_var.scan_window)) { + log::verbose("setting default params for ongoing observe"); btm_ble_stop_scan(); btm_ble_start_scan(); } /* If we have a callback registered for inquiry complete, call it */ - LOG_VERBOSE("BTM Inq Compl Callback: status 0x%02x, num results %d", - p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp); + log::verbose("BTM Inq Compl Callback: status 0x{:02x}, num results {}", + btm_cb.btm_inq_vars.inq_cmpl_info.status, + btm_cb.btm_inq_vars.inq_cmpl_info.num_resp); + // TODO: remove this call and make btm_process_inq_complete static btm_process_inq_complete( - HCI_SUCCESS, (uint8_t)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK)); + HCI_SUCCESS, + (uint8_t)(btm_cb.btm_inq_vars.inqparms.mode & BTM_BLE_INQUIRY_MASK)); } /******************************************************************************* @@ -3128,17 +2814,16 @@ void btm_ble_stop_inquiry(void) { * ******************************************************************************/ static void btm_ble_stop_observe(void) { - tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb; - tBTM_CMPL_CB* p_obs_cb = p_ble_cb->p_obs_cmpl_cb; + tBTM_CMPL_CB* p_obs_cb = btm_cb.ble_ctr_cb.p_obs_cmpl_cb; - alarm_cancel(p_ble_cb->observer_timer); + alarm_cancel(btm_cb.ble_ctr_cb.observer_timer); - p_ble_cb->reset_ble_observe(); + btm_cb.ble_ctr_cb.reset_ble_observe(); - p_ble_cb->p_obs_results_cb = NULL; - p_ble_cb->p_obs_cmpl_cb = NULL; + btm_cb.ble_ctr_cb.p_obs_results_cb = NULL; + btm_cb.ble_ctr_cb.p_obs_cmpl_cb = NULL; - if (!p_ble_cb->is_ble_scan_active()) { + if (!btm_cb.ble_ctr_cb.is_ble_scan_active()) { btm_ble_stop_scan(); } @@ -3179,7 +2864,7 @@ static bool btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR* p_handler, break; default: - LOG_ERROR("unknown adv event : %d", adv_evt); + log::error("unknown adv event : {}", adv_evt); break; } @@ -3196,14 +2881,14 @@ static bool btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR* p_handler, * ******************************************************************************/ static tBTM_STATUS btm_ble_start_adv(void) { - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; - - if (!btm_ble_adv_states_operation(btm_ble_topology_check, p_cb->evt_type)) + if (!btm_ble_adv_states_operation(btm_ble_topology_check, + btm_cb.ble_ctr_cb.inq_var.evt_type)) return BTM_WRONG_MODE; btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_ENABLE); - p_cb->adv_mode = BTM_BLE_ADV_ENABLE; - btm_ble_adv_states_operation(btm_ble_set_topology_mask, p_cb->evt_type); + btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_ENABLE; + btm_ble_adv_states_operation(btm_ble_set_topology_mask, + btm_cb.ble_ctr_cb.inq_var.evt_type); power_telemetry::GetInstance().LogBleAdvStarted(); return BTM_SUCCESS; @@ -3219,13 +2904,11 @@ static tBTM_STATUS btm_ble_start_adv(void) { * ******************************************************************************/ static tBTM_STATUS btm_ble_stop_adv(void) { - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; - - if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { + if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_DISABLE); - p_cb->fast_adv_on = false; - p_cb->adv_mode = BTM_BLE_ADV_DISABLE; + btm_cb.ble_ctr_cb.inq_var.fast_adv_on = false; + btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; /* clear all adv states */ btm_ble_clear_topology_mask(BTM_BLE_STATE_ALL_ADV_MASK); power_telemetry::GetInstance().LogBleAdvStopped(); @@ -3248,9 +2931,7 @@ static void btm_ble_fast_adv_timer_timeout(UNUSED_ATTR void* data) { * ******************************************************************************/ static void btm_ble_start_slow_adv(void) { - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; - - if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { + if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { tBTM_LE_RANDOM_CB* p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; RawAddress address = RawAddress::kEmpty; tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC; @@ -3258,13 +2939,15 @@ static void btm_ble_start_slow_adv(void) { btm_ble_stop_adv(); - p_cb->evt_type = btm_set_conn_mode_adv_init_addr(address, &init_addr_type, - &own_addr_type); + btm_cb.ble_ctr_cb.inq_var.evt_type = btm_set_conn_mode_adv_init_addr( + address, &init_addr_type, &own_addr_type); /* slow adv mode never goes into directed adv */ btsnd_hcic_ble_write_adv_params( - BTM_BLE_GAP_ADV_SLOW_INT, BTM_BLE_GAP_ADV_SLOW_INT, p_cb->evt_type, - own_addr_type, init_addr_type, address, p_cb->adv_chnl_map, p_cb->afp); + BTM_BLE_GAP_ADV_SLOW_INT, BTM_BLE_GAP_ADV_SLOW_INT, + btm_cb.ble_ctr_cb.inq_var.evt_type, own_addr_type, init_addr_type, + address, btm_cb.ble_ctr_cb.inq_var.adv_chnl_map, + btm_cb.ble_ctr_cb.inq_var.afp); btm_ble_start_adv(); } @@ -3311,11 +2994,11 @@ void btm_ble_read_remote_features_complete(uint8_t* p, uint8_t length) { if (status != HCI_SUCCESS) { if (status != HCI_ERR_UNSUPPORTED_REM_FEATURE) { - LOG_ERROR("Failed to read remote features status:%s", - hci_error_code_text(static_cast(status)).c_str()); + log::error("Failed to read remote features status:{}", + hci_error_code_text(static_cast(status)).c_str()); return; } - LOG_WARN("Remote does not support reading remote feature"); + log::warn("Remote does not support reading remote feature"); } if (status == HCI_SUCCESS) { @@ -3326,7 +3009,7 @@ void btm_ble_read_remote_features_complete(uint8_t* p, uint8_t length) { } if (!acl_set_peer_le_features_from_handle(handle, p)) { - LOG_ERROR( + log::error( "Unable to find existing connection after read remote features"); return; } @@ -3337,7 +3020,7 @@ void btm_ble_read_remote_features_complete(uint8_t* p, uint8_t length) { return; err_out: - LOG_ERROR("Bogus event packet, too short"); + log::error("Bogus event packet, too short"); } /******************************************************************************* @@ -3350,12 +3033,10 @@ err_out: * ******************************************************************************/ void btm_ble_write_adv_enable_complete(uint8_t* p, uint16_t evt_len) { - tBTM_BLE_INQ_CB* p_cb = &btm_cb.ble_ctr_cb.inq_var; - /* if write adv enable/disbale not succeed */ if (evt_len < 1 || *p != HCI_SUCCESS) { /* toggle back the adv mode */ - p_cb->adv_mode = !p_cb->adv_mode; + btm_cb.ble_ctr_cb.inq_var.adv_mode = !btm_cb.ble_ctr_cb.inq_var.adv_mode; } } @@ -3470,24 +3151,6 @@ void btm_ble_update_mode_operation(uint8_t link_role, const RawAddress* bd_addr, btm_ble_set_connectability(btm_cb.btm_inq_vars.connectable_mode | btm_cb.ble_ctr_cb.inq_var.connectable_mode); } - - /* in case of disconnected, we must cancel bgconn and restart - in order to add back device to acceptlist in order to reconnect */ - if (bd_addr != nullptr) { - LOG_DEBUG("gd_acl enabled so skip background connection logic"); - } - - /* when no connection is attempted, and controller is not rejecting last - request - due to resource limitation, start next direct connection or background - connection - now in order */ - if (btm_cb.ble_ctr_cb.is_connection_state_idle() && - status != HCI_ERR_HOST_REJECT_RESOURCES && - status != HCI_ERR_MAX_NUM_OF_CONNECTIONS) { - LOG_DEBUG("Resuming le background connections"); - btm_ble_resume_bg_conn(); - } } /******************************************************************************* @@ -3500,32 +3163,32 @@ void btm_ble_update_mode_operation(uint8_t link_role, const RawAddress* bd_addr, * ******************************************************************************/ void btm_ble_init(void) { - tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb; - - LOG_VERBOSE("%s", __func__); + log::verbose(""); - alarm_free(p_cb->observer_timer); - alarm_free(p_cb->inq_var.fast_adv_timer); - memset(p_cb, 0, sizeof(tBTM_BLE_CB)); + alarm_free(btm_cb.ble_ctr_cb.observer_timer); + alarm_free(btm_cb.ble_ctr_cb.inq_var.fast_adv_timer); + memset(&btm_cb.ble_ctr_cb, 0, sizeof(tBTM_BLE_CB)); memset(&(btm_cb.cmn_ble_vsc_cb), 0, sizeof(tBTM_BLE_VSC_CB)); btm_cb.cmn_ble_vsc_cb.values_read = false; - p_cb->observer_timer = alarm_new("btm_ble.observer_timer"); - p_cb->cur_states = 0; - - p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE; - p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; - p_cb->inq_var.adv_chnl_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP; - p_cb->inq_var.afp = BTM_BLE_DEFAULT_AFP; - p_cb->inq_var.sfp = BTM_BLE_DEFAULT_SFP; - p_cb->inq_var.connectable_mode = BTM_BLE_NON_CONNECTABLE; - p_cb->inq_var.discoverable_mode = BTM_BLE_NON_DISCOVERABLE; - p_cb->inq_var.fast_adv_timer = alarm_new("btm_ble_inq.fast_adv_timer"); - p_cb->inq_var.inquiry_timer = alarm_new("btm_ble_inq.inquiry_timer"); + btm_cb.ble_ctr_cb.observer_timer = alarm_new("btm_ble.observer_timer"); + btm_cb.ble_ctr_cb.cur_states = 0; - p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT; - - p_cb->addr_mgnt_cb.refresh_raddr_timer = + btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; + btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; + btm_cb.ble_ctr_cb.inq_var.adv_chnl_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP; + btm_cb.ble_ctr_cb.inq_var.afp = BTM_BLE_DEFAULT_AFP; + btm_cb.ble_ctr_cb.inq_var.sfp = BTM_BLE_DEFAULT_SFP; + btm_cb.ble_ctr_cb.inq_var.connectable_mode = BTM_BLE_NON_CONNECTABLE; + btm_cb.ble_ctr_cb.inq_var.discoverable_mode = BTM_BLE_NON_DISCOVERABLE; + btm_cb.ble_ctr_cb.inq_var.fast_adv_timer = + alarm_new("btm_ble_inq.fast_adv_timer"); + btm_cb.ble_ctr_cb.inq_var.inquiry_timer = + alarm_new("btm_ble_inq.inquiry_timer"); + + btm_cb.ble_ctr_cb.inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT; + + btm_cb.ble_ctr_cb.addr_mgnt_cb.refresh_raddr_timer = alarm_new("btm_ble_addr.refresh_raddr_timer"); btm_ble_pa_sync_cb = {}; sync_timeout_alarm = alarm_new("btm.sync_start_task"); @@ -3536,8 +3199,7 @@ void btm_ble_init(void) { // Clean up btm ble control block void btm_ble_free() { - tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb; - alarm_free(p_cb->addr_mgnt_cb.refresh_raddr_timer); + alarm_free(btm_cb.ble_ctr_cb.addr_mgnt_cb.refresh_raddr_timer); } /******************************************************************************* @@ -3561,7 +3223,7 @@ bool btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask) { if (request_state_mask == BTM_BLE_STATE_INVALID || request_state_mask > BTM_BLE_STATE_SCAN_ADV_BIT || (request_state_mask & (request_state_mask - 1)) != 0) { - LOG_ERROR("illegal state requested: %d", request_state_mask); + log::error("illegal state requested: {}", request_state_mask); return rt; } @@ -3576,7 +3238,7 @@ bool btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask) { controller_get_interface()->get_ble_supported_states(); if (!BTM_LE_STATES_SUPPORTED(ble_supported_states, bit_num)) { - LOG_ERROR("state requested not supported: %d", request_state); + log::error("state requested not supported: {}", request_state); return rt; } diff --git a/system/stack/btm/btm_ble_int.h b/system/stack/btm/btm_ble_int.h index 0dafe2f75192022d367ce3a54baab921823eb4d8..3f3fa77a1477bf481442ebdea937b4356909d5b9 100644 --- a/system/stack/btm/btm_ble_int.h +++ b/system/stack/btm/btm_ble_int.h @@ -48,8 +48,6 @@ void btm_ble_connected(const RawAddress& bda, uint16_t handle, uint8_t enc_mode, void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy); /* background connection function */ -bool btm_ble_suspend_bg_conn(void); -bool btm_ble_resume_bg_conn(void); void btm_ble_update_mode_operation(uint8_t link_role, const RawAddress* bda, tHCI_STATUS status); /* BLE address management */ diff --git a/system/stack/btm/btm_ble_int_types.h b/system/stack/btm/btm_ble_int_types.h index 443fc799529c53213aa45d473116cfe4d6d7eb0d..230f064c317cc5bc94b18ea9c7be56d425fb3fde 100644 --- a/system/stack/btm/btm_ble_int_types.h +++ b/system/stack/btm/btm_ble_int_types.h @@ -81,8 +81,8 @@ typedef struct { typedef struct { uint16_t discoverable_mode; uint16_t connectable_mode; - uint32_t scan_window; - uint32_t scan_interval; + uint16_t scan_window; + uint16_t scan_interval; uint8_t scan_type; /* current scan type: active or passive */ tBTM_BLE_AFP afp; /* advertising filter policy */ diff --git a/system/stack/btm/btm_ble_privacy.cc b/system/stack/btm/btm_ble_privacy.cc index 4c527c8e74839ea596577aeb096cc0cd8aa8dcdd..90c8b756cc8b7b58fb10bff7ec8d924b45c067fb 100644 --- a/system/stack/btm/btm_ble_privacy.cc +++ b/system/stack/btm/btm_ble_privacy.cc @@ -25,6 +25,8 @@ #include "stack/include/btm_ble_privacy.h" +#include + #include "btm_dev.h" #include "btm_sec_cb.h" #include "btm_sec_int_types.h" @@ -38,6 +40,8 @@ #include "stack/include/btm_api.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; /* RPA offload VSC specifics */ @@ -181,7 +185,7 @@ static uint8_t btm_ble_find_irk_index(void) { i++; } - LOG_ERROR("%s failed, list full", __func__); + log::error("no index found"); return i; } @@ -201,11 +205,11 @@ static void btm_ble_update_resolving_list(const RawAddress& pseudo_bda, if (add) { p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT; - if (!controller_get_interface()->supports_ble_privacy()) + if (!controller_get_interface()->SupportsBlePrivacy()) p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index(); } else { p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT; - if (!controller_get_interface()->supports_ble_privacy()) { + if (!controller_get_interface()->SupportsBlePrivacy()) { /* clear IRK list index mask */ btm_ble_clear_irk_index(p_dev_rec->ble.resolving_list_index); p_dev_rec->ble.resolving_list_index = 0; @@ -233,13 +237,13 @@ void btm_ble_clear_resolving_list_complete(uint8_t* p, uint16_t evt_len) { uint8_t status = 0; if (evt_len < 1) { - LOG_ERROR("malformatted event packet: containing zero bytes"); + log::error("malformatted event packet: containing zero bytes"); return; } STREAM_TO_UINT8(status, p); - LOG_VERBOSE("%s status=%d", __func__, status); + log::verbose("status={}", status); if (status == HCI_SUCCESS) { if (evt_len >= 3) { @@ -262,8 +266,8 @@ void btm_ble_clear_resolving_list_complete(uint8_t* p, uint16_t evt_len) { btm_cb.ble_ctr_cb.resolving_list_avail_size = controller_get_interface()->get_ble_resolving_list_max_size(); - LOG_VERBOSE("%s resolving_list_avail_size=%d", __func__, - btm_cb.ble_ctr_cb.resolving_list_avail_size); + log::verbose("resolving_list_avail_size={}", + btm_cb.ble_ctr_cb.resolving_list_avail_size); list_foreach(btm_sec_cb.sec_dev_rec, clear_resolving_list_bit, NULL); } @@ -283,17 +287,17 @@ void btm_ble_add_resolving_list_entry_complete(uint8_t* p, uint16_t evt_len) { uint8_t status; if (evt_len < 1) { - LOG_ERROR("malformatted event packet: containing zero byte"); + log::error("malformatted event packet: containing zero byte"); return; } STREAM_TO_UINT8(status, p); - LOG_VERBOSE("%s status = %d", __func__, status); + log::verbose("status={}", status); RawAddress pseudo_bda; if (!btm_ble_deq_resolving_pending(pseudo_bda)) { - LOG_VERBOSE("no pending resolving list operation"); + log::verbose("no pending resolving list operation"); return; } @@ -310,7 +314,7 @@ void btm_ble_add_resolving_list_entry_complete(uint8_t* p, uint16_t evt_len) { HCI_ERR_MEMORY_FULL) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */ { btm_cb.ble_ctr_cb.resolving_list_avail_size = 0; - LOG_VERBOSE("%s Resolving list Full ", __func__); + log::verbose("Resolving list Full"); } } @@ -331,10 +335,10 @@ void btm_ble_remove_resolving_list_entry_complete(uint8_t* p, STREAM_TO_UINT8(status, p); - LOG_VERBOSE("%s status = %d", __func__, status); + log::verbose("status={}", status); if (!btm_ble_deq_resolving_pending(pseudo_bda)) { - LOG_ERROR("%s no pending resolving list operation", __func__); + log::error("no pending resolving list operation"); return; } @@ -365,10 +369,10 @@ void btm_ble_read_resolving_list_entry_complete(const uint8_t* p, STREAM_TO_UINT8(status, p); - LOG_VERBOSE("%s status = %d", __func__, status); + log::verbose("status={}", status); if (!btm_ble_deq_resolving_pending(pseudo_bda)) { - LOG_ERROR("no pending resolving list operation"); + log::error("no pending resolving list operation"); return; } @@ -379,7 +383,7 @@ void btm_ble_read_resolving_list_entry_complete(const uint8_t* p, p += (2 + 16 + 1 + 6); STREAM_TO_BDADDR(rra, p); - VLOG(2) << __func__ << " peer_addr: " << rra; + log::info("peer_addr:{}", ADDRESS_TO_LOGGABLE_CSTR(rra)); } else { STREAM_TO_BDADDR(rra, p); } @@ -407,7 +411,7 @@ static void btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL* p_params) { op_subcode = *(p + 1); - LOG_VERBOSE("%s op_subcode = %d", __func__, op_subcode); + log::verbose("op_subcode={}", op_subcode); if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) { btm_ble_clear_resolving_list_complete(p, evt_len); @@ -440,7 +444,7 @@ static tBTM_STATUS btm_ble_remove_resolving_list_entry( if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) return BTM_WRONG_MODE; - if (controller_get_interface()->supports_ble_privacy()) { + if (controller_get_interface()->SupportsBlePrivacy()) { bluetooth::shim::ACL_RemoveFromAddressResolution( p_dev_rec->ble.identity_address_with_type); } else { @@ -470,7 +474,7 @@ static tBTM_STATUS btm_ble_remove_resolving_list_entry( * ******************************************************************************/ static void btm_ble_clear_resolving_list(void) { - if (controller_get_interface()->supports_ble_privacy()) { + if (controller_get_interface()->SupportsBlePrivacy()) { bluetooth::shim::ACL_ClearAddressResolution(); } else { uint8_t param[20] = {0}; @@ -496,16 +500,15 @@ static void btm_ble_clear_resolving_list(void) { ******************************************************************************/ bool btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { if (btm_cb.ble_ctr_cb.privacy_mode < BTM_PRIVACY_1_2) { - LOG_DEBUG("Privacy 1.2 is not enabled"); + log::debug("Privacy 1.2 is not enabled"); return false; } if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) { - LOG_INFO("%s Unable to read resolving list entry as resolving bit not set", - __func__); + log::info("Unable to read resolving list entry as resolving bit not set"); return false; } - if (controller_get_interface()->supports_ble_privacy()) { + if (controller_get_interface()->SupportsBlePrivacy()) { btsnd_hcic_ble_read_resolvable_addr_peer( p_dev_rec->ble.identity_address_with_type.type, p_dev_rec->ble.identity_address_with_type.bda); @@ -527,7 +530,7 @@ bool btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { static void btm_ble_ble_unsupported_resolving_list_load_dev( tBTM_SEC_DEV_REC* p_dev_rec) { - LOG_INFO("Controller does not support BLE privacy"); + log::info("Controller does not support BLE privacy"); uint8_t param[40] = {0}; uint8_t* p = param; @@ -552,28 +555,28 @@ static Octet16 get_local_irk() { return btm_sec_cb.devcb.id_keys.irk; } void btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC& dev_rec) { if (btm_cb.ble_ctr_cb.privacy_mode < BTM_PRIVACY_1_2) { - LOG_DEBUG("Privacy 1.2 is not enabled"); + log::debug("Privacy 1.2 is not enabled"); return; } if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) { - LOG_INFO("Controller does not support RPA offloading or privacy 1.2"); + log::info("Controller does not support RPA offloading or privacy 1.2"); return; } - if (!controller_get_interface()->supports_ble_privacy()) { + if (!controller_get_interface()->SupportsBlePrivacy()) { return btm_ble_ble_unsupported_resolving_list_load_dev(&dev_rec); } // No need to check for local identity key validity. It remains unchanged. if (!is_peer_identity_key_valid(dev_rec)) { - LOG_INFO("Peer is not an RPA enabled device:%s", - ADDRESS_TO_LOGGABLE_CSTR(dev_rec.ble.identity_address_with_type)); + log::info("Peer is not an RPA enabled device:{}", + ADDRESS_TO_LOGGABLE_CSTR(dev_rec.ble.identity_address_with_type)); return; } if (dev_rec.ble.in_controller_list & BTM_RESOLVING_LIST_BIT) { - LOG_WARN("Already in Address Resolving list device:%s", - ADDRESS_TO_LOGGABLE_CSTR(dev_rec.ble.identity_address_with_type)); + log::warn("Already in Address Resolving list device:{}", + ADDRESS_TO_LOGGABLE_CSTR(dev_rec.ble.identity_address_with_type)); return; } @@ -588,16 +591,16 @@ void btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC& dev_rec) { } if (!is_ble_addr_type_known(dev_rec.ble.identity_address_with_type.type)) { - LOG_ERROR("Adding unknown address type(%d) to Address Resolving list.", - dev_rec.ble.identity_address_with_type.type); + log::error("Adding unknown address type({}) to Address Resolving list.", + dev_rec.ble.identity_address_with_type.type); return; } bluetooth::shim::ACL_AddToAddressResolution( dev_rec.ble.identity_address_with_type, peer_irk, local_irk); - LOG_DEBUG("Added to Address Resolving list device:%s", - ADDRESS_TO_LOGGABLE_CSTR(dev_rec.ble.identity_address_with_type)); + log::debug("Added to Address Resolving list device:{}", + ADDRESS_TO_LOGGABLE_CSTR(dev_rec.ble.identity_address_with_type)); dev_rec.ble.in_controller_list |= BTM_RESOLVING_LIST_BIT; } @@ -615,10 +618,9 @@ void btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC& dev_rec) { ******************************************************************************/ void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) { if (btm_cb.ble_ctr_cb.privacy_mode < BTM_PRIVACY_1_2) { - LOG_DEBUG("Privacy 1.2 is not enabled"); + log::debug("Privacy 1.2 is not enabled"); return; } - LOG_VERBOSE("%s", __func__); if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && !btm_ble_brcm_find_resolving_pending_entry( @@ -626,7 +628,7 @@ void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) { btm_ble_update_resolving_list(p_dev_rec->bd_addr, false); btm_ble_remove_resolving_list_entry(p_dev_rec); } else { - LOG_VERBOSE("Device not in resolving list"); + log::verbose("Device not in resolving list"); } } @@ -658,7 +660,7 @@ void btm_ble_resolving_list_init(uint8_t max_irk_list_sz) { // NOTE: This memory is never freed btm_cb.ble_ctr_cb.irk_list_mask = (uint8_t*)osi_malloc(irk_mask_size); - LOG_VERBOSE("%s max_irk_list_sz = %d", __func__, max_irk_list_sz); + log::verbose("max_irk_list_sz={}", max_irk_list_sz); } controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz); diff --git a/system/stack/btm/btm_ble_scanner.cc b/system/stack/btm/btm_ble_scanner.cc index c4523179b19f88bdf36303ab8c1ab69cea16acfd..107d7108270c65ef324ddd20d67e454f665b8554 100644 --- a/system/stack/btm/btm_ble_scanner.cc +++ b/system/stack/btm/btm_ble_scanner.cc @@ -14,21 +14,16 @@ * limitations under the License. */ -#include -#include - -#include -#include +#include #include "ble_scanner.h" #include "ble_scanner_hci_interface.h" -#include "bt_target.h" -#include "btm_int_types.h" -#include "device/include/controller.h" +#include "internal_include/bt_target.h" #include "internal_include/stack_config.h" -#include "osi/include/alarm.h" #include "stack/btm/btm_ble_int.h" +using namespace bluetooth; + std::mutex lock1; namespace { @@ -39,7 +34,7 @@ BleScanningManager* instance; base::WeakPtr instance_weakptr; static void status_callback(uint8_t status) { - VLOG(1) << __func__ << " Received status_cb with status:" << status; + log::verbose("Received status_cb with status:{}", status); } class BleScanningManagerImpl @@ -154,13 +149,13 @@ void btm_ble_scanner_init() { if (BleScannerHciInterface::Get()) { BleScanningManager::Initialize(BleScannerHciInterface::Get()); } else { - VLOG(1) << __func__ << " BleScannerHciInterface::Get() returns null"; + log::verbose("BleScannerHciInterface::Get() returns null"); } if ((BleScannerHciInterface::Get()) && (BleScanningManager::Get())) { BleScannerHciInterface::Get()->SetScanEventObserver( (BleScanningManagerImpl*)BleScanningManager::Get().get()); } else { - VLOG(1) << __func__ << " BleScannerHciInterface or BleScanningManager is null"; + log::verbose("BleScannerHciInterface or BleScanningManager is null"); } } diff --git a/system/stack/btm/btm_ble_sec.cc b/system/stack/btm/btm_ble_sec.cc index 6d4c06f696fbcd888e41f990395247ba553ff055..adb241fc0f4f10c968b6b70fce9bd7e3670931ca 100644 --- a/system/stack/btm/btm_ble_sec.cc +++ b/system/stack/btm/btm_ble_sec.cc @@ -20,6 +20,7 @@ #include "stack/btm/btm_ble_sec.h" #include +#include #include #include @@ -58,6 +59,8 @@ #include "stack/include/smp_api_types.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; bool btm_ble_init_pseudo_addr(tBTM_SEC_DEV_REC* p_dev_rec, @@ -75,7 +78,7 @@ static constexpr char kPropertyCtkdDisableCsrkDistribution[] = /******************************************************************************/ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, tBLE_ADDR_TYPE addr_type) { - LOG_DEBUG("dev_type=0x%x", dev_type); + log::debug("dev_type=0x{:x}", dev_type); tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (!p_dev_rec) { @@ -91,9 +94,9 @@ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, p_dev_rec->conn_params.supervision_tout = BTM_BLE_CONN_PARAM_UNDEF; p_dev_rec->conn_params.peripheral_latency = BTM_BLE_CONN_PARAM_UNDEF; - LOG_DEBUG("Device added, handle=0x%x, p_dev_rec=%p, bd_addr=%s", - p_dev_rec->ble_hci_handle, p_dev_rec, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Device added, handle=0x{:x}, p_dev_rec={}, bd_addr={}", + p_dev_rec->ble_hci_handle, fmt::ptr(p_dev_rec), + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME)); @@ -102,7 +105,7 @@ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, if (is_ble_addr_type_known(addr_type)) { p_dev_rec->ble.SetAddressType(addr_type); } else { - LOG_WARN( + log::warn( "Please do not update device record from anonymous le advertisement"); } @@ -111,8 +114,8 @@ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, if (p_info) { p_info->results.ble_addr_type = p_dev_rec->ble.AddressType(); p_dev_rec->device_type |= p_info->results.device_type; - LOG_DEBUG("InqDb device_type =0x%x addr_type=0x%x", p_dev_rec->device_type, - p_info->results.ble_addr_type); + log::debug("InqDb device_type =0x{:x} addr_type=0x{:x}", + p_dev_rec->device_type, p_info->results.ble_addr_type); p_info->results.device_type = p_dev_rec->device_type; } } @@ -128,7 +131,7 @@ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, * ******************************************************************************/ bool BTM_GetRemoteDeviceName(const RawAddress& bd_addr, BD_NAME bd_name) { - LOG_VERBOSE("bd_addr:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("bd_addr:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); bool ret = FALSE; bt_bdname_t bdname; @@ -138,7 +141,7 @@ bool BTM_GetRemoteDeviceName(const RawAddress& bd_addr, BD_NAME bd_name) { if (btif_storage_get_remote_device_property(&bd_addr, &prop_name) == BT_STATUS_SUCCESS) { - LOG_VERBOSE("NV name=%s", bdname.name); + log::verbose("NV name={}", reinterpret_cast(bdname.name)); strncpy((char*)bd_name, (char*)bdname.name, BD_NAME_LEN + 1); ret = TRUE; } @@ -167,13 +170,13 @@ void BTM_SecAddBleKey(const RawAddress& bd_addr, tBTM_LE_KEY_VALUE* p_le_key, (key_type != BTM_LE_KEY_PENC && key_type != BTM_LE_KEY_PID && key_type != BTM_LE_KEY_PCSRK && key_type != BTM_LE_KEY_LENC && key_type != BTM_LE_KEY_LCSRK && key_type != BTM_LE_KEY_LID)) { - LOG_WARN("Wrong Type, or No Device record for bdaddr:%s, Type:0%hhu", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type); + log::warn("Wrong Type, or No Device record for bdaddr:{}, Type:0{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type); return; } - LOG_DEBUG("Adding BLE key device:%s key_type:%hhu", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type); + log::debug("Adding BLE key device:{} key_type:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type); btm_sec_save_le_key(bd_addr, key_type, p_le_key, false); // Only set peer irk. Local irk is always the same. @@ -198,7 +201,7 @@ void BTM_SecAddBleKey(const RawAddress& bd_addr, tBTM_LE_KEY_VALUE* p_le_key, ******************************************************************************/ void BTM_BleLoadLocalKeys(uint8_t key_type, tBTM_BLE_LOCAL_KEYS* p_key) { tBTM_SEC_DEVCB* p_devcb = &btm_sec_cb.devcb; - LOG_VERBOSE("type:%d", key_type); + log::verbose("type:{}", key_type); if (p_key != NULL) { switch (key_type) { case BTM_BLE_KEY_TYPE_ID: @@ -211,7 +214,7 @@ void BTM_BleLoadLocalKeys(uint8_t key_type, tBTM_BLE_LOCAL_KEYS* p_key) { break; default: - LOG_ERROR("unknown key type:%d", key_type); + log::error("unknown key type:{}", key_type); break; } } @@ -245,8 +248,8 @@ const Octet16& BTM_GetDeviceDHK() { return btm_sec_cb.devcb.id_keys.dhk; } void BTM_SecurityGrant(const RawAddress& bd_addr, uint8_t res) { const tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_REPEATED_ATTEMPTS; - LOG_VERBOSE("bd_addr:%s, res:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - smp_status_text(res_smp).c_str()); + log::verbose("bd_addr:{}, res:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + smp_status_text(res_smp).c_str()); BTM_LogHistory(kBtmLogTag, bd_addr, "Granted", base::StringPrintf("passkey_status:%s", smp_status_text(res_smp).c_str())); @@ -271,9 +274,9 @@ void BTM_SecurityGrant(const RawAddress& bd_addr, uint8_t res) { void BTM_BlePasskeyReply(const RawAddress& bd_addr, uint8_t res, uint32_t passkey) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); - LOG_VERBOSE("bd_addr:%s, res:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), res); + log::verbose("bd_addr:{}, res:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), res); if (p_dev_rec == NULL) { - LOG_ERROR("Unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } @@ -302,9 +305,9 @@ void BTM_BlePasskeyReply(const RawAddress& bd_addr, uint8_t res, ******************************************************************************/ void BTM_BleConfirmReply(const RawAddress& bd_addr, uint8_t res) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); - LOG_VERBOSE("bd_addr:%s, res:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), res); + log::verbose("bd_addr:{}, res:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), res); if (p_dev_rec == NULL) { - LOG_ERROR("Unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } const tSMP_STATUS res_smp = @@ -339,7 +342,7 @@ void BTM_BleOobDataReply(const RawAddress& bd_addr, uint8_t res, uint8_t len, uint8_t* p_data) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_ERROR("Unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } @@ -370,7 +373,7 @@ void BTM_BleSecureConnectionOobDataReply(const RawAddress& bd_addr, uint8_t* p_c, uint8_t* p_r) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_ERROR("Unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } @@ -416,8 +419,8 @@ void BTM_BleSetPrefConnParams(const RawAddress& bd_addr, uint16_t min_conn_int, uint16_t supervision_tout) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); - LOG_VERBOSE("min:%u,max:%u,latency:%u,tout:%u", min_conn_int, max_conn_int, - peripheral_latency, supervision_tout); + log::verbose("min:{},max:{},latency:{},tout:{}", min_conn_int, max_conn_int, + peripheral_latency, supervision_tout); if (BTM_BLE_ISVALID_PARAM(min_conn_int, BTM_BLE_CONN_INT_MIN, BTM_BLE_CONN_INT_MAX) && @@ -456,10 +459,10 @@ void BTM_BleSetPrefConnParams(const RawAddress& bd_addr, uint16_t min_conn_int, } } else { - LOG_ERROR("Unknown Device, setting rejected"); + log::error("Unknown Device, setting rejected"); } } else { - LOG_ERROR("Illegal Connection Parameters"); + log::error("Illegal Connection Parameters"); } } @@ -490,7 +493,7 @@ void BTM_ReadDevInfo(const RawAddress& remote_bda, tBT_DEVICE_TYPE* p_dev_type, *p_addr_type = p_inq_info->results.ble_addr_type; } else { /* unknown device, assume BR/EDR */ - LOG_VERBOSE("unknown device, BR/EDR assumed"); + log::verbose("unknown device, BR/EDR assumed"); } } else /* there is a security device record existing */ { @@ -500,7 +503,7 @@ void BTM_ReadDevInfo(const RawAddress& remote_bda, tBT_DEVICE_TYPE* p_dev_type, if (is_ble_addr_type_known(p_inq_info->results.ble_addr_type)) p_dev_rec->ble.SetAddressType(p_inq_info->results.ble_addr_type); else - LOG_WARN( + log::warn( "Please do not update device record from anonymous le " "advertisement"); } @@ -516,15 +519,15 @@ void BTM_ReadDevInfo(const RawAddress& remote_bda, tBT_DEVICE_TYPE* p_dev_type, if (p_dev_rec->device_type != BT_DEVICE_TYPE_UNKNOWN) { *p_dev_type = p_dev_rec->device_type; } else { - LOG_WARN("device_type not set; assuming BR/EDR"); + log::warn("device_type not set; assuming BR/EDR"); *p_dev_type = BT_DEVICE_TYPE_BREDR; } *p_addr_type = BLE_ADDR_PUBLIC; } } - LOG_DEBUG("Determined device_type:%s addr_type:%s", - DeviceTypeText(*p_dev_type).c_str(), - AddressTypeText(*p_addr_type).c_str()); + log::debug("Determined device_type:{} addr_type:{}", + DeviceTypeText(*p_dev_type).c_str(), + AddressTypeText(*p_addr_type).c_str()); } /******************************************************************************* @@ -572,17 +575,17 @@ bool BTM_ReadConnectedTransportAddress(RawAddress* remote_bda, tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr, uint16_t tx_pdu_length) { - if (!controller_get_interface()->supports_ble_packet_extension()) { - LOG_INFO("Local controller does not support le packet extension"); + if (!controller_get_interface()->SupportsBleDataPacketLengthExtension()) { + log::info("Local controller does not support le packet extension"); return BTM_ILLEGAL_VALUE; } - LOG_INFO("bd_addr:%s, tx_pdu_length:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - tx_pdu_length); + log::info("bd_addr:{}, tx_pdu_length:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + tx_pdu_length); auto p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_ERROR("Device %s not found", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Device {} not found", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return BTM_UNKNOWN_ADDR; } @@ -592,8 +595,8 @@ tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr, tx_pdu_length = BTM_BLE_DATA_SIZE_MIN; if (p_dev_rec->get_suggested_tx_octets() >= tx_pdu_length) { - LOG_INFO("Suggested TX octect already set to controller %d >= %d", - p_dev_rec->get_suggested_tx_octets(), tx_pdu_length); + log::info("Suggested TX octect already set to controller {} >= {}", + p_dev_rec->get_suggested_tx_octets(), tx_pdu_length); return BTM_SUCCESS; } @@ -604,7 +607,7 @@ tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr, tx_time = BTM_BLE_DATA_TX_TIME_MAX; if (!BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { - LOG_INFO( + log::info( "Unable to set data length because no le acl link connected to device"); return BTM_WRONG_MODE; } @@ -612,7 +615,7 @@ tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr, uint16_t hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE); if (!acl_peer_supports_ble_packet_extension(hci_handle)) { - LOG_INFO("Remote device unable to support le packet extension"); + log::info("Remote device unable to support le packet extension"); return BTM_ILLEGAL_VALUE; } @@ -650,7 +653,7 @@ static tBTM_SEC_ACTION btm_ble_determine_security_act( if (is_originator) { if ((security_required & BTM_SEC_OUT_FLAGS) == 0 && (security_required & BTM_SEC_OUT_MITM) == 0) { - LOG_INFO("No security required for outgoing connection"); + log::info("No security required for outgoing connection"); return BTM_SEC_OK; } @@ -658,7 +661,7 @@ static tBTM_SEC_ACTION btm_ble_determine_security_act( } else { if ((security_required & BTM_SEC_IN_FLAGS) == 0 && (security_required & BTM_SEC_IN_MITM) == 0) { - LOG_VERBOSE("No security required for incoming connection"); + log::verbose("No security required for incoming connection"); return BTM_SEC_OK; } @@ -668,7 +671,7 @@ static tBTM_SEC_ACTION btm_ble_determine_security_act( tBTM_BLE_SEC_REQ_ACT ble_sec_act = {BTM_BLE_SEC_REQ_ACT_NONE}; btm_ble_link_sec_check(bdaddr, auth_req, &ble_sec_act); - LOG_VERBOSE("ble_sec_act %d", ble_sec_act); + log::verbose("ble_sec_act {}", ble_sec_act); if (ble_sec_act == BTM_BLE_SEC_REQ_ACT_DISCARD) return BTM_SEC_ENC_PENDING; @@ -723,7 +726,7 @@ tBTM_STATUS btm_ble_start_sec_check(const RawAddress& bd_addr, uint16_t psm, /* If there is no application registered with this PSM do not allow connection */ if (!p_serv_rec) { - LOG_WARN("PSM: %d no application registered", psm); + log::warn("PSM: {} no application registered", psm); (*p_callback)(&bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_MODE_UNSUPPORTED); return BTM_ILLEGAL_VALUE; } @@ -734,13 +737,13 @@ tBTM_STATUS btm_ble_start_sec_check(const RawAddress& bd_addr, uint16_t psm, if (!is_originator) { if ((p_serv_rec->security_flags & BTM_SEC_IN_ENCRYPT) && !is_encrypted) { - LOG_ERROR("BTM_NOT_ENCRYPTED. service security_flags=0x%x", - p_serv_rec->security_flags); + log::error("BTM_NOT_ENCRYPTED. service security_flags=0x{:x}", + p_serv_rec->security_flags); return BTM_NOT_ENCRYPTED; } else if ((p_serv_rec->security_flags & BTM_SEC_IN_AUTHENTICATE) && !(is_link_key_authed || is_authenticated)) { - LOG_ERROR("BTM_NOT_AUTHENTICATED. service security_flags=0x%x", - p_serv_rec->security_flags); + log::error("BTM_NOT_AUTHENTICATED. service security_flags=0x{:x}", + p_serv_rec->security_flags); return BTM_NOT_AUTHENTICATED; } /* TODO: When security is required, then must check that the key size of our @@ -754,27 +757,27 @@ tBTM_STATUS btm_ble_start_sec_check(const RawAddress& bd_addr, uint16_t psm, switch (sec_act) { case BTM_SEC_OK: - LOG_DEBUG("Security met"); + log::debug("Security met"); p_callback(&bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_SUCCESS); break; case BTM_SEC_ENCRYPT: - LOG_DEBUG("Encryption needs to be done"); + log::debug("Encryption needs to be done"); ble_sec_act = BTM_BLE_SEC_ENCRYPT; break; case BTM_SEC_ENCRYPT_MITM: - LOG_DEBUG("Pairing with MITM needs to be done"); + log::debug("Pairing with MITM needs to be done"); ble_sec_act = BTM_BLE_SEC_ENCRYPT_MITM; break; case BTM_SEC_ENCRYPT_NO_MITM: - LOG_DEBUG("Pairing with No MITM needs to be done"); + log::debug("Pairing with No MITM needs to be done"); ble_sec_act = BTM_BLE_SEC_ENCRYPT_NO_MITM; break; case BTM_SEC_ENC_PENDING: - LOG_DEBUG("Ecryption pending"); + log::debug("Ecryption pending"); break; } @@ -805,8 +808,8 @@ void tBTM_SEC_REC::increment_sign_counter(bool local) { ble_keys.counter++; } - LOG_VERBOSE("local=%d local sign counter=%d peer sign counter=%d", local, - ble_keys.local_counter, ble_keys.counter); + log::verbose("local={} local sign counter={} peer sign counter={}", local, + ble_keys.local_counter, ble_keys.counter); } /******************************************************************************* @@ -822,7 +825,7 @@ void tBTM_SEC_REC::increment_sign_counter(bool local) { bool btm_ble_get_enc_key_type(const RawAddress& bd_addr, uint8_t* p_key_types) { tBTM_SEC_DEV_REC* p_dev_rec; - LOG_VERBOSE("bd_addr:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("bd_addr:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec != NULL) { @@ -851,7 +854,7 @@ bool btm_get_local_div(const RawAddress& bd_addr, uint16_t* p_div) { status = true; *p_div = p_dev_rec->sec_rec.ble_keys.div; } - LOG_VERBOSE("status=%d (1-OK) DIV=0x%x", status, *p_div); + log::verbose("status={} (1-OK) DIV=0x{:x}", status, *p_div); return status; } @@ -874,8 +877,8 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_SEC_DEV_REC* p_rec; tBTM_LE_EVT_DATA cb_data; - LOG_VERBOSE("key_type=0x%x pass_to_application=%d", key_type, - pass_to_application); + log::verbose("key_type=0x{:x} pass_to_application={}", key_type, + pass_to_application); /* Store the updated key in the device database */ if ((p_rec = btm_find_dev(bd_addr)) != NULL && @@ -896,8 +899,8 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, p_rec->sec_rec.sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED; else p_rec->sec_rec.sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED; - LOG_VERBOSE( - "BTM_LE_KEY_PENC key_type=0x%x sec_flags=0x%x sec_leve=0x%x", + log::verbose( + "BTM_LE_KEY_PENC key_type=0x{:x} sec_flags=0x{:x} sec_leve=0x{:x}", p_rec->sec_rec.ble_keys.key_type, p_rec->sec_rec.sec_flags, p_rec->sec_rec.ble_keys.sec_level); break; @@ -909,9 +912,9 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, p_rec->ble.identity_address_with_type.type = p_keys->pid_key.identity_addr_type; p_rec->sec_rec.ble_keys.key_type |= BTM_LE_KEY_PID; - LOG_VERBOSE( - "BTM_LE_KEY_PID key_type=0x%x save peer IRK, change bd_addr=%s " - "to id_addr=%s id_addr_type=0x%x", + log::verbose( + "BTM_LE_KEY_PID key_type=0x{:x} save peer IRK, change bd_addr={} " + "to id_addr={} id_addr_type=0x{:x}", p_rec->sec_rec.ble_keys.key_type, ADDRESS_TO_LOGGABLE_CSTR(p_rec->bd_addr), ADDRESS_TO_LOGGABLE_CSTR(p_keys->pid_key.identity_addr), @@ -933,9 +936,9 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, else p_rec->sec_rec.sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED; - LOG_VERBOSE( - "BTM_LE_KEY_PCSRK key_type=0x%x sec_flags=0x%x sec_level=0x%x " - "peer_counter=%d", + log::verbose( + "BTM_LE_KEY_PCSRK key_type=0x{:x} sec_flags=0x{:x} " + "sec_level=0x{:x} peer_counter={}", p_rec->sec_rec.ble_keys.key_type, p_rec->sec_rec.sec_flags, p_rec->sec_rec.ble_keys.srk_sec_level, p_rec->sec_rec.ble_keys.counter); @@ -948,9 +951,9 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, p_rec->sec_rec.ble_keys.key_size = p_keys->lenc_key.key_size; p_rec->sec_rec.ble_keys.key_type |= BTM_LE_KEY_LENC; - LOG_VERBOSE( - "BTM_LE_KEY_LENC key_type=0x%x DIV=0x%x key_size=0x%x " - "sec_level=0x%x", + log::verbose( + "BTM_LE_KEY_LENC key_type=0x{:x} DIV=0x{:x} key_size=0x{:x} " + "sec_level=0x{:x}", p_rec->sec_rec.ble_keys.key_type, p_rec->sec_rec.ble_keys.div, p_rec->sec_rec.ble_keys.key_size, p_rec->sec_rec.ble_keys.sec_level); @@ -963,9 +966,9 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, p_keys->lcsrk_key.sec_level; p_rec->sec_rec.ble_keys.local_counter = p_keys->lcsrk_key.counter; p_rec->sec_rec.ble_keys.key_type |= BTM_LE_KEY_LCSRK; - LOG_VERBOSE( - "BTM_LE_KEY_LCSRK key_type=0x%x DIV=0x%x scrk_sec_level=0x%x " - "local_counter=%d", + log::verbose( + "BTM_LE_KEY_LCSRK key_type=0x{:x} DIV=0x{:x} scrk_sec_level=0x{:x} " + "local_counter={}", p_rec->sec_rec.ble_keys.key_type, p_rec->sec_rec.ble_keys.div, p_rec->sec_rec.ble_keys.local_csrk_sec_level, p_rec->sec_rec.ble_keys.local_counter); @@ -975,12 +978,12 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, p_rec->sec_rec.ble_keys.key_type |= BTM_LE_KEY_LID; break; default: - LOG_WARN("btm_sec_save_le_key (Bad key_type 0x%02x)", key_type); + log::warn("btm_sec_save_le_key (Bad key_type 0x{:02x})", key_type); return; } - LOG_VERBOSE("BLE key type 0x%x, updated for BDA:%s", key_type, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("BLE key type 0x{:x}, updated for BDA:{}", key_type, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); /* Notify the application that one of the BLE keys has been updated If link key is in progress, it will get sent later.*/ @@ -993,11 +996,11 @@ void btm_sec_save_le_key(const RawAddress& bd_addr, tBTM_LE_KEY_TYPE key_type, return; } - LOG_WARN("BLE key type 0x%x, called for Unknown BDA or type:%s", key_type, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("BLE key type 0x{:x}, called for Unknown BDA or type:{}", key_type, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (p_rec) { - LOG_VERBOSE("sec_flags=0x%x", p_rec->sec_rec.sec_flags); + log::verbose("sec_flags=0x{:x}", p_rec->sec_rec.sec_flags); } } @@ -1014,8 +1017,8 @@ void btm_ble_update_sec_key_size(const RawAddress& bd_addr, uint8_t enc_key_size) { tBTM_SEC_DEV_REC* p_rec; - LOG_VERBOSE("bd_addr:%s, enc_key_size=%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - enc_key_size); + log::verbose("bd_addr:{}, enc_key_size={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + enc_key_size); p_rec = btm_find_dev(bd_addr); if (p_rec != NULL) { @@ -1057,11 +1060,11 @@ void btm_ble_link_sec_check(const RawAddress& bd_addr, tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); uint8_t req_sec_level = SMP_SEC_NONE, cur_sec_level = SMP_SEC_NONE; - LOG_VERBOSE("bd_addr:%s, auth_req=0x%x", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - auth_req); + log::verbose("bd_addr:{}, auth_req=0x{:x}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + auth_req); if (p_dev_rec == NULL) { - LOG_ERROR("received for unknown device"); + log::error("received for unknown device"); return; } @@ -1076,7 +1079,7 @@ void btm_ble_link_sec_check(const RawAddress& bd_addr, req_sec_level = SMP_SEC_AUTHENTICATED; } - LOG_VERBOSE("dev_rec sec_flags=0x%x", p_dev_rec->sec_rec.sec_flags); + log::verbose("dev_rec sec_flags=0x{:x}", p_dev_rec->sec_rec.sec_flags); /* currently encrpted */ if (p_dev_rec->sec_rec.sec_flags & BTM_SEC_LE_ENCRYPTED) { @@ -1103,8 +1106,8 @@ void btm_ble_link_sec_check(const RawAddress& bd_addr, } } - LOG_VERBOSE("cur_sec_level=%d req_sec_level=%d sec_req_act=%d", cur_sec_level, - req_sec_level, *p_sec_req_act); + log::verbose("cur_sec_level={} req_sec_level={} sec_req_act={}", + cur_sec_level, req_sec_level, *p_sec_req_act); } /******************************************************************************* @@ -1129,11 +1132,11 @@ tBTM_STATUS btm_ble_set_encryption(const RawAddress& bd_addr, tBTM_LE_AUTH_REQ auth_req; if (p_rec == NULL) { - LOG_WARN("NULL device record!! sec_act=0x%x", sec_act); + log::warn("NULL device record!! sec_act=0x{:x}", sec_act); return (BTM_WRONG_MODE); } - LOG_VERBOSE("sec_act=0x%x role_central=%d", sec_act, p_rec->role_central); + log::verbose("sec_act=0x{:x} role_central={}", sec_act, p_rec->role_central); if (sec_act == BTM_BLE_SEC_ENCRYPT_MITM) { p_rec->sec_rec.security_required |= BTM_SEC_IN_MITM; @@ -1157,7 +1160,7 @@ tBTM_STATUS btm_ble_set_encryption(const RawAddress& bd_addr, btm_ble_link_sec_check(bd_addr, auth_req, &sec_req_act); if (sec_req_act == BTM_BLE_SEC_REQ_ACT_NONE || sec_req_act == BTM_BLE_SEC_REQ_ACT_DISCARD) { - LOG_VERBOSE("no action needed. Ignore"); + log::verbose("no action needed. Ignore"); cmd = BTM_SUCCESS; break; } @@ -1196,7 +1199,7 @@ void btm_ble_ltk_request(uint16_t handle, BT_OCTET8 rand, uint16_t ediv) { tBTM_SEC_CB* p_cb = &btm_sec_cb; tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle); - LOG_VERBOSE("handle:0x%x", handle); + log::verbose("handle:0x{:x}", handle); p_cb->ediv = ediv; @@ -1218,15 +1221,16 @@ tBTM_STATUS btm_ble_start_encrypt(const RawAddress& bda, bool use_stk, tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bda); BT_OCTET8 dummy_rand = {0}; - LOG_VERBOSE("bd_addr:%s, use_stk:%d", ADDRESS_TO_LOGGABLE_CSTR(bda), use_stk); + log::verbose("bd_addr:{}, use_stk:{}", ADDRESS_TO_LOGGABLE_CSTR(bda), + use_stk); if (!p_rec) { - LOG_ERROR("Link is not active, can not encrypt!"); + log::error("Link is not active, can not encrypt!"); return BTM_WRONG_MODE; } if (p_rec->sec_rec.is_security_state_encrypting()) { - LOG_WARN("Link Encryption is active, Busy!"); + log::warn("Link Encryption is active, Busy!"); return BTM_BUSY; } @@ -1239,7 +1243,7 @@ tBTM_STATUS btm_ble_start_encrypt(const RawAddress& bda, bool use_stk, p_rec->ble_hci_handle, p_rec->sec_rec.ble_keys.rand, p_rec->sec_rec.ble_keys.ediv, p_rec->sec_rec.ble_keys.pltk); } else { - LOG_ERROR("No key available to encrypt the link"); + log::error("No key available to encrypt the link"); return BTM_ERR_KEY_MISSING; } @@ -1268,7 +1272,7 @@ static void btm_ble_notify_enc_cmpl(const RawAddress& bd_addr, if (!BTM_ReadRemoteVersion(bd_addr, &remote_lmp_version, nullptr, nullptr) || remote_lmp_version == 0) { - LOG_WARN("BLE Unable to determine remote version"); + log::warn("BLE Unable to determine remote version"); } if (remote_lmp_version == 0 || @@ -1297,11 +1301,11 @@ void btm_ble_link_encrypted(const RawAddress& bd_addr, uint8_t encr_enable) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); bool enc_cback; - LOG_VERBOSE("bd_addr:%s, encr_enable=%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - encr_enable); + log::verbose("bd_addr:{}, encr_enable={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + encr_enable); if (!p_dev_rec) { - LOG_WARN("No Device Found!"); + log::warn("No Device Found!"); return; } @@ -1309,8 +1313,8 @@ void btm_ble_link_encrypted(const RawAddress& bd_addr, uint8_t encr_enable) { smp_link_encrypted(bd_addr, encr_enable); - LOG_VERBOSE("p_dev_rec->sec_rec.sec_flags=0x%x", - p_dev_rec->sec_rec.sec_flags); + log::verbose("p_dev_rec->sec_rec.sec_flags=0x{:x}", + p_dev_rec->sec_rec.sec_flags); if (encr_enable && p_dev_rec->sec_rec.enc_key_size == 0) p_dev_rec->sec_rec.enc_key_size = p_dev_rec->sec_rec.ble_keys.key_size; @@ -1336,7 +1340,7 @@ void btm_ble_link_encrypted(const RawAddress& bd_addr, uint8_t encr_enable) { (const char*)remote_name) && (btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_LE_ACTIVE) && btm_sec_cb.pairing_bda == p_dev_rec->ble.pseudo_addr) { - LOG_INFO( + log::info( "INTEROP_DELAY_ATT_TRAFFIC_DURING_PAIRING: Waiting for bonding to " "complete to notify enc complete"); } else { @@ -1360,17 +1364,17 @@ void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk, tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bda); tBTM_SEC_CB* p_cb = &btm_sec_cb; - LOG_VERBOSE("bd_addr:%s, use_stk:%d", ADDRESS_TO_LOGGABLE_CSTR(bda), use_stk); + log::debug("bd_addr:{},use_stk:{}", ADDRESS_TO_LOGGABLE_CSTR(bda), use_stk); if (p_rec == NULL) { - LOG_ERROR("unknown device"); + log::error("unknown device"); return; } p_cb->enc_handle = p_rec->ble_hci_handle; p_cb->key_size = p_rec->sec_rec.ble_keys.key_size; - LOG_ERROR("key size=%d", p_rec->sec_rec.ble_keys.key_size); + log::error("key size={}", p_rec->sec_rec.ble_keys.key_size); if (use_stk) { btsnd_hcic_ble_ltk_req_reply(btm_sec_cb.enc_handle, stk); return; @@ -1388,14 +1392,15 @@ void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk, return; } - LOG_INFO("Found second sec_dev_rec for device that have LTK"); + log::info("Found second sec_dev_rec for device that have LTK"); /* This can happen when remote established LE connection using RPA to this * device, but then pair with us using Classing transport while still keeping * LE connection. If remote attempts to encrypt the LE connection, we might * end up here. We will eventually consolidate both entries, this is to avoid * race conditions. */ - LOG_ASSERT(p_rec->sec_rec.ble_keys.key_type & BTM_LE_KEY_LENC); + ASSERT_LOG(p_rec->sec_rec.ble_keys.key_type & BTM_LE_KEY_LENC, + "local enccryption key not present"); p_cb->key_size = p_rec->sec_rec.ble_keys.key_size; btsnd_hcic_ble_ltk_req_reply(btm_sec_cb.enc_handle, p_rec->sec_rec.ble_keys.lltk); @@ -1414,8 +1419,8 @@ void btm_ble_ltk_request_reply(const RawAddress& bda, bool use_stk, static uint8_t btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC* p_dev_rec, tBTM_LE_IO_REQ* p_data) { uint8_t callback_rc = BTM_SUCCESS; - LOG_VERBOSE("p_dev_rec->bd_addr:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); + log::verbose("p_dev_rec->bd_addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); if (btm_sec_cb.api.p_le_callback) { /* the callback function implementation may change the IO capability... */ callback_rc = (*btm_sec_cb.api.p_le_callback)( @@ -1424,27 +1429,27 @@ static uint8_t btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC* p_dev_rec, if ((callback_rc == BTM_SUCCESS) || (BTM_OOB_UNKNOWN != p_data->oob_data)) { p_data->auth_req &= BTM_LE_AUTH_REQ_MASK; - LOG_VERBOSE("1:p_dev_rec->sec_rec.security_required=%d, auth_req:%d", - p_dev_rec->sec_rec.security_required, p_data->auth_req); - LOG_VERBOSE("2:i_keys=0x%x r_keys=0x%x (bit 0-LTK 1-IRK 2-CSRK)", - p_data->init_keys, p_data->resp_keys); + log::verbose("1:p_dev_rec->sec_rec.security_required={}, auth_req:{}", + p_dev_rec->sec_rec.security_required, p_data->auth_req); + log::verbose("2:i_keys=0x{:x} r_keys=0x{:x} (bit 0-LTK 1-IRK 2-CSRK)", + p_data->init_keys, p_data->resp_keys); /* if authentication requires MITM protection, put on the mask */ if (p_dev_rec->sec_rec.security_required & BTM_SEC_IN_MITM) p_data->auth_req |= BTM_LE_AUTH_REQ_MITM; if (!(p_data->auth_req & SMP_AUTH_BOND)) { - LOG_VERBOSE("Non bonding: No keys should be exchanged"); + log::verbose("Non bonding: No keys should be exchanged"); p_data->init_keys = 0; p_data->resp_keys = 0; } - LOG_VERBOSE("3:auth_req:%d", p_data->auth_req); - LOG_VERBOSE("4:i_keys=0x%x r_keys=0x%x", p_data->init_keys, - p_data->resp_keys); + log::verbose("3:auth_req:{}", p_data->auth_req); + log::verbose("4:i_keys=0x{:x} r_keys=0x{:x}", p_data->init_keys, + p_data->resp_keys); - LOG_VERBOSE("5:p_data->io_cap=%d auth_req:%d", p_data->io_cap, - p_data->auth_req); + log::verbose("5:p_data->io_cap={} auth_req:{}", p_data->io_cap, + p_data->auth_req); /* remove MITM protection requirement if IO cap does not allow it */ if ((p_data->io_cap == BTM_IO_CAP_NONE) && p_data->oob_data == SMP_OOB_NONE) @@ -1454,15 +1459,15 @@ static uint8_t btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC* p_dev_rec, /* if Secure Connections are not supported then remove LK derivation, ** and keypress notifications. */ - LOG_VERBOSE( + log::verbose( "SC not supported -> No LK derivation, no keypress notifications"); p_data->auth_req &= ~SMP_KP_SUPPORT_BIT; p_data->init_keys &= ~SMP_SEC_KEY_TYPE_LK; p_data->resp_keys &= ~SMP_SEC_KEY_TYPE_LK; } - LOG_VERBOSE("6:IO_CAP:%d oob_data:%d auth_req:0x%02x", p_data->io_cap, - p_data->oob_data, p_data->auth_req); + log::verbose("6:IO_CAP:{} oob_data:{} auth_req:0x{:02x}", p_data->io_cap, + p_data->oob_data, p_data->auth_req); } return callback_rc; } @@ -1480,8 +1485,8 @@ static uint8_t btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC* p_dev_rec, static uint8_t btm_ble_br_keys_req(tBTM_SEC_DEV_REC* p_dev_rec, tBTM_LE_IO_REQ* p_data) { uint8_t callback_rc = BTM_SUCCESS; - LOG_VERBOSE("p_dev_rec->bd_addr:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); + log::verbose("p_dev_rec->bd_addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); *p_data = tBTM_LE_IO_REQ{ .io_cap = BTM_IO_CAP_UNKNOWN, .oob_data = false, @@ -1515,15 +1520,15 @@ void btm_ble_connected(const RawAddress& bda, uint16_t handle, uint8_t enc_mode, bool can_read_discoverable_characteristics) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda); - LOG_INFO("Update timestamp for ble connection:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::info("Update timestamp for ble connection:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda)); // TODO() Why is timestamp a counter ? p_dev_rec->timestamp = btm_sec_cb.dev_rec_count++; if (is_ble_addr_type_known(addr_type)) p_dev_rec->ble.SetAddressType(addr_type); else - LOG_WARN( + log::warn( "Please do not update device record from anonymous le advertisement"); p_dev_rec->ble.pseudo_addr = bda; @@ -1549,8 +1554,8 @@ void btm_ble_connected(const RawAddress& bda, uint16_t handle, uint8_t enc_mode, *****************************************************************************/ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, const tSMP_EVT_DATA* p_data) { - LOG_VERBOSE("bd_addr:%s, event=%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - smp_evt_to_text(event).c_str()); + log::verbose("bd_addr:{}, event={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + smp_evt_to_text(event).c_str()); if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) { btm_sec_cr_loc_oob_data_cback_event(RawAddress{}, p_data->loc_oob_data); @@ -1583,7 +1588,7 @@ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, case SMP_SEC_REQUEST_EVT: if (event == SMP_SEC_REQUEST_EVT && btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE) { - LOG_VERBOSE("Ignoring SMP Security request"); + log::verbose("Ignoring SMP Security request"); break; } btm_sec_cb.pairing_bda = bd_addr; @@ -1597,41 +1602,42 @@ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, if (btm_sec_cb.api.p_le_callback) { /* the callback function implementation may change the IO * capability... */ - LOG_VERBOSE("btm_sec_cb.api.p_le_callback=0x%p", - btm_sec_cb.api.p_le_callback); - (*btm_sec_cb.api.p_le_callback)(event, bd_addr, - (tBTM_LE_EVT_DATA*)p_data); + log::verbose("btm_sec_cb.api.p_le_callback=0x{}", + fmt::ptr(btm_sec_cb.api.p_le_callback)); + (*btm_sec_cb.api.p_le_callback)(static_cast(event), + bd_addr, (tBTM_LE_EVT_DATA*)p_data); } if (event == SMP_COMPLT_EVT) { p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_ERROR("p_dev_rec is NULL"); + log::error("p_dev_rec is NULL"); return BTM_SUCCESS; } - LOG_VERBOSE("before update sec_level=0x%x sec_flags=0x%x", - p_data->cmplt.sec_level, p_dev_rec->sec_rec.sec_flags); + log::verbose("before update sec_level=0x{:x} sec_flags=0x{:x}", + p_data->cmplt.sec_level, p_dev_rec->sec_rec.sec_flags); res = (p_data->cmplt.reason == SMP_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING; - LOG_VERBOSE("after update result=%d sec_level=0x%x sec_flags=0x%x", - res, p_data->cmplt.sec_level, - p_dev_rec->sec_rec.sec_flags); + log::verbose( + "after update result={} sec_level=0x{:x} sec_flags=0x{:x}", res, + p_data->cmplt.sec_level, p_dev_rec->sec_rec.sec_flags); if (p_data->cmplt.is_pair_cancel && btm_sec_cb.api.p_bond_cancel_cmpl_callback) { - LOG_VERBOSE("Pairing Cancel completed"); + log::verbose("Pairing Cancel completed"); (*btm_sec_cb.api.p_bond_cancel_cmpl_callback)(BTM_SUCCESS); } if (res != BTM_SUCCESS && p_data->cmplt.reason != SMP_CONN_TOUT) { - LOG_VERBOSE("Pairing failed - prepare to remove ACL"); + log::verbose("Pairing failed - prepare to remove ACL"); l2cu_start_post_bond_timer(p_dev_rec->ble_hci_handle); } - LOG_VERBOSE( - "btm_sec_cb.pairing_state=%x pairing_flags=%x pin_code_len=%x", + log::verbose( + "btm_sec_cb.pairing_state={:x} pairing_flags={:x} " + "pin_code_len={:x}", btm_sec_cb.pairing_state, btm_sec_cb.pairing_flags, btm_sec_cb.pin_code_len); @@ -1653,9 +1659,9 @@ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, // At this point LTK should have been dropped by btif. // Reset the flags here if LE is not connected (over BR), // otherwise they would be reset on disconnected. - LOG_DEBUG( - "SMP over BR triggered by temporary bond has completed," - " resetting the LK flags"); + log::debug( + "SMP over BR triggered by temporary bond has completed, " + "resetting the LK flags"); p_dev_rec->sec_rec.sec_flags &= ~(BTM_SEC_LE_LINK_KEY_KNOWN); p_dev_rec->sec_rec.ble_keys.key_type = BTM_LE_KEY_NONE; } @@ -1665,7 +1671,7 @@ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, remote_name) && interop_match_name(INTEROP_SUSPEND_ATT_TRAFFIC_DURING_PAIRING, (const char*)remote_name)) { - LOG_DEBUG("Notifying encryption cmpl delayed due to IOP match"); + log::debug("Notifying encryption cmpl delayed due to IOP match"); btm_ble_notify_enc_cmpl(p_dev_rec->ble.pseudo_addr, true); } @@ -1675,17 +1681,17 @@ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, case SMP_LE_ADDR_ASSOC_EVT: if (btm_sec_cb.api.p_le_callback) { - LOG_VERBOSE("btm_sec_cb.api.p_le_callback=0x%p", - btm_sec_cb.api.p_le_callback); - (*btm_sec_cb.api.p_le_callback)(event, bd_addr, - (tBTM_LE_EVT_DATA*)p_data); + log::verbose("btm_sec_cb.api.p_le_callback=0x{}", + fmt::ptr(btm_sec_cb.api.p_le_callback)); + (*btm_sec_cb.api.p_le_callback)(static_cast(event), + bd_addr, (tBTM_LE_EVT_DATA*)p_data); } break; case SMP_SIRK_VERIFICATION_REQ_EVT: res = (*btm_sec_cb.api.p_sirk_verification_callback)(bd_addr); - LOG_DEBUG("SMP SIRK verification result:%s", - btm_status_text(res).c_str()); + log::debug("SMP SIRK verification result:{}", + btm_status_text(res).c_str()); if (res != BTM_CMD_STARTED) { return res; } @@ -1693,12 +1699,12 @@ tBTM_STATUS btm_proc_smp_cback(tSMP_EVT event, const RawAddress& bd_addr, break; default: - LOG_VERBOSE("unknown event=%s", smp_evt_to_text(event).c_str()); + log::verbose("unknown event={}", smp_evt_to_text(event).c_str()); break; } } else { - LOG_WARN("Unexpected event '%s' for unknown device.", - smp_evt_to_text(event).c_str()); + log::warn("Unexpected event '{}' for unknown device.", + smp_evt_to_text(event).c_str()); } return BTM_SUCCESS; @@ -1725,7 +1731,7 @@ bool BTM_BleDataSignature(const RawAddress& bd_addr, uint8_t* p_text, tBTM_SEC_DEV_REC* p_rec = btm_find_dev(bd_addr); if (p_rec == NULL) { - LOG_ERROR("data signing can not be done from unknown device"); + log::error("data signing can not be done from unknown device"); return false; } @@ -1747,14 +1753,12 @@ bool BTM_BleDataSignature(const RawAddress& bd_addr, uint8_t* p_text, (uint16_t)(len + 4), BTM_CMAC_TLEN_SIZE, p_mac); p_rec->sec_rec.increment_sign_counter(true); - LOG_VERBOSE("p_mac = %p", p_mac); - LOG_VERBOSE( - "p_mac[0]=0x%02x p_mac[1]=0x%02x p_mac[2]=0x%02x p_mac[3]=" - "0x%02x", + log::verbose("p_mac = {}", fmt::ptr(p_mac)); + log::verbose( + "p_mac[0]=0x{:02x} p_mac[1]=0x{:02x} p_mac[2]=0x{:02x} p_mac[3]=0x{:02x}", *p_mac, *(p_mac + 1), *(p_mac + 2), *(p_mac + 3)); - LOG_VERBOSE( - "p_mac[4]=0x%02x p_mac[5]=0x%02x p_mac[6]=0x%02x p_mac[7]=" - "0x%02x", + log::verbose( + "p_mac[4]=0x{:02x} p_mac[5]=0x{:02x} p_mac[6]=0x{:02x} p_mac[7]=0x{:02x}", *(p_mac + 4), *(p_mac + 5), *(p_mac + 6), *(p_mac + 7)); osi_free(p_buf); return true; @@ -1783,14 +1787,14 @@ bool BTM_BleVerifySignature(const RawAddress& bd_addr, uint8_t* p_orig, if (p_rec == NULL || (p_rec && !(p_rec->sec_rec.ble_keys.key_type & BTM_LE_KEY_PCSRK))) { - LOG_ERROR("can not verify signature for unknown device"); + log::error("can not verify signature for unknown device"); } else if (counter < p_rec->sec_rec.ble_keys.counter) { - LOG_ERROR("signature received with out dated sign counter"); + log::error("signature received with out dated sign counter"); } else if (p_orig == NULL) { - LOG_ERROR("No signature to verify"); + log::error("No signature to verify"); } else { - LOG_VERBOSE("rcv_cnt=%d >= expected_cnt=%d", counter, - p_rec->sec_rec.ble_keys.counter); + log::verbose("rcv_cnt={} >= expected_cnt={}", counter, + p_rec->sec_rec.ble_keys.counter); crypto_toolbox::aes_cmac(p_rec->sec_rec.ble_keys.pcsrk, p_orig, len, BTM_CMAC_TLEN_SIZE, p_mac); @@ -1818,11 +1822,11 @@ void BTM_BleSirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); tSMP_STATUS res_smp = (res == BTM_SUCCESS) ? SMP_SUCCESS : SMP_FAIL; - LOG_INFO("bd_addr:%s, result:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - smp_status_text(res_smp).c_str()); + log::info("bd_addr:{}, result:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + smp_status_text(res_smp).c_str()); if (p_dev_rec == NULL) { - LOG_ERROR("Confirmation of Unknown device"); + log::error("Confirmation of Unknown device"); return; } @@ -1839,23 +1843,23 @@ void BTM_BleSirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res) { static void btm_notify_new_key(uint8_t key_type) { tBTM_BLE_LOCAL_KEYS* p_local_keys = NULL; - LOG_VERBOSE("key_type=%d", key_type); + log::verbose("key_type={}", key_type); if (btm_sec_cb.api.p_le_key_callback) { switch (key_type) { case BTM_BLE_KEY_TYPE_ID: - LOG_VERBOSE("BTM_BLE_KEY_TYPE_ID"); + log::verbose("BTM_BLE_KEY_TYPE_ID"); p_local_keys = (tBTM_BLE_LOCAL_KEYS*)&btm_sec_cb.devcb.id_keys; break; case BTM_BLE_KEY_TYPE_ER: - LOG_VERBOSE("BTM_BLE_KEY_TYPE_ER"); + log::verbose("BTM_BLE_KEY_TYPE_ER"); p_local_keys = (tBTM_BLE_LOCAL_KEYS*)&btm_sec_cb.devcb.ble_encryption_key_value; break; default: - LOG_ERROR("unknown key type: %d", key_type); + log::error("unknown key type: {}", key_type); break; } if (p_local_keys != NULL) @@ -1904,7 +1908,7 @@ struct reset_id_data { /** This function is called to reset LE device identity. */ void btm_ble_reset_id(void) { - LOG_VERBOSE("btm_ble_reset_id"); + log::verbose("btm_ble_reset_id"); /* In order to reset identity, we need four random numbers. Make four nested * calls to generate them first, then proceed to perform the actual reset in @@ -1946,8 +1950,8 @@ bool btm_ble_get_acl_remote_addr(uint16_t hci_handle, RawAddress& conn_addr, tBLE_ADDR_TYPE* p_addr_type) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); if (p_dev_rec == nullptr) { - LOG_WARN("Unable to find security device record hci_handle:%hu", - hci_handle); + log::warn("Unable to find security device record hci_handle:{}", + hci_handle); // TODO Release acl resource return false; } @@ -1971,8 +1975,8 @@ bool btm_ble_get_acl_remote_addr(uint16_t hci_handle, RawAddress& conn_addr, break; default: - LOG_WARN("Unable to find record with active address type:%d", - p_dev_rec->ble.active_addr_type); + log::warn("Unable to find record with active address type:{}", + p_dev_rec->ble.active_addr_type); st = false; break; } diff --git a/system/stack/btm/btm_ble_sec.h b/system/stack/btm/btm_ble_sec.h index 98edf6a5a8fe815c5a68ce78df65b38d9ab2c659..fde20ea1f371c7ee5952783d866c314aea1d888f 100644 --- a/system/stack/btm/btm_ble_sec.h +++ b/system/stack/btm/btm_ble_sec.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include "macros.h" @@ -33,7 +35,8 @@ typedef enum : uint8_t { BTM_BLE_SEC_REQ_ACT_DISCARD = 3, } tBTM_BLE_SEC_REQ_ACT; -inline std::string btm_ble_sec_req_act_text(const tBTM_BLE_SEC_REQ_ACT action) { +inline std::string btm_ble_sec_req_act_text( + const tBTM_BLE_SEC_REQ_ACT& action) { switch (action) { CASE_RETURN_TEXT(BTM_BLE_SEC_REQ_ACT_NONE); CASE_RETURN_TEXT(BTM_BLE_SEC_REQ_ACT_ENCRYPT); @@ -72,3 +75,9 @@ tBTM_STATUS btm_ble_start_sec_check(const RawAddress& bd_addr, uint16_t psm, bool is_originator, tBTM_SEC_CALLBACK* p_callback, void* p_ref_data); + +namespace fmt { +template <> +struct formatter + : string_formatter {}; +} // namespace fmt diff --git a/system/stack/btm/btm_client_interface.cc b/system/stack/btm/btm_client_interface.cc index 6b7950ba364ca7bc99e915d10b40da51949d47a0..b52cf082f15a89eb60a5deaca92cf5a47c5915f8 100644 --- a/system/stack/btm/btm_client_interface.cc +++ b/system/stack/btm/btm_client_interface.cc @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "stack/include/btm_client_interface.h" +#include + #include "security_client_callbacks.h" #include "stack/btm/btm_ble_int.h" #include "stack/include/acl_api.h" @@ -41,12 +42,6 @@ struct btm_client_interface_t btm_client_interface = { // Acl peer and lifecycle .peer = { - .features = - { - .SupportTransparentSynchronousData = - ACL_SupportTransparentSynchronousData, - }, - .BTM_IsAclConnectionUp = BTM_IsAclConnectionUp, .BTM_ReadConnectedTransportAddress = BTM_ReadConnectedTransportAddress, @@ -85,9 +80,6 @@ struct btm_client_interface_t btm_client_interface = { .BTM_BleGetEnergyInfo = BTM_BleGetEnergyInfo, .BTM_BleObserve = BTM_BleObserve, .BTM_SetBleDataLength = BTM_SetBleDataLength, - .BTM_BleConfirmReply = BTM_BleConfirmReply, - .BTM_BleLoadLocalKeys = BTM_BleLoadLocalKeys, - .BTM_BlePasskeyReply = BTM_BlePasskeyReply, .BTM_BleReadControllerFeatures = BTM_BleReadControllerFeatures, .BTM_BleSetPhy = BTM_BleSetPhy, .BTM_BleSetPrefConnParams = BTM_BleSetPrefConnParams, diff --git a/system/stack/btm/btm_dev.cc b/system/stack/btm/btm_dev.cc index ead44de7ff48b955c84caa9c74c7845da1aca71b..40937813278788383d2eee5d230b8ecbd11a351d 100644 --- a/system/stack/btm/btm_dev.cc +++ b/system/stack/btm/btm_dev.cc @@ -26,6 +26,9 @@ #include "stack/btm/btm_dev.h" +#include +#include + #include #include "btm_api.h" @@ -33,9 +36,10 @@ #include "btm_sec_api.h" #include "btm_sec_cb.h" #include "common/init_flags.h" -#include "device/include/controller.h" +#include "hci/controller_interface.h" #include "internal_include/bt_target.h" #include "l2c_api.h" +#include "main/shim/entry.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/compat.h" @@ -47,6 +51,8 @@ #include "stack/include/btm_log_history.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; void gatt_consolidate(const RawAddress& identity_addr, const RawAddress& rpa); @@ -87,10 +93,11 @@ bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class, tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (!p_dev_rec) { p_dev_rec = btm_sec_allocate_dev_rec(); - LOG_DEBUG( - "Caching new record from config file device:%s link_key_type:%x " - "name:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type, bd_name); + log::debug( + "Caching new record from config file device:{} link_key_type:{:x} " + "name:{}", + ADDRESS_TO_LOGGABLE_STR(bd_addr), key_type, + reinterpret_cast(bd_name)); p_dev_rec->bd_addr = bd_addr; p_dev_rec->hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_BR_EDR); @@ -99,9 +106,9 @@ bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class, /* update conn params, use default value for background connection params */ memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); } else { - LOG_DEBUG( - "Caching existing record from config file device:%s link_key_type:%x", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type); + log::debug( + "Caching existing record from config file device:{} link_key_type:{:x}", + ADDRESS_TO_LOGGABLE_STR(bd_addr), key_type); /* "Bump" timestamp for existing record */ p_dev_rec->timestamp = btm_sec_cb.dev_rec_count++; @@ -115,25 +122,31 @@ bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class, p_dev_rec->sec_rec.bond_type = BOND_TYPE_UNKNOWN; } - if (dev_class) memcpy(p_dev_rec->dev_class, dev_class, DEV_CLASS_LEN); + if (dev_class != kDevClassEmpty) p_dev_rec->dev_class = dev_class; memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME)); if (bd_name && bd_name[0]) { - LOG_DEBUG(" Remote name known for device:%s name:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bd_name); + log::debug(" Remote name known for device:{} name:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + reinterpret_cast(bd_name)); p_dev_rec->sec_rec.sec_flags |= BTM_SEC_NAME_KNOWN; strlcpy((char*)p_dev_rec->sec_bd_name, (char*)bd_name, BTM_MAX_REM_BD_NAME_LEN + 1); } if (p_link_key) { - LOG_DEBUG(" Link key known for device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug(" Link key known for device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); p_dev_rec->sec_rec.sec_flags |= BTM_SEC_LINK_KEY_KNOWN; p_dev_rec->sec_rec.link_key = *p_link_key; p_dev_rec->sec_rec.link_key_type = key_type; p_dev_rec->sec_rec.pin_code_length = pin_length; + if (IS_FLAG_ENABLED(correct_bond_type_of_loaded_devices)) { + p_dev_rec->sec_rec.bond_type = BOND_TYPE_PERSISTENT; + } + if (pin_length >= 16 || key_type == BTM_LKEY_TYPE_AUTH_COMB || key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256) { // Set the flag if the link key was made by using either a 16 digit @@ -165,8 +178,8 @@ void BTM_AcceptlistRemove(const RawAddress& address); bool BTM_SecDeleteDevice(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_WARN("Unable to delete link key for unknown device %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Unable to delete link key for unknown device {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return true; } @@ -176,15 +189,15 @@ bool BTM_SecDeleteDevice(const RawAddress& bd_addr) { if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) || BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) { - LOG_WARN("FAILED: Cannot Delete when connection to %s is active", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("FAILED: Cannot Delete when connection to {} is active", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } RawAddress bda = p_dev_rec->bd_addr; - LOG_INFO("Remove device %s from filter accept list before delete record", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Remove device {} from filter accept list before delete record", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (bluetooth::common::init_flags:: use_unified_connection_manager_is_enabled()) { bluetooth::connection::GetConnectionManager() @@ -202,7 +215,7 @@ bool BTM_SecDeleteDevice(const RawAddress& bd_addr) { wipe_secrets_and_remove(p_dev_rec); /* Tell controller to get rid of the link key, if it has one stored */ BTM_DeleteStoredLinkKey(&bda, NULL); - LOG_INFO("%s complete", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("{} complete", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); BTM_LogHistory(kBtmLogTag, bd_addr, "Device removed", base::StringPrintf("device_type:%s bond_type:%s", DeviceTypeText(device_type).c_str(), @@ -264,23 +277,24 @@ tBTM_SEC_DEV_REC* btm_sec_alloc_dev(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_dev_rec = btm_sec_allocate_dev_rec(); - LOG_DEBUG("Allocated device record bd_addr:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Allocated device record bd_addr:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); /* Check with the BT manager if details about remote device are known */ /* outgoing connection */ p_inq_info = BTM_InqDbRead(bd_addr); if (p_inq_info != NULL) { - memcpy(p_dev_rec->dev_class, p_inq_info->results.dev_class, DEV_CLASS_LEN); + p_dev_rec->dev_class = p_inq_info->results.dev_class; p_dev_rec->device_type = p_inq_info->results.device_type; if (is_ble_addr_type_known(p_inq_info->results.ble_addr_type)) p_dev_rec->ble.SetAddressType(p_inq_info->results.ble_addr_type); else - LOG_WARN( + log::warn( "Please do not update device record from anonymous le advertisement"); } else if (bd_addr == btm_sec_cb.connecting_bda) - memcpy(p_dev_rec->dev_class, btm_sec_cb.connecting_dc, DEV_CLASS_LEN); + p_dev_rec->dev_class = btm_sec_cb.connecting_dc; /* update conn params, use default value for background connection params */ memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); @@ -308,34 +322,33 @@ tBTM_SEC_DEV_REC* btm_sec_alloc_dev(const RawAddress& bd_addr) { ******************************************************************************/ bool btm_dev_support_role_switch(const RawAddress& bd_addr) { if (BTM_IsScoActiveByBdaddr(bd_addr)) { - LOG_VERBOSE("%s Role switch is not allowed if a SCO is up", __func__); + log::verbose("Role switch is not allowed if a SCO is up"); return false; } tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == nullptr) { - LOG_VERBOSE("%s Unknown address for role switch", __func__); + log::verbose("Unknown address for role switch"); return false; } - if (!controller_get_interface()->supports_central_peripheral_role_switch()) { - LOG_VERBOSE("%s Local controller does not support role switch", __func__); + if (!bluetooth::shim::GetController()->SupportsRoleSwitch()) { + log::verbose("Local controller does not support role switch"); return false; } if (p_dev_rec->remote_supports_hci_role_switch) { - LOG_VERBOSE("%s Peer controller supports role switch", __func__); + log::verbose("Peer controller supports role switch"); return true; } if (!p_dev_rec->remote_feature_received) { - LOG_VERBOSE( - "%s Unknown peer capabilities, assuming peer supports role switch", - __func__); + log::verbose( + "Unknown peer capabilities, assuming peer supports role switch"); return true; } - LOG_VERBOSE("%s Peer controller does not support role switch", __func__); + log::verbose("Peer controller does not support role switch"); return false; } @@ -360,6 +373,8 @@ static bool is_handle_equal(void* data, void* context) { * ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_dev_by_handle(uint16_t handle) { + if (btm_sec_cb.sec_dev_rec == nullptr) return nullptr; + list_node_t* n = list_foreach(btm_sec_cb.sec_dev_rec, is_handle_equal, &handle); if (n) return static_cast(list_node(n)); @@ -437,7 +452,7 @@ tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr) { void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec) { tBTM_SEC_DEV_REC temp_rec = *p_target_rec; - LOG_VERBOSE("%s", __func__); + log::verbose(""); list_node_t* end = list_end(btm_sec_cb.sec_dev_rec); list_node_t* node = list_begin(btm_sec_cb.sec_dev_rec); @@ -494,16 +509,16 @@ void BTM_SetConsolidationCallback(BTM_CONSOLIDATION_CB* cb) { void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_target_rec = btm_find_dev(bd_addr); if (!p_target_rec) { - LOG_ERROR("No security record for just bonded device!?!?"); + log::error("No security record for just bonded device!?!?"); return; } if (p_target_rec->ble_hci_handle != HCI_INVALID_HANDLE) { - LOG_INFO("Not consolidating - already have LE connection"); + log::info("Not consolidating - already have LE connection"); return; } - LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); list_node_t* end = list_end(btm_sec_cb.sec_dev_rec); list_node_t* node = list_begin(btm_sec_cb.sec_dev_rec); @@ -519,15 +534,17 @@ void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) { /* an RPA device entry is a duplicate of the target record */ if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec)) { if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) { - LOG_INFO("already disconnected - erasing entry %s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); + log::info("already disconnected - erasing entry {}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); wipe_secrets_and_remove(p_dev_rec); continue; } - LOG_INFO( - "Found existing LE connection to just bonded device on %s handle 0x%04x", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), p_dev_rec->ble_hci_handle); + log::info( + "Found existing LE connection to just bonded device on {} handle " + "0x{:04x}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), + p_dev_rec->ble_hci_handle); RawAddress ble_conn_addr = p_dev_rec->bd_addr; p_target_rec->ble_hci_handle = p_dev_rec->ble_hci_handle; @@ -543,7 +560,7 @@ void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) { /* To avoid race conditions between central/peripheral starting encryption * at same time, initiate it just from central. */ if (L2CA_GetBleConnRole(ble_conn_addr) == HCI_ROLE_CENTRAL) { - LOG_INFO("Will encrypt existing connection"); + log::info("Will encrypt existing connection"); BTM_SetEncryption(bd_addr, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT); } @@ -564,7 +581,7 @@ void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) { ******************************************************************************/ tBTM_SEC_DEV_REC* btm_find_or_alloc_dev(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_dev_rec; - LOG_VERBOSE("btm_find_or_alloc_dev"); + log::verbose("btm_find_or_alloc_dev"); p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { /* Allocate a new device record or reuse the oldest one */ @@ -633,6 +650,12 @@ static tBTM_SEC_DEV_REC* btm_find_oldest_dev_rec(void) { tBTM_SEC_DEV_REC* btm_sec_allocate_dev_rec(void) { tBTM_SEC_DEV_REC* p_dev_rec = NULL; + if (btm_sec_cb.sec_dev_rec == nullptr) { + log::warn( + "Unable to allocate device record with destructed device record list"); + return nullptr; + } + if (list_length(btm_sec_cb.sec_dev_rec) > BTM_SEC_MAX_DEVICE_RECORDS) { p_dev_rec = btm_find_oldest_dev_rec(); wipe_secrets_and_remove(p_dev_rec); @@ -735,8 +758,8 @@ bool BTM_Sec_AddressKnown(const RawAddress& address) { if (p_dev_rec == NULL || (p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) == 0) return true; - LOG_WARN("%s, device type not BLE: 0x%02x", ADDRESS_TO_LOGGABLE_CSTR(address), - p_dev_rec->device_type); + log::warn("{}, device type not BLE: 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(address), p_dev_rec->device_type); // bonded device with identity address known if (!p_dev_rec->ble.identity_address_with_type.bda.IsEmpty()) { @@ -749,8 +772,8 @@ bool BTM_Sec_AddressKnown(const RawAddress& address) { return true; } - LOG_WARN("%s, the address type is 0x%02x", ADDRESS_TO_LOGGABLE_CSTR(address), - p_dev_rec->ble.AddressType()); + log::warn("{}, the address type is 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(address), p_dev_rec->ble.AddressType()); // Only Resolvable Private Address (RPA) is known, we don't allow it into // the background connection procedure. diff --git a/system/stack/btm/btm_dev.h b/system/stack/btm/btm_dev.h index 424d865199edd97e8fc65a4e26df3582b7d3f9ab..166f5ae6611e30beef95316e2628ae3e68b765ab 100644 --- a/system/stack/btm/btm_dev.h +++ b/system/stack/btm/btm_dev.h @@ -16,6 +16,8 @@ #pragma once +#include + #include "stack/btm/security_device_record.h" #include "types/ble_address_with_type.h" #include "types/raw_address.h" diff --git a/system/stack/btm/btm_devctl.cc b/system/stack/btm/btm_devctl.cc index 61a208b246dc2abd22cba5be0ac3d2231e9c35f8..cb6a2b696b765db265f882a9fceb4be6d78699db 100644 --- a/system/stack/btm/btm_devctl.cc +++ b/system/stack/btm/btm_devctl.cc @@ -25,6 +25,7 @@ #define LOG_TAG "devctl" #include +#include #include #include #include @@ -33,8 +34,11 @@ #include "btif/include/btif_bqr.h" #include "btm_sec_cb.h" #include "btm_sec_int_types.h" +#include "device/include/controller.h" +#include "hci/controller_interface.h" #include "internal_include/bt_target.h" #include "main/shim/btm_api.h" +#include "main/shim/entry.h" #include "os/log.h" #include "stack/btm/btm_int_types.h" #include "stack/btm/btm_sec.h" @@ -44,9 +48,12 @@ #include "stack/include/bt_types.h" #include "stack/include/btm_api.h" #include "stack/include/btm_ble_privacy.h" +#include "stack/include/hcidefs.h" #include "stack/include/l2cap_controller_interface.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; void btm_inq_db_reset(void); @@ -196,18 +203,18 @@ void BTM_reset_complete() { std::srand(std::time(nullptr)); /* Set up the BLE privacy settings */ - if (controller->supports_ble() && controller->supports_ble_privacy() && + if (controller->SupportsBle() && controller->SupportsBlePrivacy() && controller->get_ble_resolving_list_max_size() > 0) { btm_ble_resolving_list_init(controller->get_ble_resolving_list_max_size()); /* set the default random private address timeout */ btsnd_hcic_ble_set_rand_priv_addr_timeout( btm_get_next_private_addrress_interval_ms() / 1000); } else { - LOG_INFO( + log::info( "Le Address Resolving list disabled due to lack of controller support"); } - if (controller->supports_ble()) { + if (controller->SupportsBle()) { l2c_link_processs_ble_num_bufs(controller->get_acl_buffer_count_ble()); } @@ -244,44 +251,42 @@ static void btm_read_local_name_timeout(UNUSED_ATTR void* data) { } static void decode_controller_support() { - const controller_t* controller = controller_get_interface(); - /* Create (e)SCO supported packet types mask */ btm_cb.btm_sco_pkt_types_supported = 0; btm_cb.sco_cb.esco_supported = false; - if (controller->supports_sco()) { + if (bluetooth::shim::GetController()->SupportsSco()) { btm_cb.btm_sco_pkt_types_supported = ESCO_PKT_TYPES_MASK_HV1; - if (controller->supports_hv2_packets()) + if (bluetooth::shim::GetController()->SupportsHv2Packets()) btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_HV2; - if (controller->supports_hv3_packets()) + if (bluetooth::shim::GetController()->SupportsHv3Packets()) btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_HV3; } - if (controller->supports_ev3_packets()) + if (bluetooth::shim::GetController()->SupportsEv3Packets()) btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_EV3; - if (controller->supports_ev4_packets()) + if (bluetooth::shim::GetController()->SupportsEv4Packets()) btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_EV4; - if (controller->supports_ev5_packets()) + if (bluetooth::shim::GetController()->SupportsEv5Packets()) btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_EV5; if (btm_cb.btm_sco_pkt_types_supported & BTM_ESCO_LINK_ONLY_MASK) { btm_cb.sco_cb.esco_supported = true; /* Add in EDR related eSCO types */ - if (controller->supports_esco_2m_phy()) { - if (!controller->supports_3_slot_edr_packets()) + if (bluetooth::shim::GetController()->SupportsEsco2mPhy()) { + if (!bluetooth::shim::GetController()->Supports3SlotEdrPackets()) btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_NO_2_EV5; } else { btm_cb.btm_sco_pkt_types_supported |= (ESCO_PKT_TYPES_MASK_NO_2_EV3 + ESCO_PKT_TYPES_MASK_NO_2_EV5); } - if (controller->supports_esco_3m_phy()) { - if (!controller->supports_3_slot_edr_packets()) + if (bluetooth::shim::GetController()->SupportsEsco3mPhy()) { + if (!bluetooth::shim::GetController()->Supports3SlotEdrPackets()) btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_NO_3_EV5; } else { btm_cb.btm_sco_pkt_types_supported |= @@ -289,20 +294,21 @@ static void decode_controller_support() { } } - LOG_VERBOSE("Local supported SCO packet types: 0x%04x", - btm_cb.btm_sco_pkt_types_supported); + log::verbose("Local supported SCO packet types: 0x{:04x}", + btm_cb.btm_sco_pkt_types_supported); BTM_acl_after_controller_started(controller_get_interface()); btm_sec_dev_reset(); - if (controller->supports_rssi_with_inquiry_results()) { - if (controller->supports_extended_inquiry_response()) + if (bluetooth::shim::GetController()->SupportsRssiWithInquiryResults()) { + if (bluetooth::shim::GetController()->SupportsExtendedInquiryResponse()) BTM_SetInquiryMode(BTM_INQ_RESULT_EXTENDED); else BTM_SetInquiryMode(BTM_INQ_RESULT_WITH_RSSI); } - l2cu_set_non_flushable_pbf(controller->supports_non_flushable_pb()); + l2cu_set_non_flushable_pbf( + bluetooth::shim::GetController()->SupportsNonFlushablePb()); BTM_EnableInterlacedPageScan(); BTM_EnableInterlacedInquiryScan(); } @@ -415,10 +421,9 @@ void btm_read_local_name_complete(uint8_t* p, UNUSED_ATTR uint16_t evt_len) { * ******************************************************************************/ tBTM_STATUS BTM_SetDeviceClass(DEV_CLASS dev_class) { - if (!memcmp(btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN)) - return (BTM_SUCCESS); + if (btm_cb.devcb.dev_class == dev_class) return (BTM_SUCCESS); - memcpy(btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN); + btm_cb.devcb.dev_class = dev_class; if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET); @@ -433,12 +438,10 @@ tBTM_STATUS BTM_SetDeviceClass(DEV_CLASS dev_class) { * * Description This function is called to read the local device class * - * Returns pointer to the device class + * Returns the device class * ******************************************************************************/ -uint8_t* BTM_ReadDeviceClass(void) { - return ((uint8_t*)btm_cb.devcb.dev_class); -} +DEV_CLASS BTM_ReadDeviceClass(void) { return btm_cb.devcb.dev_class; } /******************************************************************************* * @@ -452,8 +455,7 @@ uint8_t* BTM_ReadDeviceClass(void) { ******************************************************************************/ void BTM_VendorSpecificCommand(uint16_t opcode, uint8_t param_len, uint8_t* p_param_buf, tBTM_VSC_CMPL_CB* p_cb) { - LOG_VERBOSE("BTM: %s: Opcode: 0x%04X, ParamLen: %i.", __func__, opcode, - param_len); + log::verbose("BTM: Opcode: 0x{:04X}, ParamLen: {}.", opcode, param_len); /* Send the HCI command (opcode will be OR'd with HCI_GRP_VENDOR_SPECIFIC) */ btsnd_hcic_vendor_spec_cmd(opcode, param_len, p_param_buf, p_cb); @@ -487,7 +489,7 @@ tBTM_STATUS BTM_RegisterForVSEvents(tBTM_VS_EVT_CB* p_cb, bool is_register) { /* Found callback in lookup table. If deregistering, clear the entry. */ if (!is_register) { btm_cb.devcb.p_vend_spec_cb[i] = NULL; - LOG_VERBOSE("BTM Deregister For VSEvents is successfully"); + log::verbose("BTM Deregister For VSEvents is successfully"); } return (BTM_SUCCESS); } @@ -497,10 +499,10 @@ tBTM_STATUS BTM_RegisterForVSEvents(tBTM_VS_EVT_CB* p_cb, bool is_register) { if (is_register) { if (free_idx < BTM_MAX_VSE_CALLBACKS) { btm_cb.devcb.p_vend_spec_cb[free_idx] = p_cb; - LOG_VERBOSE("BTM Register For VSEvents is successfully"); + log::verbose("BTM Register For VSEvents is successfully"); } else { /* No free entries available */ - LOG_ERROR("BTM_RegisterForVSEvents: too many callbacks registered"); + log::error("BTM_RegisterForVSEvents: too many callbacks registered"); retval = BTM_NO_RESOURCES; } @@ -513,39 +515,25 @@ tBTM_STATUS BTM_RegisterForVSEvents(tBTM_VS_EVT_CB* p_cb, bool is_register) { * * Function btm_vendor_specific_evt * - * Description Process event HCI_VENDOR_SPECIFIC_EVT + * Description Process event HCI_VENDOR_SPECIFIC_EVT (BQR) * * Returns void * ******************************************************************************/ void btm_vendor_specific_evt(const uint8_t* p, uint8_t evt_len) { - uint8_t i; - - LOG_VERBOSE("BTM Event: Vendor Specific event from controller"); - - // Handle BQR events - const uint8_t* bqr_ptr = p; - uint8_t event_code; - uint8_t len; - - if (evt_len >= 2) { - STREAM_TO_UINT8(event_code, bqr_ptr); - STREAM_TO_UINT8(len, bqr_ptr); - // Check if there's at least a subevent code - if (len > 1 && evt_len >= 2 + 1 && event_code == HCI_VENDOR_SPECIFIC_EVT) { - uint8_t sub_event_code; - STREAM_TO_UINT8(sub_event_code, bqr_ptr); - if (sub_event_code == HCI_VSE_SUBCODE_BQR_SUB_EVT) { - // Excluding the HCI Event packet header and 1 octet sub-event code - int16_t bqr_parameter_length = evt_len - HCIE_PREAMBLE_SIZE - 1; - const uint8_t* p_bqr_event = bqr_ptr; + uint8_t sub_event_code = HCI_VSE_SUBCODE_BQR_SUB_EVT; + uint8_t bqr_parameter_length = evt_len; + const uint8_t* p_bqr_event = p; + + log::verbose("BTM Event: Vendor Specific event from controller"); + // The stream currently points to the BQR sub-event parameters switch (sub_event_code) { case bluetooth::bqr::QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE: if (bqr_parameter_length >= bluetooth::bqr::kLogDumpParamTotalLen) { bluetooth::bqr::DumpLmpLlMessage(bqr_parameter_length, p_bqr_event); } else { - LOG_INFO("Malformed LMP event of length %hd", bqr_parameter_length); + log::info("Malformed LMP event of length {}", bqr_parameter_length); } break; @@ -554,21 +542,29 @@ void btm_vendor_specific_evt(const uint8_t* p, uint8_t evt_len) { if (bqr_parameter_length >= bluetooth::bqr::kLogDumpParamTotalLen) { bluetooth::bqr::DumpBtScheduling(bqr_parameter_length, p_bqr_event); } else { - LOG_INFO("Malformed TRACE event of length %hd", - bqr_parameter_length); + log::info("Malformed TRACE event of length {}", + bqr_parameter_length); } break; default: - LOG_INFO("Unhandled BQR subevent 0x%02hxx", sub_event_code); + log::info("Unhandled BQR subevent 0x{:02x}x", sub_event_code); + } + + uint8_t i; + std::vector reconstructed_event; + reconstructed_event.reserve(4 + bqr_parameter_length); + reconstructed_event[0] = HCI_VENDOR_SPECIFIC_EVT; + reconstructed_event[1] = 3 + bqr_parameter_length; // event size + reconstructed_event[2] = HCI_VSE_SUBCODE_BQR_SUB_EVT; + for (i = 0; i < bqr_parameter_length; i++) { + reconstructed_event.emplace_back(p[i]); } - } - } - } for (i = 0; i < BTM_MAX_VSE_CALLBACKS; i++) { if (btm_cb.devcb.p_vend_spec_cb[i]) - (*btm_cb.devcb.p_vend_spec_cb[i])(evt_len, p); + (*btm_cb.devcb.p_vend_spec_cb[i])(reconstructed_event.size(), + reconstructed_event.data()); } } @@ -580,7 +576,7 @@ void btm_vendor_specific_evt(const uint8_t* p, uint8_t evt_len) { * ******************************************************************************/ void BTM_WritePageTimeout(uint16_t timeout) { - LOG_VERBOSE("BTM: BTM_WritePageTimeout: Timeout: %d.", timeout); + log::verbose("BTM: BTM_WritePageTimeout: Timeout: {}.", timeout); /* Send the HCI command */ btsnd_hcic_write_page_tout(timeout); @@ -595,7 +591,7 @@ void BTM_WritePageTimeout(uint16_t timeout) { * ******************************************************************************/ void BTM_WriteVoiceSettings(uint16_t settings) { - LOG_VERBOSE("BTM: BTM_WriteVoiceSettings: Settings: 0x%04x.", settings); + log::verbose("BTM: BTM_WriteVoiceSettings: Settings: 0x{:04x}.", settings); /* Send the HCI command */ btsnd_hcic_write_voice_settings((uint16_t)(settings & 0x03ff)); @@ -619,7 +615,7 @@ void BTM_WriteVoiceSettings(uint16_t settings) { tBTM_STATUS BTM_EnableTestMode(void) { uint8_t cond; - LOG_VERBOSE("BTM: BTM_EnableTestMode"); + log::verbose("BTM: BTM_EnableTestMode"); /* set auto accept connection as this is needed during test mode */ /* Allocate a buffer to hold HCI command */ @@ -670,8 +666,8 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(const RawAddress* bd_addr, bool delete_all_flag = !bd_addr; - LOG_VERBOSE("BTM: BTM_DeleteStoredLinkKey: delete_all_flag: %s", - delete_all_flag ? "true" : "false"); + log::verbose("BTM: BTM_DeleteStoredLinkKey: delete_all_flag: {}", + delete_all_flag ? "true" : "false"); btm_sec_cb.devcb.p_stored_link_key_cmpl_cb = p_cb; if (!bd_addr) { @@ -710,7 +706,7 @@ void btm_delete_stored_link_key_complete(uint8_t* p, uint16_t evt_len) { result.event = BTM_CB_EVT_DELETE_STORED_LINK_KEYS; if (evt_len < 3) { - LOG(ERROR) << __func__ << "Malformatted event packet, too short"; + log::error("Malformatted event packet, too short"); return; } @@ -740,7 +736,7 @@ void btm_delete_stored_link_key_complete(uint8_t* p, uint16_t evt_len) { static void BTM_BT_Quality_Report_VSE_CBack(uint8_t length, const uint8_t* p_stream) { if (length == 0) { - LOG(WARNING) << __func__ << ": Lengths of all of the parameters are zero."; + log::warn("Lengths of all of the parameters are zero."); return; } @@ -750,7 +746,7 @@ static void BTM_BT_Quality_Report_VSE_CBack(uint8_t length, if (sub_event == HCI_VSE_SUBCODE_BQR_SUB_EVT) { if (btm_cb.p_bqr_report_receiver == nullptr) { - LOG(WARNING) << __func__ << ": No registered report receiver."; + log::warn("No registered report receiver."); return; } @@ -776,8 +772,8 @@ tBTM_STATUS BTM_BT_Quality_Report_VSE_Register( BTM_RegisterForVSEvents(BTM_BT_Quality_Report_VSE_CBack, is_register); if (retval != BTM_SUCCESS) { - LOG(WARNING) << __func__ << ": Fail to (un)register VSEvents: " << retval - << ", is_register: " << logbool(is_register); + log::warn("Fail to (un)register VSEvents: {}, is_register: {}", retval, + logbool(is_register)); return retval; } @@ -787,7 +783,7 @@ tBTM_STATUS BTM_BT_Quality_Report_VSE_Register( btm_cb.p_bqr_report_receiver = nullptr; } - LOG(INFO) << __func__ << ": Success to (un)register VSEvents." - << " is_register: " << logbool(is_register); + log::info("Success to (un)register VSEvents. is_register: {}", + logbool(is_register)); return retval; } diff --git a/system/stack/btm/btm_inq.cc b/system/stack/btm/btm_inq.cc index 9245f7a421d5aeb08b4b27522fe10fc019a85cae..5cb52a781928434fd07ea5ad5fb475959404df19 100644 --- a/system/stack/btm/btm_inq.cc +++ b/system/stack/btm/btm_inq.cc @@ -28,6 +28,7 @@ #define LOG_TAG "bluetooth" #include +#include #include #include #include @@ -36,19 +37,27 @@ #include #include "advertise_data_parser.h" +#include "btif/include/btif_acl.h" #include "btif/include/btif_config.h" #include "common/time_util.h" #include "device/include/controller.h" +#include "hci/controller_interface.h" +#include "hci/event_checkers.h" +#include "hci/hci_layer.h" +#include "include/check.h" #include "internal_include/bt_target.h" +#include "main/shim/entry.h" +#include "main/shim/helpers.h" #include "main/shim/shim.h" +#include "neighbor_inquiry.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "osi/include/properties.h" #include "osi/include/stack_power_telemetry.h" +#include "packet/bit_inserter.h" #include "stack/btm/btm_int_types.h" #include "stack/btm/btm_sec.h" -#include "stack/include/acl_api.h" #include "stack/include/acl_api_types.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_lap.h" @@ -57,8 +66,11 @@ #include "stack/include/btm_api.h" #include "stack/include/btm_ble_api.h" #include "stack/include/btm_log_history.h" +#include "stack/include/hci_error_code.h" +#include "stack/include/hcidefs.h" #include "stack/include/hcimsgs.h" #include "stack/include/inq_hci_link_interface.h" +#include "stack/include/main_thread.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -122,6 +134,7 @@ tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode); tBTM_STATUS btm_ble_start_inquiry(uint8_t duration); void btm_ble_stop_inquiry(void); +using namespace bluetooth; using bluetooth::Uuid; /* 3 second timeout waiting for responses */ @@ -162,6 +175,10 @@ using bluetooth::Uuid; #define BTIF_DM_DEFAULT_INQ_MAX_DURATION 10 +#ifndef PROPERTY_INQ_LENGTH +#define PROPERTY_INQ_LENGTH "bluetooth.core.classic.inq_length" +#endif + /******************************************************************************/ /* L O C A L D A T A D E F I N I T I O N S */ /******************************************************************************/ @@ -240,6 +257,8 @@ void SendRemoteNameRequest(const RawAddress& raw_address) { btsnd_hcic_rmt_name_req(raw_address, HCI_PAGE_SCAN_REP_MODE_R1, HCI_MANDATARY_PAGE_SCAN_MODE, 0); } +static void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode); +static void on_incoming_hci_event(bluetooth::hci::EventView event); /******************************************************************************* * * Function BTM_SetDiscoverability @@ -259,15 +278,14 @@ void SendRemoteNameRequest(const RawAddress& raw_address) { tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) { uint8_t scan_mode = 0; uint16_t service_class; - uint8_t* p_cod; uint8_t major, minor; DEV_CLASS cod; LAP temp_lap[2]; bool is_limited; bool cod_limited; - LOG_VERBOSE(""); - if (controller_get_interface()->supports_ble()) { + log::verbose(""); + if (controller_get_interface()->SupportsBle()) { if (btm_ble_set_discoverability((uint16_t)(inq_mode)) == BTM_SUCCESS) { btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK); btm_cb.btm_inq_vars.discoverable_mode |= @@ -283,7 +301,7 @@ tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) { if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET); /* If the window and/or interval is '0', set to default values */ - LOG_VERBOSE("mode %d [NonDisc-0, Lim-1, Gen-2]", inq_mode); + log::verbose("mode {} [NonDisc-0, Lim-1, Gen-2]", inq_mode); (inq_mode != BTM_NON_DISCOVERABLE) ? power_telemetry::GetInstance().LogInqScanStarted() : power_telemetry::GetInstance().LogInqScanStopped(); @@ -325,13 +343,13 @@ tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) { btm_cb.btm_inq_vars.discoverable_mode |= inq_mode; /* Change the service class bit if mode has changed */ - p_cod = BTM_ReadDeviceClass(); - BTM_COD_SERVICE_CLASS(service_class, p_cod); + DEV_CLASS old_cod = BTM_ReadDeviceClass(); + BTM_COD_SERVICE_CLASS(service_class, old_cod); is_limited = (inq_mode & BTM_LIMITED_DISCOVERABLE) ? true : false; cod_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false; if (is_limited ^ cod_limited) { - BTM_COD_MINOR_CLASS(minor, p_cod); - BTM_COD_MAJOR_CLASS(major, p_cod); + BTM_COD_MINOR_CLASS(minor, old_cod); + BTM_COD_MAJOR_CLASS(major, old_cod); if (is_limited) service_class |= BTM_COD_SERVICE_LMTD_DISCOVER; else @@ -345,12 +363,12 @@ tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) { } void BTM_EnableInterlacedInquiryScan() { - LOG_VERBOSE(""); + log::verbose(""); uint16_t inq_scan_type = osi_property_get_int32(PROPERTY_INQ_SCAN_TYPE, BTM_SCAN_TYPE_INTERLACED); - if (!controller_get_interface()->supports_interlaced_inquiry_scan() || + if (!bluetooth::shim::GetController()->SupportsInterlacedInquiryScan() || inq_scan_type != BTM_SCAN_TYPE_INTERLACED || btm_cb.btm_inq_vars.inq_scan_type == BTM_SCAN_TYPE_INTERLACED) { return; @@ -361,12 +379,12 @@ void BTM_EnableInterlacedInquiryScan() { } void BTM_EnableInterlacedPageScan() { - LOG_VERBOSE(""); + log::verbose(""); uint16_t page_scan_type = osi_property_get_int32(PROPERTY_PAGE_SCAN_TYPE, BTM_SCAN_TYPE_INTERLACED); - if (!controller_get_interface()->supports_interlaced_inquiry_scan() || + if (!bluetooth::shim::GetController()->SupportsInterlacedInquiryScan() || page_scan_type != BTM_SCAN_TYPE_INTERLACED || btm_cb.btm_inq_vars.page_scan_type == BTM_SCAN_TYPE_INTERLACED) { return; @@ -392,15 +410,14 @@ void BTM_EnableInterlacedPageScan() { * ******************************************************************************/ tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) { - const controller_t* controller = controller_get_interface(); - LOG_VERBOSE(""); + log::verbose(""); if (mode == BTM_INQ_RESULT_STANDARD) { /* mandatory mode */ } else if (mode == BTM_INQ_RESULT_WITH_RSSI) { - if (!controller->supports_rssi_with_inquiry_results()) + if (!bluetooth::shim::GetController()->SupportsRssiWithInquiryResults()) return (BTM_MODE_UNSUPPORTED); } else if (mode == BTM_INQ_RESULT_EXTENDED) { - if (!controller->supports_extended_inquiry_response()) + if (!bluetooth::shim::GetController()->SupportsExtendedInquiryResponse()) return (BTM_MODE_UNSUPPORTED); } else return (BTM_ILLEGAL_VALUE); @@ -429,7 +446,7 @@ tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) { tBTM_STATUS BTM_SetConnectability(uint16_t page_mode) { uint8_t scan_mode = 0; - if (controller_get_interface()->supports_ble()) { + if (controller_get_interface()->SupportsBle()) { if (btm_ble_set_connectability(page_mode) != BTM_SUCCESS) { return BTM_NO_RESOURCES; } @@ -456,8 +473,8 @@ tBTM_STATUS BTM_SetConnectability(uint16_t page_mode) { const uint16_t interval = osi_property_get_int32(PROPERTY_PAGE_SCAN_INTERVAL, BTM_DEFAULT_CONN_INTERVAL); - LOG_VERBOSE("mode=%d [NonConn-0, Conn-1], page scan interval=(%d * 0.625)ms", - page_mode, interval); + log::verbose("mode={} [NonConn-0, Conn-1], page scan interval=({} * 0.625)ms", + page_mode, interval); if ((window != btm_cb.btm_inq_vars.page_scan_window) || (interval != btm_cb.btm_inq_vars.page_scan_period)) { @@ -489,11 +506,30 @@ tBTM_STATUS BTM_SetConnectability(uint16_t page_mode) { * ******************************************************************************/ uint16_t BTM_IsInquiryActive(void) { - LOG_VERBOSE(""); + log::verbose(""); return (btm_cb.btm_inq_vars.inq_active); } +/******************************************************************************* + * + * Function BTM_CancelLeScan + * + * Description This function cancels an le scan if active + * + ******************************************************************************/ +static void BTM_CancelLeScan() { + if (!bluetooth::shim::is_classic_discovery_only_enabled()) { + CHECK(BTM_IsDeviceUp()); + if ((btm_cb.btm_inq_vars.inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) + btm_ble_stop_inquiry(); + } else { + log::info( + "Unable to cancel le scan as `is_classic_discovery_only_enabled` is " + "true"); + } +} + /******************************************************************************* * * Function BTM_CancelInquiry @@ -502,7 +538,7 @@ uint16_t BTM_IsInquiryActive(void) { * ******************************************************************************/ void BTM_CancelInquiry(void) { - LOG_VERBOSE(""); + log::verbose(""); CHECK(BTM_IsDeviceUp()); @@ -521,14 +557,13 @@ void BTM_CancelInquiry(void) { .start_time_ms = btm_cb.neighbor.classic_inquiry.start_time_ms, }); - const auto end_time_ms = timestamper_in_milliseconds.GetTimestamp(); + const auto duration_ms = timestamper_in_milliseconds.GetTimestamp() - + btm_cb.neighbor.classic_inquiry.start_time_ms; BTM_LogHistory( kBtmLogTag, RawAddress::kEmpty, "Classic inquiry canceled", base::StringPrintf( "duration_s:%6.3f results:%lu std:%u rssi:%u ext:%u", - (end_time_ms - btm_cb.neighbor.classic_inquiry.start_time_ms) / - 1000.0, - btm_cb.neighbor.classic_inquiry.results, + duration_ms / 1000.0, btm_cb.neighbor.classic_inquiry.results, btm_cb.btm_inq_vars.inq_cmpl_info.resp_type[BTM_INQ_RESULT_STANDARD], btm_cb.btm_inq_vars.inq_cmpl_info.resp_type[BTM_INQ_RESULT_WITH_RSSI], btm_cb.btm_inq_vars.inq_cmpl_info @@ -545,13 +580,16 @@ void BTM_CancelInquiry(void) { btm_cb.btm_inq_vars.p_inq_cmpl_cb = NULL; /* Do not notify caller anymore */ if ((btm_cb.btm_inq_vars.inqparms.mode & BTM_BR_INQUIRY_MASK) != 0) { - bluetooth::legacy::hci::GetInterface().InquiryCancel(); - } - - if (!bluetooth::shim::is_classic_discovery_only_enabled()) { - if ((btm_cb.btm_inq_vars.inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) - btm_ble_stop_inquiry(); + bluetooth::shim::GetHciLayer()->EnqueueCommand( + bluetooth::hci::InquiryCancelBuilder::Create(), + get_main_thread()->BindOnce( + [](bluetooth::hci::CommandCompleteView complete_view) { + bluetooth::hci::check_complete< + bluetooth::hci::InquiryCancelCompleteView>(complete_view); + btm_process_cancel_complete(HCI_SUCCESS, BTM_BR_INQUIRY_MASK); + })); } + BTM_CancelLeScan(); btm_cb.btm_inq_vars.inq_counter++; btm_clr_inq_result_flt(); @@ -566,11 +604,42 @@ static void btm_classic_inquiry_timeout(UNUSED_ATTR void* data) { btm_process_inq_complete(HCI_SUCCESS, BTM_BLE_INQUIRY_MASK); } +/******************************************************************************* + * + * Function BTM_StartLeScan + * + * Description This function is called to start an LE scan. Currently + * this is only callable from BTM_StartInquiry. + * + * Returns tBTM_STATUS + * BTM_CMD_STARTED if le scan successfully initiated + * BTM_WRONG_MODE if controller does not support ble or the + * is_classic_discovery_only_enabled flag is set + * + ******************************************************************************/ +static tBTM_STATUS BTM_StartLeScan() { + if (!bluetooth::shim::is_classic_discovery_only_enabled()) { + if (controller_get_interface()->SupportsBle()) { + btm_ble_start_inquiry(btm_cb.btm_inq_vars.inqparms.duration); + return BTM_CMD_STARTED; + } else { + log::warn("Trying to do LE scan on a non-LE adapter"); + btm_cb.btm_inq_vars.inqparms.mode &= ~BTM_BLE_INQUIRY_MASK; + } + } else { + log::info( + "init_flag: Skip le scan as classic inquiry only flag is set enabled"); + } + return BTM_WRONG_MODE; +} + /******************************************************************************* * * Function BTM_StartInquiry * - * Description This function is called to start an inquiry. + * Description This function is called to start an inquiry on the + * classic BR/EDR link and start an le scan. This is an + * Android only API. * * Parameters: p_inqparms - pointer to the inquiry information * mode - GENERAL or LIMITED inquiry, BR/LE bit mask @@ -606,9 +675,9 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, /* Only one active inquiry is allowed in this implementation. Also do not allow an inquiry if the inquiry filter is being updated */ if (btm_cb.btm_inq_vars.inq_active) { - LOG_WARN( - "Active device discovery already in progress inq_active:0x%02x" - " state:%hhu counter:%u", + log::warn( + "Active device discovery already in progress inq_active:0x{:02x} " + "state:{} counter:{}", btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inq_counter); btm_cb.neighbor.inquiry_history_->Push({ @@ -617,9 +686,34 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, return BTM_BUSY; } + if (btm_cb.btm_inq_vars.registered_for_hci_events == false) { + bluetooth::shim::GetHciLayer()->RegisterEventHandler( + bluetooth::hci::EventCode::INQUIRY_COMPLETE, + get_main_thread()->Bind([](bluetooth::hci::EventView event) { + on_incoming_hci_event(event); + })); + bluetooth::shim::GetHciLayer()->RegisterEventHandler( + bluetooth::hci::EventCode::INQUIRY_RESULT, + get_main_thread()->Bind([](bluetooth::hci::EventView event) { + on_incoming_hci_event(event); + })); + bluetooth::shim::GetHciLayer()->RegisterEventHandler( + bluetooth::hci::EventCode::INQUIRY_RESULT_WITH_RSSI, + get_main_thread()->Bind([](bluetooth::hci::EventView event) { + on_incoming_hci_event(event); + })); + bluetooth::shim::GetHciLayer()->RegisterEventHandler( + bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT, + get_main_thread()->Bind([](bluetooth::hci::EventView event) { + on_incoming_hci_event(event); + })); + + btm_cb.btm_inq_vars.registered_for_hci_events = true; + } + /*** Make sure the device is ready ***/ if (!BTM_IsDeviceUp()) { - LOG_ERROR("adapter is not up"); + log::error("adapter is not up"); btm_cb.neighbor.inquiry_history_->Push({ .status = tBTM_INQUIRY_CMPL::NOT_STARTED, }); @@ -632,12 +726,15 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, ? "" : "ERROR Already in progress")); + const uint8_t inq_length = osi_property_get_int32( + PROPERTY_INQ_LENGTH, BTIF_DM_DEFAULT_INQ_MAX_DURATION); + /* Save the inquiry parameters to be used upon the completion of * setting/clearing the inquiry filter */ btm_cb.btm_inq_vars.inqparms = { // tBTM_INQ_PARMS .mode = BTM_GENERAL_INQUIRY | BTM_BLE_GENERAL_INQUIRY, - .duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION, + .duration = inq_length, }; /* Initialize the inquiry variables */ @@ -651,25 +748,20 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, .results = 0, }; - LOG_DEBUG("Starting device discovery inq_active:0x%02x", - btm_cb.btm_inq_vars.inq_active); + log::debug("Starting device discovery inq_active:0x{:02x}", + btm_cb.btm_inq_vars.inq_active); // Also do BLE scanning here if we aren't limiting discovery to classic only. // This path does not play nicely with GD BLE scanning and may cause issues // with other scanners. - if (!bluetooth::shim::is_classic_discovery_only_enabled()) { - if (controller_get_interface()->supports_ble()) { - btm_ble_start_inquiry(btm_cb.btm_inq_vars.inqparms.duration); - } else { - LOG_WARN("Trying to do LE scan on a non-LE adapter"); - btm_cb.btm_inq_vars.inqparms.mode &= ~BTM_BLE_INQUIRY_MASK; - } - } - - btm_acl_update_inquiry_status(BTM_INQUIRY_STARTED); + BTM_StartLeScan(); if (btm_cb.btm_inq_vars.inq_active & BTM_SSP_INQUIRY_ACTIVE) { - LOG_INFO("Not starting inquiry as SSP is in progress"); + log::info("Not starting inquiry as SSP is in progress"); + // Report the status here because inq_complete will cancel it below + BTIF_dm_report_inquiry_status_change( + tBTM_INQUIRY_STATE::BTM_INQUIRY_STARTED); + btm_process_inq_complete(HCI_ERR_MAX_NUM_OF_CONNECTIONS, BTM_GENERAL_INQUIRY); return BTM_CMD_STARTED; @@ -679,8 +771,25 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, btm_init_inq_result_flt(); - bluetooth::legacy::hci::GetInterface().StartInquiry( - general_inq_lap, btm_cb.btm_inq_vars.inqparms.duration, 0); + bluetooth::hci::Lap lap; + lap.lap_ = general_inq_lap[2]; + + // TODO: Register for the inquiry interface and use that + bluetooth::shim::GetHciLayer()->EnqueueCommand( + bluetooth::hci::InquiryBuilder::Create( + lap, btm_cb.btm_inq_vars.inqparms.duration, 0), + get_main_thread()->BindOnce( + [](bluetooth::hci::CommandStatusView status_view) { + ASSERT(status_view.IsValid()); + auto status = status_view.GetStatus(); + if (status == bluetooth::hci::ErrorCode::SUCCESS) { + BTIF_dm_report_inquiry_status_change( + tBTM_INQUIRY_STATE::BTM_INQUIRY_STARTED); + } else { + log::info("Inquiry failed to start status: {}", + bluetooth::hci::ErrorCodeText(status).c_str()); + } + })); // If we are only doing classic discovery, we should also set a timeout for // the inquiry if a duration is set. @@ -719,10 +828,11 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ +#define BTM_EXT_RMT_NAME_TIMEOUT_MS (40 * 1000) /* 40 seconds */ tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda, tBTM_NAME_CMPL_CB* p_cb, tBT_TRANSPORT transport) { - VLOG(1) << __func__ << ": bd addr " << remote_bda; + log::verbose("bd addr {}", ADDRESS_TO_LOGGABLE_STR(remote_bda)); /* Use LE transport when LE is the only available option */ if (transport == BT_TRANSPORT_LE) { return btm_ble_read_remote_name(remote_bda, p_cb); @@ -751,7 +861,7 @@ tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda, * ******************************************************************************/ tBTM_STATUS BTM_CancelRemoteDeviceName(void) { - LOG_VERBOSE(""); + log::verbose(""); /* Make sure there is not already one in progress */ if (btm_cb.btm_inq_vars.remname_active) { @@ -910,7 +1020,7 @@ void btm_inq_db_reset(void) { uint8_t num_responses; uint8_t temp_inq_active; - LOG_DEBUG("Resetting inquiry database"); + log::debug("Resetting inquiry database"); /* If an inquiry or periodic inquiry is active, reset the mode to inactive */ if (btm_cb.btm_inq_vars.inq_active != BTM_INQUIRY_INACTIVE) { @@ -999,16 +1109,23 @@ void btm_inq_stop_on_ssp(void) { uint8_t normal_active = (BTM_GENERAL_INQUIRY_ACTIVE); #if (BTM_INQ_DEBUG == TRUE) - LOG_VERBOSE("btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d ", - btm_cb.btm_inq_vars.no_inc_ssp, btm_cb.btm_inq_vars.inq_active, - btm_cb.btm_inq_vars.state); + log::verbose("btm_inq_stop_on_ssp: no_inc_ssp={} inq_active:0x{:x} state:{} ", + btm_cb.btm_inq_vars.no_inc_ssp, btm_cb.btm_inq_vars.inq_active, + btm_cb.btm_inq_vars.state); #endif if (btm_cb.btm_inq_vars.no_inc_ssp) { if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE) { if (btm_cb.btm_inq_vars.inq_active & normal_active) { /* can not call BTM_CancelInquiry() here. We need to report inquiry * complete evt */ - bluetooth::legacy::hci::GetInterface().InquiryCancel(); + bluetooth::shim::GetHciLayer()->EnqueueCommand( + bluetooth::hci::InquiryCancelBuilder::Create(), + get_main_thread()->BindOnce( + [](bluetooth::hci::CommandCompleteView complete_view) { + bluetooth::hci::check_complete< + bluetooth::hci::InquiryCancelCompleteView>(complete_view); + btm_process_cancel_complete(HCI_SUCCESS, BTM_BR_INQUIRY_MASK); + })); } } /* do not allow inquiry to start */ @@ -1046,8 +1163,8 @@ void btm_clr_inq_db(const RawAddress* p_bda) { uint16_t xx; #if (BTM_INQ_DEBUG == TRUE) - LOG_VERBOSE("btm_clr_inq_db: inq_active:0x%x state:%d", - btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state); + log::verbose("btm_clr_inq_db: inq_active:0x{:x} state:{}", + btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state); #endif std::lock_guard lock(inq_db_lock_); tINQ_DB_ENT* p_ent = inq_db_; @@ -1060,8 +1177,8 @@ void btm_clr_inq_db(const RawAddress* p_bda) { } } #if (BTM_INQ_DEBUG == TRUE) - LOG_VERBOSE("inq_active:0x%x state:%d", btm_cb.btm_inq_vars.inq_active, - btm_cb.btm_inq_vars.state); + log::verbose("inq_active:0x{:x} state:{}", btm_cb.btm_inq_vars.inq_active, + btm_cb.btm_inq_vars.state); #endif } @@ -1079,7 +1196,7 @@ static void btm_init_inq_result_flt(void) { std::lock_guard lock(bd_db_lock_); if (p_bd_db_ != nullptr) { - LOG_ERROR("Memory leak with bluetooth device database"); + log::error("Memory leak with bluetooth device database"); } /* Allocate memory to hold bd_addrs responding */ @@ -1090,7 +1207,7 @@ static void btm_init_inq_result_flt(void) { void btm_clr_inq_result_flt(void) { std::lock_guard lock(bd_db_lock_); if (p_bd_db_ == nullptr) { - LOG_WARN("Memory being reset multiple times"); + log::warn("Memory being reset multiple times"); } osi_free_and_reset((void**)&p_bd_db_); @@ -1212,22 +1329,133 @@ tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda, bool is_ble) { /******************************************************************************* * - * Function btm_process_inq_results + * Function btm_process_inq_results_standard * * Description This function is called when inquiry results are received * from the device. It updates the inquiry database. If the * inquiry database is full, the oldest entry is discarded. * - * Parameters inq_res_mode - BTM_INQ_RESULT_STANDARD - * BTM_INQ_RESULT_WITH_RSSI - * BTM_INQ_RESULT_EXTENDED + * Returns void + * + ******************************************************************************/ +static void btm_process_inq_results_standard(bluetooth::hci::EventView event) { + RawAddress bda; + tINQ_DB_ENT* p_i; + tBTM_INQ_RESULTS* p_cur = NULL; + bool is_new = true; + tBTM_INQ_RESULTS_CB* p_inq_results_cb = btm_cb.btm_inq_vars.p_inq_results_cb; + uint8_t page_scan_rep_mode = 0; + uint8_t page_scan_per_mode = 0; + uint8_t page_scan_mode = 0; + DEV_CLASS dc; + uint16_t clock_offset; + const uint8_t* p_eir_data = NULL; + + log::debug("Received inquiry result inq_active:0x{:x} state:{}", + btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state); + + /* Only process the results if the BR inquiry is still active */ + if (!(btm_cb.btm_inq_vars.inq_active & BTM_BR_INQ_ACTIVE_MASK)) { + log::info("Inquiry is inactive so dropping inquiry result"); + return; + } + + auto standard_view = bluetooth::hci::InquiryResultView::Create(event); + ASSERT(standard_view.IsValid()); + auto responses = standard_view.GetResponses(); + + btm_cb.neighbor.classic_inquiry.results += responses.size(); + for (const auto& response : responses) { + /* Extract inquiry results */ + bda = bluetooth::ToRawAddress(response.bd_addr_); + page_scan_rep_mode = + static_cast(response.page_scan_repetition_mode_); + page_scan_per_mode = 0; // reserved + page_scan_mode = 0; // reserved + + dc[0] = response.class_of_device_.cod[2]; + dc[1] = response.class_of_device_.cod[1]; + dc[2] = response.class_of_device_.cod[0]; + + clock_offset = response.clock_offset_; + + p_i = btm_inq_db_find(bda); + + /* If existing entry, use that, else get a new one (possibly reusing the + * oldest) */ + if (p_i == NULL) { + p_i = btm_inq_db_new(bda, false); + is_new = true; + } + + /* If an entry for the device already exists, overwrite it ONLY if it is + from a previous inquiry. (Ignore it if it is a duplicate response from + the same inquiry. + */ + else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && + (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR)) + is_new = false; + + p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI; + + if (is_new) { + /* Save the info */ + p_cur = &p_i->inq_info.results; + p_cur->page_scan_rep_mode = page_scan_rep_mode; + p_cur->page_scan_per_mode = page_scan_per_mode; + p_cur->page_scan_mode = page_scan_mode; + p_cur->dev_class[0] = dc[0]; + p_cur->dev_class[1] = dc[1]; + p_cur->dev_class[2] = dc[2]; + p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; + + p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); + + if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { + /* A new response was found */ + btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; + btm_cb.btm_inq_vars.inq_cmpl_info.resp_type[BTM_INQ_RESULT_STANDARD]++; + } + + p_cur->inq_result_type |= BT_DEVICE_TYPE_BREDR; + if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { + p_cur->device_type = BT_DEVICE_TYPE_BREDR; + p_i->scan_rsp = false; + } else + p_cur->device_type |= BT_DEVICE_TYPE_BREDR; + p_i->inq_count = + btm_cb.btm_inq_vars.inq_counter; /* Mark entry for current inquiry */ + + /* Initialize flag to false. This flag is set/used by application */ + p_i->inq_info.appl_knows_rem_name = false; + } + + if (is_new) { + p_eir_data = NULL; + + /* If a callback is registered, call it with the results */ + if (p_inq_results_cb) { + (p_inq_results_cb)((tBTM_INQ_RESULTS*)p_cur, p_eir_data, + HCI_EXT_INQ_RESPONSE_LEN); + } else { + log::warn("No callback is registered for inquiry result"); + } + } + } +} + +/******************************************************************************* + * + * Function btm_process_inq_results_rssi + * + * Description This function is called when inquiry results are received + * from the device. It updates the inquiry database. If the + * inquiry database is full, the oldest entry is discarded. * * Returns void * ******************************************************************************/ -void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, - uint8_t inq_res_mode) { - uint8_t num_resp, xx; +static void btm_process_inq_results_rssi(bluetooth::hci::EventView event) { RawAddress bda; tINQ_DB_ENT* p_i; tBTM_INQ_RESULTS* p_cur = NULL; @@ -1243,62 +1471,181 @@ void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, uint16_t clock_offset; const uint8_t* p_eir_data = NULL; - LOG_DEBUG("Received inquiry result inq_active:0x%x state:%d", - btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state); + log::debug("Received inquiry result inq_active:0x{:x} state:{}", + btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state); /* Only process the results if the BR inquiry is still active */ if (!(btm_cb.btm_inq_vars.inq_active & BTM_BR_INQ_ACTIVE_MASK)) { - LOG_INFO("Inquiry is inactive so dropping inquiry result"); + log::info("Inquiry is inactive so dropping inquiry result"); return; } - STREAM_TO_UINT8(num_resp, p); + auto rssi_view = bluetooth::hci::InquiryResultWithRssiView::Create(event); + ASSERT(rssi_view.IsValid()); + auto responses = rssi_view.GetResponses(); + + btm_cb.neighbor.classic_inquiry.results += responses.size(); + for (const auto& response : responses) { + update = false; + /* Extract inquiry results */ + bda = bluetooth::ToRawAddress(response.address_); + page_scan_rep_mode = + static_cast(response.page_scan_repetition_mode_); + page_scan_per_mode = 0; // reserved + page_scan_mode = 0; // reserved + + dc[0] = response.class_of_device_.cod[2]; + dc[1] = response.class_of_device_.cod[1]; + dc[2] = response.class_of_device_.cod[0]; + + clock_offset = response.clock_offset_; + rssi = response.rssi_; - if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) { - if (num_resp > 1) { - LOG_ERROR("extended results (%d) > 1", num_resp); - return; + p_i = btm_inq_db_find(bda); + + /* Check if this address has already been processed for this inquiry */ + if (btm_inq_find_bdaddr(bda)) { + /* By default suppose no update needed */ + i_rssi = (int8_t)rssi; + + /* If this new RSSI is higher than the last one */ + if ((rssi != 0) && p_i && + (i_rssi > p_i->inq_info.results.rssi || + p_i->inq_info.results.rssi == 0 + /* BR/EDR inquiry information update */ + || + (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)) { + p_cur = &p_i->inq_info.results; + log::verbose("update RSSI new:{}, old:{}", i_rssi, p_cur->rssi); + p_cur->rssi = i_rssi; + update = true; + } + /* If no update needed continue with next response (if any) */ + else + continue; } - constexpr uint16_t extended_inquiry_result_size = 254; - if (hci_evt_len - 1 != extended_inquiry_result_size) { - LOG_ERROR("can't fit %d results in %d bytes", num_resp, hci_evt_len); - return; + /* If existing entry, use that, else get a new one (possibly reusing the + * oldest) */ + if (p_i == NULL) { + p_i = btm_inq_db_new(bda, false); + is_new = true; } - } else if (inq_res_mode == BTM_INQ_RESULT_STANDARD || - inq_res_mode == BTM_INQ_RESULT_WITH_RSSI) { - constexpr uint16_t inquiry_result_size = 14; - if (hci_evt_len < num_resp * inquiry_result_size) { - LOG_ERROR("can't fit %d results in %d bytes", num_resp, hci_evt_len); - return; + + /* If an entry for the device already exists, overwrite it ONLY if it is + from a previous inquiry. (Ignore it if it is a duplicate response from + the same inquiry. + */ + else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && + (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR)) + is_new = false; + + /* keep updating RSSI to have latest value */ + p_i->inq_info.results.rssi = (int8_t)rssi; + + if (is_new) { + /* Save the info */ + p_cur = &p_i->inq_info.results; + p_cur->page_scan_rep_mode = page_scan_rep_mode; + p_cur->page_scan_per_mode = page_scan_per_mode; + p_cur->page_scan_mode = page_scan_mode; + p_cur->dev_class[0] = dc[0]; + p_cur->dev_class[1] = dc[1]; + p_cur->dev_class[2] = dc[2]; + p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; + + p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); + + if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { + /* A new response was found */ + btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; + btm_cb.btm_inq_vars.inq_cmpl_info.resp_type[BTM_INQ_RESULT_WITH_RSSI]++; + } + + p_cur->inq_result_type |= BT_DEVICE_TYPE_BREDR; + if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { + p_cur->device_type = BT_DEVICE_TYPE_BREDR; + p_i->scan_rsp = false; + } else + p_cur->device_type |= BT_DEVICE_TYPE_BREDR; + p_i->inq_count = + btm_cb.btm_inq_vars.inq_counter; /* Mark entry for current inquiry */ + + /* Initialize flag to false. This flag is set/used by application */ + p_i->inq_info.appl_knows_rem_name = false; } + + if (is_new || update) { + p_eir_data = NULL; + + /* If a callback is registered, call it with the results */ + if (p_inq_results_cb) { + (p_inq_results_cb)((tBTM_INQ_RESULTS*)p_cur, p_eir_data, + HCI_EXT_INQ_RESPONSE_LEN); + } else { + log::warn("No callback is registered for inquiry result"); + } + } + } +} + +/******************************************************************************* + * + * Function btm_process_inq_results_extended + * + * Description This function is called when inquiry results are received + * from the device. It updates the inquiry database. If the + * inquiry database is full, the oldest entry is discarded. + * + * Returns void + * + ******************************************************************************/ +static void btm_process_inq_results_extended(bluetooth::hci::EventView event) { + RawAddress bda; + tINQ_DB_ENT* p_i; + tBTM_INQ_RESULTS* p_cur = NULL; + bool is_new = true; + bool update = false; + int8_t i_rssi; + tBTM_INQ_RESULTS_CB* p_inq_results_cb = btm_cb.btm_inq_vars.p_inq_results_cb; + uint8_t page_scan_rep_mode = 0; + uint8_t page_scan_per_mode = 0; + uint8_t page_scan_mode = 0; + uint8_t rssi = 0; + DEV_CLASS dc; + uint16_t clock_offset; + + log::debug("Received inquiry result inq_active:0x{:x} state:{}", + btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state); + + /* Only process the results if the BR inquiry is still active */ + if (!(btm_cb.btm_inq_vars.inq_active & BTM_BR_INQ_ACTIVE_MASK)) { + log::info("Inquiry is inactive so dropping inquiry result"); + return; } - btm_cb.neighbor.classic_inquiry.results += num_resp; - for (xx = 0; xx < num_resp; xx++) { + auto extended_view = bluetooth::hci::ExtendedInquiryResultView::Create(event); + ASSERT(extended_view.IsValid()); + + btm_cb.neighbor.classic_inquiry.results++; + { update = false; /* Extract inquiry results */ - STREAM_TO_BDADDR(bda, p); - STREAM_TO_UINT8(page_scan_rep_mode, p); - STREAM_TO_UINT8(page_scan_per_mode, p); + bda = bluetooth::ToRawAddress(extended_view.GetAddress()); + page_scan_rep_mode = + static_cast(extended_view.GetPageScanRepetitionMode()); + page_scan_per_mode = 0; // reserved - if (inq_res_mode == BTM_INQ_RESULT_STANDARD) { - STREAM_TO_UINT8(page_scan_mode, p); - } - - STREAM_TO_DEVCLASS(dc, p); - STREAM_TO_UINT16(clock_offset, p); - if (inq_res_mode != BTM_INQ_RESULT_STANDARD) { - STREAM_TO_UINT8(rssi, p); - } + dc[0] = extended_view.GetClassOfDevice().cod[2]; + dc[1] = extended_view.GetClassOfDevice().cod[1]; + dc[2] = extended_view.GetClassOfDevice().cod[0]; + clock_offset = extended_view.GetClockOffset(); + rssi = extended_view.GetRssi(); p_i = btm_inq_db_find(bda); /* Check if this address has already been processed for this inquiry */ if (btm_inq_find_bdaddr(bda)) { - /* LOG_VERBOSE("BDA seen before %s", ADDRESS_TO_LOGGABLE_CSTR(bda)); - */ - /* By default suppose no update needed */ i_rssi = (int8_t)rssi; @@ -1310,20 +1657,20 @@ void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, || (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)) { p_cur = &p_i->inq_info.results; - LOG_VERBOSE("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi); + log::verbose("update RSSI new:{}, old:{}", i_rssi, p_cur->rssi); p_cur->rssi = i_rssi; update = true; } /* If we received a second Extended Inq Event for an already */ /* discovered device, this is because for the first one EIR was not received */ - else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i)) { + else if (p_i) { p_cur = &p_i->inq_info.results; update = true; } /* If no update needed continue with next response (if any) */ else - continue; + return; } /* If existing entry, use that, else get a new one (possibly reusing the @@ -1344,10 +1691,7 @@ void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, is_new = false; /* keep updating RSSI to have latest value */ - if (inq_res_mode != BTM_INQ_RESULT_STANDARD) - p_i->inq_info.results.rssi = (int8_t)rssi; - else - p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI; + p_i->inq_info.results.rssi = (int8_t)rssi; if (is_new) { /* Save the info */ @@ -1365,20 +1709,10 @@ void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { /* A new response was found */ btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; - switch (static_cast(inq_res_mode)) { - case BTM_INQ_RESULT_STANDARD: - case BTM_INQ_RESULT_WITH_RSSI: - case BTM_INQ_RESULT_EXTENDED: - btm_cb.btm_inq_vars.inq_cmpl_info.resp_type[inq_res_mode]++; - break; - case BTM_INQ_RES_IGNORE_RSSI: - btm_cb.btm_inq_vars.inq_cmpl_info - .resp_type[BTM_INQ_RESULT_STANDARD]++; - break; - } + btm_cb.btm_inq_vars.inq_cmpl_info.resp_type[BTM_INQ_RESULT_EXTENDED]++; } - p_cur->inq_result_type |= BTM_INQ_RESULT_BR; + p_cur->inq_result_type |= BT_DEVICE_TYPE_BREDR; if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { p_cur->device_type = BT_DEVICE_TYPE_BREDR; p_i->scan_rsp = false; @@ -1392,21 +1726,34 @@ void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, } if (is_new || update) { - if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) { + // Create a vector of EIR data and pad it with 0 + auto data = std::vector(); + data.reserve(HCI_EXT_INQ_RESPONSE_LEN); + bluetooth::packet::BitInserter bi(data); + for (const auto& eir : extended_view.GetExtendedInquiryResponse()) { + if (eir.data_type_ != static_cast(0)) { + eir.Serialize(bi); + } + } + while (data.size() < HCI_EXT_INQ_RESPONSE_LEN) { + data.push_back(0); + } + + const uint8_t* p_eir_data = data.data(); + + { memset(p_cur->eir_uuid, 0, BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS / 8)); /* set bit map of UUID list from received EIR */ - btm_set_eir_uuid(p, p_cur); - p_eir_data = p; - } else - p_eir_data = NULL; + btm_set_eir_uuid(p_eir_data, p_cur); + } /* If a callback is registered, call it with the results */ if (p_inq_results_cb) { (p_inq_results_cb)((tBTM_INQ_RESULTS*)p_cur, p_eir_data, HCI_EXT_INQ_RESPONSE_LEN); } else { - LOG_WARN("No callback is registered for inquiry result"); + log::warn("No callback is registered for inquiry result"); } } } @@ -1467,11 +1814,12 @@ void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) { btm_cb.btm_inq_vars.inqparms.mode &= ~(mode); const auto inq_active = btm_cb.btm_inq_vars.inq_active; - btm_acl_update_inquiry_status(BTM_INQUIRY_COMPLETE); + BTIF_dm_report_inquiry_status_change( + tBTM_INQUIRY_STATE::BTM_INQUIRY_COMPLETE); if (status != HCI_SUCCESS) { - LOG_WARN("Received unexpected hci status:%s", - hci_error_code_text(status).c_str()); + log::warn("Received unexpected hci status:{}", + hci_error_code_text(status).c_str()); } /* Ignore any stray or late complete messages if the inquiry is not active */ @@ -1490,7 +1838,7 @@ void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) { btm_clr_inq_result_flt(); if ((status == HCI_SUCCESS) && - controller_get_interface()->supports_rssi_with_inquiry_results()) { + bluetooth::shim::GetController()->SupportsRssiWithInquiryResults()) { btm_sort_inq_result(); } @@ -1498,7 +1846,7 @@ void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) { (btm_cb.btm_inq_vars.p_inq_cmpl_cb)( (tBTM_INQUIRY_CMPL*)&btm_cb.btm_inq_vars.inq_cmpl_info); } else { - LOG_WARN("No callback to return inquiry result"); + log::warn("No callback to return inquiry result"); } btm_cb.neighbor.inquiry_history_->Push({ @@ -1539,12 +1887,12 @@ void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) { btm_cb.btm_inq_vars.p_inq_cmpl_cb = NULL; } else { - LOG_INFO( - "Inquiry params is not clear so not sending callback inq_parms:%u", + log::info( + "Inquiry params is not clear so not sending callback inq_parms:{}", btm_cb.btm_inq_vars.inqparms.mode); } } else { - LOG_ERROR("Received inquiry complete when no inquiry was active"); + log::error("Received inquiry complete when no inquiry was active"); } } @@ -1560,8 +1908,9 @@ void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) { * Returns void * ******************************************************************************/ -void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) { - btm_acl_update_inquiry_status(BTM_INQUIRY_CANCELLED); +static void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) { + BTIF_dm_report_inquiry_status_change( + tBTM_INQUIRY_STATE::BTM_INQUIRY_CANCELLED); btm_process_inq_complete(status, mode); } /******************************************************************************* @@ -1604,7 +1953,8 @@ tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin, /* If the database entry exists for the device, use its clock offset */ tINQ_DB_ENT* p_i = btm_inq_db_find(remote_bda); - if (p_i && (p_i->inq_info.results.inq_result_type & BTM_INQ_RESULT_BR)) { + if (p_i && + (p_i->inq_info.results.inq_result_type & BT_DEVICE_TYPE_BREDR)) { tBTM_INQ_INFO* p_cur = &p_i->inq_info; uint16_t clock_offset = p_cur->results.clock_offset | BTM_CLOCK_OFFSET_VALID; int clock_offset_in_cfg = 0; @@ -1661,10 +2011,11 @@ void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn, rem_name.bd_addr = RawAddress::kEmpty; } - LOG_INFO("btm_process_remote_name for %s", - ADDRESS_TO_LOGGABLE_CSTR(rem_name.bd_addr)); + log::info("btm_process_remote_name for {}", + ADDRESS_TO_LOGGABLE_CSTR(rem_name.bd_addr)); - VLOG(2) << "Inquire BDA " << btm_cb.btm_inq_vars.remname_bda; + log::verbose("Inquire BDA {}", + ADDRESS_TO_LOGGABLE_CSTR(btm_cb.btm_inq_vars.remname_bda)); /* If the inquire BDA and remote DBA are the same, then stop the timer and set * the active to false */ @@ -1728,7 +2079,7 @@ void btm_inq_remote_name_timer_timeout(UNUSED_ATTR void* data) { * ******************************************************************************/ void btm_inq_rmt_name_failed_cancelled(void) { - LOG_ERROR("remname_active=%d", btm_cb.btm_inq_vars.remname_active); + log::error("remname_active={}", btm_cb.btm_inq_vars.remname_active); if (btm_cb.btm_inq_vars.remname_active) { btm_process_remote_name(&btm_cb.btm_inq_vars.remname_bda, NULL, 0, @@ -1752,8 +2103,8 @@ void btm_inq_rmt_name_failed_cancelled(void) { * ******************************************************************************/ tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff) { - if (controller_get_interface()->supports_extended_inquiry_response()) { - LOG_VERBOSE("Write Extended Inquiry Response to controller"); + if (bluetooth::shim::GetController()->SupportsExtendedInquiryResponse()) { + log::verbose("Write Extended Inquiry Response to controller"); btsnd_hcic_write_ext_inquiry_response(p_buff, BTM_EIR_DEFAULT_FEC_REQUIRED); return BTM_SUCCESS; } else { @@ -1929,22 +2280,22 @@ uint8_t BTM_GetEirUuidList(const uint8_t* p_eir, size_t eir_len, } if (*p_num_uuid > max_num_uuid) { - LOG_WARN("number of uuid in EIR = %d, size of uuid list = %d", *p_num_uuid, - max_num_uuid); + log::warn("number of uuid in EIR = {}, size of uuid list = {}", *p_num_uuid, + max_num_uuid); *p_num_uuid = max_num_uuid; } - LOG_VERBOSE("type = %02X, number of uuid = %d", type, *p_num_uuid); + log::verbose("type = {:02X}, number of uuid = {}", type, *p_num_uuid); if (uuid_size == Uuid::kNumBytes16) { for (yy = 0; yy < *p_num_uuid; yy++) { STREAM_TO_UINT16(*(p_uuid16 + yy), p_uuid_data); - LOG_VERBOSE(" 0x%04X", *(p_uuid16 + yy)); + log::verbose(" 0x{:04X}", *(p_uuid16 + yy)); } } else if (uuid_size == Uuid::kNumBytes32) { for (yy = 0; yy < *p_num_uuid; yy++) { STREAM_TO_UINT32(*(p_uuid32 + yy), p_uuid_data); - LOG_VERBOSE(" 0x%08X", *(p_uuid32 + yy)); + log::verbose(" 0x{:08X}", *(p_uuid32 + yy)); } } else if (uuid_size == Uuid::kNumBytes128) { for (yy = 0; yy < *p_num_uuid; yy++) { @@ -1952,7 +2303,7 @@ uint8_t BTM_GetEirUuidList(const uint8_t* p_eir, size_t eir_len, for (xx = 0; xx < Uuid::kNumBytes128; xx++) snprintf(buff + xx * 2, sizeof(buff) - xx * 2, "%02X", *(p_uuid_list + yy * Uuid::kNumBytes128 + xx)); - LOG_VERBOSE(" 0x%s", buff); + log::verbose(" 0x{}", buff); } } @@ -2065,7 +2416,7 @@ static uint16_t btm_convert_uuid_to_uuid16(const uint8_t* p_uuid, } break; default: - LOG_WARN("btm_convert_uuid_to_uuid16 invalid uuid size"); + log::warn("btm_convert_uuid_to_uuid16 invalid uuid size"); break; } @@ -2101,7 +2452,7 @@ void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) { p_results->eir_complete_list = false; } - LOG_VERBOSE("eir_complete_list=0x%02X", p_results->eir_complete_list); + log::verbose("eir_complete_list=0x{:02X}", p_results->eir_complete_list); if (p_uuid_data) { for (yy = 0; yy < num_uuid; yy++) { @@ -2131,6 +2482,46 @@ void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) { } } +static void on_inquiry_complete(bluetooth::hci::EventView event) { + auto complete = bluetooth::hci::InquiryCompleteView::Create(event); + ASSERT(complete.IsValid()); + auto status = to_hci_status_code(static_cast(complete.GetStatus())); + + btm_process_inq_complete(status, BTM_BR_INQUIRY_MASK); +} +/******************************************************************************* + * + * Function on_incoming_hci_event + * + * Description This function is called to process events from the HCI layer + * + * Parameters event - an EventView with the specific event + * + * Returns None + * + ******************************************************************************/ +static void on_incoming_hci_event(bluetooth::hci::EventView event) { + ASSERT(event.IsValid()); + auto event_code = event.GetEventCode(); + switch (event_code) { + case bluetooth::hci::EventCode::INQUIRY_COMPLETE: + on_inquiry_complete(event); + break; + case bluetooth::hci::EventCode::INQUIRY_RESULT: + btm_process_inq_results_standard(event); + break; + case bluetooth::hci::EventCode::INQUIRY_RESULT_WITH_RSSI: + btm_process_inq_results_rssi(event); + break; + case bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT: + btm_process_inq_results_extended(event); + break; + default: + log::warn("Dropping unhandled event: {}", + bluetooth::hci::EventCodeText(event_code)); + } +} + namespace bluetooth { namespace legacy { namespace testing { diff --git a/system/stack/btm/btm_int_types.h b/system/stack/btm/btm_int_types.h index b3a99b75dbc268bd13c5e64d72b682e037de4f10..cb165def2b543742d5e3b068cf09c4fde84a2ca9 100644 --- a/system/stack/btm/btm_int_types.h +++ b/system/stack/btm/btm_int_types.h @@ -24,7 +24,7 @@ #include #include -#include "gd/common/circular_buffer.h" +#include "common/circular_buffer.h" #include "internal_include/bt_target.h" #include "osi/include/fixed_queue.h" #include "stack/acl/acl.h" @@ -157,7 +157,6 @@ typedef struct tBTM_CB { uint16_t disc_handle{0}; /* for legacy devices */ uint8_t disc_reason{0}; /* for legacy devices */ - bool is_inquiry{false}; /* true, if inquiry is in progess */ fixed_queue_t* sec_pending_q{nullptr}; /* pending sequrity requests in tBTM_SEC_QUEUE_ENTRY format */ diff --git a/system/stack/btm/btm_iot_config.cc b/system/stack/btm/btm_iot_config.cc index de64ba090a17a31a16ebf1135cc6cf2d6fd4635b..c6ea9d8e4eee807a781d5b7c31e64b0f5579942a 100644 --- a/system/stack/btm/btm_iot_config.cc +++ b/system/stack/btm/btm_iot_config.cc @@ -18,13 +18,16 @@ #define LOG_TAG "btm_iot" -#include "bt_target.h" +#include + #include "btif/include/btif_storage.h" -#include "btif/include/btif_util.h" #include "btm_ble_api.h" -#include "btm_int_types.h" #include "device/include/device_iot_config.h" -#include "osi/include/log.h" +#include "internal_include/bt_target.h" +#include "os/log.h" +#include "stack/acl/acl.h" + +using namespace bluetooth; /******************************************************************************* * @@ -54,9 +57,9 @@ void btm_iot_save_remote_properties(tACL_CONN* p_acl_cb) { sizeof(cod), &cod); if (btif_storage_get_remote_device_property(&p_acl_cb->remote_addr, &prop_name) == BT_STATUS_SUCCESS) - LOG_VERBOSE("%s cod retrieved from storage is 0x%06x", __func__, cod); + log::verbose("cod retrieved from storage is 0x{:06x}", cod); if (cod == 0) { - LOG_VERBOSE("%s cod is 0, set as unclassified", __func__); + log::verbose("cod is 0, set as unclassified"); cod = (0x1F) << 8; } diff --git a/system/stack/btm/btm_iso_impl.h b/system/stack/btm/btm_iso_impl.h index 2bbc3fffb31cdc671c55da4093edd41650d1ac6a..8687e770754e3d70c3a3d5b04e342a2e1ddb5866 100644 --- a/system/stack/btm/btm_iso_impl.h +++ b/system/stack/btm/btm_iso_impl.h @@ -30,6 +30,7 @@ #include "common/time_util.h" #include "device/include/controller.h" #include "hci/include/hci_layer.h" +#include "internal_include/bt_trace.h" #include "internal_include/stack_config.h" #include "main/shim/hci_layer.h" #include "os/log.h" @@ -93,11 +94,11 @@ struct iso_impl { iso_impl() { iso_credits_ = controller_get_interface()->get_iso_buffer_count(); iso_buffer_size_ = controller_get_interface()->get_iso_data_size(); - LOG_INFO("%p created, iso credits: %d, buffer size: %d.", this, - iso_credits_.load(), iso_buffer_size_); + log::info("{} created, iso credits: {}, buffer size: {}.", fmt::ptr(this), + iso_credits_.load(), iso_buffer_size_); } - ~iso_impl() { LOG_INFO("%p removed.", this); } + ~iso_impl() { log::info("{} removed.", fmt::ptr(this)); } void handle_register_cis_callbacks(CigCallbacks* callbacks) { LOG_ASSERT(callbacks != nullptr) << "Invalid CIG callbacks"; @@ -252,7 +253,7 @@ struct iso_impl { if (!force) { LOG_ASSERT(IsCigKnown(cig_id)) << "No such cig: " << +cig_id; } else { - LOG_WARN("Forcing to remove CIG %d", cig_id); + log::warn("Forcing to remove CIG {}", cig_id); } btsnd_hcic_remove_cig(cig_id, base::BindOnce(&iso_impl::on_remove_cig, @@ -346,7 +347,7 @@ struct iso_impl { if (iso == nullptr) { /* That can happen when ACL has been disconnected while ISO patch was * creating */ - LOG(WARNING) << __func__ << "Invalid connection handle: " << +conn_handle; + log::warn("Invalid connection handle: {}", +conn_handle); return; } @@ -397,7 +398,7 @@ struct iso_impl { uint16_t conn_handle; if (len < 3) { - LOG(WARNING) << __func__ << "Malformatted packet received"; + log::warn("Malformatted packet received"); return; } STREAM_TO_UINT8(status, stream); @@ -407,7 +408,7 @@ struct iso_impl { if (iso == nullptr) { /* That could happen when ACL has been disconnected while removing data * path */ - LOG(WARNING) << __func__ << "Invalid connection handle: " << +conn_handle; + log::warn("Invalid connection handle: {}", +conn_handle); return; } @@ -459,14 +460,13 @@ struct iso_impl { // 1 + 2 + 4 * 7 #define ISO_LINK_QUALITY_SIZE 31 if (len < ISO_LINK_QUALITY_SIZE) { - LOG(ERROR) << "Malformated link quality format, len=" << len; + log::error("Malformated link quality format, len={}", len); return; } STREAM_TO_UINT8(status, stream); if (status != HCI_SUCCESS) { - LOG(ERROR) << "Failed to Read ISO Link Quality, status: " - << loghex(status); + log::error("Failed to Read ISO Link Quality, status: {}", loghex(status)); return; } @@ -476,7 +476,7 @@ struct iso_impl { if (iso == nullptr) { /* That could happen when ACL has been disconnected while waiting on the * read respose */ - LOG(WARNING) << __func__ << "Invalid connection handle: " << +conn_handle; + log::warn("Invalid connection handle: {}", +conn_handle); return; } @@ -498,7 +498,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: " << loghex(iso_handle); + log::error("No such iso connection: {}", loghex(iso_handle)); return; } @@ -538,14 +538,13 @@ struct iso_impl { if (!(iso->state_flags & kStateFlagIsBroadcast)) { if (!(iso->state_flags & kStateFlagIsConnected)) { - LOG(WARNING) << __func__ << "Cis handle: " << loghex(iso_handle) - << " not established"; + log::warn("Cis handle: {} not established", loghex(iso_handle)); return; } } if (!(iso->state_flags & kStateFlagHasDataPathSet)) { - LOG_WARN("Data path not set for handle: 0x%04x", iso_handle); + log::warn("Data path not set for handle: 0x{:04x}", iso_handle); return; } @@ -561,10 +560,10 @@ struct iso_impl { iso->cr_stats.credits_last_underflow_us = bluetooth::common::time_get_os_boottime_us(); - LOG(WARNING) << __func__ << ", dropping ISO packet, len: " - << static_cast(data_len) - << ", iso credits: " << static_cast(iso_credits_) - << ", iso handle: " << loghex(iso_handle); + log::warn( + ", dropping ISO packet, len: {}, iso credits: {}, iso handle: {}", + static_cast(data_len), static_cast(iso_credits_), + loghex(iso_handle)); return; } @@ -575,7 +574,7 @@ struct iso_impl { memcpy(packet->data + kIsoHeaderWithoutTsLen, data, data_len); auto hci = bluetooth::shim::hci_layer_get_interface(); packet->event = MSG_STACK_TO_HC_HCI_ISO | 0x0001; - hci->transmit_downward(packet->event, packet); + hci->transmit_downward(packet, iso_buffer_size_); } void process_cis_est_pkt(uint8_t len, uint8_t* data) { @@ -630,7 +629,7 @@ struct iso_impl { LOG_ASSERT(cig_callbacks_ != nullptr) << "Invalid CIG callbacks"; - LOG_INFO("%s flags: %d", __func__, +cis->state_flags); + log::info("flags: {}", +cis->state_flags); BTM_LogHistory( kBtmLogTag, cis_hdl_to_addr[handle], "CIS disconnected", @@ -731,7 +730,7 @@ struct iso_impl { uint16_t conn_handle; STREAM_TO_UINT16(conn_handle, data); evt.conn_handles.push_back(conn_handle); - LOG_INFO(" received BIS conn_hdl %d", +conn_handle); + log::info(" received BIS conn_hdl {}", +conn_handle); if (evt.status == HCI_SUCCESS) { auto bis = std::unique_ptr(new iso_bis()); @@ -792,7 +791,7 @@ struct iso_impl { << "Invalid big - already exists: " << +big_id; if (stack_config_get_interface()->get_pts_unencrypt_broadcast()) { - LOG_INFO("Force create broadcst without encryption for PTS test"); + log::info("Force create broadcst without encryption for PTS test"); big_params.enc = 0; big_params.enc_code = {0}; } @@ -832,7 +831,7 @@ struct iso_impl { /* Not supported */ break; default: - LOG_ERROR("Unhandled event code %d", +code); + log::error("Unhandled event code {}", +code); } } @@ -853,7 +852,7 @@ struct iso_impl { iso_base* iso = GetCisIfKnown(evt.cis_conn_hdl); if (iso == nullptr) { - LOG(ERROR) << __func__ << ", received data for the non-registered CIS!"; + log::error(", received data for the non-registered CIS!"); return; } @@ -875,7 +874,7 @@ struct iso_impl { iso->evt_stats.evt_last_lost_us = bluetooth::common::time_get_os_boottime_us(); - LOG(WARNING) << evt.evt_lost << " packets lost."; + log::warn("{} packets lost.", evt.evt_lost); iso->evt_stats.seq_nb_mismatch_count++; } diff --git a/system/stack/btm/btm_main.cc b/system/stack/btm/btm_main.cc index a1f72526af681b45f9e19c72415d1c6bcee0817e..1439dd5e983c63049e7d1ca823d21b5d7f0e72a7 100644 --- a/system/stack/btm/btm_main.cc +++ b/system/stack/btm/btm_main.cc @@ -22,19 +22,23 @@ * ******************************************************************************/ +#include + #include #include -#include "bt_target.h" #include "btm_int_types.h" -#include "btm_sec_cb.h" -#include "main/shim/dumpsys.h" -#include "osi/include/log.h" -#include "stack/include/btm_client_interface.h" -#include "stack/include/inq_hci_link_interface.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "stack/include/security_client_callbacks.h" #include "types/raw_address.h" +#ifdef TARGET_FLOSS +#include "stack/include/inq_hci_link_interface.h" // btm_inq_db_set_inq_by_rssi +#endif // TARGET_FLOSS + +using namespace bluetooth; + /* Global BTM control block structure */ tBTM_CB btm_cb; @@ -74,7 +78,8 @@ constexpr size_t kMaxLogHistoryMsgLength = 25; static void btm_log_history(const std::string& tag, const char* addr, const std::string& msg, const std::string& extra) { if (btm_cb.history_ == nullptr) { - LOG_ERROR("BTM_LogHistory has not been constructed or already destroyed !"); + log::error( + "BTM_LogHistory has not been constructed or already destroyed !"); return; } diff --git a/system/stack/btm/btm_sco.cc b/system/stack/btm/btm_sco.cc index 0e88190f66afeb10056436dba8c0dad6fc8949b4..a0dca7b81889d5dff4aca5fb28142816a34f7376 100644 --- a/system/stack/btm/btm_sco.cc +++ b/system/stack/btm/btm_sco.cc @@ -29,25 +29,31 @@ #include #include +#include #include #include #include +#include #include "common/bidi_queue.h" #include "device/include/controller.h" #include "device/include/device_iot_config.h" -#include "gd/hci/hci_layer.h" +#include "hci/class_of_device.h" +#include "hci/controller_interface.h" +#include "hci/hci_layer.h" #include "hci/hci_packets.h" #include "hci/include/hci_layer.h" #include "internal_include/bt_target.h" #include "main/shim/entry.h" +#include "main/shim/helpers.h" #include "osi/include/properties.h" #include "osi/include/stack_power_telemetry.h" #include "stack/btm/btm_int_types.h" #include "stack/btm/btm_sco_hfp_hal.h" #include "stack/btm/btm_sec.h" #include "stack/include/acl_api.h" +#include "stack/include/bt_dev_class.h" #include "stack/include/btm_api.h" #include "stack/include/btm_api_types.h" #include "stack/include/btm_log_history.h" @@ -56,7 +62,6 @@ #include "stack/include/main_thread.h" #include "stack/include/sdpdefs.h" #include "stack/include/stack_metrics_logging.h" -#include "types/class_of_device.h" #include "types/raw_address.h" extern tBTM_CB btm_cb; @@ -83,10 +88,15 @@ constexpr char kBtmLogTag[] = "SCO"; }; // namespace +using namespace bluetooth; using bluetooth::legacy::hci::GetInterface; // forward declaration for dequeueing packets static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet); +void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class, + uint8_t link_type); +void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason); +bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason); namespace cpp { bluetooth::common::BidiQueueEndTryDequeue(); ASSERT(packet != nullptr); if (!packet->IsValid()) { - LOG_INFO("Dropping invalid packet of size %zu", packet->size()); + log::info("Dropping invalid packet of size {}", packet->size()); return; } if (do_in_main_thread(FROM_HERE, base::Bind(&btm_route_sco_data, *packet)) != BT_STATUS_SUCCESS) { - LOG_ERROR("do_in_main_thread failed from sco_data_callback"); + log::error("do_in_main_thread failed from sco_data_callback"); } } static void register_for_sco() { @@ -118,6 +128,30 @@ static void register_for_sco() { pending_sco_data = new bluetooth::os::EnqueueBuffer( hci_sco_queue_end); + + // Register SCO for connection requests + bluetooth::shim::GetHciLayer()->RegisterForScoConnectionRequests( + get_main_thread()->Bind( + [](bluetooth::hci::Address peer, bluetooth::hci::ClassOfDevice cod, + bluetooth::hci::ConnectionRequestLinkType link_type) { + auto peer_raw_address = bluetooth::ToRawAddress(peer); + DEV_CLASS dev_class{cod.cod[0], cod.cod[1], cod.cod[2]}; + if (link_type == bluetooth::hci::ConnectionRequestLinkType::ESCO) { + btm_sco_conn_req(peer_raw_address, dev_class, + android::bluetooth::LINK_TYPE_ESCO); + } else { + btm_sco_conn_req(peer_raw_address, dev_class, + android::bluetooth::LINK_TYPE_SCO); + } + })); + // Register SCO for disconnect notifications + bluetooth::shim::GetHciLayer()->RegisterForDisconnects( + get_main_thread()->Bind( + [](uint16_t handle, bluetooth::hci::ErrorCode error_code) { + auto reason = static_cast(error_code); + btm_sco_on_disconnected(handle, reason); + btm_sco_removed(handle, reason); + })); } static void shut_down_sco() { @@ -238,10 +272,10 @@ static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status, ->supports_enhanced_setup_synchronous_connection() && !osi_property_get_bool(kPropertyDisableEnhancedConnection, kDefaultDisableEnhancedConnection)) { - LOG_VERBOSE( - "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, " - "pkt 0x%04x, path %u", - __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth, + log::verbose( + "txbw 0x{:x}, rxbw 0x{:x}, lat 0x{:x}, retrans 0x{:02x}, pkt " + "0x{:04x}, path {}", + p_setup->transmit_bandwidth, p_setup->receive_bandwidth, p_setup->max_latency_ms, p_setup->retransmission_effort, p_setup->packet_types, p_setup->input_data_path); @@ -286,19 +320,19 @@ static tSCO_CONN* btm_get_active_sco() { static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet) { uint16_t handle = valid_packet.GetHandle(); if (handle > HCI_HANDLE_MAX) { - LOG_ERROR("Dropping SCO data with invalid handle: 0x%X > 0x%X, ", handle, - HCI_HANDLE_MAX); + log::error("Dropping SCO data with invalid handle: 0x{:X} > 0x{:X}, ", + handle, HCI_HANDLE_MAX); return; } tSCO_CONN* active_sco = btm_get_active_sco(); if (active_sco == nullptr) { - LOG_ERROR("Received SCO data when there is no active SCO connection"); + log::error("Received SCO data when there is no active SCO connection"); return; } if (active_sco->hci_handle != handle) { - LOG_ERROR("Dropping packet with handle(0x%X) != active handle(0x%X)", - handle, active_sco->hci_handle); + log::error("Dropping packet with handle(0x{:X}) != active handle(0x{:X})", + handle, active_sco->hci_handle); return; } @@ -313,15 +347,15 @@ static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet) { auto status = valid_packet.GetPacketStatusFlag(); if (status != bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED) { - LOG_DEBUG("%s packet corrupted with status(%s)", codec.c_str(), - PacketStatusFlagText(status).c_str()); + log::debug("{} packet corrupted with status({})", codec.c_str(), + PacketStatusFlagText(status).c_str()); } auto enqueue_packet = codec_type == BTM_SCO_CODEC_LC3 ? &bluetooth::audio::sco::swb::enqueue_packet : &bluetooth::audio::sco::wbs::enqueue_packet; rc = enqueue_packet( data, status != bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED); - if (!rc) LOG_DEBUG("Failed to enqueue %s packet", codec.c_str()); + if (!rc) log::debug("Failed to enqueue {} packet", codec.c_str()); while (rc) { auto decode = codec_type == BTM_SCO_CODEC_LC3 @@ -355,9 +389,9 @@ static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet) { (unsigned long)(BTM_SCO_DATA_SIZE_MAX - btm_pcm_buf_write_offset)); - LOG_INFO( - "Requested to read %lu bytes of %s data but got %lu bytes of " - "PCM data from audio server: WriteOffset:%lu ReadOffset:%lu", + log::info( + "Requested to read {} bytes of {} data but got {} bytes of PCM " + "data from audio server: WriteOffset:{} ReadOffset:{}", (unsigned long)to_read, codec.c_str(), (unsigned long)read, (unsigned long)btm_pcm_buf_write_offset, (unsigned long)btm_pcm_buf_read_offset); @@ -368,8 +402,8 @@ static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet) { } else { /* We don't break here so that we can still decode the data in the * buffer to spare the buffer space when the buffer is full */ - LOG_WARN( - "Buffer is full when we try to read %s packet from audio server", + log::warn( + "Buffer is full when we try to read {} packet from audio server", codec.c_str()); ASSERT_LOG(btm_pcm_buf_write_offset - btm_pcm_buf_read_offset >= (codec_type == BTM_SCO_CODEC_MSBC ? BTM_MSBC_CODE_SIZE @@ -391,9 +425,9 @@ static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet) { btm_pcm_buf_write_offset - btm_pcm_buf_read_offset); if (!rc) - LOG_DEBUG( - "Failed to encode %s data starting at ReadOffset:%lu to " - "WriteOffset:%lu", + log::debug( + "Failed to encode {} data starting at ReadOffset:{} to " + "WriteOffset:{}", codec.c_str(), (unsigned long)btm_pcm_buf_read_offset, (unsigned long)btm_pcm_buf_write_offset); @@ -424,10 +458,10 @@ static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet) { (uint8_t*)btm_pcm_buf, written < BTM_SCO_DATA_SIZE_MAX ? written : BTM_SCO_DATA_SIZE_MAX); if (read == 0) { - LOG_INFO("Failed to read %lu bytes of PCM data from audio server", - (unsigned long)(written < BTM_SCO_DATA_SIZE_MAX - ? written - : BTM_SCO_DATA_SIZE_MAX)); + log::info("Failed to read {} bytes of PCM data from audio server", + (unsigned long)(written < BTM_SCO_DATA_SIZE_MAX + ? written + : BTM_SCO_DATA_SIZE_MAX)); break; } written -= read; @@ -478,8 +512,7 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, enh_esco_params_t* p_setup) { /* Send connect request depending on version of spec */ if (!btm_cb.sco_cb.esco_supported) { - LOG(INFO) << __func__ << ": sending non-eSCO request for handle=" - << unsigned(acl_handle); + log::info("sending non-eSCO request for handle={}", unsigned(acl_handle)); btsnd_hcic_add_SCO_conn(acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types)); } else { /* Save the previous values in case command fails */ @@ -502,17 +535,17 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, const RawAddress bd_addr = acl_address_from_handle(acl_handle); if (bd_addr != RawAddress::kEmpty) { if (!btm_peer_supports_esco_2m_phy(bd_addr)) { - LOG_VERBOSE("BTM Remote does not support 2-EDR eSCO"); + log::verbose("BTM Remote does not support 2-EDR eSCO"); temp_packet_types |= (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5); } if (!btm_peer_supports_esco_3m_phy(bd_addr)) { - LOG_VERBOSE("BTM Remote does not support 3-EDR eSCO"); + log::verbose("BTM Remote does not support 3-EDR eSCO"); temp_packet_types |= (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV5); } if (!btm_peer_supports_esco_ev3(bd_addr)) { - LOG_VERBOSE("BTM Remote does not support EV3 eSCO"); + log::verbose("BTM Remote does not support EV3 eSCO"); // If EV3 is not supported, EV4 and EV% are not supported, either. temp_packet_types &= ~BTM_ESCO_LINK_ONLY_MASK; p_setup->retransmission_effort = ESCO_RETRANSMISSION_OFF; @@ -523,43 +556,43 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, ** If so, we cannot use SCO-only packet types (HFP 1.7) */ const bool local_supports_sc = - controller_get_interface()->supports_secure_connections(); + bluetooth::shim::GetController()->SupportsSecureConnections(); const bool remote_supports_sc = BTM_PeerSupportsSecureConnections(bd_addr); if (local_supports_sc && remote_supports_sc) { temp_packet_types &= ~(BTM_SCO_PKT_TYPE_MASK); if (temp_packet_types == 0) { - LOG_ERROR( + log::error( "SCO connection cannot support any packet types for " - "acl_handle:0x%04x", + "acl_handle:0x{:04x}", acl_handle); return BTM_WRONG_MODE; } - LOG_DEBUG( + log::debug( "Both local and remote controllers support SCO secure connections " - "handle:0x%04x pkt_types:0x%04x", + "handle:0x{:04x} pkt_types:0x{:04x}", acl_handle, temp_packet_types); } else if (!local_supports_sc && !remote_supports_sc) { - LOG_DEBUG( + log::debug( "Both local and remote controllers do not support secure " - "connections for handle:0x%04x", + "connections for handle:0x{:04x}", acl_handle); } else if (remote_supports_sc) { - LOG_DEBUG( + log::debug( "Only remote controller supports secure connections for " - "handle:0x%04x", + "handle:0x{:04x}", acl_handle); } else { - LOG_DEBUG( + log::debug( "Only local controller supports secure connections for " - "handle:0x%04x", + "handle:0x{:04x}", acl_handle); } } else { - LOG_ERROR("Received SCO connect from unknown peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("Received SCO connect from unknown peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } p_setup->packet_types = temp_packet_types; @@ -569,31 +602,32 @@ static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle, ->supports_enhanced_setup_synchronous_connection() && !osi_property_get_bool(kPropertyDisableEnhancedConnection, kDefaultDisableEnhancedConnection)) { - LOG_INFO("Sending enhanced SCO connect request over handle:0x%04x", - acl_handle); - LOG(INFO) << __func__ << std::hex << ": enhanced parameter list" - << " txbw=0x" << unsigned(p_setup->transmit_bandwidth) - << ", rxbw=0x" << unsigned(p_setup->receive_bandwidth) - << ", latency_ms=0x" << unsigned(p_setup->max_latency_ms) - << ", retransmit_effort=0x" - << unsigned(p_setup->retransmission_effort) << ", pkt_type=0x" - << unsigned(p_setup->packet_types) << ", path=0x" - << unsigned(p_setup->input_data_path); + log::info("Sending enhanced SCO connect request over handle:0x{:04x}", + acl_handle); + log::info( + "enhanced parameter list txbw=0x{:x}, rxbw=0x{}, latency_ms=0x{}, " + "retransmit_effort=0x{}, pkt_type=0x{}, path=0x{}", + unsigned(p_setup->transmit_bandwidth), + unsigned(p_setup->receive_bandwidth), + unsigned(p_setup->max_latency_ms), + unsigned(p_setup->retransmission_effort), + unsigned(p_setup->packet_types), unsigned(p_setup->input_data_path)); btsnd_hcic_enhanced_set_up_synchronous_connection(acl_handle, p_setup); p_setup->packet_types = saved_packet_types; p_setup->retransmission_effort = saved_retransmission_effort; p_setup->max_latency_ms = saved_max_latency_ms; } else { /* Use older command */ - LOG_INFO("Sending eSCO connect request over handle:0x%04x", acl_handle); + log::info("Sending eSCO connect request over handle:0x{:04x}", + acl_handle); uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup); - LOG(INFO) << __func__ << std::hex << ": legacy parameter list" - << " txbw=0x" << unsigned(p_setup->transmit_bandwidth) - << ", rxbw=0x" << unsigned(p_setup->receive_bandwidth) - << ", latency_ms=0x" << unsigned(p_setup->max_latency_ms) - << ", retransmit_effort=0x" - << unsigned(p_setup->retransmission_effort) - << ", voice_content_format=0x" << unsigned(voice_content_format) - << ", pkt_type=0x" << unsigned(p_setup->packet_types); + log::info( + "legacy parameter list txbw=0x{:x}, rxbw=0x{}, latency_ms=0x{}, " + "retransmit_effort=0x{}, voice_content_format=0x{}, pkt_type=0x{}", + unsigned(p_setup->transmit_bandwidth), + unsigned(p_setup->receive_bandwidth), + unsigned(p_setup->max_latency_ms), + unsigned(p_setup->retransmission_effort), + unsigned(voice_content_format), unsigned(p_setup->packet_types)); btsnd_hcic_setup_esco_conn( acl_handle, p_setup->transmit_bandwidth, p_setup->receive_bandwidth, p_setup->max_latency_ms, voice_content_format, @@ -641,13 +675,13 @@ tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig, if (is_orig) { if (!remote_bda) { - LOG(ERROR) << __func__ << ": remote_bda is null"; + log::error("remote_bda is null"); return BTM_ILLEGAL_VALUE; } acl_handle = BTM_GetHCIConnHandle(*remote_bda, BT_TRANSPORT_BR_EDR); if (acl_handle == HCI_INVALID_HANDLE) { - LOG(ERROR) << __func__ << ": cannot find ACL handle for remote device " - << remote_bda; + log::error("cannot find ACL handle for remote device {}", + ADDRESS_TO_LOGGABLE_STR(*remote_bda)); return BTM_UNKNOWN_ADDR; } } @@ -658,8 +692,8 @@ tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig, if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) || (p->state == SCO_ST_PEND_UNPARK)) && (p->esco.data.bd_addr == *remote_bda)) { - LOG(ERROR) << __func__ << ": a sco connection is already going on for " - << *remote_bda << ", at state " << unsigned(p->state); + log::error("a sco connection is already going on for {}, at state {}", + ADDRESS_TO_LOGGABLE_STR(*remote_bda), unsigned(p->state)); return BTM_BUSY; } } @@ -667,9 +701,8 @@ tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig, /* Support only 1 wildcard BD address at a time */ for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) { - LOG(ERROR) - << __func__ - << ": remote_bda is null and not known and we are still listening"; + log::error( + "remote_bda is null and not known and we are still listening"); return BTM_BUSY; } } @@ -686,17 +719,16 @@ tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig, if (BTM_ReadPowerMode(*remote_bda, &state)) { if (state == BTM_PM_ST_SNIFF || state == BTM_PM_ST_PARK || state == BTM_PM_ST_PENDING) { - LOG(INFO) << __func__ << ": " << *remote_bda - << " in sniff, park or pending mode " - << unsigned(state); + log::info("{} in sniff, park or pending mode {}", + ADDRESS_TO_LOGGABLE_STR(*remote_bda), unsigned(state)); if (!BTM_SetLinkPolicyActiveMode(*remote_bda)) { - LOG_WARN("Unable to set link policy active"); + log::warn("Unable to set link policy active"); } p->state = SCO_ST_PEND_UNPARK; } } else { - LOG(ERROR) << __func__ << ": failed to read power mode for " - << *remote_bda; + log::error("failed to read power mode for {}", + ADDRESS_TO_LOGGABLE_STR(*remote_bda)); } } p->esco.data.bd_addr = *remote_bda; @@ -728,8 +760,8 @@ tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig, /* If role change is in progress, do not proceed with SCO setup * Wait till role change is complete */ if (!acl_is_switch_role_idle(*remote_bda, BT_TRANSPORT_BR_EDR)) { - LOG_VERBOSE("Role Change is in progress for ACL handle 0x%04x", - acl_handle); + log::verbose("Role Change is in progress for ACL handle 0x{:04x}", + acl_handle); p->state = SCO_ST_PEND_ROLECHANGE; } } @@ -738,24 +770,25 @@ tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig, if (p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE) { if (is_orig) { - LOG_DEBUG("Initiating (e)SCO link for ACL handle:0x%04x", acl_handle); + log::debug("Initiating (e)SCO link for ACL handle:0x{:04x}", + acl_handle); if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED) { - LOG(ERROR) << __func__ << ": failed to send connect request for " - << *remote_bda; + log::error("failed to send connect request for {}", + ADDRESS_TO_LOGGABLE_STR(*remote_bda)); return (BTM_NO_RESOURCES); } p->state = SCO_ST_CONNECTING; } else { - LOG_DEBUG("Listening for (e)SCO on ACL handle:0x%04x", acl_handle); + log::debug("Listening for (e)SCO on ACL handle:0x{:04x}", acl_handle); p->state = SCO_ST_LISTENING; } } *p_sco_inx = xx; - LOG_DEBUG("SCO connection successfully requested"); + log::debug("SCO connection successfully requested"); if (p->state == SCO_ST_CONNECTING) { BTM_LogHistory( kBtmLogTag, *remote_bda, "Connecting", @@ -766,7 +799,7 @@ tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig, } /* If here, all SCO blocks in use */ - LOG(ERROR) << __func__ << ": all SCO control blocks are in use"; + log::error("all SCO control blocks are in use"); return BTM_NO_RESOURCES; } @@ -787,16 +820,17 @@ void btm_sco_chk_pend_unpark(tHCI_STATUS hci_status, uint16_t hci_handle) { uint16_t acl_handle = BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR); if ((p->state == SCO_ST_PEND_UNPARK) && (acl_handle == hci_handle)) { - LOG(INFO) << __func__ << ": " << p->esco.data.bd_addr - << " unparked, sending connection request, acl_handle=" - << unsigned(acl_handle) - << ", hci_status=" << unsigned(hci_status); + log::info( + "{} unparked, sending connection request, acl_handle={}, " + "hci_status={}", + ADDRESS_TO_LOGGABLE_STR(p->esco.data.bd_addr), unsigned(acl_handle), + unsigned(hci_status)); if (btm_send_connect_request(acl_handle, &p->esco.setup) == BTM_CMD_STARTED) { p->state = SCO_ST_CONNECTING; } else { - LOG(ERROR) << __func__ << ": failed to send connection request for " - << p->esco.data.bd_addr; + log::error("failed to send connection request for {}", + ADDRESS_TO_LOGGABLE_STR(p->esco.data.bd_addr)); } } } @@ -824,8 +858,8 @@ void btm_sco_chk_pend_rolechange(uint16_t hci_handle) { p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle)) { - LOG_VERBOSE( - "btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", + log::verbose( + "btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x{:04x}", acl_handle); if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == @@ -849,9 +883,9 @@ void btm_sco_chk_pend_rolechange(uint16_t hci_handle) { void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle) { tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0]; - LOG_DEBUG( - "Checking for SCO pending mode change events hci_handle:0x%04x " - "p->state:%s", + log::debug( + "Checking for SCO pending mode change events hci_handle:0x{:04x} " + "p->state:{}", hci_handle, sco_state_text(p->state).c_str()); for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { @@ -860,7 +894,7 @@ void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle) { hci_handle) { - LOG_DEBUG("Removing SCO Link handle 0x%04x", p->hci_handle); + log::debug("Removing SCO Link handle 0x{:04x}", p->hci_handle); BTM_RemoveSco(xx); } } @@ -921,7 +955,7 @@ void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class, } else { /* Notify upper layer of connect indication */ evt_data.bd_addr = bda; - memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN); + evt_data.dev_class = dev_class; evt_data.link_type = link_type; evt_data.sco_inx = sco_index; tBTM_ESCO_EVT_DATA btm_esco_evt_data = {}; @@ -934,7 +968,7 @@ void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class, } /* If here, no one wants the SCO connection. Reject it */ - LOG_WARN("%s: rejecting SCO for %s", __func__, ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::warn("rejecting SCO for {}", ADDRESS_TO_LOGGABLE_CSTR(bda)); btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, nullptr); } @@ -975,8 +1009,8 @@ void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle, BTM_LogHistory(kBtmLogTag, bda, "Connection success", base::StringPrintf("handle:0x%04x %s", hci_handle, (spt) ? "listener" : "initiator")); - LOG_DEBUG("Connected SCO link handle:0x%04x peer:%s", hci_handle, - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::debug("Connected SCO link handle:0x{:04x} peer:{}", hci_handle, + ADDRESS_TO_LOGGABLE_CSTR(bda)); if (!btm_cb.sco_cb.esco_supported) { p->esco.data.link_type = BTM_LINK_TYPE_SCO; @@ -1043,8 +1077,8 @@ void btm_sco_connection_failed(tHCI_STATUS hci_status, const RawAddress& bda, (p->esco.data.bd_addr == bda || bda == RawAddress::kEmpty)) { /* Report the error if originator, otherwise remain in Listen mode */ if (p->is_orig) { - LOG_DEBUG("SCO initiating connection failed handle:0x%04x reason:%s", - hci_handle, hci_error_code_text(hci_status).c_str()); + log::debug("SCO initiating connection failed handle:0x{:04x} reason:{}", + hci_handle, hci_error_code_text(hci_status).c_str()); switch (hci_status) { case HCI_ERR_ROLE_SWITCH_PENDING: /* If role switch is pending, we need try again after role switch @@ -1066,8 +1100,9 @@ void btm_sco_connection_failed(tHCI_STATUS hci_status, const RawAddress& bda, hci_reason_code_text(static_cast(hci_status)) .c_str())); } else { - LOG_DEBUG("SCO terminating connection failed handle:0x%04x reason:%s", - hci_handle, hci_error_code_text(hci_status).c_str()); + log::debug( + "SCO terminating connection failed handle:0x{:04x} reason:{}", + hci_handle, hci_error_code_text(hci_status).c_str()); if (p->state == SCO_ST_CONNECTING) { p->state = SCO_ST_UNUSED; (*p->p_disc_cb)(xx); @@ -1102,7 +1137,7 @@ tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) { tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx]; tBTM_PM_STATE state = BTM_PM_ST_INVALID; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (BTM_MAX_SCO_LINKS == 0) { return BTM_NO_RESOURCES; @@ -1122,8 +1157,8 @@ tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) { if (BTM_ReadPowerMode(p->esco.data.bd_addr, &state) && (state == BTM_PM_ST_PENDING)) { - LOG_VERBOSE("%s: BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x%04x", - __func__, p->hci_handle); + log::verbose("BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x{:04x}", + p->hci_handle); p->state = SCO_ST_PEND_MODECHANGE; return (BTM_CMD_STARTED); } @@ -1133,8 +1168,8 @@ tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) { GetInterface().Disconnect(p->Handle(), HCI_ERR_PEER_USER); - LOG_DEBUG("Disconnecting link sco_handle:0x%04x peer:%s", p->Handle(), - ADDRESS_TO_LOGGABLE_CSTR(p->esco.data.bd_addr)); + log::debug("Disconnecting link sco_handle:0x{:04x} peer:{}", p->Handle(), + ADDRESS_TO_LOGGABLE_CSTR(p->esco.data.bd_addr)); BTM_LogHistory( kBtmLogTag, p->esco.data.bd_addr, "Disconnecting", base::StringPrintf("local initiated handle:0x%04x previous_state:%s", @@ -1185,43 +1220,29 @@ bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason) { hfp_hal_interface::esco_coding_to_codec( p->esco.setup.transmit_coding_format.coding_format)); - LOG_DEBUG("Disconnected SCO link handle:%hu reason:%s", hci_handle, - hci_reason_code_text(reason).c_str()); + log::debug("Disconnected SCO link handle:{} reason:{}", hci_handle, + hci_reason_code_text(reason).c_str()); return true; } } return false; } -void btm_sco_on_esco_connect_request( - const RawAddress& bda, const bluetooth::types::ClassOfDevice& cod) { - LOG_DEBUG("Remote ESCO connect request remote:%s cod:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda), cod.ToString().c_str()); - btm_sco_conn_req(bda, cod.cod, BTM_LINK_TYPE_ESCO); -} - -void btm_sco_on_sco_connect_request( - const RawAddress& bda, const bluetooth::types::ClassOfDevice& cod) { - LOG_DEBUG("Remote SCO connect request remote:%s cod:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda), cod.ToString().c_str()); - btm_sco_conn_req(bda, cod.cod, BTM_LINK_TYPE_SCO); -} - void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) { tSCO_CONN* p_sco = btm_cb.sco_cb.get_sco_connection_from_handle(hci_handle); if (p_sco == nullptr) { - LOG_ERROR("Unable to find sco connection"); + log::debug("Unable to find sco connection"); return; } if (!p_sco->is_active()) { - LOG_ERROR("Connection is not active handle:0x%04x reason:%s", hci_handle, + log::info("Connection is not active handle:0x{:04x} reason:{}", hci_handle, hci_reason_code_text(reason).c_str()); return; } if (p_sco->state == SCO_ST_LISTENING) { - LOG_ERROR("Connection is in listening state handle:0x%04x reason:%s", + log::info("Connection is in listening state handle:0x{:04x} reason:{}", hci_handle, hci_reason_code_text(reason).c_str()); return; } @@ -1233,8 +1254,8 @@ void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) { p_sco->rem_bd_known = false; p_sco->esco.p_esco_cback = NULL; /* Deregister eSCO callback */ (*p_sco->p_disc_cb)(btm_cb.sco_cb.get_index(p_sco)); - LOG_DEBUG("Disconnected SCO link handle:%hu reason:%s", hci_handle, - hci_reason_code_text(reason).c_str()); + log::debug("Disconnected SCO link handle:{} reason:{}", hci_handle, + hci_reason_code_text(reason).c_str()); BTM_LogHistory(kBtmLogTag, bd_addr, "Disconnected", base::StringPrintf("handle:0x%04x reason:%s", hci_handle, hci_reason_code_text(reason).c_str())); @@ -1258,12 +1279,12 @@ void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) { const std::string codec = sco_codec_type_text(codec_type); log_hfp_audio_packet_loss_stats(bd_addr, num_decoded_frames, packet_loss_ratio, codec_id); - LOG_DEBUG( - "Stopped SCO codec:%s, num_decoded_frames:%d, " - "packet_loss_ratio:%lf", + log::debug( + "Stopped SCO codec:{}, num_decoded_frames:{}, " + "packet_loss_ratio:{:f}", codec.c_str(), num_decoded_frames, packet_loss_ratio); } else { - LOG_WARN("Failed to get the packet loss stats"); + log::warn("Failed to get the packet loss stats"); } auto cleanup = codec_type == BTM_SCO_CODEC_LC3 @@ -1348,9 +1369,9 @@ tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) { if (btm_cb.sco_cb.esco_supported) { *p_def = *p_parms; - LOG_DEBUG( - "Setting eSCO mode parameters txbw:0x%08x rxbw:0x%08x max_lat:0x%04x" - " pkt:0x%04x rtx_effort:0x%02x", + log::debug( + "Setting eSCO mode parameters txbw:0x{:08x} rxbw:0x{:08x} " + "max_lat:0x{:04x} pkt:0x{:04x} rtx_effort:0x{:02x}", p_def->transmit_bandwidth, p_def->receive_bandwidth, p_def->max_latency_ms, p_def->packet_types, p_def->retransmission_effort); @@ -1358,10 +1379,10 @@ tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) { /* Load defaults for SCO only */ *p_def = esco_parameters_for_codec( SCO_CODEC_CVSD_D1, hfp_hal_interface::get_offload_enabled()); - LOG_WARN("eSCO not supported so setting SCO parameters instead"); - LOG_DEBUG( - "Setting SCO mode parameters txbw:0x%08x rxbw:0x%08x max_lat:0x%04x" - " pkt:0x%04x rtx_effort:0x%02x", + log::warn("eSCO not supported so setting SCO parameters instead"); + log::debug( + "Setting SCO mode parameters txbw:0x{:08x} rxbw:0x{:08x} " + "max_lat:0x{:04x} pkt:0x{:04x} rtx_effort:0x{:02x}", p_def->transmit_bandwidth, p_def->receive_bandwidth, p_def->max_latency_ms, p_def->packet_types, p_def->retransmission_effort); @@ -1443,11 +1464,11 @@ static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx, p_parms->packet_types & (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK); - LOG_VERBOSE("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__, - p_sco->hci_handle, p_setup->packet_types); + log::verbose("SCO Link for handle 0x{:04x}, pkt 0x{:04x}", + p_sco->hci_handle, p_setup->packet_types); - LOG_VERBOSE("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__, - p_sco->hci_handle, p_setup->packet_types); + log::verbose("SCO Link for handle 0x{:04x}, pkt 0x{:04x}", + p_sco->hci_handle, p_setup->packet_types); GetInterface().ChangeConnectionPacketType( p_sco->hci_handle, BTM_ESCO_2_SCO(p_setup->packet_types)); @@ -1463,12 +1484,13 @@ static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx, (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK)); p_setup->packet_types = temp_packet_types; - LOG_VERBOSE("%s -> eSCO Link for handle 0x%04x", __func__, - p_sco->hci_handle); - LOG_VERBOSE(" txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x", - p_setup->transmit_bandwidth, p_setup->receive_bandwidth, - p_parms->max_latency_ms, p_parms->retransmission_effort, - temp_packet_types); + log::verbose("-> eSCO Link for handle 0x{:04x}", p_sco->hci_handle); + log::verbose( + " txbw 0x{:x}, rxbw 0x{:x}, lat 0x{:x}, retrans 0x{:02x}, pkt " + "0x{:04x}", + p_setup->transmit_bandwidth, p_setup->receive_bandwidth, + p_parms->max_latency_ms, p_parms->retransmission_effort, + temp_packet_types); /* Use Enhanced Synchronous commands if supported */ if (controller_get_interface() @@ -1489,9 +1511,9 @@ static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx, p_setup->packet_types); } - LOG_VERBOSE( - "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x", - __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth, + log::verbose( + "txbw 0x{:x}, rxbw 0x{:x}, lat 0x{:x}, retrans 0x{:02x}, pkt 0x{:04x}", + p_setup->transmit_bandwidth, p_setup->receive_bandwidth, p_parms->max_latency_ms, p_parms->retransmission_effort, temp_packet_types); } @@ -1702,7 +1724,7 @@ static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_params) { else /* Use 8 bit for all others */ voice_settings |= HCI_INP_SAMPLE_SIZE_8BIT; - LOG_VERBOSE("%s: voice setting for legacy 0x%03x", __func__, voice_settings); + log::verbose("voice setting for legacy 0x{:03x}", voice_settings); return (voice_settings); } @@ -1755,9 +1777,7 @@ tBTM_SCO_DEBUG_DUMP BTM_GetScoDebugDump() { bool btm_peer_supports_esco_2m_phy(RawAddress remote_bda) { uint8_t* features = BTM_ReadRemoteFeatures(remote_bda); if (features == nullptr) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); return false; } return HCI_EDR_ESCO_2MPS_SUPPORTED(features); @@ -1766,9 +1786,7 @@ bool btm_peer_supports_esco_2m_phy(RawAddress remote_bda) { bool btm_peer_supports_esco_3m_phy(RawAddress remote_bda) { uint8_t* features = BTM_ReadRemoteFeatures(remote_bda); if (features == nullptr) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); return false; } return HCI_EDR_ESCO_3MPS_SUPPORTED(features); @@ -1777,9 +1795,7 @@ bool btm_peer_supports_esco_3m_phy(RawAddress remote_bda) { bool btm_peer_supports_esco_ev3(RawAddress remote_bda) { uint8_t* features = BTM_ReadRemoteFeatures(remote_bda); if (features == nullptr) { - LOG_WARN( - "Checking remote features but remote feature read is " - "incomplete"); + log::warn("Checking remote features but remote feature read is incomplete"); return false; } return HCI_ESCO_EV3_SUPPORTED(features); diff --git a/system/stack/btm/btm_sco.h b/system/stack/btm/btm_sco.h index 2ee6ecc2288686fe6c8723902bed8e7641cbe79a..bc3119625a48e8a6132d26dd0e07bacee2048c10 100644 --- a/system/stack/btm/btm_sco.h +++ b/system/stack/btm/btm_sco.h @@ -18,6 +18,7 @@ #include #include +#include #include "device/include/esco_parameters.h" #include "include/check.h" diff --git a/system/stack/btm/btm_sco_hci.cc b/system/stack/btm/btm_sco_hci.cc index a7e39ce8c58a6419d41db312e2130f469514f148..27251df15cb24cb1e65f3debea08d1b3b6473a5a 100644 --- a/system/stack/btm/btm_sco_hci.cc +++ b/system/stack/btm/btm_sco_hci.cc @@ -14,6 +14,9 @@ * limitations under the License. */ +#define LOG_TAG "sco_hci" + +#include #include #include #include @@ -22,11 +25,8 @@ #include #include -// Define before including log.h -#define LOG_TAG "sco_hci" - #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "os/log.h" #include "osi/include/allocator.h" #include "stack/btm/btm_sco.h" @@ -95,12 +95,12 @@ namespace sco { void open() { if (sco_uipc != nullptr) { - LOG_WARN("Re-opening UIPC that is already running"); + log::warn("Re-opening UIPC that is already running"); } sco_uipc = UIPC_Init(); if (sco_uipc == nullptr) { - LOG_ERROR("%s failed to init UIPC", __func__); + log::error("failed to init UIPC"); return; } @@ -110,7 +110,7 @@ void open() { if (grp) { int res = chown(SCO_HOST_DATA_PATH, -1, grp->gr_gid); if (res == -1) { - LOG_ERROR("%s failed: %s", __func__, strerror(errno)); + log::error("failed: {}", strerror(errno)); } } } @@ -125,7 +125,7 @@ void cleanup() { size_t read(uint8_t* p_buf, uint32_t len) { if (sco_uipc == nullptr) { - LOG_WARN("Read from uninitialized or closed UIPC"); + log::warn("Read from uninitialized or closed UIPC"); return 0; } return UIPC_Read(*sco_uipc, UIPC_CH_ID_AV_AUDIO, p_buf, len); @@ -133,7 +133,7 @@ size_t read(uint8_t* p_buf, uint32_t len) { size_t write(const uint8_t* p_buf, uint32_t len) { if (sco_uipc == nullptr) { - LOG_WARN("Write to uninitialized or closed UIPC"); + log::warn("Write to uninitialized or closed UIPC"); return 0; } return UIPC_Send(*sco_uipc, UIPC_CH_ID_AV_AUDIO, 0, p_buf, len) ? len : 0; @@ -396,9 +396,40 @@ struct tBTM_MSBC_INFO { size_t packet_size; /* SCO mSBC packet size supported by lower layer */ size_t buf_size; /* The size of the buffer, determined by the packet_size. */ + enum decode_buf_state { + DECODE_BUF_EMPTY, + DECODE_BUF_FULL, + + // Neither empty nor full. + DECODE_BUF_HALFFULL, + }; + + uint8_t* packet_buf; /* Temporary buffer to store the data */ uint8_t* msbc_decode_buf; /* Buffer to store mSBC packets to decode */ size_t decode_buf_wo; /* Write offset of the decode buffer */ size_t decode_buf_ro; /* Read offset of the decode buffer */ + + /* Within the circular buffer, which can be visualized as having + two halves, mirror indicators track the pointer's location, + signaling whether it resides in the first or second segment: + + [buf_size-1] ┼ - - -─┼ [0] + │ │ + │ │ + wo = x, wo_mirror = 0 ^ v ro = x, ro_mirror = 1 + │ │ + │ │ + [0] ┼ - - - ┼ [buf_size-1] + (First Half) (Second Half) + */ + bool decode_buf_wo_mirror; /* The mirror indicator specifies whether + the write pointer is currently located + in the first or second half of the + circular buffer */ + bool decode_buf_ro_mirror; /* The mirror indicator specifies whether + the read pointer is currently located + in the first or second half of the + circular buffer */ bool read_corrupted; /* If the current mSBC packet read is corrupted */ uint8_t* msbc_encode_buf; /* Buffer to store the encoded SCO packets */ @@ -421,7 +452,7 @@ struct tBTM_MSBC_INFO { /* In case of unsupported value, error log and fallback to * BTM_MSBC_PKT_LEN(60). */ if (btm_wbs_supported_pkt_size[i] == 0) { - LOG_WARN("Unsupported packet size %lu", (unsigned long)pkt_size); + log::warn("Unsupported packet size {}", (unsigned long)pkt_size); i = 0; } @@ -444,6 +475,9 @@ struct tBTM_MSBC_INFO { size_t init(size_t pkt_size) { decode_buf_wo = 0; decode_buf_ro = 0; + decode_buf_wo_mirror = false; + decode_buf_ro_mirror = false; + encode_buf_wo = 0; encode_buf_ro = 0; @@ -451,6 +485,9 @@ struct tBTM_MSBC_INFO { if (pkt_size == packet_size) return packet_size; packet_size = pkt_size; + if (packet_buf) osi_free(packet_buf); + packet_buf = (uint8_t*)osi_calloc(packet_size); + if (msbc_decode_buf) osi_free(msbc_decode_buf); msbc_decode_buf = (uint8_t*)osi_calloc(buf_size); @@ -473,6 +510,7 @@ struct tBTM_MSBC_INFO { void deinit() { if (msbc_decode_buf) osi_free(msbc_decode_buf); + if (packet_buf) osi_free(packet_buf); if (msbc_encode_buf) osi_free(msbc_encode_buf); if (plc) { plc->deinit(); @@ -481,28 +519,66 @@ struct tBTM_MSBC_INFO { if (pkt_status) osi_free_and_reset((void**)&pkt_status); } - size_t decodable() { return decode_buf_wo - decode_buf_ro; } - - void mark_pkt_decoded() { - if (decode_buf_ro + BTM_MSBC_PKT_LEN > decode_buf_wo) { - LOG_ERROR("Trying to mark read offset beyond write offset."); + void incr_buf_offset(size_t& offset, bool& mirror, size_t bsize, + size_t amount) { + if (bsize - offset > amount) { + offset += amount; return; } - decode_buf_ro += BTM_MSBC_PKT_LEN; + mirror = !mirror; + offset = amount - (bsize - offset); + } + + decode_buf_state decode_buf_status() { if (decode_buf_ro == decode_buf_wo) { - decode_buf_ro = 0; - decode_buf_wo = 0; + if (decode_buf_ro_mirror == decode_buf_wo_mirror) return DECODE_BUF_EMPTY; + return DECODE_BUF_FULL; + } + return DECODE_BUF_HALFFULL; + } + + size_t decode_buf_data_len() { + switch (decode_buf_status()) { + case DECODE_BUF_EMPTY: + return 0; + case DECODE_BUF_FULL: + return buf_size; + case DECODE_BUF_HALFFULL: + default: + if (decode_buf_wo > decode_buf_ro) return decode_buf_wo - decode_buf_ro; + return buf_size - (decode_buf_ro - decode_buf_wo); + }; + } + + size_t decode_buf_avail_len() { return buf_size - decode_buf_data_len(); } + + void mark_pkt_decoded() { + if (decode_buf_data_len() < BTM_MSBC_PKT_LEN) { + log::error("Trying to mark read offset beyond write offset."); + return; } + + incr_buf_offset(decode_buf_ro, decode_buf_ro_mirror, buf_size, + BTM_MSBC_PKT_LEN); } size_t write(const std::vector& input) { - if (input.size() > buf_size - decode_buf_wo) { + if (input.size() > decode_buf_avail_len()) { return 0; } - std::copy(input.begin(), input.end(), msbc_decode_buf + decode_buf_wo); - decode_buf_wo += input.size(); + if (buf_size - decode_buf_wo > input.size()) { + std::copy(input.begin(), input.end(), msbc_decode_buf + decode_buf_wo); + } else { + std::copy(input.begin(), input.begin() + buf_size - decode_buf_wo, + msbc_decode_buf + decode_buf_wo); + std::copy(input.begin() + buf_size - decode_buf_wo, input.end(), + msbc_decode_buf); + } + + incr_buf_offset(decode_buf_wo, decode_buf_wo_mirror, buf_size, + input.size()); return input.size(); } @@ -513,22 +589,35 @@ struct tBTM_MSBC_INFO { } size_t rp = 0; - while (rp < BTM_MSBC_PKT_LEN && - decode_buf_wo - (decode_buf_ro + rp) >= BTM_MSBC_PKT_LEN) { - if ((msbc_decode_buf[decode_buf_ro + rp] != BTM_MSBC_H2_HEADER_0) || + size_t data_len = decode_buf_data_len(); + while (rp < BTM_MSBC_PKT_LEN && data_len - rp >= BTM_MSBC_PKT_LEN) { + if ((msbc_decode_buf[(decode_buf_ro + rp) % buf_size] != + BTM_MSBC_H2_HEADER_0) || (!verify_h2_header_seq_num( - msbc_decode_buf[decode_buf_ro + rp + 1])) || - (msbc_decode_buf[decode_buf_ro + rp + 2] != BTM_MSBC_SYNC_WORD)) { + msbc_decode_buf[(decode_buf_ro + rp + 1) % buf_size])) || + (msbc_decode_buf[(decode_buf_ro + rp + 2) % buf_size] != + BTM_MSBC_SYNC_WORD)) { rp++; continue; } if (rp != 0) { - LOG_WARN("Skipped %lu bytes of mSBC data ahead of a valid mSBC frame", - (unsigned long)rp); - decode_buf_ro += rp; + log::warn("Skipped {} bytes of mSBC data ahead of a valid mSBC frame", + (unsigned long)rp); + incr_buf_offset(decode_buf_ro, decode_buf_ro_mirror, buf_size, rp); + } + + // Get the frame head. + if (buf_size - decode_buf_ro >= BTM_MSBC_PKT_LEN) { + return &msbc_decode_buf[decode_buf_ro]; } - return &msbc_decode_buf[decode_buf_ro]; + + std::copy(msbc_decode_buf + decode_buf_ro, msbc_decode_buf + buf_size, + packet_buf); + std::copy(msbc_decode_buf, + msbc_decode_buf + BTM_MSBC_PKT_LEN - (buf_size - decode_buf_ro), + packet_buf + (buf_size - decode_buf_ro)); + return packet_buf; } return nullptr; @@ -541,7 +630,7 @@ struct tBTM_MSBC_INFO { uint8_t* fill_msbc_pkt_template() { uint8_t* wp = &msbc_encode_buf[encode_buf_wo]; if (buf_size - encode_buf_wo < BTM_MSBC_PKT_LEN) { - LOG_DEBUG("Packet queue can't accommodate more packets."); + log::debug("Packet queue can't accommodate more packets."); return nullptr; } @@ -567,8 +656,8 @@ struct tBTM_MSBC_INFO { const uint8_t* sco_pkt_read_ptr() { if (encode_buf_wo - encode_buf_ro < packet_size) { - LOG_DEBUG("Insufficient data to dequeue. buf_wo:%zu, buf_ro:%zu", - encode_buf_wo, encode_buf_ro); + log::debug("Insufficient data to dequeue. buf_wo:{}, buf_ro:{}", + encode_buf_wo, encode_buf_ro); return nullptr; } @@ -582,7 +671,7 @@ size_t init(size_t pkt_size) { GetInterfaceToProfiles()->msbcCodec->initialize(); if (msbc_info) { - LOG_WARN("Re-initiating mSBC buffer that is active or not cleaned"); + log::warn("Re-initiating mSBC buffer that is active or not cleaned"); msbc_info->deinit(); osi_free(msbc_info); } @@ -617,14 +706,14 @@ bool fill_plc_stats(int* num_decoded_frames, double* packet_loss_ratio) { bool enqueue_packet(const std::vector& data, bool corrupted) { if (msbc_info == nullptr) { - LOG_WARN("mSBC buffer uninitialized or cleaned"); + log::warn("mSBC buffer uninitialized or cleaned"); return false; } if (data.size() != msbc_info->packet_size) { - LOG_WARN( - "Ignoring the coming packet with size %lu that is inconsistent with " - "the HAL reported packet size %lu", + log::warn( + "Ignoring the coming packet with size {} that is inconsistent with the " + "HAL reported packet size {}", (unsigned long)data.size(), (unsigned long)msbc_info->packet_size); return false; } @@ -641,16 +730,16 @@ size_t decode(const uint8_t** out_data) { const uint8_t* frame_head = nullptr; if (msbc_info == nullptr) { - LOG_WARN("mSBC buffer uninitialized or cleaned"); + log::warn("mSBC buffer uninitialized or cleaned"); return 0; } if (out_data == nullptr) { - LOG_WARN("%s Invalid output pointer", __func__); + log::warn("Invalid output pointer"); return 0; } - if (msbc_info->decodable() < BTM_MSBC_PKT_LEN) { + if (msbc_info->decode_buf_data_len() < BTM_MSBC_PKT_LEN) { return 0; } @@ -685,12 +774,12 @@ size_t encode(int16_t* data, size_t len) { uint8_t* pkt_body = nullptr; uint32_t encoded_size = 0; if (msbc_info == nullptr) { - LOG_WARN("mSBC buffer uninitialized or cleaned"); + log::warn("mSBC buffer uninitialized or cleaned"); return 0; } if (data == nullptr) { - LOG_WARN("Invalid data to encode"); + log::warn("Invalid data to encode"); return 0; } @@ -706,7 +795,7 @@ size_t encode(int16_t* data, size_t len) { encoded_size = GetInterfaceToProfiles()->msbcCodec->encodePacket(data, pkt_body); if (encoded_size != BTM_MSBC_PKT_FRAME_LEN) { - LOG_WARN("Encoding invalid packet size: %lu", (unsigned long)encoded_size); + log::warn("Encoding invalid packet size: {}", (unsigned long)encoded_size); std::copy(&btm_msbc_zero_packet[BTM_MSBC_H2_HEADER_LEN], std::end(btm_msbc_zero_packet), pkt_body); } @@ -716,12 +805,12 @@ size_t encode(int16_t* data, size_t len) { size_t dequeue_packet(const uint8_t** output) { if (msbc_info == nullptr) { - LOG_WARN("mSBC buffer uninitialized or cleaned"); + log::warn("mSBC buffer uninitialized or cleaned"); return 0; } if (output == nullptr) { - LOG_WARN("%s Invalid output pointer", __func__); + log::warn("Invalid output pointer"); return 0; } @@ -789,7 +878,7 @@ struct tBTM_LC3_INFO { /* In case of unsupported value, error log and fallback to * BTM_LC3_PKT_LEN(60). */ if (btm_swb_supported_pkt_size[i] == 0) { - LOG_WARN("Unsupported packet size %lu", (unsigned long)pkt_size); + log::warn("Unsupported packet size {}", (unsigned long)pkt_size); i = 0; } @@ -843,7 +932,7 @@ struct tBTM_LC3_INFO { uint8_t* fill_lc3_pkt_template() { uint8_t* wp = &lc3_encode_buf[encode_buf_wo]; if (buf_size - encode_buf_wo < BTM_LC3_PKT_LEN) { - LOG_DEBUG("Packet queue can't accommodate more packets."); + log::debug("Packet queue can't accommodate more packets."); return nullptr; } @@ -857,7 +946,7 @@ struct tBTM_LC3_INFO { void mark_pkt_decoded() { if (decode_buf_ro + BTM_LC3_PKT_LEN > decode_buf_wo) { - LOG_ERROR("Trying to mark read offset beyond write offset."); + log::error("Trying to mark read offset beyond write offset."); return; } @@ -894,8 +983,8 @@ struct tBTM_LC3_INFO { } if (rp != 0) { - LOG_WARN("Skipped %lu bytes of LC3 data ahead of a valid LC3 frame", - (unsigned long)rp); + log::warn("Skipped {} bytes of LC3 data ahead of a valid LC3 frame", + (unsigned long)rp); decode_buf_ro += rp; } return &lc3_decode_buf[decode_buf_ro]; @@ -918,8 +1007,8 @@ struct tBTM_LC3_INFO { const uint8_t* sco_pkt_read_ptr() { if (encode_buf_wo - encode_buf_ro < packet_size) { - LOG_DEBUG("Insufficient data to dequeue. buf_wo:%zu, buf_ro:%zu", - encode_buf_wo, encode_buf_ro); + log::debug("Insufficient data to dequeue. buf_wo:{}, buf_ro:{}", + encode_buf_wo, encode_buf_ro); return nullptr; } @@ -938,7 +1027,7 @@ size_t init(size_t pkt_size) { lost_frames = 0; if (lc3_info) { - LOG_WARN("Re-initiating LC3 buffer that is active or not cleaned"); + log::warn("Re-initiating LC3 buffer that is active or not cleaned"); lc3_info->deinit(); osi_free(lc3_info); } @@ -974,14 +1063,14 @@ bool fill_plc_stats(int* num_decoded_frames, double* packet_loss_ratio) { bool enqueue_packet(const std::vector& data, bool corrupted) { if (lc3_info == nullptr) { - LOG_WARN("LC3 buffer uninitialized or cleaned"); + log::warn("LC3 buffer uninitialized or cleaned"); return false; } if (data.size() != lc3_info->packet_size) { - LOG_WARN( - "Ignoring the coming packet with size %lu that is inconsistent with " - "the HAL reported packet size %lu", + log::warn( + "Ignoring the coming packet with size {} that is inconsistent with the " + "HAL reported packet size {}", (unsigned long)data.size(), (unsigned long)lc3_info->packet_size); return false; } @@ -998,12 +1087,12 @@ size_t decode(const uint8_t** out_data) { const uint8_t* frame_head = nullptr; if (lc3_info == nullptr) { - LOG_WARN("LC3 buffer uninitialized or cleaned"); + log::warn("LC3 buffer uninitialized or cleaned"); return 0; } if (out_data == nullptr) { - LOG_WARN("%s Invalid output pointer", __func__); + log::warn("Invalid output pointer"); return 0; } @@ -1030,12 +1119,12 @@ size_t decode(const uint8_t** out_data) { size_t encode(int16_t* data, size_t len) { uint8_t* pkt_body = nullptr; if (lc3_info == nullptr) { - LOG_WARN("LC3 buffer uninitialized or cleaned"); + log::warn("LC3 buffer uninitialized or cleaned"); return 0; } if (data == nullptr) { - LOG_WARN("Invalid data to encode"); + log::warn("Invalid data to encode"); return 0; } @@ -1053,12 +1142,12 @@ size_t encode(int16_t* data, size_t len) { size_t dequeue_packet(const uint8_t** output) { if (lc3_info == nullptr) { - LOG_WARN("LC3 buffer uninitialized or cleaned"); + log::warn("LC3 buffer uninitialized or cleaned"); return 0; } if (output == nullptr) { - LOG_WARN("%s Invalid output pointer", __func__); + log::warn("Invalid output pointer"); return 0; } diff --git a/system/stack/btm/btm_sco_hfp_hal.cc b/system/stack/btm/btm_sco_hfp_hal.cc index 9e2496ebd0e45dd16695146e2effc0d68450162a..e10a92148d9df752b2d05a8bd5d6e02d8d6ac105 100644 --- a/system/stack/btm/btm_sco_hfp_hal.cc +++ b/system/stack/btm/btm_sco_hfp_hal.cc @@ -48,6 +48,11 @@ void init() { cached_codecs.emplace_back(msbc); } +// This is not used in Android. +bool is_coding_format_supported(esco_coding_format_t coding_format) { + return true; +} + // Android statically compiles WBS support. bool get_wbs_supported() { return !DISABLE_WBS; } diff --git a/system/stack/btm/btm_sco_hfp_hal.h b/system/stack/btm/btm_sco_hfp_hal.h index c72ebe2daa25be9175324bd001b6924e9e78f5ae..624f387bc43f0cefae2b04dffd9954d3622d8fd1 100644 --- a/system/stack/btm/btm_sco_hfp_hal.h +++ b/system/stack/btm/btm_sco_hfp_hal.h @@ -20,8 +20,8 @@ #include -#include "bt_target.h" #include "device/include/esco_parameters.h" +#include "internal_include/bt_target.h" #include "raw_address.h" // Used by the Bluetooth stack to get WBS supported and codec, or notify SCO @@ -69,6 +69,9 @@ constexpr inline int esco_coding_to_codec(esco_coding_format_t esco_coding) { // Initialize the SCO HFP HAL module void init(); +// Check if specified coding format is supported by the adapter. +bool is_coding_format_supported(esco_coding_format_t coding_format); + // Check if wideband speech is supported on local device. bool get_wbs_supported(); diff --git a/system/stack/btm/btm_sco_hfp_hal_linux.cc b/system/stack/btm/btm_sco_hfp_hal_linux.cc index 4853ac0aa31467a00a390c523397f2f407cfa52a..122a22339f9633c69a30216b6a024320fc7335fc 100644 --- a/system/stack/btm/btm_sco_hfp_hal_linux.cc +++ b/system/stack/btm/btm_sco_hfp_hal_linux.cc @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -21,12 +22,15 @@ #include #include "btm_sco_hfp_hal.h" -#include "gd/common/init_flags.h" -#include "osi/include/log.h" +#include "common/init_flags.h" +#include "hci/controller_interface.h" +#include "main/shim/entry.h" +#include "os/log.h" #include "osi/include/properties.h" #include "stack/include/hcimsgs.h" #include "stack/include/sdpdefs.h" +using namespace bluetooth; using bluetooth::legacy::hci::GetInterface; namespace hfp_hal_interface { @@ -77,42 +81,56 @@ struct mgmt_ev_cmd_complete { struct mgmt_cp_get_codec_capabilities { uint16_t hci_dev; - uint32_t num_codecs; - uint8_t codecs[]; } __attribute__((packed)); struct mgmt_rp_get_codec_capabilities { uint16_t hci_dev; - uint8_t offload_capable; - uint32_t num_codecs; - struct mgmt_bt_codec codecs[]; + uint8_t transparent_wbs_supported; + uint8_t hci_data_path_id; + uint32_t wbs_pkt_len; } __attribute__((packed)); #define MGMT_POLL_TIMEOUT_MS 2000 void cache_codec_capabilities(struct mgmt_rp_get_codec_capabilities* rp) { - uint8_t* ptr = reinterpret_cast(rp->codecs); - // Copy into cached codec information - offload_supported = rp->offload_capable; - for (int i = 0; i < rp->num_codecs; i++) { - struct mgmt_bt_codec* mc = reinterpret_cast(ptr); - cached_codec_info c = { - .inner = - { - .codec = static_cast(1 << (mc->codec - 1)), - .data_path = mc->data_path, - .data = mc->data_length == 0 - ? std::vector{} - : std::vector(mc->data, - mc->data + mc->data_length), - }, - .pkt_size = mc->packet_size, - }; - ptr += sizeof(*mc); - - LOG_INFO("Caching HFP codec %u, data path %u, data len %d, pkt_size %u", - (uint64_t)c.inner.codec, c.inner.data_path, c.inner.data.size(), - c.pkt_size); + const uint8_t kCodecCvsd = 0x2; + const uint8_t kCodecTransparent = 0x3; + const uint8_t kCodecMsbc = 0x5; + + auto codecs = + bluetooth::shim::GetController()->GetLocalSupportedBrEdrCodecIds(); + + for (uint8_t codec_id : codecs) { + // TODO(b/323087725): Query the codec capabilities and fill in c.inner.data. + // The capabilities are not used currently so it's safe to keep this for a + // while. + cached_codec_info c{}; + switch (codec_id) { + case kCodecCvsd: + c.inner.codec = codec::CVSD; + break; + case kCodecTransparent: + if (!rp->transparent_wbs_supported) { + // Transparent wideband speech not supported, skip it. + continue; + } + c.inner.codec = codec::MSBC_TRANSPARENT; + c.pkt_size = rp->wbs_pkt_len; + break; + case kCodecMsbc: + offload_supported = true; + c.inner.codec = codec::MSBC; + c.inner.data_path = rp->hci_data_path_id; + c.pkt_size = rp->wbs_pkt_len; + break; + default: + log::debug("Unsupported codec ID: {}", codec_id); + continue; + } + + log::info("Caching HFP codec {}, data path {}, data len {}, pkt_size {}", + (uint64_t)c.inner.codec, c.inner.data_path, c.inner.data.size(), + c.pkt_size); cached_codecs.push_back(c); } @@ -131,7 +149,7 @@ constexpr uint16_t HCI_DEV_NONE = 0xffff; int btsocket_open_mgmt(uint16_t hci) { int fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_NONBLOCK, BTPROTO_HCI); if (fd < 0) { - LOG_DEBUG("Failed to open BT socket."); + log::debug("Failed to open BT socket."); return -errno; } @@ -143,7 +161,7 @@ int btsocket_open_mgmt(uint16_t hci) { int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr)); if (ret < 0) { - LOG_DEBUG("Failed to bind BT socket."); + log::debug("Failed to bind BT socket."); close(fd); return -errno; } @@ -152,19 +170,14 @@ int btsocket_open_mgmt(uint16_t hci) { } int mgmt_get_codec_capabilities(int fd, uint16_t hci) { - // Write read codec capabilities struct mgmt_pkt ev; ev.opcode = MGMT_OP_GET_SCO_CODEC_CAPABILITIES; ev.index = HCI_DEV_NONE; - ev.len = sizeof(struct mgmt_cp_get_codec_capabilities) + 3; + ev.len = sizeof(struct mgmt_cp_get_codec_capabilities); struct mgmt_cp_get_codec_capabilities* cp = reinterpret_cast(ev.data); cp->hci_dev = hci; - cp->num_codecs = 3; - cp->codecs[0] = MGMT_SCO_CODEC_CVSD; - cp->codecs[1] = MGMT_SCO_CODEC_MSBC_TRANSPARENT; - cp->codecs[2] = MGMT_SCO_CODEC_MSBC; int ret; @@ -177,8 +190,8 @@ int mgmt_get_codec_capabilities(int fd, uint16_t hci) { if (ret > 0) { RETRY_ON_INTR(ret = write(fd, &ev, MGMT_PKT_HDR_SIZE + ev.len)); if (ret < 0) { - LOG_DEBUG("Failed to call MGMT_OP_GET_SCO_CODEC_CAPABILITIES: %d", - -errno); + log::debug("Failed to call MGMT_OP_GET_SCO_CODEC_CAPABILITIES: {}", + -errno); return -errno; }; break; @@ -186,7 +199,7 @@ int mgmt_get_codec_capabilities(int fd, uint16_t hci) { } while (ret > 0); if (ret <= 0) { - LOG_DEBUG("Failed waiting for mgmt socket to be writable."); + log::debug("Failed waiting for mgmt socket to be writable."); return -1; } @@ -201,7 +214,7 @@ int mgmt_get_codec_capabilities(int fd, uint16_t hci) { if (fds[0].revents & POLLIN) { RETRY_ON_INTR(ret = read(fd, &ev, sizeof(ev))); if (ret < 0) { - LOG_DEBUG("Failed to read mgmt socket: %d", -errno); + log::debug("Failed to read mgmt socket: {}", -errno); return -errno; } @@ -221,7 +234,7 @@ int mgmt_get_codec_capabilities(int fd, uint16_t hci) { } } } else if (ret == 0) { - LOG_DEBUG("Timeout while waiting for codec capabilities response."); + log::debug("Timeout while waiting for codec capabilities response."); ret = -1; } } while (ret > 0); @@ -265,8 +278,8 @@ int mgmt_notify_sco_connection_change(int fd, int hci, RawAddress device, if (ret > 0) { RETRY_ON_INTR(ret = write(fd, &ev, MGMT_PKT_HDR_SIZE + ev.len)); if (ret < 0) { - LOG_ERROR("Failed to call MGMT_OP_NOTIFY_SCO_CONNECTION_CHANGE: %d", - -errno); + log::error("Failed to call MGMT_OP_NOTIFY_SCO_CONNECTION_CHANGE: {}", + -errno); return -errno; }; break; @@ -274,7 +287,7 @@ int mgmt_notify_sco_connection_change(int fd, int hci, RawAddress device, } while (ret > 0); if (ret <= 0) { - LOG_DEBUG("Failed waiting for mgmt socket to be writable."); + log::debug("Failed waiting for mgmt socket to be writable."); return -1; } @@ -286,39 +299,51 @@ void init() { int hci = bluetooth::common::InitFlags::GetAdapterIndex(); int fd = btsocket_open_mgmt(hci); if (fd < 0) { - LOG_ERROR("Failed to open mgmt channel, error= %d.", fd); + log::error("Failed to open mgmt channel, error= {}.", fd); return; } int ret = mgmt_get_codec_capabilities(fd, hci); if (ret) { - LOG_ERROR("Failed to get codec capabilities with error = %d.", ret); + log::error("Failed to get codec capabilities with error = {}.", ret); } else { - LOG_INFO("Successfully queried SCO codec capabilities."); + log::info("Successfully queried SCO codec capabilities."); } close(fd); } -// Check if wideband speech is supported on local device -bool get_wbs_supported() { +// Check if the specified coding format is supported by the adapter. +bool is_coding_format_supported(esco_coding_format_t coding_format) { + if (coding_format != ESCO_CODING_FORMAT_TRANSPNT && + coding_format != ESCO_CODING_FORMAT_MSBC) { + log::warn("Unsupported coding format to query: {}", coding_format); + return false; + } + for (cached_codec_info c : cached_codecs) { - if (c.inner.codec == MSBC || c.inner.codec == MSBC_TRANSPARENT) { + if (c.inner.codec == MSBC_TRANSPARENT && + coding_format == ESCO_CODING_FORMAT_TRANSPNT) { + return true; + } + if (c.inner.codec == MSBC && coding_format == ESCO_CODING_FORMAT_MSBC) { return true; } } + return false; } +// Check if wideband speech is supported on local device +bool get_wbs_supported() { + return is_coding_format_supported(ESCO_CODING_FORMAT_TRANSPNT) || + is_coding_format_supported(ESCO_CODING_FORMAT_MSBC); +} + // Check if super-wideband speech is supported on local device bool get_swb_supported() { - for (cached_codec_info c : cached_codecs) { - // SWB runs on the same path as MSBC non-offload. - if (c.inner.codec == MSBC_TRANSPARENT) { - return true; - } - } - return false; + // We only support SWB via transparent mode. + return is_coding_format_supported(ESCO_CODING_FORMAT_TRANSPNT); } // Checks the supported codecs @@ -343,8 +368,7 @@ bool get_offload_enabled() { return offload_supported && offload_enabled; } // Set offload enable/disable bool enable_offload(bool enable) { if (!offload_supported && enable) { - LOG_ERROR("%s: Cannot enable SCO-offload since it is not supported.", - __func__); + log::error("Cannot enable SCO-offload since it is not supported."); return false; } offload_enabled = enable; @@ -371,7 +395,7 @@ void set_codec_datapath(int codec_uuid) { uint8_t codec_id; if (codec_uuid == UUID_CODEC_LC3 && get_offload_enabled()) { - LOG_ERROR("Offload path for LC3 is not implemented."); + log::error("Offload path for LC3 is not implemented."); return; } @@ -386,21 +410,22 @@ void set_codec_datapath(int codec_uuid) { codec_id = get_offload_enabled() ? codec::LC3 : codec::MSBC_TRANSPARENT; break; default: - LOG_WARN("Unsupported codec (%d). Won't set datapath.", codec_uuid); + log::warn("Unsupported codec ({}). Won't set datapath.", codec_uuid); return; } found = get_single_codec(codec_id, &codec); if (!found) { - LOG_ERROR("Failed to find codec config for codec (%d). Won't set datapath.", - codec_uuid); + log::error( + "Failed to find codec config for codec ({}). Won't set datapath.", + codec_uuid); return; } - LOG_INFO("Configuring datapath for codec (%d)", codec_uuid); + log::info("Configuring datapath for codec ({})", codec_uuid); if (codec->codec == codec::MSBC && !get_offload_enabled()) { - LOG_ERROR( - "Tried to configure offload data path for format (%d) with offload " + log::error( + "Tried to configure offload data path for format ({}) with offload " "disabled. Won't set datapath.", codec_uuid); return; @@ -441,12 +466,12 @@ void notify_sco_connection_change(RawAddress device, bool is_connected, int hci = bluetooth::common::InitFlags::GetAdapterIndex(); int fd = btsocket_open_mgmt(hci); if (fd < 0) { - LOG_ERROR("Failed to open mgmt channel, error= %d.", fd); + log::error("Failed to open mgmt channel, error= {}.", fd); return; } if (codec == codec::LC3) { - LOG_ERROR("Offload path for LC3 is not implemented."); + log::error("Offload path for LC3 is not implemented."); return; } @@ -466,14 +491,14 @@ void notify_sco_connection_change(RawAddress device, bool is_connected, int ret = mgmt_notify_sco_connection_change(fd, hci, device, is_connected, converted_codec); if (ret) { - LOG_ERROR( - "Failed to notify HAL of connection change: hci %d, device %s, " - "connected %d, codec %d", + log::error( + "Failed to notify HAL of connection change: hci {}, device {}, " + "connected {}, codec {}", hci, ADDRESS_TO_LOGGABLE_CSTR(device), is_connected, codec); } else { - LOG_INFO( - "Notified HAL of connection change: hci %d, device %s, connected %d, " - "codec %d", + log::info( + "Notified HAL of connection change: hci {}, device {}, connected {}, " + "codec {}", hci, ADDRESS_TO_LOGGABLE_CSTR(device), is_connected, codec); } diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc index e3ab81394735e34959a27b5ac01dc16556d62b7b..a74cd8cda91d4c28ca9164e29e981bc6e8504c69 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -26,12 +26,10 @@ #include "stack/btm/btm_sec.h" +#include #include -#include -#include #include -#include -#include +#include #include #include @@ -43,8 +41,11 @@ #include "common/time_util.h" #include "device/include/controller.h" #include "device/include/device_iot_config.h" +#include "device/include/interop.h" +#include "hci/controller_interface.h" #include "internal_include/bt_target.h" #include "l2c_api.h" +#include "main/shim/entry.h" #include "osi/include/allocator.h" #include "osi/include/properties.h" #include "stack/btm/btm_ble_int.h" @@ -77,9 +78,12 @@ constexpr char kBtmLogTag[] = "SEC"; } +using namespace bluetooth; + extern tBTM_CB btm_cb; #define BTM_SEC_MAX_COLLISION_DELAY (5000) +#define BTM_SEC_START_AUTH_DELAY (200) #define BTM_SEC_IS_SM4(sm) ((bool)(BTM_SM4_TRUE == ((sm)&BTM_SM4_TRUE))) #define BTM_SEC_IS_SM4_LEGACY(sm) ((bool)(BTM_SM4_KNOWN == ((sm)&BTM_SM4_TRUE))) @@ -94,6 +98,7 @@ void btm_inq_stop_on_ssp(void); bool btm_ble_init_pseudo_addr(tBTM_SEC_DEV_REC* p_dev_rec, const RawAddress& new_pseudo_addr); void bta_dm_remove_device(const RawAddress& bd_addr); +void bta_dm_remote_key_missing(const RawAddress bd_addr); void bta_dm_process_remove_device(const RawAddress& bd_addr); void btm_inq_clear_ssp(void); @@ -152,8 +157,7 @@ static void NotifyBondingChange(tBTM_SEC_DEV_REC& p_dev_rec, tHCI_STATUS status) { if (btm_sec_cb.api.p_auth_complete_callback != nullptr) { (*btm_sec_cb.api.p_auth_complete_callback)( - p_dev_rec.bd_addr, static_cast(p_dev_rec.dev_class), - p_dev_rec.sec_bd_name, status); + p_dev_rec.bd_addr, p_dev_rec.dev_class, p_dev_rec.sec_bd_name, status); } } @@ -250,6 +254,110 @@ static tBTM_SEC_DEV_REC* btm_sec_find_dev_by_sec_state(uint8_t state) { return nullptr; } +/******************************************************************************* + * + * Function btm_sec_is_device_sc_downgrade + * + * Description Check for a stored device record matching the candidate + * device, and return true if the stored device has reported + * that it supports Secure Connections mode and the candidate + * device reports that it does not. Otherwise, return false. + * + * Returns bool + * + ******************************************************************************/ +static bool btm_sec_is_device_sc_downgrade(uint16_t hci_handle, + bool secure_connections_supported) { + if (secure_connections_supported) return false; + + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return false; + + uint8_t property_val = 0; + bt_property_t property = { + .type = BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED, + .len = sizeof(uint8_t), + .val = &property_val}; + + bt_status_t cached = + btif_storage_get_remote_device_property(&p_dev_rec->bd_addr, &property); + + if (cached == BT_STATUS_FAIL) return false; + + return (bool)property_val; +} + +/******************************************************************************* + * + * Function btm_sec_store_device_sc_support + * + * Description Save Secure Connections support for this device to file + * + ******************************************************************************/ + +static void btm_sec_store_device_sc_support(uint16_t hci_handle, + bool secure_connections_supported) { + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return; + + uint8_t property_val = (uint8_t)secure_connections_supported; + bt_property_t property = { + .type = BT_PROPERTY_REMOTE_SECURE_CONNECTIONS_SUPPORTED, + .len = sizeof(uint8_t), + .val = &property_val}; + + btif_storage_set_remote_device_property(&p_dev_rec->bd_addr, &property); +} + +/******************************************************************************* + * + * Function btm_sec_is_session_key_size_downgrade + * + * Description Check if there is a stored device record matching this + * handle, and return true if the stored record has a lower + * session key size than the candidate device. + * + * Returns bool + * + ******************************************************************************/ +static bool btm_sec_is_session_key_size_downgrade(uint16_t hci_handle, + uint8_t key_size) { + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return false; + + uint8_t property_val = 0; + bt_property_t property = {.type = BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE, + .len = sizeof(uint8_t), + .val = &property_val}; + + bt_status_t cached = + btif_storage_get_remote_device_property(&p_dev_rec->bd_addr, &property); + + if (cached == BT_STATUS_FAIL) return false; + + return property_val > key_size; +} + +/******************************************************************************* + * + * Function btm_sec_update_session_key_size + * + * Description Store the max session key size to disk, if possible. + * + ******************************************************************************/ +static void btm_sec_update_session_key_size(uint16_t hci_handle, + uint8_t key_size) { + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); + if (p_dev_rec == nullptr) return; + + uint8_t property_val = key_size; + bt_property_t property = {.type = BT_PROPERTY_REMOTE_MAX_SESSION_KEY_SIZE, + .len = sizeof(uint8_t), + .val = &property_val}; + + btif_storage_set_remote_device_property(&p_dev_rec->bd_addr, &property); +} + /******************************************************************************* * * Function access_secure_service_from_temp_bond @@ -265,7 +373,6 @@ static bool access_secure_service_from_temp_bond(const tBTM_SEC_DEV_REC* p_dev_r bool locally_initiated, uint16_t security_req) { return !locally_initiated && (security_req & BTM_SEC_IN_AUTHENTICATE) && - p_dev_rec->sec_rec.is_device_authenticated() && p_dev_rec->sec_rec.is_bond_type_temporary(); } @@ -282,9 +389,10 @@ static bool access_secure_service_from_temp_bond(const tBTM_SEC_DEV_REC* p_dev_r * ******************************************************************************/ bool BTM_SecRegister(const tBTM_APPL_INFO* p_cb_info) { - LOG_INFO("p_cb_info->p_le_callback == 0x%p", p_cb_info->p_le_callback); + log::info("p_cb_info->p_le_callback == 0x{}", + fmt::ptr(p_cb_info->p_le_callback)); if (p_cb_info->p_le_callback) { - LOG_VERBOSE("SMP_Register( btm_proc_smp_cback )"); + log::verbose("SMP_Register( btm_proc_smp_cback )"); SMP_Register(btm_proc_smp_cback); Octet16 zero{0}; /* if no IR is loaded, need to regenerate all the keys */ @@ -292,13 +400,13 @@ bool BTM_SecRegister(const tBTM_APPL_INFO* p_cb_info) { btm_ble_reset_id(); } } else { - LOG_WARN("p_cb_info->p_le_callback == NULL"); + log::warn("p_cb_info->p_le_callback == NULL"); } btm_sec_cb.api = *p_cb_info; - LOG_INFO("btm_sec_cb.api.p_le_callback = 0x%p ", - btm_sec_cb.api.p_le_callback); - LOG_VERBOSE("application registered"); + log::info("btm_sec_cb.api.p_le_callback = 0x{} ", + fmt::ptr(btm_sec_cb.api.p_le_callback)); + log::verbose("application registered"); return (true); } @@ -369,7 +477,7 @@ bool BTM_CanReadDiscoverableCharacteristics(const RawAddress& bd_addr) { if (p_dev_rec != nullptr) { return p_dev_rec->can_read_discoverable; } else { - LOG_ERROR( + log::error( "BTM_CanReadDiscoverableCharacteristics invoked for an invalid " "BD_ADDR"); return false; @@ -386,8 +494,8 @@ bool BTM_CanReadDiscoverableCharacteristics(const RawAddress& bd_addr) { * ******************************************************************************/ void BTM_SetPinType(uint8_t pin_type, PIN_CODE pin_code, uint8_t pin_code_len) { - LOG_VERBOSE( - "BTM_SetPinType: pin type %d [variable-0, fixed-1], code %s, length %d", + log::verbose( + "BTM_SetPinType: pin type {} [variable-0, fixed-1], code {}, length {}", pin_type, (char*)pin_code, pin_code_len); /* If device is not up security mode will be set as a part of startup */ @@ -489,26 +597,26 @@ void BTM_PINCodeReply(const RawAddress& bd_addr, tBTM_STATUS res, uint8_t pin_len, uint8_t* p_pin) { tBTM_SEC_DEV_REC* p_dev_rec; - LOG_VERBOSE( - "BTM_PINCodeReply(): PairState: %s PairFlags: 0x%02x PinLen:%d " - "Result:%d", + log::verbose( + "BTM_PINCodeReply(): PairState: {} PairFlags: 0x{:02x} PinLen:{} " + "Result:{}", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), btm_sec_cb.pairing_flags, pin_len, res); /* If timeout already expired or has been canceled, ignore the reply */ if (btm_sec_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_PIN) { - LOG_WARN("BTM_PINCodeReply() - Wrong State: %d", btm_sec_cb.pairing_state); + log::warn("BTM_PINCodeReply() - Wrong State: {}", btm_sec_cb.pairing_state); return; } if (bd_addr != btm_sec_cb.pairing_bda) { - LOG_ERROR("BTM_PINCodeReply() - Wrong BD Addr"); + log::error("BTM_PINCodeReply() - Wrong BD Addr"); return; } p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_ERROR("BTM_PINCodeReply() - no dev CB"); + log::error("BTM_PINCodeReply() - no dev CB"); return; } @@ -555,7 +663,7 @@ void BTM_PINCodeReply(const RawAddress& bd_addr, tBTM_STATUS res, * HCI_Connection_Complete event */ /* before originating */ if (btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) { - LOG_WARN( + log::warn( "BTM_PINCodeReply(): waiting HCI_Connection_Complete after rejected " "incoming connection"); /* we change state little bit early so btm_sec_connected() will originate @@ -565,7 +673,7 @@ void BTM_PINCodeReply(const RawAddress& bd_addr, tBTM_STATUS res, } /* if we already accepted incoming connection from pairing device */ else if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND) { - LOG_WARN( + log::warn( "BTM_PINCodeReply(): link is connecting so wait pin code request " "from peer"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ); @@ -601,28 +709,28 @@ tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, tBT_TRANSPORT transport) { tBTM_SEC_DEV_REC* p_dev_rec; tBTM_STATUS status; - LOG_INFO("Transport used %d, bd_addr=%s", transport, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Transport used {}, bd_addr={}", transport, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); /* Other security process is in progress */ if (btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE) { - LOG_ERROR("BTM_SecBond: already busy in state: %s", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); + log::error("BTM_SecBond: already busy in state: {}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); return (BTM_WRONG_MODE); } p_dev_rec = btm_find_or_alloc_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_ERROR("No memory to allocate new p_dev_rec"); + log::error("No memory to allocate new p_dev_rec"); return (BTM_NO_RESOURCES); } if (!controller_get_interface()->get_is_ready()) { - LOG_ERROR("controller module is not ready"); + log::error("controller module is not ready"); return (BTM_NO_RESOURCES); } - LOG_VERBOSE("before update sec_flags=0x%x", p_dev_rec->sec_rec.sec_flags); + log::verbose("before update sec_flags=0x{:x}", p_dev_rec->sec_rec.sec_flags); /* Finished if connection is active and already paired */ if (((p_dev_rec->hci_handle != HCI_INVALID_HANDLE) && @@ -631,13 +739,13 @@ tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, ((p_dev_rec->ble_hci_handle != HCI_INVALID_HANDLE) && transport == BT_TRANSPORT_LE && (p_dev_rec->sec_rec.sec_flags & BTM_SEC_LE_AUTHENTICATED))) { - LOG_WARN("BTM_SecBond -> Already Paired"); + log::warn("BTM_SecBond -> Already Paired"); return (BTM_SUCCESS); } /* Tell controller to get rid of the link key if it has one stored */ if ((BTM_DeleteStoredLinkKey(&bd_addr, NULL)) != BTM_SUCCESS) { - LOG_ERROR("Failed to delete stored link keys"); + log::error("Failed to delete stored link keys"); return (BTM_NO_RESOURCES); } @@ -670,8 +778,8 @@ tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED | BTM_SEC_LINK_KEY_AUTHED); - LOG_VERBOSE("after update sec_flags=0x%x", p_dev_rec->sec_rec.sec_flags); - if (!controller_get_interface()->supports_simple_pairing()) { + log::verbose("after update sec_flags=0x{:x}", p_dev_rec->sec_rec.sec_flags); + if (!bluetooth::shim::GetController()->SupportsSimplePairing()) { /* The special case when we authenticate keyboard. Set pin type to fixed */ /* It would be probably better to do it from the application, but it is */ /* complicated */ @@ -684,8 +792,8 @@ tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, } } - LOG_VERBOSE("BTM_SecBond: Remote sm4: 0x%x HCI Handle: 0x%04x", - p_dev_rec->sm4, p_dev_rec->hci_handle); + log::verbose("BTM_SecBond: Remote sm4: 0x{:x} HCI Handle: 0x{:04x}", + p_dev_rec->sm4, p_dev_rec->hci_handle); #if (BTM_SEC_FORCE_RNR_FOR_DBOND == TRUE) p_dev_rec->sec_rec.sec_flags &= ~BTM_SEC_NAME_KNOWN; @@ -702,8 +810,9 @@ tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, return (BTM_CMD_STARTED); } - LOG_VERBOSE("sec mode: %d sm4:x%x", btm_sec_cb.security_mode, p_dev_rec->sm4); - if (!controller_get_interface()->supports_simple_pairing() || + log::verbose("sec mode: {} sm4:x{:x}", btm_sec_cb.security_mode, + p_dev_rec->sm4); + if (!bluetooth::shim::GetController()->SupportsSimplePairing() || (p_dev_rec->sm4 == BTM_SM4_KNOWN)) { if (btm_sec_check_prefetch_pin(p_dev_rec)) return (BTM_CMD_STARTED); } @@ -722,17 +831,18 @@ tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ); status = BTM_CMD_STARTED; } - LOG_VERBOSE("State:%s sm4: 0x%x sec_state:%d", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - p_dev_rec->sm4, p_dev_rec->sec_rec.sec_state); + log::verbose("State:{} sm4: 0x{:x} sec_state:{}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + p_dev_rec->sm4, p_dev_rec->sec_rec.sec_state); } else { /* both local and peer are 2.1 */ status = btm_sec_dd_create_conn(p_dev_rec); } if (status != BTM_CMD_STARTED) { - LOG_ERROR("BTM_ReadRemoteDeviceName or btm_sec_dd_create_conn error: 0x%x", - (int)status); + log::error( + "BTM_ReadRemoteDeviceName or btm_sec_dd_create_conn error: 0x{:x}", + (int)status); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); } @@ -759,7 +869,7 @@ tBTM_STATUS BTM_SecBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, transport = BTM_UseLeLink(bd_addr) ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR; } else { - LOG_INFO("Forcing transport LE (was auto) because of the address type"); + log::info("Forcing transport LE (was auto) because of the address type"); transport = BT_TRANSPORT_LE; } } @@ -770,7 +880,7 @@ tBTM_STATUS BTM_SecBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, if ((transport == BT_TRANSPORT_LE && (dev_type & BT_DEVICE_TYPE_BLE) == 0) || (transport == BT_TRANSPORT_BR_EDR && (dev_type & BT_DEVICE_TYPE_BREDR) == 0)) { - LOG_WARN( + log::warn( "Can't start bonding - requested transport and transport we've seen " "device on don't match"); return BTM_ILLEGAL_ACTION; @@ -792,9 +902,9 @@ tBTM_STATUS BTM_SecBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, tBTM_STATUS BTM_SecBondCancel(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_dev_rec; - LOG_VERBOSE("BTM_SecBondCancel() State: %s flags:0x%x", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - btm_sec_cb.pairing_flags); + log::verbose("BTM_SecBondCancel() State: {} flags:0x{:x}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + btm_sec_cb.pairing_flags); p_dev_rec = btm_find_dev(bd_addr); if (!p_dev_rec || btm_sec_cb.pairing_bda != bd_addr) { return BTM_UNKNOWN_ADDR; @@ -802,7 +912,7 @@ tBTM_STATUS BTM_SecBondCancel(const RawAddress& bd_addr) { if (btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_LE_ACTIVE) { if (p_dev_rec->sec_rec.sec_state == BTM_SEC_STATE_AUTHENTICATING) { - LOG_VERBOSE("Cancel LE pairing"); + log::verbose("Cancel LE pairing"); if (SMP_PairCancel(bd_addr)) { return BTM_CMD_STARTED; } @@ -810,8 +920,8 @@ tBTM_STATUS BTM_SecBondCancel(const RawAddress& bd_addr) { return BTM_WRONG_MODE; } - LOG_VERBOSE("hci_handle:0x%x sec_state:%d", p_dev_rec->hci_handle, - p_dev_rec->sec_rec.sec_state); + log::verbose("hci_handle:0x{:x} sec_state:{}", p_dev_rec->hci_handle, + p_dev_rec->sec_rec.sec_state); if (BTM_PAIR_STATE_WAIT_LOCAL_PIN == btm_sec_cb.pairing_state && BTM_PAIR_FLAGS_WE_STARTED_DD & btm_sec_cb.pairing_flags) { /* pre-fetching pin for dedicated bonding */ @@ -913,7 +1023,7 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, tBTM_BLE_SEC_ACT sec_act) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == nullptr) { - LOG_ERROR("Unable to set encryption for unknown device"); + log::error("Unable to set encryption for unknown device"); return BTM_WRONG_MODE; } @@ -922,10 +1032,11 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, switch (transport) { case BT_TRANSPORT_BR_EDR: if (p_dev_rec->hci_handle == HCI_INVALID_HANDLE) { - LOG_WARN( - "Security Manager: BTM_SetEncryption not connected peer:%s " - "transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport).c_str()); + log::warn( + "Security Manager: BTM_SetEncryption not connected peer:{} " + "transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport).c_str()); if (p_callback) { do_in_main_thread( FROM_HERE, base::BindOnce(p_callback, std::move(owned_bd_addr), @@ -934,10 +1045,11 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, return BTM_WRONG_MODE; } if (p_dev_rec->sec_rec.sec_flags & BTM_SEC_ENCRYPTED) { - LOG_DEBUG( - "Security Manager: BTM_SetEncryption already encrypted peer:%s " - "transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport).c_str()); + log::debug( + "Security Manager: BTM_SetEncryption already encrypted peer:{} " + "transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport).c_str()); if (p_callback) { do_in_main_thread(FROM_HERE, base::BindOnce(p_callback, std::move(owned_bd_addr), @@ -949,10 +1061,11 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, case BT_TRANSPORT_LE: if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) { - LOG_WARN( - "Security Manager: BTM_SetEncryption not connected peer:%s " - "transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport).c_str()); + log::warn( + "Security Manager: BTM_SetEncryption not connected peer:{} " + "transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport).c_str()); if (p_callback) { do_in_main_thread( FROM_HERE, base::BindOnce(p_callback, std::move(owned_bd_addr), @@ -961,10 +1074,11 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, return BTM_WRONG_MODE; } if (p_dev_rec->sec_rec.sec_flags & BTM_SEC_LE_ENCRYPTED) { - LOG_DEBUG( - "Security Manager: BTM_SetEncryption already encrypted peer:%s " - "transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport).c_str()); + log::debug( + "Security Manager: BTM_SetEncryption already encrypted peer:{} " + "transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport).c_str()); if (p_callback) { do_in_main_thread(FROM_HERE, base::BindOnce(p_callback, std::move(owned_bd_addr), @@ -975,7 +1089,7 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, break; default: - LOG_ERROR("Unknown transport"); + log::error("Unknown transport"); break; } @@ -1011,8 +1125,8 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, } if (enqueue) { - LOG_WARN("Security Manager: Enqueue request in state:%s", - security_state_text(p_dev_rec->sec_rec.sec_state).c_str()); + log::warn("Security Manager: Enqueue request in state:{}", + security_state_text(p_dev_rec->sec_rec.sec_state).c_str()); btm_sec_queue_encrypt_request(bd_addr, transport, p_callback, p_ref_data, sec_act); return BTM_CMD_STARTED; @@ -1020,10 +1134,10 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, } else { if (p_dev_rec->sec_rec.p_callback || (p_dev_rec->sec_rec.sec_state != BTM_SEC_STATE_IDLE)) { - LOG_WARN("Security Manager: BTM_SetEncryption busy, enqueue request"); + log::warn("Security Manager: BTM_SetEncryption busy, enqueue request"); btm_sec_queue_encrypt_request(bd_addr, transport, p_callback, p_ref_data, sec_act); - LOG_INFO("Queued start encryption"); + log::info("Queued start encryption"); return BTM_CMD_STARTED; } } @@ -1034,10 +1148,10 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT); p_dev_rec->is_originator = false; - LOG_DEBUG( - "Security Manager: BTM_SetEncryption classic_handle:0x%04x " - "ble_handle:0x%04x state:%d flags:0x%x " - "required:0x%x p_callback=%c", + log::debug( + "Security Manager: BTM_SetEncryption classic_handle:0x{:04x} " + "ble_handle:0x{:04x} state:{} flags:0x{:x} required:0x{:x} " + "p_callback={:c}", p_dev_rec->hci_handle, p_dev_rec->ble_hci_handle, p_dev_rec->sec_rec.sec_state, p_dev_rec->sec_rec.sec_flags, p_dev_rec->sec_rec.security_required, (p_callback) ? 'T' : 'F'); @@ -1050,7 +1164,7 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, L2CA_GetBleConnRole(bd_addr)); } else { rc = BTM_WRONG_MODE; - LOG_WARN("cannot call btm_ble_set_encryption, p is NULL"); + log::warn("cannot call btm_ble_set_encryption, p is NULL"); } break; @@ -1059,7 +1173,7 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, break; default: - LOG_ERROR("Unknown transport"); + log::error("Unknown transport"); break; } @@ -1070,9 +1184,9 @@ tBTM_STATUS BTM_SetEncryption(const RawAddress& bd_addr, default: if (p_callback) { - LOG_DEBUG("Executing encryption callback peer:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport).c_str()); + log::debug("Executing encryption callback peer:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(transport).c_str()); p_dev_rec->sec_rec.p_callback = nullptr; do_in_main_thread( FROM_HERE, @@ -1134,8 +1248,8 @@ static tBTM_STATUS btm_sec_send_hci_disconnect(tBTM_SEC_DEV_REC* p_dev_rec, break; } - LOG_DEBUG("Send hci disconnect handle:0x%04x reason:%s", conn_handle, - hci_reason_code_text(reason).c_str()); + log::debug("Send hci disconnect handle:0x{:04x} reason:{}", conn_handle, + hci_reason_code_text(reason).c_str()); acl_disconnect_after_role_switch(conn_handle, reason, comment); return status; @@ -1154,14 +1268,15 @@ static tBTM_STATUS btm_sec_send_hci_disconnect(tBTM_SEC_DEV_REC* p_dev_rec, * ******************************************************************************/ void BTM_ConfirmReqReply(tBTM_STATUS res, const RawAddress& bd_addr) { - LOG_VERBOSE("BTM_ConfirmReqReply() State: %s Res: %u", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), res); + log::verbose("BTM_ConfirmReqReply() State: {} Res: {}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + res); /* If timeout already expired or has been canceled, ignore the reply */ if ((btm_sec_cb.pairing_state != BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM) || (btm_sec_cb.pairing_bda != bd_addr)) { - LOG_WARN( - "Unexpected pairing confirm for %s, pairing_state: %s, pairing_bda: %s", + log::warn( + "Unexpected pairing confirm for {}, pairing_state: {}, pairing_bda: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), ADDRESS_TO_LOGGABLE_CSTR(btm_sec_cb.pairing_bda)); @@ -1201,8 +1316,9 @@ void BTM_ConfirmReqReply(tBTM_STATUS res, const RawAddress& bd_addr) { ******************************************************************************/ void BTM_PasskeyReqReply(tBTM_STATUS res, const RawAddress& bd_addr, uint32_t passkey) { - LOG_VERBOSE("BTM_PasskeyReqReply: State: %s res:%d", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), res); + log::verbose("BTM_PasskeyReqReply: State: {} res:{}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + res); if ((btm_sec_cb.pairing_state == BTM_PAIR_STATE_IDLE) || (btm_sec_cb.pairing_bda != bd_addr)) { @@ -1271,8 +1387,9 @@ void BTM_ReadLocalOobData(void) { btsnd_hcic_read_local_oob_data(); } ******************************************************************************/ void BTM_RemoteOobDataReply(tBTM_STATUS res, const RawAddress& bd_addr, const Octet16& c, const Octet16& r) { - LOG_VERBOSE("State: %s res: %d", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), res); + log::verbose("State: {} res: {}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + res); /* If timeout already expired or has been canceled, ignore the reply */ if (btm_sec_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP) return; @@ -1305,7 +1422,7 @@ void BTM_RemoteOobDataReply(tBTM_STATUS res, const RawAddress& bd_addr, * ******************************************************************************/ bool BTM_BothEndsSupportSecureConnections(const RawAddress& bd_addr) { - return ((controller_get_interface()->supports_secure_connections()) && + return ((bluetooth::shim::GetController()->SupportsSecureConnections()) && (BTM_PeerSupportsSecureConnections(bd_addr))); } @@ -1327,7 +1444,7 @@ bool BTM_PeerSupportsSecureConnections(const RawAddress& bd_addr) { p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_WARN("unknown BDA: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("unknown BDA: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } @@ -1352,7 +1469,7 @@ bool BTM_PeerSupportsSecureConnections(const RawAddress& bd_addr) { tBT_DEVICE_TYPE BTM_GetPeerDeviceTypeFromFeatures(const RawAddress& bd_addr) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == nullptr) { - LOG_WARN("Unknown BDA:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Unknown BDA:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } else { if (p_dev_rec->remote_supports_ble && p_dev_rec->remote_supports_bredr) { return BT_DEVICE_TYPE_DUMO; @@ -1361,8 +1478,8 @@ tBT_DEVICE_TYPE BTM_GetPeerDeviceTypeFromFeatures(const RawAddress& bd_addr) { } else if (p_dev_rec->remote_supports_ble) { return BT_DEVICE_TYPE_BLE; } else { - LOG_WARN("Device features does not support BR/EDR and BLE:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Device features does not support BR/EDR and BLE:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } return BT_DEVICE_TYPE_BREDR; @@ -1422,8 +1539,8 @@ static bool btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC* p_dev_rec, is_possible = true; } } - LOG_VERBOSE("is_possible: %d sec_flags: 0x%x", is_possible, - p_dev_rec->sec_rec.sec_flags); + log::verbose("is_possible: {} sec_flags: 0x{:x}", is_possible, + p_dev_rec->sec_rec.sec_flags); return is_possible; } @@ -1439,13 +1556,14 @@ static bool btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC* p_dev_rec, ******************************************************************************/ static void btm_sec_check_upgrade(tBTM_SEC_DEV_REC* p_dev_rec, bool is_originator) { - LOG_VERBOSE("verify whether the link key should be upgraded"); + log::verbose("verify whether the link key should be upgraded"); /* Only check if link key already exists */ if (!(p_dev_rec->sec_rec.sec_flags & BTM_SEC_LINK_KEY_KNOWN)) return; if (btm_sec_is_upgrade_possible(p_dev_rec, is_originator)) { - LOG_VERBOSE("need upgrade!! sec_flags:0x%x", p_dev_rec->sec_rec.sec_flags); + log::verbose("need upgrade!! sec_flags:0x{:x}", + p_dev_rec->sec_rec.sec_flags); /* if the application confirms the upgrade, set the upgrade bit */ p_dev_rec->sm4 |= BTM_SM4_UPGRADE; @@ -1453,16 +1571,16 @@ static void btm_sec_check_upgrade(tBTM_SEC_DEV_REC* p_dev_rec, p_dev_rec->sec_rec.sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED); p_dev_rec->sec_rec.sec_flags &= ~BTM_SEC_AUTHENTICATED; - LOG_VERBOSE("sec_flags:0x%x", p_dev_rec->sec_rec.sec_flags); + log::verbose("sec_flags:0x{:x}", p_dev_rec->sec_rec.sec_flags); } } tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( const RawAddress& bd_addr, uint16_t security_required, bool is_originator, tBTM_SEC_CALLBACK* p_callback, void* p_ref_data) { - LOG_DEBUG( - "Checking l2cap access requirements peer:%s security:0x%x " - "is_initiator:%s", + log::debug( + "Checking l2cap access requirements peer:{} security:0x{:x} " + "is_initiator:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), security_required, logbool(is_originator).c_str()); @@ -1478,13 +1596,13 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( if ((!is_originator) && (security_required & BTM_SEC_MODE4_LEVEL4)) { bool local_supports_sc = - controller_get_interface()->supports_secure_connections(); + bluetooth::shim::GetController()->SupportsSecureConnections(); /* acceptor receives L2CAP Channel Connect Request for Secure Connections * Only service */ if (!local_supports_sc || !p_dev_rec->SupportsSecureConnections()) { - LOG_WARN( - "Policy requires mode 4 level 4, but local_support_for_sc=%d, " - "rmt_support_for_sc=%s, failing connection", + log::warn( + "Policy requires mode 4 level 4, but local_support_for_sc={}, " + "rmt_support_for_sc={}, failing connection", local_supports_sc, logbool(p_dev_rec->SupportsSecureConnections()).c_str()); if (p_callback) { @@ -1501,8 +1619,8 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( /* we will process one after another */ if ((p_dev_rec->sec_rec.p_callback) || (btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE)) { - LOG_DEBUG("security_flags:x%x, sec_flags:x%x", security_required, - p_dev_rec->sec_rec.sec_flags); + log::debug("security_flags:x{:x}, sec_flags:x{:x}", security_required, + p_dev_rec->sec_rec.sec_flags); rc = BTM_CMD_STARTED; if ((btm_sec_cb.security_mode == BTM_SEC_MODE_SERVICE) || (BTM_SM4_KNOWN == p_dev_rec->sm4) || @@ -1545,7 +1663,9 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( if (rc == BTM_SUCCESS) { if (access_secure_service_from_temp_bond(p_dev_rec, is_originator, security_required)) { - LOG_ERROR("Trying to access a secure service from a temp bonding, rejecting"); + log::error( + "Trying to access a secure service from a temp bonding, " + "rejecting"); rc = BTM_FAILED_ON_SECURITY; } @@ -1579,8 +1699,8 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( } } else if (!(BTM_SM4_KNOWN & p_dev_rec->sm4)) { /* the remote features are not known yet */ - LOG_DEBUG( - "Remote features have not yet been received sec_flags:0x%02x %s", + log::debug( + "Remote features have not yet been received sec_flags:0x{:02x} {}", p_dev_rec->sec_rec.sec_flags, (is_originator) ? "initiator" : "acceptor"); @@ -1589,18 +1709,18 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( } } - LOG_VERBOSE("sm4:0x%x, sec_flags:0x%x, security_required:0x%x chk:%d", - p_dev_rec->sm4, p_dev_rec->sec_rec.sec_flags, security_required, - chk_acp_auth_done); + log::verbose("sm4:0x{:x}, sec_flags:0x{:x}, security_required:0x{:x} chk:{}", + p_dev_rec->sm4, p_dev_rec->sec_rec.sec_flags, security_required, + chk_acp_auth_done); p_dev_rec->sec_rec.security_required = security_required; p_dev_rec->sec_rec.p_ref_data = p_ref_data; p_dev_rec->is_originator = is_originator; if (chk_acp_auth_done) { - LOG_VERBOSE( - "(SM4 to SM4) btm_sec_l2cap_access_req rspd. authenticated: x%x, enc: " - "x%x", + log::verbose( + "(SM4 to SM4) btm_sec_l2cap_access_req rspd. authenticated: x{:x}, " + "enc: x{:x}", (p_dev_rec->sec_rec.sec_flags & BTM_SEC_AUTHENTICATED), (p_dev_rec->sec_rec.sec_flags & BTM_SEC_ENCRYPTED)); /* SM4, but we do not know for sure which level of security we need. @@ -1613,7 +1733,7 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( sequence because of data path issues. Delay this disconnect a little bit */ - LOG_INFO( + log::info( "peer should have initiated security process by now (SM4 to SM4)"); p_dev_rec->sec_rec.p_callback = p_callback; p_dev_rec->sec_rec.sec_state = BTM_SEC_STATE_DELAY_FOR_ENC; @@ -1636,7 +1756,7 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( p_dev_rec->sec_rec.sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED | BTM_SEC_AUTHENTICATED); - LOG_VERBOSE("sec_flags:0x%x", p_dev_rec->sec_rec.sec_flags); + log::verbose("sec_flags:0x{:x}", p_dev_rec->sec_rec.sec_flags); } else { /* If we already have a link key to the connected peer, is it secure * enough? */ @@ -1646,8 +1766,8 @@ tBTM_STATUS btm_sec_l2cap_access_req_by_requirement( rc = btm_sec_execute_procedure(p_dev_rec); if (rc != BTM_CMD_STARTED) { - LOG_VERBOSE("p_dev_rec=%p, clearing callback. old p_callback=%p", p_dev_rec, - p_dev_rec->sec_rec.p_callback); + log::verbose("p_dev_rec={}, clearing callback. old p_callback={}", + fmt::ptr(p_dev_rec), fmt::ptr(p_dev_rec->sec_rec.p_callback)); p_dev_rec->sec_rec.p_callback = NULL; (*p_callback)(&bd_addr, transport, p_dev_rec->sec_rec.p_ref_data, rc); } @@ -1680,7 +1800,7 @@ tBTM_STATUS btm_sec_l2cap_access_req(const RawAddress& bd_addr, uint16_t psm, // should check PSM range in LE connection oriented L2CAP connection constexpr tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; - LOG_DEBUG("is_originator:%d, psm=0x%04x", is_originator, psm); + log::debug("is_originator:{}, psm=0x{:04x}", is_originator, psm); // Find the service record for the PSM tBTM_SEC_SERV_REC* p_serv_rec = @@ -1688,14 +1808,14 @@ tBTM_STATUS btm_sec_l2cap_access_req(const RawAddress& bd_addr, uint16_t psm, // If there is no application registered with this PSM do not allow connection if (!p_serv_rec) { - LOG_WARN("PSM: 0x%04x no application registered", psm); + log::warn("PSM: 0x{:04x} no application registered", psm); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED); return (BTM_MODE_UNSUPPORTED); } /* Services level0 by default have no security */ if (psm == BT_PSM_SDP) { - LOG_DEBUG("No security required for SDP"); + log::debug("No security required for SDP"); (*p_callback)(&bd_addr, transport, p_ref_data, BTM_SUCCESS_NO_SECURITY); return (BTM_SUCCESS); } @@ -1744,7 +1864,8 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, tBTM_STATUS rc; bool transport = false; /* should check PSM range in LE connection oriented L2CAP connection */ - LOG_DEBUG("Multiplex access request device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Multiplex access request device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); /* Find or get oldest record */ p_dev_rec = btm_find_or_alloc_dev(bd_addr); @@ -1754,8 +1875,8 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, /* we will process one after another */ if ((p_dev_rec->sec_rec.p_callback) || (btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE)) { - LOG_DEBUG("Pairing in progress pairing_state:%s", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); + log::debug("Pairing in progress pairing_state:{}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); rc = BTM_CMD_STARTED; @@ -1800,7 +1921,7 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, /* the new security request */ if (p_dev_rec->sec_rec.sec_state != BTM_SEC_STATE_IDLE) { - LOG_DEBUG("A pending security procedure in progress"); + log::debug("A pending security procedure in progress"); rc = BTM_CMD_STARTED; } if (rc == BTM_CMD_STARTED) { @@ -1810,11 +1931,13 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, { if (access_secure_service_from_temp_bond(p_dev_rec, is_originator, security_required)) { - LOG_ERROR("Trying to access a secure rfcomm service from a temp bonding, rejecting"); + log::error( + "Trying to access a secure rfcomm service from a temp bonding, " + "rejecting"); rc = BTM_FAILED_ON_SECURITY; } if (p_callback) { - LOG_DEBUG("Notifying client that security access has been granted"); + log::debug("Notifying client that security access has been granted"); (*p_callback)(&bd_addr, transport, p_ref_data, rc); } } @@ -1824,13 +1947,13 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, if ((!is_originator) && ((security_required & BTM_SEC_MODE4_LEVEL4) || (btm_sec_cb.security_mode == BTM_SEC_MODE_SC))) { bool local_supports_sc = - controller_get_interface()->supports_secure_connections(); + bluetooth::shim::GetController()->SupportsSecureConnections(); /* acceptor receives service connection establishment Request for */ /* Secure Connections Only service */ if (!(local_supports_sc) || !(p_dev_rec->SupportsSecureConnections())) { - LOG_DEBUG( - "Secure Connection only mode unsupported local_SC_support:%s" - " remote_SC_support:%s", + log::debug( + "Secure Connection only mode unsupported local_SC_support:{} " + "remote_SC_support:{}", logbool(local_supports_sc).c_str(), logbool(p_dev_rec->SupportsSecureConnections()).c_str()); if (p_callback) @@ -1865,9 +1988,9 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, p_dev_rec->sec_rec.sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED | BTM_SEC_AUTHENTICATED); - LOG_VERBOSE("sec_flags:0x%x", p_dev_rec->sec_rec.sec_flags); + log::verbose("sec_flags:0x{:x}", p_dev_rec->sec_rec.sec_flags); } else { - LOG_DEBUG("Already have link key; checking if link key is sufficient"); + log::debug("Already have link key; checking if link key is sufficient"); btm_sec_check_upgrade(p_dev_rec, is_originator); } } @@ -1878,9 +2001,9 @@ tBTM_STATUS btm_sec_mx_access_request(const RawAddress& bd_addr, p_dev_rec->sec_rec.p_ref_data = p_ref_data; rc = btm_sec_execute_procedure(p_dev_rec); - LOG_DEBUG("Started security procedure peer:%s btm_status:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->RemoteAddress()), - btm_status_text(rc).c_str()); + log::debug("Started security procedure peer:{} btm_status:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->RemoteAddress()), + btm_status_text(rc).c_str()); if (rc != BTM_CMD_STARTED) { if (p_callback) { p_dev_rec->sec_rec.p_callback = NULL; @@ -1907,7 +2030,8 @@ void btm_sec_conn_req(const RawAddress& bda, const DEV_CLASS dc) { if ((btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE) && (btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) && (btm_sec_cb.pairing_bda == bda)) { - LOG_VERBOSE("Security Manager: reject connect request from bonding device"); + log::verbose( + "Security Manager: reject connect request from bonding device"); /* incoming connection from bonding device is rejected */ btm_sec_cb.pairing_flags |= BTM_PAIR_FLAGS_REJECTED_CONNECT; @@ -1918,7 +2042,7 @@ void btm_sec_conn_req(const RawAddress& bda, const DEV_CLASS dc) { /* Host is not interested or approved connection. Save BDA and DC and */ /* pass request to L2CAP */ btm_sec_cb.connecting_bda = bda; - memcpy(btm_sec_cb.connecting_dc, dc, DEV_CLASS_LEN); + btm_sec_cb.connecting_dc = dc; p_dev_rec = btm_find_or_alloc_dev(bda); p_dev_rec->sm4 |= BTM_SM4_CONN_PEND; @@ -1973,9 +2097,9 @@ static void btm_sec_bond_cancel_complete(void) { * ******************************************************************************/ void btm_create_conn_cancel_complete(uint8_t status, const RawAddress bd_addr) { - LOG_VERBOSE("btm_create_conn_cancel_complete(): in State: %s status:%d", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - status); + log::verbose("btm_create_conn_cancel_complete(): in State: {} status:{}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + status); log_link_layer_connection_event( &bd_addr, bluetooth::common::kUnknownConnectionHandle, android::bluetooth::DIRECTION_OUTGOING, android::bluetooth::LINK_TYPE_ACL, @@ -2030,7 +2154,7 @@ void btm_sec_check_pending_reqs(void) { /* Check that the ACL is still up before starting security procedures */ if (BTM_IsAclConnectionUp(p_e->bd_addr, p_e->transport)) { if (p_e->psm != 0) { - LOG_VERBOSE("PSM:0x%04x Is_Orig:%u", p_e->psm, p_e->is_orig); + log::verbose("PSM:0x{:04x} Is_Orig:{}", p_e->psm, p_e->is_orig); btm_sec_mx_access_request(p_e->bd_addr, p_e->is_orig, p_e->rfcomm_security_requirement, @@ -2057,7 +2181,7 @@ void btm_sec_check_pending_reqs(void) { * ******************************************************************************/ void btm_sec_dev_reset(void) { - ASSERT_LOG(controller_get_interface()->supports_simple_pairing(), + ASSERT_LOG(bluetooth::shim::GetController()->SupportsSimplePairing(), "only controllers with SSP is supported"); /* set the default IO capabilities */ @@ -2067,7 +2191,7 @@ void btm_sec_dev_reset(void) { BTM_SEC_NONE, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, 0); BTM_SetSecurityLevel(true, "RFC_MUX", BTM_SEC_SERVICE_RFC_MUX, BTM_SEC_NONE, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, 0); - LOG_VERBOSE("btm_sec_dev_reset sec mode: %d", btm_sec_cb.security_mode); + log::verbose("btm_sec_dev_reset sec mode: {}", btm_sec_cb.security_mode); } /******************************************************************************* @@ -2093,8 +2217,8 @@ void btm_sec_abort_access_req(const RawAddress& bd_addr) { p_dev_rec->sec_rec.sec_state = BTM_SEC_STATE_IDLE; - LOG_VERBOSE("clearing callback. p_dev_rec=%p, p_callback=%p", p_dev_rec, - p_dev_rec->sec_rec.p_callback); + log::verbose("clearing callback. p_dev_rec={}, p_callback={}", + fmt::ptr(p_dev_rec), fmt::ptr(p_dev_rec->sec_rec.p_callback)); p_dev_rec->sec_rec.p_callback = NULL; } @@ -2126,8 +2250,8 @@ static tBTM_STATUS btm_sec_dd_create_conn(tBTM_SEC_DEV_REC* p_dev_rec) { /* set up the control block to indicated dedicated bonding */ btm_sec_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE; - LOG_INFO("Security Manager: %s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); + log::info("Security Manager: {}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ); @@ -2135,7 +2259,7 @@ static tBTM_STATUS btm_sec_dd_create_conn(tBTM_SEC_DEV_REC* p_dev_rec) { } static void call_registered_rmt_name_callbacks(const RawAddress* p_bd_addr, - uint8_t* pdev_class, + const DEV_CLASS& dev_class, uint8_t* p_bd_name, tHCI_STATUS status) { int i; @@ -2143,14 +2267,11 @@ static void call_registered_rmt_name_callbacks(const RawAddress* p_bd_addr, if (p_bd_addr == nullptr) { // TODO Still need to send status back to get SDP state machine // running - LOG_ERROR("Unable to issue callback with unknown address status:%s", - hci_status_code_text(status).c_str()); + log::error("Unable to issue callback with unknown address status:{}", + hci_status_code_text(status).c_str()); return; } - if (pdev_class == nullptr) { - pdev_class = (uint8_t*)kDevClassEmpty; - } if (p_bd_name == nullptr) { p_bd_name = (uint8_t*)kBtmBdNameEmpty; } @@ -2159,7 +2280,7 @@ static void call_registered_rmt_name_callbacks(const RawAddress* p_bd_addr, * clients can continue */ for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++) { if (btm_cb.p_rmt_name_callback[i]) { - (*btm_cb.p_rmt_name_callback[i])(*p_bd_addr, pdev_class, p_bd_name); + (*btm_cb.p_rmt_name_callback[i])(*p_bd_addr, dev_class, p_bd_name); } } } @@ -2180,13 +2301,14 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, tBTM_SEC_DEV_REC* p_dev_rec = nullptr; uint8_t old_sec_state; - LOG_INFO("btm_sec_rmt_name_request_complete for %s", - p_bd_addr ? ADDRESS_TO_LOGGABLE_CSTR(*p_bd_addr) : "null"); + log::info("btm_sec_rmt_name_request_complete for {}", + p_bd_addr ? ADDRESS_TO_LOGGABLE_CSTR(*p_bd_addr) : "null"); if ((!p_bd_addr && !BTM_IsAclConnectionUp(btm_sec_cb.connecting_bda, BT_TRANSPORT_BR_EDR)) || (p_bd_addr && !BTM_IsAclConnectionUp(*p_bd_addr, BT_TRANSPORT_BR_EDR))) { - LOG_WARN("Remote read request complete with no underlying link connection"); + log::warn( + "Remote read request complete with no underlying link connection"); } /* If remote name request failed, p_bd_addr is null and we need to search */ @@ -2194,7 +2316,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, if (p_bd_addr) p_dev_rec = btm_find_dev(*p_bd_addr); else { - LOG_INFO( + log::info( "Remote read request complete with no address so searching device " "database"); p_dev_rec = btm_sec_find_dev_by_sec_state(BTM_SEC_STATE_GETTING_NAME); @@ -2206,35 +2328,39 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, if (!p_bd_name) p_bd_name = (const uint8_t*)""; if (p_dev_rec == nullptr) { - LOG_DEBUG( - "Remote read request complete for unknown device pairing_state:%s " - "status:%s name:%s", + log::debug( + "Remote read request complete for unknown device pairing_state:{} " + "status:{} name:{}", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - hci_status_code_text(status).c_str(), p_bd_name); + hci_status_code_text(status).c_str(), + reinterpret_cast(p_bd_name)); - call_registered_rmt_name_callbacks(p_bd_addr, nullptr, nullptr, status); + call_registered_rmt_name_callbacks(p_bd_addr, kDevClassEmpty, nullptr, + status); return; } old_sec_state = p_dev_rec->sec_rec.sec_state; if (status == HCI_SUCCESS) { - LOG_DEBUG( - "Remote read request complete for known device pairing_state:%s " - "name:%s sec_state:%s", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), p_bd_name, + log::debug( + "Remote read request complete for known device pairing_state:{} " + "name:{} sec_state:{}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + reinterpret_cast(p_bd_name), security_state_text(p_dev_rec->sec_rec.sec_state).c_str()); strlcpy((char*)p_dev_rec->sec_bd_name, (const char*)p_bd_name, BTM_MAX_REM_BD_NAME_LEN + 1); p_dev_rec->sec_rec.sec_flags |= BTM_SEC_NAME_KNOWN; - LOG_VERBOSE("setting BTM_SEC_NAME_KNOWN sec_flags:0x%x", - p_dev_rec->sec_rec.sec_flags); + log::verbose("setting BTM_SEC_NAME_KNOWN sec_flags:0x{:x}", + p_dev_rec->sec_rec.sec_flags); } else { - LOG_WARN( - "Remote read request failed for known device pairing_state:%s " - "status:%s name:%s sec_state:%s", + log::warn( + "Remote read request failed for known device pairing_state:{} " + "status:{} name:{} sec_state:{}", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - hci_status_code_text(status).c_str(), p_bd_name, + hci_status_code_text(status).c_str(), + reinterpret_cast(p_bd_name), security_state_text(p_dev_rec->sec_rec.sec_state).c_str()); /* Notify all clients waiting for name to be resolved even if it failed so @@ -2253,14 +2379,13 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, * ask now */ if ((btm_sec_cb.pairing_state == BTM_PAIR_STATE_WAIT_LOCAL_PIN) && p_bd_addr && (btm_sec_cb.pairing_bda == *p_bd_addr)) { - LOG_VERBOSE( - "delayed pin now being requested flags:0x%x, " - "(p_pin_callback=0x%p)", - btm_sec_cb.pairing_flags, btm_sec_cb.api.p_pin_callback); + log::verbose( + "delayed pin now being requested flags:0x{:x}, (p_pin_callback=0x{})", + btm_sec_cb.pairing_flags, fmt::ptr(btm_sec_cb.api.p_pin_callback)); if ((btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0 && btm_sec_cb.api.p_pin_callback) { - LOG_VERBOSE("calling pin_callback"); + log::verbose("calling pin_callback"); btm_sec_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD; (*btm_sec_cb.api.p_pin_callback)( p_dev_rec->bd_addr, p_dev_rec->dev_class, p_bd_name, @@ -2276,8 +2401,8 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, /* Check if we were delaying bonding because name was not resolved */ if (btm_sec_cb.pairing_state == BTM_PAIR_STATE_GET_REM_NAME) { if (p_bd_addr && btm_sec_cb.pairing_bda == *p_bd_addr) { - LOG_VERBOSE("continue bonding sm4: 0x%04x, status:0x%x", p_dev_rec->sm4, - status); + log::verbose("continue bonding sm4: 0x{:04x}, status:0x{:x}", + p_dev_rec->sm4, status); if (btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_WE_CANCEL_DD) { btm_sec_bond_cancel_complete(); return; @@ -2295,15 +2420,15 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not * set.*/ /* If it is set, there may be a race condition */ - LOG_VERBOSE("IS_SM4_UNKNOWN Flags:0x%04x", btm_sec_cb.pairing_flags); + log::verbose("IS_SM4_UNKNOWN Flags:0x{:04x}", btm_sec_cb.pairing_flags); if ((btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) == 0) p_dev_rec->sm4 |= BTM_SM4_KNOWN; } - LOG_VERBOSE("SM4 Value: %x, Legacy:%d,IS SM4:%d, Unknown:%d", - p_dev_rec->sm4, BTM_SEC_IS_SM4_LEGACY(p_dev_rec->sm4), - BTM_SEC_IS_SM4(p_dev_rec->sm4), - BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)); + log::verbose("SM4 Value: {:x}, Legacy:{},IS SM4:{}, Unknown:{}", + p_dev_rec->sm4, BTM_SEC_IS_SM4_LEGACY(p_dev_rec->sm4), + BTM_SEC_IS_SM4(p_dev_rec->sm4), + BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)); bool await_connection = true; /* BT 2.1 or carkit, bring up the connection to force the peer to request @@ -2317,7 +2442,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, * HCI_Connection_Complete event */ /* before originating */ if (btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) { - LOG_WARN( + log::warn( "waiting HCI_Connection_Complete after rejecting connection"); } /* Both we and the peer are 2.1 - continue to create connection */ @@ -2326,7 +2451,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, if (req_status == BTM_SUCCESS) { await_connection = false; } else if (req_status != BTM_CMD_STARTED) { - LOG_WARN("failed to start connection"); + log::warn("failed to start connection"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); @@ -2336,14 +2461,14 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, } if (await_connection) { - LOG_DEBUG("Wait for connection to begin pairing"); + log::debug("Wait for connection to begin pairing"); return; } } else { - LOG_WARN("wrong BDA, retry with pairing BDA"); + log::warn("wrong BDA, retry with pairing BDA"); if (BTM_ReadRemoteDeviceName(btm_sec_cb.pairing_bda, NULL, BT_TRANSPORT_BR_EDR) != BTM_CMD_STARTED) { - LOG_ERROR("failed to start remote name request"); + log::error("failed to start remote name request"); NotifyBondingChange(*p_dev_rec, HCI_ERR_MEMORY_FULL); }; return; @@ -2363,7 +2488,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, /* If this is a bonding procedure can disconnect the link now */ if ((btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) && (p_dev_rec->sec_rec.sec_flags & BTM_SEC_AUTHENTICATED)) { - LOG_WARN("btm_sec_rmt_name_request_complete (none/ce)"); + log::warn("btm_sec_rmt_name_request_complete (none/ce)"); p_dev_rec->sec_rec.security_required &= ~(BTM_SEC_OUT_AUTHENTICATE); l2cu_start_post_bond_timer(p_dev_rec->hci_handle); return; @@ -2378,7 +2503,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, } if (p_dev_rec->sm4 & BTM_SM4_REQ_PEND) { - LOG_VERBOSE("waiting for remote features!!"); + log::verbose("waiting for remote features!!"); return; } @@ -2409,19 +2534,20 @@ void btm_sec_rmt_host_support_feat_evt(const RawAddress bd_addr, p_dev_rec = btm_find_or_alloc_dev(bd_addr); - LOG_INFO("Got btm_sec_rmt_host_support_feat_evt from %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Got btm_sec_rmt_host_support_feat_evt from {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); - LOG_VERBOSE("btm_sec_rmt_host_support_feat_evt sm4: 0x%x p[0]: 0x%x", - p_dev_rec->sm4, features_0); + log::verbose("btm_sec_rmt_host_support_feat_evt sm4: 0x{:x} p[0]: 0x{:x}", + p_dev_rec->sm4, features_0); if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)) { p_dev_rec->sm4 = BTM_SM4_KNOWN; if (HCI_SSP_HOST_SUPPORTED((std::array({features_0})))) { p_dev_rec->sm4 = BTM_SM4_TRUE; } - LOG_VERBOSE("btm_sec_rmt_host_support_feat_evt sm4: 0x%x features[0]: 0x%x", - p_dev_rec->sm4, features_0); + log::verbose( + "btm_sec_rmt_host_support_feat_evt sm4: 0x{:x} features[0]: 0x{:x}", + p_dev_rec->sm4, features_0); } } @@ -2438,8 +2564,8 @@ void btm_sec_rmt_host_support_feat_evt(const RawAddress bd_addr, ******************************************************************************/ void btm_io_capabilities_req(RawAddress p) { if (btm_sec_is_a_bonded_dev(p)) { - LOG_WARN("Incoming bond request, but %s is already bonded (removing)", - ADDRESS_TO_LOGGABLE_CSTR(p)); + log::warn("Incoming bond request, but {} is already bonded (removing)", + ADDRESS_TO_LOGGABLE_CSTR(p)); bta_dm_process_remove_device(p); } @@ -2447,9 +2573,9 @@ void btm_io_capabilities_req(RawAddress p) { if ((btm_sec_cb.security_mode == BTM_SEC_MODE_SC) && (!p_dev_rec->remote_feature_received)) { - LOG_VERBOSE( - "Device security mode is SC only." - "To continue need to know remote features."); + log::verbose( + "Device security mode is SC only.To continue need to know remote " + "features."); // ACL calls back to btm_sec_set_peer_sec_caps after it gets data p_dev_rec->remote_features_needed = true; @@ -2469,9 +2595,9 @@ void btm_io_capabilities_req(RawAddress p) { p_dev_rec->sm4 |= BTM_SM4_TRUE; - LOG_VERBOSE("State: %s, Security Mode: %d, Device security Flags: 0x%04x", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - btm_sec_cb.security_mode, btm_sec_cb.pairing_flags); + log::verbose("State: {}, Security Mode: {}, Device security Flags: 0x{:04x}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + btm_sec_cb.security_mode, btm_sec_cb.pairing_flags); uint8_t err_code = 0; bool is_orig = true; @@ -2505,23 +2631,23 @@ void btm_io_capabilities_req(RawAddress p) { /* any other state is unexpected */ default: err_code = HCI_ERR_HOST_BUSY_PAIRING; - LOG_ERROR("Unexpected Pairing state received %d", - btm_sec_cb.pairing_state); + log::error("Unexpected Pairing state received {}", + btm_sec_cb.pairing_state); break; } if (btm_sec_cb.pairing_disabled) { /* pairing is not allowed */ - LOG_VERBOSE("Pairing is not allowed -> fail pairing."); + log::verbose("Pairing is not allowed -> fail pairing."); err_code = HCI_ERR_PAIRING_NOT_ALLOWED; } else if (btm_sec_cb.security_mode == BTM_SEC_MODE_SC) { bool local_supports_sc = - controller_get_interface()->supports_secure_connections(); + bluetooth::shim::GetController()->SupportsSecureConnections(); /* device in Secure Connections Only mode */ if (!(local_supports_sc) || !(p_dev_rec->SupportsSecureConnections())) { - LOG_DEBUG( - "SC only service, local_support_for_sc:%s," - " remote_support_for_sc:%s -> fail pairing", + log::debug( + "SC only service, local_support_for_sc:{}, remote_support_for_sc:{} " + "-> fail pairing", logbool(local_supports_sc).c_str(), logbool(p_dev_rec->SupportsSecureConnections()).c_str()); err_code = HCI_ERR_PAIRING_NOT_ALLOWED; @@ -2560,7 +2686,7 @@ void btm_io_capabilities_req(RawAddress p) { btm_sec_cb.pairing_bda = evt_data.bd_addr; if (evt_data.bd_addr == btm_sec_cb.connecting_bda) - memcpy(p_dev_rec->dev_class, btm_sec_cb.connecting_dc, DEV_CLASS_LEN); + p_dev_rec->dev_class = btm_sec_cb.connecting_dc; btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS); @@ -2585,8 +2711,8 @@ void btm_io_capabilities_req(RawAddress p) { /* At this moment we know that both sides are SC capable, device in */ /* SC only mode requires MITM for any service so let's set MITM bit */ evt_data.auth_req |= BTM_AUTH_YN_BIT; - LOG_VERBOSE("for device in \"SC only\" mode set auth_req to 0x%02x", - evt_data.auth_req); + log::verbose("for device in \"SC only\" mode set auth_req to 0x{:02x}", + evt_data.auth_req); } /* if the user does not indicate "reply later" by setting the oob_data to @@ -2596,9 +2722,9 @@ void btm_io_capabilities_req(RawAddress p) { btm_sec_cb.devcb.loc_auth_req = evt_data.auth_req; btm_sec_cb.devcb.loc_io_caps = evt_data.io_cap; - LOG_VERBOSE("State: %s IO_CAP:%d oob_data:%d auth_req:%d", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - evt_data.io_cap, evt_data.oob_data, evt_data.auth_req); + log::verbose("State: {} IO_CAP:{} oob_data:{} auth_req:{}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + evt_data.io_cap, evt_data.oob_data, evt_data.auth_req); btsnd_hcic_io_cap_req_reply(evt_data.bd_addr, evt_data.io_cap, evt_data.oob_data, evt_data.auth_req); @@ -2636,7 +2762,7 @@ void btm_io_capabilities_rsp(const tBTM_SP_IO_RSP evt_data) { /* We must have a device record here. * Use the connecting device's CoD for the connection */ if (evt_data.bd_addr == btm_sec_cb.connecting_bda) - memcpy(p_dev_rec->dev_class, btm_sec_cb.connecting_dc, DEV_CLASS_LEN); + p_dev_rec->dev_class = btm_sec_cb.connecting_dc; /* peer sets dedicated bonding bit and we did not initiate dedicated bonding */ @@ -2677,16 +2803,16 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda, tBTM_SEC_DEV_REC* p_dev_rec; p_bda = bda; - LOG_VERBOSE("BDA: %s, event: 0x%x, state: %s", - ADDRESS_TO_LOGGABLE_CSTR(p_bda), event, - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); + log::debug("BDA:{}, event:{}, state:{}", ADDRESS_TO_LOGGABLE_CSTR(p_bda), + sp_evt_to_text(event).c_str(), + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); p_dev_rec = btm_find_dev(p_bda); if ((p_dev_rec != NULL) && (btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE) && (btm_sec_cb.pairing_bda == p_bda)) { evt_data.cfm_req.bd_addr = p_dev_rec->bd_addr; - memcpy(evt_data.cfm_req.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN); + evt_data.cfm_req.dev_class = p_dev_rec->dev_class; strlcpy((char*)evt_data.cfm_req.bd_name, (char*)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN + 1); @@ -2698,17 +2824,16 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda, /* The device record must be allocated in the "IO cap exchange" step */ evt_data.cfm_req.num_val = value; - LOG_VERBOSE("BTM_SP_CFM_REQ_EVT: num_val: %u", - evt_data.cfm_req.num_val); + log::verbose("num_val:{}", evt_data.cfm_req.num_val); evt_data.cfm_req.just_works = true; /* process user confirm req in association with the auth_req param */ if (btm_sec_cb.devcb.loc_io_caps == BTM_IO_CAP_IO) { if (p_dev_rec->sec_rec.rmt_io_caps == BTM_IO_CAP_UNKNOWN) { - LOG_ERROR( - "did not receive IO cap response prior" - " to BTM_SP_CFM_REQ_EVT, failing pairing request"); + log::error( + "did not receive IO cap response prior to BTM_SP_CFM_REQ_EVT, " + "failing pairing request"); status = BTM_WRONG_MODE; BTM_ConfirmReqReply(status, p_bda); return; @@ -2727,12 +2852,11 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda, } } - LOG_VERBOSE( - "btm_proc_sp_req_evt() just_works:%d, io loc:%d, rmt:%d, auth " - "loc:%d, rmt:%d", - evt_data.cfm_req.just_works, btm_sec_cb.devcb.loc_io_caps, - p_dev_rec->sec_rec.rmt_io_caps, btm_sec_cb.devcb.loc_auth_req, - p_dev_rec->sec_rec.rmt_auth_req); + log::verbose("just_works:{}, io loc:{}, rmt:{}, auth loc:{}, rmt:{}", + evt_data.cfm_req.just_works, btm_sec_cb.devcb.loc_io_caps, + p_dev_rec->sec_rec.rmt_io_caps, + btm_sec_cb.devcb.loc_auth_req, + p_dev_rec->sec_rec.rmt_auth_req); evt_data.cfm_req.loc_auth_req = btm_sec_cb.devcb.loc_auth_req; evt_data.cfm_req.rmt_auth_req = p_dev_rec->sec_rec.rmt_auth_req; @@ -2743,8 +2867,7 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda, case BTM_SP_KEY_NOTIF_EVT: /* Passkey notification (other side is a keyboard) */ evt_data.key_notif.passkey = value; - LOG_VERBOSE("BTM_SP_KEY_NOTIF_EVT: passkey: %u", - evt_data.key_notif.passkey); + log::verbose("passkey:{}", evt_data.key_notif.passkey); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_AUTH_COMPLETE); break; @@ -2755,6 +2878,9 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda, btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_KEY_ENTRY); } break; + default: + log::warn("unhandled event:{}", sp_evt_to_text(event).c_str()); + break; } if (btm_sec_cb.api.p_sp_callback) { @@ -2770,7 +2896,7 @@ void btm_proc_sp_req_evt(tBTM_SP_EVT event, const RawAddress bda, } if (event == BTM_SP_CFM_REQ_EVT) { - LOG_VERBOSE("calling BTM_ConfirmReqReply with status: %d", status); + log::verbose("calling BTM_ConfirmReqReply with status: {}", status); BTM_ConfirmReqReply(status, p_bda); } else if (btm_sec_cb.devcb.loc_io_caps != BTM_IO_CAP_NONE && event == BTM_SP_KEY_REQ_EVT) { @@ -2819,12 +2945,12 @@ void btm_simple_pair_complete(const RawAddress bd_addr, uint8_t status) { p_dev_rec = btm_find_dev(bd_addr); if (p_dev_rec == NULL) { - LOG_ERROR("unknown BDA: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("unknown BDA: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } - LOG_VERBOSE( - "btm_simple_pair_complete() Pair State: %s Status:%d sec_state: %u", + log::verbose( + "btm_simple_pair_complete() Pair State: {} Status:{} sec_state: {}", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), status, p_dev_rec->sec_rec.sec_state); @@ -2881,11 +3007,11 @@ void btm_rem_oob_req(const RawAddress bd_addr) { evt_data.bd_addr = bd_addr; RawAddress& p_bda = evt_data.bd_addr; - LOG_VERBOSE("BDA: %s", ADDRESS_TO_LOGGABLE_CSTR(p_bda)); + log::verbose("BDA: {}", ADDRESS_TO_LOGGABLE_CSTR(p_bda)); p_dev_rec = btm_find_dev(p_bda); if ((p_dev_rec != NULL) && btm_sec_cb.api.p_sp_callback) { evt_data.bd_addr = p_dev_rec->bd_addr; - memcpy(evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN); + evt_data.dev_class = p_dev_rec->dev_class; strlcpy((char*)evt_data.bd_name, (char*)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN + 1); @@ -2914,7 +3040,7 @@ void btm_rem_oob_req(const RawAddress bd_addr) { * ******************************************************************************/ void btm_read_local_oob_complete(const tBTM_SP_LOC_OOB evt_data) { - LOG_VERBOSE("btm_read_local_oob_complete:%d", evt_data.status); + log::verbose("btm_read_local_oob_complete:{}", evt_data.status); if (btm_sec_cb.api.p_sp_callback) { tBTM_SP_EVT_DATA btm_sp_evt_data; @@ -2950,8 +3076,8 @@ static void btm_sec_auth_collision(uint16_t handle) { p_dev_rec = btm_find_dev_by_handle(handle); if (p_dev_rec != NULL) { - LOG_VERBOSE("btm_sec_auth_collision: state %d (retrying in a moment...)", - p_dev_rec->sec_rec.sec_state); + log::verbose("btm_sec_auth_collision: state {} (retrying in a moment...)", + p_dev_rec->sec_rec.sec_state); /* We will restart authentication after timeout */ if (p_dev_rec->sec_rec.sec_state == BTM_SEC_STATE_AUTHENTICATING || p_dev_rec->sec_rec.is_security_state_bredr_encrypting()) @@ -2993,8 +3119,8 @@ static bool btm_sec_auth_retry(uint16_t handle, uint8_t status) { btm_restore_mode(); p_dev_rec->sm4 |= BTM_SM4_RETRY; p_dev_rec->sec_rec.sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN; - LOG_VERBOSE("Retry for missing key sm4:x%x sec_flags:0x%x", p_dev_rec->sm4, - p_dev_rec->sec_rec.sec_flags); + log::verbose("Retry for missing key sm4:x{:x} sec_flags:0x{:x}", + p_dev_rec->sm4, p_dev_rec->sec_rec.sec_flags); /* With BRCM controller, we do not need to delete the stored link key in controller. @@ -3015,16 +3141,17 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status) { bool was_authenticating = false; if (p_dev_rec) { - LOG_VERBOSE( - "Security Manager: in state: %s, handle: %d, status: %d, " - "dev->sec_rec.sec_state:%d, bda: %s, RName: %s", + log::verbose( + "Security Manager: in state: {}, handle: {}, status: {}, " + "dev->sec_rec.sec_state:{}, bda: {}, RName: {}", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), handle, status, p_dev_rec->sec_rec.sec_state, - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), p_dev_rec->sec_bd_name); + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), + reinterpret_cast(p_dev_rec->sec_bd_name)); } else { - LOG_VERBOSE("Security Manager: in state: %s, handle: %d, status: %d", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), - handle, status); + log::verbose("Security Manager: in state: {}, handle: {}, status: {}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), + handle, status); } /* For transaction collision we need to wait and repeat. There is no need */ @@ -3122,7 +3249,7 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status) { BTM_BLE_SEC_NONE); } else if (p_dev_rec->IsLocallyInitiated()) { // Encryption will be set in role_changed callback - LOG_INFO( + log::info( "auth completed in role=peripheral, try to switch role and " "encrypt"); BTM_SwitchRoleToCentral(p_dev_rec->RemoteAddress()); @@ -3179,8 +3306,8 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, /* for random timeout because only peripheral should receive the result */ if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) || (status == HCI_ERR_DIFF_TRANSACTION_COLLISION)) { - LOG_ERROR("Encryption collision failed status:%s", - hci_error_code_text(status).c_str()); + log::error("Encryption collision failed status:{}", + hci_error_code_text(status).c_str()); btm_sec_auth_collision(handle); return; } @@ -3188,9 +3315,9 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle); if (p_dev_rec == nullptr) { - LOG_WARN( - "Received encryption change for unknown device handle:0x%04x status:%s " - "enable:0x%x", + log::warn( + "Received encryption change for unknown device handle:0x{:04x} " + "status:{} enable:0x{:x}", handle, hci_status_code_text(status).c_str(), encr_enable); return; } @@ -3198,9 +3325,9 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, const tBT_TRANSPORT transport = BTM_IsBleConnection(handle) ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR; - LOG_DEBUG( - "Security Manager encryption change request hci_status:%s" - " request:%s state:%s sec_flags:0x%x", + log::debug( + "Security Manager encryption change request hci_status:{} request:{} " + "state:{} sec_flags:0x{:x}", hci_status_code_text(status).c_str(), (encr_enable) ? "encrypt" : "unencrypt", (p_dev_rec->sec_rec.sec_state) ? "encrypted" : "unencrypted", @@ -3222,13 +3349,14 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, p_dev_rec->sec_rec.set_le_device_authenticated(); } } else { - LOG_ERROR( - "Received encryption change for unknown device handle:0x%04x " - "status:%s enable:0x%x", + log::error( + "Received encryption change for unknown device handle:0x{:04x} " + "status:{} enable:0x{:x}", handle, hci_status_code_text(status).c_str(), encr_enable); } } else { - LOG_INFO("Encryption was not enabled locally resetting encryption state"); + log::info( + "Encryption was not enabled locally resetting encryption state"); /* It is possible that we decrypted the link to perform role switch */ /* mark link not to be encrypted, so that when we execute security next * time it will kick in again */ @@ -3237,9 +3365,9 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, } else if (p_dev_rec->ble_hci_handle == handle) { // BLE p_dev_rec->sec_rec.sec_flags &= ~BTM_SEC_LE_ENCRYPTED; } else { - LOG_ERROR( - "Received encryption change for unknown device handle:0x%04x " - "status:%s enable:0x%x", + log::error( + "Received encryption change for unknown device handle:0x{:04x} " + "status:{} enable:0x{:x}", handle, hci_status_code_text(status).c_str(), encr_enable); } } @@ -3257,8 +3385,8 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, bt_transport_text(transport).c_str(), is_encrypted ? 'T' : 'F')); - LOG_DEBUG("after update p_dev_rec->sec_rec.sec_flags=0x%x", - p_dev_rec->sec_rec.sec_flags); + log::debug("after update p_dev_rec->sec_rec.sec_flags=0x{:x}", + p_dev_rec->sec_rec.sec_flags); btm_sec_check_pending_enc_req(p_dev_rec, transport, encr_enable); @@ -3270,14 +3398,21 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, } p_dev_rec->sec_rec.sec_status = status; btm_ble_link_encrypted(p_dev_rec->ble.pseudo_addr, encr_enable); + + if (status == HCI_ERR_KEY_MISSING) { + log::info("Remote key missing - will report"); + bta_dm_remote_key_missing(p_dev_rec->ble.pseudo_addr); + return; + } + return; } else { /* BR/EDR connection, update the encryption key size to be 16 as always */ p_dev_rec->sec_rec.enc_key_size = 16; } - LOG_DEBUG("in new_encr_key_256 is %d", - p_dev_rec->sec_rec.new_encryption_key_is_p256); + log::debug("in new_encr_key_256 is {}", + p_dev_rec->sec_rec.new_encryption_key_is_p256); if ((status == HCI_SUCCESS) && encr_enable && (p_dev_rec->hci_handle == handle)) { @@ -3286,7 +3421,7 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, if (p_dev_rec->sec_rec.rmt_auth_req == BTM_AUTH_SP_NO && btm_sec_cb.devcb.loc_auth_req == BTM_AUTH_SP_NO) { derive_ltk = false; - LOG_VERBOSE("BR key is temporary, skip derivation of LE LTK"); + log::verbose("BR key is temporary, skip derivation of LE LTK"); } tHCI_ROLE role = HCI_ROLE_UNKNOWN; BTM_GetRole(p_dev_rec->bd_addr, &role); @@ -3301,7 +3436,7 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, /* BR/EDR is encrypted with LK that can be used to derive LE LTK */ p_dev_rec->sec_rec.new_encryption_key_is_p256 = false; - LOG_VERBOSE("start SM over BR/EDR"); + log::verbose("start SM over BR/EDR"); SMP_BR_PairWith(p_dev_rec->bd_addr); } } @@ -3311,8 +3446,9 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, if (!p_dev_rec->sec_rec.is_security_state_bredr_encrypting()) { if (BTM_SEC_STATE_DELAY_FOR_ENC == p_dev_rec->sec_rec.sec_state) { p_dev_rec->sec_rec.sec_state = BTM_SEC_STATE_IDLE; - LOG_VERBOSE("clearing callback. p_dev_rec=%p, p_callback=%p", p_dev_rec, - p_dev_rec->sec_rec.p_callback); + log::verbose("clearing callback. p_dev_rec={}, p_callback={}", + fmt::ptr(p_dev_rec), + fmt::ptr(p_dev_rec->sec_rec.p_callback)); p_dev_rec->sec_rec.p_callback = NULL; l2cu_resubmit_pending_sec_req(&p_dev_rec->bd_addr); return; @@ -3342,6 +3478,123 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, btm_sec_dev_rec_cback_event(p_dev_rec, btm_status, false); } +constexpr uint8_t MIN_KEY_SIZE = 7; + +static void read_encryption_key_size_complete_after_encryption_change( + uint8_t status, uint16_t handle, uint8_t key_size) { + if (status == HCI_ERR_INSUFFCIENT_SECURITY) { + /* If remote device stop the encryption before we call "Read Encryption Key + * Size", we might receive Insufficient Security, which means that link is + * no longer encrypted. */ + log::info("encryption stopped on link:0x{:x}", handle); + return; + } + + if (status != HCI_SUCCESS) { + log::error("disconnecting, status:0x{:x}", status); + acl_disconnect_from_handle(handle, HCI_ERR_PEER_USER, + "stack::btu::btu_hcif::read_encryption_key_size_" + "complete_after_encryption_change Bad key size"); + return; + } + + if (key_size < MIN_KEY_SIZE) { + log::error( + "encryption key too short, disconnecting. handle:0x{:x},key_size:{}", + handle, key_size); + + acl_disconnect_from_handle( + handle, HCI_ERR_HOST_REJECT_SECURITY, + "stack::btu::btu_hcif::read_encryption_key_size_complete_after_" + "encryption_change Key Too Short"); + return; + } + + if (IS_FLAG_ENABLED(bluffs_mitigation)) { + if (btm_sec_is_session_key_size_downgrade(handle, key_size)) { + LOG_ERROR( + "encryption key size lower than cached value, disconnecting. " + "handle: 0x%x attempted key size: %d", + handle, key_size); + acl_disconnect_from_handle( + handle, HCI_ERR_HOST_REJECT_SECURITY, + "stack::btu::btu_hcif::read_encryption_key_size_complete_after_" + "encryption_change Key Size Downgrade"); + return; + } + + btm_sec_update_session_key_size(handle, key_size); + } + + // good key size - succeed + btm_acl_encrypt_change(handle, static_cast(status), + 1 /* enable */); + btm_sec_encrypt_change(handle, static_cast(status), + 1 /* enable */); +} + +// TODO: Remove +void smp_cancel_start_encryption_attempt(); + +/******************************************************************************* + * + * Function btm_encryption_change_evt + * + * Description Process event HCI_ENCRYPTION_CHANGE_EVT + * + * Returns void + * + ******************************************************************************/ +void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, + uint8_t encr_enable) { + if (IS_FLAG_ENABLED(bluffs_mitigation)) { + if (status != HCI_SUCCESS || encr_enable == 0 || + BTM_IsBleConnection(handle) || + !bluetooth::shim::GetController()->IsSupported( + bluetooth::hci::OpCode::READ_ENCRYPTION_KEY_SIZE)) { + if (status == HCI_ERR_CONNECTION_TOUT) { + smp_cancel_start_encryption_attempt(); + return; + } + + btm_acl_encrypt_change(handle, static_cast(status), + encr_enable); + btm_sec_encrypt_change(handle, static_cast(status), + encr_enable); + } else { + btsnd_hcic_read_encryption_key_size( + handle, + base::Bind( + &read_encryption_key_size_complete_after_encryption_change)); + } + } else { + // This block added to ensure matching code flow with the bluffs_mitigation + // flag off. The entire block should be removed when the flag is. + if (status != HCI_SUCCESS || encr_enable == 0 || + BTM_IsBleConnection(handle) || + !bluetooth::shim::GetController()->IsSupported( + bluetooth::hci::OpCode::READ_ENCRYPTION_KEY_SIZE) || + // Skip encryption key size check when using set_min_encryption_key_size + (bluetooth::common::init_flags::set_min_encryption_is_enabled() && + bluetooth::shim::GetController()->IsSupported( + bluetooth::hci::OpCode::SET_MIN_ENCRYPTION_KEY_SIZE))) { + if (status == HCI_ERR_CONNECTION_TOUT) { + smp_cancel_start_encryption_attempt(); + return; + } + + btm_acl_encrypt_change(handle, static_cast(status), + encr_enable); + btm_sec_encrypt_change(handle, static_cast(status), + encr_enable); + } else { + btsnd_hcic_read_encryption_key_size( + handle, + base::Bind( + &read_encryption_key_size_complete_after_encryption_change)); + } + } +} /******************************************************************************* * * Function btm_sec_connect_after_reject_timeout @@ -3356,11 +3609,11 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, static void btm_sec_connect_after_reject_timeout(void* /* data */) { tBTM_SEC_DEV_REC* p_dev_rec = btm_sec_cb.p_collided_dev_rec; - LOG_VERBOSE("restarting ACL connection"); + log::verbose("restarting ACL connection"); btm_sec_cb.p_collided_dev_rec = 0; if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED) { - LOG_WARN("Security Manager: failed to start connection"); + log::warn("Security Manager: failed to start connection"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); @@ -3388,38 +3641,41 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bda); if (!p_dev_rec) { - LOG_DEBUG( - "Connected to new device state:%s handle:0x%04x status:%s " - "enc_mode:%hhu bda:%s", + log::debug( + "Connected to new device state:{} handle:0x{:04x} status:{} " + "enc_mode:{} bda:{}", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), handle, hci_status_code_text(status).c_str(), enc_mode, ADDRESS_TO_LOGGABLE_CSTR(bda)); if (status == HCI_SUCCESS) { p_dev_rec = btm_sec_alloc_dev(bda); - LOG_DEBUG("Allocated new device record for new connection peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::debug("Allocated new device record for new connection peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda)); } else { /* If the device matches with stored paring address * reset the paring state to idle */ if ((btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE) && btm_sec_cb.pairing_bda == bda) { - LOG_WARN("Connection failed during bonding attempt peer:%s reason:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda), hci_error_code_text(status).c_str()); + log::warn("Connection failed during bonding attempt peer:{} reason:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda), + hci_error_code_text(status).c_str()); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); } - LOG_DEBUG("Ignoring failed device connection peer:%s reason:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda), hci_error_code_text(status).c_str()); + log::debug("Ignoring failed device connection peer:{} reason:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda), + hci_error_code_text(status).c_str()); return; } } else { - LOG_DEBUG( - "Connected to known device state:%s handle:0x%04x status:%s " - "enc_mode:%hhu bda:%s RName:%s", + log::debug( + "Connected to known device state:{} handle:0x{:04x} status:{} " + "enc_mode:{} bda:{} RName:{}", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), handle, hci_status_code_text(status).c_str(), enc_mode, - ADDRESS_TO_LOGGABLE_CSTR(bda), p_dev_rec->sec_bd_name); + ADDRESS_TO_LOGGABLE_CSTR(bda), + reinterpret_cast(p_dev_rec->sec_bd_name)); bit_shift = (handle == p_dev_rec->ble_hci_handle) ? 8 : 0; /* Update the timestamp for this device */ @@ -3433,9 +3689,8 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, /* Motorola S9 disconnects without asking pin code */ if ((status != HCI_SUCCESS) && (btm_sec_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ)) { - LOG_WARN( - "Security Manager: btm_sec_connected: incoming connection " - "failed " + log::warn( + "Security Manager: btm_sec_connected: incoming connection failed " "without asking PIN"); p_dev_rec->sm4 &= ~BTM_SM4_CONN_PEND; @@ -3454,7 +3709,7 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, if (BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL, BT_TRANSPORT_BR_EDR) != BTM_CMD_STARTED) { - LOG_ERROR("cannot read remote name"); + log::error("cannot read remote name"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); } } @@ -3477,9 +3732,9 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, /* if we rejected incoming connection from bonding device */ if ((status == HCI_ERR_HOST_REJECT_DEVICE) && (btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT)) { - LOG_WARN( - "Security Manager: btm_sec_connected: HCI_Conn_Comp Flags:0x%04x, " - "sm4: 0x%x", + log::warn( + "Security Manager: btm_sec_connected: HCI_Conn_Comp Flags:0x{:04x}, " + "sm4: 0x{:x}", btm_sec_cb.pairing_flags, p_dev_rec->sm4); btm_sec_cb.pairing_flags &= ~BTM_PAIR_FLAGS_REJECTED_CONNECT; @@ -3488,7 +3743,7 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_GET_REM_NAME); if (BTM_ReadRemoteDeviceName(bda, NULL, BT_TRANSPORT_BR_EDR) != BTM_CMD_STARTED) { - LOG_ERROR("cannot read remote name"); + log::error("cannot read remote name"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); } return; @@ -3507,7 +3762,7 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, } /* wait for incoming connection without resetting pairing state */ else if (status == HCI_ERR_CONNECTION_EXISTS) { - LOG_WARN( + log::warn( "Security Manager: btm_sec_connected: Wait for incoming connection"); return; } @@ -3525,8 +3780,8 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, p_dev_rec->sec_rec.security_required &= ~BTM_SEC_OUT_AUTHENTICATE; p_dev_rec->sec_rec.sec_flags &= ~((BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED) << bit_shift); - LOG_VERBOSE("security_required:%x ", - p_dev_rec->sec_rec.security_required); + log::verbose("security_required:{:x} ", + p_dev_rec->sec_rec.security_required); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); @@ -3567,9 +3822,9 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, p_dev_rec = btm_find_dev(bda); if (!p_dev_rec) { /* Don't callback when device security record was removed */ - LOG_DEBUG( - "device security record associated with this bda has been " - "removed! bda=%s, do not callback", + log::debug( + "device security record associated with this bda has been removed! " + "bda={}, do not callback", ADDRESS_TO_LOGGABLE_CSTR(bda)); return; } @@ -3608,8 +3863,8 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, /* Let l2cap start bond timer */ l2cu_update_lcb_4_bonding(p_dev_rec->bd_addr, true); } - LOG_INFO("Connection complete during pairing process peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::info("Connection complete during pairing process peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda)); BTM_LogHistory(kBtmLogTag, bda, "Dedicated bonding", base::StringPrintf("Initiated:%c pairing_flag:0x%02x", (is_pair_flags_we_started_dd) ? 'T' : 'F', @@ -3650,8 +3905,8 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, /* After connection is established we perform security if we do not know */ /* the name, or if we are originator because some procedure can have */ /* been scheduled while connection was down */ - LOG_DEBUG("Is connection locally initiated:%s", - logbool(p_dev_rec->is_originator).c_str()); + log::debug("Is connection locally initiated:{}", + logbool(p_dev_rec->is_originator).c_str()); if (!(p_dev_rec->sec_rec.sec_flags & BTM_SEC_NAME_KNOWN) || p_dev_rec->is_originator) { res = btm_sec_execute_procedure(p_dev_rec); @@ -3689,13 +3944,14 @@ void btm_sec_disconnected(uint16_t handle, tHCI_REASON reason, std::string comment) { if ((reason != HCI_ERR_CONN_CAUSE_LOCAL_HOST) && (reason != HCI_ERR_PEER_USER) && (reason != HCI_ERR_REMOTE_POWER_OFF)) { - LOG_WARN("Got uncommon disconnection reason:%s handle:0x%04x comment:%s", - hci_error_code_text(reason).c_str(), handle, comment.c_str()); + log::warn("Got uncommon disconnection reason:{} handle:0x{:04x} comment:{}", + hci_error_code_text(reason).c_str(), handle, comment.c_str()); } tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle); if (p_dev_rec == nullptr) { - LOG_WARN("Got disconnect for unknown device record handle:0x%04x", handle); + log::warn("Got disconnect for unknown device record handle:0x{:04x}", + handle); return; } @@ -3710,8 +3966,8 @@ void btm_sec_disconnected(uint16_t handle, tHCI_REASON reason, const uint8_t old_pairing_flags = btm_sec_cb.pairing_flags; if ((btm_sec_cb.pairing_state != BTM_PAIR_STATE_IDLE) && (btm_sec_cb.pairing_bda == p_dev_rec->bd_addr)) { - LOG_DEBUG("Disconnected while pairing process active handle:0x%04x", - handle); + log::debug("Disconnected while pairing process active handle:0x{:04x}", + handle); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); p_dev_rec->sec_rec.sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN; @@ -3735,14 +3991,16 @@ void btm_sec_disconnected(uint16_t handle, tHCI_REASON reason, if (p_dev_rec == nullptr) { // |btm_sec_cb.api.p_auth_complete_callback| may cause |p_dev_rec| to be // deallocated. - LOG_WARN("Device record was deallocated after user callback"); + log::warn("Device record was deallocated after user callback"); return; } } - LOG_DEBUG( - "Disconnection complete device:%s name:%s state:%s reason:%s sec_req:%x", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), p_dev_rec->sec_bd_name, + log::debug( + "Disconnection complete device:{} name:{} state:{} reason:{} " + "sec_req:{:x}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), + reinterpret_cast(p_dev_rec->sec_bd_name), tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), hci_reason_code_text(reason).c_str(), p_dev_rec->sec_rec.security_required); @@ -3780,16 +4038,16 @@ void btm_sec_disconnected(uint16_t handle, tHCI_REASON reason, * disconnection. */ if (is_sample_ltk(p_dev_rec->sec_rec.ble_keys.pltk)) { - LOG_INFO("removing bond to device that used sample LTK: %s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); + log::info("removing bond to device that used sample LTK: {}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); bta_dm_remove_device(p_dev_rec->bd_addr); return; } if (p_dev_rec->sec_rec.sec_state == BTM_SEC_STATE_DISCONNECTING_BOTH) { - LOG_DEBUG("Waiting for other transport to disconnect current:%s", - bt_transport_text(transport).c_str()); + log::debug("Waiting for other transport to disconnect current:{}", + bt_transport_text(transport).c_str()); p_dev_rec->sec_rec.sec_state = (transport == BT_TRANSPORT_LE) ? BTM_SEC_STATE_DISCONNECTING : BTM_SEC_STATE_DISCONNECTING_BLE; @@ -3805,9 +4063,9 @@ void btm_sec_disconnected(uint16_t handle, tHCI_REASON reason, p_dev_rec->sec_rec.p_callback = nullptr; (*p_callback)(&p_dev_rec->bd_addr, transport, p_dev_rec->sec_rec.p_ref_data, BTM_ERR_PROCESSING); - LOG_DEBUG("Cleaned up pending security state device:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), - bt_transport_text(transport).c_str()); + log::debug("Cleaned up pending security state device:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), + bt_transport_text(transport).c_str()); } } @@ -3825,28 +4083,26 @@ void btm_sec_role_changed(tHCI_STATUS hci_status, const RawAddress& bd_addr, } } -constexpr uint8_t MIN_KEY_SIZE = 7; - static void read_encryption_key_size_complete_after_key_refresh( uint8_t status, uint16_t handle, uint8_t key_size) { if (status == HCI_ERR_INSUFFCIENT_SECURITY) { /* If remote device stop the encryption before we call "Read Encryption Key * Size", we might receive Insufficient Security, which means that link is * no longer encrypted. */ - LOG_INFO("encryption stopped on link: 0x%x ", handle); + log::info("encryption stopped on link: 0x{:x} ", handle); return; } if (status != HCI_SUCCESS) { - LOG_INFO("disconnecting, status: 0x%x", status); + log::info("disconnecting, status: 0x{:x}", status); acl_disconnect_from_handle(handle, HCI_ERR_PEER_USER, "stack::btu_hcif Key size fail"); return; } if (key_size < MIN_KEY_SIZE) { - LOG_ERROR( - "encryption key too short, disconnecting. handle: 0x%x key_size %d", + log::error( + "encryption key too short, disconnecting. handle: 0x{:x} key_size {}", handle, key_size); acl_disconnect_from_handle(handle, HCI_ERR_HOST_REJECT_SECURITY, @@ -3863,7 +4119,8 @@ void btm_sec_encryption_key_refresh_complete(uint16_t handle, tHCI_STATUS status) { if (status != HCI_SUCCESS || BTM_IsBleConnection(handle) || // Skip encryption key size check when using set_min_encryption_key_size - controller_get_interface()->supports_set_min_encryption_key_size()) { + bluetooth::shim::GetController()->IsSupported( + bluetooth::hci::OpCode::SET_MIN_ENCRYPTION_KEY_SIZE)) { btm_sec_encrypt_change(handle, static_cast(status), (status == HCI_SUCCESS) ? 1 : 0); } else { @@ -3880,8 +4137,8 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, bool we_are_bonding = false; bool ltk_derived_lk = false; - LOG_DEBUG("New link key generated device:%s key_type:%hhu", - ADDRESS_TO_LOGGABLE_CSTR(p_bda), key_type); + log::debug("New link key generated device:{} key_type:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_bda), key_type); if ((key_type >= BTM_LTK_DERIVED_LKEY_OFFSET + BTM_LKEY_TYPE_COMBINATION) && (key_type <= @@ -3923,8 +4180,8 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, /* save LTK derived LK no matter what */ if (ltk_derived_lk) { if (btm_sec_cb.api.p_link_key_callback) { - LOG_VERBOSE("Save LTK derived LK (key_type = %d)", - p_dev_rec->sec_rec.link_key_type); + log::verbose("Save LTK derived LK (key_type = {})", + p_dev_rec->sec_rec.link_key_type); (*btm_sec_cb.api.p_link_key_callback)( p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, link_key, p_dev_rec->sec_rec.link_key_type, true /* is_ctkd */); @@ -3933,11 +4190,19 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, if ((p_dev_rec->sec_rec.link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256) || (p_dev_rec->sec_rec.link_key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256)) { p_dev_rec->sec_rec.new_encryption_key_is_p256 = true; - LOG_VERBOSE("set new_encr_key_256 to %d", - p_dev_rec->sec_rec.new_encryption_key_is_p256); + log::verbose("set new_encr_key_256 to {}", + p_dev_rec->sec_rec.new_encryption_key_is_p256); } } + if (IS_FLAG_ENABLED(bluffs_mitigation) && + p_dev_rec->sec_rec.is_bond_type_persistent() && + (p_dev_rec->is_device_type_br_edr() || + p_dev_rec->is_device_type_dual_mode())) { + btm_sec_store_device_sc_support(p_dev_rec->get_br_edr_hci_handle(), + p_dev_rec->SupportsSecureConnections()); + } + /* If name is not known at this point delay calling callback until the name is */ /* resolved. Unless it is a HID Device and we really need to send all link @@ -3946,8 +4211,8 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) != BTM_COD_MAJOR_PERIPHERAL)) && !ltk_derived_lk) { - LOG_VERBOSE("Delayed BDA: %s, Type: %d", ADDRESS_TO_LOGGABLE_CSTR(p_bda), - key_type); + log::verbose("Delayed BDA: {}, Type: {}", ADDRESS_TO_LOGGABLE_CSTR(p_bda), + key_type); p_dev_rec->sec_rec.link_key_not_sent = true; @@ -3957,9 +4222,9 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, SendRemoteNameRequest(p_bda); } - LOG_VERBOSE("rmt_io_caps:%d, sec_flags:x%x, dev_class[1]:x%02x", - p_dev_rec->sec_rec.rmt_io_caps, p_dev_rec->sec_rec.sec_flags, - p_dev_rec->dev_class[1]); + log::verbose("rmt_io_caps:{}, sec_flags:x{:x}, dev_class[1]:x{:02x}", + p_dev_rec->sec_rec.rmt_io_caps, p_dev_rec->sec_rec.sec_flags, + p_dev_rec->dev_class[1]); return; } @@ -3971,9 +4236,9 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, { if (btm_sec_cb.api.p_link_key_callback) { if (ltk_derived_lk) { - LOG_VERBOSE( - "btm_sec_link_key_notification() LTK derived LK is saved already" - " (key_type = %d)", + log::verbose( + "btm_sec_link_key_notification() LTK derived LK is saved already " + "(key_type = {})", p_dev_rec->sec_rec.link_key_type); } else { (*btm_sec_cb.api.p_link_key_callback)( @@ -3996,7 +4261,7 @@ void btm_sec_link_key_notification(const RawAddress& p_bda, void btm_sec_link_key_request(const RawAddress bda) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda); - LOG_VERBOSE("bda: %s", ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::verbose("bda: {}", ADDRESS_TO_LOGGABLE_CSTR(bda)); if (!concurrentPeerAuthIsEnabled()) { p_dev_rec->sec_rec.sec_state = BTM_SEC_STATE_AUTHENTICATING; } @@ -4004,9 +4269,9 @@ void btm_sec_link_key_request(const RawAddress bda) { if ((btm_sec_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ) && (btm_sec_cb.collision_start_time != 0) && (btm_sec_cb.p_collided_dev_rec->bd_addr == bda)) { - LOG_VERBOSE( - "btm_sec_link_key_request() rejecting link key req " - "State: %d START_TIMEOUT : %" PRIu64, + log::verbose( + "btm_sec_link_key_request() rejecting link key req State: {} " + "START_TIMEOUT : {}", btm_sec_cb.pairing_state, btm_sec_cb.collision_start_time); btsnd_hcic_link_key_neg_reply(bda); return; @@ -4043,9 +4308,9 @@ static void btm_sec_pairing_timeout(void* /* data */) { p_dev_rec = btm_find_dev(p_cb->pairing_bda); - LOG_VERBOSE("State: %s Flags: %u", - tBTM_SEC_CB::btm_pair_state_descr(p_cb->pairing_state), - p_cb->pairing_flags); + log::verbose("State: {} Flags: {}", + tBTM_SEC_CB::btm_pair_state_descr(p_cb->pairing_state), + p_cb->pairing_flags); switch (p_cb->pairing_state) { case BTM_PAIR_STATE_WAIT_PIN_REQ: @@ -4061,7 +4326,7 @@ static void btm_sec_pairing_timeout(void* /* data */) { if (p_dev_rec == NULL) { name[0] = 0; (*btm_sec_cb.api.p_auth_complete_callback)( - p_cb->pairing_bda, NULL, name, HCI_ERR_CONNECTION_TOUT); + p_cb->pairing_bda, kDevClassEmpty, name, HCI_ERR_CONNECTION_TOUT); } else NotifyBondingChange(*p_dev_rec, HCI_ERR_CONNECTION_TOUT); } @@ -4098,8 +4363,8 @@ static void btm_sec_pairing_timeout(void* /* data */) { * complete. * now it's time to tear down the ACL link*/ if (p_dev_rec == NULL) { - LOG_ERROR("BTM_PAIR_STATE_WAIT_DISCONNECT unknown BDA: %s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::error("BTM_PAIR_STATE_WAIT_DISCONNECT unknown BDA: {}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); break; } btm_sec_send_hci_disconnect( @@ -4117,7 +4382,7 @@ static void btm_sec_pairing_timeout(void* /* data */) { if (p_dev_rec == NULL) { name[0] = 0; (*btm_sec_cb.api.p_auth_complete_callback)( - p_cb->pairing_bda, NULL, name, HCI_ERR_CONNECTION_TOUT); + p_cb->pairing_bda, kDevClassEmpty, name, HCI_ERR_CONNECTION_TOUT); } else { NotifyBondingChange(*p_dev_rec, HCI_ERR_CONNECTION_TOUT); } @@ -4125,8 +4390,8 @@ static void btm_sec_pairing_timeout(void* /* data */) { break; default: - LOG_WARN("not processed state: %s", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); + log::warn("not processed state: {}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); break; } @@ -4149,9 +4414,9 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { /* it may need to stretch timeouts */ l2c_pin_code_request(p_bda); - LOG_DEBUG("Controller requests PIN code device:%s state:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_bda), - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); + log::debug("Controller requests PIN code device:{} state:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_bda), + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); RawAddress local_bd_addr = *controller_get_interface()->get_address(); if (p_bda == local_bd_addr) { @@ -4166,8 +4431,8 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { return; } else if ((btm_sec_cb.pairing_state != BTM_PAIR_STATE_WAIT_PIN_REQ) || p_bda != btm_sec_cb.pairing_bda) { - LOG_WARN("btm_sec_pin_code_request() rejected - state: %s", - tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); + log::warn("btm_sec_pin_code_request() rejected - state: {}", + tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state)); btsnd_hcic_pin_code_neg_reply(p_bda); return; } @@ -4184,7 +4449,7 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { } if (!p_cb->pairing_disabled && (p_cb->cfg.pin_type == HCI_PIN_TYPE_FIXED)) { - LOG_VERBOSE("btm_sec_pin_code_request fixed pin replying"); + log::verbose("btm_sec_pin_code_request fixed pin replying"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_AUTH_COMPLETE); btsnd_hcic_pin_code_req_reply(p_bda, p_cb->cfg.pin_code_len, p_cb->cfg.pin_code); @@ -4195,11 +4460,11 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { if ((p_bda == p_cb->connecting_bda) && (p_cb->connecting_dc[0] || p_cb->connecting_dc[1] || p_cb->connecting_dc[2])) - memcpy(p_dev_rec->dev_class, p_cb->connecting_dc, DEV_CLASS_LEN); + p_dev_rec->dev_class = p_cb->connecting_dc; /* We could have started connection after asking user for the PIN code */ if (btm_sec_cb.pin_code_len != 0) { - LOG_VERBOSE("btm_sec_pin_code_request bonding sending reply"); + log::verbose("btm_sec_pin_code_request bonding sending reply"); btsnd_hcic_pin_code_req_reply(p_bda, btm_sec_cb.pin_code_len, p_cb->pin_code); @@ -4229,10 +4494,11 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL) && (p_dev_rec->dev_class[2] & BTM_COD_MINOR_KEYBOARD))) { - LOG_WARN( - "btm_sec_pin_code_request(): Pairing disabled:%d; PIN callback:%p, Dev " - "Rec:%p!", - p_cb->pairing_disabled, p_cb->api.p_pin_callback, p_dev_rec); + log::warn( + "btm_sec_pin_code_request(): Pairing disabled:{}; PIN callback:{}, Dev " + "Rec:{}!", + p_cb->pairing_disabled, fmt::ptr(p_cb->api.p_pin_callback), + fmt::ptr(p_dev_rec)); btsnd_hcic_pin_code_neg_reply(p_bda); } @@ -4241,7 +4507,7 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_PIN); /* Pin code request can not come at the same time as connection request */ p_cb->connecting_bda = p_bda; - memcpy(p_cb->connecting_dc, p_dev_rec->dev_class, DEV_CLASS_LEN); + p_cb->connecting_dc = p_dev_rec->dev_class; /* Check if the name is known */ /* Even if name is not known we might not be able to get one */ @@ -4250,7 +4516,7 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { /* Also cannot send remote name request while paging, i.e. connection is not * completed */ if (p_dev_rec->sec_rec.sec_flags & BTM_SEC_NAME_KNOWN) { - LOG_VERBOSE("btm_sec_pin_code_request going for callback"); + log::verbose("btm_sec_pin_code_request going for callback"); btm_sec_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD; if (p_cb->api.p_pin_callback) { @@ -4260,7 +4526,7 @@ void btm_sec_pin_code_request(const RawAddress p_bda) { BTM_SEC_IN_MIN_16_DIGIT_PIN)); } } else { - LOG_VERBOSE("btm_sec_pin_code_request going for remote name"); + log::verbose("btm_sec_pin_code_request going for remote name"); /* We received PIN code request for the device with unknown name */ /* it is not user friendly just to ask for the PIN without name */ @@ -4322,8 +4588,8 @@ uint16_t BTM_GetClockOffset(const RawAddress& remote_bda) { ******************************************************************************/ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { CHECK(p_dev_rec != nullptr); - LOG_DEBUG( - "security_required:0x%x security_flags:0x%x security_state:%s[%hhu]", + log::debug( + "security_required:0x{:x} security_flags:0x{:x} security_state:{}[{}]", p_dev_rec->sec_rec.security_required, p_dev_rec->sec_rec.sec_flags, security_state_text( static_cast(p_dev_rec->sec_rec.sec_state)) @@ -4332,17 +4598,17 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { if (p_dev_rec->sec_rec.sec_state != BTM_SEC_STATE_IDLE && p_dev_rec->sec_rec.sec_state != BTM_SEC_STATE_LE_ENCRYPTING) { - LOG_INFO("No immediate action taken in busy state: %s", - security_state_text(p_dev_rec->sec_rec.sec_state).c_str()); + log::info("No immediate action taken in busy state: {}", + security_state_text(p_dev_rec->sec_rec.sec_state).c_str()); return (BTM_CMD_STARTED); } /* If any security is required, get the name first */ if (!(p_dev_rec->sec_rec.sec_flags & BTM_SEC_NAME_KNOWN) && (p_dev_rec->hci_handle != HCI_INVALID_HANDLE)) { - LOG_DEBUG("Security Manager: Start get name"); + log::debug("Security Manager: Start get name"); if (!btm_sec_start_get_name(p_dev_rec)) { - LOG_WARN("Unable to start remote name request"); + log::warn("Unable to start remote name request"); return (BTM_NO_RESOURCES); } return (BTM_CMD_STARTED); @@ -4358,13 +4624,13 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { if (p_dev_rec->IsLocallyInitiated()) { if (p_dev_rec->sec_rec.security_required & (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) { - LOG_DEBUG("Outgoing authentication/encryption Required"); + log::debug("Outgoing authentication/encryption Required"); start_auth = true; } } else { if (p_dev_rec->sec_rec.security_required & (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) { - LOG_DEBUG("Incoming authentication/encryption Required"); + log::debug("Incoming authentication/encryption Required"); start_auth = true; } } @@ -4380,14 +4646,14 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { if (!p_dev_rec->IsLocallyInitiated()) { if (p_dev_rec->sec_rec.security_required & BTM_SEC_IN_MIN_16_DIGIT_PIN) { - LOG_DEBUG("BTM_SEC_IN_MIN_16_DIGIT_PIN Required"); + log::debug("BTM_SEC_IN_MIN_16_DIGIT_PIN Required"); start_auth = true; } } } if (start_auth) { - LOG_DEBUG("Security Manager: Start authentication"); + log::debug("Security Manager: Start authentication"); /* * If we do have a link-key, but we end up here because we need an @@ -4423,20 +4689,20 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { (!p_dev_rec->IsLocallyInitiated() && (p_dev_rec->sec_rec.security_required & BTM_SEC_IN_ENCRYPT))) && (p_dev_rec->hci_handle != HCI_INVALID_HANDLE)) { - LOG_VERBOSE("Security Manager: Start encryption"); + log::verbose("Security Manager: Start encryption"); btsnd_hcic_set_conn_encrypt(p_dev_rec->hci_handle, true); p_dev_rec->sec_rec.sec_state = BTM_SEC_STATE_ENCRYPTING; return (BTM_CMD_STARTED); } else { - LOG_DEBUG("Encryption not required"); + log::debug("Encryption not required"); } if ((p_dev_rec->sec_rec.security_required & BTM_SEC_MODE4_LEVEL4) && (p_dev_rec->sec_rec.link_key_type != BTM_LKEY_TYPE_AUTH_COMB_P_256)) { - LOG_VERBOSE( - "Security Manager: SC only service, but link key type is 0x%02x -" - "security failure", + log::verbose( + "Security Manager: SC only service, but link key type is 0x{:02x} " + "-security failure", p_dev_rec->sec_rec.link_key_type); return (BTM_FAILED_ON_SECURITY); } @@ -4444,7 +4710,8 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { if (access_secure_service_from_temp_bond( p_dev_rec, p_dev_rec->IsLocallyInitiated(), p_dev_rec->sec_rec.security_required)) { - LOG_ERROR("Trying to access a secure service from a temp bonding, rejecting"); + log::error( + "Trying to access a secure service from a temp bonding, rejecting"); return (BTM_FAILED_ON_SECURITY); } @@ -4453,7 +4720,7 @@ tBTM_STATUS btm_sec_execute_procedure(tBTM_SEC_DEV_REC* p_dev_rec) { ~(BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT | BTM_SEC_IN_ENCRYPT); - LOG_VERBOSE("Security Manager: access granted"); + log::verbose("Security Manager: access granted"); return (BTM_SUCCESS); } @@ -4488,19 +4755,20 @@ static bool btm_sec_start_get_name(tBTM_SEC_DEV_REC* p_dev_rec) { ******************************************************************************/ static void btm_sec_wait_and_start_authentication(tBTM_SEC_DEV_REC* p_dev_rec) { auto addr = new RawAddress(p_dev_rec->bd_addr); - - static const int32_t delay_auth = + int32_t delay_auth = osi_property_get_int32("bluetooth.btm.sec.delay_auth_ms.value", 0); + /* Overwrite the system-wide authentication delay if device-specific + * interoperability delay is needed. */ + if (interop_match_addr(INTEROP_DELAY_AUTH, addr)) { + delay_auth = BTM_SEC_START_AUTH_DELAY; + } + bt_status_t status = do_in_main_thread_delayed( FROM_HERE, base::Bind(&btm_sec_auth_timer_timeout, addr), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(delay_auth)); -#else - base::Milliseconds(delay_auth)); -#endif + std::chrono::milliseconds(delay_auth)); if (status != BT_STATUS_SUCCESS) { - LOG_ERROR("do_in_main_thread_delayed failed. directly calling"); + log::error("do_in_main_thread_delayed failed. directly calling"); btm_sec_auth_timer_timeout(addr); } } @@ -4517,18 +4785,18 @@ static void btm_sec_auth_timer_timeout(void* data) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(*p_addr); delete p_addr; if (p_dev_rec == NULL) { - LOG_INFO("invalid device or not found"); + log::info("invalid device or not found"); } else if (btm_dev_authenticated(p_dev_rec)) { - LOG_INFO("device is already authenticated"); + log::info("device is already authenticated"); if (p_dev_rec->sec_rec.p_callback) { (*p_dev_rec->sec_rec.p_callback)(&p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR, p_dev_rec->sec_rec.p_ref_data, BTM_SUCCESS); } } else if (p_dev_rec->sec_rec.sec_state == BTM_SEC_STATE_AUTHENTICATING) { - LOG_INFO("device is in the process of authenticating"); + log::info("device is in the process of authenticating"); } else { - LOG_INFO("starting authentication"); + log::info("starting authentication"); p_dev_rec->sec_rec.sec_state = BTM_SEC_STATE_AUTHENTICATING; btsnd_hcic_auth_request(p_dev_rec->hci_handle); } @@ -4545,7 +4813,7 @@ static void btm_sec_auth_timer_timeout(void* data) { * ******************************************************************************/ static void btm_sec_collision_timeout(void* /* data */) { - LOG_VERBOSE("restaring security process after collision"); + log::verbose("restaring security process after collision"); tBTM_STATUS status = btm_sec_execute_procedure(btm_sec_cb.p_collided_dev_rec); @@ -4606,9 +4874,9 @@ static void btm_restore_mode(void) { void tBTM_SEC_CB::change_pairing_state(tBTM_PAIRING_STATE new_state) { tBTM_PAIRING_STATE old_state = pairing_state; - LOG_DEBUG("Pairing state changed %s => %s pairing_flags:0x%x", - tBTM_SEC_CB::btm_pair_state_descr(pairing_state), - tBTM_SEC_CB::btm_pair_state_descr(new_state), pairing_flags); + log::debug("Pairing state changed {} => {} pairing_flags:0x{:x}", + tBTM_SEC_CB::btm_pair_state_descr(pairing_state), + tBTM_SEC_CB::btm_pair_state_descr(new_state), pairing_flags); if (pairing_state != new_state) { BTM_LogHistory( @@ -4692,8 +4960,8 @@ const char* tBTM_SEC_CB::btm_pair_state_descr(tBTM_PAIRING_STATE state) { void btm_sec_dev_rec_cback_event(tBTM_SEC_DEV_REC* p_dev_rec, tBTM_STATUS btm_status, bool is_le_transport) { ASSERT(p_dev_rec != nullptr); - LOG_DEBUG("transport=%s, btm_status=%s", is_le_transport ? "le" : "classic", - btm_status_text(btm_status).c_str()); + log::debug("transport={}, btm_status={}", is_le_transport ? "le" : "classic", + btm_status_text(btm_status).c_str()); tBTM_SEC_CALLBACK* p_callback = p_dev_rec->sec_rec.p_callback; p_dev_rec->sec_rec.p_callback = NULL; @@ -4743,8 +5011,8 @@ static bool btm_sec_queue_mx_request(const RawAddress& bd_addr, uint16_t psm, p_e->bd_addr = bd_addr; p_e->rfcomm_security_requirement = security_required; - LOG_VERBOSE("PSM: 0x%04x Is_Orig: %u security_required: 0x%x", psm, is_orig, - security_required); + log::verbose("PSM: 0x{:04x} Is_Orig: {} security_required: 0x{:x}", psm, + is_orig, security_required); fixed_queue_enqueue(btm_sec_cb.sec_pending_q, p_e); @@ -4759,9 +5027,8 @@ static bool btm_sec_check_prefetch_pin(tBTM_SEC_DEV_REC* p_dev_rec) { if ((major == BTM_COD_MAJOR_AUDIO) && ((minor == BTM_COD_MINOR_CONFM_HANDSFREE) || (minor == BTM_COD_MINOR_CAR_AUDIO))) { - LOG_VERBOSE( - "Skipping pre-fetch PIN for carkit COD Major: 0x%02x Minor: " - "0x%02x", + log::verbose( + "Skipping pre-fetch PIN for carkit COD Major: 0x{:02x} Minor: 0x{:02x}", major, minor); if (!btm_sec_cb.security_mode_changed) { @@ -4779,7 +5046,7 @@ static bool btm_sec_check_prefetch_pin(tBTM_SEC_DEV_REC* p_dev_rec) { /* pin was not supplied - pre-fetch pin code now */ if (btm_sec_cb.api.p_pin_callback && ((btm_sec_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0)) { - LOG_VERBOSE("PIN code callback called"); + log::verbose("PIN code callback called"); if (BTM_IsAclConnectionUp(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR)) btm_sec_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD; (btm_sec_cb.api.p_pin_callback)( @@ -4889,7 +5156,7 @@ static uint16_t btm_sec_set_serv_level4_flags(uint16_t cur_security, * ******************************************************************************/ void btm_sec_clear_ble_keys(tBTM_SEC_DEV_REC* p_dev_rec) { - LOG_VERBOSE("Clearing BLE Keys"); + log::verbose("Clearing BLE Keys"); memset(&p_dev_rec->sec_rec.ble_keys, 0, sizeof(tBTM_SEC_BLE_KEYS)); btm_ble_resolving_list_remove_dev(p_dev_rec); @@ -4927,7 +5194,7 @@ static bool btm_sec_use_smp_br_chnl(tBTM_SEC_DEV_REC* p_dev_rec) { uint32_t ext_feat; uint8_t chnl_mask[L2CAP_FIXED_CHNL_ARRAY_SIZE]; - LOG_VERBOSE("link_key_type = 0x%x", p_dev_rec->sec_rec.link_key_type); + log::verbose("link_key_type = 0x{:x}", p_dev_rec->sec_rec.link_key_type); if ((p_dev_rec->sec_rec.link_key_type != BTM_LKEY_TYPE_UNAUTH_COMB_P_256) && (p_dev_rec->sec_rec.link_key_type != BTM_LKEY_TYPE_AUTH_COMB_P_256)) @@ -4958,6 +5225,18 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(hci_handle); if (p_dev_rec == nullptr) return; + if (IS_FLAG_ENABLED(bluffs_mitigation)) { + // Drop the connection here if the remote attempts to downgrade from Secure + // Connections mode. + if (btm_sec_is_device_sc_downgrade(hci_handle, sc_supported)) { + acl_set_disconnect_reason(HCI_ERR_HOST_REJECT_SECURITY); + btm_sec_send_hci_disconnect( + p_dev_rec, HCI_ERR_AUTH_FAILURE, hci_handle, + "attempted to downgrade from Secure Connections mode"); + return; + } + } + p_dev_rec->remote_feature_received = true; p_dev_rec->remote_supports_hci_role_switch = hci_role_switch_supported; @@ -4967,8 +5246,8 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, p_dev_rec->is_originator) { tBTM_STATUS btm_status = btm_sec_execute_procedure(p_dev_rec); if (btm_status != BTM_CMD_STARTED) { - LOG_WARN("Security procedure not started! status:%s", - btm_status_text(btm_status).c_str()); + log::warn("Security procedure not started! status:{}", + btm_status_text(btm_status).c_str()); btm_sec_dev_rec_cback_event(p_dev_rec, btm_status, false); } } @@ -4985,7 +5264,7 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, } if (p_dev_rec->remote_features_needed) { - LOG_DEBUG("Now device in SC Only mode, waiting for peer remote features!"); + log::debug("Now device in SC Only mode, waiting for peer remote features!"); btm_io_capabilities_req(p_dev_rec->bd_addr); p_dev_rec->remote_features_needed = false; } @@ -5000,7 +5279,7 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, } // Return DEV_CLASS (uint8_t[3]) of bda. If record doesn't exist, create one. -const uint8_t* btm_get_dev_class(const RawAddress& bda) { +DEV_CLASS btm_get_dev_class(const RawAddress& bda) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda); return p_dev_rec->dev_class; } diff --git a/system/stack/btm/btm_sec.h b/system/stack/btm/btm_sec.h index 05938e2ee2e63dfc8cccd83a95b1c33ae9a5d2db..8760c81ece6e294e693a1ec2803cd07a7f378e82 100644 --- a/system/stack/btm/btm_sec.h +++ b/system/stack/btm/btm_sec.h @@ -591,6 +591,18 @@ void btm_read_local_oob_complete(const tBTM_SP_LOC_OOB evt_data); ******************************************************************************/ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status); +/******************************************************************************* + * + * Function btm_sec_encryption_change_evt + * + * Description This function is called to process an encryption change. + * + * Returns void + * + ******************************************************************************/ +void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, + uint8_t encr_enable); + /******************************************************************************* * * Function btm_sec_encrypt_change @@ -761,5 +773,5 @@ void btm_sec_set_peer_sec_caps(uint16_t hci_handle, bool ssp_supported, void btm_sec_cr_loc_oob_data_cback_event(const RawAddress& address, tSMP_LOC_OOB_DATA loc_oob_data); -// Return DEV_CLASS (uint8_t[3]) of bda. If record doesn't exist, create one. -const uint8_t* btm_get_dev_class(const RawAddress& bda); +// Return DEV_CLASS of bda. If record doesn't exist, create one. +DEV_CLASS btm_get_dev_class(const RawAddress& bda); diff --git a/system/stack/btm/btm_sec_cb.cc b/system/stack/btm/btm_sec_cb.cc index 7fee5aa6e90fb4d80b2bff0851349e5db74ca5b6..b1bb0e7040339bfbbf8a42ce2bd59f18cfb4278d 100644 --- a/system/stack/btm/btm_sec_cb.cc +++ b/system/stack/btm/btm_sec_cb.cc @@ -19,8 +19,11 @@ #include "stack/btm/btm_sec_cb.h" +#include + #include +#include "internal_include/bt_trace.h" #include "internal_include/stack_config.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -31,6 +34,8 @@ #include "stack/include/bt_psm_types.h" #include "types/raw_address.h" +using namespace bluetooth; + void tBTM_SEC_CB::Init(uint8_t initial_security_mode) { memset(&cfg, 0, sizeof(cfg)); memset(&devcb, 0, sizeof(devcb)); @@ -130,11 +135,11 @@ bool tBTM_SEC_CB::IsDeviceEncrypted(const RawAddress bd_addr, } else if (transport == BT_TRANSPORT_LE) { return sec_rec->is_le_device_encrypted(); } - LOG_ERROR("unknown transport:%s", bt_transport_text(transport).c_str()); + log::error("unknown transport:{}", bt_transport_text(transport).c_str()); return false; } - LOG_ERROR("unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } @@ -147,11 +152,11 @@ bool tBTM_SEC_CB::IsLinkKeyAuthenticated(const RawAddress bd_addr, } else if (transport == BT_TRANSPORT_LE) { return sec_rec->is_le_link_key_authenticated(); } - LOG_ERROR("unknown transport:%s", bt_transport_text(transport).c_str()); + log::error("unknown transport:{}", bt_transport_text(transport).c_str()); return false; } - LOG_ERROR("unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } @@ -164,11 +169,11 @@ bool tBTM_SEC_CB::IsDeviceAuthenticated(const RawAddress bd_addr, } else if (transport == BT_TRANSPORT_LE) { return sec_rec->is_le_device_authenticated(); } - LOG_ERROR("unknown transport:%s", bt_transport_text(transport).c_str()); + log::error("unknown transport:{}", bt_transport_text(transport).c_str()); return false; } - LOG_ERROR("unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } @@ -181,11 +186,11 @@ bool tBTM_SEC_CB::IsLinkKeyKnown(const RawAddress bd_addr, } else if (transport == BT_TRANSPORT_LE) { return sec_rec->is_le_link_key_known(); } - LOG_ERROR("unknown transport:%s", bt_transport_text(transport).c_str()); + log::error("unknown transport:{}", bt_transport_text(transport).c_str()); return false; } - LOG_ERROR("unknown device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::error("unknown device:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } @@ -198,8 +203,8 @@ bool tBTM_SEC_CB::IsDeviceBonded(const RawAddress bd_addr) { p_dev_rec->sec_rec.is_link_key_known())) { is_bonded = true; } - LOG_DEBUG("Device record bonded check peer:%s is_bonded:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), logbool(is_bonded).c_str()); + log::debug("Device record bonded check peer:{} is_bonded:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), logbool(is_bonded).c_str()); return is_bonded; } @@ -213,7 +218,7 @@ bool tBTM_SEC_CB::AddService(bool is_originator, const char* p_name, uint16_t first_unused_record = BTM_NO_AVAIL_SEC_SERVICES; bool record_allocated = false; - LOG_VERBOSE("sec_level:0x%x", sec_level); + log::verbose("sec_level:0x{:x}", sec_level); /* See if the record can be reused (same service name, psm, mx_proto_id, service_id, and mx_chan_id), or obtain the next unused record */ @@ -244,7 +249,7 @@ bool tBTM_SEC_CB::AddService(bool is_originator, const char* p_name, } if (!record_allocated) { - LOG_WARN("Out of Service Records (%d)", BTM_SEC_MAX_SERVICE_RECORDS); + log::warn("Out of Service Records ({})", BTM_SEC_MAX_SERVICE_RECORDS); return (record_allocated); } @@ -311,9 +316,9 @@ bool tBTM_SEC_CB::AddService(bool is_originator, const char* p_name, p_srec->security_flags |= (uint16_t)(sec_level | BTM_SEC_IN_USE); - LOG_DEBUG( - "[%d]: id:%d, is_orig:%s psm:0x%04x proto_id:%d chan_id:%d" - " : sec:0x%x service_name:[%s] (up to %d chars saved)", + log::debug( + "[{}]: id:{}, is_orig:{} psm:0x{:04x} proto_id:{} chan_id:{} : " + "sec:0x{:x} service_name:[{}] (up to {} chars saved)", index, service_id, logbool(is_originator).c_str(), psm, mx_proto_id, mx_chan_id, p_srec->security_flags, p_name, BT_MAX_SERVICE_NAME_LEN); @@ -330,7 +335,7 @@ uint8_t tBTM_SEC_CB::RemoveServiceById(uint8_t service_id) { if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm != BT_PSM_SDP) && (!service_id || (service_id == p_srec->service_id))) { - LOG_VERBOSE("BTM_SEC_CLR[%d]: id:%d", i, service_id); + log::verbose("BTM_SEC_CLR[{}]: id:{}", i, service_id); p_srec->security_flags = 0; num_freed++; } @@ -346,12 +351,12 @@ uint8_t tBTM_SEC_CB::RemoveServiceByPsm(uint16_t psm) { for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_srec++) { /* Delete services with specified name (if in use and not SDP) */ if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm == psm)) { - LOG_VERBOSE("BTM_SEC_CLR[%d]: id %d ", i, p_srec->service_id); + log::verbose("BTM_SEC_CLR[{}]: id {} ", i, p_srec->service_id); p_srec->security_flags = 0; num_freed++; } } - LOG_VERBOSE("psm:0x%x num_freed:%d", psm, num_freed); + log::verbose("psm:0x{:x} num_freed:{}", psm, num_freed); return (num_freed); } diff --git a/system/stack/btm/btm_sec_int_types.h b/system/stack/btm/btm_sec_int_types.h index 4f8d84d9cb936b6111e2a3de25fd22339bb905e3..a2e265b80f0847cc2b37c1eaa26b4553aa8bfd43 100644 --- a/system/stack/btm/btm_sec_int_types.h +++ b/system/stack/btm/btm_sec_int_types.h @@ -17,6 +17,8 @@ #pragma once +#include + #include #include "stack/include/bt_octets.h" @@ -105,3 +107,8 @@ typedef struct tBTM_SEC_DEVCB { #define BTM_SEC_ENC_PENDING 5 /* wait for link encryption pending */ typedef uint8_t tBTM_SEC_ACTION; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/btm/btm_security_client_interface.cc b/system/stack/btm/btm_security_client_interface.cc index f3b9f5a72b04457c9ff841ef5a1ca80e4147c74b..167911785e4ee2a5a8c4731ba706aac9c85488e1 100644 --- a/system/stack/btm/btm_security_client_interface.cc +++ b/system/stack/btm/btm_security_client_interface.cc @@ -15,38 +15,66 @@ * */ +#define LOG_TAG "sec_interf" + +#include + +#include "os/log.h" #include "stack/btm/btm_dev.h" #include "stack/btm/btm_sec.h" #include "stack/btm/btm_sec_cb.h" #include "stack/include/btm_ble_sec_api.h" #include "stack/include/btm_sec_api.h" #include "stack/include/security_client_callbacks.h" +#include "types/bt_transport.h" + +using namespace bluetooth; + +static void BTM_SecConfirmReqReply(tBTM_STATUS res, tBT_TRANSPORT transport, + const RawAddress bd_addr) { + if (transport == BT_TRANSPORT_BR_EDR) { + BTM_ConfirmReqReply(res, bd_addr); + } else if (transport == BT_TRANSPORT_LE) { + BTM_BleConfirmReply(bd_addr, res); + } else { + log::error("Unexpected transport:{}", transport); + } +} static SecurityClientInterface security = { .BTM_Sec_Init = BTM_Sec_Init, .BTM_Sec_Free = BTM_Sec_Free, + .BTM_SecRegister = BTM_SecRegister, + + .BTM_BleLoadLocalKeys = BTM_BleLoadLocalKeys, + .BTM_SecAddDevice = BTM_SecAddDevice, - .BTM_SecAddRmtNameNotifyCallback = BTM_SecAddRmtNameNotifyCallback, + .BTM_SecAddBleDevice = BTM_SecAddBleDevice, .BTM_SecDeleteDevice = BTM_SecDeleteDevice, - .BTM_SecRegister = BTM_SecRegister, - .BTM_SecReadDevName = BTM_SecReadDevName, - .BTM_SecBond = BTM_SecBond, - .BTM_SecBondCancel = BTM_SecBondCancel, .BTM_SecAddBleKey = BTM_SecAddBleKey, - .BTM_SecAddBleDevice = BTM_SecAddBleDevice, .BTM_SecClearSecurityFlags = BTM_SecClearSecurityFlags, - .BTM_SecClrService = BTM_SecClrService, - .BTM_SecClrServiceByPsm = BTM_SecClrServiceByPsm, - .BTM_RemoteOobDataReply = BTM_RemoteOobDataReply, - .BTM_PINCodeReply = BTM_PINCodeReply, - .BTM_ConfirmReqReply = BTM_ConfirmReqReply, - .BTM_SecDeleteRmtNameNotifyCallback = BTM_SecDeleteRmtNameNotifyCallback, .BTM_SetEncryption = BTM_SetEncryption, .BTM_IsEncrypted = BTM_IsEncrypted, .BTM_SecIsSecurityPending = BTM_SecIsSecurityPending, .BTM_IsLinkKeyKnown = BTM_IsLinkKeyKnown, + + .BTM_SetSecurityLevel = BTM_SetSecurityLevel, + .BTM_SecClrService = BTM_SecClrService, + .BTM_SecClrServiceByPsm = BTM_SecClrServiceByPsm, + + .BTM_SecBond = BTM_SecBond, + .BTM_SecBondCancel = BTM_SecBondCancel, + .BTM_RemoteOobDataReply = BTM_RemoteOobDataReply, + .BTM_PINCodeReply = BTM_PINCodeReply, + .BTM_SecConfirmReqReply = BTM_SecConfirmReqReply, .BTM_BleSirkConfirmDeviceReply = BTM_BleSirkConfirmDeviceReply, + .BTM_BlePasskeyReply = BTM_BlePasskeyReply, + .BTM_GetSecurityMode = BTM_GetSecurityMode, + + .BTM_SecReadDevName = BTM_SecReadDevName, + .BTM_SecAddRmtNameNotifyCallback = BTM_SecAddRmtNameNotifyCallback, + .BTM_SecDeleteRmtNameNotifyCallback = BTM_SecDeleteRmtNameNotifyCallback, }; const SecurityClientInterface& get_security_client_interface() { diff --git a/system/stack/btm/hfp_lc3_decoder.cc b/system/stack/btm/hfp_lc3_decoder.cc index dd828596945d8571bb046ed4646af06b627ecffb..42bc382d1f9ef50eb6ef602ad4f1f04ac07ee62f 100644 --- a/system/stack/btm/hfp_lc3_decoder.cc +++ b/system/stack/btm/hfp_lc3_decoder.cc @@ -19,12 +19,15 @@ #include "hfp_lc3_decoder.h" #include +#include #include #include +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" + +using namespace bluetooth; const int HFP_LC3_H2_HEADER_LEN = 2; const int HFP_LC3_PKT_FRAME_LEN = 58; @@ -35,8 +38,7 @@ static lc3_decoder_t hfp_lc3_decoder; bool hfp_lc3_decoder_init() { if (hfp_lc3_decoder_mem) { - LOG_WARN("%s: The decoder instance should have had been released.", - __func__); + log::warn("The decoder instance should have had been released."); osi_free(hfp_lc3_decoder_mem); } @@ -61,8 +63,8 @@ void hfp_lc3_decoder_cleanup() { bool hfp_lc3_decoder_decode_packet(const uint8_t* i_buf, int16_t* o_buf, size_t out_len) { if (o_buf == nullptr || out_len < HFP_LC3_PCM_BYTES) { - LOG_ERROR("%s: Output buffer size %zu is less than LC3 frame size %d", - __func__, out_len, HFP_LC3_PCM_BYTES); + log::error("Output buffer size {} is less than LC3 frame size {}", out_len, + HFP_LC3_PCM_BYTES); return false; } diff --git a/system/stack/btm/hfp_lc3_decoder_linux.cc b/system/stack/btm/hfp_lc3_decoder_linux.cc index 52d3d4513fde399c5fc8c417178e7de467e7a32a..68674aa1c11178152ec375948fb4e1f710f97376 100644 --- a/system/stack/btm/hfp_lc3_decoder_linux.cc +++ b/system/stack/btm/hfp_lc3_decoder_linux.cc @@ -16,12 +16,16 @@ #define LOG_TAG "hfp_lc3_decoder" +#include + #include #include "hfp_lc3_decoder.h" #include "mmc/codec_client/codec_client.h" #include "mmc/proto/mmc_config.pb.h" -#include "osi/include/log.h" +#include "os/log.h" + +using namespace bluetooth; const int HFP_LC3_H2_HEADER_LEN = 2; const int HFP_LC3_PKT_FRAME_LEN = 58; @@ -51,8 +55,7 @@ bool hfp_lc3_decoder_init() { int ret = client->init(config); if (ret < 0) { - LOG_ERROR("%s: Init failed with error message, %s", __func__, - strerror(-ret)); + log::error("Init failed with error message, {}", strerror(-ret)); return false; } @@ -70,13 +73,13 @@ void hfp_lc3_decoder_cleanup() { bool hfp_lc3_decoder_decode_packet(const uint8_t* i_buf, int16_t* o_buf, size_t out_len) { if (o_buf == nullptr || out_len < HFP_LC3_PCM_BYTES) { - LOG_ERROR("%s: Output buffer size %zu is less than LC3 frame size %d", - __func__, out_len, HFP_LC3_PCM_BYTES); + log::error("Output buffer size {} is less than LC3 frame size {}", out_len, + HFP_LC3_PCM_BYTES); return false; } if (!client) { - LOG_ERROR("%s: CodecClient has not been initialized", __func__); + log::error("CodecClient has not been initialized"); return false; } @@ -91,8 +94,7 @@ bool hfp_lc3_decoder_decode_packet(const uint8_t* i_buf, int16_t* o_buf, o_packet, out_len + 1); if (rc < 0) { - LOG_WARN("%s: Decode failed with error message, %s", __func__, - strerror(-rc)); + log::warn("Decode failed with error message, {}", strerror(-rc)); return false; } diff --git a/system/stack/btm/hfp_lc3_encoder.cc b/system/stack/btm/hfp_lc3_encoder.cc index f9685132829d71c1016f7355e3fcb10ec97ca992..767969fc6bf54b466e00b85729217f6e2e2d094c 100644 --- a/system/stack/btm/hfp_lc3_encoder.cc +++ b/system/stack/btm/hfp_lc3_encoder.cc @@ -18,12 +18,15 @@ #include "hfp_lc3_encoder.h" +#include #include #include +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" + +using namespace bluetooth; const int HFP_LC3_PCM_BYTES = 480; const int HFP_LC3_PKT_FRAME_LEN = 58; @@ -33,8 +36,7 @@ static lc3_encoder_t hfp_lc3_encoder; void hfp_lc3_encoder_init() { if (hfp_lc3_encoder_mem) { - LOG_WARN("%s: The encoder instance should have had been released.", - __func__); + log::warn("The encoder instance should have had been released."); osi_free(hfp_lc3_encoder_mem); } @@ -56,7 +58,7 @@ void hfp_lc3_encoder_cleanup() { uint32_t hfp_lc3_encode_frames(int16_t* input, uint8_t* output) { if (input == nullptr || output == nullptr) { - LOG_ERROR("%s: Buffer is null.", __func__); + log::error("Buffer is null."); return 0; } diff --git a/system/stack/btm/hfp_lc3_encoder_linux.cc b/system/stack/btm/hfp_lc3_encoder_linux.cc index 722501477640d532158f8c62adf2c9334d8f48bb..2385a2ffd843617f1209a95292e0bfcb4821e635 100644 --- a/system/stack/btm/hfp_lc3_encoder_linux.cc +++ b/system/stack/btm/hfp_lc3_encoder_linux.cc @@ -16,10 +16,14 @@ #define LOG_TAG "hfp_lc3_encoder" +#include + #include "hfp_lc3_encoder.h" #include "mmc/codec_client/codec_client.h" #include "mmc/proto/mmc_config.pb.h" -#include "osi/include/log.h" +#include "os/log.h" + +using namespace bluetooth; const int HFP_LC3_PCM_BYTES = 480; const int HFP_LC3_PKT_FRAME_LEN = 58; @@ -46,8 +50,7 @@ void hfp_lc3_encoder_init() { int ret = client->init(config); if (ret < 0) { - LOG_ERROR("%s: Init failed with error message, %s", __func__, - strerror(-ret)); + log::error("Init failed with error message, {}", strerror(-ret)); } return; } @@ -62,12 +65,12 @@ void hfp_lc3_encoder_cleanup() { uint32_t hfp_lc3_encode_frames(int16_t* input, uint8_t* output) { if (input == nullptr || output == nullptr) { - LOG_ERROR("%s: Buffer is null", __func__); + log::error("Buffer is null"); return 0; } if (!client) { - LOG_ERROR("%s: CodecClient has not been initialized", __func__); + log::error("CodecClient has not been initialized"); return 0; } @@ -75,8 +78,7 @@ uint32_t hfp_lc3_encode_frames(int16_t* input, uint8_t* output) { HFP_LC3_PKT_FRAME_LEN); if (rc < 0) { - LOG_WARN("%s: Encode failed with error message, %s", __func__, - strerror(-rc)); + log::warn("Encode failed with error message, {}", strerror(-rc)); return 0; } diff --git a/system/stack/btm/hfp_msbc_decoder.cc b/system/stack/btm/hfp_msbc_decoder.cc index 96c882528d785810de589708da30b229cc7f663c..2d4f452adf34354485618af044fa2393ea642081 100644 --- a/system/stack/btm/hfp_msbc_decoder.cc +++ b/system/stack/btm/hfp_msbc_decoder.cc @@ -19,16 +19,24 @@ #include "hfp_msbc_decoder.h" #include +#include #include #include "embdrv/sbc/decoder/include/oi_codec_sbc.h" #include "embdrv/sbc/decoder/include/oi_status.h" -#include "osi/include/log.h" +#include "os/log.h" #define HFP_MSBC_PKT_LEN 60 #define HFP_MSBC_PCM_BYTES 240 +using namespace bluetooth; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + typedef struct { OI_CODEC_SBC_DECODER_CONTEXT decoder_context; uint32_t context_data[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)]; @@ -41,15 +49,14 @@ bool hfp_msbc_decoder_init() { &hfp_msbc_decoder.decoder_context, hfp_msbc_decoder.context_data, sizeof(hfp_msbc_decoder.context_data), 1, 1, false); if (!OI_SUCCESS(status)) { - LOG_ERROR("%s: OI_CODEC_SBC_DecoderReset failed with error code %d", - __func__, status); + log::error("OI_CODEC_SBC_DecoderReset failed with error code {}", status); return false; } status = OI_CODEC_SBC_DecoderConfigureMSbc(&hfp_msbc_decoder.decoder_context); if (!OI_SUCCESS(status)) { - LOG_ERROR("%s: OI_CODEC_SBC_DecoderConfigureMSbc failed with error code %d", - __func__, status); + log::error("OI_CODEC_SBC_DecoderConfigureMSbc failed with error code {}", + status); return false; } @@ -64,8 +71,8 @@ void hfp_msbc_decoder_cleanup(void) { bool hfp_msbc_decoder_decode_packet(const uint8_t* i_buf, int16_t* o_buf, size_t out_len) { if (out_len < HFP_MSBC_PCM_BYTES) { - LOG_ERROR( - "Output buffer's size %lu is less than one complete mSBC frame %d", + log::error( + "Output buffer's size {} is less than one complete mSBC frame {}", (unsigned long)out_len, HFP_MSBC_PCM_BYTES); return false; } @@ -80,8 +87,8 @@ bool hfp_msbc_decoder_decode_packet(const uint8_t* i_buf, int16_t* o_buf, OI_STATUS status = OI_CODEC_SBC_DecodeFrame( &hfp_msbc_decoder.decoder_context, &oi_data, &oi_size, o_buf, &out_avail); if (!OI_SUCCESS(status) || out_avail != HFP_MSBC_PCM_BYTES || oi_size != 0) { - LOG_ERROR("Decoding failure: %d, %lu, %lu", status, - (unsigned long)out_avail, (unsigned long)oi_size); + log::error("Decoding failure: {}, {}, {}", status, (unsigned long)out_avail, + (unsigned long)oi_size); return false; } diff --git a/system/stack/btm/hfp_msbc_encoder.cc b/system/stack/btm/hfp_msbc_encoder.cc index 581a49d156d33eba98c36f64e0d54e72e1c0c314..4f4d6057d1ad5be4274aa6eeaba5a062ce3c220e 100644 --- a/system/stack/btm/hfp_msbc_encoder.cc +++ b/system/stack/btm/hfp_msbc_encoder.cc @@ -21,7 +21,6 @@ #include #include "embdrv/sbc/encoder/include/sbc_encoder.h" -#include "osi/include/log.h" typedef struct { SBC_ENC_PARAMS sbc_encoder_params; diff --git a/system/stack/btm/neighbor_inquiry.h b/system/stack/btm/neighbor_inquiry.h index a9400671bf15f32e5f085f819b432d4a388de8b9..c667b24e8436fe74a8e6a82e3c399c4f8eb8c8ca 100644 --- a/system/stack/btm/neighbor_inquiry.h +++ b/system/stack/btm/neighbor_inquiry.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include "internal_include/bt_target.h" @@ -222,11 +224,9 @@ typedef struct { typedef void(tBTM_NAME_CMPL_CB)(const tBTM_REMOTE_DEV_NAME*); -typedef struct { +struct tBTM_INQUIRY_VAR_ST { tBTM_NAME_CMPL_CB* p_remname_cmpl_cb; -#define BTM_EXT_RMT_NAME_TIMEOUT_MS (40 * 1000) /* 40 seconds */ - alarm_t* remote_name_timer; alarm_t* classic_inquiry_timer; @@ -266,22 +266,54 @@ typedef struct { uint8_t inq_active; /* Bit Mask indicating type of inquiry is active */ bool no_inc_ssp; /* true, to stop inquiry on incoming SSP */ + bool registered_for_hci_events; + void Init() { + p_remname_cmpl_cb = nullptr; + alarm_free(remote_name_timer); alarm_free(classic_inquiry_timer); remote_name_timer = alarm_new("btm_inq.remote_name_timer"); classic_inquiry_timer = alarm_new("btm_inq.classic_inquiry_timer"); + + discoverable_mode = BTM_NON_DISCOVERABLE; + connectable_mode = BTM_NON_CONNECTABLE; + + page_scan_window = HCI_DEF_PAGESCAN_WINDOW; + page_scan_period = HCI_DEF_PAGESCAN_INTERVAL; + inq_scan_window = HCI_DEF_INQUIRYSCAN_WINDOW; + inq_scan_period = HCI_DEF_INQUIRYSCAN_INTERVAL; + inq_scan_type = BTM_SCAN_TYPE_STANDARD; + page_scan_type = HCI_DEF_SCAN_TYPE; + + remname_bda = {}; + remname_active = false; + + p_inq_cmpl_cb = nullptr; + p_inq_results_cb = nullptr; + + inq_counter = 0; + inqparms = {}; + inq_cmpl_info = {}; + + per_min_delay = 0; + per_max_delay = 0; + state = BTM_INQ_INACTIVE_STATE; + inq_active = 0; no_inc_ssp = BTM_NO_SSP_ON_INQUIRY; + registered_for_hci_events = false; } void Free() { alarm_free(remote_name_timer); alarm_free(classic_inquiry_timer); } - -} tBTM_INQUIRY_VAR_ST; - -#define BTM_INQ_RESULT_BR 0x01 -#define BTM_INQ_RESULT_BLE 0x02 +}; bool btm_inq_find_bdaddr(const RawAddress& p_bda); tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda); + +namespace fmt { +template <> +struct formatter + : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/btm/power_mode.h b/system/stack/btm/power_mode.h index eb98945ab06dd8ec7801927cda34f92825bd78ee..e21162dfd655b8c0af81930ea1a6f9131f2c6b0e 100644 --- a/system/stack/btm/power_mode.h +++ b/system/stack/btm/power_mode.h @@ -130,7 +130,87 @@ typedef void(tBTM_PM_STATUS_CBACK)(const RawAddress& p_bda, /* Idle state - page scan, LE advt, inquiry scan */ #define BTM_CONTRL_IDLE 3 -typedef uint8_t tBTM_CONTRL_STATE; +#define BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK 0xF +#define BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_SHIFT 0 +#define BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK 0xF +#define BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_SHIFT 4 +#define BTM_CONTRL_NUM_ACL_LE_MASK 0xF +#define BTM_CONTRL_NUM_ACL_LE_SHIFT 8 +#define BTM_CONTRL_NUM_LE_ADV_MASK 0xF +#define BTM_CONTRL_NUM_LE_ADV_SHIFT 12 + +#define BTM_CONTRL_LE_SCAN_MODE_IDLE 0 +#define BTM_CONTRL_LE_SCAN_MODE_ULTRA_LOW_POWER 1 +#define BTM_CONTRL_LE_SCAN_MODE_LOW_POWER 2 +#define BTM_CONTRL_LE_SCAN_MODE_BALANCED 3 +#define BTM_CONTRL_LE_SCAN_MODE_LOW_LATENCY 4 +#define BTM_CONTRL_LE_SCAN_MODE_MASK 0xF +#define BTM_CONTRL_LE_SCAN_MODE_SHIFT 16 + +#define BTM_CONTRL_INQUIRY_SHIFT 20 +#define BTM_CONTRL_INQUIRY (1u << BTM_CONTRL_INQUIRY_SHIFT) +#define BTM_CONTRL_SCO_SHIFT 21 +#define BTM_CONTRL_SCO (1u << BTM_CONTRL_SCO_SHIFT) +#define BTM_CONTRL_A2DP_SHIFT 22 +#define BTM_CONTRL_A2DP (1u << BTM_CONTRL_A2DP_SHIFT) +#define BTM_CONTRL_LE_AUDIO_SHIFT 23 +#define BTM_CONTRL_LE_AUDIO (1u << BTM_CONTRL_LE_AUDIO_SHIFT) + +typedef uint32_t tBTM_CONTRL_STATE; + +inline void set_num_acl_active_to_ctrl_state(uint32_t num, + tBTM_CONTRL_STATE& ctrl_state) { + if (num > BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK) { + num = BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK; + } + ctrl_state |= ((num & BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_MASK) + << BTM_CONTRL_NUM_ACL_CLASSIC_ACTIVE_SHIFT); +} + +inline void set_num_acl_sniff_to_ctrl_state(uint32_t num, + tBTM_CONTRL_STATE& ctrl_state) { + if (num > BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK) { + num = BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK; + } + ctrl_state |= ((num & BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_MASK) + << BTM_CONTRL_NUM_ACL_CLASSIC_SNIFF_SHIFT); +} + +inline void set_num_acl_le_to_ctrl_state(uint32_t num, + tBTM_CONTRL_STATE& ctrl_state) { + if (num > BTM_CONTRL_NUM_ACL_LE_MASK) { + num = BTM_CONTRL_NUM_ACL_LE_MASK; + } + ctrl_state |= + ((num & BTM_CONTRL_NUM_ACL_LE_MASK) << BTM_CONTRL_NUM_ACL_LE_SHIFT); +} + +inline void set_num_le_adv_to_ctrl_state(uint32_t num, + tBTM_CONTRL_STATE& ctrl_state) { + if (num > BTM_CONTRL_NUM_LE_ADV_MASK) { + num = BTM_CONTRL_NUM_LE_ADV_MASK; + } + ctrl_state |= + ((num & BTM_CONTRL_NUM_LE_ADV_MASK) << BTM_CONTRL_NUM_LE_ADV_SHIFT); +} + +inline void set_le_scan_mode_to_ctrl_state(uint32_t duty_cycle, + tBTM_CONTRL_STATE& ctrl_state) { + uint32_t scan_mode; + if (duty_cycle == 0) { + scan_mode = BTM_CONTRL_LE_SCAN_MODE_IDLE; + } else if (duty_cycle <= 5) { + scan_mode = BTM_CONTRL_LE_SCAN_MODE_ULTRA_LOW_POWER; + } else if (duty_cycle <= 10) { + scan_mode = BTM_CONTRL_LE_SCAN_MODE_LOW_POWER; + } else if (duty_cycle <= 25) { + scan_mode = BTM_CONTRL_LE_SCAN_MODE_BALANCED; + } else { + scan_mode = BTM_CONTRL_LE_SCAN_MODE_LOW_LATENCY; + } + ctrl_state |= ((scan_mode & BTM_CONTRL_LE_SCAN_MODE_MASK) + << BTM_CONTRL_LE_SCAN_MODE_SHIFT); +} /******************************************************************************* * @@ -199,3 +279,48 @@ tBTM_STATUS BTM_SetSsrParams(const RawAddress& remote_bda, uint16_t max_lat, * ******************************************************************************/ tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void); + +/******************************************************************************* + * + * Function BTM_PM_ReadSniffLinkCount + * + * Description Return the number of BT connection in sniff mode + * + * Returns Number of BT connection in sniff mode + * + ******************************************************************************/ +uint8_t BTM_PM_ReadSniffLinkCount(void); + +/******************************************************************************* + * + * Function BTM_PM_ReadBleLinkCount + * + * Description Return the number of BLE connection + * + * Returns Number of BLE connection + * + ******************************************************************************/ +uint8_t BTM_PM_ReadBleLinkCount(void); + +/******************************************************************************* + * + * Function BTM_PM_DeviceInScanState + * + * Description This function is called to check if in inquiry + * + * Returns true, if in inquiry + * + ******************************************************************************/ +bool BTM_PM_DeviceInScanState(void); + +/******************************************************************************* + * + * Function BTM_PM_ReadBleScanDutyCycle + * + * Description Returns BLE scan duty cycle which is (window * 100) / + *interval + * + * Returns BLE scan duty cycle + * + ******************************************************************************/ +uint32_t BTM_PM_ReadBleScanDutyCycle(void); diff --git a/system/stack/btm/sco_pkt_status.h b/system/stack/btm/sco_pkt_status.h index 233bacf5e6c35c42d5ff912fb1a48a3f6e52943c..a945cf1f5ef6e73a7e17665774979d320fb792aa 100644 --- a/system/stack/btm/sco_pkt_status.h +++ b/system/stack/btm/sco_pkt_status.h @@ -28,7 +28,7 @@ #define BTM_PKT_STATUS_WBS_FRAME_US 7500 /* Object to log consecutive packets' status */ -typedef struct { +struct tBTM_SCO_PKT_STATUS { // Bytes to store packets' status. uint8_t data[BTM_PKT_STATUS_LEN]; // Total number of bits in |data|. @@ -113,4 +113,4 @@ typedef struct { return s; } -} tBTM_SCO_PKT_STATUS; +}; diff --git a/system/stack/btm/security_device_record.h b/system/stack/btm/security_device_record.h index ea25c87e1976731dad55277740b569fdd48f0edd..f66935f4b711a0292e5f71a85503495b28a702e8 100644 --- a/system/stack/btm/security_device_record.h +++ b/system/stack/btm/security_device_record.h @@ -18,23 +18,21 @@ #pragma once -#include #include +#include #include #include #include "internal_include/bt_target.h" #include "macros.h" -#include "os/logging/log_adapter.h" +#include "os/log.h" #include "stack/include/bt_device_type.h" #include "stack/include/bt_name.h" #include "stack/include/bt_octets.h" #include "stack/include/btm_sec_api_types.h" -#include "stack/include/btm_status.h" #include "stack/include/hci_error_code.h" #include "types/ble_address_with_type.h" -#include "types/hci_role.h" #include "types/raw_address.h" #include "types/remote_version_type.h" @@ -116,8 +114,7 @@ class tBTM_BLE_ADDR_INFO { if (is_ble_addr_type_known(ble_addr_type)) { ble_addr_type_ = ble_addr_type; } else { - LOG(ERROR) << "Please don't store illegal addresses into security record:" - << AddressTypeText(ble_addr_type); + bluetooth::log::error("Unknown address type:0x{:x}", ble_addr_type); } } @@ -356,6 +353,25 @@ struct tBTM_SEC_REC { uint8_t get_encryption_key_size() const { return enc_key_size; } void increment_sign_counter(bool local); + + std::string ToString() const { + return base::StringPrintf( + "bredr_linkkey_known:%c,le_linkkey_known:%c," + "bond_type:%s," + "bredr_linkkey_type:%s," + "ble_enc_key_size:%d," + "bredr_authenticated:%c,le_authenticated:%c," + "16_digit_key_authenticated:%c," + "bredr_encrypted:%c,le_encrypted:%c", + is_link_key_known() ? 'T' : 'F', is_le_link_key_known() ? 'T' : 'F', + bond_type_text(bond_type).c_str(), + linkkey_type_text(link_key_type).c_str(), enc_key_size, + is_device_authenticated() ? 'T' : 'F', + is_le_device_authenticated() ? 'T' : 'F', + is_le_link_16_digit_key_authenticated() ? 'T' : 'F', + is_device_encrypted() ? 'T' : 'F', + is_le_device_encrypted() ? 'T' : 'F'); + } }; class tBTM_SEC_DEV_REC { @@ -391,12 +407,13 @@ class tBTM_SEC_DEV_REC { std::string ToString() const { return base::StringPrintf( - "%s %6s cod:%s remote_info:%-14s sm4:0x%02x SecureConn:%c name:\"%s\"", + "%s %6s cod:%s remote_info:%-14s sm4:0x%02x SecureConn:%c name:\"%s\"" + "sec_prop:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), DeviceTypeText(device_type).c_str(), dev_class_text(dev_class).c_str(), remote_version_info.ToString().c_str(), sm4, (remote_supports_secure_connections) ? 'T' : 'F', - PRIVATE_NAME(sec_bd_name)); + PRIVATE_NAME(sec_bd_name), sec_rec.ToString().c_str()); } public: @@ -440,3 +457,11 @@ class tBTM_SEC_DEV_REC { // security related properties tBTM_SEC_REC sec_rec; }; + +namespace fmt { +template <> +struct formatter + : string_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/btm/security_event_parser.cc b/system/stack/btm/security_event_parser.cc new file mode 100644 index 0000000000000000000000000000000000000000..0e675e18fc81ce2ad5721279ab32e4d7a8251847 --- /dev/null +++ b/system/stack/btm/security_event_parser.cc @@ -0,0 +1,280 @@ +/* + * Copyright 2023 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 "security_event_parser.h" + +#include + +#include +#include + +#include "btm_sec.h" +#include "common/metrics.h" +#include "hci/hci_packets.h" +#include "main/shim/helpers.h" +#include "stack/include/btm_sec_api_types.h" +#include "stack/include/hci_error_code.h" +#include "stack/include/sec_hci_link_interface.h" +#include "stack/include/stack_metrics_logging.h" +#include "types/raw_address.h" + +using namespace bluetooth; +using namespace bluetooth::hci; +using android::bluetooth::hci::CMD_UNKNOWN; +using android::bluetooth::hci::STATUS_UNKNOWN; +using bluetooth::common::kUnknownConnectionHandle; + +namespace bluetooth::stack::btm { +namespace { +static void log_address_and_status(const Address& bda, EventCode event_code, + ErrorCode event_status) { + uint32_t cmd = android::bluetooth::hci::CMD_UNKNOWN; + uint16_t status = static_cast(event_status); + uint16_t reason = android::bluetooth::hci::STATUS_UNKNOWN; + uint16_t handle = bluetooth::common::kUnknownConnectionHandle; + int64_t value = 0; + log_classic_pairing_event(ToRawAddress(bda), handle, cmd, + static_cast(event_code), status, reason, + value); +} +static void log_address(const Address& bda, EventCode event_code) { + uint32_t cmd = android::bluetooth::hci::CMD_UNKNOWN; + uint16_t status = android::bluetooth::hci::STATUS_UNKNOWN; + uint16_t reason = android::bluetooth::hci::STATUS_UNKNOWN; + uint16_t handle = bluetooth::common::kUnknownConnectionHandle; + int64_t value = 0; + log_classic_pairing_event(ToRawAddress(bda), handle, cmd, + static_cast(event_code), status, reason, + value); +} +static void parse_encryption_change(const EventView event) { + auto change_opt = EncryptionChangeView::CreateOptional(event); + ASSERT(change_opt.has_value()); + auto change = change_opt.value(); + + ErrorCode status = change.GetStatus(); + uint16_t handle = change.GetConnectionHandle(); + EncryptionEnabled encr_enable = change.GetEncryptionEnabled(); + + btm_sec_encryption_change_evt(handle, static_cast(status), + static_cast(encr_enable)); + log_classic_pairing_event(ToRawAddress(Address::kEmpty), handle, + android::bluetooth::hci::CMD_UNKNOWN, + static_cast(change.GetEventCode()), + static_cast(status), + android::bluetooth::hci::STATUS_UNKNOWN, 0); +} +static void parse_change_connection_link_key_complete(const EventView event) { + auto complete_opt = + ChangeConnectionLinkKeyCompleteView::CreateOptional(event); + ASSERT(complete_opt.has_value()); + auto complete = complete_opt.value(); + + log_classic_pairing_event(ToRawAddress(Address::kEmpty), + complete.GetConnectionHandle(), + android::bluetooth::hci::CMD_UNKNOWN, + static_cast(complete.GetEventCode()), + static_cast(complete.GetStatus()), + android::bluetooth::hci::STATUS_UNKNOWN, 0); +} +static void parse_central_link_key_complete(const EventView event) { + auto event_opt = CentralLinkKeyCompleteView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto complete = event_opt.value(); + + log::info("Unhandled event: {}", EventCodeText(event.GetEventCode()).c_str()); +} +static void parse_return_link_keys(const EventView event) { + auto event_opt = ReturnLinkKeysView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto view = event_opt.value(); + + log::info("Unhandled event: {}", EventCodeText(event.GetEventCode()).c_str()); +} +static void parse_pin_code_request(const EventView event) { + auto event_opt = PinCodeRequestView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto request = event_opt.value(); + btm_sec_pin_code_request(ToRawAddress(request.GetBdAddr())); +} +static void parse_link_key_request(const EventView event) { + auto event_opt = LinkKeyRequestView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto request = event_opt.value(); + + btm_sec_link_key_request(ToRawAddress(request.GetBdAddr())); + log_address(request.GetBdAddr(), event.GetEventCode()); +} +static void parse_link_key_notification(const EventView event) { + auto event_opt = LinkKeyNotificationView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto notification = event_opt.value(); + + btm_sec_link_key_notification( + ToRawAddress(notification.GetBdAddr()), notification.GetLinkKey(), + static_cast(notification.GetKeyType())); + log_address(notification.GetBdAddr(), event.GetEventCode()); +} +static void parse_encryption_key_refresh_complete(const EventView event) { + auto event_opt = EncryptionKeyRefreshCompleteView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto refresh = event_opt.value(); + + btm_sec_encryption_key_refresh_complete( + refresh.GetConnectionHandle(), + static_cast(refresh.GetStatus())); +} +static void parse_io_capabilities_req(const EventView event) { + auto event_opt = IoCapabilityRequestView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto request = event_opt.value(); + + RawAddress peer = ToRawAddress(request.GetBdAddr()); + + btm_io_capabilities_req(peer); + log_address(request.GetBdAddr(), event.GetEventCode()); +} +static void parse_io_capabilities_rsp(const EventView event) { + auto response_opt = IoCapabilityResponseView::CreateOptional(event); + ASSERT(response_opt.has_value()); + auto response = response_opt.value(); + + tBTM_SP_IO_RSP evt_data{ + .bd_addr = ToRawAddress(response.GetBdAddr()), + .io_cap = static_cast(response.GetIoCapability()), + .oob_data = static_cast(response.GetOobDataPresent()), + .auth_req = + static_cast(response.GetAuthenticationRequirements()), + }; + + btm_io_capabilities_rsp(evt_data); + log_address(response.GetBdAddr(), event.GetEventCode()); +} +static void parse_remote_oob_data_request(const EventView event) { + auto event_opt = RemoteOobDataRequestView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto request = event_opt.value(); + + btm_rem_oob_req(ToRawAddress(request.GetBdAddr())); + log_address(request.GetBdAddr(), event.GetEventCode()); +} +static void parse_simple_pairing_complete(const EventView event) { + auto event_opt = SimplePairingCompleteView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto complete = event_opt.value(); + + btm_simple_pair_complete(ToRawAddress(complete.GetBdAddr()), + static_cast(complete.GetStatus())); + log_address_and_status(complete.GetBdAddr(), event.GetEventCode(), + complete.GetStatus()); +} +static void parse_user_passkey_notification(const EventView event) { + auto event_opt = UserPasskeyNotificationView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto notification = event_opt.value(); + + btm_proc_sp_req_evt(BTM_SP_KEY_NOTIF_EVT, + ToRawAddress(notification.GetBdAddr()), + notification.GetPasskey()); + log_address(notification.GetBdAddr(), event.GetEventCode()); +} +static void parse_keypress_notification(const EventView event) { + auto event_opt = KeypressNotificationView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto notification = event_opt.value(); + + log::info("Unhandled event: {}", EventCodeText(event.GetEventCode()).c_str()); + log_address(notification.GetBdAddr(), event.GetEventCode()); +} +static void parse_user_confirmation_request(const EventView event) { + auto event_opt = UserConfirmationRequestView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto request = event_opt.value(); + + btm_proc_sp_req_evt(BTM_SP_CFM_REQ_EVT, ToRawAddress(request.GetBdAddr()), + request.GetNumericValue()); + log_address(request.GetBdAddr(), event.GetEventCode()); +} +static void parse_user_passkey_request(const EventView event) { + auto event_opt = UserPasskeyRequestView::CreateOptional(event); + ASSERT(event_opt.has_value()); + auto request = event_opt.value(); + + btm_proc_sp_req_evt(BTM_SP_KEY_REQ_EVT, ToRawAddress(request.GetBdAddr()), + 0 /* No value needed */); + log_address(request.GetBdAddr(), event.GetEventCode()); +} +} // namespace +} // namespace bluetooth::stack::btm + +namespace bluetooth::stack::btm { + +void SecurityEventParser::OnSecurityEvent(bluetooth::hci::EventView event) { + switch (event.GetEventCode()) { + case EventCode::ENCRYPTION_CHANGE: + parse_encryption_change(event); + break; + case EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE: + parse_change_connection_link_key_complete(event); + break; + case EventCode::CENTRAL_LINK_KEY_COMPLETE: + parse_central_link_key_complete(event); + break; + case EventCode::RETURN_LINK_KEYS: + parse_return_link_keys(event); + break; + case EventCode::PIN_CODE_REQUEST: + parse_pin_code_request(event); + break; + case EventCode::LINK_KEY_REQUEST: + parse_link_key_request(event); + break; + case EventCode::LINK_KEY_NOTIFICATION: + parse_link_key_notification(event); + break; + case EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE: + parse_encryption_key_refresh_complete(event); + break; + case EventCode::IO_CAPABILITY_REQUEST: + parse_io_capabilities_req(event); + break; + case EventCode::IO_CAPABILITY_RESPONSE: + parse_io_capabilities_rsp(event); + break; + case EventCode::REMOTE_OOB_DATA_REQUEST: + parse_remote_oob_data_request(event); + break; + case EventCode::SIMPLE_PAIRING_COMPLETE: + parse_simple_pairing_complete(event); + break; + case EventCode::USER_PASSKEY_NOTIFICATION: + parse_user_passkey_notification(event); + break; + case EventCode::KEYPRESS_NOTIFICATION: + parse_keypress_notification(event); + break; + case EventCode::USER_CONFIRMATION_REQUEST: + parse_user_confirmation_request(event); + break; + case EventCode::USER_PASSKEY_REQUEST: + parse_user_passkey_request(event); + break; + default: + log::error("Unhandled event {}", + EventCodeText(event.GetEventCode()).c_str()); + } +} +} // namespace bluetooth::stack::btm diff --git a/system/stack/btm/security_event_parser.h b/system/stack/btm/security_event_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..f29e3724e6b4daa71a22dcdc85536a945cc0a873 --- /dev/null +++ b/system/stack/btm/security_event_parser.h @@ -0,0 +1,30 @@ +/* + * Copyright 2023 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 "hci/hci_packets.h" + +namespace bluetooth::stack::btm { + +class SecurityEventParser { + public: + SecurityEventParser() = default; + virtual ~SecurityEventParser() = default; + void OnSecurityEvent(bluetooth::hci::EventView event); +}; + +} // namespace bluetooth::stack::btm diff --git a/system/stack/btu/btu_hcif.cc b/system/stack/btu/btu_hcif.cc index 7aa290e056b54a3952f2c066b386facffe579bca..3cc68721ae5e01e38d83bbef941e3b62f31c42d3 100644 --- a/system/stack/btu/btu_hcif.cc +++ b/system/stack/btu/btu_hcif.cc @@ -31,7 +31,7 @@ #include #include -#include +#include #include @@ -39,11 +39,9 @@ #include "common/metrics.h" #include "device/include/controller.h" #include "internal_include/bt_target.h" -#include "internal_include/bt_trace.h" #include "main/shim/hci_layer.h" #include "os/log.h" #include "osi/include/allocator.h" -#include "stack/btm/neighbor_inquiry.h" #include "stack/include/acl_hci_link_interface.h" #include "stack/include/ble_acl_interface.h" #include "stack/include/ble_hci_link_interface.h" @@ -65,6 +63,7 @@ #include "types/hci_role.h" #include "types/raw_address.h" +using namespace bluetooth; using base::Location; using bluetooth::hci::IsoManager; @@ -77,8 +76,6 @@ void acl_disconnect_from_handle(uint16_t handle, tHCI_STATUS reason, /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /******************************************************************************/ -static void btu_hcif_inquiry_comp_evt(uint8_t* p); - static void btu_hcif_authentication_comp_evt(uint8_t* p); static void btu_hcif_rmt_name_request_comp_evt(const uint8_t* p, uint16_t evt_len); @@ -88,7 +85,6 @@ static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p, static void btu_hcif_command_complete_evt(BT_HDR* response, void* context); static void btu_hcif_command_status_evt(uint8_t status, BT_HDR* command, void* context); -static void btu_hcif_hardware_error_evt(uint8_t* p); static void btu_hcif_mode_change_evt(uint8_t* p); static void btu_hcif_link_key_notification_evt(const uint8_t* p); static void btu_hcif_read_clock_off_comp_evt(uint8_t* p); @@ -113,11 +109,8 @@ static void btu_hcif_read_local_oob_complete(const uint8_t* p, static void btu_hcif_io_cap_request_evt(const uint8_t* p); static void btu_hcif_io_cap_response_evt(const uint8_t* p); -static void btu_ble_ll_conn_param_upd_evt(uint8_t* p, uint16_t evt_len); static void btu_ble_proc_ltk_req(uint8_t* p, uint16_t evt_len); static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p); -static void btu_ble_data_length_change_evt(uint8_t* p, uint16_t evt_len); -static void btu_ble_rc_param_req_evt(uint8_t* p, uint8_t len); /** * Log HCI event metrics that are not handled in special functions @@ -202,8 +195,8 @@ static void btu_hcif_log_event_metrics(uint8_t evt_code, case HCI_CONNECTION_REQUEST_EVT: // EventCode::CONNECTION_REQUEST case HCI_DISCONNECTION_COMP_EVT: // EventCode::DISCONNECTION_COMPLETE default: - LOG_ERROR( - "Unexpectedly received event_code:0x%02x that should not be " + log::error( + "Unexpectedly received event_code:0x{:02x} that should not be " "handled here", evt_code); break; @@ -230,26 +223,14 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, // validate event size if (hci_evt_len < hci_event_parameters_minimum_length[hci_evt_code]) { - LOG_WARN("%s: evt:0x%2X, malformed event of size %hhd", __func__, - hci_evt_code, hci_evt_len); + log::warn("evt:0x{:2X}, malformed event of size {}", hci_evt_code, + hci_evt_len); return; } btu_hcif_log_event_metrics(hci_evt_code, p); switch (hci_evt_code) { - case HCI_INQUIRY_COMP_EVT: - btu_hcif_inquiry_comp_evt(p); - break; - case HCI_INQUIRY_RESULT_EVT: - btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_STANDARD); - break; - case HCI_INQUIRY_RSSI_RESULT_EVT: - btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_WITH_RSSI); - break; - case HCI_EXTENDED_INQUIRY_RESULT_EVT: - btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_EXTENDED); - break; case HCI_AUTHENTICATION_COMP_EVT: btu_hcif_authentication_comp_evt(p); break; @@ -266,19 +247,14 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, btu_hcif_read_rmt_ext_features_comp_evt(p, hci_evt_len); break; case HCI_COMMAND_COMPLETE_EVT: - LOG_ERROR( - "%s should not have received a command complete event. " - "Someone didn't go through the hci transmit_command function.", - __func__); + log::error( + "should not have received a command complete event. Someone didn't " + "go through the hci transmit_command function."); break; case HCI_COMMAND_STATUS_EVT: - LOG_ERROR( - "%s should not have received a command status event. " - "Someone didn't go through the hci transmit_command function.", - __func__); - break; - case HCI_HARDWARE_ERROR_EVT: - btu_hcif_hardware_error_evt(p); + log::error( + "should not have received a command status event. Someone didn't go " + "through the hci transmit_command function."); break; case HCI_MODE_CHANGE_EVT: btu_hcif_mode_change_evt(p); @@ -334,32 +310,12 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, uint8_t ble_evt_len = hci_evt_len - 1; switch (ble_sub_code) { - case HCI_BLE_ADV_PKT_RPT_EVT: /* result of inquiry */ - btm_ble_process_adv_pkt(ble_evt_len, p); - break; - case HCI_BLE_LL_CONN_PARAM_UPD_EVT: - btu_ble_ll_conn_param_upd_evt(p, ble_evt_len); - break; case HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT: btm_ble_read_remote_features_complete(p, ble_evt_len); break; case HCI_BLE_LTK_REQ_EVT: /* received only at peripheral device */ btu_ble_proc_ltk_req(p, ble_evt_len); break; - case HCI_BLE_RC_PARAM_REQ_EVT: - btu_ble_rc_param_req_evt(p, ble_evt_len); - break; - case HCI_BLE_DATA_LENGTH_CHANGE_EVT: - btu_ble_data_length_change_evt(p, hci_evt_len); - break; - - case HCI_BLE_PHY_UPDATE_COMPLETE_EVT: - btm_ble_process_phy_update_pkt(ble_evt_len, p); - break; - - case HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT: - btm_ble_process_ext_adv_pkt(hci_evt_len, p); - break; case HCI_BLE_REQ_PEER_SCA_CPL_EVT: btm_acl_process_sca_cmpl_pkt(ble_evt_len, p); @@ -375,32 +331,18 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, ble_evt_len); break; - case HCI_LE_PERIODIC_ADV_SYNC_TRANSFERE_RECEIVED_EVT: - btm_ble_periodic_adv_sync_tx_rcvd(p, hci_evt_len); - break; - - case HCI_LE_BIGINFO_ADVERTISING_REPORT_EVT: - btm_ble_biginfo_adv_report_rcvd(p, hci_evt_len); - break; - - // Events are now captured by gd/hci/le_acl_connection_interface.h - case HCI_BLE_CONN_COMPLETE_EVT: // SubeventCode::CONNECTION_COMPLETE - case HCI_BLE_ENHANCED_CONN_COMPLETE_EVT: // SubeventCode::ENHANCED_CONNECTION_COMPLETE - case HCI_LE_SUBRATE_CHANGE_EVT: // SubeventCode::LE_SUBRATE_CHANGE default: - LOG_ERROR( - "Unexpectedly received LE sub_event_code:0x%02x that should not " - "be handled here", + log::error( + "Unexpectedly received LE sub_event_code:0x{:02x} that should " + "not be handled here", ble_sub_code); break; } } break; - case HCI_VENDOR_SPECIFIC_EVT: - btm_vendor_specific_evt(const_cast(p), hci_evt_len); - break; - // Events now captured by gd::hci_layer module + case HCI_VENDOR_SPECIFIC_EVT: + case HCI_HARDWARE_ERROR_EVT: case HCI_NUM_COMPL_DATA_PKTS_EVT: // EventCode::NUMBER_OF_COMPLETED_PACKETS case HCI_CONNECTION_COMP_EVT: // EventCode::CONNECTION_COMPLETE case HCI_CONNECTION_REQUEST_EVT: // EventCode::CONNECTION_REQUEST @@ -409,8 +351,8 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, case HCI_ROLE_CHANGE_EVT: // EventCode::ROLE_CHANGE case HCI_DISCONNECTION_COMP_EVT: // EventCode::DISCONNECTION_COMPLETE default: - LOG_ERROR( - "Unexpectedly received event_code:0x%02x that should not be " + log::error( + "Unexpectedly received event_code:0x{:02x} that should not be " "handled here", hci_evt_code); break; @@ -736,8 +678,7 @@ static void btu_hcif_command_complete_evt_with_cb_on_task(BT_HDR* event, btu_hcif_log_command_complete_metrics(opcode, stream); cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)context; - LOG_VERBOSE("command complete for: %s", - cb_wrapper->posted_from.ToString().c_str()); + log::verbose("command complete for: {}", cb_wrapper->posted_from.ToString()); // 2 for event header: event code (1) + parameter length (1) // 3 for command complete header: num_hci_pkt (1) + opcode (2) uint16_t param_len = static_cast(event->len - 5); @@ -770,8 +711,7 @@ static void btu_hcif_command_status_evt_with_cb_on_task(uint8_t status, // report command status error cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)context; - LOG_VERBOSE("command status for: %s", - cb_wrapper->posted_from.ToString().c_str()); + log::verbose("command status for: {}", cb_wrapper->posted_from.ToString()); std::move(cb_wrapper->cb).Run(&status, sizeof(uint16_t)); cmd_with_cb_data_cleanup(cb_wrapper); osi_free(cb_wrapper); @@ -825,24 +765,6 @@ void btu_hcif_send_cmd_with_cb(const base::Location& posted_from, btu_hcif_command_status_evt_with_cb, (void*)cb_wrapper); } -/******************************************************************************* - * - * Function btu_hcif_inquiry_comp_evt - * - * Description Process event HCI_INQUIRY_COMP_EVT - * - * Returns void - * - ******************************************************************************/ -static void btu_hcif_inquiry_comp_evt(uint8_t* p) { - uint8_t status; - - STREAM_TO_UINT8(status, p); - - /* Tell inquiry processing that we are done */ - btm_process_inq_complete(to_hci_status_code(status), BTM_BR_INQUIRY_MASK); -} - /******************************************************************************* * * Function btu_hcif_authentication_comp_evt @@ -886,43 +808,6 @@ static void btu_hcif_rmt_name_request_comp_evt(const uint8_t* p, btm_sec_rmt_name_request_complete(&bd_addr, p, to_hci_status_code(status)); } -constexpr uint8_t MIN_KEY_SIZE = 7; - -static void read_encryption_key_size_complete_after_encryption_change(uint8_t status, uint16_t handle, - uint8_t key_size) { - if (status == HCI_ERR_INSUFFCIENT_SECURITY) { - /* If remote device stop the encryption before we call "Read Encryption Key - * Size", we might receive Insufficient Security, which means that link is - * no longer encrypted. */ - LOG(INFO) << __func__ << ": encryption stopped on link: " << loghex(handle); - return; - } - - if (status != HCI_SUCCESS) { - LOG(INFO) << __func__ << ": disconnecting, status: " << loghex(status); - acl_disconnect_from_handle(handle, HCI_ERR_PEER_USER, - "stack::btu::btu_hcif::read_encryption_key_size_" - "complete_after_encryption_change Bad key size"); - return; - } - - if (key_size < MIN_KEY_SIZE) { - LOG(ERROR) << __func__ << " encryption key too short, disconnecting. handle: " << loghex(handle) - << " key_size: " << +key_size; - - acl_disconnect_from_handle( - handle, HCI_ERR_HOST_REJECT_SECURITY, - "stack::btu::btu_hcif::read_encryption_key_size_complete_after_" - "encryption_change Key Too Short"); - return; - } - - // good key size - succeed - btm_acl_encrypt_change(handle, static_cast(status), - 1 /* enable */); - btm_sec_encrypt_change(handle, static_cast(status), - 1 /* enable */); -} /******************************************************************************* * * Function btu_hcif_encryption_change_evt @@ -941,26 +826,8 @@ static void btu_hcif_encryption_change_evt(uint8_t* p) { STREAM_TO_UINT16(handle, p); STREAM_TO_UINT8(encr_enable, p); - if (status != HCI_SUCCESS || encr_enable == 0 || - BTM_IsBleConnection(handle) || - !controller_get_interface()->supports_read_encryption_key_size() || - // Skip encryption key size check when using set_min_encryption_key_size - (bluetooth::common::init_flags::set_min_encryption_is_enabled() && - controller_get_interface()->supports_set_min_encryption_key_size())) { - if (status == HCI_ERR_CONNECTION_TOUT) { - smp_cancel_start_encryption_attempt(); - return; - } - - btm_acl_encrypt_change(handle, static_cast(status), - encr_enable); - btm_sec_encrypt_change(handle, static_cast(status), - encr_enable); - } else { - btsnd_hcic_read_encryption_key_size( - handle, - base::Bind(&read_encryption_key_size_complete_after_encryption_change)); - } + btm_sec_encryption_change_evt(handle, static_cast(status), + encr_enable); } /******************************************************************************* @@ -1070,10 +937,6 @@ static void btu_hcif_esco_connection_chg_evt(uint8_t* p) { static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, uint16_t evt_len) { switch (opcode) { - case HCI_INQUIRY_CANCEL: - /* Tell inquiry processing that we are done */ - btm_process_cancel_complete(HCI_SUCCESS, BTM_BR_INQUIRY_MASK); - break; case HCI_SET_EVENT_FILTER: break; @@ -1127,7 +990,7 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, case HCI_BLE_CREATE_LL_CONN: case HCI_LE_EXTENDED_CREATE_CONNECTION: // No command complete event for those commands according to spec - LOG(ERROR) << "No command complete expected, but received!"; + log::error("No command complete expected, but received!"); break; case HCI_BLE_TRANSMITTER_TEST: @@ -1172,8 +1035,9 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, break; default: - LOG_ERROR("Command complete for opcode:0x%02x should not be handled here", - opcode); + log::error( + "Command complete for opcode:0x{:02x} should not be handled here", + opcode); break; } } @@ -1221,7 +1085,7 @@ static void btu_hcif_command_complete_evt(BT_HDR* response, ******************************************************************************/ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, const uint8_t* p_cmd) { - CHECK_NE(p_cmd, nullptr) << "Null command for opcode 0x" << loghex(opcode); + ASSERT_LOG(p_cmd != nullptr, "Null command for opcode 0x%x", opcode); p_cmd++; // Skip parameter total length const tHCI_STATUS hci_status = to_hci_status_code(status); @@ -1230,13 +1094,6 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, uint16_t handle; switch (opcode) { - // Link Control Commands - case HCI_INQUIRY: - if (status != HCI_SUCCESS) { - // Tell inquiry processing that we are done - btm_process_inq_complete(hci_status, BTM_BR_INQUIRY_MASK); - } - break; case HCI_SWITCH_ROLE: if (status != HCI_SUCCESS) { // Tell BTM that the command failed @@ -1286,13 +1143,6 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, } break; - // BLE Commands - case HCI_BLE_CREATE_LL_CONN: - case HCI_LE_EXTENDED_CREATE_CONNECTION: - if (status != HCI_SUCCESS) { - btm_ble_create_ll_conn_complete(hci_status); - } - break; case HCI_BLE_START_ENC: // Race condition: disconnection happened right before we send // "LE Encrypt", controller responds with no connection, we should @@ -1321,16 +1171,16 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, case HCI_READ_RMT_CLOCK_OFFSET: // 0x041f case HCI_CHANGE_CONN_PACKET_TYPE: // 0x040f if (hci_status != HCI_SUCCESS) { - LOG_WARN("Received bad command status for opcode:0x%02x status:%s", - opcode, hci_status_code_text(hci_status).c_str()); + log::warn("Received bad command status for opcode:0x{:02x} status:{}", + opcode, hci_status_code_text(hci_status)); } break; default: - LOG_ERROR( - "Command status for opcode:0x%02x should not be handled here " - "status:%s", - opcode, hci_status_code_text(hci_status).c_str()); + log::error( + "Command status for opcode:0x{:02x} should not be handled here " + "status:{}", + opcode, hci_status_code_text(hci_status)); } } @@ -1368,20 +1218,6 @@ static void btu_hcif_command_status_evt(uint8_t status, BT_HDR* command, base::BindOnce(btu_hcif_command_status_evt_on_task, status, command)); } -/******************************************************************************* - * - * Function btu_hcif_hardware_error_evt - * - * Description Process event HCI_HARDWARE_ERROR_EVT - * - * Returns void - * - ******************************************************************************/ -static void btu_hcif_hardware_error_evt(uint8_t* p) { - LOG_ERROR("UNHANDLED Ctlr H/w error event - code:0x%x", *p); - BTA_sys_signal_hw_error(); -} - /******************************************************************************* * * Function btu_hcif_mode_change_evt @@ -1458,6 +1294,9 @@ void btu_hcif_proc_sp_req_evt(tBTM_SP_EVT event, const uint8_t* p) { case BTM_SP_KEY_REQ_EVT: // No value needed. break; + default: + log::warn("unexpected event:{}", sp_evt_to_text(event)); + break; } btm_proc_sp_req_evt(event, bda, value); } @@ -1465,7 +1304,7 @@ void btu_hcif_create_conn_cancel_complete(const uint8_t* p, uint16_t evt_len) { uint8_t status; if (evt_len < 1 + BD_ADDR_LEN) { - LOG_ERROR("%s malformatted event packet, too short", __func__); + log::error("malformatted event packet, too short"); return; } @@ -1495,7 +1334,7 @@ void btu_hcif_read_local_oob_complete(const uint8_t* p, uint16_t evt_len) { return; err_out: - LOG_ERROR("%s: bogus event packet, too short", __func__); + log::error("bogus event packet, too short"); } /******************************************************************************* @@ -1607,31 +1446,6 @@ static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p) { * BLE Events **********************************************/ -static void btu_ble_ll_conn_param_upd_evt(uint8_t* p, uint16_t evt_len) { - /* LE connection update has completed successfully as a central. */ - /* We can enable the update request if the result is a success. */ - /* extract the HCI handle first */ - uint8_t status; - uint16_t handle; - uint16_t interval; - uint16_t latency; - uint16_t timeout; - - if (evt_len < 9) { - LOG_ERROR("Malformated event packet, too short"); - return; - } - - STREAM_TO_UINT8(status, p); - STREAM_TO_UINT16(handle, p); - STREAM_TO_UINT16(interval, p); - STREAM_TO_UINT16(latency, p); - STREAM_TO_UINT16(timeout, p); - - acl_ble_update_event_received(static_cast(status), handle, - interval, latency, timeout); -} - static void btu_ble_proc_ltk_req(uint8_t* p, uint16_t evt_len) { uint16_t ediv, handle; uint8_t* pp; @@ -1644,7 +1458,7 @@ static void btu_ble_proc_ltk_req(uint8_t* p, uint16_t evt_len) { // - 8-byte random number // - 2 byte Encrypted_Diversifier if (evt_len < 2 + 8 + 2) { - LOG_ERROR("Event packet too short"); + log::error("Event packet too short"); return; } @@ -1655,48 +1469,6 @@ static void btu_ble_proc_ltk_req(uint8_t* p, uint16_t evt_len) { /* This is empty until an upper layer cares about returning event */ } -static void btu_ble_data_length_change_evt(uint8_t* p, uint16_t evt_len) { - uint16_t handle; - uint16_t tx_data_len; - uint16_t rx_data_len; - - if (!controller_get_interface()->supports_ble_packet_extension()) { - LOG_WARN("%s, request not supported", __func__); - return; - } - - // 2 bytes each for handle, tx_data_len, TxTimer, rx_data_len - if (evt_len < 8) { - LOG_ERROR("Event packet too short"); - return; - } - - STREAM_TO_UINT16(handle, p); - STREAM_TO_UINT16(tx_data_len, p); - p += 2; /* Skip the TxTimer */ - STREAM_TO_UINT16(rx_data_len, p); - - l2cble_process_data_length_change_event(handle, tx_data_len, rx_data_len); -} - /********************************************** * End of BLE Events Handler **********************************************/ -static void btu_ble_rc_param_req_evt(uint8_t* p, uint8_t len) { - uint16_t handle; - uint16_t int_min, int_max, latency, timeout; - - if (len < 10) { - LOG(ERROR) << __func__ << "bogus event packet, too short"; - return; - } - - STREAM_TO_UINT16(handle, p); - STREAM_TO_UINT16(int_min, p); - STREAM_TO_UINT16(int_max, p); - STREAM_TO_UINT16(latency, p); - STREAM_TO_UINT16(timeout, p); - - l2cble_process_rc_param_request_evt(handle, int_min, int_max, latency, - timeout); -} diff --git a/system/stack/btu/main_thread.cc b/system/stack/btu/main_thread.cc index b41a56bcfbdb2033a63cfcc7f9cd8af4815c027c..a2cdd7bac68370ca969531f7cbfbd7e027ab92c2 100644 --- a/system/stack/btu/main_thread.cc +++ b/system/stack/btu/main_thread.cc @@ -24,12 +24,14 @@ #include #include #include +#include #include "common/message_loop_thread.h" #include "include/hardware/bluetooth.h" #include "os/log.h" using bluetooth::common::MessageLoopThread; +using namespace bluetooth; static MessageLoopThread main_thread("bt_main_thread"); @@ -38,7 +40,7 @@ bluetooth::common::MessageLoopThread* get_main_thread() { return &main_thread; } bt_status_t do_in_main_thread(const base::Location& from_here, base::OnceClosure task) { if (!main_thread.DoInThread(from_here, std::move(task))) { - LOG(ERROR) << __func__ << ": failed from " << from_here.ToString(); + log::error("failed from {}", from_here.ToString()); return BT_STATUS_FAIL; } return BT_STATUS_SUCCESS; @@ -46,9 +48,9 @@ bt_status_t do_in_main_thread(const base::Location& from_here, bt_status_t do_in_main_thread_delayed(const base::Location& from_here, base::OnceClosure task, - const base::TimeDelta& delay) { + std::chrono::microseconds delay) { if (!main_thread.DoInThreadDelayed(from_here, std::move(task), delay)) { - LOG(ERROR) << __func__ << ": failed from " << from_here.ToString(); + log::error("failed from {}", from_here.ToString()); return BT_STATUS_FAIL; } return BT_STATUS_SUCCESS; @@ -65,13 +67,13 @@ void post_on_bt_main(BtMainClosure closure) { void main_thread_start_up() { main_thread.StartUp(); if (!main_thread.IsRunning()) { - LOG(FATAL) << __func__ << ": unable to start btu message loop thread."; + log::fatal("unable to start btu message loop thread."); } if (!main_thread.EnableRealTimeScheduling()) { #if defined(__ANDROID__) - LOG(FATAL) << __func__ << ": unable to enable real time scheduling"; + log::fatal("unable to enable real time scheduling"); #else - LOG(ERROR) << __func__ << ": unable to enable real time scheduling"; + log::error("unable to enable real time scheduling"); #endif } } diff --git a/system/stack/eatt/eatt.cc b/system/stack/eatt/eatt.cc index 9bd17d8a66545553723f10396a61f65c2ad97321..8a959c4ffb015b3822e2c92618a58094463cd69d 100644 --- a/system/stack/eatt/eatt.cc +++ b/system/stack/eatt/eatt.cc @@ -15,7 +15,7 @@ * limitations under the License. */ -#include +#include #include "eatt_impl.h" #include "stack/include/bt_hdr.h" @@ -33,7 +33,7 @@ struct EattExtension::impl { void Start() { if (eatt_impl_) { - LOG(ERROR) << "Eatt already started"; + log::error("Eatt already started"); return; }; @@ -48,7 +48,7 @@ struct EattExtension::impl { reg_info_.pL2CA_CreditBasedCollisionInd_Cb = eatt_collision_ind; if (L2CA_RegisterLECoc(BT_PSM_EATT, reg_info_, BTM_SEC_NONE, {}) == 0) { - LOG(ERROR) << __func__ << " cannot register EATT"; + log::error("cannot register EATT"); } else { eatt_impl_ = std::make_unique(); } @@ -56,7 +56,7 @@ struct EattExtension::impl { void Stop() { if (!eatt_impl_) { - LOG(ERROR) << "Eatt not started"; + log::error("Eatt not started"); return; } eatt_impl_.reset(nullptr); diff --git a/system/stack/eatt/eatt.h b/system/stack/eatt/eatt.h index a029395a6f813ea61ed662dfe774fd8227431160..62bf2482066dfeebe97aaf03e886cf829717ceaa 100644 --- a/system/stack/eatt/eatt.h +++ b/system/stack/eatt/eatt.h @@ -20,6 +20,7 @@ #include #include +#include "os/logging/log_adapter.h" #include "stack/gatt/gatt_int.h" #include "types/raw_address.h" diff --git a/system/stack/eatt/eatt_impl.h b/system/stack/eatt/eatt_impl.h index 240ac7e57bedc52adab912ada3c3b703e127e86d..79e626047ad69e5fcaabbcfdd826fb7cff58b3ab 100644 --- a/system/stack/eatt/eatt_impl.h +++ b/system/stack/eatt/eatt_impl.h @@ -16,22 +16,25 @@ */ #include +#include #include +#include #include "bind_helpers.h" #include "device/include/controller.h" #include "eatt.h" +#include "internal_include/bt_trace.h" #include "internal_include/stack_config.h" #include "l2c_api.h" #include "os/log.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "stack/btm/btm_sec.h" -#include "stack/include/btm_sec_api.h" #include "stack/gatt/gatt_int.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_psm_types.h" +#include "stack/include/btm_sec_api.h" #include "stack/include/main_thread.h" namespace bluetooth { @@ -62,6 +65,8 @@ struct eatt_impl { uint16_t max_mps_; tL2CAP_APPL_INFO reg_info_; + base::WeakPtrFactory weak_factory_{this}; + eatt_impl() { default_mtu_ = EATT_DEFAULT_MTU; max_mps_ = EATT_MIN_MTU_MPS; @@ -110,8 +115,8 @@ struct eatt_impl { void remove_channel_by_cid(eatt_device* eatt_dev, uint16_t lcid) { auto channel = eatt_dev->eatt_channels[lcid]; if (!channel->cl_cmd_q_.empty()) { - LOG_WARN("Channel %c, for device %s is not empty on disconnection.", lcid, - channel->bda_.ToString().c_str()); + log::warn("Channel {:c}, for device {} is not empty on disconnection.", + lcid, ADDRESS_TO_LOGGABLE_STR(channel->bda_)); channel->cl_cmd_q_.clear(); } @@ -140,8 +145,8 @@ struct eatt_impl { * for LE case it is not necessary to read it before establish connection. * Therefore assume, device supports EATT since we got request to create * EATT channels. Just create device here. */ - LOG(INFO) << __func__ << " Adding device: " << bda - << " on incoming EATT creation request"; + log::info("Adding device: {} on incoming EATT creation request", + ADDRESS_TO_LOGGABLE_STR(bda)); eatt_dev = add_eatt_device(bda); } @@ -174,7 +179,7 @@ struct eatt_impl { chan->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); eatt_dev->eatt_tcb_->eatt++; - LOG(INFO) << __func__ << " Channel connected CID " << loghex(cid); + log::info("Channel connected CID {}", loghex(cid)); } return true; @@ -186,8 +191,8 @@ struct eatt_impl { eatt_device* eatt_dev = find_device_by_address(bda); auto num_of_sdu = stack_config_get_interface()->get_pts_l2cap_ecoc_send_num_of_sdu(); - LOG_INFO(" device %s, num: %d", ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_), - num_of_sdu); + log::info("device {}, num: {}", ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_), + num_of_sdu); if (num_of_sdu <= 0) { return; @@ -209,7 +214,7 @@ struct eatt_impl { } if (cid == 0 || mtu == 0) { - LOG_ERROR("There is no OPEN cid or MTU is 0"); + log::error("There is no OPEN cid or MTU is 0"); return; } @@ -219,16 +224,17 @@ struct eatt_impl { p_buf->len = mtu; auto status = L2CA_DataWrite(cid, p_buf); - LOG_INFO("Data num: %d sent with status %d", i, static_cast(status)); + log::info("Data num: {} sent with status {}", i, + static_cast(status)); } } /* This is for the L2CAP ECoC Testing. */ void upper_tester_delay_connect_cb(const RawAddress& bda) { - LOG_INFO("device %s", ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::info("device {}", ADDRESS_TO_LOGGABLE_CSTR(bda)); eatt_device* eatt_dev = find_device_by_address(bda); if (eatt_dev == nullptr) { - LOG_ERROR(" device is not available"); + log::error("device is not available"); return; } @@ -239,16 +245,11 @@ struct eatt_impl { bt_status_t status = do_in_main_thread_delayed( FROM_HERE, base::BindOnce(&eatt_impl::upper_tester_delay_connect_cb, - base::Unretained(this), bda), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(timeout_ms) -#else - base::Milliseconds(timeout_ms) -#endif - ); - - LOG_INFO("Scheduled peripheral connect eatt for device with status: %d", - (int)status); + weak_factory_.GetWeakPtr(), bda), + std::chrono::milliseconds(timeout_ms)); + + log::info("Scheduled peripheral connect eatt for device with status: {}", + (int)status); } void upper_tester_l2cap_connect_ind(const RawAddress& bda, @@ -262,8 +263,8 @@ struct eatt_impl { auto key_size = btm_ble_read_sec_key_size(bda); if (key_size < min_key_size) { std::vector empty; - LOG_ERROR("Insufficient key size (%d<%d) for device %s", key_size, - min_key_size, ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::error("Insufficient key size ({}<{}) for device {}", key_size, + min_key_size, ADDRESS_TO_LOGGABLE_CSTR(bda)); L2CA_ConnectCreditBasedRsp(bda, identifier, empty, L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE, nullptr); @@ -272,7 +273,7 @@ struct eatt_impl { } if (!eatt_l2cap_connect_ind_common(bda, lcids, psm, peer_mtu, identifier)) { - LOG_DEBUG("Reject L2CAP Connection request."); + log::debug("Reject L2CAP Connection request."); return; } @@ -290,24 +291,19 @@ struct eatt_impl { if (stack_config_get_interface()->get_pts_l2cap_ecoc_reconfigure()) { bt_status_t status = do_in_main_thread_delayed( FROM_HERE, - base::BindOnce(&eatt_impl::reconfigure_all, base::Unretained(this), - bda, 300), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(4000) -#else - base::Milliseconds(4000) -#endif - ); - LOG_INFO("Scheduled ECOC reconfiguration with status: %d", (int)status); + base::BindOnce(&eatt_impl::reconfigure_all, + weak_factory_.GetWeakPtr(), bda, 300), + std::chrono::seconds(4)); + log::info("Scheduled ECOC reconfiguration with status: {}", (int)status); } } void eatt_l2cap_connect_ind(const RawAddress& bda, std::vector& lcids, uint16_t psm, uint16_t peer_mtu, uint8_t identifier) { - LOG_INFO("Device %s, num of cids: %d, psm 0x%04x, peer_mtu %d", - ADDRESS_TO_LOGGABLE_CSTR(bda), static_cast(lcids.size()), psm, - peer_mtu); + log::info("Device {}, num of cids: {}, psm 0x{:04x}, peer_mtu {}", + ADDRESS_TO_LOGGABLE_CSTR(bda), static_cast(lcids.size()), + psm, peer_mtu); if (!stack_config_get_interface() ->get_pts_connect_eatt_before_encryption() && @@ -318,14 +314,14 @@ struct eatt_impl { if (BTM_IsLinkKeyKnown(bda, BT_TRANSPORT_LE)) { result = L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP; } - LOG_ERROR("ACL to device %s is unencrypted.", - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::error("ACL to device {} is unencrypted.", + ADDRESS_TO_LOGGABLE_CSTR(bda)); L2CA_ConnectCreditBasedRsp(bda, identifier, empty, result, nullptr); return; } if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) { - LOG_INFO(" Upper tester for the L2CAP ECoC enabled"); + log::info("Upper tester for the L2CAP ECoC enabled"); return upper_tester_l2cap_connect_ind(bda, lcids, psm, peer_mtu, identifier); } @@ -335,22 +331,21 @@ struct eatt_impl { void eatt_retry_after_collision_if_needed(eatt_device* eatt_dev) { if (!eatt_dev->collision) { - LOG_DEBUG("No collision."); + log::debug("No collision."); return; } /* We are here, because remote device wanted to create channels when * Android proceed its own EATT creation. How to handle it is described * here: BT Core 5.3, Volume 3, Part G, 5.4 */ - LOG_INFO( - "EATT collision detected. If we are Central we will retry right " - "away"); + log::info( + "EATT collision detected. If we are Central we will retry right away"); eatt_dev->collision = false; uint8_t role = L2CA_GetBleConnRole(eatt_dev->bda_); if (role == HCI_ROLE_CENTRAL) { - LOG_INFO("Retrying EATT setup due to previous collision for device %s", - ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_)); + log::info("Retrying EATT setup due to previous collision for device {}", + ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_)); connect_eatt_wrap(eatt_dev); } else if (stack_config_get_interface() ->get_pts_eatt_peripheral_collision_support()) { @@ -363,19 +358,19 @@ struct eatt_impl { /* This is for the L2CAP ECoC Testing. */ void upper_tester_l2cap_connect_cfm(eatt_device* eatt_dev) { - LOG_INFO("Upper tester for L2CAP Ecoc %s", - ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_)); + log::info("Upper tester for L2CAP Ecoc {}", + ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_)); if (is_channel_connection_pending(eatt_dev)) { - LOG_INFO(" Waiting for all channels to be connected"); + log::info("Waiting for all channels to be connected"); return; } if (stack_config_get_interface()->get_pts_l2cap_ecoc_connect_remaining() && (static_cast(eatt_dev->eatt_channels.size()) < L2CAP_CREDIT_BASED_MAX_CIDS)) { - LOG_INFO("Connecting remaining channels %d", - L2CAP_CREDIT_BASED_MAX_CIDS - - static_cast(eatt_dev->eatt_channels.size())); + log::info("Connecting remaining channels {}", + L2CAP_CREDIT_BASED_MAX_CIDS - + static_cast(eatt_dev->eatt_channels.size())); upper_tester_delay_connect(eatt_dev->bda_, 1000); return; } @@ -384,24 +379,23 @@ struct eatt_impl { void eatt_l2cap_connect_cfm(const RawAddress& bda, uint16_t lcid, uint16_t peer_mtu, uint16_t result) { - LOG(INFO) << __func__ << " bda: " << bda << " cid: " << +lcid - << "peer mtu: " << +peer_mtu << " result " << +result; + log::info("bda: {} cid: {}peer mtu: {} result {}", + ADDRESS_TO_LOGGABLE_STR(bda), +lcid, +peer_mtu, +result); eatt_device* eatt_dev = find_device_by_address(bda); if (!eatt_dev) { - LOG(ERROR) << __func__ << " unknown device"; + log::error("unknown device"); return; } EattChannel* channel = this->find_channel_by_cid(bda, lcid); if (!channel) { - LOG(ERROR) << __func__ << " unknown cid: " << loghex(lcid); + log::error("unknown cid: {}", loghex(lcid)); return; } if (result != L2CAP_CONN_OK) { - LOG(ERROR) << __func__ - << " Could not connect CoC result: " << loghex(result); + log::error("Could not connect CoC result: {}", loghex(result)); remove_channel_by_cid(eatt_dev, lcid); /* If there is no channels connected, check if there was collision */ @@ -418,7 +412,7 @@ struct eatt_impl { CHECK(eatt_dev->bda_ == channel->bda_); eatt_dev->eatt_tcb_->eatt++; - LOG_INFO("Channel connected CID 0x%04x", lcid); + log::info("Channel connected CID 0x{:04x}", lcid); if (stack_config_get_interface()->get_pts_l2cap_ecoc_upper_tester()) { upper_tester_l2cap_connect_cfm(eatt_dev); @@ -428,8 +422,7 @@ struct eatt_impl { void eatt_l2cap_reconfig_completed(const RawAddress& bda, uint16_t lcid, bool is_local_cfg, tL2CAP_LE_CFG_INFO* p_cfg) { - LOG(INFO) << __func__ << "lcid: " << loghex(lcid) - << " local cfg?: " << is_local_cfg; + log::info("lcid: {} local cfg?: {}", loghex(lcid), is_local_cfg); EattChannel* channel = find_channel_by_cid(bda, lcid); if (!channel) return; @@ -438,8 +431,8 @@ struct eatt_impl { channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); if (p_cfg->result != L2CAP_CFG_OK) { - LOG(INFO) << __func__ << " reconfig failed lcid: " << loghex(lcid) - << " result: " << loghex(p_cfg->result); + log::info("reconfig failed lcid: {} result: {}", loghex(lcid), + loghex(p_cfg->result)); return; } @@ -455,21 +448,16 @@ struct eatt_impl { do_in_main_thread_delayed( FROM_HERE, base::BindOnce(&eatt_impl::upper_tester_send_data_if_needed, - base::Unretained(this), bda, lcid), -#if BASE_VER < 931007 - base::TimeDelta::FromMilliseconds(1000) -#else - base::Milliseconds(1000) -#endif - ); + weak_factory_.GetWeakPtr(), bda, lcid), + std::chrono::seconds(1)); } } void eatt_l2cap_collision_ind(const RawAddress& bda) { eatt_device* eatt_dev = find_device_by_address(bda); if (!eatt_dev) { - LOG_ERROR("Device %s not available anymore:", - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::error("Device {} not available anymore:", + ADDRESS_TO_LOGGABLE_CSTR(bda)); return; } /* Remote wanted to setup channels as well. Let's retry remote's request @@ -478,14 +466,13 @@ struct eatt_impl { } void eatt_l2cap_error_cb(uint16_t lcid, uint16_t reason) { - LOG(INFO) << __func__ << " cid: " << loghex(lcid) << " reason " - << loghex(reason); + log::info("cid: {} reason {}", loghex(lcid), loghex(reason)); /*TODO: provide address in the L2CAP callback */ EattChannel* channel = find_channel_by_cid(lcid); if (!channel) { - LOG(ERROR) << __func__ << "Unknown lcid"; + log::error("Unknown lcid"); return; } @@ -493,17 +480,16 @@ struct eatt_impl { switch (channel->state_) { case EattChannelState::EATT_CHANNEL_PENDING: - LOG(ERROR) << "Connecting failed"; + log::error("Connecting failed"); remove_channel_by_cid(eatt_dev, lcid); break; case EattChannelState::EATT_CHANNEL_RECONFIGURING: /* Just go back to open state */ - LOG(ERROR) << "Reconfig failed"; + log::error("Reconfig failed"); channel->EattChannelSetState(EattChannelState::EATT_CHANNEL_OPENED); break; default: - LOG(ERROR) << __func__ << "Invalid state: " - << static_cast(channel->state_); + log::error("Invalid state: {}", static_cast(channel->state_)); break; } @@ -513,10 +499,10 @@ struct eatt_impl { } void eatt_l2cap_disconnect_ind(uint16_t lcid, bool please_confirm) { - LOG(INFO) << __func__ << " cid: " << loghex(lcid); + log::info("cid: {}", loghex(lcid)); eatt_device* eatt_dev = find_device_by_cid(lcid); if (!eatt_dev) { - LOG(ERROR) << __func__ << " unknown cid: " << loghex(lcid); + log::error("unknown cid: {}", loghex(lcid)); return; } @@ -525,17 +511,16 @@ struct eatt_impl { } void eatt_l2cap_data_ind(uint16_t lcid, BT_HDR* data_p) { - LOG(INFO) << __func__ << " cid: " << loghex(lcid); + log::info("cid: {}", loghex(lcid)); eatt_device* eatt_dev = find_device_by_cid(lcid); if (!eatt_dev) { - LOG(ERROR) << __func__ << " unknown cid: " << loghex(lcid); + log::error("unknown cid: {}", loghex(lcid)); return; } EattChannel* channel = find_channel_by_cid(eatt_dev->bda_, lcid); if (!channel) { - LOG(ERROR) << __func__ << "Received data on closed channel " - << loghex(lcid); + log::error("Received data on closed channel {}", loghex(lcid)); return; } @@ -565,8 +550,8 @@ struct eatt_impl { if (stack_config_get_interface() ->get_pts_eatt_peripheral_collision_support()) { /* For PTS case, lets assume we support only 5 channels */ - LOG_INFO("Number of existing channels %d", - (int)eatt_dev->eatt_channels.size()); + log::info("Number of existing channels {}", + (int)eatt_dev->eatt_channels.size()); connect_eatt(eatt_dev, L2CAP_CREDIT_BASED_MAX_CIDS - (int)eatt_dev->eatt_channels.size()); return; @@ -588,24 +573,23 @@ struct eatt_impl { .number_of_channels = num_of_channels, }; - LOG_INFO("Connecting device %s, cnt count %d", - ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_), num_of_channels); + log::info("Connecting device {}, cnt count {}", + ADDRESS_TO_LOGGABLE_CSTR(eatt_dev->bda_), num_of_channels); /* Warning! CIDs in Android are unique across the ACL connections */ std::vector connecting_cids = L2CA_ConnectCreditBasedReq(psm_, eatt_dev->bda_, &local_coc_cfg); if (connecting_cids.size() == 0) { - LOG(ERROR) << "Unable to get cid"; + log::error("Unable to get cid"); return; } - LOG(INFO) << __func__ - << "Successfully sent CoC request, number of channel: " - << +connecting_cids.size(); + log::info("Successfully sent CoC request, number of channel: {}", + +connecting_cids.size()); for (uint16_t cid : connecting_cids) { - LOG(INFO) << " \t cid: " << loghex(cid); + log::info(" \t cid: {}", loghex(cid)); auto chan = std::make_shared(eatt_dev->bda_, cid, 0, eatt_dev->rx_mtu_); @@ -613,7 +597,7 @@ struct eatt_impl { } if (eatt_dev->eatt_tcb_) { - LOG(INFO) << __func__ << " has tcb ? " << eatt_dev->eatt_tcb_; + log::info("has tcb ? {}", eatt_dev->eatt_tcb_ == nullptr); return; } @@ -744,7 +728,7 @@ struct eatt_impl { EattChannel* channel = (EattChannel*)data; tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(channel->bda_, BT_TRANSPORT_LE); - LOG(WARNING) << __func__ << ": send ack now"; + log::warn("send ack now"); attp_send_cl_confirmation_msg(*p_tcb, channel->cid_); } @@ -752,15 +736,15 @@ struct eatt_impl { EattChannel* channel = (EattChannel*)data; tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(channel->bda_, BT_TRANSPORT_LE); - LOG(WARNING) << __func__ << " disconnecting..."; + log::warn("disconnecting..."); gatt_disconnect(p_tcb); } void start_indication_confirm_timer(const RawAddress& bd_addr, uint16_t cid) { EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); if (!channel) { - LOG(ERROR) << __func__ << "Unknown cid: " << loghex(cid) << " or device " - << bd_addr; + log::error("Unknown cid: {} or device {}", loghex(cid), + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -772,8 +756,8 @@ struct eatt_impl { void stop_indication_confirm_timer(const RawAddress& bd_addr, uint16_t cid) { EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); if (!channel) { - LOG(ERROR) << __func__ << "Unknown cid: " << loghex(cid) << " or device " - << bd_addr; + log::error("Unknown cid: {} or device {}", loghex(cid), + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -783,8 +767,8 @@ struct eatt_impl { void start_app_indication_timer(const RawAddress& bd_addr, uint16_t cid) { EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); if (!channel) { - LOG(ERROR) << __func__ << "Unknown cid: " << loghex(cid) << " or device " - << bd_addr; + log::error("Unknown cid: {} or device {}", loghex(cid), + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -795,8 +779,8 @@ struct eatt_impl { void stop_app_indication_timer(const RawAddress& bd_addr, uint16_t cid) { EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); if (!channel) { - LOG(ERROR) << __func__ << "Unknown cid: " << loghex(cid) << " or device " - << bd_addr; + log::error("Unknown cid: {} or device {}", loghex(cid), + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -806,19 +790,19 @@ struct eatt_impl { void reconfigure(const RawAddress& bd_addr, uint16_t cid, uint16_t new_mtu) { eatt_device* eatt_dev = find_device_by_address(bd_addr); if (!eatt_dev) { - LOG(ERROR) << __func__ << "Unknown device " << bd_addr; + log::error("Unknown device {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } EattChannel* channel = find_eatt_channel_by_cid(bd_addr, cid); if (!channel) { - LOG(ERROR) << __func__ << "Unknown cid: " << loghex(cid) << " or device " - << bd_addr; + log::error("Unknown cid: {} or device {}", loghex(cid), + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } if (new_mtu <= channel->rx_mtu_) { - LOG(ERROR) << __func__ << "Invalid mtu: " << loghex(new_mtu); + log::error("Invalid mtu: {}", loghex(new_mtu)); return; } @@ -827,8 +811,8 @@ struct eatt_impl { tL2CAP_LE_CFG_INFO cfg = {.mtu = new_mtu, .mps = eatt_dev->rx_mps_}; if (!L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, &cfg)) { - LOG(ERROR) << __func__ << "Could not start reconfig cid: " << loghex(cid) - << " or device " << bd_addr; + log::error("Could not start reconfig cid: {} or device {}", loghex(cid), + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -836,17 +820,17 @@ struct eatt_impl { } void reconfigure_all(const RawAddress& bd_addr, uint16_t new_mtu) { - LOG_INFO(" Device %s, new mtu %d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - new_mtu); + log::info("Device {}, new mtu {}", ADDRESS_TO_LOGGABLE_STR(bd_addr), + new_mtu); eatt_device* eatt_dev = find_device_by_address(bd_addr); if (!eatt_dev) { - LOG(ERROR) << __func__ << "Unknown device " << bd_addr; + log::error("Unknown device {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } uint8_t num_of_channels = eatt_dev->eatt_channels.size(); if (num_of_channels == 0) { - LOG(ERROR) << __func__ << "No channels for device " << bd_addr; + log::error("No channels for device {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -860,15 +844,15 @@ struct eatt_impl { } if (new_mtu <= EATT_MIN_MTU_MPS) { - LOG(ERROR) << __func__ << "Invalid mtu: " << loghex(new_mtu); + log::error("Invalid mtu: {}", loghex(new_mtu)); return; } tL2CAP_LE_CFG_INFO cfg = {.mtu = new_mtu, .mps = eatt_dev->rx_mps_}; if (!L2CA_ReconfigCreditBasedConnsReq(eatt_dev->bda_, cids, &cfg)) { - LOG(ERROR) << __func__ << "Could not start reconfig for device " - << bd_addr; + log::error("Could not start reconfig for device {}", + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -882,22 +866,21 @@ struct eatt_impl { uint8_t features) { bool is_eatt_supported = features & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; - LOG(INFO) << __func__ << " " << bd_addr - << " is_eatt_supported = " << int(is_eatt_supported); + log::info("{} is_eatt_supported = {}", ADDRESS_TO_LOGGABLE_STR(bd_addr), + int(is_eatt_supported)); if (!is_eatt_supported) return; eatt_device* eatt_dev = this->find_device_by_address(bd_addr); if (!eatt_dev) { - LOG(INFO) << __func__ << " Adding device: " << bd_addr - << " on supported features callback."; + log::info("Adding device: {} on supported features callback.", + ADDRESS_TO_LOGGABLE_STR(bd_addr)); eatt_dev = add_eatt_device(bd_addr); } if (role != HCI_ROLE_CENTRAL) { /* TODO For now do nothing, we could run a timer here and start EATT if * not started by central */ - LOG(INFO) - << " EATT Should be connected by the central. Let's wait for it."; + log::info(" EATT Should be connected by the central. Let's wait for it."); return; } @@ -907,29 +890,29 @@ struct eatt_impl { void disconnect_channel(uint16_t cid) { L2CA_DisconnectReq(cid); } void disconnect(const RawAddress& bd_addr, uint16_t cid) { - LOG_INFO(" Device: %s, cid: 0x%04x", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - cid); + log::info("Device: {}, cid: 0x{:04x}", ADDRESS_TO_LOGGABLE_STR(bd_addr), + cid); eatt_device* eatt_dev = find_device_by_address(bd_addr); if (!eatt_dev) { - LOG(WARNING) << __func__ << " no eatt device found"; + log::warn("no eatt device found"); return; } if (!eatt_dev->eatt_tcb_) { LOG_ASSERT(eatt_dev->eatt_channels.size() == 0); - LOG(WARNING) << __func__ << " no eatt channels found"; + log::warn("no eatt channels found"); return; } if (cid != EATT_ALL_CIDS) { auto chan = find_channel_by_cid(cid); if (!chan) { - LOG_WARN("Cid %d not found for device %s", cid, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("Cid {} not found for device {}", cid, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return; } - LOG_INFO("Disconnecting cid %d", cid); + log::info("Disconnecting cid {}", cid); disconnect_channel(cid); remove_channel_by_cid(cid); return; @@ -951,9 +934,9 @@ struct eatt_impl { void upper_tester_connect(const RawAddress& bd_addr, eatt_device* eatt_dev, uint8_t role) { - LOG_INFO( - "L2CAP Upper tester enabled, %s (%p), role: %s(%d)", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), eatt_dev, + log::info( + "L2CAP Upper tester enabled, {} ({}), role: {}({})", + ADDRESS_TO_LOGGABLE_STR(bd_addr), fmt::ptr(eatt_dev), role == HCI_ROLE_CENTRAL ? "HCI_ROLE_CENTRAL" : "HCI_ROLE_PERIPHERAL", role); @@ -981,9 +964,10 @@ struct eatt_impl { /* If we don't know yet, read GATT server supported features. */ if (gatt_cl_read_sr_supp_feat_req( bd_addr, base::BindOnce(&eatt_impl::supported_features_cb, - base::Unretained(this), role)) == false) { - LOG_INFO("Read server supported features failed for device %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + weak_factory_.GetWeakPtr(), role)) == + false) { + log::info("Read server supported features failed for device {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } @@ -992,7 +976,8 @@ struct eatt_impl { uint8_t role = L2CA_GetBleConnRole(bd_addr); if (role == HCI_ROLE_UNKNOWN) { - LOG(ERROR) << __func__ << "Could not get device role" << bd_addr; + log::error("Could not get device role{}", + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return; } @@ -1001,18 +986,18 @@ struct eatt_impl { return; } - LOG_INFO("Device %s, role %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - (role == HCI_ROLE_CENTRAL ? "central" : "peripheral")); + log::info("Device {}, role {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + (role == HCI_ROLE_CENTRAL ? "central" : "peripheral")); if (eatt_dev) { /* We are reconnecting device we know that support EATT. * Just connect CoC */ - LOG(INFO) << __func__ << " Known device, connect eCoC"; + log::info("Known device, connect eCoC"); if (role != HCI_ROLE_CENTRAL) { - LOG(INFO) - << " EATT Should be connected by the central. Let's wait for it."; + log::info( + " EATT Should be connected by the central. Let's wait for it."); return; } @@ -1023,8 +1008,8 @@ struct eatt_impl { if (role != HCI_ROLE_CENTRAL) return; if (gatt_profile_get_eatt_support(bd_addr)) { - LOG_DEBUG("Eatt is supported for device %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Eatt is supported for device {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); supported_features_cb(role, bd_addr, BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK); return; } @@ -1032,16 +1017,17 @@ struct eatt_impl { /* If we don't know yet, read GATT server supported features. */ if (gatt_cl_read_sr_supp_feat_req( bd_addr, base::BindOnce(&eatt_impl::supported_features_cb, - base::Unretained(this), role)) == false) { - LOG_INFO("Read server supported features failed for device %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + weak_factory_.GetWeakPtr(), role)) == + false) { + log::info("Read server supported features failed for device {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); } } void add_from_storage(const RawAddress& bd_addr) { eatt_device* eatt_dev = find_device_by_address(bd_addr); - LOG(INFO) << __func__ << ", restoring: " << bd_addr; + log::info("restoring: {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); if (!eatt_dev) add_eatt_device(bd_addr); } diff --git a/system/stack/fuzzers/avrc_fuzzer.cc b/system/stack/fuzzers/avrc_fuzzer.cc index 70743e9cc7009384709682e54623b536c9159155..29f6c4fb436da87bc2a21f3f923e46420bec8132 100644 --- a/system/stack/fuzzers/avrc_fuzzer.cc +++ b/system/stack/fuzzers/avrc_fuzzer.cc @@ -19,9 +19,10 @@ #include #include -#include +#include #include +#include "include/check.h" #include "osi/include/allocator.h" #include "stack/include/avct_api.h" #include "stack/include/avrc_api.h" diff --git a/system/stack/fuzzers/bnep_fuzzer.cc b/system/stack/fuzzers/bnep_fuzzer.cc index f4da8de8eceda2e4642401dbef46c4b312bc5416..70a9fcdcc2c6ac1b40c7b3add59df7f119a37653 100644 --- a/system/stack/fuzzers/bnep_fuzzer.cc +++ b/system/stack/fuzzers/bnep_fuzzer.cc @@ -18,7 +18,6 @@ #include #include -#include #include #include "osi/include/allocator.h" diff --git a/system/stack/fuzzers/gatt_fuzzer.cc b/system/stack/fuzzers/gatt_fuzzer.cc index 6444e5a870efa41d10ca0d61f35f2a612b7eee24..6e655412de167d473a80e225f2fb5cd25a22edcf 100644 --- a/system/stack/fuzzers/gatt_fuzzer.cc +++ b/system/stack/fuzzers/gatt_fuzzer.cc @@ -1,3 +1,19 @@ +/* + * Copyright 2023 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 #include @@ -24,7 +40,7 @@ bt_status_t do_in_main_thread(base::Location const&, } bt_status_t do_in_main_thread_delayed(base::Location const&, base::OnceCallback, - base::TimeDelta const&) { + std::chrono::microseconds) { // this is not properly mocked, so we use abort to catch if this is used in // any test cases abort(); diff --git a/system/stack/fuzzers/l2cap_fuzzer.cc b/system/stack/fuzzers/l2cap_fuzzer.cc index 01d7d7de308807d3590abddb62c61d71ac84209e..ec74ad47c7de82bebbb88b35627c011e8ffe8cf5 100644 --- a/system/stack/fuzzers/l2cap_fuzzer.cc +++ b/system/stack/fuzzers/l2cap_fuzzer.cc @@ -21,8 +21,9 @@ #include #include -#include "btif/include/stack_manager.h" -#include "gd/hal/snoop_logger.h" +#include "btif/include/stack_manager_t.h" +#include "hal/snoop_logger.h" +#include "include/check.h" #include "osi/include/allocator.h" #include "stack/btm/btm_int_types.h" #include "stack/include/bt_psm_types.h" @@ -55,7 +56,7 @@ bt_status_t do_in_main_thread(base::Location const&, } bt_status_t do_in_main_thread_delayed(base::Location const&, base::OnceCallback, - base::TimeDelta const&) { + std::chrono::microseconds) { // this is not properly mocked, so we use abort to catch if this is used in // any test cases abort(); diff --git a/system/stack/fuzzers/smp_fuzzer.cc b/system/stack/fuzzers/smp_fuzzer.cc index 6a23254f452a6554dad00d3ddbb5befea7b38f5b..a8667e1118c66293ac58bd9a6fae285c4a9c6f28 100644 --- a/system/stack/fuzzers/smp_fuzzer.cc +++ b/system/stack/fuzzers/smp_fuzzer.cc @@ -18,15 +18,11 @@ #include #include -#include #include #include "osi/include/allocator.h" -#include "stack/btm/btm_int_types.h" #include "stack/include/bt_hdr.h" -#include "stack/include/sdpdefs.h" #include "stack/include/smp_api.h" -#include "stack/smp/p_256_ecc_pp.h" #include "stack/smp/smp_int.h" #include "test/fake/fake_osi.h" #include "test/mock/mock_btif_config.h" @@ -34,7 +30,6 @@ #include "test/mock/mock_stack_btm_dev.h" #include "test/mock/mock_stack_l2cap_api.h" #include "test/mock/mock_stack_l2cap_ble.h" -#include "types/bluetooth/uuid.h" namespace { diff --git a/system/stack/gap/gap_ble.cc b/system/stack/gap/gap_ble.cc index b5801105a465554f32d619e0e850a97c799dc330..4e99d5d4bddca3a259f90ac9385be862e5191ab0 100644 --- a/system/stack/gap/gap_ble.cc +++ b/system/stack/gap/gap_ble.cc @@ -16,8 +16,7 @@ * ******************************************************************************/ -#include -#include +#include #include #include @@ -34,8 +33,8 @@ #include "types/bt_transport.h" #include "types/raw_address.h" -using base::StringPrintf; using bluetooth::Uuid; +using namespace bluetooth; namespace { @@ -222,17 +221,16 @@ void server_attr_request_cback(uint16_t conn_id, uint32_t trans_id, case GATTS_REQ_TYPE_WRITE_EXEC: ignore = true; - VLOG(1) << "Ignore GATTS_REQ_TYPE_WRITE_EXEC"; + log::verbose("Ignore GATTS_REQ_TYPE_WRITE_EXEC"); break; case GATTS_REQ_TYPE_MTU: - VLOG(1) << "Get MTU exchange new mtu size: " << +p_data->mtu; + log::verbose("Get MTU exchange new mtu size: {}", +p_data->mtu); ignore = true; break; default: - VLOG(1) << StringPrintf("Unknown/unexpected LE GAP ATT request: 0x%02x", - type); + log::verbose("Unknown/unexpected LE GAP ATT request: 0x{:02x}", type); break; } @@ -295,19 +293,20 @@ void client_connect_cback(tGATT_IF, const RawAddress& bda, uint16_t conn_id, tBT_TRANSPORT) { tGAP_CLCB* p_clcb = find_clcb_by_bd_addr(bda); if (p_clcb == NULL) { - LOG_INFO("No active GAP service found for peer:%s callback:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda), (connected) ? "Connected" : "Disconnected"); + log::info("No active GAP service found for peer:{} callback:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda), + (connected) ? "Connected" : "Disconnected"); return; } if (connected) { - LOG_DEBUG("Connected GAP to remote device"); + log::debug("Connected GAP to remote device"); p_clcb->conn_id = conn_id; p_clcb->connected = true; /* start operation is pending */ send_cl_read_request(*p_clcb); } else { - LOG_WARN("Disconnected GAP from remote device"); + log::warn("Disconnected GAP from remote device"); p_clcb->connected = false; cl_op_cmpl(*p_clcb, false, 0, NULL); /* clean up clcb */ @@ -545,13 +544,13 @@ bool GAP_BleCancelReadPeerDevName(const RawAddress& peer_bda) { tGAP_CLCB* p_clcb = find_clcb_by_bd_addr(peer_bda); if (p_clcb == NULL) { - LOG(ERROR) << "Cannot cancel current op is not get dev name"; + log::error("Cannot cancel current op is not get dev name"); return false; } if (!p_clcb->connected) { if (!GATT_CancelConnect(gatt_if, peer_bda, true)) { - LOG(ERROR) << "Cannot cancel where No connection id"; + log::error("Cannot cancel where No connection id"); return false; } } diff --git a/system/stack/gap/gap_conn.cc b/system/stack/gap/gap_conn.cc index 36df97466fb362371257ba1d06086916edcf9a60..bb1b7c08f1c1547188d1a39933200104aced1f02 100644 --- a/system/stack/gap/gap_conn.cc +++ b/system/stack/gap/gap_conn.cc @@ -16,13 +16,12 @@ * ******************************************************************************/ -#include -#include +#include #include #include "device/include/controller.h" #include "gap_api.h" -#include "internal_include//bt_target.h" +#include "internal_include/bt_target.h" #include "l2c_api.h" #include "l2cdefs.h" #include "osi/include/allocator.h" @@ -32,7 +31,7 @@ #include "stack/include/bt_hdr.h" #include "types/raw_address.h" -using base::StringPrintf; +using namespace bluetooth; /* Define the GAP Connection Control Block */ typedef struct { @@ -197,8 +196,8 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, /* A client MUST have specified a bd addr to connect with */ if (!p_ccb->rem_addr_specified && !is_server) { gap_release_ccb(p_ccb); - LOG(ERROR) - << "GAP ERROR: Client must specify a remote BD ADDR to connect to!"; + log::error( + "GAP ERROR: Client must specify a remote BD ADDR to connect to!"); return (GAP_INVALID_HANDLE); } @@ -212,7 +211,7 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, uint16_t max_mps = controller_get_interface()->get_acl_data_size_ble(); if (le_mps > max_mps) { - LOG(INFO) << "Limiting MPS to one buffer size - " << max_mps; + log::info("Limiting MPS to one buffer size - {}", max_mps); le_mps = max_mps; } p_ccb->local_coc_cfg.mps = le_mps; @@ -241,8 +240,7 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, L2CA_Register2(psm, conn.reg_info, false /* enable_snoop */, &p_ccb->ertm_info, L2CAP_SDU_LENGTH_MAX, 0, security); if (p_ccb->psm == 0) { - LOG(ERROR) << StringPrintf("%s: Failure registering PSM 0x%04x", __func__, - psm); + log::error("Failure registering PSM 0x{:04x}", psm); gap_release_ccb(p_ccb); return (GAP_INVALID_HANDLE); } @@ -252,8 +250,7 @@ uint16_t GAP_ConnOpen(const char* p_serv_name, uint8_t service_id, p_ccb->psm = L2CA_RegisterLECoc(psm, conn.reg_info, security, p_ccb->local_coc_cfg); if (p_ccb->psm == 0) { - LOG(ERROR) << StringPrintf("%s: Failure registering PSM 0x%04x", __func__, - psm); + log::error("Failure registering PSM 0x{:04x}", psm); gap_release_ccb(p_ccb); return (GAP_INVALID_HANDLE); } @@ -593,10 +590,10 @@ static void gap_connect_ind(const RawAddress& bd_addr, uint16_t l2cap_cid, } if (xx == GAP_MAX_CONNECTIONS) { - LOG(WARNING) << "*******"; - LOG(WARNING) << "WARNING: GAP Conn Indication for Unexpected Bd " - "Addr...Disconnecting"; - LOG(WARNING) << "*******"; + log::warn("*******"); + log::warn( + "WARNING: GAP Conn Indication for Unexpected Bd Addr...Disconnecting"); + log::warn("*******"); /* Disconnect because it is an unexpected connection */ if (BTM_UseLeLink(bd_addr)) { @@ -829,10 +826,8 @@ static void gap_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg) { fixed_queue_enqueue(p_ccb->rx_queue, p_msg); p_ccb->rx_queue_size += p_msg->len; - /* - VLOG(1) << StringPrintf ("gap_data_ind - rx_queue_size=%d, msg len=%d", - p_ccb->rx_queue_size, p_msg->len); - */ + // log::verbose("gap_data_ind - rx_queue_size={}, msg len={}", + // p_ccb->rx_queue_size, p_msg->len); p_ccb->p_callback(p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL, nullptr); } else { diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc index be04498139e070fc05aa4560761580c9fbf43c23..23243bdd7ee61aad2c34c41f376705b242a76a88 100644 --- a/system/stack/gatt/att_protocol.cc +++ b/system/stack/gatt/att_protocol.cc @@ -23,6 +23,7 @@ ******************************************************************************/ #include +#include #include "gatt_int.h" #include "internal_include/bt_target.h" @@ -39,6 +40,8 @@ using base::StringPrintf; using bluetooth::Uuid; +using namespace bluetooth; + /********************************************************************** * ATT protocl message building utility * **********************************************************************/ @@ -337,8 +340,7 @@ static BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, pair_len = (len + 2); } - LOG(WARNING) << StringPrintf( - "attribute value too long, to be truncated to %d", len); + log::warn("attribute value too long, to be truncated to {}", len); } size_now += len; @@ -375,18 +377,18 @@ tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t lcid, uint16_t l2cap_ret; if (lcid == L2CAP_ATT_CID) { - LOG_DEBUG("Sending ATT message on att fixed channel"); + log::debug("Sending ATT message on att fixed channel"); l2cap_ret = L2CA_SendFixedChnlData(lcid, tcb.peer_bda, p_toL2CAP); } else { - LOG_DEBUG("Sending ATT message on lcid:%hu", lcid); + log::debug("Sending ATT message on lcid:{}", lcid); l2cap_ret = (uint16_t)L2CA_DataWrite(lcid, p_toL2CAP); } if (l2cap_ret == L2CAP_DW_FAILED) { - LOG(ERROR) << __func__ << ": failed to write data to L2CAP"; + log::error("failed to write data to L2CAP"); return GATT_INTERNAL_ERROR; } else if (l2cap_ret == L2CAP_DW_CONGESTED) { - VLOG(1) << StringPrintf("ATT congested, message accepted"); + log::verbose("ATT congested, message accepted"); return GATT_CONGESTED; } return GATT_SUCCESS; @@ -397,11 +399,18 @@ BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code, tGATT_SR_MSG* p_msg, uint16_t payload_size) { uint16_t offset = 0; + if (payload_size == 0) { + log::error( + "Cannot send response (op: 0x{:02x}) due to payload size = 0, {}", + op_code, ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda)); + return nullptr; + } + switch (op_code) { case GATT_RSP_READ_BLOB: case GATT_RSP_PREPARE_WRITE: - VLOG(1) << StringPrintf( - "ATT_RSP_READ_BLOB/GATT_RSP_PREPARE_WRITE: len = %d offset = %d", + log::verbose( + "ATT_RSP_READ_BLOB/GATT_RSP_PREPARE_WRITE: len = {} offset = {}", p_msg->attr_value.len, p_msg->attr_value.offset); offset = p_msg->attr_value.offset; FALLTHROUGH_INTENDED; /* FALLTHROUGH */ @@ -427,7 +436,7 @@ BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code, tGATT_SR_MSG* p_msg, return attp_build_mtu_cmd(op_code, p_msg->mtu); default: - LOG(FATAL) << "attp_build_sr_msg: unknown op code = " << +op_code; + log::fatal("attp_build_sr_msg: unknown op code = {}", +op_code); return nullptr; } } @@ -448,11 +457,11 @@ BT_HDR* attp_build_sr_msg(tGATT_TCB& tcb, uint8_t op_code, tGATT_SR_MSG* p_msg, ******************************************************************************/ tGATT_STATUS attp_send_sr_msg(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_msg) { if (p_msg == NULL) { - LOG_WARN("Unable to send empty message"); + log::warn("Unable to send empty message"); return GATT_NO_RESOURCES; } - LOG_DEBUG("Sending server response or indication message to client"); + log::debug("Sending server response or indication message to client"); p_msg->offset = L2CAP_MIN_OFFSET; return attp_send_msg_to_l2cap(tcb, cid, p_msg); } @@ -476,24 +485,24 @@ static tGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, if (gatt_tcb_is_cid_busy(tcb, p_clcb->cid) && cmd_code != GATT_HANDLE_VALUE_CONF) { if (gatt_cmd_enq(tcb, p_clcb, true, cmd_code, p_cmd)) { - LOG_DEBUG("Enqueued ATT command %p conn_id=0x%04x, cid=%d", p_clcb, - p_clcb->conn_id, p_clcb->cid); + log::debug("Enqueued ATT command {} conn_id=0x{:04x}, cid={}", + fmt::ptr(p_clcb), p_clcb->conn_id, p_clcb->cid); return GATT_CMD_STARTED; } - LOG_ERROR("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), p_clcb->cid); + log::error("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), p_clcb->cid); return GATT_INTERNAL_ERROR; } - LOG_DEBUG( - "Sending ATT command to l2cap cid:0x%04x eatt_channels:%u transport:%s", - p_clcb->cid, tcb.eatt, bt_transport_text(tcb.transport).c_str()); + log::debug( + "Sending ATT command to l2cap cid:0x{:04x} eatt_channels:{} transport:{}", + p_clcb->cid, tcb.eatt, bt_transport_text(tcb.transport)); tGATT_STATUS att_ret = attp_send_msg_to_l2cap(tcb, p_clcb->cid, p_cmd); if (att_ret != GATT_CONGESTED && att_ret != GATT_SUCCESS) { - LOG_WARN( - "Unable to send ATT command to l2cap layer %p conn_id=0x%04x, cid=%d", - p_clcb, p_clcb->conn_id, p_clcb->cid); + log::warn( + "Unable to send ATT command to l2cap layer {} conn_id=0x{:04x}, cid={}", + fmt::ptr(p_clcb), p_clcb->conn_id, p_clcb->cid); return GATT_INTERNAL_ERROR; } @@ -501,12 +510,13 @@ static tGATT_STATUS attp_cl_send_cmd(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, return att_ret; } - LOG_DEBUG("Starting ATT response timer %p conn_id=0x%04x, cid=%d", p_clcb, - p_clcb->conn_id, p_clcb->cid); + log::debug("Starting ATT response timer {} conn_id=0x{:04x}, cid={}", + fmt::ptr(p_clcb), p_clcb->conn_id, p_clcb->cid); gatt_start_rsp_timer(p_clcb); if (!gatt_cmd_enq(tcb, p_clcb, false, cmd_code, NULL)) { - LOG_ERROR("Could not queue sent request. %s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), p_clcb->cid); + log::error( + "Could not queue sent request. {}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), p_clcb->cid); return GATT_INTERNAL_ERROR; } @@ -564,17 +574,22 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint16_t offset = 0, handle; if (!p_clcb) { - LOG_ERROR("Missing p_clcb"); + log::error("Missing p_clcb"); return GATT_ILLEGAL_PARAMETER; } uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid); + if (payload_size == 0) { + log::error("Cannot send request (op: 0x{:02x}) due to payload size = 0, {}", + op_code, ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda)); + return GATT_NO_RESOURCES; + } switch (op_code) { case GATT_REQ_MTU: if (p_msg->mtu > GATT_MAX_MTU_SIZE) { - LOG_WARN( - "GATT message MTU is larger than max GATT MTU size op_code:%hhu", + log::warn( + "GATT message MTU is larger than max GATT MTU size op_code:{}", op_code); return GATT_ILLEGAL_PARAMETER; } @@ -587,7 +602,7 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, if (!GATT_HANDLE_IS_VALID(p_msg->browse.s_handle) || !GATT_HANDLE_IS_VALID(p_msg->browse.e_handle) || p_msg->browse.s_handle > p_msg->browse.e_handle) { - LOG_WARN("GATT message has invalid handle op_code:%hhu", op_code); + log::warn("GATT message has invalid handle op_code:{}", op_code); return GATT_ILLEGAL_PARAMETER; } @@ -603,7 +618,7 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, (op_code == GATT_REQ_READ) ? p_msg->handle : p_msg->read_blob.handle; /* handle checking */ if (!GATT_HANDLE_IS_VALID(handle)) { - LOG_WARN("GATT message has invalid handle op_code:%hhu", op_code); + log::warn("GATT message has invalid handle op_code:{}", op_code); return GATT_ILLEGAL_PARAMETER; } @@ -617,7 +632,7 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, case GATT_CMD_WRITE: case GATT_SIGN_CMD_WRITE: if (!GATT_HANDLE_IS_VALID(p_msg->attr_value.handle)) { - LOG_WARN("GATT message has invalid handle op_code:%hhu", op_code); + log::warn("GATT message has invalid handle op_code:{}", op_code); return GATT_ILLEGAL_PARAMETER; } @@ -647,12 +662,24 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, } if (p_cmd == NULL) { - LOG_WARN( - "Unable to build proper GATT message to send to peer device " - "op_code:%hhu", + log::warn( + "Unable to build proper GATT message to send to peer device op_code:{}", op_code); return GATT_NO_RESOURCES; } return attp_cl_send_cmd(tcb, p_clcb, op_code, p_cmd); } + +namespace bluetooth { +namespace legacy { +namespace testing { +BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, + uint16_t handle, uint16_t offset, uint16_t len, + uint8_t* p_data) { + return ::attp_build_value_cmd(payload_size, op_code, handle, offset, len, + p_data); +} +} // namespace testing +} // namespace legacy +} // namespace bluetooth diff --git a/system/stack/gatt/connection_manager.cc b/system/stack/gatt/connection_manager.cc index 047988e4ae9dc312ef4652f80d46843228b43b5e..2deee85e20bf186e745455a63d5749af9c7d0de6 100644 --- a/system/stack/gatt/connection_manager.cc +++ b/system/stack/gatt/connection_manager.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,8 @@ #define DIRECT_CONNECT_TIMEOUT (30 * 1000) /* 30 seconds */ +using namespace bluetooth; + constexpr char kBtmLogTag[] = "TA"; struct closure_data { @@ -50,7 +53,7 @@ struct closure_data { static void alarm_closure_cb(void* p) { closure_data* data = (closure_data*)p; - VLOG(1) << "executing timer scheduled at %s" << data->posted_from.ToString(); + log::verbose("executing timer scheduled at {}", data->posted_from.ToString()); std::move(data->user_task).Run(); delete data; } @@ -61,7 +64,7 @@ void alarm_set_closure(const base::Location& posted_from, alarm_t* alarm, closure_data* data = new closure_data; data->posted_from = posted_from; data->user_task = std::move(user_task); - VLOG(1) << "scheduling timer %s" << data->posted_from.ToString(); + log::verbose("scheduling timer {}", data->posted_from.ToString()); alarm_set_on_mloop(alarm, interval_ms, alarm_closure_cb, data); } @@ -112,7 +115,7 @@ bool is_anyone_connecting( /** background connection device from the list. Returns pointer to the device * record, or nullptr if not found */ std::set get_apps_connecting_to(const RawAddress& address) { - LOG_DEBUG("address=%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("address={}", ADDRESS_TO_LOGGABLE_CSTR(address)); auto it = bgconn_dev.find(address); return (it != bgconn_dev.end()) ? it->second.doing_bg_conn : std::set(); @@ -135,14 +138,14 @@ bool IsTargetedAnnouncement(const uint8_t* p_eir, uint16_t eir_len) { } STREAM_TO_UINT16(uuid, p_tmp); - LOG_DEBUG("Found UUID 0x%04x", uuid); + log::debug("Found UUID 0x{:04x}", uuid); if (uuid != 0x184E && uuid != 0x1853) { continue; } STREAM_TO_UINT8(announcement_type, p_tmp); - LOG_DEBUG("Found announcement_type 0x%02x", announcement_type); + log::debug("Found announcement_type 0x{:02x}", announcement_type); if (announcement_type == 0x01) { return true; } @@ -164,21 +167,22 @@ static void target_announcement_observe_results_cb(tBTM_INQ_RESULTS* p_inq, } if (!IsTargetedAnnouncement(p_eir, eir_len)) { - LOG_DEBUG("Not a targeted announcement for device %s", - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::debug("Not a targeted announcement for device {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); return; } - LOG_INFO("Found targeted announcement for device %s", - ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::info("Found targeted announcement for device {}", + ADDRESS_TO_LOGGABLE_CSTR(addr)); if (it->second.is_in_accept_list) { - LOG_INFO("Device %s is already connecting", ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::info("Device {} is already connecting", + ADDRESS_TO_LOGGABLE_CSTR(addr)); return; } if (BTM_GetHCIConnHandle(addr, BT_TRANSPORT_LE) != 0xFFFF) { - LOG_DEBUG("Device %s already connected", ADDRESS_TO_LOGGABLE_CSTR(addr)); + log::debug("Device {} already connected", ADDRESS_TO_LOGGABLE_CSTR(addr)); return; } @@ -193,7 +197,7 @@ static void target_announcement_observe_results_cb(tBTM_INQ_RESULTS* p_inq, } void target_announcements_filtering_set(bool enable) { - LOG_DEBUG("enable %d", enable); + log::debug("enable {}", enable); BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, (enable ? "Start filtering" : "Stop filtering")); @@ -211,8 +215,8 @@ void target_announcements_filtering_set(bool enable) { */ bool background_connect_targeted_announcement_add(tAPP_ID app_id, const RawAddress& address) { - LOG_INFO("app_id=%d, address=%s", static_cast(app_id), - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("app_id={}, address={}", static_cast(app_id), + ADDRESS_TO_LOGGABLE_CSTR(address)); bool disable_accept_list = false; @@ -220,9 +224,9 @@ bool background_connect_targeted_announcement_add(tAPP_ID app_id, if (it != bgconn_dev.end()) { // check if filtering already enabled if (it->second.doing_targeted_announcements_conn.count(app_id)) { - LOG_INFO( - "app_id=%d, already doing targeted announcement filtering to " - "address=%s", + log::info( + "app_id={}, already doing targeted announcement filtering to " + "address={}", static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); return true; } @@ -232,14 +236,14 @@ bool background_connect_targeted_announcement_add(tAPP_ID app_id, // Check if connecting if (!it->second.doing_direct_conn.empty()) { - LOG_INFO("app_id=%d, address=%s, already in direct connection", - static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("app_id={}, address={}, already in direct connection", + static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); } else if (!targeted_filtering_enabled && !it->second.doing_bg_conn.empty()) { // device is already in the acceptlist so we would have to remove it - LOG_INFO( - "already doing background connection to address=%s. Need to disable " + log::info( + "already doing background connection to address={}. Need to disable " "it.", ADDRESS_TO_LOGGABLE_CSTR(address)); disable_accept_list = true; @@ -266,23 +270,23 @@ bool background_connect_targeted_announcement_add(tAPP_ID app_id, /** Add a device from the background connection list. Returns true if device * added to the list, or already in list, false otherwise */ bool background_connect_add(uint8_t app_id, const RawAddress& address) { - LOG_DEBUG("app_id=%d, address=%s", static_cast(app_id), - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("app_id={}, address={}", static_cast(app_id), + ADDRESS_TO_LOGGABLE_CSTR(address)); auto it = bgconn_dev.find(address); bool in_acceptlist = false; bool is_targeted_announcement_enabled = false; if (it != bgconn_dev.end()) { // device already in the acceptlist, just add interested app to the list if (it->second.doing_bg_conn.count(app_id)) { - LOG_DEBUG("app_id=%d, already doing background connection to address=%s", - static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("app_id={}, already doing background connection to address={}", + static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); return true; } // Already in acceptlist ? if (it->second.is_in_accept_list) { - LOG_DEBUG("app_id=%d, address=%s, already in accept list", - static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("app_id={}, address={}, already in accept list", + static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); in_acceptlist = true; } else { is_targeted_announcement_enabled = @@ -293,11 +297,11 @@ bool background_connect_add(uint8_t app_id, const RawAddress& address) { if (!in_acceptlist) { // the device is not in the acceptlist if (is_targeted_announcement_enabled) { - LOG_DEBUG("Targeted announcement enabled, do not add to AcceptList"); + log::debug("Targeted announcement enabled, do not add to AcceptList"); } else { if (!BTM_AcceptlistAdd(address)) { - LOG_WARN("Failed to add device %s to accept list for app %d", - ADDRESS_TO_LOGGABLE_CSTR(address), static_cast(app_id)); + log::warn("Failed to add device {} to accept list for app {}", + ADDRESS_TO_LOGGABLE_CSTR(address), static_cast(app_id)); return false; } bgconn_dev[address].is_in_accept_list = true; @@ -313,10 +317,10 @@ bool background_connect_add(uint8_t app_id, const RawAddress& address) { /** Removes all registrations for connection for given device. * Returns true if anything was removed, false otherwise */ bool remove_unconditional(const RawAddress& address) { - LOG_DEBUG("address=%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("address={}", ADDRESS_TO_LOGGABLE_CSTR(address)); auto it = bgconn_dev.find(address); if (it == bgconn_dev.end()) { - LOG_WARN("address %s is not found", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("address {} is not found", ADDRESS_TO_LOGGABLE_CSTR(address)); return false; } @@ -329,11 +333,11 @@ bool remove_unconditional(const RawAddress& address) { * advertising list. Returns true if device was on the list and was * successfully removed */ bool background_connect_remove(uint8_t app_id, const RawAddress& address) { - LOG_DEBUG("app_id=%d, address=%s", static_cast(app_id), - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("app_id={}, address={}", static_cast(app_id), + ADDRESS_TO_LOGGABLE_CSTR(address)); auto it = bgconn_dev.find(address); if (it == bgconn_dev.end()) { - LOG_WARN("address %s is not found", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("address {} is not found", ADDRESS_TO_LOGGABLE_CSTR(address)); return false; } @@ -345,8 +349,8 @@ bool background_connect_remove(uint8_t app_id, const RawAddress& address) { bool removed_from_ta = (it->second.doing_targeted_announcements_conn.erase(app_id) > 0); if (!removed_from_bg_conn && !removed_from_ta) { - LOG_WARN("Failed to remove background connection app %d for address %s", - static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Failed to remove background connection app {} for address {}", + static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); return false; } @@ -356,17 +360,17 @@ bool background_connect_remove(uint8_t app_id, const RawAddress& address) { } if (is_anyone_connecting(it)) { - LOG_DEBUG("some device is still connecting, app_id=%d, address=%s", - static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("some device is still connecting, app_id={}, address={}", + static_cast(app_id), ADDRESS_TO_LOGGABLE_CSTR(address)); /* Check which method should be used now.*/ if (!accept_list_enabled) { /* Accept list was not used */ if (!it->second.doing_targeted_announcements_conn.empty()) { /* Keep using filtering */ - LOG_DEBUG(" Keep using target announcement filtering"); + log::debug("Keep using target announcement filtering"); } else if (!it->second.doing_bg_conn.empty()) { if (!BTM_AcceptlistAdd(address)) { - LOG_WARN("Could not re add device to accept list"); + log::warn("Could not re add device to accept list"); } else { bgconn_dev[address].is_in_accept_list = true; } @@ -397,7 +401,7 @@ bool is_background_connection(const RawAddress& address) { /** deregister all related background connetion device. */ void on_app_deregistered(uint8_t app_id) { - LOG_DEBUG("app_id=%d", static_cast(app_id)); + log::debug("app_id={}", static_cast(app_id)); auto it = bgconn_dev.begin(); auto end = bgconn_dev.end(); /* update the BG conn device list */ @@ -418,7 +422,7 @@ void on_app_deregistered(uint8_t app_id) { static void remove_all_clients_with_pending_connections( const RawAddress& address) { - LOG_DEBUG("address=%s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("address={}", ADDRESS_TO_LOGGABLE_CSTR(address)); auto it = bgconn_dev.find(address); while (it != bgconn_dev.end() && !it->second.doing_direct_conn.empty()) { uint8_t app_id = it->second.doing_direct_conn.begin()->first; @@ -428,14 +432,14 @@ static void remove_all_clients_with_pending_connections( } void on_connection_complete(const RawAddress& address) { - LOG_INFO("Le connection completed to device:%s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Le connection completed to device:{}", + ADDRESS_TO_LOGGABLE_CSTR(address)); remove_all_clients_with_pending_connections(address); } void on_connection_timed_out_from_shim(const RawAddress& address) { - LOG_INFO("Connection failed %s", ADDRESS_TO_LOGGABLE_CSTR(address)); + log::info("Connection failed {}", ADDRESS_TO_LOGGABLE_CSTR(address)); on_connection_timed_out(0x00, address); } @@ -450,8 +454,8 @@ void reset(bool after_reset) { } void wl_direct_connect_timeout_cb(uint8_t app_id, const RawAddress& address) { - LOG_DEBUG("app_id=%d, address=%s", static_cast(app_id), - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("app_id={}, address={}", static_cast(app_id), + ADDRESS_TO_LOGGABLE_CSTR(address)); on_connection_timed_out(app_id, address); // TODO: this would free the timer, from within the timer callback, which is @@ -462,22 +466,22 @@ void wl_direct_connect_timeout_cb(uint8_t app_id, const RawAddress& address) { /** Add a device to the direct connection list. Returns true if device * added to the list, false otherwise */ bool direct_connect_add(uint8_t app_id, const RawAddress& address) { - LOG_DEBUG("app_id=%d, address=%s", static_cast(app_id), - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("app_id={}, address={}", static_cast(app_id), + ADDRESS_TO_LOGGABLE_CSTR(address)); bool in_acceptlist = false; auto it = bgconn_dev.find(address); if (it != bgconn_dev.end()) { // app already trying to connect to this particular device if (it->second.doing_direct_conn.count(app_id)) { - LOG(INFO) << "direct connect attempt from app_id=" << loghex(app_id) - << " already in progress"; + log::info("direct connect attempt from app_id={} already in progress", + loghex(app_id)); return false; } // are we already in the acceptlist ? if (it->second.is_in_accept_list) { - LOG_WARN("Background connection attempt already in progress app_id=%x", - app_id); + log::warn("Background connection attempt already in progress app_id={:x}", + app_id); in_acceptlist = true; } } @@ -485,7 +489,7 @@ bool direct_connect_add(uint8_t app_id, const RawAddress& address) { if (!in_acceptlist) { if (!BTM_AcceptlistAdd(address, true)) { // if we can't add to acceptlist, turn parameters back to slow. - LOG_WARN("Unable to add le device to acceptlist"); + log::warn("Unable to add le device to acceptlist"); return false; } bgconn_dev[address].is_in_accept_list = true; @@ -510,19 +514,19 @@ static void schedule_direct_connect_add(uint8_t app_id, bool direct_connect_remove(uint8_t app_id, const RawAddress& address, bool connection_timeout) { - LOG_DEBUG("app_id=%d, address=%s", static_cast(app_id), - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::debug("app_id={}, address={}", static_cast(app_id), + ADDRESS_TO_LOGGABLE_CSTR(address)); auto it = bgconn_dev.find(address); if (it == bgconn_dev.end()) { - LOG_WARN("Unable to find background connection to remove peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Unable to find background connection to remove peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return false; } auto app_it = it->second.doing_direct_conn.find(app_id); if (app_it == it->second.doing_direct_conn.end()) { - LOG_WARN("Unable to find direct connection to remove peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(address)); + log::warn("Unable to find direct connection to remove peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(address)); return false; } @@ -540,8 +544,8 @@ bool direct_connect_remove(uint8_t app_id, const RawAddress& address, * the allow list. */ if (!BTM_AcceptlistAdd(address)) { - LOG_WARN( - "Failed to re-add device %s to accept list after connection " + log::warn( + "Failed to re-add device {} to accept list after connection " "timeout", ADDRESS_TO_LOGGABLE_CSTR(address)); } diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc index bbe6875f62f95f40e4008be4d74b5fff271d9b3a..0061b965ea9bcdbb2adec9ded241ae2b43a8be5a 100644 --- a/system/stack/gatt/gatt_api.cc +++ b/system/stack/gatt/gatt_api.cc @@ -25,17 +25,19 @@ #include "stack/include/gatt_api.h" +#include #include +#include #include #include "device/include/controller.h" -#include "gd/os/system_properties.h" #include "internal_include/bt_target.h" #include "internal_include/bt_trace.h" #include "internal_include/stack_config.h" #include "l2c_api.h" #include "os/log.h" +#include "os/system_properties.h" #include "osi/include/allocator.h" #include "rust/src/connection/ffi/connection_shim.h" #include "stack/arbiter/acl_arbiter.h" @@ -51,6 +53,7 @@ #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; using bluetooth::Uuid; @@ -114,7 +117,7 @@ static uint16_t compute_service_size(btgatt_db_element_t* service, int count) { // if present, Characteristic Extended Properties takes one handle if (el->properties & GATT_CHAR_PROP_BIT_EXT_PROP) db_size++; } else { - LOG(ERROR) << __func__ << ": Unknown element type: " << el->type; + log::error("Unknown element type: {}", el->type); } return db_size; @@ -174,10 +177,10 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, bool is_pri = (service->type == BTGATT_DB_PRIMARY_SERVICE) ? true : false; Uuid svc_uuid = service->uuid; - LOG(INFO) << __func__; + log::info(""); if (!p_reg) { - LOG(ERROR) << "Inavlid gatt_if=" << +gatt_if; + log::error("Inavlid gatt_if={}", gatt_if); return GATT_INTERNAL_ERROR; } @@ -206,8 +209,7 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, /* check for space */ if (num_handles > (0xFFFF - s_hdl + 1)) { - LOG(ERROR) << __func__ << ": no handles, s_hdl=" << +s_hdl - << " needed=" << num_handles; + log::error("no handles, s_hdl={} needed={}", s_hdl, num_handles); return GATT_INTERNAL_ERROR; } @@ -225,11 +227,10 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, gatts_init_service_db(list.svc_db, svc_uuid, is_pri, s_hdl, num_handles); - VLOG(1) << __func__ << ": handles needed=" << num_handles - << ", s_hdl=" << loghex(list.asgn_range.s_handle) - << ", e_hdl=" << loghex(list.asgn_range.e_handle) - << ", uuid=" << list.asgn_range.svc_uuid - << ", is_primary=" << +list.asgn_range.is_primary; + log::verbose("handles needed={}, s_hdl={}, e_hdl={}, uuid={}, is_primary={}", + num_handles, loghex(list.asgn_range.s_handle), + loghex(list.asgn_range.e_handle), list.asgn_range.svc_uuid, + list.asgn_range.is_primary); service->attribute_handle = s_hdl; @@ -243,16 +244,16 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, !(el->permissions & GATT_WRITE_SIGNED_PERM)) || ((el->permissions & GATT_WRITE_SIGNED_PERM) && !(el->properties & GATT_CHAR_PROP_BIT_AUTH))) { - VLOG(1) << "Invalid configuration property=" << loghex(el->properties) - << ", perm=" << loghex(el->permissions); + log::verbose("Invalid configuration property={}, perm={}", + loghex(el->properties), loghex(el->permissions)); return GATT_INTERNAL_ERROR; } if (is_gatt_attr_type(uuid)) { - LOG(ERROR) << __func__ - << ": attept to add characteristic with UUID equal to GATT " - "Attribute Type " - << uuid; + log::error( + "attept to add characteristic with UUID equal to GATT Attribute " + "Type {}", + uuid); return GATT_INTERNAL_ERROR; } @@ -266,10 +267,10 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, } else if (el->type == BTGATT_DB_DESCRIPTOR) { if (is_gatt_attr_type(uuid)) { - LOG(ERROR) << __func__ - << ": attept to add descriptor with UUID equal to GATT " - "Attribute Type " - << uuid; + log::error( + "attept to add descriptor with UUID equal to GATT Attribute Type " + "{}", + uuid); return GATT_INTERNAL_ERROR; } @@ -279,7 +280,7 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, tGATT_HDL_LIST_ELEM* p_incl_decl; p_incl_decl = gatt_find_hdl_buffer_by_handle(el->attribute_handle); if (p_incl_decl == nullptr) { - VLOG(1) << "Included Service not created"; + log::verbose("Included Service not created"); return GATT_INTERNAL_ERROR; } @@ -289,7 +290,7 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, } } - LOG(INFO) << __func__ << ": service parsed correctly, now starting"; + log::info("service parsed correctly, now starting"); /*this is a new application service start */ @@ -326,9 +327,9 @@ tGATT_STATUS GATTS_AddService(tGATT_IF gatt_if, btgatt_db_element_t* service, gatt_update_last_srv_info(); - VLOG(1) << __func__ << ": allocated el s_hdl=" << loghex(elem.s_hdl) - << ", e_hdl=" << loghex(elem.e_hdl) << ", type=" << loghex(elem.type) - << ", sdp_hdl=" << loghex(elem.sdp_handle); + log::verbose("allocated el s_hdl={}, e_hdl={}, type={}, sdp_hdl={}", + loghex(elem.s_hdl), loghex(elem.e_hdl), loghex(elem.type), + loghex(elem.sdp_handle)); gatt_update_for_database_change(); gatt_proc_srv_chg(); @@ -343,7 +344,7 @@ bool is_active_service(const Uuid& app_uuid128, Uuid* p_svc_uuid, if (p_this_uuid && app_uuid128 == info.app_uuid && *p_svc_uuid == *p_this_uuid && (start_handle == info.s_hdl)) { - LOG(ERROR) << "Active Service Found: " << *p_svc_uuid; + log::error("Active Service Found: {}", *p_svc_uuid); return true; } } @@ -366,18 +367,18 @@ bool is_active_service(const Uuid& app_uuid128, Uuid* p_svc_uuid, ******************************************************************************/ bool GATTS_DeleteService(tGATT_IF gatt_if, Uuid* p_svc_uuid, uint16_t svc_inst) { - VLOG(1) << __func__; + log::verbose(""); tGATT_REG* p_reg = gatt_get_regcb(gatt_if); if (p_reg == NULL) { - LOG(ERROR) << "Applicaiton not foud"; + log::error("Applicaiton not foud"); return false; } auto it = gatt_find_hdl_buffer_by_app_id(p_reg->app_uuid128, p_svc_uuid, svc_inst); if (it == gatt_cb.hdl_list_info->end()) { - LOG(ERROR) << "No Service found"; + log::error("No Service found"); return false; } @@ -388,8 +389,9 @@ bool GATTS_DeleteService(tGATT_IF gatt_if, Uuid* p_svc_uuid, gatt_update_for_database_change(); gatt_proc_srv_chg(); - VLOG(1) << "released handles s_hdl=" << loghex(it->asgn_range.s_handle) - << ", e_hdl=" << loghex(it->asgn_range.e_handle); + log::verbose("released handles s_hdl={}, e_hdl={}", + loghex(it->asgn_range.s_handle), + loghex(it->asgn_range.e_handle)); if ((it->asgn_range.s_handle >= gatt_cb.hdl_cfg.app_start_hdl) && gatt_cb.cb_info.p_nv_save_callback) @@ -411,12 +413,11 @@ bool GATTS_DeleteService(tGATT_IF gatt_if, Uuid* p_svc_uuid, * ******************************************************************************/ void GATTS_StopService(uint16_t service_handle) { - LOG(INFO) << __func__ << ": service = " << loghex(service_handle); + log::info("service = {}", loghex(service_handle)); auto it = gatt_sr_find_i_rcb_by_handle(service_handle); if (it == gatt_cb.srv_list_info->end()) { - LOG(ERROR) << __func__ << ": service_handle=" << loghex(service_handle) - << " is not in use"; + log::error("service_handle={} is not in use", loghex(service_handle)); return; } @@ -450,9 +451,9 @@ tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle, tGATT_REG* p_reg = gatt_get_regcb(gatt_if); tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); - VLOG(1) << __func__; + log::verbose(""); if ((p_reg == NULL) || (p_tcb == NULL)) { - LOG(ERROR) << __func__ << ": Unknown conn_id=" << loghex(conn_id); + log::error("Unknown conn_id={}", loghex(conn_id)); return (tGATT_STATUS)GATT_INVALID_CONN_ID; } @@ -470,7 +471,7 @@ tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle, if (!gatt_tcb_get_cid_available_for_indication(p_tcb, p_reg->eatt_support, &indicate_handle_p, &cid)) { - VLOG(1) << "Add a pending indication"; + log::verbose("Add a pending indication"); gatt_add_pending_ind(p_tcb, &indication); return GATT_SUCCESS; } @@ -494,7 +495,7 @@ tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle, #if (GATT_UPPER_TESTER_MULT_VARIABLE_LENGTH_NOTIF == TRUE) static tGATT_STATUS GATTS_HandleMultileValueNotification( tGATT_TCB* p_tcb, std::vector gatt_notif_vector) { - LOG_INFO(""); + log::info(""); uint16_t cid = gatt_tcb_get_att_cid(*p_tcb, true /* eatt support */); uint16_t payload_size = gatt_tcb_get_payload_size(*p_tcb, cid); @@ -509,7 +510,7 @@ static tGATT_STATUS GATTS_HandleMultileValueNotification( p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = 1; for (auto notif : gatt_notif_vector) { - LOG_INFO("Adding handle: 0x%04x, val len %d", notif.handle, notif.len); + log::info("Adding handle: 0x{:04x}, val len {}", notif.handle, notif.len); UINT16_TO_STREAM(p, notif.handle); p_buf->len += 2; UINT16_TO_STREAM(p, notif.len); @@ -518,7 +519,7 @@ static tGATT_STATUS GATTS_HandleMultileValueNotification( p_buf->len += notif.len; } - LOG_INFO("Total len: %d", p_buf->len); + log::info("Total len: {}", p_buf->len); return attp_send_sr_msg(*p_tcb, cid, p_buf); } @@ -552,10 +553,10 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id, tGATT_VALUE* p_gatt_notif; #endif - VLOG(1) << __func__; + log::verbose(""); if ((p_reg == NULL) || (p_tcb == NULL)) { - LOG(ERROR) << __func__ << "Unknown conn_id: " << conn_id; + log::error("Unknown conn_id: {}", conn_id); return (tGATT_STATUS)GATT_INVALID_CONN_ID; } @@ -568,7 +569,7 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id, if (stack_config_get_interface()->get_pts_force_eatt_for_notifications() && gatt_sr_is_cl_multi_variable_len_notif_supported(*p_tcb)) { if (cached_tcb_idx == 0xFF) { - LOG_INFO("Storing first notification"); + log::info("Storing first notification"); p_gatt_notif = &gatt_notif_vector[0]; p_gatt_notif->handle = attr_handle; @@ -582,7 +583,7 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id, } if (cached_tcb_idx == tcb_idx) { - LOG_INFO("Storing second notification"); + log::info("Storing second notification"); cached_tcb_idx = 0xFF; p_gatt_notif = &gatt_notif_vector[1]; @@ -595,8 +596,8 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id, return GATTS_HandleMultileValueNotification(p_tcb, gatt_notif_vector); } - LOG_ERROR("PTS Mode: Invalid tcb_idx: %d, cached_tcb_idx: %d", tcb_idx, - cached_tcb_idx); + log::error("PTS Mode: Invalid tcb_idx: {}, cached_tcb_idx: {}", tcb_idx, + cached_tcb_idx); } #endif @@ -644,20 +645,18 @@ tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, tGATT_REG* p_reg = gatt_get_regcb(gatt_if); tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); - VLOG(1) << __func__ << ": conn_id=" << loghex(conn_id) - << ", trans_id=" << loghex(trans_id) - << ", status=" << loghex(static_cast(status)); + log::verbose("conn_id={}, trans_id={}, status={}", loghex(conn_id), + loghex(trans_id), loghex(static_cast(status))); if ((p_reg == NULL) || (p_tcb == NULL)) { - LOG(ERROR) << "Unknown conn_id=" << loghex(conn_id); + log::error("Unknown conn_id={}", loghex(conn_id)); return (tGATT_STATUS)GATT_INVALID_CONN_ID; } tGATT_SR_CMD* sr_res_p = gatt_sr_get_cmd_by_trans_id(p_tcb, trans_id); if (!sr_res_p) { - LOG(ERROR) << "conn_id=" << loghex(conn_id) - << " waiting for other op_code "; + log::error("conn_id={} waiting for other op_code ", loghex(conn_id)); return (GATT_WRONG_STATE); } @@ -696,9 +695,9 @@ tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) { if ((p_tcb == NULL) || (p_reg == NULL) || (mtu < GATT_DEF_BLE_MTU_SIZE) || (mtu > GATT_MAX_MTU_SIZE)) { - LOG_WARN( - "Unable to configure ATT mtu size illegal parameter conn_id:%hu " - "mtu:%hu tcb:%s reg:%s", + log::warn( + "Unable to configure ATT mtu size illegal parameter conn_id:{} mtu:{} " + "tcb:{} reg:{}", conn_id, mtu, (p_tcb == nullptr) ? "BAD" : "ok", (p_reg == nullptr) ? "BAD" : "ok"); return GATT_ILLEGAL_PARAMETER; @@ -706,12 +705,12 @@ tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) { /* Validate that the link is BLE, not BR/EDR */ if (p_tcb->transport != BT_TRANSPORT_LE) { - return GATT_ERROR; + return GATT_REQ_NOT_SUPPORTED; } tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id); if (!p_clcb) { - LOG_WARN("Unable to allocate connection link control block"); + log::warn("Unable to allocate connection link control block"); return GATT_NO_RESOURCES; } @@ -727,8 +726,8 @@ tGATT_STATUS GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) { * default MTU in the request. */ gatt_cl_msg.mtu = gatt_get_local_mtu(); - LOG_INFO("Configuring ATT mtu size conn_id:%hu mtu:%hu user mtu %hu", conn_id, - gatt_cl_msg.mtu, mtu); + log::info("Configuring ATT mtu size conn_id:{} mtu:{} user mtu {}", conn_id, + gatt_cl_msg.mtu, mtu); auto result = attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, GATT_REQ_MTU, &gatt_cl_msg); @@ -768,24 +767,24 @@ tGATTC_TryMtuRequestResult GATTC_TryMtuRequest(const RawAddress& remote_bda, tBT_TRANSPORT transport, uint16_t conn_id, uint16_t* current_mtu) { - LOG_INFO("%s conn_id=0x%04x", remote_bda.ToString().c_str(), conn_id); + log::info("{} conn_id=0x{:04x}", remote_bda.ToString(), conn_id); *current_mtu = GATT_DEF_BLE_MTU_SIZE; if (transport == BT_TRANSPORT_BR_EDR) { - LOG_ERROR("Device %s connected over BR/EDR", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::error("Device {} connected over BR/EDR", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return MTU_EXCHANGE_NOT_ALLOWED; } tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, transport); if (!p_tcb) { - LOG_ERROR("Device %s is not connected ", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::error("Device {} is not connected ", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return MTU_EXCHANGE_DEVICE_DISCONNECTED; } if (gatt_is_pending_mtu_exchange(p_tcb)) { - LOG_DEBUG("Continue MTU pending for other client."); + log::debug("Continue MTU pending for other client."); /* MTU Exchange is in progress, started by other GATT Client. * Wait until it is completed. */ @@ -795,8 +794,8 @@ tGATTC_TryMtuRequestResult GATTC_TryMtuRequest(const RawAddress& remote_bda, uint16_t mtu = gatt_get_mtu(remote_bda, transport); if (mtu == GATT_DEF_BLE_MTU_SIZE || mtu == 0) { - LOG_DEBUG("MTU not yet updated for %s", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); + log::debug("MTU not yet updated for {}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda)); return MTU_EXCHANGE_NOT_DONE_YET; } @@ -820,19 +819,19 @@ tGATTC_TryMtuRequestResult GATTC_TryMtuRequest(const RawAddress& remote_bda, void GATTC_UpdateUserAttMtuIfNeeded(const RawAddress& remote_bda, tBT_TRANSPORT transport, uint16_t user_mtu) { - LOG_INFO("%s, mtu=%hu", ADDRESS_TO_LOGGABLE_CSTR(remote_bda), user_mtu); + log::info("{}, mtu={}", ADDRESS_TO_LOGGABLE_CSTR(remote_bda), user_mtu); tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(remote_bda, transport); if (!p_tcb) { - LOG_WARN("Transport control block not found"); + log::warn("Transport control block not found"); return; } - LOG_INFO("%s, current mtu: %d, max_user_mtu:%d, user_mtu: %d", - ADDRESS_TO_LOGGABLE_CSTR(remote_bda), p_tcb->payload_size, - p_tcb->max_user_mtu, user_mtu); + log::info("{}, current mtu: {}, max_user_mtu:{}, user_mtu: {}", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda), p_tcb->payload_size, + p_tcb->max_user_mtu, user_mtu); if (p_tcb->payload_size < user_mtu) { - LOG_INFO("User requested more than what GATT can handle. Trim it."); + log::info("User requested more than what GATT can handle. Trim it."); user_mtu = p_tcb->payload_size; } @@ -882,8 +881,8 @@ tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type, tGATT_REG* p_reg = gatt_get_regcb(gatt_if); if ((p_tcb == NULL) || (p_reg == NULL) || (disc_type >= GATT_DISC_MAX)) { - LOG(ERROR) << __func__ << " Illegal param: disc_type=" << +disc_type - << " conn_id=" << loghex(conn_id); + log::error("Illegal param: disc_type={} conn_id={}", disc_type, + loghex(conn_id)); return GATT_ILLEGAL_PARAMETER; } @@ -891,19 +890,17 @@ tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type, !GATT_HANDLE_IS_VALID(end_handle) || /* search by type does not have a valid UUID param */ (disc_type == GATT_DISC_SRVC_BY_UUID && uuid.IsEmpty())) { - LOG(WARNING) << __func__ << " Illegal parameter conn_id=" << loghex(conn_id) - << ", disc_type=" << +disc_type - << ", s_handle=" << loghex(start_handle) - << ", e_handle=" << loghex(end_handle); + log::warn( + "Illegal parameter conn_id={}, disc_type={}, s_handle={}, e_handle={}", + loghex(conn_id), disc_type, loghex(start_handle), loghex(end_handle)); return GATT_ILLEGAL_PARAMETER; } tGATT_CLCB* p_clcb = gatt_clcb_alloc(conn_id); if (!p_clcb) { - LOG(WARNING) << __func__ << " No resources conn_id=" << loghex(conn_id) - << ", disc_type=" << +disc_type - << ", s_handle=" << loghex(start_handle) - << ", e_handle=" << loghex(end_handle); + log::warn("No resources conn_id={}, disc_type={}, s_handle={}, e_handle={}", + loghex(conn_id), disc_type, loghex(start_handle), + loghex(end_handle)); return GATT_NO_RESOURCES; } @@ -913,10 +910,9 @@ tGATT_STATUS GATTC_Discover(uint16_t conn_id, tGATT_DISC_TYPE disc_type, p_clcb->e_handle = end_handle; p_clcb->uuid = uuid; - LOG(INFO) << __func__ << " conn_id=" << loghex(conn_id) - << ", disc_type=" << +disc_type - << ", s_handle=" << loghex(start_handle) - << ", e_handle=" << loghex(end_handle); + log::info("conn_id={}, disc_type={}, s_handle={}, e_handle={}", + loghex(conn_id), disc_type, loghex(start_handle), + loghex(end_handle)); gatt_act_discovery(p_clcb); return GATT_SUCCESS; @@ -953,13 +949,12 @@ tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type, static int cached_tcb_idx = -1; #endif - VLOG(1) << __func__ << ": conn_id=" << loghex(conn_id) - << ", type=" << loghex(type); + log::verbose("conn_id={}, type={}", loghex(conn_id), loghex(type)); if ((p_tcb == NULL) || (p_reg == NULL) || (p_read == NULL) || ((type >= GATT_READ_MAX) || (type == 0))) { - LOG(ERROR) << ": illegal param: conn_id=" << loghex(conn_id) - << "type=" << loghex(type); + log::error("illegal param: conn_id={}, type={}", loghex(conn_id), + loghex(type)); return GATT_ILLEGAL_PARAMETER; } @@ -991,15 +986,15 @@ tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type, } case GATT_READ_BY_HANDLE: #if (GATT_UPPER_TESTER_MULT_VARIABLE_LENGTH_READ == TRUE) - LOG_INFO("Upper tester: Handle read 0x%04x", p_read->by_handle.handle); + log::info("Upper tester: Handle read 0x{:04x}", p_read->by_handle.handle); /* This is upper tester for the Multi Read stuff as this is mandatory for * EATT, even Android is not making use of this operation :/ */ if (cached_tcb_idx < 0) { cached_tcb_idx = tcb_idx; - LOG_INFO("Upper tester: Read multiple - first read"); + log::info("Upper tester: Read multiple - first read"); cached_read_handle = p_read->by_handle.handle; } else if (cached_tcb_idx == tcb_idx) { - LOG_INFO("Upper tester: Read multiple - second read"); + log::info("Upper tester: Read multiple - second read"); cached_tcb_idx = -1; tGATT_READ_MULTI* p_read_multi = (tGATT_READ_MULTI*)osi_malloc(sizeof(tGATT_READ_MULTI)); @@ -1061,8 +1056,8 @@ tGATT_STATUS GATTC_Write(uint16_t conn_id, tGATT_WRITE_TYPE type, if ((p_tcb == NULL) || (p_reg == NULL) || (p_write == NULL) || ((type != GATT_WRITE) && (type != GATT_WRITE_PREPARE) && (type != GATT_WRITE_NO_RSP))) { - LOG(ERROR) << __func__ << " Illegal param: conn_id=" << loghex(conn_id) - << ", type=" << loghex(type); + log::error("Illegal param: conn_id={}, type={}", loghex(conn_id), + loghex(type)); return GATT_ILLEGAL_PARAMETER; } @@ -1107,11 +1102,10 @@ tGATT_STATUS GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) { tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); tGATT_REG* p_reg = gatt_get_regcb(gatt_if); - VLOG(1) << __func__ << ": conn_id=" << loghex(conn_id) - << ", is_execute=" << +is_execute; + log::verbose("conn_id={}, is_execute={}", loghex(conn_id), is_execute); if ((p_tcb == NULL) || (p_reg == NULL)) { - LOG(ERROR) << " Illegal param: conn_id=" << loghex(conn_id); + log::error(" Illegal param: conn_id={}", loghex(conn_id)); return GATT_ILLEGAL_PARAMETER; } @@ -1139,21 +1133,22 @@ tGATT_STATUS GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) { * ******************************************************************************/ tGATT_STATUS GATTC_SendHandleValueConfirm(uint16_t conn_id, uint16_t cid) { - LOG_INFO(" conn_id=0x%04x , cid=0x%04x", conn_id, cid); + log::info("conn_id=0x{:04x} , cid=0x{:04x}", conn_id, cid); tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(GATT_GET_TCB_IDX(conn_id)); if (!p_tcb) { - LOG(ERROR) << "Unknown conn_id=" << loghex(conn_id); + log::error("Unknown conn_id={}", loghex(conn_id)); return GATT_ILLEGAL_PARAMETER; } if (p_tcb->ind_count == 0) { - LOG_INFO("conn_id: 0x%04x ignored not waiting for indicaiton ack", conn_id); + log::info("conn_id: 0x{:04x} ignored not waiting for indicaiton ack", + conn_id); return GATT_SUCCESS; } - LOG_INFO("Received confirmation, ind_count= %d, sending confirmation", - p_tcb->ind_count); + log::info("Received confirmation, ind_count= {}, sending confirmation", + p_tcb->ind_count); /* Just wait for first confirmation.*/ p_tcb->ind_count = 0; @@ -1205,8 +1200,8 @@ void GATT_SetIdleTimeout(const RawAddress& bd_addr, uint16_t idle_tout, } } - LOG_INFO("idle_timeout=%d, is_active=%d, status=%d (1-OK 0-not performed)", - idle_tout, is_active, +status); + log::info("idle_timeout={}, is_active={}, status={} (1-OK 0-not performed)", + idle_tout, is_active, status); } /******************************************************************************* @@ -1233,14 +1228,14 @@ tGATT_IF GATT_Register(const Uuid& app_uuid128, const std::string& name, for (i_gatt_if = 0, p_reg = gatt_cb.cl_rcb; i_gatt_if < GATT_MAX_APPS; i_gatt_if++, p_reg++) { if (p_reg->in_use && p_reg->app_uuid128 == app_uuid128) { - LOG_ERROR("Application already registered, uuid=%s", - app_uuid128.ToString().c_str()); + log::error("Application already registered, uuid={}", + app_uuid128.ToString()); return 0; } } if (stack_config_get_interface()->get_pts_use_eatt_for_all_services()) { - LOG_INFO("PTS: Force to use EATT for servers"); + log::info("PTS: Force to use EATT for servers"); eatt_support = true; } @@ -1255,15 +1250,14 @@ tGATT_IF GATT_Register(const Uuid& app_uuid128, const std::string& name, p_reg->in_use = true; p_reg->eatt_support = eatt_support; p_reg->name = name; - LOG_INFO("Allocated name:%s uuid:%s gatt_if:%hhu eatt_support:%u", - name.c_str(), app_uuid128.ToString().c_str(), gatt_if, - eatt_support); + log::info("Allocated name:{} uuid:{} gatt_if:{} eatt_support:{}", name, + app_uuid128.ToString(), gatt_if, eatt_support); return gatt_if; } } - LOG_ERROR("Unable to register GATT client, MAX client reached: %d", - GATT_MAX_APPS); + log::error("Unable to register GATT client, MAX client reached: {}", + GATT_MAX_APPS); return 0; } @@ -1279,14 +1273,12 @@ tGATT_IF GATT_Register(const Uuid& app_uuid128, const std::string& name, * ******************************************************************************/ void GATT_Deregister(tGATT_IF gatt_if) { - LOG(INFO) << __func__ << " gatt_if=" << +gatt_if; + log::info("gatt_if={}", +gatt_if); tGATT_REG* p_reg = gatt_get_regcb(gatt_if); /* Index 0 is GAP and is never deregistered */ if ((gatt_if == 0) || (p_reg == NULL)) { - LOG(ERROR) << __func__ - << ": Unable to deregister client with invalid gatt_if=" - << +gatt_if; + log::error("Unable to deregister client with invalid gatt_if={}", gatt_if); return; } @@ -1362,7 +1354,7 @@ void GATT_StartIf(tGATT_IF gatt_if) { uint16_t conn_id; tBT_TRANSPORT transport; - LOG_DEBUG("Starting GATT interface gatt_if_:%hu", gatt_if); + log::debug("Starting GATT interface gatt_if_:{}", gatt_if); p_reg = gatt_get_regcb(gatt_if); if (p_reg != NULL) { @@ -1370,15 +1362,15 @@ void GATT_StartIf(tGATT_IF gatt_if) { while ( gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport)) { p_tcb = gatt_find_tcb_by_addr(bda, transport); - LOG_INFO("GATT interface %d already has connected device %s", +gatt_if, - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::info("GATT interface {} already has connected device {}", gatt_if, + ADDRESS_TO_LOGGABLE_CSTR(bda)); if (p_reg->app_cb.p_conn_cb && p_tcb) { conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if); - LOG_INFO("Invoking callback with connection id %d", conn_id); + log::info("Invoking callback with connection id {}", conn_id); (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, true, GATT_CONN_OK, transport); } else { - LOG_INFO("Skipping callback as none is registered"); + log::info("Skipping callback as none is registered"); } start_idx = ++found_idx; } @@ -1416,42 +1408,42 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, /* Make sure app is registered */ tGATT_REG* p_reg = gatt_get_regcb(gatt_if); if (!p_reg) { - LOG_ERROR("Unable to find registered app gatt_if=%d", +gatt_if); + log::error("Unable to find registered app gatt_if={}", gatt_if); return false; } bool is_direct = (connection_type == BTM_BLE_DIRECT_CONNECTION); if (!is_direct && transport != BT_TRANSPORT_LE) { - LOG_WARN("Unsupported transport for background connection gatt_if=%d", - +gatt_if); + log::warn("Unsupported transport for background connection gatt_if={}", + gatt_if); return false; } if (opportunistic) { - LOG_INFO("Registered for opportunistic connection gatt_if=%d", +gatt_if); + log::info("Registered for opportunistic connection gatt_if={}", gatt_if); return true; } - bool ret; + bool ret = false; if (is_direct) { - LOG_DEBUG("Starting direct connect gatt_if=%u address=%s", gatt_if, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Starting direct connect gatt_if={} address={}", gatt_if, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); ret = gatt_act_connect(p_reg, bd_addr, addr_type, transport, initiating_phys); } else { - LOG_DEBUG("Starting background connect gatt_if=%u address=%s", gatt_if, - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Starting background connect gatt_if={} address={}", gatt_if, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (!BTM_Sec_AddressKnown(bd_addr)) { // RPA can rotate, causing address to "expire" in the background // connection list. RPA is allowed for direct connect, as such request // times out after 30 seconds - LOG_WARN("Unable to add RPA %s to background connection gatt_if=%d", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), +gatt_if); + log::warn("Unable to add RPA {} to background connection gatt_if={}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), gatt_if); ret = false; } else { - LOG_DEBUG("Adding to background connect to device:%s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::debug("Adding to background connect to device:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (bluetooth::common::init_flags:: use_unified_connection_manager_is_enabled()) { if (connection_type == BTM_BLE_BKG_CONNECT_ALLOW_LIST) { @@ -1460,7 +1452,7 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, gatt_if, bluetooth::connection::ResolveRawAddress(bd_addr)); ret = true; // TODO(aryarahul): error handling } else { - LOG_ALWAYS_FATAL("unimplemented, TODO(aryarahul)"); + log::fatal("unimplemented, TODO(aryarahul)"); } } else { if (connection_type == BTM_BLE_BKG_CONNECT_ALLOW_LIST) { @@ -1480,10 +1472,10 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, gatt_update_app_use_link_flag(p_reg->gatt_if, p_tcb, true, !is_direct); } else { if (p_tcb == nullptr) { - LOG_DEBUG("p_tcb is null"); + log::debug("p_tcb is null"); } if (!ret) { - LOG_DEBUG("Previous step returned false"); + log::debug("Previous step returned false"); } } @@ -1514,15 +1506,14 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, ******************************************************************************/ bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr, bool is_direct) { - LOG(INFO) << __func__ << ": gatt_if:" << +gatt_if - << ", address: " << ADDRESS_TO_LOGGABLE_CSTR(bd_addr) - << ", direct:" << is_direct; + log::info("gatt_if:{}, address: {}, direct:{}", gatt_if, + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), is_direct); tGATT_REG* p_reg; if (gatt_if) { p_reg = gatt_get_regcb(gatt_if); if (!p_reg) { - LOG(ERROR) << "gatt_if=" << +gatt_if << " is not registered"; + log::error("gatt_if={} is not registered", gatt_if); return false; } @@ -1533,7 +1524,7 @@ bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr, } } - VLOG(1) << " unconditional"; + log::verbose(" unconditional"); /* only LE connection can be cancelled */ tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); @@ -1555,9 +1546,8 @@ bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr, bluetooth::connection::ResolveRawAddress(bd_addr)); } else { if (!connection_manager::remove_unconditional(bd_addr)) { - LOG(ERROR) << __func__ - << ": no app associated with the bg device for unconditional " - "removal "; + log::error( + "no app associated with the bg device for unconditional removal"); return false; } } @@ -1578,12 +1568,12 @@ bool GATT_CancelConnect(tGATT_IF gatt_if, const RawAddress& bd_addr, * ******************************************************************************/ tGATT_STATUS GATT_Disconnect(uint16_t conn_id) { - LOG_INFO("conn_id=%d", +conn_id); + log::info("conn_id={}", conn_id); uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); if (!p_tcb) { - LOG_WARN("Cannot find TCB for connection %d", conn_id); + log::warn("Cannot find TCB for connection {}", conn_id); return GATT_ILLEGAL_PARAMETER; } @@ -1613,7 +1603,7 @@ bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if, uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB* p_tcb = gatt_get_tcb_by_idx(tcb_idx); - VLOG(1) << __func__ << " conn_id=" << loghex(conn_id); + log::verbose("conn_id={}", loghex(conn_id)); if (!p_tcb || !p_reg) return false; @@ -1649,7 +1639,7 @@ bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, const RawAddress& bd_addr, status = true; } - LOG_DEBUG("status=%d", status); + log::debug("status={}", status); return status; } @@ -1679,19 +1669,19 @@ static bool gatt_load_bonded_is_enabled() { */ void gatt_load_bonded(void) { const bool load_bonded = gatt_load_bonded_is_enabled(); - LOG_INFO("load bonded: %s", load_bonded ? "True" : "False"); + log::info("load bonded: {}", load_bonded ? "True" : "False"); if (!load_bonded) { return; } for (tBTM_SEC_DEV_REC* p_dev_rec : btm_get_sec_dev_rec()) { if (p_dev_rec->sec_rec.is_link_key_known()) { - LOG_VERBOSE("Add bonded BR/EDR transport %s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); + log::verbose("Add bonded BR/EDR transport {}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr)); gatt_bonded_check_add_address(p_dev_rec->bd_addr); } if (p_dev_rec->sec_rec.is_le_link_key_known()) { - LOG_VERBOSE("Add bonded BLE %s", - ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->ble.pseudo_addr)); + log::verbose("Add bonded BLE {}", + ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->ble.pseudo_addr)); gatt_bonded_check_add_address(p_dev_rec->ble.pseudo_addr); } } diff --git a/system/stack/gatt/gatt_attr.cc b/system/stack/gatt/gatt_attr.cc index 3fa164776a3c4612ae3e425121681801e045adab..526fb05257b9f6efe437f4a4c3742d04a419b8d9 100644 --- a/system/stack/gatt/gatt_attr.cc +++ b/system/stack/gatt/gatt_attr.cc @@ -24,6 +24,7 @@ ******************************************************************************/ #include +#include #include #include @@ -46,6 +47,7 @@ using base::StringPrintf; using bluetooth::Uuid; +using namespace bluetooth; #define BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK 0x01 @@ -329,12 +331,12 @@ static void gatt_request_cback(uint16_t conn_id, uint32_t trans_id, break; case GATTS_REQ_TYPE_MTU: - VLOG(1) << "Get MTU exchange new mtu size: " << +p_data->mtu; + log::verbose("Get MTU exchange new mtu size: {}", p_data->mtu); rsp_needed = false; break; default: - VLOG(1) << "Unknown/unexpected LE GAP ATT request: " << loghex(type); + log::verbose("Unknown/unexpected LE GAP ATT request: {}", loghex(type)); break; } @@ -354,13 +356,13 @@ static void gatt_connect_cback(UNUSED_ATTR tGATT_IF gatt_if, const RawAddress& bda, uint16_t conn_id, bool connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport) { - VLOG(1) << __func__ << ": from " << ADDRESS_TO_LOGGABLE_STR(bda) - << " connected: " << connected << ", conn_id: " << loghex(conn_id); + log::verbose("from {} connected: {}, conn_id: {}", + ADDRESS_TO_LOGGABLE_STR(bda), connected, loghex(conn_id)); // if the device is not trusted, remove data when the link is disconnected if (!connected && !btm_sec_is_a_bonded_dev(bda)) { - LOG(INFO) << __func__ << ": remove untrusted client status, bda=" - << ADDRESS_TO_LOGGABLE_STR(bda); + log::info("remove untrusted client status, bda={}", + ADDRESS_TO_LOGGABLE_STR(bda)); btif_storage_remove_gatt_cl_supp_feat(bda); btif_storage_remove_gatt_cl_db_hash(bda); } @@ -452,7 +454,7 @@ void gatt_profile_db_init(void) { if (gatt_cl_is_robust_caching_enabled()) gatt_cb.gatt_cl_supported_feat_mask |= BLE_GATT_CL_SUP_FEAT_CACHING_BITMASK; - VLOG(1) << __func__ << ": gatt_if=" << gatt_cb.gatt_if << " EATT supported"; + log::verbose("gatt_if={} EATT supported", gatt_cb.gatt_if); } /******************************************************************************* @@ -491,7 +493,7 @@ static void gatt_disc_res_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, case GATT_DISC_SRVC_ALL: case GATT_DISC_INC_SRVC: case GATT_DISC_MAX: - LOG_ERROR("Illegal discovery item handled"); + log::error("Illegal discovery item handled"); break; } } @@ -509,17 +511,17 @@ static void gatt_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status) { tGATT_PROFILE_CLCB* p_clcb = gatt_profile_find_clcb_by_conn_id(conn_id); if (p_clcb == NULL) { - LOG_WARN("Unable to find gatt profile after discovery complete"); + log::warn("Unable to find gatt profile after discovery complete"); return; } if (status != GATT_SUCCESS) { - LOG_WARN("Gatt discovery completed with errors status:%u", status); + log::warn("Gatt discovery completed with errors status:{}", status); return; } if (p_clcb->ccc_result == 0) { - LOG_WARN("Gatt discovery completed but connection was idle id:%hu", - conn_id); + log::warn("Gatt discovery completed but connection was idle id:{}", + conn_id); return; } @@ -541,8 +543,7 @@ static bool gatt_svc_read_cl_supp_feat_req(uint16_t conn_id) { tGATT_STATUS status = GATTC_Read(conn_id, GATT_READ_BY_TYPE, ¶m); if (status != GATT_SUCCESS) { - LOG(ERROR) << __func__ << " Read failed. Status: " - << loghex(static_cast(status)); + log::error("Read failed. Status: {}", loghex(static_cast(status))); return false; } @@ -568,8 +569,8 @@ static bool gatt_att_write_cl_supp_feat(uint16_t conn_id, uint16_t handle) { tGATT_STATUS status = GATTC_Write(conn_id, GATT_WRITE, &attr); if (status != GATT_SUCCESS) { - LOG(ERROR) << __func__ << " Write failed. Status: " - << loghex(static_cast(status)); + log::error("Write failed. Status: {}", + loghex(static_cast(status))); return false; } @@ -590,19 +591,19 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE* p_data) { auto iter = OngoingOps.find(conn_id); - VLOG(1) << __func__ << " opcode: " << loghex(static_cast(op)) - << " status: " << status - << " conn id: " << loghex(static_cast(conn_id)); + log::verbose("opcode: {} status: {} conn id: {}", + loghex(static_cast(op)), status, + loghex(static_cast(conn_id))); if (op != GATTC_OPTYPE_READ && op != GATTC_OPTYPE_WRITE) { - LOG_DEBUG("Not interested in opcode %d", op); + log::debug("Not interested in opcode {}", op); return; } if (iter == OngoingOps.end() || (iter->second.size() == 0)) { /* If OngoingOps is empty it means we are not interested in the result here. */ - LOG_DEBUG("Unexpected read complete"); + log::debug("Unexpected read complete"); return; } @@ -610,14 +611,14 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, if (op == GATTC_OPTYPE_WRITE) { if (cl_op_uuid == GATT_UUID_GATT_SRV_CHGD) { - LOG_DEBUG("Write response from Service Changed CCC"); + log::debug("Write response from Service Changed CCC"); iter->second.pop_front(); /* Read server supported features here supported */ read_sr_supported_feat_req( conn_id, base::BindOnce([](const RawAddress& bdaddr, uint8_t support) { return; })); } else { - LOG_DEBUG("Not interested in that write response"); + log::debug("Not interested in that write response"); } return; } @@ -625,7 +626,7 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, /* Handle Read operations */ uint8_t* pp = p_data->att_value.value; - VLOG(1) << __func__ << " cl_op_uuid " << loghex(cl_op_uuid); + log::verbose("cl_op_uuid {}", loghex(cl_op_uuid)); switch (cl_op_uuid) { case GATT_UUID_SERVER_SUP_FEAT: { @@ -677,8 +678,7 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, iter->second.pop_front(); if (status != GATT_SUCCESS) { - LOG(INFO) << __func__ - << " Client supported features charcteristic not found"; + log::info("Client supported features charcteristic not found"); return; } @@ -698,8 +698,7 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, * ******************************************************************************/ static void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB* p_clcb) { - - VLOG(1) << __func__ << ": stage: " << +p_clcb->ccc_stage; + log::verbose("stage: {}", p_clcb->ccc_stage); switch (p_clcb->ccc_stage) { case GATT_SVC_CHANGED_SERVICE: /* discover GATT service */ @@ -801,7 +800,7 @@ static bool read_sr_supported_feat_req( param.service.uuid = bluetooth::Uuid::From16Bit(GATT_UUID_SERVER_SUP_FEAT); if (GATTC_Read(conn_id, GATT_READ_BY_TYPE, ¶m) != GATT_SUCCESS) { - LOG_ERROR("Read GATT Support features GATT_Read Failed"); + log::error("Read GATT Support features GATT_Read Failed"); return false; } @@ -828,8 +827,8 @@ static bool read_sr_sirk_req( param.service.uuid = bluetooth::Uuid::From16Bit(GATT_UUID_CSIS_SIRK); if (GATTC_Read(conn_id, GATT_READ_BY_TYPE, ¶m) != GATT_SUCCESS) { - LOG_ERROR("Read GATT Support features GATT_Read Failed, conn_id: %d", - static_cast(conn_id)); + log::error("Read GATT Support features GATT_Read Failed, conn_id: {}", + static_cast(conn_id)); return false; } @@ -859,8 +858,8 @@ bool gatt_cl_read_sr_supp_feat_req( if (!cb) return false; - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(peer_bda) - << " read gatt supported features"; + log::verbose("BDA: {} read gatt supported features", + ADDRESS_TO_LOGGABLE_STR(peer_bda)); GATT_GetConnIdIfConnected(gatt_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE); @@ -872,7 +871,7 @@ bool gatt_cl_read_sr_supp_feat_req( } if (!p_clcb) { - VLOG(1) << __func__ << " p_clcb is NULL " << loghex(conn_id); + log::verbose("p_clcb is NULL {}", loghex(conn_id)); return false; } @@ -903,7 +902,7 @@ bool gatt_cl_read_sirk_req( if (!cb) return false; - LOG_DEBUG("BDA: %s, read SIRK", ADDRESS_TO_LOGGABLE_CSTR(peer_bda)); + log::debug("BDA: {}, read SIRK", ADDRESS_TO_LOGGABLE_CSTR(peer_bda)); GATT_GetConnIdIfConnected(gatt_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE); @@ -915,7 +914,7 @@ bool gatt_cl_read_sirk_req( } if (!p_clcb) { - LOG_VERBOSE("p_clcb is NULL, conn_id: %04x", conn_id); + log::verbose("p_clcb is NULL, conn_id: {:04x}", conn_id); return false; } @@ -940,8 +939,8 @@ bool gatt_cl_read_sirk_req( bool gatt_profile_get_eatt_support(const RawAddress& remote_bda) { uint16_t conn_id; - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(remote_bda) - << " read GATT support"; + log::verbose("BDA: {} read GATT support", + ADDRESS_TO_LOGGABLE_STR(remote_bda)); GATT_GetConnIdIfConnected(gatt_cb.gatt_if, remote_bda, &conn_id, BT_TRANSPORT_LE); @@ -1049,9 +1048,9 @@ void gatt_sr_init_cl_status(tGATT_TCB& tcb) { tcb.is_robust_cache_change_aware = true; } - LOG(INFO) << __func__ << ": bda=" << ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda) - << ", cl_supp_feat=" << loghex(tcb.cl_supp_feat) - << ", aware=" << tcb.is_robust_cache_change_aware; + log::info("bda={}, cl_supp_feat={}, aware={}", + ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda), loghex(tcb.cl_supp_feat), + tcb.is_robust_cache_change_aware); } /******************************************************************************* @@ -1075,8 +1074,8 @@ void gatt_sr_update_cl_status(tGATT_TCB& tcb, bool chg_aware) { // only when the status is changed, print the log if (tcb.is_robust_cache_change_aware != chg_aware) { - LOG(INFO) << __func__ << ": bda=" << ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda) - << ", chg_aware=" << chg_aware; + log::info("bda={}, chg_aware={}", ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda), + chg_aware); } tcb.is_robust_cache_change_aware = chg_aware; @@ -1085,7 +1084,7 @@ void gatt_sr_update_cl_status(tGATT_TCB& tcb, bool chg_aware) { /* handle request for reading database hash */ static tGATT_STATUS gatt_sr_read_db_hash(uint16_t conn_id, tGATT_VALUE* p_value) { - LOG(INFO) << __func__ << ": conn_id=" << loghex(conn_id); + log::info("conn_id={}", loghex(conn_id)); uint8_t* p = p_value->value; Octet16& db_hash = gatt_cb.database_hash; @@ -1139,14 +1138,14 @@ static tGATT_STATUS gatt_sr_write_cl_supp_feat(uint16_t conn_id, // If input length is zero, return value_not_allowed if (tmp.empty()) { - LOG(INFO) << __func__ << ": zero length, conn_id=" << loghex(conn_id) - << ", bda=" << ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda); + log::info("zero length, conn_id={}, bda={}", loghex(conn_id), + ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda)); return GATT_VALUE_NOT_ALLOWED; } // if original length is longer than new one, it must be the bit reset case. if (feature_list.size() > tmp.size()) { - LOG(INFO) << __func__ << ": shorter length, conn_id=" << loghex(conn_id) - << ", bda=" << ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda); + log::info("shorter length, conn_id={}, bda={}", loghex(conn_id), + ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda)); return GATT_VALUE_NOT_ALLOWED; } // new length is longer or equals to the original, need to check bits @@ -1160,9 +1159,8 @@ static tGATT_STATUS gatt_sr_write_cl_supp_feat(uint16_t conn_id, uint8_t val_xor = *it_old ^ *it_new; uint8_t val_and = val_xor & *it_new; if (val_and != val_xor) { - LOG(INFO) << __func__ - << ": bit cannot be reset, conn_id=" << loghex(conn_id) - << ", bda=" << ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda); + log::info("bit cannot be reset, conn_id={}, bda={}", loghex(conn_id), + ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda)); return GATT_VALUE_NOT_ALLOWED; } } @@ -1174,9 +1172,8 @@ static tGATT_STATUS gatt_sr_write_cl_supp_feat(uint16_t conn_id, if (!gatt_sr_is_robust_caching_enabled()) { // remove robust caching bit tcb.cl_supp_feat &= ~BLE_GATT_CL_SUP_FEAT_CACHING_BITMASK; - LOG(INFO) << __func__ - << ": reset robust caching bit, conn_id=" << loghex(conn_id) - << ", bda=" << ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda); + log::info("reset robust caching bit, conn_id={}, bda={}", loghex(conn_id), + ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda)); } // TODO(hylo): save data as byte array btif_storage_set_gatt_cl_supp_feat(tcb.peer_bda, tcb.cl_supp_feat); @@ -1185,8 +1182,7 @@ static tGATT_STATUS gatt_sr_write_cl_supp_feat(uint16_t conn_id, bool new_caching_state = gatt_sr_is_cl_robust_caching_supported(tcb); // only when the first time robust caching request, print the log if (!curr_caching_state && new_caching_state) { - LOG(INFO) << __func__ << ": robust caching enabled by client" - << ", conn_id=" << loghex(conn_id); + log::info("robust caching enabled by client, conn_id={}", loghex(conn_id)); } return GATT_SUCCESS; diff --git a/system/stack/gatt/gatt_auth.cc b/system/stack/gatt/gatt_auth.cc index 126baebbf37d3cb28f1848fb67c3231b989d5875..0b2ccebd3eb6d4de3c87f638d1220bd50e0ddf89 100644 --- a/system/stack/gatt/gatt_auth.cc +++ b/system/stack/gatt/gatt_auth.cc @@ -22,11 +22,12 @@ * ******************************************************************************/ #include +#include #include -#include "bt_target.h" #include "gatt_api.h" #include "gatt_int.h" +#include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "stack/btm/btm_ble_sec.h" @@ -36,7 +37,7 @@ #include "stack/include/btm_ble_sec_api.h" #include "types/raw_address.h" -using base::StringPrintf; +using namespace bluetooth; /******************************************************************************* * @@ -104,8 +105,8 @@ void gatt_verify_signature(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) { uint32_t counter; if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) { - LOG(ERROR) << StringPrintf("%s: Data length %u less than expected %u", - __func__, p_buf->len, GATT_AUTH_SIGN_LEN + 4); + log::error("Data length {} less than expected {}", p_buf->len, + GATT_AUTH_SIGN_LEN + 4); return; } cmd_len = p_buf->len - GATT_AUTH_SIGN_LEN + 4; @@ -114,7 +115,7 @@ void gatt_verify_signature(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) { if (!BTM_BleVerifySignature(tcb.peer_bda, p_orig, cmd_len, counter, p)) { /* if this is a bad signature, assume from attacker, ignore it */ - LOG(ERROR) << StringPrintf("Signature Verification Failed, data ignored"); + log::error("Signature Verification Failed, data ignored"); return; } @@ -158,19 +159,17 @@ static void gatt_enc_cmpl_cback(const RawAddress* bd_addr, tBT_TRANSPORT transport, UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) { - VLOG(1) << StringPrintf("gatt_enc_cmpl_cback"); + log::verbose(""); tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(*bd_addr, transport); if (!p_tcb) { - LOG(ERROR) << StringPrintf("%s: enc callback for unknown bd_addr", - __func__); + log::error("enc callback for unknown bd_addr"); return; } if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING) return; if (p_tcb->pending_enc_clcb.empty()) { - LOG(ERROR) << StringPrintf("%s: no operation waiting for encrypting", - __func__); + log::error("no operation waiting for encrypting"); return; } @@ -214,8 +213,7 @@ static void gatt_enc_cmpl_cback(const RawAddress* bd_addr, void gatt_notify_enc_cmpl(const RawAddress& bd_addr) { tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE); if (!p_tcb) { - VLOG(1) << StringPrintf( - "notify GATT for encryption completion of unknown device"); + log::verbose("notify GATT for encryption completion of unknown device"); return; } @@ -365,8 +363,7 @@ tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB& tcb) { } } - VLOG(1) << StringPrintf("gatt_get_link_encrypt_status status=0x%x", - encrypt_status); + log::verbose("gatt_get_link_encrypt_status status=0x{:x}", encrypt_status); return encrypt_status; } @@ -412,24 +409,21 @@ bool gatt_security_check_start(tGATT_CLCB* p_clcb) { switch (gatt_sec_act) { case GATT_SEC_SIGN_DATA: - VLOG(1) << StringPrintf("%s: Do data signing", __func__); + log::verbose("Do data signing"); gatt_sign_data(p_clcb); break; case GATT_SEC_ENCRYPT: case GATT_SEC_ENCRYPT_NO_MITM: case GATT_SEC_ENCRYPT_MITM: if (sec_act_old < GATT_SEC_ENCRYPT) { - VLOG(1) << StringPrintf("%s: Encrypt now or key upgreade first", - __func__); + log::verbose("Encrypt now or key upgreade first"); tBTM_BLE_SEC_ACT btm_ble_sec_act; gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act); tBTM_STATUS btm_status = BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport, gatt_enc_cmpl_cback, NULL, btm_ble_sec_act); if ((btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED)) { - LOG(ERROR) << StringPrintf( - "%s BTM_SetEncryption failed btm_status=%d", __func__, - btm_status); + log::error("BTM_SetEncryption failed btm_status={}", btm_status); gatt_set_sec_act(p_tcb, GATT_SEC_NONE); gatt_set_ch_state(p_tcb, GATT_CH_OPEN); diff --git a/system/stack/gatt/gatt_cl.cc b/system/stack/gatt/gatt_cl.cc index 69df1ea9fa874826748b9548ce2be82a7b6083ef..f273f626549b487aac649497db6dca06a1501f19 100644 --- a/system/stack/gatt/gatt_cl.cc +++ b/system/stack/gatt/gatt_cl.cc @@ -25,11 +25,14 @@ #define LOG_TAG "bluetooth" #include +#include #include #include "gatt_int.h" #include "hardware/bt_gatt_types.h" +#include "include/check.h" #include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" @@ -51,7 +54,7 @@ #define L2CAP_PKT_OVERHEAD 4 -using base::StringPrintf; +using namespace bluetooth; using bluetooth::Uuid; using bluetooth::eatt::EattExtension; using bluetooth::eatt::EattChannel; @@ -92,7 +95,7 @@ void gatt_act_discovery(tGATT_CLCB* p_clcb) { uint8_t op_code = disc_type_to_att_opcode[p_clcb->op_subtype]; if (p_clcb->s_handle > p_clcb->e_handle || p_clcb->s_handle == 0) { - LOG_DEBUG("Completed GATT discovery of all handle ranges"); + log::debug("Completed GATT discovery of all handle ranges"); gatt_end_operation(p_clcb, GATT_SUCCESS, NULL); return; } @@ -133,7 +136,7 @@ void gatt_act_discovery(tGATT_CLCB* p_clcb) { tGATT_STATUS st = attp_send_cl_msg(*p_clcb->p_tcb, p_clcb, op_code, &cl_req); if (st != GATT_SUCCESS && st != GATT_CMD_STARTED) { - LOG_WARN("Unable to send ATT message"); + log::warn("Unable to send ATT message"); gatt_end_operation(p_clcb, GATT_ERROR, NULL); } } @@ -179,8 +182,8 @@ void gatt_act_read(tGATT_CLCB* p_clcb, uint16_t offset) { else p_clcb->first_read_blob_after_read = false; - VLOG(1) << __func__ << ": first_read_blob_after_read=" - << p_clcb->first_read_blob_after_read; + log::verbose("first_read_blob_after_read={}", + p_clcb->first_read_blob_after_read); op_code = GATT_REQ_READ_BLOB; msg.read_blob.offset = offset; msg.read_blob.handle = p_clcb->s_handle; @@ -211,7 +214,7 @@ void gatt_act_read(tGATT_CLCB* p_clcb, uint16_t offset) { break; default: - LOG(ERROR) << "Unknown read type:" << +p_clcb->op_subtype; + log::error("Unknown read type:{}", p_clcb->op_subtype); break; } @@ -240,8 +243,8 @@ void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) { attr.len, 0, attr.value); if (rt != GATT_CMD_STARTED) { if (rt != GATT_SUCCESS) { - LOG(ERROR) << StringPrintf( - "gatt_act_write() failed op_code=0x%x rt=%d", op_code, rt); + log::error("gatt_act_write() failed op_code=0x{:x} rt={}", op_code, + rt); } gatt_end_operation(p_clcb, rt, NULL); } @@ -257,9 +260,8 @@ void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) { if (rt != GATT_SUCCESS && rt != GATT_CMD_STARTED && rt != GATT_CONGESTED) { if (rt != GATT_SUCCESS) { - LOG(ERROR) << StringPrintf( - "gatt_act_write() failed op_code=0x%x rt=%d", GATT_REQ_WRITE, - rt); + log::error("gatt_act_write() failed op_code=0x{:x} rt={}", + GATT_REQ_WRITE, rt); } gatt_end_operation(p_clcb, rt, NULL); } @@ -293,7 +295,7 @@ void gatt_send_queue_write_cancel(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, tGATT_EXEC_FLAG flag) { tGATT_STATUS rt; - VLOG(1) << __func__; + log::verbose(""); tGATT_CL_MSG gatt_cl_msg; gatt_cl_msg.exec_write = flag; @@ -318,7 +320,7 @@ bool gatt_check_write_long_terminate(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, bool terminate = false; tGATT_EXEC_FLAG flag = GATT_PREP_WRITE_EXEC; - VLOG(1) << __func__; + log::verbose(""); /* check the first write response status */ if (p_rsp_value != NULL) { if (p_rsp_value->handle != p_attr->handle || @@ -347,7 +349,7 @@ void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb) { tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf; uint8_t type = p_clcb->op_subtype; - VLOG(1) << __func__ << StringPrintf(" type=0x%x", type); + log::verbose("type=0x{:x}", type); uint16_t to_send = p_attr->len - p_attr->offset; uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid); @@ -362,7 +364,7 @@ void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb) { offset += p_clcb->start_offset; } - VLOG(1) << StringPrintf("offset =0x%x len=%d", offset, to_send); + log::verbose("offset =0x{:x} len={}", offset, to_send); tGATT_STATUS rt = gatt_send_write_msg( tcb, p_clcb, GATT_REQ_PREPARE_WRITE, p_attr->handle, to_send, /* length */ @@ -393,7 +395,7 @@ void gatt_process_find_type_value_rsp(UNUSED_ATTR tGATT_TCB& tcb, tGATT_DISC_RES result; uint8_t* p = p_data; - VLOG(1) << __func__; + log::verbose(""); /* unexpected response */ if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY || p_clcb->op_subtype != GATT_DISC_SRVC_BY_UUID) @@ -441,7 +443,7 @@ void gatt_process_read_info_rsp(UNUSED_ATTR tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t *p = p_data, uuid_len = 0, type; if (len < GATT_INFO_RSP_MIN_LEN) { - LOG(ERROR) << "invalid Info Response PDU received, discard."; + log::error("invalid Info Response PDU received, discard."); gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL); return; } @@ -493,8 +495,7 @@ void gatt_proc_disc_error_rsp(UNUSED_ATTR tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint8_t reason) { tGATT_STATUS status = (tGATT_STATUS)reason; - VLOG(1) << __func__ - << StringPrintf("reason: %02x cmd_code %04x", reason, opcode); + log::verbose("reason: {:02x} cmd_code {:04x}", reason, opcode); switch (opcode) { case GATT_REQ_READ_BY_GRP_TYPE: @@ -503,11 +504,11 @@ void gatt_proc_disc_error_rsp(UNUSED_ATTR tGATT_TCB& tcb, tGATT_CLCB* p_clcb, case GATT_REQ_FIND_INFO: if (reason == GATT_NOT_FOUND) { status = GATT_SUCCESS; - VLOG(1) << "Discovery completed"; + log::verbose("Discovery completed"); } break; default: - LOG(ERROR) << StringPrintf("Incorrect discovery opcode %04x", opcode); + log::error("Incorrect discovery opcode {:04x}", opcode); break; } @@ -532,10 +533,10 @@ void gatt_process_error_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint16_t handle; tGATT_VALUE* p_attr = (tGATT_VALUE*)p_clcb->p_attr_buf; - VLOG(1) << __func__; + log::verbose(""); if (len < 4) { - LOG(ERROR) << "Error response too short"; + log::error("Error response too short"); // Specification does not clearly define what should happen if error // response is too short. General rule in BT Spec 5.0 Vol 3, Part F 3.4.1.1 // is: "If an error code is received in the Error Response that is not @@ -591,12 +592,12 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, .conn_id = p_clcb->conn_id, .auth_req = GATT_AUTH_REQ_NONE, }; - VLOG(1) << StringPrintf("value resp op_code = %s len = %d", - gatt_dbg_op_name(op_code), len); + log::verbose("value resp op_code = {} len = {}", gatt_dbg_op_name(op_code), + len); if (len < GATT_PREP_WRITE_RSP_MIN_LEN || len > GATT_PREP_WRITE_RSP_MIN_LEN + sizeof(value.value)) { - LOG(ERROR) << "illegal prepare write response length, discard"; + log::error("illegal prepare write response length, discard"); gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value); return; } @@ -646,11 +647,11 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, ? GATTC_OPTYPE_INDICATION : GATTC_OPTYPE_NOTIFICATION; - VLOG(1) << __func__; + log::verbose(""); // Ensure our packet has enough data (2 bytes) if (len < GATT_NOTIFICATION_MIN_LEN) { - LOG(ERROR) << "illegal notification PDU length, discard"; + log::error("illegal notification PDU length, discard"); return; } @@ -669,7 +670,7 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, if (op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) { // Ensure our packet has enough data; MIN + 2 more bytes for len value if (len < GATT_NOTIFICATION_MIN_LEN + 2) { - LOG(ERROR) << "illegal notification PDU length, discard"; + log::error("illegal notification PDU length, discard"); return; } @@ -677,8 +678,8 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, STREAM_TO_UINT16(value.len, p); if (value.len > len - 4) { - LOG(ERROR) << "value.len (" << value.len << ") greater than length (" - << (len - 4); + log::error("value.len ({}) greater than length ({})", value.len, + (len - 4)); return; } @@ -689,7 +690,7 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, // Verify the new calculated length if (value.len > GATT_MAX_ATTR_LEN) { - LOG(ERROR) << "value.len larger than GATT_MAX_ATTR_LEN, discard"; + log::error("value.len larger than GATT_MAX_ATTR_LEN, discard"); return; } @@ -701,8 +702,8 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, For now, just log the error reset the counter. Later we need to disconnect the link unconditionally. */ - LOG(ERROR) << __func__ << " rcv Ind. but ind_count=" << tcb.ind_count - << " (will reset ind_count)"; + log::error("rcv Ind. but ind_count={} (will reset ind_count)", + tcb.ind_count); } // Zero out the ind_count @@ -762,7 +763,7 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, // we can Also need to watch comparing the int16_t with the uint16_t value.len = std::min((uint16_t)rem_len, value.len); if (value.len > sizeof(value.value)) { - LOG(ERROR) << "Unexpected value.len (>GATT_MAX_ATTR_LEN), stop"; + log::error("Unexpected value.len (>GATT_MAX_ATTR_LEN), stop"); return ; } STREAM_TO_ARRAY(value.value, p, value.len); @@ -807,7 +808,7 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, return; if (len < GATT_READ_BY_TYPE_RSP_MIN_LEN) { - LOG(ERROR) << "Illegal ReadByType/ReadByGroupType Response length, discard"; + log::error("Illegal ReadByType/ReadByGroupType Response length, discard"); gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL); return; } @@ -818,18 +819,16 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, /* this is an error case that server's response containing a value length which is larger than MTU-2 or value_len > message total length -1 */ - LOG(ERROR) << __func__ - << StringPrintf( - ": Discard response op_code=%d " - "vale_len=%d > (MTU-2=%d or msg_len-1=%d)", - op_code, value_len, (payload_size - 2), (len - 1)); + log::error( + "Discard response op_code={} vale_len={} > (MTU-2={} or msg_len-1={})", + op_code, value_len, (payload_size - 2), (len - 1)); gatt_end_operation(p_clcb, GATT_ERROR, NULL); return; } if (op_code == GATT_RSP_READ_BY_GRP_TYPE) handle_len = 4; - value_len -= handle_len; /* substract the handle pairs bytes */ + value_len -= handle_len; /* subtract the handle pairs bytes */ len -= 1; while (len >= (handle_len + value_len)) { @@ -860,7 +859,7 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, record_value.group_value.e_handle = handle; if (!gatt_parse_uuid_from_cmd(&record_value.group_value.service_type, value_len, &p)) { - LOG(ERROR) << "discover all service response parsing failure"; + log::error("discover all service response parsing failure"); break; } } @@ -869,7 +868,7 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, else if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->op_subtype == GATT_DISC_INC_SRVC) { if (value_len < 4) { - LOG(ERROR) << __func__ << " Illegal Response length, must be at least 4."; + log::error("Illegal Response length, must be at least 4."); gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL); return; } @@ -898,9 +897,8 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, gatt_act_read(p_clcb, 0); return; } else { - LOG(ERROR) << __func__ - << ": INCL_SRVC failed with invalid data value_len=" - << +value_len; + log::error("INCL_SRVC failed with invalid data value_len={}", + value_len); gatt_end_operation(p_clcb, GATT_INVALID_PDU, (void*)p); return; } @@ -924,10 +922,10 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, gatt_end_operation(p_clcb, GATT_SUCCESS, (void*)p); } return; - } else /* discover characterisitic */ + } else /* discover characteristic */ { if (value_len < 3) { - LOG(ERROR) << __func__ << " Illegal Response length, must be at least 3."; + log::error("Illegal Response length, must be at least 3."); gatt_end_operation(p_clcb, GATT_INVALID_PDU, NULL); return; } @@ -1014,7 +1012,7 @@ void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, if (!p_clcb->p_attr_buf) p_clcb->p_attr_buf = (uint8_t*)osi_malloc(GATT_MAX_ATTR_LEN); - /* copy attrobute value into cb buffer */ + /* copy attribute value into cb buffer */ if (offset < GATT_MAX_ATTR_LEN) { if ((len + offset) > GATT_MAX_ATTR_LEN) len = GATT_MAX_ATTR_LEN - offset; @@ -1035,9 +1033,9 @@ void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, /* send next request if needed */ if (packet_is_full && (len + offset < GATT_MAX_ATTR_LEN)) { - VLOG(1) << StringPrintf( - "full pkt issue read blob for remianing bytes old offset=%d " - "len=%d new offset=%d", + log::verbose( + "full pkt issue read blob for remaining bytes old offset={} " + "len={} new offset={}", offset, len, p_clcb->counter); gatt_act_read(p_clcb, p_clcb->counter); } else /* end of request, send callback */ @@ -1046,8 +1044,8 @@ void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, } } else /* exception, should not happen */ { - LOG(ERROR) << "attr offset = " << +offset - << " p_attr_buf = " << p_clcb->p_attr_buf; + log::error("attr offset = {} p_attr_buf = {}", offset, + fmt::ptr(p_clcb->p_attr_buf)); gatt_end_operation(p_clcb, GATT_NO_RESOURCES, (void*)p_clcb->p_attr_buf); } @@ -1102,14 +1100,14 @@ void gatt_process_mtu_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint16_t len, tGATT_STATUS status = GATT_SUCCESS; if (len < GATT_MTU_RSP_MIN_LEN) { - LOG(ERROR) << "invalid MTU response PDU received, discard."; + log::error("invalid MTU response PDU received, discard."); status = GATT_INVALID_PDU; } else { STREAM_TO_UINT16(mtu, p_data); - LOG_INFO("Local pending MTU %d, Remote (%s) MTU %d", - tcb.pending_user_mtu_exchange_value, - tcb.peer_bda.ToString().c_str(), mtu); + log::info("Local pending MTU {}, Remote ({}) MTU {}", + tcb.pending_user_mtu_exchange_value, + ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda), mtu); /* Aim for default as we did in the request */ if (mtu < GATT_DEF_BLE_MTU_SIZE) { @@ -1131,7 +1129,7 @@ void gatt_process_mtu_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, uint16_t len, } tcb.pending_user_mtu_exchange_value = 0; - LOG_INFO("MTU Exchange resulted in: %d", tcb.payload_size); + log::info("MTU Exchange resulted in: {}", tcb.payload_size); BTM_SetBleDataLength(tcb.peer_bda, tcb.max_user_mtu + L2CAP_PKT_OVERHEAD); } @@ -1182,7 +1180,7 @@ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) { att_ret = attp_send_msg_to_l2cap(tcb, cmd.cid, cmd.p_cmd); if (att_ret != GATT_SUCCESS && att_ret != GATT_CONGESTED) { - LOG(ERROR) << __func__ << ": L2CAP sent error"; + log::error("L2CAP sent error"); cl_cmd_q->pop_front(); continue; } @@ -1215,16 +1213,15 @@ bool gatt_cl_send_next_cmd_inq(tGATT_TCB& tcb) { void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, uint16_t len, uint8_t* p_data) { - VLOG(1) << __func__ << " opcode: " << loghex(op_code) << " cid" << +cid; + log::verbose("opcode: {} cid{}", loghex(op_code), cid); uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid); if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF || op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) { if (len >= payload_size) { - LOG(ERROR) << StringPrintf( - "%s: invalid indicate pkt size: %d, PDU size: %d", __func__, len + 1, - payload_size); + log::error("invalid indicate pkt size: {}, PDU size: {}", len + 1, + payload_size); return; } @@ -1235,21 +1232,22 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, uint8_t cmd_code = 0; tGATT_CLCB* p_clcb = gatt_cmd_dequeue(tcb, cid, &cmd_code); if (!p_clcb) { - LOG_WARN("ATT - clcb already not in use, ignoring response"); + log::warn("ATT - clcb already not in use, ignoring response"); gatt_cl_send_next_cmd_inq(tcb); return; } uint8_t rsp_code = gatt_cmd_to_rsp_code(cmd_code); if (!p_clcb) { - LOG_WARN("ATT - clcb already not in use, ignoring response"); + log::warn("ATT - clcb already not in use, ignoring response"); gatt_cl_send_next_cmd_inq(tcb); return; } if (rsp_code != op_code && op_code != GATT_RSP_ERROR) { - LOG(WARNING) << StringPrintf( - "ATT - Ignore wrong response. Receives (%02x) Request(%02x) Ignored", + log::warn( + "ATT - Ignore wrong response. Receives ({:02x}) Request({:02x}) " + "Ignored", op_code, rsp_code); return; } @@ -1261,9 +1259,8 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, /* The message has to be smaller than the agreed MTU, len does not count * op_code */ if (len >= payload_size) { - LOG(ERROR) << StringPrintf( - "%s: invalid response pkt size: %d, PDU size: %d", __func__, len + 1, - payload_size); + log::error("invalid response pkt size: {}, PDU size: {}", len + 1, + payload_size); gatt_end_operation(p_clcb, GATT_ERROR, NULL); } else { switch (op_code) { @@ -1308,7 +1305,7 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, break; default: - LOG(ERROR) << __func__ << ": Unknown opcode = " << std::hex << op_code; + log::error("Unknown opcode = {:x}", op_code); break; } } diff --git a/system/stack/gatt/gatt_db.cc b/system/stack/gatt/gatt_db.cc index 30aee99766cd84c486e9c2a59bbb0b353c7fb8e7..55ded60a182b97cc37cc51a7c7b17146711ceda6 100644 --- a/system/stack/gatt/gatt_db.cc +++ b/system/stack/gatt/gatt_db.cc @@ -23,6 +23,7 @@ ******************************************************************************/ #include +#include #include #include #include @@ -34,8 +35,8 @@ #include "stack/include/bt_types.h" #include "types/bluetooth/uuid.h" -using base::StringPrintf; using bluetooth::Uuid; +using namespace bluetooth; /******************************************************************************* * L O C A L F U N C T I O N P R O T O T Y P E S * @@ -53,8 +54,7 @@ void gatts_init_service_db(tGATT_SVC_DB& db, const Uuid& service_uuid, bool is_pri, uint16_t s_hdl, uint16_t num_handle) { db.attr_list.reserve(num_handle); - VLOG(1) << StringPrintf("%s: s_hdl= %d num_handle= %d", __func__, s_hdl, - num_handle); + log::verbose("s_hdl= {} num_handle= {}", s_hdl, num_handle); /* update service database information */ db.next_handle = s_hdl; @@ -70,7 +70,7 @@ void gatts_init_service_db(tGATT_SVC_DB& db, const Uuid& service_uuid, Uuid* gatts_get_service_uuid(tGATT_SVC_DB* p_db) { if (!p_db || p_db->attr_list.empty()) { - LOG(ERROR) << "service DB empty"; + log::error("service DB empty"); return NULL; } else { return &p_db->attr_list[0].p_value->uuid; @@ -92,29 +92,29 @@ static tGATT_STATUS gatts_check_attr_readability(const tGATT_ATTR& attr, } if (!(perm & GATT_READ_ALLOWED)) { - LOG(ERROR) << __func__ << ": GATT_READ_NOT_PERMIT"; + log::error("GATT_READ_NOT_PERMIT"); return GATT_READ_NOT_PERMIT; } if ((perm & GATT_READ_AUTH_REQUIRED) && !sec_flag.is_link_key_known && !sec_flag.is_encrypted) { - LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION"; + log::error("GATT_INSUF_AUTHENTICATION"); return GATT_INSUF_AUTHENTICATION; } if ((perm & GATT_READ_MITM_REQUIRED) && !sec_flag.is_link_key_authed) { - LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION: MITM Required"; + log::error("GATT_INSUF_AUTHENTICATION: MITM Required"); return GATT_INSUF_AUTHENTICATION; } if ((perm & GATT_READ_ENCRYPTED_REQUIRED) && !sec_flag.is_encrypted) { - LOG(ERROR) << __func__ << ": GATT_INSUF_ENCRYPTION"; + log::error("GATT_INSUF_ENCRYPTION"); return GATT_INSUF_ENCRYPTION; } if ((perm & GATT_READ_ENCRYPTED_REQUIRED) && sec_flag.is_encrypted && (key_size < min_key_size)) { - LOG(ERROR) << __func__ << ": GATT_INSUF_KEY_SIZE"; + log::error("GATT_INSUF_KEY_SIZE"); return GATT_INSUF_KEY_SIZE; } @@ -141,7 +141,7 @@ static tGATT_STATUS gatts_check_attr_readability(const tGATT_ATTR& attr, case GATT_UUID_CHAR_CLIENT_CONFIG: case GATT_UUID_CHAR_SRVR_CONFIG: case GATT_UUID_CHAR_PRESENT_FORMAT: - LOG(ERROR) << __func__ << ": GATT_NOT_LONG"; + log::error("GATT_NOT_LONG"); return GATT_NOT_LONG; default: @@ -176,9 +176,8 @@ static tGATT_STATUS read_attr_value(tGATT_ATTR& attr16, uint16_t offset, tGATT_SEC_FLAG sec_flag, uint8_t key_size) { uint8_t* p = *p_data; - VLOG(1) << __func__ << " uuid=" << attr16.uuid - << StringPrintf(" perm=0x%02x offset=%d read_long=%d", - attr16.permission, offset, read_long); + log::verbose("uuid={} perm=0x{:02x} offset={} read_long={}", attr16.uuid, + attr16.permission, offset, read_long); tGATT_STATUS status = gatts_check_attr_readability(attr16, offset, read_long, sec_flag, key_size); @@ -312,7 +311,7 @@ tGATT_STATUS gatts_db_read_attr_value_by_type( p_rsp->len += (len + 2); *p_len -= (len + 2); } else { - LOG(ERROR) << "format mismatch"; + log::error("format mismatch"); status = GATT_NO_RESOURCES; break; } @@ -340,12 +339,11 @@ uint16_t gatts_add_included_service(tGATT_SVC_DB& db, uint16_t s_handle, uint16_t e_handle, const Uuid& service) { Uuid uuid = Uuid::From16Bit(GATT_UUID_INCLUDE_SERVICE); - VLOG(1) << __func__ - << StringPrintf(": s_hdl=0x%04x e_hdl=0x%04x ", s_handle, e_handle) - << "service uuid = " << service; + log::verbose("s_hdl=0x{:04x} e_hdl=0x{:04x} service uuid = {}", s_handle, + e_handle, service); if (service.IsEmpty() || s_handle == 0 || e_handle == 0) { - LOG(ERROR) << __func__ << ": Illegal Params."; + log::error("Illegal Params."); return 0; } @@ -380,8 +378,7 @@ uint16_t gatts_add_characteristic(tGATT_SVC_DB& db, tGATT_PERM perm, const Uuid& char_uuid) { Uuid uuid = Uuid::From16Bit(GATT_UUID_CHAR_DECLARE); - VLOG(1) << StringPrintf("%s: perm=0x%0x property=0x%0x", __func__, perm, - property); + log::verbose("perm=0x{:0x} property=0x{:0x}", perm, property); tGATT_ATTR& char_decl = allocate_attr_in_db(db, uuid, GATT_PERM_READ); tGATT_ATTR& char_val = allocate_attr_in_db(db, char_uuid, perm); @@ -410,8 +407,7 @@ uint16_t gatts_add_char_ext_prop_descr( tGATT_SVC_DB& db, uint16_t extended_properties) { Uuid descr_uuid = Uuid::From16Bit(GATT_UUID_CHAR_EXT_PROP); - VLOG(1) << StringPrintf("gatts_add_char_ext_prop_descr uuid=%s", - descr_uuid.ToString().c_str()); + log::verbose("gatts_add_char_ext_prop_descr uuid={}", descr_uuid.ToString()); tGATT_ATTR& char_dscptr = allocate_attr_in_db(db, descr_uuid, GATT_PERM_READ); char_dscptr.gatt_type = BTGATT_DB_DESCRIPTOR; @@ -437,8 +433,7 @@ uint16_t gatts_add_char_ext_prop_descr( ******************************************************************************/ uint16_t gatts_add_char_descr(tGATT_SVC_DB& db, tGATT_PERM perm, const Uuid& descr_uuid) { - VLOG(1) << StringPrintf("gatts_add_char_descr uuid=%s", - descr_uuid.ToString().c_str()); + log::verbose("gatts_add_char_descr uuid={}", descr_uuid.ToString()); /* Add characteristic descriptors */ tGATT_ATTR& char_dscptr = allocate_attr_in_db(db, descr_uuid, perm); @@ -551,10 +546,8 @@ tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code, uint8_t* p_data, uint16_t len, tGATT_SEC_FLAG sec_flag, uint8_t key_size) { - VLOG(1) << StringPrintf( - "%s: op_code=0x%0x handle=0x%04x offset=%d len=%d " - "key_size=%d", - __func__, op_code, handle, offset, len, key_size); + log::verbose("op_code=0x%{:x} handle=0x{:04x} offset={} len={} key_size={}", + op_code, handle, offset, len, key_size); tGATT_ATTR* p_attr = find_attr_by_handle(p_db, handle); if (!p_attr) return GATT_NOT_FOUND; @@ -564,8 +557,8 @@ tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code, if (min_key_size != 0) { min_key_size += 6; } - VLOG(1) << StringPrintf("%s: p_attr->permission =0x%04x min_key_size==0x%04x", - __func__, p_attr->permission, min_key_size); + log::verbose("p_attr->permission =0x{:04x} min_key_size==0x{:04x}", + p_attr->permission, min_key_size); if ((op_code == GATT_CMD_WRITE || op_code == GATT_REQ_WRITE) && (perm & GATT_WRITE_SIGNED_PERM)) { @@ -589,38 +582,36 @@ tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code, tGATT_STATUS status = GATT_NOT_FOUND; if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM)) { status = GATT_WRITE_NOT_PERMIT; - VLOG(1) << __func__ << ": sign cmd write not allowed"; + log::verbose("sign cmd write not allowed"); } if ((op_code == GATT_SIGN_CMD_WRITE) && sec_flag.is_encrypted) { status = GATT_INVALID_PDU; - LOG(ERROR) << __func__ - << ": Error!! sign cmd write sent on a encypted link"; + log::error("Error!! sign cmd write sent on a encypted link"); } else if (!(perm & GATT_WRITE_ALLOWED)) { status = GATT_WRITE_NOT_PERMIT; - LOG(ERROR) << __func__ << ": GATT_WRITE_NOT_PERMIT"; + log::error("GATT_WRITE_NOT_PERMIT"); } /* require authentication, but not been authenticated */ else if ((perm & GATT_WRITE_AUTH_REQUIRED) && !sec_flag.is_link_key_known) { status = GATT_INSUF_AUTHENTICATION; - LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION"; + log::error("GATT_INSUF_AUTHENTICATION"); } else if ((perm & GATT_WRITE_MITM_REQUIRED) && !sec_flag.is_link_key_authed) { status = GATT_INSUF_AUTHENTICATION; - LOG(ERROR) << __func__ << ": GATT_INSUF_AUTHENTICATION: MITM required"; + log::error("GATT_INSUF_AUTHENTICATION: MITM required"); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM) && !sec_flag.is_encrypted) { status = GATT_INSUF_ENCRYPTION; - LOG(ERROR) << __func__ << ": GATT_INSUF_ENCRYPTION"; + log::error("GATT_INSUF_ENCRYPTION"); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM) && sec_flag.is_encrypted && (key_size < min_key_size)) { status = GATT_INSUF_KEY_SIZE; - LOG(ERROR) << __func__ << ": GATT_INSUF_KEY_SIZE"; + log::error("GATT_INSUF_KEY_SIZE"); } /* LE security mode 2 attribute */ else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !sec_flag.is_encrypted && (perm & GATT_WRITE_ALLOWED) == 0) { status = GATT_INSUF_AUTHENTICATION; - LOG(ERROR) << __func__ - << ": GATT_INSUF_AUTHENTICATION: LE security mode 2 required"; + log::error("GATT_INSUF_AUTHENTICATION: LE security mode 2 required"); } else /* writable: must be char value declaration or char descritpors */ { uint16_t max_size = 0; @@ -661,11 +652,11 @@ tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code, if (op_code == GATT_REQ_PREPARE_WRITE && offset != 0) { /* does not allow write blob */ status = GATT_NOT_LONG; - LOG(ERROR) << __func__ << ": GATT_NOT_LONG"; + log::error("GATT_NOT_LONG"); } else if (len != max_size) { /* data does not match the required format */ status = GATT_INVALID_ATTR_LEN; - LOG(ERROR) << __func__ << ": GATT_INVALID_PDU"; + log::error("GATT_INVALID_PDU"); } else { return GATT_SUCCESS; } @@ -689,9 +680,8 @@ tGATT_STATUS gatts_write_attr_perm_check(tGATT_SVC_DB* p_db, uint8_t op_code, static tGATT_ATTR& allocate_attr_in_db(tGATT_SVC_DB& db, const Uuid& uuid, tGATT_PERM perm) { if (db.next_handle >= db.end_handle) { - LOG(FATAL) << __func__ - << " wrong number of handles! handle_max = " << +db.end_handle - << ", next_handle = " << +db.next_handle; + log::fatal("wrong number of handles! handle_max = {}, next_handle = {}", + db.end_handle, db.next_handle); } db.attr_list.emplace_back(); @@ -736,9 +726,9 @@ static tGATT_STATUS gatts_send_app_read_request( } else if (gatt_type == BTGATT_DB_CHARACTERISTIC) { opcode = GATTS_REQ_TYPE_READ_CHARACTERISTIC; } else { - LOG(ERROR) << __func__ - << ": Attempt to read attribute that's not tied with " - "characteristic or descriptor value."; + log::error( + "Attempt to read attribute that's not tied with characteristic or " + "descriptor value."); return GATT_ERROR; } diff --git a/system/stack/gatt/gatt_int.h b/system/stack/gatt/gatt_int.h index 1e4867ce25fb3f60711900070d6f6a30ac270b05..8a1c023a6eca358d9686a7e5de294c90b81853e7 100644 --- a/system/stack/gatt/gatt_int.h +++ b/system/stack/gatt/gatt_int.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -518,7 +519,7 @@ tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t cid, /* utility functions */ uint16_t gatt_get_local_mtu(void); -uint8_t* gatt_dbg_op_name(uint8_t op_code); +char const* gatt_dbg_op_name(uint8_t op_code); uint32_t gatt_add_sdp_record(const bluetooth::Uuid& uuid, uint16_t start_hdl, uint16_t end_hdl); bool gatt_parse_uuid_from_cmd(bluetooth::Uuid* p_uuid, uint16_t len, @@ -690,4 +691,9 @@ bluetooth::Uuid* gatts_get_service_uuid(tGATT_SVC_DB* p_db); /* gatt_sr_hash.cc */ Octet16 gatts_calculate_database_hash(std::list* lst_ptr); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/stack/gatt/gatt_main.cc b/system/stack/gatt/gatt_main.cc index 0e78432dae7cfd203c14b850ab933645932f42c2..c09cbc6d0ecaf4d080c1262071b03ed3ba51f1d1 100644 --- a/system/stack/gatt/gatt_main.cc +++ b/system/stack/gatt/gatt_main.cc @@ -22,14 +22,17 @@ * ******************************************************************************/ +#include #include +#include #include "btif/include/btif_dm.h" #include "btif/include/btif_storage.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "connection_manager.h" #include "device/include/interop.h" #include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "internal_include/stack_config.h" #include "l2c_api.h" #include "main/shim/acl_api.h" @@ -42,6 +45,7 @@ #include "stack/btm/btm_sec.h" #include "stack/eatt/eatt.h" #include "stack/gatt/gatt_int.h" +#include "stack/include/acl_api.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_psm_types.h" #include "stack/include/bt_types.h" @@ -49,8 +53,8 @@ #include "stack/include/srvc_api.h" // tDIS_VALUE #include "types/raw_address.h" -using base::StringPrintf; using bluetooth::eatt::EattExtension; +using namespace bluetooth; /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ @@ -110,7 +114,7 @@ tGATT_CB gatt_cb; void gatt_init(void) { tL2CAP_FIXED_CHNL_REG fixed_reg; - VLOG(1) << __func__; + log::verbose(""); gatt_cb = tGATT_CB(); connection_manager::reset(true); @@ -136,7 +140,7 @@ void gatt_init(void) { if (gatt_cb.over_br_enabled && !L2CA_Register2(BT_PSM_ATT, dyn_info, false /* enable_snoop */, nullptr, GATT_MAX_MTU_SIZE, 0, BTM_SEC_NONE)) { - LOG(ERROR) << "ATT Dynamic Registration failed"; + log::error("ATT Dynamic Registration failed"); } gatt_cb.hdl_cfg.gatt_start_hdl = GATT_GATT_START_HANDLE; @@ -164,7 +168,7 @@ void gatt_init(void) { ******************************************************************************/ void gatt_free(void) { int i; - VLOG(1) << __func__; + log::verbose(""); fixed_queue_free(gatt_cb.sign_op_queue, NULL); gatt_cb.sign_op_queue = NULL; @@ -251,18 +255,18 @@ bool gatt_connect(const RawAddress& rem_bda, tGATT_TCB* p_tcb, * ******************************************************************************/ bool gatt_disconnect(tGATT_TCB* p_tcb) { - VLOG(1) << __func__; + log::verbose(""); if (!p_tcb) { - LOG_WARN("Unable to disconnect an unknown device"); + log::warn("Unable to disconnect an unknown device"); return false; } tGATT_CH_STATE ch_state = gatt_get_ch_state(p_tcb); if (ch_state == GATT_CH_CLOSING) { - LOG_DEBUG("Device already in closing state peer:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda)); - VLOG(1) << __func__ << " already in closing state"; + log::debug("Device already in closing state peer:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda)); + log::verbose("already in closing state"); return true; } @@ -282,10 +286,9 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) { if (!connection_manager::direct_connect_remove(CONN_MGR_ID_L2CAP, p_tcb->peer_bda)) { BTM_AcceptlistRemove(p_tcb->peer_bda); - LOG_INFO( + log::info( "GATT connection manager has no record but removed filter " - "acceptlist " - "gatt_if:%hhu peer:%s", + "acceptlist gatt_if:{} peer:{}", static_cast(CONN_MGR_ID_L2CAP), ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda)); } @@ -298,7 +301,7 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) { if ((ch_state == GATT_CH_OPEN) || (ch_state == GATT_CH_CFG)) { gatt_l2cif_disconnect(p_tcb->att_lcid); } else { - VLOG(1) << __func__ << " gatt_disconnect channel not opened"; + log::verbose("gatt_disconnect channel not opened"); } } @@ -317,27 +320,27 @@ bool gatt_disconnect(tGATT_TCB* p_tcb) { ******************************************************************************/ bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb, bool is_add) { - LOG_DEBUG("gatt_if=%d, is_add=%d, peer_bda=%s", +gatt_if, is_add, - ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda)); + log::debug("gatt_if={}, is_add={}, peer_bda={}", gatt_if, is_add, + ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda)); auto& holders = p_tcb->app_hold_link; if (is_add) { auto ret = holders.insert(gatt_if); if (ret.second) { - LOG_DEBUG("added gatt_if=%d", +gatt_if); + log::debug("added gatt_if={}", gatt_if); } else { - LOG_DEBUG("attempt to add already existing gatt_if=%d", +gatt_if); + log::debug("attempt to add already existing gatt_if={}", gatt_if); } return true; } //! is_add if (!holders.erase(gatt_if)) { - LOG_WARN("attempt to remove non-existing gatt_if=%d", +gatt_if); + log::warn("attempt to remove non-existing gatt_if={}", gatt_if); return false; } - LOG_INFO("removed gatt_if=%d", +gatt_if); + log::info("removed gatt_if={}", gatt_if); return true; } @@ -354,23 +357,23 @@ bool gatt_update_app_hold_link_status(tGATT_IF gatt_if, tGATT_TCB* p_tcb, ******************************************************************************/ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb, bool is_add, bool check_acl_link) { - LOG_DEBUG("gatt_if=%d, is_add=%d chk_link=%d", +gatt_if, is_add, - check_acl_link); + log::debug("gatt_if={}, is_add={} chk_link={}", gatt_if, is_add, + check_acl_link); if (!p_tcb) { - LOG_WARN("p_tcb is null"); + log::warn("p_tcb is null"); return; } // If we make no modification, i.e. kill app that was never connected to a // device, skip updating the device state. if (!gatt_update_app_hold_link_status(gatt_if, p_tcb, is_add)) { - LOG_INFO("App status is not updated for gatt_if=%d", +gatt_if); + log::info("App status is not updated for gatt_if={}", gatt_if); return; } if (!check_acl_link) { - LOG_INFO("check_acl_link is false, no need to check"); + log::info("check_acl_link is false, no need to check"); return; } @@ -380,14 +383,14 @@ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb, if (is_add) { if (p_tcb->att_lcid == L2CAP_ATT_CID && is_valid_handle) { - LOG_INFO("disable link idle timer for %s", - ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda)); + log::info("disable link idle timer for {}", + ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda)); /* acl link is connected disable the idle timeout */ GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport, true /* is_active */); } else { - LOG_INFO("invalid handle %d or dynamic CID %d", is_valid_handle, - p_tcb->att_lcid); + log::info("invalid handle {} or dynamic CID {}", is_valid_handle, + p_tcb->att_lcid); } } else { if (p_tcb->app_hold_link.empty()) { @@ -398,19 +401,19 @@ void gatt_update_app_use_link_flag(tGATT_IF gatt_if, tGATT_TCB* p_tcb, /* for fixed channel, set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */ - LOG_INFO( + log::info( "GATT fixed channel is no longer useful, start link idle timer for " - "%d seconds", + "{} seconds", GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP); GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport, false /* is_active */); } else { // disconnect the dynamic channel - LOG_INFO("disconnect GATT dynamic channel"); + log::info("disconnect GATT dynamic channel"); gatt_disconnect(p_tcb); } } else { - LOG_INFO("is_add=false, but some app is still using the ACL link"); + log::info("is_add=false, but some app is still using the ACL link"); } } } @@ -429,7 +432,7 @@ bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, p_reg->gatt_if)) return false; } else if (st == GATT_CH_CLOSING) { - LOG(INFO) << "Must finish disconnection before new connection"; + log::info("Must finish disconnection before new connection"); /* need to complete the closing first */ return false; } @@ -439,13 +442,13 @@ bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport); if (!p_tcb) { - LOG(ERROR) << "Max TCB for gatt_if [ " << +p_reg->gatt_if << "] reached."; + log::error("Max TCB for gatt_if [ {}] reached.", p_reg->gatt_if); return false; } if (!gatt_connect(bd_addr, addr_type, p_tcb, transport, initiating_phys, p_reg->gatt_if)) { - LOG(ERROR) << "gatt_connect failed"; + log::error("gatt_connect failed"); fixed_queue_free(p_tcb->pending_ind_q, NULL); *p_tcb = tGATT_TCB(); return false; @@ -462,7 +465,11 @@ bool gatt_act_connect(tGATT_REG* p_reg, const RawAddress& bd_addr, namespace connection_manager { void on_connection_timed_out(uint8_t app_id, const RawAddress& address) { - gatt_le_connect_cback(L2CAP_ATT_CID, address, false, 0xff, BT_TRANSPORT_LE); + if (IS_FLAG_ENABLED(enumerate_gatt_errors)) { + gatt_le_connect_cback(L2CAP_ATT_CID, address, false, 0x08, BT_TRANSPORT_LE); + } else { + gatt_le_connect_cback(L2CAP_ATT_CID, address, false, 0xff, BT_TRANSPORT_LE); + } } } // namespace connection_manager @@ -477,13 +484,13 @@ static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr, tGATTS_SRV_CHG* p_srv_chg_clt = NULL; if (transport == BT_TRANSPORT_BR_EDR) { - LOG_WARN("Ignoring fixed channel connect/disconnect on br_edr for GATT"); + log::warn("Ignoring fixed channel connect/disconnect on br_edr for GATT"); return; } - VLOG(1) << "GATT ATT protocol channel with BDA: " - << ADDRESS_TO_LOGGABLE_STR(bd_addr) << " is " - << ((connected) ? "connected" : "disconnected"); + log::verbose("GATT ATT protocol channel with BDA: {} is {}", + ADDRESS_TO_LOGGABLE_STR(bd_addr), + ((connected) ? "connected" : "disconnected")); p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr); if (p_srv_chg_clt != NULL) { @@ -519,7 +526,14 @@ static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr, else { p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE); if (!p_tcb) { - LOG(ERROR) << "CCB max out, no rsources"; + log::error("CCB max out, no rsources"); + if (IS_FLAG_ENABLED(gatt_drop_acl_on_out_of_resources_fix)) { + log::error("Disconnecting address:{} due to out of resources.", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + // When single FIXED channel cannot be created, there is no reason to + // keep the link + btm_remove_acl(bd_addr, transport); + } return; } @@ -544,18 +558,18 @@ static void gatt_le_connect_cback(uint16_t chan, const RawAddress& bd_addr, } if (is_device_le_audio_capable(bd_addr)) { - LOG_INFO("Read model name for le audio capable device"); + log::info("Read model name for le audio capable device"); if (!check_cached_model_name(bd_addr)) { if (!DIS_ReadDISInfo(bd_addr, read_dis_cback, DIS_ATTR_MODEL_NUM_BIT)) { - LOG_WARN("Read DIS failed"); + log::warn("Read DIS failed"); } } } else if (check_cached_model_name(bd_addr)) { - LOG_INFO("Get cache model name for device"); + log::info("Get cache model name for device"); } if (stack_config_get_interface()->get_pts_connect_eatt_before_encryption()) { - LOG_INFO(" Start EATT before encryption "); + log::info("Start EATT before encryption "); EattExtension::GetInstance()->Connect(bd_addr); } } @@ -569,8 +583,8 @@ bool check_cached_model_name(const RawAddress& bd_addr) { if (btif_storage_get_remote_device_property(&bd_addr, &prop) != BT_STATUS_SUCCESS || prop.len == 0) { - LOG_INFO("Device %s no cached model name", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::info("Device {} no cached model name", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } @@ -581,7 +595,7 @@ bool check_cached_model_name(const RawAddress& bd_addr) { static void read_dis_cback(const RawAddress& bd_addr, tDIS_VALUE* p_dis_value) { if (p_dis_value == NULL) { - LOG_ERROR("received unexpected/error DIS callback"); + log::error("received unexpected/error DIS callback"); return; } @@ -593,8 +607,8 @@ static void read_dis_cback(const RawAddress& bd_addr, tDIS_VALUE* p_dis_value) { prop.val = p_dis_value->data_string[i]; prop.len = strlen((char*)prop.val); - LOG_INFO("Device %s, model name: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - ((char*)prop.val)); + log::info("Device {}, model name: {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), ((char*)prop.val)); btif_storage_set_remote_device_property(&bd_addr, &prop); GetInterfaceToProfiles()->events->invoke_remote_device_properties_cb( @@ -602,7 +616,7 @@ static void read_dis_cback(const RawAddress& bd_addr, tDIS_VALUE* p_dis_value) { } } } else { - LOG_ERROR("unknown bit, mask: %d", (int)p_dis_value->attr_mask); + log::error("unknown bit, mask: {}", (int)p_dis_value->attr_mask); } } @@ -631,7 +645,7 @@ void gatt_notify_phy_updated(tHCI_STATUS status, uint16_t handle, uint8_t tx_phy, uint8_t rx_phy) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle); if (!p_dev_rec) { - LOG_WARN("No Device Found!"); + log::warn("No Device Found!"); return; } @@ -675,7 +689,7 @@ void gatt_notify_subrate_change(uint16_t handle, uint16_t subrate_factor, uint16_t timeout, uint8_t status) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev_by_handle(handle); if (!p_dev_rec) { - LOG_WARN("No Device Found!"); + log::warn("No Device Found!"); return; } @@ -732,8 +746,8 @@ static void gatt_le_data_ind(uint16_t chan, const RawAddress& bd_addr, if (decision == bluetooth::shim::arbiter::InterceptAction::DROP) { // do nothing, just free it at the end } else if (gatt_get_ch_state(p_tcb) < GATT_CH_OPEN) { - LOG(WARNING) << "ATT - Ignored L2CAP data while in state: " - << +gatt_get_ch_state(p_tcb); + log::warn("ATT - Ignored L2CAP data while in state: {}", + gatt_get_ch_state(p_tcb)); } else gatt_data_process(*p_tcb, L2CAP_ATT_CID, p_buf); } @@ -756,7 +770,7 @@ static void gatt_l2cif_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, UNUSED_ATTR uint16_t psm, uint8_t id) { uint8_t result = L2CAP_CONN_OK; - LOG(INFO) << "Connection indication cid = " << +lcid; + log::info("Connection indication cid = {}", lcid); /* new connection ? */ tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR); @@ -803,9 +817,8 @@ static void gatt_l2cif_connect_cfm_cback(uint16_t lcid, uint16_t result) { p_tcb = gatt_find_tcb_by_cid(lcid); if (!p_tcb) return; - VLOG(1) << __func__ - << StringPrintf(" result: %d ch_state: %d, lcid:0x%x", result, - gatt_get_ch_state(p_tcb), p_tcb->att_lcid); + log::verbose("result: {} ch_state: {}, lcid:0x{:x}", result, + gatt_get_ch_state(p_tcb), p_tcb->att_lcid); if (gatt_get_ch_state(p_tcb) == GATT_CH_CONN && result == L2CAP_CONN_OK) { gatt_set_ch_state(p_tcb, GATT_CH_CFG); @@ -962,8 +975,8 @@ void gatt_consolidate(const RawAddress& identity_addr, const RawAddress& rpa) { tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(rpa, BT_TRANSPORT_LE); if (p_tcb == NULL) return; - LOG_INFO("consolidate %s -> %s", ADDRESS_TO_LOGGABLE_CSTR(rpa), - ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); + log::info("consolidate {} -> {}", ADDRESS_TO_LOGGABLE_CSTR(rpa), + ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); p_tcb->peer_bda = identity_addr; // Address changed, notify GATT clients/servers device is available under new @@ -991,7 +1004,7 @@ void gatt_data_process(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) { uint8_t op_code, pseudo_op_code; if (p_buf->len <= 0) { - LOG(ERROR) << "invalid data length, ignore"; + log::error("invalid data length, ignore"); return; } @@ -1004,8 +1017,7 @@ void gatt_data_process(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) { if (pseudo_op_code >= GATT_OP_CODE_MAX) { /* Note: PTS: GATT/SR/UNS/BI-01-C mandates error on unsupported ATT request. */ - LOG(ERROR) << __func__ - << ": ATT - Rcvd L2CAP data, unknown cmd: " << loghex(op_code); + log::error("ATT - Rcvd L2CAP data, unknown cmd: {}", loghex(op_code)); gatt_send_error_rsp(tcb, cid, GATT_REQ_NOT_SUPPORTED, op_code, 0, false); return; } @@ -1047,14 +1059,14 @@ void gatt_send_srv_chg_ind(const RawAddress& peer_bda) { static const uint16_t sGATT_LAST_HANDLE = (uint16_t)osi_property_get_int32( "bluetooth.gatt.last_handle_for_srvc_change.value", 0xFFFF); - VLOG(1) << __func__; + log::verbose(""); if (!gatt_cb.handle_of_h_r) return; uint16_t conn_id = gatt_profile_find_conn_id_by_bd_addr(peer_bda); if (conn_id == GATT_INVALID_CONN_ID) { - LOG(ERROR) << "Unable to find conn_id for " - << ADDRESS_TO_LOGGABLE_STR(peer_bda); + log::error("Unable to find conn_id for {}", + ADDRESS_TO_LOGGABLE_STR(peer_bda)); return; } @@ -1069,7 +1081,7 @@ void gatt_send_srv_chg_ind(const RawAddress& peer_bda) { /** Check sending service chnaged Indication is required or not if required then * send the Indication */ void gatt_chk_srv_chg(tGATTS_SRV_CHG* p_srv_chg_clt) { - VLOG(1) << __func__ << " srv_changed=" << +p_srv_chg_clt->srv_changed; + log::verbose("srv_changed={}", p_srv_chg_clt->srv_changed); if (p_srv_chg_clt->srv_changed) { gatt_send_srv_chg_ind(p_srv_chg_clt->bda); @@ -1082,9 +1094,9 @@ void gatt_init_srv_chg(void) { tGATTS_SRV_CHG_RSP rsp; tGATTS_SRV_CHG srv_chg_clt; - VLOG(1) << __func__; + log::verbose(""); if (!gatt_cb.cb_info.p_srv_chg_callback) { - VLOG(1) << __func__ << " callback not registered yet"; + log::verbose("callback not registered yet"); return; } @@ -1093,7 +1105,7 @@ void gatt_init_srv_chg(void) { if (!(status && rsp.num_clients)) return; - VLOG(1) << "num_srv_chg_clt_clients=" << +rsp.num_clients; + log::verbose("num_srv_chg_clt_clients={}", rsp.num_clients); uint8_t num_clients = rsp.num_clients; uint8_t i = 1; /* use one based index */ while ((i <= num_clients) && status) { @@ -1103,7 +1115,7 @@ void gatt_init_srv_chg(void) { if (status) { memcpy(&srv_chg_clt, &rsp.srv_chg, sizeof(tGATTS_SRV_CHG)); if (gatt_add_srv_chg_clt(&srv_chg_clt) == NULL) { - LOG(ERROR) << "Unable to add a service change client"; + log::error("Unable to add a service change client"); status = false; } } @@ -1117,7 +1129,7 @@ void gatt_proc_srv_chg(void) { tBT_TRANSPORT transport; uint8_t found_idx; - VLOG(1) << __func__; + log::verbose(""); if (!gatt_cb.cb_info.p_srv_chg_callback || !gatt_cb.handle_of_h_r) return; @@ -1130,7 +1142,7 @@ void gatt_proc_srv_chg(void) { if (gatt_is_srv_chg_ind_pending(p_tcb)) { send_indication = false; - VLOG(1) << "discard srv chg - already has one in the queue"; + log::verbose("discard srv chg - already has one in the queue"); } // Some LE GATT clients don't respond to service changed indications. @@ -1139,7 +1151,7 @@ void gatt_proc_srv_chg(void) { btif_storage_get_stored_remote_name(bda, remote_name)) { if (interop_match_name(INTEROP_GATTC_NO_SERVICE_CHANGED_IND, remote_name)) { - VLOG(1) << "discard srv chg - interop matched " << remote_name; + log::verbose("discard srv chg - interop matched {}", remote_name); send_indication = false; } } @@ -1154,8 +1166,8 @@ void gatt_proc_srv_chg(void) { void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) { if (!p_tcb) return; - VLOG(1) << __func__ << ": old=" << +p_tcb->ch_state - << " new=" << loghex(static_cast(ch_state)); + log::verbose("old={} new={}", p_tcb->ch_state, + loghex(static_cast(ch_state))); p_tcb->ch_state = ch_state; } @@ -1163,6 +1175,6 @@ void gatt_set_ch_state(tGATT_TCB* p_tcb, tGATT_CH_STATE ch_state) { tGATT_CH_STATE gatt_get_ch_state(tGATT_TCB* p_tcb) { if (!p_tcb) return GATT_CH_CLOSE; - VLOG(1) << "gatt_get_ch_state: ch_state=" << +p_tcb->ch_state; + log::verbose("gatt_get_ch_state: ch_state={}", p_tcb->ch_state); return p_tcb->ch_state; } diff --git a/system/stack/gatt/gatt_sr.cc b/system/stack/gatt/gatt_sr.cc index 3f55c6a84ff25256284aa64cd9472324958ee2ac..e7809a1490bc68a8eeedee37fbbfaf503703c4df 100644 --- a/system/stack/gatt/gatt_sr.cc +++ b/system/stack/gatt/gatt_sr.cc @@ -22,6 +22,7 @@ * ******************************************************************************/ #include +#include #include #include @@ -29,24 +30,24 @@ #include "gatt_int.h" #include "hardware/bt_gatt_types.h" #include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "l2c_api.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "osi/include/osi.h" #include "stack/arbiter/acl_arbiter.h" #include "stack/eatt/eatt.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" -#include "stack/l2cap/l2c_int.h" #include "types/bluetooth/uuid.h" #define GATT_MTU_REQ_MIN_LEN 2 #define L2CAP_PKT_OVERHEAD 4 -using base::StringPrintf; using bluetooth::Uuid; using bluetooth::eatt::EattExtension; using bluetooth::eatt::EattChannel; +using namespace bluetooth; /******************************************************************************* * @@ -68,8 +69,8 @@ uint32_t gatt_sr_enqueue_cmd(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return 0; } @@ -114,8 +115,8 @@ bool gatt_sr_cmd_empty(tGATT_TCB& tcb, uint16_t cid) { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return false; } @@ -140,8 +141,8 @@ void gatt_dequeue_sr_cmd(tGATT_TCB& tcb, uint16_t cid) { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return; } @@ -149,10 +150,9 @@ void gatt_dequeue_sr_cmd(tGATT_TCB& tcb, uint16_t cid) { } /* Double check in case any buffers are queued */ - VLOG(1) << "gatt_dequeue_sr_cmd cid: " << loghex(cid); + log::verbose("gatt_dequeue_sr_cmd cid: {}", loghex(cid)); if (p_cmd->p_rsp_msg) - LOG(ERROR) << "free tcb.sr_cmd.p_rsp_msg = " - << p_cmd->p_rsp_msg; + log::error("free tcb.sr_cmd.p_rsp_msg = {}", fmt::ptr(p_cmd->p_rsp_msg)); osi_free_and_reset((void**)&p_cmd->p_rsp_msg); while (!fixed_queue_is_empty(p_cmd->multi_rsp_q)) @@ -204,22 +204,21 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { } if (total_len > mtu) { - VLOG(1) << "Buffer space not enough for this data item, skipping"; + log::verbose("Buffer space not enough for this data item, skipping"); break; } len = std::min((size_t) p_rsp->attr_value.len, mtu - total_len); if (len == 0) { - VLOG(1) << "Buffer space not enough for this data item, skipping"; + log::verbose("Buffer space not enough for this data item, skipping"); break; } if (len < p_rsp->attr_value.len) { is_overflow = true; - VLOG(1) << StringPrintf( - "multi read overflow available len=%zu val_len=%d", len, - p_rsp->attr_value.len); + log::verbose("multi read overflow available len={} val_len={}", len, + p_rsp->attr_value.len); } if (p_cmd->multi_req.variable_len) { @@ -246,10 +245,10 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { /* Sanity check on the buffer length */ if (p_buf->len == 0) { - LOG(ERROR) << __func__ << " nothing found!!"; + log::error("nothing found!!"); p_cmd->status = GATT_NOT_FOUND; osi_free(p_buf); - VLOG(1) << __func__ << "osi_free(p_buf)"; + log::verbose("osi_free(p_buf)"); } else if (p_cmd->p_rsp_msg != NULL) { osi_free(p_buf); } else { @@ -268,7 +267,7 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { ******************************************************************************/ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, tGATTS_RSP* p_msg, uint16_t mtu) { - VLOG(1) << StringPrintf("%s status=%d mtu=%d", __func__, status, mtu); + log::verbose("status={} mtu={}", status, mtu); if (p_cmd->multi_rsp_q == NULL) p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX); @@ -280,9 +279,9 @@ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, p_cmd->status = status; if (status == GATT_SUCCESS) { - VLOG(1) << "Multi read count=" << fixed_queue_length(p_cmd->multi_rsp_q) - << " num_hdls=" << p_cmd->multi_req.num_handles - << " variable=" << p_cmd->multi_req.variable_len; + log::verbose("Multi read count={} num_hdls={} variable={}", + fixed_queue_length(p_cmd->multi_rsp_q), + p_cmd->multi_req.num_handles, p_cmd->multi_req.variable_len); /* Wait till we get all the responses */ if (fixed_queue_length(p_cmd->multi_rsp_q) == p_cmd->multi_req.num_handles) { @@ -316,7 +315,7 @@ tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if, tGATT_STATUS ret_code = GATT_SUCCESS; uint16_t payload_size = gatt_tcb_get_payload_size(tcb, sr_res_p->cid); - VLOG(1) << __func__ << " gatt_if=" << +gatt_if; + log::verbose("gatt_if={}", gatt_if); gatt_sr_update_cback_cnt(tcb, sr_res_p->cid, gatt_if, false, false); @@ -339,7 +338,7 @@ tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if, sr_res_p->p_rsp_msg = attp_build_sr_msg( tcb, (uint8_t)(op_code + 1), (tGATT_SR_MSG*)p_msg, payload_size); } else { - LOG(ERROR) << "Exception!!! already has respond message"; + log::error("Exception!!! already has respond message"); } } } @@ -355,7 +354,7 @@ tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if, gatt_dequeue_sr_cmd(tcb, sr_res_p->cid); } - VLOG(1) << __func__ << " ret_code=" << +ret_code; + log::verbose("ret_code={}", ret_code); return ret_code; } @@ -379,9 +378,9 @@ void gatt_process_exec_write_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, #if (GATT_CONFORMANCE_TESTING == TRUE) if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) { - VLOG(1) - << "Conformance tst: forced err rspv for Execute Write: error status=" - << +gatt_cb.err_status; + log::verbose( + "Conformance tst: forced err rspv for Execute Write: error status={}", + gatt_cb.err_status); gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code, gatt_cb.handle, false); @@ -391,7 +390,7 @@ void gatt_process_exec_write_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, #endif if (len < sizeof(flag)) { - LOG(ERROR) << __func__ << "invalid length"; + log::error("invalid length"); gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, GATT_REQ_EXEC_WRITE, 0, false); return; @@ -420,7 +419,7 @@ void gatt_process_exec_write_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, } } else /* nothing needs to be executed , send response now */ { - LOG(ERROR) << "gatt_process_exec_write_req: no prepare write pending"; + log::error("gatt_process_exec_write_req: no prepare write pending"); gatt_send_error_rsp(tcb, cid, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, false); } } @@ -444,12 +443,12 @@ void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, tGATT_SEC_FLAG sec_flag; uint8_t key_size; - VLOG(1) << __func__; + log::verbose(""); tGATT_READ_MULTI* multi_req = gatt_sr_get_read_multi(tcb, cid); if (multi_req == nullptr) { - LOG_ERROR("Could not proceed request. %s, 0x%02x", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::error("Could not proceed request. {}, 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return; } multi_req->num_handles = 0; @@ -458,8 +457,9 @@ void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, #if (GATT_CONFORMANCE_TESTING == TRUE) if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) { - VLOG(1) << "Conformance tst: forced err rspvofr ReadMultiple: error status=" - << +gatt_cb.err_status; + log::verbose( + "Conformance tst: forced err rspvofr ReadMultiple: error status={}", + gatt_cb.err_status); STREAM_TO_UINT16(handle, p); @@ -481,7 +481,7 @@ void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, err = gatts_read_attr_perm_check(it->p_db, false, handle, sec_flag, key_size); if (err != GATT_SUCCESS) { - VLOG(1) << StringPrintf("read permission denied : 0x%02x", err); + log::verbose("read permission denied : 0x{:02x}", err); break; } } else { @@ -493,7 +493,7 @@ void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, } if (ll != 0) { - LOG(ERROR) << "max attribute handle reached in ReadMultiple Request."; + log::error("max attribute handle reached in ReadMultiple Request."); } if (multi_req->num_handles == 0) err = GATT_INVALID_HANDLE; @@ -503,8 +503,8 @@ void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, if (trans_id != 0) { tGATT_SR_CMD* sr_cmd_p = gatt_sr_get_cmd_by_cid(tcb, cid); if (sr_cmd_p == nullptr) { - LOG_ERROR( - "Could not send response on CID were request arrived. %s, 0x%02x", + log::error( + "Could not send response on CID were request arrived. {}, 0x{:02x}", ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return; } @@ -595,7 +595,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp( if (gatt_cb.last_service_handle && gatt_cb.last_service_handle == el.s_hdl) { - VLOG(1) << "Use 0xFFFF for the last primary attribute"; + log::verbose("Use 0xFFFF for the last primary attribute"); /* see GATT ERRATA 4065, 4063, ATT ERRATA 4062 */ UINT16_TO_STREAM(p, 0xFFFF); } else { @@ -655,7 +655,7 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SRV_LIST_ELEM& el, UINT16_TO_STREAM(p, attr.handle); ARRAY_TO_STREAM(p, attr.uuid.To128BitLE(), (int)Uuid::kNumBytes128); } else { - LOG(ERROR) << "format mismatch"; + log::error("format mismatch"); return GATT_NO_RESOURCES; /* format mismatch */ } @@ -697,7 +697,7 @@ static tGATT_STATUS gatts_validate_packet_format(uint8_t op_code, uint16_t& len, CHECK(p_uuid); uint16_t uuid_len = (op_code == GATT_REQ_FIND_TYPE_VALUE) ? 2 : len; if (!gatt_parse_uuid_from_cmd(p_uuid, uuid_len, &p)) { - VLOG(1) << "Bad UUID"; + log::verbose("Bad UUID"); return GATT_INVALID_PDU; } @@ -733,15 +733,13 @@ void gatts_process_primary_service_req(tGATT_TCB& tcb, uint16_t cid, if (op_code == GATT_REQ_READ_BY_GRP_TYPE) { gatt_send_error_rsp(tcb, cid, GATT_UNSUPPORT_GRP_TYPE, op_code, s_hdl, false); - VLOG(1) << StringPrintf("unexpected ReadByGrpType Group: %s", - uuid.ToString().c_str()); + log::verbose("unexpected ReadByGrpType Group: {}", uuid.ToString()); return; } // we do not support ReadByTypeValue with any non-primamry_service type gatt_send_error_rsp(tcb, cid, GATT_NOT_FOUND, op_code, s_hdl, false); - VLOG(1) << StringPrintf("unexpected ReadByTypeValue type: %s", - uuid.ToString().c_str()); + log::verbose("unexpected ReadByTypeValue type: {}", uuid.ToString()); return; } @@ -843,7 +841,7 @@ static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t cid, uint16_t len, } if (len < GATT_MTU_REQ_MIN_LEN) { - LOG(ERROR) << "invalid MTU request PDU received."; + log::error("invalid MTU request PDU received."); gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, GATT_REQ_MTU, 0, false); return; } @@ -863,8 +861,8 @@ static void gatts_process_mtu_req(tGATT_TCB& tcb, uint16_t cid, uint16_t len, /* Always say to remote our default MTU. */ gatt_sr_msg.mtu = gatt_get_local_mtu(); - LOG_INFO("MTU %d request from remote (%s), resulted MTU %d", mtu, - tcb.peer_bda.ToString().c_str(), tcb.payload_size); + log::info("MTU {} request from remote ({}), resulted MTU {}", mtu, + tcb.peer_bda.ToString(), tcb.payload_size); BTM_SetBleDataLength(tcb.peer_bda, tcb.payload_size + L2CAP_PKT_OVERHEAD); @@ -913,8 +911,9 @@ static void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint16_t cid, #if (GATT_CONFORMANCE_TESTING == TRUE) if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) { - VLOG(1) << "Conformance tst: forced err rsp for ReadByType: error status=" - << +gatt_cb.err_status; + log::verbose( + "Conformance tst: forced err rsp for ReadByType: error status={}", + gatt_cb.err_status); gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, gatt_cb.req_op_code, s_hdl, false); @@ -997,9 +996,9 @@ static void gatts_process_write_req(tGATT_TCB& tcb, uint16_t cid, switch (op_code) { case GATT_REQ_PREPARE_WRITE: if (len < 2 || p == nullptr) { - LOG(ERROR) << __func__ - << ": Prepare write request was invalid - missing offset, " - "sending error response"; + log::error( + "Prepare write request was invalid - missing offset, sending error " + "response"); gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, handle, false); return; } @@ -1009,7 +1008,7 @@ static void gatts_process_write_req(tGATT_TCB& tcb, uint16_t cid, FALLTHROUGH_INTENDED; /* FALLTHROUGH */ case GATT_SIGN_CMD_WRITE: if (op_code == GATT_SIGN_CMD_WRITE) { - VLOG(1) << "Write CMD with data sigining"; + log::verbose("Write CMD with data sigining"); len -= GATT_AUTH_SIGN_LEN; } FALLTHROUGH_INTENDED; /* FALLTHROUGH */ @@ -1043,9 +1042,9 @@ static void gatts_process_write_req(tGATT_TCB& tcb, uint16_t cid, } else if (gatt_type == BTGATT_DB_CHARACTERISTIC) { opcode = GATTS_REQ_TYPE_WRITE_CHARACTERISTIC; } else { - LOG(ERROR) << __func__ - << "%s: Attempt to write attribute that's not tied with" - " characteristic or descriptor value."; + log::error( + "Attempt to write attribute that's not tied with " + "characteristic or descriptor value."); status = GATT_ERROR; } @@ -1054,7 +1053,7 @@ static void gatts_process_write_req(tGATT_TCB& tcb, uint16_t cid, status = GATT_PENDING; } } else { - LOG(ERROR) << "max pending command, send error"; + log::error("max pending command, send error"); status = GATT_BUSY; /* max pending command, application error */ } } @@ -1082,8 +1081,7 @@ static void gatts_process_read_req(tGATT_TCB& tcb, uint16_t cid, if (op_code == GATT_REQ_READ_BLOB && len < sizeof(uint16_t)) { /* Error: packet length is too short */ - LOG(ERROR) << __func__ << ": packet length=" << len - << " too short. min=" << sizeof(uint16_t); + log::error("packet length={} too short. min={}", len, sizeof(uint16_t)); gatt_send_error_rsp(tcb, cid, GATT_INVALID_PDU, op_code, 0, false); return; } @@ -1138,7 +1136,7 @@ void gatts_process_attribute_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, tGATT_STATUS status = GATT_INVALID_HANDLE; if (len < 2) { - LOG(ERROR) << "Illegal PDU length, discard request"; + log::error("Illegal PDU length, discard request"); status = GATT_INVALID_PDU; } else { STREAM_TO_UINT16(handle, p); @@ -1148,8 +1146,8 @@ void gatts_process_attribute_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, #if (GATT_CONFORMANCE_TESTING == TRUE) gatt_cb.handle = handle; if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code) { - VLOG(1) << "Conformance tst: forced err rsp: error status=" - << +gatt_cb.err_status; + log::verbose("Conformance tst: forced err rsp: error status={}", + gatt_cb.err_status); gatt_send_error_rsp(tcb, cid, gatt_cb.err_status, cid, gatt_cb.req_op_code, handle, false); @@ -1206,11 +1204,11 @@ void gatts_proc_srv_chg_ind_ack(tGATT_TCB tcb) { tGATTS_SRV_CHG_REQ req; tGATTS_SRV_CHG* p_buf = NULL; - VLOG(1) << __func__; + log::verbose(""); p_buf = gatt_is_bda_in_the_srv_chg_clt_list(tcb.peer_bda); if (p_buf != NULL) { - VLOG(1) << "NV update set srv chg = false"; + log::verbose("NV update set srv chg = false"); p_buf->srv_changed = false; memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG)); if (gatt_cb.cb_info.p_srv_chg_callback) @@ -1230,7 +1228,7 @@ void gatts_proc_srv_chg_ind_ack(tGATT_TCB tcb) { * ******************************************************************************/ static void gatts_chk_pending_ind(tGATT_TCB& tcb) { - VLOG(1) << __func__; + log::verbose(""); tGATT_VALUE* p_buf = (tGATT_VALUE*)fixed_queue_try_peek_first(tcb.pending_ind_q); @@ -1254,7 +1252,7 @@ static void gatts_chk_pending_ind(tGATT_TCB& tcb) { static bool gatts_proc_ind_ack(tGATT_TCB& tcb, uint16_t ack_handle) { bool continue_processing = true; - VLOG(1) << __func__ << " ack handle=%d" << ack_handle; + log::verbose("ack handle={}", ack_handle); if (ack_handle == gatt_cb.handle_of_h_r) { gatts_proc_srv_chg_ind_ack(tcb); @@ -1284,7 +1282,7 @@ void gatts_process_value_conf(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code) { uint16_t handle; if (!gatt_tcb_find_indicate_handle(tcb, cid, &handle)) { - LOG(ERROR) << "unexpected handle value confirmation"; + log::error("unexpected handle value confirmation"); return; } @@ -1371,10 +1369,9 @@ static bool gatts_process_db_out_of_sync(tGATT_TCB& tcb, uint16_t cid, gatt_send_error_rsp(tcb, cid, GATT_DATABASE_OUT_OF_SYNC, op_code, 0x0000, false); } - LOG(INFO) << __func__ << ": database out of sync, device=" - << ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda) - << ", op_code=" << loghex((uint16_t)op_code) - << ", should_rsp=" << should_rsp; + log::info("database out of sync, device={}, op_code={}, should_rsp={}", + ADDRESS_TO_LOGGABLE_STR(tcb.peer_bda), loghex((uint16_t)op_code), + should_rsp); gatt_sr_update_cl_status(tcb, /* chg_aware= */ should_rsp); } @@ -1394,8 +1391,8 @@ void gatt_server_handle_client_req(tGATT_TCB& tcb, uint16_t cid, uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid); if (len >= payload_size) { - LOG(ERROR) << StringPrintf("server receive invalid PDU size:%d pdu size:%d", - len + 1, payload_size); + log::error("server receive invalid PDU size:{} pdu size:{}", len + 1, + payload_size); /* for invalid request expecting response, send it now */ if (op_code != GATT_CMD_WRITE && op_code != GATT_SIGN_CMD_WRITE && op_code != GATT_HANDLE_VALUE_CONF) { diff --git a/system/stack/gatt/gatt_sr_hash.cc b/system/stack/gatt/gatt_sr_hash.cc index 660ffe1172b92579379ec2765b46646b1fae9026..1400379460353fbac9142a696692a3618f4d84be 100644 --- a/system/stack/gatt/gatt_sr_hash.cc +++ b/system/stack/gatt/gatt_sr_hash.cc @@ -18,6 +18,7 @@ #include #include +#include #include @@ -27,6 +28,7 @@ #include "types/bluetooth/uuid.h" using bluetooth::Uuid; +using namespace bluetooth; static size_t calculate_database_info_size(std::list* lst_ptr) { size_t len = 0; @@ -125,8 +127,7 @@ Octet16 gatts_calculate_database_hash(std::list* lst_ptr) { std::reverse(serialized.begin(), serialized.end()); Octet16 db_hash = crypto_toolbox::aes_cmac(Octet16{0}, serialized.data(), serialized.size()); - LOG(INFO) << __func__ << ": hash=" - << base::HexEncode(db_hash.data(), db_hash.size()); + log::info("hash={}", base::HexEncode(db_hash.data(), db_hash.size())); return db_hash; } diff --git a/system/stack/gatt/gatt_utils.cc b/system/stack/gatt/gatt_utils.cc index 0e8bf7e6aeb3492c776794924061c16360df389f..b48593da7f7a70f54d551035867cbd1837a37e4b 100644 --- a/system/stack/gatt/gatt_utils.cc +++ b/system/stack/gatt/gatt_utils.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -50,8 +51,8 @@ uint8_t btm_ble_read_sec_key_size(const RawAddress& bd_addr); using namespace bluetooth::legacy::stack::sdp; +using namespace bluetooth; -using base::StringPrintf; using bluetooth::Uuid; using bluetooth::eatt::EattExtension; using bluetooth::eatt::EattChannel; @@ -114,7 +115,7 @@ uint16_t gatt_get_local_mtu(void) { * ******************************************************************************/ void gatt_free_pending_ind(tGATT_TCB* p_tcb) { - VLOG(1) << __func__; + log::verbose(""); if (p_tcb->pending_ind_q == NULL) return; @@ -135,7 +136,7 @@ void gatt_free_pending_ind(tGATT_TCB* p_tcb) { * ******************************************************************************/ void gatt_delete_dev_from_srv_chg_clt_list(const RawAddress& bd_addr) { - VLOG(1) << __func__; + log::verbose(""); tGATTS_SRV_CHG* p_buf = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr); if (p_buf != NULL) { @@ -160,18 +161,18 @@ void gatt_delete_dev_from_srv_chg_clt_list(const RawAddress& bd_addr) { * ******************************************************************************/ void gatt_set_srv_chg(void) { - VLOG(1) << __func__; + log::verbose(""); if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return; list_t* list = fixed_queue_get_list(gatt_cb.srv_chg_clt_q); for (const list_node_t* node = list_begin(list); node != list_end(list); node = list_next(node)) { - VLOG(1) << "found a srv_chg clt"; + log::verbose("found a srv_chg clt"); tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node); if (!p_buf->srv_changed) { - VLOG(1) << "set srv_changed to true"; + log::verbose("set srv_changed to true"); p_buf->srv_changed = true; tGATTS_SRV_CHG_REQ req; memcpy(&req.srv_chg, p_buf, sizeof(tGATTS_SRV_CHG)); @@ -184,7 +185,7 @@ void gatt_set_srv_chg(void) { /** Add a pending indication */ void gatt_add_pending_ind(tGATT_TCB* p_tcb, tGATT_VALUE* p_ind) { - VLOG(1) << __func__ << "enqueue a pending indication"; + log::verbose("enqueue a pending indication"); tGATT_VALUE* p_buf = (tGATT_VALUE*)osi_malloc(sizeof(tGATT_VALUE)); memcpy(p_buf, p_ind, sizeof(tGATT_VALUE)); @@ -203,7 +204,7 @@ void gatt_add_pending_ind(tGATT_TCB* p_tcb, tGATT_VALUE* p_ind) { ******************************************************************************/ tGATTS_SRV_CHG* gatt_add_srv_chg_clt(tGATTS_SRV_CHG* p_srv_chg) { tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)osi_malloc(sizeof(tGATTS_SRV_CHG)); - VLOG(1) << __func__ << "enqueue a srv chg client"; + log::verbose("enqueue a srv chg client"); memcpy(p_buf, p_srv_chg, sizeof(tGATTS_SRV_CHG)); fixed_queue_enqueue(gatt_cb.srv_chg_clt_q, p_buf); @@ -276,7 +277,7 @@ bool gatt_find_the_connected_bda(uint8_t start_idx, RawAddress& bda, tBT_TRANSPORT* p_transport) { uint8_t i; bool found = false; - LOG_DEBUG("start_idx=%d", +start_idx); + log::debug("start_idx={}", start_idx); for (i = start_idx; i < GATT_MAX_PHY_CHANNEL; i++) { if (gatt_cb.tcb[i].in_use && gatt_cb.tcb[i].ch_state == GATT_CH_OPEN) { @@ -284,11 +285,11 @@ bool gatt_find_the_connected_bda(uint8_t start_idx, RawAddress& bda, *p_found_idx = i; *p_transport = gatt_cb.tcb[i].transport; found = true; - LOG_DEBUG("bda: %s", ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::debug("bda: {}", ADDRESS_TO_LOGGABLE_CSTR(bda)); break; } } - LOG_DEBUG("found=%d found_idx=%d", found, +i); + log::debug("found={} found_idx={}", found, i); return found; } @@ -303,8 +304,7 @@ bool gatt_find_the_connected_bda(uint8_t start_idx, RawAddress& bda, * ******************************************************************************/ bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb) { - VLOG(1) << __func__ - << " is_queue_empty=" << fixed_queue_is_empty(p_tcb->pending_ind_q); + log::verbose("is_queue_empty={}", fixed_queue_is_empty(p_tcb->pending_ind_q)); if (p_tcb->indicate_handle == gatt_cb.handle_of_h_r) return true; @@ -337,8 +337,7 @@ bool gatt_is_srv_chg_ind_pending(tGATT_TCB* p_tcb) { * ******************************************************************************/ tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(const RawAddress& bda) { - - VLOG(1) << __func__ << ": " << bda; + log::verbose("{}", ADDRESS_TO_LOGGABLE_STR(bda)); if (fixed_queue_is_empty(gatt_cb.srv_chg_clt_q)) return NULL; @@ -347,7 +346,7 @@ tGATTS_SRV_CHG* gatt_is_bda_in_the_srv_chg_clt_list(const RawAddress& bda) { node = list_next(node)) { tGATTS_SRV_CHG* p_buf = (tGATTS_SRV_CHG*)list_node(node); if (bda == p_buf->bda) { - VLOG(1) << "bda is in the srv chg clt list"; + log::verbose("bda is in the srv chg clt list"); return p_buf; } } @@ -437,6 +436,36 @@ tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda, return p_tcb; } +/******************************************************************************* + * + * Function gatt_tcb_dump + * + * Description Print gatt_cb.tcb[] into dumpsys + * + * Returns void + * + ******************************************************************************/ +void gatt_tcb_dump(int fd) { + std::stringstream stream; + int in_use_cnt = 0; + + for (int i = 0; i < GATT_MAX_PHY_CHANNEL; i++) { + tGATT_TCB* p_tcb = &gatt_cb.tcb[i]; + + if (p_tcb->in_use) { + in_use_cnt++; + stream << " id: " << +p_tcb->tcb_idx + << " address: " << ADDRESS_TO_LOGGABLE_STR(p_tcb->peer_bda) + << " transport: " << bt_transport_text(p_tcb->transport) + << " ch_state: " << gatt_channel_state_text(p_tcb->ch_state); + stream << "\n"; + } + } + + dprintf(fd, "TCB (GATT_MAX_PHY_CHANNEL: %d) in_use: %d\n%s\n", + GATT_MAX_PHY_CHANNEL, in_use_cnt, stream.str().c_str()); +} + /******************************************************************************* * * Function gatt_allocate_tcb_by_bdaddr @@ -496,9 +525,9 @@ void gatt_set_conn_id_waiting_for_mtu_exchange(tGATT_TCB* p_tcb, p_tcb->conn_ids_waiting_for_mtu_exchange.end(), conn_id); if (it == p_tcb->conn_ids_waiting_for_mtu_exchange.end()) { p_tcb->conn_ids_waiting_for_mtu_exchange.push_back(conn_id); - LOG_INFO("Put conn_id=0x%04x on wait list", conn_id); + log::info("Put conn_id=0x{:04x} on wait list", conn_id); } else { - LOG_INFO("Conn_id=0x%04x already on wait list", conn_id); + log::info("Conn_id=0x{:04x} already on wait list", conn_id); } } @@ -555,12 +584,12 @@ bool gatt_parse_uuid_from_cmd(Uuid* p_uuid_rec, uint16_t uuid_size, /* do not allow 32 bits UUID in ATT PDU now */ case Uuid::kNumBytes32: - LOG(ERROR) << "DO NOT ALLOW 32 BITS UUID IN ATT PDU"; + log::error("DO NOT ALLOW 32 BITS UUID IN ATT PDU"); return false; case 0: default: if (uuid_size != 0) ret = false; - LOG(WARNING) << __func__ << ": invalid uuid size"; + log::warn("invalid uuid size"); break; } @@ -690,16 +719,16 @@ void gatt_rsp_timeout(void* data) { tGATT_CLCB* p_clcb = (tGATT_CLCB*)data; if (p_clcb == NULL || p_clcb->p_tcb == NULL) { - LOG(WARNING) << __func__ << " clcb is already deleted"; + log::warn("clcb is already deleted"); return; } if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->op_subtype == GATT_DISC_SRVC_ALL && p_clcb->retry_count < GATT_REQ_RETRY_LIMIT) { uint8_t rsp_code; - LOG(WARNING) << __func__ << " retry discovery primary service"; + log::warn("retry discovery primary service"); if (p_clcb != gatt_cmd_dequeue(*p_clcb->p_tcb, p_clcb->cid, &rsp_code)) { - LOG(ERROR) << __func__ << " command queue out of sync, disconnect"; + log::error("command queue out of sync, disconnect"); } else { p_clcb->retry_count++; gatt_act_discovery(p_clcb); @@ -710,11 +739,11 @@ void gatt_rsp_timeout(void* data) { auto eatt_channel = EattExtension::GetInstance()->FindEattChannelByCid( p_clcb->p_tcb->peer_bda, p_clcb->cid); if (eatt_channel) { - LOG_WARN("disconnecting EATT cid: %d", p_clcb->cid); + log::warn("disconnecting EATT cid: {}", p_clcb->cid); EattExtension::GetInstance()->Disconnect(p_clcb->p_tcb->peer_bda, p_clcb->cid); } else { - LOG_WARN("disconnecting GATT..."); + log::warn("disconnecting GATT..."); gatt_disconnect(p_clcb->p_tcb); } } @@ -747,13 +776,14 @@ void gatt_indication_confirmation_timeout(void* data) { * TODO: In future, we should properly expose CCC, and send indication only * to devices that register for it. */ - LOG(WARNING) << " Service Changed notification timed out in 30 " - "seconds, assuming server-only remote, not disconnecting"; + log::warn( + "Service Changed notification timed out in 30 seconds, assuming " + "server-only remote, not disconnecting"); gatts_proc_srv_chg_ind_ack(*p_tcb); return; } - LOG(WARNING) << __func__ << " disconnecting..."; + log::warn("disconnecting..."); gatt_disconnect(p_tcb); } @@ -770,7 +800,7 @@ void gatt_ind_ack_timeout(void* data) { tGATT_TCB* p_tcb = (tGATT_TCB*)data; CHECK(p_tcb); - LOG(WARNING) << __func__ << ": send ack now"; + log::warn("send ack now"); p_tcb->ind_count = 0; /*TODO: For now ATT used only, but we need to have timeout per CID * and use it here corretly. @@ -836,14 +866,14 @@ void gatt_sr_send_req_callback(uint16_t conn_id, uint32_t trans_id, tGATT_REG* p_reg = gatt_get_regcb(gatt_if); if (!p_reg) { - LOG(ERROR) << "p_reg not found discard request"; + log::error("p_reg not found discard request"); return; } if (p_reg->in_use && p_reg->app_cb.p_req_cb) { (*p_reg->app_cb.p_req_cb)(conn_id, trans_id, type, p_data); } else { - LOG(WARNING) << "Call back not found for application conn_id=" << conn_id; + log::warn("Call back not found for application conn_id={}", conn_id); } } @@ -893,8 +923,7 @@ uint32_t gatt_add_sdp_record(const Uuid& uuid, uint16_t start_hdl, uint8_t buff[60]; uint8_t* p = buff; - VLOG(1) << __func__ - << StringPrintf(" s_hdl=0x%x s_hdl=0x%x", start_hdl, end_hdl); + log::verbose("s_hdl=0x{:x} s_hdl=0x{:x}", start_hdl, end_hdl); uint32_t sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) return 0; @@ -958,9 +987,8 @@ uint32_t gatt_add_sdp_record(const Uuid& uuid, uint16_t start_hdl, * ******************************************************************************/ void gatt_set_err_rsp(bool enable, uint8_t req_op_code, uint8_t err_status) { - VLOG(1) << __func__ - << StringPrintf(" enable=%d op_code=%d, err_status=%d", enable, - req_op_code, err_status); + log::verbose("enable={} op_code={}, err_status={}", enable, req_op_code, + err_status); gatt_cb.enable_err_rsp = enable; gatt_cb.req_op_code = req_op_code; gatt_cb.err_status = err_status; @@ -981,7 +1009,7 @@ tGATT_REG* gatt_get_regcb(tGATT_IF gatt_if) { tGATT_REG* p_reg = NULL; if (ii < 1 || ii > GATT_MAX_APPS) { - LOG(WARNING) << "gatt_if out of range = " << +ii; + log::warn("gatt_if out of range = {}", ii); return NULL; } @@ -989,7 +1017,7 @@ tGATT_REG* gatt_get_regcb(tGATT_IF gatt_if) { p_reg = &gatt_cb.cl_rcb[ii - 1]; if (!p_reg->in_use) { - LOG(WARNING) << "gatt_if found but not in use."; + log::warn("gatt_if found but not in use."); return NULL; } @@ -1012,8 +1040,8 @@ bool gatt_tcb_is_cid_busy(tGATT_TCB& tcb, uint16_t cid) { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return false; } @@ -1051,8 +1079,8 @@ tGATT_CLCB* gatt_clcb_alloc(uint16_t conn_id) { * bigger than that and also if it is bigger, we believe it should not * cause the problem. This WARN is just to monitor number of CLCB and will * help in debugging in case we are wrong */ - LOG_WARN("Number of CLCB: %zu > %d", gatt_cb.clcb_queue.size(), - GATT_CL_MAX_LCB); + log::warn("Number of CLCB: {} > {}", gatt_cb.clcb_queue.size(), + GATT_CL_MAX_LCB); } return p_clcb; } @@ -1156,8 +1184,8 @@ uint16_t gatt_tcb_get_payload_size(tGATT_TCB& tcb, uint16_t cid) { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return 0; } @@ -1205,8 +1233,9 @@ void gatt_clcb_invalidate(tGATT_TCB* p_tcb, const tGATT_CLCB* p_clcb) { if (!p_tcb->pending_enc_clcb.empty()) { for (size_t i = 0; i < p_tcb->pending_enc_clcb.size(); i++) { if (p_tcb->pending_enc_clcb.at(i) == p_clcb) { - LOG_WARN("Removing clcb (%p) for conn id=0x%04x from pending_enc_clcb", - p_clcb, p_clcb->conn_id); + log::warn( + "Removing clcb ({}) for conn id=0x{:04x} from pending_enc_clcb", + fmt::ptr(p_clcb), p_clcb->conn_id); p_tcb->pending_enc_clcb.at(i) = NULL; break; } @@ -1219,8 +1248,8 @@ void gatt_clcb_invalidate(tGATT_TCB* p_tcb, const tGATT_CLCB* p_clcb) { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid( p_tcb->peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(p_tcb->peer_bda), cid); return; } cl_cmd_q_p = &channel->cl_cmd_q_; @@ -1240,15 +1269,15 @@ void gatt_clcb_invalidate(tGATT_TCB* p_tcb, const tGATT_CLCB* p_clcb) { if (iter->to_send) { /* If command was not send, just remove the entire element */ cl_cmd_q_p->erase(iter); - LOG_WARN("Removing scheduled clcb (%p) for conn_id=0x%04x", p_clcb, - p_clcb->conn_id); + log::warn("Removing scheduled clcb ({}) for conn_id=0x{:04x}", + fmt::ptr(p_clcb), p_clcb->conn_id); } else { /* If command has been sent, just invalidate p_clcb pointer for proper * response handling */ iter->p_clcb = NULL; - LOG_WARN( - "Invalidating clcb (%p) for already sent request on conn_id=0x%04x", - p_clcb, p_clcb->conn_id); + log::warn( + "Invalidating clcb ({}) for already sent request on conn_id=0x{:04x}", + fmt::ptr(p_clcb), p_clcb->conn_id); } } /******************************************************************************* @@ -1368,8 +1397,8 @@ void gatt_sr_reset_cback_cnt(tGATT_TCB& tcb, uint16_t cid) { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return; } channel->server_outstanding_cmd_.cback_cnt[i] = 0; @@ -1396,15 +1425,15 @@ void gatt_sr_reset_prep_cnt(tGATT_TCB& tcb) { tGATT_SR_CMD* gatt_sr_get_cmd_by_cid(tGATT_TCB& tcb, uint16_t cid) { tGATT_SR_CMD* sr_cmd_p; - LOG(INFO) << __func__ << " cid: " << int(cid) << " tcb cid " << tcb.att_lcid; + log::info("cid: {} tcb cid {}", int(cid), tcb.att_lcid); if (cid == tcb.att_lcid) { sr_cmd_p = &tcb.sr_cmd; } else { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return nullptr; } @@ -1418,15 +1447,15 @@ tGATT_SR_CMD* gatt_sr_get_cmd_by_cid(tGATT_TCB& tcb, uint16_t cid) { tGATT_READ_MULTI* gatt_sr_get_read_multi(tGATT_TCB& tcb, uint16_t cid) { tGATT_READ_MULTI* read_multi_p; - LOG(INFO) << __func__ << " cid: " << int(cid) << " tcb cid " << tcb.att_lcid; + log::info("cid: {} tcb cid {}", int(cid), tcb.att_lcid); if (cid == tcb.att_lcid) { read_multi_p = &tcb.sr_cmd.multi_req; } else { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return nullptr; } read_multi_p = &channel->server_outstanding_cmd_.multi_req; @@ -1455,8 +1484,8 @@ void gatt_sr_update_cback_cnt(tGATT_TCB& tcb, uint16_t cid, tGATT_IF gatt_if, EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return; } sr_cmd_p = &channel->server_outstanding_cmd_; @@ -1487,9 +1516,8 @@ void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc, bool is_reset_first) { uint8_t idx = ((uint8_t)gatt_if) - 1; - VLOG(1) << StringPrintf( - "%s tcb idx=%d gatt_if=%d is_inc=%d is_reset_first=%d", __func__, - tcb.tcb_idx, gatt_if, is_inc, is_reset_first); + log::verbose("tcb idx={} gatt_if={} is_inc={} is_reset_first={}", tcb.tcb_idx, + gatt_if, is_inc, is_reset_first); if (is_reset_first) { gatt_sr_reset_prep_cnt(tcb); @@ -1507,23 +1535,22 @@ void gatt_sr_update_prep_cnt(tGATT_TCB& tcb, tGATT_IF gatt_if, bool is_inc, bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) { tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE); if (!p_tcb) { - LOG_WARN( - "Unable to cancel open for unknown connection gatt_if:%hhu peer:%s", - gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::warn("Unable to cancel open for unknown connection gatt_if:{} peer:{}", + gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda)); return true; } if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) { - LOG(ERROR) << __func__ << ": link connected Too late to cancel"; + log::error("link connected Too late to cancel"); return false; } gatt_update_app_use_link_flag(gatt_if, p_tcb, false, false); if (p_tcb->app_hold_link.empty()) { - LOG_DEBUG( - "Client reference count is zero disconnecting device gatt_if:%hhu " - "peer:%s", + log::debug( + "Client reference count is zero disconnecting device gatt_if:{} " + "peer:{}", gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda)); gatt_disconnect(p_tcb); } @@ -1536,14 +1563,14 @@ bool gatt_cancel_open(tGATT_IF gatt_if, const RawAddress& bda) { if (!connection_manager::direct_connect_remove(gatt_if, bda)) { if (!connection_manager::is_background_connection(bda)) { BTM_AcceptlistRemove(bda); - LOG_INFO( - "Gatt connection manager has no background record but " - " removed filter acceptlist gatt_if:%hhu peer:%s", + log::info( + "Gatt connection manager has no background record but removed " + "filter acceptlist gatt_if:{} peer:{}", gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda)); } else { - LOG_INFO( - "Gatt connection manager maintains a background record" - " preserving filter acceptlist gatt_if:%hhu peer:%s", + log::info( + "Gatt connection manager maintains a background record preserving " + "filter acceptlist gatt_if:{} peer:{}", gatt_if, ADDRESS_TO_LOGGABLE_CSTR(bda)); } } @@ -1568,8 +1595,8 @@ bool gatt_cmd_enq(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, bool to_send, EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cmd.cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cmd.cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cmd.cid); return false; } channel->cl_cmd_q_.push_back(cmd); @@ -1588,8 +1615,8 @@ tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint16_t cid, uint8_t* p_op_code) { EattChannel* channel = EattExtension::GetInstance()->FindEattChannelByCid(tcb.peer_bda, cid); if (channel == nullptr) { - LOG_WARN("%s, cid 0x%02x already disconnected", - ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); + log::warn("{}, cid 0x{:02x} already disconnected", + ADDRESS_TO_LOGGABLE_CSTR(tcb.peer_bda), cid); return nullptr; } @@ -1606,8 +1633,8 @@ tGATT_CLCB* gatt_cmd_dequeue(tGATT_TCB& tcb, uint16_t cid, uint8_t* p_op_code) { * peer, device p_clcb will be null. */ if (p_clcb && p_clcb->cid != cid) { - LOG_WARN(" CID does not match (%d!=%d), conn_id=0x%04x", p_clcb->cid, cid, - p_clcb->conn_id); + log::warn("CID does not match ({}!={}), conn_id=0x{:04x}", p_clcb->cid, cid, + p_clcb->conn_id); } cl_cmd_q_p->pop_front(); @@ -1662,9 +1689,8 @@ void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) { uint16_t conn_id; uint8_t operation; - VLOG(1) << __func__ - << StringPrintf(" status=%d op=%d subtype=%d", status, - p_clcb->operation, p_clcb->op_subtype); + log::verbose("status={} op={} subtype={}", status, p_clcb->operation, + p_clcb->op_subtype); memset(&cb_data.att_value, 0, sizeof(tGATT_VALUE)); if (p_cmpl_cb != NULL && p_clcb->operation != 0) { @@ -1673,9 +1699,7 @@ void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) { cb_data.att_value.len = p_clcb->counter; if (cb_data.att_value.len > GATT_MAX_ATTR_LEN) { - LOG(WARNING) << __func__ - << StringPrintf(" Large cb_data.att_value, size=%d", - cb_data.att_value.len); + log::warn("Large cb_data.att_value, size={}", cb_data.att_value.len); cb_data.att_value.len = GATT_MAX_ATTR_LEN; } @@ -1690,7 +1714,7 @@ void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) { if (p_data) { cb_data.att_value = *((tGATT_VALUE*)p_data); } else { - VLOG(1) << "Rcv Prepare write rsp but no data"; + log::verbose("Rcv Prepare write rsp but no data"); } } } @@ -1716,23 +1740,21 @@ void gatt_end_operation(tGATT_CLCB* p_clcb, tGATT_STATUS status, void* p_data) { else if (p_cmpl_cb && op) (*p_cmpl_cb)(conn_id, op, status, &cb_data); else - LOG(WARNING) << __func__ - << StringPrintf( - ": not sent out op=%d p_disc_cmpl_cb:%p p_cmpl_cb:%p", - operation, p_disc_cmpl_cb, p_cmpl_cb); + log::warn("not sent out op={} p_disc_cmpl_cb:{} p_cmpl_cb:{}", operation, + fmt::ptr(p_disc_cmpl_cb), fmt::ptr(p_cmpl_cb)); } /** This function cleans up the control blocks when L2CAP channel disconnect */ void gatt_cleanup_upon_disc(const RawAddress& bda, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport) { - VLOG(1) << __func__; + log::verbose(""); tGATT_TCB* p_tcb = gatt_find_tcb_by_addr(bda, transport); if (!p_tcb) { - LOG_ERROR( - "Disconnect for unknown connection bd_addr:%s reason:%s transport:%s", - ADDRESS_TO_LOGGABLE_CSTR(bda), gatt_disconnection_reason_text(reason).c_str(), - bt_transport_text(transport).c_str()); + log::error( + "Disconnect for unknown connection bd_addr:{} reason:{} transport:{}", + ADDRESS_TO_LOGGABLE_CSTR(bda), gatt_disconnection_reason_text(reason), + bt_transport_text(transport)); return; } @@ -1749,7 +1771,7 @@ void gatt_cleanup_upon_disc(const RawAddress& bda, tGATT_DISCONN_REASON reason, } gatt_stop_rsp_timer(&(*clcb_it)); - VLOG(1) << "found p_clcb conn_id=" << +clcb_it->conn_id; + log::verbose("found p_clcb conn_id={}", clcb_it->conn_id); if (clcb_it->operation == GATTC_OPTYPE_NONE) { clcb_it = gatt_cb.clcb_queue.erase(clcb_it); continue; @@ -1781,7 +1803,7 @@ void gatt_cleanup_upon_disc(const RawAddress& bda, tGATT_DISCONN_REASON reason, } *p_tcb = tGATT_TCB(); - VLOG(1) << __func__ << ": exit"; + log::verbose("exit"); } /******************************************************************************* * @@ -1792,7 +1814,7 @@ void gatt_cleanup_upon_disc(const RawAddress& bda, tGATT_DISCONN_REASON reason, * Returns uint8_t *: name of the operation. * ******************************************************************************/ -uint8_t* gatt_dbg_op_name(uint8_t op_code) { +char const* gatt_dbg_op_name(uint8_t op_code) { uint8_t pseduo_op_code_idx = op_code & (~GATT_WRITE_CMD_MASK); if (op_code == GATT_CMD_WRITE) { @@ -1805,10 +1827,10 @@ uint8_t* gatt_dbg_op_name(uint8_t op_code) { #define ARR_SIZE(a) (sizeof(a)/sizeof(a[0])) if (pseduo_op_code_idx < ARR_SIZE(op_code_name)) - return (uint8_t*)op_code_name[pseduo_op_code_idx]; + return op_code_name[pseduo_op_code_idx]; else - return (uint8_t*)"Op Code Exceed Max"; - #undef ARR_SIZE + return "Op Code Exceed Max"; +#undef ARR_SIZE } /** Remove the application interface for the specified background device */ diff --git a/system/stack/hcic/hciblecmds.cc b/system/stack/hcic/hciblecmds.cc index a17c78b99476baa4b856b847dfbf8aa6d0e1abce..37e307dd2a51e31f55694ea6341adaa03c293934 100644 --- a/system/stack/hcic/hciblecmds.cc +++ b/system/stack/hcic/hciblecmds.cc @@ -31,6 +31,7 @@ #include "hcidefs.h" #include "hcimsgs.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" diff --git a/system/stack/hcic/hcicmds.cc b/system/stack/hcic/hcicmds.cc index 40b008b8369d28f8a6fde9d38bfdfe7be777c605..21c819dd59dfdf12e67609eff03478608cdcb7c5 100644 --- a/system/stack/hcic/hcicmds.cc +++ b/system/stack/hcic/hcicmds.cc @@ -27,12 +27,13 @@ #include #include -#include "bt_target.h" #include "device/include/esco_parameters.h" #include "hcidefs.h" #include "hcimsgs.h" +#include "internal_include/bt_target.h" #include "main/shim/acl_api.h" #include "osi/include/allocator.h" +#include "stack/include/bt_dev_class.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_lap.h" #include "stack/include/bt_octets.h" @@ -47,10 +48,6 @@ #define HCIC_INQ_INQ_LAP_OFF 0 #define HCIC_INQ_DUR_OFF 3 #define HCIC_INQ_RSP_CNT_OFF 4 -/* Inquiry */ - -/* Inquiry Cancel */ -#define HCIC_PARAM_SIZE_INQ_CANCEL 0 /* Periodic Inquiry Mode */ #define HCIC_PARAM_SIZE_PER_INQ_MODE 9 @@ -481,36 +478,6 @@ #define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY 14 #define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY 3 -static void btsnd_hcic_inquiry(const LAP inq_lap, uint8_t duration, - uint8_t response_cnt) { - BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); - uint8_t* pp = (uint8_t*)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_INQUIRY; - p->offset = 0; - - UINT16_TO_STREAM(pp, HCI_INQUIRY); - UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_INQUIRY); - - LAP_TO_STREAM(pp, inq_lap); - UINT8_TO_STREAM(pp, duration); - UINT8_TO_STREAM(pp, response_cnt); - - btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); -} - -static void btsnd_hcic_inq_cancel(void) { - BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); - uint8_t* pp = (uint8_t*)(p + 1); - - p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_INQ_CANCEL; - p->offset = 0; - UINT16_TO_STREAM(pp, HCI_INQUIRY_CANCEL); - UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_INQ_CANCEL); - - btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); -} - static void btsnd_hcic_disconnect(uint16_t handle, uint8_t reason) { BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); uint8_t* pp = (uint8_t*)(p + 1); @@ -977,11 +944,11 @@ void btsnd_hcic_set_event_filter(uint8_t filt_type, uint8_t filt_cond_type, if (filt_cond_type == HCI_FILTER_COND_DEVICE_CLASS) { DEVCLASS_TO_STREAM(pp, filt_cond); - filt_cond += DEV_CLASS_LEN; + filt_cond += kDevClassLength; DEVCLASS_TO_STREAM(pp, filt_cond); - filt_cond += DEV_CLASS_LEN; + filt_cond += kDevClassLength; - filt_cond_len -= (2 * DEV_CLASS_LEN); + filt_cond_len -= (2 * kDevClassLength); } else if (filt_cond_type == HCI_FILTER_COND_BD_ADDR) { BDADDR_TO_STREAM(pp, *((RawAddress*)filt_cond)); filt_cond += BD_ADDR_LEN; @@ -1689,11 +1656,6 @@ void btsnd_hcic_configure_data_path(hci_data_direction_t data_path_direction, namespace bluetooth::legacy::hci { class InterfaceImpl : public Interface { - void StartInquiry(const uint8_t* inq_lap, uint8_t duration, - uint8_t response_cnt) const override { - btsnd_hcic_inquiry(inq_lap, duration, response_cnt); - } - void InquiryCancel() const override { btsnd_hcic_inq_cancel(); } void Disconnect(uint16_t handle, uint8_t reason) const override { btsnd_hcic_disconnect(handle, reason); } diff --git a/system/stack/hid/hid_conn.h b/system/stack/hid/hid_conn.h index 22e9b9dc8a9aac68bbd79fd0c9ec3fc6c7363c1c..562525e5d145e1eea35a4663f35055212341a334 100644 --- a/system/stack/hid/hid_conn.h +++ b/system/stack/hid/hid_conn.h @@ -26,6 +26,7 @@ #define HID_CONN_H #include +#include #include "macros.h" #include "osi/include/alarm.h" @@ -77,4 +78,9 @@ typedef struct hid_conn { #define HIDD_SEC_CHN 3 +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/stack/hid/hidd_api.cc b/system/stack/hid/hidd_api.cc index fad8e977ad077adc4c6dc1cb95bf979bc6b19fb0..602f9a7153b3344d24f56c4ea5f436b210865dc2 100644 --- a/system/stack/hid/hidd_api.cc +++ b/system/stack/hid/hidd_api.cc @@ -27,6 +27,7 @@ #include "hidd_api.h" +#include #include #include #include @@ -44,6 +45,7 @@ #include "stack/include/stack_metrics_logging.h" #include "types/raw_address.h" +using namespace bluetooth; using namespace bluetooth::legacy::stack::sdp; tHID_DEV_CTB hd_cb; @@ -58,7 +60,7 @@ tHID_DEV_CTB hd_cb; * ******************************************************************************/ void HID_DevInit(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); memset(&hd_cb, 0, sizeof(tHID_DEV_CTB)); } @@ -75,7 +77,7 @@ void HID_DevInit(void) { tHID_STATUS HID_DevRegister(tHID_DEV_HOST_CALLBACK* host_cback) { tHID_STATUS st; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (hd_cb.reg_flag) { log_counter_metrics( @@ -116,7 +118,7 @@ tHID_STATUS HID_DevRegister(tHID_DEV_HOST_CALLBACK* host_cback) { * ******************************************************************************/ tHID_STATUS HID_DevDeregister(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!hd_cb.reg_flag) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: @@ -146,7 +148,7 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, uint16_t desc_len, uint8_t* p_desc_data) { bool result = TRUE; - LOG_VERBOSE("%s", __func__); + log::verbose(""); // Service Class ID List if (result) { @@ -266,8 +268,8 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, uint8_t seq_len = 4 + desc_len; if (desc_len > HIDD_APP_DESCRIPTOR_LEN) { - LOG_ERROR("%s: descriptor length = %d, larger than max %d", __func__, - desc_len, HIDD_APP_DESCRIPTOR_LEN); + log::error("descriptor length = {}, larger than max {}", desc_len, + HIDD_APP_DESCRIPTOR_LEN); log_counter_metrics( android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_NOT_REGISTERED_DUE_TO_DESCRIPTOR_LENGTH, @@ -278,7 +280,7 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, p_buf = (uint8_t*)osi_malloc(HIDD_APP_DESCRIPTOR_LEN + 6); if (p_buf == NULL) { - LOG_ERROR("%s: Buffer allocation failure for size = 2048 ", __func__); + log::error("Buffer allocation failure for size = 2048"); log_counter_metrics( android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_NOT_REGISTERED_DUE_TO_BUFFER_ALLOCATION, @@ -352,7 +354,7 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, } if (!result) { - LOG_ERROR("%s: failed to complete SDP record", __func__); + log::error("failed to complete SDP record"); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_NOT_REGISTERED_AT_SDP, 1); @@ -373,8 +375,7 @@ tHID_STATUS HID_DevAddRecord(uint32_t handle, char* p_name, char* p_description, ******************************************************************************/ tHID_STATUS HID_DevSendReport(uint8_t channel, uint8_t type, uint8_t id, uint16_t len, uint8_t* p_data) { - LOG_VERBOSE("%s: channel=%d type=%d id=%d len=%d", __func__, channel, type, - id, len); + log::verbose("channel={} type={} id={} len={}", channel, type, id, len); if (channel == HID_CHANNEL_CTRL) { return hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_DATA, type, id, len, @@ -402,7 +403,7 @@ tHID_STATUS HID_DevSendReport(uint8_t channel, uint8_t type, uint8_t id, * ******************************************************************************/ tHID_STATUS HID_DevVirtualCableUnplug(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); return hidd_conn_send_data(HID_CHANNEL_CTRL, HID_TRANS_CONTROL, HID_PAR_CONTROL_VIRTUAL_CABLE_UNPLUG, 0, 0, NULL); @@ -549,7 +550,7 @@ tHID_STATUS HID_DevSetIncomingPolicy(bool allow) { tHID_STATUS HID_DevReportError(uint8_t error) { uint8_t handshake_param; - LOG_VERBOSE("%s: error = %d", __func__, error); + log::verbose("error = {}", error); switch (error) { case HID_PAR_HANDSHAKE_RSP_SUCCESS: @@ -580,7 +581,7 @@ tHID_STATUS HID_DevReportError(uint8_t error) { * ******************************************************************************/ tHID_STATUS HID_DevGetDevice(RawAddress* addr) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (hd_cb.device.in_use) { *addr = hd_cb.device.addr; @@ -607,7 +608,7 @@ tHID_STATUS HID_DevSetIncomingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size, uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); hd_cb.use_in_qos = TRUE; @@ -634,7 +635,7 @@ tHID_STATUS HID_DevSetOutgoingQos(uint8_t service_type, uint32_t token_rate, uint32_t token_bucket_size, uint32_t peak_bandwidth, uint32_t latency, uint32_t delay_variation) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); hd_cb.l2cap_intr_cfg.qos_present = TRUE; diff --git a/system/stack/hid/hidd_conn.cc b/system/stack/hid/hidd_conn.cc index 9b9129f19b60db7746ab154d5fdd6158cbee546d..fe417c0d3edea02fc0f0257aced13001546b9325 100644 --- a/system/stack/hid/hidd_conn.cc +++ b/system/stack/hid/hidd_conn.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -40,6 +41,8 @@ #include "stack/include/stack_metrics_logging.h" #include "types/raw_address.h" +using namespace bluetooth; + static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid, uint16_t psm, uint8_t id); static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result); @@ -107,12 +110,12 @@ static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid, tHID_DEV_DEV_CTB* p_dev; bool accept = TRUE; // accept by default - LOG_VERBOSE("%s: psm=%04x cid=%04x", __func__, psm, cid); + log::verbose("psm={:04x} cid={:04x}", psm, cid); p_dev = &hd_cb.device; if (!hd_cb.allow_incoming) { - LOG_WARN("%s: incoming connections not allowed, rejecting", __func__); + log::warn("incoming connections not allowed, rejecting"); L2CA_DisconnectReq(cid); return; @@ -124,13 +127,13 @@ static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid, case HID_PSM_INTERRUPT: if (p_hcon->ctrl_cid == 0) { accept = FALSE; - LOG_WARN("%s: incoming INTR without CTRL, rejecting", __func__); + log::warn("incoming INTR without CTRL, rejecting"); } if (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) { accept = FALSE; - LOG_WARN("%s: incoming INTR in invalid state (%d), rejecting", __func__, - p_hcon->conn_state); + log::warn("incoming INTR in invalid state ({}), rejecting", + p_hcon->conn_state); } break; @@ -138,15 +141,15 @@ static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid, case HID_PSM_CONTROL: if (p_hcon->conn_state != HID_CONN_STATE_UNUSED) { accept = FALSE; - LOG_WARN("%s: incoming CTRL in invalid state (%d), rejecting", __func__, - p_hcon->conn_state); + log::warn("incoming CTRL in invalid state ({}), rejecting", + p_hcon->conn_state); } break; default: accept = FALSE; - LOG_ERROR("%s: received invalid PSM, rejecting", __func__); + log::error("received invalid PSM, rejecting"); break; } @@ -176,7 +179,7 @@ static void hidd_l2cif_connect_ind(const RawAddress& bd_addr, uint16_t cid, } static void hidd_on_l2cap_error(uint16_t lcid, uint16_t result) { - LOG_WARN("%s: connection of config failed, now disconnect", __func__); + log::warn("connection of config failed, now disconnect"); hidd_conn_disconnect(); @@ -197,10 +200,10 @@ static void hidd_on_l2cap_error(uint16_t lcid, uint16_t result) { static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) { tHID_CONN* p_hcon = &hd_cb.device.conn; - LOG_VERBOSE("%s: cid=%04x result=%d", __func__, cid, result); + log::verbose("cid={:04x} result={}", cid, result); if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - LOG_WARN("%s: unknown cid", __func__); + log::warn("unknown cid"); return; } @@ -209,12 +212,12 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) { (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_CTRL)) || ((cid == p_hcon->intr_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR))) { - LOG_WARN("%s: unexpected", __func__); + log::warn("unexpected"); return; } if (result != L2CAP_CONN_OK) { - LOG(ERROR) << __func__ << ": invoked with non OK status"; + log::error("invoked with non OK status"); return; } @@ -239,12 +242,12 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) { * ******************************************************************************/ static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { - LOG_VERBOSE("%s: cid=%04x", __func__, cid); + log::verbose("cid={:04x}", cid); tHID_CONN* p_hcon = &hd_cb.device.conn; if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - LOG_WARN("%s: unknown cid", __func__); + log::warn("unknown cid"); return; } @@ -267,12 +270,12 @@ static void hidd_l2cif_config_cfm(uint16_t cid, uint16_t initiator, tL2CAP_CFG_INFO* p_cfg) { hidd_l2cif_config_ind(cid, p_cfg); - LOG_VERBOSE("%s: cid=%04x", __func__, cid); + log::verbose("cid={:04x}", cid); tHID_CONN* p_hcon = &hd_cb.device.conn; if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - LOG_WARN("%s: unknown cid", __func__); + log::warn("unknown cid"); return; } @@ -286,7 +289,7 @@ static void hidd_l2cif_config_cfm(uint16_t cid, uint16_t initiator, hidd_conn_disconnect(); p_hcon->conn_state = HID_CONN_STATE_UNUSED; - LOG_WARN("%s: could not start L2CAP connection for INTR", __func__); + log::warn("could not start L2CAP connection for INTR"); hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: @@ -312,13 +315,13 @@ static void hidd_l2cif_config_cfm(uint16_t cid, uint16_t initiator, * ******************************************************************************/ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) { - LOG_VERBOSE("%s: cid=%04x ack_needed=%d", __func__, cid, ack_needed); + log::verbose("cid={:04x} ack_needed={}", cid, ack_needed); tHID_CONN* p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - LOG_WARN("%s: unknown cid", __func__); + log::warn("unknown cid"); return; } @@ -330,7 +333,7 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) { p_hcon->intr_cid = 0; if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) { - LOG_VERBOSE("%s: INTR and CTRL disconnected", __func__); + log::verbose("INTR and CTRL disconnected"); // clean any outstanding data on intr if (hd_cb.pending_data) { @@ -349,13 +352,13 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) { static void hidd_l2cif_disconnect(uint16_t cid) { L2CA_DisconnectReq(cid); - LOG_VERBOSE("%s: cid=%04x", __func__, cid); + log::verbose("cid={:04x}", cid); tHID_CONN* p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - LOG_WARN("%s: unknown cid", __func__); + log::warn("unknown cid"); return; } @@ -373,7 +376,7 @@ static void hidd_l2cif_disconnect(uint16_t cid) { } if ((p_hcon->ctrl_cid == 0) && (p_hcon->intr_cid == 0)) { - LOG_VERBOSE("%s: INTR and CTRL disconnected", __func__); + log::verbose("INTR and CTRL disconnected"); hd_cb.device.state = HIDD_DEV_NO_CONN; p_hcon->conn_state = HID_CONN_STATE_UNUSED; @@ -399,13 +402,13 @@ static void hidd_l2cif_disconnect(uint16_t cid) { * ******************************************************************************/ static void hidd_l2cif_cong_ind(uint16_t cid, bool congested) { - LOG_VERBOSE("%s: cid=%04x congested=%d", __func__, cid, congested); + log::verbose("cid={:04x} congested={}", cid, congested); tHID_CONN* p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - LOG_WARN("%s: unknown cid", __func__); + log::warn("unknown cid"); return; } @@ -430,10 +433,10 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg) { uint8_t msg_type, param; bool err = FALSE; - LOG_VERBOSE("%s: cid=%04x", __func__, cid); + log::verbose("cid={:04x}", cid); if (p_msg->len < 1) { - LOG_ERROR("Invalid data length, ignore"); + log::error("Invalid data length, ignore"); osi_free(p_msg); return; } @@ -442,7 +445,7 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg) { if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - LOG_WARN("%s: unknown cid", __func__); + log::warn("unknown cid"); osi_free(p_msg); return; } @@ -481,15 +484,14 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg) { case HID_TRANS_SET_IDLE: if (p_msg->len != 2) { - LOG_ERROR("%s: invalid len (%d) set idle request received", __func__, - p_msg->len); + log::error("invalid len ({}) set idle request received", p_msg->len); err = TRUE; } else { hd_cb.device.idle_time = p_data[1]; - LOG_VERBOSE("%s: idle_time = %d", __func__, hd_cb.device.idle_time); + log::verbose("idle_time = {}", hd_cb.device.idle_time); if (hd_cb.device.idle_time) { - LOG_WARN("%s: idle_time of %d ms not supported by HID Device", - __func__, (hd_cb.device.idle_time * 4)); + log::warn("idle_time of {} ms not supported by HID Device", + (hd_cb.device.idle_time * 4)); err = TRUE; } } @@ -544,7 +546,7 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg) { case HID_TRANS_DATA: default: - LOG_WARN("%s: got unsupported msg (%d)", __func__, msg_type); + log::warn("got unsupported msg ({})", msg_type); hidd_conn_send_data(0, HID_TRANS_HANDSHAKE, HID_PAR_HANDSHAKE_RSP_ERR_UNSUPPORTED_REQ, 0, 0, NULL); @@ -563,7 +565,7 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR* p_msg) { * ******************************************************************************/ tHID_STATUS hidd_conn_reg(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); memset(&hd_cb.l2cap_cfg, 0, sizeof(tL2CAP_CFG_INFO)); @@ -576,7 +578,7 @@ tHID_STATUS hidd_conn_reg(void) { if (!L2CA_Register2(HID_PSM_CONTROL, dev_reg_info, false /* enable_snoop */, nullptr, HID_DEV_MTU_SIZE, 0, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) { - LOG_ERROR("HID Control (device) registration failed"); + log::error("HID Control (device) registration failed"); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_L2CAP_FAILED_CONTROL, 1); @@ -587,7 +589,7 @@ tHID_STATUS hidd_conn_reg(void) { nullptr, HID_DEV_MTU_SIZE, 0, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) { L2CA_Deregister(HID_PSM_CONTROL); - LOG_ERROR("HID Interrupt (device) registration failed"); + log::error("HID Interrupt (device) registration failed"); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_L2CAP_FAILED_INTERRUPT, 1); @@ -607,7 +609,7 @@ tHID_STATUS hidd_conn_reg(void) { * ******************************************************************************/ void hidd_conn_dereg(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); L2CA_Deregister(HID_PSM_CONTROL); L2CA_Deregister(HID_PSM_INTERRUPT); @@ -625,10 +627,10 @@ void hidd_conn_dereg(void) { tHID_STATUS hidd_conn_initiate(void) { tHID_DEV_DEV_CTB* p_dev = &hd_cb.device; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!p_dev->in_use) { - LOG_WARN("%s: no virtual cable established", __func__); + log::warn("no virtual cable established"); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_NOT_REGISTERED_AT_INITIATE, 1); @@ -636,7 +638,7 @@ tHID_STATUS hidd_conn_initiate(void) { } if (p_dev->conn.conn_state != HID_CONN_STATE_UNUSED) { - LOG_WARN("%s: connection already in progress", __func__); + log::warn("connection already in progress"); log_counter_metrics( android::bluetooth::CodePathCounterKeyEnum::HIDD_ERR_CONN_IN_PROCESS, 1); @@ -653,7 +655,7 @@ tHID_STATUS hidd_conn_initiate(void) { if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq2(HID_PSM_CONTROL, p_dev->addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) == 0) { - LOG_WARN("%s: could not start L2CAP connection", __func__); + log::warn("could not start L2CAP connection"); hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: @@ -676,7 +678,7 @@ tHID_STATUS hidd_conn_initiate(void) { * ******************************************************************************/ tHID_STATUS hidd_conn_disconnect(void) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); // clean any outstanding data on intr if (hd_cb.pending_data) { @@ -699,7 +701,7 @@ tHID_STATUS hidd_conn_disconnect(void) { hidd_l2cif_disconnect(p_hcon->ctrl_cid); } } else { - LOG_WARN("%s: already disconnected", __func__); + log::warn("already disconnected"); p_hcon->conn_state = HID_CONN_STATE_UNUSED; } @@ -723,8 +725,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint16_t cid; uint16_t buf_size; - LOG_VERBOSE("%s: channel(%d), msg_type(%d), len(%d)", __func__, channel, - msg_type, len); + log::verbose("channel({}), msg_type({}), len({})", channel, msg_type, len); tHID_CONN* p_hcon = &hd_cb.device.conn; @@ -808,12 +809,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, return HID_ERR_NO_CONNECTION; } -#ifdef REPORT_TRANSFER_TIMESTAMP - if (report_transfer) { - LOG_ERROR("%s: report sent", __func__); - } -#endif - LOG_VERBOSE("%s: report sent", __func__); + log::verbose("report sent"); if (!L2CA_DataWrite(cid, p_buf)) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: diff --git a/system/stack/hid/hidh_api.cc b/system/stack/hid/hidh_api.cc index 0bb7926a6841f22c55d5af276459a40680584a24..24f0f18078db7994f29bde462e898791fbd4c73a 100644 --- a/system/stack/hid/hidh_api.cc +++ b/system/stack/hid/hidh_api.cc @@ -26,6 +26,7 @@ #include "hidh_api.h" +#include #include #include #include @@ -44,6 +45,7 @@ #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +using namespace bluetooth; using namespace bluetooth::legacy::stack::sdp; using bluetooth::Uuid; @@ -107,7 +109,7 @@ void hidh_get_str_attr(tSDP_DISC_REC* p_rec, uint16_t attr_id, uint16_t max_len, } } else { str[0] = '\0'; - LOG_ERROR("attr type not str!!"); + log::error("attr type not str!!"); } } else str[0] = '\0'; @@ -496,13 +498,13 @@ tHID_STATUS HID_HostWriteDev(uint8_t dev_handle, uint8_t t_type, uint8_t param, tHID_STATUS status = HID_SUCCESS; if (!hh_cb.reg_flag) { - LOG_ERROR("HID_ERR_NOT_REGISTERED"); + log::error("HID_ERR_NOT_REGISTERED"); status = HID_ERR_NOT_REGISTERED; } if ((dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use)) { - LOG_ERROR("HID_ERR_INVALID_PARAM"); + log::error("HID_ERR_INVALID_PARAM"); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDH_ERR_INVALID_PARAM_AT_HOST_WRITE_DEV, 1); @@ -510,7 +512,7 @@ tHID_STATUS HID_HostWriteDev(uint8_t dev_handle, uint8_t t_type, uint8_t param, } else if (hh_cb.devices[dev_handle].state != HID_DEV_CONNECTED) { - LOG_ERROR("HID_ERR_NO_CONNECTION dev_handle %d", dev_handle); + log::error("HID_ERR_NO_CONNECTION dev_handle {}", dev_handle); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDH_ERR_NO_CONNECTION_AT_HOST_WRITE_DEV, 1); diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc index b9da24ebe2001f0b79837c6d2fc0d42ea4583b25..261446dbf2ef5a43587124685e1c40504519df8d 100644 --- a/system/stack/hid/hidh_conn.cc +++ b/system/stack/hid/hidh_conn.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,8 @@ #include "stack/include/stack_metrics_logging.h" #include "types/raw_address.h" +using namespace bluetooth; + namespace { constexpr char kBtmLogTag[] = "HIDH"; constexpr uint8_t kHID_HOST_MAX_DEVICES = HID_HOST_MAX_DEVICES; @@ -108,7 +111,7 @@ tHID_STATUS hidh_conn_reg(void) { if (!L2CA_Register2(HID_PSM_CONTROL, hst_reg_info, false /* enable_snoop */, nullptr, HID_HOST_MTU, 0, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) { - LOG_ERROR("HID-Host Control Registration failed"); + log::error("HID-Host Control Registration failed"); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDH_ERR_L2CAP_FAILED_AT_REGISTER_CONTROL, 1); @@ -118,7 +121,7 @@ tHID_STATUS hidh_conn_reg(void) { nullptr, HID_HOST_MTU, 0, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)) { L2CA_Deregister(HID_PSM_CONTROL); - LOG_ERROR("HID-Host Interrupt Registration failed"); + log::error("HID-Host Interrupt Registration failed"); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDH_ERR_L2CAP_FAILED_AT_REGISTER_INTERRUPT, 1); @@ -183,8 +186,8 @@ static void hidh_l2cif_connect_ind(const RawAddress& bd_addr, bool bAccept = true; uint8_t i = kHID_HOST_MAX_DEVICES; - LOG_VERBOSE("HID-Host Rcvd L2CAP conn ind, PSM: 0x%04x CID 0x%x", psm, - l2cap_cid); + log::verbose("HID-Host Rcvd L2CAP conn ind, PSM: 0x{:04x} CID 0x{:x}", psm, + l2cap_cid); /* always add incoming connection device into HID database by default */ if (HID_HostAddDev(bd_addr, HID_SEC_REQUIRED, &i) != HID_SUCCESS) { @@ -203,12 +206,12 @@ static void hidh_l2cif_connect_ind(const RawAddress& bd_addr, /* Check we are in the correct state for this */ if (psm == HID_PSM_INTERRUPT) { if (p_hcon->ctrl_cid == 0) { - LOG_WARN("HID-Host Rcvd INTR L2CAP conn ind, but no CTL channel"); + log::warn("HID-Host Rcvd INTR L2CAP conn ind, but no CTL channel"); bAccept = false; } if (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) { - LOG_WARN("HID-Host Rcvd INTR L2CAP conn ind, wrong state: %d", - p_hcon->conn_state); + log::warn("HID-Host Rcvd INTR L2CAP conn ind, wrong state: {}", + p_hcon->conn_state); bAccept = false; } } else /* CTRL channel */ @@ -218,8 +221,8 @@ static void hidh_l2cif_connect_ind(const RawAddress& bd_addr, p_hcon->conn_state = HID_CONN_STATE_UNUSED; #else if (p_hcon->conn_state != HID_CONN_STATE_UNUSED) { - LOG_WARN("HID-Host - Rcvd CTL L2CAP conn ind, wrong state: %d", - p_hcon->conn_state); + log::warn("HID-Host - Rcvd CTL L2CAP conn ind, wrong state: {}", + p_hcon->conn_state); bAccept = false; } #endif @@ -246,8 +249,9 @@ static void hidh_l2cif_connect_ind(const RawAddress& bd_addr, p_hcon->conn_state = HID_CONN_STATE_CONFIG; p_hcon->intr_cid = l2cap_cid; - LOG_VERBOSE( - "HID-Host Rcvd L2CAP conn ind, sent config req, PSM: 0x%04x CID 0x%x", + log::verbose( + "HID-Host Rcvd L2CAP conn ind, sent config req, PSM: 0x{:04x} CID " + "0x{:x}", psm, l2cap_cid); } @@ -280,9 +284,8 @@ static void hidh_try_repage(uint8_t dhandle) { static void hidh_on_l2cap_error(uint16_t l2cap_cid, uint16_t result) { auto dhandle = find_conn_by_cid(l2cap_cid); if (dhandle == kHID_HOST_MAX_DEVICES) { - LOG_WARN("Received error for unknown device cid:0x%04x reason:%s", - l2cap_cid, - hci_reason_code_text(to_hci_reason_code(result)).c_str()); + log::warn("Received error for unknown device cid:0x{:04x} reason:{}", + l2cap_cid, hci_reason_code_text(to_hci_reason_code(result))); return; } @@ -336,13 +339,13 @@ static void hidh_l2cif_connect_cfm(uint16_t l2cap_cid, uint16_t result) { ((l2cap_cid == p_hcon->intr_cid) && (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR) && (p_hcon->conn_state != HID_CONN_STATE_DISCONNECTING))) { - LOG_WARN("HID-Host Rcvd unexpected conn cnf, CID 0x%x ", l2cap_cid); + log::warn("HID-Host Rcvd unexpected conn cnf, CID 0x{:x} ", l2cap_cid); return; } if (result != L2CAP_CONN_OK) { // TODO: We need to provide the real HCI status if we want to retry. - LOG(ERROR) << __func__ << ": invoked with non OK status"; + log::error("invoked with non OK status"); return; } /* receive Control Channel connect confirmation */ @@ -386,11 +389,11 @@ static void hidh_l2cif_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg) { } if (p_hcon == NULL) { - LOG_WARN("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); + log::warn("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x{:x}", l2cap_cid); return; } - LOG_VERBOSE("HID-Host Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid); + log::verbose("HID-Host Rcvd cfg ind, sent cfg cfm, CID: 0x{:x}", l2cap_cid); /* Remember the remote MTU size */ if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_HOST_MTU)) @@ -417,14 +420,14 @@ static void hidh_l2cif_config_cfm(uint16_t l2cap_cid, uint16_t initiator, tHID_CONN* p_hcon = NULL; uint32_t reason; - LOG_VERBOSE("HID-Host Rcvd cfg cfm, CID: 0x%x", l2cap_cid); + log::verbose("HID-Host Rcvd cfg cfm, CID: 0x{:x}", l2cap_cid); /* Find CCB based on CID */ dhandle = find_conn_by_cid(l2cap_cid); if (dhandle < kHID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; if (p_hcon == NULL) { - LOG_WARN("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); + log::warn("HID-Host Rcvd L2CAP cfg ind, unknown CID: 0x{:x}", l2cap_cid); return; } @@ -439,7 +442,7 @@ static void hidh_l2cif_config_cfm(uint16_t l2cap_cid, uint16_t initiator, L2CA_ConnectReq2(HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); if (p_hcon->intr_cid == 0) { - LOG_WARN("HID-Host INTR Originate failed"); + log::warn("HID-Host INTR Originate failed"); reason = HID_L2CAP_REQ_FAIL; p_hcon->conn_state = HID_CONN_STATE_UNUSED; BTM_LogHistory(kBtmLogTag, hh_cb.devices[dhandle].addr, "Failed"); @@ -496,11 +499,11 @@ static void hidh_l2cif_disconnect_ind(uint16_t l2cap_cid, bool ack_needed) { if (dhandle < kHID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; if (p_hcon == NULL) { - LOG_WARN("HID-Host Rcvd L2CAP disc, unknown CID: 0x%x", l2cap_cid); + log::warn("HID-Host Rcvd L2CAP disc, unknown CID: 0x{:x}", l2cap_cid); return; } - LOG_VERBOSE("HID-Host Rcvd L2CAP disc, CID: 0x%x", l2cap_cid); + log::verbose("HID-Host Rcvd L2CAP disc, CID: 0x{:x}", l2cap_cid); p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING; BTM_LogHistory( @@ -566,7 +569,7 @@ static void hidh_l2cif_disconnect(uint16_t l2cap_cid) { /* Find CCB based on CID */ const uint8_t dhandle = find_conn_by_cid(l2cap_cid); if (dhandle == kHID_HOST_MAX_DEVICES) { - LOG_WARN("HID-Host Rcvd L2CAP disc cfm, unknown CID: 0x%x", l2cap_cid); + log::warn("HID-Host Rcvd L2CAP disc cfm, unknown CID: 0x{:x}", l2cap_cid); return; } @@ -576,7 +579,7 @@ static void hidh_l2cif_disconnect(uint16_t l2cap_cid) { } else { p_hcon->intr_cid = 0; if (p_hcon->ctrl_cid) { - LOG_VERBOSE("HID-Host Initiating L2CAP Ctrl disconnection"); + log::verbose("HID-Host Initiating L2CAP Ctrl disconnection"); L2CA_DisconnectReq(p_hcon->ctrl_cid); p_hcon->ctrl_cid = 0; } @@ -609,13 +612,13 @@ static void hidh_l2cif_cong_ind(uint16_t l2cap_cid, bool congested) { if (dhandle < kHID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; if (p_hcon == NULL) { - LOG_WARN("HID-Host Rcvd L2CAP congestion status, unknown CID: 0x%x", - l2cap_cid); + log::warn("HID-Host Rcvd L2CAP congestion status, unknown CID: 0x{:x}", + l2cap_cid); return; } - LOG_VERBOSE("HID-Host Rcvd L2CAP congestion status, CID: 0x%x Cong: %d", - l2cap_cid, congested); + log::verbose("HID-Host Rcvd L2CAP congestion status, CID: 0x{:x} Cong: {}", + l2cap_cid, congested); if (congested) p_hcon->conn_flags |= HID_CONN_FLAGS_CONGESTED; @@ -646,20 +649,20 @@ static void hidh_l2cif_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg) { uint8_t dhandle; tHID_CONN* p_hcon = NULL; - LOG_VERBOSE("HID-Host hidh_l2cif_data_ind [l2cap_cid=0x%04x]", l2cap_cid); + log::verbose("HID-Host hidh_l2cif_data_ind [l2cap_cid=0x{:04x}]", l2cap_cid); /* Find CCB based on CID */ dhandle = find_conn_by_cid(l2cap_cid); if (dhandle < kHID_HOST_MAX_DEVICES) p_hcon = &hh_cb.devices[dhandle].conn; if (p_hcon == NULL) { - LOG_WARN("HID-Host Rcvd L2CAP data, unknown CID: 0x%x", l2cap_cid); + log::warn("HID-Host Rcvd L2CAP data, unknown CID: 0x{:x}", l2cap_cid); osi_free(p_msg); return; } if (p_msg->len < 1) { - LOG_WARN("Rcvd L2CAP data, invalid length %d, should be >= 1", p_msg->len); + log::warn("Rcvd L2CAP data, invalid length {}, should be >= 1", p_msg->len); osi_free(p_msg); return; } @@ -884,7 +887,7 @@ tHID_STATUS hidh_conn_initiate(uint8_t dhandle) { p_dev->conn.ctrl_cid = L2CA_ConnectReq2( HID_PSM_CONTROL, p_dev->addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); if (p_dev->conn.ctrl_cid == 0) { - LOG_WARN("HID-Host Originate failed"); + log::warn("HID-Host Originate failed"); hh_cb.callback(dhandle, hh_cb.devices[dhandle].addr, HID_HDEV_EVT_CLOSE, HID_ERR_L2CAP_FAILED, NULL); log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: diff --git a/system/stack/include/a2dp_aac.h b/system/stack/include/a2dp_aac.h index de89f0ccb886c6c5c12a1d0f9eebc0a6ac542be7..1b0311af53f1d77c9fa7dee863bf35471e67f2a5 100644 --- a/system/stack/include/a2dp_aac.h +++ b/system/stack/include/a2dp_aac.h @@ -21,13 +21,12 @@ #ifndef A2DP_AAC_H #define A2DP_AAC_H -#include -#include #include #include "a2dp_aac_constants.h" #include "a2dp_codec_api.h" #include "avdt_api.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" class A2dpCodecConfigAacBase : public A2dpCodecConfig { @@ -36,7 +35,7 @@ class A2dpCodecConfigAacBase : public A2dpCodecConfig { const std::string& name, btav_a2dp_codec_priority_t codec_priority, bool is_source) - : A2dpCodecConfig(codec_index, name, codec_priority), + : A2dpCodecConfig(codec_index, A2DP_CODEC_ID_AAC, name, codec_priority), is_source_(is_source) {} bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; diff --git a/system/stack/include/a2dp_codec_api.h b/system/stack/include/a2dp_codec_api.h index 01e01fd51597a558a5dea2367ad13cd19f83e800..7de3e9ab942e4dc605cbc33245940c846d2e49be 100644 --- a/system/stack/include/a2dp_codec_api.h +++ b/system/stack/include/a2dp_codec_api.h @@ -26,11 +26,11 @@ #include #include -#include #include #include #include #include +#include #include "a2dp_api.h" #include "audio_a2dp_hw/include/audio_a2dp_hw.h" @@ -65,6 +65,18 @@ class A2dpCodecConfig { // Gets the pre-defined codec index. btav_a2dp_codec_index_t codecIndex() const { return codec_index_; } + // Gets the standardized codec identifier. + // The codec identifier is 40 bits, + // - Bits 0-7: Audio Codec ID, as defined by [ID 6.5.1] + // 0x00: SBC + // 0x02: AAC + // 0xFF: Vendor + // - Bits 8-23: Company ID, + // set to 0, if octet 0 is not 0xFF. + // - Bits 24-39: Vendor-defined codec ID, + // set to 0, if octet 0 is not 0xFF. + uint64_t codecId() const { return codec_id_; } + // Gets the codec name. const std::string& name() const { return name_; } @@ -189,7 +201,8 @@ class A2dpCodecConfig { // The default codec priority is |codec_priority|. If the value is // |BTAV_A2DP_CODEC_PRIORITY_DEFAULT|, the codec priority is computed // internally. - A2dpCodecConfig(btav_a2dp_codec_index_t codec_index, const std::string& name, + A2dpCodecConfig(btav_a2dp_codec_index_t codec_index, uint64_t codec_id, + const std::string& name, btav_a2dp_codec_priority_t codec_priority); // Initializes the codec entry. @@ -238,6 +251,7 @@ class A2dpCodecConfig { std::recursive_mutex codec_mutex_; const btav_a2dp_codec_index_t codec_index_; // The unique codec index + const uint64_t codec_id_; // The standardized codec id const std::string name_; // The codec name btav_a2dp_codec_priority_t codec_priority_; // Codec priority: must be unique btav_a2dp_codec_priority_t default_codec_priority_; @@ -277,6 +291,10 @@ class A2dpCodecs { // Returns the Source codec if found, otherwise nullptr. A2dpCodecConfig* findSourceCodecConfig(const uint8_t* p_codec_info); + // Finds the Source codec that corresponds to the A2DP codec index. + // Returns the Source codec if found, otherwise nullptr. + A2dpCodecConfig* findSourceCodecConfig(btav_a2dp_codec_index_t codec_index); + // Finds the Sink codec that corresponds to the A2DP over-the-air // |p_codec_info| information. // Returns the Sink codec if found, otherwise nullptr. @@ -293,6 +311,13 @@ class A2dpCodecs { return current_codec_config_; } + // Selects the codec config. + // /!\ Must only be used with offloaded codecs. + void setCurrentCodecConfig(A2dpCodecConfig* codec_config) { + std::lock_guard lock(codec_mutex_); + current_codec_config_ = codec_config; + } + // Gets the list of Source codecs ordered by priority: higher priority first. const std::list orderedSourceCodecs() const { return ordered_source_codecs_; diff --git a/system/stack/include/a2dp_constants.h b/system/stack/include/a2dp_constants.h index f0d7b227abdac06243a30c97a793257e2d4392f5..56e1aa3d8c6f36fe62bf43a938296a379adaa257 100644 --- a/system/stack/include/a2dp_constants.h +++ b/system/stack/include/a2dp_constants.h @@ -25,6 +25,8 @@ #include +#include + /* Profile supported features */ #define A2DP_SUPF_PLAYER 0x0001 #define A2DP_SUPF_MIC 0x0002 @@ -44,4 +46,23 @@ typedef uint8_t tA2DP_CODEC_TYPE; /* A2DP Codec type: A2DP_MEDIA_CT_* */ +// Standardized codec identifiers. +// The codec identifier is 40 bits, +// - Bits 0-7: Audio Codec ID, as defined by [ID 6.5.1] +// 0x00: SBC +// 0x02: AAC +// 0xFF: Vendor +// - Bits 8-23: Company ID, +// set to 0, if octet 0 is not 0xFF. +// - Bits 24-39: Vendor-defined codec ID, +// set to 0, if octet 0 is not 0xFF. +enum : uint64_t { + A2DP_CODEC_ID_SBC = 0x0000000000, + A2DP_CODEC_ID_AAC = 0x0000000002, + A2DP_CODEC_ID_APTX = 0x0001004fff, + A2DP_CODEC_ID_APTX_HD = 0x002400d7ff, + A2DP_CODEC_ID_LDAC = 0x00aa012dff, + A2DP_CODEC_ID_OPUS = 0x000100e0ff, +}; + #endif // A2DP_CONSTANTS_H diff --git a/system/stack/include/a2dp_ext.h b/system/stack/include/a2dp_ext.h new file mode 100644 index 0000000000000000000000000000000000000000..efff7cdbef27dd75825c3f8cd9b11ce5623e9fac --- /dev/null +++ b/system/stack/include/a2dp_ext.h @@ -0,0 +1,66 @@ +/** + * Copyright 2023 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 + +#include "a2dp_codec_api.h" +#include "audio_hal_interface/a2dp_encoding.h" + +/// Codec configuration for codecs that are supported by a2dp hardware offload +/// codec extensibility. The codec index may be a standard codec, in which case +/// this class is preferred over the dedicated class, or an unknown codec in +/// the reserved ranges for codec extensibility. +/// The codec priority is always the lowest, so that software codecs +/// can be picked over offloaded codecs. +class A2dpCodecConfigExt : public A2dpCodecConfig { + public: + A2dpCodecConfigExt(btav_a2dp_codec_index_t codec_index, bool is_source); + + bool init() override { return false; } + bool useRtpHeaderMarkerBit() const override { return false; } + bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, + uint8_t* p_result_codec_config) override; + bool setPeerCodecCapabilities( + const uint8_t* p_peer_codec_capabilities) override; + + const std::vector& getVendorCodecParameters() const { + return vendor_specific_parameters_; + } + + void setVendorSpecificParameters(std::vector const& parameters) {} + + void setCodecConfig(btav_a2dp_codec_config_t codec_parameters, + uint8_t const codec_config[AVDT_CODEC_SIZE], + std::vector const& vendor_specific_parameters) { + codec_config_ = codec_parameters; + codec_capability_ = codec_parameters; + memcpy(ota_codec_config_, codec_config, sizeof(ota_codec_config_)); + vendor_specific_parameters_ = vendor_specific_parameters; + } + + private: + [[maybe_unused]] bool is_source_; // True if local is Source + std::vector vendor_specific_parameters_; +}; + +// Gets a mock A2DP encoder interface. +// The A2DP source path always sets up the encoder interface, +// whether the codec encoding is offloaded or not. +// |p_codec_info| contains the codec information. +const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterfaceExt( + const uint8_t* p_codec_info); diff --git a/system/stack/include/a2dp_sbc.h b/system/stack/include/a2dp_sbc.h index 4e064bdc87aa4e614853785ada445b8240998bfc..60997c629c6eaf7d7cfd258fc7b661a7501fc9e2 100644 --- a/system/stack/include/a2dp_sbc.h +++ b/system/stack/include/a2dp_sbc.h @@ -21,13 +21,13 @@ #ifndef A2DP_SBC_H #define A2DP_SBC_H -#include #include #include #include "a2dp_codec_api.h" #include "a2dp_sbc_constants.h" #include "avdt_api.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" class A2dpCodecConfigSbcBase : public A2dpCodecConfig { @@ -36,7 +36,7 @@ class A2dpCodecConfigSbcBase : public A2dpCodecConfig { const std::string& name, btav_a2dp_codec_priority_t codec_priority, bool is_source) - : A2dpCodecConfig(codec_index, name, codec_priority), + : A2dpCodecConfig(codec_index, A2DP_CODEC_ID_SBC, name, codec_priority), is_source_(is_source) {} bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; diff --git a/system/stack/include/a2dp_vendor_aptx.h b/system/stack/include/a2dp_vendor_aptx.h index 283cce6c7856f50a7fccf0c0118817a9c82ee964..4dc34e10912b2bacfd51495e6fef44fb4053fe49 100644 --- a/system/stack/include/a2dp_vendor_aptx.h +++ b/system/stack/include/a2dp_vendor_aptx.h @@ -21,13 +21,13 @@ #ifndef A2DP_VENDOR_APTX_H #define A2DP_VENDOR_APTX_H -#include #include #include #include "a2dp_codec_api.h" #include "a2dp_vendor_aptx_constants.h" #include "avdt_api.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" class A2dpCodecConfigAptx : public A2dpCodecConfig { diff --git a/system/stack/include/a2dp_vendor_aptx_hd.h b/system/stack/include/a2dp_vendor_aptx_hd.h index 03e82513a8845751902f51a72bc1a0b0a653bc9f..d8363a776850a84a4972d8bd2922baa77123b401 100644 --- a/system/stack/include/a2dp_vendor_aptx_hd.h +++ b/system/stack/include/a2dp_vendor_aptx_hd.h @@ -21,13 +21,13 @@ #ifndef A2DP_VENDOR_APTX_HD_H #define A2DP_VENDOR_APTX_HD_H -#include #include #include #include "a2dp_codec_api.h" #include "a2dp_vendor_aptx_hd_constants.h" #include "avdt_api.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" class A2dpCodecConfigAptxHd : public A2dpCodecConfig { diff --git a/system/stack/include/a2dp_vendor_ldac.h b/system/stack/include/a2dp_vendor_ldac.h index 0c9734a5024a2a3d1facebc88a51e41973c2774f..b28faa90abae6f03ce9e5a97b065a334a0e7d142 100644 --- a/system/stack/include/a2dp_vendor_ldac.h +++ b/system/stack/include/a2dp_vendor_ldac.h @@ -21,13 +21,13 @@ #ifndef A2DP_VENDOR_LDAC_H #define A2DP_VENDOR_LDAC_H -#include #include #include #include "a2dp_codec_api.h" #include "a2dp_vendor_ldac_constants.h" #include "avdt_api.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" class A2dpCodecConfigLdacBase : public A2dpCodecConfig { @@ -36,7 +36,7 @@ class A2dpCodecConfigLdacBase : public A2dpCodecConfig { const std::string& name, btav_a2dp_codec_priority_t codec_priority, bool is_source) - : A2dpCodecConfig(codec_index, name, codec_priority), + : A2dpCodecConfig(codec_index, A2DP_CODEC_ID_LDAC, name, codec_priority), is_source_(is_source) {} bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; diff --git a/system/stack/include/a2dp_vendor_opus.h b/system/stack/include/a2dp_vendor_opus.h index 16831259199c159a9cfeabc57d8734b8c3bb615c..897c593cedad89fff2015b28f0a682483facfd49 100644 --- a/system/stack/include/a2dp_vendor_opus.h +++ b/system/stack/include/a2dp_vendor_opus.h @@ -31,7 +31,7 @@ class A2dpCodecConfigOpusBase : public A2dpCodecConfig { const std::string& name, btav_a2dp_codec_priority_t codec_priority, bool is_source) - : A2dpCodecConfig(codec_index, name, codec_priority), + : A2dpCodecConfig(codec_index, A2DP_CODEC_ID_OPUS, name, codec_priority), is_source_(is_source) {} bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; diff --git a/system/stack/include/acl_api.h b/system/stack/include/acl_api.h index 68f1ec6a8d5bbfd371b5c8646ee298683a6eb277..34d2d504a3736f6b411c2c48a0a6e1ef15429999 100644 --- a/system/stack/include/acl_api.h +++ b/system/stack/include/acl_api.h @@ -302,8 +302,6 @@ bool acl_peer_supports_ble_connection_subrating(const RawAddress& remote_bda); bool acl_peer_supports_ble_connection_subrating_host( const RawAddress& remote_bda); -void btm_process_cancel_complete(uint8_t status, uint8_t mode); - uint8_t btm_handle_to_acl_index(uint16_t hci_handle); tHCI_REASON btm_get_acl_disc_reason_code(void); @@ -313,10 +311,8 @@ bool btm_is_acl_locally_initiated(void); tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr, tBT_TRANSPORT transport); void btm_acl_device_down(void); -void btm_acl_update_inquiry_status(uint8_t status); void ACL_RegisterClient(struct acl_client_callback_s* callbacks); void ACL_UnregisterClient(struct acl_client_callback_s* callbacks); -bool ACL_SupportTransparentSynchronousData(const RawAddress& bd_addr); void btm_acl_consolidate(const RawAddress& identity_addr, const RawAddress& rpa); diff --git a/system/stack/include/acl_api_types.h b/system/stack/include/acl_api_types.h index 432c839ced5f357ca0c59eaf3120fd8182c75cf9..072c9675d16f4659b75027ef47445bcbbe537c9f 100644 --- a/system/stack/include/acl_api_types.h +++ b/system/stack/include/acl_api_types.h @@ -85,6 +85,8 @@ typedef struct { uint8_t link_quality; } tBTM_LINK_QUALITY_RESULT; -#define BTM_INQUIRY_STARTED 1 -#define BTM_INQUIRY_CANCELLED 2 -#define BTM_INQUIRY_COMPLETE 3 +enum class tBTM_INQUIRY_STATE : uint8_t { + BTM_INQUIRY_STARTED = 1, + BTM_INQUIRY_CANCELLED = 2, + BTM_INQUIRY_COMPLETE = 3, +}; diff --git a/system/stack/include/acl_hci_link_interface.h b/system/stack/include/acl_hci_link_interface.h index e6a1ce1386b5c0d913fed7c9c8a88d5860bc95ed..8e3289424ca369184c762acb05d378d2958eb4be 100644 --- a/system/stack/include/acl_hci_link_interface.h +++ b/system/stack/include/acl_hci_link_interface.h @@ -19,18 +19,18 @@ #include +#include "hci/class_of_device.h" #include "stack/include/bt_hdr.h" #include "stack/include/hci_error_code.h" #include "stack/include/hci_mode.h" #include "stack/include/hcidefs.h" -#include "types/class_of_device.h" #include "types/hci_role.h" #include "types/raw_address.h" // This header contains functions for HCIF-Acl Management to invoke // void btm_connection_request(const RawAddress& bda, - const bluetooth::types::ClassOfDevice& cod); + const bluetooth::hci::ClassOfDevice& cod); void btm_acl_connected(const RawAddress& bda, uint16_t handle, tHCI_STATUS status, uint8_t enc_mode); void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle, @@ -39,9 +39,6 @@ void on_acl_br_edr_failed(const RawAddress& bda, tHCI_STATUS status, bool locally_initiated); void btm_acl_disconnected(tHCI_STATUS status, uint16_t handle, tHCI_STATUS reason); -void btm_acl_iso_disconnected(uint16_t handle, tHCI_STATUS reason); -void btm_acl_encrypt_change(uint16_t handle, uint8_t status, - uint8_t encr_enable); void btm_acl_role_changed(tHCI_STATUS hci_status, const RawAddress& bd_addr, tHCI_ROLE new_role); void btm_rejectlist_role_change_device(const RawAddress& bd_addr, diff --git a/system/stack/include/avct_api.h b/system/stack/include/avct_api.h index 41fb60cc214c902e9292bbc3e5fac0cadb04f5f9..220ac679faf5d09ee9db1bab98b5fcd0dd20bf1e 100644 --- a/system/stack/include/avct_api.h +++ b/system/stack/include/avct_api.h @@ -27,7 +27,7 @@ #include -#include "bt_target.h" +#include "internal_include/bt_target.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" diff --git a/system/stack/include/avdt_api.h b/system/stack/include/avdt_api.h index 606bc62295752eefc3ac2403a87741d0883d3180..301898893f7c30c280e342e51beefb74ab3e6867 100644 --- a/system/stack/include/avdt_api.h +++ b/system/stack/include/avdt_api.h @@ -30,9 +30,9 @@ #include #include -#include "bt_target.h" +#include "internal_include/bt_target.h" #include "macros.h" -#include "osi/include/log.h" +#include "os/log.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" @@ -41,8 +41,6 @@ ****************************************************************************/ #define AVDT_VERSION_1_3 0x0103 -#define AVDTP_VERSION_CONFIG_KEY "AvdtpVersion" - /* Maximum size in bytes of the codec capabilities information element. */ #define AVDT_CODEC_SIZE 20 diff --git a/system/stack/include/avrc_api.h b/system/stack/include/avrc_api.h index 2e3a031d630884f1237695a4730abf69d0fae4c3..8aa6f500fe63388dceddbaaad79b253d08079a8a 100644 --- a/system/stack/include/avrc_api.h +++ b/system/stack/include/avrc_api.h @@ -28,11 +28,12 @@ #include -#include "bt_target.h" +#include "internal_include/bt_target.h" #include "stack/include/avct_api.h" #include "stack/include/avrc_defs.h" #include "stack/include/bt_hdr.h" #include "stack/include/sdp_api.h" +#include "stack/sdp/sdp_discovery_db.h" #include "types/raw_address.h" /***************************************************************************** @@ -149,15 +150,6 @@ "persist.bluetooth.dynamic_avrcp.enable" #endif -/* Avrcp controller version key for bt_config.conf */ -#ifndef AVRCP_CONTROLLER_VERSION_CONFIG_KEY -#define AVRCP_CONTROLLER_VERSION_CONFIG_KEY "AvrcpControllerVersion" -#endif - -#ifndef AV_REM_CTRL_FEATURES_CONFIG_KEY -#define AV_REM_CTRL_FEATURES_CONFIG_KEY "AvrcpPeerFeatures" -#endif - /* Supported categories */ #define AVRC_SUPF_CT_CAT1 0x0001 /* Category 1 */ #define AVRC_SUPF_CT_CAT2 0x0002 /* Category 2 */ diff --git a/system/stack/include/ble_hci_link_interface.h b/system/stack/include/ble_hci_link_interface.h index 4c10c8f3401f1bc62204462c95fbde2df3966909..cedc7cb2d9d6644ef28cbc1138a182a178b4a90b 100644 --- a/system/stack/include/ble_hci_link_interface.h +++ b/system/stack/include/ble_hci_link_interface.h @@ -22,12 +22,8 @@ #include "stack/include/hci_error_code.h" // This header contains functions for HCI-ble to invoke -void btm_ble_process_adv_pkt(uint8_t len, const uint8_t* p); -void btm_ble_process_ext_adv_pkt(uint8_t len, const uint8_t* p); -void btm_ble_process_phy_update_pkt(uint8_t len, uint8_t* p); void btm_ble_read_remote_features_complete(uint8_t* p, uint8_t length); void btm_ble_write_adv_enable_complete(uint8_t* p, uint16_t evt_len); -void btm_ble_create_ll_conn_complete(tHCI_STATUS status); void btm_ble_ltk_request(uint16_t handle, uint8_t rand[8], uint16_t ediv); void btm_ble_test_command_complete(uint8_t* p); void btm_ble_read_resolving_list_entry_complete(const uint8_t* p, diff --git a/system/stack/include/bnep_api.h b/system/stack/include/bnep_api.h index c32449a237ef453fe817dca5320e47b9fb45141c..c02adf237d3417aa2b955a1803d081034a24c275 100644 --- a/system/stack/include/bnep_api.h +++ b/system/stack/include/bnep_api.h @@ -274,13 +274,12 @@ tBNEP_RESULT BNEP_Disconnect(uint16_t handle); * Description This function sends data in a GKI buffer on BNEP connection * * Parameters: handle - handle of the connection to write - * p_dest_addr - BD_ADDR/Ethernet addr of the destination + * dest_addr - BD_ADDR/Ethernet addr of the destination * p_buf - pointer to address of buffer with data * protocol - protocol type of the packet - * p_src_addr - (optional) BD_ADDR/ethernet address of the - * source (should be NULL if it is the local BD - * Addr) - * fw_ext_present - forwarded extensions present + * src_addr - (optional) BD_ADDR/ethernet address of the + * source (should be kEmpty if it is the local + *BD Addr) fw_ext_present - forwarded extensions present * * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid * BNEP_MTU_EXCEDED - If the data length is greater @@ -290,9 +289,9 @@ tBNEP_RESULT BNEP_Disconnect(uint16_t handle); * BNEP_SUCCESS - If written successfully * ******************************************************************************/ -tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, +tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& dest_addr, BT_HDR* p_buf, uint16_t protocol, - const RawAddress* p_src_addr, bool fw_ext_present); + const RawAddress& src_addr, bool fw_ext_present); /******************************************************************************* * @@ -301,13 +300,12 @@ tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, * Description This function sends data over a BNEP connection * * Parameters: handle - handle of the connection to write - * p_dest_addr - BD_ADDR/Ethernet addr of the destination + * dest_addr - BD_ADDR/Ethernet addr of the destination * p_data - pointer to data start * protocol - protocol type of the packet - * p_src_addr - (optional) BD_ADDR/ethernet address of the - * source (should be NULL if it is the local BD - * Addr) - * fw_ext_present - forwarded extensions present + * src_addr - (optional) BD_ADDR/ethernet address of the + * source (should be kEmpty if it is the local + *BD Addr) fw_ext_present - forwarded extensions present * * Returns: BNEP_WRONG_HANDLE - if passed handle is not valid * BNEP_MTU_EXCEDED - If the data length is greater than @@ -318,9 +316,9 @@ tBNEP_RESULT BNEP_WriteBuf(uint16_t handle, const RawAddress& p_dest_addr, * BNEP_SUCCESS - If written successfully * ******************************************************************************/ -tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& p_dest_addr, +tBNEP_RESULT BNEP_Write(uint16_t handle, const RawAddress& dest_addr, uint8_t* p_data, uint16_t len, uint16_t protocol, - const RawAddress* p_src_addr, bool fw_ext_present); + const RawAddress& src_addr, bool fw_ext_present); /******************************************************************************* * diff --git a/system/stack/include/bt_dev_class.h b/system/stack/include/bt_dev_class.h index a0d182db56255dcf1fbd28c4b98f1c6ac7825524..1b2cbb701d1c6bdbde78ab8b21c518cbf32848e7 100644 --- a/system/stack/include/bt_dev_class.h +++ b/system/stack/include/bt_dev_class.h @@ -16,18 +16,14 @@ #pragma once -#ifdef __cplusplus +#include +#include #include -#else -#include -#endif // __cplusplus -#define DEV_CLASS_LEN 3 -typedef uint8_t DEV_CLASS[DEV_CLASS_LEN]; /* Device class */ +constexpr size_t kDevClassLength = 3; +typedef std::array DEV_CLASS; /* Device class */ -#ifdef __cplusplus inline constexpr DEV_CLASS kDevClassEmpty = {}; -#endif // __cplusplus /* 0x00 is used as unclassified for all minor device classes */ #define BTM_COD_MINOR_UNCLASSIFIED 0x00 @@ -102,6 +98,9 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; #define BTM_COD_SERVICE_CLASS_LO_B 0x00E0 #define BTM_COD_SERVICE_CLASS_MASK 0xFFE0 +inline constexpr DEV_CLASS kDevClassUnclassified = { + 0x00, BTM_COD_MAJOR_UNCLASSIFIED, BTM_COD_MINOR_UNCLASSIFIED}; + /* class of device field macros */ #define BTM_COD_MINOR_CLASS(u8, pd) \ { (u8) = (pd)[2] & BTM_COD_MINOR_CLASS_MASK; } @@ -122,13 +121,6 @@ inline constexpr DEV_CLASS kDevClassEmpty = {}; (pd)[0] = (sv) >> 8; \ } -#ifdef __cplusplus -inline void dev_class_copy(DEV_CLASS& dst, const DEV_CLASS& src) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; -} - #include inline std::string dev_class_text(const DEV_CLASS& dev_class) { std::ostringstream oss; @@ -141,18 +133,17 @@ inline std::string dev_class_text(const DEV_CLASS& dev_class) { << std::to_string(sv); return oss.str(); } -#endif // __cplusplus -#define DEVCLASS_TO_STREAM(p, a) \ - { \ - int ijk; \ - for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) \ - *(p)++ = (uint8_t)(a)[DEV_CLASS_LEN - 1 - ijk]; \ +#define DEVCLASS_TO_STREAM(p, a) \ + { \ + size_t ijk; \ + for (ijk = 0; ijk < kDevClassLength; ijk++) \ + *(p)++ = (a)[kDevClassLength - 1 - ijk]; \ } -#define STREAM_TO_DEVCLASS(a, p) \ - { \ - int ijk; \ - uint8_t* _pa = (uint8_t*)(a) + DEV_CLASS_LEN - 1; \ - for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *(p)++; \ +#define STREAM_TO_DEVCLASS(a, p) \ + { \ + size_t ijk; \ + uint8_t* _pa = a.data() + kDevClassLength - 1; \ + for (ijk = 0; ijk < kDevClassLength; ijk++) *_pa-- = *(p)++; \ } diff --git a/system/stack/include/bt_name.h b/system/stack/include/bt_name.h index 5d71549cf671272a2dd12a56e996757333306105..80a89c62e9d4873ccbcbaf037e0db4155eb860fb 100644 --- a/system/stack/include/bt_name.h +++ b/system/stack/include/bt_name.h @@ -47,6 +47,7 @@ typedef uint8_t tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1]; #include "osi/include/compat.h" // strlcpy inline constexpr tBTM_BD_NAME kBtmBdNameEmpty = {}; constexpr size_t kBdNameLength = static_cast(BD_NAME_LEN); +constexpr uint8_t kBdNameDelim = (uint8_t)NULL; inline size_t bd_name_copy(BD_NAME bd_name_dest, const char* src) { return strlcpy(reinterpret_cast(bd_name_dest), const_cast(src), diff --git a/system/stack/include/bt_octets.h b/system/stack/include/bt_octets.h index 3a90164e1d7e5239f243ae4e7717eb5f6f990a0a..11a48a84ef2d3f7c696a495a90f65ed609b045bf 100644 --- a/system/stack/include/bt_octets.h +++ b/system/stack/include/bt_octets.h @@ -18,7 +18,7 @@ #include -#include "gd/hci/octets.h" +#include "hci/octets.h" using Octet16 = bluetooth::hci::Octet16; using LinkKey = bluetooth::hci::Octet16; /* Link Key */ diff --git a/system/stack/include/bt_types.h b/system/stack/include/bt_types.h index 1831b83dd808a16d8a7e4171e15365149b2c207c..f4c77022fddb56501b072d86ad0e988d1e31344a 100644 --- a/system/stack/include/bt_types.h +++ b/system/stack/include/bt_types.h @@ -21,7 +21,6 @@ #include -#include "stack/include/bt_dev_class.h" #include "stack/include/bt_device_type.h" #include "stack/include/bt_hdr.h" #ifdef __cplusplus diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h index 24fe955de8f65a32a6c4fb9e2d8b9c2cdaf43990..4457931e5d32452d0878128c6b4cd59804a7033f 100644 --- a/system/stack/include/btm_api.h +++ b/system/stack/include/btm_api.h @@ -117,10 +117,10 @@ tBTM_STATUS BTM_ReadLocalDeviceNameFromController( * * Description This function is called to read the local device class * - * Returns pointer to the device class + * Returns the device class * ******************************************************************************/ -uint8_t* BTM_ReadDeviceClass(void); +DEV_CLASS BTM_ReadDeviceClass(void); /******************************************************************************* * diff --git a/system/stack/include/btm_api_types.h b/system/stack/include/btm_api_types.h index be170ca65b7bf5ee1b8c036a0900a03a7c020633..eec25a40d907b5a725575bd1dd9a36399d548cdb 100644 --- a/system/stack/include/btm_api_types.h +++ b/system/stack/include/btm_api_types.h @@ -89,8 +89,6 @@ typedef void(tBTM_VSC_CMPL_CB)(tBTM_VSC_CMPL* p1); /*************************** * Device Discovery Types ***************************/ -/* Definitions of the parameters passed to BTM_StartInquiry. - */ constexpr uint8_t BLE_EVT_CONNECTABLE_BIT = 0; constexpr uint8_t BLE_EVT_SCANNABLE_BIT = 1; constexpr uint8_t BLE_EVT_DIRECTED_BIT = 2; diff --git a/system/stack/include/btm_ble_api.h b/system/stack/include/btm_ble_api.h index 2260a2257f224261a9e60eed1d005e5a50f01607..582093f69fef50cdae67a50f46a13e020552e20f 100644 --- a/system/stack/include/btm_ble_api.h +++ b/system/stack/include/btm_ble_api.h @@ -71,49 +71,6 @@ void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB* p_cmn_vsc_cb); void BTM_BleGetDynamicAudioBuffer( tBTM_BT_DYNAMIC_AUDIO_BUFFER_CB* p_dynamic_audio_buffer_cb); -/******************************************************************************* - * - * Function BTM_BleSetStorageConfig - * - * Description This function is called to setup storage configuration and - * setup callbacks. - * - * Parameters uint8_t batch_scan_full_max -Batch scan full maximum - uint8_t batch_scan_trunc_max - Batch scan truncated value - maximum - uint8_t batch_scan_notify_threshold - Threshold value - cb - Setup callback - tBTM_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback -Threshold - callback - void *p_ref - Reference value - * - * - ******************************************************************************/ -void BTM_BleSetStorageConfig(uint8_t batch_scan_full_max, - uint8_t batch_scan_trunc_max, - uint8_t batch_scan_notify_threshold, - base::Callback cb, - tBTM_BLE_SCAN_THRESHOLD_CBACK* p_thres_cback, - tBTM_BLE_REF_VALUE ref_value); - -/* This function is called to enable batch scan */ -void BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode, - uint32_t scan_interval, uint32_t scan_window, - tBTM_BLE_DISCARD_RULE discard_rule, - tBLE_ADDR_TYPE addr_type, - base::Callback cb); - -/* This function is called to disable batch scanning */ -void BTM_BleDisableBatchScan(base::Callback cb); - -/* This function is called to read batch scan reports */ -void BTM_BleReadScanReports(tBLE_SCAN_MODE scan_mode, - tBTM_BLE_SCAN_REP_CBACK cb); - -/* This function is called to setup the callback for tracking */ -void BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK* p_track_cback, - tBTM_BLE_REF_VALUE ref_value); - /******************************************************************************* * * Function BTM_BleObserve @@ -474,105 +431,6 @@ void btm_ble_periodic_adv_sync_lost(uint16_t sync_handle); void btm_ble_biginfo_adv_report_rcvd(const uint8_t* param, uint16_t param_len); void btm_ble_periodic_adv_sync_tx_rcvd(const uint8_t* param, uint16_t param_len); -/******************************************************************************* - * - * Function BTM_BleStartPeriodicSync - * - * Description This function is called to invoke HCI Command - * HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC to synchronize to - * PA train specified in input parameters. - * - * Parameters PA train info corresponding to particualr PA train and - * callbacks to sync established, pa report and sync lost - *events - * - * Returns void - * - ******************************************************************************/ -void BTM_BleStartPeriodicSync(uint8_t adv_sid, RawAddress address, - uint16_t skip, uint16_t timeout, - StartSyncCb syncCb, SyncReportCb reportCb, - SyncLostCb lostCb, - BigInfoReportCb biginfo_reportCb); -/******************************************************************************* - * - * Function BTM_BleStopPeriodicSync - * - * Description This function is called to invoke HCI Command - * HCI_LE_PERIODIC_ADVERTISING_TERMINATE_SYNC to stop - *synchronising to PA train. - * - * Parameters sync handle - * - * Returns void - * - ******************************************************************************/ -void BTM_BleStopPeriodicSync(uint16_t handle); -/******************************************************************************* - * - * Function BTM_BleCancelPeriodicSync - * - * Description This function is called to invoke HCI Command - * HCI_LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL to - * cancel pending sync to PA train. - * - * Parameters adv sid, address corrosponds to PA train - * - * Returns void - * - ******************************************************************************/ -void BTM_BleCancelPeriodicSync(uint8_t adv_sid, RawAddress address); - -using SyncTransferCb = base::Callback; - -/******************************************************************************* - * - * Function BTM_BlePeriodicSyncTransfer - * - * Description This function is called to invoke HCI Command - * HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER to transfer - * sync info of remote advertiser to connected remote device - * - * Parameters PAST specific parameters - * - * Returns void - * - ******************************************************************************/ -void BTM_BlePeriodicSyncTransfer(RawAddress addr, uint16_t service_data, - uint16_t sync_handle, SyncTransferCb cb); -/******************************************************************************* - * - * Function BTM_BlePeriodicSyncSetInfo - * - * Description This function is called to invoke HCI Command - * HCI_LE_SET_PERIODIC_ADVERTISING_SET_INFO_TRANSFER to - *transfer colocated advertiser sync info to connected remote device - * - * Parameters PAST specific parameters - * - * Returns void - * - ******************************************************************************/ -void BTM_BlePeriodicSyncSetInfo(RawAddress addr, uint16_t service_data, - uint8_t adv_handle, SyncTransferCb cb); -/******************************************************************************* - * - * Function BTM_BlePeriodicSyncTxParameters - * - * Description This function is called to invoke HCI Command - * HCI_LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS, - * this command is used to specify how BT SoC will process PA - * sync information received from the remote device identified - * by the addr. - * - * Parameters HCI command specific parameters - * - * Returns void - * - ******************************************************************************/ -void BTM_BlePeriodicSyncTxParameters(RawAddress addr, uint8_t mode, - uint16_t skip, uint16_t timeout, - StartSyncCb syncCb); /******************************************************************************* * diff --git a/system/stack/include/btm_ble_api_types.h b/system/stack/include/btm_ble_api_types.h index 07f5bd9963026598d2362c0d23ae95af65667db6..d3519f0632ca8a2f33dbe84e475710c486adbfa7 100644 --- a/system/stack/include/btm_ble_api_types.h +++ b/system/stack/include/btm_ble_api_types.h @@ -334,6 +334,7 @@ typedef struct { uint8_t quality_report_support; uint32_t dynamic_audio_buffer_support; uint16_t adv_filter_extended_features_mask; + uint8_t a2dp_offload_v2_support; } tBTM_BLE_VSC_CB; /* Stored the default/maximum/minimum buffer time for dynamic audio buffer. diff --git a/system/stack/include/btm_client_interface.h b/system/stack/include/btm_client_interface.h index da6dc02d1d4a662576422f18366196ada3f8a8ae..a1970f6030f36ab06319065e7b3627af5c2a4a83 100644 --- a/system/stack/include/btm_client_interface.h +++ b/system/stack/include/btm_client_interface.h @@ -23,7 +23,6 @@ #include "stack/btm/power_mode.h" #include "stack/include/acl_client_callbacks.h" #include "stack/include/bt_hdr.h" -#include "stack/include/bt_octets.h" #include "stack/include/btm_api_types.h" #include "stack/include/btm_ble_api_types.h" #include "stack/include/btm_status.h" @@ -51,10 +50,6 @@ struct btm_client_interface_t { // Acl peer and lifecycle struct { - struct { - bool (*SupportTransparentSynchronousData)(const RawAddress& bd_addr); - } features; - bool (*BTM_IsAclConnectionUp)(const RawAddress& bd_addr, tBT_TRANSPORT transport); bool (*BTM_ReadConnectedTransportAddress)(RawAddress* bd_addr, @@ -104,10 +99,6 @@ struct btm_client_interface_t { bool low_latency_scan); tBTM_STATUS (*BTM_SetBleDataLength)(const RawAddress& bd_addr, uint16_t tx_pdu_length); - void (*BTM_BleConfirmReply)(const RawAddress& bd_addr, uint8_t res); - void (*BTM_BleLoadLocalKeys)(uint8_t key_type, tBTM_BLE_LOCAL_KEYS* p_key); - void (*BTM_BlePasskeyReply)(const RawAddress& bd_addr, uint8_t res, - uint32_t passkey); void (*BTM_BleReadControllerFeatures)( tBTM_BLE_CTRL_FEATURES_CBACK* p_vsc_cback); void (*BTM_BleSetConnScanParams)(uint32_t scan_interval, @@ -143,7 +134,7 @@ struct btm_client_interface_t { tBTM_STATUS (*BTM_SetLocalDeviceName)(const char* p_name); tBTM_STATUS (*BTM_SetDeviceClass)(DEV_CLASS dev_class); bool (*BTM_IsDeviceUp)(); - uint8_t* (*BTM_ReadDeviceClass)(); + DEV_CLASS (*BTM_ReadDeviceClass)(); } local; struct { diff --git a/system/stack/include/btm_sec_api.h b/system/stack/include/btm_sec_api.h index 3997733bab31498dc47f7bb3b8871f22ab8f42bc..cf588e47f17f9b540c594809ab25bb5bd4ce0f00 100644 --- a/system/stack/include/btm_sec_api.h +++ b/system/stack/include/btm_sec_api.h @@ -44,7 +44,7 @@ * Returns true if added OK, else false * ******************************************************************************/ -bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class, +bool BTM_SecAddDevice(const RawAddress& bd_addr, const DEV_CLASS dev_class, const BD_NAME& bd_name, uint8_t* features, LinkKey* link_key, uint8_t key_type, uint8_t pin_length); diff --git a/system/stack/include/btm_sec_api_types.h b/system/stack/include/btm_sec_api_types.h index 21ea173c0116d113f61221215e3f0ab3c0833412..77985ec4e555cab76cc8f5834f301e13158ad1c6 100644 --- a/system/stack/include/btm_sec_api_types.h +++ b/system/stack/include/btm_sec_api_types.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -173,7 +174,7 @@ typedef uint8_t tBTM_LINK_KEY_TYPE; * trusted services ******************************************************************************/ -enum { +typedef enum : uint8_t { BTM_SP_IO_REQ_EVT, /* received IO_CAPABILITY_REQUEST event */ BTM_SP_IO_RSP_EVT, /* received IO_CAPABILITY_RESPONSE event */ BTM_SP_CFM_REQ_EVT, /* received USER_CONFIRMATION_REQUEST event */ @@ -181,8 +182,21 @@ enum { BTM_SP_KEY_REQ_EVT, /* received USER_PASSKEY_REQUEST event */ BTM_SP_LOC_OOB_EVT, /* received result for READ_LOCAL_OOB_DATA command */ BTM_SP_RMT_OOB_EVT, /* received REMOTE_OOB_DATA_REQUEST event */ -}; -typedef uint8_t tBTM_SP_EVT; +} tBTM_SP_EVT; + +inline std::string sp_evt_to_text(const tBTM_SP_EVT evt) { + switch (evt) { + CASE_RETURN_TEXT(BTM_SP_IO_REQ_EVT); + CASE_RETURN_TEXT(BTM_SP_IO_RSP_EVT); + CASE_RETURN_TEXT(BTM_SP_CFM_REQ_EVT); + CASE_RETURN_TEXT(BTM_SP_KEY_NOTIF_EVT); + CASE_RETURN_TEXT(BTM_SP_KEY_REQ_EVT); + CASE_RETURN_TEXT(BTM_SP_LOC_OOB_EVT); + CASE_RETURN_TEXT(BTM_SP_RMT_OOB_EVT); + } + + return base::StringPrintf("UNKNOWN[%hhu]", evt); +} enum : uint8_t { BTM_IO_CAP_OUT = 0, /* DisplayOnly */ @@ -372,35 +386,65 @@ typedef tBTM_SEC_CALLBACK tBTM_SEC_CALLBACK; */ typedef void(tBTM_BOND_CANCEL_CMPL_CALLBACK)(tBTM_STATUS result); -/* LE related event and data structure */ -/* received IO_CAPABILITY_REQUEST event */ -#define BTM_LE_IO_REQ_EVT SMP_IO_CAP_REQ_EVT -/* security request event */ -#define BTM_LE_SEC_REQUEST_EVT SMP_SEC_REQUEST_EVT -/* received USER_PASSKEY_NOTIFY event */ -#define BTM_LE_KEY_NOTIF_EVT SMP_PASSKEY_NOTIF_EVT -/* received USER_PASSKEY_REQUEST event */ -#define BTM_LE_KEY_REQ_EVT SMP_PASSKEY_REQ_EVT -/* OOB data request event */ -#define BTM_LE_OOB_REQ_EVT SMP_OOB_REQ_EVT -/* Numeric Comparison request event */ -#define BTM_LE_NC_REQ_EVT SMP_NC_REQ_EVT -/* Peer keypress notification recd event */ -#define BTM_LE_PR_KEYPR_NOT_EVT SMP_PEER_KEYPR_NOT_EVT -/* SC OOB request event (both local and peer OOB data) can be expected in - * response */ -#define BTM_LE_SC_OOB_REQ_EVT SMP_SC_OOB_REQ_EVT -/* SC OOB local data set is created (as result of SMP_CrLocScOobData(...)) */ -#define BTM_LE_SC_LOC_OOB_EVT SMP_SC_LOC_OOB_DATA_UP_EVT -/* SMP complete event */ -#define BTM_LE_COMPLT_EVT SMP_COMPLT_EVT -#define BTM_LE_LAST_FROM_SMP SMP_BR_KEYS_REQ_EVT -/* KEY update event */ -#define BTM_LE_KEY_EVT (BTM_LE_LAST_FROM_SMP + 1) -#define BTM_LE_CONSENT_REQ_EVT SMP_CONSENT_REQ_EVT -/* Identity address associate event */ -#define BTM_LE_ADDR_ASSOC_EVT SMP_LE_ADDR_ASSOC_EVT -typedef uint8_t tBTM_LE_EVT; +typedef enum : uint8_t { + /* LE related event and data structure */ + /* received IO_CAPABILITY_REQUEST event */ + BTM_LE_IO_REQ_EVT = SMP_IO_CAP_REQ_EVT, + /* security request event */ + BTM_LE_SEC_REQUEST_EVT = SMP_SEC_REQUEST_EVT, + + /* received USER_PASSKEY_NOTIFY event */ + BTM_LE_KEY_NOTIF_EVT = SMP_PASSKEY_NOTIF_EVT, + + /* received USER_PASSKEY_REQUEST event */ + BTM_LE_KEY_REQ_EVT = SMP_PASSKEY_REQ_EVT, + + /* OOB data request event */ + BTM_LE_OOB_REQ_EVT = SMP_OOB_REQ_EVT, + + /* Numeric Comparison request event */ + BTM_LE_NC_REQ_EVT = SMP_NC_REQ_EVT, + + /* Peer keypress notification recd event */ + BTM_LE_PR_KEYPR_NOT_EVT = SMP_PEER_KEYPR_NOT_EVT, + + /* SC OOB request event (both local and peer OOB data) can be expected in + * response */ + BTM_LE_SC_OOB_REQ_EVT = SMP_SC_OOB_REQ_EVT, + + /* SC OOB local data set is created (as result of SMP_CrLocScOobData(...)) */ + BTM_LE_SC_LOC_OOB_EVT = SMP_SC_LOC_OOB_DATA_UP_EVT, + /* SMP complete event */ + BTM_LE_COMPLT_EVT = SMP_COMPLT_EVT, + BTM_LE_LAST_FROM_SMP = SMP_BR_KEYS_REQ_EVT, + /* KEY update event */ + BTM_LE_KEY_EVT = (BTM_LE_LAST_FROM_SMP + 1), + BTM_LE_CONSENT_REQ_EVT = SMP_CONSENT_REQ_EVT, + + /* Identity address associate event */ + BTM_LE_ADDR_ASSOC_EVT = SMP_LE_ADDR_ASSOC_EVT, +} tBTM_LE_EVT; + +inline std::string ble_evt_to_text(const tBTM_LE_EVT evt) { + switch (evt) { + CASE_RETURN_TEXT(BTM_LE_IO_REQ_EVT); + CASE_RETURN_TEXT(BTM_LE_SEC_REQUEST_EVT); + CASE_RETURN_TEXT(BTM_LE_KEY_NOTIF_EVT); + CASE_RETURN_TEXT(BTM_LE_KEY_REQ_EVT); + CASE_RETURN_TEXT(BTM_LE_OOB_REQ_EVT); + CASE_RETURN_TEXT(BTM_LE_NC_REQ_EVT); + CASE_RETURN_TEXT(BTM_LE_PR_KEYPR_NOT_EVT); + CASE_RETURN_TEXT(BTM_LE_SC_OOB_REQ_EVT); + CASE_RETURN_TEXT(BTM_LE_SC_LOC_OOB_EVT); + CASE_RETURN_TEXT(BTM_LE_COMPLT_EVT); + CASE_RETURN_TEXT(BTM_LE_LAST_FROM_SMP); + CASE_RETURN_TEXT(BTM_LE_KEY_EVT); + CASE_RETURN_TEXT(BTM_LE_CONSENT_REQ_EVT); + CASE_RETURN_TEXT(BTM_LE_ADDR_ASSOC_EVT); + } + + return base::StringPrintf("UNKNOWN[%hhu]", evt); +} enum : uint8_t { BTM_LE_KEY_NONE = 0, @@ -481,3 +525,10 @@ inline std::string bond_type_text(const tBTM_BOND_TYPE& bond_type) { return base::StringPrintf("UNKNOWN[%hhu]", bond_type); } } + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/include/dev_hci_link_interface.h b/system/stack/include/dev_hci_link_interface.h index 81cd138a20dbd0fc242c3e68005bd561c8f7592e..36455f417ec949b73ea8120ed58f41edc1fde861 100644 --- a/system/stack/include/dev_hci_link_interface.h +++ b/system/stack/include/dev_hci_link_interface.h @@ -21,8 +21,6 @@ #include -#include "types/raw_address.h" - void btm_delete_stored_link_key_complete(uint8_t* p, uint16_t evt_len); void btm_vendor_specific_evt(const uint8_t* p, uint8_t evt_len); void btm_read_local_name_complete(uint8_t* p, uint16_t evt_len); diff --git a/system/stack/include/gatt_api.h b/system/stack/include/gatt_api.h index 942cea1f287d2921b5ae047402840636d0e6163d..60a8c1a04a6b52f1b8d19a129b2e55b6ad2a89f9 100644 --- a/system/stack/include/gatt_api.h +++ b/system/stack/include/gatt_api.h @@ -19,16 +19,20 @@ #define GATT_API_H #include +#include #include #include #include -#include "bt_target.h" #include "btm_ble_api.h" #include "gattdefs.h" #include "hardware/bt_gatt_types.h" +#include "include/hardware/bt_common_types.h" +#include "internal_include/bt_target.h" #include "macros.h" +#include "stack/include/btm_ble_api_types.h" +#include "stack/include/hci_error_code.h" #include "types/bluetooth/uuid.h" #include "types/bt_transport.h" #include "types/raw_address.h" @@ -59,7 +63,6 @@ typedef enum GattStatus : uint8_t { GATT_DATABASE_OUT_OF_SYNC = 0x12, GATT_VALUE_NOT_ALLOWED = 0x13, GATT_ILLEGAL_PARAMETER = 0x87, - GATT_TOO_SHORT = 0x7f, GATT_NO_RESOURCES = 0x80, GATT_INTERNAL_ERROR = 0x81, GATT_WRONG_STATE = 0x82, @@ -69,7 +72,6 @@ typedef enum GattStatus : uint8_t { GATT_CMD_STARTED = 0x86, GATT_PENDING = 0x88, GATT_AUTH_FAIL = 0x89, - GATT_MORE = 0x8a, GATT_INVALID_CFG = 0x8b, GATT_SERVICE_STARTED = 0x8c, GATT_ENCRYPED_MITM = GATT_SUCCESS, @@ -79,6 +81,7 @@ typedef enum GattStatus : uint8_t { GATT_DUP_REG = 0x90, /* 0x90 */ GATT_ALREADY_OPEN = 0x91, /* 0x91 */ GATT_CANCEL = 0x92, /* 0x92 */ + GATT_CONNECTION_TIMEOUT = 0x93, /* = 0xE0 ~ 0xFC reserved for future use */ /* Client Characteristic Configuration Descriptor Improperly Configured */ @@ -112,7 +115,6 @@ inline std::string gatt_status_text(const tGATT_STATUS& status) { CASE_RETURN_TEXT(GATT_DATABASE_OUT_OF_SYNC); CASE_RETURN_TEXT(GATT_VALUE_NOT_ALLOWED); CASE_RETURN_TEXT(GATT_ILLEGAL_PARAMETER); - CASE_RETURN_TEXT(GATT_TOO_SHORT); CASE_RETURN_TEXT(GATT_NO_RESOURCES); CASE_RETURN_TEXT(GATT_INTERNAL_ERROR); CASE_RETURN_TEXT(GATT_WRONG_STATE); @@ -122,7 +124,6 @@ inline std::string gatt_status_text(const tGATT_STATUS& status) { CASE_RETURN_TEXT(GATT_CMD_STARTED); CASE_RETURN_TEXT(GATT_PENDING); CASE_RETURN_TEXT(GATT_AUTH_FAIL); - CASE_RETURN_TEXT(GATT_MORE); CASE_RETURN_TEXT(GATT_INVALID_CFG); CASE_RETURN_TEXT(GATT_SERVICE_STARTED); CASE_RETURN_TEXT(GATT_ENCRYPED_NO_MITM); @@ -131,6 +132,7 @@ inline std::string gatt_status_text(const tGATT_STATUS& status) { CASE_RETURN_TEXT(GATT_DUP_REG); CASE_RETURN_TEXT(GATT_ALREADY_OPEN); CASE_RETURN_TEXT(GATT_CANCEL); + CASE_RETURN_TEXT(GATT_CONNECTION_TIMEOUT); CASE_RETURN_TEXT(GATT_CCC_CFG_ERR); CASE_RETURN_TEXT(GATT_PRC_IN_PROGRESS); CASE_RETURN_TEXT(GATT_OUT_OF_RANGE); @@ -267,7 +269,7 @@ typedef enum : uint16_t { GATT_CONN_TIMEOUT = HCI_ERR_CONNECTION_TOUT, /* 0x13 connection terminate by peer user */ GATT_CONN_TERMINATE_PEER_USER = HCI_ERR_PEER_USER, - /* 0x16 connectionterminated by local host */ + /* 0x16 connection terminated by local host */ GATT_CONN_TERMINATE_LOCAL_HOST = HCI_ERR_CONN_CAUSE_LOCAL_HOST, /* 0x22 connection fail for LMP response tout */ GATT_CONN_LMP_TIMEOUT = HCI_ERR_LMP_RESPONSE_TIMEOUT, @@ -485,7 +487,7 @@ typedef uint8_t tGATT_AUTH_REQ; typedef struct { uint16_t conn_id; uint16_t handle; /* attribute handle */ - uint16_t offset; /* attribute value offset, if no offfset is needed for the + uint16_t offset; /* attribute value offset, if no offset is needed for the command, ignore it */ uint16_t len; /* length of attribute value */ tGATT_AUTH_REQ auth_req; /* authentication request */ @@ -519,7 +521,7 @@ typedef struct { /* write request data */ typedef struct { uint16_t handle; /* attribute handle */ - uint16_t offset; /* attribute value offset, if no offfset is needed for the + uint16_t offset; /* attribute value offset, if no offset is needed for the command, ignore it */ uint16_t len; /* length of attribute value */ uint8_t value[GATT_MAX_ATTR_LEN]; /* the actual attribute value */ @@ -564,7 +566,7 @@ typedef enum : uint8_t { GATT_DISC_CHAR, /* discover characteristics of a service with/without type requirement */ GATT_DISC_CHAR_DSCPT, /* discover characteristic descriptors of a character */ - GATT_DISC_MAX /* maximnun discover type */ + GATT_DISC_MAX /* maximum discover type */ } tGATT_DISC_TYPE; /* GATT read type enumeration @@ -617,7 +619,7 @@ typedef struct { */ typedef union { tGATT_READ_BY_TYPE service; - tGATT_READ_BY_TYPE char_type; /* characterisitc type */ + tGATT_READ_BY_TYPE char_type; /* characteristic type */ tGATT_READ_MULTI read_multiple; tGATT_READ_BY_HANDLE by_handle; tGATT_READ_PARTIAL partial; @@ -652,7 +654,7 @@ typedef enum : uint8_t { /* characteristic declaration */ typedef struct { - tGATT_CHAR_PROP char_prop; /* characterisitc properties */ + tGATT_CHAR_PROP char_prop; /* characteristic properties */ uint16_t val_handle; /* characteristic value attribute handle */ bluetooth::Uuid char_uuid; /* characteristic UUID type */ } tGATT_CHAR_DCLR_VAL; @@ -797,8 +799,8 @@ typedef union { uint8_t num_clients; } tGATTS_SRV_CHG_RSP; -/* Attibute server handle ranges NV storage callback functions -*/ +/* Attribute server handle ranges NV storage callback functions + */ typedef void(tGATTS_NV_SAVE_CBACK)(bool is_saved, tGATTS_HNDL_RANGE* p_hndl_range); typedef bool(tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, @@ -830,7 +832,7 @@ typedef struct { * NV save callback function. There can be one and only one * NV save callback function. * - * Parameter p_cb_info : callback informaiton + * Parameter p_cb_info : callback information * * Returns true if registered OK, else false * @@ -899,7 +901,7 @@ void GATTS_StopService(uint16_t service_handle); * val_len: Length of the indicated attribute value. * p_val: Pointer to the indicated attribute value data. * - * Returns GATT_SUCCESS if sucessfully sent or queued; otherwise error + * Returns GATT_SUCCESS if successfully sent or queued; otherwise error * code. * ******************************************************************************/ @@ -918,7 +920,7 @@ tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle, * val_len: Length of the indicated attribute value. * p_val: Pointer to the indicated attribute value data. * - * Returns GATT_SUCCESS if sucessfully sent; otherwise error code. + * Returns GATT_SUCCESS if successfully sent; otherwise error code. * ******************************************************************************/ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id, @@ -936,7 +938,7 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id, * status: response status * p_msg: pointer to message parameters structure. * - * Returns GATT_SUCCESS if sucessfully sent; otherwise error code. + * Returns GATT_SUCCESS if successfully sent; otherwise error code. * ******************************************************************************/ tGATT_STATUS GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, @@ -982,7 +984,7 @@ void GATTC_UpdateUserAttMtuIfNeeded(const RawAddress& remote_bda, * Function GATTC_TryMtuRequest * * Description This function shall be called before calling - * GATTC_ConfgureMTU in order to check if operation is + * GATTC_ConfigureMTU in order to check if operation is * available to do. * * Parameters remote_bda : peer device address. (input) @@ -1102,7 +1104,7 @@ tGATT_STATUS GATTC_SendHandleValueConfirm(uint16_t conn_id, uint16_t handle); * Function GATT_SetIdleTimeout * * Description This function (common to both client and server) sets the - * idle timeout for a tansport connection + * idle timeout for a transport connection * * Parameter bd_addr: target device bd address. * idle_tout: timeout value in seconds. @@ -1144,7 +1146,7 @@ tGATT_IF GATT_Register(const bluetooth::Uuid& p_app_uuid128, * * Description This function deregistered the application from GATT. * - * Parameters gatt_if: applicaiton interface. + * Parameters gatt_if: application interface. * * Returns None. * @@ -1159,7 +1161,7 @@ void GATT_Deregister(tGATT_IF gatt_if); * receiving callbacks for registered interface. Function may * call back with connection status and queued notifications * - * Parameter gatt_if: applicaiton interface. + * Parameter gatt_if: application interface. * * Returns None * @@ -1170,10 +1172,10 @@ void GATT_StartIf(tGATT_IF gatt_if); * * Function GATT_Connect * - * Description This function initiate a connecttion to a remote device on + * Description This function initiate a connection to a remote device on * GATT channel. * - * Parameters gatt_if: applicaiton interface + * Parameters gatt_if: application interface * bd_addr: peer device address * addr_type: peer device address type * connection_type: connection type @@ -1208,7 +1210,7 @@ bool GATT_Connect(tGATT_IF gatt_if, const RawAddress& bd_addr, * disconnect, typically used for direct connection * cancellation. * bd_addr: peer device address. - * is_direct: is a direct conenection or a background auto + * is_direct: is a direct connection or a background auto * connection * * Returns true if connection started; else false @@ -1238,12 +1240,12 @@ tGATT_STATUS GATT_Disconnect(uint16_t conn_id); * application interface * * Parameters conn_id: connection id (input) - * p_gatt_if: applicaiton interface (output) + * p_gatt_if: application interface (output) * bd_addr: peer device address. (output) * transport : physical transport of the GATT connection * (BR/EDR or LE) * - * Returns true the ligical link information is found for conn_id + * Returns true the logical link information is found for conn_id * ******************************************************************************/ bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if, @@ -1256,13 +1258,13 @@ bool GATT_GetConnectionInfor(uint16_t conn_id, tGATT_IF* p_gatt_if, * Description Find the conn_id if the logical link for a BD address * and application interface is connected * - * Parameters gatt_if: applicaiton interface (input) + * Parameters gatt_if: application interface (input) * bd_addr: peer device address. (input) * p_conn_id: connection id (output) * transport : physical transport of the GATT connection * (BR/EDR or LE) * - * Returns true the ligical link is connected + * Returns true the logical link is connected * ******************************************************************************/ bool GATT_GetConnIdIfConnected(tGATT_IF gatt_if, const RawAddress& bd_addr, @@ -1298,4 +1300,18 @@ void gatt_reset_bgdev_list(bool after_reset); // Initialize GATTS list of bonded device service change updates. void gatt_load_bonded(void); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter { +}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* GATT_API_H */ diff --git a/system/stack/include/hci_error_code.h b/system/stack/include/hci_error_code.h index 20acb745868d657f87fe01aa1002786002faf66d..af6c35281775489882c5060b11b7c9362cc67735 100644 --- a/system/stack/include/hci_error_code.h +++ b/system/stack/include/hci_error_code.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include @@ -147,3 +148,8 @@ inline tHCI_REASON to_hci_reason_code(const uint8_t& reason_code) { if (reason_code > _HCI_ERR_MAX_ERR) return HCI_ERR_UNDEFINED; return static_cast(reason_code); } + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/include/hcidefs.h b/system/stack/include/hcidefs.h index 9cc8be39d5bab686b67bb28319d8a1a2345e0bd2..ce79afaac33a55cecc2d33404657e00c4589787c 100644 --- a/system/stack/include/hcidefs.h +++ b/system/stack/include/hcidefs.h @@ -433,9 +433,6 @@ /* Multi adv opcode */ #define HCI_BLE_MULTI_ADV (0x0154 | HCI_GRP_VENDOR_SPECIFIC) -/* Batch scan opcode */ -#define HCI_BLE_BATCH_SCAN (0x0156 | HCI_GRP_VENDOR_SPECIFIC) - /* ADV filter opcode */ #define HCI_BLE_ADV_FILTER (0x0157 | HCI_GRP_VENDOR_SPECIFIC) diff --git a/system/stack/include/hcimsgs.h b/system/stack/include/hcimsgs.h index 2638220996749c7d55d28c1db6dd1feaffbeedf8..8713ccce985f82a8c6f768d70f5c4a4eb3069a95 100644 --- a/system/stack/include/hcimsgs.h +++ b/system/stack/include/hcimsgs.h @@ -43,9 +43,6 @@ enum hci_data_direction_t { namespace bluetooth::legacy::hci { class Interface { public: - virtual void StartInquiry(const LAP inq_lap, uint8_t duration, - uint8_t response_cnt) const = 0; - virtual void InquiryCancel() const = 0; virtual void Disconnect(uint16_t handle, uint8_t reason) const = 0; virtual void ChangeConnectionPacketType(uint16_t handle, uint16_t packet_types) const = 0; diff --git a/system/stack/include/hiddefs.h b/system/stack/include/hiddefs.h index aadafdb49109f2a1ce76180f91faf7808d134de5..3f051fcde1e0fa35f637b7ae0ca0c06bf726b581 100644 --- a/system/stack/include/hiddefs.h +++ b/system/stack/include/hiddefs.h @@ -26,9 +26,9 @@ #define HIDDEFS_H #include +#include -#include - +#include "internal_include/bt_target.h" #include "macros.h" #include "stack/include/sdp_api.h" /* @@ -184,4 +184,9 @@ typedef struct sdp_info { tSDP_DISC_REC* p_sdp_layer_rec; } tHID_DEV_SDP_INFO; +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/stack/include/inq_hci_link_interface.h b/system/stack/include/inq_hci_link_interface.h index 5f712c399bba91672a98540e55ec9c96016c45a5..c48c65246b0f3a6078f42b259cbc1cc78361819f 100644 --- a/system/stack/include/inq_hci_link_interface.h +++ b/system/stack/include/inq_hci_link_interface.h @@ -26,11 +26,7 @@ void btm_process_remote_name(const RawAddress* bda, const BD_NAME name, uint16_t evt_len, tHCI_STATUS hci_status); -void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, - uint8_t inq_res_mode); - void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode); -void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode); void btm_acl_process_sca_cmpl_pkt(uint8_t len, uint8_t* data); tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda, bool is_ble); diff --git a/system/stack/include/l2c_api.h b/system/stack/include/l2c_api.h index b744acf376c158d8f48dab1d5581f3e83271dc8e..bc1ad238362fb86f0ff14095f2902cb745406606 100644 --- a/system/stack/include/l2c_api.h +++ b/system/stack/include/l2c_api.h @@ -24,13 +24,14 @@ #ifndef L2C_API_H #define L2C_API_H +#include #include #include #include -#include "bt_target.h" #include "hcidefs.h" +#include "internal_include/bt_target.h" #include "l2cdefs.h" #include "stack/include/bt_hdr.h" #include "types/bt_transport.h" @@ -735,6 +736,8 @@ typedef struct { tL2CA_FIXED_CONGESTION_STATUS_CB* pL2CA_FixedCong_Cb; uint16_t default_idle_tout; + tL2CA_TX_COMPLETE_CB* + pL2CA_FixedTxComplete_Cb; /* fixed channel tx complete callback */ } tL2CAP_FIXED_CHNL_REG; /******************************************************************************* @@ -824,19 +827,19 @@ bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int, uint16_t timeout, uint16_t min_ce_len, uint16_t max_ce_len); -/******************************************************************************* - * - * Function L2CA_EnableUpdateBleConnParams - * - * Description Update BLE connection parameters. - * - * Parameters: BD Address of remote - * enable flag - * - * Return value: true if update started - * - ******************************************************************************/ -bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable); +/* When called with lock=true, LE connection parameters will be locked on + * fastest value, and we won't accept request to change it from remote. When + * called with lock=false, parameters are relaxed. + */ +void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& rem_bda, + bool lock); + +/* When called with lock=true, LE connection parameters will be locked on + * fastest value, and we won't accept request to change it from remote. When + * called with lock=false, parameters are relaxed. + */ +void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& rem_bda, + bool lock); /******************************************************************************* * @@ -923,4 +926,11 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status); bool L2CA_isMediaChannel(uint16_t handle, uint16_t channel_id, bool is_local_cid); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* L2C_API_H */ diff --git a/system/stack/include/l2cdefs.h b/system/stack/include/l2cdefs.h index be9e1f23deded761beaa97d2c0eb0b64c8c15e90..c1c26f7de09800e1a86a39c62b8f9c9df67d0fc7 100644 --- a/system/stack/include/l2cdefs.h +++ b/system/stack/include/l2cdefs.h @@ -21,6 +21,7 @@ #include +#include "internal_include/bt_target.h" // L2CAP_EXTFEA_SUPPORTED_MASK #include "macros.h" /* L2CAP command codes @@ -480,4 +481,9 @@ constexpr uint16_t L2CAP_SDU_LENGTH_LE_MAX = 0xffff; /* Mask for sequence numbers (range 0 - 63) */ #define L2CAP_FCR_SEQ_MODULO 0x3F +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/stack/include/main_thread.h b/system/stack/include/main_thread.h index 454c0db696da096aea0f37f0f7675f0695ce6b11..5c3b1240484354d9527fc164365744396aaf446b 100644 --- a/system/stack/include/main_thread.h +++ b/system/stack/include/main_thread.h @@ -31,7 +31,7 @@ bt_status_t do_in_main_thread(const base::Location& from_here, base::OnceClosure task); bt_status_t do_in_main_thread_delayed(const base::Location& from_here, base::OnceClosure task, - const base::TimeDelta& delay); + std::chrono::microseconds delay); void post_on_bt_main(BtMainClosure closure); void main_thread_start_up(); void main_thread_shut_down(); diff --git a/system/stack/include/pan_api.h b/system/stack/include/pan_api.h index 2a020a8d2121ceec84c6a6e414def21b677d337a..6af1fdef6d9f00ce02d1fd1e73ab4e35d32cd6c0 100644 --- a/system/stack/include/pan_api.h +++ b/system/stack/include/pan_api.h @@ -25,6 +25,7 @@ #define PAN_API_H #include +#include #include @@ -441,4 +442,9 @@ void PAN_Init(void); void PAN_Dumpsys(int fd); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* PAN_API_H */ diff --git a/system/stack/include/port_api.h b/system/stack/include/port_api.h index f9c7062a49d497472302f098165401071eabe7bc..8d2cbbb98b4e66553f1e29d40fd7d1efcfea261d 100644 --- a/system/stack/include/port_api.h +++ b/system/stack/include/port_api.h @@ -26,7 +26,7 @@ #include -#include "bt_target.h" +#include "internal_include/bt_target.h" #include "types/raw_address.h" /***************************************************************************** diff --git a/system/stack/include/sco_hci_link_interface.h b/system/stack/include/sco_hci_link_interface.h index 34dc174113dfb2e7e5c159464546fdfed80c0857..c4b5e551fe7699443a84f77d4615f25b26f453fb 100644 --- a/system/stack/include/sco_hci_link_interface.h +++ b/system/stack/include/sco_hci_link_interface.h @@ -19,9 +19,9 @@ #include +#include "hci/class_of_device.h" #include "stack/include/bt_dev_class.h" #include "stack/include/hci_error_code.h" -#include "types/class_of_device.h" #include "types/raw_address.h" struct tBTM_ESCO_DATA; @@ -39,6 +39,6 @@ bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason); void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason); void btm_sco_on_esco_connect_request(const RawAddress&, - const bluetooth::types::ClassOfDevice&); + const bluetooth::hci::ClassOfDevice&); void btm_sco_on_sco_connect_request(const RawAddress&, - const bluetooth::types::ClassOfDevice&); + const bluetooth::hci::ClassOfDevice&); diff --git a/system/stack/include/sdp_api.h b/system/stack/include/sdp_api.h index c2adbefc9cd20431c2bc4c0b87fd739ac1c85ccc..2d5dd61ea50446c77f5afe820ed41d2fe40aff11 100644 --- a/system/stack/include/sdp_api.h +++ b/system/stack/include/sdp_api.h @@ -22,7 +22,6 @@ #include -#include "bt_target.h" #include "stack/include/sdp_callback.h" #include "stack/include/sdp_device_id.h" #include "stack/include/sdp_status.h" diff --git a/system/stack/include/sdp_status.h b/system/stack/include/sdp_status.h index cfb81f8efad95a0a242cf7efccb437955b6dc299..d71922cfdb91077af49c16e3ad4c1f1f926be704 100644 --- a/system/stack/include/sdp_status.h +++ b/system/stack/include/sdp_status.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include @@ -85,3 +86,8 @@ inline std::string sdp_status_text(const tSDP_STATUS& status) { } } const auto sdp_result_text = sdp_status_text; + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/include/sec_hci_link_interface.h b/system/stack/include/sec_hci_link_interface.h index cc85265630f0d33e43d23a70e7aa03f2da477b99..4b07e84f21e1eb31e32a0c57855573548af689bd 100644 --- a/system/stack/include/sec_hci_link_interface.h +++ b/system/stack/include/sec_hci_link_interface.h @@ -36,6 +36,8 @@ void btm_sec_auth_complete(uint16_t handle, tHCI_STATUS status); void btm_sec_disconnected(uint16_t handle, tHCI_STATUS reason, std::string); void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable); +void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, + uint8_t encr_enable); void btm_sec_encryption_key_refresh_complete(uint16_t handle, tHCI_STATUS status); void btm_sec_link_key_notification(const RawAddress& p_bda, diff --git a/system/stack/include/security_client_callbacks.h b/system/stack/include/security_client_callbacks.h index efffe164bbdc93e1e21ca9df2805e89e9fbdcfeb..d07b08d3bf6da5d09ed6b1b27aeae8339b013eab 100644 --- a/system/stack/include/security_client_callbacks.h +++ b/system/stack/include/security_client_callbacks.h @@ -24,6 +24,7 @@ #include "stack/include/bt_octets.h" #include "stack/include/btm_ble_sec_api_types.h" #include "stack/include/hci_error_code.h" +#include "types/bt_transport.h" #include "types/raw_address.h" /**************************************** @@ -94,34 +95,28 @@ struct tBTM_APPL_INFO { typedef struct { void (*BTM_Sec_Init)(); void (*BTM_Sec_Free)(); - bool (*BTM_SecAddDevice)(const RawAddress& bd_addr, DEV_CLASS dev_class, + + bool (*BTM_SecRegister)(const tBTM_APPL_INFO* p_cb_info); + + void (*BTM_BleLoadLocalKeys)(uint8_t key_type, tBTM_BLE_LOCAL_KEYS* p_key); + + // Update/Query in-memory device records + bool (*BTM_SecAddDevice)(const RawAddress& bd_addr, const DEV_CLASS dev_class, const BD_NAME& bd_name, uint8_t* features, LinkKey* link_key, uint8_t key_type, uint8_t pin_length); - bool (*BTM_SecAddRmtNameNotifyCallback)(tBTM_RMT_NAME_CALLBACK* p_callback); + void (*BTM_SecAddBleDevice)(const RawAddress& bd_addr, + tBT_DEVICE_TYPE dev_type, + tBLE_ADDR_TYPE addr_type); + bool (*BTM_SecDeleteDevice)(const RawAddress& bd_addr); - bool (*BTM_SecRegister)(const tBTM_APPL_INFO* p_cb_info); - const char* (*BTM_SecReadDevName)(const RawAddress& bd_addr); - tBTM_STATUS (*BTM_SecBond)(const RawAddress& bd_addr, - tBLE_ADDR_TYPE addr_type, tBT_TRANSPORT transport, - tBT_DEVICE_TYPE device_type); - tBTM_STATUS (*BTM_SecBondCancel)(const RawAddress& bd_addr); + void (*BTM_SecAddBleKey)(const RawAddress& bd_addr, tBTM_LE_KEY_VALUE* p_le_key, tBTM_LE_KEY_TYPE key_type); - void (*BTM_SecAddBleDevice)(const RawAddress& bd_addr, - tBT_DEVICE_TYPE dev_type, - tBLE_ADDR_TYPE addr_type); + void (*BTM_SecClearSecurityFlags)(const RawAddress& bd_addr); - uint8_t (*BTM_SecClrService)(uint8_t service_id); - uint8_t (*BTM_SecClrServiceByPsm)(uint16_t psm); - void (*BTM_RemoteOobDataReply)(tBTM_STATUS res, const RawAddress& bd_addr, - const Octet16& c, const Octet16& r); - void (*BTM_PINCodeReply)(const RawAddress& bd_addr, tBTM_STATUS res, - uint8_t pin_len, uint8_t* p_pin); - void (*BTM_ConfirmReqReply)(tBTM_STATUS res, const RawAddress& bd_addr); - bool (*BTM_SecDeleteRmtNameNotifyCallback)( - tBTM_RMT_NAME_CALLBACK* p_callback); + tBTM_STATUS (*BTM_SetEncryption)(const RawAddress& bd_addr, tBT_TRANSPORT transport, tBTM_SEC_CALLBACK* p_callback, @@ -130,8 +125,41 @@ typedef struct { bool (*BTM_SecIsSecurityPending)(const RawAddress& bd_addr); bool (*BTM_IsLinkKeyKnown)(const RawAddress& bd_addr, tBT_TRANSPORT transport); + + // Secure service management + bool (*BTM_SetSecurityLevel)(bool is_originator, const char* p_name, + uint8_t service_id, uint16_t sec_level, + uint16_t psm, uint32_t mx_proto_id, + uint32_t mx_chan_id); + uint8_t (*BTM_SecClrService)(uint8_t service_id); + uint8_t (*BTM_SecClrServiceByPsm)(uint16_t psm); + + // Pairing related APIs + tBTM_STATUS (*BTM_SecBond)(const RawAddress& bd_addr, + tBLE_ADDR_TYPE addr_type, tBT_TRANSPORT transport, + tBT_DEVICE_TYPE device_type); + tBTM_STATUS (*BTM_SecBondCancel)(const RawAddress& bd_addr); + + void (*BTM_RemoteOobDataReply)(tBTM_STATUS res, const RawAddress& bd_addr, + const Octet16& c, const Octet16& r); + void (*BTM_PINCodeReply)(const RawAddress& bd_addr, tBTM_STATUS res, + uint8_t pin_len, uint8_t* p_pin); + void (*BTM_SecConfirmReqReply)(tBTM_STATUS res, tBT_TRANSPORT transport, + const RawAddress bd_addr); void (*BTM_BleSirkConfirmDeviceReply)(const RawAddress& bd_addr, uint8_t res); + + void (*BTM_BlePasskeyReply)(const RawAddress& bd_addr, uint8_t res, + uint32_t passkey); + + // other misc APIs uint8_t (*BTM_GetSecurityMode)(); + + // remote name request related APIs + // TODO: remove them from this structure + const char* (*BTM_SecReadDevName)(const RawAddress& bd_addr); + bool (*BTM_SecAddRmtNameNotifyCallback)(tBTM_RMT_NAME_CALLBACK* p_callback); + bool (*BTM_SecDeleteRmtNameNotifyCallback)( + tBTM_RMT_NAME_CALLBACK* p_callback); } SecurityClientInterface; const SecurityClientInterface& get_security_client_interface(); diff --git a/system/stack/include/smp_api_types.h b/system/stack/include/smp_api_types.h index de56be94be82d6af1f334a638a7a4aa4bc6dc845..8ab40c15992064922b8a5b84cd46f5c44bcadb92 100644 --- a/system/stack/include/smp_api_types.h +++ b/system/stack/include/smp_api_types.h @@ -20,6 +20,7 @@ #define SMP_API_TYPES_H #include +#include #include #include @@ -92,8 +93,12 @@ enum { SMP_OOB_NONE, SMP_OOB_PRESENT, SMP_OOB_UNKNOWN }; typedef uint8_t tSMP_OOB_FLAG; /* type of OOB data required from application */ -enum { SMP_OOB_INVALID_TYPE, SMP_OOB_PEER, SMP_OOB_LOCAL, SMP_OOB_BOTH }; -typedef uint8_t tSMP_OOB_DATA_TYPE; +typedef enum : uint8_t { + SMP_OOB_INVALID_TYPE, + SMP_OOB_PEER, + SMP_OOB_LOCAL, + SMP_OOB_BOTH, +} tSMP_OOB_DATA_TYPE; enum : uint8_t { SMP_AUTH_NO_BOND = 0x00, @@ -225,4 +230,13 @@ typedef tBTM_STATUS(tSMP_CALLBACK)(tSMP_EVT event, const RawAddress& bd_addr, * Manager requires verification from CSIP.*/ typedef tBTM_STATUS(tSMP_SIRK_CALLBACK)(const RawAddress& bd_addr); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif // SMP_API_TYPES_H diff --git a/system/stack/include/smp_status.h b/system/stack/include/smp_status.h index 821dd0e18440782f0818b5e55a79f0925ea72ffd..b3ef27f8191f998d2ea177c4b0f912525986117e 100644 --- a/system/stack/include/smp_status.h +++ b/system/stack/include/smp_status.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include @@ -93,3 +94,8 @@ inline std::string smp_status_text(const tSMP_STATUS& status) { return base::StringPrintf("UNKNOWN[%hhu]", status); } } + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/include/srvc_api.h b/system/stack/include/srvc_api.h index 106c932ac296361b8eada5ad813f6f4f99eadba9..8d79f998aab7813fec446aed0927a01b8fd4dc1b 100644 --- a/system/stack/include/srvc_api.h +++ b/system/stack/include/srvc_api.h @@ -21,9 +21,9 @@ #include -#include "bt_target.h" #include "gatt_api.h" #include "gattdefs.h" +#include "internal_include/bt_target.h" #include "types/bt_transport.h" #include "types/raw_address.h" diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc index 1c90cc2b26f706409778af9df0fb21006695432f..83d9b93901f5157a19c1f233ff31462d2aa5ff6b 100644 --- a/system/stack/l2cap/l2c_api.cc +++ b/system/stack/l2cap/l2c_api.cc @@ -29,28 +29,33 @@ #include #include #include +#include #include #include #include "common/init_flags.h" -#include "device/include/controller.h" // TODO Remove -#include "gd/hal/snoop_logger.h" -#include "gd/os/system_properties.h" +#include "hal/snoop_logger.h" +#include "hci/controller_interface.h" +#include "include/check.h" #include "internal_include/bt_target.h" #include "internal_include/bt_trace.h" #include "main/shim/entry.h" #include "os/log.h" +#include "os/system_properties.h" #include "osi/include/allocator.h" #include "stack/btm/btm_sec.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_psm_types.h" #include "stack/include/btm_api.h" +#include "stack/include/btm_client_interface.h" #include "stack/include/l2c_api.h" #include "stack/include/main_thread.h" #include "stack/l2cap/l2c_int.h" #include "types/raw_address.h" +using namespace bluetooth; + void btsnd_hcic_enhanced_flush(uint16_t handle, uint8_t packet_type); // TODO Remove @@ -71,7 +76,8 @@ uint16_t L2CA_Register2(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, uint16_t sec_level) { auto ret = L2CA_Register(psm, p_cb_info, enable_snoop, p_ertm_info, my_mtu, required_remote_mtu, sec_level); - BTM_SetSecurityLevel(false, "", 0, sec_level, psm, 0, 0); + get_btm_client_interface().security.BTM_SetSecurityLevel( + false, "", 0, sec_level, psm, 0, 0); return ret; } @@ -130,16 +136,16 @@ uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, ** or only a server. */ if (!config_cfm_cb || !data_ind_cb || !disconnect_ind_cb) { - LOG_ERROR( - "L2CAP - no cb registering PSM: 0x%04x cfg_cfm:%u cfg_ind:%u" - " data_ind:%u discon_int:%u", + log::error( + "L2CAP - no cb registering PSM: 0x{:04x} cfg_cfm:{} cfg_ind:{} " + "data_ind:{} discon_int:{}", psm, config_cfm_cb, config_ind_cb, data_ind_cb, disconnect_ind_cb); return (0); } /* Verify PSM is valid */ if (L2C_INVALID_PSM(psm)) { - LOG_ERROR("L2CAP - invalid PSM value, PSM: 0x%04x", psm); + log::error("L2CAP - invalid PSM value, PSM: 0x{:04x}", psm); return (0); } @@ -151,7 +157,7 @@ uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, if (p_rcb == NULL) break; } - LOG_DEBUG("L2CAP - Real PSM: 0x%04x Virtual PSM: 0x%04x", psm, vpsm); + log::debug("L2CAP - Real PSM: 0x{:04x} Virtual PSM: 0x{:04x}", psm, vpsm); } /* If registration block already there, just overwrite it */ @@ -159,13 +165,13 @@ uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, if (p_rcb == NULL) { p_rcb = l2cu_allocate_rcb(vpsm); if (p_rcb == NULL) { - LOG_WARN("L2CAP - no RCB available, PSM: 0x%04x vPSM: 0x%04x", psm, - vpsm); + log::warn("L2CAP - no RCB available, PSM: 0x{:04x} vPSM: 0x{:04x}", psm, + vpsm); return (0); } } - LOG_INFO("L2CAP Registered service classic PSM: 0x%04x", psm); + log::info("L2CAP Registered service classic PSM: 0x{:04x}", psm); p_rcb->log_packets = enable_snoop; p_rcb->api = p_cb_info; p_rcb->real_psm = psm; @@ -195,7 +201,7 @@ void L2CA_Deregister(uint16_t psm) { tL2C_LCB* p_lcb; int ii; - LOG_VERBOSE("L2CAP - L2CA_Deregister() called for PSM: 0x%04x", psm); + log::verbose("L2CAP - L2CA_Deregister() called for PSM: 0x{:04x}", psm); p_rcb = l2cu_find_rcb_by_psm(psm); if (p_rcb != NULL) { @@ -220,7 +226,7 @@ void L2CA_Deregister(uint16_t psm) { } l2cu_release_rcb(p_rcb); } else { - LOG_WARN("L2CAP - PSM: 0x%04x not found for deregistration", psm); + log::warn("L2CAP - PSM: 0x{:04x} not found for deregistration", psm); } } @@ -238,11 +244,11 @@ uint16_t L2CA_AllocateLePSM(void) { uint16_t psm = l2cb.le_dyn_psm; uint16_t count = 0; - LOG_VERBOSE("%s: last psm=%d", __func__, psm); + log::verbose("last psm={}", psm); while (!done) { count++; if (count > LE_DYNAMIC_PSM_RANGE) { - LOG_ERROR("%s: Out of free BLE PSM", __func__); + log::error("Out of free BLE PSM"); return 0; } @@ -254,13 +260,12 @@ uint16_t L2CA_AllocateLePSM(void) { if (!l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START]) { /* make sure the newly allocated psm is not used right now */ if (l2cu_find_ble_rcb_by_psm(psm)) { - LOG_WARN("%s: supposedly-free PSM=%d have allocated rcb!", __func__, - psm); + log::warn("supposedly-free PSM={} have allocated rcb!", psm); continue; } l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START] = true; - LOG_VERBOSE("%s: assigned PSM=%d", __func__, psm); + log::verbose("assigned PSM={}", psm); done = true; break; } @@ -280,22 +285,23 @@ uint16_t L2CA_AllocateLePSM(void) { * ******************************************************************************/ void L2CA_FreeLePSM(uint16_t psm) { - LOG_VERBOSE("%s: to free psm=%d", __func__, psm); + log::verbose("to free psm={}", psm); if ((psm < LE_DYNAMIC_PSM_START) || (psm > LE_DYNAMIC_PSM_END)) { - LOG_ERROR("%s: Invalid PSM=%d value!", __func__, psm); + log::error("Invalid PSM={} value!", psm); return; } if (!l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START]) { - LOG_WARN("%s: PSM=%d was not allocated!", __func__, psm); + log::warn("PSM={} was not allocated!", psm); } l2cb.le_dyn_psm_assigned[psm - LE_DYNAMIC_PSM_START] = false; } uint16_t L2CA_ConnectReq2(uint16_t psm, const RawAddress& p_bd_addr, uint16_t sec_level) { - BTM_SetSecurityLevel(true, "", 0, sec_level, psm, 0, 0); + get_btm_client_interface().security.BTM_SetSecurityLevel( + true, "", 0, sec_level, psm, 0, 0); return L2CA_ConnectReq(psm, p_bd_addr); } @@ -313,18 +319,17 @@ uint16_t L2CA_ConnectReq2(uint16_t psm, const RawAddress& p_bd_addr, * ******************************************************************************/ uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) { - VLOG(1) << __func__ << "BDA " << ADDRESS_TO_LOGGABLE_STR(p_bd_addr) - << StringPrintf(" PSM: 0x%04x", psm); + log::verbose("BDA {} PSM: 0x{:04x}", ADDRESS_TO_LOGGABLE_STR(p_bd_addr), psm); /* Fail if we have not established communications with the controller */ if (!BTM_IsDeviceUp()) { - LOG(WARNING) << __func__ << ": BTU not ready"; + log::warn("BTU not ready"); return 0; } /* Fail if the PSM is not registered */ tL2C_RCB* p_rcb = l2cu_find_rcb_by_psm(psm); if (p_rcb == nullptr) { - LOG(WARNING) << __func__ << ": no RCB, PSM=" << loghex(psm); + log::warn("no RCB, PSM={}", loghex(psm)); return 0; } @@ -336,9 +341,8 @@ uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) { p_lcb = l2cu_allocate_lcb(p_bd_addr, false, BT_TRANSPORT_BR_EDR); /* currently use BR/EDR for ERTM mode l2cap connection */ if (p_lcb == nullptr) { - LOG(WARNING) << __func__ - << ": connection not started for PSM=" << loghex(psm) - << ", p_lcb=" << p_lcb; + log::warn("connection not started for PSM={}, p_lcb={}", loghex(psm), + fmt::ptr(p_lcb)); return 0; } l2cu_create_conn_br_edr(p_lcb); @@ -347,7 +351,7 @@ uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) { /* Allocate a channel control block */ tL2C_CCB* p_ccb = l2cu_allocate_ccb(p_lcb, 0); if (p_ccb == nullptr) { - LOG(WARNING) << __func__ << ": no CCB, PSM=" << loghex(psm); + log::warn("no CCB, PSM={}", loghex(psm)); return 0; } @@ -366,14 +370,14 @@ uint16_t L2CA_ConnectReq(uint16_t psm, const RawAddress& p_bd_addr) { * ccb will be automatically retried after link disconnect * arrives */ - LOG_VERBOSE("L2CAP API - link disconnecting: RETRY LATER"); + log::verbose("L2CAP API - link disconnecting: RETRY LATER"); /* Save ccb so it can be started after disconnect is finished */ p_lcb->p_pending_ccb = p_ccb; } - LOG_VERBOSE("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x", psm, - p_ccb->local_cid); + log::verbose("L2CAP - L2CA_conn_req(psm: 0x{:04x}) returned CID: 0x{:04x}", + psm, p_ccb->local_cid); /* Return the local CID as our handle */ return p_ccb->local_cid; @@ -398,7 +402,8 @@ uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, if (p_cb_info.pL2CA_ConnectInd_Cb != nullptr || psm < LE_DYNAMIC_PSM_START) { // If we register LE COC for outgoing connection only, don't register with // BTM_Sec, because it's handled by L2CA_ConnectLECocReq. - BTM_SetSecurityLevel(false, "", 0, sec_level, psm, 0, 0); + get_btm_client_interface().security.BTM_SetSecurityLevel( + false, "", 0, sec_level, psm, 0, 0); } /* Verify that the required callback info has been filled in @@ -407,13 +412,13 @@ uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, ** or only a server. */ if ((!p_cb_info.pL2CA_DataInd_Cb) || (!p_cb_info.pL2CA_DisconnectInd_Cb)) { - LOG_ERROR("No cb registering BLE PSM: 0x%04x", psm); + log::error("No cb registering BLE PSM: 0x{:04x}", psm); return 0; } /* Verify PSM is valid */ if (!L2C_IS_VALID_LE_PSM(psm)) { - LOG_ERROR("Invalid BLE PSM value, PSM: 0x%04x", psm); + log::error("Invalid BLE PSM value, PSM: 0x{:04x}", psm); return 0; } @@ -426,25 +431,26 @@ uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, (p_cb_info.pL2CA_ConnectInd_Cb == NULL)) { vpsm = L2CA_AllocateLePSM(); if (vpsm == 0) { - LOG_ERROR("Out of free BLE PSM"); + log::error("Out of free BLE PSM"); return 0; } - LOG_DEBUG("Real PSM: 0x%04x Virtual PSM: 0x%04x", psm, vpsm); + log::debug("Real PSM: 0x{:04x} Virtual PSM: 0x{:04x}", psm, vpsm); } /* If registration block already there, just overwrite it */ p_rcb = l2cu_find_ble_rcb_by_psm(vpsm); if (p_rcb == NULL) { - LOG_DEBUG("Allocate rcp for Virtual PSM: 0x%04x", vpsm); + log::debug("Allocate rcp for Virtual PSM: 0x{:04x}", vpsm); p_rcb = l2cu_allocate_ble_rcb(vpsm); if (p_rcb == NULL) { - LOG_WARN("No BLE RCB available, PSM: 0x%04x vPSM: 0x%04x", psm, vpsm); + log::warn("No BLE RCB available, PSM: 0x{:04x} vPSM: 0x{:04x}", psm, + vpsm); return 0; } } - LOG_INFO("Registered service LE COC PSM: 0x%04x", psm); + log::info("Registered service LE COC PSM: 0x{:04x}", psm); p_rcb->api = p_cb_info; p_rcb->real_psm = psm; p_rcb->coc_cfg = cfg; @@ -463,11 +469,11 @@ uint16_t L2CA_RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, * ******************************************************************************/ void L2CA_DeregisterLECoc(uint16_t psm) { - LOG_VERBOSE("%s called for PSM: 0x%04x", __func__, psm); + log::verbose("called for PSM: 0x{:04x}", psm); tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm); if (p_rcb == NULL) { - LOG_WARN("%s PSM: 0x%04x not found for deregistration", __func__, psm); + log::warn("PSM: 0x{:04x} not found for deregistration", psm); return; } @@ -508,21 +514,22 @@ void L2CA_DeregisterLECoc(uint16_t psm) { ******************************************************************************/ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, tL2CAP_LE_CFG_INFO* p_cfg, uint16_t sec_level) { - BTM_SetSecurityLevel(true, "", 0, sec_level, psm, 0, 0); + get_btm_client_interface().security.BTM_SetSecurityLevel( + true, "", 0, sec_level, psm, 0, 0); - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(p_bd_addr) - << StringPrintf(" PSM: 0x%04x", psm); + log::verbose("BDA: {} PSM: 0x{:04x}", ADDRESS_TO_LOGGABLE_STR(p_bd_addr), + psm); /* Fail if we have not established communications with the controller */ if (!BTM_IsDeviceUp()) { - LOG_WARN("%s BTU not ready", __func__); + log::warn("BTU not ready"); return 0; } /* Fail if the PSM is not registered */ tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm); if (p_rcb == NULL) { - LOG_WARN("%s No BLE RCB, PSM: 0x%04x", __func__, psm); + log::warn("No BLE RCB, PSM: 0x{:04x}", psm); return 0; } @@ -534,8 +541,8 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, if ((p_lcb == NULL) /* currently use BR/EDR for ERTM mode l2cap connection */ || (!l2cu_create_conn_le(p_lcb))) { - LOG_WARN("%s conn not started for PSM: 0x%04x p_lcb: 0x%p", __func__, - psm, p_lcb); + log::warn("conn not started for PSM: 0x{:04x} p_lcb: 0x{}", psm, + fmt::ptr(p_lcb)); return 0; } } @@ -543,7 +550,7 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, /* Allocate a channel control block */ tL2C_CCB* p_ccb = l2cu_allocate_ccb(p_lcb, 0); if (p_ccb == NULL) { - LOG_WARN("%s no CCB, PSM: 0x%04x", __func__, psm); + log::warn("no CCB, PSM: 0x{:04x}", psm); return 0; } @@ -561,7 +568,7 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, /* If link is up, start the L2CAP connection */ if (p_lcb->link_state == LST_CONNECTED) { if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) { - LOG_VERBOSE("%s LE Link is up", __func__); + log::verbose("LE Link is up"); // post this asynchronously to avoid out-of-order callback invocation // should this operation fail do_in_main_thread( @@ -577,14 +584,13 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, * arrives */ else if (p_lcb->link_state == LST_DISCONNECTING) { - LOG_VERBOSE("%s link disconnecting: RETRY LATER", __func__); + log::verbose("link disconnecting: RETRY LATER"); /* Save ccb so it can be started after disconnect is finished */ p_lcb->p_pending_ccb = p_ccb; } - LOG_VERBOSE("%s(psm: 0x%04x) returned CID: 0x%04x", __func__, psm, - p_ccb->local_cid); + log::verbose("(psm: 0x{:04x}) returned CID: 0x{:04x}", psm, p_ccb->local_cid); /* Return the local CID as our handle */ return p_ccb->local_cid; @@ -604,11 +610,11 @@ uint16_t L2CA_ConnectLECocReq(uint16_t psm, const RawAddress& p_bd_addr, * ******************************************************************************/ bool L2CA_GetPeerLECocConfig(uint16_t lcid, tL2CAP_LE_CFG_INFO* peer_cfg) { - LOG_VERBOSE("%s CID: 0x%04x", __func__, lcid); + log::verbose("CID: 0x{:04x}", lcid); tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, lcid); if (p_ccb == NULL) { - LOG_ERROR("%s No CCB for CID:0x%04x", __func__, lcid); + log::error("No CCB for CID:0x{:04x}", lcid); return false; } @@ -633,13 +639,13 @@ uint16_t L2CA_GetPeerLECocCredit(const RawAddress& bd_addr, uint16_t lcid) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); if (p_lcb == NULL) { /* No link. Get an LCB and start link establishment */ - LOG_WARN("%s no LCB", __func__); + log::warn("no LCB"); return L2CAP_LE_CREDIT_MAX; } tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid); if (p_ccb == NULL) { - LOG_ERROR("%s No CCB for CID:0x%04x", __func__, lcid); + log::error("No CCB for CID:0x{:04x}", lcid); return L2CAP_LE_CREDIT_MAX; } @@ -665,15 +671,15 @@ uint16_t L2CA_GetPeerLECocCredit(const RawAddress& bd_addr, uint16_t lcid) { bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id, std::vector& accepted_lcids, uint16_t result, tL2CAP_LE_CFG_INFO* p_cfg) { - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(p_bd_addr) - << StringPrintf(" num of cids: %d Result: %d", - int(accepted_lcids.size()), +result); + log::verbose("BDA: {} num of cids: {} Result: {}", + ADDRESS_TO_LOGGABLE_STR(p_bd_addr), int(accepted_lcids.size()), + result); /* First, find the link control block */ tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE); if (p_lcb == NULL) { /* No link. Get an LCB and start link establishment */ - LOG_WARN("%s no LCB", __func__); + log::warn("no LCB"); return false; } @@ -682,14 +688,14 @@ bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id, tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, p_lcb->pending_lead_cid); if (!p_ccb) { - LOG_ERROR("%s No CCB for CID:0x%04x", __func__, p_lcb->pending_lead_cid); + log::error("No CCB for CID:0x{:04x}", p_lcb->pending_lead_cid); return false; } for (uint16_t cid : accepted_lcids) { tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid); if (temp_p_ccb == NULL) { - LOG_WARN("%s no CCB", __func__); + log::warn("no CCB"); return false; } @@ -701,8 +707,7 @@ bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id, /* The IDs must match */ if (p_ccb->remote_id != id) { - LOG_WARN("%s bad id. Expected: %d Got: %d", __func__, p_ccb->remote_id, - id); + log::warn("bad id. Expected: {} Got: {}", p_ccb->remote_id, id); return false; } @@ -737,46 +742,46 @@ bool L2CA_ConnectCreditBasedRsp(const RawAddress& p_bd_addr, uint8_t id, std::vector L2CA_ConnectCreditBasedReq(uint16_t psm, const RawAddress& p_bd_addr, tL2CAP_LE_CFG_INFO* p_cfg) { - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(p_bd_addr) - << StringPrintf(" PSM: 0x%04x", psm); + log::verbose("BDA: {} PSM: 0x{:04x}", ADDRESS_TO_LOGGABLE_STR(p_bd_addr), + psm); std::vector allocated_cids; /* Fail if we have not established communications with the controller */ if (!BTM_IsDeviceUp()) { - LOG_WARN("%s BTU not ready", __func__); + log::warn("BTU not ready"); return allocated_cids; } if (!p_cfg) { - LOG_WARN("%s p_cfg is NULL", __func__); + log::warn("p_cfg is NULL"); return allocated_cids; } /* Fail if the PSM is not registered */ tL2C_RCB* p_rcb = l2cu_find_ble_rcb_by_psm(psm); if (p_rcb == NULL) { - LOG_WARN("%s No BLE RCB, PSM: 0x%04x", __func__, psm); + log::warn("No BLE RCB, PSM: 0x{:04x}", psm); return allocated_cids; } /* First, see if we already have a le link to the remote */ tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE); if (p_lcb == NULL) { - LOG_WARN("%s No link available", __func__); + log::warn("No link available"); return allocated_cids; } if (p_lcb->link_state != LST_CONNECTED) { - LOG_WARN("%s incorrect link state: %d", __func__, p_lcb->link_state); + log::warn("incorrect link state: {}", p_lcb->link_state); return allocated_cids; } - LOG_VERBOSE("%s LE Link is up", __func__); + log::verbose("LE Link is up"); /* Check if there is no ongoing connection request */ if (p_lcb->pending_ecoc_conn_cnt > 0) { - LOG_WARN("There is ongoing connection request, PSM: 0x%04x", psm); + log::warn("There is ongoing connection request, PSM: 0x{:04x}", psm); return allocated_cids; } @@ -794,7 +799,7 @@ std::vector L2CA_ConnectCreditBasedReq(uint16_t psm, l2cu_allocate_ccb(p_lcb, 0, psm == BT_PSM_EATT /* is_eatt */); if (p_ccb == NULL) { if (i == 0) { - LOG_WARN("%s no CCB, PSM: 0x%04x", __func__, psm); + log::warn("no CCB, PSM: 0x{:04x}", psm); return allocated_cids; } else { break; @@ -826,8 +831,8 @@ std::vector L2CA_ConnectCreditBasedReq(uint16_t psm, p_lcb->pending_ecoc_conn_cnt = (uint16_t)(allocated_cids.size()); l2c_csm_execute(p_ccb_primary, L2CEVT_L2CA_CREDIT_BASED_CONNECT_REQ, NULL); - LOG_VERBOSE("%s(psm: 0x%04x) returned CID: 0x%04x", __func__, psm, - p_ccb_primary->local_cid); + log::verbose("(psm: 0x{:04x}) returned CID: 0x{:04x}", psm, + p_ccb_primary->local_cid); return allocated_cids; } @@ -850,10 +855,10 @@ bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bda, tL2CAP_LE_CFG_INFO* p_cfg) { tL2C_CCB* p_ccb; - LOG_VERBOSE("L2CA_ReconfigCreditBasedConnsReq() "); + log::verbose("L2CA_ReconfigCreditBasedConnsReq() "); if (lcids.empty()) { - LOG_WARN("L2CAP - no lcids given to %s", __func__); + log::warn("L2CAP - empty lcids"); return (false); } @@ -861,28 +866,28 @@ bool L2CA_ReconfigCreditBasedConnsReq(const RawAddress& bda, p_ccb = l2cu_find_ccb_by_cid(NULL, cid); if (!p_ccb) { - LOG_WARN("L2CAP - no CCB for L2CA_cfg_req, CID: %d", cid); + log::warn("L2CAP - no CCB for L2CA_cfg_req, CID: {}", cid); return (false); } if ((p_ccb->local_conn_cfg.mtu > p_cfg->mtu) || (p_ccb->local_conn_cfg.mps > p_cfg->mps)) { - LOG_WARN("L2CAP - MPS or MTU reduction, CID: %d", cid); + log::warn("L2CAP - MPS or MTU reduction, CID: {}", cid); return (false); } } if (p_cfg->mtu > L2CAP_MTU_SIZE) { - LOG_WARN("L2CAP - adjust MTU: %u too large", p_cfg->mtu); + log::warn("L2CAP - adjust MTU: {} too large", p_cfg->mtu); p_cfg->mtu = L2CAP_MTU_SIZE; } /* Mark all the p_ccbs which going to be reconfigured */ for (uint16_t cid : lcids) { - LOG_VERBOSE(" cid: %d", cid); + log::verbose("cid: {}", cid); p_ccb = l2cu_find_ccb_by_cid(NULL, cid); if (!p_ccb) { - LOG(ERROR) << __func__ << "Missing cid? " << int(cid); + log::error("Missing cid? {}", int(cid)); return (false); } p_ccb->reconfig_started = true; @@ -921,11 +926,11 @@ bool L2CA_DisconnectReq(uint16_t cid) { /* Find the channel control block. We don't know the link it is on. */ p_ccb = l2cu_find_ccb_by_cid(NULL, cid); if (p_ccb == NULL) { - LOG_WARN("L2CAP - no CCB for L2CA_disc_req, CID: %d", cid); + log::warn("L2CAP - no CCB for L2CA_disc_req, CID: {}", cid); return (false); } - LOG_DEBUG("L2CAP Local disconnect request CID: 0x%04x", cid); + log::debug("L2CAP Local disconnect request CID: 0x{:04x}", cid); l2c_csm_execute(p_ccb, L2CEVT_L2CA_DISCONNECT_REQ, NULL); @@ -1003,12 +1008,12 @@ bool L2CA_UseLatencyMode(const RawAddress& bd_addr, bool use_latency_mode) { /* Find the link control block for the acl channel */ tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb == nullptr) { - LOG_WARN("L2CAP - no LCB for L2CA_SetUseLatencyMode, BDA: %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("L2CAP - no LCB for L2CA_SetUseLatencyMode, BDA: {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return false; } - LOG_INFO("BDA: %s, use_latency_mode: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - use_latency_mode ? "true" : "false"); + log::info("BDA: {}, use_latency_mode: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + use_latency_mode ? "true" : "false"); p_lcb->use_latency_mode = use_latency_mode; return true; } @@ -1025,8 +1030,8 @@ bool L2CA_UseLatencyMode(const RawAddress& bd_addr, bool use_latency_mode) { * ******************************************************************************/ bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) { - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(bd_addr) - << ", priority: " << std::to_string(priority); + log::verbose("BDA: {}, priority: {}", ADDRESS_TO_LOGGABLE_STR(bd_addr), + priority); return (l2cu_set_acl_priority(bd_addr, priority, false)); } @@ -1040,8 +1045,8 @@ bool L2CA_SetAclPriority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority) { * ******************************************************************************/ bool L2CA_SetAclLatency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) { - LOG_INFO("BDA: %s, latency: %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - std::to_string(latency).c_str()); + log::info("BDA: {}, latency: {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + std::to_string(latency)); return l2cu_set_acl_latency(bd_addr, latency); } @@ -1057,12 +1062,13 @@ bool L2CA_SetAclLatency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) { bool L2CA_SetTxPriority(uint16_t cid, tL2CAP_CHNL_PRIORITY priority) { tL2C_CCB* p_ccb; - LOG_VERBOSE("L2CA_SetTxPriority() CID: 0x%04x, priority:%d", cid, priority); + log::verbose("L2CA_SetTxPriority() CID: 0x{:04x}, priority:{}", cid, + priority); /* Find the channel control block. We don't know the link it is on. */ p_ccb = l2cu_find_ccb_by_cid(NULL, cid); if (p_ccb == NULL) { - LOG_WARN("L2CAP - no CCB for L2CA_SetTxPriority, CID: %d", cid); + log::warn("L2CAP - no CCB for L2CA_SetTxPriority, CID: {}", cid); return (false); } @@ -1092,13 +1098,13 @@ bool L2CA_GetPeerFeatures(const RawAddress& bd_addr, uint32_t* p_ext_feat, /* We must already have a link to the remote */ p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb == NULL) { - LOG(WARNING) << __func__ << " No BDA: " << ADDRESS_TO_LOGGABLE_STR(bd_addr); + log::warn("No BDA: {}", ADDRESS_TO_LOGGABLE_STR(bd_addr)); return false; } - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(bd_addr) - << StringPrintf(" ExtFea: 0x%08x Chnl_Mask[0]: 0x%02x", - p_lcb->peer_ext_fea, p_lcb->peer_chnl_mask[0]); + log::verbose("BDA: {} ExtFea: 0x{:08x} Chnl_Mask[0]: 0x{:02x}", + ADDRESS_TO_LOGGABLE_STR(bd_addr), p_lcb->peer_ext_fea, + p_lcb->peer_chnl_mask[0]); *p_ext_feat = p_lcb->peer_ext_fea; @@ -1144,13 +1150,12 @@ bool L2CA_RegisterFixedChannel(uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)) { - LOG_ERROR("Invalid fixed CID: 0x%04x", fixed_cid); + log::error("Invalid fixed CID: 0x{:04x}", fixed_cid); return false; } l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = *p_freg; - LOG_DEBUG("Registered fixed channel:%s", - fixed_channel_text(fixed_cid).c_str()); + log::debug("Registered fixed channel:{}", fixed_channel_text(fixed_cid)); return true; } @@ -1170,20 +1175,20 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { tL2C_LCB* p_lcb; tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; - LOG_DEBUG(" fixed_cid:0x%04x", fixed_cid); + log::debug("fixed_cid:0x{:04x}", fixed_cid); // Check CID is valid and registered if ((fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL) || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL)) { - LOG_ERROR("Invalid fixed_cid:0x%04x", fixed_cid); + log::error("Invalid fixed_cid:0x{:04x}", fixed_cid); return (false); } // Fail if BT is not yet up if (!BTM_IsDeviceUp()) { - LOG_WARN("Bt controller is not ready fixed_cid:0x%04x", fixed_cid); + log::warn("Bt controller is not ready fixed_cid:0x{:04x}", fixed_cid); return (false); } @@ -1205,21 +1210,21 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { // Check for supported channel if (!(peer_channel_mask & (1 << fixed_cid))) { - LOG_INFO("Peer device does not support fixed_cid:0x%04x", fixed_cid); + log::info("Peer device does not support fixed_cid:0x{:04x}", fixed_cid); return false; } // Get a CCB and link the lcb to it if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) { - LOG_WARN("Unable to allocate fixed channel resource fixed_cid:0x%04x", - fixed_cid); + log::warn("Unable to allocate fixed channel resource fixed_cid:0x{:04x}", + fixed_cid); return false; } // racing with disconnecting, queue the connection request if (p_lcb->link_state == LST_DISCONNECTING) { - LOG_DEBUG( - "Link is disconnecting so deferring connection fixed_cid:0x%04x", + log::debug( + "Link is disconnecting so deferring connection fixed_cid:0x{:04x}", fixed_cid); /* Save ccb so it can be started after disconnect is finished */ p_lcb->p_pending_ccb = @@ -1235,15 +1240,16 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { // No link. Get an LCB and start link establishment p_lcb = l2cu_allocate_lcb(rem_bda, false, transport); if (p_lcb == NULL) { - LOG_WARN("Unable to allocate link resource for connection fixed_cid:0x%04x", - fixed_cid); + log::warn( + "Unable to allocate link resource for connection fixed_cid:0x{:04x}", + fixed_cid); return false; } // Get a CCB and link the lcb to it if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) { - LOG_WARN("Unable to allocate fixed channel resource fixed_cid:0x%04x", - fixed_cid); + log::warn("Unable to allocate fixed channel resource fixed_cid:0x{:04x}", + fixed_cid); l2cu_release_lcb(p_lcb); return false; } @@ -1251,8 +1257,9 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { if (transport == BT_TRANSPORT_LE) { bool ret = l2cu_create_conn_le(p_lcb); if (!ret) { - LOG_WARN("Unable to create fixed channel le connection fixed_cid:0x%04x", - fixed_cid); + log::warn( + "Unable to create fixed channel le connection fixed_cid:0x{:04x}", + fixed_cid); l2cu_release_lcb(p_lcb); return false; } @@ -1288,13 +1295,13 @@ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, (fixed_cid > L2CAP_LAST_FIXED_CHNL) || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL)) { - LOG_WARN("No service registered or invalid CID: 0x%04x", fixed_cid); + log::warn("No service registered or invalid CID: 0x{:04x}", fixed_cid); osi_free(p_buf); return (L2CAP_DW_FAILED); } if (!BTM_IsDeviceUp()) { - LOG_WARN("Controller is not ready CID: 0x%04x", fixed_cid); + log::warn("Controller is not ready CID: 0x{:04x}", fixed_cid); osi_free(p_buf); return (L2CAP_DW_FAILED); } @@ -1302,7 +1309,8 @@ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport); if (p_lcb == NULL || p_lcb->link_state == LST_DISCONNECTING) { /* if link is disconnecting, also report data sending failure */ - LOG_WARN("Link is disconnecting or does not exist CID: 0x%04x", fixed_cid); + log::warn("Link is disconnecting or does not exist CID: 0x{:04x}", + fixed_cid); osi_free(p_buf); return (L2CAP_DW_FAILED); } @@ -1316,7 +1324,7 @@ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, peer_channel_mask = p_lcb->peer_chnl_mask[0]; if ((peer_channel_mask & (1 << fixed_cid)) == 0) { - LOG_WARN("Peer does not support fixed channel CID: 0x%04x", fixed_cid); + log::warn("Peer does not support fixed channel CID: 0x{:04x}", fixed_cid); osi_free(p_buf); return (L2CAP_DW_FAILED); } @@ -1326,16 +1334,16 @@ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) { if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) { - LOG_WARN("No channel control block found for CID: 0x%4x", fixed_cid); + log::warn("No channel control block found for CID: 0x{:4x}", fixed_cid); osi_free(p_buf); return (L2CAP_DW_FAILED); } } if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) { - LOG_WARN( - "Unable to send data due to congestion CID: 0x%04x xmit_hold_q.count: " - "%zu buff_quota: %u", + log::warn( + "Unable to send data due to congestion CID: 0x{:04x} " + "xmit_hold_q.count: {} buff_quota: {}", fixed_cid, fixed_queue_length( p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] @@ -1345,7 +1353,7 @@ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, return (L2CAP_DW_FAILED); } - LOG_DEBUG("Enqueued data for CID: 0x%04x len:%hu", fixed_cid, p_buf->len); + log::debug("Enqueued data for CID: 0x{:04x} len:{}", fixed_cid, p_buf->len); l2c_enqueue_peer_data(p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL], p_buf); @@ -1359,7 +1367,7 @@ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, } if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) { - LOG_DEBUG("Link congested for CID: 0x%04x", fixed_cid); + log::debug("Link congested for CID: 0x{:04x}", fixed_cid); return (L2CAP_DW_CONGESTED); } @@ -1389,7 +1397,7 @@ bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { (fixed_cid > L2CAP_LAST_FIXED_CHNL) || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL)) { - LOG_ERROR("L2CA_RemoveFixedChnl() Invalid CID: 0x%04x", fixed_cid); + log::error("L2CA_RemoveFixedChnl() Invalid CID: 0x{:04x}", fixed_cid); return (false); } @@ -1401,13 +1409,13 @@ bool L2CA_RemoveFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { if (((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])) { - LOG(WARNING) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(rem_bda) - << StringPrintf(" CID: 0x%04x not connected", fixed_cid); + log::warn("BDA: {} CID: 0x{:04x} not connected", + ADDRESS_TO_LOGGABLE_STR(rem_bda), fixed_cid); return (false); } - VLOG(2) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(rem_bda) - << StringPrintf(" CID: 0x%04x", fixed_cid); + log::verbose("BDA: {} CID: 0x{:04x}", ADDRESS_TO_LOGGABLE_STR(rem_bda), + fixed_cid); /* Release the CCB, starting an inactivity timeout on the LCB if no other CCBs * exist */ @@ -1452,8 +1460,8 @@ bool L2CA_SetLeGattTimeout(const RawAddress& rem_bda, uint16_t idle_tout) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); if (((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[kAttCid - L2CAP_FIRST_FIXED_CHNL])) { - LOG(WARNING) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(rem_bda) - << StringPrintf(" CID: 0x%04x not connected", kAttCid); + log::warn("BDA: {} CID: 0x{:04x} not connected", + ADDRESS_TO_LOGGABLE_STR(rem_bda), kAttCid); return (false); } @@ -1475,8 +1483,7 @@ bool L2CA_MarkLeLinkAsActive(const RawAddress& rem_bda) { if (p_lcb == NULL) { return false; } - LOG(INFO) << __func__ << "setting link to " - << ADDRESS_TO_LOGGABLE_STR(rem_bda) << " as active"; + log::info("setting link to {} as active", ADDRESS_TO_LOGGABLE_STR(rem_bda)); p_lcb->with_active_local_clients = true; return true; } @@ -1494,7 +1501,7 @@ bool L2CA_MarkLeLinkAsActive(const RawAddress& rem_bda) { * ******************************************************************************/ uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { - LOG_VERBOSE("L2CA_DataWrite() CID: 0x%04x Len: %d", cid, p_data->len); + log::verbose("L2CA_DataWrite() CID: 0x{:04x} Len: {}", cid, p_data->len); return l2c_data_write(cid, p_data, L2CAP_FLUSHABLE_CH_BASED); } @@ -1518,14 +1525,14 @@ bool L2CA_SetChnlFlushability(uint16_t cid, bool is_flushable) { /* Find the channel control block. We don't know the link it is on. */ p_ccb = l2cu_find_ccb_by_cid(NULL, cid); if (p_ccb == NULL) { - LOG_WARN("L2CAP - no CCB for L2CA_SetChnlFlushability, CID: %d", cid); + log::warn("L2CAP - no CCB for L2CA_SetChnlFlushability, CID: {}", cid); return (false); } p_ccb->is_flushable = is_flushable; - LOG_VERBOSE("L2CA_SetChnlFlushability() CID: 0x%04x is_flushable: %d", cid, - is_flushable); + log::verbose("L2CA_SetChnlFlushability() CID: 0x{:04x} is_flushable: {}", + cid, is_flushable); return (true); } @@ -1552,30 +1559,30 @@ uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) { p_ccb = l2cu_find_ccb_by_cid(NULL, lcid); if (!p_ccb || (p_ccb->p_lcb == NULL)) { - LOG_WARN("L2CA_FlushChannel() abnormally returning 0 CID: 0x%04x", lcid); + log::warn("L2CA_FlushChannel() abnormally returning 0 CID: 0x{:04x}", + lcid); return (0); } p_lcb = p_ccb->p_lcb; if (num_to_flush != L2CAP_FLUSH_CHANS_GET) { - LOG_VERBOSE( - "L2CA_FlushChannel (FLUSH) CID: 0x%04x NumToFlush: %d QC: %zu " - "pFirst: 0x%p", + log::verbose( + "L2CA_FlushChannel (FLUSH) CID: 0x{:04x} NumToFlush: {} QC: {} " + "pFirst: 0x{}", lcid, num_to_flush, fixed_queue_length(p_ccb->xmit_hold_q), - fixed_queue_try_peek_first(p_ccb->xmit_hold_q)); + fmt::ptr(fixed_queue_try_peek_first(p_ccb->xmit_hold_q))); } else { - LOG_VERBOSE("L2CA_FlushChannel (QUERY) CID: 0x%04x", lcid); + log::verbose("L2CA_FlushChannel (QUERY) CID: 0x{:04x}", lcid); } /* Cannot flush eRTM buffers once they have a sequence number */ if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_ERTM_MODE) { - const controller_t* controller = controller_get_interface(); // Don't need send enhanced_flush to controller if it is LE transport. if (p_lcb->transport != BT_TRANSPORT_LE && num_to_flush != L2CAP_FLUSH_CHANS_GET) { /* If the controller supports enhanced flush, flush the data queued at the * controller */ - if (controller->supports_non_flushable_pb() && + if (bluetooth::shim::GetController()->SupportsNonFlushablePb() && (BTM_GetNumScoLinks() == 0)) { /* The only packet type defined - 0 - Automatically-Flushable Only */ btsnd_hcic_enhanced_flush(p_lcb->Handle(), 0); @@ -1622,8 +1629,8 @@ uint16_t L2CA_FlushChannel(uint16_t lcid, uint16_t num_to_flush) { num_left += fixed_queue_length(p_ccb->xmit_hold_q); /* Return the local number of buffers left for the CID */ - LOG_VERBOSE("L2CA_FlushChannel() flushed: %u + %u, num_left: %u", - num_flushed1, num_flushed2, num_left); + log::verbose("L2CA_FlushChannel() flushed: {} + {}, num_left: {}", + num_flushed1, num_flushed2, num_left); /* If we were congested, and now we are not, tell the app */ l2cu_check_channel_congestion(p_ccb); @@ -1656,7 +1663,7 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) { bluetooth::hal::SnoopLogger* snoop_logger = bluetooth::shim::GetSnoopLogger(); if (snoop_logger == nullptr) { - LOG_ERROR("bluetooth::shim::GetSnoopLogger() is nullptr"); + log::error("bluetooth::shim::GetSnoopLogger() is nullptr"); return; } @@ -1664,8 +1671,8 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) { return; } - LOG_DEBUG("local_media_cid=%d, status=%s", local_media_cid, - (status ? "add" : "remove")); + log::debug("local_media_cid={}, status={}", local_media_cid, + (status ? "add" : "remove")); if (status) { for (i = 0; i < MAX_ACTIVE_AVDT_CONN; i++) { @@ -1676,7 +1683,7 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) { } if (set_channel < 0) { - LOG_ERROR("%s: No empty slot found to set media channel", __func__); + log::error("No empty slot found to set media channel"); return; } @@ -1694,10 +1701,9 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) { av_media_channels[set_channel].local_cid, av_media_channels[set_channel].p_ccb->remote_cid); - LOG_VERBOSE( - "%s: Set A2DP media snoop filtering for local_cid: %d, remote_cid: %d", - __func__, local_media_cid, - av_media_channels[set_channel].p_ccb->remote_cid); + log::verbose( + "Set A2DP media snoop filtering for local_cid: {}, remote_cid: {}", + local_media_cid, av_media_channels[set_channel].p_ccb->remote_cid); } else { for (i = 0; i < MAX_ACTIVE_AVDT_CONN; i++) { if (av_media_channels[i].is_active && @@ -1708,8 +1714,8 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) { } if (set_channel < 0) { - LOG_ERROR("%s: The channel %d not found in active media channels", - __func__, local_media_cid); + log::error("The channel {} not found in active media channels", + local_media_cid); return; } @@ -1722,8 +1728,8 @@ void L2CA_SetMediaStreamChannel(uint16_t local_media_cid, bool status) { av_media_channels[set_channel].p_ccb->p_lcb->Handle(), av_media_channels[set_channel].local_cid); - LOG_VERBOSE("%s: Reset A2DP media snoop filtering for local_cid: %d", - __func__, local_media_cid); + log::verbose("Reset A2DP media snoop filtering for local_cid: {}", + local_media_cid); } av_media_channels[set_channel].is_active = status; diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc index ff5445a0cda9a4f591caa46b16c31bf178901235..d83d253824ae88e1f31564fac5a75b3eb3fb901e 100644 --- a/system/stack/l2cap/l2c_ble.cc +++ b/system/stack/l2cap/l2c_ble.cc @@ -26,6 +26,7 @@ #include #include +#include #include #ifdef __ANDROID__ @@ -33,7 +34,7 @@ #endif #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "device/include/controller.h" #include "internal_include/bt_target.h" #include "internal_include/stack_config.h" @@ -57,6 +58,8 @@ #include "stack/l2cap/l2c_int.h" #include "types/raw_address.h" +using namespace bluetooth; + namespace { constexpr char kBtmLogTag[] = "L2CAP"; @@ -67,105 +70,7 @@ extern tBTM_CB btm_cb; using base::StringPrintf; -static void l2cble_start_conn_update(tL2C_LCB* p_lcb); -static void l2cble_start_subrate_change(tL2C_LCB* p_lcb); - -/******************************************************************************* - * - * Function L2CA_UpdateBleConnParams - * - * Description Update BLE connection parameters. - * - * Parameters: BD Address of remote - * - * Return value: true if update started - * - ******************************************************************************/ -bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int, - uint16_t max_int, uint16_t latency, - uint16_t timeout, uint16_t min_ce_len, - uint16_t max_ce_len) { - tL2C_LCB* p_lcb; - - /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); - - /* If we do not have one, create one and accept the connection. */ - if (!p_lcb || !BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) { - LOG(WARNING) << __func__ << " - unknown BD_ADDR " << rem_bda; - return (false); - } - - if (p_lcb->transport != BT_TRANSPORT_LE) { - LOG(WARNING) << __func__ << " - BD_ADDR " << rem_bda << " not LE"; - return (false); - } - - VLOG(2) << __func__ << ": BD_ADDR=" << ADDRESS_TO_LOGGABLE_STR(rem_bda) - << ", min_int=" << min_int << ", max_int=" << max_int - << ", min_ce_len=" << min_ce_len << ", max_ce_len=" << max_ce_len; - - p_lcb->min_interval = min_int; - p_lcb->max_interval = max_int; - p_lcb->latency = latency; - p_lcb->timeout = timeout; - p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; - p_lcb->min_ce_len = min_ce_len; - p_lcb->max_ce_len = max_ce_len; - - l2cble_start_conn_update(p_lcb); - - return (true); -} - -/******************************************************************************* - * - * Function L2CA_EnableUpdateBleConnParams - * - * Description Enable or disable update based on the request from the peer - * - * Parameters: BD Address of remote - * - * Return value: true if update started - * - ******************************************************************************/ -bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable) { - if (stack_config_get_interface()->get_pts_conn_updates_disabled()) - return false; - - tL2C_LCB* p_lcb; - - /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); - - if (!p_lcb) { - LOG(WARNING) << __func__ << " - unknown BD_ADDR " << rem_bda; - return false; - } - - VLOG(2) << __func__ << " - BD_ADDR " << ADDRESS_TO_LOGGABLE_STR(rem_bda) - << StringPrintf(" enable %d current upd state 0x%02x", enable, - p_lcb->conn_update_mask); - - if (p_lcb->transport != BT_TRANSPORT_LE) { - LOG(WARNING) << __func__ << " - BD_ADDR " - << ADDRESS_TO_LOGGABLE_STR(rem_bda) << " not LE, link role " - << p_lcb->LinkRole(); - return false; - } - - if (enable) { - p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE; - p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_DISABLE; - } else { - p_lcb->conn_update_mask |= L2C_BLE_CONN_UPDATE_DISABLE; - p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_DISABLE; - } - - l2cble_start_conn_update(p_lcb); - - return (true); -} +void l2cble_start_conn_update(tL2C_LCB* p_lcb); void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rpa, BT_TRANSPORT_LE); @@ -173,9 +78,9 @@ void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa) { return; } - LOG_INFO("consolidating l2c_lcb record %s -> %s", - ADDRESS_TO_LOGGABLE_CSTR(rpa), - ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); + log::info("consolidating l2c_lcb record {} -> {}", + ADDRESS_TO_LOGGABLE_CSTR(rpa), + ADDRESS_TO_LOGGABLE_CSTR(identity_addr)); p_lcb->remote_bd_addr = identity_addr; } @@ -199,7 +104,7 @@ hci_role_t L2CA_GetBleConnRole(const RawAddress& bd_addr) { void l2cble_notify_le_connection(const RawAddress& bda) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE); if (p_lcb == nullptr) { - LOG_WARN("Received notification for le connection but no lcb found"); + log::warn("Received notification for le connection but no lcb found"); return; } @@ -236,17 +141,17 @@ bool l2cble_conn_comp(uint16_t handle, uint8_t role, const RawAddress& bda, if (!p_lcb) { p_lcb = l2cu_allocate_lcb(bda, false, BT_TRANSPORT_LE); if (!p_lcb) { - LOG_ERROR("Unable to allocate link resource for le acl connection"); + log::error("Unable to allocate link resource for le acl connection"); return false; } else { if (!l2cu_initialize_fixed_ccb(p_lcb, L2CAP_ATT_CID)) { - LOG_ERROR("Unable to allocate channel resource for le acl connection"); + log::error("Unable to allocate channel resource for le acl connection"); return false; } } p_lcb->link_state = LST_CONNECTING; } else if (role == HCI_ROLE_CENTRAL && p_lcb->link_state != LST_CONNECTING) { - LOG_ERROR( + log::error( "Received le acl connection as role central but not in connecting " "state"); return false; @@ -273,6 +178,8 @@ bool l2cble_conn_comp(uint16_t handle, uint8_t role, const RawAddress& bda, p_lcb->timeout = conn_timeout; p_lcb->latency = conn_latency; p_lcb->conn_update_mask = L2C_BLE_NOT_DEFAULT_PARAM; + p_lcb->conn_update_blocked_by_profile_connection = false; + p_lcb->conn_update_blocked_by_service_discovery = false; p_lcb->subrate_req_mask = 0; p_lcb->subrate_min = 1; @@ -287,7 +194,7 @@ bool l2cble_conn_comp(uint16_t handle, uint8_t role, const RawAddress& bda, if (role == HCI_ROLE_PERIPHERAL) { if (!controller_get_interface() - ->supports_ble_peripheral_initiated_feature_exchange()) { + ->SupportsBlePeripheralInitiatedFeaturesExchange()) { p_lcb->link_state = LST_CONNECTED; l2cu_process_fixed_chnl_resp(p_lcb); } @@ -295,132 +202,6 @@ bool l2cble_conn_comp(uint16_t handle, uint8_t role, const RawAddress& bda, return true; } -/******************************************************************************* - * - * Function l2cble_start_conn_update - * - * Description Start the BLE connection parameter update process based on - * status. - * - * Parameters: lcb : l2cap link control block - * - * Return value: none - * - ******************************************************************************/ -static void l2cble_start_conn_update(tL2C_LCB* p_lcb) { - uint16_t min_conn_int, max_conn_int, peripheral_latency, supervision_tout; - if (!BTM_IsAclConnectionUp(p_lcb->remote_bd_addr, BT_TRANSPORT_LE)) { - LOG(ERROR) << "No known connection ACL for " << p_lcb->remote_bd_addr; - return; - } - - // TODO(armansito): The return value of this call wasn't being used but the - // logic of this function might be depending on its side effects. We should - // verify if this call is needed at all and remove it otherwise. - btm_find_or_alloc_dev(p_lcb->remote_bd_addr); - - if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) || - (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING)) { - return; - } - - if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) { - /* application requests to disable parameters update. - If parameters are already updated, lets set them - up to what has been requested during connection establishement */ - if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM && - /* current connection interval is greater than default min */ - p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) { - /* use 7.5 ms as fast connection parameter, 0 peripheral latency */ - min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN; - - L2CA_AdjustConnectionIntervals(&min_conn_int, &max_conn_int, - BTM_BLE_CONN_INT_MIN); - - peripheral_latency = BTM_BLE_CONN_PERIPHERAL_LATENCY_DEF; - supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF; - - /* if both side 4.1, or we are central device, send HCI command */ - if (p_lcb->IsLinkRoleCentral() - || (controller_get_interface() - ->supports_ble_connection_parameter_request() && - acl_peer_supports_ble_connection_parameters_request( - p_lcb->remote_bd_addr)) - ) { - btsnd_hcic_ble_upd_ll_conn_params(p_lcb->Handle(), min_conn_int, - max_conn_int, peripheral_latency, - supervision_tout, 0, 0); - p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; - } else { - l2cu_send_peer_ble_par_req(p_lcb, min_conn_int, max_conn_int, - peripheral_latency, supervision_tout); - } - p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM; - p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; - } - } else { - /* application allows to do update, if we were delaying one do it now */ - if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM) { - /* if both side 4.1, or we are central device, send HCI command */ - if (p_lcb->IsLinkRoleCentral() - || (controller_get_interface() - ->supports_ble_connection_parameter_request() && - acl_peer_supports_ble_connection_parameters_request( - p_lcb->remote_bd_addr)) - ) { - btsnd_hcic_ble_upd_ll_conn_params(p_lcb->Handle(), p_lcb->min_interval, - p_lcb->max_interval, p_lcb->latency, - p_lcb->timeout, p_lcb->min_ce_len, - p_lcb->max_ce_len); - p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; - } else { - l2cu_send_peer_ble_par_req(p_lcb, p_lcb->min_interval, - p_lcb->max_interval, p_lcb->latency, - p_lcb->timeout); - } - p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM; - p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM; - } - } -} - -/******************************************************************************* - * - * Function l2cble_process_conn_update_evt - * - * Description This function enables the connection update request from - * remote after a successful connection update response is - * received. - * - * Returns void - * - ******************************************************************************/ -void l2cble_process_conn_update_evt(uint16_t handle, uint8_t status, - uint16_t interval, uint16_t latency, - uint16_t timeout) { - LOG_VERBOSE("%s", __func__); - - /* See if we have a link control block for the remote device */ - tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); - if (!p_lcb) { - LOG_WARN("%s: Invalid handle: %d", __func__, handle); - return; - } - - p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; - - if (status != HCI_SUCCESS) { - LOG_WARN("%s: Error status: %d", __func__, status); - } - - l2cble_start_conn_update(p_lcb); - - l2cble_start_subrate_change(p_lcb); - - LOG_VERBOSE("%s: conn_update_mask=%d , subrate_req_mask=%d", __func__, - p_lcb->conn_update_mask, p_lcb->subrate_req_mask); -} - /******************************************************************************* * * Function l2cble_handle_connect_rsp_neg @@ -470,7 +251,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { p_pkt_end = p + pkt_len; if (p + 4 > p_pkt_end) { - LOG(ERROR) << "invalid read"; + log::error("invalid read"); return; } @@ -480,8 +261,8 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* Check command length does not exceed packet length */ if ((p + cmd_len) > p_pkt_end) { - LOG_WARN("L2CAP - LE - format error, pkt_len: %d cmd_len: %d code: %d", - pkt_len, cmd_len, cmd_code); + log::warn("L2CAP - LE - format error, pkt_len: {} cmd_len: {} code: {}", + pkt_len, cmd_len, cmd_code); return; } @@ -490,8 +271,9 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { uint16_t reason; if (p + 2 > p_pkt_end) { - LOG(ERROR) << "invalid L2CAP_CMD_REJECT packet," - << " not containing enough data for `reason` field"; + log::error( + "invalid L2CAP_CMD_REJECT packet, not containing enough data for " + "`reason` field"); return; } @@ -513,7 +295,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_BLE_UPDATE_REQ: if (p + 8 > p_pkt_end) { - LOG(ERROR) << "invalid read"; + log::error("invalid read"); return; } @@ -561,7 +343,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_CREDIT_BASED_CONN_REQ: { if (p + 10 > p_pkt_end) { - LOG(ERROR) << "invalid L2CAP_CMD_CREDIT_BASED_CONN_REQ len"; + log::error("invalid L2CAP_CMD_CREDIT_BASED_CONN_REQ len"); return; } @@ -573,33 +355,31 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* Check how many channels remote side wants. */ num_of_channels = (p_pkt_end - p) / sizeof(uint16_t); if (num_of_channels > L2CAP_CREDIT_BASED_MAX_CIDS) { - LOG_WARN("L2CAP - invalid number of channels requested: %d", - num_of_channels); + log::warn("L2CAP - invalid number of channels requested: {}", + num_of_channels); l2cu_reject_credit_based_conn_req(p_lcb, id, L2CAP_CREDIT_BASED_MAX_CIDS, L2CAP_LE_RESULT_INVALID_PARAMETERS); return; } - LOG_DEBUG( - "Recv L2CAP_CMD_CREDIT_BASED_CONN_REQ with " - "mtu = %d, " - "mps = %d, " - "initial credit = %d" - "num_of_channels = %d", + log::debug( + "Recv L2CAP_CMD_CREDIT_BASED_CONN_REQ with mtu = {}, mps = {}, " + "initial credit = {}num_of_channels = {}", mtu, mps, initial_credit, num_of_channels); /* Check PSM Support */ p_rcb = l2cu_find_ble_rcb_by_psm(con_info.psm); if (p_rcb == NULL) { - LOG_WARN("L2CAP - rcvd conn req for unknown PSM: 0x%04x", con_info.psm); + log::warn("L2CAP - rcvd conn req for unknown PSM: 0x{:04x}", + con_info.psm); l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels, L2CAP_LE_RESULT_NO_PSM); return; } if (p_lcb->pending_ecoc_conn_cnt > 0) { - LOG_WARN("L2CAP - L2CAP_CMD_CREDIT_BASED_CONN_REQ collision:"); + log::warn("L2CAP - L2CAP_CMD_CREDIT_BASED_CONN_REQ collision:"); if (p_rcb->api.pL2CA_CreditBasedCollisionInd_Cb && con_info.psm == BT_PSM_EATT) { (*p_rcb->api.pL2CA_CreditBasedCollisionInd_Cb)(p_lcb->remote_bd_addr); @@ -612,8 +392,8 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { p_lcb->pending_ecoc_conn_cnt = num_of_channels; if (!p_rcb->api.pL2CA_CreditBasedConnectInd_Cb) { - LOG_WARN("L2CAP - rcvd conn req for outgoing-only connection PSM: %d", - con_info.psm); + log::warn("L2CAP - rcvd conn req for outgoing-only connection PSM: {}", + con_info.psm); l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels, L2CAP_CONN_NO_PSM); return; @@ -622,7 +402,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* validate the parameters */ if (mtu < L2CAP_CREDIT_BASED_MIN_MTU || mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) { - LOG_ERROR("L2CAP don't like the params"); + log::error("L2CAP don't like the params"); l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels, L2CAP_LE_RESULT_INVALID_PARAMETERS); return; @@ -634,7 +414,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { STREAM_TO_UINT16(rcid, p); temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid); if (temp_p_ccb) { - LOG_WARN("L2CAP - rcvd conn req for duplicated cid: 0x%04x", rcid); + log::warn("L2CAP - rcvd conn req for duplicated cid: 0x{:04x}", rcid); p_lcb->pending_ecoc_connection_cids[i] = 0; p_lcb->pending_l2cap_result = L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED; @@ -643,7 +423,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { temp_p_ccb = l2cu_allocate_ccb( p_lcb, 0, con_info.psm == BT_PSM_EATT /* is_eatt */); if (temp_p_ccb == NULL) { - LOG_ERROR("L2CAP - unable to allocate CCB"); + log::error("L2CAP - unable to allocate CCB"); p_lcb->pending_ecoc_connection_cids[i] = 0; p_lcb->pending_l2cap_result = L2CAP_LE_RESULT_NO_RESOURCES; continue; @@ -680,23 +460,23 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { } if (!lead_cid_set) { - LOG_ERROR("L2CAP - unable to allocate CCB"); + log::error("L2CAP - unable to allocate CCB"); l2cu_reject_credit_based_conn_req(p_lcb, id, num_of_channels, p_lcb->pending_l2cap_result); return; } - LOG_DEBUG("L2CAP - processing peer credit based connect request"); + log::debug("L2CAP - processing peer credit based connect request"); l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CREDIT_BASED_CONNECT_REQ, NULL); break; } case L2CAP_CMD_CREDIT_BASED_CONN_RES: if (p + 8 > p_pkt_end) { - LOG(ERROR) << "invalid L2CAP_CMD_CREDIT_BASED_CONN_RES len"; + log::error("invalid L2CAP_CMD_CREDIT_BASED_CONN_RES len"); return; } - LOG_VERBOSE("Recv L2CAP_CMD_CREDIT_BASED_CONN_RES"); + log::verbose("Recv L2CAP_CMD_CREDIT_BASED_CONN_RES"); /* For all channels, see whose identifier matches this id */ for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb; temp_p_ccb = temp_p_ccb->p_next_ccb) { @@ -707,7 +487,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { } if (!p_ccb) { - LOG_VERBOSE(" Cannot find matching connection req"); + log::verbose("Cannot find matching connection req"); con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_SOURCE_CID; l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info); return; @@ -728,7 +508,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { con_info.l2cap_result == L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION || con_info.l2cap_result == L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS || con_info.l2cap_result == L2CAP_LE_RESULT_INVALID_PARAMETERS) { - LOG_ERROR("L2CAP - not accepted. Status %d", con_info.l2cap_result); + log::error("L2CAP - not accepted. Status {}", con_info.l2cap_result); l2cble_handle_connect_rsp_neg(p_lcb, &con_info); return; } @@ -736,7 +516,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* validate the parameters */ if (mtu < L2CAP_CREDIT_BASED_MIN_MTU || mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) { - LOG_ERROR("L2CAP - invalid params"); + log::error("L2CAP - invalid params"); con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_PARAMETERS; l2cble_handle_connect_rsp_neg(p_lcb, &con_info); return; @@ -746,20 +526,16 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { * good*/ num_of_channels = (p_pkt_end - p) / sizeof(uint16_t); if (num_of_channels != p_lcb->pending_ecoc_conn_cnt) { - LOG_ERROR( - "Incorrect response." - "expected num of channels = %d" - "received num of channels = %d", + log::error( + "Incorrect response.expected num of channels = {} received num of " + "channels = {}", num_of_channels, p_lcb->pending_ecoc_conn_cnt); return; } - LOG_VERBOSE( - "mtu = %d, " - "mps = %d, " - "initial_credit = %d, " - "con_info.l2cap_result = %d" - "num_of_channels = %d", + log::verbose( + "mtu = {}, mps = {}, initial_credit = {}, con_info.l2cap_result = " + "{} num_of_channels = {}", mtu, mps, initial_credit, con_info.l2cap_result, num_of_channels); con_info.peer_mtu = mtu; @@ -783,10 +559,9 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { */ temp_p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid); if (temp_p_ccb != nullptr) { - LOG_ERROR( - "Already Allocated Destination cid. " - "rcid = %d " - "send peer_disc_req", + log::error( + "Already Allocated Destination cid. rcid = {} send " + "peer_disc_req", rcid); l2cu_send_peer_disc_req(temp_p_ccb); @@ -803,10 +578,8 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid); temp_p_ccb->remote_cid = rcid; - LOG_VERBOSE( - "local cid = %d " - "remote cid = %d", - cid, temp_p_ccb->remote_cid); + log::verbose("local cid = {} remote cid = {}", cid, + temp_p_ccb->remote_cid); /* Check if peer accepted channel, if not release the one not * created @@ -842,7 +615,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* validate the parameters */ if (mtu < L2CAP_CREDIT_BASED_MIN_MTU || mps < L2CAP_CREDIT_BASED_MIN_MPS || mps > L2CAP_LE_MAX_MPS) { - LOG_ERROR("L2CAP - invalid params"); + log::error("L2CAP - invalid params"); l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_UNACCAPTED_PARAM); return; } @@ -850,11 +623,9 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* Check how many channels remote side wants to reconfigure */ num_of_channels = (p_pkt_end - p) / sizeof(uint16_t); - LOG_VERBOSE( - "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ with " - "mtu = %d, " - "mps = %d, " - "num_of_channels = %d", + log::verbose( + "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ with mtu = {}, mps = {}, " + "num_of_channels = {}", mtu, mps, num_of_channels); uint8_t* p_tmp = p; @@ -862,15 +633,15 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { STREAM_TO_UINT16(rcid, p_tmp); p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid); if (!p_ccb) { - LOG_WARN("L2CAP - rcvd config req for non existing cid: 0x%04x", - rcid); + log::warn("L2CAP - rcvd config req for non existing cid: 0x{:04x}", + rcid); l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_INVALID_DCID); return; } if (p_ccb->peer_conn_cfg.mtu > mtu) { - LOG_WARN( - "L2CAP - rcvd config req mtu reduction new mtu < mtu (%d < %d)", + log::warn( + "L2CAP - rcvd config req mtu reduction new mtu < mtu ({} < {})", mtu, p_ccb->peer_conn_cfg.mtu); l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_REDUCTION_MTU_NO_ALLOWED); @@ -878,8 +649,8 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { } if (p_ccb->peer_conn_cfg.mps > mps && num_of_channels > 1) { - LOG_WARN( - "L2CAP - rcvd config req mps reduction new mps < mps (%d < %d)", + log::warn( + "L2CAP - rcvd config req mps reduction new mps < mps ({} < {})", mtu, p_ccb->peer_conn_cfg.mtu); l2cu_send_ble_reconfig_rsp(p_lcb, id, L2CAP_RECONFIG_REDUCTION_MPS_NO_ALLOWED); @@ -911,14 +682,13 @@ 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) { - LOG(ERROR) << "invalid read"; + log::error("invalid read"); return; } STREAM_TO_UINT16(result, p); - LOG_VERBOSE( - "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_RES for " - "result = 0x%04x", + log::verbose( + "Recv L2CAP_CMD_CREDIT_BASED_RECONFIG_RES for result = 0x{:04x}", result); p_lcb->pending_ecoc_reconfig_cfg.result = result; @@ -944,7 +714,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ: if (p + 10 > p_pkt_end) { - LOG(ERROR) << "invalid read"; + log::error("invalid read"); return; } @@ -954,16 +724,14 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { STREAM_TO_UINT16(mps, p); STREAM_TO_UINT16(initial_credit, p); - LOG_VERBOSE( - "Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ with " - "mtu = %d, " - "mps = %d, " - "initial credit = %d", + log::verbose( + "Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ with mtu = {}, mps = {}, " + "initial credit = {}", mtu, mps, initial_credit); p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, rcid); if (p_ccb) { - LOG_WARN("L2CAP - rcvd conn req for duplicated cid: 0x%04x", rcid); + log::warn("L2CAP - rcvd conn req for duplicated cid: 0x{:04x}", rcid); l2cu_reject_ble_coc_connection( p_lcb, id, L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED); break; @@ -971,13 +739,15 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { p_rcb = l2cu_find_ble_rcb_by_psm(con_info.psm); if (p_rcb == NULL) { - LOG_WARN("L2CAP - rcvd conn req for unknown PSM: 0x%04x", con_info.psm); + log::warn("L2CAP - rcvd conn req for unknown PSM: 0x{:04x}", + con_info.psm); l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_LE_RESULT_NO_PSM); break; } else { if (!p_rcb->api.pL2CA_ConnectInd_Cb) { - LOG_WARN("L2CAP - rcvd conn req for outgoing-only connection PSM: %d", - con_info.psm); + log::warn( + "L2CAP - rcvd conn req for outgoing-only connection PSM: {}", + con_info.psm); l2cu_reject_ble_coc_connection(p_lcb, id, L2CAP_CONN_NO_PSM); break; } @@ -987,7 +757,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { p_ccb = l2cu_allocate_ccb(p_lcb, 0, con_info.psm == BT_PSM_EATT /* is_eatt */); if (p_ccb == NULL) { - LOG_ERROR("L2CAP - unable to allocate CCB"); + log::error("L2CAP - unable to allocate CCB"); l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES); break; } @@ -995,7 +765,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* validate the parameters */ if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MPS || mps > L2CAP_LE_MAX_MPS) { - LOG_ERROR("L2CAP do not like the params"); + log::error("L2CAP do not like the params"); l2cu_reject_ble_connection(p_ccb, id, L2CAP_CONN_NO_RESOURCES); break; } @@ -1026,7 +796,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { break; case L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES: - LOG_VERBOSE("Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES"); + log::verbose("Recv L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES"); /* For all channels, see whose identifier matches this id */ for (temp_p_ccb = p_lcb->ccb_queue.p_first_ccb; temp_p_ccb; temp_p_ccb = temp_p_ccb->p_next_ccb) { @@ -1036,9 +806,9 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { } } if (p_ccb) { - LOG_VERBOSE("I remember the connection req"); + log::verbose("I remember the connection req"); if (p + 10 > p_pkt_end) { - LOG(ERROR) << "invalid read"; + log::error("invalid read"); return; } @@ -1049,12 +819,9 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { STREAM_TO_UINT16(con_info.l2cap_result, p); con_info.remote_cid = p_ccb->remote_cid; - LOG_VERBOSE( - "remote_cid = %d, " - "mtu = %d, " - "mps = %d, " - "initial_credit = %d, " - "con_info.l2cap_result = %d", + log::verbose( + "remote_cid = {}, mtu = {}, mps = {}, initial_credit = {}, " + "con_info.l2cap_result = {}", p_ccb->remote_cid, p_ccb->peer_conn_cfg.mtu, p_ccb->peer_conn_cfg.mps, p_ccb->peer_conn_cfg.credits, con_info.l2cap_result); @@ -1063,7 +830,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { if (p_ccb->peer_conn_cfg.mtu < L2CAP_LE_MIN_MTU || p_ccb->peer_conn_cfg.mps < L2CAP_LE_MIN_MPS || p_ccb->peer_conn_cfg.mps > L2CAP_LE_MAX_MPS) { - LOG_ERROR("L2CAP do not like the params"); + log::error("L2CAP do not like the params"); con_info.l2cap_result = L2CAP_LE_RESULT_NO_RESOURCES; l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info); break; @@ -1080,7 +847,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { else l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info); } else { - LOG_VERBOSE("I DO NOT remember the connection req"); + log::verbose("I DO NOT remember the connection req"); con_info.l2cap_result = L2CAP_LE_RESULT_INVALID_SOURCE_CID; l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info); } @@ -1088,21 +855,20 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_BLE_FLOW_CTRL_CREDIT: if (p + 4 > p_pkt_end) { - LOG(ERROR) << "invalid read"; + log::error("invalid read"); return; } STREAM_TO_UINT16(lcid, p); p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, lcid); if (p_ccb == NULL) { - LOG_VERBOSE("%s Credit received for unknown channel id %d", __func__, - lcid); + log::verbose("Credit received for unknown channel id {}", lcid); break; } STREAM_TO_UINT16(credit, p); l2c_csm_execute(p_ccb, L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT, &credit); - LOG_VERBOSE("%s Credit received", __func__); + log::verbose("Credit received"); break; case L2CAP_CMD_DISC_REQ: @@ -1125,7 +891,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_DISC_RSP: if (p + 4 > p_pkt_end) { - LOG(ERROR) << "invalid read"; + log::error("invalid read"); return; } STREAM_TO_UINT16(rcid, p); @@ -1139,7 +905,7 @@ void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { break; default: - LOG_WARN("L2CAP - LE - unknown cmd code: %d", cmd_code); + log::warn("L2CAP - LE - unknown cmd code: {}", cmd_code); l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); break; } @@ -1254,9 +1020,9 @@ void l2c_ble_link_adjust_allocation(void) { l2cb.ble_round_robin_unacked = 0; qq = qq_remainder = 0; } - LOG_VERBOSE( - "l2c_ble_link_adjust_allocation num_hipri: %u num_lowpri: %u " - "low_quota: %u round_robin_quota: %u qq: %u", + log::verbose( + "l2c_ble_link_adjust_allocation num_hipri: {} num_lowpri: {} " + "low_quota: {} round_robin_quota: {} qq: {}", num_hipri_links, num_lowpri_links, low_quota, l2cb.ble_round_robin_quota, qq); @@ -1281,12 +1047,12 @@ void l2c_ble_link_adjust_allocation(void) { } } - LOG_VERBOSE( - "l2c_ble_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d", + log::verbose( + "l2c_ble_link_adjust_allocation LCB {} Priority: {} XmitQuota: {}", yy, p_lcb->acl_priority, p_lcb->link_xmit_quota); - LOG_VERBOSE(" SentNotAcked: %d RRUnacked: %d", - p_lcb->sent_not_acked, l2cb.round_robin_unacked); + log::verbose("SentNotAcked: {} RRUnacked: {}", p_lcb->sent_not_acked, + l2cb.round_robin_unacked); /* There is a special case where we have readjusted the link quotas and */ /* this link may have sent anything but some other link sent packets so */ @@ -1302,42 +1068,6 @@ void l2c_ble_link_adjust_allocation(void) { } } -/******************************************************************************* - * - * Function l2cble_process_rc_param_request_evt - * - * Description process LE Remote Connection Parameter Request Event. - * - * Returns void - * - ******************************************************************************/ -void l2cble_process_rc_param_request_evt(uint16_t handle, uint16_t int_min, - uint16_t int_max, uint16_t latency, - uint16_t timeout) { - tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); - - if (p_lcb != NULL) { - p_lcb->min_interval = int_min; - p_lcb->max_interval = int_max; - p_lcb->latency = latency; - p_lcb->timeout = timeout; - - /* if update is enabled, always accept connection parameter update */ - if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) { - btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, - timeout, 0, 0); - } else { - LOG_VERBOSE("L2CAP - LE - update currently disabled"); - p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; - btsnd_hcic_ble_rc_param_req_neg_reply(handle, - HCI_ERR_UNACCEPT_CONN_INTERVAL); - } - - } else { - LOG_WARN("No link to update connection parameter"); - } -} - /******************************************************************************* * * Function l2cble_update_data_length @@ -1351,7 +1081,7 @@ void l2cble_update_data_length(tL2C_LCB* p_lcb) { uint16_t tx_mtu = 0; uint16_t i = 0; - LOG_VERBOSE("%s", __func__); + log::verbose(""); /* See if we have a link control block for the connection */ if (p_lcb == NULL) return; @@ -1389,16 +1119,17 @@ void l2cble_process_data_length_change_event(uint16_t handle, uint16_t rx_data_len) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); if (p_lcb == nullptr) { - LOG_WARN("Received data length change event for unknown ACL handle:0x%04x", - handle); + log::warn( + "Received data length change event for unknown ACL handle:0x{:04x}", + handle); return; } if (is_legal_tx_data_len(tx_data_len)) { if (p_lcb->tx_data_len != tx_data_len) { - LOG_DEBUG( - "Received data length change event for device:%s tx_data_len:%hu => " - "%hu", + log::debug( + "Received data length change event for device:{} tx_data_len:{} => " + "{}", ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr), p_lcb->tx_data_len, tx_data_len); BTM_LogHistory(kBtmLogTag, p_lcb->remote_bd_addr, "LE Data length change", @@ -1406,15 +1137,15 @@ void l2cble_process_data_length_change_event(uint16_t handle, p_lcb->tx_data_len, tx_data_len)); p_lcb->tx_data_len = tx_data_len; } else { - LOG_DEBUG( - "Received duplicated data length change event for device:%s " - "tx_data_len:%hu", + log::debug( + "Received duplicated data length change event for device:{} " + "tx_data_len:{}", ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr), tx_data_len); } } else { - LOG_WARN( - "Received illegal data length change event for device:%s " - "tx_data_len:%hu", + log::warn( + "Received illegal data length change event for device:{} " + "tx_data_len:{}", ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr), tx_data_len); } /* ignore rx_data len for now */ @@ -1434,7 +1165,7 @@ void l2cble_credit_based_conn_req(tL2C_CCB* p_ccb) { if (!p_ccb) return; if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { - LOG_WARN("LE link doesn't exist"); + log::warn("LE link doesn't exist"); return; } @@ -1460,7 +1191,7 @@ void l2cble_credit_based_conn_res(tL2C_CCB* p_ccb, uint16_t result) { if (!p_ccb) return; if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { - LOG_WARN("LE link doesn't exist"); + log::warn("LE link doesn't exist"); return; } @@ -1482,7 +1213,7 @@ void l2cble_send_flow_control_credit(tL2C_CCB* p_ccb, uint16_t credit_value) { if (!p_ccb) return; if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { - LOG_WARN("LE link doesn't exist"); + log::warn("LE link doesn't exist"); return; } @@ -1501,11 +1232,11 @@ void l2cble_send_flow_control_credit(tL2C_CCB* p_ccb, uint16_t credit_value) { * ******************************************************************************/ void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!p_ccb) return; if (p_ccb->p_lcb && p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { - LOG_WARN("LE link doesn't exist"); + log::warn("LE link doesn't exist"); return; } @@ -1531,8 +1262,8 @@ void l2cble_sec_comp(const RawAddress* bda, tBT_TRANSPORT transport, uint8_t sec_act; if (!p_lcb) { - LOG_WARN("%s: security complete for unknown device. bda=%s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(*bda)); + log::warn("security complete for unknown device. bda={}", + ADDRESS_TO_LOGGABLE_CSTR(*bda)); return; } @@ -1542,8 +1273,7 @@ void l2cble_sec_comp(const RawAddress* bda, tBT_TRANSPORT transport, if (!fixed_queue_is_empty(p_lcb->le_sec_pending_q)) { p_buf = (tL2CAP_SEC_DATA*)fixed_queue_dequeue(p_lcb->le_sec_pending_q); if (!p_buf) { - LOG_WARN("%s Security complete for request not initiated from L2CAP", - __func__); + log::warn("Security complete for request not initiated from L2CAP"); return; } @@ -1556,21 +1286,20 @@ void l2cble_sec_comp(const RawAddress* bda, tBT_TRANSPORT transport, (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status); else { - LOG_VERBOSE("%s MITM Protection Not present", __func__); + log::verbose("MITM Protection Not present"); (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data, BTM_FAILED_ON_SECURITY); } } else { - LOG_VERBOSE("%s MITM Protection not required sec_act = %d", __func__, - p_lcb->sec_act); + log::verbose("MITM Protection not required sec_act = {}", + p_lcb->sec_act); (*(p_buf->p_callback))(bda, BT_TRANSPORT_LE, p_buf->p_ref_data, status); } osi_free(p_buf); } } else { - LOG_WARN("%s Security complete for request not initiated from L2CAP", - __func__); + log::warn("Security complete for request not initiated from L2CAP"); return; } @@ -1608,14 +1337,14 @@ tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr, tL2C_LCB* p_lcb = NULL; if (!p_callback) { - LOG_ERROR("No callback function"); + log::error("No callback function"); return L2CAP_LE_RESULT_NO_RESOURCES; } p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); if (!p_lcb) { - LOG_ERROR("Security check for unknown device"); + log::error("Security check for unknown device"); p_callback(&bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_UNKNOWN_ADDR); return L2CAP_LE_RESULT_NO_RESOURCES; } @@ -1623,7 +1352,7 @@ tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr, tL2CAP_SEC_DATA* p_buf = (tL2CAP_SEC_DATA*)osi_malloc((uint16_t)sizeof(tL2CAP_SEC_DATA)); if (!p_buf) { - LOG_ERROR("No resources for connection"); + log::error("No resources for connection"); p_callback(&bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_NO_RESOURCES); return L2CAP_LE_RESULT_NO_RESOURCES; } @@ -1650,7 +1379,7 @@ tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr, case BTM_INSUFFICIENT_ENCRYPT_KEY_SIZE: return L2CAP_LE_RESULT_INSUFFICIENT_ENCRYP_KEY_SIZE; default: - LOG_ERROR("unexpected return value: %s", btm_status_text(result).c_str()); + log::error("unexpected return value: {}", btm_status_text(result)); return L2CAP_LE_RESULT_INVALID_PARAMETERS; } } @@ -1678,13 +1407,13 @@ void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, // When there are bonded Hearing Aid devices, we will constrained this // minimum interval. phone_min_interval = BTM_BLE_CONN_INT_MIN_HEARINGAID; - LOG_VERBOSE("%s: Have Hearing Aids. Min. interval is set to %d", __func__, - phone_min_interval); + log::verbose("Have Hearing Aids. Min. interval is set to {}", + phone_min_interval); } if (*min_interval < phone_min_interval) { - LOG_VERBOSE("%s: requested min_interval=%d too small. Set to %d", __func__, - *min_interval, phone_min_interval); + log::verbose("requested min_interval={} too small. Set to {}", + *min_interval, phone_min_interval); *min_interval = phone_min_interval; } @@ -1693,229 +1422,8 @@ void L2CA_AdjustConnectionIntervals(uint16_t* min_interval, // to remain established. // In other words, this is a workaround for certain peripherals. if (*max_interval < phone_min_interval) { - LOG_VERBOSE("%s: requested max_interval=%d too small. Set to %d", __func__, - *max_interval, phone_min_interval); + log::verbose("requested max_interval={} too small. Set to {}", + *max_interval, phone_min_interval); *max_interval = phone_min_interval; } } - -void l2cble_use_preferred_conn_params(const RawAddress& bda) { - tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE); - tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda); - - /* If there are any preferred connection parameters, set them now */ - if ((p_lcb != NULL) && (p_dev_rec != NULL) && - (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN) && - (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX) && - (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN) && - (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX) && - (p_dev_rec->conn_params.peripheral_latency <= BTM_BLE_CONN_LATENCY_MAX) && - (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) && - (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) && - ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int && - p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) || - (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) || - (p_lcb->latency > p_dev_rec->conn_params.peripheral_latency) || - (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout))) { - LOG_VERBOSE( - "%s: HANDLE=%d min_conn_int=%d max_conn_int=%d peripheral_latency=%d " - "supervision_tout=%d", - __func__, p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int, - p_dev_rec->conn_params.max_conn_int, - p_dev_rec->conn_params.peripheral_latency, - p_dev_rec->conn_params.supervision_tout); - - p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int; - p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int; - p_lcb->timeout = p_dev_rec->conn_params.supervision_tout; - p_lcb->latency = p_dev_rec->conn_params.peripheral_latency; - - btsnd_hcic_ble_upd_ll_conn_params( - p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int, - p_dev_rec->conn_params.max_conn_int, - p_dev_rec->conn_params.peripheral_latency, - p_dev_rec->conn_params.supervision_tout, 0, 0); - } -} - -/******************************************************************************* - * - * Function l2cble_start_subrate_change - * - * Description Start the BLE subrate change process based on - * status. - * - * Parameters: lcb : l2cap link control block - * - * Return value: none - * - ******************************************************************************/ -static void l2cble_start_subrate_change(tL2C_LCB* p_lcb) { - if (!BTM_IsAclConnectionUp(p_lcb->remote_bd_addr, BT_TRANSPORT_LE)) { - LOG(ERROR) << "No known connection ACL for " - << ADDRESS_TO_LOGGABLE_STR(p_lcb->remote_bd_addr); - return; - } - - btm_find_or_alloc_dev(p_lcb->remote_bd_addr); - - LOG_VERBOSE("%s: subrate_req_mask=%d conn_update_mask=%d", __func__, - p_lcb->subrate_req_mask, p_lcb->conn_update_mask); - - if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING) { - LOG_VERBOSE("%s: returning L2C_BLE_SUBRATE_REQ_PENDING ", __func__); - return; - } - - if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_DISABLE) { - LOG_VERBOSE("%s: returning L2C_BLE_SUBRATE_REQ_DISABLE ", __func__); - return; - } - - /* application allows to do update, if we were delaying one do it now */ - if (!(p_lcb->subrate_req_mask & L2C_BLE_NEW_SUBRATE_PARAM) || - (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) || - (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM)) { - LOG_VERBOSE("%s: returning L2C_BLE_NEW_SUBRATE_PARAM", __func__); - return; - } - - if (!controller_get_interface()->supports_ble_connection_subrating() || - !acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr) || - !acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr)) { - LOG_VERBOSE( - "%s: returning L2C_BLE_NEW_SUBRATE_PARAM local_host_sup=%d, " - "local_conn_subrarte_sup=%d, peer_subrate_sup=%d, peer_host_sup=%d", - __func__, - controller_get_interface()->supports_ble_connection_subrating_host(), - controller_get_interface()->supports_ble_connection_subrating(), - acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr), - acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr)); - return; - } - - LOG_VERBOSE("%s: Sending HCI cmd for subrate req", __func__); - bluetooth::shim::ACL_LeSubrateRequest( - p_lcb->Handle(), p_lcb->subrate_min, p_lcb->subrate_max, - p_lcb->max_latency, p_lcb->cont_num, p_lcb->supervision_tout); - - p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_PENDING; - p_lcb->subrate_req_mask &= ~L2C_BLE_NEW_SUBRATE_PARAM; - p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM; -} - -/******************************************************************************* - * - * Function L2CA_SetDefaultSubrate - * - * Description BLE Set Default Subrate - * - * Parameters: Subrate parameters - * - * Return value: void - * - ******************************************************************************/ -void L2CA_SetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, - uint16_t max_latency, uint16_t cont_num, - uint16_t timeout) { - VLOG(1) << __func__ << " subrate_min=" << subrate_min - << ", subrate_max=" << subrate_max << ", max_latency=" << max_latency - << ", cont_num=" << cont_num << ", timeout=" << timeout; - - bluetooth::shim::ACL_LeSetDefaultSubrate(subrate_min, subrate_max, - max_latency, cont_num, timeout); -} - -/******************************************************************************* - * - * Function L2CA_SubrateRequest - * - * Description BLE Subrate request. - * - * Parameters: Subrate parameters - * - * Return value: true if update started - * - ******************************************************************************/ -bool L2CA_SubrateRequest(const RawAddress& rem_bda, uint16_t subrate_min, - uint16_t subrate_max, uint16_t max_latency, - uint16_t cont_num, uint16_t timeout) { - tL2C_LCB* p_lcb; - - /* See if we have a link control block for the remote device */ - p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); - - /* If we don't have one, create one and accept the connection. */ - if (!p_lcb || !BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) { - LOG(WARNING) << __func__ << " - unknown BD_ADDR " - << ADDRESS_TO_LOGGABLE_STR(rem_bda); - return (false); - } - - if (p_lcb->transport != BT_TRANSPORT_LE) { - LOG(WARNING) << __func__ << " - BD_ADDR " - << ADDRESS_TO_LOGGABLE_STR(rem_bda) << " not LE"; - return (false); - } - - VLOG(1) << __func__ << ": BD_ADDR=" << ADDRESS_TO_LOGGABLE_STR(rem_bda) - << ", subrate_min=" << subrate_min << ", subrate_max=" << subrate_max - << ", max_latency=" << max_latency << ", cont_num=" << cont_num - << ", timeout=" << timeout; - - p_lcb->subrate_min = subrate_min; - p_lcb->subrate_max = subrate_max; - p_lcb->max_latency = max_latency; - p_lcb->cont_num = cont_num; - p_lcb->subrate_req_mask |= L2C_BLE_NEW_SUBRATE_PARAM; - p_lcb->supervision_tout = timeout; - - l2cble_start_subrate_change(p_lcb); - - return (true); -} - -/******************************************************************************* - * - * Function l2cble_process_subrate_change_evt - * - * Description This function enables LE subrating - * after a successful subrate change process is - * done. - * - * Parameters: LE connection handle - * status - * subrate factor - * peripheral latency - * continuation number - * supervision timeout - * - * Returns void - * - ******************************************************************************/ -void l2cble_process_subrate_change_evt(uint16_t handle, uint8_t status, - uint16_t subrate_factor, - uint16_t peripheral_latency, - uint16_t cont_num, uint16_t timeout) { - LOG_VERBOSE("%s", __func__); - - /* See if we have a link control block for the remote device */ - tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); - if (!p_lcb) { - LOG_WARN("%s: Invalid handle: %d", __func__, handle); - return; - } - - p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_PENDING; - - if (status != HCI_SUCCESS) { - LOG_WARN("%s: Error status: %d", __func__, status); - } - - l2cble_start_conn_update(p_lcb); - - l2cble_start_subrate_change(p_lcb); - - LOG_VERBOSE("%s: conn_update_mask=%d , subrate_req_mask=%d", __func__, - p_lcb->conn_update_mask, p_lcb->subrate_req_mask); -} diff --git a/system/stack/l2cap/l2c_ble_conn_params.cc b/system/stack/l2cap/l2c_ble_conn_params.cc new file mode 100644 index 0000000000000000000000000000000000000000..2db0debba1314c06e9b2e1b0d847c7d64100fa0c --- /dev/null +++ b/system/stack/l2cap/l2c_ble_conn_params.cc @@ -0,0 +1,572 @@ +/****************************************************************************** + * + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/****************************************************************************** + * + * this file contains functions relating to BLE connection parameter + *management. + * + ******************************************************************************/ + +#define LOG_TAG "l2c_ble_conn_params" + +#include +#include +#include + +#include "internal_include/stack_config.h" +#include "main/shim/acl_api.h" +#include "os/log.h" +#include "stack/btm/btm_dev.h" +#include "stack/include/acl_api.h" +#include "stack/include/btm_ble_api_types.h" +#include "stack/include/l2c_api.h" +#include "stack/l2cap/l2c_int.h" +#include "types/raw_address.h" + +using namespace bluetooth; + +void l2cble_start_conn_update(tL2C_LCB* p_lcb); +static void l2cble_start_subrate_change(tL2C_LCB* p_lcb); + +/******************************************************************************* + * + * Function L2CA_UpdateBleConnParams + * + * Description Update BLE connection parameters. + * + * Parameters: BD Address of remote + * + * Return value: true if update started + * + ******************************************************************************/ +bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int, + uint16_t max_int, uint16_t latency, + uint16_t timeout, uint16_t min_ce_len, + uint16_t max_ce_len) { + tL2C_LCB* p_lcb; + + /* See if we have a link control block for the remote device */ + p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); + + /* If we do not have one, create one and accept the connection. */ + if (!p_lcb || !BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) { + log::warn("- unknown BD_ADDR {}", ADDRESS_TO_LOGGABLE_STR(rem_bda)); + return (false); + } + + if (p_lcb->transport != BT_TRANSPORT_LE) { + log::warn("- BD_ADDR {} not LE", ADDRESS_TO_LOGGABLE_STR(rem_bda)); + return (false); + } + + log::verbose( + "BD_ADDR={}, min_int={}, max_int={}, min_ce_len={}, max_ce_len={}", + ADDRESS_TO_LOGGABLE_STR(rem_bda), min_int, max_int, min_ce_len, + max_ce_len); + + p_lcb->min_interval = min_int; + p_lcb->max_interval = max_int; + p_lcb->latency = latency; + p_lcb->timeout = timeout; + p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; + p_lcb->min_ce_len = min_ce_len; + p_lcb->max_ce_len = max_ce_len; + + l2cble_start_conn_update(p_lcb); + + return (true); +} + +static bool l2c_enable_update_ble_conn_params(tL2C_LCB* p_lcb, bool enable); + +/* When called with lock=true, LE connection parameters will be locked on + * fastest value, and we won't accept request to change it from remote. When + * called with lock=false, parameters are relaxed. + */ +void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& rem_bda, + bool lock) { + if (stack_config_get_interface()->get_pts_conn_updates_disabled()) return; + + tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); + if (!p_lcb) { + log::warn("unknown address {}", ADDRESS_TO_LOGGABLE_CSTR(rem_bda)); + return; + } + + if (p_lcb->transport != BT_TRANSPORT_LE) { + log::warn("{} not LE, link role {}", ADDRESS_TO_LOGGABLE_CSTR(rem_bda), + p_lcb->LinkRole()); + return; + } + + if (lock == p_lcb->conn_update_blocked_by_service_discovery) { + log::warn("{} service discovery already locked/unlocked conn params: {}", + ADDRESS_TO_LOGGABLE_CSTR(rem_bda), lock); + return; + } + + p_lcb->conn_update_blocked_by_service_discovery = lock; + + if (p_lcb->conn_update_blocked_by_profile_connection) { + log::info("{} conn params stay locked because of audio setup", + ADDRESS_TO_LOGGABLE_CSTR(rem_bda)); + return; + } + + log::info("{} Locking/unlocking conn params for service discovery: {}", + ADDRESS_TO_LOGGABLE_CSTR(rem_bda), lock); + l2c_enable_update_ble_conn_params(p_lcb, !lock); +} + +/* When called with lock=true, LE connection parameters will be locked on + * fastest value, and we won't accept request to change it from remote. When + * called with lock=false, parameters are relaxed. + */ +void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& rem_bda, + bool lock) { + if (stack_config_get_interface()->get_pts_conn_updates_disabled()) return; + + tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); + if (!p_lcb) { + log::warn("unknown address {}", ADDRESS_TO_LOGGABLE_CSTR(rem_bda)); + return; + } + + if (p_lcb->transport != BT_TRANSPORT_LE) { + log::warn("{} not LE, link role {}", ADDRESS_TO_LOGGABLE_CSTR(rem_bda), + p_lcb->LinkRole()); + return; + } + + if (lock == p_lcb->conn_update_blocked_by_profile_connection) { + log::info("{} audio setup already locked/unlocked conn params: {}", + ADDRESS_TO_LOGGABLE_CSTR(rem_bda), lock); + return; + } + + p_lcb->conn_update_blocked_by_profile_connection = lock; + + if (p_lcb->conn_update_blocked_by_service_discovery) { + log::info("{} conn params stay locked because of service discovery", + ADDRESS_TO_LOGGABLE_CSTR(rem_bda)); + return; + } + + log::info("{} Locking/unlocking conn params for audio setup: {}", + ADDRESS_TO_LOGGABLE_CSTR(rem_bda), lock); + l2c_enable_update_ble_conn_params(p_lcb, !lock); +} + +static bool l2c_enable_update_ble_conn_params(tL2C_LCB* p_lcb, bool enable) { + log::debug("{} enable {} current upd state 0x{:02x}", + ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr), enable, + p_lcb->conn_update_mask); + + if (enable) { + p_lcb->conn_update_mask &= ~L2C_BLE_CONN_UPDATE_DISABLE; + p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_DISABLE; + } else { + p_lcb->conn_update_mask |= L2C_BLE_CONN_UPDATE_DISABLE; + p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_DISABLE; + } + + l2cble_start_conn_update(p_lcb); + + return (true); +} + +/******************************************************************************* + * + * Function l2cble_start_conn_update + * + * Description Start the BLE connection parameter update process based on + * status. + * + * Parameters: lcb : l2cap link control block + * + * Return value: none + * + ******************************************************************************/ +void l2cble_start_conn_update(tL2C_LCB* p_lcb) { + uint16_t min_conn_int, max_conn_int, peripheral_latency, supervision_tout; + if (!BTM_IsAclConnectionUp(p_lcb->remote_bd_addr, BT_TRANSPORT_LE)) { + log::error("No known connection ACL for {}", + ADDRESS_TO_LOGGABLE_STR(p_lcb->remote_bd_addr)); + return; + } + + // TODO(armansito): The return value of this call wasn't being used but the + // logic of this function might be depending on its side effects. We should + // verify if this call is needed at all and remove it otherwise. + btm_find_or_alloc_dev(p_lcb->remote_bd_addr); + + if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) || + (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING)) { + return; + } + + if (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) { + /* application requests to disable parameters update. + If parameters are already updated, lets set them + up to what has been requested during connection establishement */ + if (p_lcb->conn_update_mask & L2C_BLE_NOT_DEFAULT_PARAM && + /* current connection interval is greater than default min */ + p_lcb->min_interval > BTM_BLE_CONN_INT_MIN) { + /* use 7.5 ms as fast connection parameter, 0 peripheral latency */ + min_conn_int = max_conn_int = BTM_BLE_CONN_INT_MIN; + + L2CA_AdjustConnectionIntervals(&min_conn_int, &max_conn_int, + BTM_BLE_CONN_INT_MIN); + + peripheral_latency = BTM_BLE_CONN_PERIPHERAL_LATENCY_DEF; + supervision_tout = BTM_BLE_CONN_TIMEOUT_DEF; + + /* if both side 4.1, or we are central device, send HCI command */ + if (p_lcb->IsLinkRoleCentral() || + (controller_get_interface() + ->SupportsBleConnectionParametersRequest() && + acl_peer_supports_ble_connection_parameters_request( + p_lcb->remote_bd_addr))) { + btsnd_hcic_ble_upd_ll_conn_params(p_lcb->Handle(), min_conn_int, + max_conn_int, peripheral_latency, + supervision_tout, 0, 0); + p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; + } else { + l2cu_send_peer_ble_par_req(p_lcb, min_conn_int, max_conn_int, + peripheral_latency, supervision_tout); + } + p_lcb->conn_update_mask &= ~L2C_BLE_NOT_DEFAULT_PARAM; + p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; + } + } else { + /* application allows to do update, if we were delaying one do it now */ + if (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM) { + /* if both side 4.1, or we are central device, send HCI command */ + if (p_lcb->IsLinkRoleCentral() || + (controller_get_interface() + ->SupportsBleConnectionParametersRequest() && + acl_peer_supports_ble_connection_parameters_request( + p_lcb->remote_bd_addr))) { + btsnd_hcic_ble_upd_ll_conn_params(p_lcb->Handle(), p_lcb->min_interval, + p_lcb->max_interval, p_lcb->latency, + p_lcb->timeout, p_lcb->min_ce_len, + p_lcb->max_ce_len); + p_lcb->conn_update_mask |= L2C_BLE_UPDATE_PENDING; + } else { + l2cu_send_peer_ble_par_req(p_lcb, p_lcb->min_interval, + p_lcb->max_interval, p_lcb->latency, + p_lcb->timeout); + } + p_lcb->conn_update_mask &= ~L2C_BLE_NEW_CONN_PARAM; + p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM; + } + } +} + +/******************************************************************************* + * + * Function l2cble_process_conn_update_evt + * + * Description This function enables the connection update request from + * remote after a successful connection update response is + * received. + * + * Returns void + * + ******************************************************************************/ +void l2cble_process_conn_update_evt(uint16_t handle, uint8_t status, + uint16_t interval, uint16_t latency, + uint16_t timeout) { + log::verbose(""); + + /* See if we have a link control block for the remote device */ + tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); + if (!p_lcb) { + log::warn("Invalid handle: {}", handle); + return; + } + + p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PENDING; + + if (status != HCI_SUCCESS) { + log::warn("Error status: {}", status); + } + + l2cble_start_conn_update(p_lcb); + + l2cble_start_subrate_change(p_lcb); + + log::verbose("conn_update_mask={} , subrate_req_mask={}", + p_lcb->conn_update_mask, p_lcb->subrate_req_mask); +} + +/******************************************************************************* + * + * Function l2cble_process_rc_param_request_evt + * + * Description process LE Remote Connection Parameter Request Event. + * + * Returns void + * + ******************************************************************************/ +void l2cble_process_rc_param_request_evt(uint16_t handle, uint16_t int_min, + uint16_t int_max, uint16_t latency, + uint16_t timeout) { + tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); + + if (p_lcb != NULL) { + p_lcb->min_interval = int_min; + p_lcb->max_interval = int_max; + p_lcb->latency = latency; + p_lcb->timeout = timeout; + + /* if update is enabled, always accept connection parameter update */ + if ((p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE) == 0) { + btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, + timeout, 0, 0); + } else { + log::verbose("L2CAP - LE - update currently disabled"); + p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM; + btsnd_hcic_ble_rc_param_req_neg_reply(handle, + HCI_ERR_UNACCEPT_CONN_INTERVAL); + } + + } else { + log::warn("No link to update connection parameter"); + } +} + +void l2cble_use_preferred_conn_params(const RawAddress& bda) { + tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE); + tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda); + + /* If there are any preferred connection parameters, set them now */ + if ((p_lcb != NULL) && (p_dev_rec != NULL) && + (p_dev_rec->conn_params.min_conn_int >= BTM_BLE_CONN_INT_MIN) && + (p_dev_rec->conn_params.min_conn_int <= BTM_BLE_CONN_INT_MAX) && + (p_dev_rec->conn_params.max_conn_int >= BTM_BLE_CONN_INT_MIN) && + (p_dev_rec->conn_params.max_conn_int <= BTM_BLE_CONN_INT_MAX) && + (p_dev_rec->conn_params.peripheral_latency <= BTM_BLE_CONN_LATENCY_MAX) && + (p_dev_rec->conn_params.supervision_tout >= BTM_BLE_CONN_SUP_TOUT_MIN) && + (p_dev_rec->conn_params.supervision_tout <= BTM_BLE_CONN_SUP_TOUT_MAX) && + ((p_lcb->min_interval < p_dev_rec->conn_params.min_conn_int && + p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) || + (p_lcb->min_interval > p_dev_rec->conn_params.max_conn_int) || + (p_lcb->latency > p_dev_rec->conn_params.peripheral_latency) || + (p_lcb->timeout > p_dev_rec->conn_params.supervision_tout))) { + log::verbose( + "HANDLE={} min_conn_int={} max_conn_int={} peripheral_latency={} " + "supervision_tout={}", + p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int, + p_dev_rec->conn_params.max_conn_int, + p_dev_rec->conn_params.peripheral_latency, + p_dev_rec->conn_params.supervision_tout); + + p_lcb->min_interval = p_dev_rec->conn_params.min_conn_int; + p_lcb->max_interval = p_dev_rec->conn_params.max_conn_int; + p_lcb->timeout = p_dev_rec->conn_params.supervision_tout; + p_lcb->latency = p_dev_rec->conn_params.peripheral_latency; + + btsnd_hcic_ble_upd_ll_conn_params( + p_lcb->Handle(), p_dev_rec->conn_params.min_conn_int, + p_dev_rec->conn_params.max_conn_int, + p_dev_rec->conn_params.peripheral_latency, + p_dev_rec->conn_params.supervision_tout, 0, 0); + } +} + +/******************************************************************************* + * + * Function l2cble_start_subrate_change + * + * Description Start the BLE subrate change process based on + * status. + * + * Parameters: lcb : l2cap link control block + * + * Return value: none + * + ******************************************************************************/ +static void l2cble_start_subrate_change(tL2C_LCB* p_lcb) { + if (!BTM_IsAclConnectionUp(p_lcb->remote_bd_addr, BT_TRANSPORT_LE)) { + log::error("No known connection ACL for {}", + ADDRESS_TO_LOGGABLE_STR(p_lcb->remote_bd_addr)); + return; + } + + btm_find_or_alloc_dev(p_lcb->remote_bd_addr); + + log::verbose("subrate_req_mask={} conn_update_mask={}", + p_lcb->subrate_req_mask, p_lcb->conn_update_mask); + + if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_PENDING) { + log::verbose("returning L2C_BLE_SUBRATE_REQ_PENDING "); + return; + } + + if (p_lcb->subrate_req_mask & L2C_BLE_SUBRATE_REQ_DISABLE) { + log::verbose("returning L2C_BLE_SUBRATE_REQ_DISABLE "); + return; + } + + /* application allows to do update, if we were delaying one do it now */ + if (!(p_lcb->subrate_req_mask & L2C_BLE_NEW_SUBRATE_PARAM) || + (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) || + (p_lcb->conn_update_mask & L2C_BLE_NEW_CONN_PARAM)) { + log::verbose("returning L2C_BLE_NEW_SUBRATE_PARAM"); + return; + } + + if (!controller_get_interface()->SupportsBleConnectionSubrating() || + !acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr) || + !acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr)) { + log::verbose( + "returning L2C_BLE_NEW_SUBRATE_PARAM local_host_sup={}, " + "local_conn_subrarte_sup={}, peer_subrate_sup={}, peer_host_sup={}", + controller_get_interface()->SupportsBleConnectionSubratingHost(), + controller_get_interface()->SupportsBleConnectionSubrating(), + acl_peer_supports_ble_connection_subrating(p_lcb->remote_bd_addr), + acl_peer_supports_ble_connection_subrating_host(p_lcb->remote_bd_addr)); + return; + } + + log::verbose("Sending HCI cmd for subrate req"); + bluetooth::shim::ACL_LeSubrateRequest( + p_lcb->Handle(), p_lcb->subrate_min, p_lcb->subrate_max, + p_lcb->max_latency, p_lcb->cont_num, p_lcb->supervision_tout); + + p_lcb->subrate_req_mask |= L2C_BLE_SUBRATE_REQ_PENDING; + p_lcb->subrate_req_mask &= ~L2C_BLE_NEW_SUBRATE_PARAM; + p_lcb->conn_update_mask |= L2C_BLE_NOT_DEFAULT_PARAM; +} + +/******************************************************************************* + * + * Function L2CA_SetDefaultSubrate + * + * Description BLE Set Default Subrate + * + * Parameters: Subrate parameters + * + * Return value: void + * + ******************************************************************************/ +void L2CA_SetDefaultSubrate(uint16_t subrate_min, uint16_t subrate_max, + uint16_t max_latency, uint16_t cont_num, + uint16_t timeout) { + log::verbose( + "subrate_min={}, subrate_max={}, max_latency={}, cont_num={}, timeout={}", + subrate_min, subrate_max, max_latency, cont_num, timeout); + + bluetooth::shim::ACL_LeSetDefaultSubrate(subrate_min, subrate_max, + max_latency, cont_num, timeout); +} + +/******************************************************************************* + * + * Function L2CA_SubrateRequest + * + * Description BLE Subrate request. + * + * Parameters: Subrate parameters + * + * Return value: true if update started + * + ******************************************************************************/ +bool L2CA_SubrateRequest(const RawAddress& rem_bda, uint16_t subrate_min, + uint16_t subrate_max, uint16_t max_latency, + uint16_t cont_num, uint16_t timeout) { + tL2C_LCB* p_lcb; + + /* See if we have a link control block for the remote device */ + p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); + + /* If we don't have one, create one and accept the connection. */ + if (!p_lcb || !BTM_IsAclConnectionUp(rem_bda, BT_TRANSPORT_LE)) { + log::warn("unknown BD_ADDR {}", ADDRESS_TO_LOGGABLE_STR(rem_bda)); + return (false); + } + + if (p_lcb->transport != BT_TRANSPORT_LE) { + log::warn("BD_ADDR {} not LE", ADDRESS_TO_LOGGABLE_STR(rem_bda)); + return (false); + } + + log::verbose( + "BD_ADDR={}, subrate_min={}, subrate_max={}, max_latency={}, " + "cont_num={}, timeout={}", + ADDRESS_TO_LOGGABLE_STR(rem_bda), subrate_min, subrate_max, max_latency, + cont_num, timeout); + + p_lcb->subrate_min = subrate_min; + p_lcb->subrate_max = subrate_max; + p_lcb->max_latency = max_latency; + p_lcb->cont_num = cont_num; + p_lcb->subrate_req_mask |= L2C_BLE_NEW_SUBRATE_PARAM; + p_lcb->supervision_tout = timeout; + + l2cble_start_subrate_change(p_lcb); + + return (true); +} + +/******************************************************************************* + * + * Function l2cble_process_subrate_change_evt + * + * Description This function enables LE subrating + * after a successful subrate change process is + * done. + * + * Parameters: LE connection handle + * status + * subrate factor + * peripheral latency + * continuation number + * supervision timeout + * + * Returns void + * + ******************************************************************************/ +void l2cble_process_subrate_change_evt(uint16_t handle, uint8_t status, + uint16_t subrate_factor, + uint16_t peripheral_latency, + uint16_t cont_num, uint16_t timeout) { + log::verbose(""); + + /* See if we have a link control block for the remote device */ + tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); + if (!p_lcb) { + log::warn("Invalid handle: {}", handle); + return; + } + + p_lcb->subrate_req_mask &= ~L2C_BLE_SUBRATE_REQ_PENDING; + + if (status != HCI_SUCCESS) { + log::warn("Error status: {}", status); + } + + l2cble_start_conn_update(p_lcb); + + l2cble_start_subrate_change(p_lcb); + + log::verbose("conn_update_mask={} , subrate_req_mask={}", + p_lcb->conn_update_mask, p_lcb->subrate_req_mask); +} diff --git a/system/stack/l2cap/l2c_csm.cc b/system/stack/l2cap/l2c_csm.cc index b64571d3bcf740656e786e4922253004ed1b9a8f..fbab24bcea3acd89c763852206c978ba01843e0e 100644 --- a/system/stack/l2cap/l2c_csm.cc +++ b/system/stack/l2cap/l2c_csm.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -43,6 +44,8 @@ #include "stack/include/l2cdefs.h" #include "stack/l2cap/l2c_int.h" +using namespace bluetooth; + /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /******************************************************************************/ @@ -106,7 +109,7 @@ static void l2c_csm_indicate_connection_open(tL2C_CCB* p_ccb) { p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, p_ccb->p_rcb->psm, p_ccb->remote_id); } else { - LOG_WARN("pL2CA_ConnectInd_Cb is null"); + log::warn("pL2CA_ConnectInd_Cb is null"); } } if (p_ccb->chnl_state == CST_OPEN && !p_ccb->p_lcb->is_transport_ble()) { @@ -129,18 +132,18 @@ static void l2c_csm_indicate_connection_open(tL2C_CCB* p_ccb) { ******************************************************************************/ void l2c_csm_execute(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { if (p_ccb == nullptr) { - LOG_WARN("CCB is null for event (%d)", event); + log::warn("CCB is null for event ({})", event); return; } if (!l2cu_is_ccb_active(p_ccb)) { - LOG_WARN("CCB not in use, event (%d) cannot be processed", event); + log::warn("CCB not in use, event ({}) cannot be processed", event); return; } - LOG_VERBOSE("Entry chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Entry chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); switch (p_ccb->chnl_state) { case CST_CLOSED: @@ -180,7 +183,7 @@ void l2c_csm_execute(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { break; default: - LOG_ERROR("Unhandled state %d, event %d", p_ccb->chnl_state, event); + log::error("Unhandled state {}, event {}", p_ccb->chnl_state, event); break; } } @@ -202,20 +205,20 @@ static void l2c_csm_closed(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { tL2CA_DISCONNECT_IND_CB* disconnect_ind; if (p_ccb->p_rcb == NULL) { - LOG_ERROR("LCID: 0x%04x st: CLOSED evt: %s p_rcb == NULL", - p_ccb->local_cid, l2c_csm_get_event_name(event)); + log::error("LCID: 0x{:04x} st: CLOSED evt: {} p_rcb == NULL", + p_ccb->local_cid, l2c_csm_get_event_name(event)); return; } disconnect_ind = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - LOG_DEBUG("LCID: 0x%04x st: CLOSED evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::debug("LCID: 0x{:04x} st: CLOSED evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; @@ -255,7 +258,7 @@ static void l2c_csm_closed(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { true, &l2c_link_sec_comp, p_ccb); } else { if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) { - LOG_WARN("Unable to set link policy active"); + log::warn("Unable to set link policy active"); } /* If sec access does not result in started SEC_COM or COMP_NEG are * already processed */ @@ -332,7 +335,7 @@ static void l2c_csm_closed(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { } } else { if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) { - LOG_WARN("Unable to set link policy active"); + log::warn("Unable to set link policy active"); } p_ccb->chnl_state = CST_TERM_W4_SEC_COMP; auto status = btm_sec_l2cap_access_req(p_ccb->p_lcb->remote_bd_addr, @@ -342,8 +345,8 @@ static void l2c_csm_closed(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { // started the security process, tell the peer to set a longer timer l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0); } else { - LOG_INFO("Check security for psm 0x%04x, status %d", - p_ccb->p_rcb->psm, status); + log::info("Check security for psm 0x{:04x}, status {}", + p_ccb->p_rcb->psm, status); } } break; @@ -367,11 +370,11 @@ static void l2c_csm_closed(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -390,16 +393,16 @@ static void l2c_csm_orig_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; uint16_t local_cid = p_ccb->local_cid; - LOG_DEBUG("%s - LCID: 0x%04x st: ORIG_W4_SEC_COMP evt: %s", - ((p_ccb->p_lcb) && (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)) - ? "LE " - : "", - p_ccb->local_cid, l2c_csm_get_event_name(event)); + log::debug("{} - LCID: 0x{:04x} st: ORIG_W4_SEC_COMP evt: {}", + ((p_ccb->p_lcb) && (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)) + ? "LE " + : "", + p_ccb->local_cid, l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; @@ -475,11 +478,11 @@ static void l2c_csm_orig_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -494,8 +497,8 @@ static void l2c_csm_orig_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, ******************************************************************************/ static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { - LOG_DEBUG("LCID: 0x%04x st: TERM_W4_SEC_COMP evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::debug("LCID: 0x{:04x} st: TERM_W4_SEC_COMP evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ @@ -511,20 +514,20 @@ static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, /* Wait for the info resp in next state before sending connect ind (if * needed) */ if (!p_ccb->p_lcb->w4_info_rsp) { - LOG_DEBUG("Not waiting for info response, sending connect response"); + log::debug("Not waiting for info response, sending connect response"); /* Don't need to get info from peer or already retrieved so continue */ alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS, l2c_ccb_timer_timeout, p_ccb); if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { - LOG_DEBUG("Not LE connection, sending configure request"); + log::debug("Not LE connection, sending configure request"); l2c_csm_send_connect_rsp(p_ccb); l2c_csm_send_config_req(p_ccb); } else { if (p_ccb->ecoc) { /* Handle Credit Based Connection */ - LOG_DEBUG("Calling CreditBasedConnect_Ind_Cb(), num of cids: %d", - p_ccb->p_lcb->pending_ecoc_conn_cnt); + log::debug("Calling CreditBasedConnect_Ind_Cb(), num of cids: {}", + p_ccb->p_lcb->pending_ecoc_conn_cnt); std::vector pending_cids; for (int i = 0; i < p_ccb->p_lcb->pending_ecoc_conn_cnt; i++) { @@ -537,8 +540,8 @@ static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, p_ccb->peer_conn_cfg.mtu, p_ccb->remote_id); } else { /* Handle BLE CoC */ - LOG_DEBUG("Calling Connect_Ind_Cb(), CID: 0x%04x", - p_ccb->local_cid); + log::debug("Calling Connect_Ind_Cb(), CID: 0x{:04x}", + p_ccb->local_cid); l2c_csm_send_connect_rsp(p_ccb); l2c_csm_indicate_connection_open(p_ccb); } @@ -560,7 +563,7 @@ static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, alarm_cancel(p_ccb->l2c_ccb_timer); /* Waiting for the info resp, tell the peer to set a longer timer */ - LOG_DEBUG("Waiting for info response, sending connect pending"); + log::debug("Waiting for info response, sending connect pending"); l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0); } break; @@ -615,11 +618,11 @@ static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -642,8 +645,8 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, uint16_t local_cid = p_ccb->local_cid; tL2C_LCB* p_lcb = p_ccb->p_lcb; - LOG_DEBUG("LCID: 0x%04x st: W4_L2CAP_CON_RSP evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::debug("LCID: 0x{:04x} st: W4_L2CAP_CON_RSP evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ @@ -654,8 +657,8 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, p_ccb->chnl_state = CST_CLOSED; if ((p_ccb->flags & CCB_FLAG_NO_RETRY) || !p_data || (*((uint8_t*)p_data) != HCI_ERR_PEER_USER)) { - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); } @@ -677,8 +680,8 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS, l2c_ccb_timer_timeout, p_ccb); } - LOG_DEBUG("Calling Connect_Cfm_Cb(), CID: 0x%04x, Success", - p_ccb->local_cid); + log::debug("Calling Connect_Cfm_Cb(), CID: 0x{:04x}, Success", + p_ccb->local_cid); l2c_csm_send_config_req(p_ccb); break; @@ -693,20 +696,16 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP: alarm_cancel(p_ccb->l2c_ccb_timer); p_ccb->chnl_state = CST_OPEN; - LOG_DEBUG( - "Calling credit_based_connect_cfm()," - "cid %d, result 0x%04x", - p_ccb->local_cid, L2CAP_CONN_OK); + log::debug("Calling credit_based_connect_cfm(),cid {}, result 0x{:04x}", + p_ccb->local_cid, L2CAP_CONN_OK); (*credit_based_connect_cfm)(p_lcb->remote_bd_addr, p_ccb->local_cid, p_ci->peer_mtu, L2CAP_CONN_OK); break; case L2CEVT_L2CAP_CREDIT_BASED_CONNECT_RSP_NEG: - LOG_DEBUG( - "Calling pL2CA_Error_Cb()," - "cid %d, result 0x%04x", - local_cid, p_ci->l2cap_result); + log::debug("Calling pL2CA_Error_Cb(),cid {}, result 0x{:04x}", local_cid, + p_ci->l2cap_result); (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid, p_ci->l2cap_result); bluetooth::shim::CountCounterMetrics( android::bluetooth::CodePathCounterKeyEnum:: @@ -717,9 +716,8 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, break; case L2CEVT_L2CAP_CONNECT_RSP_NEG: /* Peer rejected connection */ - LOG(WARNING) << __func__ << ": L2CAP connection rejected, lcid=" - << loghex(p_ccb->local_cid) - << ", reason=" << loghex(p_ci->l2cap_result); + log::warn("L2CAP connection rejected, lcid={}, reason={}", + loghex(p_ccb->local_cid), loghex(p_ci->l2cap_result)); l2cu_release_ccb(p_ccb); if (p_lcb->transport == BT_TRANSPORT_LE) { (*p_ccb->p_rcb->api.pL2CA_Error_Cb)( @@ -732,13 +730,13 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, break; case L2CEVT_TIMEOUT: - LOG(WARNING) << __func__ << ": L2CAP connection timeout"; + log::warn("L2CAP connection timeout"); if (p_ccb->ecoc) { for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) { uint16_t cid = p_lcb->pending_ecoc_connection_cids[i]; tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid); - LOG(WARNING) << __func__ << ": lcid= " << loghex(cid); + log::warn("lcid= {}", loghex(cid)); (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(p_ccb->local_cid, L2CAP_CONN_TIMEOUT); bluetooth::shim::CountCounterMetrics( @@ -752,7 +750,7 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, L2CAP_CREDIT_BASED_MAX_CIDS); } else { - LOG(WARNING) << __func__ << ": lcid= " << loghex(p_ccb->local_cid); + log::warn("lcid= {}", loghex(p_ccb->local_cid)); l2cu_release_ccb(p_ccb); (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(local_cid, L2CAP_CONN_OTHER_ERROR); bluetooth::shim::CountCounterMetrics( @@ -803,11 +801,11 @@ static void l2c_csm_w4_l2cap_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -828,13 +826,13 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; uint16_t local_cid = p_ccb->local_cid; - LOG_DEBUG("LCID: 0x%04x st: W4_L2CA_CON_RSP evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::debug("LCID: 0x{:04x} st: W4_L2CA_CON_RSP evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; @@ -842,7 +840,7 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, case L2CEVT_L2CA_CREDIT_BASED_CONNECT_RSP: p_ci = (tL2C_CONN_INFO*)p_data; if ((p_lcb == nullptr) || (p_lcb && p_lcb->transport != BT_TRANSPORT_LE)) { - LOG_WARN("LE link doesn't exist"); + log::warn("LE link doesn't exist"); return; } l2cu_send_peer_credit_based_conn_res(p_ccb, p_ci->lcids, @@ -852,8 +850,8 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) { uint16_t cid = p_lcb->pending_ecoc_connection_cids[i]; if (cid == 0) { - LOG_WARN("pending_ecoc_connection_cids[%d] is %d", i, cid); - continue; + log::warn("pending_ecoc_connection_cids[{}] is {}", i, cid); + continue; } tL2C_CCB* temp_p_ccb = l2cu_find_ccb_by_cid(p_lcb, cid); @@ -866,7 +864,9 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, } } else { - LOG_WARN("temp_p_ccb is NULL, pending_ecoc_connection_cids[%d] is %d", i, cid); + log::warn( + "temp_p_ccb is NULL, pending_ecoc_connection_cids[{}] is {}", i, + cid); } } p_lcb->pending_ecoc_conn_cnt = 0; @@ -889,15 +889,15 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, } else { /* Result should be OK or PENDING */ if ((!p_ci) || (p_ci->l2cap_result == L2CAP_CONN_OK)) { - LOG_DEBUG("Sending connection ok for BR_EDR"); + log::debug("Sending connection ok for BR_EDR"); l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_OK, 0); p_ccb->chnl_state = CST_CONFIG; alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CFG_TIMEOUT_MS, l2c_ccb_timer_timeout, p_ccb); } else { /* If pending, stay in same state and start extended timer */ - LOG_DEBUG("Sending connection result %d and status %d", - p_ci->l2cap_result, p_ci->l2cap_status); + log::debug("Sending connection result {} and status {}", + p_ci->l2cap_result, p_ci->l2cap_status); l2cu_send_peer_connect_rsp(p_ccb, p_ci->l2cap_result, p_ci->l2cap_status); alarm_set_on_mloop(p_ccb->l2c_ccb_timer, @@ -938,8 +938,8 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, case L2CEVT_TIMEOUT: l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_NO_PSM, 0); - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; @@ -960,17 +960,17 @@ static void l2c_csm_w4_l2ca_connect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, /* We have feature info, so now give the upper layer connect IND */ alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_CONNECT_TIMEOUT_MS, l2c_ccb_timer_timeout, p_ccb); - LOG_DEBUG("Calling Connect_Ind_Cb(), CID: 0x%04x", p_ccb->local_cid); + log::debug("Calling Connect_Ind_Cb(), CID: 0x{:04x}", p_ccb->local_cid); l2c_csm_send_connect_rsp(p_ccb); l2c_csm_send_config_req(p_ccb); break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -993,13 +993,13 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { tL2C_CCB* temp_p_ccb; tL2CAP_LE_CFG_INFO* p_le_cfg = (tL2CAP_LE_CFG_INFO*)p_data; - LOG_DEBUG("LCID: 0x%04x st: CONFIG evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::debug("LCID: 0x{:04x} st: CONFIG evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; @@ -1008,8 +1008,8 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { /* For ecoc reconfig is handled below in l2c_ble. In case of success * let us notify upper layer about the reconfig */ - LOG_DEBUG("Calling LeReconfigCompleted_Cb(), CID: 0x%04x", - p_ccb->local_cid); + log::debug("Calling LeReconfigCompleted_Cb(), CID: 0x{:04x}", + p_ccb->local_cid); (*p_ccb->p_rcb->api.pL2CA_CreditBasedReconfigCompleted_Cb)( p_lcb->remote_bd_addr, p_ccb->local_cid, false, p_le_cfg); @@ -1017,8 +1017,9 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { case L2CEVT_L2CAP_CONFIG_REQ: /* Peer config request */ cfg_result = l2cu_process_peer_cfg_req(p_ccb, p_cfg); if (cfg_result == L2CAP_PEER_CFG_OK) { - LOG_DEBUG("Calling Config_Req_Cb(), CID: 0x%04x, C-bit %d", - p_ccb->local_cid, (p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT)); + log::debug("Calling Config_Req_Cb(), CID: 0x{:04x}, C-bit {}", + p_ccb->local_cid, + (p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT)); l2c_csm_send_config_rsp_ok(p_ccb, p_cfg->flags & L2CAP_CFG_FLAGS_MASK_CONT); if (p_ccb->config_done & OB_CFG_DONE) { @@ -1037,11 +1038,11 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { } } else if (cfg_result == L2CAP_PEER_CFG_DISCONNECT) { /* Disconnect if channels are incompatible */ - LOG_DEBUG("incompatible configurations disconnect"); + log::debug("incompatible configurations disconnect"); l2cu_disconnect_chnl(p_ccb); } else /* Return error to peer so it can renegotiate if possible */ { - LOG_DEBUG("incompatible configurations trying reconfig"); + log::debug("incompatible configurations trying reconfig"); l2cu_send_peer_config_rsp(p_ccb, p_cfg); } break; @@ -1052,7 +1053,7 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { p_ccb->chnl_state = CST_OPEN; alarm_cancel(p_ccb->l2c_ccb_timer); - LOG_DEBUG("Calling Config_Rsp_Cb(), CID: 0x%04x", p_ccb->local_cid); + log::debug("Calling Config_Rsp_Cb(), CID: 0x{:04x}", p_ccb->local_cid); p_ccb->p_rcb->api.pL2CA_CreditBasedReconfigCompleted_Cb( p_lcb->remote_bd_addr, p_ccb->local_cid, true, p_le_cfg); @@ -1073,9 +1074,9 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { /* Verify two sides are in compatible modes before continuing */ if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) { l2cu_send_peer_disc_req(p_ccb); - LOG_WARN( - "Calling Disconnect_Ind_Cb(Incompatible CFG), CID: " - "0x%04x No Conf Needed", + log::warn( + "Calling Disconnect_Ind_Cb(Incompatible CFG), CID: 0x{:04x} No " + "Conf Needed", p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); @@ -1116,7 +1117,7 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE); } - LOG_DEBUG("Calling Config_Rsp_Cb(), CID: 0x%04x", p_ccb->local_cid); + log::debug("Calling Config_Rsp_Cb(), CID: 0x{:04x}", p_ccb->local_cid); p_ccb->remote_config_rsp_result = p_cfg->result; if (p_ccb->config_done & IB_CFG_DONE) { l2c_csm_indicate_connection_open(p_ccb); @@ -1129,8 +1130,8 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { /* If failure was channel mode try to renegotiate */ if (!l2c_fcr_renegotiate_chan(p_ccb, p_cfg)) { - LOG_DEBUG("Calling Config_Rsp_Cb(), CID: 0x%04x, Failure: %d", - p_ccb->local_cid, p_cfg->result); + log::debug("Calling Config_Rsp_Cb(), CID: 0x{:04x}, Failure: {}", + p_ccb->local_cid, p_cfg->result); if (p_ccb->connection_initiator == L2CAP_INITIATOR_LOCAL) { (*p_ccb->p_rcb->api.pL2CA_Error_Cb)(p_ccb->local_cid, L2CAP_CFG_FAILED_NO_REASON); @@ -1145,8 +1146,8 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS, l2c_ccb_timer_timeout, p_ccb); p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP; - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} Conf Needed", + p_ccb->local_cid); (*p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb)(p_ccb->local_cid, true); l2c_csm_send_disconnect_rsp(p_ccb); break; @@ -1172,9 +1173,9 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { /* Verify two sides are in compatible modes before continuing */ if (p_ccb->our_cfg.fcr.mode != p_ccb->peer_cfg.fcr.mode) { l2cu_send_peer_disc_req(p_ccb); - LOG_WARN( - "Calling Disconnect_Ind_Cb(Incompatible CFG), CID: " - "0x%04x No Conf Needed", + log::warn( + "Calling Disconnect_Ind_Cb(Incompatible CFG), CID: 0x{:04x} No " + "Conf Needed", p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); @@ -1215,7 +1216,7 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { break; case L2CEVT_L2CAP_DATA: /* Peer data packet rcvd */ - LOG_DEBUG("Calling DataInd_Cb(), CID: 0x%04x", p_ccb->local_cid); + log::debug("Calling DataInd_Cb(), CID: 0x{:04x}", p_ccb->local_cid); if (p_ccb->local_cid >= L2CAP_FIRST_FIXED_CHNL && p_ccb->local_cid <= L2CAP_LAST_FIXED_CHNL) { if (p_ccb->local_cid < L2CAP_BASE_APPL_CID) { @@ -1261,17 +1262,17 @@ static void l2c_csm_config(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { } l2cu_send_peer_disc_req(p_ccb); - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -1293,13 +1294,13 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { uint16_t credit = 0; tL2CAP_LE_CFG_INFO* p_le_cfg = (tL2CAP_LE_CFG_INFO*)p_data; - LOG_VERBOSE("LCID: 0x%04x st: OPEN evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::verbose("LCID: 0x{:04x} st: OPEN evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); power_telemetry::GetInstance().LogChannelDisconnected( p_ccb->p_rcb->psm, p_ccb->local_cid, p_ccb->remote_id, p_ccb->p_lcb->remote_bd_addr); @@ -1313,8 +1314,8 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { * let us notify upper layer about the reconfig */ if (p_le_cfg) { - LOG_DEBUG("Calling LeReconfigCompleted_Cb(), CID: 0x%04x", - p_ccb->local_cid); + log::debug("Calling LeReconfigCompleted_Cb(), CID: 0x{:04x}", + p_ccb->local_cid); (*p_ccb->p_rcb->api.pL2CA_CreditBasedReconfigCompleted_Cb)( p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, false, p_le_cfg); } @@ -1362,15 +1363,15 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { case L2CEVT_L2CAP_DISCONNECT_REQ: /* Peer disconnected request */ if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) { - LOG_WARN("Unable to set link policy active"); + log::warn("Unable to set link policy active"); } } p_ccb->chnl_state = CST_W4_L2CA_DISCONNECT_RSP; alarm_set_on_mloop(p_ccb->l2c_ccb_timer, L2CAP_CHNL_DISCONNECT_TIMEOUT_MS, l2c_ccb_timer_timeout, p_ccb); - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} Conf Needed", + p_ccb->local_cid); power_telemetry::GetInstance().LogChannelDisconnected( p_ccb->p_rcb->psm, p_ccb->local_cid, p_ccb->remote_id, p_ccb->p_lcb->remote_bd_addr); @@ -1397,7 +1398,7 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) { /* Make sure we are not in sniff mode */ if (!BTM_SetLinkPolicyActiveMode(p_ccb->p_lcb->remote_bd_addr)) { - LOG_WARN("Unable to set link policy active"); + log::warn("Unable to set link policy active"); } } power_telemetry::GetInstance().LogChannelDisconnected( @@ -1437,7 +1438,7 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { break; case L2CEVT_L2CA_CONFIG_REQ: /* Upper layer config req */ - LOG_ERROR( + log::error( "Dropping L2CAP re-config request because there is no usage and " "should not be invoked"); break; @@ -1455,7 +1456,7 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { case L2CEVT_L2CA_SEND_FLOW_CONTROL_CREDIT: if (p_data) { - LOG_DEBUG("Sending credit"); + log::debug("Sending credit"); credit = *(uint16_t*)p_data; l2cble_send_flow_control_credit(p_ccb, credit); } @@ -1464,7 +1465,7 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { case L2CEVT_L2CAP_RECV_FLOW_CONTROL_CREDIT: if (p_data) { credit = *(uint16_t*)p_data; - LOG_DEBUG("Credits received %d", credit); + log::debug("Credits received {}", credit); if ((p_ccb->peer_conn_cfg.credits + credit) > L2CAP_LE_CREDIT_MAX) { /* we have received credits more than max coc credits, * so disconnecting the Le Coc Channel @@ -1477,11 +1478,11 @@ static void l2c_csm_open(tL2C_CCB* p_ccb, tL2CEVT event, void* p_data) { } break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -1500,8 +1501,8 @@ static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, p_ccb->p_rcb->api.pL2CA_DisconnectCfm_Cb; uint16_t local_cid = p_ccb->local_cid; - LOG_DEBUG("LCID: 0x%04x st: W4_L2CAP_DISC_RSP evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::debug("LCID: 0x{:04x} st: W4_L2CAP_DISC_RSP evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_L2CAP_DISCONNECT_RSP: /* Peer disconnect response */ @@ -1534,11 +1535,11 @@ static void l2c_csm_w4_l2cap_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, osi_free(p_data); break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -1557,13 +1558,13 @@ static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; uint16_t local_cid = p_ccb->local_cid; - LOG_DEBUG("LCID: 0x%04x st: W4_L2CA_DISC_RSP evt: %s", p_ccb->local_cid, - l2c_csm_get_event_name(event)); + log::debug("LCID: 0x{:04x} st: W4_L2CA_DISC_RSP evt: {}", p_ccb->local_cid, + l2c_csm_get_event_name(event)); switch (event) { case L2CEVT_LP_DISCONNECT_IND: /* Link was disconnected */ - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; @@ -1571,8 +1572,8 @@ static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, case L2CEVT_TIMEOUT: l2cu_send_peer_disc_rsp(p_ccb->p_lcb, p_ccb->remote_id, p_ccb->local_cid, p_ccb->remote_cid); - LOG_DEBUG("Calling Disconnect_Ind_Cb(), CID: 0x%04x No Conf Needed", - p_ccb->local_cid); + log::debug("Calling Disconnect_Ind_Cb(), CID: 0x{:04x} No Conf Needed", + p_ccb->local_cid); l2cu_release_ccb(p_ccb); (*disconnect_ind)(local_cid, false); break; @@ -1589,11 +1590,11 @@ static void l2c_csm_w4_l2ca_disconnect_rsp(tL2C_CCB* p_ccb, tL2CEVT event, osi_free(p_data); break; default: - LOG_ERROR("Handling unexpected event:%s", l2c_csm_get_event_name(event)); + log::error("Handling unexpected event:{}", l2c_csm_get_event_name(event)); } - LOG_VERBOSE("Exit chnl_state=%s [%d], event=%s [%d]", - channel_state_text(p_ccb->chnl_state).c_str(), p_ccb->chnl_state, - l2c_csm_get_event_name(event), event); + log::verbose("Exit chnl_state={} [{}], event={} [{}]", + channel_state_text(p_ccb->chnl_state), p_ccb->chnl_state, + l2c_csm_get_event_name(event), event); } /******************************************************************************* @@ -1744,10 +1745,10 @@ void l2c_enqueue_peer_data(tL2C_CCB* p_ccb, BT_HDR* p_buf) { } if (p_ccb->xmit_hold_q == NULL) { - LOG_ERROR( - "empty queue: p_ccb = %p p_ccb->in_use = %d p_ccb->chnl_state = %d " - "p_ccb->local_cid = %u p_ccb->remote_cid = %u", - p_ccb, p_ccb->in_use, p_ccb->chnl_state, p_ccb->local_cid, + log::error( + "empty queue: p_ccb = {} p_ccb->in_use = {} p_ccb->chnl_state = {} " + "p_ccb->local_cid = {} p_ccb->remote_cid = {}", + fmt::ptr(p_ccb), p_ccb->in_use, p_ccb->chnl_state, p_ccb->local_cid, p_ccb->remote_cid); } else { fixed_queue_enqueue(p_ccb->xmit_hold_q, p_buf); diff --git a/system/stack/l2cap/l2c_fcr.cc b/system/stack/l2cap/l2c_fcr.cc index ccbd2967fde22b7020b8a096dbc783ffc60b5934..be6678561ab97d0f4b36b218d7debcdf5de05ec0 100644 --- a/system/stack/l2cap/l2c_fcr.cc +++ b/system/stack/l2cap/l2c_fcr.cc @@ -24,10 +24,12 @@ ******************************************************************************/ #include +#include #include #include #include +#include "include/check.h" #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -41,6 +43,8 @@ */ #define L2C_FCR_RETX_ALL_PKTS 0xFF +using namespace bluetooth; + /* this is the minimal offset required by OBX to process incoming packets */ static const uint16_t OBX_BUF_MIN_OFFSET = 4; @@ -348,18 +352,18 @@ static void prepare_I_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, p_buf->len += L2CAP_FCS_LEN; if (is_retransmission) { - LOG_VERBOSE( - "L2CAP eRTM ReTx I-frame CID: 0x%04x Len: %u SAR: %s TxSeq: %u " - "ReqSeq: %u F: %u", + log::verbose( + "L2CAP eRTM ReTx I-frame CID: 0x{:04x} Len: {} SAR: {} TxSeq: {} " + "ReqSeq: {} F: {}", p_ccb->local_cid, p_buf->len, SAR_types[(ctrl_word & L2CAP_FCR_SAR_BITS) >> L2CAP_FCR_SAR_BITS_SHIFT], (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); } else { - LOG_VERBOSE( - "L2CAP eRTM Tx I-frame CID: 0x%04x Len: %u SAR: %-12s TxSeq: %u " - "ReqSeq: %u F: %u", + log::verbose( + "L2CAP eRTM Tx I-frame CID: 0x{:04x} Len: {} SAR: {:<12s} TxSeq: {} " + " ReqSeq: {} F: {}", p_ccb->local_cid, p_buf->len, SAR_types[(ctrl_word & L2CAP_FCR_SAR_BITS) >> L2CAP_FCR_SAR_BITS_SHIFT], (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, @@ -426,25 +430,25 @@ void l2c_fcr_send_S_frame(tL2C_CCB* p_ccb, uint16_t function_code, if ((((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 1) || (((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 3)) { - LOG_WARN( - "L2CAP eRTM Tx S-frame CID: 0x%04x ctrlword: 0x%04x Type: %s " - "ReqSeq: %u P: %u F: %u", + log::warn( + "L2CAP eRTM Tx S-frame CID: 0x{:04x} ctrlword: 0x{:04x} Type: {} " + "ReqSeq: {} P: {} F: {}", p_ccb->local_cid, ctrl_word, SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, (ctrl_word & L2CAP_FCR_P_BIT) >> L2CAP_FCR_P_BIT_SHIFT, (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); - LOG_WARN(" Buf Len: %u", p_buf->len); + log::warn("Buf Len: {}", p_buf->len); } else { - LOG_VERBOSE( - "L2CAP eRTM Tx S-frame CID: 0x%04x ctrlword: 0x%04x Type: %s " - "ReqSeq: %u P: %u F: %u", + log::verbose( + "L2CAP eRTM Tx S-frame CID: 0x{:04x} ctrlword: 0x{:04x} Type: {} " + "ReqSeq: {} P: {} F: {}", p_ccb->local_cid, ctrl_word, SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, (ctrl_word & L2CAP_FCR_P_BIT) >> L2CAP_FCR_P_BIT_SHIFT, (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); - LOG_VERBOSE(" Buf Len: %u", p_buf->len); + log::verbose("Buf Len: {}", p_buf->len); } l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); @@ -477,8 +481,8 @@ void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { min_pdu_len = (uint16_t)(L2CAP_FCS_LEN + L2CAP_FCR_OVERHEAD); if (p_buf->len < min_pdu_len) { - LOG_WARN("Rx L2CAP PDU: CID: 0x%04x Len too short: %u", p_ccb->local_cid, - p_buf->len); + log::warn("Rx L2CAP PDU: CID: 0x{:04x} Len too short: {}", + p_ccb->local_cid, p_buf->len); osi_free(p_buf); return; } @@ -491,18 +495,18 @@ void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { if ((((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 1) || (((ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT) == 3)) { /* REJ or SREJ */ - LOG_WARN( - "L2CAP eRTM Rx S-frame: cid: 0x%04x Len: %u Type: %s ReqSeq: %u " - "P: %u F: %u", + log::warn( + "L2CAP eRTM Rx S-frame: cid: 0x{:04x} Len: {} Type: {} ReqSeq: {} " + " P: {} F: {}", p_ccb->local_cid, p_buf->len, SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, (ctrl_word & L2CAP_FCR_P_BIT) >> L2CAP_FCR_P_BIT_SHIFT, (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); } else { - LOG_VERBOSE( - "L2CAP eRTM Rx S-frame: cid: 0x%04x Len: %u Type: %s ReqSeq: %u " - "P: %u F: %u", + log::verbose( + "L2CAP eRTM Rx S-frame: cid: 0x{:04x} Len: {} Type: {} ReqSeq: {} " + " P: {} F: {}", p_ccb->local_cid, p_buf->len, SUP_types[(ctrl_word & L2CAP_FCR_SUP_BITS) >> L2CAP_FCR_SUP_SHIFT], (ctrl_word & L2CAP_FCR_REQ_SEQ_BITS) >> L2CAP_FCR_REQ_SEQ_BITS_SHIFT, @@ -510,9 +514,9 @@ void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); } } else { - LOG_VERBOSE( - "L2CAP eRTM Rx I-frame: cid: 0x%04x Len: %u SAR: %-12s TxSeq: %u " - "ReqSeq: %u F: %u", + log::verbose( + "L2CAP eRTM Rx I-frame: cid: 0x{:04x} Len: {} SAR: {:<12s} TxSeq: " + "{} ReqSeq: {} F: {}", p_ccb->local_cid, p_buf->len, SAR_types[(ctrl_word & L2CAP_FCR_SAR_BITS) >> L2CAP_FCR_SAR_BITS_SHIFT], (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, @@ -520,9 +524,9 @@ void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { (ctrl_word & L2CAP_FCR_F_BIT) >> L2CAP_FCR_F_BIT_SHIFT); } - LOG_VERBOSE( - " eRTM Rx Nxt_tx_seq %u, Lst_rx_ack %u, Nxt_seq_exp %u, Lst_ack_snt " - "%u, wt_q.cnt %zu, tries %u", + log::verbose( + "eRTM Rx Nxt_tx_seq {}, Lst_rx_ack {}, Nxt_seq_exp {}, Lst_ack_snt {}, " + "wt_q.cnt {}, tries {}", p_ccb->fcrb.next_tx_seq, p_ccb->fcrb.last_rx_ack, p_ccb->fcrb.next_seq_expected, p_ccb->fcrb.last_ack_sent, fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q), p_ccb->fcrb.num_tries); @@ -535,7 +539,7 @@ void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { p_buf->len -= L2CAP_FCS_LEN; if (l2c_fcr_rx_get_fcs(p_buf) != fcs) { - LOG_WARN("Rx L2CAP PDU: CID: 0x%04x BAD FCS", p_ccb->local_cid); + log::warn("Rx L2CAP PDU: CID: 0x{:04x} BAD FCS", p_ccb->local_cid); osi_free(p_buf); return; } @@ -618,9 +622,9 @@ void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { STREAM_TO_UINT16(ctrl_word, p); - LOG_VERBOSE( - "l2c_fcr_proc_pdu() CID: 0x%04x Process Buffer from SREJ_Hold_Q " - "TxSeq: %u Expected_Seq: %u", + log::verbose( + "l2c_fcr_proc_pdu() CID: 0x{:04x} Process Buffer from SREJ_Hold_Q " + " TxSeq: {} Expected_Seq: {}", p_ccb->local_cid, (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT, p_ccb->fcrb.next_seq_expected); @@ -646,9 +650,9 @@ void l2c_fcr_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { (p_ccb->fcrb.next_seq_expected != p_ccb->fcrb.last_ack_sent)) l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_RR, 0); else { - LOG_VERBOSE( - "l2c_fcr_proc_pdu() not sending RR CID: 0x%04x local_busy:%d " - "rej_sent:%d srej_sent:%d Expected_Seq:%u Last_Ack:%u", + log::verbose( + "l2c_fcr_proc_pdu() not sending RR CID: 0x{:04x} local_busy:{} " + "rej_sent:{} srej_sent:{} Expected_Seq:{} Last_Ack:{}", p_ccb->local_cid, 0, p_ccb->fcrb.rej_sent, p_ccb->fcrb.srej_sent, p_ccb->fcrb.next_seq_expected, p_ccb->fcrb.last_ack_sent); } @@ -681,8 +685,8 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { /* Buffer length should not exceed local mps */ if (p_buf->len > p_ccb->local_conn_cfg.mps) { - LOG_ERROR("buffer length=%d exceeds local mps=%d. Drop and disconnect.", - p_buf->len, p_ccb->local_conn_cfg.mps); + log::error("buffer length={} exceeds local mps={}. Drop and disconnect.", + p_buf->len, p_ccb->local_conn_cfg.mps); /* Discard the buffer and disconnect*/ osi_free(p_buf); @@ -692,8 +696,7 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { if (p_ccb->is_first_seg) { if (p_buf->len < sizeof(sdu_length)) { - LOG_ERROR("%s: buffer length=%d too small. Need at least 2.", __func__, - p_buf->len); + log::error("buffer length={} too small. Need at least 2.", p_buf->len); /* Discard the buffer */ osi_free(p_buf); return; @@ -702,8 +705,8 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { /* Check the SDU Length with local MTU size */ if (sdu_length > p_ccb->local_conn_cfg.mtu) { - LOG_ERROR("sdu length=%d exceeds local mtu=%d. Drop and disconnect.", - sdu_length, p_ccb->local_conn_cfg.mtu); + log::error("sdu length={} exceeds local mtu={}. Drop and disconnect.", + sdu_length, p_ccb->local_conn_cfg.mtu); /* Discard the buffer and disconnect*/ osi_free(p_buf); l2cu_disconnect_chnl(p_ccb); @@ -714,7 +717,7 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { p_buf->offset += sizeof(sdu_length); if (sdu_length < p_buf->len) { - LOG_ERROR("%s: Invalid sdu_length: %d", __func__, sdu_length); + log::error("Invalid sdu_length: {}", sdu_length); /* Discard the buffer */ osi_free(p_buf); return; @@ -729,7 +732,7 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { p_ccb->ble_sdu = p_data; p_data->len = 0; p_ccb->ble_sdu_length = sdu_length; - LOG_VERBOSE("%s SDU Length = %d", __func__, sdu_length); + log::verbose("SDU Length = {}", sdu_length); p_data->offset = 0; } else { @@ -739,8 +742,8 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { return; } if (p_buf->len > (p_ccb->ble_sdu_length - p_data->len)) { - LOG_ERROR("%s: buffer length=%d too big. max=%d. Dropped", __func__, - p_data->len, (p_ccb->ble_sdu_length - p_data->len)); + log::error("buffer length={} too big. max={}. Dropped", p_data->len, + (p_ccb->ble_sdu_length - p_data->len)); osi_free(p_buf); /* Throw away all pending fragments and disconnects */ @@ -781,9 +784,9 @@ void l2c_lcc_proc_pdu(tL2C_CCB* p_ccb, BT_HDR* p_buf) { ******************************************************************************/ void l2c_fcr_proc_tout(tL2C_CCB* p_ccb) { CHECK(p_ccb != NULL); - LOG_VERBOSE( - "l2c_fcr_proc_tout: CID: 0x%04x num_tries: %u (max: %u) wait_ack: %u " - "ack_q_count: %zu", + log::verbose( + "l2c_fcr_proc_tout: CID: 0x{:04x} num_tries: {} (max: {}) wait_ack: " + "{} ack_q_count: {}", p_ccb->local_cid, p_ccb->fcrb.num_tries, p_ccb->peer_cfg.fcr.max_transmit, p_ccb->fcrb.wait_ack, fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q)); @@ -808,8 +811,9 @@ void l2c_fcr_proc_tout(tL2C_CCB* p_ccb) { ******************************************************************************/ void l2c_fcr_proc_ack_tout(tL2C_CCB* p_ccb) { CHECK(p_ccb != NULL); - LOG_VERBOSE( - "l2c_fcr_proc_ack_tout: CID: 0x%04x State: %u Wack:%u Rq:%d Acked:%d", + log::verbose( + "l2c_fcr_proc_ack_tout: CID: 0x{:04x} State: {} Wack:{} Rq:{} " + "Acked:{}", p_ccb->local_cid, p_ccb->chnl_state, p_ccb->fcrb.wait_ack, p_ccb->fcrb.next_seq_expected, p_ccb->fcrb.last_ack_sent); @@ -857,9 +861,9 @@ static bool process_reqseq(tL2C_CCB* p_ccb, uint16_t ctrl_word) { /* Verify the request sequence is in range before proceeding */ if (num_bufs_acked > fixed_queue_length(p_fcrb->waiting_for_ack_q)) { /* The channel is closed if ReqSeq is not in range */ - LOG_WARN( - "L2CAP eRTM Frame BAD Req_Seq - ctrl_word: 0x%04x req_seq 0x%02x " - "last_rx_ack: 0x%02x QCount: %zu", + log::warn( + "L2CAP eRTM Frame BAD Req_Seq - ctrl_word: 0x{:04x} req_seq 0x{:02x} " + "last_rx_ack: 0x{:02x} QCount: {}", ctrl_word, req_seq, p_fcrb->last_rx_ack, fixed_queue_length(p_fcrb->waiting_for_ack_q)); @@ -930,11 +934,11 @@ static void process_s_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, bool all_ok = true; if (p_buf->len != 0) { - LOG_WARN("Incorrect S-frame Length (%d)", p_buf->len); + log::warn("Incorrect S-frame Length ({})", p_buf->len); } - LOG_VERBOSE("process_s_frame ctrl_word 0x%04x fcrb_remote_busy:%d", ctrl_word, - p_fcrb->remote_busy); + log::verbose("process_s_frame ctrl_word 0x{:04x} fcrb_remote_busy:{}", + ctrl_word, p_fcrb->remote_busy); if (ctrl_word & L2CAP_FCR_P_BIT) { p_fcrb->rej_sent = false; /* After checkpoint, we can send anoher REJ */ @@ -980,7 +984,7 @@ static void process_s_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, p_fcrb->send_f_rsp = false; } } else { - LOG_VERBOSE("process_s_frame hit_max_retries"); + log::verbose("process_s_frame hit_max_retries"); } osi_free(p_buf); @@ -1022,15 +1026,15 @@ static void process_i_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word, /* Is the frame a duplicate ? If so, just drop it */ if (num_lost >= p_ccb->our_cfg.fcr.tx_win_sz) { /* Duplicate - simply drop it */ - LOG_WARN( - "process_i_frame() Dropping Duplicate Frame tx_seq:%u ExpectedTxSeq " - "%u", + log::warn( + "process_i_frame() Dropping Duplicate Frame tx_seq:{} ExpectedTxSeq " + "{}", tx_seq, p_fcrb->next_seq_expected); osi_free(p_buf); } else { - LOG_WARN( - "process_i_frame() CID: 0x%04x Lost: %u tx_seq:%u ExpTxSeq %u " - "Rej: %u SRej: %u", + log::warn( + "process_i_frame() CID: 0x{:04x} Lost: {} tx_seq:{} ExpTxSeq {} " + "Rej: {} SRej: {}", p_ccb->local_cid, num_lost, tx_seq, p_fcrb->next_seq_expected, p_fcrb->rej_sent, p_fcrb->srej_sent); @@ -1046,17 +1050,17 @@ static void process_i_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word, if ((tx_seq == next_srej) && (fixed_queue_length(p_fcrb->srej_rcv_hold_q) < p_ccb->our_cfg.fcr.tx_win_sz)) { - LOG_VERBOSE( - "process_i_frame() Lost: %u tx_seq:%u ExpTxSeq %u Rej: %u " + log::verbose( + "process_i_frame() Lost: {} tx_seq:{} ExpTxSeq {} Rej: {} " "SRej1", num_lost, tx_seq, p_fcrb->next_seq_expected, p_fcrb->rej_sent); p_buf->layer_specific = tx_seq; fixed_queue_enqueue(p_fcrb->srej_rcv_hold_q, p_buf); } else { - LOG_WARN( - "process_i_frame() CID: 0x%04x frame dropped in Srej Sent " - "next_srej:%u hold_q.count:%zu win_sz:%u", + log::warn( + "process_i_frame() CID: 0x{:04x} frame dropped in Srej Sent " + "next_srej:{} hold_q.count:{} win_sz:{}", p_ccb->local_cid, next_srej, fixed_queue_length(p_fcrb->srej_rcv_hold_q), p_ccb->our_cfg.fcr.tx_win_sz); @@ -1065,17 +1069,17 @@ static void process_i_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word, osi_free(p_buf); } } else if (p_fcrb->rej_sent) { - LOG_WARN( - "process_i_frame() CID: 0x%04x Lost: %u tx_seq:%u ExpTxSeq %u " - "Rej: 1 SRej: %u", + log::warn( + "process_i_frame() CID: 0x{:04x} Lost: {} tx_seq:{} ExpTxSeq {} " + " Rej: 1 SRej: {}", p_ccb->local_cid, num_lost, tx_seq, p_fcrb->next_seq_expected, p_fcrb->srej_sent); /* If REJ sent, just drop the frame */ osi_free(p_buf); } else { - LOG_VERBOSE( - "process_i_frame() CID: 0x%04x tx_seq:%u ExpTxSeq %u Rej: %u", + log::verbose( + "process_i_frame() CID: 0x{:04x} tx_seq:{} ExpTxSeq {} Rej: {}", p_ccb->local_cid, tx_seq, p_fcrb->next_seq_expected, p_fcrb->rej_sent); @@ -1086,9 +1090,9 @@ static void process_i_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word, l2c_fcr_send_S_frame(p_ccb, L2CAP_FCR_SUP_REJ, 0); } else { if (!fixed_queue_is_empty(p_fcrb->srej_rcv_hold_q)) { - LOG_ERROR( - "process_i_frame() CID: 0x%04x sending SREJ tx_seq:%d " - "hold_q.count:%zu", + log::error( + "process_i_frame() CID: 0x{:04x} sending SREJ tx_seq:{} " + "hold_q.count:{}", p_ccb->local_cid, tx_seq, fixed_queue_length(p_fcrb->srej_rcv_hold_q)); } @@ -1114,8 +1118,8 @@ static void process_i_frame(tL2C_CCB* p_ccb, BT_HDR* p_buf, uint16_t ctrl_word, /* If any SAR problem in eRTM mode, spec says disconnect. */ if (!do_sar_reassembly(p_ccb, p_buf, ctrl_word)) { - LOG_WARN("process_i_frame() CID: 0x%04x reassembly failed", - p_ccb->local_cid); + log::warn("process_i_frame() CID: 0x{:04x} reassembly failed", + p_ccb->local_cid); l2cu_disconnect_chnl(p_ccb); return; } @@ -1167,9 +1171,9 @@ static bool do_sar_reassembly(tL2C_CCB* p_ccb, BT_HDR* p_buf, /* Check if the SAR state is correct */ if ((sar_type == L2CAP_FCR_UNSEG_SDU) || (sar_type == L2CAP_FCR_START_SDU)) { if (p_fcrb->p_rx_sdu != NULL) { - LOG_WARN( - "SAR - got unexpected unsegmented or start SDU Expected len: %u " - "Got so far: %u", + log::warn( + "SAR - got unexpected unsegmented or start SDU Expected len: {} " + "Got so far: {}", p_fcrb->rx_sdu_len, p_fcrb->p_rx_sdu->len); packet_ok = false; @@ -1177,12 +1181,12 @@ static bool do_sar_reassembly(tL2C_CCB* p_ccb, BT_HDR* p_buf, /* Check the length of the packet */ if ((sar_type == L2CAP_FCR_START_SDU) && (p_buf->len < L2CAP_SDU_LEN_OVERHEAD)) { - LOG_WARN("SAR start packet too short: %u", p_buf->len); + log::warn("SAR start packet too short: {}", p_buf->len); packet_ok = false; } } else { if (p_fcrb->p_rx_sdu == NULL) { - LOG_WARN("SAR - got unexpected cont or end SDU"); + log::warn("SAR - got unexpected cont or end SDU"); packet_ok = false; } } @@ -1198,8 +1202,8 @@ static bool do_sar_reassembly(tL2C_CCB* p_ccb, BT_HDR* p_buf, p_buf->len -= 2; if (p_fcrb->rx_sdu_len > p_ccb->max_rx_mtu) { - LOG_WARN("SAR - SDU len: %u larger than MTU: %u", p_fcrb->rx_sdu_len, - p_ccb->max_rx_mtu); + log::warn("SAR - SDU len: {} larger than MTU: {}", p_fcrb->rx_sdu_len, + p_ccb->max_rx_mtu); packet_ok = false; } else { p_fcrb->p_rx_sdu = (BT_HDR*)osi_malloc( @@ -1211,14 +1215,14 @@ static bool do_sar_reassembly(tL2C_CCB* p_ccb, BT_HDR* p_buf, if (packet_ok) { if ((p_fcrb->p_rx_sdu->len + p_buf->len) > p_fcrb->rx_sdu_len) { - LOG_ERROR("SAR - SDU len exceeded Type: %u Lengths: %u %u %u", - sar_type, p_fcrb->p_rx_sdu->len, p_buf->len, - p_fcrb->rx_sdu_len); + log::error("SAR - SDU len exceeded Type: {} Lengths: {} {} {}", + sar_type, p_fcrb->p_rx_sdu->len, p_buf->len, + p_fcrb->rx_sdu_len); packet_ok = false; } else if ((sar_type == L2CAP_FCR_END_SDU) && ((p_fcrb->p_rx_sdu->len + p_buf->len) != p_fcrb->rx_sdu_len)) { - LOG_WARN("SAR - SDU end rcvd but SDU incomplete: %u %u %u", - p_fcrb->p_rx_sdu->len, p_buf->len, p_fcrb->rx_sdu_len); + log::warn("SAR - SDU end rcvd but SDU incomplete: {} {} {}", + p_fcrb->p_rx_sdu->len, p_buf->len, p_fcrb->rx_sdu_len); packet_ok = false; } else { memcpy(((uint8_t*)(p_fcrb->p_rx_sdu + 1)) + p_fcrb->p_rx_sdu->offset + @@ -1276,9 +1280,9 @@ static bool retransmit_i_frames(tL2C_CCB* p_ccb, uint8_t tx_seq) { if ((!fixed_queue_is_empty(p_ccb->fcrb.waiting_for_ack_q)) && (p_ccb->peer_cfg.fcr.max_transmit != 0) && (p_ccb->fcrb.num_tries >= p_ccb->peer_cfg.fcr.max_transmit)) { - LOG_VERBOSE( - "Max Tries Exceeded: (last_acq: %d CID: 0x%04x num_tries: %u (max: " - "%u) ack_q_count: %zu", + log::verbose( + "Max Tries Exceeded: (last_acq: {} CID: 0x{:04x} num_tries: {} " + "(max: {}) ack_q_count: {}", p_ccb->fcrb.last_rx_ack, p_ccb->local_cid, p_ccb->fcrb.num_tries, p_ccb->peer_cfg.fcr.max_transmit, fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q)); @@ -1309,16 +1313,16 @@ static bool retransmit_i_frames(tL2C_CCB* p_ccb, uint8_t tx_seq) { buf_seq = (ctrl_word & L2CAP_FCR_TX_SEQ_BITS) >> L2CAP_FCR_TX_SEQ_BITS_SHIFT; - LOG_VERBOSE("retransmit_i_frames() cur seq: %u looking for: %u", - buf_seq, tx_seq); + log::verbose("retransmit_i_frames() cur seq: {} looking for: {}", + buf_seq, tx_seq); if (tx_seq == buf_seq) break; } } if (!p_buf) { - LOG_ERROR("retransmit_i_frames() UNKNOWN seq: %u q_count: %zu", tx_seq, - fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q)); + log::error("retransmit_i_frames() UNKNOWN seq: {} q_count: {}", tx_seq, + fixed_queue_length(p_ccb->fcrb.waiting_for_ack_q)); return (true); } } else { @@ -1438,8 +1442,8 @@ BT_HDR* l2c_fcr_get_next_xmit_sdu_seg(tL2C_CCB* p_ccb, } else /* Should never happen if the application has configured buffers correctly */ { - LOG_ERROR("L2CAP - cannot get buffer for segmentation, max_pdu: %u", - max_pdu); + log::error("L2CAP - cannot get buffer for segmentation, max_pdu: {}", + max_pdu); return (NULL); } } else /* Use the original buffer if no segmentation, or the last segment */ @@ -1494,8 +1498,9 @@ BT_HDR* l2c_fcr_get_next_xmit_sdu_seg(tL2C_CCB* p_ccb, l2c_fcr_clone_buf(p_xmit, HCI_DATA_PREAMBLE_SIZE, p_xmit->len); if (!p_wack) { - LOG_ERROR("L2CAP - no buffer for xmit cloning, CID: 0x%04x Length: %u", - p_ccb->local_cid, p_xmit->len); + log::error( + "L2CAP - no buffer for xmit cloning, CID: 0x{:04x} Length: {}", + p_ccb->local_cid, p_xmit->len); /* We will not save the FCS in case we reconfigure and change options */ p_xmit->len -= L2CAP_FCS_LEN; @@ -1599,7 +1604,7 @@ uint8_t l2c_fcr_chk_chan_modes(tL2C_CCB* p_ccb) { /* Remove nonbasic options that the peer does not support */ if (!(p_ccb->p_lcb->peer_ext_fea & L2CAP_EXTFEA_ENH_RETRANS) && p_ccb->p_rcb->ertm_info.preferred_mode == L2CAP_FCR_ERTM_MODE) { - LOG_WARN("L2CAP - Peer does not support our desired channel types"); + log::warn("L2CAP - Peer does not support our desired channel types"); p_ccb->p_rcb->ertm_info.preferred_mode = 0; return false; } @@ -1635,8 +1640,8 @@ void l2c_fcr_adj_monitor_retran_timeout(tL2C_CCB* p_ccb) { p_ccb->our_cfg.fcr.rtrans_tout = 0; } - LOG_VERBOSE( - "l2c_fcr_adj_monitor_retran_timeout: mon_tout:%d, rtrans_tout:%d", + log::verbose( + "l2c_fcr_adj_monitor_retran_timeout: mon_tout:{}, rtrans_tout:{}", p_ccb->our_cfg.fcr.mon_tout, p_ccb->our_cfg.fcr.rtrans_tout); } } @@ -1666,8 +1671,8 @@ void l2c_fcr_adj_our_rsp_options(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { * adjust it. For now, respond with our own tx_wnd_sz. */ /* Note: peer is not guaranteed to obey our adjustment */ if (p_ccb->peer_cfg.fcr.tx_win_sz > p_ccb->our_cfg.fcr.tx_win_sz) { - LOG_VERBOSE("%s: adjusting requested tx_win_sz from %i to %i", __func__, - p_ccb->peer_cfg.fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz); + log::verbose("adjusting requested tx_win_sz from {} to {}", + p_ccb->peer_cfg.fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz); p_ccb->peer_cfg.fcr.tx_win_sz = p_ccb->our_cfg.fcr.tx_win_sz; } @@ -1711,7 +1716,7 @@ bool l2c_fcr_renegotiate_chan(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { if (p_ccb->our_cfg.fcr.mode != peer_mode) { if ((--p_ccb->fcr_cfg_tries) == 0) { p_cfg->result = L2CAP_CFG_FAILED_NO_REASON; - LOG_WARN("l2c_fcr_renegotiate_chan (Max retries exceeded)"); + log::warn("l2c_fcr_renegotiate_chan (Max retries exceeded)"); } can_renegotiate = false; @@ -1722,7 +1727,7 @@ bool l2c_fcr_renegotiate_chan(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { case L2CAP_FCR_ERTM_MODE: /* We can try basic for any other peer mode because it's always * supported */ - LOG_VERBOSE("%s(Trying Basic)", __func__); + log::verbose("(Trying Basic)"); can_renegotiate = true; p_ccb->our_cfg.fcr.mode = L2CAP_FCR_BASIC_MODE; break; @@ -1741,7 +1746,7 @@ bool l2c_fcr_renegotiate_chan(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { /* Basic Mode uses ACL Data Pool, make sure the MTU fits */ if ((p_cfg->mtu_present) && (p_cfg->mtu > L2CAP_MTU_SIZE)) { - LOG_WARN("L2CAP - adjust MTU: %u too large", p_cfg->mtu); + log::warn("L2CAP - adjust MTU: {} too large", p_cfg->mtu); p_cfg->mtu = L2CAP_MTU_SIZE; } } @@ -1757,8 +1762,8 @@ bool l2c_fcr_renegotiate_chan(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { /* Disconnect if the channels do not match */ if (p_ccb->our_cfg.fcr.mode != peer_mode) { - LOG_WARN("L2C CFG: Channels incompatible (local %d, peer %d)", - p_ccb->our_cfg.fcr.mode, peer_mode); + log::warn("L2C CFG: Channels incompatible (local {}, peer {})", + p_ccb->our_cfg.fcr.mode, peer_mode); l2cu_disconnect_chnl(p_ccb); } @@ -1786,9 +1791,9 @@ uint8_t l2c_fcr_process_peer_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { p_ccb->p_lcb->w4_info_rsp = false; /* Handles T61x SonyEricsson Bug in Info Request */ - LOG_VERBOSE( - "l2c_fcr_process_peer_cfg_req() CFG fcr_present:%d fcr.mode:%d CCB FCR " - "mode:%d preferred: %u", + log::verbose( + "l2c_fcr_process_peer_cfg_req() CFG fcr_present:{} fcr.mode:{} CCB FCR " + "mode:{} preferred: {}", p_cfg->fcr_present, p_cfg->fcr.mode, p_ccb->our_cfg.fcr.mode, p_ccb->p_rcb->ertm_info.preferred_mode); @@ -1845,8 +1850,8 @@ uint8_t l2c_fcr_process_peer_cfg_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { /* Ensure the MPS is not bigger than our retransmission buffer */ if (p_cfg->fcr.mps > max_retrans_size) { - LOG_VERBOSE("CFG: Overriding MPS to %d (orig %d)", max_retrans_size, - p_cfg->fcr.mps); + log::verbose("CFG: Overriding MPS to {} (orig {})", max_retrans_size, + p_cfg->fcr.mps); p_cfg->fcr.mps = max_retrans_size; p_ccb->out_cfg_fcr_present = true; diff --git a/system/stack/l2cap/l2c_int.h b/system/stack/l2cap/l2c_int.h index 778261acb7eb3342ab774057eae0cc7c86699753..6221ff16461eff44b9dec00483fb86dc582eab5d 100644 --- a/system/stack/l2cap/l2c_int.h +++ b/system/stack/l2cap/l2c_int.h @@ -25,6 +25,7 @@ #define L2C_INT_H #include +#include #include #include @@ -526,6 +527,9 @@ typedef struct t_l2c_linkcb { uint8_t conn_update_mask; + bool conn_update_blocked_by_service_discovery; + bool conn_update_blocked_by_profile_connection; + uint16_t min_interval; /* parameters as requested by peripheral */ uint16_t max_interval; uint16_t latency; @@ -668,6 +672,14 @@ typedef struct { typedef void(tL2C_FCR_MGMT_EVT_HDLR)(uint8_t, tL2C_CCB*); +/* Necessary info for postponed TX completion callback + */ +typedef struct { + uint16_t local_cid; + uint16_t num_sdu; + tL2CA_TX_COMPLETE_CB* cb; +} tL2C_TX_COMPLETE_CB_INFO; + /* The offset in a buffer that L2CAP will use when building commands. */ #define L2CAP_SEND_CMD_OFFSET 0 @@ -735,6 +747,8 @@ void l2cu_set_acl_hci_header(BT_HDR* p_buf, tL2C_CCB* p_ccb); void l2cu_check_channel_congestion(tL2C_CCB* p_ccb); void l2cu_disconnect_chnl(tL2C_CCB* p_ccb); +void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi); + void l2cu_send_peer_ble_par_req(tL2C_LCB* p_lcb, uint16_t min_int, uint16_t max_int, uint16_t latency, uint16_t timeout); @@ -871,4 +885,13 @@ void l2cble_process_subrate_change_evt(uint16_t handle, uint8_t status, uint16_t peripheral_latency, uint16_t cont_num, uint16_t timeout); +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/stack/l2cap/l2c_link.cc b/system/stack/l2cap/l2c_link.cc index 9cf7d74496831986e56584e23656520551eb1c8f..9279a66311a673a82d4c7a3bc8f07a26e13e7dc3 100644 --- a/system/stack/l2cap/l2c_link.cc +++ b/system/stack/l2cap/l2c_link.cc @@ -25,6 +25,8 @@ ******************************************************************************/ #define LOG_TAG "l2c_link" +#include + #include #include "device/include/device_iot_config.h" @@ -44,6 +46,8 @@ #include "types/bt_transport.h" #include "types/raw_address.h" +using namespace bluetooth; + extern tBTM_CB btm_cb; bool BTM_ReadPowerMode(const RawAddress& remote_bda, tBTM_PM_MODE* p_mode); @@ -56,8 +60,10 @@ void btm_acl_removed(uint16_t handle); void btm_ble_decrement_link_topology_mask(uint8_t link_role); void btm_sco_acl_removed(const RawAddress* bda); -static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf); -static BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb); +static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, + tL2C_TX_COMPLETE_CB_INFO* p_cbi); +static BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, + tL2C_TX_COMPLETE_CB_INFO* p_cbi); void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, const RawAddress& p_bda) { @@ -76,26 +82,26 @@ void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, if (p_lcb == nullptr) { p_lcb = l2cu_allocate_lcb(ci.bd_addr, false, BT_TRANSPORT_BR_EDR); if (p_lcb == nullptr) { - LOG_WARN("Failed to allocate an LCB"); + log::warn("Failed to allocate an LCB"); return; } - LOG_DEBUG("Allocated l2cap control block for new connection state:%s", - link_state_text(p_lcb->link_state).c_str()); + log::debug("Allocated l2cap control block for new connection state:{}", + link_state_text(p_lcb->link_state)); p_lcb->link_state = LST_CONNECTING; } if ((p_lcb->link_state == LST_CONNECTED) && (status == HCI_ERR_CONNECTION_EXISTS)) { - LOG_WARN("Connection already exists handle:0x%04x", handle); + log::warn("Connection already exists handle:0x{:04x}", handle); return; } else if (p_lcb->link_state != LST_CONNECTING) { - LOG_ERROR( - "Link received unexpected connection complete state:%s status:%s " - "handle:0x%04x", - link_state_text(p_lcb->link_state).c_str(), - hci_error_code_text(status).c_str(), p_lcb->Handle()); + log::error( + "Link received unexpected connection complete state:{} status:{} " + "handle:0x{:04x}", + link_state_text(p_lcb->link_state), hci_error_code_text(status), + p_lcb->Handle()); if (status != HCI_SUCCESS) { - LOG_ERROR("Disconnecting..."); + log::error("Disconnecting..."); l2c_link_hci_disc_comp(p_lcb->Handle(), status); } return; @@ -112,7 +118,7 @@ void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, l2cu_send_peer_info_req(p_lcb, L2CAP_EXTENDED_FEATURES_INFO_TYPE); if (p_lcb->IsBonding()) { - LOG_DEBUG("Link is dedicated bonding handle:0x%04x", p_lcb->Handle()); + log::debug("Link is dedicated bonding handle:0x{:04x}", p_lcb->Handle()); if (l2cu_start_post_bond_timer(handle)) return; } @@ -134,8 +140,8 @@ void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, /* If there's an lcb disconnecting set this one to holding */ else if ((ci.status == HCI_ERR_MAX_NUM_OF_CONNECTIONS) && l2cu_lcb_disconnecting()) { - LOG_WARN("Delaying connection as reached max number of links:%u", - HCI_ERR_MAX_NUM_OF_CONNECTIONS); + log::warn("Delaying connection as reached max number of links:{}", + HCI_ERR_MAX_NUM_OF_CONNECTIONS); p_lcb->link_state = LST_CONNECT_HOLDING; p_lcb->InvalidateHandle(); } else { @@ -152,8 +158,8 @@ void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, p_ccb = pn; } - LOG_INFO("Disconnecting link handle:0x%04x status:%s", p_lcb->Handle(), - hci_error_code_text(status).c_str()); + log::info("Disconnecting link handle:0x{:04x} status:{}", p_lcb->Handle(), + hci_error_code_text(status)); p_lcb->SetDisconnectReason(status); /* Release the LCB */ if (p_lcb->ccb_queue.p_first_ccb == NULL) @@ -189,9 +195,8 @@ void l2c_link_sec_comp(const RawAddress* p_bda, tL2C_CCB* p_ccb; tL2C_CCB* p_next_ccb; - LOG_DEBUG("btm_status=%s, BD_ADDR=%s, transport=%s", - btm_status_text(status).c_str(), ADDRESS_TO_LOGGABLE_CSTR(*p_bda), - bt_transport_text(transport).c_str()); + log::debug("btm_status={}, BD_ADDR={}, transport={}", btm_status_text(status), + ADDRESS_TO_LOGGABLE_CSTR(*p_bda), bt_transport_text(transport)); if (status == BTM_SUCCESS_NO_SECURITY) { status = BTM_SUCCESS; @@ -205,7 +210,7 @@ void l2c_link_sec_comp(const RawAddress* p_bda, /* If we don't have one, this is an error */ if (!p_lcb) { - LOG_WARN("L2CAP got sec_comp for unknown BD_ADDR"); + log::warn("L2CAP got sec_comp for unknown BD_ADDR"); return; } @@ -322,7 +327,7 @@ bool l2c_link_hci_disc_comp(uint16_t handle, tHCI_REASON reason) { disconnecting */ if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb) { - LOG_DEBUG("l2c_link_hci_disc_comp: Restarting pending ACL request"); + log::debug("l2c_link_hci_disc_comp: Restarting pending ACL request"); /* Release any held buffers */ while (!list_is_empty(p_lcb->link_xmit_data_q)) { BT_HDR* p_buf = @@ -393,9 +398,8 @@ void l2c_link_timeout(tL2C_LCB* p_lcb) { tL2C_CCB* p_ccb; tBTM_STATUS rc; - LOG_DEBUG("L2CAP - l2c_link_timeout() link state:%s is_bonding:%s", - link_state_text(p_lcb->link_state).c_str(), - logbool(p_lcb->IsBonding()).c_str()); + log::debug("L2CAP - l2c_link_timeout() link state:{} is_bonding:{}", + link_state_text(p_lcb->link_state), logbool(p_lcb->IsBonding())); /* If link was connecting or disconnecting, clear all channels and drop the * LCB */ @@ -426,7 +430,7 @@ void l2c_link_timeout(tL2C_LCB* p_lcb) { uint64_t timeout_ms; bool start_timeout = true; - LOG_WARN("TODO: Remove this callback into bcm_sec_disconnect"); + log::warn("TODO: Remove this callback into bcm_sec_disconnect"); rc = btm_sec_disconnect( p_lcb->Handle(), HCI_ERR_PEER_USER, "stack::l2cap::l2c_link::l2c_link_timeout All channels closed"); @@ -594,9 +598,9 @@ void l2c_link_adjust_allocation(void) { qq = qq_remainder = 1; } - LOG_DEBUG( - "l2c_link_adjust_allocation num_hipri: %u num_lowpri: %u low_quota: " - "%u round_robin_quota: %u qq: %u", + log::debug( + "l2c_link_adjust_allocation num_hipri: {} num_lowpri: {} low_quota: " + "{} round_robin_quota: {} qq: {}", num_hipri_links, num_lowpri_links, low_quota, l2cb.round_robin_quota, qq); /* Now, assign the quotas to each link */ @@ -621,12 +625,12 @@ void l2c_link_adjust_allocation(void) { } } - LOG_DEBUG( - "l2c_link_adjust_allocation LCB %d Priority: %d XmitQuota: %d", yy, + log::debug( + "l2c_link_adjust_allocation LCB {} Priority: {} XmitQuota: {}", yy, p_lcb->acl_priority, p_lcb->link_xmit_quota); - LOG_DEBUG(" SentNotAcked: %d RRUnacked: %d", - p_lcb->sent_not_acked, l2cb.round_robin_unacked); + log::debug("SentNotAcked: {} RRUnacked: {}", p_lcb->sent_not_acked, + l2cb.round_robin_unacked); /* There is a special case where we have readjusted the link quotas and */ /* this link may have sent anything but some other link sent packets so */ @@ -665,9 +669,9 @@ void l2c_link_adjust_chnl_allocation(void) { tL2CAP_CHNL_DATA_RATE data_rate = p_ccb->tx_data_rate + p_ccb->rx_data_rate; p_ccb->buff_quota = L2CAP_CBB_DEFAULT_DATA_RATE_BUFF_QUOTA * data_rate; - LOG_DEBUG( - "CID:0x%04x FCR Mode:%u Priority:%u TxDataRate:%u RxDataRate:%u " - "Quota:%u", + log::debug( + "CID:0x{:04x} FCR Mode:{} Priority:{} TxDataRate:{} RxDataRate:{} " + "Quota:{}", p_ccb->local_cid, p_ccb->peer_cfg.fcr.mode, p_ccb->ccb_priority, p_ccb->tx_data_rate, p_ccb->rx_data_rate, p_ccb->buff_quota); @@ -778,7 +782,7 @@ static bool l2c_link_check_power_mode(tL2C_LCB* p_lcb) { tBTM_PM_MODE mode; if (BTM_ReadPowerMode(p_lcb->remote_bd_addr, &mode)) { if (mode == BTM_PM_STS_PENDING) { - LOG_DEBUG("LCB(0x%x) is in PM pending state", p_lcb->Handle()); + log::debug("LCB(0x{:x}) is in PM pending state", p_lcb->Handle()); return true; } } @@ -824,7 +828,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, uint16_t local_cid, ** This LCB will be served when receiving number of completed packet event. */ if (l2cb.is_cong_cback_context) { - LOG_INFO("skipping, is_cong_cback_context=true"); + log::warn("skipping, is_cong_cback_context=true"); return; } @@ -832,7 +836,7 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, uint16_t local_cid, ** have at least 1, then do a round-robin for all the LCBs */ if ((p_lcb == NULL) || (p_lcb->link_xmit_quota == 0)) { - LOG_DEBUG("Round robin"); + log::debug("Round robin"); if (p_lcb == NULL) { p_lcb = l2cb.lcb_pool; } else if (!single_write) { @@ -851,34 +855,35 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, uint16_t local_cid, (p_lcb->transport == BT_TRANSPORT_LE && (l2cb.ble_round_robin_unacked >= l2cb.ble_round_robin_quota || l2cb.controller_le_xmit_window == 0))) { - LOG_DEBUG("Skipping lcb %d due to controller window full", xx); + log::debug("Skipping lcb {} due to controller window full", xx); continue; } if ((!p_lcb->in_use) || (p_lcb->link_state != LST_CONNECTED) || (p_lcb->link_xmit_quota != 0) || (l2c_link_check_power_mode(p_lcb))) { - LOG_DEBUG("Skipping lcb %d due to quota", xx); + log::debug("Skipping lcb {} due to quota", xx); continue; } /* See if we can send anything from the Link Queue */ if (!list_is_empty(p_lcb->link_xmit_data_q)) { - LOG_VERBOSE("Sending to lower layer"); + log::verbose("Sending to lower layer"); p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q); list_remove(p_lcb->link_xmit_data_q, p_buf); - l2c_link_send_to_lower(p_lcb, p_buf); + l2c_link_send_to_lower(p_lcb, p_buf, NULL); } else if (single_write) { /* If only doing one write, break out */ - LOG_DEBUG("single_write is true, skipping"); + log::debug("single_write is true, skipping"); break; } /* If nothing on the link queue, check the channel queue */ else { - LOG_DEBUG("Check next buffer"); - p_buf = l2cu_get_next_buffer_to_send(p_lcb); + tL2C_TX_COMPLETE_CB_INFO cbi = {}; + log::debug("Check next buffer"); + p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi); if (p_buf != NULL) { - LOG_DEBUG("Sending next buffer"); - l2c_link_send_to_lower(p_lcb, p_buf); + log::debug("Sending next buffer"); + l2c_link_send_to_lower(p_lcb, p_buf, &cbi); } } } @@ -895,15 +900,16 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, uint16_t local_cid, l2cb.ble_check_round_robin = false; } else /* if this is not round-robin service */ { - /* If a partial segment is being sent, can't send anything else */ + /* link_state or power mode not ready, can't send anything else */ if ((p_lcb->link_state != LST_CONNECTED) || (l2c_link_check_power_mode(p_lcb))) { - LOG_INFO("A partial segment is being sent, cannot send anything else"); + log::warn("Can't send, link state: {} not LST_CONNECTED or power mode BTM_PM_STS_PENDING", + p_lcb->link_state); return; } - LOG_VERBOSE( - "Direct send, transport=%d, xmit_window=%d, le_xmit_window=%d, " - "sent_not_acked=%d, link_xmit_quota=%d", + log::verbose( + "Direct send, transport={}, xmit_window={}, le_xmit_window={}, " + "sent_not_acked={}, link_xmit_quota={}", p_lcb->transport, l2cb.controller_xmit_window, l2cb.controller_le_xmit_window, p_lcb->sent_not_acked, p_lcb->link_xmit_quota); @@ -915,30 +921,31 @@ void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, uint16_t local_cid, (p_lcb->transport == BT_TRANSPORT_LE))) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) { if (list_is_empty(p_lcb->link_xmit_data_q)) { - LOG_VERBOSE("No transmit data, skipping"); + log::verbose("No transmit data, skipping"); break; } - LOG_VERBOSE("Sending to lower layer"); + log::verbose("Sending to lower layer"); p_buf = (BT_HDR*)list_front(p_lcb->link_xmit_data_q); list_remove(p_lcb->link_xmit_data_q, p_buf); - l2c_link_send_to_lower(p_lcb, p_buf); + l2c_link_send_to_lower(p_lcb, p_buf, NULL); } if (!single_write) { /* See if we can send anything for any channel */ - LOG_VERBOSE("Trying to send other data when single_write is false"); + log::verbose("Trying to send other data when single_write is false"); while (((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) || (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE))) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota)) { - p_buf = l2cu_get_next_buffer_to_send(p_lcb); + tL2C_TX_COMPLETE_CB_INFO cbi = {}; + p_buf = l2cu_get_next_buffer_to_send(p_lcb, &cbi); if (p_buf == NULL) { - LOG_VERBOSE("No next buffer, skipping"); + log::verbose("No next buffer, skipping"); break; } - LOG_VERBOSE("Sending to lower layer"); - l2c_link_send_to_lower(p_lcb, p_buf); + log::verbose("Sending to lower layer"); + l2c_link_send_to_lower(p_lcb, p_buf, &cbi); } } @@ -959,7 +966,7 @@ void l2c_OnHciModeChangeSendPendingPackets(RawAddress remote) { if (p_lcb != NULL) { /* There might be any pending packets due to SNIFF or PENDING state */ /* Trigger L2C to start transmission of the pending packets. */ - LOG_VERBOSE( + log::verbose( "btm mode change to active; check l2c_link for outgoing packets"); l2c_link_check_send_pkts(p_lcb, 0, NULL); } @@ -983,10 +990,10 @@ static void l2c_link_send_to_lower_br_edr(tL2C_LCB* p_lcb, BT_HDR* p_buf) { l2cb.controller_xmit_window--; acl_send_data_packet_br_edr(p_lcb->remote_bd_addr, p_buf); - LOG_VERBOSE("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d", - l2cb.controller_xmit_window, p_lcb->Handle(), - p_lcb->link_xmit_quota, p_lcb->sent_not_acked, - l2cb.round_robin_quota, l2cb.round_robin_unacked); + log::verbose( + "TotalWin={},Hndl=0x{:x},Quota={},Unack={},RRQuota={},RRUnack={}", + l2cb.controller_xmit_window, p_lcb->Handle(), p_lcb->link_xmit_quota, + p_lcb->sent_not_acked, l2cb.round_robin_quota, l2cb.round_robin_unacked); } static void l2c_link_send_to_lower_ble(tL2C_LCB* p_lcb, BT_HDR* p_buf) { @@ -1000,18 +1007,20 @@ static void l2c_link_send_to_lower_ble(tL2C_LCB* p_lcb, BT_HDR* p_buf) { l2cb.controller_le_xmit_window--; acl_send_data_packet_ble(p_lcb->remote_bd_addr, p_buf); - LOG_DEBUG("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d", - l2cb.controller_le_xmit_window, p_lcb->Handle(), - p_lcb->link_xmit_quota, p_lcb->sent_not_acked, - l2cb.ble_round_robin_quota, l2cb.ble_round_robin_unacked); + log::debug("TotalWin={},Hndl=0x{:x},Quota={},Unack={},RRQuota={},RRUnack={}", + l2cb.controller_le_xmit_window, p_lcb->Handle(), + p_lcb->link_xmit_quota, p_lcb->sent_not_acked, + l2cb.ble_round_robin_quota, l2cb.ble_round_robin_unacked); } -static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf) { +static void l2c_link_send_to_lower(tL2C_LCB* p_lcb, BT_HDR* p_buf, + tL2C_TX_COMPLETE_CB_INFO* p_cbi) { if (p_lcb->transport == BT_TRANSPORT_BR_EDR) { l2c_link_send_to_lower_br_edr(p_lcb, p_buf); } else { l2c_link_send_to_lower_ble(p_lcb, p_buf); } + if (p_cbi) l2cu_tx_complete(p_cbi); } void l2c_packets_completed(uint16_t handle, uint16_t num_sent) { @@ -1033,7 +1042,7 @@ void l2c_packets_completed(uint16_t handle, uint16_t num_sent) { l2cb.update_outstanding_le_packets(num_sent); break; default: - LOG_ERROR("Unknown transport received:%u", p_lcb->transport); + log::error("Unknown transport received:{}", p_lcb->transport); return; } @@ -1079,15 +1088,15 @@ void l2c_link_segments_xmitted(BT_HDR* p_msg) { /* Find the LCB based on the handle */ tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); if (p_lcb == nullptr) { - LOG_WARN("Received segment complete for unknown connection handle:%d", - handle); + log::warn("Received segment complete for unknown connection handle:{}", + handle); osi_free(p_msg); return; } if (p_lcb->link_state != LST_CONNECTED) { - LOG_INFO("Received segment complete for unconnected connection handle:%d:", - handle); + log::info("Received segment complete for unconnected connection handle:{}:", + handle); osi_free(p_msg); return; } @@ -1103,14 +1112,14 @@ tBTM_STATUS l2cu_ConnectAclForSecurity(const RawAddress& bd_addr) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb && (p_lcb->link_state == LST_CONNECTED || p_lcb->link_state == LST_CONNECTING)) { - LOG_WARN("Connection already exists"); + log::warn("Connection already exists"); return BTM_CMD_STARTED; } /* Make sure an L2cap link control block is available */ if (!p_lcb && (p_lcb = l2cu_allocate_lcb(bd_addr, true, BT_TRANSPORT_BR_EDR)) == NULL) { - LOG_WARN("failed allocate LCB for %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::warn("failed allocate LCB for {}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return BTM_NO_RESOURCES; } @@ -1149,13 +1158,13 @@ tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) { p_ccb = p_lcb->rr_serv[p_lcb->rr_pri].p_serve_ccb; if (!p_ccb) { - LOG_ERROR("p_serve_ccb is NULL, rr_pri=%d", p_lcb->rr_pri); + log::error("p_serve_ccb is NULL, rr_pri={}", p_lcb->rr_pri); return NULL; } - LOG_VERBOSE("RR scan pri=%d, lcid=0x%04x, q_cout=%zu", - p_ccb->ccb_priority, p_ccb->local_cid, - fixed_queue_length(p_ccb->xmit_hold_q)); + log::verbose("RR scan pri={}, lcid=0x{:04x}, q_cout={}", + p_ccb->ccb_priority, p_ccb->local_cid, + fixed_queue_length(p_ccb->xmit_hold_q)); /* store the next serving channel */ /* this channel is the last channel of its priority group */ @@ -1172,7 +1181,7 @@ tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) { if (p_ccb->chnl_state != CST_OPEN) continue; if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) { - LOG_DEBUG("Connection oriented channel"); + log::debug("Connection oriented channel"); if (fixed_queue_is_empty(p_ccb->xmit_hold_q)) continue; } else { @@ -1211,10 +1220,10 @@ tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) { } if (p_serve_ccb) { - LOG_VERBOSE("RR service pri=%d, quota=%d, lcid=0x%04x", - p_serve_ccb->ccb_priority, - p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota, - p_serve_ccb->local_cid); + log::verbose("RR service pri={}, quota={}, lcid=0x{:04x}", + p_serve_ccb->ccb_priority, + p_lcb->rr_serv[p_serve_ccb->ccb_priority].quota, + p_serve_ccb->local_cid); } return p_serve_ccb; @@ -1230,13 +1239,16 @@ tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) { * Returns pointer to buffer or NULL * ******************************************************************************/ -BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { +BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, + tL2C_TX_COMPLETE_CB_INFO* p_cbi) { tL2C_CCB* p_ccb; BT_HDR* p_buf; /* Highest priority are fixed channels */ int xx; + p_cbi->cb = NULL; + for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { p_ccb = p_lcb->p_fixed_ccbs[xx]; if (p_ccb == NULL) continue; @@ -1265,10 +1277,15 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { if (!fixed_queue_is_empty(p_ccb->xmit_hold_q)) { p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q); if (NULL == p_buf) { - LOG_ERROR("No data to be sent"); + log::error("No data to be sent"); return (NULL); } + /* Prepare callback info for TX completion */ + p_cbi->cb = l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb; + p_cbi->local_cid = p_ccb->local_cid; + p_cbi->num_sdu = 1; + l2cu_check_channel_congestion(p_ccb); l2cu_set_acl_hci_header(p_buf, p_ccb); return (p_buf); @@ -1285,7 +1302,7 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE) { /* Check credits */ if (p_ccb->peer_conn_cfg.credits == 0) { - LOG_DEBUG("No credits to send packets"); + log::debug("No credits to send packets"); return NULL; } @@ -1305,7 +1322,7 @@ BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb) { } else { p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_hold_q); if (NULL == p_buf) { - LOG_ERROR("#2: No data to be sent"); + log::error("#2: No data to be sent"); return (NULL); } } diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc index 588ba3989d4cddb8f4257d83a1fdb80652e93b0f..6634b7bab799f2965b6d54efa47d2caa11051040 100644 --- a/system/stack/l2cap/l2c_main.cc +++ b/system/stack/l2cap/l2c_main.cc @@ -24,10 +24,11 @@ #define LOG_TAG "bt_l2c_main" +#include #include #include "common/init_flags.h" -#include "gd/hal/snoop_logger.h" +#include "hal/snoop_logger.h" #include "hcimsgs.h" // HCID_GET_ #include "internal_include/bt_target.h" #include "main/shim/entry.h" @@ -41,6 +42,8 @@ #include "stack/include/l2cdefs.h" #include "stack/l2cap/l2c_int.h" +using namespace bluetooth; + /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /******************************************************************************/ @@ -73,7 +76,7 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { /* Since the HCI Transport is putting segmented packets back together, we */ /* should never get a valid packet with the type set to "continuation" */ if (pkt_type == L2CAP_PKT_CONTINUE) { - LOG_WARN("L2CAP - received packet continuation"); + log::warn("L2CAP - received packet continuation"); osi_free(p_msg); return; } @@ -82,7 +85,7 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { STREAM_TO_UINT16(hci_len, p); if (hci_len < L2CAP_PKT_OVERHEAD || hci_len != p_msg->len - 4) { /* Remote-declared packet size must match HCI_ACL size - ACL header (4) */ - LOG_WARN("L2CAP - got incorrect hci header"); + log::warn("L2CAP - got incorrect hci header"); osi_free(p_msg); return; } @@ -94,8 +97,8 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { /* Find the LCB based on the handle */ tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); if (!p_lcb) { - LOG_ERROR("L2CAP - rcvd ACL for unknown handle:%d ls:%d cid:%d", handle, - p_msg->layer_specific, rcv_cid); + log::error("L2CAP - rcvd ACL for unknown handle:{} ls:{} cid:{}", handle, + p_msg->layer_specific, rcv_cid); osi_free(p_msg); return; } @@ -117,7 +120,7 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { if (rcv_cid >= L2CAP_BASE_APPL_CID) { p_ccb = l2cu_find_ccb_by_cid(p_lcb, rcv_cid); if (!p_ccb) { - LOG_WARN("L2CAP - unknown CID: 0x%04x", rcv_cid); + log::warn("L2CAP - unknown CID: 0x{:04x}", rcv_cid); osi_free(p_msg); return; } @@ -127,8 +130,8 @@ void l2c_rcv_acl_data(BT_HDR* p_msg) { p_msg->offset += L2CAP_PKT_OVERHEAD; if (l2cap_len != p_msg->len) { - LOG_WARN("L2CAP - bad length in pkt. Exp: %d Act: %d", l2cap_len, - p_msg->len); + log::warn("L2CAP - bad length in pkt. Exp: {} Act: {}", l2cap_len, + p_msg->len); osi_free(p_msg); return; } @@ -226,7 +229,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* if l2cap command received in CID 1 on top of an LE link, ignore this * command */ if (p_lcb->transport == BT_TRANSPORT_LE) { - LOG_INFO("Dropping data on CID 1 for LE link"); + log::info("Dropping data on CID 1 for LE link"); return; } @@ -238,8 +241,8 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { * will be ignored. Here we simply mark the bad packet and decide which cmd * ID to reject later */ pkt_size_rej = true; - LOG_WARN("Signaling pkt_len=%d exceeds MTU size %d", pkt_len, - L2CAP_DEFAULT_MTU); + log::warn("Signaling pkt_len={} exceeds MTU size {}", pkt_len, + L2CAP_DEFAULT_MTU); } uint8_t* p_next_cmd = p; @@ -276,8 +279,8 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { first_cmd = false; if (cmd_len > BT_SMALL_BUFFER_SIZE) { - LOG_WARN("Command size %u exceeds limit %d", cmd_len, - BT_SMALL_BUFFER_SIZE); + log::warn("Command size {} exceeds limit {}", cmd_len, + BT_SMALL_BUFFER_SIZE); l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, 0, 0); return; } @@ -285,22 +288,22 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { /* Check command length does not exceed packet length */ p_next_cmd = p + cmd_len; if (p_next_cmd > p_pkt_end) { - LOG_WARN("cmd_len > pkt_len, pkt_len=%d, cmd_len=%d, code=%d", pkt_len, - cmd_len, cmd_code); + log::warn("cmd_len > pkt_len, pkt_len={}, cmd_len={}, code={}", pkt_len, + cmd_len, cmd_code); break; } - LOG_DEBUG("cmd: %s, id:%d, cmd_len:%d", - l2cap_command_code_text(cmd_code).c_str(), id, cmd_len); + log::debug("cmd: {}, id:{}, cmd_len:{}", l2cap_command_code_text(cmd_code), + id, cmd_len); /* Bad L2CAP packet length, look for cmd to reject */ if (pkt_size_rej) { /* If command found rejected it and we're done, otherwise keep looking */ if (l2c_is_cmd_rejected(cmd_code, id, p_lcb)) { - LOG_WARN("Rejected command %d due to bad packet length", cmd_code); + log::warn("Rejected command {} due to bad packet length", cmd_code); return; } else { - LOG_WARN("No need to reject command %d for bad packet len", cmd_code); + log::warn("No need to reject command {} for bad packet len", cmd_code); continue; /* Look for next cmd/response in current packet */ } } @@ -309,39 +312,40 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_REJECT: uint16_t rej_reason; if (p + 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_REJECT"); + log::warn("Not enough data for L2CAP_CMD_REJECT"); return; } STREAM_TO_UINT16(rej_reason, p); if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED) { uint16_t rej_mtu; if (p + 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_REJ_MTU_EXCEEDED"); + log::warn("Not enough data for L2CAP_CMD_REJ_MTU_EXCEEDED"); return; } STREAM_TO_UINT16(rej_mtu, p); /* What to do with the MTU reject ? We have negotiated an MTU. For now * we will ignore it and let a higher protocol timeout take care of it */ - LOG_WARN("MTU rej Handle: %d MTU: %d", p_lcb->Handle(), rej_mtu); + log::warn("MTU rej Handle: {} MTU: {}", p_lcb->Handle(), rej_mtu); } if (rej_reason == L2CAP_CMD_REJ_INVALID_CID) { uint16_t lcid, rcid; if (p + 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_REJ_INVALID_CID"); + log::warn("Not enough data for L2CAP_CMD_REJ_INVALID_CID"); return; } STREAM_TO_UINT16(rcid, p); STREAM_TO_UINT16(lcid, p); - LOG_WARN("Rejected due to invalid CID, LCID: 0x%04x RCID: 0x%04x", - lcid, rcid); + log::warn( + "Rejected due to invalid CID, LCID: 0x{:04x} RCID: 0x{:04x}", + lcid, rcid); /* Remote CID invalid. Treat as a disconnect */ tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid); if ((p_ccb != NULL) && (p_ccb->remote_cid == rcid)) { /* Fake link disconnect - no reply is generated */ - LOG_WARN("Remote CID is invalid, treat as disconnected"); + log::warn("Remote CID is invalid, treat as disconnected"); l2c_csm_execute(p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); } } @@ -367,27 +371,27 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_CONN_REQ: { uint16_t rcid; if (p + 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_CONN_REQ"); + log::warn("Not enough data for L2CAP_CMD_CONN_REQ"); return; } STREAM_TO_UINT16(con_info.psm, p); STREAM_TO_UINT16(rcid, p); p_rcb = l2cu_find_rcb_by_psm(con_info.psm); if (!p_rcb) { - LOG_WARN("Rcvd conn req for unknown PSM: %d", con_info.psm); + log::warn("Rcvd conn req for unknown PSM: {}", con_info.psm); l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_PSM); break; } else { if (!p_rcb->api.pL2CA_ConnectInd_Cb) { - LOG_WARN("Rcvd conn req for outgoing-only connection PSM: %d", - con_info.psm); + log::warn("Rcvd conn req for outgoing-only connection PSM: {}", + con_info.psm); l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_PSM); break; } } tL2C_CCB* p_ccb = l2cu_allocate_ccb(p_lcb, 0); if (p_ccb == nullptr) { - LOG_ERROR("Unable to allocate CCB"); + log::error("Unable to allocate CCB"); l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_RESOURCES); break; } @@ -411,7 +415,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_CONN_RSP: { uint16_t lcid; if (p + 8 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_CONN_REQ"); + log::warn("Not enough data for L2CAP_CMD_CONN_REQ"); return; } STREAM_TO_UINT16(con_info.remote_cid, p); @@ -421,12 +425,12 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid); if (!p_ccb) { - LOG_WARN("no CCB for conn rsp, LCID: %d RCID: %d", lcid, - con_info.remote_cid); + log::warn("no CCB for conn rsp, LCID: {} RCID: {}", lcid, + con_info.remote_cid); break; } if (p_ccb->local_id != id) { - LOG_WARN("con rsp - bad ID. Exp: %d Got: %d", p_ccb->local_id, id); + log::warn("con rsp - bad ID. Exp: {} Got: {}", p_ccb->local_id, id); break; } @@ -457,7 +461,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { uint16_t lcid; if (p + 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_REQ"); + log::warn("Not enough data for L2CAP_CMD_CONFIG_REQ"); return; } STREAM_TO_UINT16(lcid, p); @@ -472,7 +476,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { while (p < p_cfg_end) { uint8_t cfg_code, cfg_len; if (p + 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_REQ sub_event"); + log::warn("Not enough data for L2CAP_CMD_CONFIG_REQ sub_event"); return; } STREAM_TO_UINT8(cfg_code, p); @@ -601,7 +605,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { uint8_t* p_cfg_end = p + cmd_len; uint16_t lcid; if (p + 6 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_RSP"); + log::warn("Not enough data for L2CAP_CMD_CONFIG_RSP"); return; } STREAM_TO_UINT16(lcid, p); @@ -615,7 +619,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { while (p < p_cfg_end) { uint8_t cfg_code, cfg_len; if (p + 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_CONFIG_RSP sub_event"); + log::warn("Not enough data for L2CAP_CMD_CONFIG_RSP sub_event"); return; } STREAM_TO_UINT8(cfg_code, p); @@ -625,7 +629,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CFG_TYPE_MTU: cfg_info.mtu_present = true; if (p + 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CFG_TYPE_MTU"); + log::warn("Not enough data for L2CAP_CFG_TYPE_MTU"); return; } STREAM_TO_UINT16(cfg_info.mtu, p); @@ -634,7 +638,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CFG_TYPE_FLUSH_TOUT: cfg_info.flush_to_present = true; if (p + 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CFG_TYPE_FLUSH_TOUT"); + log::warn("Not enough data for L2CAP_CFG_TYPE_FLUSH_TOUT"); return; } STREAM_TO_UINT16(cfg_info.flush_to, p); @@ -643,7 +647,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CFG_TYPE_QOS: cfg_info.qos_present = true; if (p + 2 + 5 * 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CFG_TYPE_QOS"); + log::warn("Not enough data for L2CAP_CFG_TYPE_QOS"); return; } STREAM_TO_UINT8(cfg_info.qos.qos_flags, p); @@ -658,7 +662,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CFG_TYPE_FCR: cfg_info.fcr_present = true; if (p + 3 + 3 * 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CFG_TYPE_FCR"); + log::warn("Not enough data for L2CAP_CFG_TYPE_FCR"); return; } STREAM_TO_UINT8(cfg_info.fcr.mode, p); @@ -672,7 +676,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CFG_TYPE_FCS: cfg_info.fcs_present = true; if (p + 1 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CFG_TYPE_FCS"); + log::warn("Not enough data for L2CAP_CFG_TYPE_FCS"); return; } STREAM_TO_UINT8(cfg_info.fcs, p); @@ -681,7 +685,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CFG_TYPE_EXT_FLOW: cfg_info.ext_flow_spec_present = true; if (p + 2 + 2 + 3 * 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CFG_TYPE_EXT_FLOW"); + log::warn("Not enough data for L2CAP_CFG_TYPE_EXT_FLOW"); return; } STREAM_TO_UINT8(cfg_info.ext_flow_spec.id, p); @@ -697,7 +701,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid); if (p_ccb) { if (p_ccb->local_id != id) { - LOG_WARN("cfg rsp - bad ID. Exp: %d Got: %d", p_ccb->local_id, id); + log::warn("cfg rsp - bad ID. Exp: {} Got: {}", p_ccb->local_id, id); break; } if (cfg_info.result == L2CAP_CFG_OK) { @@ -706,7 +710,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONFIG_RSP_NEG, &cfg_info); } } else { - LOG_WARN("Rcvd cfg rsp for unknown CID: 0x%04x", lcid); + log::warn("Rcvd cfg rsp for unknown CID: 0x{:04x}", lcid); } break; } @@ -714,7 +718,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_DISC_REQ: { uint16_t lcid, rcid; if (p + 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_DISC_REQ"); + log::warn("Not enough data for L2CAP_CMD_DISC_REQ"); return; } STREAM_TO_UINT16(lcid, p); @@ -735,7 +739,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_DISC_RSP: { uint16_t lcid, rcid; if (p + 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_DISC_RSP"); + log::warn("Not enough data for L2CAP_CMD_DISC_RSP"); return; } STREAM_TO_UINT16(rcid, p); @@ -757,7 +761,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { case L2CAP_CMD_INFO_REQ: { uint16_t info_type; if (p + 2 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_INFO_REQ"); + log::warn("Not enough data for L2CAP_CMD_INFO_REQ"); return; } STREAM_TO_UINT16(info_type, p); @@ -774,7 +778,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { uint16_t info_type, result; if (p + 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_INFO_RSP"); + log::warn("Not enough data for L2CAP_CMD_INFO_RSP"); return; } STREAM_TO_UINT16(info_type, p); @@ -783,7 +787,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { if ((info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) && (result == L2CAP_INFO_RESP_RESULT_SUCCESS)) { if (p + 4 > p_next_cmd) { - LOG_WARN("Not enough data for L2CAP_CMD_INFO_RSP sub_event"); + log::warn("Not enough data for L2CAP_CMD_INFO_RSP sub_event"); return; } STREAM_TO_UINT32(p_lcb->peer_ext_fea, p); @@ -818,7 +822,7 @@ static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { break; default: - LOG_WARN("Bad cmd code: %d", cmd_code); + log::warn("Bad cmd code: {}", cmd_code); l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); return; @@ -906,7 +910,7 @@ uint8_t l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { /* Find the channel control block. We don't know the link it is on. */ tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, cid); if (!p_ccb) { - LOG_WARN("L2CAP - no CCB for L2CA_DataWrite, CID: %d", cid); + log::warn("L2CAP - no CCB for L2CA_DataWrite, CID: {}", cid); osi_free(p_data); return (L2CAP_DW_FAILED); } @@ -920,9 +924,9 @@ uint8_t l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { mtu = p_ccb->peer_cfg.mtu; if (p_data->len > mtu) { - LOG_WARN( - "L2CAP - CID: 0x%04x cannot send message bigger than peer's mtu size: " - "len=%u mtu=%u", + log::warn( + "L2CAP - CID: 0x{:04x} cannot send message bigger than peer's mtu " + "size: len={} mtu={}", cid, p_data->len, mtu); osi_free(p_data); return (L2CAP_DW_FAILED); @@ -933,9 +937,9 @@ uint8_t l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { /* If already congested, do not accept any more packets */ if (p_ccb->cong_sent) { - LOG_ERROR( - "L2CAP - CID: 0x%04x cannot send, already congested " - "xmit_hold_q.count: %zu buff_quota: %u", + log::error( + "L2CAP - CID: 0x{:04x} cannot send, already congested " + "xmit_hold_q.count: {} buff_quota: {}", p_ccb->local_cid, fixed_queue_length(p_ccb->xmit_hold_q), p_ccb->buff_quota); diff --git a/system/stack/l2cap/l2c_utils.cc b/system/stack/l2cap/l2c_utils.cc index 657b5b0997537db0eef9b766eda7805546a477a3..e7b9f962575a00947e5226e781b042667d57bb9f 100644 --- a/system/stack/l2cap/l2c_utils.cc +++ b/system/stack/l2cap/l2c_utils.cc @@ -24,11 +24,13 @@ #define LOG_TAG "l2c_utils" #include +#include #include #include #include "device/include/controller.h" -#include "gd/hal/snoop_logger.h" +#include "hal/snoop_logger.h" +#include "hci/controller_interface.h" #include "internal_include/bt_target.h" #include "main/shim/entry.h" #include "os/log.h" @@ -47,6 +49,8 @@ #include "stack/l2cap/l2c_int.h" #include "types/raw_address.h" +using namespace bluetooth; + tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb); // TODO Move /******************************************************************************* @@ -107,8 +111,8 @@ tL2C_LCB* l2cu_allocate_lcb(const RawAddress& p_bd_addr, bool is_bonding, void l2cu_set_lcb_handle(struct t_l2c_linkcb& p_lcb, uint16_t handle) { if (p_lcb.Handle() != HCI_INVALID_HANDLE) { - LOG_WARN("Should not replace active handle:%hu with new handle:%hu", - p_lcb.Handle(), handle); + log::warn("Should not replace active handle:{} with new handle:{}", + p_lcb.Handle(), handle); } p_lcb.SetHandle(handle); } @@ -127,8 +131,8 @@ void l2cu_update_lcb_4_bonding(const RawAddress& p_bd_addr, bool is_bonding) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb) { - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(p_bd_addr) - << " is_bonding: " << is_bonding; + log::verbose("BDA: {} is_bonding: {}", ADDRESS_TO_LOGGABLE_STR(p_bd_addr), + is_bonding); if (is_bonding) { p_lcb->SetBonding(); } else { @@ -277,7 +281,7 @@ bool l2c_is_cmd_rejected(uint8_t cmd_code, uint8_t signal_id, tL2C_LCB* p_lcb) { case L2CAP_CMD_BLE_UPDATE_REQ: l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, signal_id, L2CAP_DEFAULT_MTU, 0); - LOG_WARN("Dumping first Command (%d)", cmd_code); + log::warn("Dumping first Command ({})", cmd_code); return true; default: /* Otherwise a response */ @@ -372,7 +376,7 @@ void l2cu_send_peer_cmd_reject(tL2C_LCB* p_lcb, uint16_t reason, uint8_t rem_id, p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_CMD_REJECT_LEN + param_len), L2CAP_CMD_REJECT, rem_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer cmd_rej"); + log::warn("L2CAP - no buffer cmd_rej"); return; } @@ -411,7 +415,7 @@ void l2cu_send_peer_connect_req(tL2C_CCB* p_ccb) { p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_REQ_LEN, L2CAP_CMD_CONN_REQ, p_ccb->local_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for conn_req"); + log::warn("L2CAP - no buffer for conn_req"); return; } @@ -439,7 +443,7 @@ void l2cu_send_peer_connect_rsp(tL2C_CCB* p_ccb, uint16_t result, if (result == L2CAP_CONN_PENDING) { /* if we already sent pending response */ if (p_ccb->flags & CCB_FLAG_SENT_PENDING) { - LOG_DEBUG("Already sent connection pending, not sending again"); + log::debug("Already sent connection pending, not sending again"); return; } else { p_ccb->flags |= CCB_FLAG_SENT_PENDING; @@ -449,7 +453,7 @@ void l2cu_send_peer_connect_rsp(tL2C_CCB* p_ccb, uint16_t result, BT_HDR* p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, p_ccb->remote_id); if (p_buf == nullptr) { - LOG_WARN("no buffer for conn_rsp"); + log::warn("no buffer for conn_rsp"); return; } @@ -483,7 +487,7 @@ void l2cu_reject_connection(tL2C_LCB* p_lcb, uint16_t remote_cid, p_buf = l2cu_build_header(p_lcb, L2CAP_CONN_RSP_LEN, L2CAP_CMD_CONN_RSP, rem_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for conn_req"); + log::warn("L2CAP - no buffer for conn_req"); return; } @@ -528,15 +532,15 @@ void l2cu_send_credit_based_reconfig_req(tL2C_CCB* p_ccb, p_buf = l2cu_build_header(p_lcb, cmd_len, L2CAP_CMD_CREDIT_BASED_RECONFIG_REQ, p_lcb->signal_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_reconfig_req - no buffer"); + log::warn("l2cu_send_reconfig_req - no buffer"); return; } p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; - LOG_VERBOSE("l2cu_send_reconfig_req number of cids: %d mtu:%d mps:%d", - p_lcb->pending_ecoc_reconfig_cnt, p_cfg->mtu, p_cfg->mps); + log::verbose("l2cu_send_reconfig_req number of cids: {} mtu:{} mps:{}", + p_lcb->pending_ecoc_reconfig_cnt, p_cfg->mtu, p_cfg->mps); UINT16_TO_STREAM(p, p_cfg->mtu); UINT16_TO_STREAM(p, p_cfg->mps); @@ -589,7 +593,7 @@ void l2cu_send_peer_config_req(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { (uint16_t)(L2CAP_CONFIG_REQ_LEN + cfg_len), L2CAP_CMD_CONFIG_REQ, p_ccb->local_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for conn_req"); + log::warn("L2CAP - no buffer for conn_req"); return; } @@ -683,7 +687,7 @@ void l2cu_send_peer_config_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { (uint16_t)(L2CAP_CONFIG_RSP_LEN + cfg_len), L2CAP_CMD_CONFIG_RSP, p_ccb->remote_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for conn_req"); + log::warn("L2CAP - no buffer for conn_req"); return; } @@ -758,14 +762,14 @@ void l2cu_send_peer_config_rej(tL2C_CCB* p_ccb, uint8_t* p_data, uint8_t *p, *p_hci_len, *p_data_end; uint8_t cfg_code; - LOG_VERBOSE("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", data_len, - rej_len); + log::verbose("l2cu_send_peer_config_rej: data_len={}, rej_len={}", data_len, + rej_len); len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN; len1 = 0xFFFF - len; if (rej_len > len1) { - LOG_ERROR("L2CAP - cfg_rej pkt size exceeds buffer design max limit."); + log::error("L2CAP - cfg_rej pkt size exceeds buffer design max limit."); return; } @@ -773,14 +777,11 @@ void l2cu_send_peer_config_rej(tL2C_CCB* p_ccb, uint8_t* p_data, p_buf->offset = L2CAP_SEND_CMD_OFFSET; p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET; - const controller_t* controller = controller_get_interface(); - /* Put in HCI header - handle + pkt boundary */ - if (controller->supports_non_flushable_pb()) { + if (bluetooth::shim::GetController()->SupportsNonFlushablePb()) { UINT16_TO_STREAM(p, (p_ccb->p_lcb->Handle() | (L2CAP_PKT_START_NON_FLUSHABLE << L2CAP_PKT_TYPE_SHIFT))); - } else - { + } else { UINT16_TO_STREAM(p, (p_ccb->p_lcb->Handle() | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT))); } @@ -832,7 +833,7 @@ void l2cu_send_peer_config_rej(tL2C_CCB* p_ccb, uint8_t* p_data, p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD); } else { - LOG_WARN("L2CAP - cfg_rej exceeds allocated buffer"); + log::warn("L2CAP - cfg_rej exceeds allocated buffer"); p_data = p_data_end; /* force loop exit */ break; } @@ -852,8 +853,8 @@ void l2cu_send_peer_config_rej(tL2C_CCB* p_ccb, uint8_t* p_data, p_buf->len = len + 4; - LOG_VERBOSE("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d", len, - (L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len)); + log::verbose("L2CAP - cfg_rej pkt hci_len={}, l2cap_len={}", len, + (L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN + rej_len)); l2c_link_check_send_pkts(p_ccb->p_lcb, 0, p_buf); } @@ -873,7 +874,7 @@ void l2cu_send_peer_disc_req(tL2C_CCB* p_ccb) { uint8_t* p; if ((!p_ccb) || (p_ccb->p_lcb == NULL)) { - LOG_ERROR("%s L2CAP - ccb or lcb invalid", __func__); + log::error("L2CAP - ccb or lcb invalid"); return; } @@ -886,7 +887,7 @@ void l2cu_send_peer_disc_req(tL2C_CCB* p_ccb) { p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_ccb->local_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for disc_req"); + log::warn("L2CAP - no buffer for disc_req"); return; } @@ -932,7 +933,7 @@ void l2cu_send_peer_disc_rsp(tL2C_LCB* p_lcb, uint8_t remote_id, p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_RSP_LEN, L2CAP_CMD_DISC_RSP, remote_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for disc_rsp"); + log::warn("L2CAP - no buffer for disc_rsp"); return; } @@ -964,7 +965,7 @@ void l2cu_send_peer_echo_rsp(tL2C_LCB* p_lcb, uint8_t signal_id, * checking) */ if (!signal_id || signal_id == p_lcb->cur_echo_id) { /* Dump this request since it is illegal */ - LOG_WARN("L2CAP ignoring duplicate echo request (%d)", signal_id); + log::warn("L2CAP ignoring duplicate echo request ({})", signal_id); return; } else p_lcb->cur_echo_id = signal_id; @@ -986,7 +987,7 @@ void l2cu_send_peer_echo_rsp(tL2C_LCB* p_lcb, uint8_t signal_id, p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP, signal_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for echo_rsp"); + log::warn("L2CAP - no buffer for echo_rsp"); return; } @@ -1019,11 +1020,11 @@ void l2cu_send_peer_info_req(tL2C_LCB* p_lcb, uint16_t info_type) { p_buf = l2cu_build_header(p_lcb, 2, L2CAP_CMD_INFO_REQ, p_lcb->signal_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for info_req"); + log::warn("L2CAP - no buffer for info_req"); return; } - LOG_VERBOSE("l2cu_send_peer_info_req: type 0x%04x", info_type); + log::verbose("l2cu_send_peer_info_req: type 0x{:04x}", info_type); p = (uint8_t*)(p_buf + 1) + L2CAP_SEND_CMD_OFFSET + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD; @@ -1077,7 +1078,7 @@ void l2cu_send_peer_info_rsp(tL2C_LCB* p_lcb, uint8_t remote_id, p_buf = l2cu_build_header(p_lcb, len, L2CAP_CMD_INFO_RSP, remote_id); if (p_buf == NULL) { - LOG_WARN("L2CAP - no buffer for info_rsp"); + log::warn("L2CAP - no buffer for info_rsp"); return; } @@ -1163,13 +1164,13 @@ void l2cu_enqueue_ccb(tL2C_CCB* p_ccb) { if (p_ccb->p_lcb != NULL) p_q = &p_ccb->p_lcb->ccb_queue; if ((!p_ccb->in_use) || (p_q == NULL)) { - LOG_ERROR("%s: CID: 0x%04x ERROR in_use: %u p_lcb: %p", __func__, - p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb); + log::error("CID: 0x{:04x} ERROR in_use: {} p_lcb: {}", p_ccb->local_cid, + p_ccb->in_use, fmt::ptr(p_ccb->p_lcb)); return; } - LOG_VERBOSE("l2cu_enqueue_ccb CID: 0x%04x priority: %d", p_ccb->local_cid, - p_ccb->ccb_priority); + log::verbose("l2cu_enqueue_ccb CID: 0x{:04x} priority: {}", p_ccb->local_cid, + p_ccb->ccb_priority); /* If the queue is empty, we go at the front */ if (!p_q->p_first_ccb) { @@ -1237,18 +1238,18 @@ void l2cu_enqueue_ccb(tL2C_CCB* p_ccb) { void l2cu_dequeue_ccb(tL2C_CCB* p_ccb) { tL2C_CCB_Q* p_q = NULL; - LOG_VERBOSE("l2cu_dequeue_ccb CID: 0x%04x", p_ccb->local_cid); + log::verbose("l2cu_dequeue_ccb CID: 0x{:04x}", p_ccb->local_cid); /* Find out which queue the channel is on */ if (p_ccb->p_lcb != NULL) p_q = &p_ccb->p_lcb->ccb_queue; if ((!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL)) { - LOG_ERROR( - "l2cu_dequeue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%p p_q: " - "0x%p p_q->p_first_ccb: 0x%p", - p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q, - p_q ? p_q->p_first_ccb : 0); + log::error( + "l2cu_dequeue_ccb CID: 0x{:04x} ERROR in_use: {} p_lcb: 0x{} p_q: " + "0x{} p_q->p_first_ccb: 0x{}", + p_ccb->local_cid, p_ccb->in_use, fmt::ptr(p_ccb->p_lcb), fmt::ptr(p_q), + fmt::ptr(p_q ? p_q->p_first_ccb : 0)); return; } @@ -1310,7 +1311,7 @@ void l2cu_change_pri_ccb(tL2C_CCB* p_ccb, tL2CAP_CHNL_PRIORITY priority) { if (p_ccb->ccb_priority != priority) { /* If CCB is not the only guy on the queue */ if ((p_ccb->p_next_ccb != NULL) || (p_ccb->p_prev_ccb != NULL)) { - LOG_VERBOSE("Update CCB list in logical link"); + log::verbose("Update CCB list in logical link"); /* Remove CCB from queue and re-queue it at new priority */ l2cu_dequeue_ccb(p_ccb); @@ -1348,9 +1349,9 @@ void l2cu_change_pri_ccb(tL2C_CCB* p_ccb, tL2CAP_CHNL_PRIORITY priority) { * ******************************************************************************/ tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid, bool is_eatt) { - LOG_DEBUG("is_dynamic = %d, cid 0x%04x", p_lcb != nullptr, cid); + log::debug("is_dynamic = {}, cid 0x{:04x}", p_lcb != nullptr, cid); if (!l2cb.p_free_ccb_first) { - LOG_ERROR("First free ccb is null for cid 0x%04x", cid); + log::error("First free ccb is null for cid 0x{:04x}", cid); return nullptr; } tL2C_CCB* p_ccb; @@ -1379,7 +1380,7 @@ tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid, bool is_eatt) { } } if (p_prev == nullptr) { - LOG_ERROR("Could not find CCB for CID 0x%04x in the free list", cid); + log::error("Could not find CCB for CID 0x{:04x} in the free list", cid); return nullptr; } } @@ -1449,7 +1450,7 @@ tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid, bool is_eatt) { if (cid == 0) { p_ccb->config_done = 0; } else { - LOG_DEBUG("cid 0x%04x config_done:0x%x", cid, p_ccb->config_done); + log::debug("cid 0x{:04x} config_done:0x{:x}", cid, p_ccb->config_done); } p_ccb->chnl_state = CST_CLOSED; @@ -1494,14 +1495,15 @@ tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid, bool is_eatt) { bool l2cu_start_post_bond_timer(uint16_t handle) { tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle); if (p_lcb == nullptr) { - LOG_WARN("Unable to find link control block for handle:0x%04x", handle); + log::warn("Unable to find link control block for handle:0x{:04x}", handle); return true; } p_lcb->ResetBonding(); /* Only start timer if no control blocks allocated */ if (p_lcb->ccb_queue.p_first_ccb != nullptr) { - LOG_DEBUG("Unable to start post bond timer with existing dynamic channels"); + log::debug( + "Unable to start post bond timer with existing dynamic channels"); return false; } @@ -1521,13 +1523,13 @@ bool l2cu_start_post_bond_timer(uint16_t handle) { } alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, p_lcb); - LOG_DEBUG("Started link IDLE timeout_ms:%lu", (unsigned long)timeout_ms); + log::debug("Started link IDLE timeout_ms:{}", (unsigned long)timeout_ms); return true; } break; default: - LOG_DEBUG("Will not start post bond timer with link state:%s", - link_state_text(p_lcb->link_state).c_str()); + log::debug("Will not start post bond timer with link state:{}", + link_state_text(p_lcb->link_state)); break; } return false; @@ -1548,8 +1550,8 @@ void l2cu_release_ccb(tL2C_CCB* p_ccb) { tL2C_LCB* p_lcb = p_ccb->p_lcb; tL2C_RCB* p_rcb = p_ccb->p_rcb; - LOG_VERBOSE("l2cu_release_ccb: cid 0x%04x in_use: %u", p_ccb->local_cid, - p_ccb->in_use); + log::verbose("l2cu_release_ccb: cid 0x{:04x} in_use: {}", p_ccb->local_cid, + p_ccb->in_use); /* If already released, could be race condition */ if (!p_ccb->in_use) return; @@ -1623,7 +1625,7 @@ void l2cu_release_ccb(tL2C_CCB* p_ccb) { if (!p_lcb->ccb_queue.p_first_ccb) { if (p_lcb->transport == BT_TRANSPORT_LE && p_ccb->local_cid == L2CAP_ATT_CID) { - LOG_WARN("%s - disconnecting the LE link", __func__); + log::warn("disconnecting the LE link"); l2cu_no_dynamic_ccbs(p_lcb); } } @@ -1753,7 +1755,7 @@ void l2cu_disconnect_chnl(tL2C_CCB* p_ccb) { tL2CA_DISCONNECT_IND_CB* p_disc_cb = p_ccb->p_rcb->api.pL2CA_DisconnectInd_Cb; - LOG_WARN("L2CAP - disconnect_chnl CID: 0x%04x", local_cid); + log::warn("L2CAP - disconnect_chnl CID: 0x{:04x}", local_cid); l2cu_send_peer_disc_req(p_ccb); @@ -1762,7 +1764,7 @@ void l2cu_disconnect_chnl(tL2C_CCB* p_ccb) { (*p_disc_cb)(local_cid, false); } else { /* failure on the AMP channel, probably need to disconnect ACL */ - LOG_ERROR("L2CAP - disconnect_chnl CID: 0x%04x Ignored", local_cid); + log::error("L2CAP - disconnect_chnl CID: 0x{:04x} Ignored", local_cid); } } @@ -1965,9 +1967,9 @@ void l2cu_process_peer_cfg_rsp(tL2C_CCB* p_ccb, tL2CAP_CFG_INFO* p_cfg) { else p_ccb->fcrb.max_held_acks = p_ccb->our_cfg.fcr.tx_win_sz / 3; - LOG_VERBOSE( - "l2cu_process_peer_cfg_rsp(): peer tx_win_sz: %d, our tx_win_sz: %d, " - "max_held_acks: %d", + log::verbose( + "l2cu_process_peer_cfg_rsp(): peer tx_win_sz: {}, our tx_win_sz: {}, " + "max_held_acks: {}", p_cfg->fcr.tx_win_sz, p_ccb->our_cfg.fcr.tx_win_sz, p_ccb->fcrb.max_held_acks); } @@ -2065,7 +2067,7 @@ void l2cu_device_reset(void) { /* This function initiates an acl connection to a LE device. * Returns true if request started successfully, false otherwise. */ bool l2cu_create_conn_le(tL2C_LCB* p_lcb) { - if (!controller_get_interface()->supports_ble()) return false; + if (!controller_get_interface()->SupportsBle()) return false; p_lcb->transport = BT_TRANSPORT_LE; return (l2cble_create_conn(p_lcb)); } @@ -2073,7 +2075,7 @@ bool l2cu_create_conn_le(tL2C_LCB* p_lcb) { /* This function initiates an acl connection to a Classic device via HCI. */ void l2cu_create_conn_br_edr(tL2C_LCB* p_lcb) { const bool controller_supports_role_switch = - controller_get_interface()->supports_role_switch(); + bluetooth::shim::GetController()->SupportsRoleSwitch(); /* While creating a new classic connection, check check all the other * active connections where we are not SCO nor central. @@ -2085,8 +2087,7 @@ void l2cu_create_conn_br_edr(tL2C_LCB* p_lcb) { if (p_lcb_cur == p_lcb) continue; if (!p_lcb_cur->in_use) continue; if (BTM_IsScoActiveByBdaddr(p_lcb_cur->remote_bd_addr)) { - LOG_VERBOSE("%s Central peripheral switch not allowed when SCO active", - __func__); + log::verbose("Central peripheral switch not allowed when SCO active"); continue; } if (p_lcb->IsLinkRoleCentral()) continue; @@ -2242,16 +2243,16 @@ static void l2cu_set_acl_priority_latency_brcm(tL2C_LCB* p_lcb, // priority to high, if using latency mode check preset latency if (p_lcb->use_latency_mode && p_lcb->preset_acl_latency == L2CAP_LATENCY_LOW) { - LOG_INFO("Set ACL priority: High Priority and Low Latency Mode"); + log::info("Set ACL priority: High Priority and Low Latency Mode"); vs_param = HCI_BRCM_ACL_HIGH_PRIORITY_LOW_LATENCY; p_lcb->set_latency(L2CAP_LATENCY_LOW); } else { - LOG_INFO("Set ACL priority: High Priority Mode"); + log::info("Set ACL priority: High Priority Mode"); vs_param = HCI_BRCM_ACL_HIGH_PRIORITY; } } else { // priority to normal - LOG_INFO("Set ACL priority: Normal Mode"); + log::info("Set ACL priority: Normal Mode"); vs_param = HCI_BRCM_ACL_NORMAL_PRIORITY; p_lcb->set_latency(L2CAP_LATENCY_NORMAL); } @@ -2283,16 +2284,16 @@ static void l2cu_set_acl_priority_latency_syna(tL2C_LCB* p_lcb, // priority to high, if using latency mode check preset latency if (p_lcb->use_latency_mode && p_lcb->preset_acl_latency == L2CAP_LATENCY_LOW) { - LOG_INFO("Set ACL priority: High Priority and Low Latency Mode"); + log::info("Set ACL priority: High Priority and Low Latency Mode"); vs_param = HCI_SYNA_ACL_HIGH_PRIORITY_LOW_LATENCY; p_lcb->set_latency(L2CAP_LATENCY_LOW); } else { - LOG_INFO("Set ACL priority: High Priority Mode"); + log::info("Set ACL priority: High Priority Mode"); vs_param = HCI_SYNA_ACL_HIGH_PRIORITY; } } else { // priority to normal - LOG_INFO("Set ACL priority: Normal Mode"); + log::info("Set ACL priority: Normal Mode"); vs_param = HCI_SYNA_ACL_NORMAL_PRIORITY; p_lcb->set_latency(L2CAP_LATENCY_NORMAL); } @@ -2321,11 +2322,11 @@ static void l2cu_set_acl_priority_unisoc(tL2C_LCB* p_lcb, uint8_t vs_param; if (priority == L2CAP_PRIORITY_HIGH) { // priority to high - LOG_INFO("Set ACL priority: High Priority Mode"); + log::info("Set ACL priority: High Priority Mode"); vs_param = HCI_UNISOC_ACL_HIGH_PRIORITY; } else { // priority to normal - LOG_INFO("Set ACL priority: Normal Mode"); + log::info("Set ACL priority: Normal Mode"); vs_param = HCI_UNISOC_ACL_NORMAL_PRIORITY; } @@ -2354,12 +2355,12 @@ bool l2cu_set_acl_priority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority, bool reset_after_rs) { tL2C_LCB* p_lcb; - LOG_VERBOSE("SET ACL PRIORITY %d", priority); + log::verbose("SET ACL PRIORITY {}", priority); /* Find the link control block for the acl channel */ p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb == NULL) { - LOG_WARN("L2CAP - no LCB for L2CA_SetAclPriority"); + log::warn("L2CAP - no LCB for L2CA_SetAclPriority"); return (false); } @@ -2368,6 +2369,7 @@ bool l2cu_set_acl_priority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority, * 2. High priority requested because of central/peripheral role switch */ if ((!reset_after_rs && (priority != p_lcb->acl_priority)) || (reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) { +#ifndef TARGET_FLOSS /* Use vendor specific commands to set the link priority */ switch (controller_get_interface()->get_bt_version()->manufacturer) { case LMP_COMPID_BROADCOM: @@ -2386,6 +2388,7 @@ bool l2cu_set_acl_priority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority, /* Not supported/required for other vendors */ break; } +#endif } /* Adjust lmp buffer allocation for this channel if priority changed */ @@ -2407,8 +2410,8 @@ bool l2cu_set_acl_priority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority, ******************************************************************************/ static void l2cu_set_acl_latency_brcm(tL2C_LCB* p_lcb, tL2CAP_LATENCY latency) { - LOG_INFO("Set ACL latency: %s", - latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency"); + log::info("Set ACL latency: {}", + latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency"); uint8_t command[HCI_BRCM_ACL_PRIORITY_PARAM_SIZE]; uint8_t* pp = command; @@ -2433,8 +2436,8 @@ static void l2cu_set_acl_latency_brcm(tL2C_LCB* p_lcb, tL2CAP_LATENCY latency) { ******************************************************************************/ static void l2cu_set_acl_latency_syna(tL2C_LCB* p_lcb, tL2CAP_LATENCY latency) { - LOG_INFO("Set ACL latency: %s", - latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency"); + log::info("Set ACL latency: {}", + latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency"); uint8_t command[HCI_SYNA_ACL_PRIORITY_PARAM_SIZE]; uint8_t* pp = command; @@ -2459,7 +2462,7 @@ static void l2cu_set_acl_latency_syna(tL2C_LCB* p_lcb, tL2CAP_LATENCY latency) { ******************************************************************************/ static void l2cu_set_acl_latency_mtk(tL2CAP_LATENCY latency) { - LOG_INFO("Set ACL latency: %s", + log::info("Set ACL latency: {}", latency == L2CAP_LATENCY_LOW ? "Low Latancy" : "Normal Latency"); uint8_t command[HCI_MTK_ACL_PRIORITY_PARAM_SIZE]; @@ -2487,13 +2490,13 @@ static void l2cu_set_acl_latency_mtk(tL2CAP_LATENCY latency) { ******************************************************************************/ bool l2cu_set_acl_latency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) { - LOG_INFO("Set ACL low latency: %d", latency); + log::info("Set ACL low latency: {}", latency); /* Find the link control block for the acl channel */ tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR); if (p_lcb == nullptr) { - LOG_WARN("Set latency failed: LCB is null"); + log::warn("Set latency failed: LCB is null"); return false; } /* only change controller's latency when stream using latency mode */ @@ -2557,7 +2560,7 @@ void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda) { tL2C_CCB* p_next_ccb; int xx; - LOG_VERBOSE("l2cu_resubmit_pending_sec_req p_bda: 0x%p", p_bda); + log::verbose("l2cu_resubmit_pending_sec_req p_bda: 0x{}", fmt::ptr(p_bda)); /* If we are called with a BDA, only resubmit for that BDA */ if (p_bda) { @@ -2571,7 +2574,7 @@ void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda) { l2c_csm_execute(p_ccb, L2CEVT_SEC_RE_SEND_CMD, NULL); } } else { - LOG_WARN("l2cu_resubmit_pending_sec_req - unknown BD_ADDR"); + log::warn("l2cu_resubmit_pending_sec_req - unknown BD_ADDR"); } } else { /* No BDA pasesed in, so check all links */ @@ -2620,8 +2623,8 @@ void l2cu_adjust_out_mps(tL2C_CCB* p_ccb) { if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) { /* something is very wrong */ - LOG_ERROR("l2cu_adjust_out_mps bad packet size: %u will use MPS: %u", - packet_size, p_ccb->peer_cfg.fcr.mps); + log::error("l2cu_adjust_out_mps bad packet size: {} will use MPS: {}", + packet_size, p_ccb->peer_cfg.fcr.mps); p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps; } else { packet_size -= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + @@ -2643,9 +2646,9 @@ void l2cu_adjust_out_mps(tL2C_CCB* p_ccb) { else p_ccb->tx_mps = p_ccb->peer_cfg.fcr.mps; - LOG_VERBOSE( - "l2cu_adjust_out_mps use %d Based on peer_cfg.fcr.mps: %u " - "packet_size: %u", + log::verbose( + "l2cu_adjust_out_mps use {} Based on peer_cfg.fcr.mps: {} " + "packet_size: {}", p_ccb->tx_mps, p_ccb->peer_cfg.fcr.mps, packet_size); } } @@ -2678,8 +2681,9 @@ bool l2cu_initialize_fixed_ccb(tL2C_LCB* p_lcb, uint16_t fixed_cid) { if (p_lcb->link_state == LST_DISCONNECTED) { alarm_cancel(p_lcb->l2c_lcb_timer); } else { - LOG_WARN("Unable to cancel link control block for link connection to device %s", - ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr)); + log::warn( + "Unable to cancel link control block for link connection to device {}", + ADDRESS_TO_LOGGABLE_CSTR(p_lcb->remote_bd_addr)); } /* Set CID for the connection */ @@ -2725,8 +2729,8 @@ void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) { (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000 > timeout_ms)) { if (p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout == L2CAP_NO_IDLE_TIMEOUT) { - LOG_VERBOSE("%s NO IDLE timeout set for fixed cid 0x%04x", __func__, - p_lcb->p_fixed_ccbs[xx]->local_cid); + log::verbose("NO IDLE timeout set for fixed cid 0x{:04x}", + p_lcb->p_fixed_ccbs[xx]->local_cid); start_timeout = false; } timeout_ms = p_lcb->p_fixed_ccbs[xx]->fixed_chnl_idle_tout * 1000; @@ -2736,8 +2740,8 @@ void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) { /* If the link is pairing, do not mess with the timeouts */ if (p_lcb->IsBonding()) return; - LOG_VERBOSE("l2cu_no_dynamic_ccbs() with_active_local_clients=%d", - p_lcb->with_active_local_clients); + log::verbose("l2cu_no_dynamic_ccbs() with_active_local_clients={}", + p_lcb->with_active_local_clients); // Inactive connections should not timeout, since the ATT channel might still // be in use even without a GATT client. We only timeout if either a dynamic // channel or a GATT client was used, since then we expect the client to @@ -2747,7 +2751,7 @@ void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) { } if (timeout_ms == 0) { - LOG_VERBOSE("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link"); + log::verbose("l2cu_no_dynamic_ccbs() IDLE timer 0, disconnecting link"); rc = btm_sec_disconnect( p_lcb->Handle(), HCI_ERR_PEER_USER, @@ -2778,7 +2782,7 @@ void l2cu_no_dynamic_ccbs(tL2C_LCB* p_lcb) { if (start_timeout) { alarm_set_on_mloop(p_lcb->l2c_lcb_timer, timeout_ms, l2c_lcb_timer_timeout, p_lcb); - LOG_DEBUG("Started link IDLE timeout_ms:%lu", (unsigned long)timeout_ms); + log::debug("Started link IDLE timeout_ms:{}", (unsigned long)timeout_ms); } else { alarm_cancel(p_lcb->l2c_lcb_timer); } @@ -2897,7 +2901,7 @@ void l2cu_send_peer_ble_par_req(tL2C_LCB* p_lcb, uint16_t min_int, p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_REQ_LEN, L2CAP_CMD_BLE_UPDATE_REQ, p_lcb->signal_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_peer_ble_par_req - no buffer"); + log::warn("l2cu_send_peer_ble_par_req - no buffer"); return; } @@ -2930,7 +2934,7 @@ void l2cu_send_peer_ble_par_rsp(tL2C_LCB* p_lcb, uint16_t reason, p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_UPD_RSP_LEN, L2CAP_CMD_BLE_UPDATE_RSP, rem_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_peer_ble_par_rsp - no buffer"); + log::warn("l2cu_send_peer_ble_par_rsp - no buffer"); return; } @@ -2973,7 +2977,7 @@ void l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB* p_ccb) { l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ_LEN, L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ, p_lcb->signal_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_peer_ble_credit_based_conn_req - no buffer"); + log::warn("l2cu_send_peer_ble_credit_based_conn_req - no buffer"); return; } @@ -2984,9 +2988,9 @@ void l2cu_send_peer_ble_credit_based_conn_req(tL2C_CCB* p_ccb) { mps = p_ccb->local_conn_cfg.mps; initial_credit = p_ccb->local_conn_cfg.credits; - LOG_VERBOSE( - "l2cu_send_peer_ble_credit_based_conn_req PSM:0x%04x local_cid:%d" - " mtu:%d mps:%d initial_credit:%d", + log::verbose( + "l2cu_send_peer_ble_credit_based_conn_req PSM:0x{:04x} local_cid:{} " + "mtu:{} mps:{} initial_credit:{}", p_ccb->p_rcb->real_psm, p_ccb->local_cid, mtu, mps, initial_credit); UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm); @@ -3031,7 +3035,7 @@ void l2cu_send_peer_credit_based_conn_req(tL2C_CCB* p_ccb) { 2 * p_lcb->pending_ecoc_conn_cnt, L2CAP_CMD_CREDIT_BASED_CONN_REQ, p_ccb->local_id); if (p_buf == NULL) { - LOG_WARN("%s - no buffer", __func__); + log::warn("no buffer"); return; } @@ -3042,9 +3046,9 @@ void l2cu_send_peer_credit_based_conn_req(tL2C_CCB* p_ccb) { mps = p_ccb->local_conn_cfg.mps; initial_credit = p_ccb->local_conn_cfg.credits; - LOG_VERBOSE("%s PSM:0x%04x mtu:%d mps:%d initial_credit:%d, cids_cnt %d", - __func__, p_ccb->p_rcb->real_psm, mtu, mps, initial_credit, - p_lcb->pending_ecoc_conn_cnt); + log::verbose("PSM:0x{:04x} mtu:{} mps:{} initial_credit:{}, cids_cnt {}", + p_ccb->p_rcb->real_psm, mtu, mps, initial_credit, + p_lcb->pending_ecoc_conn_cnt); UINT16_TO_STREAM(p, p_ccb->p_rcb->real_psm); UINT16_TO_STREAM(p, mtu); @@ -3053,7 +3057,7 @@ void l2cu_send_peer_credit_based_conn_req(tL2C_CCB* p_ccb) { for (int i = 0; i < p_lcb->pending_ecoc_conn_cnt; i++) { uint16_t cid = p_lcb->pending_ecoc_connection_cids[i]; - LOG_VERBOSE("\n\t cid: %d", cid); + log::verbose(" cid: {}", cid); UINT16_TO_STREAM(p, cid); } @@ -3079,7 +3083,7 @@ void l2cu_reject_ble_coc_connection(tL2C_LCB* p_lcb, uint8_t rem_id, p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, rem_id); if (p_buf == NULL) { - LOG_WARN("l2cu_reject_ble_coc_connection - no buffer"); + log::warn("l2cu_reject_ble_coc_connection - no buffer"); return; } @@ -3116,7 +3120,7 @@ void l2cu_reject_credit_based_conn_req(tL2C_LCB* p_lcb, uint8_t rem_id, p_buf = l2cu_build_header(p_lcb, rsp_len, L2CAP_CMD_CREDIT_BASED_CONN_RES, rem_id); if (p_buf == NULL) { - LOG_WARN("l2cu_reject_credit_based_conn_req - no buffer"); + log::warn("l2cu_reject_credit_based_conn_req - no buffer"); return; } @@ -3149,14 +3153,14 @@ void l2cu_send_peer_credit_based_conn_res(tL2C_CCB* p_ccb, BT_HDR* p_buf; uint8_t* p; - LOG_VERBOSE("%s", __func__); + log::verbose(""); uint8_t rsp_len = L2CAP_CMD_CREDIT_BASED_CONN_RES_MIN_LEN + p_ccb->p_lcb->pending_ecoc_conn_cnt * sizeof(uint16_t); p_buf = l2cu_build_header(p_ccb->p_lcb, rsp_len, L2CAP_CMD_CREDIT_BASED_CONN_RES, p_ccb->remote_id); if (p_buf == NULL) { - LOG_WARN("%s - no buffer", __func__); + log::warn("no buffer"); return; } @@ -3238,12 +3242,12 @@ void l2cu_send_ble_reconfig_rsp(tL2C_LCB* p_lcb, uint8_t rem_id, BT_HDR* p_buf; uint8_t* p; - LOG_VERBOSE("l2cu_send_ble_reconfig_rsp result 0x04%x", result); + log::verbose("l2cu_send_ble_reconfig_rsp result 0x04{:x}", result); p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_CREDIT_BASED_RECONFIG_RES_LEN, L2CAP_CMD_CREDIT_BASED_RECONFIG_RES, rem_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_peer_ble_credit_based_conn_res - no buffer"); + log::warn("l2cu_send_peer_ble_credit_based_conn_res - no buffer"); return; } @@ -3272,12 +3276,12 @@ void l2cu_send_peer_ble_credit_based_conn_res(tL2C_CCB* p_ccb, BT_HDR* p_buf; uint8_t* p; - LOG_VERBOSE("l2cu_send_peer_ble_credit_based_conn_res"); + log::verbose("l2cu_send_peer_ble_credit_based_conn_res"); p_buf = l2cu_build_header(p_ccb->p_lcb, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES_LEN, L2CAP_CMD_BLE_CREDIT_BASED_CONN_RES, p_ccb->remote_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_peer_ble_credit_based_conn_res - no buffer"); + log::warn("l2cu_send_peer_ble_credit_based_conn_res - no buffer"); return; } @@ -3321,7 +3325,7 @@ void l2cu_send_peer_ble_flow_control_credit(tL2C_CCB* p_ccb, p_buf = l2cu_build_header(p_lcb, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT_LEN, L2CAP_CMD_BLE_FLOW_CTRL_CREDIT, p_lcb->signal_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_peer_ble_credit_based_conn_req - no buffer"); + log::warn("l2cu_send_peer_ble_credit_based_conn_req - no buffer"); return; } @@ -3348,7 +3352,7 @@ void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB* p_ccb) { BT_HDR* p_buf; uint8_t* p; tL2C_LCB* p_lcb = NULL; - LOG_VERBOSE("%s", __func__); + log::verbose(""); if (!p_ccb) return; p_lcb = p_ccb->p_lcb; @@ -3361,7 +3365,7 @@ void l2cu_send_peer_ble_credit_based_disconn_req(tL2C_CCB* p_ccb) { p_buf = l2cu_build_header(p_lcb, L2CAP_DISC_REQ_LEN, L2CAP_CMD_DISC_REQ, p_lcb->signal_id); if (p_buf == NULL) { - LOG_WARN("l2cu_send_peer_ble_credit_based_disconn_req - no buffer"); + log::warn("l2cu_send_peer_ble_credit_based_disconn_req - no buffer"); return; } @@ -3435,6 +3439,10 @@ tL2C_CCB* l2cu_find_ccb_by_cid(tL2C_LCB* p_lcb, uint16_t local_cid) { return (p_ccb); } +void l2cu_tx_complete(tL2C_TX_COMPLETE_CB_INFO* p_cbi) { + if (p_cbi->cb != NULL) p_cbi->cb(p_cbi->local_cid, p_cbi->num_sdu); +} + /****************************************************************************** * * Function l2cu_set_acl_hci_header @@ -3491,9 +3499,9 @@ static void send_congestion_status_to_all_clients(tL2C_CCB* p_ccb, p_ccb->cong_sent = status; if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb) { - LOG_VERBOSE( - "L2CAP - Calling CongestionStatus_Cb (%d), CID: 0x%04x " - "xmit_hold_q.count: %zu buff_quota: %u", + log::verbose( + "L2CAP - Calling CongestionStatus_Cb ({}), CID: 0x{:04x} " + "xmit_hold_q.count: {} buff_quota: {}", status, p_ccb->local_cid, fixed_queue_length(p_ccb->xmit_hold_q), p_ccb->buff_quota); diff --git a/system/stack/mmc/BUILD.gn b/system/stack/mmc/BUILD.gn index a3a85edf72a32b9303af8331f7b6b0b027d6a355..8111db73b6ea96236223d37858203927b49401b4 100644 --- a/system/stack/mmc/BUILD.gn +++ b/system/stack/mmc/BUILD.gn @@ -38,6 +38,7 @@ group("mmc") { pkg_config("target_defaults") { include_dirs = [ "//bt/system", + "//bt/system/gd", "//bt/system/include", "//bt/system/stack", "//bt/system/stack/include", @@ -112,7 +113,6 @@ if (use.test) { "//bt/system/test/common/mock_functions.cc", ] include_dirs = [ - "//bt/system/gd", "//bt/system/types", ] configs += [ @@ -137,7 +137,6 @@ if (use.test) { "//bt/system/test/common/mock_functions.cc", ] include_dirs = [ - "//bt/system/gd", "//bt/system/types", ] configs += [ diff --git a/system/stack/mmc/codec_server/BUILD.gn b/system/stack/mmc/codec_server/BUILD.gn index ed575ed3e8d351e14996107d8d09e9ff1c17dc77..7cb958ef287d31141530b2fe55c96573a17cf450 100644 --- a/system/stack/mmc/codec_server/BUILD.gn +++ b/system/stack/mmc/codec_server/BUILD.gn @@ -22,7 +22,6 @@ source_set("libcodec_server_a2dp_aac") { include_dirs = [ "//bt/system", "//bt/system/include", - "//bt/system/internal_include", "//bt/system/stack", "//bt/system/stack/include", ] @@ -34,7 +33,6 @@ source_set("libcodec_server_a2dp_aac") { libs = [ # Following are for AAC using FFmpeg "avcodec", - "avformat", "avutil", ] } diff --git a/system/stack/mmc/proto/BUILD.gn b/system/stack/mmc/proto/BUILD.gn index 8245c2aa5da206a4cf4cdb054a0d76eec5e4d2f3..01a4c7c66daa1bbe4d7383c0a86528102bd38a60 100644 --- a/system/stack/mmc/proto/BUILD.gn +++ b/system/stack/mmc/proto/BUILD.gn @@ -23,11 +23,6 @@ proto_library("mmc_config_proto") { "${proto_in_dir}/mmc_config.proto", ] standalone=true - if (use.test) { - # Override optimize_for option in proto file. - gen_cpp_mode = "speed" - all_dependent_pkg_deps = [ "protobuf" ] - } } proto_library("mmc_service_proto") { @@ -38,9 +33,4 @@ proto_library("mmc_service_proto") { ] deps = [ ":mmc_config_proto" ] standalone=true - if (use.test) { - # Override optimize_for option in proto file. - gen_cpp_mode = "speed" - all_dependent_pkg_deps = [ "protobuf" ] - } } diff --git a/system/stack/mmc/test/hfp_lc3_mmc_decoder_test.cc b/system/stack/mmc/test/hfp_lc3_mmc_decoder_test.cc index 580358602eb0182e7f8d96305631cc3c9e262144..605fef4c4f70fbd46b4fa03a008fee2e24a40e4e 100644 --- a/system/stack/mmc/test/hfp_lc3_mmc_decoder_test.cc +++ b/system/stack/mmc/test/hfp_lc3_mmc_decoder_test.cc @@ -17,7 +17,6 @@ #include "mmc/codec_server/hfp_lc3_mmc_decoder.h" #include -#include #include #include @@ -31,20 +30,11 @@ namespace { -using ::google::protobuf::TextFormat; using ::testing::Contains; using ::testing::Each; using ::testing::Ne; using ::testing::Test; -constexpr char kLc3EncoderConfig[] = R"( - hfp_lc3_encoder_param: {} -)"; - -constexpr char kLc3DecoderConfig[] = R"( - hfp_lc3_decoder_param: {} -)"; - const int kInputLen = mmc::HFP_LC3_PKT_FRAME_LEN; const int kOutputLen = mmc::HFP_LC3_PCM_BYTES + 1; const uint8_t kInputBuf[kInputLen] = {0}; @@ -82,10 +72,9 @@ class HfpLc3DecoderWithInitTest : public HfpLc3DecoderTest { std::fill(kOutputBuf, kOutputBuf + kOutputLen, 1); HfpLc3DecoderTest::SetUp(); - mmc::ConfigParam lc3_decoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); - ASSERT_EQ(decoder_->init(lc3_decoder_config), mmc::HFP_LC3_PKT_FRAME_LEN); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_decoder_param() = mmc::Lc3Param(); + ASSERT_EQ(decoder_->init(config), mmc::HFP_LC3_PKT_FRAME_LEN); } void TearDown() override { HfpLc3DecoderTest::TearDown(); @@ -98,25 +87,23 @@ class HfpLc3DecoderWithInitTest : public HfpLc3DecoderTest { }; TEST_F(HfpLc3DecoderTest, InitWrongCodec) { - mmc::ConfigParam lc3_encoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_encoder_param() = mmc::Lc3Param(); - int ret = decoder_->init(lc3_encoder_config); + int ret = decoder_->init(config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 0); } TEST_F(HfpLc3DecoderTest, InitWrongConfig) { - mmc::ConfigParam lc3_decoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_decoder_param() = mmc::Lc3Param(); // lc3_setup_decoder failed due to wrong parameters (returned nullptr). test::mock::embdrv_lc3::lc3_setup_decoder.body = [](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return nullptr; }; - int ret = decoder_->init(lc3_decoder_config); + int ret = decoder_->init(config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 1); @@ -124,9 +111,8 @@ TEST_F(HfpLc3DecoderTest, InitWrongConfig) { } TEST_F(HfpLc3DecoderTest, InitSuccess) { - mmc::ConfigParam lc3_decoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_decoder_param() = mmc::Lc3Param(); // lc3_setup_decoder returns decoder instance pointer. struct lc3_decoder lc3_decoder; @@ -135,7 +121,7 @@ TEST_F(HfpLc3DecoderTest, InitSuccess) { return &lc3_decoder; }; - int ret = decoder_->init(lc3_decoder_config); + int ret = decoder_->init(config); EXPECT_EQ(ret, mmc::HFP_LC3_PKT_FRAME_LEN); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 1); diff --git a/system/stack/mmc/test/hfp_lc3_mmc_encoder_test.cc b/system/stack/mmc/test/hfp_lc3_mmc_encoder_test.cc index 8d462b1a463cc87a85a9eaba4c8822e48ead8171..f1791a3b7bdc503d75470030737d5e5b066713e0 100644 --- a/system/stack/mmc/test/hfp_lc3_mmc_encoder_test.cc +++ b/system/stack/mmc/test/hfp_lc3_mmc_encoder_test.cc @@ -17,7 +17,6 @@ #include "mmc/codec_server/hfp_lc3_mmc_encoder.h" #include -#include #include #include @@ -31,20 +30,11 @@ namespace { -using ::google::protobuf::TextFormat; using ::testing::Contains; using ::testing::Each; using ::testing::Ne; using ::testing::Test; -constexpr char kLc3EncoderConfig[] = R"( - hfp_lc3_encoder_param: {} -)"; - -constexpr char kLc3DecoderConfig[] = R"( - hfp_lc3_decoder_param: {} -)"; - const int kInputLen = mmc::HFP_LC3_PCM_BYTES; const int kOutputLen = mmc::HFP_LC3_PKT_FRAME_LEN; const uint8_t kInputBuf[kInputLen] = {0}; @@ -82,10 +72,9 @@ class HfpLc3EncoderWithInitTest : public HfpLc3EncoderTest { std::fill(kOutputBuf, kOutputBuf + kOutputLen, 1); HfpLc3EncoderTest::SetUp(); - mmc::ConfigParam lc3_encoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); - ASSERT_EQ(encoder_->init(lc3_encoder_config), mmc::HFP_LC3_PCM_BYTES); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_encoder_param() = mmc::Lc3Param(); + ASSERT_EQ(encoder_->init(config), mmc::HFP_LC3_PCM_BYTES); } void TearDown() override { HfpLc3EncoderTest::TearDown(); @@ -98,25 +87,23 @@ class HfpLc3EncoderWithInitTest : public HfpLc3EncoderTest { }; TEST_F(HfpLc3EncoderTest, InitWrongCodec) { - mmc::ConfigParam lc3_decoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_decoder_param() = mmc::Lc3Param(); - int ret = encoder_->init(lc3_decoder_config); + int ret = encoder_->init(config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 0); } TEST_F(HfpLc3EncoderTest, InitWrongConfig) { - mmc::ConfigParam lc3_encoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_encoder_param() = mmc::Lc3Param(); // lc3_setup_encoder failed due to wrong parameters (returned nullptr). test::mock::embdrv_lc3::lc3_setup_encoder.body = [](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return nullptr; }; - int ret = encoder_->init(lc3_encoder_config); + int ret = encoder_->init(config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 1); @@ -124,9 +111,8 @@ TEST_F(HfpLc3EncoderTest, InitWrongConfig) { } TEST_F(HfpLc3EncoderTest, InitSuccess) { - mmc::ConfigParam lc3_encoder_config; - ASSERT_TRUE( - TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); + mmc::ConfigParam config; + *config.mutable_hfp_lc3_encoder_param() = mmc::Lc3Param(); // lc3_setup_encoder returns encoder instance pointer. struct lc3_encoder lc3_encoder; @@ -135,7 +121,7 @@ TEST_F(HfpLc3EncoderTest, InitSuccess) { return &lc3_encoder; }; - int ret = encoder_->init(lc3_encoder_config); + int ret = encoder_->init(config); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 1); diff --git a/system/stack/pan/pan_api.cc b/system/stack/pan/pan_api.cc index 779ea7b3e7c7f37eb8e3c0b46129e1b83c5434c1..0e6aaaad6cea2d0ef1b88c657fad0d3cac971b03 100644 --- a/system/stack/pan/pan_api.cc +++ b/system/stack/pan/pan_api.cc @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -47,6 +48,7 @@ #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +using namespace bluetooth; using namespace bluetooth::legacy::stack::sdp; using bluetooth::Uuid; @@ -153,18 +155,18 @@ tPAN_RESULT PAN_SetRole(uint8_t role, std::string p_user_name, /* If the role is not a valid combination reject it */ if ((!(role & (PAN_ROLE_CLIENT | PAN_ROLE_NAP_SERVER))) && role != PAN_ROLE_INACTIVE) { - LOG_ERROR("PAN role %d is invalid", role); + log::error("PAN role {} is invalid", role); return PAN_FAILURE; } /* If the current active role is same as the role being set do nothing */ if (pan_cb.role == role) { - LOG_VERBOSE("PAN role already was set to: %d", role); + log::verbose("PAN role already was set to: {}", role); return PAN_SUCCESS; } /* Register all the roles with SDP */ - LOG_VERBOSE("PAN_SetRole() called with role 0x%x", role); + log::verbose("PAN_SetRole() called with role 0x{:x}", role); if (role & PAN_ROLE_NAP_SERVER) { /* Check the service name */ if (p_nap_name.empty()) @@ -222,7 +224,7 @@ tPAN_RESULT PAN_SetRole(uint8_t role, std::string p_user_name, } pan_cb.role = role; - LOG_VERBOSE("PAN role set to: %d", role); + log::verbose("PAN role set to: {}", role); BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Role change", base::StringPrintf("role:0x%x", role)); @@ -264,15 +266,15 @@ tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, tPAN_ROLE src_role, /* Check if PAN is active or not */ if (!(pan_cb.role & src_role)) { - LOG_ERROR("PAN is not active for the role %d", src_role); + log::error("PAN is not active for the role {}", src_role); return PAN_FAILURE; } /* Validate the parameters before proceeding */ if ((src_role != PAN_ROLE_CLIENT && src_role != PAN_ROLE_NAP_SERVER) || (dst_role != PAN_ROLE_CLIENT && dst_role != PAN_ROLE_NAP_SERVER)) { - LOG_ERROR("Either source %d or destination role %d is invalid", src_role, - dst_role); + log::error("Either source {} or destination role {} is invalid", src_role, + dst_role); return PAN_FAILURE; } @@ -288,7 +290,7 @@ tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, tPAN_ROLE src_role, ** because if there is already a connection we cannot accept ** another connection in PANU role */ - LOG_ERROR( + log::error( "Cannot make PANU connections when there are more than one " "connection"); return PAN_INVALID_SRC_ROLE; @@ -305,7 +307,7 @@ tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, tPAN_ROLE src_role, /* If destination is PANU role validate source role */ else if (dst_role == PAN_ROLE_CLIENT) { if (pan_cb.num_conns && pan_cb.active_role == PAN_ROLE_CLIENT && !pcb) { - LOG_ERROR("Device already have a connection in PANU role"); + log::error("Device already have a connection in PANU role"); return PAN_INVALID_SRC_ROLE; } @@ -315,19 +317,19 @@ tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, tPAN_ROLE src_role, } /* The role combination is not valid */ else { - LOG_ERROR("Source %d and Destination roles %d are not valid combination", - src_role, dst_role); + log::error("Source {} and Destination roles {} are not valid combination", + src_role, dst_role); return PAN_FAILURE; } /* Allocate control block and initiate connection */ if (!pcb) pcb = pan_allocate_pcb(rem_bda, BNEP_INVALID_HANDLE); if (!pcb) { - LOG_ERROR("PAN Connection failed because of no resources"); + log::error("PAN Connection failed because of no resources"); return PAN_NO_RESOURCES; } - VLOG(0) << __func__ << " for BD Addr: " << rem_bda; + log::verbose("for BD Addr: {}", ADDRESS_TO_LOGGABLE_STR(rem_bda)); if (pcb->con_state == PAN_STATE_IDLE) { pan_cb.num_conns++; } else if (pcb->con_state == PAN_STATE_CONNECTED) { @@ -351,7 +353,7 @@ tPAN_RESULT PAN_Connect(const RawAddress& rem_bda, tPAN_ROLE src_role, return (tPAN_RESULT)ret; } - LOG_VERBOSE("PAN_Connect() current active role set to %d", src_role); + log::verbose("PAN_Connect() current active role set to {}", src_role); pan_cb.prv_active_role = pan_cb.active_role; pan_cb.active_role = src_role; *handle = pcb->handle; @@ -379,7 +381,7 @@ tPAN_RESULT PAN_Disconnect(uint16_t handle) { /* Check if the connection exists */ pcb = pan_get_pcb_by_handle(handle); if (!pcb) { - LOG_ERROR("PAN connection not found for the handle %d", handle); + log::error("PAN connection not found for the handle {}", handle); return PAN_FAILURE; } @@ -394,11 +396,11 @@ tPAN_RESULT PAN_Disconnect(uint16_t handle) { pan_release_pcb(pcb); if (result != BNEP_SUCCESS) { - LOG_VERBOSE("Error in closing PAN connection"); + log::verbose("Error in closing PAN connection"); return PAN_FAILURE; } - LOG_VERBOSE("PAN connection closed"); + log::verbose("PAN connection closed"); return PAN_SUCCESS; } @@ -429,7 +431,7 @@ tPAN_RESULT PAN_Write(uint16_t handle, const RawAddress& dst, const RawAddress& src, uint16_t protocol, uint8_t* p_data, uint16_t len, bool ext) { if (pan_cb.role == PAN_ROLE_INACTIVE || !pan_cb.num_conns) { - LOG_ERROR("%s PAN is not active, data write failed.", __func__); + log::error("PAN is not active, data write failed."); return PAN_FAILURE; } @@ -441,7 +443,7 @@ tPAN_RESULT PAN_Write(uint16_t handle, const RawAddress& dst, int i; for (i = 0; i < MAX_PAN_CONNS; ++i) { if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED) - BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, ext); + BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); } return PAN_SUCCESS; } @@ -486,7 +488,7 @@ tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst, tBNEP_RESULT result; if (pan_cb.role == PAN_ROLE_INACTIVE || (!(pan_cb.num_conns))) { - LOG_ERROR("PAN is not active Data write failed"); + log::error("PAN is not active Data write failed"); osi_free(p_buf); return PAN_FAILURE; } @@ -496,7 +498,7 @@ tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst, uint8_t* data = (uint8_t*)p_buf + sizeof(BT_HDR) + p_buf->offset; for (i = 0; i < MAX_PAN_CONNS; ++i) { if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED) - BNEP_Write(pan_cb.pcb[i].handle, dst, data, p_buf->len, protocol, &src, + BNEP_Write(pan_cb.pcb[i].handle, dst, data, p_buf->len, protocol, src, ext); } osi_free(p_buf); @@ -513,51 +515,51 @@ tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst, } if (i == MAX_PAN_CONNS) { - LOG_ERROR("PAN Don't have any user connections"); + log::error("PAN Don't have any user connections"); osi_free(p_buf); return PAN_FAILURE; } result = - BNEP_WriteBuf(pan_cb.pcb[i].handle, dst, p_buf, protocol, &src, ext); + BNEP_WriteBuf(pan_cb.pcb[i].handle, dst, p_buf, protocol, src, ext); if (result == BNEP_IGNORE_CMD) { - LOG_VERBOSE("PAN ignored data write for PANU connection"); + log::verbose("PAN ignored data write for PANU connection"); return (tPAN_RESULT)result; } else if (result != BNEP_SUCCESS) { - LOG_ERROR("PAN failed to write data for the PANU connection"); + log::error("PAN failed to write data for the PANU connection"); return (tPAN_RESULT)result; } pan_cb.pcb[i].write.octets += p_buf->len; pan_cb.pcb[i].write.packets++; - LOG_VERBOSE("PAN successfully wrote data for the PANU connection"); + log::verbose("PAN successfully wrote data for the PANU connection"); return PAN_SUCCESS; } /* findout to which connection the data is meant for */ pcb = pan_get_pcb_by_handle(handle); if (!pcb) { - LOG_ERROR("PAN Buf write for wrong handle"); + log::error("PAN Buf write for wrong handle"); osi_free(p_buf); return PAN_FAILURE; } if (pcb->con_state != PAN_STATE_CONNECTED) { - LOG_ERROR("PAN Buf write when conn is not active"); + log::error("PAN Buf write when conn is not active"); pcb->write.drops++; osi_free(p_buf); return PAN_FAILURE; } uint16_t len = p_buf->len; - result = BNEP_WriteBuf(pcb->handle, dst, p_buf, protocol, &src, ext); + result = BNEP_WriteBuf(pcb->handle, dst, p_buf, protocol, src, ext); if (result == BNEP_IGNORE_CMD) { - LOG_VERBOSE("PAN ignored data buf write to PANU"); + log::verbose("PAN ignored data buf write to PANU"); pcb->write.errors++; return PAN_IGNORE_CMD; } else if (result != BNEP_SUCCESS) { - LOG_ERROR("PAN failed to send data buf to the PANU"); + log::error("PAN failed to send data buf to the PANU"); pcb->write.errors++; return (tPAN_RESULT)result; } @@ -565,7 +567,7 @@ tPAN_RESULT PAN_WriteBuf(uint16_t handle, const RawAddress& dst, pcb->write.octets += len; pcb->write.packets++; - LOG_VERBOSE("PAN successfully sent data buf to the PANU"); + log::verbose("PAN successfully sent data buf to the PANU"); return PAN_SUCCESS; } @@ -594,18 +596,18 @@ tPAN_RESULT PAN_SetProtocolFilters(uint16_t handle, uint16_t num_filters, /* Check if the connection exists */ pcb = pan_get_pcb_by_handle(handle); if (!pcb) { - LOG_ERROR("PAN connection not found for the handle %d", handle); + log::error("PAN connection not found for the handle {}", handle); return PAN_FAILURE; } tBNEP_RESULT result = BNEP_SetProtocolFilters(pcb->handle, num_filters, p_start_array, p_end_array); if (result != BNEP_SUCCESS) { - LOG_ERROR("PAN failed to set protocol filters for handle %d", handle); + log::error("PAN failed to set protocol filters for handle {}", handle); return (tPAN_RESULT)result; } - LOG_VERBOSE("PAN successfully sent protocol filters for handle %d", handle); + log::verbose("PAN successfully sent protocol filters for handle {}", handle); return PAN_SUCCESS; } @@ -633,18 +635,18 @@ tPAN_RESULT PAN_SetMulticastFilters(uint16_t handle, uint16_t num_mcast_filters, /* Check if the connection exists */ pcb = pan_get_pcb_by_handle(handle); if (!pcb) { - LOG_ERROR("PAN connection not found for the handle %d", handle); + log::error("PAN connection not found for the handle {}", handle); return PAN_FAILURE; } tBNEP_RESULT result = BNEP_SetMulticastFilters(pcb->handle, num_mcast_filters, p_start_array, p_end_array); if (result != BNEP_SUCCESS) { - LOG_ERROR("PAN failed to set multicast filters for handle %d", handle); + log::error("PAN failed to set multicast filters for handle {}", handle); return (tPAN_RESULT)result; } - LOG_VERBOSE("PAN successfully sent multicast filters for handle %d", handle); + log::verbose("PAN successfully sent multicast filters for handle {}", handle); return PAN_SUCCESS; } diff --git a/system/stack/pan/pan_int.h b/system/stack/pan/pan_int.h index bf0060d1bdde35c7481dabe11de2206bf401ee22..b73eae77c6395eab9a8e14160596699a8ff83428 100644 --- a/system/stack/pan/pan_int.h +++ b/system/stack/pan/pan_int.h @@ -25,6 +25,8 @@ #ifndef PAN_INT_H #define PAN_INT_H +#include + #include #include "internal_include/bt_target.h" @@ -134,4 +136,9 @@ void pan_dump_status(void); /******************************************************************************/ +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif diff --git a/system/stack/pan/pan_main.cc b/system/stack/pan/pan_main.cc index 293c1e7d18239855ff1812a84789be64a4097c22..28d1291ac3574f00116e757e8beb24c1c0f74a03 100644 --- a/system/stack/pan/pan_main.cc +++ b/system/stack/pan/pan_main.cc @@ -26,12 +26,13 @@ #define LOG_TAG "pan" #include +#include #include // memset #include +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/bnep_api.h" #include "stack/include/bt_hdr.h" @@ -40,6 +41,7 @@ #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +using namespace bluetooth; using bluetooth::Uuid; tPAN_CB pan_cb; @@ -101,13 +103,13 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, */ if (!remote_uuid.Is16Bit()) { - LOG_ERROR("PAN Connection failed because of wrong remote UUID "); + log::error("PAN Connection failed because of wrong remote UUID"); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID); return; } if (!local_uuid.Is16Bit()) { - LOG_ERROR("PAN Connection failed because of wrong local UUID "); + log::error("PAN Connection failed because of wrong local UUID"); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID); return; } @@ -115,17 +117,17 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, uint16_t remote_uuid16 = remote_uuid.As16Bit(); uint16_t local_uuid16 = local_uuid.As16Bit(); - LOG_VERBOSE( - "%s - handle %d, current role %d, dst uuid 0x%x, src uuid 0x%x, role " - "change %s", - __func__, handle, pan_cb.role, local_uuid16, remote_uuid16, + log::verbose( + "handle {}, current role {}, dst uuid 0x{:x}, src uuid 0x{:x}, role " + "change {}", + handle, pan_cb.role, local_uuid16, remote_uuid16, is_role_change ? "YES" : "NO"); /* Check if the source UUID is a valid one */ if (remote_uuid16 != UUID_SERVCLASS_PANU && remote_uuid16 != UUID_SERVCLASS_NAP && remote_uuid16 != UUID_SERVCLASS_GN) { - LOG_ERROR("Src UUID 0x%x is not valid", remote_uuid16); + log::error("Src UUID 0x{:x} is not valid", remote_uuid16); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID); return; } @@ -133,7 +135,7 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, /* Check if the destination UUID is a valid one */ if (local_uuid16 != UUID_SERVCLASS_PANU && local_uuid16 != UUID_SERVCLASS_NAP && local_uuid16 != UUID_SERVCLASS_GN) { - LOG_ERROR("Dst UUID 0x%x is not valid", local_uuid16); + log::error("Dst UUID 0x{:x} is not valid", local_uuid16); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID); return; } @@ -145,8 +147,8 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, local_uuid16 == UUID_SERVCLASS_GN) || ((!(pan_cb.role & UUID_SERVCLASS_NAP)) && local_uuid16 == UUID_SERVCLASS_NAP)) { - LOG_ERROR( - "PAN Connection failed because of unsupported destination UUID 0x%x", + log::error( + "PAN Connection failed because of unsupported destination UUID 0x{:x}", local_uuid16); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID); return; @@ -176,9 +178,9 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, is_valid_interaction = false; } if (!is_valid_interaction) { - LOG_ERROR( + log::error( "PAN Connection failed because of invalid PAN profile roles " - "interaction: Remote UUID 0x%x Local UUID 0x%x", + "interaction: Remote UUID 0x{:x} Local UUID 0x{:x}", remote_uuid16, local_uuid16); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_SRC_UUID); return; @@ -200,7 +202,7 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, /* There are connections other than this one ** so we cann't accept PANU role. Reject */ - LOG_ERROR( + log::error( "Dst UUID should be either GN or NAP only because there are other " "connections"); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID); @@ -209,8 +211,8 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, /* If it is already in connected state check for bridging status */ if (pcb->con_state == PAN_STATE_CONNECTED) { - LOG_VERBOSE("PAN Role changing New Src 0x%x Dst 0x%x", remote_uuid16, - local_uuid16); + log::verbose("PAN Role changing New Src 0x{:x} Dst 0x{:x}", remote_uuid16, + local_uuid16); pcb->prv_src_uuid = pcb->src_uuid; pcb->prv_dst_uuid = pcb->dst_uuid; @@ -235,22 +237,22 @@ void pan_conn_ind_cb(uint16_t handle, const RawAddress& p_bda, */ if (pan_cb.num_conns && (local_uuid16 == UUID_SERVCLASS_PANU || pan_cb.active_role == PAN_ROLE_CLIENT)) { - LOG_ERROR("PAN already have a connection and can't be user"); + log::error("PAN already have a connection and can't be user"); BNEP_ConnectResp(handle, BNEP_CONN_FAILED_DST_UUID); return; } } /* This is a new connection */ - LOG_VERBOSE("New connection indication for handle %d", handle); + log::verbose("New connection indication for handle {}", handle); pcb = pan_allocate_pcb(p_bda, handle); if (!pcb) { - LOG_ERROR("PAN no control block for new connection"); + log::error("PAN no control block for new connection"); BNEP_ConnectResp(handle, BNEP_CONN_FAILED); return; } - LOG_VERBOSE("PAN connection destination UUID is 0x%x", local_uuid16); + log::verbose("PAN connection destination UUID is 0x{:x}", local_uuid16); /* Set the latest active PAN role */ pan_cb.active_role = req_role; pcb->src_uuid = local_uuid16; @@ -287,11 +289,11 @@ void pan_connect_state_cb(uint16_t handle, tPAN_CONN* pcb; uint8_t peer_role; - LOG_VERBOSE("pan_connect_state_cb - for handle %d, result %d", handle, - result); + log::verbose("pan_connect_state_cb - for handle {}, result {}", handle, + result); pcb = pan_get_pcb_by_handle(handle); if (!pcb) { - LOG_ERROR("PAN State change indication for wrong handle %d", handle); + log::error("PAN State change indication for wrong handle {}", handle); return; } @@ -307,7 +309,7 @@ void pan_connect_state_cb(uint16_t handle, if (pcb->con_state != PAN_STATE_CONNECTED && (pcb->con_flags & PAN_FLAGS_CONN_COMPLETED)) { /* restore the original values */ - LOG_VERBOSE("restoring the connection state to active"); + log::verbose("restoring the connection state to active"); pcb->con_state = PAN_STATE_CONNECTED; pcb->con_flags &= (~PAN_FLAGS_CONN_COMPLETED); @@ -352,7 +354,7 @@ void pan_connect_state_cb(uint16_t handle, /* Create bridge if the destination role is NAP */ if (pan_cb.pan_bridge_req_cb && pcb->src_uuid == UUID_SERVCLASS_NAP) { - LOG_VERBOSE("PAN requesting for bridge"); + log::verbose("PAN requesting for bridge"); (*pan_cb.pan_bridge_req_cb)(pcb->rem_bda, true); } } @@ -389,14 +391,14 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src, /* Check if the connection is in right state */ pcb = pan_get_pcb_by_handle(handle); if (!pcb) { - LOG_ERROR("PAN Data buffer indication for wrong handle %d", handle); + log::error("PAN Data buffer indication for wrong handle {}", handle); osi_free(p_buf); return; } if (pcb->con_state != PAN_STATE_CONNECTED) { - LOG_ERROR("PAN Data indication in wrong state %d for handle %d", - pcb->con_state, handle); + log::error("PAN Data indication in wrong state {} for handle {}", + pcb->con_state, handle); pcb->read.drops++; osi_free(p_buf); return; @@ -408,8 +410,8 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src, pcb->read.octets += len; pcb->read.packets++; - LOG_VERBOSE( - "pan_data_buf_ind_cb - for handle %d, protocol 0x%x, length %d, ext %d", + log::verbose( + "pan_data_buf_ind_cb - for handle {}, protocol 0x{:x}, length {}, ext {}", handle, protocol, len, ext); if (pcb->src_uuid == UUID_SERVCLASS_NAP) @@ -420,13 +422,14 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src, /* Check if it is broadcast or multicast packet */ if (pcb->src_uuid != UUID_SERVCLASS_PANU) { if (dst.address[0] & 0x01) { - LOG_VERBOSE("PAN received broadcast packet on handle %d, src uuid 0x%x", - handle, pcb->src_uuid); + log::verbose( + "PAN received broadcast packet on handle {}, src uuid 0x{:x}", handle, + pcb->src_uuid); for (i = 0; i < MAX_PAN_CONNS; i++) { if (pan_cb.pcb[i].con_state == PAN_STATE_CONNECTED && pan_cb.pcb[i].handle != handle && pcb->src_uuid == pan_cb.pcb[i].src_uuid) { - BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, &src, + BNEP_Write(pan_cb.pcb[i].handle, dst, p_data, len, protocol, src, ext); } } @@ -445,15 +448,15 @@ void pan_data_buf_ind_cb(uint16_t handle, const RawAddress& src, /* Check if it is for any other PAN connection */ dst_pcb = pan_get_pcb_by_addr(dst); if (dst_pcb) { - LOG_VERBOSE( - "%s - destination PANU found on handle %d and sending data, len: %d", - __func__, dst_pcb->handle, len); + log::verbose( + "destination PANU found on handle {} and sending data, len: {}", + dst_pcb->handle, len); result = - BNEP_Write(dst_pcb->handle, dst, p_data, len, protocol, &src, ext); + BNEP_Write(dst_pcb->handle, dst, p_data, len, protocol, src, ext); if (result != BNEP_SUCCESS && result != BNEP_IGNORE_CMD) - LOG_ERROR("Failed to write data for PAN connection handle %d", - dst_pcb->handle); + log::error("Failed to write data for PAN connection handle {}", + dst_pcb->handle); pcb->read.errors++; osi_free(p_buf); return; @@ -515,9 +518,9 @@ void pan_tx_data_flow_cb(uint16_t handle, tBNEP_RESULT result) { void pan_proto_filt_ind_cb(uint16_t handle, bool indication, tBNEP_RESULT result, uint16_t num_filters, uint8_t* p_filters) { - LOG_VERBOSE( - "pan_proto_filt_ind_cb - called for handle %d with ind %d, result %d, " - "num %d", + log::verbose( + "pan_proto_filt_ind_cb - called for handle {} with ind {}, result {}, " + "num {}", handle, indication, result, num_filters); if (pan_cb.pan_pfilt_ind_cb) @@ -549,9 +552,9 @@ void pan_proto_filt_ind_cb(uint16_t handle, bool indication, void pan_mcast_filt_ind_cb(uint16_t handle, bool indication, tBNEP_RESULT result, uint16_t num_filters, uint8_t* p_filters) { - LOG_VERBOSE( - "pan_mcast_filt_ind_cb - called for handle %d with ind %d, result %d, " - "num %d", + log::verbose( + "pan_mcast_filt_ind_cb - called for handle {} with ind {}, result {}, " + "num {}", handle, indication, result, num_filters); if (pan_cb.pan_mfilt_ind_cb) diff --git a/system/stack/pan/pan_utils.cc b/system/stack/pan/pan_utils.cc index e33f1e38d9914fe7fb6786d898cd4cef73d9ef29..6156d1659eb0d32f4273f080990b144293b74714 100644 --- a/system/stack/pan/pan_utils.cc +++ b/system/stack/pan/pan_utils.cc @@ -26,6 +26,7 @@ #define LOG_TAG "pan" #include +#include #include @@ -38,6 +39,7 @@ #include "stack/pan/pan_int.h" #include "types/raw_address.h" +using namespace bluetooth; using namespace bluetooth::legacy::stack::sdp; static const uint8_t pan_proto_elem_data[] = { @@ -76,7 +78,7 @@ uint32_t pan_register_with_sdp(uint16_t uuid, const char* p_name, sdp_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); if (sdp_handle == 0) { - LOG_ERROR("PAN_SetRole - could not create SDP record"); + log::error("PAN_SetRole - could not create SDP record"); return 0; } @@ -279,13 +281,13 @@ void pan_dump_status(void) { uint16_t i; tPAN_CONN* p_pcb; - LOG_VERBOSE("PAN role %x, active role %d, num_conns %d", pan_cb.role, - pan_cb.active_role, pan_cb.num_conns); + log::verbose("PAN role {:x}, active role {}, num_conns {}", pan_cb.role, + pan_cb.active_role, pan_cb.num_conns); for (i = 0, p_pcb = pan_cb.pcb; i < MAX_PAN_CONNS; i++, p_pcb++) { - VLOG(1) << +i << " state:" << p_pcb->con_state - << ", handle:" << p_pcb->handle << ", src" << p_pcb->src_uuid - << ", BD:" << p_pcb->rem_bda; + log::verbose("{} state:{}, handle:{}, src{}, BD:{}", i, p_pcb->con_state, + p_pcb->handle, p_pcb->src_uuid, + ADDRESS_TO_LOGGABLE_STR(p_pcb->rem_bda)); } #endif } diff --git a/system/stack/rfcomm/port_api.cc b/system/stack/rfcomm/port_api.cc index a481c18602b072b8435c9c0a3462ec102b7accef..daf9b89721df66f5adab1b95c1fd87618533c373 100644 --- a/system/stack/rfcomm/port_api.cc +++ b/system/stack/rfcomm/port_api.cc @@ -27,10 +27,12 @@ #include "stack/include/port_api.h" #include +#include #include #include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/mutex.h" @@ -40,8 +42,7 @@ #include "stack/rfcomm/rfc_int.h" #include "types/raw_address.h" -#define error(fmt, ...) \ - LOG_ERROR("## ERROR : %s: " fmt "##", __func__, ##__VA_ARGS__) +using namespace bluetooth; /* Mapping from PORT_* result codes to human readable strings. */ static const char* result_code_strings[] = {"Success", @@ -112,11 +113,9 @@ int RFCOMM_CreateConnectionWithSecurity(uint16_t uuid, uint8_t scn, if ((scn == 0) || (scn > RFCOMM_MAX_SCN)) { // Server Channel Number (SCN) should be in range [1, 30] - LOG(ERROR) << __func__ << ": Invalid SCN, bd_addr=" << bd_addr - << ", scn=" << static_cast(scn) - << ", is_server=" << is_server - << ", mtu=" << static_cast(mtu) - << ", uuid=" << loghex(uuid); + log::error("Invalid SCN, bd_addr={}, scn={}, is_server={}, mtu={}, uuid={}", + ADDRESS_TO_LOGGABLE_STR(bd_addr), static_cast(scn), + is_server, static_cast(mtu), loghex(uuid)); return (PORT_INVALID_SCN); } @@ -138,16 +137,15 @@ int RFCOMM_CreateConnectionWithSecurity(uint16_t uuid, uint8_t scn, if (p_port != nullptr) { // if existing port is also a client port, error out if (!p_port->is_server) { - LOG(ERROR) << __func__ << ": already at opened state " - << static_cast(p_port->state) - << ", RFC_state=" << static_cast(p_port->rfc.state) - << ", MCB_state=" - << (p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0) - << ", bd_addr=" << bd_addr << ", scn=" << std::to_string(scn) - << ", is_server=" << is_server << ", mtu=" << mtu - << ", uuid=" << loghex(uuid) << ", dlci=" << +dlci - << ", p_mcb=" << p_mcb - << ", port=" << std::to_string(p_port->handle); + log::error( + "already at opened state {}, RFC_state={}, MCB_state={}, " + "bd_addr={}, scn={}, is_server={}, mtu={}, uuid={}, dlci={}, " + "p_mcb={}, port={}", + static_cast(p_port->state), + static_cast(p_port->rfc.state), + (p_port->rfc.p_mcb ? p_port->rfc.p_mcb->state : 0), + ADDRESS_TO_LOGGABLE_STR(bd_addr), scn, is_server, mtu, loghex(uuid), + dlci, fmt::ptr(p_mcb), p_port->handle); *p_handle = p_port->handle; return (PORT_ALREADY_OPENED); } @@ -157,10 +155,11 @@ int RFCOMM_CreateConnectionWithSecurity(uint16_t uuid, uint8_t scn, // On the server side, always allocate a new port. p_port = port_allocate_port(dlci, bd_addr); if (p_port == nullptr) { - LOG(ERROR) << __func__ << ": no resources, bd_addr=" << bd_addr - << ", scn=" << std::to_string(scn) << ", is_server=" << is_server - << ", mtu=" << mtu << ", uuid=" << loghex(uuid) - << ", dlci=" << +dlci; + log::error( + "no resources, bd_addr={}, scn={}, is_server={}, mtu={}, uuid={}, " + "dlci={}", + ADDRESS_TO_LOGGABLE_STR(bd_addr), scn, is_server, mtu, loghex(uuid), + dlci); return PORT_NO_RESOURCES; } p_port->sec_mask = sec_mask; @@ -218,12 +217,11 @@ int RFCOMM_CreateConnectionWithSecurity(uint16_t uuid, uint8_t scn, p_port->p_mgmt_callback = p_mgmt_cb; p_port->bd_addr = bd_addr; - LOG(INFO) << __func__ << ": bd_addr=" << bd_addr - << ", scn=" << std::to_string(scn) << ", is_server=" << is_server - << ", mtu=" << mtu << ", uuid=" << loghex(uuid) - << ", dlci=" << std::to_string(dlci) - << ", signal_state=" << loghex(p_port->default_signal_state) - << ", p_port=" << p_port; + log::info( + "bd_addr={}, scn={}, is_server={}, mtu={}, uuid={}, dlci={}, " + "signal_state={}, p_port={}", + ADDRESS_TO_LOGGABLE_STR(bd_addr), scn, is_server, mtu, loghex(uuid), dlci, + loghex(p_port->default_signal_state), fmt::ptr(p_port)); // If this is not initiator of the connection need to just wait if (p_port->is_server) { @@ -287,17 +285,17 @@ int RFCOMM_ControlReqFromBTSOCK(uint8_t dlci, const RawAddress& bd_addr, int RFCOMM_RemoveConnection(uint16_t handle) { tPORT* p_port; - LOG_VERBOSE("RFCOMM_RemoveConnection() handle:%d", handle); + log::verbose("RFCOMM_RemoveConnection() handle:{}", handle); /* Check if handle is valid to avoid crashing */ if ((handle == 0) || (handle > MAX_RFC_PORTS)) { - LOG_ERROR("RFCOMM_RemoveConnection() BAD handle:%d", handle); + log::error("RFCOMM_RemoveConnection() BAD handle:{}", handle); return (PORT_BAD_HANDLE); } p_port = &rfc_cb.port.port[handle - 1]; if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) { - LOG_VERBOSE("RFCOMM_RemoveConnection() Not opened:%d", handle); + log::verbose("RFCOMM_RemoveConnection() Not opened:{}", handle); return (PORT_SUCCESS); } @@ -320,7 +318,7 @@ int RFCOMM_RemoveConnection(uint16_t handle) { int RFCOMM_RemoveServer(uint16_t handle) { /* Check if handle is valid to avoid crashing */ if ((handle == 0) || (handle > MAX_RFC_PORTS)) { - LOG(ERROR) << __func__ << ": bad handle " << handle; + log::error("bad handle {}", handle); return (PORT_BAD_HANDLE); } tPORT* p_port = &rfc_cb.port.port[handle - 1]; @@ -329,10 +327,10 @@ int RFCOMM_RemoveServer(uint16_t handle) { p_port->p_mgmt_callback = nullptr; if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) { - VLOG(1) << __func__ << ": handle " << handle << " not opened"; + log::debug("handle {} not opened", handle); return (PORT_SUCCESS); } - LOG(INFO) << __func__ << ": handle=" << handle; + log::info("handle={}", handle); /* this port will be deallocated after closing */ p_port->keep_port_handle = false; @@ -372,7 +370,7 @@ int PORT_SetEventCallback(uint16_t port_handle, tPORT_CALLBACK* p_port_cb) { return (PORT_NOT_OPENED); } - LOG_VERBOSE("PORT_SetEventCallback() handle:%d", port_handle); + log::verbose("PORT_SetEventCallback() handle:{}", port_handle); p_port->p_callback = p_port_cb; @@ -418,8 +416,8 @@ int PORT_SetDataCOCallback(uint16_t port_handle, tPORT_DATA_CO_CALLBACK* p_port_cb) { tPORT* p_port; - LOG_VERBOSE("PORT_SetDataCOCallback() handle:%d cb 0x%p", port_handle, - p_port_cb); + log::verbose("PORT_SetDataCOCallback() handle:{} cb 0x{}", port_handle, + fmt::ptr(p_port_cb)); /* Check if handle is valid to avoid crashing */ if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) { @@ -450,7 +448,7 @@ int PORT_SetDataCOCallback(uint16_t port_handle, int PORT_SetEventMask(uint16_t port_handle, uint32_t mask) { tPORT* p_port; - LOG_VERBOSE("PORT_SetEventMask() handle:%d mask:0x%x", port_handle, mask); + log::verbose("PORT_SetEventMask() handle:{} mask:0x{:x}", port_handle, mask); /* Check if handle is valid to avoid crashing */ if ((port_handle == 0) || (port_handle > MAX_RFC_PORTS)) { @@ -487,10 +485,10 @@ int PORT_CheckConnection(uint16_t handle, RawAddress* bd_addr, return (PORT_BAD_HANDLE); } tPORT* p_port = &rfc_cb.port.port[handle - 1]; - LOG_VERBOSE( - "%s: handle=%d, in_use=%d, port_state=%d, p_mcb=%p, peer_ready=%d, " - "rfc_state=%d", - __func__, handle, p_port->in_use, p_port->state, p_port->rfc.p_mcb, + log::verbose( + "handle={}, in_use={}, port_state={}, p_mcb={}, peer_ready={}, " + "rfc_state={}", + handle, p_port->in_use, p_port->state, fmt::ptr(p_port->rfc.p_mcb), (p_port->rfc.p_mcb ? p_port->rfc.p_mcb->peer_ready : -1), p_port->rfc.state); @@ -526,7 +524,7 @@ bool PORT_IsOpening(RawAddress* bd_addr) { if ((multiplexer_cb.state > RFC_MX_STATE_IDLE) && (multiplexer_cb.state < RFC_MX_STATE_CONNECTED)) { *bd_addr = multiplexer_cb.bd_addr; - LOG_INFO( + log::info( "Found a rfc_mcb in the middle of opening a port, returning true"); return true; } @@ -543,20 +541,20 @@ bool PORT_IsOpening(RawAddress* bd_addr) { } } - LOG_INFO("RFC_MX_STATE_CONNECTED, found_port=%d, tRFC_PORT_STATE=%d", - found_port, p_port != nullptr ? p_port->rfc.state : 0); + log::info("RFC_MX_STATE_CONNECTED, found_port={}, tRFC_PORT_STATE={}", + found_port, p_port != nullptr ? p_port->rfc.state : 0); if ((!found_port) || (found_port && (p_port->rfc.state < RFC_STATE_OPENED))) { /* Port is not established yet. */ *bd_addr = multiplexer_cb.bd_addr; - LOG_INFO( + log::info( "In RFC_MX_STATE_CONNECTED but port is not established yet, " "returning true"); return true; } } } - LOG_INFO("false"); + log::info("false"); return false; } @@ -577,7 +575,7 @@ int PORT_SetState(uint16_t handle, tPORT_STATE* p_settings) { tPORT* p_port; uint8_t baud_rate; - LOG_VERBOSE("PORT_SetState() handle:%d", handle); + log::verbose("PORT_SetState() handle:{}", handle); /* Check if handle is valid to avoid crashing */ if ((handle == 0) || (handle > MAX_RFC_PORTS)) { @@ -594,8 +592,8 @@ int PORT_SetState(uint16_t handle, tPORT_STATE* p_settings) { return (PORT_LINE_ERR); } - LOG_VERBOSE("PORT_SetState() handle:%d FC_TYPE:0x%x", handle, - p_settings->fc_type); + log::verbose("PORT_SetState() handle:{} FC_TYPE:0x{:x}", handle, + p_settings->fc_type); baud_rate = p_port->user_port_pars.baud_rate; p_port->user_port_pars = *p_settings; @@ -622,7 +620,7 @@ int PORT_SetState(uint16_t handle, tPORT_STATE* p_settings) { int PORT_GetState(uint16_t handle, tPORT_STATE* p_settings) { tPORT* p_port; - LOG_VERBOSE("PORT_GetState() handle:%d", handle); + log::verbose("PORT_GetState() handle:{}", handle); /* Check if handle is valid to avoid crashing */ if ((handle == 0) || (handle > MAX_RFC_PORTS)) { @@ -662,7 +660,7 @@ int PORT_FlowControl_MaxCredit(uint16_t handle, bool enable) { bool old_fc; uint32_t events; - LOG_VERBOSE("PORT_FlowControl() handle:%d enable: %d", handle, enable); + log::verbose("PORT_FlowControl() handle:{} enable: {}", handle, enable); /* Check if handle is valid to avoid crashing */ if ((handle == 0) || (handle > MAX_RFC_PORTS)) { @@ -730,7 +728,7 @@ int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len, BT_HDR* p_buf; uint16_t count; - LOG_VERBOSE("PORT_ReadData() handle:%d max_len:%d", handle, max_len); + log::verbose("PORT_ReadData() handle:{} max_len:{}", handle, max_len); /* Initialize this in case of an error */ *p_len = 0; @@ -747,7 +745,7 @@ int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len, } if (p_port->state == PORT_CONNECTION_STATE_OPENING) { - LOG_WARN("Trying to read a port in PORT_CONNECTION_STATE_OPENING state"); + log::warn("Trying to read a port in PORT_CONNECTION_STATE_OPENING state"); } if (p_port->line_status) { @@ -755,7 +753,7 @@ int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len, } if (fixed_queue_is_empty(p_port->rx.queue)) { - LOG_WARN("Read on empty input queue"); + log::warn("Read on empty input queue"); return (PORT_SUCCESS); } @@ -802,11 +800,11 @@ int PORT_ReadData(uint16_t handle, char* p_data, uint16_t max_len, } if (*p_len == 1) { - LOG_VERBOSE("PORT_ReadData queue:%d returned:%d %x", p_port->rx.queue_size, - *p_len, (p_data[0])); + log::verbose("PORT_ReadData queue:{} returned:{} {:x}", + p_port->rx.queue_size, *p_len, (p_data[0])); } else { - LOG_VERBOSE("PORT_ReadData queue:%d returned:%d", p_port->rx.queue_size, - *p_len); + log::verbose("PORT_ReadData queue:{} returned:{}", p_port->rx.queue_size, + *p_len); } /* If rfcomm suspended traffic from the peer based on the rx_queue_size */ @@ -845,7 +843,7 @@ static int port_write(tPORT* p_port, BT_HDR* p_buf) { (PORT_CTRL_REQ_SENT | PORT_CTRL_IND_RECEIVED))) { if ((p_port->tx.queue_size > PORT_TX_CRITICAL_WM) || (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_CRITICAL_WM)) { - LOG_WARN("PORT_Write: Queue size: %d", p_port->tx.queue_size); + log::warn("PORT_Write: Queue size: {}", p_port->tx.queue_size); osi_free(p_buf); @@ -855,9 +853,9 @@ static int port_write(tPORT* p_port, BT_HDR* p_buf) { return (PORT_TX_FULL); } - LOG_VERBOSE( - "PORT_Write : Data is enqued. flow disabled %d peer_ready %d state %d " - "ctrl_state %x", + log::verbose( + "PORT_Write : Data is enqued. flow disabled {} peer_ready {} state {} " + "ctrl_state {:x}", p_port->tx.peer_fc, (p_port->rfc.p_mcb && p_port->rfc.p_mcb->peer_ready), p_port->rfc.state, p_port->port_ctrl); @@ -867,7 +865,7 @@ static int port_write(tPORT* p_port, BT_HDR* p_buf) { return (PORT_CMD_PENDING); } else { - LOG_VERBOSE("PORT_Write : Data is being sent"); + log::verbose("PORT_Write : Data is being sent"); RFCOMM_DataReq(p_port->rfc.p_mcb, p_port->dlci, p_buf); return (PORT_SUCCESS); @@ -893,7 +891,7 @@ int PORT_WriteDataCO(uint16_t handle, int* p_len) { int rc = 0; uint16_t length; - LOG_VERBOSE("PORT_WriteDataCO() handle:%d", handle); + log::verbose("PORT_WriteDataCO() handle:{}", handle); *p_len = 0; /* Check if handle is valid to avoid crashing */ @@ -903,12 +901,12 @@ int PORT_WriteDataCO(uint16_t handle, int* p_len) { p_port = &rfc_cb.port.port[handle - 1]; if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) { - LOG_WARN("PORT_WriteDataByFd() no port state:%d", p_port->state); + log::warn("PORT_WriteDataByFd() no port state:{}", p_port->state); return (PORT_NOT_OPENED); } if (!p_port->peer_mtu) { - LOG_ERROR("PORT_WriteDataByFd() peer_mtu:%d", p_port->peer_mtu); + log::error("PORT_WriteDataByFd() peer_mtu:{}", p_port->peer_mtu); return (PORT_UNKNOWN_ERROR); } int available = 0; @@ -916,9 +914,9 @@ int PORT_WriteDataCO(uint16_t handle, int* p_len) { if (!p_port->p_data_co_callback(handle, (uint8_t*)&available, sizeof(available), DATA_CO_CALLBACK_TYPE_OUTGOING_SIZE)) { - LOG_ERROR( + log::error( "p_data_co_callback DATA_CO_CALLBACK_TYPE_INCOMING_SIZE failed, " - "available:%d", + "available:{}", available); return (PORT_UNKNOWN_ERROR); } @@ -943,9 +941,9 @@ int PORT_WriteDataCO(uint16_t handle, int* p_len) { available, DATA_CO_CALLBACK_TYPE_OUTGOING)) { - error( + log::error( "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, " - "available:%d", + "available:{}", available); mutex_global_unlock(); return (PORT_UNKNOWN_ERROR); @@ -974,8 +972,8 @@ int PORT_WriteDataCO(uint16_t handle, int* p_len) { (fixed_queue_length(p_port->tx.queue) > PORT_TX_BUF_HIGH_WM)) { port_flow_control_user(p_port); event |= PORT_EV_FC; - LOG_VERBOSE( - "tx queue is full,tx.queue_size:%d,tx.queue.count:%zu,available:%d", + log::verbose( + "tx queue is full,tx.queue_size:{},tx.queue.count:{},available:{}", p_port->tx.queue_size, fixed_queue_length(p_port->tx.queue), available); break; @@ -997,13 +995,13 @@ int PORT_WriteDataCO(uint16_t handle, int* p_len) { if (!p_port->p_data_co_callback(handle, (uint8_t*)(p_buf + 1) + p_buf->offset, length, DATA_CO_CALLBACK_TYPE_OUTGOING)) { - error( - "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:%d", + log::error( + "p_data_co_callback DATA_CO_CALLBACK_TYPE_OUTGOING failed, length:{}", length); return (PORT_UNKNOWN_ERROR); } - LOG_VERBOSE("PORT_WriteData %d bytes", length); + log::verbose("PORT_WriteData {} bytes", length); rc = port_write(p_port, p_buf); @@ -1050,7 +1048,7 @@ int PORT_WriteData(uint16_t handle, const char* p_data, uint16_t max_len, int rc = 0; uint16_t length; - LOG_VERBOSE("PORT_WriteData() max_len:%d", max_len); + log::verbose("PORT_WriteData() max_len:{}", max_len); *p_len = 0; @@ -1061,16 +1059,16 @@ int PORT_WriteData(uint16_t handle, const char* p_data, uint16_t max_len, p_port = &rfc_cb.port.port[handle - 1]; if (!p_port->in_use || (p_port->state == PORT_CONNECTION_STATE_CLOSED)) { - LOG_WARN("PORT_WriteData() no port state:%d", p_port->state); + log::warn("PORT_WriteData() no port state:{}", p_port->state); return (PORT_NOT_OPENED); } if (p_port->state == PORT_CONNECTION_STATE_OPENING) { - LOG_WARN("Write data received but port is in OPENING state"); + log::warn("Write data received but port is in OPENING state"); } if (!max_len || !p_port->peer_mtu) { - LOG_ERROR("PORT_WriteData() peer_mtu:%d", p_port->peer_mtu); + log::error("PORT_WriteData() peer_mtu:{}", p_port->peer_mtu); return (PORT_UNKNOWN_ERROR); } @@ -1117,7 +1115,7 @@ int PORT_WriteData(uint16_t handle, const char* p_data, uint16_t max_len, memcpy((uint8_t*)(p_buf + 1) + p_buf->offset, p_data, length); - LOG_VERBOSE("PORT_WriteData %d bytes", length); + log::verbose("PORT_WriteData {} bytes", length); rc = port_write(p_port, p_buf); diff --git a/system/stack/rfcomm/port_rfc.cc b/system/stack/rfcomm/port_rfc.cc index 793c7b325514d3964913d1dcfe0d589a71ec47e0..973740bf79f2deb80b0682720084e3ae088a78ae 100644 --- a/system/stack/rfcomm/port_rfc.cc +++ b/system/stack/rfcomm/port_rfc.cc @@ -27,12 +27,13 @@ #include #include +#include #include #include #include -#include "gd/hal/snoop_logger.h" +#include "hal/snoop_logger.h" #include "internal_include/bt_target.h" #include "internal_include/bt_trace.h" #include "main/shim/entry.h" @@ -47,6 +48,8 @@ #include "stack/rfcomm/port_int.h" #include "stack/rfcomm/rfc_int.h" +using namespace bluetooth; + /* * Local function definitions */ @@ -65,12 +68,12 @@ void port_get_credits(tPORT* p_port, uint8_t k); * ******************************************************************************/ int port_open_continue(tPORT* p_port) { - LOG_VERBOSE("port_open_continue, p_port:%p", p_port); + log::verbose("port_open_continue, p_port:{}", fmt::ptr(p_port)); /* Check if multiplexer channel has already been established */ tRFC_MCB* p_mcb = rfc_alloc_multiplexer_channel(p_port->bd_addr, true); if (p_mcb == nullptr) { - LOG_WARN("port_open_continue no mx channel"); + log::warn("port_open_continue no mx channel"); port_release_port(p_port); return (PORT_NO_RESOURCES); } @@ -93,8 +96,8 @@ int port_open_continue(tPORT* p_port) { } else { // MX state machine ignores RFC_MX_EVENT_START_REQ in these states // When it enters RFC_MX_STATE_CONNECTED, it will check any openning ports - LOG_VERBOSE("port_open_continue: mx state(%d) mx channel is opening", - p_mcb->state); + log::verbose("port_open_continue: mx state({}) mx channel is opening", + p_mcb->state); } return (PORT_SUCCESS); } @@ -193,7 +196,7 @@ void port_start_close(tPORT* p_port) { void PORT_StartCnf(tRFC_MCB* p_mcb, uint16_t result) { bool no_ports_up = true; - LOG_VERBOSE("%s: result %d", __func__, result); + log::verbose("result {}", result); tPORT* p_port = &rfc_cb.port.port[0]; for (int i = 0; i < MAX_RFC_PORTS; i++, p_port++) { @@ -201,10 +204,10 @@ void PORT_StartCnf(tRFC_MCB* p_mcb, uint16_t result) { no_ports_up = false; if (result == RFCOMM_SUCCESS) { - LOG_VERBOSE("%s: dlci %d", __func__, p_port->dlci); + log::verbose("dlci {}", p_port->dlci); RFCOMM_ParameterNegotiationRequest(p_mcb, p_port->dlci, p_port->mtu); } else { - LOG_WARN("%s: failed result:%d", __func__, result); + log::warn("failed result:{}", result); /* Warning: result is also set to 4 when l2cap connection fails due to l2cap connect cnf (no_resources) */ @@ -253,13 +256,13 @@ void PORT_StartInd(tRFC_MCB* p_mcb) { tPORT* p_port; int i; - LOG_VERBOSE("PORT_StartInd"); + log::verbose("PORT_StartInd"); p_port = &rfc_cb.port.port[0]; for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) { if ((p_port->rfc.p_mcb == NULL) || (p_port->rfc.p_mcb == p_mcb)) { - LOG_VERBOSE("PORT_StartInd, RFCOMM_StartRsp RFCOMM_SUCCESS: p_mcb:%p", - p_mcb); + log::verbose("PORT_StartInd, RFCOMM_StartRsp RFCOMM_SUCCESS: p_mcb:{}", + fmt::ptr(p_mcb)); RFCOMM_StartRsp(p_mcb, RFCOMM_SUCCESS); return; } @@ -279,16 +282,16 @@ void PORT_StartInd(tRFC_MCB* p_mcb) { ******************************************************************************/ void PORT_ParNegInd(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl, uint8_t k) { - LOG_VERBOSE("%s: bd_addr=%s, dlci=%d, mtu=%d", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr), dlci, mtu); + log::verbose("bd_addr={}, dlci={}, mtu={}", + ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr), dlci, mtu); tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (!p_port) { /* This can be a first request for this port */ p_port = port_find_dlci_port(dlci); if (!p_port) { - LOG(ERROR) << __func__ << ": Disconnect RFCOMM, port not found, dlci=" - << std::to_string(dlci) << ", p_mcb=" << p_mcb - << ", bd_addr=" << p_mcb->bd_addr; + log::error( + "Disconnect RFCOMM, port not found, dlci={}, p_mcb={}, bd_addr={}", + dlci, fmt::ptr(p_mcb), ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); /* If the port cannot be opened, send a DM. Per Errata 1205 */ rfc_send_dm(p_mcb, dlci, false); /* check if this is the last port open, some headsets have @@ -296,8 +299,8 @@ void PORT_ParNegInd(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl, rfc_check_mcb_active(p_mcb); return; } - LOG_VERBOSE("%s: port_handles[dlci:%d]:%d->%d", __func__, dlci, - p_mcb->port_handles[dlci], p_port->handle); + log::verbose("port_handles[dlci:{}]:{}->{}", dlci, + p_mcb->port_handles[dlci], p_port->handle); p_mcb->port_handles[dlci] = p_port->handle; } @@ -368,10 +371,10 @@ void PORT_ParNegInd(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl, ******************************************************************************/ void PORT_ParNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl, uint8_t k) { - LOG_VERBOSE("PORT_ParNegCnf dlci:%d mtu:%d cl: %d k: %d", dlci, mtu, cl, k); + log::verbose("PORT_ParNegCnf dlci:{} mtu:{} cl: {} k: {}", dlci, mtu, cl, k); tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (!p_port) { - LOG(WARNING) << __func__ << ": port is null for " << p_mcb->bd_addr; + log::warn("port is null for {}", ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); return; } @@ -382,7 +385,7 @@ void PORT_ParNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl, /* This is illegal-- negotiation fails. */ if ((PORT_FC_DEFAULT == PORT_FC_TS710) && (cl == RFCOMM_PN_CONV_LAYER_CBFC_R)) { - LOG_WARN("%s, negotiation fails, index=%d", __func__, p_port->handle); + log::warn("negotiation fails, index={}", p_port->handle); rfc_send_disc(p_mcb, p_port->dlci); rfc_port_closed(p_port); return; @@ -427,10 +430,9 @@ void PORT_ParNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint8_t cl, void PORT_DlcEstablishInd(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); - LOG_VERBOSE("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", - p_mcb, dlci, mtu, p_port); - VLOG(1) << __func__ - << " p_mcb addr:" << ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr); + log::verbose("p_mcb:{}, dlci:{} mtu:{}i, p_port:{}, bd_addr:{}", + fmt::ptr(p_mcb), dlci, mtu, fmt::ptr(p_port), + ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr)); if (!p_port) { /* This can be a first request for this port */ @@ -479,8 +481,8 @@ void PORT_DlcEstablishCnf(tRFC_MCB* p_mcb, uint8_t dlci, uint16_t mtu, uint16_t result) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); - LOG_VERBOSE("PORT_DlcEstablishCnf dlci:%d mtu:%d result:%d", dlci, mtu, - result); + log::verbose("PORT_DlcEstablishCnf dlci:{} mtu:{} result:{}", dlci, mtu, + result); if (!p_port) return; @@ -535,7 +537,7 @@ void PORT_PortNegInd(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_STATE* p_pars, uint16_t param_mask) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); - LOG_VERBOSE("PORT_PortNegInd"); + log::verbose("PORT_PortNegInd"); if (!p_port) { /* This can be a first request for this port */ @@ -564,10 +566,10 @@ void PORT_PortNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, UNUSED_ATTR tPORT_STATE* p_pars, uint16_t result) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); - LOG_VERBOSE("PORT_PortNegCnf"); + log::verbose("PORT_PortNegCnf"); if (!p_port) { - LOG_WARN("PORT_PortNegCnf no port"); + log::warn("PORT_PortNegCnf no port"); return; } /* Port negotiation failed. Drop the connection */ @@ -585,7 +587,7 @@ void PORT_PortNegCnf(tRFC_MCB* p_mcb, uint8_t dlci, if (!(p_port->port_ctrl & PORT_CTRL_REQ_SENT)) { RFCOMM_ControlReq(p_port->rfc.p_mcb, p_port->dlci, &p_port->local_ctrl); } else { - LOG_WARN("PORT_PortNegCnf Control Already sent"); + log::warn("PORT_PortNegCnf Control Already sent"); } } @@ -602,7 +604,7 @@ void PORT_ControlInd(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* p_pars) { uint32_t event; uint8_t old_signals; - LOG_VERBOSE("PORT_ControlInd"); + log::verbose("PORT_ControlInd"); if (!p_port) return; @@ -633,11 +635,11 @@ void PORT_ControlInd(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* p_pars) { */ if (event && p_port->p_callback) (p_port->p_callback)(event, p_port->handle); - LOG_VERBOSE("PORT_ControlInd DTR_DSR : %d, RTS_CTS : %d, RI : %d, DCD : %d", - ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0), - ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0), - ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0), - ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0)); + log::verbose("PORT_ControlInd DTR_DSR : {}, RTS_CTS : {}, RI : {}, DCD : {}", + ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DTRDSR) ? 1 : 0), + ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RTSCTS) ? 1 : 0), + ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_RI) ? 1 : 0), + ((p_port->peer_ctrl.modem_signal & MODEM_SIGNAL_DCD) ? 1 : 0)); } /******************************************************************************* @@ -653,7 +655,7 @@ void PORT_ControlCnf(tRFC_MCB* p_mcb, uint8_t dlci, tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); uint32_t event = 0; - LOG_VERBOSE("PORT_ControlCnf"); + log::verbose("PORT_ControlCnf"); if (!p_port) return; @@ -685,7 +687,7 @@ void PORT_LineStatusInd(tRFC_MCB* p_mcb, uint8_t dlci, uint8_t line_status) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); uint32_t event = 0; - LOG_VERBOSE("PORT_LineStatusInd"); + log::verbose("PORT_LineStatusInd"); if (!p_port) return; @@ -710,8 +712,8 @@ void PORT_LineStatusInd(tRFC_MCB* p_mcb, uint8_t dlci, uint8_t line_status) { * ******************************************************************************/ void PORT_DlcReleaseInd(tRFC_MCB* p_mcb, uint8_t dlci) { - VLOG(1) << __func__ << ": dlci=" << std::to_string(dlci) - << ", bd_addr=" << p_mcb->bd_addr; + log::verbose("dlci:{}, bd_addr:{}", dlci, + ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr)); tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (!p_port) return; port_rfc_closed(p_port, PORT_CLOSED); @@ -731,7 +733,7 @@ void PORT_CloseInd(tRFC_MCB* p_mcb) { tPORT* p_port; int i; - LOG_VERBOSE("PORT_CloseInd"); + log::verbose("PORT_CloseInd"); p_port = &rfc_cb.port.port[0]; for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) { @@ -757,7 +759,7 @@ void PORT_TimeOutCloseMux(tRFC_MCB* p_mcb) { tPORT* p_port; int i; - LOG_VERBOSE("PORT_TimeOutCloseMux"); + log::verbose("PORT_TimeOutCloseMux"); p_port = &rfc_cb.port.port[0]; for (i = 0; i < MAX_RFC_PORTS; i++, p_port++) { @@ -785,8 +787,8 @@ void PORT_DataInd(tRFC_MCB* p_mcb, uint8_t dlci, BT_HDR* p_buf) { uint8_t* p; int i; - LOG_VERBOSE("PORT_DataInd with data length %d, p_mcb:%p,p_port:%p,dlci:%d", - p_buf->len, p_mcb, p_port, dlci); + log::verbose("PORT_DataInd with data length {}, p_mcb:{},p_port:{},dlci:{}", + p_buf->len, fmt::ptr(p_mcb), fmt::ptr(p_port), dlci); if (!p_port) { osi_free(p_buf); return; @@ -816,7 +818,7 @@ void PORT_DataInd(tRFC_MCB* p_mcb, uint8_t dlci, BT_HDR* p_buf) { /* Check if rx queue exceeds the limit */ if ((p_port->rx.queue_size + p_buf->len > PORT_RX_CRITICAL_WM) || (fixed_queue_length(p_port->rx.queue) + 1 > p_port->rx_buf_critical)) { - LOG_VERBOSE("PORT_DataInd. Buffer over run. Dropping the buffer"); + log::verbose("PORT_DataInd. Buffer over run. Dropping the buffer"); osi_free(p_buf); RFCOMM_LineStatusReq(p_mcb, dlci, LINE_STATUS_OVERRUN); return; @@ -873,7 +875,7 @@ void PORT_FlowInd(tRFC_MCB* p_mcb, uint8_t dlci, bool enable_data) { uint32_t events = 0; int i; - LOG_VERBOSE("PORT_FlowInd fc:%d", enable_data); + log::verbose("PORT_FlowInd fc:{}", enable_data); if (dlci == 0) { p_mcb->peer_ready = enable_data; @@ -937,8 +939,8 @@ uint32_t port_rfc_send_tx_data(tPORT* p_port) { mutex_global_unlock(); - LOG_VERBOSE("Sending RFCOMM_DataReq tx.queue_size=%d", - p_port->tx.queue_size); + log::verbose("Sending RFCOMM_DataReq tx.queue_size={}", + p_port->tx.queue_size); RFCOMM_DataReq(p_port->rfc.p_mcb, p_port->dlci, p_buf); @@ -977,7 +979,7 @@ void port_rfc_closed(tPORT* p_port, uint8_t res) { if ((p_port->state == PORT_CONNECTION_STATE_OPENING) && (p_port->is_server)) { /* The server side was not informed that connection is up, ignore */ - LOG_WARN("port_rfc_closed in OPENING state ignored"); + log::warn("port_rfc_closed in OPENING state ignored"); rfc_port_timer_stop(p_port); p_port->rfc.state = RFC_STATE_CLOSED; @@ -1033,13 +1035,12 @@ void port_rfc_closed(tPORT* p_port, uint8_t res) { p_port->rfc.state = RFC_STATE_CLOSED; - LOG(INFO) << __func__ << ": RFCOMM connection closed, index=" - << std::to_string(p_port->handle) - << ", state=" << std::to_string(p_port->state) - << ", reason=" << PORT_GetResultString(res) << "[" - << std::to_string(res) << "], UUID=" << loghex(p_port->uuid) - << ", bd_addr=" << p_port->bd_addr - << ", is_server=" << p_port->is_server; + log::info( + "RFCOMM connection closed, index={}, state={}, reason={}[{}], UUID={}, " + "bd_addr={}, is_server={}", + p_port->handle, p_port->state, PORT_GetResultString(res), res, + loghex(p_port->uuid), ADDRESS_TO_LOGGABLE_STR(p_port->bd_addr), + p_port->is_server); port_release_port(p_port); } diff --git a/system/stack/rfcomm/port_utils.cc b/system/stack/rfcomm/port_utils.cc index fb4097d9045e39a505309f76a2932e1d6e35f6be..79de26e92bba6ce8b9e6cd92715ae2e83b17d84a 100644 --- a/system/stack/rfcomm/port_utils.cc +++ b/system/stack/rfcomm/port_utils.cc @@ -25,11 +25,13 @@ #define LOG_TAG "rfcomm_port_utils" #include +#include #include #include #include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/mutex.h" @@ -39,6 +41,8 @@ #include "stack/rfcomm/rfc_int.h" #include "types/raw_address.h" +using namespace bluetooth; + static const tPORT_STATE default_port_pars = { PORT_BAUD_RATE_9600, PORT_8_BITS, @@ -84,16 +88,15 @@ tPORT* port_allocate_port(uint8_t dlci, const RawAddress& bd_addr) { p_port->dlci = dlci; p_port->bd_addr = bd_addr; rfc_cb.rfc.last_port_index = port_index; - LOG_VERBOSE( - "%s: rfc_cb.port.port[%d]:%p chosen, " - "last_port_index:%d, bd_addr=%s", - __func__, port_index, p_port, rfc_cb.rfc.last_port_index, + log::verbose( + "rfc_cb.port.port[{}]:{} chosen, last_port_index:{}, bd_addr={}", + port_index, fmt::ptr(p_port), rfc_cb.rfc.last_port_index, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return p_port; } } - LOG(WARNING) << __func__ << ": running out of free ports for dlci " - << std::to_string(dlci) << ", bd_addr " << bd_addr; + log::warn("running out of free ports for dlci {}, bd_addr {}", dlci, + ADDRESS_TO_LOGGABLE_STR(bd_addr)); return nullptr; } @@ -150,7 +153,8 @@ void port_select_mtu(tPORT* p_port) { get_btm_client_interface().peer.BTM_GetMaxPacketSize(p_port->bd_addr); if (packet_size == 0) { /* something is very wrong */ - LOG(WARNING) << __func__ << ": bad packet size 0 for" << p_port->bd_addr; + log::warn("bad packet size 0 for{}", + ADDRESS_TO_LOGGABLE_STR(p_port->bd_addr)); p_port->mtu = RFCOMM_DEFAULT_MTU; } else { /* We try to negotiate MTU that each packet can be split into whole @@ -170,16 +174,14 @@ void port_select_mtu(tPORT* p_port) { p_port->mtu = ((L2CAP_MTU_SIZE + L2CAP_PKT_OVERHEAD) / packet_size * packet_size) - RFCOMM_DATA_OVERHEAD - L2CAP_PKT_OVERHEAD; - LOG_VERBOSE("%s: selected %d based on connection speed", __func__, - p_port->mtu); + log::verbose("selected {} based on connection speed", p_port->mtu); } else { p_port->mtu = L2CAP_MTU_SIZE - RFCOMM_DATA_OVERHEAD; - LOG_VERBOSE("%s: selected %d based on l2cap PDU size", __func__, - p_port->mtu); + log::verbose("selected {} based on l2cap PDU size", p_port->mtu); } } } else { - LOG_VERBOSE("%s: application selected %d", __func__, p_port->mtu); + log::verbose("application selected {}", p_port->mtu); } p_port->credit_rx_max = (PORT_RX_HIGH_WM / p_port->mtu); if (p_port->credit_rx_max > PORT_RX_BUF_HIGH_WM) @@ -190,9 +192,9 @@ void port_select_mtu(tPORT* p_port) { p_port->rx_buf_critical = (PORT_RX_CRITICAL_WM / p_port->mtu); if (p_port->rx_buf_critical > PORT_RX_BUF_CRITICAL_WM) p_port->rx_buf_critical = PORT_RX_BUF_CRITICAL_WM; - LOG_VERBOSE("%s: credit_rx_max %d, credit_rx_low %d, rx_buf_critical %d", - __func__, p_port->credit_rx_max, p_port->credit_rx_low, - p_port->rx_buf_critical); + log::verbose("credit_rx_max {}, credit_rx_low {}, rx_buf_critical {}", + p_port->credit_rx_max, p_port->credit_rx_low, + p_port->rx_buf_critical); } /******************************************************************************* @@ -205,8 +207,8 @@ void port_select_mtu(tPORT* p_port) { * ******************************************************************************/ void port_release_port(tPORT* p_port) { - LOG_VERBOSE("%s p_port: %p state: %d keep_handle: %d", __func__, p_port, - p_port->rfc.state, p_port->keep_port_handle); + log::verbose("p_port: {} state: {} keep_handle: {}", fmt::ptr(p_port), + p_port->rfc.state, p_port->keep_port_handle); mutex_global_lock(); BT_HDR* p_buf; @@ -245,7 +247,7 @@ void port_release_port(tPORT* p_port) { mutex_global_unlock(); if (p_port->keep_port_handle) { - LOG_VERBOSE("%s Re-initialize handle: %d", __func__, p_port->handle); + log::verbose("Re-initialize handle: {}", p_port->handle); /* save event mask and callback */ uint32_t mask = p_port->ev_mask; @@ -267,7 +269,7 @@ void port_release_port(tPORT* p_port) { p_port->local_ctrl.modem_signal = p_port->default_signal_state; p_port->bd_addr = RawAddress::kAny; } else { - LOG_VERBOSE("%s Clean-up handle: %d", __func__, p_port->handle); + log::verbose("Clean-up handle: {}", p_port->handle); alarm_free(p_port->rfc.port_timer); memset(p_port, 0, sizeof(tPORT)); } @@ -286,14 +288,13 @@ tRFC_MCB* port_find_mcb(const RawAddress& bd_addr) { for (tRFC_MCB& mcb : rfc_cb.port.rfc_mcb) { if ((mcb.state != RFC_MX_STATE_IDLE) && (mcb.bd_addr == bd_addr)) { /* Multiplexer channel found do not change anything */ - VLOG(1) << __func__ - << ": found bd_addr=" << ADDRESS_TO_LOGGABLE_STR(bd_addr) - << ", rfc_mcb=" << &mcb << ", lcid=" << loghex(mcb.lcid); + log::verbose("found, bd_addr:{}, rfc_mcb:{}, lcid:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), fmt::ptr(&mcb), + loghex(mcb.lcid)); return &mcb; } } - VLOG(1) << __func__ - << ": not found, bd_addr:" << ADDRESS_TO_LOGGABLE_STR(bd_addr); + log::warn("not found, bd_addr:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); return nullptr; } @@ -311,22 +312,21 @@ tRFC_MCB* port_find_mcb(const RawAddress& bd_addr) { ******************************************************************************/ tPORT* port_find_mcb_dlci_port(tRFC_MCB* p_mcb, uint8_t dlci) { if (!p_mcb) { - LOG(ERROR) << __func__ << ": p_mcb is null, dlci=" << std::to_string(dlci); + log::error("p_mcb is null, dlci={}", dlci); return nullptr; } if (dlci > RFCOMM_MAX_DLCI) { - LOG(WARNING) << __func__ << ": DLCI " << std::to_string(dlci) - << " is too large, bd_addr=" << p_mcb->bd_addr - << ", p_mcb=" << p_mcb; + log::warn("DLCI {} is too large, bd_addr={}, p_mcb={}", dlci, + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), fmt::ptr(p_mcb)); return nullptr; } uint8_t handle = p_mcb->port_handles[dlci]; if (handle == 0) { - LOG(INFO) << __func__ << ": Cannot find allocated RFCOMM app port for DLCI " - << std::to_string(dlci) << " on " << p_mcb->bd_addr - << ", p_mcb=" << p_mcb; + log::info( + "Cannot find allocated RFCOMM app port for DLCI {} on {}, p_mcb={}", + dlci, ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), fmt::ptr(p_mcb)); return nullptr; } return &rfc_cb.port.port[handle - 1]; @@ -521,7 +521,7 @@ void port_flow_control_peer(tPORT* p_port, bool enable, uint16_t count) { else if (((p_port->rx.queue_size > PORT_RX_HIGH_WM) || (fixed_queue_length(p_port->rx.queue) > PORT_RX_BUF_HIGH_WM)) && !p_port->rx.peer_fc) { - LOG_VERBOSE("PORT_DataInd Data reached HW. Sending FC set."); + log::verbose("PORT_DataInd Data reached HW. Sending FC set."); p_port->rx.peer_fc = true; RFCOMM_FlowReq(p_port->rfc.p_mcb, p_port->dlci, false); diff --git a/system/stack/rfcomm/rfc_event.h b/system/stack/rfcomm/rfc_event.h index 47f4f4638ff231282095d809427bedcb99d2fbf8..5ba2ad639af9f9aeef85b667d9be5840c954fc1a 100644 --- a/system/stack/rfcomm/rfc_event.h +++ b/system/stack/rfcomm/rfc_event.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include "macros.h" @@ -136,3 +138,12 @@ inline std::string rfcomm_port_event_text(const tRFC_PORT_EVENT& event) { return std::string("UNKNOWN[") + std::to_string(event) + std::string("]"); } } + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt diff --git a/system/stack/rfcomm/rfc_l2cap_if.cc b/system/stack/rfcomm/rfc_l2cap_if.cc index 9f9b0724484d622303cb85125cb777f46f7a3e49..907889ac5e4fdd1cfb8ce483c55f81d4c5c28ac4 100644 --- a/system/stack/rfcomm/rfc_l2cap_if.cc +++ b/system/stack/rfcomm/rfc_l2cap_if.cc @@ -23,6 +23,7 @@ ******************************************************************************/ #include +#include #include #include @@ -40,6 +41,8 @@ #include "stack/rfcomm/rfc_int.h" #include "types/raw_address.h" +using namespace bluetooth; + /* * Define Callback functions to be called by L2CAP */ @@ -101,9 +104,9 @@ void RFCOMM_ConnectInd(const RawAddress& bd_addr, uint16_t lcid, * continues as initiator */ /* if timeout, local device disconnects outgoing connection and continues * as acceptor */ - LOG_VERBOSE( + log::verbose( "RFCOMM_ConnectInd start timer for collision, initiator's " - "LCID(0x%x), acceptor's LCID(0x%x)", + "LCID(0x{:x}), acceptor's LCID(0x{:x})", p_mcb->lcid, p_mcb->pending_lcid); rfc_timer_start( @@ -142,7 +145,7 @@ void RFCOMM_ConnectCnf(uint16_t lcid, uint16_t result) { tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); if (!p_mcb) { - LOG_ERROR("RFCOMM_ConnectCnf LCID:0x%x", lcid); + log::error("RFCOMM_ConnectCnf LCID:0x{:x}", lcid); return; } @@ -152,8 +155,8 @@ void RFCOMM_ConnectCnf(uint16_t lcid, uint16_t result) { if (result != L2CAP_CONN_OK) { return; } else { - LOG_VERBOSE("RFCOMM_ConnectCnf peer gave up pending LCID(0x%x)", - p_mcb->pending_lcid); + log::verbose("RFCOMM_ConnectCnf peer gave up pending LCID(0x{:x})", + p_mcb->pending_lcid); /* Peer gave up its connection request, make sure cleaning up L2CAP * channel */ @@ -180,14 +183,14 @@ void RFCOMM_ConnectCnf(uint16_t lcid, uint16_t result) { ******************************************************************************/ void RFCOMM_ConfigInd(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) { if (p_cfg == nullptr) { - LOG_ERROR("Received l2cap configuration info with nullptr"); + log::error("Received l2cap configuration info with nullptr"); return; } tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); if (!p_mcb) { - LOG_ERROR("RFCOMM_ConfigInd LCID:0x%x", lcid); + log::error("RFCOMM_ConfigInd LCID:0x{:x}", lcid); for (auto& [cid, mcb] : rfc_lcid_mcb) { if (mcb != nullptr && mcb->pending_lcid == lcid) { tL2CAP_CFG_INFO l2cap_cfg_info(*p_cfg); @@ -218,7 +221,7 @@ void RFCOMM_ConfigCnf(uint16_t lcid, UNUSED_ATTR uint16_t initiator, tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); if (!p_mcb) { - LOG_ERROR("RFCOMM_ConfigCnf no MCB LCID:0x%x", lcid); + log::error("RFCOMM_ConfigCnf no MCB LCID:0x{:x}", lcid); return; } uintptr_t result_as_ptr = L2CAP_CFG_OK; @@ -234,11 +237,10 @@ void RFCOMM_ConfigCnf(uint16_t lcid, UNUSED_ATTR uint16_t initiator, * ******************************************************************************/ void RFCOMM_DisconnectInd(uint16_t lcid, bool is_conf_needed) { - VLOG(1) << __func__ << ": lcid=" << loghex(lcid) - << ", is_conf_needed=" << is_conf_needed; + log::verbose("lcid:{}, is_conf_needed:{}", loghex(lcid), is_conf_needed); tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); if (!p_mcb) { - LOG(WARNING) << __func__ << ": no mcb for lcid " << loghex(lcid); + log::warn("no mcb for lcid {}", loghex(lcid)); return; } rfc_mx_sm_execute(p_mcb, RFC_MX_EVENT_DISC_IND, nullptr); @@ -258,8 +260,7 @@ void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) { tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); if (!p_mcb) { - LOG(WARNING) << __func__ << ": Cannot find RFCOMM multiplexer for lcid " - << loghex(lcid); + log::warn("Cannot find RFCOMM multiplexer for lcid {}", loghex(lcid)); osi_free(p_buf); return; } @@ -268,15 +269,16 @@ void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) { /* If the frame did not pass validation just ignore it */ if (event == RFC_EVENT_BAD_FRAME) { - LOG(WARNING) << __func__ << ": Bad RFCOMM frame from lcid=" << loghex(lcid) - << ", bd_addr=" << p_mcb->bd_addr << ", p_mcb=" << p_mcb; + log::warn("Bad RFCOMM frame from lcid={}, bd_addr={}, p_mcb={}", + loghex(lcid), ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), + fmt::ptr(p_mcb)); osi_free(p_buf); return; } if (rfc_cb.rfc.rx_frame.dlci == RFCOMM_MX_DLCI) { - LOG_VERBOSE("%s: handle multiplexer event %d, p_mcb=%p", __func__, event, - p_mcb); + log::verbose("handle multiplexer event {}, p_mcb={}", event, + fmt::ptr(p_mcb)); /* Take special care of the Multiplexer Control Messages */ if (event == RFC_EVENT_UIH) { rfc_process_mx_message(p_mcb, p_buf); @@ -294,14 +296,14 @@ void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) { if (p_port == nullptr || !p_port->rfc.p_mcb) { /* If this is a SABME on new port, check if any app is waiting for it */ if (event != RFC_EVENT_SABME) { - LOG(WARNING) << __func__ - << ": no for none-SABME event, lcid=" << loghex(lcid) - << ", bd_addr=" << p_mcb->bd_addr << ", p_mcb=" << p_mcb; + log::warn("no for none-SABME event, lcid={}, bd_addr={}, p_mcb={}", + loghex(lcid), ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), + fmt::ptr(p_mcb)); if ((p_mcb->is_initiator && !rfc_cb.rfc.rx_frame.cr) || (!p_mcb->is_initiator && rfc_cb.rfc.rx_frame.cr)) { - LOG(ERROR) << __func__ - << ": Disconnecting RFCOMM, lcid=" << loghex(lcid) - << ", bd_addr=" << p_mcb->bd_addr << ", p_mcb=" << p_mcb; + log::error("Disconnecting RFCOMM, lcid={}, bd_addr={}, p_mcb={}", + loghex(lcid), ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), + fmt::ptr(p_mcb)); rfc_send_dm(p_mcb, rfc_cb.rfc.rx_frame.dlci, rfc_cb.rfc.rx_frame.pf); } osi_free(p_buf); @@ -310,24 +312,26 @@ void RFCOMM_BufDataInd(uint16_t lcid, BT_HDR* p_buf) { p_port = port_find_dlci_port(rfc_cb.rfc.rx_frame.dlci); if (p_port == nullptr) { - LOG(ERROR) << __func__ << ":Disconnecting RFCOMM, no port for dlci " - << +rfc_cb.rfc.rx_frame.dlci << ", lcid=" << loghex(lcid) - << ", bd_addr=" << p_mcb->bd_addr << ", p_mcb=" << p_mcb; + log::error( + "Disconnecting RFCOMM, no port for dlci {}, lcid={}, bd_addr={}, " + "p_mcb={}", + rfc_cb.rfc.rx_frame.dlci, loghex(lcid), + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), fmt::ptr(p_mcb)); rfc_send_dm(p_mcb, rfc_cb.rfc.rx_frame.dlci, true); osi_free(p_buf); return; } - LOG_VERBOSE("%s: port_handles[dlci=%d]:%d->%d, p_mcb=%p", __func__, - rfc_cb.rfc.rx_frame.dlci, - p_mcb->port_handles[rfc_cb.rfc.rx_frame.dlci], p_port->handle, - p_mcb); + log::verbose("port_handles[dlci={}]:{}->{}, p_mcb={}", + rfc_cb.rfc.rx_frame.dlci, + p_mcb->port_handles[rfc_cb.rfc.rx_frame.dlci], p_port->handle, + fmt::ptr(p_mcb)); p_mcb->port_handles[rfc_cb.rfc.rx_frame.dlci] = p_port->handle; p_port->rfc.p_mcb = p_mcb; } if (event == RFC_EVENT_UIH) { - LOG_VERBOSE("%s: Handling UIH event, buf_len=%u, credit=%u", __func__, - p_buf->len, rfc_cb.rfc.rx_frame.credit); + log::verbose("Handling UIH event, buf_len={}, credit={}", p_buf->len, + rfc_cb.rfc.rx_frame.credit); if (p_buf->len > 0) { rfc_port_sm_execute(p_port, static_cast(event), p_buf); } else { @@ -356,10 +360,10 @@ void RFCOMM_CongestionStatusInd(uint16_t lcid, bool is_congested) { tRFC_MCB* p_mcb = rfc_find_lcid_mcb(lcid); if (!p_mcb) { - LOG_ERROR("RFCOMM_CongestionStatusInd dropped LCID:0x%x", lcid); + log::error("RFCOMM_CongestionStatusInd dropped LCID:0x{:x}", lcid); return; } else { - LOG_VERBOSE("RFCOMM_CongestionStatusInd LCID:0x%x", lcid); + log::verbose("RFCOMM_CongestionStatusInd LCID:0x{:x}", lcid); } rfc_process_l2cap_congestion(p_mcb, is_congested); } @@ -375,8 +379,8 @@ tRFC_MCB* rfc_find_lcid_mcb(uint16_t lcid) { tRFC_MCB* p_mcb = rfc_lcid_mcb[lcid]; if (p_mcb != nullptr) { if (p_mcb->lcid != lcid) { - LOG(WARNING) << __func__ << "LCID reused lcid=:" << loghex(lcid) - << ", current_lcid=" << loghex(p_mcb->lcid); + log::warn("LCID reused lcid=:{}, current_lcid={}", loghex(lcid), + loghex(p_mcb->lcid)); return nullptr; } } diff --git a/system/stack/rfcomm/rfc_mx_fsm.cc b/system/stack/rfcomm/rfc_mx_fsm.cc index 42916d4159410133966a58f3fe27ac39738ac305..e406670213daaae1467db8a967ff80a65e8c723a 100644 --- a/system/stack/rfcomm/rfc_mx_fsm.cc +++ b/system/stack/rfcomm/rfc_mx_fsm.cc @@ -24,9 +24,11 @@ ******************************************************************************/ #include +#include #include +#include "include/check.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" // UNUSED_ATTR @@ -39,6 +41,8 @@ #define L2CAP_SUCCESS 0 #define L2CAP_ERROR 1 +using namespace bluetooth; + /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /******************************************************************************/ @@ -64,7 +68,7 @@ static void rfc_mx_conf_cnf(tRFC_MCB* p_mcb, uint16_t result); * * Function rfc_mx_sm_execute * - * Description This function sends multiplexor events through the state + * Description This function sends multiplexer events through the state * machine. * * Returns void @@ -73,10 +77,9 @@ static void rfc_mx_conf_cnf(tRFC_MCB* p_mcb, uint16_t result); void rfc_mx_sm_execute(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { CHECK(p_mcb != nullptr) << __func__ << ": NULL mcb for event " << event; - LOG_INFO( - "RFCOMM peer:%s event:%d state:%s", ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr), - event, - rfcomm_mx_state_text(static_cast(p_mcb->state)).c_str()); + log::info("RFCOMM peer:{} event:{} state:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr), event, + rfcomm_mx_state_text(static_cast(p_mcb->state))); switch (p_mcb->state) { case RFC_MX_STATE_IDLE: @@ -108,8 +111,8 @@ void rfc_mx_sm_execute(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { break; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_mcb->state); + log::error("Received unexpected event:{} in state:{}", event, + p_mcb->state); } } @@ -132,8 +135,8 @@ void rfc_mx_sm_state_idle(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { uint16_t lcid = L2CA_ConnectReq(BT_PSM_RFCOMM, p_mcb->bd_addr); if (lcid == 0) { - LOG(ERROR) << __func__ << ": failed to open L2CAP channel for " - << p_mcb->bd_addr; + log::error("failed to open L2CAP channel for {}", + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); rfc_save_lcid_mcb(nullptr, p_mcb->lcid); p_mcb->lcid = 0; PORT_StartCnf(p_mcb, RFCOMM_ERROR); @@ -170,10 +173,10 @@ void rfc_mx_sm_state_idle(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { return; default: - LOG_ERROR("Mx error state %d event %d", p_mcb->state, event); + log::error("Mx error state {} event {}", p_mcb->state, event); return; } - LOG_VERBOSE("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::verbose("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } /******************************************************************************* @@ -188,10 +191,10 @@ void rfc_mx_sm_state_idle(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { ******************************************************************************/ void rfc_mx_sm_state_wait_conn_cnf(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { - LOG_VERBOSE("%s: evt %d", __func__, event); + log::verbose("evt {}", event); switch (event) { case RFC_MX_EVENT_START_REQ: - LOG_ERROR("Mx error state %d event %d", p_mcb->state, event); + log::error("Mx error state {} event {}", p_mcb->state, event); return; /* There is some new timing so that Config Ind comes before security is @@ -225,9 +228,9 @@ void rfc_mx_sm_state_wait_conn_cnf(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, uint16_t i; uint8_t handle; - LOG_VERBOSE( - "RFCOMM MX retry as acceptor in collision case - evt:%d in " - "state:%d", + log::verbose( + "RFCOMM MX retry as acceptor in collision case - evt:{} in " + "state:{}", event, p_mcb->state); rfc_save_lcid_mcb(NULL, p_mcb->lcid); @@ -243,8 +246,8 @@ void rfc_mx_sm_state_wait_conn_cnf(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, p_mcb->port_handles[i] = 0; p_mcb->port_handles[i + 1] = handle; rfc_cb.port.port[handle - 1].dlci += 1; - LOG_VERBOSE("RFCOMM MX - DLCI:%d -> %d", i, - rfc_cb.port.port[handle - 1].dlci); + log::verbose("RFCOMM MX - DLCI:{} -> {}", i, + rfc_cb.port.port[handle - 1].dlci); } } @@ -254,10 +257,10 @@ void rfc_mx_sm_state_wait_conn_cnf(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, } return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_mcb->state); + log::error("Received unexpected event:{} in state:{}", event, + p_mcb->state); } - LOG_VERBOSE("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::verbose("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } /******************************************************************************* @@ -272,12 +275,12 @@ void rfc_mx_sm_state_wait_conn_cnf(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, ******************************************************************************/ void rfc_mx_sm_state_configure(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { - LOG_VERBOSE("%s: event %d", __func__, event); + log::verbose("event {}", event); switch (event) { case RFC_MX_EVENT_START_REQ: case RFC_MX_EVENT_CONN_CNF: - LOG_ERROR("Mx error state %d event %d", p_mcb->state, event); + log::error("Mx error state {} event {}", p_mcb->state, event); return; case RFC_MX_EVENT_CONF_IND: @@ -294,18 +297,18 @@ void rfc_mx_sm_state_configure(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, return; case RFC_MX_EVENT_TIMEOUT: - LOG(ERROR) << __func__ << ": L2CAP configuration timeout for " - << p_mcb->bd_addr; + log::error("L2CAP configuration timeout for {}", + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); p_mcb->state = RFC_MX_STATE_IDLE; L2CA_DisconnectReq(p_mcb->lcid); PORT_StartCnf(p_mcb, RFCOMM_ERROR); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_mcb->state); + log::error("Received unexpected event:{} in state:{}", event, + p_mcb->state); } - LOG_VERBOSE("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::verbose("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } /******************************************************************************* @@ -320,11 +323,11 @@ void rfc_mx_sm_state_configure(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, ******************************************************************************/ void rfc_mx_sm_sabme_wait_ua(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, UNUSED_ATTR void* p_data) { - LOG_VERBOSE("%s: event %d", __func__, event); + log::verbose("event {}", event); switch (event) { case RFC_MX_EVENT_START_REQ: case RFC_MX_EVENT_CONN_CNF: - LOG_ERROR("Mx error state %d event %d", p_mcb->state, event); + log::error("Mx error state {} event {}", p_mcb->state, event); return; /* workaround: we don't support reconfig */ @@ -365,10 +368,10 @@ void rfc_mx_sm_sabme_wait_ua(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, PORT_StartCnf(p_mcb, RFCOMM_ERROR); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_mcb->state); + log::error("Received unexpected event:{} in state:{}", event, + p_mcb->state); } - LOG_VERBOSE("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::verbose("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } /******************************************************************************* @@ -383,7 +386,7 @@ void rfc_mx_sm_sabme_wait_ua(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, ******************************************************************************/ void rfc_mx_sm_state_wait_sabme(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { - LOG_VERBOSE("%s: event %d", __func__, event); + log::verbose("event {}", event); switch (event) { case RFC_MX_EVENT_DISC_IND: p_mcb->state = RFC_MX_STATE_IDLE; @@ -431,9 +434,9 @@ void rfc_mx_sm_state_wait_sabme(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, return; default: - LOG_WARN("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::warn("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } - LOG_VERBOSE("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::verbose("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } /******************************************************************************* @@ -448,7 +451,7 @@ void rfc_mx_sm_state_wait_sabme(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, ******************************************************************************/ void rfc_mx_sm_state_connected(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, UNUSED_ATTR void* p_data) { - LOG_VERBOSE("%s: event %d", __func__, event); + log::verbose("event {}", event); switch (event) { case RFC_MX_EVENT_TIMEOUT: @@ -474,10 +477,10 @@ void rfc_mx_sm_state_connected(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, PORT_CloseInd(p_mcb); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_mcb->state); + log::error("Received unexpected event:{} in state:{}", event, + p_mcb->state); } - LOG_VERBOSE("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::verbose("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } /******************************************************************************* @@ -494,7 +497,7 @@ void rfc_mx_sm_state_disc_wait_ua(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, void* p_data) { BT_HDR* p_buf; - LOG_VERBOSE("%s: event %d", __func__, event); + log::verbose("event {}", event); switch (event) { case RFC_MX_EVENT_UA: case RFC_MX_EVENT_DM: @@ -553,10 +556,10 @@ void rfc_mx_sm_state_disc_wait_ua(tRFC_MCB* p_mcb, tRFC_MX_EVENT event, case RFC_MX_EVENT_QOS_VIOLATION_IND: break; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_mcb->state); + log::error("Received unexpected event:{} in state:{}", event, + p_mcb->state); } - LOG_VERBOSE("RFCOMM MX ignored - evt:%d in state:%d", event, p_mcb->state); + log::verbose("RFCOMM MX ignored - evt:{} in state:{}", event, p_mcb->state); } void rfc_on_l2cap_error(uint16_t lcid, uint16_t result) { @@ -567,8 +570,9 @@ void rfc_on_l2cap_error(uint16_t lcid, uint16_t result) { /* if peer rejects our connect request but peer's connect request is pending */ if (p_mcb->pending_lcid) { - LOG_VERBOSE("RFCOMM_ConnectCnf retry as acceptor on pending LCID(0x%x)", - p_mcb->pending_lcid); + log::verbose( + "RFCOMM_ConnectCnf retry as acceptor on pending LCID(0x{:x})", + p_mcb->pending_lcid); /* remove mcb from mapping table */ rfc_save_lcid_mcb(NULL, p_mcb->lcid); @@ -587,13 +591,13 @@ void rfc_on_l2cap_error(uint16_t lcid, uint16_t result) { p_mcb->port_handles[i] = 0; p_mcb->port_handles[i + 1] = handle; rfc_cb.port.port[handle - 1].dlci += 1; - LOG_VERBOSE("RFCOMM MX, port_handle=%d, DLCI[%d->%d]", handle, i, - rfc_cb.port.port[handle - 1].dlci); + log::verbose("RFCOMM MX, port_handle={}, DLCI[{}->{}]", handle, i, + rfc_cb.port.port[handle - 1].dlci); } } rfc_mx_sm_execute(p_mcb, RFC_MX_EVENT_CONN_IND, nullptr); if (p_mcb->pending_configure_complete) { - LOG_INFO("Configuration of the pending connection was completed"); + log::info("Configuration of the pending connection was completed"); p_mcb->pending_configure_complete = false; uintptr_t result_as_ptr = L2CAP_CFG_OK; rfc_mx_sm_execute(p_mcb, RFC_MX_EVENT_CONF_IND, @@ -606,11 +610,11 @@ void rfc_on_l2cap_error(uint16_t lcid, uint16_t result) { p_mcb->lcid = lcid; rfc_mx_sm_execute(p_mcb, RFC_MX_EVENT_CONN_CNF, &result); } else if (result == L2CAP_CFG_FAILED_NO_REASON) { - LOG(ERROR) << __func__ << ": failed to configure L2CAP for " - << p_mcb->bd_addr; + log::error("failed to configure L2CAP for {}", + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); if (p_mcb->is_initiator) { - LOG(ERROR) << __func__ << ": disconnect L2CAP due to config failure for " - << p_mcb->bd_addr; + log::error("disconnect L2CAP due to config failure for {}", + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); PORT_StartCnf(p_mcb, result); L2CA_DisconnectReq(p_mcb->lcid); } diff --git a/system/stack/rfcomm/rfc_port_fsm.cc b/system/stack/rfcomm/rfc_port_fsm.cc index 55c1d00b3a360cde7488b3c6f30ab910e4d9f3f0..295fc7d1cad6692741fa2c41c29e8bdaee925d88 100644 --- a/system/stack/rfcomm/rfc_port_fsm.cc +++ b/system/stack/rfcomm/rfc_port_fsm.cc @@ -24,12 +24,14 @@ ******************************************************************************/ #include +#include #include #include #include -#include "gd/hal/snoop_logger.h" +#include "hal/snoop_logger.h" +#include "include/check.h" #include "main/shim/entry.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -41,6 +43,8 @@ #include "stack/rfcomm/port_int.h" #include "stack/rfcomm/rfc_int.h" +using namespace bluetooth; + static const std::set uuid_logging_acceptlist = { UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, UUID_SERVCLASS_AG_HANDSFREE, @@ -80,11 +84,13 @@ static void rfc_set_port_state(tPORT_STATE* port_pars, MX_FRAME* p_frame); ******************************************************************************/ void rfc_port_sm_execute(tPORT* p_port, tRFC_PORT_EVENT event, void* p_data) { CHECK(p_port != nullptr) << __func__ << ": NULL port event " << event; - VLOG(1) << __func__ - << ": BD_ADDR=" << ADDRESS_TO_LOGGABLE_STR(p_port->bd_addr) - << ", PORT=" << std::to_string(p_port->handle) - << ", STATE=" << std::to_string(p_port->rfc.state) - << ", EVENT=" << event; + + // logs for state RFC_STATE_OPENED handled in rfc_port_sm_opened() + if (p_port->rfc.state != RFC_STATE_OPENED) { + log::info("bd_addr:{}, index:{}, state:{}, event:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle, + p_port->rfc.state, event); + } switch (p_port->rfc.state) { case RFC_STATE_CLOSED: rfc_port_sm_state_closed(p_port, event, p_data); @@ -159,7 +165,7 @@ void rfc_port_sm_state_closed(tPORT* p_port, tRFC_PORT_EVENT event, return; case RFC_PORT_EVENT_DM: - LOG_WARN("%s, RFC_EVENT_DM, index=%d", __func__, p_port->handle); + log::warn("RFC_EVENT_DM, index={}", p_port->handle); rfc_port_closed(p_port); return; @@ -174,14 +180,14 @@ void rfc_port_sm_state_closed(tPORT* p_port, tRFC_PORT_EVENT event, case RFC_PORT_EVENT_TIMEOUT: PORT_TimeOutCloseMux(p_port->rfc.p_mcb); - LOG_ERROR("Port error state %d event %d", p_port->rfc.state, event); + log::error("Port error state {} event {}", p_port->rfc.state, event); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_port->rfc.state); + log::error("Received unexpected event:{} in state:{}", event, + p_port->rfc.state); } - LOG_WARN("Port state closed Event ignored %d", event); + log::warn("Port state closed Event ignored {}", event); return; } @@ -200,7 +206,7 @@ void rfc_port_sm_sabme_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, switch (event) { case RFC_PORT_EVENT_OPEN: case RFC_PORT_EVENT_ESTABLISH_RSP: - LOG_ERROR("Port error state %d event %d", p_port->rfc.state, event); + log::error("Port error state {} event {}", p_port->rfc.state, event); return; case RFC_PORT_EVENT_CLOSE: @@ -211,7 +217,7 @@ void rfc_port_sm_sabme_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, return; case RFC_PORT_EVENT_CLEAR: - LOG_WARN("%s, RFC_PORT_EVENT_CLEAR, index=%d", __func__, p_port->handle); + log::warn("RFC_PORT_EVENT_CLEAR, index={}", p_port->handle); rfc_port_closed(p_port); return; @@ -252,7 +258,7 @@ void rfc_port_sm_sabme_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, return; case RFC_PORT_EVENT_DM: - LOG_WARN("%s, RFC_EVENT_DM, index=%d", __func__, p_port->handle); + log::warn("RFC_EVENT_DM, index={}", p_port->handle); p_port->rfc.p_mcb->is_disc_initiator = true; PORT_DlcEstablishCnf(p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR); @@ -260,7 +266,7 @@ void rfc_port_sm_sabme_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, return; case RFC_PORT_EVENT_DISC: - LOG_WARN("%s, RFC_EVENT_DISC, index=%d", __func__, p_port->handle); + log::warn("RFC_EVENT_DISC, index={}", p_port->handle); rfc_send_ua(p_port->rfc.p_mcb, p_port->dlci); PORT_DlcEstablishCnf(p_port->rfc.p_mcb, p_port->dlci, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR); @@ -282,10 +288,10 @@ void rfc_port_sm_sabme_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, p_port->rfc.p_mcb->peer_l2cap_mtu, RFCOMM_ERROR); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_port->rfc.state); + log::error("Received unexpected event:{} in state:{}", event, + p_port->rfc.state); } - LOG_WARN("Port state sabme_wait_ua Event ignored %d", event); + log::warn("Port state sabme_wait_ua Event ignored {}", event); } /******************************************************************************* @@ -320,17 +326,17 @@ void rfc_port_sm_term_wait_sec_check(tPORT* p_port, tRFC_PORT_EVENT event, case RFC_PORT_EVENT_OPEN: case RFC_PORT_EVENT_CLOSE: - LOG_ERROR("Port error state %d event %d", p_port->rfc.state, event); + log::error("Port error state {} event {}", p_port->rfc.state, event); return; case RFC_PORT_EVENT_CLEAR: - LOG_WARN("%s, RFC_PORT_EVENT_CLEAR, index=%d", __func__, p_port->handle); + log::warn("RFC_PORT_EVENT_CLEAR, index={}", p_port->handle); btm_sec_abort_access_req(p_port->rfc.p_mcb->bd_addr); rfc_port_closed(p_port); return; case RFC_PORT_EVENT_DATA: - LOG_ERROR("Port error state Term Wait Sec event Data"); + log::error("Port error state Term Wait Sec event Data"); osi_free(p_data); return; @@ -384,10 +390,10 @@ void rfc_port_sm_term_wait_sec_check(tPORT* p_port, tRFC_PORT_EVENT event, } return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_port->rfc.state); + log::error("Received unexpected event:{} in state:{}", event, + p_port->rfc.state); } - LOG_WARN("Port state term_wait_sec_check Event ignored %d", event); + log::warn("Port state term_wait_sec_check Event ignored {}", event); } /******************************************************************************* @@ -406,8 +412,8 @@ void rfc_port_sm_orig_wait_sec_check(tPORT* p_port, tRFC_PORT_EVENT event, switch (event) { case RFC_PORT_EVENT_SEC_COMPLETE: if (*((uint8_t*)p_data) != BTM_SUCCESS) { - LOG_ERROR("%s, RFC_PORT_EVENT_SEC_COMPLETE, index=%d, result=%d", - __func__, p_port->handle, *((uint8_t*)p_data)); + log::error("RFC_PORT_EVENT_SEC_COMPLETE, index={}, result={}", + p_port->handle, *((uint8_t*)p_data)); p_port->rfc.p_mcb->is_disc_initiator = true; PORT_DlcEstablishCnf(p_port->rfc.p_mcb, p_port->dlci, 0, RFCOMM_SECURITY_ERR); @@ -421,17 +427,17 @@ void rfc_port_sm_orig_wait_sec_check(tPORT* p_port, tRFC_PORT_EVENT event, case RFC_PORT_EVENT_OPEN: case RFC_PORT_EVENT_SABME: /* Peer should not use the same dlci */ - LOG_ERROR("Port error state %d event %d", p_port->rfc.state, event); + log::error("Port error state {} event {}", p_port->rfc.state, event); return; case RFC_PORT_EVENT_CLOSE: - LOG_WARN("%s, RFC_PORT_EVENT_CLOSE, index=%d", __func__, p_port->handle); + log::warn("RFC_PORT_EVENT_CLOSE, index={}", p_port->handle); btm_sec_abort_access_req(p_port->rfc.p_mcb->bd_addr); rfc_port_closed(p_port); return; case RFC_PORT_EVENT_DATA: - LOG_ERROR("Port error state Orig Wait Sec event Data"); + log::error("Port error state Orig Wait Sec event Data"); osi_free(p_data); return; @@ -439,10 +445,10 @@ void rfc_port_sm_orig_wait_sec_check(tPORT* p_port, tRFC_PORT_EVENT event, osi_free(p_data); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_port->rfc.state); + log::error("Received unexpected event:{} in state:{}", event, + p_port->rfc.state); } - LOG_WARN("Port state orig_wait_sec_check Event ignored %d", event); + log::warn("Port state orig_wait_sec_check Event ignored {}", event); } /******************************************************************************* @@ -458,10 +464,14 @@ void rfc_port_sm_orig_wait_sec_check(tPORT* p_port, tRFC_PORT_EVENT event, void rfc_port_sm_opened(tPORT* p_port, tRFC_PORT_EVENT event, void* p_data) { switch (event) { case RFC_PORT_EVENT_OPEN: - LOG_ERROR("Port error state %d event %d", p_port->rfc.state, event); + log::error("Port error, bd_addr={}, state={}, event={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->rfc.state, + event); return; case RFC_PORT_EVENT_CLOSE: + log::info("RFC_PORT_EVENT_CLOSE bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle); rfc_port_timer_start(p_port, RFC_DISC_TIMEOUT); rfc_send_disc(p_port->rfc.p_mcb, p_port->dlci); p_port->rfc.expected_rsp = 0; @@ -469,7 +479,8 @@ void rfc_port_sm_opened(tPORT* p_port, tRFC_PORT_EVENT event, void* p_data) { return; case RFC_PORT_EVENT_CLEAR: - LOG_WARN("%s, RFC_PORT_EVENT_CLEAR, index=%d", __func__, p_port->handle); + log::warn("RFC_PORT_EVENT_CLEAR, bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle); rfc_port_closed(p_port); return; @@ -479,6 +490,8 @@ void rfc_port_sm_opened(tPORT* p_port, tRFC_PORT_EVENT event, void* p_data) { /* There might be an initial case when we reduced rx_max and credit_rx is * still */ /* bigger. Make sure that we do not send 255 */ + log::verbose("RFC_PORT_EVENT_DATA bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle); if ((p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) && (((BT_HDR*)p_data)->len < p_port->peer_mtu) && (!p_port->rx.user_fc) && @@ -494,42 +507,54 @@ void rfc_port_sm_opened(tPORT* p_port, tRFC_PORT_EVENT event, void* p_data) { return; case RFC_PORT_EVENT_UA: + log::verbose("RFC_PORT_EVENT_UA bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle); return; case RFC_PORT_EVENT_SABME: + log::verbose("RFC_PORT_EVENT_SABME bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle); rfc_send_ua(p_port->rfc.p_mcb, p_port->dlci); return; case RFC_PORT_EVENT_DM: - LOG_WARN("%s, RFC_EVENT_DM, index=%d", __func__, p_port->handle); + log::info("RFC_EVENT_DM, bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle); PORT_DlcReleaseInd(p_port->rfc.p_mcb, p_port->dlci); rfc_port_closed(p_port); return; case RFC_PORT_EVENT_DISC: + log::info("RFC_PORT_EVENT_DISC, bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle, + p_port->rfc.state, event); p_port->rfc.state = RFC_STATE_CLOSED; rfc_send_ua(p_port->rfc.p_mcb, p_port->dlci); if (!fixed_queue_is_empty(p_port->rx.queue)) { /* give a chance to upper stack to close port properly */ - LOG_VERBOSE("port queue is not empty"); + log::verbose("port queue is not empty"); rfc_port_timer_start(p_port, RFC_DISC_TIMEOUT); } else PORT_DlcReleaseInd(p_port->rfc.p_mcb, p_port->dlci); return; case RFC_PORT_EVENT_UIH: + log::verbose("RFC_PORT_EVENT_UIH bd_addr={}, index={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->handle); rfc_port_uplink_data(p_port, (BT_HDR*)p_data); return; case RFC_PORT_EVENT_TIMEOUT: PORT_TimeOutCloseMux(p_port->rfc.p_mcb); - LOG_ERROR("Port error state %d event %d", p_port->rfc.state, event); + log::error("Port error, bd_addr={}, state={}, event={}", + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->rfc.state, + event); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_port->rfc.state); + log::error("Received unexpected event {}, bd_addr={}, state={}", event, + ADDRESS_TO_LOGGABLE_CSTR(p_port->bd_addr), p_port->rfc.state); } - LOG_WARN("Port state opened Event ignored %d", event); + log::warn("Port state opened Event ignored {}", event); } /******************************************************************************* @@ -547,11 +572,11 @@ void rfc_port_sm_disc_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, switch (event) { case RFC_PORT_EVENT_OPEN: case RFC_PORT_EVENT_ESTABLISH_RSP: - LOG_ERROR("Port error state %d event %d", p_port->rfc.state, event); + log::error("Port error state {} event {}", p_port->rfc.state, event); return; case RFC_PORT_EVENT_CLEAR: - LOG_WARN("%s, RFC_PORT_EVENT_CLEAR, index=%d", __func__, p_port->handle); + log::warn("RFC_PORT_EVENT_CLEAR, index={}", p_port->handle); rfc_port_closed(p_port); return; @@ -564,8 +589,8 @@ void rfc_port_sm_disc_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, FALLTHROUGH_INTENDED; /* FALLTHROUGH */ case RFC_PORT_EVENT_DM: - LOG_WARN("%s, RFC_EVENT_DM|RFC_EVENT_UA[%d], index=%d", __func__, event, - p_port->handle); + log::warn("RFC_EVENT_DM|RFC_EVENT_UA[{}], index={}", event, + p_port->handle); rfc_port_closed(p_port); return; @@ -583,15 +608,15 @@ void rfc_port_sm_disc_wait_ua(tPORT* p_port, tRFC_PORT_EVENT event, return; case RFC_PORT_EVENT_TIMEOUT: - LOG_ERROR("%s, RFC_EVENT_TIMEOUT, index=%d", __func__, p_port->handle); + log::error("RFC_EVENT_TIMEOUT, index={}", p_port->handle); rfc_port_closed(p_port); return; default: - LOG_ERROR("Received unexpected event:%hu in state:%hhu", event, - p_port->rfc.state); + log::error("Received unexpected event:{} in state:{}", event, + p_port->rfc.state); } - LOG_WARN("Port state disc_wait_ua Event ignored %d", event); + log::warn("Port state disc_wait_ua Event ignored {}", event); } /******************************************************************************* @@ -614,9 +639,9 @@ void rfc_port_uplink_data(tPORT* p_port, BT_HDR* p_buf) { * ******************************************************************************/ void rfc_process_pn(tRFC_MCB* p_mcb, bool is_command, MX_FRAME* p_frame) { - LOG_VERBOSE("%s: is_initiator=%d, is_cmd=%d, state=%d, bd_addr=%s", __func__, - p_mcb->is_initiator, is_command, p_mcb->state, - ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr)); + log::verbose("is_initiator={}, is_cmd={}, state={}, bd_addr={}", + p_mcb->is_initiator, is_command, p_mcb->state, + ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr)); uint8_t dlci = p_frame->dlci; if (is_command) { @@ -625,9 +650,8 @@ void rfc_process_pn(tRFC_MCB* p_mcb, bool is_command, MX_FRAME* p_frame) { PORT_ParNegInd(p_mcb, dlci, p_frame->u.pn.mtu, p_frame->u.pn.conv_layer, p_frame->u.pn.k); } else { - LOG(WARNING) << __func__ - << ": MX PN while disconnecting, bd_addr=" << p_mcb->bd_addr - << ", p_mcb=" << p_mcb; + log::warn("MX PN while disconnecting, bd_addr={}, p_mcb={}", + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), fmt::ptr(p_mcb)); rfc_send_dm(p_mcb, dlci, false); } @@ -636,9 +660,8 @@ void rfc_process_pn(tRFC_MCB* p_mcb, bool is_command, MX_FRAME* p_frame) { /* If we are not awaiting response just ignore it */ tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if ((p_port == nullptr) || !(p_port->rfc.expected_rsp & RFC_RSP_PN)) { - LOG(WARNING) << ": Ignore unwanted response, p_mcb=" << p_mcb - << ", bd_addr=" << p_mcb->bd_addr - << ", dlci=" << std::to_string(dlci); + log::warn(": Ignore unwanted response, p_mcb={}, bd_addr={}, dlci={}", + fmt::ptr(p_mcb), ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr), dlci); return; } @@ -696,8 +719,7 @@ void rfc_process_rpn(tRFC_MCB* p_mcb, bool is_command, bool is_request, p_port = port_find_mcb_dlci_port(p_mcb, p_frame->dlci); if ((p_port == nullptr) || !(p_port->rfc.expected_rsp & (RFC_RSP_RPN | RFC_RSP_RPN_REPLY))) { - LOG(WARNING) << __func__ << ": ignore DLC parameter negotiation as we are" - << " not waiting for any"; + log::warn("ignore DLC parameter negotiation as we are not waiting for any"); return; } diff --git a/system/stack/rfcomm/rfc_port_if.cc b/system/stack/rfcomm/rfc_port_if.cc index f6eb46fb3a55cf08ebcc113ec6c3be19f72a4054..ca7eb8f33d8c8e526b1444fdb9ae5a6c4c5f1723 100644 --- a/system/stack/rfcomm/rfc_port_if.cc +++ b/system/stack/rfcomm/rfc_port_if.cc @@ -25,6 +25,8 @@ #define LOG_TAG "rfcomm" +#include + #include #include @@ -35,6 +37,8 @@ #include "stack/rfcomm/port_int.h" #include "stack/rfcomm/rfc_int.h" +using namespace bluetooth; + tRFC_CB rfc_cb; std::unordered_map rfc_lcid_mcb; @@ -85,7 +89,7 @@ void RFCOMM_DlcEstablishReq(tRFC_MCB* p_mcb, uint8_t dlci, tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (p_port == nullptr) { - LOG_WARN("%s Unable to find DLCI port dlci:%d", __func__, dlci); + log::warn("Unable to find DLCI port dlci:{}", dlci); return; } @@ -109,7 +113,7 @@ void RFCOMM_DlcEstablishRsp(tRFC_MCB* p_mcb, uint8_t dlci, tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (p_port == nullptr) { - LOG_WARN("%s Unable to find DLCI port dlci:%d", __func__, dlci); + log::warn("Unable to find DLCI port dlci:{}", dlci); return; } rfc_port_sm_execute(p_port, RFC_PORT_EVENT_ESTABLISH_RSP, &result); @@ -134,7 +138,7 @@ void RFCOMM_ParameterNegotiationRequest(tRFC_MCB* p_mcb, uint8_t dlci, tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (p_port == nullptr) { - LOG_WARN("%s Unable to find DLCI port dlci:%d", __func__, dlci); + log::warn("Unable to find DLCI port dlci:{}", dlci); return; } @@ -203,7 +207,7 @@ void RFCOMM_PortParameterNegotiationRequest(tRFC_MCB* p_mcb, uint8_t dlci, tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (p_port == nullptr) { - LOG_WARN("%s Unable to find DLCI port dlci:%d", __func__, dlci); + log::warn("Unable to find DLCI port dlci:{}", dlci); return; } @@ -244,7 +248,7 @@ void RFCOMM_PortParameterNegotiationResponse(tRFC_MCB* p_mcb, uint8_t dlci, void RFCOMM_ControlReq(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* p_pars) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (p_port == nullptr) { - LOG_WARN("%s Unable to find DLCI port dlci:%d", __func__, dlci); + log::warn("Unable to find DLCI port dlci:{}", dlci); return; } @@ -272,7 +276,7 @@ void RFCOMM_ControlReq(tRFC_MCB* p_mcb, uint8_t dlci, tPORT_CTRL* p_pars) { void RFCOMM_FlowReq(tRFC_MCB* p_mcb, uint8_t dlci, bool enable) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (p_port == nullptr) { - LOG_WARN("%s Unable to find DLCI port dlci:%d", __func__, dlci); + log::warn("Unable to find DLCI port dlci:{}", dlci); return; } @@ -299,7 +303,7 @@ void RFCOMM_FlowReq(tRFC_MCB* p_mcb, uint8_t dlci, bool enable) { void RFCOMM_LineStatusReq(tRFC_MCB* p_mcb, uint8_t dlci, uint8_t status) { tPORT* p_port = port_find_mcb_dlci_port(p_mcb, dlci); if (p_port == nullptr) { - LOG_WARN("%s Unable to find DLCI port dlci:%d", __func__, dlci); + log::warn("Unable to find DLCI port dlci:{}", dlci); return; } diff --git a/system/stack/rfcomm/rfc_ts_frames.cc b/system/stack/rfcomm/rfc_ts_frames.cc index 8db32d68f925aa727c5017fdddaad5e36e2c71e5..cf49eda06503d862a228b0b35d96a4014e9d82c6 100644 --- a/system/stack/rfcomm/rfc_ts_frames.cc +++ b/system/stack/rfcomm/rfc_ts_frames.cc @@ -25,6 +25,7 @@ #define LOG_TAG "rfcomm" #include +#include #include #include @@ -38,6 +39,8 @@ #include "stack/rfcomm/port_int.h" #include "stack/rfcomm/rfc_int.h" +using namespace bluetooth; + /******************************************************************************* * * Function rfc_send_sabme @@ -518,13 +521,13 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { uint16_t len; if (p_buf->len < RFCOMM_CTRL_FRAME_LEN) { - LOG_ERROR("Bad Length1: %d", p_buf->len); + log::error("Bad Length1: {}", p_buf->len); return (RFC_EVENT_BAD_FRAME); } RFCOMM_PARSE_CTRL_FIELD(ead, p_frame->cr, p_frame->dlci, p_data); if (!ead) { - LOG_ERROR("Bad Address(EA must be 1)"); + log::error("Bad Address(EA must be 1)"); return (RFC_EVENT_BAD_FRAME); } RFCOMM_PARSE_TYPE_FIELD(p_frame->type, p_frame->pf, p_data); @@ -534,12 +537,12 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { if (eal == 0 && p_buf->len > RFCOMM_CTRL_FRAME_LEN) { len += (*(p_data)++ << RFCOMM_SHIFT_LENGTH2); } else if (eal == 0) { - LOG_ERROR("Bad Length when EAL = 0: %d", p_buf->len); + log::error("Bad Length when EAL = 0: {}", p_buf->len); return RFC_EVENT_BAD_FRAME; } if (p_buf->len < (3 + !ead + !eal + 1)) { - LOG_ERROR("Bad Length: %d", p_buf->len); + log::error("Bad Length: {}", p_buf->len); return RFC_EVENT_BAD_FRAME; } p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */ @@ -549,7 +552,7 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) && (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1)) { if (p_buf->len < sizeof(uint8_t)) { - LOG_ERROR("Bad Length in flow control: %d", p_buf->len); + log::error("Bad Length in flow control: {}", p_buf->len); return RFC_EVENT_BAD_FRAME; } p_frame->credit = *p_data++; @@ -560,7 +563,7 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { } if (p_buf->len != len) { - LOG_ERROR("Bad Length2 %d %d", p_buf->len, len); + log::error("Bad Length2 {} {}", p_buf->len, len); return (RFC_EVENT_BAD_FRAME); } @@ -575,7 +578,7 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) || !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) || !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) { - LOG_ERROR("Bad SABME"); + log::error("Bad SABME"); return (RFC_EVENT_BAD_FRAME); } else return (RFC_EVENT_SABME); @@ -584,7 +587,7 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) || !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) || !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) { - LOG_ERROR("Bad UA"); + log::error("Bad UA"); return (RFC_EVENT_BAD_FRAME); } else return (RFC_EVENT_UA); @@ -593,7 +596,7 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) || len || !RFCOMM_VALID_DLCI(p_frame->dlci) || !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) { - LOG_ERROR("Bad DM"); + log::error("Bad DM"); return (RFC_EVENT_BAD_FRAME); } else return (RFC_EVENT_DM); @@ -602,21 +605,21 @@ tRFC_EVENT rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) { if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) || !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) || !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) { - LOG_ERROR("Bad DISC"); + log::error("Bad DISC"); return (RFC_EVENT_BAD_FRAME); } else return (RFC_EVENT_DISC); case RFCOMM_UIH: if (!RFCOMM_VALID_DLCI(p_frame->dlci)) { - LOG_ERROR("Bad UIH - invalid DLCI"); + log::error("Bad UIH - invalid DLCI"); return (RFC_EVENT_BAD_FRAME); } else if (!rfc_check_fcs(2, p_start, fcs)) { - LOG_ERROR("Bad UIH - FCS"); + log::error("Bad UIH - FCS"); return (RFC_EVENT_BAD_FRAME); } else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)) { /* we assume that this is ok to allow bad implementations to work */ - LOG_ERROR("Bad UIH - response"); + log::error("Bad UIH - response"); return (RFC_EVENT_UIH); } else { return (RFC_EVENT_UIH); @@ -641,8 +644,7 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { uint8_t ea, cr, mx_len; if (length < 2) { - LOG_ERROR("%s: Illegal MX Frame len when reading EA, C/R. len:%d < 2", - __func__, length); + log::error("Illegal MX Frame len when reading EA, C/R. len:{} < 2", length); osi_free(p_buf); return; } @@ -651,9 +653,8 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { p_rx_frame->type = *p_data++ & ~(RFCOMM_CR_MASK | RFCOMM_EA_MASK); if (!p_rx_frame->ea || !length) { - LOG(ERROR) << __func__ - << ": Invalid MX frame ea=" << std::to_string(p_rx_frame->ea) - << ", len=" << length << ", bd_addr=" << p_mcb->bd_addr; + log::error("Invalid MX frame ea={}, len={}, bd_addr={}", p_rx_frame->ea, + length, ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); osi_free(p_buf); return; } @@ -669,8 +670,7 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { if (!ea) { if (length < 1) { - LOG_ERROR("%s: Illegal MX Frame when EA = 0. len:%d < 1", __func__, - length); + log::error("Illegal MX Frame when EA = 0. len:{} < 1", length); osi_free(p_buf); return; } @@ -679,19 +679,19 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { } if (mx_len != length) { - LOG(ERROR) << __func__ << ": Bad MX frame, p_mcb=" << p_mcb - << ", bd_addr=" << p_mcb->bd_addr; + log::error("Bad MX frame, p_mcb={}, bd_addr={}", fmt::ptr(p_mcb), + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); osi_free(p_buf); return; } - LOG_VERBOSE("%s: type=0x%02x, bd_addr=%s", __func__, p_rx_frame->type, - ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr)); + log::verbose("type=0x{:02x}, bd_addr={}", p_rx_frame->type, + ADDRESS_TO_LOGGABLE_CSTR(p_mcb->bd_addr)); switch (p_rx_frame->type) { case RFCOMM_MX_PN: if (length != RFCOMM_MX_PN_LEN) { - LOG(ERROR) << __func__ << ": Invalid PN length, p_mcb=" << p_mcb - << ", bd_addr=" << p_mcb->bd_addr; + log::error("Invalid PN length, p_mcb={}, bd_addr={}", fmt::ptr(p_mcb), + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); break; } @@ -708,8 +708,8 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { if (!p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci) || (p_rx_frame->u.pn.mtu < RFCOMM_MIN_MTU) || (p_rx_frame->u.pn.mtu > RFCOMM_MAX_MTU)) { - LOG(ERROR) << __func__ << ": Bad PN frame, p_mcb=" << p_mcb - << ", bd_addr=" << p_mcb->bd_addr; + log::error("Bad PN frame, p_mcb={}, bd_addr={}", fmt::ptr(p_mcb), + ADDRESS_TO_LOGGABLE_STR(p_mcb->bd_addr)); break; } @@ -752,7 +752,7 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { case RFCOMM_MX_MSC: if (length != RFCOMM_MX_MSC_LEN_WITH_BREAK && length != RFCOMM_MX_MSC_LEN_NO_BREAK) { - LOG_ERROR("%s: Illegal MX MSC Frame len:%d", __func__, length); + log::error("Illegal MX MSC Frame len:{}", length); osi_free(p_buf); return; } @@ -762,7 +762,7 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { if (!ea || !cr || !p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci)) { - LOG_ERROR("Bad MSC frame"); + log::error("Bad MSC frame"); break; } @@ -804,7 +804,7 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { if (!ea || !cr || !p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci)) { - LOG_ERROR("Bad RPN frame"); + log::error("Bad RPN frame"); break; } @@ -845,7 +845,7 @@ void rfc_process_mx_message(tRFC_MCB* p_mcb, BT_HDR* p_buf) { if (!ea || !cr || !p_rx_frame->dlci || !RFCOMM_VALID_DLCI(p_rx_frame->dlci)) { - LOG_ERROR("Bad RPN frame"); + log::error("Bad RPN frame"); break; } diff --git a/system/stack/rfcomm/rfc_utils.cc b/system/stack/rfcomm/rfc_utils.cc index 1d86998bb489f360be0e83bbf471cbf675b73aee..91651ba7d6abea5457954a8827c4672c4231ac54 100644 --- a/system/stack/rfcomm/rfc_utils.cc +++ b/system/stack/rfcomm/rfc_utils.cc @@ -24,18 +24,22 @@ #define LOG_TAG "rfcomm" +#include +#include + #include -#include "bt_target.h" +#include "include/check.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/bt_hdr.h" #include "stack/include/port_ext.h" #include "stack/rfcomm/rfc_int.h" #include "types/raw_address.h" -#include +using namespace bluetooth; /******************************************************************************* * @@ -133,15 +137,13 @@ tRFC_MCB* rfc_alloc_multiplexer_channel(const RawAddress& bd_addr, bool is_initiator) { int i, j; tRFC_MCB* p_mcb = NULL; - VLOG(1) << __func__ << ": bd_addr:" << ADDRESS_TO_LOGGABLE_STR(bd_addr); - LOG_VERBOSE("rfc_alloc_multiplexer_channel:is_initiator:%d", is_initiator); + log::verbose("bd_addr:{}, is_initiator:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + is_initiator); for (i = 0; i < MAX_BD_CONNECTIONS; i++) { - LOG_VERBOSE( - "rfc_alloc_multiplexer_channel rfc_cb.port.rfc_mcb[%d].state:%d", i, - rfc_cb.port.rfc_mcb[i].state); - VLOG(1) << "(rfc_cb.port.rfc_mcb[i].bd_addr:" - << ADDRESS_TO_LOGGABLE_STR(rfc_cb.port.rfc_mcb[i].bd_addr); + log::verbose("rfc_cb.port.rfc_mcb[{}] - state:{}, bd_addr:{}", i, + rfc_cb.port.rfc_mcb[i].state, + ADDRESS_TO_LOGGABLE_CSTR(rfc_cb.port.rfc_mcb[i].bd_addr)); if ((rfc_cb.port.rfc_mcb[i].state != RFC_MX_STATE_IDLE) && rfc_cb.port.rfc_mcb[i].bd_addr == bd_addr) { @@ -149,10 +151,11 @@ tRFC_MCB* rfc_alloc_multiplexer_channel(const RawAddress& bd_addr, /* If there was an inactivity timer running stop it now */ if (rfc_cb.port.rfc_mcb[i].state == RFC_MX_STATE_CONNECTED) rfc_timer_stop(&rfc_cb.port.rfc_mcb[i]); - LOG_VERBOSE( - "rfc_alloc_multiplexer_channel:is_initiator:%d, found, state:%d, " - "p_mcb:%p", - is_initiator, rfc_cb.port.rfc_mcb[i].state, &rfc_cb.port.rfc_mcb[i]); + log::verbose( + "rfc_alloc_multiplexer_channel:is_initiator:{}, found, state:{}, " + "p_mcb:{}", + is_initiator, rfc_cb.port.rfc_mcb[i].state, + fmt::ptr(&rfc_cb.port.rfc_mcb[i])); return (&rfc_cb.port.rfc_mcb[i]); } } @@ -168,10 +171,10 @@ tRFC_MCB* rfc_alloc_multiplexer_channel(const RawAddress& bd_addr, fixed_queue_free(p_mcb->cmd_q, NULL); memset(p_mcb, 0, sizeof(tRFC_MCB)); p_mcb->bd_addr = bd_addr; - LOG_VERBOSE( - "rfc_alloc_multiplexer_channel:is_initiator:%d, create new p_mcb:%p, " - "index:%d", - is_initiator, &rfc_cb.port.rfc_mcb[j], j); + log::verbose( + "rfc_alloc_multiplexer_channel:is_initiator:{}, create new p_mcb:{}, " + "index:{}", + is_initiator, fmt::ptr(&rfc_cb.port.rfc_mcb[j]), j); p_mcb->mcb_timer = alarm_new("rfcomm_mcb.mcb_timer"); p_mcb->cmd_q = fixed_queue_new(SIZE_MAX); @@ -221,7 +224,7 @@ void rfc_release_multiplexer_channel(tRFC_MCB* p_mcb) { * ******************************************************************************/ void rfc_timer_start(tRFC_MCB* p_mcb, uint16_t timeout) { - LOG_VERBOSE("%s - timeout:%d seconds", __func__, timeout); + log::verbose("- timeout:{} seconds", timeout); uint64_t interval_ms = timeout * 1000; alarm_set_on_mloop(p_mcb->mcb_timer, interval_ms, rfcomm_mcb_timer_timeout, @@ -236,7 +239,7 @@ void rfc_timer_start(tRFC_MCB* p_mcb, uint16_t timeout) { * ******************************************************************************/ void rfc_timer_stop(tRFC_MCB* p_mcb) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); alarm_cancel(p_mcb->mcb_timer); } @@ -249,7 +252,7 @@ void rfc_timer_stop(tRFC_MCB* p_mcb) { * ******************************************************************************/ void rfc_port_timer_start(tPORT* p_port, uint16_t timeout) { - LOG_VERBOSE("%s - timeout:%d seconds", __func__, timeout); + log::verbose("- timeout:{} seconds", timeout); uint64_t interval_ms = timeout * 1000; alarm_set_on_mloop(p_port->rfc.port_timer, interval_ms, @@ -264,7 +267,7 @@ void rfc_port_timer_start(tPORT* p_port, uint16_t timeout) { * ******************************************************************************/ void rfc_port_timer_stop(tPORT* p_port) { - LOG_VERBOSE("%s", __func__); + log::verbose(""); alarm_cancel(p_port->rfc.port_timer); } @@ -377,7 +380,7 @@ void rfc_inc_credit(tPORT* p_port, uint8_t credit) { if (p_port->rfc.p_mcb->flow == PORT_FC_CREDIT) { p_port->credit_tx += credit; - LOG_VERBOSE("rfc_inc_credit:%d", p_port->credit_tx); + log::verbose("rfc_inc_credit:{}", p_port->credit_tx); if (p_port->tx.peer_fc) PORT_FlowInd(p_port->rfc.p_mcb, p_port->dlci, true); } @@ -416,9 +419,9 @@ void rfc_check_send_cmd(tRFC_MCB* p_mcb, BT_HDR* p_buf) { /* if passed a buffer queue it */ if (p_buf != NULL) { if (p_mcb->cmd_q == NULL) { - LOG_ERROR( - "%s: empty queue: p_mcb = %p p_mcb->lcid = %u cached p_mcb = %p", - __func__, p_mcb, p_mcb->lcid, rfc_find_lcid_mcb(p_mcb->lcid)); + log::error("empty queue: p_mcb = {} p_mcb->lcid = {} cached p_mcb = {}", + fmt::ptr(p_mcb), p_mcb->lcid, + fmt::ptr(rfc_find_lcid_mcb(p_mcb->lcid))); } fixed_queue_enqueue(p_mcb->cmd_q, p_buf); } diff --git a/system/stack/sdp/sdp_api.cc b/system/stack/sdp/sdp_api.cc index 22d2d0430f85c30e9e8df5a77fc680c1e6bd0850..aad95adb17e29ef27527fed1bae18d7ccb589280 100644 --- a/system/stack/sdp/sdp_api.cc +++ b/system/stack/sdp/sdp_api.cc @@ -26,21 +26,24 @@ #include "stack/include/sdp_api.h" +#include #include #include -#include "bt_target.h" -#include "osi/include/log.h" -#include "osi/include/osi.h" // PTR_TO_UINT + +#include "internal_include/bt_target.h" +#include "os/log.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "stack/include/sdp_api.h" +#include "stack/include/sdpdefs.h" #include "stack/sdp/internal/sdp_api.h" #include "stack/sdp/sdpint.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; /********************************************************************** * C L I E N T F U N C T I O N P R O T O T Y P E S * @@ -76,10 +79,10 @@ bool SDP_InitDiscoveryDb(tSDP_DISCOVERY_DB* p_db, uint32_t len, /* verify the parameters */ if (p_db == NULL || (sizeof(tSDP_DISCOVERY_DB) > len) || num_attr > SDP_MAX_ATTR_FILTERS || num_uuid > SDP_MAX_UUID_FILTERS) { - LOG_ERROR( - "SDP_InitDiscoveryDb Illegal param: p_db 0x%x, len %d, num_uuid %d, " - "num_attr %d", - PTR_TO_UINT(p_db), len, num_uuid, num_attr); + log::error( + "SDP_InitDiscoveryDb Illegal param: p_db {}, len {}, num_uuid {}, " + "num_attr {}", + fmt::ptr(p_db), len, num_uuid, num_attr); return (false); } @@ -394,13 +397,14 @@ tSDP_DISC_REC* SDP_FindServiceInDb(const tSDP_DISCOVERY_DB* p_db, p_sattr = p_sattr->p_next_attr) { if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE) && (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 2)) { - LOG_VERBOSE( - "SDP_FindServiceInDb - p_sattr value = 0x%x serviceuuid = 0x%x", + log::verbose( + "SDP_FindServiceInDb - p_sattr value = 0x{:x} serviceuuid = " + "0x{:x}", p_sattr->attr_value.v.u16, service_uuid); if (service_uuid == UUID_SERVCLASS_HDP_PROFILE) { if ((p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SOURCE) || (p_sattr->attr_value.v.u16 == UUID_SERVCLASS_HDP_SINK)) { - LOG_VERBOSE("SDP_FindServiceInDb found HDP source or sink\n"); + log::verbose("SDP_FindServiceInDb found HDP source or sink\n"); return (p_rec); } } @@ -805,11 +809,10 @@ static void SDP_AttrStringCopy(char* dst, const tSDP_DISC_ATTR* p_attr, memcpy(dst, (const void*)p_attr->attr_value.v.array, len); dst[len] = '\0'; } else { - LOG_ERROR("unexpected attr type=%d, expected=%d", - type, expected_type); + log::error("unexpected attr type={}, expected={}", type, expected_type); } } else { - LOG_ERROR("p_attr is NULL"); + log::error("p_attr is NULL"); } } diff --git a/system/stack/sdp/sdp_db.cc b/system/stack/sdp/sdp_db.cc index a4326272dced308d150444b767283ef23418bad8..7ec98fbbcc5abe246348d77d3f7d91997c44353a 100644 --- a/system/stack/sdp/sdp_db.cc +++ b/system/stack/sdp/sdp_db.cc @@ -25,19 +25,22 @@ #define LOG_TAG "sdp" +#include #include #include -#include "bt_target.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "stack/include/sdpdefs.h" #include "stack/sdp/sdp_discovery_db.h" #include "stack/sdp/sdpint.h" +using namespace bluetooth; + /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ /******************************************************************************/ @@ -125,7 +128,7 @@ static bool find_uuid_in_seq(uint8_t* p, uint32_t seq_len, type = *p++; p = sdpu_get_len_from_type(p, p_end, type, &len); if (p == NULL || (p + len) > p_end) { - LOG_WARN("%s: bad length", __func__); + log::warn("bad length"); break; } type = type >> 3; @@ -275,7 +278,7 @@ uint32_t SDP_CreateRecord(void) { p_db->record[p_db->num_records].record_handle = handle; p_db->num_records++; - LOG_VERBOSE("SDP_CreateRecord ok, num_records:%d", p_db->num_records); + log::verbose("SDP_CreateRecord ok, num_records:{}", p_db->num_records); /* Add the first attribute (the handle) automatically */ UINT32_TO_BE_FIELD(buf, handle); SDP_AddAttribute(handle, ATTR_ID_SERVICE_RECORD_HDL, UINT_DESC_TYPE, 4, @@ -283,8 +286,8 @@ uint32_t SDP_CreateRecord(void) { return (p_db->record[p_db->num_records - 1].record_handle); } else - LOG_ERROR("SDP_CreateRecord fail, exceed maximum records:%d", - SDP_MAX_RECORDS); + log::error("SDP_CreateRecord fail, exceed maximum records:{}", + SDP_MAX_RECORDS); return (0); } @@ -328,8 +331,8 @@ bool SDP_DeleteRecord(uint32_t handle) { sdp_cb.server_db.num_records--; - LOG_VERBOSE("SDP_DeleteRecord ok, num_records:%d", - sdp_cb.server_db.num_records); + log::verbose("SDP_DeleteRecord ok, num_records:{}", + sdp_cb.server_db.num_records); /* if we're deleting the primary DI record, clear the */ /* value in the control block */ if (sdp_cb.server_db.di_primary_handle == handle) { @@ -363,7 +366,7 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type, tSDP_RECORD* p_rec = &sdp_cb.server_db.record[0]; if (p_val == nullptr) { - LOG_WARN("Trying to add attribute with p_val == nullptr, skipped"); + log::warn("Trying to add attribute with p_val == nullptr, skipped"); return (false); } @@ -378,39 +381,41 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type, #define MAX_ARR_LEN 200 // one extra byte for storing terminating zero byte - uint8_t num_array[2 * MAX_ARR_LEN + 1] = {0}; + char num_array[2 * MAX_ARR_LEN + 1] = {0}; uint32_t len = (attr_len > MAX_ARR_LEN) ? MAX_ARR_LEN : attr_len; #undef MAX_ARR_LEN for (uint32_t i = 0; i < len; i++) { - snprintf((char*)&num_array[i * 2], sizeof(num_array) - i * 2, "%02X", + snprintf(&num_array[i * 2], sizeof(num_array) - i * 2, "%02X", (uint8_t)(p_val[i])); } - LOG_VERBOSE( - "SDP_AddAttribute: handle:%X, id:%04X, type:%d, len:%d, p_val:%p, " - "*p_val:%s", - handle, attr_id, attr_type, attr_len, p_val, num_array); + log::verbose( + "SDP_AddAttribute: handle:{:X}, id:{:04X}, type:{}, len:{}, " + "p_val:{}, *p_val:{}", + handle, attr_id, attr_type, attr_len, fmt::ptr(p_val), num_array); } else if (attr_type == BOOLEAN_DESC_TYPE) { - LOG_VERBOSE( - "SDP_AddAttribute: handle:%X, id:%04X, type:%d, len:%d, p_val:%p, " - "*p_val:%d", - handle, attr_id, attr_type, attr_len, p_val, *p_val); + log::verbose( + "SDP_AddAttribute: handle:{:X}, id:{:04X}, type:{}, len:{}, " + "p_val:{}, *p_val:{}", + handle, attr_id, attr_type, attr_len, fmt::ptr(p_val), *p_val); } else if ((attr_type == TEXT_STR_DESC_TYPE) || (attr_type == URL_DESC_TYPE)) { if (p_val[attr_len - 1] == '\0') { - LOG_VERBOSE( - "SDP_AddAttribute: handle:%X, id:%04X, type:%d, len:%d, p_val:%p, " - "*p_val:%s", - handle, attr_id, attr_type, attr_len, p_val, (char*)p_val); + log::verbose( + "SDP_AddAttribute: handle:{:X}, id:{:04X}, type:{}, len:{}, " + "p_val:{}, *p_val:{}", + handle, attr_id, attr_type, attr_len, fmt::ptr(p_val), + (char*)p_val); } else { - LOG_VERBOSE( - "SDP_AddAttribute: handle:%X, id:%04X, type:%d, len:%d, p_val:%p", - handle, attr_id, attr_type, attr_len, p_val); + log::verbose( + "SDP_AddAttribute: handle:{:X}, id:{:04X}, type:{}, len:{}, " + "p_val:{}", + handle, attr_id, attr_type, attr_len, fmt::ptr(p_val)); } } else { - LOG_VERBOSE( - "SDP_AddAttribute: handle:%X, id:%04X, type:%d, len:%d, p_val:%p", - handle, attr_id, attr_type, attr_len, p_val); + log::verbose( + "SDP_AddAttribute: handle:{:X}, id:{:04X}, type:{}, len:{}, p_val:{}", + handle, attr_id, attr_type, attr_len, fmt::ptr(p_val)); } } @@ -420,9 +425,9 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type, // error out early, no need to look up if (p_rec->free_pad_ptr >= SDP_MAX_PAD_LEN) { - LOG_ERROR( - "the free pad for SDP record with handle %d is " - "full, skip adding the attribute", + log::error( + "the free pad for SDP record with handle {} is full, skip adding " + "the attribute", handle); return (false); } @@ -481,17 +486,17 @@ bool SDP_AddAttributeToRecord(tSDP_RECORD* p_rec, uint16_t attr_id, if (p_rec->free_pad_ptr + attr_len >= SDP_MAX_PAD_LEN) { if (p_rec->free_pad_ptr >= SDP_MAX_PAD_LEN) { - LOG_ERROR( - "SDP_AddAttributeToRecord failed: free pad %d equals or exceeds max " - "padding length %d", + log::error( + "SDP_AddAttributeToRecord failed: free pad {} equals or exceeds max " + "padding length {}", p_rec->free_pad_ptr, SDP_MAX_PAD_LEN); return (false); } /* do truncate only for text string type descriptor */ if (attr_type == TEXT_STR_DESC_TYPE) { - LOG_WARN( - "SDP_AddAttributeToRecord: attr_len:%d too long. truncate to (%d)", + log::warn( + "SDP_AddAttributeToRecord: attr_len:{} too long. truncate to ({})", attr_len, SDP_MAX_PAD_LEN - p_rec->free_pad_ptr); attr_len = SDP_MAX_PAD_LEN - p_rec->free_pad_ptr; @@ -507,9 +512,9 @@ bool SDP_AddAttributeToRecord(tSDP_RECORD* p_rec, uint16_t attr_id, p_rec->free_pad_ptr += attr_len; } else if (attr_len == 0 && p_attr->len != 0) { /* if truncate to 0 length, simply don't add */ - LOG_ERROR( - "SDP_AddAttributeToRecord fail, length exceed maximum: ID %d: " - "attr_len:%d ", + log::error( + "SDP_AddAttributeToRecord fail, length exceed maximum: ID {}: " + "attr_len:{}", attr_id, attr_len); p_attr->id = p_attr->type = p_attr->len = 0; return (false); @@ -575,12 +580,12 @@ bool SDP_AddSequence(uint32_t handle, uint16_t attr_id, uint16_t num_elem, p = p_head; if (p_head == p_buff) { /* the first element exceed the max length */ - LOG_ERROR("SDP_AddSequence - too long(attribute is not added)!!"); + log::error("SDP_AddSequence - too long(attribute is not added)!!"); osi_free(p_buff); return false; } else - LOG_ERROR("SDP_AddSequence - too long, add %d elements of %d", xx, - num_elem); + log::error("SDP_AddSequence - too long, add {} elements of {}", xx, + num_elem); break; } } @@ -619,8 +624,8 @@ bool SDP_AddUuidSequence(uint32_t handle, uint16_t attr_id, uint16_t num_uuids, UINT16_TO_BE_STREAM(p, *p_uuids); if ((p - p_buff) > max_len) { - LOG_WARN("SDP_AddUuidSequence - too long, add %d uuids of %d", xx, - num_uuids); + log::warn("SDP_AddUuidSequence - too long, add {} uuids of {}", xx, + num_uuids); break; } } diff --git a/system/stack/sdp/sdp_discovery.cc b/system/stack/sdp/sdp_discovery.cc index 5238c06696e481a8fa1cc6583ed32a02d13fc12c..a007c1e7da1725cafb4d28d07df9a30e9a961ed6 100644 --- a/system/stack/sdp/sdp_discovery.cc +++ b/system/stack/sdp/sdp_discovery.cc @@ -24,9 +24,11 @@ #define LOG_TAG "sdp_discovery" +#include + #include -#include "bt_target.h" +#include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" @@ -38,6 +40,7 @@ #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; /******************************************************************************/ /* L O C A L F U N C T I O N P R O T O T Y P E S */ @@ -277,7 +280,7 @@ void sdp_disc_server_rsp(tCONN_CB* p_ccb, BT_HDR* p_msg) { } if (invalid_pdu) { - LOG_WARN("SDP - Unexp. PDU: %d in state: %d", rsp_pdu, p_ccb->disc_state); + log::warn("SDP - Unexp. PDU: {} in state: {}", rsp_pdu, p_ccb->disc_state); sdp_disconnect(p_ccb, SDP_GENERIC_ERROR); } } @@ -310,7 +313,7 @@ static void process_service_search_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, orig = p_ccb->num_handles; p_ccb->num_handles += cur_handles; if (p_ccb->num_handles == 0 || p_ccb->num_handles < orig) { - LOG_WARN("SDP - Rcvd ServiceSearchRsp, no matches"); + log::warn("SDP - Rcvd ServiceSearchRsp, no matches"); sdp_disconnect(p_ccb, SDP_NO_RECS_MATCH); return; } @@ -380,11 +383,11 @@ static bool sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { uint8_t* old_p = p; p = sdpu_get_len_from_type(p, p_end, type, &list_len); if (p == NULL || (p + list_len) > p_end) { - LOG_WARN("%s: bad length", __func__); + log::warn("bad length"); return false; } if ((int)cpy_len < (p - old_p)) { - LOG_WARN("%s: no bytes left for data", __func__); + log::warn("no bytes left for data"); return false; } cpy_len -= (p - old_p); @@ -394,7 +397,7 @@ static bool sdp_copy_raw_data(tCONN_CB* p_ccb, bool offset) { } rem_len = SDP_MAX_LIST_BYTE_COUNT - (unsigned int)(p - &p_ccb->rsp_list[0]); if (cpy_len > rem_len) { - LOG_WARN("rem_len :%d less than cpy_len:%d", rem_len, cpy_len); + log::warn("rem_len :{} less than cpy_len:{}", rem_len, cpy_len); cpy_len = rem_len; } memcpy(&p_ccb->p_db->raw_data[p_ccb->p_db->raw_used], p, cpy_len); @@ -456,9 +459,9 @@ static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, } cont_request_needed = true; } else { - LOG_WARN("process_service_attr_rsp"); + log::warn("process_service_attr_rsp"); if (!sdp_copy_raw_data(p_ccb, false)) { - LOG_ERROR("sdp_copy_raw_data failed"); + log::error("sdp_copy_raw_data failed"); sdp_disconnect(p_ccb, SDP_ILLEGAL_PARAMETER); return; } @@ -666,7 +669,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, /*******************************************************************/ if (!sdp_copy_raw_data(p_ccb, true)) { - LOG_ERROR("sdp_copy_raw_data failed"); + log::error("sdp_copy_raw_data failed"); sdp_disconnect(p_ccb, SDP_ILLEGAL_PARAMETER); return; } @@ -677,13 +680,13 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, type = *p++; if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) { - LOG_WARN("Wrong element in attr_rsp type:0x%02x", type); + log::warn("Wrong element in attr_rsp type:0x{:02x}", type); sdp_disconnect(p_ccb, SDP_ILLEGAL_PARAMETER); return; } p = sdpu_get_len_from_type(p, p + p_ccb->list_len, type, &seq_len); if (p == NULL || (p + seq_len) > (p + p_ccb->list_len)) { - LOG_WARN("Illegal search attribute length"); + log::warn("Illegal search attribute length"); sdp_disconnect(p_ccb, SDP_ILLEGAL_PARAMETER); return; } @@ -726,19 +729,19 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { type = *p++; if ((type >> 3) != DATA_ELE_SEQ_DESC_TYPE) { - LOG_WARN("SDP - Wrong type: 0x%02x in attr_rsp", type); + log::warn("SDP - Wrong type: 0x{:02x} in attr_rsp", type); return (NULL); } p = sdpu_get_len_from_type(p, p_msg_end, type, &seq_len); if (p == NULL || (p + seq_len) > p_msg_end) { - LOG_WARN("SDP - Bad len in attr_rsp %d", seq_len); + log::warn("SDP - Bad len in attr_rsp {}", seq_len); return (NULL); } /* Create a record */ p_rec = add_record(p_ccb->p_db, p_ccb->device_address); if (!p_rec) { - LOG_WARN("SDP - DB full add_record"); + log::warn("SDP - DB full add_record"); return (NULL); } @@ -749,11 +752,12 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { type = *p++; p = sdpu_get_len_from_type(p, p_msg_end, type, &attr_len); if (p == NULL || (p + attr_len) > p_seq_end) { - LOG_WARN("%s: Bad len in attr_rsp %d", __func__, attr_len); + log::warn("Bad len in attr_rsp {}", attr_len); return (NULL); } if (((type >> 3) != UINT_DESC_TYPE) || (attr_len != 2)) { - LOG_WARN("SDP - Bad type: 0x%02x or len: %d in attr_rsp", type, attr_len); + log::warn("SDP - Bad type: 0x{:02x} or len: {} in attr_rsp", type, + attr_len); return (NULL); } BE_STREAM_TO_UINT16(attr_id, p); @@ -762,7 +766,7 @@ static uint8_t* save_attr_seq(tCONN_CB* p_ccb, uint8_t* p, uint8_t* p_msg_end) { p = add_attr(p, p_seq_end, p_ccb->p_db, p_rec, attr_id, NULL, 0); if (!p) { - LOG_WARN("SDP - DB full add_attr"); + log::warn("SDP - DB full add_attr"); return (NULL); } } @@ -836,7 +840,7 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, type = *p++; p = sdpu_get_len_from_type(p, p_end, type, &attr_len); if (p == NULL || (p + attr_len) > p_end) { - LOG_WARN("%s: bad length in attr_rsp", __func__); + log::warn("bad length in attr_rsp"); return NULL; } attr_len &= SDP_DISC_ATTR_LEN_MASK; @@ -850,7 +854,7 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, p_attr_end = p + attr_len; if (p_attr_end > p_end) { - LOG_WARN("%s: SDP - Attribute length beyond p_end", __func__); + log::warn("SDP - Attribute length beyond p_end"); return NULL; } @@ -881,7 +885,7 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, /* LOG_VERBOSE ("SDP - attr nest level:%d(list)", nest_level); */ if (nest_level >= MAX_NEST_LEVELS) { - LOG_ERROR("SDP - attr nesting too deep"); + log::error("SDP - attr nesting too deep"); return p_attr_end; } @@ -945,7 +949,7 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, } break; default: - LOG_WARN("SDP - bad len in UUID attr: %d", attr_len); + log::warn("SDP - bad len in UUID attr: {}", attr_len); return p_attr_end; } break; @@ -960,7 +964,7 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, /* LOG_VERBOSE ("SDP - attr nest level:%d", nest_level); */ if (nest_level >= MAX_NEST_LEVELS) { - LOG_ERROR("SDP - attr nesting too deep"); + log::error("SDP - attr nesting too deep"); return p_attr_end; } if (is_additional_list != 0 || @@ -988,7 +992,7 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db, p_attr->attr_value.v.u8 = *p++; break; default: - LOG_WARN("SDP - bad len in boolean attr: %d", attr_len); + log::warn("SDP - bad len in boolean attr: {}", attr_len); return p_attr_end; } break; diff --git a/system/stack/sdp/sdp_discovery_db.h b/system/stack/sdp/sdp_discovery_db.h index f67f026cc37524bed26ec01a55084c3080680728..ac727df406e6310be062a7dc27f3eb10cb10bede 100644 --- a/system/stack/sdp/sdp_discovery_db.h +++ b/system/stack/sdp/sdp_discovery_db.h @@ -16,12 +16,13 @@ * ******************************************************************************/ +#pragma once + #include -#include "bt_target.h" // SDP_MAX_PROTOCOL_PARAMS +#include "internal_include/bt_target.h" #include "types/bluetooth/uuid.h" - -#pragma once +#include "types/raw_address.h" /* Masks for attr_value field of tSDP_DISC_ATTR */ #define SDP_DISC_ATTR_LEN_MASK 0x0FFF diff --git a/system/stack/sdp/sdp_main.cc b/system/stack/sdp/sdp_main.cc index 829268f3c3de4b0c7c2caec8d7db7f5800c85d1a..8070636367ed1167cbbebc285f3c185fb8b4c7da 100644 --- a/system/stack/sdp/sdp_main.cc +++ b/system/stack/sdp/sdp_main.cc @@ -25,11 +25,13 @@ #define LOG_TAG "sdp" #include +#include #include // memset -#include "gd/common/init_flags.h" +#include "common/init_flags.h" +#include "internal_include/bt_target.h" +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/bt_hdr.h" #include "stack/include/bt_psm_types.h" @@ -38,6 +40,8 @@ #include "stack/sdp/sdpint.h" #include "types/raw_address.h" +using namespace bluetooth; + /******************************************************************************/ /* G L O B A L S D P D A T A */ /******************************************************************************/ @@ -94,7 +98,7 @@ void sdp_init(void) { /* Now, register with L2CAP */ if (!L2CA_Register2(BT_PSM_SDP, sdp_cb.reg_info, true /* enable_snoop */, nullptr, SDP_MTU_SIZE, 0, BTM_SEC_NONE)) { - LOG_ERROR("SDP Registration failed"); + log::error("SDP Registration failed"); } } @@ -152,7 +156,7 @@ static void sdp_connect_cfm(uint16_t l2cap_cid, uint16_t result) { /* Find CCB based on CID */ p_ccb = sdpu_find_ccb_by_cid(l2cap_cid); if (p_ccb == NULL) { - LOG_WARN("SDP - Rcvd conn cnf for unknown CID 0x%x", l2cap_cid); + log::warn("SDP - Rcvd conn cnf for unknown CID 0x{:x}", l2cap_cid); return; } @@ -161,7 +165,7 @@ static void sdp_connect_cfm(uint16_t l2cap_cid, uint16_t result) { if ((result == L2CAP_CONN_OK) && (p_ccb->con_state == SDP_STATE_CONN_SETUP)) { p_ccb->con_state = SDP_STATE_CFG_SETUP; } else { - LOG(ERROR) << __func__ << ": invoked with non OK status"; + log::error("invoked with non OK status"); } } @@ -181,7 +185,7 @@ static void sdp_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg) { /* Find CCB based on CID */ p_ccb = sdpu_find_ccb_by_cid(l2cap_cid); if (p_ccb == NULL) { - LOG_WARN("SDP - Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); + log::warn("SDP - Rcvd L2CAP cfg ind, unknown CID: 0x{:x}", l2cap_cid); return; } @@ -197,7 +201,7 @@ static void sdp_config_ind(uint16_t l2cap_cid, tL2CAP_CFG_INFO* p_cfg) { p_ccb->rem_mtu_size = p_cfg->mtu; } - LOG_VERBOSE("SDP - Rcvd cfg ind, sent cfg cfm, CID: 0x%x", l2cap_cid); + log::verbose("SDP - Rcvd cfg ind, sent cfg cfm, CID: 0x{:x}", l2cap_cid); } /******************************************************************************* @@ -216,12 +220,12 @@ static void sdp_config_cfm(uint16_t l2cap_cid, uint16_t initiator, tCONN_CB* p_ccb; - LOG_VERBOSE("SDP - Rcvd cfg cfm, CID: 0x%x", l2cap_cid); + log::verbose("SDP - Rcvd cfg cfm, CID: 0x{:x}", l2cap_cid); /* Find CCB based on CID */ p_ccb = sdpu_find_ccb_by_cid(l2cap_cid); if (p_ccb == NULL) { - LOG_WARN("SDP - Rcvd L2CAP cfg ind, unknown CID: 0x%x", l2cap_cid); + log::warn("SDP - Rcvd L2CAP cfg ind, unknown CID: 0x{:x}", l2cap_cid); return; } @@ -253,7 +257,7 @@ static void sdp_disconnect_ind(uint16_t l2cap_cid, bool ack_needed) { /* Find CCB based on CID */ p_ccb = sdpu_find_ccb_by_cid(l2cap_cid); if (p_ccb == NULL) { - LOG_WARN("SDP - Rcvd L2CAP disc, unknown CID: 0x%x", l2cap_cid); + log::warn("SDP - Rcvd L2CAP disc, unknown CID: 0x{:x}", l2cap_cid); return; } tCONN_CB& ccb = *p_ccb; @@ -263,10 +267,10 @@ static void sdp_disconnect_ind(uint16_t l2cap_cid, bool ack_needed) { sdpu_callback(ccb, reason); if (ack_needed) { - LOG_WARN("SDP - Rcvd L2CAP disc, process pend sdp ccb: 0x%x", l2cap_cid); + log::warn("SDP - Rcvd L2CAP disc, process pend sdp ccb: 0x{:x}", l2cap_cid); sdpu_process_pend_ccb_new_cid(ccb); } else { - LOG_WARN("SDP - Rcvd L2CAP disc, clear pend sdp ccb: 0x%x", l2cap_cid); + log::warn("SDP - Rcvd L2CAP disc, clear pend sdp ccb: 0x{:x}", l2cap_cid); sdpu_clear_pend_ccb(ccb); } @@ -300,11 +304,11 @@ static void sdp_data_ind(uint16_t l2cap_cid, BT_HDR* p_msg) { else sdp_server_handle_client_req(p_ccb, p_msg); } else { - LOG_WARN("SDP - Ignored L2CAP data while in state: %d, CID: 0x%x", - p_ccb->con_state, l2cap_cid); + log::warn("SDP - Ignored L2CAP data while in state: {}, CID: 0x{:x}", + p_ccb->con_state, l2cap_cid); } } else { - LOG_WARN("SDP - Rcvd L2CAP data, unknown CID: 0x%x", l2cap_cid); + log::warn("SDP - Rcvd L2CAP data, unknown CID: 0x{:x}", l2cap_cid); } osi_free(p_msg); @@ -327,13 +331,12 @@ tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr) { /* Allocate a new CCB. Return if none available. */ p_ccb = sdpu_allocate_ccb(); if (p_ccb == NULL) { - LOG_WARN("%s: no spare CCB for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr)); + log::warn("no spare CCB for peer {}", ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr)); return (NULL); } - LOG_VERBOSE("%s: SDP - Originate started for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr)); + log::verbose("SDP - Originate started for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr)); /* Look for any active sdp connection on the remote device */ cid = sdpu_get_active_ccb_cid(p_bd_addr); @@ -351,14 +354,14 @@ tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr) { cid = L2CA_ConnectReq2(BT_PSM_SDP, p_bd_addr, BTM_SEC_NONE); } else { p_ccb->con_state = SDP_STATE_CONN_PEND; - LOG_WARN("SDP already active for peer %s. cid=%#0x", - ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr), cid); + log::warn("SDP already active for peer {}. cid={:#0x}", + ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr), cid); } /* Check if L2CAP started the connection process */ if (cid == 0) { - LOG_WARN("%s: SDP - Originate failed for peer %s", __func__, - ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr)); + log::warn("SDP - Originate failed for peer {}", + ADDRESS_TO_LOGGABLE_CSTR(p_bd_addr)); sdpu_release_ccb(*p_ccb); return (NULL); } @@ -377,7 +380,7 @@ tCONN_CB* sdp_conn_originate(const RawAddress& p_bd_addr) { ******************************************************************************/ void sdp_disconnect(tCONN_CB* p_ccb, tSDP_REASON reason) { tCONN_CB& ccb = *p_ccb; - LOG_VERBOSE("SDP - disconnect CID: 0x%x", ccb.connection_id); + log::verbose("SDP - disconnect CID: 0x{:x}", ccb.connection_id); /* Check if we have a connection ID */ if (ccb.connection_id != 0) { @@ -416,12 +419,12 @@ static void sdp_disconnect_cfm(uint16_t l2cap_cid, /* Find CCB based on CID */ p_ccb = sdpu_find_ccb_by_cid(l2cap_cid); if (p_ccb == NULL) { - LOG_WARN("SDP - Rcvd L2CAP disc cfm, unknown CID: 0x%x", l2cap_cid); + log::warn("SDP - Rcvd L2CAP disc cfm, unknown CID: 0x{:x}", l2cap_cid); return; } tCONN_CB& ccb = *p_ccb; - LOG_VERBOSE("SDP - Rcvd L2CAP disc cfm, CID: 0x%x", l2cap_cid); + log::verbose("SDP - Rcvd L2CAP disc cfm, CID: 0x{:x}", l2cap_cid); sdpu_callback(ccb, static_cast(ccb.disconnect_reason)); sdpu_process_pend_ccb_new_cid(ccb); @@ -441,8 +444,8 @@ static void sdp_disconnect_cfm(uint16_t l2cap_cid, void sdp_conn_timer_timeout(void* data) { tCONN_CB& ccb = *(tCONN_CB*)data; - LOG_VERBOSE("SDP - CCB timeout in state: %d CID: 0x%x", ccb.con_state, - ccb.connection_id); + log::verbose("SDP - CCB timeout in state: {} CID: 0x{:x}", ccb.con_state, + ccb.connection_id); L2CA_DisconnectReq(ccb.connection_id); diff --git a/system/stack/sdp/sdp_server.cc b/system/stack/sdp/sdp_server.cc index 3bbb8fc63566e0236ed84d84a6912dc79aa81b52..20dbb3823687c0522537f4a9b5f0f11442d260a3 100644 --- a/system/stack/sdp/sdp_server.cc +++ b/system/stack/sdp/sdp_server.cc @@ -24,15 +24,18 @@ ******************************************************************************/ #define LOG_TAG "sdp_server" +#include +#include #include // memcpy #include #include "btif/include/btif_profile_storage.h" #include "btif/include/btif_storage.h" +#include "common/init_flags.h" #include "device/include/interop.h" #include "device/include/interop_config.h" -#include "gd/common/init_flags.h" +#include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/properties.h" @@ -64,6 +67,8 @@ #define PBAP_1_2 0x0102 #define PBAP_1_2_BL_LEN 14 +using namespace bluetooth; + /* Used to set PBAP local SDP device record for PBAP 1.2 upgrade */ typedef struct { int32_t rfcomm_channel_number; @@ -178,9 +183,9 @@ bool sdp_dynamic_change_hfp_version(const tSDP_ATTRIBUTE* p_attr, } else { p_attr->value_ptr[PROFILE_VERSION_POSITION] = HFP_PROFILE_MINOR_VERSION_7; } - LOG_VERBOSE("%s SDP Change HFP Version = %d for %s", __func__, - p_attr->value_ptr[PROFILE_VERSION_POSITION], - ADDRESS_TO_LOGGABLE_CSTR(remote_address)); + log::verbose("SDP Change HFP Version = {} for {}", + p_attr->value_ptr[PROFILE_VERSION_POSITION], + ADDRESS_TO_LOGGABLE_CSTR(remote_address)); return true; } /****************************************************************************** @@ -195,7 +200,7 @@ bool sdp_dynamic_change_hfp_version(const tSDP_ATTRIBUTE* p_attr, void hfp_fallback(bool& is_hfp_fallback, const tSDP_ATTRIBUTE* p_attr) { /* Update HFP version back to 1.6 */ p_attr->value_ptr[PROFILE_VERSION_POSITION] = HFP_PROFILE_MINOR_VERSION_6; - LOG_VERBOSE("Restore HFP version to 1.6"); + log::verbose("Restore HFP version to 1.6"); is_hfp_fallback = false; } @@ -264,7 +269,7 @@ void sdp_server_handle_client_req(tCONN_CB* p_ccb, BT_HDR* p_msg) { default: sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX, SDP_TEXT_BAD_PDU); - LOG_WARN("SDP - server got unknown PDU: 0x%x", pdu_id); + log::warn("SDP - server got unknown PDU: 0x{:x}", pdu_id); break; } } @@ -377,10 +382,10 @@ static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num, UINT16_TO_BE_STREAM(p_rsp, num_rsp_handles); UINT16_TO_BE_STREAM(p_rsp, cur_handles); - /* LOG_VERBOSE("SDP Service Rsp: tothdl %d, curhdlr %d, start %d, end %d, - cont %d", - num_rsp_handles, cur_handles, cont_offset, - cont_offset + cur_handles-1, is_cont); */ + /* + log::verbose("SDP Service Rsp: tothdl {}, curhdlr {}, start {}, end {}, cont + {}", num_rsp_handles, cur_handles, cont_offset, cont_offset + cur_handles-1, + is_cont); */ for (xx = cont_offset; xx < cont_offset + cur_handles; xx++) UINT32_TO_BE_STREAM(p_rsp, rsp_handles[xx]); @@ -472,7 +477,7 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, pbap_pse_dynamic_version_upgrade_is_enabled()) { p_rec = sdp_upgrade_pse_record(p_rec, p_ccb->device_address); } else { - LOG_WARN("PBAP PSE dynamic version upgrade is not enabled"); + log::warn("PBAP PSE dynamic version upgrade is not enabled"); } /* Free and reallocate buffer */ @@ -538,7 +543,7 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, dynamic_avrcp_version_enhancement_is_enabled()) { avrc_sdp_version = sdpu_is_avrcp_profile_description_list( p_attr_profile_desc_list_id); - LOG_ERROR("avrc_sdp_version in SDP records %x", avrc_sdp_version); + log::error("avrc_sdp_version in SDP records {:x}", avrc_sdp_version); sdpu_set_avrc_target_features(p_attr, &(p_ccb->device_address), avrc_sdp_version); } @@ -561,7 +566,7 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, /* if there is a partial attribute pending to be sent */ if (p_ccb->cont_info.attr_offset) { if (attr_len < p_ccb->cont_info.attr_offset) { - LOG(ERROR) << "offset is bigger than attribute length"; + log::error("offset is bigger than attribute length"); sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN); return; @@ -578,8 +583,8 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, attr_len) /* Not enough space for attr... so add partially */ { if (attr_len >= SDP_MAX_ATTR_LEN) { - LOG_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d", - max_list_len, attr_len); + log::error("SDP attr too big: max_list_len={},attr_len={}", + max_list_len, attr_len); sdpu_build_n_send_error(p_ccb, trans_num, SDP_NO_RESOURCES, NULL); return; } @@ -789,7 +794,7 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, pbap_pse_dynamic_version_upgrade_is_enabled()) { p_rec = sdp_upgrade_pse_record(p_rec, p_ccb->device_address); } else { - LOG_WARN("PBAP PSE dynamic version upgrade is not enabled"); + log::warn("PBAP PSE dynamic version upgrade is not enabled"); } /* Allow space for attribute sequence type and length */ p_seq_start = p_rsp; @@ -832,7 +837,8 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, p_attr_profile_desc_list_id != nullptr) { avrc_sdp_version = sdpu_is_avrcp_profile_description_list( p_attr_profile_desc_list_id); - LOG_ERROR("avrc_sdp_version in SDP records %x", avrc_sdp_version); + log::error("avrc_sdp_version in SDP records {:x}", + avrc_sdp_version); sdpu_set_avrc_target_features(p_attr, &(p_ccb->device_address), avrc_sdp_version); } @@ -856,7 +862,7 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, /* if there is a partial attribute pending to be sent */ if (p_ccb->cont_info.attr_offset) { if (attr_len < p_ccb->cont_info.attr_offset) { - LOG(ERROR) << "offset is bigger than attribute length"; + log::error("offset is bigger than attribute length"); sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN); return; @@ -874,8 +880,8 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, attr_len) /* Not enough space for attr... so add partially */ { if (attr_len >= SDP_MAX_ATTR_LEN) { - LOG_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d", - max_list_len, attr_len); + log::error("SDP attr too big: max_list_len={},attr_len={}", + max_list_len, attr_len); sdpu_build_n_send_error(p_ccb, trans_num, SDP_NO_RESOURCES, NULL); return; } @@ -977,12 +983,12 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, sdp_pbap_pse_dynamic_attributes_len_update(p_ccb, &attr_seq_sav, &uid_seq); } else { - LOG_WARN("PBAP PSE dynamic version upgrade is not enabled"); + log::warn("PBAP PSE dynamic version upgrade is not enabled"); p_ccb->pse_dynamic_attributes_len = 0; } - LOG_VERBOSE("p_ccb->list_len = %d pse_dynamic_attributes_len = %d", - p_ccb->list_len, p_ccb->pse_dynamic_attributes_len); + log::verbose("p_ccb->list_len = {} pse_dynamic_attributes_len = {}", + p_ccb->list_len, p_ccb->pse_dynamic_attributes_len); /* Put in the sequence header (2 or 3 bytes) */ if (p_ccb->list_len > 255) { @@ -1028,9 +1034,9 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, p_ccb->cont_offset += len_to_send; - LOG_VERBOSE( - "p_ccb->pse_dynamic_attributes_len %d, cont_offset = %d, p_ccb->list_len " - "= %d", + log::verbose( + "p_ccb->pse_dynamic_attributes_len {}, cont_offset = {}, p_ccb->list_len " + "= {}", p_ccb->pse_dynamic_attributes_len, p_ccb->cont_offset, p_ccb->list_len + p_ccb->pse_dynamic_attributes_len); /* If anything left to send, continuation needed */ @@ -1071,7 +1077,7 @@ static bool is_device_in_allowlist_for_pbap(RawAddress remote_address, if (!check_for_1_2 && interop_match_addr_or_name(INTEROP_ADV_PBAP_VER_1_1, &remote_address, &btif_storage_get_remote_device_property)) { - LOG_VERBOSE("device is in allowlist for pbap version < 1.2 "); + log::verbose("device is in allowlist for pbap version < 1.2"); return true; } if (check_for_1_2) { @@ -1079,14 +1085,15 @@ static bool is_device_in_allowlist_for_pbap(RawAddress remote_address, if (interop_match_addr_or_name( INTEROP_ADV_PBAP_VER_1_2, &remote_address, &btif_storage_get_remote_device_property)) { - LOG_VERBOSE("device is in allowlist for pbap version 1.2 "); + log::verbose("device is in allowlist for pbap version 1.2"); return true; } } else { const char* p_name = BTM_SecReadDevName(remote_address); if ((p_name != NULL) && interop_match_name(INTEROP_ADV_PBAP_VER_1_2, p_name)) { - LOG_VERBOSE("device is not paired & in allowlist for pbap version 1.2"); + log::verbose( + "device is not paired & in allowlist for pbap version 1.2"); return true; } } @@ -1120,10 +1127,9 @@ static uint16_t sdp_pbap_pse_dynamic_attributes_len_update( is_device_in_allowlist_for_pbap(p_ccb->device_address, true); bool running_pts = osi_property_get_bool(SDP_ENABLE_PTS_PBAP, false); - LOG_VERBOSE( - "remote BD Addr : %s is_pbap_102_supported = %d " - "is_pbap_101_allowlisted = %d is_pbap_102_allowlisted = %d " - "running_pts = %d", + log::verbose( + "remote BD Addr : {} is_pbap_102_supported = {} is_pbap_101_allowlisted " + "= {} is_pbap_102_allowlisted = {} running_pts = {}", ADDRESS_TO_LOGGABLE_CSTR(p_ccb->device_address), is_pbap_102_supported, is_pbap_101_allowlisted, is_pbap_102_allowlisted, running_pts); @@ -1143,16 +1149,15 @@ static uint16_t sdp_pbap_pse_dynamic_attributes_len_update( UUID_SERVCLASS_PBAP_PSE)) { // PBAP PSE Record p_rec = sdp_upgrade_pse_record(p_rec, p_ccb->device_address); - LOG_VERBOSE("response has PBAP PSE record for allowlist device"); + log::verbose("response has PBAP PSE record for allowlist device"); int att_index; bool l2cap_psm_len_included = false, supp_attr_len_included = false; for (xx = p_ccb->cont_info.next_attr_index; xx < attr_seq->num_attr; xx++) { - LOG_VERBOSE( - "xx = %d attr_seq->num_attr = %d, " - "attr_seq->attr_entry[xx].start = %d , " - "attr_seq->attr_entry[xx].end = %d", + log::verbose( + "xx = {} attr_seq->num_attr = {}, attr_seq->attr_entry[xx].start = " + "{} , attr_seq->attr_entry[xx].end = {}", xx, attr_seq->num_attr, attr_seq->attr_entry[xx].start, attr_seq->attr_entry[xx].end); @@ -1164,9 +1169,8 @@ static uint16_t sdp_pbap_pse_dynamic_attributes_len_update( cur_attr.id <= attr_seq->attr_entry[xx].end) { l2cap_psm_len_included = true; p_ccb->pse_dynamic_attributes_len += PBAP_GOEP_L2CAP_PSM_LEN; - LOG_ERROR( - "ATTR_ID_GOEP_L2CAP_PSM requested," - " need to change length by %d", + log::error( + "ATTR_ID_GOEP_L2CAP_PSM requested, need to change length by {}", p_ccb->pse_dynamic_attributes_len); } else if (cur_attr.id == ATTR_ID_PBAP_SUPPORTED_FEATURES && !supp_attr_len_included && @@ -1174,9 +1178,9 @@ static uint16_t sdp_pbap_pse_dynamic_attributes_len_update( cur_attr.id <= attr_seq->attr_entry[xx].end) { supp_attr_len_included = true; p_ccb->pse_dynamic_attributes_len += PBAP_SUPP_FEA_LEN; - LOG_VERBOSE( - "ATTR_ID_PBAP_SUPPORTED_FEATURES requested," - " need to change length by %d", + log::verbose( + "ATTR_ID_PBAP_SUPPORTED_FEATURES requested, need to change " + "length by {}", p_ccb->pse_dynamic_attributes_len); } } @@ -1185,8 +1189,8 @@ static uint16_t sdp_pbap_pse_dynamic_attributes_len_update( break; } } - LOG_VERBOSE("pse_dynamic_attributes_len = %d", - p_ccb->pse_dynamic_attributes_len); + log::verbose("pse_dynamic_attributes_len = {}", + p_ccb->pse_dynamic_attributes_len); return p_ccb->pse_dynamic_attributes_len; } @@ -1219,11 +1223,10 @@ static const tSDP_RECORD* sdp_upgrade_pse_record(const tSDP_RECORD* p_rec, is_device_in_allowlist_for_pbap(remote_address, true); bool running_pts = osi_property_get_bool(SDP_ENABLE_PTS_PBAP, false); - LOG_VERBOSE( - "%s remote BD Addr : %s is_pbap_102_supported : %d " - "is_pbap_101_allowlisted = %d is_pbap_102_allowlisted = %d " - "running_pts = %d", - __func__, ADDRESS_TO_LOGGABLE_CSTR(remote_address), is_pbap_102_supported, + log::verbose( + "remote BD Addr : {} is_pbap_102_supported : {} is_pbap_101_allowlisted " + "= {} is_pbap_102_allowlisted = {} running_pts = {}", + ADDRESS_TO_LOGGABLE_CSTR(remote_address), is_pbap_102_supported, is_pbap_101_allowlisted, is_pbap_102_allowlisted, running_pts); if (is_pbap_101_allowlisted || @@ -1267,7 +1270,7 @@ static const tSDP_RECORD* sdp_upgrade_pse_record(const tSDP_RECORD* p_rec, UINT_DESC_TYPE, (uint32_t)2, temp); if (!status) { - LOG_ERROR("FAILED"); + log::error("FAILED"); return p_rec; } return &pbap_102_sdp_rec; @@ -1284,11 +1287,11 @@ void update_pce_entry_to_interop_database(RawAddress remote_addr) { if (!interop_match_addr_or_name(INTEROP_ADV_PBAP_VER_1_2, &remote_addr, &btif_storage_get_remote_device_property)) { interop_database_add_addr(INTEROP_ADV_PBAP_VER_1_2, &remote_addr, 3); - LOG_VERBOSE("device: %s is added into interop list", - ADDRESS_TO_LOGGABLE_CSTR(remote_addr)); + log::verbose("device: {} is added into interop list", + ADDRESS_TO_LOGGABLE_CSTR(remote_addr)); } else { - LOG_WARN("device: %s is already found on interop list", - ADDRESS_TO_LOGGABLE_CSTR(remote_addr)); + log::warn("device: {} is already found on interop list", + ADDRESS_TO_LOGGABLE_CSTR(remote_addr)); } } @@ -1306,7 +1309,7 @@ bool is_sdp_pbap_pce_disabled(RawAddress remote_address) { if (interop_match_addr_or_name(INTEROP_DISABLE_PCE_SDP_AFTER_PAIRING, &remote_address, &btif_storage_get_remote_device_property)) { - LOG_VERBOSE("device is denylisted for PCE SDP "); + log::verbose("device is denylisted for PCE SDP"); return true; } else { return false; @@ -1328,9 +1331,9 @@ void sdp_save_local_pse_record_attributes(int32_t rfcomm_channel_number, int32_t profile_version, uint32_t supported_features, uint32_t supported_repositories) { - LOG_WARN( - "rfcomm_channel_number: 0x%x, l2cap_psm: 0x%x profile_version: 0x%x" - "supported_features: 0x%x supported_repositories: 0x%x", + log::warn( + "rfcomm_channel_number: 0x{:x}, l2cap_psm: 0x{:x} profile_version: " + "0x{:x}supported_features: 0x{:x} supported_repositories: 0x{:x}", rfcomm_channel_number, l2cap_psm, profile_version, supported_features, supported_repositories); sdpPseLocalRecord.rfcomm_channel_number = rfcomm_channel_number; diff --git a/system/stack/sdp/sdp_utils.cc b/system/stack/sdp/sdp_utils.cc index 0f494cf93c67029ec690ea76e6658565da4a9687..576100cd5a34794659bc9224cbbb652c50b1b3b3 100644 --- a/system/stack/sdp/sdp_utils.cc +++ b/system/stack/sdp/sdp_utils.cc @@ -25,6 +25,7 @@ ******************************************************************************/ #include +#include #include #include @@ -36,9 +37,11 @@ #include #include "btif/include/btif_config.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "common/init_flags.h" #include "device/include/interop.h" +#include "internal_include/bt_target.h" +#include "internal_include/bt_trace.h" #include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/properties.h" @@ -48,15 +51,16 @@ #include "stack/include/bt_psm_types.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" -#include "stack/include/btm_api_types.h" #include "stack/include/btm_sec_api_types.h" #include "stack/include/sdpdefs.h" #include "stack/include/stack_metrics_logging.h" #include "stack/sdp/sdpint.h" +#include "storage/config_keys.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" using bluetooth::Uuid; +using namespace bluetooth; bool SDP_FindProtocolListElemInRec(const tSDP_DISC_REC* p_rec, uint16_t layer_uuid, @@ -105,8 +109,8 @@ static std::vector> sdpu_find_profile_version( // Safety check - each entry should itself be a sequence if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) { - LOG(WARNING) << __func__ << ": Descriptor type is not sequence: " - << loghex(SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type)); + log::warn("Descriptor type is not sequence: {}", + loghex(SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type))); return std::vector>(); } // Now, see if the entry contains the profile UUID we are interested in @@ -123,13 +127,11 @@ static std::vector> sdpu_find_profile_version( SDP_DISC_ATTR_TYPE(version_attr->attr_len_type) != UINT_DESC_TYPE || SDP_DISC_ATTR_LEN(version_attr->attr_len_type) != 2) { if (version_attr == nullptr) { - LOG(WARNING) << __func__ << ": version attr not found"; + log::warn("version attr not found"); } else { - LOG(WARNING) << __func__ << ": Bad version type " - << loghex( - SDP_DISC_ATTR_TYPE(version_attr->attr_len_type)) - << ", or length " - << SDP_DISC_ATTR_LEN(version_attr->attr_len_type); + log::warn("Bad version type {}, or length {}", + loghex(SDP_DISC_ATTR_TYPE(version_attr->attr_len_type)), + SDP_DISC_ATTR_LEN(version_attr->attr_len_type)); } return std::vector>(); } @@ -177,7 +179,7 @@ static uint16_t sdpu_find_most_specific_service_uuid(tSDP_DISC_REC* p_rec) { } } } else { - LOG(WARNING) << __func__ << ": Bad Service Class ID list attribute"; + log::warn("Bad Service Class ID list attribute"); return 0; } } else if (p_attr->attr_id == ATTR_ID_SERVICE_ID) { @@ -198,8 +200,8 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, p_rec = p_rec->p_next_rec) { uint16_t service_uuid = sdpu_find_most_specific_service_uuid(p_rec); if (service_uuid == 0) { - LOG(INFO) << __func__ << ": skipping record without service uuid " - << ADDRESS_TO_LOGGABLE_STR(bda); + log::info("skipping record without service uuid {}", + ADDRESS_TO_LOGGABLE_STR(bda)); continue; } // Log the existence of a profile role @@ -319,13 +321,13 @@ void sdpu_log_attribute_metrics(const RawAddress& bda, std::string bda_string = bda.ToString(); // write manufacturer, model, HW version to config - btif_config_set_int(bda_string, BT_CONFIG_KEY_SDP_DI_MANUFACTURER, + btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_MANUFACTURER, di_record.rec.vendor); - btif_config_set_int(bda_string, BT_CONFIG_KEY_SDP_DI_MODEL, + btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_MODEL, di_record.rec.product); - btif_config_set_int(bda_string, BT_CONFIG_KEY_SDP_DI_HW_VERSION, + btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_HW_VERSION, di_record.rec.version); - btif_config_set_int(bda_string, BT_CONFIG_KEY_SDP_DI_VENDOR_ID_SRC, + btif_config_set_int(bda_string, BTIF_STORAGE_KEY_SDP_DI_VENDOR_ID_SRC, di_record.rec.vendor_id_source); } } @@ -445,7 +447,7 @@ void sdpu_release_ccb(tCONN_CB& ccb) { ccb.is_attr_search = false; /* Free the response buffer */ - if (ccb.rsp_list) LOG_VERBOSE("releasing SDP rsp_list"); + if (ccb.rsp_list) log::verbose("releasing SDP rsp_list"); osi_free_and_reset((void**)&ccb.rsp_list); } @@ -721,8 +723,8 @@ void sdpu_build_n_send_error(tCONN_CB* p_ccb, uint16_t trans_num, uint16_t rsp_param_len; BT_HDR* p_buf = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE); - LOG_WARN("SDP - sdpu_build_n_send_error code: 0x%x CID: 0x%x", error_code, - p_ccb->connection_id); + log::warn("SDP - sdpu_build_n_send_error code: 0x{:x} CID: 0x{:x}", + error_code, p_ccb->connection_id); /* Send the packet to L2CAP */ p_buf->offset = L2CAP_MIN_OFFSET; @@ -1072,7 +1074,7 @@ bool sdpu_compare_uuid_arrays(const uint8_t* p_uuid1, uint32_t len1, if (((len1 != 2) && (len1 != 4) && (len1 != 16)) || ((len2 != 2) && (len2 != 4) && (len2 != 16))) { - LOG_ERROR("%s: invalid length", __func__); + log::error("invalid length"); return false; } @@ -1356,7 +1358,7 @@ uint8_t* sdpu_build_partial_attrib_entry(uint8_t* p_out, uint16_t attr_len = sdpu_get_attrib_entry_len(p_attr); if (len > SDP_MAX_ATTR_LEN) { - LOG_ERROR("%s len %d exceeds SDP_MAX_ATTR_LEN", __func__, len); + log::error("len {} exceeds SDP_MAX_ATTR_LEN", len); len = SDP_MAX_ATTR_LEN; } @@ -1468,10 +1470,10 @@ void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr, // Check attribute is AVRCP profile description list and get AVRC Target // version uint16_t avrcp_version = sdpu_is_avrcp_profile_description_list(p_attr); - LOG_INFO("SDP AVRCP DB Version %x", avrcp_version); + log::info("SDP AVRCP DB Version {:x}", avrcp_version); if (avrcp_version == 0) { - LOG_INFO("Not AVRCP version attribute or version not valid for device %s", - ADDRESS_TO_LOGGABLE_CSTR(*bdaddr)); + log::info("Not AVRCP version attribute or version not valid for device {}", + ADDRESS_TO_LOGGABLE_CSTR(*bdaddr)); return; } @@ -1482,7 +1484,7 @@ void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr, ->profileSpecific_HACK->AVRC_GetProfileVersion() : avrcp_version; - LOG_INFO("Current DUT AVRCP Version %x", dut_avrcp_version); + log::info("Current DUT AVRCP Version {:x}", dut_avrcp_version); // Some remote devices will have interoperation issue when receive higher // AVRCP version. If those devices are in IOP database and our version higher // than device, we reply a lower version to them. @@ -1496,9 +1498,9 @@ void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr, } if (iop_version != 0) { - LOG_INFO( - "device=%s is in IOP database. " - "Reply AVRC Target version %x instead of %x.", + log::info( + "device={} is in IOP database. Reply AVRC Target version {:x} instead " + "of {:x}.", ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), iop_version, avrcp_version); uint8_t* p_version = p_attr->value_ptr + 6; UINT16_TO_BE_FIELD(p_version, iop_version); @@ -1508,7 +1510,7 @@ void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr, // Dynamic AVRCP version. If our version high than remote device's version, // reply version same as its. Otherwise, reply default version. if (!osi_property_get_bool(AVRC_DYNAMIC_AVRCP_ENABLE_PROPERTY, true)) { - LOG_INFO( + log::info( "Dynamic AVRCP version feature is not enabled, skipping this method"); return; } @@ -1516,30 +1518,28 @@ void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr, // Read the remote device's AVRC Controller version from local storage uint16_t cached_version = 0; size_t version_value_size = btif_config_get_bin_length( - bdaddr->ToString(), AVRCP_CONTROLLER_VERSION_CONFIG_KEY); + bdaddr->ToString(), BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION); if (version_value_size != sizeof(cached_version)) { - LOG_ERROR( - "cached value len wrong, bdaddr=%s. Len is %zu but should be %zu.", - ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), version_value_size, - sizeof(cached_version)); + log::error("cached value len wrong, bdaddr={}. Len is {} but should be {}.", + ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), version_value_size, + sizeof(cached_version)); return; } if (!btif_config_get_bin(bdaddr->ToString(), - AVRCP_CONTROLLER_VERSION_CONFIG_KEY, + BTIF_STORAGE_KEY_AVRCP_CONTROLLER_VERSION, (uint8_t*)&cached_version, &version_value_size)) { - LOG_INFO( - "no cached AVRC Controller version for %s. " - "Reply default AVRC Target version %x." - "DUT AVRC Target version %x.", + log::info( + "no cached AVRC Controller version for {}. Reply default AVRC Target " + "version {:x}.DUT AVRC Target version {:x}.", ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), avrcp_version, dut_avrcp_version); return; } if (!spdu_is_avrcp_version_valid(cached_version)) { - LOG_ERROR( - "cached AVRC Controller version %x of %s is not valid. " - "Reply default AVRC Target version %x.", + log::error( + "cached AVRC Controller version {:x} of {} is not valid. Reply default " + "AVRC Target version {:x}.", cached_version, ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), avrcp_version); return; } @@ -1552,10 +1552,9 @@ void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr, uint16_t negotiated_avrcp_version = std::min(dut_avrcp_version, cached_version); - LOG_INFO( - "read cached AVRC Controller version %x of %s. " - "DUT AVRC Target version %x." - "Negotiated AVRCP version to update peer %x. ", + log::info( + "read cached AVRC Controller version {:x} of {}. DUT AVRC Target version " + "{:x}.Negotiated AVRCP version to update peer {:x}.", cached_version, ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), dut_avrcp_version, negotiated_avrcp_version); uint8_t* p_version = p_attr->value_ptr + 6; @@ -1577,43 +1576,42 @@ void sdpu_set_avrc_target_version(const tSDP_ATTRIBUTE* p_attr, void sdpu_set_avrc_target_features(const tSDP_ATTRIBUTE* p_attr, const RawAddress* bdaddr, uint16_t avrcp_version) { - LOG_INFO("SDP AVRCP Version %x", avrcp_version); + log::info("SDP AVRCP Version {:x}", avrcp_version); if ((p_attr->id != ATTR_ID_SUPPORTED_FEATURES) || (p_attr->len != 2) || (p_attr->value_ptr == nullptr)) { - LOG_INFO("Invalid request for AVRC feature ignore"); + log::info("Invalid request for AVRC feature ignore"); return; } if (avrcp_version == 0) { - LOG_INFO("AVRCP version not valid for device %s", - ADDRESS_TO_LOGGABLE_CSTR(*bdaddr)); + log::info("AVRCP version not valid for device {}", + ADDRESS_TO_LOGGABLE_CSTR(*bdaddr)); return; } // Dynamic AVRCP version. If our version high than remote device's version, // reply version same as its. Otherwise, reply default version. if (!osi_property_get_bool(AVRC_DYNAMIC_AVRCP_ENABLE_PROPERTY, false)) { - LOG_INFO( + log::info( "Dynamic AVRCP version feature is not enabled, skipping this method"); return; } // Read the remote device's AVRC Controller version from local storage uint16_t avrcp_peer_features = 0; size_t version_value_size = btif_config_get_bin_length( - bdaddr->ToString(), AV_REM_CTRL_FEATURES_CONFIG_KEY); + bdaddr->ToString(), BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES); if (version_value_size != sizeof(avrcp_peer_features)) { - LOG_ERROR( - "cached value len wrong, bdaddr=%s. Len is %zu but should be %zu.", - ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), version_value_size, - sizeof(avrcp_peer_features)); + log::error("cached value len wrong, bdaddr={}. Len is {} but should be {}.", + ADDRESS_TO_LOGGABLE_CSTR(*bdaddr), version_value_size, + sizeof(avrcp_peer_features)); return; } - if (!btif_config_get_bin(bdaddr->ToString(), AV_REM_CTRL_FEATURES_CONFIG_KEY, - (uint8_t*)&avrcp_peer_features, - &version_value_size)) { - LOG_ERROR("Unable to fetch cached AVRC features"); + if (!btif_config_get_bin( + bdaddr->ToString(), BTIF_STORAGE_KEY_AV_REM_CTRL_FEATURES, + (uint8_t*)&avrcp_peer_features, &version_value_size)) { + log::error("Unable to fetch cached AVRC features"); return; } @@ -1622,11 +1620,12 @@ void sdpu_set_avrc_target_features(const tSDP_ATTRIBUTE* p_attr, bool coverart_supported = ((AVRCP_FEAT_CA_BIT & avrcp_peer_features) == AVRCP_FEAT_CA_BIT); - LOG_INFO( - "SDP AVRCP DB Version 0x%x, browse supported %d, cover art supported %d", + log::info( + "SDP AVRCP DB Version 0x{:x}, browse supported {}, cover art supported " + "{}", avrcp_peer_features, browsing_supported, coverart_supported); if (avrcp_version < AVRC_REV_1_4 || !browsing_supported) { - LOG_INFO("Reset Browsing Feature "); + log::info("Reset Browsing Feature"); p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] &= ~AVRCP_BROWSE_SUPPORT_BITMASK; p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] &= @@ -1634,13 +1633,13 @@ void sdpu_set_avrc_target_features(const tSDP_ATTRIBUTE* p_attr, } if (avrcp_version < AVRC_REV_1_6 || !coverart_supported) { - LOG_INFO("Reset CoverArt Feature "); + log::info("Reset CoverArt Feature"); p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION - 1] &= ~AVRCP_CA_SUPPORT_BITMASK; } if (avrcp_version >= AVRC_REV_1_4 && browsing_supported) { - LOG_INFO("Set Browsing Feature "); + log::info("Set Browsing Feature"); p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] |= AVRCP_BROWSE_SUPPORT_BITMASK; p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION] |= @@ -1648,7 +1647,7 @@ void sdpu_set_avrc_target_features(const tSDP_ATTRIBUTE* p_attr, } if (avrcp_version == AVRC_REV_1_6 && coverart_supported) { - LOG_INFO("Set CoverArt Feature "); + log::info("Set CoverArt Feature"); p_attr->value_ptr[AVRCP_SUPPORTED_FEATURES_POSITION - 1] |= AVRCP_CA_SUPPORT_BITMASK; } diff --git a/system/stack/sdp/sdpint.h b/system/stack/sdp/sdpint.h index e643ba12fa96f90ccc1685cc54a38b174a020374..8493f540382a22b45e7bb81c804351f617d5ba2d 100644 --- a/system/stack/sdp/sdpint.h +++ b/system/stack/sdp/sdpint.h @@ -29,7 +29,7 @@ #include -#include "bt_target.h" +#include "internal_include/bt_target.h" #include "macros.h" #include "osi/include/alarm.h" #include "stack/include/bt_hdr.h" diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc index b9f13c03d8abbb24b30f6e465e5b278ac62a3d1e..b11a064dd472d5d2ee6885e851bf1da3d0d613c3 100644 --- a/system/stack/smp/smp_act.cc +++ b/system/stack/smp/smp_act.cc @@ -18,11 +18,14 @@ #define LOG_TAG "smp_act" +#include +#include + #include #include "btif/include/btif_common.h" #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "crypto_toolbox/crypto_toolbox.h" #include "device/include/interop.h" #include "internal_include/bt_target.h" @@ -39,6 +42,8 @@ #include "stack/include/smp_api_types.h" #include "types/raw_address.h" +using namespace bluetooth; + namespace { constexpr char kBtmLogTag[] = "SMP"; } @@ -73,11 +78,12 @@ static bool pts_test_send_authentication_complete_failure(tSMP_CB* p_cb) { * Description This function updates the key mask for sending or receiving. ******************************************************************************/ static void smp_update_key_mask(tSMP_CB* p_cb, uint8_t key_type, bool recv) { - LOG_VERBOSE( - "before update role=%d recv=%d local_i_key=0x%02x, local_r_key=0x%02x", + log::verbose( + "before update role={} recv={} local_i_key=0x{:02x}, " + "local_r_key=0x{:02x}", p_cb->role, recv, p_cb->local_i_key, p_cb->local_r_key); - if (((p_cb->le_secure_connections_mode_is_used) || (p_cb->smp_over_br)) && + if (((p_cb->sc_mode_required_by_peer) || (p_cb->smp_over_br)) && ((key_type == SMP_SEC_KEY_TYPE_ENC) || (key_type == SMP_SEC_KEY_TYPE_LK))) { /* in LE SC mode LTK, CSRK and BR/EDR LK are derived locally instead of @@ -96,8 +102,8 @@ static void smp_update_key_mask(tSMP_CB* p_cb, uint8_t key_type, bool recv) { p_cb->local_i_key &= ~key_type; } - LOG_VERBOSE("updated local_i_key=0x%02x, local_r_key=0x%02x", - p_cb->local_i_key, p_cb->local_r_key); + log::verbose("updated local_i_key=0x{:02x}, local_r_key=0x{:02x}", + p_cb->local_i_key, p_cb->local_r_key); } /******************************************************************************* @@ -109,6 +115,10 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tSMP_EVT_DATA cb_data; tBTM_STATUS callback_rc; uint8_t remote_lmp_version = 0; + + log::debug("addr:{} event:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), + smp_evt_to_text(p_cb->cb_evt)); + if (p_cb->p_callback && p_cb->cb_evt != 0) { switch (p_cb->cb_evt) { case SMP_IO_CAP_REQ_EVT: @@ -118,7 +128,7 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { cb_data.io_req.max_key_size = SMP_MAX_ENC_KEY_SIZE; cb_data.io_req.init_keys = p_cb->local_i_key; cb_data.io_req.resp_keys = p_cb->local_r_key; - LOG_DEBUG("Notify app io_cap=%hhu", cb_data.io_req.io_cap); + log::debug("Notify app io_cap={}", cb_data.io_req.io_cap); break; case SMP_NC_REQ_EVT: @@ -145,7 +155,7 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { break; default: - LOG_ERROR("Unexpected event:%hhu", p_cb->cb_evt); + log::error("Unexpected event:{}", p_cb->cb_evt); break; } @@ -163,42 +173,40 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->local_r_key = cb_data.io_req.resp_keys; if (!(p_cb->loc_auth_req & SMP_AUTH_BOND)) { - LOG_INFO("Non bonding: No keys will be exchanged"); + log::debug("Non bonding: No keys will be exchanged"); p_cb->local_i_key = 0; p_cb->local_r_key = 0; } - LOG_DEBUG( - "Remote request IO capabilities precondition auth_req:0x%02x," - " io_cap:%d loc_oob_flag:%d loc_enc_size:%d, " - "local_i_key:0x%02x, local_r_key:0x%02x", + log::debug( + "Remote request IO capabilities precondition " + "auth_req:0x{:02x},io_cap:{} loc_oob_flag:{} loc_enc_size:{}, " + "local_i_key:0x{:02x}, local_r_key:0x{:02x}", p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag, p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key); - p_cb->secure_connections_only_mode_required = + p_cb->sc_only_mode_locally_required = (p_cb->init_security_mode == BTM_SEC_MODE_SC) ? true : false; /* just for PTS, force SC bit */ - if (p_cb->secure_connections_only_mode_required) { + if (p_cb->sc_only_mode_locally_required) { p_cb->loc_auth_req |= SMP_SC_SUPPORT_BIT; } if (!BTM_ReadRemoteVersion(p_cb->pairing_bda, &remote_lmp_version, nullptr, nullptr)) { - LOG_WARN( - "SMP Unable to determine remote security authentication " - "remote_lmp_version:%hu", - remote_lmp_version); + log::warn("SMP Unable to determine remote_lmp_version:{}", + remote_lmp_version); } - if (!p_cb->secure_connections_only_mode_required && + if (!p_cb->sc_only_mode_locally_required && (!(p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) || (remote_lmp_version && remote_lmp_version < HCI_PROTO_VERSION_4_2) || interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, (const RawAddress*)&p_cb->pairing_bda))) { - LOG_DEBUG( - "Setting SC, H7 and LinkKey bits to false to support " - "legacy device with lmp version:%d", + log::debug( + "Setting SC, H7 and LinkKey bits to false to support legacy " + "device with lmp version:{}", remote_lmp_version); p_cb->loc_auth_req &= ~SMP_SC_SUPPORT_BIT; p_cb->loc_auth_req &= ~SMP_KP_SUPPORT_BIT; @@ -211,9 +219,9 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->loc_auth_req &= ~SMP_H7_SUPPORT_BIT; } - LOG_DEBUG( - "Remote request IO capabilities postcondition auth_req:0x%02x," - " local_i_key:0x%02x, local_r_key:0x%02x", + log::debug( + "Remote request IO capabilities postcondition " + "auth_req:0x{:02x},local_i_key:0x{:02x}, local_r_key:0x{:02x}", p_cb->loc_auth_req, p_cb->local_i_key, p_cb->local_r_key); smp_sm_event(p_cb, SMP_IO_RSP_EVT, NULL); @@ -228,9 +236,9 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK; p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK; - LOG_DEBUG( - "for SMP over BR max_key_size:0x%02x, local_i_key:0x%02x, " - "local_r_key:0x%02x, p_cb->loc_auth_req:0x%02x", + log::debug( + "for SMP over BR max_key_size:0x{:02x}, local_i_key:0x{:02x}, " + "local_r_key:0x{:02x}, p_cb->loc_auth_req:0x{:02x}", p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key, p_cb->loc_auth_req); @@ -245,7 +253,7 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { break; default: - LOG_ERROR("Unexpected event:%hhu", p_cb->cb_evt); + log::error("Unexpected event:{}", p_cb->cb_evt); } } } @@ -266,8 +274,7 @@ void smp_send_pair_fail(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { if (p_cb->status <= SMP_MAX_FAIL_RSN_PER_SPEC && p_cb->status != SMP_SUCCESS) { - LOG_ERROR("Pairing failed smp_status:%s", - smp_status_text(p_cb->status).c_str()); + log::error("Pairing failed smp_status:{}", smp_status_text(p_cb->status)); BTM_LogHistory(kBtmLogTag, p_cb->pairing_bda, "Pairing failed", base::StringPrintf("smp_status:%s", smp_status_text(p_cb->status).c_str())); @@ -282,7 +289,7 @@ void smp_send_pair_fail(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { ******************************************************************************/ void smp_send_pair_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* erase all keys when central sends pairing req*/ if (p_dev_rec) btm_sec_clear_ble_keys(p_dev_rec); @@ -296,7 +303,7 @@ void smp_send_pair_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description actions related to sending pairing response ******************************************************************************/ void smp_send_pair_rsp(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p_cb->local_i_key &= p_cb->peer_i_key; p_cb->local_r_key &= p_cb->peer_r_key; @@ -314,8 +321,9 @@ void smp_send_pair_rsp(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send confirmation to the peer ******************************************************************************/ void smp_send_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb); + p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM_SENT; } /******************************************************************************* @@ -323,7 +331,7 @@ void smp_send_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send pairing random to the peer ******************************************************************************/ void smp_send_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_send_cmd(SMP_OPCODE_RAND, p_cb); } @@ -332,7 +340,7 @@ void smp_send_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send pairing public key command to the peer ******************************************************************************/ void smp_send_pair_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_send_cmd(SMP_OPCODE_PAIR_PUBLIC_KEY, p_cb); } @@ -341,7 +349,7 @@ void smp_send_pair_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send commitment command to the peer ******************************************************************************/ void smp_send_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_send_cmd(SMP_OPCODE_PAIR_COMMITM, p_cb); } @@ -350,7 +358,7 @@ void smp_send_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send DHKey Check command to the peer ******************************************************************************/ void smp_send_dhkey_check(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_send_cmd(SMP_OPCODE_PAIR_DHKEY_CHECK, p_cb); } @@ -368,7 +376,7 @@ void smp_send_keypress_notification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send encryption information command. ******************************************************************************/ void smp_send_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("p_cb->loc_enc_size=%d", p_cb->loc_enc_size); + log::verbose("p_cb->loc_enc_size={}", p_cb->loc_enc_size); smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false); smp_send_cmd(SMP_OPCODE_ENCRYPT_INFO, p_cb); @@ -396,7 +404,7 @@ void smp_send_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send ID information command. ******************************************************************************/ void smp_send_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ID, false); smp_send_cmd(SMP_OPCODE_IDENTITY_INFO, p_cb); @@ -411,7 +419,7 @@ void smp_send_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { /** send CSRK command. */ void smp_send_csrk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_CSRK, false); if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb)) { @@ -435,7 +443,7 @@ void smp_send_csrk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description send LTK reply ******************************************************************************/ void smp_send_ltk_reply(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); Octet16 stk; memcpy(stk.data(), p_data->key.p_data, stk.size()); @@ -458,26 +466,26 @@ void smp_proc_sec_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_LE_AUTH_REQ auth_req = *(tBTM_LE_AUTH_REQ*)p_data->p_data; tBTM_BLE_SEC_REQ_ACT sec_req_act; - LOG_VERBOSE("auth_req=0x%x", auth_req); + log::verbose("auth_req=0x{:x}", auth_req); p_cb->cb_evt = SMP_EVT_NONE; btm_ble_link_sec_check(p_cb->pairing_bda, auth_req, &sec_req_act); - LOG_VERBOSE("sec_req_act=0x%x", sec_req_act); + log::verbose("sec_req_act={}", sec_req_act); switch (sec_req_act) { case BTM_BLE_SEC_REQ_ACT_ENCRYPT: - LOG_VERBOSE("BTM_BLE_SEC_REQ_ACT_ENCRYPT"); + log::verbose("BTM_BLE_SEC_REQ_ACT_ENCRYPT"); smp_sm_event(p_cb, SMP_ENC_REQ_EVT, NULL); break; case BTM_BLE_SEC_REQ_ACT_PAIR: - p_cb->secure_connections_only_mode_required = + p_cb->sc_only_mode_locally_required = (p_cb->init_security_mode == BTM_SEC_MODE_SC) ? true : false; /* respond to non SC pairing request as failure in SC only mode */ - if (p_cb->secure_connections_only_mode_required && + if (p_cb->sc_only_mode_locally_required && (auth_req & SMP_SC_SUPPORT_BIT) == 0) { tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_AUTH_FAIL; @@ -506,7 +514,7 @@ void smp_proc_sec_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { ******************************************************************************/ void smp_proc_sec_grant(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t res = p_data->status; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (res != SMP_SUCCESS) { smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, p_data); } else /*otherwise, start pairing */ @@ -521,14 +529,18 @@ void smp_proc_sec_grant(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description process pairing failure from peer device ******************************************************************************/ void smp_proc_pair_fail(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->rcvd_cmd_len < 2) { - LOG_WARN("rcvd_cmd_len %d too short: must be at least 2", - p_cb->rcvd_cmd_len); + log::warn("rcvd_cmd_len {} too short: must be at least 2", + p_cb->rcvd_cmd_len); p_cb->status = SMP_INVALID_PARAMETERS; } else { - p_cb->status = p_data->status; + if (IS_FLAG_ENABLED(fix_pairing_failure_reason_from_remote)) { + p_cb->status = static_cast(p_data->p_data[0]); + } else { + p_cb->status = p_data->status; + } } /* Cancel pending auth complete timer if set */ @@ -543,7 +555,7 @@ void smp_proc_pair_cmd(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda); - LOG_VERBOSE("pairing_bda=%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("pairing_bda={}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* erase all keys if it is peripheral proc pairing req */ if (p_dev_rec && (p_cb->role == HCI_ROLE_PERIPHERAL)) @@ -597,11 +609,11 @@ void smp_proc_pair_cmd(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->local_r_key &= p_cb->peer_r_key; p_cb->selected_association_model = smp_select_association_model(p_cb); - if (p_cb->secure_connections_only_mode_required && - (!(p_cb->le_secure_connections_mode_is_used) || + if (p_cb->sc_only_mode_locally_required && + (!(p_cb->sc_mode_required_by_peer) || (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) { - LOG_ERROR( + log::error( "pairing failed - peripheral requires secure connection only mode"); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_AUTH_FAIL; @@ -619,12 +631,12 @@ void smp_proc_pair_cmd(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { { p_cb->selected_association_model = smp_select_association_model(p_cb); - if (p_cb->secure_connections_only_mode_required && - (!(p_cb->le_secure_connections_mode_is_used) || + if (p_cb->sc_only_mode_locally_required && + (!(p_cb->sc_mode_required_by_peer) || (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) { - LOG_ERROR( - "Central requires secure connection only mode " - "but it can't be provided -> Central fails pairing"); + log::error( + "Central requires secure connection only mode but it can't be " + "provided -> Central fails pairing"); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_AUTH_FAIL; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); @@ -641,7 +653,7 @@ void smp_proc_pair_cmd(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { /** process pairing confirm from peer device */ void smp_proc_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("pairing_bda=%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("pairing_bda={}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -658,7 +670,7 @@ void smp_proc_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { } } - p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM; + p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM_RCVD; } /******************************************************************************* @@ -668,7 +680,7 @@ void smp_proc_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_proc_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("pairing_bda=%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("pairing_bda={}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -677,6 +689,19 @@ void smp_proc_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { return; } + if (IS_FLAG_ENABLED(fix_le_pairing_passkey_entry_bypass)) { + if (!((p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) && + (p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT)) && + !(p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM_SENT)) { + // in legacy pairing, the peer should send its rand after + // we send our confirm + tSMP_INT_DATA smp_int_data{}; + smp_int_data.status = SMP_INVALID_PARAMETERS; + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); + return; + } + } + /* save the SRand for comparison */ STREAM_TO_ARRAY(p_cb->rrand.data(), p, OCTET16_LEN); } @@ -692,7 +717,7 @@ void smp_proc_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_process_pairing_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -709,7 +734,7 @@ void smp_process_pairing_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { memcpy(pt.y, p_cb->peer_publ_key.y, BT_OCTET32_LEN); if (!memcmp(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x, BT_OCTET32_LEN)) { - LOG_WARN("Remote and local public keys can't match"); + log::warn("Remote and local public keys can't match"); tSMP_INT_DATA smp; smp.status = SMP_PAIR_AUTH_FAIL; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp); @@ -735,7 +760,7 @@ void smp_process_pairing_public_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_process_pairing_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -758,7 +783,7 @@ void smp_process_pairing_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_process_dhkey_check(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -781,7 +806,7 @@ void smp_process_dhkey_check(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_process_keypress_notification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p_cb->status = p_data->status; if (smp_command_has_invalid_parameters(p_cb)) { @@ -808,7 +833,7 @@ void smp_br_process_pairing_command(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* rejecting BR pairing request over non-SC BR link */ if (!p_dev_rec->sec_rec.new_encryption_key_is_p256 && p_cb->role == HCI_ROLE_PERIPHERAL) { @@ -857,9 +882,9 @@ void smp_br_process_pairing_command(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->cb_evt = SMP_BR_KEYS_REQ_EVT; } else { /* Central receives pairing response */ - LOG_VERBOSE( - "central rcvs valid PAIRING RESPONSE." - " Supposed to move to key distribution phase."); + log::verbose( + "central rcvs valid PAIRING RESPONSE. Supposed to move to key " + "distribution phase."); } /* auth_req received via BR/EDR SM channel is set to 0, @@ -873,7 +898,7 @@ void smp_br_process_pairing_command(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description process security grant in case of pairing over BR/EDR transport. ******************************************************************************/ void smp_br_process_security_grant(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_data->status != SMP_SUCCESS) { smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, p_data); } else { @@ -888,8 +913,8 @@ void smp_br_process_security_grant(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * before starting the distribution/derivation ******************************************************************************/ void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("rcvs i_keys=0x%x r_keys=0x%x (i-initiator r-responder)", - p_cb->local_i_key, p_cb->local_r_key); + log::verbose("rcvs i_keys=0x{:x} r_keys=0x{:x} (i-initiator r-responder)", + p_cb->local_i_key, p_cb->local_r_key); /* In LE SC mode LK field is ignored when BR/EDR transport is used */ p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK; @@ -906,9 +931,9 @@ void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { (p_cb->peer_auth_req & SMP_H7_SUPPORT_BIT)) { p_cb->key_derivation_h7_used = TRUE; } - LOG_VERBOSE("use h7=%d, i_keys=0x%x r_keys=0x%x (i-initiator r-responder)", - p_cb->key_derivation_h7_used, p_cb->local_i_key, - p_cb->local_r_key); + log::verbose( + "use h7={}, i_keys=0x{:x} r_keys=0x{:x} (i-initiator r-responder)", + p_cb->key_derivation_h7_used, p_cb->local_i_key, p_cb->local_r_key); if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) || (p_cb->loc_auth_req & SMP_AUTH_BOND)) &&*/ @@ -931,8 +956,8 @@ void smp_br_check_authorization_request(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * used. ******************************************************************************/ void smp_br_select_next_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("role=%d (0-central) r_keys=0x%x i_keys=0x%x", p_cb->role, - p_cb->local_r_key, p_cb->local_i_key); + log::verbose("role={} (0-central) r_keys=0x{:x} i_keys=0x{:x}", p_cb->role, + p_cb->local_r_key, p_cb->local_i_key); if (p_cb->role == HCI_ROLE_PERIPHERAL || (!p_cb->local_r_key && p_cb->role == HCI_ROLE_CENTRAL)) { @@ -957,7 +982,7 @@ void smp_br_select_next_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_proc_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -975,11 +1000,11 @@ void smp_proc_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_proc_central_id(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->rcvd_cmd_len < 11) { // 1(Code) + 2(EDIV) + 8(Rand) - LOG_ERROR("Invalid command length:%d, should be at least 11", - p_cb->rcvd_cmd_len); + log::error("Invalid command length:{}, should be at least 11", + p_cb->rcvd_cmd_len); return; } @@ -1007,7 +1032,7 @@ void smp_proc_central_id(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_proc_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -1024,7 +1049,7 @@ void smp_proc_id_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { const uint8_t* p = p_data->p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -1060,7 +1085,7 @@ void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { /* process security information from peer device */ void smp_proc_srk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_command_has_invalid_parameters(p_cb)) { tSMP_INT_DATA smp_int_data; @@ -1097,7 +1122,7 @@ void smp_proc_srk_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description process compare value ******************************************************************************/ void smp_proc_compare(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (!memcmp(p_cb->rconfirm.data(), p_data->key.p_data, OCTET16_LEN)) { /* compare the max encryption key size, and save the smaller one for the * link */ @@ -1129,13 +1154,13 @@ void smp_proc_compare(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_proc_sl_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t key_type = p_data->key.key_type; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (key_type == SMP_KEY_TYPE_TK) { smp_generate_srand_mrand_confirm(p_cb, NULL); } else if (key_type == SMP_KEY_TYPE_CFM) { smp_set_state(SMP_STATE_WAIT_CONFIRM); - if (p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM) + if (p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM_RCVD) smp_sm_event(p_cb, SMP_CONFIRM_EVT, NULL); } } @@ -1147,7 +1172,7 @@ void smp_proc_sl_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_start_enc(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_STATUS cmd; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_data != NULL) { cmd = btm_ble_start_encrypt(p_cb->pairing_bda, true, (Octet16*)p_data->key.p_data); @@ -1167,7 +1192,7 @@ void smp_start_enc(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description processing for discard security request ******************************************************************************/ void smp_proc_discard(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (!(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) smp_reset_control_value(p_cb); } @@ -1179,7 +1204,7 @@ void smp_proc_discard(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_enc_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t enc_enable = p_data->status; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); tSMP_INT_DATA smp_int_data; smp_int_data.status = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); @@ -1191,11 +1216,11 @@ void smp_enc_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { ******************************************************************************/ void smp_sirk_verify(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_STATUS callback_rc; - LOG_DEBUG("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::debug("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_data->status != SMP_SUCCESS) { - LOG_DEBUG( - "Cancel device verification due to invalid status(%d) while bonding.", + log::debug( + "Cancel device verification due to invalid status({}) while bonding.", p_data->status); tSMP_INT_DATA smp_int_data; @@ -1225,7 +1250,7 @@ void smp_sirk_verify(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { smp_sm_event(p_cb, SMP_SIRK_DEVICE_VALID_EVT, &smp_int_data); } } else { - LOG_ERROR("There are no registrated callbacks for SMP"); + log::error("There are no registrated callbacks for SMP"); } } @@ -1236,11 +1261,12 @@ void smp_sirk_verify(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_check_auth_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t enc_enable = p_data->status; - LOG_VERBOSE( - "rcvs enc_enable=%d i_keys=0x%x r_keys=0x%x (i-initiator r-responder)", + log::verbose( + "rcvs enc_enable={} i_keys=0x{:x} r_keys=0x{:x} (i-initiator " + "r-responder)", enc_enable, p_cb->local_i_key, p_cb->local_r_key); if (enc_enable == 1) { - if (p_cb->le_secure_connections_mode_is_used) { + if (p_cb->sc_mode_required_by_peer) { /* In LE SC mode LTK is used instead of STK and has to be always saved */ p_cb->local_i_key |= SMP_SEC_KEY_TYPE_ENC; p_cb->local_r_key |= SMP_SEC_KEY_TYPE_ENC; @@ -1263,8 +1289,8 @@ void smp_check_auth_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK; p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK; } - LOG_VERBOSE( - "rcvs upgrades:i_keys=0x%x r_keys=0x%x (i-initiator r-responder)", + log::verbose( + "rcvs upgrades:i_keys=0x{:x} r_keys=0x{:x} (i-initiator r-responder)", p_cb->local_i_key, p_cb->local_r_key); if (/*((p_cb->peer_auth_req & SMP_AUTH_BOND) || @@ -1300,12 +1326,12 @@ void smp_key_pick_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { : p_cb->local_i_key; uint8_t i = 0; - LOG_VERBOSE("key_to_dist=0x%x", key_to_dist); + log::verbose("key_to_dist=0x{:x}", key_to_dist); while (i < SMP_KEY_DIST_TYPE_MAX) { - LOG_VERBOSE("key to send=0x%02x, i=%d", key_to_dist, i); + log::verbose("key to send=0x{:02x}, i={}", key_to_dist, i); if (key_to_dist & (1 << i)) { - LOG_VERBOSE("smp_distribute_act[%d]", i); + log::verbose("smp_distribute_act[{}]", i); (*smp_distribute_act[i])(p_cb, p_data); break; } @@ -1317,8 +1343,8 @@ void smp_key_pick_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description start key distribution if required. ******************************************************************************/ void smp_key_distribution(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("role=%d (0-central) r_keys=0x%x i_keys=0x%x", p_cb->role, - p_cb->local_r_key, p_cb->local_i_key); + log::verbose("role={} (0-central) r_keys=0x{:x} i_keys=0x{:x}", p_cb->role, + p_cb->local_r_key, p_cb->local_i_key); if (p_cb->role == HCI_ROLE_PERIPHERAL || (!p_cb->local_r_key && p_cb->role == HCI_ROLE_CENTRAL)) { @@ -1332,9 +1358,9 @@ void smp_key_distribution(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda); if (!(p_dev_rec->sec_rec.sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED) && (p_dev_rec->sec_rec.sec_flags & BTM_SEC_LINK_KEY_AUTHED)) { - LOG_VERBOSE( - "BR key is higher security than existing LE keys, don't " - "derive LK from LTK"); + log::verbose( + "BR key is higher security than existing LE keys, don't derive " + "LK from LTK"); } else { smp_derive_link_key_from_long_term_key(p_cb, NULL); } @@ -1350,7 +1376,7 @@ void smp_key_distribution(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * state should remain in SMP_STATE_BOND_PENDING. */ if (!alarm_is_scheduled(p_cb->delayed_auth_timer_ent)) { - LOG_VERBOSE("delaying auth complete"); + log::verbose("delaying auth complete"); alarm_set_on_mloop(p_cb->delayed_auth_timer_ent, SMP_DELAYED_AUTH_TIMEOUT_MS, smp_delayed_auth_complete_timeout, NULL); @@ -1372,14 +1398,14 @@ void smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tSMP_EVENT int_evt = SMP_NOP_EVT; tSMP_INT_DATA smp_int_data; - LOG_VERBOSE("Association Model=%d", p_cb->selected_association_model); + log::verbose("Association Model={}", p_cb->selected_association_model); switch (p_cb->selected_association_model) { case SMP_MODEL_ENCRYPTION_ONLY: /* TK = 0, go calculate Confirm */ if (p_cb->role == HCI_ROLE_CENTRAL && ((p_cb->peer_auth_req & SMP_AUTH_YN_BIT) != 0) && ((p_cb->loc_auth_req & SMP_AUTH_YN_BIT) == 0)) { - LOG_ERROR("IO capability does not meet authentication requirement"); + log::error("IO capability does not meet authentication requirement"); smp_int_data.status = SMP_PAIR_AUTH_FAIL; int_evt = SMP_AUTH_CMPL_EVT; } else { @@ -1387,14 +1413,14 @@ void smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { (p_cb->local_io_capability == SMP_IO_CAP_IO || p_cb->local_io_capability == SMP_IO_CAP_KBDISP)) { /* display consent dialog if this device has a display */ - LOG_VERBOSE("ENCRYPTION_ONLY showing Consent Dialog"); + log::verbose("ENCRYPTION_ONLY showing Consent Dialog"); p_cb->cb_evt = SMP_CONSENT_REQ_EVT; smp_set_state(SMP_STATE_WAIT_NONCE); smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL); } else { p_cb->sec_level = SMP_SEC_UNAUTHENTICATE; - LOG_VERBOSE("p_cb->sec_level=%d (SMP_SEC_UNAUTHENTICATE) ", - p_cb->sec_level); + log::verbose("p_cb->sec_level={} (SMP_SEC_UNAUTHENTICATE)", + p_cb->sec_level); tSMP_KEY key; key.key_type = SMP_KEY_TYPE_TK; @@ -1410,18 +1436,18 @@ void smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { case SMP_MODEL_PASSKEY: p_cb->sec_level = SMP_SEC_AUTHENTICATED; - LOG_VERBOSE("p_cb->sec_level=%d(SMP_SEC_AUTHENTICATED) ", - p_cb->sec_level); + log::verbose("p_cb->sec_level={}(SMP_SEC_AUTHENTICATED)", + p_cb->sec_level); p_cb->cb_evt = SMP_PASSKEY_REQ_EVT; int_evt = SMP_TK_REQ_EVT; break; case SMP_MODEL_OOB: - LOG_ERROR("Association Model=SMP_MODEL_OOB"); + log::error("Association Model=SMP_MODEL_OOB"); p_cb->sec_level = SMP_SEC_AUTHENTICATED; - LOG_VERBOSE("p_cb->sec_level=%d(SMP_SEC_AUTHENTICATED) ", - p_cb->sec_level); + log::verbose("p_cb->sec_level={}(SMP_SEC_AUTHENTICATED)", + p_cb->sec_level); p_cb->cb_evt = SMP_OOB_REQ_EVT; int_evt = SMP_TK_REQ_EVT; @@ -1429,7 +1455,7 @@ void smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { case SMP_MODEL_KEY_NOTIF: p_cb->sec_level = SMP_SEC_AUTHENTICATED; - LOG_VERBOSE("Need to generate Passkey"); + log::verbose("Need to generate Passkey"); /* generate passkey and notify application */ smp_generate_passkey(p_cb, NULL); @@ -1444,19 +1470,19 @@ void smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { break; case SMP_MODEL_OUT_OF_RANGE: - LOG_ERROR("Association Model=SMP_MODEL_OUT_OF_RANGE (failed)"); + log::error("Association Model=SMP_MODEL_OUT_OF_RANGE (failed)"); smp_int_data.status = SMP_UNKNOWN_IO_CAP; int_evt = SMP_AUTH_CMPL_EVT; break; default: - LOG_ERROR("Association Model=%d (SOMETHING IS WRONG WITH THE CODE)", - p_cb->selected_association_model); + log::error("Association Model={} (SOMETHING IS WRONG WITH THE CODE)", + p_cb->selected_association_model); smp_int_data.status = SMP_UNKNOWN_IO_CAP; int_evt = SMP_AUTH_CMPL_EVT; } - LOG_VERBOSE("sec_level=%d ", p_cb->sec_level); + log::verbose("sec_level={}", p_cb->sec_level); if (int_evt) smp_sm_event(p_cb, int_evt, &smp_int_data); } @@ -1465,7 +1491,7 @@ void smp_decide_association_model(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Description process IO response for a peripheral device. ******************************************************************************/ void smp_process_io_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) { /* pairing started by local (peripheral) Security Request */ smp_set_state(SMP_STATE_SEC_REQ_PENDING); @@ -1475,12 +1501,12 @@ void smp_process_io_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { /* pairing started by peer (central) Pairing Request */ p_cb->selected_association_model = smp_select_association_model(p_cb); - if (p_cb->secure_connections_only_mode_required && - (!(p_cb->le_secure_connections_mode_is_used) || + if (p_cb->sc_only_mode_locally_required && + (!(p_cb->sc_mode_required_by_peer) || (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS))) { - LOG_ERROR( - "Peripheral requires secure connection only mode " - "but it can't be provided -> Peripheral fails pairing"); + log::error( + "Peripheral requires secure connection only mode but it can't be " + "provided -> Peripheral fails pairing"); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_AUTH_FAIL; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); @@ -1509,15 +1535,15 @@ void smp_process_io_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { switch (p_cb->loc_oob_flag) { case SMP_OOB_NONE: - LOG_INFO("SMP_MODEL_SEC_CONN_OOB with SMP_OOB_NONE"); + log::info("SMP_MODEL_SEC_CONN_OOB with SMP_OOB_NONE"); smp_send_pair_rsp(p_cb, NULL); break; case SMP_OOB_PRESENT: - LOG_INFO("SMP_MODEL_SEC_CONN_OOB with SMP_OOB_PRESENT"); + log::info("SMP_MODEL_SEC_CONN_OOB with SMP_OOB_PRESENT"); if (smp_request_oob_data(p_cb)) return; break; case SMP_OOB_UNKNOWN: - LOG_WARN("SMP_MODEL_SEC_CONN_OOB with SMP_OOB_UNKNOWN"); + log::warn("SMP_MODEL_SEC_CONN_OOB with SMP_OOB_UNKNOWN"); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_AUTH_FAIL; smp_send_pair_fail(p_cb, &smp_int_data); @@ -1548,7 +1574,7 @@ void smp_br_process_peripheral_keys_response(tSMP_CB* p_cb, * transport. ******************************************************************************/ void smp_br_send_pair_response(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p_cb->local_i_key &= p_cb->peer_i_key; p_cb->local_r_key &= p_cb->peer_r_key; @@ -1574,7 +1600,7 @@ void smp_pairing_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * callback and remove the connection if needed. ******************************************************************************/ void smp_pair_terminate(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p_cb->status = SMP_CONN_TOUT; smp_proc_pairing_cmpl(p_cb); } @@ -1586,7 +1612,7 @@ void smp_pair_terminate(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { ******************************************************************************/ void smp_idle_terminate(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) { - LOG_VERBOSE("Pairing terminated at IDLE state."); + log::verbose("Pairing terminated at IDLE state."); p_cb->status = SMP_FAIL; smp_proc_pairing_cmpl(p_cb); } @@ -1603,7 +1629,7 @@ void smp_idle_terminate(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * - invokes SC phase 1 process. ******************************************************************************/ void smp_both_have_public_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* invokes DHKey computation */ smp_compute_dhkey(p_cb); @@ -1622,15 +1648,15 @@ void smp_both_have_public_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * model. ******************************************************************************/ void smp_start_secure_connection_phase1(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) { p_cb->sec_level = SMP_SEC_UNAUTHENTICATE; - LOG_VERBOSE("p_cb->sec_level=%d (SMP_SEC_UNAUTHENTICATE) ", - p_cb->sec_level); + log::verbose("p_cb->sec_level={} (SMP_SEC_UNAUTHENTICATE)", + p_cb->sec_level); } else { p_cb->sec_level = SMP_SEC_AUTHENTICATED; - LOG_VERBOSE("p_cb->sec_level=%d (SMP_SEC_AUTHENTICATED) ", p_cb->sec_level); + log::verbose("p_cb->sec_level={} (SMP_SEC_AUTHENTICATED)", p_cb->sec_level); } switch (p_cb->selected_association_model) { @@ -1646,7 +1672,7 @@ void smp_start_secure_connection_phase1(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { break; case SMP_MODEL_SEC_CONN_PASSKEY_DISP: /* passkey has to be provided to user */ - LOG_VERBOSE("Need to generate SC Passkey"); + log::verbose("Need to generate SC Passkey"); smp_generate_passkey(p_cb, NULL); break; case SMP_MODEL_SEC_CONN_OOB: @@ -1654,8 +1680,8 @@ void smp_start_secure_connection_phase1(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { smp_process_secure_connection_oob_data(p_cb, NULL); break; default: - LOG_ERROR("Association Model=%d is not used in LE SC", - p_cb->selected_association_model); + log::error("Association Model={} is not used in LE SC", + p_cb->selected_association_model); break; } } @@ -1667,7 +1693,7 @@ void smp_start_secure_connection_phase1(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Note It is supposed to be called in SC phase1. ******************************************************************************/ void smp_process_local_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); switch (p_cb->selected_association_model) { case SMP_MODEL_SEC_CONN_JUSTWORKS: @@ -1683,9 +1709,9 @@ void smp_process_local_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_COMM) { /* peripheral commitment is already received, send local nonce, wait * for remote nonce*/ - LOG_VERBOSE( - "central in assoc mode=%d " - "already rcvd peripheral commitment - race condition", + log::verbose( + "central in assoc mode={} already rcvd peripheral commitment - " + "race condition", p_cb->selected_association_model); p_cb->flags &= ~SMP_PAIR_FLAG_HAVE_PEER_COMM; smp_send_rand(p_cb, NULL); @@ -1716,8 +1742,8 @@ void smp_process_local_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { smp_set_state(SMP_STATE_WAIT_NONCE); break; default: - LOG_ERROR("Association Model=%d is not used in LE SC", - p_cb->selected_association_model); + log::error("Association Model={} is not used in LE SC", + p_cb->selected_association_model); break; } } @@ -1731,13 +1757,13 @@ void smp_process_local_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * Note It is supposed to be called in SC phase1. ******************************************************************************/ void smp_process_peer_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s, selected_association_model:%d", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), - p_cb->selected_association_model); + log::verbose("addr:{}, selected_association_model:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), + p_cb->selected_association_model); // PTS Testing failure modes if (p_cb->cert_failure == SMP_CONFIRM_VALUE_ERR) { - LOG_ERROR("failure case=%d", p_cb->cert_failure); + log::error("failure case={}", p_cb->cert_failure); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_CONFIRM_VALUE_ERR; p_cb->failure = SMP_CONFIRM_VALUE_ERR; @@ -1748,7 +1774,7 @@ void smp_process_peer_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { if ((p_cb->cert_failure == SMP_NUMERIC_COMPAR_FAIL) && (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) && (p_cb->role == HCI_ROLE_PERIPHERAL)) { - LOG_ERROR("failure case=%d", p_cb->cert_failure); + log::error("failure case={}", p_cb->cert_failure); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL; p_cb->failure = SMP_NUMERIC_COMPAR_FAIL; @@ -1778,7 +1804,7 @@ void smp_process_peer_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { (p_cb->local_io_capability == SMP_IO_CAP_IO || p_cb->local_io_capability == SMP_IO_CAP_KBDISP)) { /* display consent dialog */ - LOG_VERBOSE("JUST WORKS showing Consent Dialog"); + log::verbose("JUST WORKS showing Consent Dialog"); p_cb->cb_evt = SMP_CONSENT_REQ_EVT; smp_set_state(SMP_STATE_WAIT_NONCE); smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL); @@ -1824,8 +1850,8 @@ void smp_process_peer_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL); break; default: - LOG_ERROR("Association Model=%d is not used in LE SC", - p_cb->selected_association_model); + log::error("Association Model={} is not used in LE SC", + p_cb->selected_association_model); break; } } @@ -1836,11 +1862,11 @@ void smp_process_peer_nonce(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * received from the peer DHKey check value. ******************************************************************************/ void smp_match_dhkey_checks(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (memcmp(p_data->key.p_data, p_cb->remote_dhkey_check.data(), OCTET16_LEN)) { - LOG_WARN("dhkey chcks do no match"); + log::warn("dhkey chcks do no match"); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_DHKEY_CHK_FAIL; p_cb->failure = SMP_DHKEY_CHK_FAIL; @@ -1872,7 +1898,7 @@ void smp_match_dhkey_checks(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { ******************************************************************************/ void smp_move_to_secure_connections_phase2(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL); } @@ -1887,7 +1913,7 @@ void smp_move_to_secure_connections_phase2(tSMP_CB* p_cb, ******************************************************************************/ void smp_phase_2_dhkey_checks_are_present(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK) smp_sm_event(p_cb, SMP_SC_2_DHCK_CHKS_PRES_EVT, NULL); @@ -1902,7 +1928,7 @@ void smp_phase_2_dhkey_checks_are_present(tSMP_CB* p_cb, * ******************************************************************************/ void smp_wait_for_both_public_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if ((p_cb->flags & SMP_PAIR_FLAG_HAVE_PEER_PUBL_KEY) && (p_cb->flags & SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY)) { @@ -1922,7 +1948,7 @@ void smp_wait_for_both_public_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { void smp_start_passkey_verification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t* p = NULL; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = p_cb->local_random.data(); UINT32_TO_STREAM(p, p_data->passkey); @@ -1939,18 +1965,18 @@ void smp_start_passkey_verification(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { ******************************************************************************/ void smp_process_secure_connection_oob_data(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); tSMP_SC_OOB_DATA* p_sc_oob_data = &p_cb->sc_oob_data; if (p_sc_oob_data->loc_oob_data.present) { p_cb->local_random = p_sc_oob_data->loc_oob_data.randomizer; } else { - LOG_VERBOSE("local OOB randomizer is absent"); + log::verbose("local OOB randomizer is absent"); p_cb->local_random = {0}; } if (!p_sc_oob_data->peer_oob_data.present) { - LOG_VERBOSE("peer OOB data is absent"); + log::verbose("peer OOB data is absent"); p_cb->peer_random = {0}; } else { p_cb->peer_random = p_sc_oob_data->peer_oob_data.randomizer; @@ -1967,14 +1993,14 @@ void smp_process_secure_connection_oob_data(tSMP_CB* p_cb, if (p_cb->peer_oob_flag != SMP_OOB_PRESENT) { /* the peer doesn't have local randomiser */ - LOG_VERBOSE( + log::verbose( "peer didn't receive local OOB data, set local randomizer to 0"); p_cb->local_random = {0}; } } - print128(p_cb->local_random, (const uint8_t*)"local OOB randomizer"); - print128(p_cb->peer_random, (const uint8_t*)"peer OOB randomizer"); + print128(p_cb->local_random, "local OOB randomizer"); + print128(p_cb->peer_random, "peer OOB randomizer"); smp_start_nonce_generation(p_cb); } @@ -1985,7 +2011,7 @@ void smp_process_secure_connection_oob_data(tSMP_CB* p_cb, * (to be saved in sc_oob_data.loc_oob_data.randomizer). ******************************************************************************/ void smp_set_local_oob_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); memcpy(p_cb->sc_oob_data.loc_oob_data.private_key_used, p_cb->private_key, BT_OCTET32_LEN); @@ -2000,7 +2026,7 @@ void smp_set_local_oob_keys(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * for safekeeping. ******************************************************************************/ void smp_set_local_oob_random_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p_cb->sc_oob_data.loc_oob_data.randomizer = p_cb->rand; p_cb->sc_oob_data.loc_oob_data.commitment = @@ -2042,8 +2068,8 @@ void smp_link_encrypted(const RawAddress& bda, uint8_t encr_enable) { tSMP_CB* p_cb = &smp_cb; if (smp_cb.pairing_bda == bda) { - LOG_DEBUG("SMP encryption enable:%hhu device:%s", encr_enable, - ADDRESS_TO_LOGGABLE_CSTR(bda)); + log::debug("SMP encryption enable:{} device:{}", encr_enable, + ADDRESS_TO_LOGGABLE_CSTR(bda)); /* encryption completed with STK, remember the key size now, could be * overwritten when key exchange happens */ @@ -2059,14 +2085,14 @@ void smp_link_encrypted(const RawAddress& bda, uint8_t encr_enable) { smp_sm_event(&smp_cb, SMP_ENCRYPTED_EVT, &smp_int_data); } else { - LOG_WARN( - "SMP state machine busy so skipping encryption enable:%hhu device:%s", + log::warn( + "SMP state machine busy so skipping encryption enable:{} device:{}", encr_enable, ADDRESS_TO_LOGGABLE_CSTR(bda)); } } void smp_cancel_start_encryption_attempt() { - LOG_ERROR("Encryption request cancelled"); + log::error("Encryption request cancelled"); smp_sm_event(&smp_cb, SMP_DISCARD_SEC_REQ_EVT, NULL); } @@ -2081,7 +2107,7 @@ void smp_cancel_start_encryption_attempt() { * ******************************************************************************/ bool smp_proc_ltk_request(const RawAddress& bda) { - LOG_VERBOSE("addr:%s,state=%d", ADDRESS_TO_LOGGABLE_CSTR(bda), smp_cb.state); + log::verbose("addr:{},state={}", ADDRESS_TO_LOGGABLE_CSTR(bda), smp_cb.state); bool match = false; if (bda == smp_cb.pairing_bda) { @@ -2116,7 +2142,7 @@ bool smp_proc_ltk_request(const RawAddress& bda) { void smp_process_secure_connection_long_term_key(void) { tSMP_CB* p_cb = &smp_cb; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_save_secure_connections_long_term_key(p_cb); smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false); @@ -2135,7 +2161,7 @@ void smp_process_secure_connection_long_term_key(void) { * ******************************************************************************/ void smp_set_derive_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p_cb->derive_lk = true; smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_LK, false); smp_key_distribution(p_cb, NULL); @@ -2154,9 +2180,9 @@ void smp_derive_link_key_from_long_term_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (!smp_calculate_link_key_from_long_term_key(p_cb)) { - LOG_ERROR("calc link key failed"); + log::error("calc link key failed"); tSMP_INT_DATA smp_int_data; smp_int_data.status = status; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); @@ -2178,9 +2204,9 @@ void smp_derive_link_key_from_long_term_key(tSMP_CB* p_cb, void smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (!smp_calculate_long_term_key_from_link_key(p_cb)) { - LOG_ERROR("calc LTK failed"); + log::error("calc LTK failed"); tSMP_INT_DATA smp_int_data; smp_int_data.status = status; smp_sm_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data); @@ -2189,13 +2215,13 @@ void smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda); if (p_dev_rec) { - LOG_VERBOSE("dev_type=%d ", p_dev_rec->device_type); + log::verbose("dev_type={}", p_dev_rec->device_type); p_dev_rec->device_type |= BT_DEVICE_TYPE_BLE; } else { - LOG_ERROR("failed to find Security Record"); + log::error("failed to find Security Record"); } - LOG_VERBOSE("LTK derivation from LK successfully completed"); + log::verbose("LTK derivation from LK successfully completed"); smp_save_secure_connections_long_term_key(p_cb); smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false); smp_br_select_next_key(p_cb, NULL); @@ -2208,7 +2234,7 @@ void smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { ******************************************************************************/ static void smp_key_distribution_by_transport(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->smp_over_br) { smp_br_select_next_key(p_cb, NULL); } else { @@ -2222,7 +2248,7 @@ static void smp_key_distribution_by_transport(tSMP_CB* p_cb, * callback and remove the connection if needed. ******************************************************************************/ void smp_br_pairing_complete(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->total_tx_unacked == 0) { /* process the pairing complete */ diff --git a/system/stack/smp/smp_api.cc b/system/stack/smp/smp_api.cc index 606cc1f60429d98538cd234e9fab501628def76b..f4422079101a124ada707dbca723d3acb5a5b9a3 100644 --- a/system/stack/smp/smp_api.cc +++ b/system/stack/smp/smp_api.cc @@ -26,6 +26,7 @@ #include "smp_api.h" +#include #include #include "l2c_api.h" @@ -36,6 +37,8 @@ #include "stack/include/btm_sec_api_types.h" #include "types/raw_address.h" +using namespace bluetooth; + /******************************************************************************* * * Function SMP_Init @@ -57,10 +60,10 @@ void SMP_Init(uint8_t init_security_mode) { smp_cb.init(init_security_mode); } * ******************************************************************************/ bool SMP_Register(tSMP_CALLBACK* p_cback) { - LOG_VERBOSE("state=%d", smp_cb.state); + log::verbose("state={}", smp_cb.state); if (smp_cb.p_callback != NULL) { - LOG_ERROR("duplicate registration, overwrite it"); + log::error("duplicate registration, overwrite it"); } smp_cb.p_callback = p_cback; @@ -82,8 +85,8 @@ bool SMP_Register(tSMP_CALLBACK* p_cback) { tSMP_STATUS SMP_Pair(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type) { tSMP_CB* p_cb = &smp_cb; - LOG_VERBOSE("state=%d br_state=%d flag=0x%x, bd_addr=%s", p_cb->state, - p_cb->br_state, p_cb->flags, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("state={} br_state={} flag=0x{:x}, bd_addr={}", p_cb->state, + p_cb->br_state, p_cb->flags, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (p_cb->state != SMP_STATE_IDLE || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD || p_cb->smp_over_br) { @@ -101,7 +104,7 @@ tSMP_STATUS SMP_Pair(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type) { tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_INTERNAL_ERR; p_cb->status = SMP_PAIR_INTERNAL_ERR; - LOG_ERROR("L2C connect fixed channel failed."); + log::error("L2C connect fixed channel failed."); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); return SMP_PAIR_INTERNAL_ERR; } @@ -130,8 +133,8 @@ tSMP_STATUS SMP_Pair(const RawAddress& bd_addr) { tSMP_STATUS SMP_BR_PairWith(const RawAddress& bd_addr) { tSMP_CB* p_cb = &smp_cb; - LOG_VERBOSE("state=%d br_state=%d flag=0x%x, bd_addr=%s", p_cb->state, - p_cb->br_state, p_cb->flags, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("state={} br_state={} flag=0x{:x}, bd_addr={}", p_cb->state, + p_cb->br_state, p_cb->flags, ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); if (p_cb->state != SMP_STATE_IDLE || p_cb->smp_over_br || p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) { @@ -145,7 +148,7 @@ tSMP_STATUS SMP_BR_PairWith(const RawAddress& bd_addr) { p_cb->pairing_bda = bd_addr; if (!L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, bd_addr)) { - LOG_ERROR("L2C connect fixed channel failed."); + log::error("L2C connect fixed channel failed."); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_INTERNAL_ERR; p_cb->status = SMP_PAIR_INTERNAL_ERR; @@ -170,10 +173,10 @@ tSMP_STATUS SMP_BR_PairWith(const RawAddress& bd_addr) { bool SMP_PairCancel(const RawAddress& bd_addr) { tSMP_CB* p_cb = &smp_cb; - LOG_VERBOSE("state=%d flag=0x%x ", p_cb->state, p_cb->flags); + log::verbose("state={} flag=0x{:x}", p_cb->state, p_cb->flags); if (p_cb->state != SMP_STATE_IDLE && p_cb->pairing_bda == bd_addr) { p_cb->is_pair_cancel = true; - LOG_VERBOSE("set fail reason Unknown"); + log::verbose("set fail reason Unknown"); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_FAIL_UNKNOWN; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); @@ -197,7 +200,7 @@ bool SMP_PairCancel(const RawAddress& bd_addr) { * ******************************************************************************/ void SMP_SecurityGrant(const RawAddress& bd_addr, tSMP_STATUS res) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); // If just showing consent dialog, send response if (smp_cb.cb_evt == SMP_CONSENT_REQ_EVT) { @@ -206,7 +209,7 @@ void SMP_SecurityGrant(const RawAddress& bd_addr, tSMP_STATUS res) { if (res == SMP_SUCCESS) { smp_sm_event(&smp_cb, SMP_SC_NC_OK_EVT, NULL); } else { - LOG_WARN("Consent dialog fails for JUSTWORKS"); + log::warn("Consent dialog fails for JUSTWORKS"); /* send pairing failure */ tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL; @@ -225,7 +228,7 @@ void SMP_SecurityGrant(const RawAddress& bd_addr, tSMP_STATUS res) { smp_cb.tk = {0}; smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &smp_int_data); } else { - LOG_WARN("Consent dialog fails for ENCRYPTION_ONLY"); + log::warn("Consent dialog fails for ENCRYPTION_ONLY"); /* send pairing failure */ tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL; @@ -266,8 +269,8 @@ void SMP_SecurityGrant(const RawAddress& bd_addr, tSMP_STATUS res) { * * Function SMP_PasskeyReply * - * Description This function is called after Security Manager submitted - * passkey request to the application. + * Description This function is called when the user replies + * passkey after being requested. * * Parameters: bd_addr - Address of the device for which passkey was * requested @@ -281,26 +284,25 @@ void SMP_PasskeyReply(const RawAddress& bd_addr, uint8_t res, uint32_t passkey) { tSMP_CB* p_cb = &smp_cb; - LOG_VERBOSE("Key:%d Result:%d", passkey, res); + log::verbose("Key:{} Result:{}", passkey, res); /* If timeout already expired or has been canceled, ignore the reply */ if (p_cb->cb_evt != SMP_PASSKEY_REQ_EVT) { - LOG_WARN("Wrong State:%d", p_cb->state); + log::warn("Wrong State:{}", p_cb->state); return; } if (bd_addr != p_cb->pairing_bda) { - LOG_ERROR("Wrong BD Addr"); + log::error("Wrong BD Addr"); return; } if (passkey > BTM_MAX_PASSKEY_VAL || res != SMP_SUCCESS) { - LOG_WARN("Wrong key len:%d or passkey entry fail", passkey); + log::warn("Invalid passkey value:{} or passkey entry fail", passkey); /* send pairing failure */ tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PASSKEY_ENTRY_FAIL; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); - } else if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_ENT) { tSMP_INT_DATA smp_int_data; @@ -309,8 +311,6 @@ void SMP_PasskeyReply(const RawAddress& bd_addr, uint8_t res, } else { smp_convert_string_to_tk(&p_cb->tk, passkey); } - - return; } /******************************************************************************* @@ -328,21 +328,21 @@ void SMP_PasskeyReply(const RawAddress& bd_addr, uint8_t res, void SMP_ConfirmReply(const RawAddress& bd_addr, uint8_t res) { tSMP_CB* p_cb = &smp_cb; - LOG_VERBOSE("addr:%s, Result:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), res); + log::verbose("addr:{}, Result:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), res); /* If timeout already expired or has been canceled, ignore the reply */ if (p_cb->cb_evt != SMP_NC_REQ_EVT) { - LOG_WARN("Wrong State:%d", p_cb->state); + log::warn("Wrong State:{}", p_cb->state); return; } if (bd_addr != p_cb->pairing_bda) { - LOG_ERROR("Wrong BD Addr"); + log::error("Wrong BD Addr"); return; } if (res != SMP_SUCCESS) { - LOG_WARN("Numeric Comparison fails"); + log::warn("Numeric Comparison fails"); /* send pairing failure */ tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL; @@ -369,7 +369,7 @@ void SMP_OobDataReply(const RawAddress& bd_addr, tSMP_STATUS res, uint8_t len, tSMP_CB* p_cb = &smp_cb; tSMP_KEY key; - LOG_VERBOSE("State:%d res:%d", smp_cb.state, res); + log::verbose("State:{} res:{}", smp_cb.state, res); /* If timeout already expired or has been canceled, ignore the reply */ if (p_cb->state != SMP_STATE_WAIT_APP_RSP || p_cb->cb_evt != SMP_OOB_REQ_EVT) @@ -408,16 +408,15 @@ void SMP_SecureConnectionOobDataReply(uint8_t* p_data) { tSMP_SC_OOB_DATA* p_oob = (tSMP_SC_OOB_DATA*)p_data; if (!p_oob) { - LOG_ERROR("received no data"); + log::error("received no data"); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_OOB_FAIL; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); return; } - LOG_VERBOSE( - "req_oob_type:%d, loc_oob_data.present:%d, " - "peer_oob_data.present:%d", + log::verbose( + "req_oob_type:{}, loc_oob_data.present:{}, peer_oob_data.present:{}", p_cb->req_oob_type, p_oob->loc_oob_data.present, p_oob->peer_oob_data.present); @@ -444,7 +443,7 @@ void SMP_SecureConnectionOobDataReply(uint8_t* p_data) { data_missing = true; break; default: - LOG_VERBOSE("Unexpected OOB data type requested. Fail OOB"); + log::verbose("Unexpected OOB data type requested. Fail OOB"); data_missing = true; break; } @@ -502,24 +501,24 @@ void SMP_ClearLocScOobData() { smp_clear_local_oob_data(); } void SMP_SirkConfirmDeviceReply(const RawAddress& bd_addr, uint8_t res) { tSMP_CB* p_cb = &smp_cb; - LOG_INFO("Result:%d", res); + log::info("Result:{}", res); /* If timeout already expired or has been canceled, ignore the reply */ if (p_cb->cb_evt != SMP_SIRK_VERIFICATION_REQ_EVT) { - LOG_WARN("Wrong State:%d", p_cb->state); + log::warn("Wrong State:{}", p_cb->state); return; } if (bd_addr != p_cb->pairing_bda) { - LOG_WARN("Wrong confirmation BD Addr: %s vs expected %s", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::warn("Wrong confirmation BD Addr: {} vs expected {}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); return; } tSMP_INT_DATA smp_int_data; if (res != SMP_SUCCESS) { - LOG_WARN("Verification fails"); + log::warn("Verification fails"); /* send pairing failure */ smp_int_data.status = SMP_SIRK_DEVICE_INVALID; smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); diff --git a/system/stack/smp/smp_br_main.cc b/system/stack/smp/smp_br_main.cc index 24a84ab350e72d0b777f32d576ff0155e3773c06..3832590b3633304af8cea81aa53fefd80cf14803 100644 --- a/system/stack/smp/smp_br_main.cc +++ b/system/stack/smp/smp_br_main.cc @@ -18,10 +18,14 @@ #define LOG_TAG "smp" +#include + #include "os/log.h" #include "smp_int.h" #include "types/hci_role.h" +using namespace bluetooth; + const char* const smp_br_state_name[SMP_BR_STATE_MAX + 1] = { "SMP_BR_STATE_IDLE", "SMP_BR_STATE_WAIT_APP_RSP", "SMP_BR_STATE_PAIR_REQ_RSP", "SMP_BR_STATE_BOND_PENDING", @@ -246,12 +250,12 @@ static const tSMP_BR_ENTRY_TBL smp_br_entry_table[] = { ******************************************************************************/ void smp_set_br_state(tSMP_BR_STATE br_state) { if (br_state < SMP_BR_STATE_MAX) { - LOG_VERBOSE("BR_State change:%s(%d)==>%s(%d)", - smp_get_br_state_name(smp_cb.br_state), smp_cb.br_state, - smp_get_br_state_name(br_state), br_state); + log::verbose("BR_State change:{}({})==>{}({})", + smp_get_br_state_name(smp_cb.br_state), smp_cb.br_state, + smp_get_br_state_name(br_state), br_state); smp_cb.br_state = br_state; } else { - LOG_VERBOSE("invalid br_state=%d", br_state); + log::verbose("invalid br_state={}", br_state); } } @@ -305,23 +309,22 @@ void smp_br_state_machine_event(tSMP_CB* p_cb, tSMP_BR_EVENT event, tSMP_BR_SM_TBL state_table; uint8_t action, entry; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::debug("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (curr_state >= SMP_BR_STATE_MAX) { - LOG_VERBOSE("Invalid br_state: %d", curr_state); + log::error("Invalid br_state: {}", curr_state); return; } if (p_cb->role > HCI_ROLE_PERIPHERAL) { - LOG_ERROR("invalid role %d", p_cb->role); + log::error("invalid role {}", p_cb->role); return; } tSMP_BR_ENTRY_TBL entry_table = smp_br_entry_table[p_cb->role]; - LOG_VERBOSE("SMP Role:%s State:[%s(%d)], Event:[%s(%d)]", - (p_cb->role == HCI_ROLE_PERIPHERAL) ? "Peripheral" : "Central", - smp_get_br_state_name(p_cb->br_state), p_cb->br_state, - smp_get_br_event_name(event), event); + log::debug("Role:{} State:[{}({})], Event:[{}({})]", + hci_role_text(p_cb->role), smp_get_br_state_name(p_cb->br_state), + p_cb->br_state, smp_get_br_event_name(event), event); /* look up the state table for the current state */ /* lookup entry / w event & curr_state */ @@ -336,9 +339,9 @@ void smp_br_state_machine_event(tSMP_CB* p_cb, tSMP_BR_EVENT event, state_table = smp_br_state_table[curr_state][p_cb->role]; } } else { - LOG_VERBOSE("Ignore event[%s(%d)] in state[%s(%d)]", - smp_get_br_event_name(event), event, - smp_get_br_state_name(curr_state), curr_state); + log::verbose("Ignore event[{}({})] in state[{}({})]", + smp_get_br_event_name(event), event, + smp_get_br_state_name(curr_state), curr_state); return; } @@ -358,5 +361,5 @@ void smp_br_state_machine_event(tSMP_CB* p_cb, tSMP_BR_EVENT event, break; } } - LOG_VERBOSE("result state=%s", smp_get_br_state_name(p_cb->br_state)); + log::verbose("result state={}", smp_get_br_state_name(p_cb->br_state)); } diff --git a/system/stack/smp/smp_int.h b/system/stack/smp/smp_int.h index 7ddd471d9a4d13c51c19b3323bcf46efbd9b2af1..773997922b7a4ba9a2c1afd68df00d4f76a0fcc1 100644 --- a/system/stack/smp/smp_int.h +++ b/system/stack/smp/smp_int.h @@ -24,6 +24,8 @@ #ifndef SMP_INT_H #define SMP_INT_H +#include + #include #include "macros.h" @@ -31,6 +33,7 @@ #include "stack/include/bt_hdr.h" #include "stack/include/bt_octets.h" #include "stack/include/smp_api_types.h" +#include "types/hci_role.h" #include "types/raw_address.h" typedef enum : uint16_t { @@ -59,10 +62,6 @@ typedef enum : uint8_t { SMP_MODEL_OUT_OF_RANGE = 9, } tSMP_ASSO_MODEL; -#ifndef SMP_MAX_CONN -#define SMP_MAX_CONN 2 -#endif - #define SMP_WAIT_FOR_RSP_TIMEOUT_MS (30 * 1000) #define SMP_DELAYED_AUTH_TIMEOUT_MS 500 @@ -256,7 +255,7 @@ typedef union { /* internal status mask */ #define SMP_PAIR_FLAGS_WE_STARTED_DD (1) #define SMP_PAIR_FLAGS_PEER_STARTED_DD (1 << 1) -#define SMP_PAIR_FLAGS_CMD_CONFIRM (1 << SMP_OPCODE_CONFIRM) /* 1 << 3 */ +#define SMP_PAIR_FLAGS_CMD_CONFIRM_RCVD (1 << SMP_OPCODE_CONFIRM) /* 1 << 3 */ #define SMP_PAIR_FLAG_ENC_AFTER_PAIR (1 << 4) #define SMP_PAIR_FLAG_HAVE_PEER_DHK_CHK \ (1 << 5) /* used on peripheral to resolve race condition */ @@ -267,14 +266,11 @@ typedef union { #define SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY \ (1 << 8) /* used on peripheral to resolve race condition */ +#define SMP_PAIR_FLAGS_CMD_CONFIRM_SENT (1 << 9) + /* check if authentication requirement need MITM protection */ #define SMP_NO_MITM_REQUIRED(x) (((x)&SMP_AUTH_YN_BIT) == 0) -typedef struct { - RawAddress bd_addr; - BT_HDR* p_copy; -} tSMP_REQ_Q_ENTRY; - /* SMP control block */ class tSMP_CB { public: @@ -295,7 +291,7 @@ class tSMP_CB { tSMP_BR_STATE br_state; /* if SMP over BR/ERD has priority over SMP */ uint8_t failure; tSMP_STATUS status; - uint8_t role; + tHCI_ROLE role; uint16_t flags; tSMP_EVT cb_evt; tSMP_SEC_LEVEL sec_level; @@ -322,11 +318,14 @@ class tSMP_CB { tSMP_OOB_FLAG loc_oob_flag; tSMP_AUTH_REQ peer_auth_req; tSMP_AUTH_REQ loc_auth_req; - bool secure_connections_only_mode_required; /* true if locally SM is required - to operate */ + + bool sc_only_mode_locally_required; /* true if sc_only required required + locally */ + bool sc_mode_required_by_peer; /* true if peer requires sc in pair_req or + pair_rsp */ + /* either in Secure Connections mode or not at all */ tSMP_ASSO_MODEL selected_association_model; - bool le_secure_connections_mode_is_used; bool key_derivation_h7_used; bool le_sc_kp_notif_is_used; tSMP_SC_KEY_TYPE local_keypress_notification; @@ -500,7 +499,7 @@ void smp_start_nonce_generation(tSMP_CB* p_cb); bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb); bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb); -void print128(const Octet16& x, const uint8_t* key_name); +void print128(const Octet16& x, const char* key_name); void smp_xor_128(Octet16* a, const Octet16& b); /* Save the p_cb->sc_oob_data.loc_oob_data for later, since the p_cb gets @@ -508,4 +507,14 @@ void smp_xor_128(Octet16* a, const Octet16& b); void smp_save_local_oob_data(tSMP_CB* p_cb); void smp_clear_local_oob_data(); bool smp_has_local_oob_data(); + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + #endif /* SMP_INT_H */ diff --git a/system/stack/smp/smp_keys.cc b/system/stack/smp/smp_keys.cc index c03e100c079381374d1b8fc01c22e307a6febe22..d0c01da36a4ad0e9657faf372a178b7f4c82dcaa 100644 --- a/system/stack/smp/smp_keys.cc +++ b/system/stack/smp/smp_keys.cc @@ -25,12 +25,15 @@ #include #include +#include #include +#include #include #include "crypto_toolbox/crypto_toolbox.h" -#include "device/include/controller.h" +#include "hci/controller_interface.h" +#include "main/shim/entry.h" #include "os/log.h" #include "osi/include/osi.h" #include "p_256_ecc_pp.h" @@ -45,8 +48,10 @@ #include "stack/include/btm_ble_sec_api.h" #include "types/raw_address.h" -using base::Bind; +using bluetooth::common::BindOnce; +using bluetooth::common::OnceCallback; using crypto_toolbox::aes_128; +using namespace bluetooth; #ifndef SMP_MAX_ENC_REPEAT #define SMP_MAX_ENC_REPEAT 3 @@ -56,7 +61,9 @@ static void smp_process_stk(tSMP_CB* p_cb, Octet16* p); static Octet16 smp_calculate_legacy_short_term_key(tSMP_CB* p_cb); static void smp_process_private_key(tSMP_CB* p_cb); -#define SMP_PASSKEY_MASK 0xfff00000 +static void send_ble_rand(OnceCallback callback); + +#define SMP_PASSKEY_MASK 0x000fffff // If there is data saved here, then use its info instead // This needs to be cleared on a successfult pairing using the oob data @@ -91,14 +98,11 @@ void smp_debug_print_nbyte_big_endian(uint8_t* p, const char* key_name, uint8_t len) {} /** This function is called to process a passkey. */ -void smp_proc_passkey(tSMP_CB* p_cb, BT_OCTET8 rand) { +void smp_proc_passkey(tSMP_CB* p_cb, uint64_t rand) { uint8_t* tt = p_cb->tk.data(); - uint32_t passkey; /* 19655 test number; */ - uint8_t* pp = rand; + uint32_t passkey = static_cast(rand & SMP_PASSKEY_MASK); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); - STREAM_TO_UINT32(passkey, pp); - passkey &= ~SMP_PASSKEY_MASK; + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* truncate by maximum value */ while (passkey > BTM_MAX_PASSKEY_VAL) passkey >>= 1; @@ -139,9 +143,9 @@ void smp_proc_passkey(tSMP_CB* p_cb, BT_OCTET8 rand) { * ******************************************************************************/ void smp_generate_passkey(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* generate MRand or SRand */ - btsnd_hcic_ble_rand(Bind(&smp_proc_passkey, p_cb)); + send_ble_rand(BindOnce(&smp_proc_passkey, p_cb)); } /******************************************************************************* @@ -158,10 +162,10 @@ void smp_generate_passkey(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { void smp_generate_stk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { Octet16 output; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); - if (p_cb->le_secure_connections_mode_is_used) { - LOG_VERBOSE("FOR LE SC LTK IS USED INSTEAD OF STK"); + if (p_cb->sc_mode_required_by_peer) { + log::verbose("FOR LE SC LTK IS USED INSTEAD OF STK"); output = p_cb->ltk; } else { output = smp_calculate_legacy_short_term_key(p_cb); @@ -180,7 +184,7 @@ void smp_compute_csrk(uint16_t div, tSMP_CB* p_cb) { p_cb->div = div; - LOG_VERBOSE("div=0x%x", p_cb->div); + log::verbose("div=0x{:x}", p_cb->div); const Octet16& er = BTM_GetDeviceEncRoot(); /* CSRK = d1(ER, DIV, 1) */ UINT16_TO_STREAM(p, p_cb->div); @@ -196,17 +200,16 @@ void smp_compute_csrk(uint16_t div, tSMP_CB* p_cb) { void smp_generate_csrk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { bool div_status; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); div_status = btm_get_local_div(p_cb->pairing_bda, &p_cb->div); if (div_status) { smp_compute_csrk(p_cb->div, p_cb); } else { - LOG_VERBOSE("Generate DIV for CSRK"); - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - uint16_t div; - STREAM_TO_UINT16(div, rand); + log::verbose("Generate DIV for CSRK"); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + uint16_t div = static_cast(rand); smp_compute_csrk(div, p_cb); }, p_cb)); @@ -220,7 +223,7 @@ void smp_generate_csrk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { void smp_concatenate_local(tSMP_CB* p_cb, uint8_t** p_data, uint8_t op_code) { uint8_t* p = *p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); UINT8_TO_STREAM(p, op_code); UINT8_TO_STREAM(p, p_cb->local_io_capability); UINT8_TO_STREAM(p, p_cb->loc_oob_flag); @@ -239,7 +242,7 @@ void smp_concatenate_local(tSMP_CB* p_cb, uint8_t** p_data, uint8_t op_code) { void smp_concatenate_peer(tSMP_CB* p_cb, uint8_t** p_data, uint8_t op_code) { uint8_t* p = *p_data; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); UINT8_TO_STREAM(p, op_code); UINT8_TO_STREAM(p, p_cb->peer_io_caps); UINT8_TO_STREAM(p, p_cb->peer_oob_flag); @@ -258,9 +261,9 @@ void smp_concatenate_peer(tSMP_CB* p_cb, uint8_t** p_data, uint8_t op_code) { */ Octet16 smp_gen_p1_4_confirm(tSMP_CB* p_cb, tBLE_ADDR_TYPE remote_bd_addr_type) { - LOG_VERBOSE("pairing_addr:%s, rmt_addr_type:%s", - ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), - AddressTypeText(remote_bd_addr_type).c_str()); + log::verbose("pairing_addr:{}, rmt_addr_type:{}", + ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), + AddressTypeText(remote_bd_addr_type)); Octet16 p1; uint8_t* p = p1.data(); if (p_cb->role == HCI_ROLE_CENTRAL) { @@ -294,7 +297,7 @@ Octet16 smp_gen_p1_4_confirm(tSMP_CB* p_cb, * p2 = ra || ia || padding */ Octet16 smp_gen_p2_4_confirm(tSMP_CB* p_cb, const RawAddress& remote_bda) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); Octet16 p2{0}; uint8_t* p = p2.data(); /* 32-bit Padding */ @@ -325,13 +328,13 @@ Octet16 smp_gen_p2_4_confirm(tSMP_CB* p_cb, const RawAddress& remote_bda) { ******************************************************************************/ tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, const Octet16& rand, Octet16* output) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); RawAddress remote_bda; tBLE_ADDR_TYPE remote_bd_addr_type = BLE_ADDR_PUBLIC; /* get remote connection specific bluetooth address */ if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, remote_bda, &remote_bd_addr_type, true)) { - LOG_ERROR("cannot obtain remote device address"); + log::error("cannot obtain remote device address"); return SMP_PAIR_FAIL_UNKNOWN; } /* get local connection specific bluetooth address */ @@ -368,7 +371,7 @@ tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, const Octet16& rand, * ******************************************************************************/ static void smp_generate_confirm(tSMP_CB* p_cb) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_debug_print_nbyte_little_endian(p_cb->rand.data(), "local_rand", 16); Octet16 output; tSMP_STATUS status = smp_calculate_comfirm(p_cb, p_cb->rand, &output); @@ -402,16 +405,16 @@ static void smp_generate_confirm(tSMP_CB* p_cb) { ******************************************************************************/ void smp_generate_srand_mrand_confirm(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* generate MRand or SRand */ - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy(p_cb->rand.data(), rand, 8); - + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(p_cb->rand.data(), (uint8_t*)&rand, sizeof(uint64_t)); /* generate 64 MSB of MRand or SRand */ - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy((void*)&p_cb->rand[8], rand, BT_OCTET8_LEN); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(p_cb->rand.data() + sizeof(uint64_t), (uint8_t*)&rand, + sizeof(uint64_t)); smp_generate_confirm(p_cb); }, p_cb)); @@ -432,7 +435,7 @@ void smp_generate_srand_mrand_confirm(tSMP_CB* p_cb, * ******************************************************************************/ void smp_generate_compare(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_debug_print_nbyte_little_endian(p_cb->rrand, "peer rand", 16); Octet16 output; tSMP_STATUS status = smp_calculate_comfirm(p_cb, p_cb->rrand, &output); @@ -457,7 +460,7 @@ void smp_generate_compare(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { static void smp_process_stk(tSMP_CB* p_cb, Octet16* p) { tSMP_KEY key; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_mask_enc_key(p_cb->loc_enc_size, p); key.key_type = SMP_KEY_TYPE_STK; @@ -474,7 +477,7 @@ static void smp_process_ediv(tSMP_CB* p_cb, Octet16& p) { uint8_t* pp = p.data(); uint16_t y; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); STREAM_TO_UINT16(y, pp); /* EDIV = Y xor DIV */ @@ -491,14 +494,14 @@ static void smp_process_ediv(tSMP_CB* p_cb, Octet16& p) { /** * This function is to proceed generate Y = E(DHK, Rand) */ -static void smp_generate_y(tSMP_CB* p_cb, BT_OCTET8 rand) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); +static void smp_generate_y(tSMP_CB* p_cb, uint64_t rand) { + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); const Octet16& dhk = BTM_GetDeviceDHK(); - memcpy(p_cb->enc_rand, rand, BT_OCTET8_LEN); + memcpy(p_cb->enc_rand, (uint8_t*)&rand, sizeof(uint64_t)); Octet16 rand16{}; - memcpy(rand16.data(), rand, BT_OCTET8_LEN); + memcpy(rand16.data(), (uint8_t*)&rand, sizeof(uint64_t)); Octet16 output = aes_128(dhk, rand16); smp_process_ediv(p_cb, output); } @@ -509,7 +512,7 @@ static void smp_generate_y(tSMP_CB* p_cb, BT_OCTET8 rand) { static void smp_generate_ltk_cont(uint16_t div, tSMP_CB* p_cb) { p_cb->div = div; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); const Octet16& er = BTM_GetDeviceEncRoot(); /* LTK = d1(ER, DIV, 0)= e(ER, DIV)*/ @@ -522,7 +525,7 @@ static void smp_generate_ltk_cont(uint16_t div, tSMP_CB* p_cb) { p_cb->ltk = ltk; /* generate EDIV and rand now */ - btsnd_hcic_ble_rand(Bind(&smp_generate_y, p_cb)); + send_ble_rand(BindOnce(&smp_generate_y, p_cb)); } /******************************************************************************* @@ -541,12 +544,12 @@ static void smp_generate_ltk_cont(uint16_t div, tSMP_CB* p_cb) { * ******************************************************************************/ void smp_generate_ltk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (smp_get_br_state() == SMP_BR_STATE_BOND_PENDING) { smp_br_process_link_key(p_cb, NULL); return; - } else if (p_cb->le_secure_connections_mode_is_used) { + } else if (p_cb->sc_mode_required_by_peer) { smp_process_secure_connection_long_term_key(); return; } @@ -556,13 +559,12 @@ void smp_generate_ltk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { if (div_status) { smp_generate_ltk_cont(p_cb->div, p_cb); } else { - LOG_VERBOSE("Generate DIV for LTK"); + log::verbose("Generate DIV for LTK"); /* generate MRand or SRand */ - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - uint16_t div; - STREAM_TO_UINT16(div, rand); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + uint16_t div = static_cast(rand); smp_generate_ltk_cont(div, p_cb); }, p_cb)); @@ -571,7 +573,7 @@ void smp_generate_ltk(tSMP_CB* p_cb, UNUSED_ATTR tSMP_INT_DATA* p_data) { /* The function calculates legacy STK */ Octet16 smp_calculate_legacy_short_term_key(tSMP_CB* p_cb) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); Octet16 text{}; if (p_cb->role == HCI_ROLE_CENTRAL) { @@ -599,17 +601,17 @@ Octet16 smp_calculate_legacy_short_term_key(tSMP_CB* p_cb) { * ******************************************************************************/ void smp_create_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); // Only use the stored OOB data if we are in an oob association model if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { - LOG_WARN("OOB Association Model"); + log::warn("OOB Association Model"); // Make sure our data isn't empty, otherwise we generate new and eventually // pairing will fail Not much we can do about it at this point, just have to // generate new data The data will be cleared after the advertiser times // out, so if the advertiser times out we want the pairing to fail anyway. if (!is_oob_data_empty(&saved_local_oob_data)) { - LOG_WARN("Found OOB data, loading keys"); + log::warn("Found OOB data, loading keys"); for (int i = 0; i < BT_OCTET32_LEN; i++) { p_cb->private_key[i] = saved_local_oob_data.private_key_used[i]; p_cb->loc_publ_key.x[i] = saved_local_oob_data.publ_key_used.x[i]; @@ -620,22 +622,23 @@ void smp_create_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { smp_process_private_key(p_cb); return; } - LOG_WARN("OOB Association Model with no saved data present"); + log::warn("OOB Association Model with no saved data present"); } - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy((void*)p_cb->private_key, rand, BT_OCTET8_LEN); - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy((void*)&p_cb->private_key[8], rand, BT_OCTET8_LEN); - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy((void*)&p_cb->private_key[16], rand, BT_OCTET8_LEN); - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy((void*)&p_cb->private_key[24], rand, - BT_OCTET8_LEN); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(p_cb->private_key, (uint8_t*)&rand, sizeof(uint64_t)); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(&p_cb->private_key[8], (uint8_t*)&rand, sizeof(uint64_t)); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(&p_cb->private_key[16], (uint8_t*)&rand, + sizeof(uint64_t)); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(&p_cb->private_key[24], (uint8_t*)&rand, + sizeof(uint64_t)); smp_process_private_key(p_cb); }, p_cb)); @@ -664,22 +667,22 @@ void smp_create_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { * ******************************************************************************/ void smp_use_oob_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_INFO("req_oob_type:%d, role:%d", p_cb->req_oob_type, p_cb->role); + log::info("req_oob_type:{}, role:{}", p_cb->req_oob_type, p_cb->role); switch (p_cb->req_oob_type) { case SMP_OOB_BOTH: case SMP_OOB_LOCAL: - LOG_INFO("restore secret key"); + log::info("restore secret key"); // Only use the stored OOB data if we are in an oob association model if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { - LOG_INFO("OOB Association Model"); + log::info("OOB Association Model"); // Make sure our data isn't empty, otherwise we generate new and // eventually pairing will fail Not much we can do about it at this // point, just have to generate new data The data will be cleared after // the advertiser times out, so if the advertiser times out we want the // pairing to fail anyway. if (!is_oob_data_empty(&saved_local_oob_data)) { - LOG_INFO("Found OOB data, loading keys"); + log::info("Found OOB data, loading keys"); for (int i = 0; i < BT_OCTET32_LEN; i++) { p_cb->private_key[i] = saved_local_oob_data.private_key_used[i]; p_cb->loc_publ_key.x[i] = saved_local_oob_data.publ_key_used.x[i]; @@ -690,7 +693,7 @@ void smp_use_oob_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { smp_process_private_key(p_cb); return; } - LOG_INFO("OOB Association Model with no saved data present"); + log::info("OOB Association Model with no saved data present"); } memcpy(p_cb->private_key, p_cb->sc_oob_data.loc_oob_data.private_key_used, @@ -698,7 +701,7 @@ void smp_use_oob_private_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { smp_process_private_key(p_cb); break; default: - LOG_INFO("create secret key anew"); + log::info("create secret key anew"); smp_set_state(SMP_STATE_PAIR_REQ_RSP); smp_decide_association_model(p_cb, NULL); break; @@ -720,7 +723,7 @@ void smp_process_private_key(tSMP_CB* p_cb) { Point public_key; BT_OCTET32 private_key; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); ECC_PointMult(&public_key, &(curve_p256.G), (uint32_t*)private_key); @@ -753,7 +756,7 @@ void smp_compute_dhkey(tSMP_CB* p_cb) { Point peer_publ_key, new_publ_key; BT_OCTET32 private_key; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); memcpy(peer_publ_key.x, p_cb->peer_publ_key.x, BT_OCTET32_LEN); @@ -779,15 +782,15 @@ void smp_compute_dhkey(tSMP_CB* p_cb) { void smp_calculate_local_commitment(tSMP_CB* p_cb) { uint8_t random_input; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); switch (p_cb->selected_association_model) { case SMP_MODEL_SEC_CONN_JUSTWORKS: case SMP_MODEL_SEC_CONN_NUM_COMP: if (p_cb->role == HCI_ROLE_CENTRAL) - LOG_WARN( - "local commitment calc on central is not expected " - "for Just Works/Numeric Comparison models"); + log::warn( + "local commitment calc on central is not expected for Just " + "Works/Numeric Comparison models"); p_cb->commitment = crypto_toolbox::f4( p_cb->loc_publ_key.x, p_cb->peer_publ_key.x, p_cb->rand, 0); break; @@ -800,14 +803,14 @@ void smp_calculate_local_commitment(tSMP_CB* p_cb) { p_cb->rand, random_input); break; case SMP_MODEL_SEC_CONN_OOB: - LOG_WARN( + log::warn( "local commitment calc is expected for OOB model BEFORE pairing"); p_cb->commitment = crypto_toolbox::f4( p_cb->loc_publ_key.x, p_cb->loc_publ_key.x, p_cb->local_random, 0); break; default: - LOG_ERROR("Association Model=%d is not used in LE SC", - p_cb->selected_association_model); + log::error("Association Model={} is not used in LE SC", + p_cb->selected_association_model); return; } } @@ -816,15 +819,15 @@ void smp_calculate_local_commitment(tSMP_CB* p_cb) { Octet16 smp_calculate_peer_commitment(tSMP_CB* p_cb) { uint8_t ri; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); Octet16 output{0}; switch (p_cb->selected_association_model) { case SMP_MODEL_SEC_CONN_JUSTWORKS: case SMP_MODEL_SEC_CONN_NUM_COMP: if (p_cb->role == HCI_ROLE_PERIPHERAL) - LOG_WARN( - "peer commitment calc on peripheral is not expected " - "for Just Works/Numeric Comparison models"); + log::warn( + "peer commitment calc on peripheral is not expected for Just " + "Works/Numeric Comparison models"); output = crypto_toolbox::f4(p_cb->peer_publ_key.x, p_cb->loc_publ_key.x, p_cb->rrand, 0); break; @@ -839,8 +842,8 @@ Octet16 smp_calculate_peer_commitment(tSMP_CB* p_cb) { p_cb->peer_random, 0); break; default: - LOG_ERROR("Association Model=%d is not used in LE SC", - p_cb->selected_association_model); + log::error("Association Model={} is not used in LE SC", + p_cb->selected_association_model); return output; } @@ -859,7 +862,7 @@ Octet16 smp_calculate_peer_commitment(tSMP_CB* p_cb) { ******************************************************************************/ void smp_calculate_numeric_comparison_display_number(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->role == HCI_ROLE_CENTRAL) { p_cb->number_to_display = crypto_toolbox::g2( @@ -873,8 +876,8 @@ void smp_calculate_numeric_comparison_display_number(tSMP_CB* p_cb, tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_PAIR_FAIL_UNKNOWN; p_cb->failure = SMP_PAIR_FAIL_UNKNOWN; - LOG_VERBOSE("Number to display in numeric comparison=%d too large", - p_cb->number_to_display); + log::verbose("Number to display in numeric comparison={} too large", + p_cb->number_to_display); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); return; } @@ -902,7 +905,7 @@ void smp_calculate_numeric_comparison_display_number(tSMP_CB* p_cb, void smp_calculate_local_dhkey_check(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t iocap[3], a[7], b[7]; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_calculate_f5_mackey_and_long_term_key(p_cb); @@ -927,7 +930,7 @@ void smp_calculate_peer_dhkey_check(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { uint8_t iocap[3], a[7], b[7]; tSMP_KEY key; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); smp_collect_peer_io_capabilities(iocap, p_cb); @@ -957,24 +960,24 @@ bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb) { RawAddress bda_for_lk; tBLE_ADDR_TYPE conn_addr_type; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->id_addr_rcvd && p_cb->id_addr_type == BLE_ADDR_PUBLIC) { - LOG_VERBOSE( + log::verbose( "Use rcvd identity address as BD_ADDR of LK rcvd identity address"); bda_for_lk = p_cb->id_addr; } else if ((BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, bda_for_lk, &conn_addr_type, true)) && conn_addr_type == BLE_ADDR_PUBLIC) { - LOG_VERBOSE("Use rcvd connection address as BD_ADDR of LK"); + log::verbose("Use rcvd connection address as BD_ADDR of LK"); } else { - LOG_WARN("Don't have peer public address to associate with LK"); + log::warn("Don't have peer public address to associate with LK"); return false; } p_dev_rec = btm_find_dev(p_cb->pairing_bda); if (p_dev_rec == NULL) { - LOG_ERROR("failed to find Security Record"); + log::error("failed to find Security Record"); return false; } @@ -985,7 +988,7 @@ bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb) { if (p_cb->init_security_mode == BTM_SEC_MODE_SC) { /* Secure Connections Only Mode */ link_key_type = BTM_LKEY_TYPE_AUTH_COMB_P_256; - } else if (controller_get_interface()->supports_secure_connections()) { + } else if (bluetooth::shim::GetController()->SupportsSecureConnections()) { /* both transports are SC capable */ if (p_cb->sec_level == SMP_SEC_AUTHENTICATED) link_key_type = BTM_LKEY_TYPE_AUTH_COMB_P_256; @@ -998,8 +1001,8 @@ bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb) { else link_key_type = BTM_LKEY_TYPE_UNAUTH_COMB; } else { - LOG_ERROR("failed to update link_key. Sec Mode=%d, sm4=0x%02x", - p_cb->init_security_mode, p_dev_rec->sm4); + log::error("failed to update link_key. Sec Mode={}, sm4=0x{:02x}", + p_cb->init_security_mode, p_dev_rec->sm4); return false; } @@ -1016,24 +1019,24 @@ bool smp_calculate_link_key_from_long_term_key(tSMP_CB* p_cb) { bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb) { tBTM_SEC_DEV_REC* p_dev_rec; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p_dev_rec = btm_find_dev(p_cb->pairing_bda); if (p_dev_rec == NULL) { - LOG_ERROR("ailed to find Security Record"); + log::error("ailed to find Security Record"); return false; } uint8_t br_link_key_type; br_link_key_type = BTM_SecGetDeviceLinkKeyType(p_cb->pairing_bda); if (br_link_key_type == BTM_LKEY_TYPE_IGNORE) { - LOG_ERROR("failed to retrieve BR link type"); + log::error("failed to retrieve BR link type"); return false; } if ((br_link_key_type != BTM_LKEY_TYPE_AUTH_COMB_P_256) && (br_link_key_type != BTM_LKEY_TYPE_UNAUTH_COMB_P_256)) { - LOG_ERROR("LE SC LTK can't be derived from LK %d", br_link_key_type); + log::error("LE SC LTK can't be derived from LK {}", br_link_key_type); return false; } @@ -1053,14 +1056,15 @@ bool smp_calculate_long_term_key_from_link_key(tSMP_CB* p_cb) { * This function generates nonce. */ void smp_start_nonce_generation(tSMP_CB* p_cb) { - LOG_VERBOSE("start generating nonce"); - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy(p_cb->rand.data(), rand, BT_OCTET8_LEN); - btsnd_hcic_ble_rand(Bind( - [](tSMP_CB* p_cb, BT_OCTET8 rand) { - memcpy(p_cb->rand.data() + 8, rand, BT_OCTET8_LEN); - LOG_VERBOSE("round %d, done", p_cb->round); + log::verbose("start generating nonce"); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(p_cb->rand.data(), (uint8_t*)&rand, sizeof(uint64_t)); + send_ble_rand(BindOnce( + [](tSMP_CB* p_cb, uint64_t rand) { + memcpy(p_cb->rand.data() + sizeof(uint64_t), (uint8_t*)&rand, + sizeof(uint64_t)); + log::verbose("round {}, done", p_cb->round); /* notifies SM that it has new nonce. */ smp_sm_event(p_cb, SMP_HAVE_LOC_NONCE_EVT, NULL); }, @@ -1068,3 +1072,7 @@ void smp_start_nonce_generation(tSMP_CB* p_cb) { }, p_cb)); } + +static void send_ble_rand(OnceCallback callback) { + bluetooth::shim::GetController()->LeRand(std::move(callback)); +} diff --git a/system/stack/smp/smp_l2c.cc b/system/stack/smp/smp_l2c.cc index 1fccd76bcef30ff964b2128b374db75e327d6488..829577a3ccf17bf7781fcf8a507d72e0ca5a8f6d 100644 --- a/system/stack/smp/smp_l2c.cc +++ b/system/stack/smp/smp_l2c.cc @@ -24,6 +24,9 @@ #define LOG_TAG "smp" +#include +#include + #include "internal_include/bt_target.h" #include "os/log.h" #include "osi/include/allocator.h" @@ -35,6 +38,10 @@ #include "stack/include/l2c_api.h" #include "types/raw_address.h" +using namespace bluetooth; + +static void smp_tx_complete_callback(uint16_t cid, uint16_t num_pkt); + static void smp_connect_callback(uint16_t channel, const RawAddress& bd_addr, bool connected, uint16_t reason, tBT_TRANSPORT transport); @@ -57,10 +64,11 @@ static void smp_br_data_received(uint16_t channel, const RawAddress& bd_addr, ******************************************************************************/ void smp_l2cap_if_init(void) { tL2CAP_FIXED_CHNL_REG fixed_reg; - LOG_VERBOSE("SMDBG l2c"); + log::verbose("SMDBG l2c"); fixed_reg.pL2CA_FixedConn_Cb = smp_connect_callback; fixed_reg.pL2CA_FixedData_Cb = smp_data_received; + fixed_reg.pL2CA_FixedTxComplete_Cb = smp_tx_complete_callback; fixed_reg.pL2CA_FixedCong_Cb = NULL; /* do not handle congestion on this channel */ @@ -91,22 +99,22 @@ static void smp_connect_callback(UNUSED_ATTR uint16_t channel, tSMP_CB* p_cb = &smp_cb; tSMP_INT_DATA int_data; - LOG_DEBUG("bd_addr:%s transport:%s, connected:%d", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - bt_transport_text(transport).c_str(), connected); + log::debug("bd_addr:{} transport:{}, connected:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bt_transport_text(transport), + connected); if (bd_addr.IsEmpty()) { - LOG_WARN("empty address"); + log::warn("empty address"); return; } if (transport == BT_TRANSPORT_BR_EDR) { - LOG_WARN("unexpected transport"); + log::warn("unexpected transport"); return; } if (bd_addr == p_cb->pairing_bda) { - LOG_DEBUG("in pairing process"); + log::debug("in pairing process"); if (connected) { if (!p_cb->connect_initialized) { @@ -145,19 +153,19 @@ static void smp_data_received(uint16_t channel, const RawAddress& bd_addr, uint8_t cmd; if (p_buf->len < 1) { - LOG_WARN("packet too short"); + log::warn("packet too short"); osi_free(p_buf); return; } STREAM_TO_UINT8(cmd, p); - LOG_VERBOSE("cmd=%s[0x%02x]", - smp_opcode_text(static_cast(cmd)).c_str(), cmd); + log::verbose("cmd={}[0x{:02x}]", + smp_opcode_text(static_cast(cmd)), cmd); /* sanity check */ if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) { - LOG_WARN("invalid command"); + log::warn("invalid command"); osi_free(p_buf); return; } @@ -187,8 +195,8 @@ static void smp_data_received(uint16_t channel, const RawAddress& bd_addr, false /* is_over_br */); if (cmd == SMP_OPCODE_CONFIRM) { - LOG_VERBOSE("peer_auth_req=0x%02x, loc_auth_req=0x%02x", - p_cb->peer_auth_req, p_cb->loc_auth_req); + log::verbose("peer_auth_req=0x{:02x}, loc_auth_req=0x{:02x}", + p_cb->peer_auth_req, p_cb->loc_auth_req); if ((p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) && (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT)) { @@ -208,6 +216,41 @@ static void smp_data_received(uint16_t channel, const RawAddress& bd_addr, osi_free(p_buf); } +/******************************************************************************* + * + * Function smp_tx_complete_callback + * + * Description SMP channel tx complete callback + * + ******************************************************************************/ +static void smp_tx_complete_callback(uint16_t cid, uint16_t num_pkt) { + tSMP_CB* p_cb = &smp_cb; + +#ifndef TARGET_FLOSS + if (!IS_FLAG_ENABLED(l2cap_tx_complete_cb_info)) { + log::verbose("Exit since l2cap_tx_complete_cb_info is disabled"); + return; + } +#endif + + log::verbose("l2cap_tx_complete_cb_info is enabled, continue"); + if (p_cb->total_tx_unacked >= num_pkt) { + p_cb->total_tx_unacked -= num_pkt; + } else { + log::error("Unexpected complete callback: num_pkt = {}", num_pkt); + } + + if (p_cb->total_tx_unacked == 0 && p_cb->wait_for_authorization_complete) { + tSMP_INT_DATA smp_int_data; + smp_int_data.status = SMP_SUCCESS; + if (cid == L2CAP_SMP_CID) { + smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); + } else { + smp_br_state_machine_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &smp_int_data); + } + } +} + /******************************************************************************* * * Function smp_br_connect_callback @@ -224,13 +267,13 @@ static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr, tSMP_INT_DATA int_data; if (transport != BT_TRANSPORT_BR_EDR) { - LOG_WARN("unexpected transport %s", bt_transport_text(transport).c_str()); + log::warn("unexpected transport {}", bt_transport_text(transport)); return; } - LOG_INFO("BDA:%s pairing_bda:%s, connected:%d", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), - ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), connected); + log::info("BDA:{} pairing_bda:{}, connected:{}", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), connected); if (bd_addr != p_cb->pairing_bda) return; @@ -249,7 +292,7 @@ static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr, * stack restart, when we re-read record from storage. Service discovery * would stay broken. */ - LOG_INFO("Classic event after CTKD on LE transport"); + log::info("Classic event after CTKD on LE transport"); return; } @@ -265,10 +308,11 @@ static void smp_br_connect_callback(uint16_t channel, const RawAddress& bd_addr, } else { /* Disconnected while doing security */ if (p_cb->smp_over_br) { - LOG_DEBUG("SMP over BR/EDR not supported, terminate the ongoing pairing"); + log::debug( + "SMP over BR/EDR not supported, terminate the ongoing pairing"); smp_br_state_machine_event(p_cb, SMP_BR_L2CAP_DISCONN_EVT, &int_data); } else { - LOG_DEBUG("SMP over BR/EDR not supported, continue the LE pairing"); + log::debug("SMP over BR/EDR not supported, continue the LE pairing"); } } } @@ -288,21 +332,21 @@ static void smp_br_data_received(uint16_t channel, const RawAddress& bd_addr, tSMP_CB* p_cb = &smp_cb; uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset; uint8_t cmd; - LOG_VERBOSE("SMDBG l2c"); + log::verbose("SMDBG l2c"); if (p_buf->len < 1) { - LOG_WARN("packet too short"); + log::warn("packet too short"); osi_free(p_buf); return; } STREAM_TO_UINT8(cmd, p); - LOG_VERBOSE("cmd=%s[0x%02x]", - smp_opcode_text(static_cast(cmd)).c_str(), cmd); + log::verbose("cmd={}[0x{:02x}]", + smp_opcode_text(static_cast(cmd)), cmd); /* sanity check */ if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) { - LOG_WARN("invalid command 0x%02x", cmd); + log::warn("invalid command 0x{:02x}", cmd); osi_free(p_buf); return; } diff --git a/system/stack/smp/smp_main.cc b/system/stack/smp/smp_main.cc index 00310d75133eaf737f047de9ceef961556596538..ba41019d55e32bf487d0f1d39615566c0f36f7a7 100644 --- a/system/stack/smp/smp_main.cc +++ b/system/stack/smp/smp_main.cc @@ -18,10 +18,14 @@ #define LOG_TAG "smp" +#include + #include "os/log.h" #include "smp_int.h" #include "stack/include/btm_log_history.h" +using namespace bluetooth; + namespace { constexpr char kBtmLogTag[] = "SMP"; @@ -952,9 +956,9 @@ tSMP_CB smp_cb; ******************************************************************************/ void smp_set_state(tSMP_STATE state) { if (state < SMP_STATE_MAX) { - LOG_VERBOSE("State change: %s(%d)==>%s(%d)", - smp_get_state_name(smp_cb.state), smp_cb.state, - smp_get_state_name(state), state); + log::debug("State change: {}({})==>{}({})", + smp_get_state_name(smp_cb.state), smp_cb.state, + smp_get_state_name(state), state); if (smp_cb.state != state) { BTM_LogHistory( kBtmLogTag, smp_cb.pairing_ble_bd_addr, "Security state changed", @@ -963,7 +967,7 @@ void smp_set_state(tSMP_STATE state) { } smp_cb.state = state; } else { - LOG_VERBOSE("invalid state=%d", state); + log::error("invalid state={}", state); } } @@ -995,22 +999,22 @@ bool smp_sm_event(tSMP_CB* p_cb, tSMP_EVENT event, tSMP_INT_DATA* p_data) { tSMP_SM_TBL state_table; uint8_t action, entry, i; + log::debug("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->role >= 2) { - LOG_VERBOSE("Invalid role:%d", p_cb->role); + log::error("Invalid role:{}", p_cb->role); return false; } tSMP_ENTRY_TBL entry_table = smp_entry_table[p_cb->role]; if (curr_state >= SMP_STATE_MAX) { - LOG_VERBOSE("Invalid state:%d", curr_state); + log::error("Invalid state:{}", curr_state); return false; } - LOG_VERBOSE("SMP Role:%s State:[%s(%d)], Event:[%s(%d)]", - (p_cb->role == 0x01) ? "Peripheral" : "Central", - smp_get_state_name(p_cb->state), p_cb->state, - smp_get_event_name(event), event); + log::debug("Role:{}, State:[{}({})], Event:[{}({})]", + hci_role_text(p_cb->role), smp_get_state_name(p_cb->state), + p_cb->state, smp_get_event_name(event), event); /* look up the state table for the current state */ /* lookup entry /w event & curr_state */ @@ -1021,12 +1025,13 @@ bool smp_sm_event(tSMP_CB* p_cb, tSMP_EVENT event, tSMP_INT_DATA* p_data) { if (entry & SMP_ALL_TBL_MASK) { entry &= ~SMP_ALL_TBL_MASK; state_table = smp_all_table; - } else + } else { state_table = smp_state_table[curr_state][p_cb->role]; + } } else { - LOG_VERBOSE("Ignore event[%s(%d)] in state[%s(%d)]", - smp_get_event_name(event), event, - smp_get_state_name(curr_state), curr_state); + log::warn("Ignore event[{}({})] in state[{}({})]", + smp_get_event_name(event), event, smp_get_state_name(curr_state), + curr_state); return false; } @@ -1046,7 +1051,7 @@ bool smp_sm_event(tSMP_CB* p_cb, tSMP_EVENT event, tSMP_INT_DATA* p_data) { break; } } - LOG_VERBOSE("result state=%s", smp_get_state_name(p_cb->state)); + log::debug("result state={}", smp_get_state_name(p_cb->state)); return true; } diff --git a/system/stack/smp/smp_utils.cc b/system/stack/smp/smp_utils.cc index 70471b3d577e09ad114d784c8228f8fbb59c17ab..8ba3457fb35943fd305f330fcce60200e912e7a6 100644 --- a/system/stack/smp/smp_utils.cc +++ b/system/stack/smp/smp_utils.cc @@ -23,6 +23,9 @@ ******************************************************************************/ #define LOG_TAG "smp" +#include +#include + #include #include @@ -67,6 +70,8 @@ Check*/) #define SMP_PAIR_KEYPR_NOTIF_SIZE (1 /* opcode */ + 1 /*Notif Type*/) +using namespace bluetooth; + namespace { constexpr char kBtmLogTag[] = "SMP"; } @@ -324,7 +329,7 @@ static tSMP_ASSO_MODEL smp_select_association_model_secure_connections( void smp_log_metrics(const RawAddress& bd_addr, bool is_outgoing, const uint8_t* p_buf, size_t buf_len, bool is_over_br) { if (buf_len < 1) { - LOG_WARN("buffer is too small"); + log::warn("buffer is too small"); return; } uint8_t raw_cmd; @@ -362,20 +367,39 @@ bool smp_send_msg_to_L2CAP(const RawAddress& rem_bda, BT_HDR* p_toL2CAP) { fixed_cid = L2CAP_SMP_BR_CID; } - LOG_VERBOSE("rem_bda:%s, over_bredr:%d", ADDRESS_TO_LOGGABLE_CSTR(rem_bda), - smp_cb.smp_over_br); + log::verbose("rem_bda:{}, over_bredr:{}", ADDRESS_TO_LOGGABLE_CSTR(rem_bda), + smp_cb.smp_over_br); smp_log_metrics(rem_bda, true /* outgoing */, p_toL2CAP->data + p_toL2CAP->offset, p_toL2CAP->len, smp_cb.smp_over_br /* is_over_br */); +#ifdef TARGET_FLOSS + if (true) +#else + if (IS_FLAG_ENABLED(l2cap_tx_complete_cb_info)) +#endif + { + /* Unacked needs to be incremented before calling SendFixedChnlData */ + smp_cb.total_tx_unacked++; + l2cap_ret = L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_toL2CAP); + if (l2cap_ret == L2CAP_DW_FAILED) { + smp_cb.total_tx_unacked--; + log::error("SMP failed to pass msg to L2CAP"); + return false; + } + log::verbose("l2cap_tx_complete_cb_info is enabled"); + return true; + } + l2cap_ret = L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_toL2CAP); if (l2cap_ret == L2CAP_DW_FAILED) { - LOG_ERROR("SMP failed to pass msg to L2CAP"); + log::error("SMP failed to pass msg to L2CAP"); return false; } else { tSMP_CB* p_cb = &smp_cb; + log::verbose("l2cap_tx_complete_cb_info is disabled"); if (p_cb->wait_for_authorization_complete) { tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_SUCCESS; @@ -400,9 +424,9 @@ bool smp_send_cmd(uint8_t cmd_code, tSMP_CB* p_cb) { BT_HDR* p_buf; bool sent = false; - LOG_DEBUG("Sending SMP command:%s[0x%x] pairing_bda=%s", - smp_opcode_text(static_cast(cmd_code)).c_str(), - cmd_code, ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::debug("Sending SMP command:{}[0x{:x}] pairing_bda={}", + smp_opcode_text(static_cast(cmd_code)), cmd_code, + ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (cmd_code <= (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */) && smp_cmd_build_act[cmd_code] != NULL) { @@ -439,7 +463,7 @@ bool smp_send_cmd(uint8_t cmd_code, tSMP_CB* p_cb) { void smp_rsp_timeout(UNUSED_ATTR void* data) { tSMP_CB* p_cb = &smp_cb; - LOG_VERBOSE("state:%d br_state:%d", p_cb->state, p_cb->br_state); + log::verbose("state:{} br_state:{}", p_cb->state, p_cb->br_state); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_RSP_TIMEOUT; @@ -466,7 +490,7 @@ void smp_delayed_auth_complete_timeout(UNUSED_ATTR void* data) { * the state is still in bond pending. */ if (smp_get_state() == SMP_STATE_BOND_PENDING) { - LOG_VERBOSE("sending delayed auth complete."); + log::verbose("sending delayed auth complete."); tSMP_INT_DATA smp_int_data; smp_int_data.status = SMP_SUCCESS; smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); @@ -485,8 +509,8 @@ BT_HDR* smp_build_pairing_cmd(uint8_t cmd_code, tSMP_CB* p_cb) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_PAIRING_REQ_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("building cmd:%s", - smp_opcode_text(static_cast(cmd_code)).c_str()); + log::verbose("building cmd:{}", + smp_opcode_text(static_cast(cmd_code))); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, cmd_code); @@ -517,7 +541,7 @@ static BT_HDR* smp_build_confirm_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_CONFIRM_CMD_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -542,7 +566,7 @@ static BT_HDR* smp_build_rand_cmd(UNUSED_ATTR uint8_t cmd_code, tSMP_CB* p_cb) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_RAND_CMD_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_RAND); @@ -567,7 +591,7 @@ static BT_HDR* smp_build_encrypt_info_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_ENC_INFO_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_ENCRYPT_INFO); @@ -592,7 +616,7 @@ static BT_HDR* smp_build_central_id_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_CENTRAL_ID_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_CENTRAL_ID); @@ -618,7 +642,7 @@ static BT_HDR* smp_build_identity_info_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_ID_INFO_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; @@ -646,7 +670,7 @@ static BT_HDR* smp_build_id_addr_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_ID_ADDR_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_ID_ADDR); @@ -672,7 +696,7 @@ static BT_HDR* smp_build_signing_info_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_SIGN_INFO_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_SIGN_INFO); @@ -697,7 +721,7 @@ static BT_HDR* smp_build_pairing_fail(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_PAIRING_FAILED); @@ -721,7 +745,7 @@ static BT_HDR* smp_build_security_request(UNUSED_ATTR uint8_t cmd_code, uint8_t* p; BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + 2 + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_SEC_REQ); @@ -730,8 +754,8 @@ static BT_HDR* smp_build_security_request(UNUSED_ATTR uint8_t cmd_code, p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = SMP_SECURITY_REQUEST_SIZE; - LOG_VERBOSE("opcode=%d auth_req=0x%x", SMP_OPCODE_SEC_REQ, - p_cb->loc_auth_req); + log::verbose("opcode={} auth_req=0x{:x}", SMP_OPCODE_SEC_REQ, + p_cb->loc_auth_req); return p_buf; } @@ -751,7 +775,7 @@ static BT_HDR* smp_build_pair_public_key_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_PAIR_PUBL_KEY_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); memcpy(p_publ_key, p_cb->loc_publ_key.x, BT_OCTET32_LEN); memcpy(p_publ_key + BT_OCTET32_LEN, p_cb->loc_publ_key.y, BT_OCTET32_LEN); @@ -779,7 +803,7 @@ static BT_HDR* smp_build_pairing_commitment_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_PAIR_COMMITM_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_CONFIRM); @@ -804,7 +828,7 @@ static BT_HDR* smp_build_pair_dhkey_check_cmd(UNUSED_ATTR uint8_t cmd_code, BT_HDR* p_buf = (BT_HDR*)osi_malloc( sizeof(BT_HDR) + SMP_PAIR_DHKEY_CHECK_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_PAIR_DHKEY_CHECK); @@ -829,7 +853,7 @@ static BT_HDR* smp_build_pairing_keypress_notification_cmd( BT_HDR* p_buf = (BT_HDR*)osi_malloc( sizeof(BT_HDR) + SMP_PAIR_KEYPR_NOTIF_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_PAIR_KEYPR_NOTIF); @@ -846,7 +870,7 @@ static BT_HDR* smp_build_pairing_keypress_notification_cmd( void smp_convert_string_to_tk(Octet16* tk, uint32_t passkey) { uint8_t* p = tk->data(); tSMP_KEY key; - LOG_VERBOSE("smp_convert_string_to_tk"); + log::verbose("smp_convert_string_to_tk"); UINT32_TO_STREAM(p, passkey); key.key_type = SMP_KEY_TYPE_TK; @@ -860,7 +884,7 @@ void smp_convert_string_to_tk(Octet16* tk, uint32_t passkey) { /** This function is called to mask off the encryption key based on the maximum * encryption key size. */ void smp_mask_enc_key(uint8_t loc_enc_size, Octet16* p_data) { - LOG_VERBOSE("smp_mask_enc_key"); + log::verbose("smp_mask_enc_key"); if (loc_enc_size < OCTET16_LEN) { for (; loc_enc_size < OCTET16_LEN; loc_enc_size++) (*p_data)[loc_enc_size] = 0; @@ -888,7 +912,7 @@ void tSMP_CB::init(uint8_t security_mode) { smp_cb.smp_rsp_timer_ent = alarm_new("smp.smp_rsp_timer_ent"); smp_cb.delayed_auth_timer_ent = alarm_new("smp.delayed_auth_timer_ent"); - LOG_VERBOSE("init_security_mode:%d", init_security_mode); + log::verbose("init_security_mode:{}", init_security_mode); smp_l2cap_if_init(); /* initialization of P-256 parameters */ @@ -898,7 +922,7 @@ void tSMP_CB::init(uint8_t security_mode) { smp_cb.cert_failure = static_cast( stack_config_get_interface()->get_pts_smp_failure_case()); if (smp_cb.cert_failure) - LOG_ERROR("PTS FAILURE MODE IN EFFECT (CASE %d)", smp_cb.cert_failure); + log::error("PTS FAILURE MODE IN EFFECT (CASE {})", smp_cb.cert_failure); } /******************************************************************************* @@ -916,12 +940,13 @@ void tSMP_CB::reset() { alarm_t* smp_rsp_timer_ent = this->smp_rsp_timer_ent; alarm_t* delayed_auth_timer_ent = this->delayed_auth_timer_ent; - LOG_VERBOSE("resetting SMP_CB"); + log::verbose("resetting SMP_CB"); alarm_cancel(this->smp_rsp_timer_ent); alarm_cancel(this->delayed_auth_timer_ent); - init(init_security_mode); + *this = {}; + this->init_security_mode = init_security_mode; this->p_callback = p_callback; this->init_security_mode = init_security_mode; @@ -939,7 +964,7 @@ void tSMP_CB::reset() { * ******************************************************************************/ void smp_remove_fixed_channel(tSMP_CB* p_cb) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->smp_over_br) L2CA_RemoveFixedChnl(L2CAP_SMP_BR_CID, p_cb->pairing_bda); @@ -959,7 +984,7 @@ void smp_remove_fixed_channel(tSMP_CB* p_cb) { * ******************************************************************************/ void smp_reset_control_value(tSMP_CB* p_cb) { - LOG_VERBOSE("reset smp_cb"); + log::verbose("reset smp_cb"); alarm_cancel(p_cb->smp_rsp_timer_ent); p_cb->flags = 0; @@ -1001,16 +1026,17 @@ void smp_proc_pairing_cmpl(tSMP_CB* p_cb) { }; if (p_cb->status == SMP_SUCCESS) { - LOG_DEBUG( - "Pairing process has completed successfully remote:%s sec_level:0x%0x", + log::debug( + "Pairing process has completed successfully remote:{} " + "sec_level:0x{:0x}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), evt_data.cmplt.sec_level); BTM_LogHistory(kBtmLogTag, pairing_bda, "Pairing success"); } else { - LOG_WARN( - "Pairing process has failed to remote:%s smp_reason:%s sec_level:0x%0x", + log::warn( + "Pairing process has failed to remote:{} smp_reason:{} " + "sec_level:0x{:0x}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda), - smp_status_text(evt_data.cmplt.reason).c_str(), - evt_data.cmplt.sec_level); + smp_status_text(evt_data.cmplt.reason), evt_data.cmplt.sec_level); BTM_LogHistory( kBtmLogTag, pairing_bda, "Pairing failed", base::StringPrintf("reason:%s", @@ -1058,7 +1084,7 @@ bool smp_command_has_invalid_length(tSMP_CB* p_cb) { if ((cmd_code > (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */)) || (cmd_code < SMP_OPCODE_MIN)) { - LOG_WARN("Received command with RESERVED code 0x%02x", cmd_code); + log::warn("Received command with RESERVED code 0x{:02x}", cmd_code); return true; } @@ -1086,17 +1112,17 @@ bool smp_command_has_invalid_parameters(tSMP_CB* p_cb) { if ((cmd_code > (SMP_OPCODE_MAX + 1 /* for SMP_OPCODE_PAIR_COMMITM */)) || (cmd_code < SMP_OPCODE_MIN)) { - LOG_WARN("Received command with RESERVED code 0x%02x", cmd_code); + log::warn("Received command with RESERVED code 0x{:02x}", cmd_code); return true; } if (!(*smp_cmd_len_is_valid[cmd_code])(p_cb)) { - LOG_WARN("Command length not valid for cmd_code 0x%02x", cmd_code); + log::warn("Command length not valid for cmd_code 0x{:02x}", cmd_code); return true; } if (!(*smp_cmd_param_ranges_are_valid[cmd_code])(p_cb)) { - LOG_WARN("Parameter ranges not valid code 0x%02x", cmd_code); + log::warn("Parameter ranges not valid code 0x{:02x}", cmd_code); return true; } @@ -1117,12 +1143,12 @@ bool smp_command_has_invalid_parameters(tSMP_CB* p_cb) { bool smp_command_has_valid_fixed_length(tSMP_CB* p_cb) { uint8_t cmd_code = p_cb->rcvd_cmd_code; - LOG_VERBOSE("cmd code 0x%02x", cmd_code); + log::verbose("cmd code 0x{:02x}", cmd_code); if (p_cb->rcvd_cmd_len != smp_cmd_size_per_spec[cmd_code]) { - LOG_WARN( - "Rcvd from the peer cmd 0x%02x with invalid length " - "0x%02x (per spec the length is 0x%02x).", + log::warn( + "Rcvd from the peer cmd 0x{:02x} with invalid length 0x{:02x} (per " + "spec the length is 0x{:02x}).", cmd_code, p_cb->rcvd_cmd_len, smp_cmd_size_per_spec[cmd_code]); return false; } @@ -1152,27 +1178,27 @@ bool smp_pairing_request_response_parameters_are_valid(tSMP_CB* p_cb) { p_cb->peer_auth_req & 0x03; // 0x03 is gen bond with appropriate mask uint8_t enc_size = p_cb->peer_enc_size; - LOG_VERBOSE("cmd code 0x%02x", p_cb->rcvd_cmd_code); + log::verbose("cmd code 0x{:02x}", p_cb->rcvd_cmd_code); if (io_caps >= BTM_IO_CAP_MAX) { - LOG_WARN( - "Rcvd from the peer cmd 0x%02x with IO Capability " - "value (0x%02x) out of range).", + log::warn( + "Rcvd from the peer cmd 0x{:02x} with IO Capability value (0x{:02x}) " + "out of range).", p_cb->rcvd_cmd_code, io_caps); return false; } if (!((oob_flag == SMP_OOB_NONE) || (oob_flag == SMP_OOB_PRESENT))) { - LOG_WARN( - "Rcvd from the peer cmd 0x%02x with OOB data flag value " - "(0x%02x) out of range).", + log::warn( + "Rcvd from the peer cmd 0x{:02x} with OOB data flag value (0x{:02x}) " + "out of range).", p_cb->rcvd_cmd_code, oob_flag); return false; } if (!((bond_flag == SMP_AUTH_NO_BOND) || (bond_flag == SMP_AUTH_BOND))) { - LOG_WARN( - "Rcvd from the peer cmd 0x%02x with Bonding_Flags value (0x%02x) " + log::warn( + "Rcvd from the peer cmd 0x{:02x} with Bonding_Flags value (0x{:02x}) " "out of range).", p_cb->rcvd_cmd_code, bond_flag); return false; @@ -1180,9 +1206,9 @@ bool smp_pairing_request_response_parameters_are_valid(tSMP_CB* p_cb) { if ((enc_size < SMP_ENCR_KEY_SIZE_MIN) || (enc_size > SMP_ENCR_KEY_SIZE_MAX)) { - LOG_WARN( - "Rcvd from the peer cmd 0x%02x with Maximum Encryption " - "Key value (0x%02x) out of range).", + log::warn( + "Rcvd from the peer cmd 0x{:02x} with Maximum Encryption Key value " + "(0x{:02x}) out of range).", p_cb->rcvd_cmd_code, enc_size); return false; } @@ -1202,12 +1228,12 @@ bool smp_pairing_request_response_parameters_are_valid(tSMP_CB* p_cb) { bool smp_pairing_keypress_notification_is_valid(tSMP_CB* p_cb) { tSMP_SC_KEY_TYPE keypress_notification = p_cb->peer_keypress_notification; - LOG_VERBOSE("cmd code 0x%02x", p_cb->rcvd_cmd_code); + log::verbose("cmd code 0x{:02x}", p_cb->rcvd_cmd_code); if (keypress_notification >= SMP_SC_KEY_OUT_OF_RANGE) { - LOG_WARN( - "Rcvd from the peer cmd 0x%02x with Pairing Keypress " - "Notification value (0x%02x) out of range).", + log::warn( + "Rcvd from the peer cmd 0x{:02x} with Pairing Keypress Notification " + "value (0x{:02x}) out of range).", p_cb->rcvd_cmd_code, keypress_notification); return false; } @@ -1252,7 +1278,7 @@ void smp_reject_unexpected_pairing_command(const RawAddress& bd_addr) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET); - LOG_VERBOSE("bd_addr:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); + log::verbose("bd_addr:{}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; UINT8_TO_STREAM(p, SMP_OPCODE_PAIRING_FAILED); @@ -1274,7 +1300,7 @@ void smp_reject_unexpected_pairing_command(const RawAddress& bd_addr) { * Note If Secure Connections Only mode is required locally then we * come to this point only if both sides support Secure * Connections mode, i.e. - * if p_cb->secure_connections_only_mode_required = true + * if p_cb->sc_only_mode_locally_required = true * then we come to this point only if * (p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) == * (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) == @@ -1283,20 +1309,20 @@ void smp_reject_unexpected_pairing_command(const RawAddress& bd_addr) { ******************************************************************************/ tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB* p_cb) { tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE; - p_cb->le_secure_connections_mode_is_used = false; + p_cb->sc_mode_required_by_peer = false; - LOG_VERBOSE("p_cb->peer_io_caps = %d p_cb->local_io_capability = %d", - p_cb->peer_io_caps, p_cb->local_io_capability); - LOG_VERBOSE("p_cb->peer_oob_flag = %d p_cb->loc_oob_flag = %d", - p_cb->peer_oob_flag, p_cb->loc_oob_flag); - LOG_VERBOSE("p_cb->peer_auth_req = 0x%02x p_cb->loc_auth_req = 0x%02x", - p_cb->peer_auth_req, p_cb->loc_auth_req); - LOG_VERBOSE("p_cb->secure_connections_only_mode_required = %s", - p_cb->secure_connections_only_mode_required ? "true" : "false"); + log::verbose("p_cb->peer_io_caps = {} p_cb->local_io_capability = {}", + p_cb->peer_io_caps, p_cb->local_io_capability); + log::verbose("p_cb->peer_oob_flag = {} p_cb->loc_oob_flag = {}", + p_cb->peer_oob_flag, p_cb->loc_oob_flag); + log::verbose("p_cb->peer_auth_req = 0x{:02x} p_cb->loc_auth_req = 0x{:02x}", + p_cb->peer_auth_req, p_cb->loc_auth_req); + log::verbose("p_cb->sc_only_mode_locally_required = {}", + p_cb->sc_only_mode_locally_required); if ((p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT) && (p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT)) { - p_cb->le_secure_connections_mode_is_used = true; + p_cb->sc_mode_required_by_peer = true; } if ((p_cb->peer_auth_req & SMP_H7_SUPPORT_BIT) && @@ -1304,11 +1330,10 @@ tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB* p_cb) { p_cb->key_derivation_h7_used = TRUE; } - LOG_VERBOSE("use_sc_process = %d, h7 use = %d", - p_cb->le_secure_connections_mode_is_used, - p_cb->key_derivation_h7_used); + log::verbose("use_sc_process = {}, h7 use = {}", + p_cb->sc_mode_required_by_peer, p_cb->key_derivation_h7_used); - if (p_cb->le_secure_connections_mode_is_used) { + if (p_cb->sc_mode_required_by_peer) { model = smp_select_association_model_secure_connections(p_cb); } else { model = smp_select_legacy_association_model(p_cb); @@ -1326,7 +1351,7 @@ tSMP_ASSO_MODEL smp_select_association_model(tSMP_CB* p_cb) { tSMP_ASSO_MODEL smp_select_legacy_association_model(tSMP_CB* p_cb) { tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* if OOB data is present on both devices, then use OOB association model */ if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT) @@ -1363,7 +1388,7 @@ tSMP_ASSO_MODEL smp_select_legacy_association_model(tSMP_CB* p_cb) { tSMP_ASSO_MODEL smp_select_association_model_secure_connections(tSMP_CB* p_cb) { tSMP_ASSO_MODEL model = SMP_MODEL_OUT_OF_RANGE; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); /* if OOB data is present on at least one device, then use OOB association * model */ if (p_cb->peer_oob_flag == SMP_OOB_PRESENT || @@ -1408,8 +1433,8 @@ uint8_t smp_calculate_random_input(uint8_t* random, uint8_t round) { uint8_t ri; ri = ((random[i] >> j) & 1) | 0x80; - LOG_VERBOSE("random:0x%02x, round:%d, i:%d, j:%d, ri:0x%02x", random[i], - round, i, j, ri); + log::verbose("random:0x{:02x}, round:{}, i:{}, j:{}, ri:0x{:02x}", random[i], + round, i, j, ri); return ri; } @@ -1423,7 +1448,7 @@ uint8_t smp_calculate_random_input(uint8_t* random, uint8_t round) { * ******************************************************************************/ void smp_collect_local_io_capabilities(uint8_t* iocap, tSMP_CB* p_cb) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); iocap[0] = p_cb->local_io_capability; iocap[1] = p_cb->loc_oob_flag; @@ -1440,7 +1465,7 @@ void smp_collect_local_io_capabilities(uint8_t* iocap, tSMP_CB* p_cb) { * ******************************************************************************/ void smp_collect_peer_io_capabilities(uint8_t* iocap, tSMP_CB* p_cb) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); iocap[0] = p_cb->peer_io_caps; iocap[1] = p_cb->peer_oob_flag; @@ -1462,7 +1487,7 @@ void smp_collect_local_ble_address(uint8_t* le_addr, tSMP_CB* p_cb) { RawAddress bda; uint8_t* p = le_addr; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); BTM_ReadConnectionAddr(p_cb->pairing_bda, bda, &addr_type, true); BDADDR_TO_STREAM(p, bda); @@ -1484,10 +1509,10 @@ void smp_collect_peer_ble_address(uint8_t* le_addr, tSMP_CB* p_cb) { RawAddress bda; uint8_t* p = le_addr; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, bda, &addr_type, true)) { - LOG_ERROR("can not collect peer le addr information for unknown device"); + log::error("can not collect peer le addr information for unknown device"); return; } @@ -1507,14 +1532,14 @@ void smp_collect_peer_ble_address(uint8_t* le_addr, tSMP_CB* p_cb) { * ******************************************************************************/ bool smp_check_commitment(tSMP_CB* p_cb) { - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); Octet16 expected = smp_calculate_peer_commitment(p_cb); - print128(expected, (const uint8_t*)"calculated peer commitment"); - print128(p_cb->remote_commitment, (const uint8_t*)"received peer commitment"); + print128(expected, "calculated peer commitment"); + print128(p_cb->remote_commitment, "received peer commitment"); if (memcmp(p_cb->remote_commitment.data(), expected.data(), OCTET16_LEN)) { - LOG_WARN("Commitment check fails"); + log::warn("Commitment check fails"); return false; } @@ -1532,7 +1557,7 @@ bool smp_check_commitment(tSMP_CB* p_cb) { * ******************************************************************************/ void smp_save_secure_connections_long_term_key(tSMP_CB* p_cb) { - LOG_VERBOSE("Save LTK as local and peer key"); + log::verbose("Save LTK as local and peer key"); tBTM_LE_KEY_VALUE lle_key = { .lenc_key = { @@ -1566,7 +1591,7 @@ void smp_calculate_f5_mackey_and_long_term_key(tSMP_CB* p_cb) { Octet16 na; Octet16 nb; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->role == HCI_ROLE_CENTRAL) { smp_collect_local_ble_address(a, p_cb); @@ -1596,7 +1621,7 @@ void smp_calculate_f5_mackey_and_long_term_key(tSMP_CB* p_cb) { bool smp_request_oob_data(tSMP_CB* p_cb) { tSMP_OOB_DATA_TYPE req_oob_type = SMP_OOB_INVALID_TYPE; - LOG_VERBOSE("addr:%s", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); + log::verbose("addr:{}", ADDRESS_TO_LOGGABLE_CSTR(p_cb->pairing_bda)); if (p_cb->peer_oob_flag == SMP_OOB_PRESENT && p_cb->loc_oob_flag == SMP_OOB_PRESENT) { @@ -1609,7 +1634,7 @@ bool smp_request_oob_data(tSMP_CB* p_cb) { req_oob_type = SMP_OOB_PEER; } - LOG_VERBOSE("req_oob_type=%d", req_oob_type); + log::verbose("req_oob_type={}", req_oob_type); if (req_oob_type == SMP_OOB_INVALID_TYPE) return false; @@ -1622,15 +1647,13 @@ bool smp_request_oob_data(tSMP_CB* p_cb) { return true; } -void print128(const Octet16& x, const uint8_t* key_name) { - if (VLOG_IS_ON(2) && DLOG_IS_ON(INFO)) { - uint8_t* p = (uint8_t*)x.data(); +void print128(const Octet16& x, const char* key_name) { + uint8_t* p = (uint8_t*)x.data(); - LOG_INFO("%s(MSB~LSB):", key_name); - for (int i = 0; i < 4; i++) { - LOG_INFO("%02x:%02x:%02x:%02x", p[OCTET16_LEN - i * 4 - 1], - p[OCTET16_LEN - i * 4 - 2], p[OCTET16_LEN - i * 4 - 3], - p[OCTET16_LEN - i * 4 - 4]); - } + log::info("{}(MSB~LSB):", key_name); + for (int i = 0; i < 4; i++) { + log::info("{:02x}:{:02x}:{:02x}:{:02x}", p[OCTET16_LEN - i * 4 - 1], + p[OCTET16_LEN - i * 4 - 2], p[OCTET16_LEN - i * 4 - 3], + p[OCTET16_LEN - i * 4 - 4]); } } diff --git a/system/stack/srvc/srvc_dis.cc b/system/stack/srvc/srvc_dis.cc index 16a3d60c06cd03b842d4f1e2b04420bc01e51179..fe4f2bc26cf5733e981da37b2cac80c8b74a1a8a 100644 --- a/system/stack/srvc/srvc_dis.cc +++ b/system/stack/srvc/srvc_dis.cc @@ -19,6 +19,7 @@ #define LOG_TAG "bt_srvc" #include +#include #include "gatt_api.h" #include "hardware/bt_gatt_types.h" @@ -33,6 +34,8 @@ #include "types/raw_address.h" using base::StringPrintf; +using namespace bluetooth; + #define DIS_MAX_NUM_INC_SVR 0 #define DIS_MAX_CHAR_NUM 9 #define DIS_MAX_ATTR_NUM (DIS_MAX_CHAR_NUM * 2 + DIS_MAX_NUM_INC_SVR + 1) @@ -160,8 +163,7 @@ uint8_t dis_read_attr_value(UNUSED_ATTR uint8_t clcb_idx, uint16_t handle, p_value->len -= offset; pp += offset; ARRAY_TO_STREAM(p, pp, p_value->len); - VLOG(1) << "GATT_UUID_MANU_NAME len=0x" << std::hex - << +p_value->len; + log::verbose("GATT_UUID_MANU_NAME len=0x{:x}", p_value->len); } break; @@ -202,8 +204,8 @@ static void dis_gatt_c_read_dis_value_cmpl(uint16_t conn_id) { srvc_eng_release_channel(conn_id); if (dis_cb.p_read_dis_cback && p_clcb) { - LOG_INFO("%s conn_id:%d attr_mask = 0x%04x", __func__, conn_id, - p_clcb->dis_value.attr_mask); + log::info("conn_id:{} attr_mask = 0x{:04x}", conn_id, + p_clcb->dis_value.attr_mask); (*dis_cb.p_read_dis_cback)(p_clcb->bda, &p_clcb->dis_value); dis_cb.p_read_dis_cback = NULL; @@ -237,8 +239,7 @@ bool dis_gatt_c_read_dis_req(uint16_t conn_id) { if (GATTC_Read(conn_id, GATT_READ_BY_TYPE, ¶m) == GATT_SUCCESS) return true; - LOG(ERROR) << "Read DISInfo: " << param.service.uuid - << " GATT_Read Failed"; + log::error("Read DISInfo: {} GATT_Read Failed", param.service.uuid); } dis_cb.dis_read_uuid_idx++; @@ -271,9 +272,8 @@ void dis_c_cmpl_cback(tSRVC_CLCB* p_clcb, tGATTC_OPTYPE op, tGATT_STATUS status, read_type = dis_attr_uuid[dis_cb.dis_read_uuid_idx]; - VLOG(1) << __func__ - << StringPrintf("op_code: 0x%02x status: 0x%02x read_type: 0x%04x", - op, status, read_type); + log::verbose("op_code: 0x{:02x} status: 0x{:02x} read_type: 0x{:04x}", op, + status, read_type); if (op != GATTC_OPTYPE_READ) return; @@ -282,7 +282,7 @@ void dis_c_cmpl_cback(tSRVC_CLCB* p_clcb, tGATTC_OPTYPE op, tGATT_STATUS status, switch (read_type) { case GATT_UUID_SYSTEM_ID: - VLOG(1) << "DIS_ATTR_SYS_ID_BIT"; + log::verbose("DIS_ATTR_SYS_ID_BIT"); if (p_data->att_value.len == DIS_SYSTEM_ID_SIZE) { p_clcb->dis_value.attr_mask |= DIS_ATTR_SYS_ID_BIT; /* save system ID*/ @@ -341,7 +341,7 @@ tDIS_STATUS DIS_SrInit(tDIS_ATTR_MASK dis_attr_mask) { tGATT_STATUS status; if (dis_cb.enabled) { - LOG(ERROR) << "DIS already initalized"; + log::error("DIS already initalized"); return DIS_SUCCESS; } @@ -372,7 +372,7 @@ tDIS_STATUS DIS_SrInit(tDIS_ATTR_MASK dis_attr_mask) { status = GATTS_AddService(srvc_eng_cb.gatt_if, service, sizeof(service) / sizeof(btgatt_db_element_t)); if (status != GATT_SERVICE_STARTED) { - LOG(ERROR) << "Can not create service, DIS_Init failed!"; + log::error("Can not create service, DIS_Init failed!"); return GATT_ERROR; } @@ -382,9 +382,8 @@ tDIS_STATUS DIS_SrInit(tDIS_ATTR_MASK dis_attr_mask) { for (int i = 0; i < DIS_MAX_CHAR_NUM; i++) { dis_cb.dis_attr[i].handle = service[i + 1].attribute_handle; - VLOG(1) << StringPrintf("%s: handle of new attribute 0x%04x = %d", - __func__, dis_cb.dis_attr[i].uuid, - dis_cb.dis_attr[i].handle); + log::verbose("handle of new attribute 0x{:04x} = {}", + dis_cb.dis_attr[i].uuid, dis_cb.dis_attr[i].handle); } dis_cb.enabled = true; @@ -456,9 +455,9 @@ bool DIS_ReadDISInfo(const RawAddress& peer_bda, tDIS_READ_CBACK* p_cback, dis_cb.request_mask = mask; - VLOG(1) << __func__ << " BDA: " << ADDRESS_TO_LOGGABLE_STR(peer_bda) - << StringPrintf(" cl_read_uuid: 0x%04x", - dis_attr_uuid[dis_cb.dis_read_uuid_idx]); + log::verbose("BDA: {} cl_read_uuid: 0x{:04x}", + ADDRESS_TO_LOGGABLE_STR(peer_bda), + dis_attr_uuid[dis_cb.dis_read_uuid_idx]); if (!GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE)) { diff --git a/system/stack/srvc/srvc_dis_int.h b/system/stack/srvc/srvc_dis_int.h index fb3703e87fd477404d9370f2ac14c10de651e0a2..9189cef1b4d3072820392870d6b4812ab781a587 100644 --- a/system/stack/srvc/srvc_dis_int.h +++ b/system/stack/srvc/srvc_dis_int.h @@ -19,8 +19,8 @@ #ifndef SRVC_DIS_INT_H #define SRVC_DIS_INT_H -#include "bt_target.h" #include "gatt_api.h" +#include "internal_include/bt_target.h" #include "srvc_api.h" #include "srvc_eng_int.h" diff --git a/system/stack/srvc/srvc_eng.cc b/system/stack/srvc/srvc_eng.cc index 6fe0463209aac3027e888ac42cc56911c3ead015..cc2f1cb29506240a9752108abd1affdba4bda1fe 100644 --- a/system/stack/srvc/srvc_eng.cc +++ b/system/stack/srvc/srvc_eng.cc @@ -17,8 +17,10 @@ ******************************************************************************/ #include +#include #include "gatt_api.h" +#include "os/logging/log_adapter.h" #include "osi/include/allocator.h" #include "osi/include/osi.h" #include "srvc_dis_int.h" @@ -28,6 +30,8 @@ #include "types/raw_address.h" using base::StringPrintf; +using namespace bluetooth; + static void srvc_eng_s_request_cback(uint16_t conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA* p_data); static void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if, @@ -236,8 +240,7 @@ static void srvc_eng_s_request_cback(uint16_t conn_id, uint32_t trans_id, uint8_t act = SRVC_ACT_IGNORE; uint8_t clcb_idx = srvc_eng_find_clcb_idx_by_conn_id(conn_id); - VLOG(1) << StringPrintf("srvc_eng_s_request_cback : recv type (0x%02x)", - type); + log::verbose("srvc_eng_s_request_cback : recv type (0x{:02x})", type); memset(&rsp_msg, 0, sizeof(tGATTS_RSP)); @@ -258,16 +261,15 @@ static void srvc_eng_s_request_cback(uint16_t conn_id, uint32_t trans_id, break; case GATTS_REQ_TYPE_WRITE_EXEC: - VLOG(1) << "Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD"; + log::verbose("Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD"); break; case GATTS_REQ_TYPE_MTU: - VLOG(1) << "Get MTU exchange new mtu size: " << p_data->mtu; + log::verbose("Get MTU exchange new mtu size: {}", p_data->mtu); break; default: - VLOG(1) << StringPrintf("Unknown/unexpected LE GAP ATT request: 0x%02x", - type); + log::verbose("Unknown/unexpected LE GAP ATT request: 0x{:02x}", type); break; } @@ -290,11 +292,11 @@ static void srvc_eng_c_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE* p_data) { tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_conn_id(conn_id); - VLOG(1) << StringPrintf( - "srvc_eng_c_cmpl_cback() - op_code: 0x%02x status: 0x%02x ", op, status); + log::verbose("srvc_eng_c_cmpl_cback() - op_code: 0x{:02x} status: 0x{:02x}", + op, status); if (p_clcb == NULL) { - LOG(ERROR) << __func__ << " received for unknown connection"; + log::error("received for unknown connection"); return; } @@ -315,12 +317,12 @@ static void srvc_eng_connect_cback(UNUSED_ATTR tGATT_IF gatt_if, const RawAddress& bda, uint16_t conn_id, bool connected, tGATT_DISCONN_REASON reason, UNUSED_ATTR tBT_TRANSPORT transport) { - VLOG(1) << __func__ << ": from " << ADDRESS_TO_LOGGABLE_STR(bda) - << StringPrintf(" connected:%d conn_id=%d", connected, conn_id); + log::verbose("from {} connected:{} conn_id={}", ADDRESS_TO_LOGGABLE_STR(bda), + connected, conn_id); if (connected) { if (srvc_eng_clcb_alloc(conn_id, bda) == NULL) { - LOG(ERROR) << __func__ << "srvc_eng_connect_cback: no_resource"; + log::error("srvc_eng_connect_cback: no_resource"); return; } } else { @@ -362,7 +364,7 @@ void srvc_eng_release_channel(uint16_t conn_id) { tSRVC_CLCB* p_clcb = srvc_eng_find_clcb_by_conn_id(conn_id); if (p_clcb == NULL) { - LOG(ERROR) << __func__ << ": invalid connection id " << conn_id; + log::error("invalid connection id {}", conn_id); return; } @@ -381,7 +383,7 @@ void srvc_eng_release_channel(uint16_t conn_id) { tGATT_STATUS srvc_eng_init(void) { if (srvc_eng_cb.enabled) { - LOG(ERROR) << "DIS already initalized"; + log::error("DIS already initalized"); } else { memset(&srvc_eng_cb, 0, sizeof(tSRVC_ENG_CB)); @@ -392,7 +394,7 @@ tGATT_STATUS srvc_eng_init(void) { GATT_Register(app_uuid, "GattServiceEngine", &srvc_gatt_cback, false); GATT_StartIf(srvc_eng_cb.gatt_if); - VLOG(1) << "Srvc_Init: gatt_if=" << +srvc_eng_cb.gatt_if; + log::verbose("Srvc_Init: gatt_if={}", srvc_eng_cb.gatt_if); srvc_eng_cb.enabled = true; dis_cb.dis_read_uuid_idx = 0xff; diff --git a/system/stack/srvc/srvc_eng_int.h b/system/stack/srvc/srvc_eng_int.h index d42a0405c59b40fe1bdb60a53dd6ee2ac96a084d..fbab0c6f1f8a065abb09073d3fa7f1d85aec9b66 100644 --- a/system/stack/srvc/srvc_eng_int.h +++ b/system/stack/srvc/srvc_eng_int.h @@ -19,8 +19,8 @@ #ifndef SRVC_ENG_INT_H #define SRVC_ENG_INT_H -#include "bt_target.h" #include "gatt_api.h" +#include "internal_include/bt_target.h" #include "srvc_api.h" #include "types/raw_address.h" diff --git a/system/stack/test/a2dp/a2dp_aac_unittest.cc b/system/stack/test/a2dp/a2dp_aac_unittest.cc index 21c07006df9fea9c85715c1427865254422ec1c7..bc83ab974cbfe7434aa9bc32ebbb9b800a7130a7 100644 --- a/system/stack/test/a2dp/a2dp_aac_unittest.cc +++ b/system/stack/test/a2dp/a2dp_aac_unittest.cc @@ -17,13 +17,11 @@ #include "stack/include/a2dp_aac.h" #include +#include #include #include #include -#include -#include -#include #include #include "common/init_flags.h" @@ -180,7 +178,7 @@ TEST_F(A2dpAacTest, a2dp_enqueue_cb_is_invoked) { return len; }; auto enqueue_cb = +[](BT_HDR* p_buf, size_t frames_n, uint32_t len) -> bool { - LOG_INFO("%s", kEnqueueCallbackIsInvoked); + log::info("{}", kEnqueueCallbackIsInvoked); osi_free(p_buf); return false; }; @@ -205,7 +203,7 @@ TEST_F(A2dpAacTest, decoded_data_cb_not_invoked_when_empty_packet) { TEST_F(A2dpAacTest, decoded_data_cb_invoked) { log_capture_ = std::make_unique(); auto data_cb = +[](uint8_t* p_buf, uint32_t len) { - LOG_INFO("%s", kDecodedDataCallbackIsInvoked); + log::info("{}", kDecodedDataCallbackIsInvoked); }; InitializeDecoder(data_cb); @@ -217,7 +215,7 @@ TEST_F(A2dpAacTest, decoded_data_cb_invoked) { }; auto enqueue_cb = +[](BT_HDR* p_buf, size_t frames_n, uint32_t len) -> bool { packet = p_buf; - LOG_INFO("%s", kEnqueueCallbackIsInvoked); + log::info("{}", kEnqueueCallbackIsInvoked); return false; }; InitializeEncoder(true, read_cb, enqueue_cb); diff --git a/system/stack/test/a2dp/a2dp_opus_unittest.cc b/system/stack/test/a2dp/a2dp_opus_unittest.cc index 8e13bef9c6434e7954b9c9b43cc81769c588d33b..02de89d9853d019af6145e09a477ae2703d0d136 100644 --- a/system/stack/test/a2dp/a2dp_opus_unittest.cc +++ b/system/stack/test/a2dp/a2dp_opus_unittest.cc @@ -20,10 +20,7 @@ #include #include -#include #include -#include -#include #include #include "common/init_flags.h" diff --git a/system/stack/test/a2dp/a2dp_sbc_regression_tests.cc b/system/stack/test/a2dp/a2dp_sbc_regression_tests.cc index daa8ecf0cdd2b8a215f664383eb0b774681528e7..d1fa110f9509ebf129377350d4d90a9b094a73b7 100644 --- a/system/stack/test/a2dp/a2dp_sbc_regression_tests.cc +++ b/system/stack/test/a2dp/a2dp_sbc_regression_tests.cc @@ -16,8 +16,6 @@ #include -#include - #include "a2dp_sbc.h" namespace bluetooth { diff --git a/system/stack/test/a2dp/a2dp_sbc_unittest.cc b/system/stack/test/a2dp/a2dp_sbc_unittest.cc index 24b03feb35d49eca684c0f13f2e861e1ac7871d7..9487fbc0d51208add8d2eb050c6831bf5c4e8b7b 100644 --- a/system/stack/test/a2dp/a2dp_sbc_unittest.cc +++ b/system/stack/test/a2dp/a2dp_sbc_unittest.cc @@ -22,10 +22,7 @@ #include #include -#include #include -#include -#include #include #include "common/init_flags.h" diff --git a/system/stack/test/a2dp/a2dp_vendor_ldac_decoder_test.cc b/system/stack/test/a2dp/a2dp_vendor_ldac_decoder_test.cc index 44b90806738639c78e32341d17af53939066f851..a5bc0658bfef3baec0fd4b8b8c28ac7835601f05 100644 --- a/system/stack/test/a2dp/a2dp_vendor_ldac_decoder_test.cc +++ b/system/stack/test/a2dp/a2dp_vendor_ldac_decoder_test.cc @@ -22,9 +22,9 @@ #include +#include "include/check.h" #include "osi/include/allocator.h" #include "stack/include/bt_hdr.h" -#include "stack/include/ldacBT_bco_for_fluoride.h" namespace { diff --git a/system/stack/test/a2dp/mock_bta_av_codec.cc b/system/stack/test/a2dp/mock_bta_av_codec.cc index af13c80957ff6738904d58f96143ded0c835671d..5b92e13cf380a7791e05c858ada972c3c4569067 100644 --- a/system/stack/test/a2dp/mock_bta_av_codec.cc +++ b/system/stack/test/a2dp/mock_bta_av_codec.cc @@ -14,9 +14,6 @@ * limitations under the License. */ -#include -#include - #include "a2dp_codec_api.h" A2dpCodecConfig* bta_av_get_a2dp_current_codec(void) { diff --git a/system/stack/test/a2dp/wav_reader.cc b/system/stack/test/a2dp/wav_reader.cc index 4eb0ac46f4f5fafa4d0c79e8f7535df7d1ddebcf..bf535c06b1a66efc7f81332d26c9a705f3121718 100644 --- a/system/stack/test/a2dp/wav_reader.cc +++ b/system/stack/test/a2dp/wav_reader.cc @@ -19,7 +19,7 @@ #include #include -#include "gd/os/files.h" +#include "os/files.h" #include "os/log.h" namespace bluetooth { diff --git a/system/stack/test/a2dp/wav_reader_unittest.cc b/system/stack/test/a2dp/wav_reader_unittest.cc index 401814315f3db4d33dd48adc421870783b49724b..4c128495bfe685e9c55af9ba22923e1f8420ebb9 100644 --- a/system/stack/test/a2dp/wav_reader_unittest.cc +++ b/system/stack/test/a2dp/wav_reader_unittest.cc @@ -18,12 +18,9 @@ #include -#include -#include #include #include -#include "os/log.h" #include "test_util.h" namespace { diff --git a/system/stack/test/btm/sco_hci_test.cc b/system/stack/test/btm/sco_hci_test.cc index 0dd96fa2c3aec09b904ec0d979b60bfd4d825a37..cbe4c265ea695ec172c0afb7d2723637025e8276 100644 --- a/system/stack/test/btm/sco_hci_test.cc +++ b/system/stack/test/btm/sco_hci_test.cc @@ -20,11 +20,10 @@ #include #include -#include #include #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "stack/btm/btm_sco.h" #include "stack/include/hfp_lc3_decoder.h" #include "stack/include/hfp_lc3_encoder.h" diff --git a/system/stack/test/btm/stack_btm_dev_test.cc b/system/stack/test/btm/stack_btm_dev_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..47d9b433ce02a821d6dc26374c50c805200afc20 --- /dev/null +++ b/system/stack/test/btm/stack_btm_dev_test.cc @@ -0,0 +1,50 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "stack/btm/btm_dev.h" +#include "stack/btm/btm_sec_cb.h" +#include "test/common/mock_functions.h" +#include "test/mock/mock_main_shim_entry.h" + +class StackBtmTest : public testing::Test { + public: + protected: + void SetUp() override { reset_mock_function_count_map(); } + void TearDown() override {} +}; + +class StackBtmDevTest : public StackBtmTest { + protected: + void SetUp() override { StackBtmTest::SetUp(); } + void TearDown() override { StackBtmTest::TearDown(); } +}; + +TEST_F(StackBtmDevTest, btm_sec_allocate_dev_rec__no_list) { + ASSERT_EQ(nullptr, btm_sec_allocate_dev_rec()); + ::btm_sec_cb.Init(BTM_SEC_MODE_SC); + ::btm_sec_cb.Free(); + ASSERT_EQ(nullptr, btm_sec_allocate_dev_rec()); +} + +TEST_F(StackBtmDevTest, btm_sec_allocate_dev_rec__with_list) { + ::btm_sec_cb.Init(BTM_SEC_MODE_SC); + ASSERT_NE(nullptr, btm_sec_allocate_dev_rec()); + ::btm_sec_cb.Free(); +} diff --git a/system/stack/test/btm/stack_btm_dm_inq_db_test.cc b/system/stack/test/btm/stack_btm_dm_inq_db_test.cc index 0954ca9208b0203adf6e7e258663cd5c23e08f8c..0f19a3f484318f08e94bd8c69cda9a75ab3998ab 100644 --- a/system/stack/test/btm/stack_btm_dm_inq_db_test.cc +++ b/system/stack/test/btm/stack_btm_dm_inq_db_test.cc @@ -18,12 +18,10 @@ #include #include -#include #include #include #include -#include "osi/include/log.h" #include "stack/btm/btm_int_types.h" #include "stack/btm/neighbor_inquiry.h" #include "stack/include/inq_hci_link_interface.h" diff --git a/system/stack/test/btm/stack_btm_power_mode_test.cc b/system/stack/test/btm/stack_btm_power_mode_test.cc index 52158b9b3f5babd27ecd3658b002d76ae5d2cea6..39a74fac54e4fb24b6bf534da85926369f7bee15 100644 --- a/system/stack/test/btm/stack_btm_power_mode_test.cc +++ b/system/stack/test/btm/stack_btm_power_mode_test.cc @@ -18,16 +18,17 @@ #include -#include "btm_api_types.h" -#include "gd/common/init_flags.h" -#include "gd/os/log.h" +#include "common/init_flags.h" +#include "hci/controller_interface_mock.h" #include "stack/include/acl_api.h" #include "stack/include/acl_hci_link_interface.h" -#include "stack/include/btm_api.h" #include "stack/include/hci_error_code.h" #include "test/common/mock_functions.h" +#include "test/mock/mock_main_shim_entry.h" #include "types/raw_address.h" +using testing::Return; + namespace { const char* test_flags[] = { "INIT_default_log_level_str=LOG_DEBUG", @@ -52,6 +53,8 @@ std::deque power_mode_callback_queue; class StackBtmPowerMode : public testing::Test { protected: void SetUp() override { + ON_CALL(controller_, SupportsSniffMode).WillByDefault(Return(true)); + bluetooth::hci::testing::mock_controller_ = &controller_; power_mode_callback_queue.clear(); reset_mock_function_count_map(); bluetooth::common::InitFlags::Load(test_flags); @@ -74,8 +77,10 @@ class StackBtmPowerMode : public testing::Test { BTM_PmRegister(BTM_PM_DEREG, &pm_id_, [](const RawAddress& p_bda, tBTM_PM_STATUS status, uint16_t value, tHCI_STATUS hci_status) {})); + bluetooth::hci::testing::mock_controller_ = nullptr; } + bluetooth::hci::testing::MockControllerInterface controller_; uint8_t pm_id_{0}; }; diff --git a/system/stack/test/btm/stack_btm_sec_test.cc b/system/stack/test/btm/stack_btm_sec_test.cc index 73631887f76aec84e2d64191d5028661ea283451..3d7e29b28749e53c593d241358268ecb9e1efbf9 100644 --- a/system/stack/test/btm/stack_btm_sec_test.cc +++ b/system/stack/test/btm/stack_btm_sec_test.cc @@ -20,7 +20,7 @@ #include -#include "gd/common/init_flags.h" +#include "common/init_flags.h" #include "hci/hci_layer_mock.h" #include "internal_include/bt_target.h" #include "stack/btm/btm_ble_sec.h" diff --git a/system/stack/test/btm/stack_btm_test.cc b/system/stack/test/btm/stack_btm_test.cc index 89db47e1d9533af3957debbe6543503c10b4e002..b2cbf5cfe994a37be0eef1e08250cc93b0b9fcd9 100644 --- a/system/stack/test/btm/stack_btm_test.cc +++ b/system/stack/test/btm/stack_btm_test.cc @@ -18,12 +18,13 @@ #include #include +#include #include #include -#include "gd/common/init_flags.h" +#include "common/init_flags.h" +#include "hci/controller_interface_mock.h" #include "hci/hci_layer_mock.h" -#include "hci/include/hci_layer.h" #include "internal_include/bt_target.h" #include "stack/btm/btm_dev.h" #include "stack/btm/btm_int_types.h" @@ -46,8 +47,6 @@ extern tBTM_CB btm_cb; tL2C_CB l2cb; -const hci_t* hci_layer_get_interface() { return nullptr; } - const std::string kSmpOptions("mock smp options"); const std::string kBroadcastAudioConfigOptions( "mock broadcast audio config options"); @@ -62,8 +61,12 @@ class StackBtmTest : public Test { protected: void SetUp() override { reset_mock_function_count_map(); + bluetooth::hci::testing::mock_controller_ = &controller_; + } + void TearDown() override { + bluetooth::hci::testing::mock_controller_ = nullptr; } - void TearDown() override {} + bluetooth::hci::testing::MockControllerInterface controller_; }; class StackBtmWithQueuesTest : public StackBtmTest { @@ -235,7 +238,7 @@ TEST_F(StackBtmWithInitFreeTest, btm_sec_rmt_name_request_complete) { ASSERT_TRUE(BTM_SecAddRmtNameNotifyCallback( [](const RawAddress& bd_addr, DEV_CLASS dc, tBTM_BD_NAME bd_name) { btm_test.bd_addr = bd_addr; - memcpy(btm_test.dc, dc, DEV_CLASS_LEN); + btm_test.dc = dc; memcpy(btm_test.bd_name, bd_name, BTM_MAX_REM_BD_NAME_LEN); })); @@ -300,3 +303,7 @@ TEST_F(StackBtmWithInitFreeTest, is_disconnect_reason_valid) { ASSERT_FALSE(is_disconnect_reason_valid(reason)); } } + +TEST_F(StackBtmWithInitFreeTest, Init) { + ASSERT_FALSE(btm_cb.btm_inq_vars.remname_active); +} diff --git a/system/stack/test/btm_iso_test.cc b/system/stack/test/btm_iso_test.cc index 4f78638a243d8b02ad70f58b28a3ae27fa96db1b..3c7a1f88f7a0cf5ca04fd8d5ab3a8d7779587dcb 100644 --- a/system/stack/test/btm_iso_test.cc +++ b/system/stack/test/btm_iso_test.cc @@ -29,6 +29,7 @@ #include "stack/include/bt_types.h" #include "stack/include/hci_error_code.h" #include "stack/include/hcidefs.h" +#include "test/mock/mock_main_shim_hci_layer.h" using bluetooth::hci::IsoManager; using testing::_; @@ -51,13 +52,13 @@ void BTM_LogHistory(const std::string& tag, const RawAddress& bd_addr, namespace bluetooth::shim { class IsoInterface { public: - virtual void HciSend(BT_HDR* packet, uint16_t event) = 0; + virtual void HciSend(BT_HDR* packet) = 0; virtual ~IsoInterface() = default; }; class MockIsoInterface : public IsoInterface { public: - MOCK_METHOD((void), HciSend, (BT_HDR * p_msg, uint16_t event), (override)); + MOCK_METHOD((void), HciSend, (BT_HDR * p_msg), (override)); }; static MockIsoInterface* iso_interface = nullptr; @@ -76,8 +77,8 @@ static void transmit_command(const BT_HDR* command, FAIL() << __func__ << " should never be called"; } -static void transmit_downward(uint16_t type, void* data) { - iso_interface->HciSend((BT_HDR*)data, type); +static void transmit_downward(void* data, uint16_t iso_Data_size) { + iso_interface->HciSend((BT_HDR*)data); osi_free(data); } @@ -85,7 +86,6 @@ static hci_t interface = {.set_data_cb = set_data_cb, .transmit_command = transmit_command, .transmit_downward = transmit_downward}; -const hci_t* hci_layer_get_interface() { return &interface; } } // namespace bluetooth::shim namespace { @@ -139,6 +139,8 @@ class IsoManagerTest : public Test { bluetooth::shim::SetMockIsoInterface(&iso_interface_); hcic::SetMockHcicInterface(&hcic_interface_); controller::SetMockControllerInterface(&controller_interface_); + bluetooth::shim::testing::hci_layer_set_interface( + &bluetooth::shim::interface); big_callbacks_.reset(new MockBigCallbacks()); cig_callbacks_.reset(new MockCigCallbacks()); @@ -163,6 +165,7 @@ class IsoManagerTest : public Test { bluetooth::shim::SetMockIsoInterface(nullptr); hcic::SetMockHcicInterface(nullptr); controller::SetMockControllerInterface(nullptr); + bluetooth::shim::testing::hci_layer_set_interface(nullptr); } virtual void InitIsoManager() { @@ -2090,12 +2093,11 @@ TEST_F(IsoManagerTest, SendIsoDataCigValid) { constexpr uint8_t data_len = 108; EXPECT_CALL(iso_interface_, HciSend) - .WillOnce([handle, data_len](BT_HDR* p_msg, uint16_t event) { + .WillOnce([handle, data_len](BT_HDR* p_msg) { uint8_t* p = p_msg->data; uint16_t msg_handle; uint16_t iso_load_len; - ASSERT_TRUE((event & MSG_STACK_TO_HC_HCI_ISO) != 0); ASSERT_NE(p_msg, nullptr); ASSERT_EQ(p_msg->len, data_len + ((p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) @@ -2142,12 +2144,11 @@ TEST_F(IsoManagerTest, SendIsoDataBigValid) { constexpr uint8_t data_len = 108; EXPECT_CALL(iso_interface_, HciSend) - .WillOnce([handle, data_len](BT_HDR* p_msg, uint16_t event) { + .WillOnce([handle, data_len](BT_HDR* p_msg) { uint8_t* p = p_msg->data; uint16_t msg_handle; uint16_t iso_load_len; - ASSERT_TRUE((event & MSG_STACK_TO_HC_HCI_ISO) != 0); ASSERT_NE(p_msg, nullptr); ASSERT_EQ(p_msg->len, data_len + ((p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) diff --git a/system/stack/test/common/mock_btm_api_layer.h b/system/stack/test/common/mock_btm_api_layer.h index 2dd565943281a3a93e7f22a989e767dd7f1ac7a0..46ae23cb523b7268aff0cceff6e615eae78187fb 100644 --- a/system/stack/test/common/mock_btm_api_layer.h +++ b/system/stack/test/common/mock_btm_api_layer.h @@ -18,7 +18,7 @@ #include -#include "btm_api.h" +#include "types/bt_transport.h" #include "types/raw_address.h" namespace bluetooth { diff --git a/system/stack/test/common/mock_btm_layer.h b/system/stack/test/common/mock_btm_layer.h index 741d55c130ccb200f8bc6a11ad9e5bf057d29e2c..8c5c38e612395aa4c5b613c282125bace8ec967d 100644 --- a/system/stack/test/common/mock_btm_layer.h +++ b/system/stack/test/common/mock_btm_layer.h @@ -19,7 +19,6 @@ #include -#include "stack/include/btm_api_types.h" #include "stack/include/btm_sec_api_types.h" #include "stack/include/btm_status.h" #include "types/raw_address.h" diff --git a/system/stack/test/common/mock_controller.h b/system/stack/test/common/mock_controller.h index 359a03b39ae9e24199c19f1eb85c7d800b1db075..31e5da739947e7a6536c0e52a67af86df961a996 100644 --- a/system/stack/test/common/mock_controller.h +++ b/system/stack/test/common/mock_controller.h @@ -19,7 +19,6 @@ #include #include - namespace controller { class ControllerInterface { public: diff --git a/system/stack/test/common/mock_hcic_layer.cc b/system/stack/test/common/mock_hcic_layer.cc index 33a57ce69a42b8e1f373324c921e4b21bafea729..d885b9daa4c7e6b8d6c56a8036a680dacfeb0657 100644 --- a/system/stack/test/common/mock_hcic_layer.cc +++ b/system/stack/test/common/mock_hcic_layer.cc @@ -108,11 +108,6 @@ namespace bluetooth::legacy::hci { class MockInterface : public Interface { public: - virtual void StartInquiry(const LAP inq_lap, uint8_t duration, - uint8_t response_cnt) const override { - FAIL(); - } - virtual void InquiryCancel() const override { FAIL(); } virtual void Disconnect(uint16_t handle, uint8_t reason) const override { btsnd_hcic_disconnect(handle, reason); } diff --git a/system/stack/test/common/mock_hcic_layer.h b/system/stack/test/common/mock_hcic_layer.h index 251184c4153bdae4f9ccc356b4bb3582223bb34d..33cbf7343511f92cdcabbebda421339484a23241 100644 --- a/system/stack/test/common/mock_hcic_layer.h +++ b/system/stack/test/common/mock_hcic_layer.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include "btm_iso_api_types.h" diff --git a/system/stack/test/common/mock_l2cap_layer.cc b/system/stack/test/common/mock_l2cap_layer.cc index 78d96b5d0c0aa80146ed4d82c1445d354eb3fb99..678419d50327c4e38a486360abf562d618cba88f 100644 --- a/system/stack/test/common/mock_l2cap_layer.cc +++ b/system/stack/test/common/mock_l2cap_layer.cc @@ -17,6 +17,9 @@ ******************************************************************************/ #include "mock_l2cap_layer.h" +#include +#include + #include "stack/include/bt_hdr.h" #include "stack/l2cap/l2c_int.h" #include "types/raw_address.h" @@ -36,7 +39,7 @@ uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, uint16_t required_remote_mtu, uint16_t sec_level) { - VLOG(1) << __func__ << ": psm=" << psm << ", enable_snoop=" << enable_snoop; + bluetooth::log::verbose("psm={}, enable_snoop={}", psm, enable_snoop); return l2cap_interface->Register(psm, p_cb_info, enable_snoop, p_ertm_info); } diff --git a/system/stack/test/common/mock_l2cap_layer.h b/system/stack/test/common/mock_l2cap_layer.h index cb2b36df2d90d2da2e5c45071f9814aa4c6fb0c0..81e76b0ec1d247d51bb59e6732ae6316cc172a01 100644 --- a/system/stack/test/common/mock_l2cap_layer.h +++ b/system/stack/test/common/mock_l2cap_layer.h @@ -19,6 +19,8 @@ #include +#include + #include "l2c_api.h" #include "stack/include/bt_hdr.h" #include "types/raw_address.h" diff --git a/system/stack/test/common/mock_stack_avdt_msg.cc b/system/stack/test/common/mock_stack_avdt_msg.cc index ca74951b3bfe1f81c34bbcf6a3e12465362ad465..4cddd52e585bd6afbe045dc70b5b0345e949a61d 100644 --- a/system/stack/test/common/mock_stack_avdt_msg.cc +++ b/system/stack/test/common/mock_stack_avdt_msg.cc @@ -14,8 +14,6 @@ * limitations under the License. */ -#include -#include #include #include "stack/avdt/avdt_int.h" diff --git a/system/stack/test/common/mock_stack_avdt_msg.h b/system/stack/test/common/mock_stack_avdt_msg.h index 038ee79e623b0a4829326d90837575139acea95b..c24452529c20e58809ee72ab265d351f4e1a9071 100644 --- a/system/stack/test/common/mock_stack_avdt_msg.h +++ b/system/stack/test/common/mock_stack_avdt_msg.h @@ -16,6 +16,9 @@ #pragma once +#include +#include + /** * Get how many responses sent * @@ -58,4 +61,4 @@ void mock_avdt_msg_send_cmd_clear_history(void); * * @note undefined behavior if nth >= total count */ -uint8_t mock_avdt_msg_send_cmd_get_sig_id_at(size_t nth); \ No newline at end of file +uint8_t mock_avdt_msg_send_cmd_get_sig_id_at(size_t nth); diff --git a/system/stack/test/eatt/eatt_test.cc b/system/stack/test/eatt/eatt_test.cc index a0310b8e999479b4b338c7822b6084e97a69f11d..6a89016250daaa1f10a4f7c97c3c2ac2db5974c9 100644 --- a/system/stack/test/eatt/eatt_test.cc +++ b/system/stack/test/eatt/eatt_test.cc @@ -15,6 +15,7 @@ * limitations under the License. */ +#include #include #include @@ -44,6 +45,7 @@ using testing::StrictMock; using bluetooth::eatt::EattChannel; using bluetooth::eatt::EattChannelState; +using namespace bluetooth; #define BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK 0x01 @@ -54,7 +56,7 @@ void gatt_consolidate(const RawAddress& identity_addr, const RawAddress& rpa) {} void gatt_data_process(tGATT_TCB& tcb, uint16_t cid, BT_HDR* p_buf) { return; } tGATT_TCB* gatt_find_tcb_by_addr(const RawAddress& bda, tBT_TRANSPORT transport) { - LOG(INFO) << __func__; + log::info(""); return &test_tcb; } diff --git a/system/stack/test/fuzzers/Android.bp b/system/stack/test/fuzzers/Android.bp index 720f0c0f2b2a94af2a84e63b98a573ab307322f3..66e8ee08c7b1f8e12dacfc8559ddc645d6067b0e 100644 --- a/system/stack/test/fuzzers/Android.bp +++ b/system/stack/test/fuzzers/Android.bp @@ -11,30 +11,45 @@ cc_defaults { name: "libbt-stack_fuzz_defaults", defaults: [ "fluoride_defaults", - "latest_android_hardware_bluetooth_audio_ndk_shared", + "latest_android_hardware_audio_common_ndk_static", + "latest_android_hardware_bluetooth_audio_ndk_static", + "latest_android_media_audio_common_types_ndk_static", ], include_dirs: [ "packages/modules/Bluetooth/system/", "packages/modules/Bluetooth/system/gd/", "packages/modules/Bluetooth/system/include/", - "packages/modules/Bluetooth/system/internal_include/", "packages/modules/Bluetooth/system/stack/include", "packages/modules/Bluetooth/system/stack/test", "packages/modules/Bluetooth/system/types/", ], static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.a2dp@1.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.bluetooth@1.0", + "android.hardware.bluetooth@1.1", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", + "android.system.suspend-V1-ndk", + "android.system.suspend.control-V1-ndk", "libFraunhoferAAC", + "libaudio-a2dp-hw-utils", "libbluetooth-dumpsys", + "libbluetooth-gdx", "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", "libbt-btu-main-thread", "libbt-common", "libbt-hci", + "libbt-jni-thread", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", @@ -53,12 +68,6 @@ cc_defaults { "libudrv-uipc", ], shared_libs: [ - "android.hardware.bluetooth.a2dp@1.0", - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", - "android.hardware.bluetooth@1.0", - "android.hardware.bluetooth@1.1", - "android.system.suspend.control-V1-ndk", "libPlatformProperties", "libaaudio", "libbase", @@ -66,6 +75,7 @@ cc_defaults { "libbinder_ndk", "libcrypto", "libcutils", + "libevent", "libfmq", "libhidlbase", "liblog", diff --git a/system/stack/test/fuzzers/a2dp/a2dpFuzzHelpers.h b/system/stack/test/fuzzers/a2dp/a2dpFuzzHelpers.h index 937203169cbb33abdd5d42eec0a582c1aa037231..d159496691d2ff474365fc63e090fed02f845b1c 100644 --- a/system/stack/test/fuzzers/a2dp/a2dpFuzzHelpers.h +++ b/system/stack/test/fuzzers/a2dp/a2dpFuzzHelpers.h @@ -24,8 +24,8 @@ #include -#include "bt_target.h" #include "fuzzers/sdp/sdpFuzzHelpers.h" +#include "internal_include/bt_target.h" #include "osi/include/allocator.h" #include "stack/a2dp/a2dp_int.h" #include "types/raw_address.h" diff --git a/system/stack/test/fuzzers/common/commonFuzzHelpers.h b/system/stack/test/fuzzers/common/commonFuzzHelpers.h index 01828434f2aa2e47b6195390ba5ec3feae6f10a2..59759395f9a1c946ef525cb8fa84fd1fc7324c26 100644 --- a/system/stack/test/fuzzers/common/commonFuzzHelpers.h +++ b/system/stack/test/fuzzers/common/commonFuzzHelpers.h @@ -20,9 +20,9 @@ #include #include // For memcpy +#include #include -#include "stack/include/sdp_api.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" diff --git a/system/stack/test/gatt/gatt_sr_test.cc b/system/stack/test/gatt/gatt_sr_test.cc index 2283b9e4c6da3cc87c82da07273d3090a7126269..8969c863971f580eb55c513a2565cf389a9e6a0b 100644 --- a/system/stack/test/gatt/gatt_sr_test.cc +++ b/system/stack/test/gatt/gatt_sr_test.cc @@ -20,14 +20,12 @@ #include +#include "include/check.h" #include "stack/gatt/gatt_int.h" #include "stack/include/bt_hdr.h" #include "stack/include/main_thread.h" -#include "stack/test/common/mock_eatt.h" #undef LOG_TAG #include "stack/gatt/gatt_sr.cc" -#include "test/common/mock_functions.h" -#include "types/bluetooth/uuid.h" #include "types/raw_address.h" #define MAX_UINT16 ((uint16_t)0xffff) diff --git a/system/stack/test/gatt/mock_gatt_utils_ref.cc b/system/stack/test/gatt/mock_gatt_utils_ref.cc index 4c729389615ca4bc88c4e472d8eedbb4bc4d3a1e..fc600a7ec56df0be8eaf194814eb47e2cfffe0e5 100644 --- a/system/stack/test/gatt/mock_gatt_utils_ref.cc +++ b/system/stack/test/gatt/mock_gatt_utils_ref.cc @@ -14,10 +14,8 @@ * limitations under the License. */ -#include "common/message_loop_thread.h" #include "stack/gatt/gatt_int.h" #include "stack/include/bt_hdr.h" -#include "types/bluetooth/uuid.h" #include "types/raw_address.h" /** stack/gatt/connection_manager.cc */ diff --git a/system/stack/test/gatt/stack_gatt_test.cc b/system/stack/test/gatt/stack_gatt_test.cc index 6d0e0b58f31f74db68369ce4ced914f063a44a9c..4120f4bbba3cb899dd7f54611afcba43b65593dd 100644 --- a/system/stack/test/gatt/stack_gatt_test.cc +++ b/system/stack/test/gatt/stack_gatt_test.cc @@ -14,21 +14,39 @@ * limitations under the License. */ +#include +#include #include #include +#include #include #include #include #include "common/strings.h" +#include "osi/include/allocator.h" #include "stack/gatt/gatt_int.h" +#include "stack/include/bt_types.h" #include "stack/include/gatt_api.h" +#include "stack/include/l2c_api.h" #include "stack/sdp/internal/sdp_api.h" #include "test/mock/mock_stack_sdp_legacy_api.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" +#define TEST_BT com::android::bluetooth::flags + +namespace bluetooth { +namespace legacy { +namespace testing { +BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, + uint16_t handle, uint16_t offset, uint16_t len, + uint8_t* p_data); +} // namespace testing +} // namespace legacy +} // namespace bluetooth + class StackGattTest : public ::testing::Test { protected: void SetUp() override { @@ -151,7 +169,9 @@ TEST_F(StackGattTest, GATT_Register_Deregister) { gatt_free(); } -TEST_F(StackGattTest, gatt_status_text) { +TEST_F_WITH_FLAGS(StackGattTest, gatt_status_text, + REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, + enumerate_gatt_errors))) { std::vector> statuses = { std::make_pair(GATT_SUCCESS, "GATT_SUCCESS"), // Also GATT_ENCRYPED_MITM std::make_pair(GATT_INVALID_HANDLE, "GATT_INVALID_HANDLE"), @@ -174,7 +194,6 @@ TEST_F(StackGattTest, gatt_status_text) { std::make_pair(GATT_DATABASE_OUT_OF_SYNC, "GATT_DATABASE_OUT_OF_SYNC"), std::make_pair(GATT_VALUE_NOT_ALLOWED, "GATT_VALUE_NOT_ALLOWED"), std::make_pair(GATT_ILLEGAL_PARAMETER, "GATT_ILLEGAL_PARAMETER"), - std::make_pair(GATT_TOO_SHORT, "GATT_TOO_SHORT"), std::make_pair(GATT_NO_RESOURCES, "GATT_NO_RESOURCES"), std::make_pair(GATT_INTERNAL_ERROR, "GATT_INTERNAL_ERROR"), std::make_pair(GATT_WRONG_STATE, "GATT_WRONG_STATE"), @@ -184,7 +203,6 @@ TEST_F(StackGattTest, gatt_status_text) { std::make_pair(GATT_CMD_STARTED, "GATT_CMD_STARTED"), std::make_pair(GATT_PENDING, "GATT_PENDING"), std::make_pair(GATT_AUTH_FAIL, "GATT_AUTH_FAIL"), - std::make_pair(GATT_MORE, "GATT_MORE"), std::make_pair(GATT_INVALID_CFG, "GATT_INVALID_CFG"), std::make_pair(GATT_SERVICE_STARTED, "GATT_SERVICE_STARTED"), std::make_pair(GATT_ENCRYPED_NO_MITM, "GATT_ENCRYPED_NO_MITM"), @@ -193,6 +211,7 @@ TEST_F(StackGattTest, gatt_status_text) { std::make_pair(GATT_DUP_REG, "GATT_DUP_REG"), std::make_pair(GATT_ALREADY_OPEN, "GATT_ALREADY_OPEN"), std::make_pair(GATT_CANCEL, "GATT_CANCEL"), + std::make_pair(GATT_CONNECTION_TIMEOUT, "GATT_CONNECTION_TIMEOUT"), std::make_pair(GATT_CCC_CFG_ERR, "GATT_CCC_CFG_ERR"), std::make_pair(GATT_PRC_IN_PROGRESS, "GATT_PRC_IN_PROGRESS"), std::make_pair(GATT_OUT_OF_RANGE, "GATT_OUT_OF_RANGE"), @@ -205,3 +224,164 @@ TEST_F(StackGattTest, gatt_status_text) { ASSERT_STREQ(unknown.c_str(), gatt_status_text(static_cast(0xfc)).c_str()); } + +const static std::map gatt_min_value_cmd_size{ + {GATT_RSP_READ_BY_TYPE, 4}, // op_code (1) + pair_len (1) + handle (2) + {GATT_RSP_READ_BLOB, 1}, // op_code (1) + {GATT_RSP_READ, 1}, + {GATT_REQ_PREPARE_WRITE, 5}, // op_code (1) + handle (2) + offset (2) + {GATT_REQ_READ_BY_GRP_TYPE, 3}, // op_code + handle +}; + +static void attp_build_value_cmd_test_with_p_data(uint16_t payload_size, + uint8_t op_code, + uint16_t handle, + uint16_t offset, uint16_t len, + uint8_t* p_data) { + uint16_t min_payload_size; + uint8_t pair_len_read; + uint16_t offset_read = 0; + uint16_t handle_read = 0; + + ASSERT_TRUE(gatt_min_value_cmd_size.find(op_code) != + gatt_min_value_cmd_size.end()); + min_payload_size = gatt_min_value_cmd_size.at(op_code); + + ASSERT_GE(payload_size, min_payload_size); + + BT_HDR* ret = bluetooth::legacy::testing::attp_build_value_cmd( + payload_size, op_code, handle, offset, len, p_data); + + ASSERT_NE(ret, nullptr); + uint8_t* p = (uint8_t*)(ret + 1) + L2CAP_MIN_OFFSET; + + uint8_t op_code_read; + STREAM_TO_UINT8(op_code_read, p); + ASSERT_EQ(op_code_read, op_code); + + if (op_code == GATT_RSP_READ_BY_TYPE) { + STREAM_TO_UINT8(pair_len_read, p); + + STREAM_TO_UINT16(handle_read, p); + ASSERT_EQ(handle_read, handle); + } else if (op_code == GATT_RSP_READ_BLOB || op_code == GATT_RSP_READ) { + ; + } else if (op_code == GATT_REQ_PREPARE_WRITE || + op_code == GATT_RSP_PREPARE_WRITE) { + STREAM_TO_UINT16(handle_read, p); + ASSERT_EQ(handle_read, handle); + STREAM_TO_UINT16(offset_read, p); + ASSERT_EQ(offset_read, offset); + } else { + STREAM_TO_UINT16(handle_read, p); + ASSERT_EQ(handle_read, handle); + } + + uint16_t actual_payload_size; + uint8_t pair_len; + + if (p_data != nullptr) { + if (min_payload_size + len <= payload_size) { + actual_payload_size = min_payload_size + len; + pair_len = len + 2; + } else { + actual_payload_size = payload_size; + pair_len = payload_size - min_payload_size + 2; + } + + size_t cmp_size = actual_payload_size - min_payload_size; + int ret = memcmp(p_data, p, cmp_size); + ASSERT_EQ(ret, 0); + + } else { + pair_len = len + 2; + actual_payload_size = min_payload_size; + } + + ASSERT_EQ(ret->len, actual_payload_size); + + if (op_code == GATT_RSP_READ_BY_TYPE) { + ASSERT_EQ(pair_len_read, pair_len); + } + + osi_free_and_reset((void**)&ret); +} + +TEST_F(StackGattTest, attp_build_value_cmd_p_data_null) { + for (auto it = gatt_min_value_cmd_size.begin(); + it != gatt_min_value_cmd_size.end(); it++) { + attp_build_value_cmd_test_with_p_data(it->second, it->first, 0x1, 0x1234, 0, + nullptr); + } +} + +TEST_F(StackGattTest, attp_build_value_cmd_no_p_data) { + for (auto it = gatt_min_value_cmd_size.begin(); + it != gatt_min_value_cmd_size.end(); it++) { + attp_build_value_cmd_test_with_p_data(it->second, it->first, 0x1, 0x1234, 3, + (uint8_t*)"abc"); + } +} + +TEST_F(StackGattTest, attp_build_value_cmd_partial_p_data) { + for (auto it = gatt_min_value_cmd_size.begin(); + it != gatt_min_value_cmd_size.end(); it++) { + attp_build_value_cmd_test_with_p_data(it->second + 1, it->first, 0x1, + 0x1234, 3, (uint8_t*)"abc"); + } +} + +TEST_F(StackGattTest, attp_build_value_cmd_full_p_data) { + for (auto it = gatt_min_value_cmd_size.begin(); + it != gatt_min_value_cmd_size.end(); it++) { + attp_build_value_cmd_test_with_p_data(it->second + 5, it->first, 0x1, + 0x1234, 3, (uint8_t*)"abc"); + } +} + +static void attp_build_value_cmd_small_payload_size(uint8_t op_code) { + // payload size too small + uint16_t offset_0 = 0; + uint16_t handle = 0x1; + uint16_t len = 0; + uint8_t* p_data = nullptr; + uint16_t test_payload_size = gatt_min_value_cmd_size.at(op_code) - 1; + + ASSERT_TRUE(gatt_min_value_cmd_size.find(op_code) != + gatt_min_value_cmd_size.end()); + test_payload_size = gatt_min_value_cmd_size.at(op_code) - 1; + + BT_HDR* ret = bluetooth::legacy::testing::attp_build_value_cmd( + test_payload_size, op_code, handle, offset_0, len, p_data); + + ASSERT_EQ(ret, nullptr); +} + +TEST_F(StackGattTest, + attp_build_value_cmd_test_payload_size_less_than_mimimal) { + for (auto it = gatt_min_value_cmd_size.begin(); + it != gatt_min_value_cmd_size.end(); it++) { + attp_build_value_cmd_small_payload_size(it->first); + } +} + +TEST_F(StackGattTest, attp_build_value_cmd_read_by_type_test_long_data) { + // p_data too large and does not fit in pair_len + // only for GATT_RSP_READ_BY_TYPE + uint16_t offset_0 = 0; + uint16_t handle = 0x1; + const uint8_t op_code = GATT_RSP_READ_BY_TYPE; + + const int data_size = 255; + uint16_t payload_size = data_size + 4; + + uint8_t data[data_size]; + + for (int i = 0; i < data_size; i++) { + data[i] = 'A'; + } + + BT_HDR* ret = bluetooth::legacy::testing::attp_build_value_cmd( + payload_size, op_code, handle, offset_0, data_size, data); + ASSERT_EQ(ret, nullptr); +} diff --git a/system/stack/test/gatt_connection_manager_test.cc b/system/stack/test/gatt_connection_manager_test.cc index 4d2efa10a054c10e1813e913423ce73f49da4664..039e829cc20f45bef0585127d3c3d2b5c5ce40ab 100644 --- a/system/stack/test/gatt_connection_manager_test.cc +++ b/system/stack/test/gatt_connection_manager_test.cc @@ -10,8 +10,8 @@ #include "common/init_flags.h" #include "osi/include/alarm.h" #include "osi/test/alarm_mock.h" +#include "stack/btm/neighbor_inquiry.h" #include "stack/gatt/connection_manager.h" -#include "stack/test/common/mock_btm_api_layer.h" using testing::_; using testing::DoAll; diff --git a/system/stack/test/hci/stack_hci_test.cc b/system/stack/test/hci/stack_hci_test.cc index 944f373b59286d2f8a71bbb80d9c3a49f0f34541..3c6cf1c562a6b72dbedd13528eb82c829303c690 100644 --- a/system/stack/test/hci/stack_hci_test.cc +++ b/system/stack/test/hci/stack_hci_test.cc @@ -18,10 +18,8 @@ #include #include -#include #include -#include "osi/include/log.h" #include "stack/include/hcidefs.h" #include "stack/include/l2cdefs.h" #include "test/common/mock_functions.h" diff --git a/system/stack/test/hid/stack_hid_test.cc b/system/stack/test/hid/stack_hid_test.cc index 90d052502a6b2862a74fcf86b4573ac931acf416..20c509892db589b80da7c63d5103f8b167aad976 100644 --- a/system/stack/test/hid/stack_hid_test.cc +++ b/system/stack/test/hid/stack_hid_test.cc @@ -17,11 +17,7 @@ #include #include -#include -#include - #include "common/message_loop_thread.h" -#include "osi/include/log.h" #include "stack/hid/hidh_int.h" #include "stack/include/hci_error_code.h" #include "test/common/mock_functions.h" diff --git a/system/stack/test/rfcomm/stack_rfcomm_test.cc b/system/stack/test/rfcomm/stack_rfcomm_test.cc index c40400e3d641f49cc1373a2494fae0f17928cfc3..eeb7080b21bfaa7924a8fae9cb5e19c525647e84 100644 --- a/system/stack/test/rfcomm/stack_rfcomm_test.cc +++ b/system/stack/test/rfcomm/stack_rfcomm_test.cc @@ -17,6 +17,7 @@ ******************************************************************************/ #include +#include #include #include @@ -33,6 +34,8 @@ #include "stack_test_packet_utils.h" #include "types/raw_address.h" +using namespace bluetooth; + std::string DumpByteBufferToString(uint8_t* p_data, size_t len) { std::stringstream str; str.setf(std::ios_base::hex, std::ios::basefield); @@ -133,7 +136,7 @@ class StackRfcommTest : public Test { tPORT_CALLBACK* management_callback, tPORT_CALLBACK* event_callback, uint16_t* server_handle) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); ASSERT_EQ(RFCOMM_CreateConnectionWithSecurity( uuid, scn, true, mtu, RawAddress::kAny, server_handle, management_callback, 0), @@ -145,7 +148,7 @@ class StackRfcommTest : public Test { void ConnectServerL2cap(const RawAddress& peer_addr, uint16_t acl_handle, uint16_t lcid) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); // Remote device connect to this channel, we shall accept static const uint8_t cmd_id = 0x07; EXPECT_CALL(l2cap_interface_, @@ -157,19 +160,19 @@ class StackRfcommTest : public Test { l2cap_appl_info_.pL2CA_ConnectInd_Cb(peer_addr, lcid, BT_PSM_RFCOMM, cmd_id); - VLOG(1) << "Step 2"; + log::verbose("Step 2"); // MTU configuration is done cfg_req.mtu_present = false; l2cap_appl_info_.pL2CA_ConfigCfm_Cb(lcid, L2CAP_CFG_OK, {}); - VLOG(1) << "Step 3"; + log::verbose("Step 3"); // Remote device also ask to configure MTU size EXPECT_CALL(l2cap_interface_, ConfigResponse(lcid, PointerMemoryEqual(&cfg_req))) .WillOnce(Return(true)); l2cap_appl_info_.pL2CA_ConfigInd_Cb(lcid, &cfg_req); - VLOG(1) << "Step 4"; + log::verbose("Step 4"); // Remote device connect to server channel 0 BT_HDR* sabm_channel_0 = AllocateWrappedIncomingL2capAclPacket( CreateQuickSabmPacket(RFCOMM_MX_DLCI, lcid, acl_handle)); @@ -185,7 +188,7 @@ class StackRfcommTest : public Test { void ConnectServerPort(const RawAddress& peer_addr, uint16_t port_handle, uint8_t scn, uint16_t mtu, uint16_t acl_handle, uint16_t lcid, int port_callback_index) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); // Negotiate parameters on scn BT_HDR* uih_pn_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket( CreateQuickPnPacket(true, GetDlci(false, scn), true, mtu, @@ -202,7 +205,7 @@ class StackRfcommTest : public Test { l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_cmd_from_peer); osi_free(uih_pn_rsp_to_peer); - VLOG(1) << "Step 2"; + log::verbose("Step 2"); // Remote device connect to scn tBTM_SEC_CALLBACK* security_callback = nullptr; void* p_port = nullptr; @@ -217,7 +220,7 @@ class StackRfcommTest : public Test { // sabm_channel_dlci should be freed by this method l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, sabm_channel_dlci); - VLOG(1) << "Step 3"; + log::verbose("Step 3"); // Confirm security check should trigger port as connected EXPECT_CALL( rfcomm_callback_, @@ -230,7 +233,7 @@ class StackRfcommTest : public Test { security_callback(&peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS); osi_free(ua_channel_dlci); - VLOG(1) << "Step 4"; + log::verbose("Step 4"); // Remote also need to configure its modem signal before we can send data BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket( CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, true, @@ -252,7 +255,7 @@ class StackRfcommTest : public Test { l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer); osi_free(uih_msc_response_to_peer); - VLOG(1) << "Step 5"; + log::verbose("Step 5"); // modem configuration is done BT_HDR* uih_msc_response_from_peer = AllocateWrappedIncomingL2capAclPacket( CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, false, @@ -267,7 +270,7 @@ class StackRfcommTest : public Test { tPORT_CALLBACK* event_callback, uint16_t lcid, uint16_t acl_handle, uint16_t* client_handle, bool is_first_connection) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); BT_HDR* uih_pn_channel_3 = AllocateWrappedOutgoingL2capAclPacket(CreateQuickPnPacket( true, GetDlci(false, scn), true, mtu, RFCOMM_PN_CONV_LAYER_TYPE_1, @@ -291,7 +294,7 @@ class StackRfcommTest : public Test { } void TestConnectClientPortL2cap(uint16_t acl_handle, uint16_t lcid) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); // Send configuration request when L2CAP connect is succsseful tL2CAP_CFG_INFO cfg_req = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE}; EXPECT_CALL(l2cap_interface_, @@ -299,12 +302,12 @@ class StackRfcommTest : public Test { .WillOnce(Return(true)); l2cap_appl_info_.pL2CA_ConnectCfm_Cb(lcid, L2CAP_CONN_OK); - VLOG(1) << "Step 2"; + log::verbose("Step 2"); // Remote device confirms our configuration request cfg_req.mtu_present = false; l2cap_appl_info_.pL2CA_ConfigCfm_Cb(lcid, L2CAP_CFG_OK, {}); - VLOG(1) << "Step 3"; + log::verbose("Step 3"); // Remote device also asks to configure MTU // Once configuration is done, we connect to multiplexer control channel 0 EXPECT_CALL(l2cap_interface_, @@ -323,9 +326,9 @@ class StackRfcommTest : public Test { uint8_t scn, uint16_t mtu, uint16_t acl_handle, uint16_t lcid, int port_callback_index, bool is_first_connection) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); if (is_first_connection) { - VLOG(1) << "Step 1.5"; + log::verbose("Step 1.5"); // Once remote accept multiplexer control channel 0 // We change to desired channel on non-initiating device (remote device) BT_HDR* ua_channel_0 = AllocateWrappedIncomingL2capAclPacket( @@ -342,7 +345,7 @@ class StackRfcommTest : public Test { osi_free(uih_pn_channel_3); } - VLOG(1) << "Step 2"; + log::verbose("Step 2"); // Once remote accept service channel change, we start security procedure BT_HDR* uih_pn_channel_3_accept = AllocateWrappedIncomingL2capAclPacket(CreateQuickPnPacket( @@ -359,7 +362,7 @@ class StackRfcommTest : public Test { Return(BTM_SUCCESS))); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_channel_3_accept); - VLOG(1) << "Step 3"; + log::verbose("Step 3"); // Once security procedure is done, we officially connect to target scn BT_HDR* sabm_channel_3 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickSabmPacket(GetDlci(false, scn), lcid, acl_handle)); @@ -369,7 +372,7 @@ class StackRfcommTest : public Test { security_callback(&peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS); osi_free(sabm_channel_3); - VLOG(1) << "Step 4"; + log::verbose("Step 4"); // When target scn is accepted by remote, we need to configure modem signal // state beofre using the port EXPECT_CALL( @@ -385,14 +388,14 @@ class StackRfcommTest : public Test { l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_3); osi_free(uih_msc_cmd); - VLOG(1) << "Step 5"; + log::verbose("Step 5"); // modem configuration is done BT_HDR* uih_msc_response = AllocateWrappedIncomingL2capAclPacket( CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, false, false, true, true, false, true)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_response); - VLOG(1) << "Step 6"; + log::verbose("Step 6"); // Remote also need to configure its modem signal before we can send data BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket( CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, true, @@ -412,7 +415,7 @@ class StackRfcommTest : public Test { bool cr, const std::string& message, int credits, uint16_t acl_handle, uint16_t lcid) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); BT_HDR* data_packet = AllocateWrappedOutgoingL2capAclPacket( CreateQuickDataPacket(GetDlci(is_initiator, scn), cr, lcid, acl_handle, credits, message)); @@ -431,7 +434,7 @@ class StackRfcommTest : public Test { int credits, uint16_t acl_handle, uint16_t lcid, int port_callback_index) { - VLOG(1) << "Step 1"; + log::verbose("Step 1"); BT_HDR* data_packet = AllocateWrappedIncomingL2capAclPacket( CreateQuickDataPacket(GetDlci(is_initiator, scn), cr, lcid, acl_handle, credits, message)); @@ -439,7 +442,7 @@ class StackRfcommTest : public Test { PortEventCallback(_, port_handle, port_callback_index)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, data_packet); - VLOG(1) << "Step 2"; + log::verbose("Step 2"); char buffer[L2CAP_MTU_SIZE] = {}; uint16_t length = 0; int status = PORT_ReadData(port_handle, buffer, L2CAP_MTU_SIZE, &length); @@ -722,7 +725,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { static const uint16_t test_mtu = 1000; static const RawAddress test_address = GetTestAddress(0); uint16_t server_handle = 0; - VLOG(1) << "Step 1"; + log::verbose("Step 1"); // Prepare a server port int status = RFCOMM_CreateConnectionWithSecurity( test_uuid, test_server_scn, true, test_mtu, RawAddress::kAny, @@ -733,7 +736,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { status = PORT_SetEventCallback(server_handle, port_event_cback_0); ASSERT_EQ(status, PORT_SUCCESS); - VLOG(1) << "Step 2"; + log::verbose("Step 2"); // Try to connect to a client port uint16_t client_handle_1 = 0; EXPECT_CALL(l2cap_interface_, ConnectRequest(BT_PSM_RFCOMM, test_address)) @@ -748,7 +751,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { status = PORT_SetEventCallback(client_handle_1, port_event_cback_1); ASSERT_EQ(status, PORT_SUCCESS); - VLOG(1) << "Step 3"; + log::verbose("Step 3"); // While our connection is pending, remote device tries to connect to // new_lcid, with L2CAP command id: pending_cmd_id static const uint8_t pending_cmd_id = 0x05; @@ -756,7 +759,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { l2cap_appl_info_.pL2CA_ConnectInd_Cb(test_address, new_lcid, BT_PSM_RFCOMM, pending_cmd_id); - VLOG(1) << "Step 4"; + log::verbose("Step 4"); // Remote reject our connection request saying PSM not allowed // This should trigger RFCOMM to accept remote L2CAP connection at new_lcid EXPECT_CALL(l2cap_interface_, ConnectResponse(test_address, pending_cmd_id, @@ -769,7 +772,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { .WillOnce(Return(true)); l2cap_appl_info_.pL2CA_ConnectCfm_Cb(old_lcid, L2CAP_CONN_NO_PSM); - VLOG(1) << "Step 5"; + log::verbose("Step 5"); // Remote device also ask to configure MTU size as well tL2CAP_CFG_INFO peer_cfg_req = {.mtu_present = true, .mtu = test_mtu}; // We responded by saying OK @@ -780,13 +783,13 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { .WillOnce(Return(true)); l2cap_appl_info_.pL2CA_ConfigInd_Cb(new_lcid, &peer_cfg_req); - VLOG(1) << "Step 6"; + log::verbose("Step 6"); // Remote device accepted our MTU size l2cap_appl_info_.pL2CA_ConfigCfm_Cb(new_lcid, L2CAP_CFG_OK, {}); // L2CAP collision and connection setup done - VLOG(1) << "Step 7"; + log::verbose("Step 7"); // Remote device connect multiplexer channel BT_HDR* sabm_channel_0 = AllocateWrappedIncomingL2capAclPacket( CreateQuickSabmPacket(RFCOMM_MX_DLCI, new_lcid, acl_handle)); @@ -808,7 +811,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { osi_free(ua_channel_0); osi_free(uih_pn_cmd_to_peer); - VLOG(1) << "Step 8"; + log::verbose("Step 8"); // Peer tries to configure test_server_scn BT_HDR* uih_pn_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket( CreateQuickPnPacket(true, GetDlci(false, test_server_scn), true, test_mtu, @@ -826,7 +829,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_pn_cmd_from_peer); osi_free(uih_pn_rsp_to_peer); - VLOG(1) << "Step 9"; + log::verbose("Step 9"); // Remote never replies our configuration request for test_peer_scn // But instead connect to test_server_scn directly BT_HDR* sabm_server_scn = @@ -843,7 +846,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { Return(BTM_SUCCESS))); l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, sabm_server_scn); - VLOG(1) << "Step 10"; + log::verbose("Step 10"); // After security check, we accept the connection ASSERT_TRUE(security_callback); BT_HDR* ua_server_scn = @@ -858,7 +861,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { security_callback(&test_address, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS); osi_free(ua_server_scn); - VLOG(1) << "Step 11"; + log::verbose("Step 11"); // MPX_CTRL Modem Status Command (MSC) BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket( CreateQuickMscPacket(true, GetDlci(false, test_server_scn), new_lcid, @@ -880,7 +883,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { osi_free(uih_msc_rsp_to_peer); osi_free(uih_msc_cmd_to_peer); - VLOG(1) << "Step 12"; + log::verbose("Step 12"); BT_HDR* uih_msc_rsp_from_peer = AllocateWrappedIncomingL2capAclPacket( CreateQuickMscPacket(true, GetDlci(false, test_server_scn), new_lcid, acl_handle, false, false, true, true, false, true)); diff --git a/system/stack/test/rfcomm/stack_rfcomm_test_main.cc b/system/stack/test/rfcomm/stack_rfcomm_test_main.cc index dea28eda031866fc0b963b89008e1f0af64bd3e0..9de02ea6a7f13c63a092f73b77ad9f3bf82da1da 100644 --- a/system/stack/test/rfcomm/stack_rfcomm_test_main.cc +++ b/system/stack/test/rfcomm/stack_rfcomm_test_main.cc @@ -20,15 +20,18 @@ #include #include #include +#include #include #include +using namespace bluetooth; + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); if (base::CommandLine::InitializedForCurrentProcess()) { - LOG(FATAL) << "base::CommandLine::Init should not be called twice"; + log::fatal("base::CommandLine::Init should not be called twice"); return 1; } @@ -45,14 +48,14 @@ int main(int argc, char** argv) { const char* logging_argv[] = {"bt_stack", log_level_arg}; // Init command line object with logging switches if (!base::CommandLine::Init(2, logging_argv)) { - LOG(FATAL) << "base::CommandLine::Init failed, arg0=" << logging_argv[0] - << ", arg1=" << logging_argv[1]; + log::fatal("base::CommandLine::Init failed, arg0={}, arg1={}", + logging_argv[0], logging_argv[1]); return 1; } logging::LoggingSettings log_settings; if (!logging::InitLogging(log_settings)) { - LOG(ERROR) << "Failed to set up logging"; + log::error("Failed to set up logging"); } // Android already logs thread_id, proc_id, timestamp, so disable those. diff --git a/system/stack/test/sdp/stack_sdp_utils_test.cc b/system/stack/test/sdp/stack_sdp_utils_test.cc index 1ca9d3901bb2b7d6991097ae1689d18683d1e960..77bf15899577652057ec1df11c9b1436947a83b7 100644 --- a/system/stack/test/sdp/stack_sdp_utils_test.cc +++ b/system/stack/test/sdp/stack_sdp_utils_test.cc @@ -19,7 +19,7 @@ #include #include "btif/include/btif_storage.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "common/init_flags.h" #include "device/include/interop.h" #include "mock_btif_config.h" diff --git a/system/stack/test/stack_a2dp_test.cc b/system/stack/test/stack_a2dp_test.cc index c3550bf9608e9e1a6659cf2df5248d9d3920fc27..85b3e7675a741deefdf26f89e84a6a5ceb3f2b75 100644 --- a/system/stack/test/stack_a2dp_test.cc +++ b/system/stack/test/stack_a2dp_test.cc @@ -313,6 +313,8 @@ class StackA2dpTest : public ::testing::Test { supported = true; break; case BTAV_A2DP_CODEC_INDEX_MAX: + case BTAV_A2DP_CODEC_INDEX_SOURCE_MAX: + case BTAV_A2DP_CODEC_INDEX_SINK_MAX: // Needed to avoid using "default:" case so we can capture when // a new codec is added, and it can be included here. break; @@ -914,6 +916,12 @@ TEST_F(StackA2dpTest, test_a2dp_codec_index_str) { // Test that each codec has a known string for (int i = BTAV_A2DP_CODEC_INDEX_MIN; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) { + if ((i >= BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN && + i < BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX) || + (i >= BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN && + i < BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX)) { + continue; + } btav_a2dp_codec_index_t codec_index = static_cast(i); EXPECT_STRNE(A2DP_CodecIndexStr(codec_index), "UNKNOWN CODEC INDEX"); diff --git a/system/stack/test/stack_acl_test.cc b/system/stack/test/stack_acl_test.cc index 19e8533e5a9ffc6f2ce75231576e9bcab73d7b2d..2d5d1be24563f8f03ff8ab47b3e4ac396abf0589 100644 --- a/system/stack/test/stack_acl_test.cc +++ b/system/stack/test/stack_acl_test.cc @@ -19,6 +19,7 @@ #include #include "common/init_flags.h" +#include "hci/controller_interface_mock.h" #include "stack/acl/acl.h" #include "stack/btm/btm_int_types.h" #include "stack/btm/security_device_record.h" @@ -26,6 +27,7 @@ #include "stack/include/acl_hci_link_interface.h" #include "stack/include/hcidefs.h" #include "test/common/mock_functions.h" +#include "test/mock/mock_main_shim_entry.h" #include "types/hci_role.h" #include "types/raw_address.h" @@ -53,10 +55,14 @@ class StackAclTest : public testing::Test { void SetUp() override { reset_mock_function_count_map(); bluetooth::common::InitFlags::Load(test_flags); + bluetooth::hci::testing::mock_controller_ = &controller_; + } + void TearDown() override { + bluetooth::hci::testing::mock_controller_ = nullptr; } - void TearDown() override {} tBTM_SEC_DEV_REC device_record_; + bluetooth::hci::testing::MockControllerInterface controller_; }; TEST_F(StackAclTest, nop) {} diff --git a/system/stack/test/stack_btu_test.cc b/system/stack/test/stack_btu_test.cc index 80e9b26631e153b716d8a30a3c0099d3f2a6fc0a..3ea7b168c5bdf478229366cb50b854de72f10320 100644 --- a/system/stack/test/stack_btu_test.cc +++ b/system/stack/test/stack_btu_test.cc @@ -17,8 +17,6 @@ #include #include -#include -#include #include "stack/include/btu_hcif.h" #include "stack/include/hci_error_code.h" diff --git a/system/stack/test/stack_gatt_sr_hash_test.cc b/system/stack/test/stack_gatt_sr_hash_test.cc index d60fc46f5f59a9051a3b84675ff1988de0ebeae7..ad3ac96832cc71dde9dbf799102a58d9b2dc374b 100644 --- a/system/stack/test/stack_gatt_sr_hash_test.cc +++ b/system/stack/test/stack_gatt_sr_hash_test.cc @@ -18,10 +18,7 @@ #include -#include "crypto_toolbox/crypto_toolbox.h" #include "stack/gatt/gatt_int.h" -#include "stack/test/common/mock_eatt.h" -#include "test/common/mock_functions.h" #include "types/bluetooth/uuid.h" using bluetooth::Uuid; diff --git a/system/stack/test/stack_include_test.cc b/system/stack/test/stack_include_test.cc index 775cda75ee7cd4979f497b257a88060adc7b64d2..8ea07a76563cedab87012466e8cb8022120de472 100644 --- a/system/stack/test/stack_include_test.cc +++ b/system/stack/test/stack_include_test.cc @@ -16,7 +16,6 @@ #include -#include "os/log.h" #include "stack/include/bt_dev_class.h" class StackIncludeTest : public ::testing::Test { diff --git a/system/stack/test/stack_l2cap_test.cc b/system/stack/test/stack_l2cap_test.cc index 91f58764a50399c62eb78879716ad7fc41b8dec3..6e3b0132991c39abe87d5712239d801b06fa0fb9 100644 --- a/system/stack/test/stack_l2cap_test.cc +++ b/system/stack/test/stack_l2cap_test.cc @@ -45,7 +45,7 @@ class StackL2capTest : public ::testing::Test { return kAclBufferCountClassic; }; controller_.get_acl_buffer_count_ble = []() { return kAclBufferCountBle; }; - controller_.supports_ble = []() -> bool { return true; }; + controller_.SupportsBle = []() -> bool { return true; }; l2c_init(); } diff --git a/system/test/Android.bp b/system/test/Android.bp index 7c80d78002a7cc068c41a75c646d629e3baf1865..95836dada5fa27808ecd6b6d96535dc33981708e 100644 --- a/system/test/Android.bp +++ b/system/test/Android.bp @@ -12,6 +12,11 @@ subdirs = [ "suite", ] +filegroup { + name: "TestMockAudioHalInterface", + srcs: ["mock/mock_audio_hal_interface*.cc"], +} + filegroup { name: "TestMockAudioA2dp", srcs: ["mock/mock_audio_a2dp*.cc"], @@ -182,10 +187,30 @@ filegroup { ], } +filegroup { + name: "TestMockMainShimDumpsys", + srcs: [ + "mock/mock_main_shim_dumpsys.cc", + ], +} + filegroup { name: "TestMockMainShim", srcs: [ - "mock/mock_main_shim*.cc", + "mock/mock_main_shim.cc", + "mock/mock_main_shim_BtifConfigInterface.cc", + "mock/mock_main_shim_acl.cc", + "mock/mock_main_shim_acl_api.cc", + "mock/mock_main_shim_acl_legacy_interface.cc", + "mock/mock_main_shim_btm_api.cc", + "mock/mock_main_shim_controller.cc", + "mock/mock_main_shim_distance_measurement_manager.cc", + "mock/mock_main_shim_hci_layer.cc", + "mock/mock_main_shim_l2cap_api.cc", + "mock/mock_main_shim_le_advertising_manager.cc", + "mock/mock_main_shim_le_scanning_manager.cc", + "mock/mock_main_shim_metric_id_api.cc", + "mock/mock_main_shim_metrics_api.cc", ], } @@ -333,6 +358,13 @@ filegroup { ], } +filegroup { + name: "TestMockJni", + srcs: [ + "mock/mock_jni*.cc", + ], +} + filegroup { name: "TestMockStackHid", srcs: [ @@ -568,3 +600,43 @@ cc_defaults { }, }, } + +cc_test { + name: "bluetooth_audio_hal_version_test", + local_include_dirs: ["common"], + defaults: [ + "latest_android_hardware_audio_common_ndk_static", + "latest_android_hardware_bluetooth_audio_ndk_static", + "latest_android_media_audio_common_types_ndk_static", + "mts_defaults", + ], + shared_libs: [ + "libbase", + "libbinder", + "libbinder_ndk", + "libchrome", + "libcutils", + "libhidlbase", + "liblog", + "libutils", + ], + include_dirs: ["packages/modules/Bluetooth/system"], + srcs: ["common/hal_version_manager_test.cc"], + static_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", + "libbt-audio-hal-interface", + ], + test_suites: ["general-tests"], + cflags: [ + "-Wall", + "-Werror", + "-Wextra", + ], + sanitize: { + address: true, + }, +} diff --git a/system/test/common/core_interface.cc b/system/test/common/core_interface.cc index c1998cc73bde04a2d6ccd034bfdc636f0c79cc36..e6da45c4dc3695823e29a05730095852bbaeef34 100644 --- a/system/test/common/core_interface.cc +++ b/system/test/common/core_interface.cc @@ -18,7 +18,7 @@ #include "btif/include/btif_common.h" #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" namespace { @@ -38,7 +38,8 @@ static bluetooth::core::EventCallbacks eventCallbacks = { .invoke_thread_evt_cb = invoke_thread_evt_cb, .invoke_le_test_mode_cb = invoke_le_test_mode_cb, .invoke_energy_info_cb = invoke_energy_info_cb, - .invoke_link_quality_report_cb = invoke_link_quality_report_cb}; + .invoke_link_quality_report_cb = invoke_link_quality_report_cb, + .invoke_key_missing_cb = invoke_key_missing_cb}; // This interface lets us query for configuration properties of the stack that // could change at runtime diff --git a/system/test/common/core_interface.h b/system/test/common/core_interface.h index 14490fa701c0bf4db139f7c5a103841eff049e82..96e38cad89ac473cb31491244ecd20b228d38ccf 100644 --- a/system/test/common/core_interface.h +++ b/system/test/common/core_interface.h @@ -14,9 +14,9 @@ * limitations under the License. */ -#include "btif/include/btif_common.h" +#include "bta/include/bta_api.h" #include "btif/include/core_callbacks.h" -#include "btif/include/stack_manager.h" +#include "types/raw_address.h" void InitializeCoreInterface(); void CleanCoreInterface(); diff --git a/system/test/common/hal_version_manager_test.cc b/system/test/common/hal_version_manager_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..936ca8e3f788a933d3eea77fe698c3c89134e34c --- /dev/null +++ b/system/test/common/hal_version_manager_test.cc @@ -0,0 +1,259 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_hal_interface/hal_version_manager.h" + +#include + +using bluetooth::audio::BluetoothAudioHalTransport; +using bluetooth::audio::BluetoothAudioHalVersion; +using bluetooth::audio::HalVersionManager; + +class BluetoothAudioHalVersionTest : public ::testing::Test {}; + +TEST_F(BluetoothAudioHalVersionTest, versionOperatorEqual) { + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_0 == + BluetoothAudioHalVersion::VERSION_2_0); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1 == + BluetoothAudioHalVersion::VERSION_2_1); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1 == + BluetoothAudioHalVersion::VERSION_AIDL_V1); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2 == + BluetoothAudioHalVersion::VERSION_AIDL_V2); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3 == + BluetoothAudioHalVersion::VERSION_AIDL_V3); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V4 == + BluetoothAudioHalVersion::VERSION_AIDL_V4); +} + +TEST_F(BluetoothAudioHalVersionTest, versionOperatorLessOrEqual) { + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_0 < + BluetoothAudioHalVersion::VERSION_2_1); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_0 <= + BluetoothAudioHalVersion::VERSION_2_1); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1 < + BluetoothAudioHalVersion::VERSION_AIDL_V1); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1 <= + BluetoothAudioHalVersion::VERSION_AIDL_V1); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1 < + BluetoothAudioHalVersion::VERSION_AIDL_V2); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1 <= + BluetoothAudioHalVersion::VERSION_AIDL_V2); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2 < + BluetoothAudioHalVersion::VERSION_AIDL_V3); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2 <= + BluetoothAudioHalVersion::VERSION_AIDL_V3); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3 < + BluetoothAudioHalVersion::VERSION_AIDL_V4); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3 <= + BluetoothAudioHalVersion::VERSION_AIDL_V4); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_1 < + BluetoothAudioHalVersion::VERSION_2_0); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_1 <= + BluetoothAudioHalVersion::VERSION_2_0); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V1 < + BluetoothAudioHalVersion::VERSION_2_1); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V1 <= + BluetoothAudioHalVersion::VERSION_2_1); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V2 < + BluetoothAudioHalVersion::VERSION_AIDL_V1); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V2 <= + BluetoothAudioHalVersion::VERSION_AIDL_V1); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V3 < + BluetoothAudioHalVersion::VERSION_AIDL_V2); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V3 <= + BluetoothAudioHalVersion::VERSION_AIDL_V2); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V4 < + BluetoothAudioHalVersion::VERSION_AIDL_V3); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V4 <= + BluetoothAudioHalVersion::VERSION_AIDL_V3); +} + +TEST_F(BluetoothAudioHalVersionTest, versionOperatorGreaterOrEqual) { + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1 > + BluetoothAudioHalVersion::VERSION_2_0); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1 >= + BluetoothAudioHalVersion::VERSION_2_0); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1 > + BluetoothAudioHalVersion::VERSION_2_1); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1 >= + BluetoothAudioHalVersion::VERSION_2_1); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2 > + BluetoothAudioHalVersion::VERSION_AIDL_V1); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2 >= + BluetoothAudioHalVersion::VERSION_AIDL_V1); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3 > + BluetoothAudioHalVersion::VERSION_AIDL_V2); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3 >= + BluetoothAudioHalVersion::VERSION_AIDL_V2); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V4 > + BluetoothAudioHalVersion::VERSION_AIDL_V3); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V4 >= + BluetoothAudioHalVersion::VERSION_AIDL_V3); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_0 > + BluetoothAudioHalVersion::VERSION_2_1); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_0 >= + BluetoothAudioHalVersion::VERSION_2_1); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_1 > + BluetoothAudioHalVersion::VERSION_AIDL_V1); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_1 >= + BluetoothAudioHalVersion::VERSION_AIDL_V1); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V1 > + BluetoothAudioHalVersion::VERSION_AIDL_V2); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V1 >= + BluetoothAudioHalVersion::VERSION_AIDL_V2); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V2 > + BluetoothAudioHalVersion::VERSION_AIDL_V3); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V2 >= + BluetoothAudioHalVersion::VERSION_AIDL_V3); + + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V3 > + BluetoothAudioHalVersion::VERSION_AIDL_V4); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V3 >= + BluetoothAudioHalVersion::VERSION_AIDL_V4); +} + +TEST_F(BluetoothAudioHalVersionTest, HIDL_VERSION_2_0) { + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_2_0, + BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 0)); + + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_2_0.getTransport(), + BluetoothAudioHalTransport::HIDL); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_0.isHIDL()); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_0.isAIDL()); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_0.toString().find( + "transport: HIDL") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_0.toString().find( + "major: 2") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_0.toString().find( + "minor: 0") != std::string::npos); +} + +TEST_F(BluetoothAudioHalVersionTest, HIDL_VERSION_2_1) { + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_2_1, + BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 1)); + + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_2_1.getTransport(), + BluetoothAudioHalTransport::HIDL); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1.isHIDL()); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_2_1.isAIDL()); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1.toString().find( + "transport: HIDL") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1.toString().find( + "major: 2") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_2_1.toString().find( + "minor: 1") != std::string::npos); +} + +TEST_F(BluetoothAudioHalVersionTest, AIDL_VERSIONS_V1) { + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V1, + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 1, 0)); + + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V1.getTransport(), + BluetoothAudioHalTransport::AIDL); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V1.isHIDL()); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1.isAIDL()); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1.toString().find( + "transport: AIDL") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1.toString().find( + "major: 1") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V1.toString().find( + "minor: 0") != std::string::npos); +} + +TEST_F(BluetoothAudioHalVersionTest, AIDL_VERSIONS_V2) { + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V2, + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 2, 0)); + + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V2.getTransport(), + BluetoothAudioHalTransport::AIDL); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V2.isHIDL()); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2.isAIDL()); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2.toString().find( + "transport: AIDL") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2.toString().find( + "major: 2") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V2.toString().find( + "minor: 0") != std::string::npos); +} + +TEST_F(BluetoothAudioHalVersionTest, AIDL_VERSIONS_V3) { + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V3, + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 3, 0)); + + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V3.getTransport(), + BluetoothAudioHalTransport::AIDL); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V3.isHIDL()); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3.isAIDL()); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3.toString().find( + "transport: AIDL") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3.toString().find( + "major: 3") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V3.toString().find( + "minor: 0") != std::string::npos); +} + +TEST_F(BluetoothAudioHalVersionTest, AIDL_VERSIONS_V4) { + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V4, + BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 4, 0)); + + EXPECT_EQ(BluetoothAudioHalVersion::VERSION_AIDL_V4.getTransport(), + BluetoothAudioHalTransport::AIDL); + EXPECT_FALSE(BluetoothAudioHalVersion::VERSION_AIDL_V4.isHIDL()); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V4.isAIDL()); + + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V4.toString().find( + "transport: AIDL") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V4.toString().find( + "major: 4") != std::string::npos); + EXPECT_TRUE(BluetoothAudioHalVersion::VERSION_AIDL_V4.toString().find( + "minor: 0") != std::string::npos); +} + +/** + * An example of future AIDL version (next one will be V5), we check that next + * AIDL version will be larger than existing AIDL versions + */ +TEST_F(BluetoothAudioHalVersionTest, AIDL_VERSIONS_Vx) { + EXPECT_TRUE(BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 5, 0) > + BluetoothAudioHalVersion::VERSION_AIDL_V4); + EXPECT_FALSE(BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 5, 0) + .isHIDL()); + EXPECT_TRUE(BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 5, 0) + .isAIDL()); +} diff --git a/system/test/common/init_flags.cc b/system/test/common/init_flags.cc index c3618d7a9fcd1acc217ec76032f4e3a7ff865558..bb2d7ad2e157ae2d2d2f1234eec389cec33da8d3 100644 --- a/system/test/common/init_flags.cc +++ b/system/test/common/init_flags.cc @@ -1,10 +1,10 @@ +#include "common/init_flags.h" + #include #include -#include "gd/common/init_flags.h" - namespace bluetooth { namespace common { diff --git a/system/test/common/jni_thread.cc b/system/test/common/jni_thread.cc index 8216671445a41e3b49885e3e389427d94cdb8fa5..720e6ddc2172be2833dc57f29548bca6de7cef76 100644 --- a/system/test/common/jni_thread.cc +++ b/system/test/common/jni_thread.cc @@ -20,7 +20,7 @@ #include -#include "osi/include/log.h" +#include "os/log.h" std::queue do_in_jni_thread_task_queue; diff --git a/system/test/common/main_handler.cc b/system/test/common/main_handler.cc index af7cc06efacad78bceae245184dec86ab39bceba..a1c2f1a9bae3735bc3fdd23f84f4c1f1d2b14784 100644 --- a/system/test/common/main_handler.cc +++ b/system/test/common/main_handler.cc @@ -17,15 +17,15 @@ #include #include #include -#include #include #include + #include #include #include "common/message_loop_thread.h" #include "include/hardware/bluetooth.h" -#include "osi/include/log.h" +#include "os/log.h" using bluetooth::common::MessageLoopThread; using BtMainClosure = std::function; @@ -46,7 +46,7 @@ bt_status_t do_in_main_thread(const base::Location& from_here, bt_status_t do_in_main_thread_delayed(const base::Location& from_here, base::OnceClosure task, - const base::TimeDelta& delay) { + std::chrono::microseconds delay) { ASSERT_LOG(!main_thread.DoInThreadDelayed(from_here, std::move(task), delay), "Unable to run on main thread delayed"); return BT_STATUS_SUCCESS; diff --git a/system/test/common/main_handler.h b/system/test/common/main_handler.h index 9719fa4a5c08e09a1f3bd080d2f5d1b442cc732b..07fc190f217fead994a30e05a967321267a94a68 100644 --- a/system/test/common/main_handler.h +++ b/system/test/common/main_handler.h @@ -18,10 +18,11 @@ #include #include -#include + #include #include "common/message_loop_thread.h" +#include "include/hardware/bluetooth.h" using bluetooth::common::MessageLoopThread; using BtMainClosure = std::function; @@ -30,10 +31,10 @@ bt_status_t do_in_main_thread(const base::Location& from_here, base::OnceClosure task); bt_status_t do_in_main_thread_delayed(const base::Location& from_here, base::OnceClosure task, - const base::TimeDelta& delay); + std::chrono::microseconds delay); void post_on_bt_main(BtMainClosure closure); void main_thread_start_up(); void main_thread_shut_down(); -extern int sync_timeout_in_ms; +extern const int sync_timeout_in_ms; void sync_main_handler(); bluetooth::common::MessageLoopThread* get_main_thread(); diff --git a/system/test/common/mock_functions.cc b/system/test/common/mock_functions.cc index 776cf1d4a4e3d049d230472345447dd1be83f4b2..638d5b32fd6ed7ba3e7a194a7a29e5386afa5b91 100644 --- a/system/test/common/mock_functions.cc +++ b/system/test/common/mock_functions.cc @@ -18,7 +18,7 @@ #include -#include "osi/include/log.h" +#include "os/log.h" static std::map& _get_func_call_count_map() { static std::map mock_function_count_map; diff --git a/system/test/fake/fake_looper.cc b/system/test/fake/fake_looper.cc index 582fe124b11c5d10c5bfbf7ca2d8b2106f984ea8..a9ea6064c4727e94967ee95d83762ed85dd7d9b3 100644 --- a/system/test/fake/fake_looper.cc +++ b/system/test/fake/fake_looper.cc @@ -26,8 +26,8 @@ #include #include +#include "os/log.h" #include "osi/include/allocator.h" -#include "osi/include/log.h" #include "test/fake/fake_thread.h" pid_t get_thread_id() { diff --git a/system/test/fake/fake_osi.cc b/system/test/fake/fake_osi.cc index 2b2a79d12119cbc935989194c7118b64a5ad4023..c1b4da181e1de97b9ae09359dc17cedabeaa695f 100644 --- a/system/test/fake/fake_osi.cc +++ b/system/test/fake/fake_osi.cc @@ -15,6 +15,7 @@ */ #include "test/fake/fake_osi.h" +#include "include/check.h" #include "test/mock/mock_osi_alarm.h" #include "test/mock/mock_osi_allocator.h" #include "test/mock/mock_osi_fixed_queue.h" @@ -25,7 +26,7 @@ struct alarm_t { alarm_callback_t cb; void* data; - alarm_t(const char* name) { + alarm_t(const char* /* name */) { cb = nullptr; data = nullptr; }; @@ -91,7 +92,7 @@ FakeOsi::FakeOsi() { }; test::mock::osi_alarm::alarm_set_on_mloop.body = - [](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, + [](alarm_t* alarm, uint64_t /* interval_ms */, alarm_callback_t cb, void* data) { alarm->cb = cb; alarm->data = data; @@ -332,34 +333,34 @@ FakeOsi::FakeOsi() { [](fixed_queue_t* q) { return q ? q->list_ : nullptr; }; test::mock::osi_fixed_queue::fixed_queue_try_remove_from_queue.body = - [](fixed_queue_t* q, void* data) { + [](fixed_queue_t* /* q */, void* /* data */) { // not implemented abort(); return nullptr; }; test::mock::osi_fixed_queue::fixed_queue_get_enqueue_fd.body = - [](const fixed_queue_t* q) { + [](const fixed_queue_t* /* q */) { // not implemented abort(); return 0; }; test::mock::osi_fixed_queue::fixed_queue_get_dequeue_fd.body = - [](const fixed_queue_t* q) { + [](const fixed_queue_t* /* q */) { // not implemented abort(); return 0; }; test::mock::osi_fixed_queue::fixed_queue_register_dequeue.body = - [](fixed_queue_t* q, reactor_t* reactor, fixed_queue_cb ready_cb, - void* context) { + [](fixed_queue_t* /* q */, reactor_t* /* reactor */, + fixed_queue_cb /* ready_cb */, void* /* context */) { // not implemented abort(); }; test::mock::osi_fixed_queue::fixed_queue_unregister_dequeue.body = - [](fixed_queue_t* q) { + [](fixed_queue_t* /* q */) { // not implemented abort(); }; diff --git a/system/test/headless/Android.bp b/system/test/headless/Android.bp index ce9dcd47e5a8a065a840199e29d360a64ae37205..5903b4b960f674f01e2a02bb0833547021267e68 100644 --- a/system/test/headless/Android.bp +++ b/system/test/headless/Android.bp @@ -26,9 +26,12 @@ genrule { cc_binary { name: "bt_headless", + host_supported: true, defaults: [ "fluoride_defaults", - "latest_android_hardware_bluetooth_audio_ndk_shared", + "latest_android_hardware_audio_common_ndk_static", + "latest_android_hardware_bluetooth_audio_ndk_static", + "latest_android_media_audio_common_types_ndk_static", ], cflags: [ "-Wall", @@ -40,7 +43,8 @@ cc_binary { "HeadlessBuildTimestamp", ], srcs: [ - "bt_property.cc", + "adapter/adapter.cc", + "bt_stack_info.cc", "connect/connect.cc", "discovery/discovery.cc", "dumpsys/dumpsys.cc", @@ -50,6 +54,7 @@ cc_binary { "log.cc", "main.cc", "messenger.cc", + "mode/mode.cc", "nop/nop.cc", "pairing/pairing.cc", "property.cc", @@ -58,34 +63,43 @@ cc_binary { "scan/scan.cc", "sdp/sdp.cc", "sdp/sdp_db.cc", + "text.cc", "util.cc", ], include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", + "packages/modules/Bluetooth/system/include", "packages/modules/Bluetooth/system/stack/include", ], static_libs: [ + "android.hardware.audio.common@5.0", "android.hardware.bluetooth.a2dp@1.0", - "android.system.suspend.control-V1-ndk", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", "avrcp-target-service", "lib-bt-packets", "lib-bt-packets-avrcp", "lib-bt-packets-base", "libFraunhoferAAC", "libaudio-a2dp-hw-utils", + "libbase", "libbluetooth-dumpsys", + "libbluetooth-gdx", "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_log", "libbluetooth_rust_interop", + "libbt-audio-asrc", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", "libbt-btu-main-thread", "libbt-common", "libbt-hci", + "libbt-jni-thread", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", @@ -101,6 +115,7 @@ cc_binary { "libchrome", "libevent", "libflatbuffers-cpp", + "libfmq", "libg722codec", "liblc3", "libmodpb64", @@ -112,24 +127,39 @@ cc_binary { "libz", ], shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", - "android.hardware.bluetooth@1.0", - "android.hardware.bluetooth@1.1", - "android.system.suspend-V1-ndk", "libPlatformProperties", - "libaaudio", - "libbase", - "libbinder_ndk", "libcrypto", "libcutils", // property_get_bool - "libfmq", "libhidlbase", "libjsoncpp", "liblog", // __android_log_print - "libstatssocket", "libutils", "server_configurable_flags", ], header_libs: ["libbluetooth_headers"], + target: { + android: { + static_libs: [ + "android.hardware.bluetooth.audio-V4-ndk", + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "android.hardware.bluetooth@1.0", + "android.hardware.bluetooth@1.1", + "android.system.suspend.control-V1-ndk", + ], + shared_libs: [ + "android.system.suspend-V1-ndk", + "libaaudio", + "libbinder_ndk", + "libstatssocket", + ], + }, + host: { + static_libs: [ + "android.hardware.bluetooth.audio@2.0", + "android.hardware.bluetooth.audio@2.1", + "libbinder_ndk", + ], + }, + }, } diff --git a/system/test/headless/adapter/adapter.cc b/system/test/headless/adapter/adapter.cc new file mode 100644 index 0000000000000000000000000000000000000000..7de75c7a4b51bccfcead97d0e31caf1032e92d25 --- /dev/null +++ b/system/test/headless/adapter/adapter.cc @@ -0,0 +1,90 @@ +/* + * Copyright 2023 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 "bt_headless_scan" + +#include "test/headless/adapter/adapter.h" + +#include "base/logging.h" // LOG() stdout and android log +#include "gd/os/log.h" +#include "test/headless/headless.h" +#include "test/headless/interface.h" +#include "test/headless/log.h" +#include "test/headless/messenger.h" +#include "test/headless/stopwatch.h" + +using namespace bluetooth::test; +using namespace std::chrono_literals; + +namespace { + +unsigned kTimeoutMs = 5000; + +int get_adapter_info([[maybe_unused]] unsigned int num_loops) { + LOG(INFO) << "Started Device Adapter Properties"; + + ASSERT(bluetoothInterface.get_adapter_properties() == BT_STATUS_SUCCESS); + LOG_CONSOLE("Started get adapter properties"); + + headless::messenger::Context context{ + .stop_watch = Stopwatch(__func__), + .timeout = 1s, // Poll time + .check_point = {}, + .callbacks = {Callback::AdapterProperties}, + }; + + bool adapter_properties_found = false; + while (context.stop_watch.LapMs() < kTimeoutMs) { + // If we have received callback results within this timeframe... + if (headless::messenger::await_callback(context)) { + while (!context.callback_ready_q.empty()) { + std::shared_ptr p = context.callback_ready_q.front(); + context.callback_ready_q.pop_front(); + switch (p->CallbackType()) { + case Callback::AdapterProperties: { + adapter_properties_params_t* q = + static_cast(p.get()); + for (const auto& p2 : q->properties()) { + LOG_CONSOLE(" %s prop:%s", p->Name().c_str(), + p2->ToString().c_str()); + } + adapter_properties_found = true; + } break; + default: + LOG_CONSOLE("WARN Received callback for unasked:%s", + p->Name().c_str()); + break; + } + } + } + if (adapter_properties_found) break; + } + + LOG_CONSOLE("Retrieved adapter properties"); + return 0; +} + +} // namespace + +int bluetooth::test::headless::Adapter::Run() { + if (options_.loop_ < 1) { + LOG_CONSOLE("This test requires at least a single loop"); + options_.Usage(); + return -1; + } + return RunOnHeadlessStack( + [this]() { return get_adapter_info(options_.loop_); }); +} diff --git a/system/test/headless/adapter/adapter.h b/system/test/headless/adapter/adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..b6b7e1c2a77a84d36097c4b6d1b108c926f3ae21 --- /dev/null +++ b/system/test/headless/adapter/adapter.h @@ -0,0 +1,37 @@ +/* + * Copyright 2023 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 "test/headless/get_options.h" +#include "test/headless/headless.h" + +namespace bluetooth { +namespace test { +namespace headless { + +class Adapter : public HeadlessTest { + public: + Adapter(const bluetooth::test::headless::GetOpt& options) + : HeadlessTest(options) {} + virtual ~Adapter() = default; + + int Run() override; +}; + +} // namespace headless +} // namespace test +} // namespace bluetooth diff --git a/system/test/headless/android_namespace.cc b/system/test/headless/android_namespace.cc new file mode 100644 index 0000000000000000000000000000000000000000..4d4a1b11657fcdfaefa648543dc16fe455f0c875 --- /dev/null +++ b/system/test/headless/android_namespace.cc @@ -0,0 +1,21 @@ +/* + * Copyright 2023 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. + */ + +extern "C" { +struct android_namespace_t* android_get_exported_namespace(const char*) { + return nullptr; +} +} // "C" diff --git a/system/test/headless/bt_property.cc b/system/test/headless/bt_property.cc deleted file mode 100644 index 5b6c2d53978da514b756c7c297adca3cb11eac85..0000000000000000000000000000000000000000 --- a/system/test/headless/bt_property.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 "bt_headless_property" - -#include "test/headless/bt_property.h" - -#include "base/logging.h" // LOG() stdout and android log -#include "btif/include/btif_api.h" -#include "osi/include/log.h" // android log only -#include "stack/include/sdp_api.h" -#include "test/headless/get_options.h" -#include "test/headless/headless.h" -#include "test/headless/interface.h" -#include "test/headless/log.h" -#include "test/headless/sdp/sdp.h" -#include "test/headless/stopwatch.h" -#include "types/bluetooth/uuid.h" -#include "types/raw_address.h" - -using namespace bluetooth::test::headless; -using namespace std::chrono_literals; - -namespace bluetooth { -namespace test { -namespace headless { - -void process_property(const RawAddress& bd_addr, const bt_property_t* prop) { - LOG_INFO("%s bt_property type:%d len:%d val:%p", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), prop->type, - prop->len, prop->val); - switch (prop->type) { - case BT_PROPERTY_BDNAME: { - ASSERT(prop->len >= 0); - std::string name(static_cast(prop->val), - static_cast(prop->len)); - LOG_CONSOLE("BT_PROPERTY_BDNAME NAME:%s", name.c_str()); - } break; - case BT_PROPERTY_BDADDR: - LOG_CONSOLE("BT_PROPERTY_BDADDR"); - break; - case BT_PROPERTY_UUIDS: { - const size_t remainder = prop->len % sizeof(bluetooth::Uuid); - ASSERT(remainder == 0); - bluetooth::Uuid* uuid = reinterpret_cast(prop->val); - for (int len = prop->len; len > 0; len -= sizeof(*uuid)) { - LOG_CONSOLE("BT_PROPERTY_UUIDS UUID:%s", uuid->ToString().c_str()); - uuid++; - } - } break; - case BT_PROPERTY_CLASS_OF_DEVICE: { - ASSERT(prop->len == 4); - uint32_t cod = *(reinterpret_cast(prop->val)); - LOG_CONSOLE("BT_PROPERTY_CLASS_OF_DEVICE 0x%04x", cod); - } break; - case BT_PROPERTY_TYPE_OF_DEVICE: { - ASSERT(prop->len == 4); - uint32_t devtype = *(reinterpret_cast(prop->val)); - LOG_CONSOLE("BT_PROPERTY_TYPE_OF_DEVICE 0x%04x", devtype); - } break; - case BT_PROPERTY_SERVICE_RECORD: - LOG_CONSOLE("BT_PROPERTY_SERVICE_RECORD"); - break; - case BT_PROPERTY_ADAPTER_SCAN_MODE: - LOG_CONSOLE("BT_PROPERTY_ADAPTER_SCAN_MODE"); - break; - case BT_PROPERTY_ADAPTER_BONDED_DEVICES: - LOG_CONSOLE("BT_PROPERTY_ADAPTER_BONDED_DEVICES"); - break; - case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT: - LOG_CONSOLE("BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT"); - break; - case BT_PROPERTY_REMOTE_FRIENDLY_NAME: - LOG_CONSOLE("BT_PROPERTY_REMOTE_FRIENDLY_NAME"); - break; - case BT_PROPERTY_REMOTE_RSSI: - LOG_CONSOLE("BT_PROPERTY_REMOTE_RSSI"); - break; - case BT_PROPERTY_REMOTE_VERSION_INFO: - LOG_CONSOLE("BT_PROPERTY_REMOTE_VERSION_INFO"); - break; - case BT_PROPERTY_LOCAL_LE_FEATURES: - LOG_CONSOLE("BT_PROPERTY_LOCAL_LE_FEATURES"); - break; - case BT_PROPERTY_LOCAL_IO_CAPS: - LOG_CONSOLE("BT_PROPERTY_LOCAL_IO_CAPS"); - break; - case BT_PROPERTY_DYNAMIC_AUDIO_BUFFER: - LOG_CONSOLE("BT_PROPERTY_DYNAMIC_AUDIO_BUFFER"); - break; - case BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER: - LOG_CONSOLE("BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER"); - break; - case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: - LOG_CONSOLE("BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER"); - break; - default: { - LOG_CONSOLE("Unable to find BT property bd_addr:%s type:%d ptr:%p", - ADDRESS_TO_LOGGABLE_CSTR(bd_addr), prop->type, prop); - const uint8_t* p = reinterpret_cast(prop); - for (size_t i = 0; i < sizeof(bt_property_t); i++, p++) { - LOG_CONSOLE(" %p:0x%02x", p, *p); - } - } break; - } -} - -} // namespace headless -} // namespace test -} // namespace bluetooth diff --git a/system/test/headless/bt_property.h b/system/test/headless/bt_property.h index 75cbd0c9b6aef586d08f6b4df9515d1426e09acd..cfec58892991cf1f7115f8f7b00423515feba715 100644 --- a/system/test/headless/bt_property.h +++ b/system/test/headless/bt_property.h @@ -9,6 +9,8 @@ namespace test { namespace headless { void process_property(const RawAddress& bd_addr, const bt_property_t* prop); -} +void process_property2(const bt_property_t* prop); + +} // namespace headless } // namespace test } // namespace bluetooth diff --git a/system/test/headless/bt_stack_info.cc b/system/test/headless/bt_stack_info.cc new file mode 100644 index 0000000000000000000000000000000000000000..943ab03d724f6f33aa34180774f1ef0c948ba98b --- /dev/null +++ b/system/test/headless/bt_stack_info.cc @@ -0,0 +1,65 @@ +/* + * Copyright 2023 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 "test/headless/bt_stack_info.h" + +#include + +#include "btif/include/btif_common.h" // do_in_jni_thread +#include "btif/include/btif_hh.h" // DumpsysHid +#include "main/shim/dumpsys.h" +#include "stack/gatt/connection_manager.h" +#include "stack/include/main_thread.h" +#include "stack/include/pan_api.h" // PAN_Dumpsys +#include "test/headless/log.h" + +BtStackInfo::BtStackInfo() { + { + std::promise promise; + auto future = promise.get_future(); + do_in_main_thread(FROM_HERE, base::BindOnce( + [](std::promise promise) { + promise.set_value(getpid()); + }, + std::move(promise))); + main_pid_ = future.get(); + } + + { + std::promise promise; + auto future = promise.get_future(); + do_in_jni_thread(FROM_HERE, base::BindOnce( + [](std::promise promise) { + promise.set_value(getpid()); + }, + std::move(promise))); + jni_pid_ = future.get(); + } +} + +void BtStackInfo::DumpsysLite() { + LOG_CONSOLE("main_pid:%u", main_pid_); + LOG_CONSOLE("jni_pid:%u", jni_pid_); + + int fd = STDIN_FILENO; + const char** arguments = nullptr; + + connection_manager::dump(fd); + PAN_Dumpsys(fd); + DumpsysHid(fd); + DumpsysBtaDm(fd); + bluetooth::shim::Dump(fd, arguments); +} diff --git a/system/test/headless/bt_stack_info.h b/system/test/headless/bt_stack_info.h new file mode 100644 index 0000000000000000000000000000000000000000..19afe0d2c10d54d2b061d93ff59e796911748bce --- /dev/null +++ b/system/test/headless/bt_stack_info.h @@ -0,0 +1,33 @@ +/* + * Copyright 2023 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 + +class BtStackInfo { + public: + BtStackInfo(); + + void DumpsysLite(); + + pid_t MainPid() const { return main_pid_; } + pid_t JniPid() const { return jni_pid_; } + + private: + pid_t main_pid_; + pid_t jni_pid_; +}; diff --git a/system/test/headless/config.cc b/system/test/headless/config.cc new file mode 100644 index 0000000000000000000000000000000000000000..10cb1b0fbf17cdc528f5231f124a2d9024a77a5d --- /dev/null +++ b/system/test/headless/config.cc @@ -0,0 +1,32 @@ +/* + * Copyright 2023 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 "bt_config" + +#include "gd/hal/snoop_logger.h" +#include "test/headless/log.h" + +using namespace bluetooth::hal; + +class Config { + Config(){}; + + void Help() const { + // setprop persist.bluetooth.btsnoopdefaultmode full + LOG_CONSOLE("Flag: %s", SnoopLogger::kBtSnoopLogPersists.c_str()); + // setprop persist.bluetooth.btsnooplogpersists 1 + } +}; diff --git a/system/test/headless/connect/connect.cc b/system/test/headless/connect/connect.cc index f19ce6f4df47e4d6246bc861e602e3824f16c44f..415501f441fb6112626e1499a2ab239972f79641 100644 --- a/system/test/headless/connect/connect.cc +++ b/system/test/headless/connect/connect.cc @@ -16,53 +16,39 @@ #define LOG_TAG "bt_headless_mode" +#include "test/headless/connect/connect.h" + #include + #include #include #include #include -#include #include #include "base/logging.h" // LOG() stdout and android log -#include "btif/include/stack_manager.h" -#include "osi/include/log.h" // android log only +#include "btif/include/stack_manager_t.h" +#include "os/log.h" // android log only +#include "stack/include/acl_api.h" #include "stack/include/btm_api.h" #include "stack/include/btm_api_types.h" #include "stack/include/hci_error_code.h" #include "stack/include/l2cap_acl_interface.h" -#include "test/headless/connect/connect.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" #include "test/headless/interface.h" +#include "test/headless/messenger.h" #include "types/raw_address.h" -const stack_manager_t* stack_manager_get_interface(); - -void power_mode_callback([[maybe_unused]] const RawAddress& p_bda, - [[maybe_unused]] tBTM_PM_STATUS status, - [[maybe_unused]] uint16_t value, - [[maybe_unused]] tHCI_STATUS hci_status) { - fprintf(stdout, "Got callback\n"); -}; +using namespace bluetooth::test; +using namespace std::chrono_literals; -namespace connect { -std::promise acl_state_changed_promise; - -} // namespace connect - -void callback_interface(callback_data_t* data) { - if (data->Name() == "acl_state_changed") { - LOG(INFO) << "Received acl state changed discovery"; - auto params = static_cast(data); - acl_state_changed_params_t p(*params); - connect::acl_state_changed_promise.set_value(p); - } - LOG(ERROR) << "Received unexpected interface callback"; -} +const stack_manager_t* stack_manager_get_interface(); namespace { +bool f_simulate_stack_crash = false; + int do_connect([[maybe_unused]] unsigned int num_loops, [[maybe_unused]] const RawAddress& bd_addr, [[maybe_unused]] std::list options) { @@ -78,49 +64,91 @@ int do_connect([[maybe_unused]] unsigned int num_loops, } ASSERT_LOG(disconnect_wait_time >= 0, "Time cannot go backwards"); - headless_add_callback("acl_state_changed", callback_interface); - - connect::acl_state_changed_promise = - std::promise(); - auto future = connect::acl_state_changed_promise.get_future(); + headless::messenger::Context context{ + .stop_watch = Stopwatch("Connect_timeout"), + .timeout = 3s, + .check_point = {}, + .callbacks = {Callback::AclStateChanged}, + }; - fprintf(stdout, "Creating connection to:%s\n", bd_addr.ToString().c_str()); + LOG_CONSOLE("Creating connection to:%s", bd_addr.ToString().c_str()); LOG(INFO) << "Creating classic connection to " << bd_addr.ToString(); acl_create_classic_connection(bd_addr, false, false); - auto result = future.get(); - LOG_CONSOLE("Connected created %s", result.ToString().c_str()); + std::shared_ptr acl{nullptr}; + while (context.stop_watch.LapMs() < 10000) { + // If we have received callback results within this timeframe... + if (headless::messenger::await_callback(context)) { + while (!context.callback_ready_q.empty()) { + std::shared_ptr p = context.callback_ready_q.front(); + context.callback_ready_q.pop_front(); + switch (p->CallbackType()) { + case Callback::AclStateChanged: { + acl = p; + } break; + default: + LOG_CONSOLE("WARN Received callback for unasked:%s", + p->Name().c_str()); + break; + } + } + } + if (acl != nullptr) break; + } - connect::acl_state_changed_promise = - std::promise(); - future = connect::acl_state_changed_promise.get_future(); + if (acl != nullptr) { + LOG_CONSOLE("Acl state changed:%s", acl->ToString().c_str()); + } uint64_t connect = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count(); - fprintf(stdout, "Just crushing stack\n"); - LOG(INFO) << "Just crushing stack"; - bluetoothInterface.disable(); + if (f_simulate_stack_crash) { + LOG_CONSOLE("Just crushing stack"); + LOG(INFO) << "Just crushing stack"; + bluetoothInterface.disable(); + } + std::shared_ptr acl2{nullptr}; if (disconnect_wait_time == 0) { - fprintf(stdout, "Waiting to disconnect from supervision timeout\n"); - auto result = future.get(); + LOG_CONSOLE("Waiting to disconnect from supervision timeout\n"); + while (context.stop_watch.LapMs() < 10000) { + // If we have received callback results within this timeframe... + if (headless::messenger::await_callback(context)) { + while (!context.callback_ready_q.empty()) { + std::shared_ptr p = + context.callback_ready_q.front(); + context.callback_ready_q.pop_front(); + switch (p->CallbackType()) { + case Callback::AclStateChanged: { + acl2 = p; + } break; + default: + LOG_CONSOLE("WARN Received callback for unasked:%s", + p->Name().c_str()); + break; + } + } + } + if (acl2 != nullptr) break; + } uint64_t disconnect = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count(); - LOG_CONSOLE("Disconnected after:%" PRId64 "ms from:%s result:%s[%u]\n", + LOG_CONSOLE("Disconnected after:%" PRId64 "ms from:%s acl:%s", disconnect - connect, bd_addr.ToString().c_str(), - bt_status_text(result.status).c_str(), result.status); - headless_remove_callback("acl_state_changed", callback_interface); - } else { - fprintf(stdout, "Waiting %d seconds to just shutdown\n", - disconnect_wait_time); - bluetoothInterface.dump(1, nullptr); - bluetoothInterface.cleanup(); + acl->ToString().c_str()); } + + acl_disconnect_from_handle( + ((acl_state_changed_params_t*)(acl2.get()))->acl_handle, HCI_SUCCESS, + "BT headless disconnect"); + + sleep(3); + return 0; } diff --git a/system/test/headless/discovery/discovery.cc b/system/test/headless/discovery/discovery.cc index 7faf81ca4871c529bd3ae88249816b5900a1a105..a9742673d7be0e9ae4cfb8db032b0d604acd0fb6 100644 --- a/system/test/headless/discovery/discovery.cc +++ b/system/test/headless/discovery/discovery.cc @@ -22,7 +22,7 @@ #include "base/logging.h" // LOG() stdout and android log #include "btif/include/btif_api.h" -#include "osi/include/log.h" // android log only +#include "os/log.h" // android log only #include "stack/include/sdp_api.h" #include "test/headless/bt_property.h" #include "test/headless/get_options.h" @@ -48,113 +48,7 @@ int start_discovery([[maybe_unused]] unsigned int num_loops, Stopwatch acl_stopwatch("ACL_connection"); Stopwatch sdp_stopwatch("SDP_discovery"); - LOG_CONSOLE("Started service discovery"); - auto check_point = messenger::sdp::get_check_point(); - ASSERT(bluetoothInterface.get_remote_services(&bd_addr, 0) == - BT_STATUS_SUCCESS); - - if (!messenger::acl::await_connected(8s)) { - LOG_CONSOLE("TIMEOUT waiting for connection to %s", - raw_address.ToString().c_str()); - return -1; - } - LOG_CONSOLE("ACL connected to %s :%sms", STR(raw_address), - STR(acl_stopwatch)); - - if (!messenger::sdp::await_service_discovery(8s, check_point, 1UL)) { - LOG_CONSOLE("TIMEOUT waiting for service discovery to %s", - raw_address.ToString().c_str()); - return -1; - } - auto callback_queue = messenger::sdp::collect_from(check_point); - ASSERT_LOG(callback_queue.size() == 1, - "Received unexpected number of SDP queries"); - - auto params = callback_queue.front(); - callback_queue.pop_front(); - - LOG_CONSOLE("got remote services :%s", params.ToString().c_str()); - - for (int i = 0; i < params.num_properties; i++) { - process_property(params.bd_addr, params.properties + i); - } - - // Run a second fetch SDP - { - LOG_CONSOLE("Sending second SDP request"); - auto check_point = messenger::sdp::get_check_point(); - - ASSERT(bluetoothInterface.get_remote_services(&bd_addr, 0) == - BT_STATUS_SUCCESS); - - if (!messenger::acl::await_connected(8s)) { - LOG_CONSOLE("TIMEOUT waiting for connection to %s", - raw_address.ToString().c_str()); - return -1; - } - LOG_CONSOLE("ACL connected to %s :%sms", STR(raw_address), - STR(acl_stopwatch)); - - if (!messenger::sdp::await_service_discovery(8s, check_point, 1UL)) { - LOG_CONSOLE("TIMEOUT waiting for service discovery to %s", - raw_address.ToString().c_str()); - return -1; - } - auto callback_queue = messenger::sdp::collect_from(check_point); - ASSERT_LOG(callback_queue.size() == 1, - "Received unexpected number of SDP queries"); - - auto params = callback_queue.front(); - callback_queue.pop_front(); - - LOG_CONSOLE("got remote services :%s", params.ToString().c_str()); - - for (int i = 0; i < params.num_properties; i++) { - process_property(params.bd_addr, params.properties + i); - } - } - - // Run a third fetch SDP - { - LOG_CONSOLE("Sending third SDP request"); - auto check_point = messenger::sdp::get_check_point(); - - ASSERT(bluetoothInterface.get_remote_services(&bd_addr, 0) == - BT_STATUS_SUCCESS); - - if (!messenger::acl::await_connected(8s)) { - LOG_CONSOLE("TIMEOUT waiting for connection to %s", - raw_address.ToString().c_str()); - return -1; - } - LOG_CONSOLE("ACL connected to %s :%sms", STR(raw_address), - STR(acl_stopwatch)); - - if (!messenger::sdp::await_service_discovery(8s, check_point, 1UL)) { - LOG_CONSOLE("TIMEOUT waiting for service discovery to %s", - raw_address.ToString().c_str()); - return -1; - } - auto callback_queue = messenger::sdp::collect_from(check_point); - ASSERT_LOG(callback_queue.size() == 1, - "Received unexpected number of SDP queries"); - - auto params = callback_queue.front(); - callback_queue.pop_front(); - - LOG_CONSOLE("got remote services :%s", params.ToString().c_str()); - - for (int i = 0; i < params.num_properties; i++) { - process_property(params.bd_addr, params.properties + i); - } - } - - LOG_CONSOLE("Awaiting disconnect"); - if (!messenger::acl::await_disconnected(6s)) { - LOG_CONSOLE("TIMEOUT waiting for disconnection to %s", - raw_address.ToString().c_str()); - return -1; - } + LOG_CONSOLE("Started service discovery %s", bd_addr.ToString().c_str()); LOG_CONSOLE("Dumpsys system"); bluetoothInterface.dump(2, nullptr); diff --git a/system/test/headless/dumpsys/dumpsys.cc b/system/test/headless/dumpsys/dumpsys.cc index 33737ecb64e791505315a74b47fcbbe214b12511..0de639ce43b96ce41cce06e88db84f3fbb08b9ae 100644 --- a/system/test/headless/dumpsys/dumpsys.cc +++ b/system/test/headless/dumpsys/dumpsys.cc @@ -16,14 +16,15 @@ #define LOG_TAG "bt_headless_sdp" +#include "test/headless/dumpsys/dumpsys.h" + #include -#include "base/logging.h" // LOG() stdout and android log -#include "osi/include/log.h" // android log only +#include "base/logging.h" // LOG() stdout and android log +#include "os/log.h" // android log only #include "stack/include/btm_api.h" #include "stack/include/btm_api_types.h" #include "stack/include/hci_error_code.h" -#include "test/headless/dumpsys/dumpsys.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" #include "types/raw_address.h" diff --git a/system/test/headless/get_options.cc b/system/test/headless/get_options.cc index 3cf6898414ac7f0c24f1955b283595ce2909f9b5..213564bc48832c61b29cbfcab581a5944cd6f6f2 100644 --- a/system/test/headless/get_options.cc +++ b/system/test/headless/get_options.cc @@ -24,7 +24,8 @@ #include #include -#include "gd/os/log.h" +#include "include/check.h" +#include "os/log.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" diff --git a/system/test/headless/get_options.h b/system/test/headless/get_options.h index 321ac82bb4980ae1276985718d9d0e4cbda19ebf..d541fb7f65c531fbf7063dc6c37a874776eab9a6 100644 --- a/system/test/headless/get_options.h +++ b/system/test/headless/get_options.h @@ -16,9 +16,10 @@ #pragma once -#include #include #include +#include + #include "types/bluetooth/uuid.h" #include "types/raw_address.h" diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc index 6d1f476e2abc8c529e0a5aa66672517a76191d01..e364803cfd656be8e9850cf5d19bd3b3e2a28e42 100644 --- a/system/test/headless/headless.cc +++ b/system/test/headless/headless.cc @@ -20,19 +20,23 @@ #include // dlopen -#include #include #include +#include #include "base/logging.h" // LOG() stdout and android log +#include "gd/os/log.h" +#include "include/check.h" #include "include/hardware/bluetooth.h" -#include "internal_include/bt_trace.h" -#include "osi/include/log.h" // android log only -#include "test/headless/get_options.h" +#include "test/headless/bt_stack_info.h" #include "test/headless/interface.h" #include "test/headless/log.h" +#include "test/headless/messenger.h" #include "types/raw_address.h" +// +// Aggregate disparate variables from callback API into unified single structure +// extern bt_interface_t bluetoothInterface; using namespace bluetooth::test::headless; @@ -56,14 +60,13 @@ void headless_add_callback(const std::string interface_name, interface_api_callback_map_[interface_name].push_back(function); } -void headless_remove_callback(const std::string interface_name, - callback_function_t function) { +void headless_remove_callback(const std::string interface_name) { if (interface_api_callback_map_.find(interface_name) == interface_api_callback_map_.end()) { ASSERT_LOG(false, "No callbacks registered for interface:%s", interface_name.c_str()); } - interface_api_callback_map_[interface_name].remove(function); + interface_api_callback_map_.erase(interface_name); } std::mutex adapter_state_mutex_; @@ -75,10 +78,21 @@ void adapter_state_changed(bt_state_t state) { bt_state_ = state; adapter_state_cv_.notify_all(); } -void adapter_properties([[maybe_unused]] bt_status_t status, - [[maybe_unused]] int num_properties, - [[maybe_unused]] ::bt_property_t* properties) { - LOG_INFO("%s", __func__); +void adapter_properties(bt_status_t status, int num_properties, + ::bt_property_t* properties) { + const size_t num_callbacks = interface_api_callback_map_.size(); + auto callback_list = interface_api_callback_map_.find(__func__); + if (callback_list != interface_api_callback_map_.end()) { + for (auto callback : callback_list->second) { + adapter_properties_params_t params(status, num_properties, properties); + (callback)(¶ms); + } + } + LOG_INFO( + "num_callbacks:%zu status:%s num_properties:%d " + "properties:%p", + num_callbacks, bt_status_text(status).c_str(), num_properties, + properties); } void remote_device_properties(bt_status_t status, RawAddress* bd_addr, @@ -96,15 +110,25 @@ void remote_device_properties(bt_status_t status, RawAddress* bd_addr, } } LOG_INFO( - "%s num_callbacks:%zu status:%s device:%s num_properties:%d " + "num_callbacks:%zu status:%s device:%s num_properties:%d " "properties:%p", - __func__, num_callbacks, bt_status_text(status).c_str(), STR(*bd_addr), + num_callbacks, bt_status_text(status).c_str(), STR(*bd_addr), num_properties, properties); } -void device_found([[maybe_unused]] int num_properties, - [[maybe_unused]] ::bt_property_t* properties) { - LOG_INFO("%s", __func__); +// Aggregate disparate variables from callback API into unified single structure +void device_found(int num_properties, ::bt_property_t* properties) { + [[maybe_unused]] const size_t num_callbacks = + interface_api_callback_map_.size(); + auto callback_list = interface_api_callback_map_.find(__func__); + if (callback_list != interface_api_callback_map_.end()) { + for (auto callback : callback_list->second) { + device_found_params_t params(num_properties, properties); + (callback)(¶ms); + } + } + LOG_INFO("Device found callback: num_properties:%d properties:%p", + num_properties, properties); } void discovery_state_changed(bt_discovery_state_t state) { @@ -284,6 +308,8 @@ void HeadlessStack::SetUp() { while (bt_state_ != BT_STATE_ON) adapter_state_cv_.wait(lck); LOG_INFO("%s HeadlessStack stack is operational", __func__); + bt_stack_info_ = std::make_unique(); + bluetooth::test::headless::start_messenger(); LOG_CONSOLE("%s Headless stack has started up successfully", kHeadlessIcon); diff --git a/system/test/headless/headless.h b/system/test/headless/headless.h index 78e75910323716670ee8b4cd60882fad60fa604b..37ad7c927a44872f8d9a23905b778da3e03925c0 100644 --- a/system/test/headless/headless.h +++ b/system/test/headless/headless.h @@ -22,8 +22,9 @@ #include "base/logging.h" // LOG() stdout and android log #include "include/hardware/bluetooth.h" +#include "test/headless/bt_stack_info.h" #include "test/headless/get_options.h" -#include "test/headless/messenger.h" +#include "test/headless/log.h" extern bt_interface_t bluetoothInterface; @@ -35,17 +36,13 @@ template using ExecutionUnit = std::function; constexpr char kHeadlessInitialSentinel[] = - " INITIAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS " - "HEADLESS"; + " INITIAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; constexpr char kHeadlessStartSentinel[] = - " START HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS " - "HEADLESS"; + " START HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; constexpr char kHeadlessStopSentinel[] = - " STOP HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS " - "HEADLESS"; + " STOP HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; constexpr char kHeadlessFinalSentinel[] = - " FINAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS " - "HEADLESS"; + " FINAL HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS HEADLESS"; class HeadlessStack { protected: @@ -60,6 +57,7 @@ class HeadlessStack { private: const char** stack_init_flags_; + std::unique_ptr bt_stack_info_; }; class HeadlessRun : public HeadlessStack { diff --git a/system/test/headless/interface.h b/system/test/headless/interface.h index 370d86138ec85771c14fb63ff8dd44337e24b593..8b4c9efd07b367e4f7100e2b0ab7c4c84fe469c4 100644 --- a/system/test/headless/interface.h +++ b/system/test/headless/interface.h @@ -1,38 +1,118 @@ - +/* + * Copyright 2023 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 -#include -#include +#include #include +#include "gd/os/log.h" #include "include/hardware/bluetooth.h" +#include "macros.h" #include "test/headless/log.h" +#include "test/headless/property.h" +#include "test/headless/text.h" #include "types/raw_address.h" +enum class Callback { + AclStateChanged, + AdapterProperties, + DeviceFound, + DiscoveryStateChanged, + RemoteDeviceProperties, +}; + +inline std::string callback_text(const Callback& callback) { + switch (callback) { + CASE_RETURN_TEXT(Callback::AclStateChanged); + CASE_RETURN_TEXT(Callback::AdapterProperties); + CASE_RETURN_TEXT(Callback::DeviceFound); + CASE_RETURN_TEXT(Callback::DiscoveryStateChanged); + CASE_RETURN_TEXT(Callback::RemoteDeviceProperties); + } +} + struct callback_data_t { std::string Name() const { return std::string(name_); } + Callback CallbackType() const { return callback_type_; } + uint64_t TimestampInMs() const { return static_cast(timestamp_ms_); } + virtual ~callback_data_t() = default; + + virtual std::string ToString() const = 0; protected: - callback_data_t(const char* name) - : name_(name), timestamp_ms_(GetTimestampMs()) {} - virtual ~callback_data_t() = default; + callback_data_t(const char* name, Callback callback_type_) + : name_(name), + callback_type_(callback_type_), + timestamp_ms_(GetTimestampMs()) {} private: const char* name_; + const Callback callback_type_; const long long timestamp_ms_; }; struct callback_params_t : public callback_data_t { + virtual std::string ToString() const override { + return std::string("VIRTUAL"); + } + protected: - callback_params_t(const char* name) : callback_data_t(name) {} + callback_params_t(const char* name, Callback callback_type) + : callback_data_t(name, callback_type) {} virtual ~callback_params_t() = default; - virtual std::string ToString() const = 0; +}; + +// Specializes the callback parameter +template +// std::shared_ptr Cast(std::shared_ptr params) { return +// std::shared_ptr(static_cast(params.get()));} +std::shared_ptr Cast(std::shared_ptr params) { + return std::make_shared(*(static_cast(params.get()))); +} + +struct callback_params_with_properties_t : public callback_params_t { + public: + std::deque properties() const { + return property_queue_; + } + size_t num_properties() const { return property_queue_.size(); } + + protected: + callback_params_with_properties_t(const char* name, Callback callback_type, + int num_properties, + ::bt_property_t* properties) + : callback_params_t(name, callback_type) { + for (int i = 0; i < num_properties; i++) { + LOG_DEBUG("Processing property %d/%d %p type:%d val:%p", i, + num_properties, &properties[i], properties[i].type, + properties[i].val); + property_queue_.push_back( + bluetooth::test::headless::property_factory(properties[i])); + } + } + virtual ~callback_params_with_properties_t() = default; + + private: + std::deque property_queue_; }; struct acl_state_changed_params_t : public callback_params_t { @@ -40,7 +120,7 @@ struct acl_state_changed_params_t : public callback_params_t { bt_acl_state_t state, int transport_link_type, bt_hci_error_code_t hci_reason, bt_conn_direction_t direction, uint16_t acl_handle) - : callback_params_t("acl_state_changed"), + : callback_params_t("acl_state_changed", Callback::AclStateChanged), status(status), remote_bd_addr(remote_bd_addr), state(state), @@ -62,20 +142,22 @@ struct acl_state_changed_params_t : public callback_params_t { std::string ToString() const override { return base::StringPrintf( - "status:%s remote_bd_addr:%s state:%s transport:%s reason:%s " - "direction:%d handle:%d", + "status:%s remote_bd_addr:%s state:%s transport:%s reason:%s" + " direction:%s handle:%hu", bt_status_text(status).c_str(), remote_bd_addr.ToString().c_str(), (state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED", bt_transport_text(static_cast(transport_link_type)) .c_str(), bt_status_text(static_cast(hci_reason)).c_str(), - direction, acl_handle); + bt_conn_direction_text(direction).c_str(), acl_handle); } }; struct discovery_state_changed_params_t : public callback_params_t { discovery_state_changed_params_t(bt_discovery_state_t state) - : callback_params_t("discovery_state_changed"), state(state) {} + : callback_params_t("discovery_state_changed", + Callback::DiscoveryStateChanged), + state(state) {} discovery_state_changed_params_t( const discovery_state_changed_params_t& params) = default; @@ -83,33 +165,64 @@ struct discovery_state_changed_params_t : public callback_params_t { bt_discovery_state_t state; std::string ToString() const override { - return base::StringPrintf( - "state:%s", (state == BT_DISCOVERY_STOPPED) ? "STOPPED" : "STARTED"); + return base::StringPrintf("state:%s", + bt_discovery_state_text(state).c_str()); } }; -struct remote_device_properties_params_t : public callback_params_t { +struct adapter_properties_params_t : public callback_params_with_properties_t { + adapter_properties_params_t(bt_status_t status, int num_properties, + ::bt_property_t* properties) + : callback_params_with_properties_t("adapter_properties", + Callback::AdapterProperties, + num_properties, properties), + status(status) {} + adapter_properties_params_t(const adapter_properties_params_t& params) = + default; + + virtual ~adapter_properties_params_t() {} + bt_status_t status; + + std::string ToString() const override { + return base::StringPrintf("status:%s num_properties:%zu", + bt_status_text(status).c_str(), num_properties()); + } +}; + +struct remote_device_properties_params_t + : public callback_params_with_properties_t { remote_device_properties_params_t(bt_status_t status, RawAddress bd_addr, int num_properties, - bt_property_t* properties) - : callback_params_t("remote_device_properties"), + ::bt_property_t* properties) + : callback_params_with_properties_t("remote_device_properties", + Callback::RemoteDeviceProperties, + num_properties, properties), status(status), - bd_addr(bd_addr), - num_properties(num_properties), - properties(properties) {} + bd_addr(bd_addr) {} remote_device_properties_params_t( const remote_device_properties_params_t& params) = default; virtual ~remote_device_properties_params_t() {} bt_status_t status; RawAddress bd_addr; - int num_properties; - bt_property_t* properties; + std::string ToString() const override { - return base::StringPrintf( - "status:%s bd_addr:%s num_properties:%d properties:%p", - bt_status_text(status).c_str(), bd_addr.ToString().c_str(), - num_properties, properties); + return base::StringPrintf("status:%s bd_addr:%s num_properties:%zu", + bt_status_text(status).c_str(), + bd_addr.ToString().c_str(), num_properties()); + } +}; + +struct device_found_params_t : public callback_params_with_properties_t { + device_found_params_t(int num_properties, ::bt_property_t* properties) + : callback_params_with_properties_t("device_found", Callback::DeviceFound, + num_properties, properties) {} + + device_found_params_t(const device_found_params_t& params) = default; + virtual ~device_found_params_t() {} + + std::string ToString() const override { + return base::StringPrintf("num_properties:%zu", num_properties()); } }; @@ -117,5 +230,4 @@ using callback_function_t = void (*)(callback_data_t*); void headless_add_callback(const std::string interface_name, callback_function_t function); -void headless_remove_callback(const std::string interface_name, - callback_function_t function); +void headless_remove_callback(const std::string interface_name); diff --git a/system/test/headless/log.cc b/system/test/headless/log.cc index 3bab572737515e7751a39202e3ae0633437a71ca..6105a9afcff73708a1df53486c7e1b2414527b32 100644 --- a/system/test/headless/log.cc +++ b/system/test/headless/log.cc @@ -14,13 +14,13 @@ * limitations under the License. */ -#include "osi/include/log.h" +#include "os/log.h" #include #include #include -#include "gd/common/circular_buffer.h" // TimestamperInMilliseconds +#include "common/circular_buffer.h" // TimestamperInMilliseconds #include "internal_include/bt_trace.h" #include "stack/btm/btm_int_types.h" diff --git a/system/test/headless/log.h b/system/test/headless/log.h index 303e220b44f4bbffe4a7ffbb26beb349adcf6344..4fb439e6bce1c039219f1bcca98dc4e0ef59219b 100644 --- a/system/test/headless/log.h +++ b/system/test/headless/log.h @@ -16,14 +16,11 @@ #pragma once -#include #include -#include #include /* Definition of SYS_* constants */ #include #include -#include #include #include "build_timestamp.h" // generated diff --git a/system/test/headless/main.cc b/system/test/headless/main.cc index f40ee53a7bc861b7c33a4f229a81ef7b61058840..e40bf85234cff50f020ec864a758b0d049fad012 100644 --- a/system/test/headless/main.cc +++ b/system/test/headless/main.cc @@ -26,13 +26,15 @@ #include #include "base/logging.h" // LOG() stdout and android log -#include "osi/include/log.h" // android log only +#include "os/log.h" // android log only +#include "test/headless/adapter/adapter.h" #include "test/headless/connect/connect.h" #include "test/headless/discovery/discovery.h" #include "test/headless/dumpsys/dumpsys.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" #include "test/headless/log.h" +#include "test/headless/mode/mode.h" #include "test/headless/nop/nop.h" #include "test/headless/pairing/pairing.h" #include "test/headless/read/read.h" @@ -91,12 +93,17 @@ class Main : public HeadlessTest { public: Main(const bluetooth::test::headless::GetOpt& options) : HeadlessTest(options) { + test_nodes_.emplace( + "adapter", + std::make_unique(options)); test_nodes_.emplace( "dumpsys", std::make_unique(options)); test_nodes_.emplace( "connect", std::make_unique(options)); + test_nodes_.emplace( + "mode", std::make_unique(options)); test_nodes_.emplace( "nop", std::make_unique(options)); test_nodes_.emplace( diff --git a/system/test/headless/messenger.cc b/system/test/headless/messenger.cc index 6231fb682d250d4f6bee05824921e32623af5272..604196b200847d17c3df64297688e19373cadc68 100644 --- a/system/test/headless/messenger.cc +++ b/system/test/headless/messenger.cc @@ -18,178 +18,125 @@ #include "test/headless/messenger.h" -#include +#include +#include +#include +#include #include "base/logging.h" // LOG() stdout and android log -#include "btif/include/btif_api.h" -#include "osi/include/log.h" // android log only -#include "stack/include/sdp_api.h" -#include "test/headless/bt_property.h" -#include "test/headless/get_options.h" -#include "test/headless/headless.h" #include "test/headless/interface.h" #include "test/headless/log.h" -#include "test/headless/sdp/sdp.h" -#include "test/headless/stopwatch.h" -#include "test/headless/timeout.h" -#include "types/bluetooth/uuid.h" -#include "types/raw_address.h" using namespace bluetooth::test::headless; using namespace std::chrono_literals; template +struct callback_queue_t { + callback_queue_t(const std::string name) : name_(name) {} + // Must be held with lock + size_t size() const { return callback_queue.size(); } + + private: + const std::string name_; + std::deque callback_queue; + + public: + void Push(T elem) { callback_queue.push_back(elem); } + // Must be held with lock + T Pop() { + T p = callback_queue.front(); + callback_queue.pop_front(); + return p; + } + // Must be held with lock + bool empty() const { return callback_queue.empty(); } +}; + struct messenger_t { - std::mutex mutex; + mutable std::mutex mutex; std::condition_variable cv; - std::deque params_queue; - void Notify() { cv.notify_all(); } + callback_queue_t> callback_queue = + callback_queue_t>("callbacks"); + void Push(std::shared_ptr elem) { + std::unique_lock lk(mutex); + callback_queue.Push(elem); + cv.notify_all(); + } }; -namespace { - -namespace acl { -messenger_t acl_state_changed_; - -void acl_state_changed_cb(callback_data_t* data) { - auto params = static_cast(data); - - acl_state_changed_.params_queue.push_back(*params); - acl_state_changed_.Notify(); -} +namespace bluetooth { +namespace test { +namespace headless { +namespace messenger { -bool await_event(const bt_acl_state_t& state, const Timeout& timeout) { - std::unique_lock lk(acl_state_changed_.mutex); - if (!acl_state_changed_.params_queue.empty()) { - auto params = acl_state_changed_.params_queue.back(); - if (params.state == state) return true; +// Called by client to await any callback for the given callbacks +messenger_t callback_data_; + +bool await_callback(Context& context) { + std::unique_lock lk(callback_data_.mutex); + while (!callback_data_.callback_queue.empty()) { + std::shared_ptr cb = callback_data_.callback_queue.Pop(); + if (std::find(context.callbacks.begin(), context.callbacks.end(), + cb->CallbackType()) != context.callbacks.end()) { + context.callback_ready_q.push_back(cb); + } } - return acl_state_changed_.cv.wait_for(lk, timeout, [=] { - return !acl_state_changed_.params_queue.empty() && - acl_state_changed_.params_queue.back().state == state; - }); -} - -} // namespace acl - -namespace sdp { -messenger_t remote_device_properties_; - -void remote_device_properties_cb(callback_data_t* data) { - auto params = static_cast(data); - // TODO Save timestamp into queue - remote_device_properties_.params_queue.push_back(*params); - remote_device_properties_.Notify(); -} - -bool await_event(const Timeout& timeout, const CheckPoint& check_point, - const size_t count) { - std::unique_lock lk(remote_device_properties_.mutex); - if (!remote_device_properties_.params_queue.empty()) { - if (remote_device_properties_.params_queue.size() - check_point > count) - return true; + if (context.callback_ready_q.size() == 0) { + callback_data_.cv.wait_for(lk, context.timeout); } - return remote_device_properties_.cv.wait_for(lk, timeout, [=] { - return !remote_device_properties_.params_queue.empty() && - remote_device_properties_.params_queue.size() - check_point >= count; - }); + return true; } -} // namespace sdp - -namespace inquiry {} // namespace inquiry - -} // namespace +} // namespace messenger +} // namespace headless +} // namespace test +} // namespace bluetooth namespace bluetooth::test::headless { -namespace messenger { -namespace acl { - -bool await_connected(const Timeout& timeout) { - return ::acl::await_event(BT_ACL_STATE_CONNECTED, timeout); -} - -bool await_disconnected(const Timeout& timeout) { - return ::acl::await_event(BT_ACL_STATE_DISCONNECTED, timeout); -} - -} // namespace acl - -namespace sdp { - -bool await_service_discovery(const Timeout& timeout, - const CheckPoint& check_point, - const size_t count) { - return ::sdp::await_event(timeout, check_point, count); +void messenger_stats() { + // LOG_CONSOLE("%30s cnt:%zu", "device_found", + // discovered::device_found_.size()); LOG_CONSOLE("%30s cnt:%zu", + // "remote_device_properties", + // properties::remote_device_properties_.size()); } -CheckPoint get_check_point() { - std::unique_lock lk(::sdp::remote_device_properties_.mutex); - return ::sdp::remote_device_properties_.params_queue.size(); -} - -std::deque collect_from( - CheckPoint& check_point) { - std::unique_lock lk(::sdp::remote_device_properties_.mutex); - ASSERT_LOG( - !(check_point > ::sdp::remote_device_properties_.params_queue.size()), - "Checkpoint larger than size"); - std::deque deque; - for (size_t size = check_point; - size < ::sdp::remote_device_properties_.params_queue.size(); ++size) { - deque.push_back(::sdp::remote_device_properties_.params_queue[size]); - } - return deque; -} - -} // namespace sdp - -namespace inquiry { - -CheckPoint get_check_point() { - std::unique_lock lk(::sdp::remote_device_properties_.mutex); - return ::sdp::remote_device_properties_.params_queue.size(); -} - -bool await_inquiry_result(const Timeout& timeout, const CheckPoint& check_point, - const size_t count) { - return ::sdp::await_event(timeout, check_point, count); -} - -std::deque collect_from( - CheckPoint& check_point) { - std::unique_lock lk(::sdp::remote_device_properties_.mutex); - ASSERT_LOG( - !(check_point > ::sdp::remote_device_properties_.params_queue.size()), - "Checkpoint larger than size"); - std::deque deque; - for (size_t size = check_point; - size < ::sdp::remote_device_properties_.params_queue.size(); ++size) { - deque.push_back(::sdp::remote_device_properties_.params_queue[size]); - } - check_point += - (::sdp::remote_device_properties_.params_queue.size() - check_point); - return deque; -} - -} // namespace inquiry -} // namespace messenger - +// Callbacks that the messenger will handle from the bluetooth stack void start_messenger() { - headless_add_callback("acl_state_changed", ::acl::acl_state_changed_cb); - headless_add_callback("remote_device_properties", - ::sdp::remote_device_properties_cb); - + headless_add_callback("acl_state_changed", [](callback_data_t* data) { + ASSERT_LOG(data != nullptr, "Received nullptr callback data:%s", __func__); + messenger::callback_data_.Push(std::make_shared( + *(static_cast(data)))); + }); + headless_add_callback("adapter_properties", [](callback_data_t* data) { + ASSERT_LOG(data != nullptr, "Received nullptr callback data:%s", __func__); + messenger::callback_data_.Push( + std::make_shared( + *(static_cast(data)))); + }); + headless_add_callback("device_found", [](callback_data_t* data) { + ASSERT_LOG(data != nullptr, "Received nullptr callback data:%s", __func__); + messenger::callback_data_.Push(std::make_shared( + *(static_cast(data)))); + }); + headless_add_callback("remote_device_properties", [](callback_data_t* data) { + ASSERT_LOG(data != nullptr, "Received nullptr callback data:%s", __func__); + messenger::callback_data_.Push( + std::make_shared( + *(static_cast(data)))); + }); LOG_CONSOLE("Started messenger service"); } void stop_messenger() { - headless_remove_callback("acl_state_changed", ::acl::acl_state_changed_cb); - headless_remove_callback("remote_device_properties", - ::sdp::remote_device_properties_cb); + headless_remove_callback("remote_device_properties"); + headless_remove_callback("device_found"); + headless_remove_callback("adapter_properties"); + headless_remove_callback("acl_state_changed"); LOG_CONSOLE("Stopped messenger service"); + + messenger_stats(); } } // namespace bluetooth::test::headless diff --git a/system/test/headless/messenger.h b/system/test/headless/messenger.h index f8c08ada8474e341d66246b8d153d5a3280beb93..67313124edb411fe3c26e131535c021c5a9c1b22 100644 --- a/system/test/headless/messenger.h +++ b/system/test/headless/messenger.h @@ -1,11 +1,27 @@ - +/* + * Copyright 2023 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 #include +#include #include "test/headless/interface.h" +#include "test/headless/stopwatch.h" #include "test/headless/timeout.h" namespace bluetooth::test::headless { @@ -16,12 +32,18 @@ void start_messenger(); void stop_messenger(); namespace messenger { -namespace acl { -bool await_connected(const Timeout& timeout); -bool await_disconnected(const Timeout& timeout); +struct Context { + Stopwatch stop_watch; + Timeout timeout; + CheckPoint check_point; + bool SetCallbacks(const std::vector& callbacks); + std::vector callbacks; + std::deque> callback_ready_q; +}; -} // namespace acl +// Called by client to await any callback for the given callbacks +bool await_callback(Context& context); namespace sdp { @@ -32,17 +54,6 @@ std::deque collect_from( CheckPoint& check_point); } // namespace sdp - -namespace inquiry { - -CheckPoint get_check_point(); -bool await_inquiry_result(const Timeout& timeout, const CheckPoint& check_point, - const size_t count); -std::deque collect_from( - CheckPoint& check_point); - -} // namespace inquiry - } // namespace messenger } // namespace bluetooth::test::headless diff --git a/system/test/headless/mode/mode.cc b/system/test/headless/mode/mode.cc new file mode 100644 index 0000000000000000000000000000000000000000..207b71129bc1eb82918a3d1c743771c849f8d92c --- /dev/null +++ b/system/test/headless/mode/mode.cc @@ -0,0 +1,153 @@ +/* + * Copyright 2023 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 "bt_headless_mode" + +#include "test/headless/mode/mode.h" + +#include +#include +#include + +#include "base/logging.h" // LOG() stdout and android log +#include "btm_status.h" +#include "hci_error_code.h" +#include "include/macros.h" +#include "stack/include/acl_api.h" +#include "stack/include/l2cap_acl_interface.h" +#include "test/headless/get_options.h" +#include "test/headless/headless.h" +#include "test/headless/messenger.h" +#include "test/headless/utils/power_mode_client.h" +#include "types/raw_address.h" + +using namespace bluetooth::test; +using namespace std::chrono_literals; + +namespace { +int do_mode([[maybe_unused]] unsigned int num_loops, + [[maybe_unused]] const RawAddress& bd_addr, + [[maybe_unused]] std::list options) { + LOG_CONSOLE("Starting mode change test"); + // Requires a BR_EDR connection to work + + headless::messenger::Context context{ + .stop_watch = Stopwatch("Connect_timeout"), + .timeout = 3s, + .check_point = {}, + .callbacks = {Callback::AclStateChanged}, + }; + + PowerMode power_mode; + + acl_create_classic_connection(bd_addr, false, false); + + std::shared_ptr acl{nullptr}; + + while (context.stop_watch.LapMs() < 10000) { + // If we have received callback results within this timeframe... + if (headless::messenger::await_callback(context)) { + while (!context.callback_ready_q.empty()) { + std::shared_ptr p = context.callback_ready_q.front(); + context.callback_ready_q.pop_front(); + switch (p->CallbackType()) { + case Callback::AclStateChanged: { + acl = Cast(p); + LOG_CONSOLE("Acl state changed:%s", acl->ToString().c_str()); + } break; + default: + LOG_CONSOLE("WARN Received callback for unasked:%s", + p->Name().c_str()); + break; + } + } + } + if (acl != nullptr) break; + } + + if (acl->state == BT_ACL_STATE_DISCONNECTED) { + LOG_CONSOLE("Connection failed"); + return 1; + } + + LOG_CONSOLE("Connection completed"); + PowerMode::Client client = power_mode.GetClient(bd_addr); + + { + pwr_command_t pwr_command; + pwr_result_t result = client.set_typical_sniff(std::move(pwr_command)); + LOG_CONSOLE("Sniff mode command sent"); + if (result.btm_status == BTM_CMD_STARTED) { + // This awaits the command status callback + power_mode_callback_t cmd_status = result.cmd_status_future.get(); + LOG_CONSOLE("Sniff mode command complete:%s", + cmd_status.ToString().c_str()); + if (cmd_status.status == BTM_PM_STS_PENDING) { + LOG_CONSOLE("Sniff mode command accepted; awaiting mode change event"); + power_mode_callback_t mode_event = result.mode_event_future.get(); + LOG_CONSOLE("Sniff mode command complete:%s", + mode_event.ToString().c_str()); + } else { + client.remove_mode_event_promise(); + LOG_CONSOLE("Command failed; no mode change event forthcoming"); + } + } else { + LOG_CONSOLE("Smiff mode command failed:%s", + btm_status_text(result.btm_status).c_str()); + } + } + + { + pwr_command_t pwr_command; + pwr_result_t result = client.set_active(std::move(pwr_command)); + LOG_CONSOLE("Active mode command sent"); + if (result.btm_status == BTM_CMD_STARTED) { + power_mode_callback_t cmd_status = result.cmd_status_future.get(); + LOG_CONSOLE("Active mode command complete:%s", + cmd_status.ToString().c_str()); + if (cmd_status.status == BTM_PM_STS_PENDING) { + LOG_CONSOLE("Active mode command accepted; awaiting mode change event"); + power_mode_callback_t mode_event = result.mode_event_future.get(); + LOG_CONSOLE("Active mode command complete:%s", + mode_event.ToString().c_str()); + } else { + client.remove_mode_event_promise(); + LOG_CONSOLE("Command failed; no mode change event forthcoming"); + } + } else { + LOG_CONSOLE("Active mode command failed:%s", + btm_status_text(result.btm_status).c_str()); + } + } + + LOG_CONSOLE("Disconnecting"); + acl_disconnect_from_handle(acl->acl_handle, HCI_SUCCESS, + "BT headless disconnect"); + LOG_CONSOLE("Waiting to disconnect"); + + sleep(3); + + return 0; +} + +} // namespace + // +int bluetooth::test::headless::Mode::Run() { + return RunOnHeadlessStack([this]() { + return do_mode(options_.loop_, options_.device_.front(), + options_.non_options_); + }); +} diff --git a/system/test/headless/mode/mode.h b/system/test/headless/mode/mode.h new file mode 100644 index 0000000000000000000000000000000000000000..b75042c02fe5aad735773bca919d3cc6fed857fa --- /dev/null +++ b/system/test/headless/mode/mode.h @@ -0,0 +1,35 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "test/headless/get_options.h" +#include "test/headless/headless.h" + +namespace bluetooth { +namespace test { +namespace headless { + +class Mode : public HeadlessTest { + public: + Mode(const bluetooth::test::headless::GetOpt& options) + : HeadlessTest(options) {} + int Run() override; +}; + +} // namespace headless +} // namespace test +} // namespace bluetooth diff --git a/system/test/headless/nop/nop.cc b/system/test/headless/nop/nop.cc index f6ac42c45aac2f1169631e33534d9fefa569e95b..9b194ba5e90f6ca6b03b36e2d4cc8349af2ca4fb 100644 --- a/system/test/headless/nop/nop.cc +++ b/system/test/headless/nop/nop.cc @@ -16,14 +16,15 @@ #define LOG_TAG "bt_headless_sdp" +#include "test/headless/nop/nop.h" + #include -#include "base/logging.h" // LOG() stdout and android log -#include "osi/include/log.h" // android log only +#include "base/logging.h" // LOG() stdout and android log +#include "os/log.h" // android log only #include "stack/include/sdp_api.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" -#include "test/headless/nop/nop.h" #include "types/raw_address.h" int bluetooth::test::headless::Nop::Run() { diff --git a/system/test/headless/pairing/pairing.cc b/system/test/headless/pairing/pairing.cc index ed5c490d2184b7978c1cfb4b9d50349b0321f6fe..1f654ed1897cd312f2d2bad769a4a1915c7a7887 100644 --- a/system/test/headless/pairing/pairing.cc +++ b/system/test/headless/pairing/pairing.cc @@ -16,14 +16,12 @@ #define LOG_TAG "bt_headless_sdp" -#include +#include "test/headless/pairing/pairing.h" #include "base/logging.h" // LOG() stdout and android log #include "btif/include/btif_api.h" -#include "osi/include/log.h" // android log only #include "test/headless/get_options.h" #include "test/headless/headless.h" -#include "test/headless/pairing/pairing.h" #include "types/raw_address.h" int bluetooth::test::headless::Pairing::Run() { @@ -38,7 +36,7 @@ int bluetooth::test::headless::Pairing::Run() { return -1; } - RawAddress raw_address = options_.device_.front(); + [[maybe_unused]] RawAddress raw_address = options_.device_.front(); return RunOnHeadlessStack([raw_address]() { btif_dm_create_bond(raw_address, BT_TRANSPORT_BR_EDR); diff --git a/system/test/headless/property.cc b/system/test/headless/property.cc index b0a098a84c343d7d82dc6333dfb87dbf246ebdd6..ad5485ae508cd6efa223ce84feb0197efca89189 100644 --- a/system/test/headless/property.cc +++ b/system/test/headless/property.cc @@ -14,18 +14,22 @@ * limitations under the License. */ +#define LOG_TAG "bt_property" + #include "test/headless/property.h" #include +#include "gd/os/log.h" #include "include/hardware/bluetooth.h" +#include "test/headless/log.h" using namespace bluetooth::test; namespace { // Map the bluetooth property names to the corresponding headless property -// structure +// structure factor std::map<::bt_property_type_t, std::function> property_map = { @@ -33,6 +37,10 @@ std::map<::bt_property_type_t, std::function headless::bt_property_t* { return new headless::property::name_t(data, len); }}, + {BT_PROPERTY_BDADDR, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::bdaddr_t(data, len); + }}, {BT_PROPERTY_UUIDS, [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { return new headless::property::uuid_t(data, len); @@ -45,6 +53,66 @@ std::map<::bt_property_type_t, std::function headless::bt_property_t* { return new headless::property::type_of_device_t(data, len); }}, + {BT_PROPERTY_SERVICE_RECORD, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t(data, len, + BT_PROPERTY_SERVICE_RECORD); + }}, + {BT_PROPERTY_ADAPTER_SCAN_MODE, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t(data, len, + BT_PROPERTY_ADAPTER_SCAN_MODE); + }}, + {BT_PROPERTY_ADAPTER_BONDED_DEVICES, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t( + data, len, BT_PROPERTY_ADAPTER_BONDED_DEVICES); + }}, + {BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t( + data, len, BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT); + }}, + {BT_PROPERTY_REMOTE_FRIENDLY_NAME, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t( + data, len, BT_PROPERTY_REMOTE_FRIENDLY_NAME); + }}, + {BT_PROPERTY_REMOTE_RSSI, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t(data, len, + BT_PROPERTY_REMOTE_RSSI); + }}, + {BT_PROPERTY_REMOTE_VERSION_INFO, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t( + data, len, BT_PROPERTY_REMOTE_VERSION_INFO); + }}, + {BT_PROPERTY_LOCAL_LE_FEATURES, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t(data, len, + BT_PROPERTY_LOCAL_LE_FEATURES); + }}, + {BT_PROPERTY_LOCAL_IO_CAPS, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t(data, len, + BT_PROPERTY_LOCAL_IO_CAPS); + }}, + {BT_PROPERTY_DYNAMIC_AUDIO_BUFFER, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t( + data, len, BT_PROPERTY_DYNAMIC_AUDIO_BUFFER); + }}, + {BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t( + data, len, BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER); + }}, + {BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, + [](const uint8_t* data, const size_t len) -> headless::bt_property_t* { + return new headless::property::void_t( + data, len, BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP); + }}, }; } // namespace @@ -52,12 +120,13 @@ std::map<::bt_property_type_t, std::function -1, "Property count is less than zero"); - ASSERT_LOG(bt_property.val != nullptr, "Property data value is null"); - const uint8_t* data = static_cast(bt_property.val); const size_t size = static_cast(bt_property.len); + if (size > 0) { + ASSERT_LOG(data != nullptr, "Property value pointer is null"); + } + const auto factory = property_map.find(bt_property.type); if (factory != property_map.end()) { return factory->second(data, size); diff --git a/system/test/headless/property.h b/system/test/headless/property.h index bbc6d5a571c33b08b9b2496458978a0353d70263..35d2f73f3ecba8784aa438f624bfc8a727e442da 100644 --- a/system/test/headless/property.h +++ b/system/test/headless/property.h @@ -20,21 +20,64 @@ #include #include #include +#include #include #include "include/hardware/bluetooth.h" +#include "macros.h" #include "test/headless/log.h" #include "types/bluetooth/uuid.h" +inline std::string bt_property_type_text(const ::bt_property_type_t type) { + switch (type) { + CASE_RETURN_TEXT(BT_PROPERTY_BDNAME); + CASE_RETURN_TEXT(BT_PROPERTY_BDADDR); + CASE_RETURN_TEXT(BT_PROPERTY_UUIDS); + CASE_RETURN_TEXT(BT_PROPERTY_CLASS_OF_DEVICE); + CASE_RETURN_TEXT(BT_PROPERTY_TYPE_OF_DEVICE); + 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_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); + CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_LE_FEATURES); + CASE_RETURN_TEXT(BT_PROPERTY_LOCAL_IO_CAPS); + CASE_RETURN_TEXT(BT_PROPERTY_RESERVED_0F); + CASE_RETURN_TEXT(BT_PROPERTY_DYNAMIC_AUDIO_BUFFER); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER); + CASE_RETURN_TEXT(BT_PROPERTY_APPEARANCE); + CASE_RETURN_TEXT(BT_PROPERTY_VENDOR_PRODUCT_INFO); + CASE_RETURN_TEXT(BT_PROPERTY_WL_MEDIA_PLAYERS_LIST); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ASHA_CAPABILITY); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_MODEL_NUM); + CASE_RETURN_TEXT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP); + default: + return base::StringPrintf("UNKNOWN[%d]", type); + } +} + namespace bluetooth { namespace test { namespace headless { struct bt_property_t { - int Type() const { return type; } + ::bt_property_type_t Type() const { return type; } virtual std::string ToString() const = 0; + // TODO verify this prints as expected + std::string ToRaw() { + std::ostringstream oss; + const uint8_t* p = data.get(); + for (size_t i = 0; i < sizeof(bt_property_t); i++, p++) { + oss << "0x" << std::hex << *p << " "; + } + return oss.str(); + } + protected: bt_property_t(const uint8_t* data, const size_t len) { this->len = len; @@ -45,7 +88,7 @@ struct bt_property_t { std::unique_ptr data; size_t len; - int type; + ::bt_property_type_t type; }; namespace property { @@ -53,12 +96,13 @@ namespace property { struct void_t : public bt_property_t { void_t(const uint8_t* data, const size_t len, int type) : bt_property_t(data, len) { - this->type = type; + this->type = (::bt_property_type_t)type; } public: virtual std::string ToString() const override { - return base::StringPrintf("void property type:%d", type); + return base::StringPrintf("Unimplemented property type:%d name:%s", type, + bt_property_type_text(type).c_str()); } }; @@ -100,6 +144,24 @@ struct name_t : public bt_property_t { } }; +struct bdaddr_t : public bt_property_t { + bdaddr_t(const uint8_t* data, const size_t len) : bt_property_t(data, len) { + type = BT_PROPERTY_BDNAME; + } + + RawAddress get_addr() const { + uint8_t* s = reinterpret_cast(data.get()); + // TODO This may need to be reversed + RawAddress bd_addr; + ASSERT_LOG(6U == bd_addr.FromOctets(s), "Mac address is not 6 bytes"); + return bd_addr; + } + + virtual std::string ToString() const override { + return base::StringPrintf("bd_addr:%s", get_addr().ToString().c_str()); + } +}; + struct class_of_device_t : public bt_property_t { class_of_device_t(const uint8_t* data, const size_t len) : bt_property_t(data, len) { diff --git a/system/test/headless/pushme.sh b/system/test/headless/pushme.sh new file mode 100755 index 0000000000000000000000000000000000000000..8d24f5cc470121d77e9c6c4608bb7fd0c6d89e67 --- /dev/null +++ b/system/test/headless/pushme.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +## Cuttlefish 64 bit bt_headless installation +PRODUCT=vsoc_x86_64 + +## Ensure that the device storage has been remounted +adb root +adb remount -R +adb wait-for-device + +## Push various shared libraries where the executable expects to find them +adb push ${ANDROID_BUILD_TOP}/out/target/product/${PRODUCT}/symbols/system/bin/bt_headless /system/bin/bt_headless diff --git a/system/test/headless/read/name.cc b/system/test/headless/read/name.cc index 5666d88a0bfce0457823c007558fb2d334b1f10a..f7f49bec2e53e5421ca15a3f8ca911846fa7a09d 100644 --- a/system/test/headless/read/name.cc +++ b/system/test/headless/read/name.cc @@ -16,15 +16,16 @@ #define LOG_TAG "bt_headless_sdp" +#include "test/headless/read/name.h" + #include -#include "base/logging.h" // LOG() stdout and android log -#include "osi/include/log.h" // android log only +#include "base/logging.h" // LOG() stdout and android log +#include "os/log.h" // android log only #include "stack/include/btm_api.h" #include "stack/include/btm_api_types.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" -#include "test/headless/read/name.h" #include "types/raw_address.h" std::promise promise_; diff --git a/system/test/headless/read/read.cc b/system/test/headless/read/read.cc index d1a3b8d295d5cbf3091c7bcbe14bc32fff0caa56..f01f8aa3b20751c2579e2c0429bfacc8a3b60747 100644 --- a/system/test/headless/read/read.cc +++ b/system/test/headless/read/read.cc @@ -17,8 +17,9 @@ #define LOG_TAG "bt_headless" #include "test/headless/read/read.h" -#include "base/logging.h" // LOG() stdout and android log -#include "osi/include/log.h" // android log only + +#include "base/logging.h" // LOG() stdout and android log +#include "os/log.h" // android log only #include "test/headless/get_options.h" #include "test/headless/headless.h" #include "test/headless/read/name.h" diff --git a/system/test/headless/scan/scan.cc b/system/test/headless/scan/scan.cc index 0c9e14fcdc6446bb99a56d125c61285370aa4549..4cc674a09d8af1752b5e6d8f1bb9e83d1785a4e6 100644 --- a/system/test/headless/scan/scan.cc +++ b/system/test/headless/scan/scan.cc @@ -18,74 +18,61 @@ #include "test/headless/scan/scan.h" -#include - #include "base/logging.h" // LOG() stdout and android log -#include "btif/include/btif_api.h" -#include "osi/include/log.h" // android log only -#include "stack/include/sdp_api.h" -#include "test/headless/bt_property.h" +#include "os/log.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" #include "test/headless/interface.h" #include "test/headless/log.h" +#include "test/headless/messenger.h" +#include "test/headless/property.h" #include "test/headless/stopwatch.h" -#include "types/bluetooth/uuid.h" -#include "types/raw_address.h" -using namespace bluetooth::test::headless; +using namespace bluetooth::test; using namespace std::chrono_literals; -namespace scan { -std::promise acl_state_changed_promise; -std::promise - remote_device_properties_promise; - -std::mutex mutex; -std::condition_variable cv; - -std::queue acl_state_changed_params_queue; -std::queue - discovery_state_changed_params_queue; -; - -// Callback from another thread -void callback_interface(callback_data_t* data) { - if (data->Name() == "discovery_state_changed") { - LOG(INFO) << "Received discovery_state_changed"; - auto params = static_cast(data); - discovery_state_changed_params_queue.push(*params); - LOG_CONSOLE("Received discovery state change callback %s", - params->ToString().c_str()); - cv.notify_all(); - return; - } - LOG(ERROR) << "Received unexpected interface callback"; -} - -} // namespace scan - namespace { int start_scan([[maybe_unused]] unsigned int num_loops) { LOG(INFO) << "Started Device Scan"; - Stopwatch stop_watch("Inquiry_timeout"); - auto check_point = messenger::inquiry::get_check_point(); - ASSERT(bluetoothInterface.start_discovery() == BT_STATUS_SUCCESS); LOG_CONSOLE("Started inquiry - device discovery"); - while (stop_watch.LapMs() < 10000) { - if (messenger::inquiry::await_inquiry_result(1s, check_point, 1)) { - auto callback_queue = messenger::inquiry::collect_from(check_point); - while (!callback_queue.empty()) { - remote_device_properties_params_t params = callback_queue.front(); - callback_queue.pop_front(); - LOG_CONSOLE("Received remote inquiry :%s", STR(params)); - bt_property_t* prop = params.properties; - for (int i = 0; i < params.num_properties; ++i, prop++) { - process_property(params.bd_addr, prop); + headless::messenger::Context context{ + .stop_watch = Stopwatch("Inquiry_timeout"), + .timeout = 1s, + .check_point = {}, + .callbacks = {Callback::RemoteDeviceProperties, Callback::DeviceFound}, + }; + + while (context.stop_watch.LapMs() < 10000) { + // If we have received callback results within this timeframe... + if (headless::messenger::await_callback(context)) { + while (!context.callback_ready_q.empty()) { + std::shared_ptr p = context.callback_ready_q.front(); + context.callback_ready_q.pop_front(); + switch (p->CallbackType()) { + case Callback::RemoteDeviceProperties: { + remote_device_properties_params_t* q = + static_cast(p.get()); + for (const auto& p2 : q->properties()) { + LOG_CONSOLE(" %s prop:%s", p->Name().c_str(), + p2->ToString().c_str()); + } + } break; + case Callback::DeviceFound: { + device_found_params_t* q = + static_cast(p.get()); + for (const auto& p2 : q->properties()) { + LOG_CONSOLE(" %s prop:%s", p->Name().c_str(), + p2->ToString().c_str()); + } + } break; + default: + LOG_CONSOLE("WARN Received callback for unasked:%s", + p->Name().c_str()); + break; } } } diff --git a/system/test/headless/sdp/sdp.cc b/system/test/headless/sdp/sdp.cc index 6750f5a71539c128ce4ee552a21915619c29c986..b9756723955816e736640e0cdaa45d2c4bc1fb28 100644 --- a/system/test/headless/sdp/sdp.cc +++ b/system/test/headless/sdp/sdp.cc @@ -21,7 +21,9 @@ #include #include "base/logging.h" // LOG() stdout and android log -#include "osi/include/log.h" // android log only +#include "bta/dm/bta_dm_int.h" +#include "bta/include/bta_api.h" +#include "os/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/sdp_api.h" #include "test/headless/get_options.h" @@ -43,60 +45,23 @@ static void bta_jv_start_discovery_callback( namespace { -struct sdp_error_code_s { - const char* name; - uint16_t error_code; -} sdp_error_code[] = { - {"KsdpSuccess", 0}, - {"KsdpInvalidVersion", 0x0001}, - {"KsdpInvalidServRecHdl", 0x0002}, - {"KsdpInvalidReqSyntax", 0x0003}, - {"KsdpInvalidPduSize", 0x0004}, - {"KsdpInvalidContState", 0x0005}, - {"KsdpNoResources", 0x0006}, - {"KsdpDiRegFailed", 0x0007}, - {"KsdpDiDiscFailed", 0x0008}, - {"KsdpNoDiRecordFound", 0x0009}, - {"KsdpErrAttrNotPresent", 0x000a}, - {"KsdpIllegalParameter", 0x000b}, - {"KsdpNoRecsMatch", 0xFFF0}, - {"KsdpConnFailed", 0xFFF1}, - {"KsdpCfgFailed", 0xFFF2}, - {"KsdpGenericError", 0xFFF3}, - {"KsdpDbFull", 0xFFF4}, - {"KsdpInvalidPdu", 0xFFF5}, - {"KsdpSecurityErr", 0xFFF6}, - {"KsdpConnRejected", 0xFFF7}, - {"KsdpCancel", 0xFFF8}, -}; - -const char* kUnknownText = "Unknown"; - -const char* SdpErrorCodeToString(uint16_t code) { - for (size_t i = 0; i < sizeof(sdp_error_code) / sizeof(sdp_error_code_s); - ++i) { - if (sdp_error_code[i].error_code == code) { - return sdp_error_code[i].name; - } - } - return kUnknownText; -} - -constexpr size_t kMaxDiscoveryRecords = 64; +constexpr size_t kMaxDiscoveryRecords = 1024; int sdp_query_uuid([[maybe_unused]] unsigned int num_loops, - const RawAddress& raw_address, const bluetooth::Uuid& uuid) { + [[maybe_unused]] const RawAddress& raw_address, + [[maybe_unused]] const bluetooth::Uuid& uuid) { SdpDb sdp_discovery_db(kMaxDiscoveryRecords); if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb( sdp_discovery_db.RawPointer(), sdp_discovery_db.Length(), 1, // num_uuid, &uuid, 0, nullptr)) { - fprintf(stdout, "%s Unable to initialize sdp discovery\n", __func__); + LOG_CONSOLE("Unable to initialize sdp discovery"); return -1; } + LOG_CONSOLE("Initialized sdp discovery database"); - std::promise promise; + std::promise promise; auto future = promise.get_future(); sdp_discovery_db.Print(stdout); @@ -107,24 +72,26 @@ int sdp_query_uuid([[maybe_unused]] unsigned int num_loops, fprintf(stdout, "%s Failed to start search attribute request\n", __func__); return -2; } + LOG_CONSOLE("Started service search for uuid:%s", uuid.ToString().c_str()); - uint16_t result = future.get(); - if (result != 0) { + const tSDP_STATUS result = future.get(); + if (result != SDP_SUCCESS) { fprintf(stdout, "Failed search discovery result:%s\n", - SdpErrorCodeToString(result)); + sdp_status_text(result).c_str()); return result; } - tSDP_DISC_REC* rec = get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb( - sdp_discovery_db.RawPointer(), uuid.As16Bit(), nullptr); - if (rec == nullptr) { - fprintf(stdout, "discovery record is null from:%s uuid:%s\n", - raw_address.ToString().c_str(), uuid.ToString().c_str()); - } else { - fprintf(stdout, "result:%d attr_id:%x from:%s uuid:%s\n", result, - rec->p_first_attr->attr_id, rec->remote_bd_addr.ToString().c_str(), - uuid.ToString().c_str()); + LOG_CONSOLE("Found records peer:%s uuid:%s", raw_address.ToString().c_str(), + uuid.ToString().c_str()); + for (unsigned i = 0; i < BTA_MAX_SERVICE_ID; i++) { + uint16_t uuid_as16Bit = bta_service_id_to_uuid_lkup_tbl[i]; + tSDP_DISC_REC* rec = SDP_FindServiceInDb(sdp_discovery_db.RawPointer(), + uuid_as16Bit, nullptr); + if (rec != nullptr) { + LOG_CONSOLE(" uuid:0x%x", uuid_as16Bit); + } } + return 0; } diff --git a/system/test/headless/sdp/sdp_db.cc b/system/test/headless/sdp/sdp_db.cc index 023861b70b1bdb04bee7535599f875e028119bd4..d275b888c06d14152a0fca7efaf81c5f11ba7979 100644 --- a/system/test/headless/sdp/sdp_db.cc +++ b/system/test/headless/sdp/sdp_db.cc @@ -17,11 +17,10 @@ #define LOG_TAG "bt_headless" #include "test/headless/sdp/sdp_db.h" -#include "base/logging.h" // LOG() stdout and android log -#include "osi/include/log.h" // android log only + +#include "base/logging.h" // LOG() stdout and android log #include "stack/include/sdp_api.h" #include "types/bluetooth/uuid.h" -#include "types/raw_address.h" using namespace bluetooth::test::headless; diff --git a/system/test/headless/text.cc b/system/test/headless/text.cc new file mode 100644 index 0000000000000000000000000000000000000000..5a013ce1bbb841ad36f41a7ae72f95d2a560d68f --- /dev/null +++ b/system/test/headless/text.cc @@ -0,0 +1,42 @@ +/* + * Copyright 2023 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 "test/headless/text.h" + +#include + +#include "include/hardware/bluetooth.h" +#include "macros.h" +#include "os/log.h" + +std::string bt_conn_direction_text(const bt_conn_direction_t& direction) { + switch (direction) { + CASE_RETURN_TEXT(BT_CONN_DIRECTION_UNKNOWN); + CASE_RETURN_TEXT(BT_CONN_DIRECTION_OUTGOING); + CASE_RETURN_TEXT(BT_CONN_DIRECTION_INCOMING); + default: + ASSERT_LOG(false, "Illegal bt_conn_direction:%d", direction); + } +} + +std::string bt_discovery_state_text(const bt_discovery_state_t& state) { + switch (state) { + CASE_RETURN_TEXT(BT_DISCOVERY_STOPPED); + CASE_RETURN_TEXT(BT_DISCOVERY_STARTED); + default: + ASSERT_LOG(false, "Illegal bt_discovery state:%d", state); + } +} diff --git a/system/gd/module_dumper_flatbuffer.cc b/system/test/headless/text.h similarity index 73% rename from system/gd/module_dumper_flatbuffer.cc rename to system/test/headless/text.h index aa232d27cd67f98197c6b59e36d65877e1c93802..dac565d66dbf3d7a59c6fcaf89ea0c4533d8804a 100644 --- a/system/gd/module_dumper_flatbuffer.cc +++ b/system/test/headless/text.h @@ -14,11 +14,9 @@ * limitations under the License. */ -#include "module_dumper_flatbuffer.h" +#include -#include "dumpsys_data_generated.h" +#include "include/hardware/bluetooth.h" -namespace bluetooth { -DumpsysDataFinisher EmptyDumpsysDataFinisher = [](DumpsysDataBuilder* /* dumpsys_data_builder */) { -}; -} // namespace bluetooth +std::string bt_conn_direction_text(const bt_conn_direction_t& direction); +std::string bt_discovery_state_text(const bt_discovery_state_t& state); diff --git a/system/test/headless/util.cc b/system/test/headless/util.cc index 6eeeb3e7c56a4741d7324c10b9cace7782307504..df3a15fd0ea6fe11b7ab7a55ea23aced7cb5163c 100644 --- a/system/test/headless/util.cc +++ b/system/test/headless/util.cc @@ -16,19 +16,16 @@ #include +#include "include/hardware/bluetooth.h" #include "osi/include/properties.h" -namespace { -constexpr char kZygoteService[] = "init.svc.zygote"; -constexpr char kZygoteServiceRunning[] = "running"; - -} // namespace - bool is_android_running() { +#ifdef __ANDROID__ char value[PROPERTY_VALUE_MAX]; - osi_property_get(kZygoteService, value, kZygoteServiceRunning); - if (!strncmp(kZygoteServiceRunning, value, PROPERTY_VALUE_MAX)) { + osi_property_get("init.svc.zygote", value, "running"); + if (!strncmp("running", value, PROPERTY_VALUE_MAX)) { return true; } +#endif return false; } diff --git a/system/test/headless/utils/power_mode_client.h b/system/test/headless/utils/power_mode_client.h new file mode 100644 index 0000000000000000000000000000000000000000..e35d455625ff7089ddd7ca06f5907ae98db08810 --- /dev/null +++ b/system/test/headless/utils/power_mode_client.h @@ -0,0 +1,213 @@ +/* + * Copyright 2023 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 + +#define LOG_TAG "bt_headless_mode" + +#include + +#include +#include + +#include "base/logging.h" // LOG() stdout and android log +#include "bta/dm/bta_dm_int.h" +#include "stack/include/btm_client_interface.h" +#include "stack/include/btm_status.h" +#include "stack/include/hci_error_code.h" +#include "types/raw_address.h" + +using namespace std::chrono_literals; + +namespace { +const tBTM_PM_PWR_MD default_mandatory_sniff_mode = { + .max = 0x0006, + .min = 0x0006, + .attempt = 0x0020, + .timeout = 0x7fff, + .mode = BTM_PM_MD_SNIFF, +}; + +const tBTM_PM_PWR_MD typical_sniff_mode = { + .max = 800, // 5 seconds + .min = 400, // 2.5 seconds + .attempt = 4, + .timeout = 1, + .mode = BTM_PM_MD_SNIFF, +}; + +const tBTM_PM_PWR_MD default_active_mode = { + .max = 0, // Unused + .min = 0, // Unused + .attempt = 0, // Unused + .timeout = 0, // Unused + .mode = BTM_PM_MD_ACTIVE, +}; +} // namespace + +// tBTM_PM_STATUS_CBACK +struct power_mode_callback_t { + const RawAddress bd_addr; + tBTM_PM_STATUS status; + uint16_t value; + tHCI_STATUS hci_status; + + std::string ToString() const { + return base::StringPrintf("bd_addr:%s pm_status:%s value:%hu hci_status:%s", + bd_addr.ToString().c_str(), + power_mode_status_text(status).c_str(), value, + hci_status_code_text(hci_status).c_str()); + } +}; + +struct pwr_command_t { + std::promise cmd_status_promise; + std::promise mode_event_promise; +}; + +struct pwr_result_t { + tBTM_STATUS btm_status; + std::future cmd_status_future; + std::future mode_event_future; +}; + +namespace { + +class Queue { + public: + void CallbackReceived(const power_mode_callback_t& data) { + LOG_INFO("Power mode callback cnt:%zu data:%s", cnt++, + data.ToString().c_str()); + std::unique_lock lk(mutex); + if (promises_map_[data.bd_addr].empty()) { + LOG_INFO("Received unsolicited power mode callback: %s", + data.ToString().c_str()); + return; + } + promises_map_[data.bd_addr].front().set_value(data); + promises_map_[data.bd_addr].pop_front(); + } + + void CommandSent(const RawAddress& bd_addr, pwr_command_t&& pwr_command) { + std::unique_lock lk(mutex); + promises_map_[bd_addr].push_back(std::move(pwr_command.cmd_status_promise)); + promises_map_[bd_addr].push_back(std::move(pwr_command.mode_event_promise)); + } + + void PopFront(const RawAddress& bd_addr) { + std::unique_lock lk(mutex); + ASSERT_LOG(!promises_map_[bd_addr].empty(), + "Unable to remove promise from empty bag of promises"); + promises_map_[bd_addr].pop_front(); + } + + private: + mutable std::mutex mutex; + std::unordered_map>> + promises_map_; + size_t cnt = 0; + +} queue_; + +} // namespace + +class PowerMode { + public: + class Client { + public: + Client(const uint8_t pm_id, const RawAddress& bd_addr) + : pm_id_(pm_id), bd_addr_(bd_addr) {} + + // Used when the power mode command status is unsuccessful + // to prevent waiting for a mode event that will never arrive. + // Exposed to allow testing of these conditions. + void remove_mode_event_promise() { queue_.PopFront(bd_addr_); } + + pwr_result_t set_sniff(pwr_command_t&& pwr_command) { + return send_power_mode_command( + std::move(pwr_command), + get_btm_client_interface().link_policy.BTM_SetPowerMode( + pm_id_, bd_addr_, &default_mandatory_sniff_mode)); + } + pwr_result_t set_typical_sniff(pwr_command_t&& pwr_command) { + return send_power_mode_command( + std::move(pwr_command), + get_btm_client_interface().link_policy.BTM_SetPowerMode( + pm_id_, bd_addr_, &typical_sniff_mode)); + } + + pwr_result_t set_active(pwr_command_t&& pwr_command) { + return send_power_mode_command( + std::move(pwr_command), + get_btm_client_interface().link_policy.BTM_SetPowerMode( + pm_id_, bd_addr_, &default_active_mode)); + } + + private: + pwr_result_t send_power_mode_command(pwr_command_t&& pwr_command, + const tBTM_STATUS btm_status) { + pwr_result_t result = { + .btm_status = btm_status, + .cmd_status_future = pwr_command.cmd_status_promise.get_future(), + .mode_event_future = pwr_command.mode_event_promise.get_future(), + }; + queue_.CommandSent(bd_addr_, std::move(pwr_command)); + return result; + } + + const uint8_t pm_id_; + const RawAddress bd_addr_; + }; + + PowerMode() { + BTM_PmRegister(BTM_PM_DEREG, &bta_dm_cb.pm_id, + []([[maybe_unused]] const RawAddress& bd_addr, + [[maybe_unused]] tBTM_PM_STATUS status, + [[maybe_unused]] uint16_t value, + [[maybe_unused]] tHCI_STATUS hci_status) {}); + + tBTM_STATUS btm_status = + get_btm_client_interface().lifecycle.BTM_PmRegister( + BTM_PM_REG_SET, &pm_id_, + [](const RawAddress& bd_addr, tBTM_PM_STATUS status, uint16_t value, + tHCI_STATUS hci_status) { + queue_.CallbackReceived(power_mode_callback_t{ + .bd_addr = bd_addr, + .status = status, + .value = value, + .hci_status = hci_status, + }); + }); + + ASSERT_LOG(BTM_SUCCESS == btm_status, "Failed to register power mode:%s", + btm_status_text(btm_status).c_str()); + } + + ~PowerMode() { + ASSERT(BTM_SUCCESS == get_btm_client_interface().lifecycle.BTM_PmRegister( + BTM_PM_DEREG, &pm_id_, + []([[maybe_unused]] const RawAddress& bd_addr, + [[maybe_unused]] tBTM_PM_STATUS status, + [[maybe_unused]] uint16_t value, + [[maybe_unused]] tHCI_STATUS hci_status) {})); + } + + Client GetClient(const RawAddress bd_addr) { return Client(pm_id_, bd_addr); } + + private: + uint8_t pm_id_; +}; diff --git a/system/test/mock/mock_audio_hal_interface_a2dp_encoding.cc b/system/test/mock/mock_audio_hal_interface_a2dp_encoding.cc new file mode 100644 index 0000000000000000000000000000000000000000..394d1b645a4893a13eab5829c5a8669c5a935c22 --- /dev/null +++ b/system/test/mock/mock_audio_hal_interface_a2dp_encoding.cc @@ -0,0 +1,208 @@ +/* + * Copyright 2023 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. + */ +/* + * Generated mock file from original source file + * Functions generated:21 + * + * mockcify.pl ver 0.7.0 + */ + +// Mock include file to share data between tests and mock +#include "test/mock/mock_audio_hal_interface_a2dp_encoding.h" + +#include +#include + +#include "test/common/mock_functions.h" + +// Original usings + +// Mocked internal structures, if any + +namespace test { +namespace mock { +namespace audio_hal_interface_a2dp_encoding { + +// Function state capture and return values, if needed +struct ack_stream_started ack_stream_started; +struct ack_stream_suspended ack_stream_suspended; +struct cleanup cleanup; +struct codec_index_str codec_index_str; +struct codec_info codec_info; +struct end_session end_session; +struct get_a2dp_configuration get_a2dp_configuration; +struct init init; +struct is_hal_enabled is_hal_enabled; +struct is_hal_offloading is_hal_offloading; +struct is_opus_supported is_opus_supported; +struct parse_a2dp_configuration parse_a2dp_configuration; +struct read read; +struct set_audio_low_latency_mode_allowed set_audio_low_latency_mode_allowed; +struct set_remote_delay set_remote_delay; +struct setup_codec setup_codec; +struct sink_codec_index sink_codec_index; +struct source_codec_index source_codec_index; +struct start_session start_session; +struct supports_codec supports_codec; +struct update_codec_offloading_capabilities + update_codec_offloading_capabilities; + +} // namespace audio_hal_interface_a2dp_encoding +} // namespace mock +} // namespace test + +// Mocked function return values, if any +namespace test { +namespace mock { +namespace audio_hal_interface_a2dp_encoding { + +std::optional codec_index_str::return_value = std::nullopt; +bool codec_info::return_value = false; +std::optional get_a2dp_configuration::return_value = + std::nullopt; +bool init::return_value = false; +bool is_hal_enabled::return_value = false; +bool is_hal_offloading::return_value = false; +bool is_opus_supported::return_value = false; +tA2DP_STATUS parse_a2dp_configuration::return_value = 0; +size_t read::return_value = 0; +bool setup_codec::return_value = false; +std::optional sink_codec_index::return_value = + std::nullopt; +std::optional source_codec_index::return_value = + std::nullopt; +bool supports_codec::return_value = false; +bool update_codec_offloading_capabilities::return_value = false; + +} // namespace audio_hal_interface_a2dp_encoding +} // namespace mock +} // namespace test + +// Mocked functions, if any +void ack_stream_started(const tA2DP_CTRL_ACK& status) { + inc_func_call_count(__func__); + test::mock::audio_hal_interface_a2dp_encoding::ack_stream_started(status); +} +void ack_stream_suspended(const tA2DP_CTRL_ACK& status) { + inc_func_call_count(__func__); + test::mock::audio_hal_interface_a2dp_encoding::ack_stream_suspended(status); +} +void cleanup() { + inc_func_call_count(__func__); + test::mock::audio_hal_interface_a2dp_encoding::cleanup(); +} +std::optional bluetooth::audio::a2dp::provider::codec_index_str( + btav_a2dp_codec_index_t codec_index) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::codec_index_str( + codec_index); +} +bool bluetooth::audio::a2dp::provider::codec_info( + btav_a2dp_codec_index_t codec_index, uint64_t* codec_id, + uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::codec_info( + codec_index, codec_id, codec_info, codec_config); +} +void end_session() { + inc_func_call_count(__func__); + test::mock::audio_hal_interface_a2dp_encoding::end_session(); +} +std::optional +bluetooth::audio::a2dp::provider::get_a2dp_configuration( + RawAddress peer_address, + std::vector const& remote_seps, + btav_a2dp_codec_config_t const& user_preferences) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::get_a2dp_configuration( + peer_address, remote_seps, user_preferences); +} +bool init(bluetooth::common::MessageLoopThread* message_loop) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::init(message_loop); +} +bool is_hal_enabled() { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::is_hal_enabled(); +} +bool is_hal_offloading() { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::is_hal_offloading(); +} +bool is_opus_supported() { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::is_opus_supported(); +} +tA2DP_STATUS bluetooth::audio::a2dp::provider::parse_a2dp_configuration( + btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_parameters, + std::vector* vendor_specific_parameters) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding:: + parse_a2dp_configuration(codec_index, codec_info, codec_parameters, + vendor_specific_parameters); +} +size_t read(uint8_t* p_buf, uint32_t len) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::read(p_buf, len); +} +void set_audio_low_latency_mode_allowed(bool allowed) { + inc_func_call_count(__func__); + test::mock::audio_hal_interface_a2dp_encoding:: + set_audio_low_latency_mode_allowed(allowed); +} +void set_remote_delay(uint16_t delay_report) { + inc_func_call_count(__func__); + test::mock::audio_hal_interface_a2dp_encoding::set_remote_delay(delay_report); +} +bool setup_codec() { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::setup_codec(); +} +std::optional +bluetooth::audio::a2dp::provider::sink_codec_index( + const uint8_t* p_codec_info) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::sink_codec_index( + p_codec_info); +} +std::optional +bluetooth::audio::a2dp::provider::source_codec_index( + const uint8_t* p_codec_info) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::source_codec_index( + p_codec_info); +} +void start_session() { + inc_func_call_count(__func__); + test::mock::audio_hal_interface_a2dp_encoding::start_session(); +} +bool bluetooth::audio::a2dp::provider::supports_codec( + btav_a2dp_codec_index_t codec_index) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding::supports_codec( + codec_index); +} +bool update_codec_offloading_capabilities( + const std::vector& framework_preference, + bool supports_a2dp_hw_offload_v2) { + inc_func_call_count(__func__); + return test::mock::audio_hal_interface_a2dp_encoding:: + update_codec_offloading_capabilities(framework_preference, + supports_a2dp_hw_offload_v2); +} +// Mocked functions complete +// END mockcify generation diff --git a/system/test/mock/mock_audio_hal_interface_a2dp_encoding.h b/system/test/mock/mock_audio_hal_interface_a2dp_encoding.h new file mode 100644 index 0000000000000000000000000000000000000000..da94f0ea433b5f7e767d5c3a05a3e67a249c8f18 --- /dev/null +++ b/system/test/mock/mock_audio_hal_interface_a2dp_encoding.h @@ -0,0 +1,332 @@ +/* + * Copyright 2023 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 + +/* + * Generated mock file from original source file + * Functions generated:21 + * + * mockcify.pl ver 0.7.0 + */ + +#include +#include + +// Original included files, if any +// NOTE: Since this is a mock file with mock definitions some number of +// include files may not be required. The include-what-you-use +// still applies, but crafting proper inclusion is out of scope +// for this effort. This compilation unit may compile as-is, or +// may need attention to prune from (or add to ) the inclusion set. +#include "audio_hal_interface/a2dp_encoding.h" + +// Original usings +using bluetooth::audio::a2dp::provider::a2dp_configuration; +using bluetooth::audio::a2dp::provider::a2dp_remote_capabilities; + +// Mocked compile conditionals, if any + +namespace test { +namespace mock { +namespace audio_hal_interface_a2dp_encoding { + +// Shared state between mocked functions and tests +// Name: ack_stream_started +// Params: const tA2DP_CTRL_ACK& status +// Return: void +struct ack_stream_started { + std::function body{ + [](const tA2DP_CTRL_ACK& /* status */) {}}; + void operator()(const tA2DP_CTRL_ACK& status) { body(status); }; +}; +extern struct ack_stream_started ack_stream_started; + +// Name: ack_stream_suspended +// Params: const tA2DP_CTRL_ACK& status +// Return: void +struct ack_stream_suspended { + std::function body{ + [](const tA2DP_CTRL_ACK& /* status */) {}}; + void operator()(const tA2DP_CTRL_ACK& status) { body(status); }; +}; +extern struct ack_stream_suspended ack_stream_suspended; + +// Name: cleanup +// Params: +// Return: void +struct cleanup { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct cleanup cleanup; + +// Name: codec_index_str +// Params: btav_a2dp_codec_index_t codec_index +// Return: std::optional +struct codec_index_str { + static std::optional return_value; + std::function(btav_a2dp_codec_index_t codec_index)> + body{[](btav_a2dp_codec_index_t /* codec_index */) { + return return_value; + }}; + std::optional operator()(btav_a2dp_codec_index_t codec_index) { + return body(codec_index); + }; +}; +extern struct codec_index_str codec_index_str; + +// Name: codec_info +// Params: btav_a2dp_codec_index_t codec_index, uint64_t *codec_id, uint8_t* +// codec_info, btav_a2dp_codec_config_t* codec_config Return: bool +struct codec_info { + static bool return_value; + std::function + body{[](btav_a2dp_codec_index_t /* codec_index */, + uint64_t* /* codec_id */, uint8_t* /* codec_info */, + btav_a2dp_codec_config_t* /* codec_config */) { + return return_value; + }}; + bool operator()(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id, + uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) { + return body(codec_index, codec_id, codec_info, codec_config); + }; +}; +extern struct codec_info codec_info; + +// Name: end_session +// Params: +// Return: void +struct end_session { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct end_session end_session; + +// Name: get_a2dp_configuration +// Params: RawAddress peer_address, std::vector const& +// remote_seps, btav_a2dp_codec_config_t const& user_preferences Return: +// std::optional +struct get_a2dp_configuration { + static std::optional return_value; + std::function( + RawAddress peer_address, + std::vector const& remote_seps, + btav_a2dp_codec_config_t const& user_preferences)> + body{[](RawAddress /* peer_address */, + std::vector const& /* remote_seps */, + btav_a2dp_codec_config_t const& /* user_preferences */) { + return return_value; + }}; + std::optional operator()( + RawAddress peer_address, + std::vector const& remote_seps, + btav_a2dp_codec_config_t const& user_preferences) { + return body(peer_address, remote_seps, user_preferences); + }; +}; +extern struct get_a2dp_configuration get_a2dp_configuration; + +// Name: init +// Params: bluetooth::common::MessageLoopThread* message_loop +// Return: bool +struct init { + static bool return_value; + std::function body{ + [](bluetooth::common::MessageLoopThread* /* message_loop */) { + return return_value; + }}; + bool operator()(bluetooth::common::MessageLoopThread* message_loop) { + return body(message_loop); + }; +}; +extern struct init init; + +// Name: is_hal_enabled +// Params: +// Return: bool +struct is_hal_enabled { + static bool return_value; + std::function body{[]() { return return_value; }}; + bool operator()() { return body(); }; +}; +extern struct is_hal_enabled is_hal_enabled; + +// Name: is_hal_offloading +// Params: +// Return: bool +struct is_hal_offloading { + static bool return_value; + std::function body{[]() { return return_value; }}; + bool operator()() { return body(); }; +}; +extern struct is_hal_offloading is_hal_offloading; + +// Name: is_opus_supported +// Params: +// Return: bool +struct is_opus_supported { + static bool return_value; + std::function body{[]() { return return_value; }}; + bool operator()() { return body(); }; +}; +extern struct is_opus_supported is_opus_supported; + +// Name: parse_a2dp_configuration +// Params: btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info, +// btav_a2dp_codec_config_t* codec_parameters, std::vector* +// vendor_specific_parameters Return: tA2DP_STATUS +struct parse_a2dp_configuration { + static tA2DP_STATUS return_value; + std::function* vendor_specific_parameters)> + body{[](btav_a2dp_codec_index_t /* codec_index */, + const uint8_t* /* codec_info */, + btav_a2dp_codec_config_t* /* codec_parameters */, + std::vector* /* vendor_specific_parameters */) { + return return_value; + }}; + tA2DP_STATUS operator()(btav_a2dp_codec_index_t codec_index, + const uint8_t* codec_info, + btav_a2dp_codec_config_t* codec_parameters, + std::vector* vendor_specific_parameters) { + return body(codec_index, codec_info, codec_parameters, + vendor_specific_parameters); + }; +}; +extern struct parse_a2dp_configuration parse_a2dp_configuration; + +// Name: read +// Params: uint8_t* p_buf, uint32_t len +// Return: size_t +struct read { + static size_t return_value; + std::function body{ + [](uint8_t* /* p_buf */, uint32_t /* len */) { return return_value; }}; + size_t operator()(uint8_t* p_buf, uint32_t len) { return body(p_buf, len); }; +}; +extern struct read read; + +// Name: set_audio_low_latency_mode_allowed +// Params: bool allowed +// Return: void +struct set_audio_low_latency_mode_allowed { + std::function body{[](bool /* allowed */) {}}; + void operator()(bool allowed) { body(allowed); }; +}; +extern struct set_audio_low_latency_mode_allowed + set_audio_low_latency_mode_allowed; + +// Name: set_remote_delay +// Params: uint16_t delay_report +// Return: void +struct set_remote_delay { + std::function body{ + [](uint16_t /* delay_report */) {}}; + void operator()(uint16_t delay_report) { body(delay_report); }; +}; +extern struct set_remote_delay set_remote_delay; + +// Name: setup_codec +// Params: +// Return: bool +struct setup_codec { + static bool return_value; + std::function body{[]() { return return_value; }}; + bool operator()() { return body(); }; +}; +extern struct setup_codec setup_codec; + +// Name: sink_codec_index +// Params: const uint8_t* p_codec_info +// Return: std::optional +struct sink_codec_index { + static std::optional return_value; + std::function( + const uint8_t* p_codec_info)> + body{[](const uint8_t* /* p_codec_info */) { return return_value; }}; + std::optional operator()( + const uint8_t* p_codec_info) { + return body(p_codec_info); + }; +}; +extern struct sink_codec_index sink_codec_index; + +// Name: source_codec_index +// Params: const uint8_t* p_codec_info +// Return: std::optional +struct source_codec_index { + static std::optional return_value; + std::function( + const uint8_t* p_codec_info)> + body{[](const uint8_t* /* p_codec_info */) { return return_value; }}; + std::optional operator()( + const uint8_t* p_codec_info) { + return body(p_codec_info); + }; +}; +extern struct source_codec_index source_codec_index; + +// Name: start_session +// Params: +// Return: void +struct start_session { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct start_session start_session; + +// Name: supports_codec +// Params: btav_a2dp_codec_index_t codec_index +// Return: bool +struct supports_codec { + static bool return_value; + std::function body{ + [](btav_a2dp_codec_index_t /* codec_index */) { return return_value; }}; + bool operator()(btav_a2dp_codec_index_t codec_index) { + return body(codec_index); + }; +}; +extern struct supports_codec supports_codec; + +// Name: update_codec_offloading_capabilities +// Params: const std::vector& framework_preference +// Return: bool +struct update_codec_offloading_capabilities { + static bool return_value; + std::function& framework_preference, + bool supports_a2dp_hw_offload_v2)> + body{[](const std::vector< + btav_a2dp_codec_config_t>& /* framework_preference */, + bool /*supports_a2dp_hw_offload_v2*/) { return return_value; }}; + bool operator()( + const std::vector& framework_preference, + bool supports_a2dp_hw_offload_v2) { + return body(framework_preference, supports_a2dp_hw_offload_v2); + }; +}; +extern struct update_codec_offloading_capabilities + update_codec_offloading_capabilities; + +} // namespace audio_hal_interface_a2dp_encoding +} // namespace mock +} // namespace test + +// END mockcify generation diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc index 311afb619db6bd175e340edda30d474514e49917..86edb3faefdb0c47c78e67142fa2c4953a8c08e8 100644 --- a/system/test/mock/mock_bluetooth_interface.cc +++ b/system/test/mock/mock_bluetooth_interface.cc @@ -16,58 +16,71 @@ #include -#include "btif/include/stack_manager.h" +#include "btif/include/stack_manager_t.h" #include "hardware/bluetooth.h" #include "stack/include/bt_octets.h" #include "types/raw_address.h" -void invoke_adapter_state_changed_cb(bt_state_t state) {} -void invoke_adapter_properties_cb(bt_status_t status, int num_properties, - bt_property_t* properties) {} -void invoke_remote_device_properties_cb(bt_status_t status, RawAddress bd_addr, - int num_properties, - bt_property_t* properties) {} -void invoke_device_found_cb(int num_properties, bt_property_t* properties) {} -void invoke_discovery_state_changed_cb(bt_discovery_state_t state) {} -void invoke_pin_request_cb(RawAddress bd_addr, bt_bdname_t bd_name, - uint32_t cod, bool min_16_digit) {} -void invoke_ssp_request_cb(RawAddress bd_addr, bt_bdname_t bd_name, - uint32_t cod, bt_ssp_variant_t pairing_variant, - uint32_t pass_key) {} -void invoke_oob_data_request_cb(tBT_TRANSPORT t, bool valid, Octet16 c, - Octet16 r, RawAddress raw_address, - uint8_t address_type) {} -void invoke_bond_state_changed_cb(bt_status_t status, RawAddress bd_addr, - bt_bond_state_t state, int fail_reason) {} -void invoke_address_consolidate_cb(RawAddress main_bd_addr, - RawAddress secondary_bd_addr) {} -void invoke_le_address_associate_cb(RawAddress main_bd_addr, - RawAddress secondary_bd_addr) {} -void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr, - bt_acl_state_t state, int transport_link_type, - bt_hci_error_code_t hci_reason, - bt_conn_direction_t direction, - uint16_t acl_handle) {} -void invoke_thread_evt_cb(bt_cb_thread_evt event) {} +void invoke_adapter_state_changed_cb(bt_state_t /* state */) {} +void invoke_adapter_properties_cb(bt_status_t /* status */, + int /* num_properties */, + bt_property_t* /* properties */) {} +void invoke_remote_device_properties_cb(bt_status_t /* status */, + RawAddress /* bd_addr */, + int /* num_properties */, + bt_property_t* /* properties */) {} +void invoke_device_found_cb(int /* num_properties */, + bt_property_t* /* properties */) {} +void invoke_discovery_state_changed_cb(bt_discovery_state_t /* state */) {} +void invoke_pin_request_cb(RawAddress /* bd_addr */, bt_bdname_t /* bd_name */, + uint32_t /* cod */, bool /* min_16_digit */) {} +void invoke_ssp_request_cb(RawAddress /* bd_addr */, bt_bdname_t /* bd_name */, + uint32_t /* cod */, + bt_ssp_variant_t /* pairing_variant */, + uint32_t /* pass_key */) {} +void invoke_oob_data_request_cb(tBT_TRANSPORT /* t */, bool /* valid */, + Octet16 /* c */, Octet16 /* r */, + RawAddress /* raw_address */, + uint8_t /* address_type */) {} +void invoke_bond_state_changed_cb(bt_status_t /* status */, + RawAddress /* bd_addr */, + bt_bond_state_t /* state */, + int /* fail_reason */) {} +void invoke_address_consolidate_cb(RawAddress /* main_bd_addr */, + RawAddress /* secondary_bd_addr */) {} +void invoke_le_address_associate_cb(RawAddress /* main_bd_addr */, + RawAddress /* secondary_bd_addr */) {} +void invoke_acl_state_changed_cb(bt_status_t /* status */, + RawAddress /* bd_addr */, + bt_acl_state_t /* state */, + int /* transport_link_type */, + bt_hci_error_code_t /* hci_reason */, + bt_conn_direction_t /* direction */, + uint16_t /* acl_handle */) {} +void invoke_thread_evt_cb(bt_cb_thread_evt /* event */) {} -void invoke_le_test_mode_cb(bt_status_t status, uint16_t count) {} +void invoke_le_test_mode_cb(bt_status_t /* status */, uint16_t /* count */) {} -void invoke_energy_info_cb(bt_activity_energy_info energy_info, - bt_uid_traffic_t* uid_data) {} -void invoke_link_quality_report_cb(uint64_t timestamp, int report_id, int rssi, - int snr, int retransmission_count, - int packets_not_receive_count, - int negative_acknowledgement_count) {} +void invoke_energy_info_cb(bt_activity_energy_info /* energy_info */, + bt_uid_traffic_t* /* uid_data */) {} +void invoke_link_quality_report_cb(uint64_t /* timestamp */, + int /* report_id */, int /* rssi */, + int /* snr */, + int /* retransmission_count */, + int /* packets_not_receive_count */, + int /* negative_acknowledgement_count */) {} +void invoke_key_missing_cb(const RawAddress /* bd_addr */) {} -static void init_stack(bluetooth::core::CoreInterface* interface) {} +static void init_stack(bluetooth::core::CoreInterface* /* interface */) {} -static void start_up_stack_async(bluetooth::core::CoreInterface* interface, - ProfileStartCallback startProfiles, - ProfileStopCallback stopProfiles) {} +static void start_up_stack_async( + bluetooth::core::CoreInterface* /* interface */, + ProfileStartCallback /* startProfiles */, + ProfileStopCallback /* stopProfiles */) {} -static void shut_down_stack_async(ProfileStopCallback stopProfiles) {} +static void shut_down_stack_async(ProfileStopCallback /* stopProfiles */) {} -static void clean_up_stack(ProfileStopCallback stopProfiles) {} +static void clean_up_stack(ProfileStopCallback /* stopProfiles */) {} static bool get_stack_is_running() { return true; } diff --git a/system/test/mock/mock_bta_av_api.h b/system/test/mock/mock_bta_av_api.h index 80481c7c05eae4ea44c9d9e28d8afabb1ef28bac..2e5811c9f92b7f8be8ad1cd4cc3782c19848b1cd 100644 --- a/system/test/mock/mock_bta_av_api.h +++ b/system/test/mock/mock_bta_av_api.h @@ -31,7 +31,6 @@ // still applies, but crafting proper inclusion is out of scope // for this effort. This compilation unit may compile as-is, or // may need attention to prune from (or add to ) the inclusion set. -#include "bt_target.h" #include "bta/av/bta_av_int.h" #include "btif/include/btif_av.h" #include "os/log.h" @@ -364,4 +363,4 @@ extern struct BTA_AvVendorRsp BTA_AvVendorRsp; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_bta_csis.cc b/system/test/mock/mock_bta_csis.cc index 6ec2761d88f0352f22fcbe4c6e20113bf38f95ee..3280acb2f9821d654c43e1fda26a93a424e3a66b 100644 --- a/system/test/mock/mock_bta_csis.cc +++ b/system/test/mock/mock_bta_csis.cc @@ -25,8 +25,7 @@ using bluetooth::csis::CsisClient; using bluetooth::csis::CsisClientCallbacks; void CsisClient::AddFromStorage(const RawAddress& addr, - const std::vector& in, - bool autoconnect) { + const std::vector& in) { inc_func_call_count(__func__); } bool CsisClient::GetForStorage(const RawAddress& addr, diff --git a/system/test/mock/mock_bta_dm_act.cc b/system/test/mock/mock_bta_dm_act.cc index 5ebe4f30195a205b63e6b443bf97bba6e84b81eb..86e14cefe86d28e195d9c176c2a3ed3f3be42d15 100644 --- a/system/test/mock/mock_bta_dm_act.cc +++ b/system/test/mock/mock_bta_dm_act.cc @@ -74,6 +74,7 @@ struct bta_dm_is_search_request_queued bta_dm_is_search_request_queued; struct bta_dm_pin_reply bta_dm_pin_reply; struct bta_dm_process_remove_device bta_dm_process_remove_device; struct bta_dm_remove_device bta_dm_remove_device; +struct bta_dm_remote_key_missing bta_dm_remote_key_missing; struct bta_dm_rm_cback bta_dm_rm_cback; struct bta_dm_sdp_result bta_dm_sdp_result; struct bta_dm_set_dev_name bta_dm_set_dev_name; @@ -257,6 +258,10 @@ void bta_dm_remove_device(const RawAddress& bd_addr) { inc_func_call_count(__func__); test::mock::bta_dm_act::bta_dm_remove_device(bd_addr); } +void bta_dm_remote_key_missing(const RawAddress bd_addr) { + inc_func_call_count(__func__); + test::mock::bta_dm_act::bta_dm_remote_key_missing(bd_addr); +} void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id, uint8_t app_id, const RawAddress& peer_addr) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_bta_dm_act.h b/system/test/mock/mock_bta_dm_act.h index 1450c0bd5479f83ce7c5d3c5bc191ed9de0ad239..66e063b44633958f61bb628ef0f9913bd66cd8d8 100644 --- a/system/test/mock/mock_bta_dm_act.h +++ b/system/test/mock/mock_bta_dm_act.h @@ -515,6 +515,16 @@ struct bta_dm_remove_device { }; extern struct bta_dm_remove_device bta_dm_remove_device; +// Name: bta_dm_remote_key_missing +// Params: const RawAddress bd_addr +// Return: void +struct bta_dm_remote_key_missing { + std::function body{ + [](const RawAddress bd_addr) {}}; + void operator()(const RawAddress bd_addr) { body(bd_addr); }; +}; +extern struct bta_dm_remote_key_missing bta_dm_remote_key_missing; + // Name: bta_dm_rm_cback // Params: tBTA_SYS_CONN_STATUS status, uint8_t id, uint8_t app_id, const // RawAddress& peer_addr Return: void diff --git a/system/test/mock/mock_bta_gattc_api.cc b/system/test/mock/mock_bta_gattc_api.cc index 4e8265c818a340dd35068de80d7ac0822ce293a1..cfc7a9fa7e78f42ca4e894b85413e965e8ef1336 100644 --- a/system/test/mock/mock_bta_gattc_api.cc +++ b/system/test/mock/mock_bta_gattc_api.cc @@ -31,138 +31,160 @@ #include "types/raw_address.h" void BTA_GATTC_Disable(void) { inc_func_call_count(__func__); } -const gatt::Characteristic* BTA_GATTC_GetCharacteristic(uint16_t conn_id, - uint16_t handle) { +const gatt::Characteristic* BTA_GATTC_GetCharacteristic(uint16_t /* conn_id */, + uint16_t /* handle */) { inc_func_call_count(__func__); return nullptr; } -const gatt::Characteristic* BTA_GATTC_GetOwningCharacteristic(uint16_t conn_id, - uint16_t handle) { +const gatt::Characteristic* BTA_GATTC_GetOwningCharacteristic( + uint16_t /* conn_id */, uint16_t /* handle */) { inc_func_call_count(__func__); return nullptr; } -const gatt::Descriptor* BTA_GATTC_GetDescriptor(uint16_t conn_id, - uint16_t handle) { +const gatt::Descriptor* BTA_GATTC_GetDescriptor(uint16_t /* conn_id */, + uint16_t /* handle */) { inc_func_call_count(__func__); return nullptr; } -const gatt::Service* BTA_GATTC_GetOwningService(uint16_t conn_id, - uint16_t handle) { +const gatt::Service* BTA_GATTC_GetOwningService(uint16_t /* conn_id */, + uint16_t /* handle */) { inc_func_call_count(__func__); return nullptr; } -const std::list* BTA_GATTC_GetServices(uint16_t conn_id) { +const std::list* BTA_GATTC_GetServices(uint16_t /* conn_id */) { inc_func_call_count(__func__); return nullptr; } -tGATT_STATUS BTA_GATTC_DeregisterForNotifications(tGATT_IF client_if, - const RawAddress& bda, - uint16_t handle) { +tGATT_STATUS BTA_GATTC_DeregisterForNotifications(tGATT_IF /* client_if */, + const RawAddress& /* bda */, + uint16_t /* handle */) { inc_func_call_count(__func__); return GATT_SUCCESS; } -tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF client_if, - const RawAddress& bda, - uint16_t handle) { +tGATT_STATUS BTA_GATTC_RegisterForNotifications(tGATT_IF /* client_if */, + const RawAddress& /* bda */, + uint16_t /* handle */) { inc_func_call_count(__func__); return GATT_SUCCESS; } -void BTA_GATTC_AppDeregister(tGATT_IF client_if) { +void BTA_GATTC_AppDeregister(tGATT_IF /* client_if */) { inc_func_call_count(__func__); } -void BTA_GATTC_AppRegister(tBTA_GATTC_CBACK* p_client_cb, - BtaAppRegisterCallback cb, bool eatt_support) { +void BTA_GATTC_AppRegister(tBTA_GATTC_CBACK* /* p_client_cb */, + BtaAppRegisterCallback /* cb */, + bool /* eatt_support */) { inc_func_call_count(__func__); } -void BTA_GATTC_CancelOpen(tGATT_IF client_if, const RawAddress& remote_bda, - bool is_direct) { +void BTA_GATTC_CancelOpen(tGATT_IF /* client_if */, + const RawAddress& /* remote_bda */, + bool /* is_direct */) { inc_func_call_count(__func__); } -void BTA_GATTC_Close(uint16_t conn_id) { inc_func_call_count(__func__); } -void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu) { +void BTA_GATTC_Close(uint16_t /* conn_id */) { inc_func_call_count(__func__); } +void BTA_GATTC_ConfigureMTU(uint16_t /* conn_id */, uint16_t /* mtu */) { inc_func_call_count(__func__); } -void BTA_GATTC_ConfigureMTU(uint16_t conn_id, uint16_t mtu, - GATT_CONFIGURE_MTU_OP_CB callback, void* cb_data) { +void BTA_GATTC_ConfigureMTU(uint16_t /* conn_id */, uint16_t /* mtu */, + GATT_CONFIGURE_MTU_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void BTA_GATTC_DiscoverServiceByUuid(uint16_t conn_id, - const bluetooth::Uuid& srvc_uuid) { +void BTA_GATTC_DiscoverServiceByUuid(uint16_t /* conn_id */, + const bluetooth::Uuid& /* srvc_uuid */) { inc_func_call_count(__func__); } -void BTA_GATTC_ExecuteWrite(uint16_t conn_id, bool is_execute) { +void BTA_GATTC_ExecuteWrite(uint16_t /* conn_id */, bool /* is_execute */) { inc_func_call_count(__func__); } -void BTA_GATTC_GetGattDb(uint16_t conn_id, uint16_t start_handle, - uint16_t end_handle, btgatt_db_element_t** db, - int* count) { +void BTA_GATTC_GetGattDb(uint16_t /* conn_id */, uint16_t /* start_handle */, + uint16_t /* end_handle */, + btgatt_db_element_t** /* db */, int* /* count */) { inc_func_call_count(__func__); } -void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda, - tBTM_BLE_CONN_TYPE connection_type, bool opportunistic) { +void BTA_GATTC_Open(tGATT_IF /* client_if */, + const RawAddress& /* remote_bda */, + tBTM_BLE_CONN_TYPE /* connection_type */, + bool /* opportunistic */) { inc_func_call_count(__func__); } -void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda, - tBTM_BLE_CONN_TYPE connection_type, tBT_TRANSPORT transport, - bool opportunistic, uint8_t initiating_phys) { +void BTA_GATTC_Open(tGATT_IF /* client_if */, + const RawAddress& /* remote_bda */, + tBTM_BLE_CONN_TYPE /* connection_type */, + tBT_TRANSPORT /* transport */, bool /* opportunistic */, + uint8_t /* initiating_phys */) { inc_func_call_count(__func__); } -void BTA_GATTC_Open(tGATT_IF client_if, const RawAddress& remote_bda, - tBLE_ADDR_TYPE addr_type, - tBTM_BLE_CONN_TYPE connection_type, tBT_TRANSPORT transport, - bool opportunistic, uint8_t initiating_phys) { +void BTA_GATTC_Open(tGATT_IF /* client_if */, + const RawAddress& /* remote_bda */, + tBLE_ADDR_TYPE /* addr_type */, + tBTM_BLE_CONN_TYPE /* connection_type */, + tBT_TRANSPORT /* transport */, bool /* opportunistic */, + uint8_t /* initiating_phys */) { inc_func_call_count(__func__); } -void BTA_GATTC_PrepareWrite(uint16_t conn_id, uint16_t handle, uint16_t offset, - std::vector value, tGATT_AUTH_REQ auth_req, - GATT_WRITE_OP_CB callback, void* cb_data) { +void BTA_GATTC_PrepareWrite(uint16_t /* conn_id */, uint16_t /* handle */, + uint16_t /* offset */, + std::vector /* value */, + tGATT_AUTH_REQ /* auth_req */, + GATT_WRITE_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void BTA_GATTC_ReadCharDescr(uint16_t conn_id, uint16_t handle, - tGATT_AUTH_REQ auth_req, GATT_READ_OP_CB callback, - void* cb_data) { +void BTA_GATTC_ReadCharDescr(uint16_t /* conn_id */, uint16_t /* handle */, + tGATT_AUTH_REQ /* auth_req */, + GATT_READ_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void BTA_GATTC_ReadCharacteristic(uint16_t conn_id, uint16_t handle, - tGATT_AUTH_REQ auth_req, - GATT_READ_OP_CB callback, void* cb_data) { +void BTA_GATTC_ReadCharacteristic(uint16_t /* conn_id */, uint16_t /* handle */, + tGATT_AUTH_REQ /* auth_req */, + GATT_READ_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void BTA_GATTC_ReadMultiple(uint16_t conn_id, tBTA_GATTC_MULTI& handles, - bool variable_len, tGATT_AUTH_REQ auth_req, - GATT_READ_MULTI_OP_CB callback, void* cb_data) { +void BTA_GATTC_ReadMultiple(uint16_t /* conn_id */, + tBTA_GATTC_MULTI& /* handles */, + bool /* variable_len */, + tGATT_AUTH_REQ /* auth_req */, + GATT_READ_MULTI_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void BTA_GATTC_ReadUsingCharUuid(uint16_t conn_id, const bluetooth::Uuid& uuid, - uint16_t s_handle, uint16_t e_handle, - tGATT_AUTH_REQ auth_req, - GATT_READ_OP_CB callback, void* cb_data) { +void BTA_GATTC_ReadUsingCharUuid(uint16_t /* conn_id */, + const bluetooth::Uuid& /* uuid */, + uint16_t /* s_handle */, + uint16_t /* e_handle */, + tGATT_AUTH_REQ /* auth_req */, + GATT_READ_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void BTA_GATTC_Refresh(const RawAddress& remote_bda) { +void BTA_GATTC_Refresh(const RawAddress& /* remote_bda */) { inc_func_call_count(__func__); } -void BTA_GATTC_SendIndConfirm(uint16_t conn_id, uint16_t cid) { +void BTA_GATTC_SendIndConfirm(uint16_t /* conn_id */, uint16_t /* cid */) { inc_func_call_count(__func__); } -void BTA_GATTC_ServiceSearchRequest(uint16_t conn_id, - const bluetooth::Uuid* p_srvc_uuid) { +void BTA_GATTC_ServiceSearchRequest(uint16_t /* conn_id */, + const bluetooth::Uuid* /* p_srvc_uuid */) { inc_func_call_count(__func__); } -void BTA_GATTC_WriteCharDescr(uint16_t conn_id, uint16_t handle, - std::vector value, - tGATT_AUTH_REQ auth_req, - GATT_WRITE_OP_CB callback, void* cb_data) { +void BTA_GATTC_WriteCharDescr(uint16_t /* conn_id */, uint16_t /* handle */, + std::vector /* value */, + tGATT_AUTH_REQ /* auth_req */, + GATT_WRITE_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void BTA_GATTC_WriteCharValue(uint16_t conn_id, uint16_t handle, - tGATT_WRITE_TYPE write_type, - std::vector value, - tGATT_AUTH_REQ auth_req, - GATT_WRITE_OP_CB callback, void* cb_data) { +void BTA_GATTC_WriteCharValue(uint16_t /* conn_id */, uint16_t /* handle */, + tGATT_WRITE_TYPE /* write_type */, + std::vector /* value */, + tGATT_AUTH_REQ /* auth_req */, + GATT_WRITE_OP_CB /* callback */, + void* /* cb_data */) { inc_func_call_count(__func__); } -void bta_gattc_continue_discovery_if_needed(const RawAddress& bd_addr, - uint16_t acl_handle) { +void bta_gattc_continue_discovery_if_needed(const RawAddress& /* bd_addr */, + uint16_t /* acl_handle */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_bta_gatts_api.cc b/system/test/mock/mock_bta_gatts_api.cc index 5610478a883fed74faad3ada682343889de12700..eba8de3a14f1ea33864c78eb5f16ee861a8dec2b 100644 --- a/system/test/mock/mock_bta_gatts_api.cc +++ b/system/test/mock/mock_bta_gatts_api.cc @@ -33,45 +33,49 @@ #include "types/raw_address.h" void BTA_GATTS_Disable(void) { inc_func_call_count(__func__); } -void BTA_GATTS_AppDeregister(tGATT_IF server_if) { +void BTA_GATTS_AppDeregister(tGATT_IF /* server_if */) { inc_func_call_count(__func__); } -void BTA_GATTS_AppRegister(const bluetooth::Uuid& app_uuid, - tBTA_GATTS_CBACK* p_cback, bool eatt_support) { +void BTA_GATTS_AppRegister(const bluetooth::Uuid& /* app_uuid */, + tBTA_GATTS_CBACK* /* p_cback */, + bool /* eatt_support */) { inc_func_call_count(__func__); } -void BTA_GATTS_CancelOpen(tGATT_IF server_if, const RawAddress& remote_bda, - bool is_direct) { +void BTA_GATTS_CancelOpen(tGATT_IF /* server_if */, + const RawAddress& /* remote_bda */, + bool /* is_direct */) { inc_func_call_count(__func__); } -void BTA_GATTS_Close(uint16_t conn_id) { inc_func_call_count(__func__); } -void BTA_GATTS_AddService(tGATT_IF server_if, - std::vector service, - BTA_GATTS_AddServiceCb cb) { +void BTA_GATTS_Close(uint16_t /* conn_id */) { inc_func_call_count(__func__); } +void BTA_GATTS_AddService(tGATT_IF /* server_if */, + std::vector /* service */, + BTA_GATTS_AddServiceCb /* cb */) { inc_func_call_count(__func__); } -void BTA_GATTS_DeleteService(uint16_t service_id) { +void BTA_GATTS_DeleteService(uint16_t /* service_id */) { inc_func_call_count(__func__); } -void BTA_GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_id, - std::vector value, - bool need_confirm) { +void BTA_GATTS_HandleValueIndication(uint16_t /* conn_id */, + uint16_t /* attr_id */, + std::vector /* value */, + bool /* need_confirm */) { inc_func_call_count(__func__); } -void BTA_GATTS_Open(tGATT_IF server_if, const RawAddress& remote_bda, - bool is_direct, tBT_TRANSPORT transport) { +void BTA_GATTS_Open(tGATT_IF /* server_if */, + const RawAddress& /* remote_bda */, bool /* is_direct */, + tBT_TRANSPORT /* transport */) { inc_func_call_count(__func__); } -void BTA_GATTS_SendRsp(uint16_t conn_id, uint32_t trans_id, tGATT_STATUS status, - tGATTS_RSP* p_msg) { +void BTA_GATTS_SendRsp(uint16_t /* conn_id */, uint32_t /* trans_id */, + tGATT_STATUS /* status */, tGATTS_RSP* /* p_msg */) { inc_func_call_count(__func__); } -void BTA_GATTS_StopService(uint16_t service_id) { +void BTA_GATTS_StopService(uint16_t /* service_id */) { inc_func_call_count(__func__); } -void bta_gatts_add_service_impl(tGATT_IF server_if, - std::vector service, - BTA_GATTS_AddServiceCb cb) { +void bta_gatts_add_service_impl(tGATT_IF /* server_if */, + std::vector /* service */, + BTA_GATTS_AddServiceCb /* cb */) { inc_func_call_count(__func__); } void BTA_GATTS_InitBonded(void) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_bta_hh_api.cc b/system/test/mock/mock_bta_hh_api.cc index 70dd17a3165a411c6b5e094d7fe8204a53b600b6..ee1d1fdc3ae546714ed6b88fba8fb7e3963c7592 100644 --- a/system/test/mock/mock_bta_hh_api.cc +++ b/system/test/mock/mock_bta_hh_api.cc @@ -29,7 +29,7 @@ void BTA_HhEnable(tBTA_HH_CBACK* p_cback, bool enable_hidp, bool enable_hogp) { inc_func_call_count(__func__); } -void BTA_HhAddDev(const RawAddress& bda, tBTA_HH_ATTR_MASK attr_mask, +void BTA_HhAddDev(const tAclLinkSpec& link_spec, tBTA_HH_ATTR_MASK attr_mask, uint8_t sub_class, uint8_t app_id, tBTA_HH_DEV_DSCP_INFO dscp_info) { inc_func_call_count(__func__); @@ -43,12 +43,14 @@ void BTA_HhGetReport(uint8_t dev_handle, tBTA_HH_RPT_TYPE r_type, uint8_t rpt_id, uint16_t buf_size) { inc_func_call_count(__func__); } -void BTA_HhOpen(const RawAddress& dev_bda) { inc_func_call_count(__func__); } +void BTA_HhOpen(const tAclLinkSpec& link_spec) { + inc_func_call_count(__func__); +} void BTA_HhRemoveDev(uint8_t dev_handle) { inc_func_call_count(__func__); } void BTA_HhSendCtrl(uint8_t dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type) { inc_func_call_count(__func__); } -void BTA_HhSendData(uint8_t dev_handle, const RawAddress& dev_bda, +void BTA_HhSendData(uint8_t dev_handle, const tAclLinkSpec& link_spec, BT_HDR* p_data) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_bta_hh_utils.cc b/system/test/mock/mock_bta_hh_utils.cc index bb15bd8908f08c9b872df65c4ba82a4f2f3c90fc..2d7a8bc9725a3079812ea010ececcf140c95a91a 100644 --- a/system/test/mock/mock_bta_hh_utils.cc +++ b/system/test/mock/mock_bta_hh_utils.cc @@ -74,20 +74,20 @@ uint8_t bta_hh_dev_handle_to_cb_idx(uint8_t dev_handle) { inc_func_call_count(__func__); return test::mock::bta_hh_utils::bta_hh_dev_handle_to_cb_idx(dev_handle); } -uint8_t bta_hh_find_cb(const RawAddress& bda) { +uint8_t bta_hh_find_cb(const tAclLinkSpec& link_spec) { inc_func_call_count(__func__); - return test::mock::bta_hh_utils::bta_hh_find_cb(bda); + return test::mock::bta_hh_utils::bta_hh_find_cb(link_spec); } -tBTA_HH_DEV_CB* bta_hh_get_cb(const RawAddress& bda) { +tBTA_HH_DEV_CB* bta_hh_get_cb(const tAclLinkSpec& link_spec) { inc_func_call_count(__func__); - return test::mock::bta_hh_utils::bta_hh_get_cb(bda); + return test::mock::bta_hh_utils::bta_hh_get_cb(link_spec); } -tBTA_HH_STATUS bta_hh_read_ssr_param(const RawAddress& bd_addr, +tBTA_HH_STATUS bta_hh_read_ssr_param(const tAclLinkSpec& link_spec, uint16_t* p_max_ssr_lat, uint16_t* p_min_ssr_tout) { inc_func_call_count(__func__); - return test::mock::bta_hh_utils::bta_hh_read_ssr_param(bd_addr, p_max_ssr_lat, - p_min_ssr_tout); + return test::mock::bta_hh_utils::bta_hh_read_ssr_param( + link_spec, p_max_ssr_lat, p_min_ssr_tout); } bool bta_hh_tod_spt(tBTA_HH_DEV_CB* p_cb, uint8_t sub_class) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_bta_hh_utils.h b/system/test/mock/mock_bta_hh_utils.h index 7ae214e99ab5cb7bd4cad5a000e8179ebd7404a8..cfee660ae9c1b2bf07125d99b30229fc42432298 100644 --- a/system/test/mock/mock_bta_hh_utils.h +++ b/system/test/mock/mock_bta_hh_utils.h @@ -88,40 +88,42 @@ struct bta_hh_dev_handle_to_cb_idx { extern struct bta_hh_dev_handle_to_cb_idx bta_hh_dev_handle_to_cb_idx; // Name: bta_hh_find_cb -// Params: const RawAddress& bda +// Params: const tAclLinkSpec& link_spec // Return: uint8_t struct bta_hh_find_cb { uint8_t return_value{0}; - std::function body{ - [this](const RawAddress& bda) { return return_value; }}; - uint8_t operator()(const RawAddress& bda) { return body(bda); }; + std::function body{ + [this](const tAclLinkSpec& link_spec) { return return_value; }}; + uint8_t operator()(const tAclLinkSpec& link_spec) { return body(link_spec); }; }; extern struct bta_hh_find_cb bta_hh_find_cb; // Name: bta_hh_get_cb -// Params: const RawAddress& bda +// Params: const tAclLinkSpec& link_spec // Return: tBTA_HH_DEV_CB* struct bta_hh_get_cb { tBTA_HH_DEV_CB* return_value{0}; - std::function body{ - [this](const RawAddress& bda) { return return_value; }}; - tBTA_HH_DEV_CB* operator()(const RawAddress& bda) { return body(bda); }; + std::function body{ + [this](const tAclLinkSpec& link_spec) { return return_value; }}; + tBTA_HH_DEV_CB* operator()(const tAclLinkSpec& link_spec) { + return body(link_spec); + }; }; extern struct bta_hh_get_cb bta_hh_get_cb; // Name: bta_hh_read_ssr_param -// Params: const RawAddress& bd_addr, uint16_t* p_max_ssr_lat, uint16_t* +// Params: const tAclLinkSpec& bd_addr, uint16_t* p_max_ssr_lat, uint16_t* // p_min_ssr_tout Return: tBTA_HH_STATUS struct bta_hh_read_ssr_param { tBTA_HH_STATUS return_value{0}; - std::function - body{[this](const RawAddress& bd_addr, uint16_t* p_max_ssr_lat, + body{[this](const tAclLinkSpec& link_spec, uint16_t* p_max_ssr_lat, uint16_t* p_min_ssr_tout) { return return_value; }}; - tBTA_HH_STATUS operator()(const RawAddress& bd_addr, uint16_t* p_max_ssr_lat, - uint16_t* p_min_ssr_tout) { - return body(bd_addr, p_max_ssr_lat, p_min_ssr_tout); + tBTA_HH_STATUS operator()(const tAclLinkSpec& link_spec, + uint16_t* p_max_ssr_lat, uint16_t* p_min_ssr_tout) { + return body(link_spec, p_max_ssr_lat, p_min_ssr_tout); }; }; extern struct bta_hh_read_ssr_param bta_hh_read_ssr_param; diff --git a/system/test/mock/mock_bta_leaudio.cc b/system/test/mock/mock_bta_leaudio.cc index 743a10bc7e22405d26c225931c656243ddcdcc60..41a9643658427763a733658bec8e675701a74c2d 100644 --- a/system/test/mock/mock_bta_leaudio.cc +++ b/system/test/mock/mock_bta_leaudio.cc @@ -42,34 +42,37 @@ class HalVersionManager { } // namespace bluetooth void LeAudioClient::AddFromStorage( - const RawAddress& addr, bool autoconnect, int sink_audio_location, - int source_audio_location, int sink_supported_context_types, - int source_supported_context_types, const std::vector& handles, - const std::vector& sink_pacs, - const std::vector& source_pacs, const std::vector& ases) { + const RawAddress& /* addr */, bool /* autoconnect */, + int /* sink_audio_location */, int /* source_audio_location */, + int /* sink_supported_context_types */, + int /* source_supported_context_types */, + const std::vector& /* handles */, + const std::vector& /* sink_pacs */, + const std::vector& /* source_pacs */, + const std::vector& /* ases */) { inc_func_call_count(__func__); } -bool LeAudioClient::GetHandlesForStorage(const RawAddress& addr, - std::vector& out) { +bool LeAudioClient::GetHandlesForStorage(const RawAddress& /* addr */, + std::vector& /* out */) { inc_func_call_count(__func__); return false; } -bool LeAudioClient::GetSinkPacsForStorage(const RawAddress& addr, - std::vector& out) { +bool LeAudioClient::GetSinkPacsForStorage(const RawAddress& /* addr */, + std::vector& /* out */) { inc_func_call_count(__func__); return false; } -bool LeAudioClient::GetSourcePacsForStorage(const RawAddress& addr, - std::vector& out) { +bool LeAudioClient::GetSourcePacsForStorage(const RawAddress& /* addr */, + std::vector& /* out */) { inc_func_call_count(__func__); return false; } -bool LeAudioClient::GetAsesForStorage(const RawAddress& addr, - std::vector& out) { +bool LeAudioClient::GetAsesForStorage(const RawAddress& /* addr */, + std::vector& /* out */) { inc_func_call_count(__func__); return false; } @@ -84,11 +87,21 @@ bool LeAudioClient::IsLeAudioClientRunning(void) { inc_func_call_count(__func__); return false; } +bool LeAudioClient::IsLeAudioClientInStreaming(void) { + inc_func_call_count(__func__); + return false; +} void LeAudioClient::Initialize( - bluetooth::le_audio::LeAudioClientCallbacks* callbacks_, - base::Closure initCb, base::Callback hal_2_1_verifier, + bluetooth::le_audio::LeAudioClientCallbacks* /* callbacks_ */, + base::Closure /* initCb */, base::Callback /* hal_2_1_verifier */, const std::vector& - offloading_preference) { + /* offloading_preference */) { + inc_func_call_count(__func__); +} +void LeAudioClient::DebugDump(int /* fd */) { inc_func_call_count(__func__); } + +bool LeAudioClient::RegisterIsoDataConsumer( + LeAudioIsoDataCallback /* callback */) { inc_func_call_count(__func__); + return true; } -void LeAudioClient::DebugDump(int fd) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_bta_scn.cc b/system/test/mock/mock_bta_scn.cc index e376bdc49f2a4fc81e56440988d14ea153dd27f8..bc4b63a8caacbe7622d898add479ba290a290968 100644 --- a/system/test/mock/mock_bta_scn.cc +++ b/system/test/mock/mock_bta_scn.cc @@ -22,14 +22,13 @@ #include #include "bta/include/bta_rfcomm_scn.h" -#include "bta/jv/bta_jv_int.h" #include "test/common/mock_functions.h" -bool BTA_FreeSCN(uint8_t scn) { +bool BTA_FreeSCN(uint8_t /* scn */) { inc_func_call_count(__func__); return false; } -bool BTA_TryAllocateSCN(uint8_t scn) { +bool BTA_TryAllocateSCN(uint8_t /* scn */) { inc_func_call_count(__func__); return false; } diff --git a/system/test/mock/mock_bta_sdp_api.h b/system/test/mock/mock_bta_sdp_api.h index 24256a690ee0913b0b3a3e55fdaeb0545e3b0bbe..cb351af65b26021907d63dc781055424611f6a9e 100644 --- a/system/test/mock/mock_bta_sdp_api.h +++ b/system/test/mock/mock_bta_sdp_api.h @@ -44,7 +44,7 @@ namespace bta_sdp_api { struct BTA_SdpCreateRecordByUser { static tBTA_SDP_STATUS return_value; std::function body{ - [](void* user_data) { return return_value; }}; + [](void* /* user_data */) { return return_value; }}; tBTA_SDP_STATUS operator()(void* user_data) { return body(user_data); }; }; extern struct BTA_SdpCreateRecordByUser BTA_SdpCreateRecordByUser; @@ -53,7 +53,7 @@ extern struct BTA_SdpCreateRecordByUser BTA_SdpCreateRecordByUser; // Params: int fd // Return: void struct BTA_SdpDumpsys { - std::function body{[](int fd) {}}; + std::function body{[](int /* fd */) {}}; void operator()(int fd) { body(fd); }; }; extern struct BTA_SdpDumpsys BTA_SdpDumpsys; @@ -64,7 +64,7 @@ extern struct BTA_SdpDumpsys BTA_SdpDumpsys; struct BTA_SdpEnable { static tBTA_SDP_STATUS return_value; std::function body{ - [](tBTA_SDP_DM_CBACK* p_cback) { return return_value; }}; + [](tBTA_SDP_DM_CBACK* /* p_cback */) { return return_value; }}; tBTA_SDP_STATUS operator()(tBTA_SDP_DM_CBACK* p_cback) { return body(p_cback); }; @@ -77,7 +77,7 @@ extern struct BTA_SdpEnable BTA_SdpEnable; struct BTA_SdpRemoveRecordByUser { static tBTA_SDP_STATUS return_value; std::function body{ - [](void* user_data) { return return_value; }}; + [](void* /* user_data */) { return return_value; }}; tBTA_SDP_STATUS operator()(void* user_data) { return body(user_data); }; }; extern struct BTA_SdpRemoveRecordByUser BTA_SdpRemoveRecordByUser; @@ -89,9 +89,8 @@ struct BTA_SdpSearch { static tBTA_SDP_STATUS return_value; std::function - body{[](const RawAddress& bd_addr, const bluetooth::Uuid& uuid) { - return return_value; - }}; + body{[](const RawAddress& /* bd_addr */, + const bluetooth::Uuid& /* uuid */) { return return_value; }}; tBTA_SDP_STATUS operator()(const RawAddress& bd_addr, const bluetooth::Uuid& uuid) { return body(bd_addr, uuid); diff --git a/system/test/mock/mock_bta_sys_conn.cc b/system/test/mock/mock_bta_sys_conn.cc index febd7ce9ba9bb24a8f461913f465cb4eda41b23c..23663d575d40f02a47032332a02cd10fcf064d17 100644 --- a/system/test/mock/mock_bta_sys_conn.cc +++ b/system/test/mock/mock_bta_sys_conn.cc @@ -26,86 +26,99 @@ #include "types/hci_role.h" #include "types/raw_address.h" -void bta_sys_app_close(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_app_close(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_app_open(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_app_open(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_busy(tBTA_SYS_ID id, uint8_t app_id, const RawAddress& peer_addr) { +void bta_sys_busy(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_chg_ssr_config(tBTA_SYS_ID id, uint8_t app_id, - uint16_t max_latency, uint16_t min_tout) { +void bta_sys_chg_ssr_config(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + uint16_t /* max_latency */, + uint16_t /* min_tout */) { inc_func_call_count(__func__); } -void bta_sys_collision_register(tBTA_SYS_ID bta_id, - tBTA_SYS_CONN_CBACK* p_cback) { +void bta_sys_collision_register(tBTA_SYS_ID /* bta_id */, + tBTA_SYS_CONN_CBACK* /* p_cback */) { inc_func_call_count(__func__); } -void bta_sys_conn_close(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_conn_close(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_conn_open(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_conn_open(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_idle(tBTA_SYS_ID id, uint8_t app_id, const RawAddress& peer_addr) { +void bta_sys_idle(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_notify_collision(const RawAddress& peer_addr) { +void bta_sys_notify_collision(const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_notify_role_chg(const RawAddress& peer_addr, tHCI_ROLE new_role, - tHCI_STATUS hci_status) { +void bta_sys_notify_role_chg(const RawAddress& /* peer_addr */, + tHCI_ROLE /* new_role */, + tHCI_STATUS /* hci_status */) { inc_func_call_count(__func__); } -void bta_sys_pm_register(tBTA_SYS_CONN_CBACK* p_cback) { +void bta_sys_pm_register(tBTA_SYS_CONN_CBACK* /* p_cback */) { inc_func_call_count(__func__); } -void bta_sys_rm_register(tBTA_SYS_CONN_CBACK* p_cback) { +void bta_sys_sniff_register(tBTA_SYS_SNIFF_CBACK* /* p_cback */) { inc_func_call_count(__func__); } -void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK* p_cback) { +void bta_sys_reset_sniff(uint8_t /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_sco_close(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_rm_register(tBTA_SYS_CONN_CBACK* /* p_cback */) { inc_func_call_count(__func__); } -void bta_sys_sco_open(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK* /* p_cback */) { inc_func_call_count(__func__); } -void bta_sys_sco_register(tBTA_SYS_CONN_SCO_CBACK* p_cback) { +void bta_sys_sco_close(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_sco_unuse(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_sco_open(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_sco_use(tBTA_SYS_ID id, uint8_t app_id, - const RawAddress& peer_addr) { +void bta_sys_sco_register(tBTA_SYS_CONN_SCO_CBACK* /* p_cback */) { inc_func_call_count(__func__); } -void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK* p_cback) { +void bta_sys_sco_unuse(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { inc_func_call_count(__func__); } -void bta_sys_eir_register(tBTA_SYS_EIR_CBACK* p_cback) { +void bta_sys_sco_use(tBTA_SYS_ID /* id */, uint8_t /* app_id */, + const RawAddress& /* peer_addr */) { + inc_func_call_count(__func__); +} +void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK* /* p_cback */) { + inc_func_call_count(__func__); +} +void bta_sys_eir_register(tBTA_SYS_EIR_CBACK* /* p_cback */) { inc_func_call_count(__func__); } void bta_sys_eir_unregister() { inc_func_call_count(__func__); } -void bta_sys_cust_eir_register(tBTA_SYS_CUST_EIR_CBACK* p_cback) { +void bta_sys_cust_eir_register(tBTA_SYS_CUST_EIR_CBACK* /* p_cback */) { + inc_func_call_count(__func__); +} +void bta_sys_add_uuid(uint16_t /* uuid16 */) { inc_func_call_count(__func__); } +void bta_sys_remove_uuid(uint16_t /* uuid16 */) { inc_func_call_count(__func__); } -void bta_sys_add_uuid(uint16_t uuid16) { inc_func_call_count(__func__); } -void bta_sys_remove_uuid(uint16_t uuid16) { inc_func_call_count(__func__); } -void bta_sys_add_cust_uuid(const tBTA_CUSTOM_UUID& curr) { +void bta_sys_add_cust_uuid(const tBTA_CUSTOM_UUID& /* curr */) { inc_func_call_count(__func__); } -void bta_sys_remove_cust_uuid(const tBTA_CUSTOM_UUID& curr) { +void bta_sys_remove_cust_uuid(const tBTA_CUSTOM_UUID& /* curr */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_bta_sys_main.cc b/system/test/mock/mock_bta_sys_main.cc index 56ae8ea8bb31bf51db480815f1187605c8006bae..c081c01a9572c4c5ab4c9f61f38bb2da0e476755 100644 --- a/system/test/mock/mock_bta_sys_main.cc +++ b/system/test/mock/mock_bta_sys_main.cc @@ -36,7 +36,6 @@ namespace bta_sys_main { // Function state capture and return values, if needed struct BTA_sys_signal_hw_error BTA_sys_signal_hw_error; -struct bta_set_forward_hw_failures bta_set_forward_hw_failures; struct bta_sys_deregister bta_sys_deregister; struct bta_sys_disable bta_sys_disable; struct bta_sys_init bta_sys_init; @@ -55,10 +54,6 @@ void BTA_sys_signal_hw_error() { inc_func_call_count(__func__); test::mock::bta_sys_main::BTA_sys_signal_hw_error(); } -void bta_set_forward_hw_failures(bool value) { - inc_func_call_count(__func__); - test::mock::bta_sys_main::bta_set_forward_hw_failures(value); -} void bta_sys_deregister(uint8_t id) { inc_func_call_count(__func__); test::mock::bta_sys_main::bta_sys_deregister(id); @@ -83,7 +78,7 @@ void bta_sys_sendmsg(void* p_msg) { inc_func_call_count(__func__); test::mock::bta_sys_main::bta_sys_sendmsg(p_msg); } -void bta_sys_sendmsg_delayed(void* p_msg, const base::TimeDelta& delay) { +void bta_sys_sendmsg_delayed(void* p_msg, std::chrono::microseconds delay) { inc_func_call_count(__func__); test::mock::bta_sys_main::bta_sys_sendmsg_delayed(p_msg, delay); } diff --git a/system/test/mock/mock_bta_sys_main.h b/system/test/mock/mock_bta_sys_main.h index 5ddf18b41d6eb3303d0d70326be59890704e97a9..e95e44dd5b03ca4f7cf462617b9d5b94001a33df 100644 --- a/system/test/mock/mock_bta_sys_main.h +++ b/system/test/mock/mock_bta_sys_main.h @@ -44,20 +44,11 @@ struct BTA_sys_signal_hw_error { }; extern struct BTA_sys_signal_hw_error BTA_sys_signal_hw_error; -// Name: bta_set_forward_hw_failures -// Params: bool value -// Return: void -struct bta_set_forward_hw_failures { - std::function body{[](bool value) {}}; - void operator()(bool value) { body(value); }; -}; -extern struct bta_set_forward_hw_failures bta_set_forward_hw_failures; - // Name: bta_sys_deregister // Params: uint8_t id // Return: void struct bta_sys_deregister { - std::function body{[](uint8_t id) {}}; + std::function body{[](uint8_t /* id */) {}}; void operator()(uint8_t id) { body(id); }; }; extern struct bta_sys_deregister bta_sys_deregister; @@ -86,7 +77,7 @@ extern struct bta_sys_init bta_sys_init; struct bta_sys_is_register { bool return_value{false}; std::function body{ - [this](uint8_t id) { return return_value; }}; + [this](uint8_t /* id */) { return return_value; }}; bool operator()(uint8_t id) { return body(id); }; }; extern struct bta_sys_is_register bta_sys_is_register; @@ -96,7 +87,7 @@ extern struct bta_sys_is_register bta_sys_is_register; // Return: void struct bta_sys_register { std::function body{ - [](uint8_t id, const tBTA_SYS_REG* p_reg) {}}; + [](uint8_t /* id */, const tBTA_SYS_REG* /* p_reg */) {}}; void operator()(uint8_t id, const tBTA_SYS_REG* p_reg) { body(id, p_reg); }; }; extern struct bta_sys_register bta_sys_register; @@ -105,18 +96,18 @@ extern struct bta_sys_register bta_sys_register; // Params: void* p_msg // Return: void struct bta_sys_sendmsg { - std::function body{[](void* p_msg) {}}; + std::function body{[](void* /* p_msg */) {}}; void operator()(void* p_msg) { body(p_msg); }; }; extern struct bta_sys_sendmsg bta_sys_sendmsg; // Name: bta_sys_sendmsg_delayed -// Params: void* p_msg, const base::TimeDelta& delay +// Params: void* p_msg, std::chrono::microseconds delay // Return: void struct bta_sys_sendmsg_delayed { - std::function body{ - [](void* p_msg, const base::TimeDelta& delay) {}}; - void operator()(void* p_msg, const base::TimeDelta& delay) { + std::function body{ + [](void* /* p_msg */, std::chrono::microseconds /* delay */) {}}; + void operator()(void* p_msg, std::chrono::microseconds delay) { body(p_msg, delay); }; }; @@ -128,8 +119,8 @@ extern struct bta_sys_sendmsg_delayed bta_sys_sendmsg_delayed; struct bta_sys_start_timer { std::function - body{[](alarm_t* alarm, uint64_t interval_ms, uint16_t event, - uint16_t layer_specific) {}}; + body{[](alarm_t* /* alarm */, uint64_t /* interval_ms */, + uint16_t /* event */, uint16_t /* layer_specific */) {}}; void operator()(alarm_t* alarm, uint64_t interval_ms, uint16_t event, uint16_t layer_specific) { body(alarm, interval_ms, event, layer_specific); diff --git a/system/test/mock/mock_bta_sys_utl.cc b/system/test/mock/mock_bta_sys_utl.cc index a098d0770a4fbd6b199aea3b31a07b781bdc0103..68a05ab074cf38c41612832de05e436801ab7461 100644 --- a/system/test/mock/mock_bta_sys_utl.cc +++ b/system/test/mock/mock_bta_sys_utl.cc @@ -24,31 +24,31 @@ #include "bta/include/utl.h" #include "test/common/mock_functions.h" -bool utl_isdialchar(const char d) { +bool utl_isdialchar(const char /* d */) { inc_func_call_count(__func__); return false; } -bool utl_isdialstr(const char* p_s) { +bool utl_isdialstr(const char* /* p_s */) { inc_func_call_count(__func__); return false; } -bool utl_isintstr(const char* p_s) { +bool utl_isintstr(const char* /* p_s */) { inc_func_call_count(__func__); return false; } -bool utl_set_device_class(tBTA_UTL_COD* p_cod, uint8_t cmd) { +bool utl_set_device_class(tBTA_UTL_COD* /* p_cod */, uint8_t /* cmd */) { inc_func_call_count(__func__); return false; } -int utl_strucmp(const char* p_s, const char* p_t) { +int utl_strucmp(const char* /* p_s */, const char* /* p_t */) { inc_func_call_count(__func__); return 0; } -int16_t utl_str2int(const char* p_s) { +int16_t utl_str2int(const char* /* p_s */) { inc_func_call_count(__func__); return 0; } -uint8_t utl_itoa(uint16_t i, char* p_s) { +uint8_t utl_itoa(uint16_t /* i */, char* /* p_s */) { inc_func_call_count(__func__); return 0; } diff --git a/system/test/mock/mock_btif_av.h b/system/test/mock/mock_btif_av.h index ee2fa23a1f530856f0d741748145b3b3391eed36..519c394d96a287ebf4fec01ddae9884a979ea5d3 100644 --- a/system/test/mock/mock_btif_av.h +++ b/system/test/mock/mock_btif_av.h @@ -60,7 +60,7 @@ namespace btif_av { // Return: void struct btif_av_acl_disconnected { std::function body{ - [](const RawAddress& peer_address) {}}; + [](const RawAddress& /* peer_address */) {}}; void operator()(const RawAddress& peer_address) { body(peer_address); }; }; extern struct btif_av_acl_disconnected btif_av_acl_disconnected; @@ -81,7 +81,7 @@ extern struct btif_av_clear_remote_suspend_flag struct btif_av_find_by_handle { static const RawAddress& return_value; std::function body{ - [](tBTA_AV_HNDL bta_handle) { return return_value; }}; + [](tBTA_AV_HNDL /* bta_handle */) { return return_value; }}; const RawAddress& operator()(tBTA_AV_HNDL bta_handle) { return body(bta_handle); }; @@ -166,7 +166,7 @@ extern struct btif_av_is_connected btif_av_is_connected; struct btif_av_is_connected_addr { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -179,7 +179,7 @@ extern struct btif_av_is_connected_addr btif_av_is_connected_addr; struct btif_av_is_peer_edr { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -192,7 +192,7 @@ extern struct btif_av_is_peer_edr btif_av_is_peer_edr; struct btif_av_is_peer_silenced { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -225,7 +225,7 @@ extern struct btif_av_is_source_enabled btif_av_is_source_enabled; struct btif_av_peer_is_connected_sink { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -238,7 +238,7 @@ extern struct btif_av_peer_is_connected_sink btif_av_peer_is_connected_sink; struct btif_av_peer_is_connected_source { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -251,7 +251,7 @@ extern struct btif_av_peer_is_connected_source btif_av_peer_is_connected_source; struct btif_av_peer_is_sink { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -264,7 +264,7 @@ extern struct btif_av_peer_is_sink btif_av_peer_is_sink; struct btif_av_peer_is_source { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -277,7 +277,7 @@ extern struct btif_av_peer_is_source btif_av_peer_is_source; struct btif_av_peer_prefers_mandatory_codec { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -291,7 +291,7 @@ extern struct btif_av_peer_prefers_mandatory_codec struct btif_av_peer_supports_3mbps { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -310,12 +310,12 @@ struct btif_av_report_source_codec_state { const std::vector& codecs_local_capabilities, const std::vector& codecs_selectable_capabilities)> - body{[](const RawAddress& peer_address, - const btav_a2dp_codec_config_t& codec_config, + body{[](const RawAddress& /* peer_address */, + const btav_a2dp_codec_config_t& /* codec_config */, const std::vector& - codecs_local_capabilities, + /* codecs_local_capabilities */, const std::vector& - codecs_selectable_capabilities) {}}; + /* codecs_selectable_capabilities */) {}}; void operator()( const RawAddress& peer_address, const btav_a2dp_codec_config_t& codec_config, @@ -343,7 +343,7 @@ extern struct btif_av_reset_audio_delay btif_av_reset_audio_delay; // Return: void struct btif_av_set_audio_delay { std::function body{ - [](const RawAddress& peer_address, uint16_t delay) {}}; + [](const RawAddress& /* peer_address */, uint16_t /* delay */) {}}; void operator()(const RawAddress& peer_address, uint16_t delay) { body(peer_address, delay); }; @@ -355,7 +355,7 @@ extern struct btif_av_set_audio_delay btif_av_set_audio_delay; // Return: void struct btif_av_set_dynamic_audio_buffer_size { std::function body{ - [](uint8_t dynamic_audio_buffer_size) {}}; + [](uint8_t /* dynamic_audio_buffer_size */) {}}; void operator()(uint8_t dynamic_audio_buffer_size) { body(dynamic_audio_buffer_size); }; @@ -367,7 +367,8 @@ extern struct btif_av_set_dynamic_audio_buffer_size // Params: bool is_low_latency // Return: void struct btif_av_set_low_latency { - std::function body{[](bool is_low_latency) {}}; + std::function body{ + [](bool /* is_low_latency */) {}}; void operator()(bool is_low_latency) { body(is_low_latency); }; }; extern struct btif_av_set_low_latency btif_av_set_low_latency; @@ -388,7 +389,7 @@ extern struct btif_av_sink_active_peer btif_av_sink_active_peer; struct btif_av_sink_execute_service { static bt_status_t return_value; std::function body{ - [](bool enable) { return return_value; }}; + [](bool /* enable */) { return return_value; }}; bt_status_t operator()(bool enable) { return body(enable); }; }; extern struct btif_av_sink_execute_service btif_av_sink_execute_service; @@ -409,7 +410,7 @@ extern struct btif_av_source_active_peer btif_av_source_active_peer; struct btif_av_source_execute_service { static bt_status_t return_value; std::function body{ - [](bool enable) { return return_value; }}; + [](bool /* enable */) { return return_value; }}; bt_status_t operator()(bool enable) { return body(enable); }; }; extern struct btif_av_source_execute_service btif_av_source_execute_service; @@ -419,7 +420,7 @@ extern struct btif_av_source_execute_service btif_av_source_execute_service; // Return: void struct btif_av_src_disconnect_sink { std::function body{ - [](const RawAddress& peer_address) {}}; + [](const RawAddress& /* peer_address */) {}}; void operator()(const RawAddress& peer_address) { body(peer_address); }; }; extern struct btif_av_src_disconnect_sink btif_av_src_disconnect_sink; @@ -466,7 +467,8 @@ extern struct btif_av_stream_start_offload btif_av_stream_start_offload; // Params: bool use_latency_mode // Return: void struct btif_av_stream_start_with_latency { - std::function body{[](bool use_latency_mode) {}}; + std::function body{ + [](bool /* use_latency_mode */) {}}; void operator()(bool use_latency_mode) { body(use_latency_mode); }; }; extern struct btif_av_stream_start_with_latency @@ -487,7 +489,7 @@ extern struct btif_av_stream_started_ready btif_av_stream_started_ready; // Return: void struct btif_av_stream_stop { std::function body{ - [](const RawAddress& peer_address) {}}; + [](const RawAddress& /* peer_address */) {}}; void operator()(const RawAddress& peer_address) { body(peer_address); }; }; extern struct btif_av_stream_stop btif_av_stream_stop; @@ -505,7 +507,7 @@ extern struct btif_av_stream_suspend btif_av_stream_suspend; // Params: int fd // Return: void struct btif_debug_av_dump { - std::function body{[](int fd) {}}; + std::function body{[](int /* fd */) {}}; void operator()(int fd) { body(fd); }; }; extern struct btif_debug_av_dump btif_debug_av_dump; @@ -516,7 +518,7 @@ extern struct btif_debug_av_dump btif_debug_av_dump; struct dump_av_sm_event_name { static const char* return_value; std::function body{ - [](int event) { return return_value; }}; + [](int /* event */) { return return_value; }}; const char* operator()(int event) { return body(event); }; }; extern struct dump_av_sm_event_name dump_av_sm_event_name; @@ -526,7 +528,7 @@ extern struct dump_av_sm_event_name dump_av_sm_event_name; // Return: void struct src_do_suspend_in_main_thread { std::function body{ - [](btif_av_sm_event_t event) {}}; + [](btif_av_sm_event_t /* event */) {}}; void operator()(btif_av_sm_event_t event) { body(event); }; }; extern struct src_do_suspend_in_main_thread src_do_suspend_in_main_thread; diff --git a/system/test/mock/mock_btif_avrcp_service.h b/system/test/mock/mock_btif_avrcp_service.h index 3ba33f735c78d1caeed1e1b877fc250c799f1a31..a0484d3b5bf7e7d53db9948583b953b4d712d6ef 100644 --- a/system/test/mock/mock_btif_avrcp_service.h +++ b/system/test/mock/mock_btif_avrcp_service.h @@ -41,7 +41,7 @@ namespace btif_avrcp_service { // Return: void struct do_in_avrcp_jni { std::function body{ - [](const base::Closure& task) {}}; + [](const base::Closure& /* task */) {}}; void operator()(const base::Closure& task) { body(task); }; }; extern struct do_in_avrcp_jni do_in_avrcp_jni; diff --git a/system/test/mock/mock_btif_bluetooth.cc b/system/test/mock/mock_btif_bluetooth.cc index f293d9d46d0854aac0f28f1e0391a896914c72c1..c5d51ad4411396d3e61b2a8da40618ec73b4fd1a 100644 --- a/system/test/mock/mock_btif_bluetooth.cc +++ b/system/test/mock/mock_btif_bluetooth.cc @@ -49,6 +49,7 @@ struct get_remote_services get_remote_services; struct le_test_mode le_test_mode; struct set_remote_device_property set_remote_device_property; struct set_hal_cbacks set_hal_cbacks; +struct invoke_switch_buffer_size_cb invoke_switch_buffer_size_cb; } // namespace btif_bluetooth } // namespace mock @@ -108,5 +109,10 @@ void set_hal_cbacks(bt_callbacks_t* callbacks) { inc_func_call_count(__func__); test::mock::btif_bluetooth::set_hal_cbacks(callbacks); } +void invoke_switch_buffer_size_cb(bool invoke_switch_buffer_size_cb) { + inc_func_call_count(__func__); + test::mock::btif_bluetooth::invoke_switch_buffer_size_cb( + invoke_switch_buffer_size_cb); +} // END mockcify generation diff --git a/system/test/mock/mock_btif_bluetooth.h b/system/test/mock/mock_btif_bluetooth.h index 4b9479d9e485a24c2731384a870f5cc1d208dfc7..fb06c563a1c984b33a6643f7c44b2bfd1d0f6615 100644 --- a/system/test/mock/mock_btif_bluetooth.h +++ b/system/test/mock/mock_btif_bluetooth.h @@ -62,7 +62,8 @@ extern struct is_restricted_mode is_restricted_mode; // Params: uint8_t enable // Returns: int struct dut_mode_configure { - std::function body{[](uint8_t enable) { return 0; }}; + std::function body{ + [](uint8_t /* enable */) { return 0; }}; int operator()(uint8_t enable) { return body(enable); }; }; extern struct dut_mode_configure dut_mode_configure; @@ -70,8 +71,11 @@ extern struct dut_mode_configure dut_mode_configure; // Params: uint16_t opcode, uint8_t* buf, uint8_t len // Returns: int struct dut_mode_send { - std::function body{ - [](uint16_t opcode, uint8_t* buf, uint8_t len) { return 0; }}; + std::function + body{[](uint16_t /* opcode */, uint8_t* /* buf */, uint8_t /* len */) { + return 0; + }}; int operator()(uint16_t opcode, uint8_t* buf, uint8_t len) { return body(opcode, buf, len); }; @@ -91,7 +95,7 @@ extern struct get_common_criteria_config_compare_result // Returns: int struct get_remote_device_properties { std::function body{ - [](RawAddress* remote_addr) { return 0; }}; + [](RawAddress* /* remote_addr */) { return 0; }}; int operator()(RawAddress* remote_addr) { return body(remote_addr); }; }; extern struct get_remote_device_properties get_remote_device_properties; @@ -100,7 +104,9 @@ extern struct get_remote_device_properties get_remote_device_properties; // Returns: int struct get_remote_device_property { std::function body{ - [](RawAddress* remote_addr, bt_property_type_t type) { return 0; }}; + [](RawAddress* /* remote_addr */, bt_property_type_t /* type */) { + return 0; + }}; int operator()(RawAddress* remote_addr, bt_property_type_t type) { return body(remote_addr, type); }; @@ -111,7 +117,7 @@ extern struct get_remote_device_property get_remote_device_property; // Returns: int struct get_remote_services { std::function body{ - [](RawAddress* remote_addr) { return 0; }}; + [](RawAddress* /* remote_addr */) { return 0; }}; int operator()(RawAddress* remote_addr) { return body(remote_addr); }; }; extern struct get_remote_services get_remote_services; @@ -120,7 +126,9 @@ extern struct get_remote_services get_remote_services; // Returns: int struct le_test_mode { std::function body{ - [](uint16_t opcode, uint8_t* buf, uint8_t len) { return 0; }}; + [](uint16_t /* opcode */, uint8_t* /* buf */, uint8_t /* len */) { + return 0; + }}; int operator()(uint16_t opcode, uint8_t* buf, uint8_t len) { return body(opcode, buf, len); }; @@ -131,9 +139,8 @@ extern struct le_test_mode le_test_mode; // Returns: int struct set_remote_device_property { std::function - body{[](RawAddress* remote_addr, const bt_property_t* property) { - return 0; - }}; + body{[](RawAddress* /* remote_addr */, + const bt_property_t* /* property */) { return 0; }}; int operator()(RawAddress* remote_addr, const bt_property_t* property) { return body(remote_addr, property); }; @@ -144,11 +151,22 @@ extern struct set_remote_device_property set_remote_device_property; // Returns: void struct set_hal_cbacks { std::function body{ - [](bt_callbacks_t* callbacks) { ; }}; + [](bt_callbacks_t* /* callbacks */) { ; }}; void operator()(bt_callbacks_t* callbacks) { body(callbacks); }; }; extern struct set_hal_cbacks set_hal_cbacks; +// Name: invoke_switch_buffer_size_cb +// Params: bool invoke_switch_buffer_size_cb +// Returns: void +struct invoke_switch_buffer_size_cb { + std::function body{[](bool) {}}; + void operator()(bool invoke_switch_buffer_size_cb) { + body(invoke_switch_buffer_size_cb); + }; +}; +extern struct invoke_switch_buffer_size_cb invoke_switch_buffer_size_cb; + } // namespace btif_bluetooth } // namespace mock } // namespace test diff --git a/system/test/mock/mock_btif_bqr.cc b/system/test/mock/mock_btif_bqr.cc index 8e2ffb38ba0deb536efbe8c03fed4ba131aebb66..b6347043739e9136d8383343d844c00b983a1465 100644 --- a/system/test/mock/mock_btif_bqr.cc +++ b/system/test/mock/mock_btif_bqr.cc @@ -26,11 +26,11 @@ namespace bluetooth { namespace bqr { -void DumpLmpLlMessage(uint8_t length, const uint8_t* p_event) { +void DumpLmpLlMessage(uint8_t /* length */, const uint8_t* /* p_event */) { inc_func_call_count(__func__); } -void DumpBtScheduling(uint8_t length, const uint8_t* p_event) { +void DumpBtScheduling(uint8_t /* length */, const uint8_t* /* p_event */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_btif_bta_pan_co_rx.h b/system/test/mock/mock_btif_bta_pan_co_rx.h index 9f5e90e45c09696e550e4bcdf8946c339a7ef4b7..d9059c54273b7780e7aa7dfdc7f7d20ab9899a6b 100644 --- a/system/test/mock/mock_btif_bta_pan_co_rx.h +++ b/system/test/mock/mock_btif_bta_pan_co_rx.h @@ -37,7 +37,7 @@ namespace btif_bta_pan_co_rx { // Returns: uint8_t struct bta_pan_co_init { std::function body{ - [](uint8_t* q_level) { return 0; }}; + [](uint8_t* /* q_level */) { return 0; }}; uint8_t operator()(uint8_t* q_level) { return body(q_level); }; }; extern struct bta_pan_co_init bta_pan_co_init; @@ -46,7 +46,7 @@ extern struct bta_pan_co_init bta_pan_co_init; // Returns: void struct bta_pan_co_close { std::function body{ - [](uint16_t handle, uint8_t app_id) { ; }}; + [](uint16_t /* handle */, uint8_t /* app_id */) { ; }}; void operator()(uint16_t handle, uint8_t app_id) { body(handle, app_id); }; }; extern struct bta_pan_co_close bta_pan_co_close; @@ -57,8 +57,9 @@ extern struct bta_pan_co_close bta_pan_co_close; struct bta_pan_co_mfilt_ind { std::function - body{[](uint16_t handle, bool indication, tBTA_PAN_STATUS result, - uint16_t len, uint8_t* p_filters) { ; }}; + body{[](uint16_t /* handle */, bool /* indication */, + tBTA_PAN_STATUS /* result */, uint16_t /* len */, + uint8_t* /* p_filters */) { ; }}; void operator()(uint16_t handle, bool indication, tBTA_PAN_STATUS result, uint16_t len, uint8_t* p_filters) { body(handle, indication, result, len, p_filters); @@ -72,8 +73,9 @@ extern struct bta_pan_co_mfilt_ind bta_pan_co_mfilt_ind; struct bta_pan_co_pfilt_ind { std::function - body{[](uint16_t handle, bool indication, tBTA_PAN_STATUS result, - uint16_t len, uint8_t* p_filters) { ; }}; + body{[](uint16_t /* handle */, bool /* indication */, + tBTA_PAN_STATUS /* result */, uint16_t /* len */, + uint8_t* /* p_filters */) { ; }}; void operator()(uint16_t handle, bool indication, tBTA_PAN_STATUS result, uint16_t len, uint8_t* p_filters) { body(handle, indication, result, len, p_filters); @@ -85,7 +87,7 @@ extern struct bta_pan_co_pfilt_ind bta_pan_co_pfilt_ind; // bool enable Returns: void struct bta_pan_co_rx_flow { std::function body{ - [](uint16_t handle, uint8_t app_id, bool enable) { ; }}; + [](uint16_t /* handle */, uint8_t /* app_id */, bool /* enable */) { ; }}; void operator()(uint16_t handle, uint8_t app_id, bool enable) { body(handle, app_id, enable); }; @@ -96,7 +98,7 @@ extern struct bta_pan_co_rx_flow bta_pan_co_rx_flow; // Returns: void struct bta_pan_co_rx_path { std::function body{ - [](uint16_t handle, uint8_t app_id) { ; }}; + [](uint16_t /* handle */, uint8_t /* app_id */) { ; }}; void operator()(uint16_t handle, uint8_t app_id) { body(handle, app_id); }; }; extern struct bta_pan_co_rx_path bta_pan_co_rx_path; @@ -105,7 +107,7 @@ extern struct bta_pan_co_rx_path bta_pan_co_rx_path; // Returns: void struct bta_pan_co_tx_path { std::function body{ - [](uint16_t handle, uint8_t app_id) { ; }}; + [](uint16_t /* handle */, uint8_t /* app_id */) { ; }}; void operator()(uint16_t handle, uint8_t app_id) { body(handle, app_id); }; }; extern struct bta_pan_co_tx_path bta_pan_co_tx_path; diff --git a/system/test/mock/mock_btif_co_bta_av_co.cc b/system/test/mock/mock_btif_co_bta_av_co.cc index 1cbad4fc1342cc7f61a42df177a1bc5bfe5c7823..94156c352e0483679d442d37a752ba3eaef27e17 100644 --- a/system/test/mock/mock_btif_co_bta_av_co.cc +++ b/system/test/mock/mock_btif_co_bta_av_co.cc @@ -197,9 +197,11 @@ btav_a2dp_scmst_info_t bta_av_co_get_scmst_info( return test::mock::btif_co_bta_av_co::bta_av_co_get_scmst_info(peer_address); } void bta_av_co_init( - const std::vector& codec_priorities) { + const std::vector& codec_priorities, + std::vector* supported_codecs) { inc_func_call_count(__func__); - test::mock::btif_co_bta_av_co::bta_av_co_init(codec_priorities); + test::mock::btif_co_bta_av_co::bta_av_co_init(codec_priorities, + supported_codecs); } bool bta_av_co_is_supported_codec(btav_a2dp_codec_index_t codec_index) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_btif_co_bta_av_co.h b/system/test/mock/mock_btif_co_bta_av_co.h index 82783bcafa41ab328e58b1fd664989488262e895..69de9c777982436cd9ecfc5889cd287c8662b5e6 100644 --- a/system/test/mock/mock_btif_co_bta_av_co.h +++ b/system/test/mock/mock_btif_co_bta_av_co.h @@ -51,7 +51,8 @@ namespace btif_co_bta_av_co { struct bta_av_co_audio_close { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) { body(bta_av_handle, peer_address); }; @@ -64,8 +65,8 @@ extern struct bta_av_co_audio_close bta_av_co_audio_close; struct bta_av_co_audio_delay { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - uint16_t delay) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */, uint16_t /* delay */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t delay) { body(bta_av_handle, peer_address, delay); @@ -81,9 +82,10 @@ struct bta_av_co_audio_disc_res { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - uint8_t num_seps, uint8_t num_sinks, uint8_t num_sources, - uint16_t uuid_local) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */, uint8_t /* num_seps */, + uint8_t /* num_sinks */, uint8_t /* num_sources */, + uint16_t /* uuid_local */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint8_t num_seps, uint8_t num_sinks, uint8_t num_sources, uint16_t uuid_local) { @@ -99,7 +101,8 @@ extern struct bta_av_co_audio_disc_res bta_av_co_audio_disc_res; struct bta_av_co_audio_drop { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) { body(bta_av_handle, peer_address); }; @@ -116,10 +119,11 @@ struct bta_av_co_audio_getconfig { tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid, uint8_t* p_num_protect, uint8_t* p_protect_info)> - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid, - uint8_t* p_num_protect, - uint8_t* p_protect_info) { return return_value; }}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */, uint8_t* /* p_codec_info */, + uint8_t* /* p_sep_info_idx */, uint8_t /* seid */, + uint8_t* /* p_num_protect */, + uint8_t* /* p_protect_info */) { return return_value; }}; tA2DP_STATUS operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint8_t* p_codec_info, uint8_t* p_sep_info_idx, uint8_t seid, @@ -137,9 +141,8 @@ struct bta_av_co_audio_init { static bool return_value; std::function - body{[](btav_a2dp_codec_index_t codec_index, AvdtpSepConfig* p_cfg) { - return return_value; - }}; + body{[](btav_a2dp_codec_index_t /* codec_index */, + AvdtpSepConfig* /* p_cfg */) { return return_value; }}; bool operator()(btav_a2dp_codec_index_t codec_index, AvdtpSepConfig* p_cfg) { return body(codec_index, p_cfg); }; @@ -152,8 +155,8 @@ extern struct bta_av_co_audio_init bta_av_co_audio_init; struct bta_av_co_audio_open { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - uint16_t mtu) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */, uint16_t /* mtu */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t mtu) { body(bta_av_handle, peer_address, mtu); @@ -170,10 +173,11 @@ struct bta_av_co_audio_setconfig { const uint8_t* p_codec_info, uint8_t seid, uint8_t num_protect, const uint8_t* p_protect_info, uint8_t t_local_sep, uint8_t avdt_handle)> - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - const uint8_t* p_codec_info, uint8_t seid, uint8_t num_protect, - const uint8_t* p_protect_info, uint8_t t_local_sep, - uint8_t avdt_handle) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */, + const uint8_t* /* p_codec_info */, uint8_t /* seid */, + uint8_t /* num_protect */, const uint8_t* /* p_protect_info */, + uint8_t /* t_local_sep */, uint8_t /* avdt_handle */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, const uint8_t* p_codec_info, uint8_t seid, uint8_t num_protect, const uint8_t* p_protect_info, @@ -190,7 +194,7 @@ extern struct bta_av_co_audio_setconfig bta_av_co_audio_setconfig; struct bta_av_co_audio_source_data_path { static BT_HDR* return_value; std::function - body{[](const uint8_t* p_codec_info, uint32_t* p_timestamp) { + body{[](const uint8_t* /* p_codec_info */, uint32_t* /* p_timestamp */) { return return_value; }}; BT_HDR* operator()(const uint8_t* p_codec_info, uint32_t* p_timestamp) { @@ -205,8 +209,10 @@ extern struct bta_av_co_audio_source_data_path bta_av_co_audio_source_data_path; struct bta_av_co_audio_start { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - const uint8_t* p_codec_info, bool* p_no_rtp_header) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */, + const uint8_t* /* p_codec_info */, + bool* /* p_no_rtp_header */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, const uint8_t* p_codec_info, bool* p_no_rtp_header) { body(bta_av_handle, peer_address, p_codec_info, p_no_rtp_header); @@ -220,7 +226,8 @@ extern struct bta_av_co_audio_start bta_av_co_audio_start; struct bta_av_co_audio_stop { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address) { body(bta_av_handle, peer_address); }; @@ -233,8 +240,8 @@ extern struct bta_av_co_audio_stop bta_av_co_audio_stop; struct bta_av_co_audio_update_mtu { std::function - body{[](tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, - uint16_t mtu) {}}; + body{[](tBTA_AV_HNDL /* bta_av_handle */, + const RawAddress& /* peer_address */, uint16_t /* mtu */) {}}; void operator()(tBTA_AV_HNDL bta_av_handle, const RawAddress& peer_address, uint16_t mtu) { body(bta_av_handle, peer_address, mtu); @@ -270,8 +277,8 @@ extern struct bta_av_co_get_encoder_interface bta_av_co_get_encoder_interface; struct bta_av_co_get_peer_params { std::function - body{[](const RawAddress& peer_address, - tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) {}}; + body{[](const RawAddress& /* peer_address */, + tA2DP_ENCODER_INIT_PEER_PARAMS* /* p_peer_params */) {}}; void operator()(const RawAddress& peer_address, tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params) { body(peer_address, p_peer_params); @@ -285,7 +292,7 @@ extern struct bta_av_co_get_peer_params bta_av_co_get_peer_params; struct bta_av_co_get_scmst_info { static btav_a2dp_scmst_info_t return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; btav_a2dp_scmst_info_t operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -297,12 +304,14 @@ extern struct bta_av_co_get_scmst_info bta_av_co_get_scmst_info; // Return: void struct bta_av_co_init { std::function& codec_priorities)> - body{ - [](const std::vector& codec_priorities) {}}; - void operator()( - const std::vector& codec_priorities) { - body(codec_priorities); + const std::vector& codec_priorities, + std::vector* supported_codecs)> + body{[](const std::vector< + btav_a2dp_codec_config_t>& /* codec_priorities */, + std::vector* /* supported_codecs */) {}}; + void operator()(const std::vector& codec_priorities, + std::vector* supported_codecs) { + body(codec_priorities, supported_codecs); }; }; extern struct bta_av_co_init bta_av_co_init; @@ -313,7 +322,7 @@ extern struct bta_av_co_init bta_av_co_init; struct bta_av_co_is_supported_codec { static bool return_value; std::function body{ - [](btav_a2dp_codec_index_t codec_index) { return return_value; }}; + [](btav_a2dp_codec_index_t /* codec_index */) { return return_value; }}; bool operator()(btav_a2dp_codec_index_t codec_index) { return body(codec_index); }; @@ -326,7 +335,7 @@ extern struct bta_av_co_is_supported_codec bta_av_co_is_supported_codec; struct bta_av_co_set_active_peer { static bool return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; bool operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -339,7 +348,7 @@ extern struct bta_av_co_set_active_peer bta_av_co_set_active_peer; struct bta_av_co_set_codec_audio_config { static bool return_value; std::function body{ - [](const btav_a2dp_codec_config_t& codec_audio_config) { + [](const btav_a2dp_codec_config_t& /* codec_audio_config */) { return return_value; }}; bool operator()(const btav_a2dp_codec_config_t& codec_audio_config) { @@ -356,9 +365,9 @@ struct bta_av_co_set_codec_user_config { std::function - body{[](const RawAddress& peer_address, - const btav_a2dp_codec_config_t& codec_user_config, - bool* p_restart_output) { return return_value; }}; + body{[](const RawAddress& /* peer_address */, + const btav_a2dp_codec_config_t& /* codec_user_config */, + bool* /* p_restart_output */) { return return_value; }}; bool operator()(const RawAddress& peer_address, const btav_a2dp_codec_config_t& codec_user_config, bool* p_restart_output) { @@ -383,7 +392,7 @@ extern struct bta_av_get_a2dp_current_codec bta_av_get_a2dp_current_codec; struct bta_av_get_a2dp_peer_current_codec { static A2dpCodecConfig* return_value; std::function body{ - [](const RawAddress& peer_address) { return return_value; }}; + [](const RawAddress& /* peer_address */) { return return_value; }}; A2dpCodecConfig* operator()(const RawAddress& peer_address) { return body(peer_address); }; @@ -395,7 +404,7 @@ extern struct bta_av_get_a2dp_peer_current_codec // Params: int fd // Return: void struct btif_a2dp_codec_debug_dump { - std::function body{[](int fd) {}}; + std::function body{[](int /* fd */) {}}; void operator()(int fd) { body(fd); }; }; extern struct btif_a2dp_codec_debug_dump btif_a2dp_codec_debug_dump; @@ -404,4 +413,4 @@ extern struct btif_a2dp_codec_debug_dump btif_a2dp_codec_debug_dump; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_btif_co_bta_dm_co.cc b/system/test/mock/mock_btif_co_bta_dm_co.cc index 63cbfc13899eb0ae0fa890fc1fc869d055443f0e..d7ccf69a36b4a1bc0d3d41ec2a14928304c031dc 100644 --- a/system/test/mock/mock_btif_co_bta_dm_co.cc +++ b/system/test/mock/mock_btif_co_bta_dm_co.cc @@ -20,18 +20,17 @@ #include -#include "bta/include/bta_api.h" #include "bta/include/bta_sec_api.h" #include "bta/sys/bta_sys.h" #include "internal_include/bte_appl.h" -#include "stack/include/btm_api_types.h" tBTE_APPL_CFG bte_appl_cfg = { BTA_LE_AUTH_REQ_SC_MITM_BOND, // Authentication requirements BTM_IO_CAP_UNKNOWN, BTM_BLE_INITIATOR_KEY_SIZE, BTM_BLE_RESPONDER_KEY_SIZE, BTM_BLE_MAX_KEY_SIZE}; -bool bta_dm_co_get_compress_memory(tBTA_SYS_ID id, uint8_t** memory_p, - uint32_t* memory_size) { +bool bta_dm_co_get_compress_memory(tBTA_SYS_ID /* id */, + uint8_t** /* memory_p */, + uint32_t* /* memory_size */) { return true; } diff --git a/system/test/mock/mock_btif_co_bta_hh_co.cc b/system/test/mock/mock_btif_co_bta_hh_co.cc index 35c20aeb394cf48c6fa6c3528c8343bc3dbced00..0fd0bc1b6e6dbf3a70eb93064466995e4792d255 100644 --- a/system/test/mock/mock_btif_co_bta_hh_co.cc +++ b/system/test/mock/mock_btif_co_bta_hh_co.cc @@ -27,47 +27,52 @@ #include "test/common/mock_functions.h" #include "types/raw_address.h" -int bta_hh_co_write(int fd, uint8_t* rpt, uint16_t len) { +int bta_hh_co_write(int /* fd */, uint8_t* /* rpt */, uint16_t /* len */) { inc_func_call_count(__func__); return 0; } -tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load(const RawAddress& remote_bda, - uint8_t* p_num_rpt, - uint8_t app_id) { +tBTA_HH_RPT_CACHE_ENTRY* bta_hh_le_co_cache_load( + const tAclLinkSpec& /* link_spec */, uint8_t* /* p_num_rpt */, + uint8_t /* app_id */) { inc_func_call_count(__func__); return nullptr; } -void bta_hh_co_close(btif_hh_device_t* p_dev) { inc_func_call_count(__func__); } -void bta_hh_co_data(uint8_t dev_handle, uint8_t* p_rpt, uint16_t len, - tBTA_HH_PROTO_MODE mode, uint8_t sub_class, - uint8_t ctry_code, const RawAddress& peer_addr, - uint8_t app_id) { +void bta_hh_co_close(btif_hh_device_t* /* p_dev */) { inc_func_call_count(__func__); } -void bta_hh_co_get_rpt_rsp(uint8_t dev_handle, uint8_t status, - const uint8_t* p_rpt, uint16_t len) { +void bta_hh_co_data(uint8_t /* dev_handle */, uint8_t* /* p_rpt */, + uint16_t /* len */, tBTA_HH_PROTO_MODE /* mode */, + uint8_t /* sub_class */, uint8_t /* ctry_code */, + const tAclLinkSpec& /* link_spec */, uint8_t /* app_id */) { inc_func_call_count(__func__); } -bool bta_hh_co_open(uint8_t dev_handle, uint8_t sub_class, - tBTA_HH_ATTR_MASK attr_mask, uint8_t app_id) { +void bta_hh_co_get_rpt_rsp(uint8_t /* dev_handle */, uint8_t /* status */, + const uint8_t* /* p_rpt */, uint16_t /* len */) { + inc_func_call_count(__func__); +} +bool bta_hh_co_open(uint8_t /* dev_handle */, uint8_t /* sub_class */, + tBTA_HH_ATTR_MASK /* attr_mask */, uint8_t /* app_id */) { inc_func_call_count(__func__); return true; } -void bta_hh_co_send_hid_info(btif_hh_device_t* p_dev, const char* dev_name, - uint16_t vendor_id, uint16_t product_id, - uint16_t version, uint8_t ctry_code, int dscp_len, - uint8_t* p_dscp) { +void bta_hh_co_send_hid_info(btif_hh_device_t* /* p_dev */, + const char* /* dev_name */, + uint16_t /* vendor_id */, + uint16_t /* product_id */, uint16_t /* version */, + uint8_t /* ctry_code */, int /* dscp_len */, + uint8_t* /* p_dscp */) { inc_func_call_count(__func__); } -void bta_hh_co_set_rpt_rsp(uint8_t dev_handle, uint8_t status) { +void bta_hh_co_set_rpt_rsp(uint8_t /* dev_handle */, uint8_t /* status */) { inc_func_call_count(__func__); } -void bta_hh_le_co_reset_rpt_cache(const RawAddress& remote_bda, - uint8_t app_id) { +void bta_hh_le_co_reset_rpt_cache(const tAclLinkSpec& /* link_spec */, + uint8_t /* app_id */) { inc_func_call_count(__func__); } -void bta_hh_le_co_rpt_info(const RawAddress& remote_bda, - tBTA_HH_RPT_CACHE_ENTRY* p_entry, uint8_t app_id) { +void bta_hh_le_co_rpt_info(const tAclLinkSpec& /* link_spec */, + tBTA_HH_RPT_CACHE_ENTRY* /* p_entry */, + uint8_t /* app_id */) { inc_func_call_count(__func__); } -void uhid_set_non_blocking(int fd) { inc_func_call_count(__func__); } +void uhid_set_non_blocking(int /* fd */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_btif_config.h b/system/test/mock/mock_btif_config.h index 153fd09e63ec258bb1729d3522b818ff9d6196bd..68466fa62c02fcabb41f257a2814a0e0eb124a9c 100644 --- a/system/test/mock/mock_btif_config.h +++ b/system/test/mock/mock_btif_config.h @@ -22,6 +22,7 @@ */ #include +#include #include #include @@ -41,7 +42,9 @@ namespace btif_config { // Returns: bool struct btif_get_device_clockoffset { std::function body{ - [](const RawAddress& bda, int* p_clock_offset) { return false; }}; + [](const RawAddress& /* bda */, int* /* p_clock_offset */) { + return false; + }}; bool operator()(const RawAddress& bda, int* p_clock_offset) { return body(bda, p_clock_offset); }; @@ -51,7 +54,9 @@ struct btif_get_device_clockoffset { // Returns: bool struct btif_set_device_clockoffset { std::function body{ - [](const RawAddress& bda, int clock_offset) { return false; }}; + [](const RawAddress& /* bda */, int /* clock_offset */) { + return false; + }}; bool operator()(const RawAddress& bda, int clock_offset) { return body(bda, clock_offset); }; @@ -61,7 +66,9 @@ struct btif_set_device_clockoffset { // Returns: bool struct btif_config_exist { std::function body{ - [](const std::string& section, const std::string& key) { return false; }}; + [](const std::string& /* section */, const std::string& /* key */) { + return false; + }}; bool operator()(const std::string& section, const std::string& key) { return body(section, key); }; @@ -73,9 +80,8 @@ extern struct btif_config_exist btif_config_exist; struct btif_config_get_int { std::function - body{[](const std::string& section, const std::string& key, int* value) { - return false; - }}; + body{[](const std::string& /* section */, const std::string& /* key */, + int* /* value */) { return false; }}; bool operator()(const std::string& section, const std::string& key, int* value) { return body(section, key, value); @@ -88,9 +94,8 @@ extern struct btif_config_get_int btif_config_get_int; struct btif_config_set_int { std::function - body{[](const std::string& section, const std::string& key, int value) { - return false; - }}; + body{[](const std::string& /* section */, const std::string& /* key */, + int /* value */) { return false; }}; bool operator()(const std::string& section, const std::string& key, int value) { return body(section, key, value); @@ -103,8 +108,8 @@ extern struct btif_config_set_int btif_config_set_int; struct btif_config_get_uint64 { std::function - body{[](const std::string& section, const std::string& key, - uint64_t* value) { return false; }}; + body{[](const std::string& /* section */, const std::string& /* key */, + uint64_t* /* value */) { return false; }}; bool operator()(const std::string& section, const std::string& key, uint64_t* value) { return body(section, key, value); @@ -117,8 +122,8 @@ extern struct btif_config_get_uint64 btif_config_get_uint64; struct btif_config_set_uint64 { std::function - body{[](const std::string& section, const std::string& key, - uint64_t value) { return false; }}; + body{[](const std::string& /* section */, const std::string& /* key */, + uint64_t /* value */) { return false; }}; bool operator()(const std::string& section, const std::string& key, uint64_t value) { return body(section, key, value); @@ -131,8 +136,8 @@ extern struct btif_config_set_uint64 btif_config_set_uint64; struct btif_config_get_str { std::function - body{[](const std::string& section, const std::string& key, char* value, - int* size_bytes) { return false; }}; + body{[](const std::string& /* section */, const std::string& /* key */, + char* /* value */, int* /* size_bytes */) { return false; }}; bool operator()(const std::string& section, const std::string& key, char* value, int* size_bytes) { return body(section, key, value, size_bytes); @@ -145,8 +150,8 @@ extern struct btif_config_get_str btif_config_get_str; struct btif_config_set_str { std::function - body{[](const std::string& section, const std::string& key, - const std::string& value) { return false; }}; + body{[](const std::string& /* section */, const std::string& /* key */, + const std::string& /* value */) { return false; }}; bool operator()(const std::string& section, const std::string& key, const std::string& value) { return body(section, key, value); @@ -159,8 +164,8 @@ extern struct btif_config_set_str btif_config_set_str; struct btif_config_get_bin { std::function - body{[](const std::string& section, const std::string& key, - uint8_t* value, size_t* length) { return false; }}; + body{[](const std::string& /* section */, const std::string& /* key */, + uint8_t* /* value */, size_t* /* length */) { return false; }}; bool operator()(const std::string& section, const std::string& key, uint8_t* value, size_t* length) { return body(section, key, value, length); @@ -172,8 +177,9 @@ extern struct btif_config_get_bin btif_config_get_bin; // Returns: size_t struct btif_config_get_bin_length { std::function - body{ - [](const std::string& section, const std::string& key) { return 0; }}; + body{[](const std::string& /* section */, const std::string& /* key */) { + return 0; + }}; size_t operator()(const std::string& section, const std::string& key) { return body(section, key); }; @@ -185,8 +191,9 @@ extern struct btif_config_get_bin_length btif_config_get_bin_length; struct btif_config_set_bin { std::function - body{[](const std::string& section, const std::string& key, - const uint8_t* value, size_t length) { return false; }}; + body{[](const std::string& /* section */, const std::string& /* key */, + const uint8_t* /* value */, + size_t /* length */) { return false; }}; bool operator()(const std::string& section, const std::string& key, const uint8_t* value, size_t length) { return body(section, key, value, length); @@ -208,7 +215,9 @@ extern struct btif_config_get_paired_devices btif_config_get_paired_devices; // Returns: bool struct btif_config_remove { std::function body{ - [](const std::string& section, const std::string& key) { return false; }}; + [](const std::string& /* section */, const std::string& /* key */) { + return false; + }}; bool operator()(const std::string& section, const std::string& key) { return body(section, key); }; @@ -219,10 +228,8 @@ extern struct btif_config_remove btif_config_remove; // Returns: void struct btif_config_remove_device { std::function body{ - [](const std::string& section) { return; }}; - void operator()(const std::string& section) { - return; - }; + [](const std::string& /* section */) { return; }}; + void operator()(const std::string& /* section */) { return; }; }; extern struct btif_config_remove_device btif_config_remove_device; // Name: btif_config_clear @@ -237,7 +244,7 @@ extern struct btif_config_clear btif_config_clear; // Params: int fd // Returns: void struct btif_debug_config_dump { - std::function body{[](int fd) {}}; + std::function body{[](int /* fd */) {}}; void operator()(int fd) { body(fd); }; }; extern struct btif_debug_config_dump btif_debug_config_dump; diff --git a/system/test/mock/mock_btif_core.cc b/system/test/mock/mock_btif_core.cc index c031b2cef64717f3cd631ee1bd7f129b3f1dece1..7c90eab5efdce8659b67cf07bb18d2e2cc5069ea 100644 --- a/system/test/mock/mock_btif_core.cc +++ b/system/test/mock/mock_btif_core.cc @@ -26,7 +26,6 @@ #include "bta/include/bta_api.h" #include "btif/include/btif_common.h" #include "include/hardware/bluetooth.h" -#include "test/common/jni_thread.h" #include "test/common/mock_functions.h" #include "types/raw_address.h" @@ -34,11 +33,7 @@ bool btif_is_dut_mode() { inc_func_call_count(__func__); return false; } -bool is_on_jni_thread() { - inc_func_call_count(__func__); - return false; -} -bt_property_t* property_deep_copy(const bt_property_t* prop) { +bt_property_t* property_deep_copy(const bt_property_t* /* prop */) { inc_func_call_count(__func__); return nullptr; } @@ -50,25 +45,9 @@ bt_status_t btif_init_bluetooth() { inc_func_call_count(__func__); return BT_STATUS_SUCCESS; } -bt_status_t btif_set_dynamic_audio_buffer_size(int codec, int size) { - inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; -} -bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, - char* p_params, int param_len, - tBTIF_COPY_CBACK* p_copy_cback) { - inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; -} -bt_status_t do_in_jni_thread(base::OnceClosure task) { - inc_func_call_count(__func__); - do_in_jni_thread_task_queue.push(std::move(task)); - return BT_STATUS_SUCCESS; -} -bt_status_t do_in_jni_thread(const base::Location& from_here, - base::OnceClosure task) { +bt_status_t btif_set_dynamic_audio_buffer_size(int /* codec */, + int /* size */) { inc_func_call_count(__func__); - do_in_jni_thread_task_queue.push(std::move(task)); return BT_STATUS_SUCCESS; } int btif_is_enabled(void) { @@ -79,44 +58,47 @@ tBTA_SERVICE_MASK btif_get_enabled_services_mask(void) { inc_func_call_count(__func__); return 0; } -void DynamicAudiobufferSizeCompleteCallback(tBTM_VSC_CMPL* p_vsc_cmpl_params) { +void btif_adapter_properties_evt(bt_status_t /* status */, + uint32_t /* num_props */, + bt_property_t* /* p_props */) { inc_func_call_count(__func__); } -void btif_adapter_properties_evt(bt_status_t status, uint32_t num_props, - bt_property_t* p_props) { +void btif_disable_service(tBTA_SERVICE_ID /* service_id */) { inc_func_call_count(__func__); } -void btif_disable_service(tBTA_SERVICE_ID service_id) { +void btif_dut_mode_configure(uint8_t /* enable */) { inc_func_call_count(__func__); } -void btif_dut_mode_configure(uint8_t enable) { inc_func_call_count(__func__); } -void btif_dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len) { +void btif_dut_mode_send(uint16_t /* opcode */, uint8_t* /* buf */, + uint8_t /* len */) { inc_func_call_count(__func__); } void btif_enable_bluetooth_evt() { inc_func_call_count(__func__); } -void btif_enable_service(tBTA_SERVICE_ID service_id) { +void btif_enable_service(tBTA_SERVICE_ID /* service_id */) { inc_func_call_count(__func__); } void btif_get_adapter_properties(void) { inc_func_call_count(__func__); } -void btif_get_adapter_property(bt_property_type_t type) { +void btif_get_adapter_property(bt_property_type_t /* type */) { inc_func_call_count(__func__); } -void btif_get_remote_device_properties(RawAddress remote_addr) { +void btif_get_remote_device_properties(RawAddress /* remote_addr */) { inc_func_call_count(__func__); } -void btif_get_remote_device_property(RawAddress remote_addr, - bt_property_type_t type) { +void btif_get_remote_device_property(RawAddress /* remote_addr */, + bt_property_type_t /* type */) { inc_func_call_count(__func__); } void btif_init_ok() { inc_func_call_count(__func__); } -void btif_remote_properties_evt(bt_status_t status, RawAddress* remote_addr, - uint32_t num_props, bt_property_t* p_props) { +void btif_remote_properties_evt(bt_status_t /* status */, + RawAddress* /* remote_addr */, + uint32_t /* num_props */, + bt_property_t* /* p_props */) { inc_func_call_count(__func__); } -void btif_set_adapter_property(bt_property_t* property) { +void btif_set_adapter_property(bt_property_t* /* property */) { inc_func_call_count(__func__); } -void btif_set_remote_device_property(RawAddress* remote_addr, - bt_property_t* property) { +void btif_set_remote_device_property(RawAddress* /* remote_addr */, + bt_property_t* /* property */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_btif_debug_conn.cc b/system/test/mock/mock_btif_debug_conn.cc index 1427ffd3d7d431c0ab4d5de64d6616eefb2429ad..666e8a813a899e1a07d57cd7292722acbf8620e3 100644 --- a/system/test/mock/mock_btif_debug_conn.cc +++ b/system/test/mock/mock_btif_debug_conn.cc @@ -24,9 +24,9 @@ #include "test/common/mock_functions.h" #include "types/raw_address.h" -void btif_debug_conn_dump(int fd) { inc_func_call_count(__func__); } -void btif_debug_conn_state(const RawAddress& bda, - const btif_debug_conn_state_t state, - const tGATT_DISCONN_REASON disconnect_reason) { +void btif_debug_conn_dump(int /* fd */) { inc_func_call_count(__func__); } +void btif_debug_conn_state(const RawAddress& /* bda */, + const btif_debug_conn_state_t /* state */, + const tGATT_DISCONN_REASON /* disconnect_reason */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_btif_dm.cc b/system/test/mock/mock_btif_dm.cc index 9038ad0c47710ff309c45c11c0617a64c540865b..55f29a33f77de1b1b0d799d9060a0ff76b96b958 100644 --- a/system/test/mock/mock_btif_dm.cc +++ b/system/test/mock/mock_btif_dm.cc @@ -25,6 +25,8 @@ #include "bta/include/bta_sec_api.h" #include "include/hardware/bluetooth.h" #include "internal_include/bte_appl.h" +#include "stack/include/acl_api_types.h" +#include "stack/include/bt_dev_class.h" #include "test/common/mock_functions.h" #include "types/bt_transport.h" #include "types/raw_address.h" @@ -35,137 +37,148 @@ bool btif_dm_pairing_is_busy() { inc_func_call_count(__func__); return false; } -bool check_cod(const RawAddress* remote_bdaddr, uint32_t cod) { +bool check_cod(const RawAddress* /* remote_bdaddr */, uint32_t /* cod */) { inc_func_call_count(__func__); return false; } -bool check_cod_hid(const RawAddress* remote_bdaddr) { +bool check_cod_hid(const RawAddress* /* remote_bdaddr */) { inc_func_call_count(__func__); return false; } -bool check_cod_hid(const RawAddress& remote_bdaddr) { +bool check_cod_hid(const RawAddress& /* remote_bdaddr */) { inc_func_call_count(__func__); return false; } -bool is_device_le_audio_capable(const RawAddress bd_addr) { +bool is_device_le_audio_capable(const RawAddress /* bd_addr */) { inc_func_call_count(__func__); return false; } -uint16_t btif_dm_get_connection_state(const RawAddress& bd_addr) { +uint16_t btif_dm_get_connection_state(const RawAddress& /* bd_addr */) { inc_func_call_count(__func__); return 0; } void BTIF_dm_disable() { inc_func_call_count(__func__); } void BTIF_dm_enable() { inc_func_call_count(__func__); } -void BTIF_dm_on_hw_error() { inc_func_call_count(__func__); } -void BTIF_dm_report_inquiry_status_change(uint8_t status) { +void BTIF_dm_report_inquiry_status_change(tBTM_INQUIRY_STATE /* state */) { inc_func_call_count(__func__); } -void btif_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { +void btif_dm_sec_evt(tBTA_DM_SEC_EVT /* event */, tBTA_DM_SEC* /* p_data */) { + inc_func_call_count(__func__); +} +void btif_ble_receiver_test(uint8_t /* rx_freq */) { inc_func_call_count(__func__); } -void btif_ble_receiver_test(uint8_t rx_freq) { inc_func_call_count(__func__); } void btif_ble_test_end() { inc_func_call_count(__func__); } -void btif_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len, - uint8_t packet_payload) { +void btif_ble_transmitter_test(uint8_t /* tx_freq */, + uint8_t /* test_data_len */, + uint8_t /* packet_payload */) { inc_func_call_count(__func__); } -void btif_debug_bond_event_dump(int fd) { inc_func_call_count(__func__); } -void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent) { +void btif_debug_bond_event_dump(int /* fd */) { inc_func_call_count(__func__); } +void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* /* p_ble_req */, + bool /* is_consent */) { inc_func_call_count(__func__); } -void btif_dm_cancel_bond(const RawAddress bd_addr) { +void btif_dm_cancel_bond(const RawAddress /* bd_addr */) { inc_func_call_count(__func__); } void btif_dm_cancel_discovery(void) { inc_func_call_count(__func__); } void btif_dm_cleanup(void) { inc_func_call_count(__func__); } -void btif_dm_create_bond(const RawAddress bd_addr, int transport) { +void btif_dm_create_bond(const RawAddress /* bd_addr */, int /* transport */) { inc_func_call_count(__func__); } -void btif_dm_create_bond_le(const RawAddress bd_addr, - tBLE_ADDR_TYPE addr_type) { +void btif_dm_create_bond_le(const RawAddress /* bd_addr */, + tBLE_ADDR_TYPE /* addr_type */) { inc_func_call_count(__func__); } -void btif_dm_create_bond_out_of_band(const RawAddress bd_addr, int transport, - const bt_oob_data_t p192_data, - const bt_oob_data_t p256_data) { +void btif_dm_create_bond_out_of_band(const RawAddress /* bd_addr */, + int /* transport */, + const bt_oob_data_t /* p192_data */, + const bt_oob_data_t /* p256_data */) { inc_func_call_count(__func__); } -void btif_dm_enable_service(tBTA_SERVICE_ID service_id, bool enable) { +void btif_dm_enable_service(tBTA_SERVICE_ID /* service_id */, + bool /* enable */) { inc_func_call_count(__func__); } -void btif_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK* p_key_mask, - Octet16* p_er, - tBTA_BLE_LOCAL_ID_KEYS* p_id_keys) { +void btif_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK* /* p_key_mask */, + Octet16* /* p_er */, + tBTA_BLE_LOCAL_ID_KEYS* /* p_id_keys */) { inc_func_call_count(__func__); } -void btif_dm_get_remote_services(RawAddress remote_addr, const int transport) { +void btif_dm_get_remote_services(RawAddress /* remote_addr */, + const int /* transport */) { inc_func_call_count(__func__); } -void btif_dm_hh_open_failed(RawAddress* bdaddr) { +void btif_dm_hh_open_failed(RawAddress* /* bdaddr */) { inc_func_call_count(__func__); } -void btif_dm_init(uid_set_t* set) { inc_func_call_count(__func__); } -void btif_dm_get_local_class_of_device(DEV_CLASS device_class) { +void btif_dm_init(uid_set_t* /* set */) { inc_func_call_count(__func__); } +DEV_CLASS btif_dm_get_local_class_of_device() { inc_func_call_count(__func__); + return kDevClassUnclassified; } void btif_dm_load_ble_local_keys(void) { inc_func_call_count(__func__); } void btif_dm_on_disable() { inc_func_call_count(__func__); } -void btif_dm_pin_reply(const RawAddress bd_addr, uint8_t accept, - uint8_t pin_len, bt_pin_code_t pin_code) { +void btif_dm_pin_reply(const RawAddress /* bd_addr */, uint8_t /* accept */, + uint8_t /* pin_len */, bt_pin_code_t /* pin_code */) { inc_func_call_count(__func__); } -void btif_dm_proc_io_req(tBTM_AUTH_REQ* p_auth_req, bool is_orig) { +void btif_dm_proc_io_req(tBTM_AUTH_REQ* /* p_auth_req */, bool /* is_orig */) { inc_func_call_count(__func__); } -void btif_dm_proc_io_rsp(const RawAddress& bd_addr, tBTM_IO_CAP io_cap, - tBTM_OOB_DATA oob_data, tBTM_AUTH_REQ auth_req) { +void btif_dm_proc_io_rsp(const RawAddress& /* bd_addr */, + tBTM_IO_CAP /* io_cap */, tBTM_OOB_DATA /* oob_data */, + tBTM_AUTH_REQ /* auth_req */) { inc_func_call_count(__func__); } void btif_dm_read_energy_info() { inc_func_call_count(__func__); } void btif_dm_remove_ble_bonding_keys(void) { inc_func_call_count(__func__); } -void btif_dm_remove_bond(const RawAddress bd_addr) { +void btif_dm_remove_bond(const RawAddress /* bd_addr */) { inc_func_call_count(__func__); } -void btif_dm_set_oob_for_io_req(tBTM_OOB_DATA* p_has_oob_data) { +void btif_dm_set_oob_for_io_req(tBTM_OOB_DATA* /* p_has_oob_data */) { inc_func_call_count(__func__); } -void btif_dm_set_oob_for_le_io_req(const RawAddress& bd_addr, - tBTM_OOB_DATA* p_has_oob_data, - tBTM_LE_AUTH_REQ* p_auth_req) { +void btif_dm_set_oob_for_le_io_req(const RawAddress& /* bd_addr */, + tBTM_OOB_DATA* /* p_has_oob_data */, + tBTM_LE_AUTH_REQ* /* p_auth_req */) { inc_func_call_count(__func__); } -void btif_dm_ssp_reply(const RawAddress bd_addr, bt_ssp_variant_t variant, - uint8_t accept) { +void btif_dm_ssp_reply(const RawAddress /* bd_addr */, + bt_ssp_variant_t /* variant */, uint8_t /* accept */) { inc_func_call_count(__func__); } void btif_dm_start_discovery(void) { inc_func_call_count(__func__); } -void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr, - BD_NAME bd_name, DEV_CLASS dev_class, - tBT_DEVICE_TYPE dev_type) { +void btif_dm_update_ble_remote_properties(const RawAddress& /* bd_addr */, + BD_NAME /* bd_name */, + DEV_CLASS /* dev_class */, + tBT_DEVICE_TYPE /* dev_type */) { inc_func_call_count(__func__); } -bool btif_dm_get_smp_config(tBTE_APPL_CFG* p_cfg) { +bool btif_dm_get_smp_config(tBTE_APPL_CFG* /* p_cfg */) { inc_func_call_count(__func__); return true; } -bool btif_dm_proc_rmt_oob(const RawAddress& bd_addr, Octet16* p_c, - Octet16* p_r) { +bool btif_dm_proc_rmt_oob(const RawAddress& /* bd_addr */, Octet16* /* p_c */, + Octet16* /* p_r */) { inc_func_call_count(__func__); return false; } -void btif_dm_proc_loc_oob(tBT_TRANSPORT transport, bool is_valid, - const Octet16& c, const Octet16& r) { +void btif_dm_proc_loc_oob(tBT_TRANSPORT /* transport */, bool /* is_valid */, + const Octet16& /* c */, const Octet16& /* r */) { inc_func_call_count(__func__); } -bool btif_get_device_type(const RawAddress& bda, int* p_device_type) { +bool btif_get_device_type(const RawAddress& /* bda */, + int* /* p_device_type */) { inc_func_call_count(__func__); return false; } -bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type) { +bool btif_get_address_type(const RawAddress& /* bda */, + tBLE_ADDR_TYPE* /* p_addr_type */) { inc_func_call_count(__func__); return false; } diff --git a/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc b/system/test/mock/mock_btif_hf.cc similarity index 59% rename from system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc rename to system/test/mock/mock_btif_hf.cc index 1320c49336ec015ad92fa64eb8f6ddc542ce04b3..e49f8f09fc8ce2a2ef6d09ebdd67cac4f3f8d1a2 100644 --- a/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.cc +++ b/system/test/mock/mock_btif_hf.cc @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Android Open Source Project + * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,41 +13,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /* * Generated mock file from original source file - * Functions generated:6 + * Functions generated:0 * - * mockcify.pl ver 0.2 + * mockcify.pl ver 0.7.0 */ -// Mock include file to share data between tests and mock -#include "test/mock/mock_stack_acl_btm_ble_connection_establishment.h" - -#include -// Original included files, if any +// Mock include file to share data between tests and mock +#include "test/mock/mock_btif_hf.h" #include "test/common/mock_functions.h" -#include "types/raw_address.h" -// Mocked compile conditionals, if any +// Original usings + // Mocked internal structures, if any namespace test { namespace mock { -namespace stack_acl_btm_ble_connection_establishment { +namespace btif_hf { // Function state capture and return values, if needed -struct btm_ble_create_ll_conn_complete btm_ble_create_ll_conn_complete; - -} // namespace stack_acl_btm_ble_connection_establishment +struct GetInterface GetInterface; +} // namespace btif_hf } // namespace mock } // namespace test -void btm_ble_create_ll_conn_complete(tHCI_STATUS status) { +// Mocked functions, if any +namespace bluetooth { +namespace headset { +Interface* GetInterface() { inc_func_call_count(__func__); - test::mock::stack_acl_btm_ble_connection_establishment:: - btm_ble_create_ll_conn_complete(status); + return test::mock::btif_hf::GetInterface(); } +} // namespace headset +} // namespace bluetooth +// Mocked functions complete // END mockcify generation diff --git a/system/test/mock/mock_btif_hf.h b/system/test/mock/mock_btif_hf.h new file mode 100644 index 0000000000000000000000000000000000000000..92c8bff07bbb0be68dd74f9f0f4fe8a7961486c7 --- /dev/null +++ b/system/test/mock/mock_btif_hf.h @@ -0,0 +1,61 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +/* + * Generated mock file from original source file + * Functions generated:0 + * + * mockcify.pl ver 0.7.0 + */ + +#include + +#include "include/hardware/bluetooth_headset_interface.h" + +// Original included files, if any +// NOTE: Since this is a mock file with mock definitions some number of +// include files may not be required. The include-what-you-use +// still applies, but crafting proper inclusion is out of scope +// for this effort. This compilation unit may compile as-is, or +// may need attention to prune from (or add to ) the inclusion set. + +// Original usings + +// Mocked compile conditionals, if any + +namespace test { +namespace mock { +namespace btif_hf { + +// Shared state between mocked functions and tests +// Name: GetInterface +// Params: +// Returns: bluetooth::headset::Interface* + +struct GetInterface { + std::function body{ + []() { return nullptr; }}; + bluetooth::headset::Interface* operator()() { return body(); }; +}; +extern struct GetInterface GetInterface; + +// Shared state between mocked functions and tests +} // namespace btif_hf +} // namespace mock +} // namespace test + +// END mockcify generation diff --git a/system/test/mock/mock_btif_profile_queue.h b/system/test/mock/mock_btif_profile_queue.h index 7576690908f024d61e473a12d04a83b8d514bdfb..fd1635dcb5a84dc5d0a0e5e991e734a2c4aa4d2b 100644 --- a/system/test/mock/mock_btif_profile_queue.h +++ b/system/test/mock/mock_btif_profile_queue.h @@ -51,7 +51,7 @@ extern struct btif_queue_advance btif_queue_advance; // Params: uint16_t uuid // Return: void struct btif_queue_cleanup { - std::function body{[](uint16_t uuid) {}}; + std::function body{[](uint16_t /* uuid */) {}}; void operator()(uint16_t uuid) { body(uuid); }; }; extern struct btif_queue_cleanup btif_queue_cleanup; @@ -63,8 +63,8 @@ struct btif_queue_connect { static bt_status_t return_value; std::function - body{[](uint16_t uuid, const RawAddress* bda, - btif_connect_cb_t connect_cb) { return return_value; }}; + body{[](uint16_t /* uuid */, const RawAddress* /* bda */, + btif_connect_cb_t /* connect_cb */) { return return_value; }}; bt_status_t operator()(uint16_t uuid, const RawAddress* bda, btif_connect_cb_t connect_cb) { return body(uuid, bda, connect_cb); diff --git a/system/test/mock/mock_btif_profile_storage.cc b/system/test/mock/mock_btif_profile_storage.cc new file mode 100644 index 0000000000000000000000000000000000000000..1390f39a23dd53687520daffbb6332a5770530fc --- /dev/null +++ b/system/test/mock/mock_btif_profile_storage.cc @@ -0,0 +1,341 @@ +/* + * Copyright 2023 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. + */ +/* + * Generated mock file from original source file + * Functions generated:40 + * + * mockcify.pl ver 0.7.0 + */ + +// Mock include file to share data between tests and mock +#include "test/mock/mock_btif_profile_storage.h" + +#include + +#include "test/common/mock_functions.h" + +// Original usings +using bluetooth::Uuid; + +// Mocked internal structures, if any + +namespace test { +namespace mock { +namespace btif_profile_storage { + +// Function state capture and return values, if needed +struct btif_storage_add_groups btif_storage_add_groups; +struct btif_storage_add_hearing_aid btif_storage_add_hearing_aid; +struct btif_storage_add_hid_device_info btif_storage_add_hid_device_info; +struct btif_storage_add_leaudio_has_device btif_storage_add_leaudio_has_device; +struct btif_storage_get_hearing_aid_prop btif_storage_get_hearing_aid_prop; +struct btif_storage_get_le_hid_devices btif_storage_get_le_hid_devices; +struct btif_storage_get_leaudio_has_features + btif_storage_get_leaudio_has_features; +struct btif_storage_get_leaudio_has_presets + btif_storage_get_leaudio_has_presets; +struct btif_storage_get_wake_capable_classic_hid_devices + btif_storage_get_wake_capable_classic_hid_devices; +struct btif_storage_is_pce_version_102 btif_storage_is_pce_version_102; +struct btif_storage_leaudio_clear_service_data + btif_storage_leaudio_clear_service_data; +struct btif_storage_leaudio_update_ase_bin btif_storage_leaudio_update_ase_bin; +struct btif_storage_leaudio_update_handles_bin + btif_storage_leaudio_update_handles_bin; +struct btif_storage_leaudio_update_pacs_bin + btif_storage_leaudio_update_pacs_bin; +struct btif_storage_load_bonded_csis_devices + btif_storage_load_bonded_csis_devices; +struct btif_storage_load_bonded_groups btif_storage_load_bonded_groups; +struct btif_storage_load_bonded_hearing_aids + btif_storage_load_bonded_hearing_aids; +struct btif_storage_load_bonded_hid_info btif_storage_load_bonded_hid_info; +struct btif_storage_load_bonded_leaudio btif_storage_load_bonded_leaudio; +struct btif_storage_load_bonded_leaudio_has_devices + btif_storage_load_bonded_leaudio_has_devices; +struct btif_storage_load_bonded_volume_control_devices + btif_storage_load_bonded_volume_control_devices; +struct btif_storage_load_hidd btif_storage_load_hidd; +struct btif_storage_remove_csis_device btif_storage_remove_csis_device; +struct btif_storage_remove_groups btif_storage_remove_groups; +struct btif_storage_remove_hearing_aid btif_storage_remove_hearing_aid; +struct btif_storage_remove_hid_info btif_storage_remove_hid_info; +struct btif_storage_remove_hidd btif_storage_remove_hidd; +struct btif_storage_remove_leaudio btif_storage_remove_leaudio; +struct btif_storage_remove_leaudio_has btif_storage_remove_leaudio_has; +struct btif_storage_set_hearing_aid_acceptlist + btif_storage_set_hearing_aid_acceptlist; +struct btif_storage_set_hidd btif_storage_set_hidd; +struct btif_storage_set_leaudio_audio_location + btif_storage_set_leaudio_audio_location; +struct btif_storage_set_leaudio_autoconnect + btif_storage_set_leaudio_autoconnect; +struct btif_storage_set_leaudio_has_acceptlist + btif_storage_set_leaudio_has_acceptlist; +struct btif_storage_set_leaudio_has_active_preset + btif_storage_set_leaudio_has_active_preset; +struct btif_storage_set_leaudio_has_features + btif_storage_set_leaudio_has_features; +struct btif_storage_set_leaudio_has_presets + btif_storage_set_leaudio_has_presets; +struct btif_storage_set_leaudio_supported_context_types + btif_storage_set_leaudio_supported_context_types; +struct btif_storage_set_pce_profile_version + btif_storage_set_pce_profile_version; +struct btif_storage_update_csis_info btif_storage_update_csis_info; + +} // namespace btif_profile_storage +} // namespace mock +} // namespace test + +// Mocked function return values, if any +namespace test { +namespace mock { +namespace btif_profile_storage { + +bt_status_t btif_storage_add_hid_device_info::return_value = BT_STATUS_SUCCESS; +bool btif_storage_get_hearing_aid_prop::return_value = false; +std::vector> + btif_storage_get_le_hid_devices::return_value = {}; +bool btif_storage_get_leaudio_has_features::return_value = false; +bool btif_storage_get_leaudio_has_presets::return_value = false; +std::vector + btif_storage_get_wake_capable_classic_hid_devices::return_value = {}; +bool btif_storage_is_pce_version_102::return_value = false; +bt_status_t btif_storage_load_bonded_hid_info::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_load_hidd::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_remove_hid_info::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_remove_hidd::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_set_hidd::return_value = BT_STATUS_SUCCESS; + +} // namespace btif_profile_storage +} // namespace mock +} // namespace test + +// Mocked functions, if any +void btif_storage_add_groups(const RawAddress& addr) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_add_groups(addr); +} +void btif_storage_add_hearing_aid(const HearingDevice& dev_info) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_add_hearing_aid(dev_info); +} +bt_status_t btif_storage_add_hid_device_info( + RawAddress* remote_bd_addr, uint16_t attr_mask, uint8_t sub_class, + uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version, + uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout, + uint16_t dl_len, uint8_t* dsc_list) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_add_hid_device_info( + remote_bd_addr, attr_mask, sub_class, app_id, vendor_id, product_id, + version, ctry_code, ssr_max_latency, ssr_min_tout, dl_len, dsc_list); +} +void btif_storage_add_leaudio_has_device(const RawAddress& address, + std::vector presets_bin, + uint8_t features, + uint8_t active_preset) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_add_leaudio_has_device( + address, presets_bin, features, active_preset); +} +bool btif_storage_get_hearing_aid_prop( + const RawAddress& address, uint8_t* capabilities, uint64_t* hi_sync_id, + uint16_t* render_delay, uint16_t* preparation_delay, uint16_t* codecs) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_get_hearing_aid_prop( + address, capabilities, hi_sync_id, render_delay, preparation_delay, + codecs); +} +std::vector> btif_storage_get_le_hid_devices( + void) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_get_le_hid_devices(); +} +bool btif_storage_get_leaudio_has_features(const RawAddress& address, + uint8_t& features) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage:: + btif_storage_get_leaudio_has_features(address, features); +} +bool btif_storage_get_leaudio_has_presets(const RawAddress& address, + std::vector& presets_bin, + uint8_t& active_preset) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_get_leaudio_has_presets( + address, presets_bin, active_preset); +} +std::vector btif_storage_get_wake_capable_classic_hid_devices( + void) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage:: + btif_storage_get_wake_capable_classic_hid_devices(); +} +bool btif_storage_is_pce_version_102(const RawAddress& remote_bd_addr) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_is_pce_version_102( + remote_bd_addr); +} +void btif_storage_leaudio_clear_service_data(const RawAddress& address) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_leaudio_clear_service_data( + address); +} +void btif_storage_leaudio_update_ase_bin(const RawAddress& addr) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_leaudio_update_ase_bin(addr); +} +void btif_storage_leaudio_update_handles_bin(const RawAddress& addr) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_leaudio_update_handles_bin( + addr); +} +void btif_storage_leaudio_update_pacs_bin(const RawAddress& addr) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_leaudio_update_pacs_bin(addr); +} +void btif_storage_load_bonded_csis_devices(void) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_load_bonded_csis_devices(); +} +void btif_storage_load_bonded_groups(void) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_load_bonded_groups(); +} +void btif_storage_load_bonded_hearing_aids() { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_load_bonded_hearing_aids(); +} +bt_status_t btif_storage_load_bonded_hid_info(void) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_load_bonded_hid_info(); +} +void btif_storage_load_bonded_leaudio() { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_load_bonded_leaudio(); +} +void btif_storage_load_bonded_leaudio_has_devices() { + inc_func_call_count(__func__); + test::mock::btif_profile_storage:: + btif_storage_load_bonded_leaudio_has_devices(); +} +void btif_storage_load_bonded_volume_control_devices(void) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage:: + btif_storage_load_bonded_volume_control_devices(); +} +bt_status_t btif_storage_load_hidd(void) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_load_hidd(); +} +void btif_storage_remove_csis_device(const RawAddress& address) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_remove_csis_device(address); +} +void btif_storage_remove_groups(const RawAddress& address) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_remove_groups(address); +} +void btif_storage_remove_hearing_aid(const RawAddress& address) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_remove_hearing_aid(address); +} +bt_status_t btif_storage_remove_hid_info(const RawAddress& remote_bd_addr) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_remove_hid_info( + remote_bd_addr); +} +bt_status_t btif_storage_remove_hidd(RawAddress* remote_bd_addr) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_remove_hidd( + remote_bd_addr); +} +void btif_storage_remove_leaudio(const RawAddress& address) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_remove_leaudio(address); +} +void btif_storage_remove_leaudio_has(const RawAddress& address) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_remove_leaudio_has(address); +} +void btif_storage_set_hearing_aid_acceptlist(const RawAddress& address, + bool add_to_acceptlist) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_hearing_aid_acceptlist( + address, add_to_acceptlist); +} +bt_status_t btif_storage_set_hidd(const RawAddress& remote_bd_addr) { + inc_func_call_count(__func__); + return test::mock::btif_profile_storage::btif_storage_set_hidd( + remote_bd_addr); +} +void btif_storage_set_leaudio_audio_location(const RawAddress& addr, + uint32_t sink_location, + uint32_t source_location) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_leaudio_audio_location( + addr, sink_location, source_location); +} +void btif_storage_set_leaudio_autoconnect(const RawAddress& addr, + bool autoconnect) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_leaudio_autoconnect( + addr, autoconnect); +} +void btif_storage_set_leaudio_has_acceptlist(const RawAddress& address, + bool add_to_acceptlist) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_leaudio_has_acceptlist( + address, add_to_acceptlist); +} +void btif_storage_set_leaudio_has_active_preset(const RawAddress& address, + uint8_t active_preset) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_leaudio_has_active_preset( + address, active_preset); +} +void btif_storage_set_leaudio_has_features(const RawAddress& address, + uint8_t features) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_leaudio_has_features( + address, features); +} +void btif_storage_set_leaudio_has_presets(const RawAddress& address, + std::vector presets_bin) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_leaudio_has_presets( + address, presets_bin); +} +void btif_storage_set_leaudio_supported_context_types( + const RawAddress& addr, uint16_t sink_supported_context_type, + uint16_t source_supported_context_type) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage:: + btif_storage_set_leaudio_supported_context_types( + addr, sink_supported_context_type, source_supported_context_type); +} +void btif_storage_set_pce_profile_version(const RawAddress& remote_bd_addr, + uint16_t peer_pce_version) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_set_pce_profile_version( + remote_bd_addr, peer_pce_version); +} +void btif_storage_update_csis_info(const RawAddress& addr) { + inc_func_call_count(__func__); + test::mock::btif_profile_storage::btif_storage_update_csis_info(addr); +} +// Mocked functions complete +// END mockcify generation diff --git a/system/test/mock/mock_btif_profile_storage.h b/system/test/mock/mock_btif_profile_storage.h new file mode 100644 index 0000000000000000000000000000000000000000..66e61ae821d65f5d706f3786d44264dec1e76d81 --- /dev/null +++ b/system/test/mock/mock_btif_profile_storage.h @@ -0,0 +1,574 @@ +/* + * Copyright 2023 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 + +/* + * Generated mock file from original source file + * Functions generated:40 + * + * mockcify.pl ver 0.7.0 + */ + +#include +#include + +// Original included files, if any +// NOTE: Since this is a mock file with mock definitions some number of +// include files may not be required. The include-what-you-use +// still applies, but crafting proper inclusion is out of scope +// for this effort. This compilation unit may compile as-is, or +// may need attention to prune from (or add to ) the inclusion set. +#include +#include +#include + +#include + +#include "bta/include/bta_hearing_aid_api.h" +#include "types/bluetooth/uuid.h" +#include "types/raw_address.h" + +// Original usings +using bluetooth::Uuid; + +// Mocked compile conditionals, if any + +namespace test { +namespace mock { +namespace btif_profile_storage { + +// Shared state between mocked functions and tests +// Name: btif_storage_add_groups +// Params: const RawAddress& addr +// Return: void +struct btif_storage_add_groups { + std::function body{ + [](const RawAddress& /* addr */) {}}; + void operator()(const RawAddress& addr) { body(addr); }; +}; +extern struct btif_storage_add_groups btif_storage_add_groups; + +// Name: btif_storage_add_hearing_aid +// Params: const HearingDevice& dev_info +// Return: void +struct btif_storage_add_hearing_aid { + std::function body{ + [](const HearingDevice& /* dev_info */) {}}; + void operator()(const HearingDevice& dev_info) { body(dev_info); }; +}; +extern struct btif_storage_add_hearing_aid btif_storage_add_hearing_aid; + +// Name: btif_storage_add_hid_device_info +// Params: RawAddress* remote_bd_addr, uint16_t attr_mask, uint8_t sub_class, +// uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version, +// uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout, uint16_t +// dl_len, uint8_t* dsc_list Return: bt_status_t +struct btif_storage_add_hid_device_info { + static bt_status_t return_value; + std::function + body{[](RawAddress* /* remote_bd_addr */, uint16_t /* attr_mask */, + uint8_t /* sub_class */, uint8_t /* app_id */, + uint16_t /* vendor_id */, uint16_t /* product_id */, + uint16_t /* version */, uint8_t /* ctry_code */, + uint16_t /* ssr_max_latency */, uint16_t /* ssr_min_tout */, + uint16_t /* dl_len */, + uint8_t* /* dsc_list */) { return return_value; }}; + bt_status_t operator()(RawAddress* remote_bd_addr, uint16_t attr_mask, + uint8_t sub_class, uint8_t app_id, uint16_t vendor_id, + uint16_t product_id, uint16_t version, + uint8_t ctry_code, uint16_t ssr_max_latency, + uint16_t ssr_min_tout, uint16_t dl_len, + uint8_t* dsc_list) { + return body(remote_bd_addr, attr_mask, sub_class, app_id, vendor_id, + product_id, version, ctry_code, ssr_max_latency, ssr_min_tout, + dl_len, dsc_list); + }; +}; +extern struct btif_storage_add_hid_device_info btif_storage_add_hid_device_info; + +// Name: btif_storage_add_leaudio_has_device +// Params: const RawAddress& address, std::vector presets_bin, uint8_t +// features, uint8_t active_preset Return: void +struct btif_storage_add_leaudio_has_device { + std::function presets_bin, uint8_t features, + uint8_t active_preset)> + body{[](const RawAddress& /* address */, + std::vector /* presets_bin */, uint8_t /* features */, + uint8_t /* active_preset */) {}}; + void operator()(const RawAddress& address, std::vector presets_bin, + uint8_t features, uint8_t active_preset) { + body(address, presets_bin, features, active_preset); + }; +}; +extern struct btif_storage_add_leaudio_has_device + btif_storage_add_leaudio_has_device; + +// Name: btif_storage_get_hearing_aid_prop +// Params: const RawAddress& address, uint8_t* capabilities, uint64_t* +// hi_sync_id, uint16_t* render_delay, uint16_t* preparation_delay, uint16_t* +// codecs Return: bool +struct btif_storage_get_hearing_aid_prop { + static bool return_value; + std::function + body{[](const RawAddress& /* address */, uint8_t* /* capabilities */, + uint64_t* /* hi_sync_id */, uint16_t* /* render_delay */, + uint16_t* /* preparation_delay */, + uint16_t* /* codecs */) { return return_value; }}; + bool operator()(const RawAddress& address, uint8_t* capabilities, + uint64_t* hi_sync_id, uint16_t* render_delay, + uint16_t* preparation_delay, uint16_t* codecs) { + return body(address, capabilities, hi_sync_id, render_delay, + preparation_delay, codecs); + }; +}; +extern struct btif_storage_get_hearing_aid_prop + btif_storage_get_hearing_aid_prop; + +// Name: btif_storage_get_le_hid_devices +// Params: void +// Return: std::vector> +struct btif_storage_get_le_hid_devices { + static std::vector> return_value; + std::function>(void)> body{ + [](void) { return return_value; }}; + std::vector> operator()(void) { + return body(); + }; +}; +extern struct btif_storage_get_le_hid_devices btif_storage_get_le_hid_devices; + +// Name: btif_storage_get_leaudio_has_features +// Params: const RawAddress& address, uint8_t& features +// Return: bool +struct btif_storage_get_leaudio_has_features { + static bool return_value; + std::function body{ + [](const RawAddress& /* address */, uint8_t& /* features */) { + return return_value; + }}; + bool operator()(const RawAddress& address, uint8_t& features) { + return body(address, features); + }; +}; +extern struct btif_storage_get_leaudio_has_features + btif_storage_get_leaudio_has_features; + +// Name: btif_storage_get_leaudio_has_presets +// Params: const RawAddress& address, std::vector& presets_bin, +// uint8_t& active_preset Return: bool +struct btif_storage_get_leaudio_has_presets { + static bool return_value; + std::function& presets_bin, uint8_t& active_preset)> + body{[](const RawAddress& /* address */, + std::vector& /* presets_bin */, + uint8_t& /* active_preset */) { return return_value; }}; + bool operator()(const RawAddress& address, std::vector& presets_bin, + uint8_t& active_preset) { + return body(address, presets_bin, active_preset); + }; +}; +extern struct btif_storage_get_leaudio_has_presets + btif_storage_get_leaudio_has_presets; + +// Name: btif_storage_get_wake_capable_classic_hid_devices +// Params: void +// Return: std::vector +struct btif_storage_get_wake_capable_classic_hid_devices { + static std::vector return_value; + std::function(void)> body{ + [](void) { return return_value; }}; + std::vector operator()(void) { return body(); }; +}; +extern struct btif_storage_get_wake_capable_classic_hid_devices + btif_storage_get_wake_capable_classic_hid_devices; + +// Name: btif_storage_is_pce_version_102 +// Params: const RawAddress& remote_bd_addr +// Return: bool +struct btif_storage_is_pce_version_102 { + static bool return_value; + std::function body{ + [](const RawAddress& /* remote_bd_addr */) { return return_value; }}; + bool operator()(const RawAddress& remote_bd_addr) { + return body(remote_bd_addr); + }; +}; +extern struct btif_storage_is_pce_version_102 btif_storage_is_pce_version_102; + +// Name: btif_storage_leaudio_clear_service_data +// Params: const RawAddress& address +// Return: void +struct btif_storage_leaudio_clear_service_data { + std::function body{ + [](const RawAddress& /* address */) {}}; + void operator()(const RawAddress& address) { body(address); }; +}; +extern struct btif_storage_leaudio_clear_service_data + btif_storage_leaudio_clear_service_data; + +// Name: btif_storage_leaudio_update_ase_bin +// Params: const RawAddress& addr +// Return: void +struct btif_storage_leaudio_update_ase_bin { + std::function body{ + [](const RawAddress& /* addr */) {}}; + void operator()(const RawAddress& addr) { body(addr); }; +}; +extern struct btif_storage_leaudio_update_ase_bin + btif_storage_leaudio_update_ase_bin; + +// Name: btif_storage_leaudio_update_handles_bin +// Params: const RawAddress& addr +// Return: void +struct btif_storage_leaudio_update_handles_bin { + std::function body{ + [](const RawAddress& /* addr */) {}}; + void operator()(const RawAddress& addr) { body(addr); }; +}; +extern struct btif_storage_leaudio_update_handles_bin + btif_storage_leaudio_update_handles_bin; + +// Name: btif_storage_leaudio_update_pacs_bin +// Params: const RawAddress& addr +// Return: void +struct btif_storage_leaudio_update_pacs_bin { + std::function body{ + [](const RawAddress& /* addr */) {}}; + void operator()(const RawAddress& addr) { body(addr); }; +}; +extern struct btif_storage_leaudio_update_pacs_bin + btif_storage_leaudio_update_pacs_bin; + +// Name: btif_storage_load_bonded_csis_devices +// Params: void +// Return: void +struct btif_storage_load_bonded_csis_devices { + std::function body{[](void) {}}; + void operator()(void) { body(); }; +}; +extern struct btif_storage_load_bonded_csis_devices + btif_storage_load_bonded_csis_devices; + +// Name: btif_storage_load_bonded_groups +// Params: void +// Return: void +struct btif_storage_load_bonded_groups { + std::function body{[](void) {}}; + void operator()(void) { body(); }; +}; +extern struct btif_storage_load_bonded_groups btif_storage_load_bonded_groups; + +// Name: btif_storage_load_bonded_hearing_aids +// Params: +// Return: void +struct btif_storage_load_bonded_hearing_aids { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct btif_storage_load_bonded_hearing_aids + btif_storage_load_bonded_hearing_aids; + +// Name: btif_storage_load_bonded_hid_info +// Params: void +// Return: bt_status_t +struct btif_storage_load_bonded_hid_info { + static bt_status_t return_value; + std::function body{[](void) { return return_value; }}; + bt_status_t operator()(void) { return body(); }; +}; +extern struct btif_storage_load_bonded_hid_info + btif_storage_load_bonded_hid_info; + +// Name: btif_storage_load_bonded_leaudio +// Params: +// Return: void +struct btif_storage_load_bonded_leaudio { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct btif_storage_load_bonded_leaudio btif_storage_load_bonded_leaudio; + +// Name: btif_storage_load_bonded_leaudio_has_devices +// Params: +// Return: void +struct btif_storage_load_bonded_leaudio_has_devices { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct btif_storage_load_bonded_leaudio_has_devices + btif_storage_load_bonded_leaudio_has_devices; + +// Name: btif_storage_load_bonded_volume_control_devices +// Params: void +// Return: void +struct btif_storage_load_bonded_volume_control_devices { + std::function body{[](void) {}}; + void operator()(void) { body(); }; +}; +extern struct btif_storage_load_bonded_volume_control_devices + btif_storage_load_bonded_volume_control_devices; + +// Name: btif_storage_load_hidd +// Params: void +// Return: bt_status_t +struct btif_storage_load_hidd { + static bt_status_t return_value; + std::function body{[](void) { return return_value; }}; + bt_status_t operator()(void) { return body(); }; +}; +extern struct btif_storage_load_hidd btif_storage_load_hidd; + +// Name: btif_storage_remove_csis_device +// Params: const RawAddress& address +// Return: void +struct btif_storage_remove_csis_device { + std::function body{ + [](const RawAddress& /* address */) {}}; + void operator()(const RawAddress& address) { body(address); }; +}; +extern struct btif_storage_remove_csis_device btif_storage_remove_csis_device; + +// Name: btif_storage_remove_groups +// Params: const RawAddress& address +// Return: void +struct btif_storage_remove_groups { + std::function body{ + [](const RawAddress& /* address */) {}}; + void operator()(const RawAddress& address) { body(address); }; +}; +extern struct btif_storage_remove_groups btif_storage_remove_groups; + +// Name: btif_storage_remove_hearing_aid +// Params: const RawAddress& address +// Return: void +struct btif_storage_remove_hearing_aid { + std::function body{ + [](const RawAddress& /* address */) {}}; + void operator()(const RawAddress& address) { body(address); }; +}; +extern struct btif_storage_remove_hearing_aid btif_storage_remove_hearing_aid; + +// Name: btif_storage_remove_hid_info +// Params: const RawAddress& remote_bd_addr +// Return: bt_status_t +struct btif_storage_remove_hid_info { + static bt_status_t return_value; + std::function body{ + [](const RawAddress& /* remote_bd_addr */) { return return_value; }}; + bt_status_t operator()(const RawAddress& remote_bd_addr) { + return body(remote_bd_addr); + }; +}; +extern struct btif_storage_remove_hid_info btif_storage_remove_hid_info; + +// Name: btif_storage_remove_hidd +// Params: RawAddress* remote_bd_addr +// Return: bt_status_t +struct btif_storage_remove_hidd { + static bt_status_t return_value; + std::function body{ + [](RawAddress* /* remote_bd_addr */) { return return_value; }}; + bt_status_t operator()(RawAddress* remote_bd_addr) { + return body(remote_bd_addr); + }; +}; +extern struct btif_storage_remove_hidd btif_storage_remove_hidd; + +// Name: btif_storage_remove_leaudio +// Params: const RawAddress& address +// Return: void +struct btif_storage_remove_leaudio { + std::function body{ + [](const RawAddress& /* address */) {}}; + void operator()(const RawAddress& address) { body(address); }; +}; +extern struct btif_storage_remove_leaudio btif_storage_remove_leaudio; + +// Name: btif_storage_remove_leaudio_has +// Params: const RawAddress& address +// Return: void +struct btif_storage_remove_leaudio_has { + std::function body{ + [](const RawAddress& /* address */) {}}; + void operator()(const RawAddress& address) { body(address); }; +}; +extern struct btif_storage_remove_leaudio_has btif_storage_remove_leaudio_has; + +// Name: btif_storage_set_hearing_aid_acceptlist +// Params: const RawAddress& address, bool add_to_acceptlist +// Return: void +struct btif_storage_set_hearing_aid_acceptlist { + std::function body{ + [](const RawAddress& /* address */, bool /* add_to_acceptlist */) {}}; + void operator()(const RawAddress& address, bool add_to_acceptlist) { + body(address, add_to_acceptlist); + }; +}; +extern struct btif_storage_set_hearing_aid_acceptlist + btif_storage_set_hearing_aid_acceptlist; + +// Name: btif_storage_set_hidd +// Params: const RawAddress& remote_bd_addr +// Return: bt_status_t +struct btif_storage_set_hidd { + static bt_status_t return_value; + std::function body{ + [](const RawAddress& /* remote_bd_addr */) { return return_value; }}; + bt_status_t operator()(const RawAddress& remote_bd_addr) { + return body(remote_bd_addr); + }; +}; +extern struct btif_storage_set_hidd btif_storage_set_hidd; + +// Name: btif_storage_set_leaudio_audio_location +// Params: const RawAddress& addr, uint32_t sink_location, uint32_t +// source_location Return: void +struct btif_storage_set_leaudio_audio_location { + std::function + body{[](const RawAddress& /* addr */, uint32_t /* sink_location */, + uint32_t /* source_location */) {}}; + void operator()(const RawAddress& addr, uint32_t sink_location, + uint32_t source_location) { + body(addr, sink_location, source_location); + }; +}; +extern struct btif_storage_set_leaudio_audio_location + btif_storage_set_leaudio_audio_location; + +// Name: btif_storage_set_leaudio_autoconnect +// Params: const RawAddress& addr, bool autoconnect +// Return: void +struct btif_storage_set_leaudio_autoconnect { + std::function body{ + [](const RawAddress& /* addr */, bool /* autoconnect */) {}}; + void operator()(const RawAddress& addr, bool autoconnect) { + body(addr, autoconnect); + }; +}; +extern struct btif_storage_set_leaudio_autoconnect + btif_storage_set_leaudio_autoconnect; + +// Name: btif_storage_set_leaudio_has_acceptlist +// Params: const RawAddress& address, bool add_to_acceptlist +// Return: void +struct btif_storage_set_leaudio_has_acceptlist { + std::function body{ + [](const RawAddress& /* address */, bool /* add_to_acceptlist */) {}}; + void operator()(const RawAddress& address, bool add_to_acceptlist) { + body(address, add_to_acceptlist); + }; +}; +extern struct btif_storage_set_leaudio_has_acceptlist + btif_storage_set_leaudio_has_acceptlist; + +// Name: btif_storage_set_leaudio_has_active_preset +// Params: const RawAddress& address, uint8_t active_preset +// Return: void +struct btif_storage_set_leaudio_has_active_preset { + std::function body{ + [](const RawAddress& /* address */, uint8_t /* active_preset */) {}}; + void operator()(const RawAddress& address, uint8_t active_preset) { + body(address, active_preset); + }; +}; +extern struct btif_storage_set_leaudio_has_active_preset + btif_storage_set_leaudio_has_active_preset; + +// Name: btif_storage_set_leaudio_has_features +// Params: const RawAddress& address, uint8_t features +// Return: void +struct btif_storage_set_leaudio_has_features { + std::function body{ + [](const RawAddress& /* address */, uint8_t /* features */) {}}; + void operator()(const RawAddress& address, uint8_t features) { + body(address, features); + }; +}; +extern struct btif_storage_set_leaudio_has_features + btif_storage_set_leaudio_has_features; + +// Name: btif_storage_set_leaudio_has_presets +// Params: const RawAddress& address, std::vector presets_bin +// Return: void +struct btif_storage_set_leaudio_has_presets { + std::function presets_bin)> + body{[](const RawAddress& /* address */, + std::vector /* presets_bin */) {}}; + void operator()(const RawAddress& address, std::vector presets_bin) { + body(address, presets_bin); + }; +}; +extern struct btif_storage_set_leaudio_has_presets + btif_storage_set_leaudio_has_presets; + +// Name: btif_storage_set_leaudio_supported_context_types +// Params: const RawAddress& addr, uint16_t sink_supported_context_type, +// uint16_t source_supported_context_type Return: void +struct btif_storage_set_leaudio_supported_context_types { + std::function + body{[](const RawAddress& /* addr */, + uint16_t /* sink_supported_context_type */, + uint16_t /* source_supported_context_type */) {}}; + void operator()(const RawAddress& addr, uint16_t sink_supported_context_type, + uint16_t source_supported_context_type) { + body(addr, sink_supported_context_type, source_supported_context_type); + }; +}; +extern struct btif_storage_set_leaudio_supported_context_types + btif_storage_set_leaudio_supported_context_types; + +// Name: btif_storage_set_pce_profile_version +// Params: const RawAddress& remote_bd_addr, uint16_t peer_pce_version +// Return: void +struct btif_storage_set_pce_profile_version { + std::function + body{[](const RawAddress& /* remote_bd_addr */, + uint16_t /* peer_pce_version */) {}}; + void operator()(const RawAddress& remote_bd_addr, uint16_t peer_pce_version) { + body(remote_bd_addr, peer_pce_version); + }; +}; +extern struct btif_storage_set_pce_profile_version + btif_storage_set_pce_profile_version; + +// Name: btif_storage_update_csis_info +// Params: const RawAddress& addr +// Return: void +struct btif_storage_update_csis_info { + std::function body{ + [](const RawAddress& /* addr */) {}}; + void operator()(const RawAddress& addr) { body(addr); }; +}; +extern struct btif_storage_update_csis_info btif_storage_update_csis_info; + +} // namespace btif_profile_storage +} // namespace mock +} // namespace test + +// END mockcify generation diff --git a/system/test/mock/mock_btif_sock_rfc.h b/system/test/mock/mock_btif_sock_rfc.h index be8be5dd1fe4a83f1f5679d74b2ddbcb428f3acd..eadf438e5165f925b9b1c9133d250f123e597c42 100644 --- a/system/test/mock/mock_btif_sock_rfc.h +++ b/system/test/mock/mock_btif_sock_rfc.h @@ -50,7 +50,7 @@ namespace btif_sock_rfc { struct bta_co_rfc_data_incoming { static int return_value; std::function body{ - [](uint32_t id, BT_HDR* p_buf) { return return_value; }}; + [](uint32_t /* id */, BT_HDR* /* p_buf */) { return return_value; }}; int operator()(uint32_t id, BT_HDR* p_buf) { return body(id, p_buf); }; }; extern struct bta_co_rfc_data_incoming bta_co_rfc_data_incoming; @@ -61,7 +61,9 @@ extern struct bta_co_rfc_data_incoming bta_co_rfc_data_incoming; struct bta_co_rfc_data_outgoing { static int return_value; std::function body{ - [](uint32_t id, uint8_t* buf, uint16_t size) { return return_value; }}; + [](uint32_t /* id */, uint8_t* /* buf */, uint16_t /* size */) { + return return_value; + }}; int operator()(uint32_t id, uint8_t* buf, uint16_t size) { return body(id, buf, size); }; @@ -74,7 +76,7 @@ extern struct bta_co_rfc_data_outgoing bta_co_rfc_data_outgoing; struct bta_co_rfc_data_outgoing_size { static int return_value; std::function body{ - [](uint32_t id, int* size) { return return_value; }}; + [](uint32_t /* id */, int* /* size */) { return return_value; }}; int operator()(uint32_t id, int* size) { return body(id, size); }; }; extern struct bta_co_rfc_data_outgoing_size bta_co_rfc_data_outgoing_size; @@ -95,8 +97,9 @@ struct btsock_rfc_connect { static bt_status_t return_value; std::function - body{[](const RawAddress* bd_addr, const Uuid* service_uuid, int channel, - int* sock_fd, int flags, int app_uid) { return return_value; }}; + body{[](const RawAddress* /* bd_addr */, const Uuid* /* service_uuid */, + int /* channel */, int* /* sock_fd */, int /* flags */, + int /* app_uid */) { return return_value; }}; bt_status_t operator()(const RawAddress* bd_addr, const Uuid* service_uuid, int channel, int* sock_fd, int flags, int app_uid) { return body(bd_addr, service_uuid, channel, sock_fd, flags, app_uid); @@ -114,9 +117,10 @@ struct btsock_rfc_control_req { uint8_t modem_signal, uint8_t break_signal, uint8_t discard_buffers, uint8_t break_signal_seq, bool fc)> - body{[](uint8_t dlci, const RawAddress& bd_addr, uint8_t modem_signal, - uint8_t break_signal, uint8_t discard_buffers, - uint8_t break_signal_seq, bool fc) { return return_value; }}; + body{[](uint8_t /* dlci */, const RawAddress& /* bd_addr */, + uint8_t /* modem_signal */, uint8_t /* break_signal */, + uint8_t /* discard_buffers */, uint8_t /* break_signal_seq */, + bool /* fc */) { return return_value; }}; bt_status_t operator()(uint8_t dlci, const RawAddress& bd_addr, uint8_t modem_signal, uint8_t break_signal, uint8_t discard_buffers, uint8_t break_signal_seq, @@ -133,7 +137,7 @@ extern struct btsock_rfc_control_req btsock_rfc_control_req; struct btsock_rfc_disconnect { static bt_status_t return_value; std::function body{ - [](const RawAddress* bd_addr) { return return_value; }}; + [](const RawAddress* /* bd_addr */) { return return_value; }}; bt_status_t operator()(const RawAddress* bd_addr) { return body(bd_addr); }; }; extern struct btsock_rfc_disconnect btsock_rfc_disconnect; @@ -144,7 +148,9 @@ extern struct btsock_rfc_disconnect btsock_rfc_disconnect; struct btsock_rfc_init { static bt_status_t return_value; std::function body{ - [](int poll_thread_handle, uid_set_t* set) { return return_value; }}; + [](int /* poll_thread_handle */, uid_set_t* /* set */) { + return return_value; + }}; bt_status_t operator()(int poll_thread_handle, uid_set_t* set) { return body(poll_thread_handle, set); }; @@ -158,8 +164,9 @@ struct btsock_rfc_listen { static bt_status_t return_value; std::function - body{[](const char* service_name, const Uuid* service_uuid, int channel, - int* sock_fd, int flags, int app_uid) { return return_value; }}; + body{[](const char* /* service_name */, const Uuid* /* service_uuid */, + int /* channel */, int* /* sock_fd */, int /* flags */, + int /* app_uid */) { return return_value; }}; bt_status_t operator()(const char* service_name, const Uuid* service_uuid, int channel, int* sock_fd, int flags, int app_uid) { return body(service_name, service_uuid, channel, sock_fd, flags, app_uid); @@ -172,7 +179,7 @@ extern struct btsock_rfc_listen btsock_rfc_listen; // Return: void struct btsock_rfc_signaled { std::function body{ - [](int fd, int flags, uint32_t id) {}}; + [](int /* fd */, int /* flags */, uint32_t /* id */) {}}; void operator()(int fd, int flags, uint32_t id) { body(fd, flags, id); }; }; extern struct btsock_rfc_signaled btsock_rfc_signaled; @@ -181,4 +188,4 @@ extern struct btsock_rfc_signaled btsock_rfc_signaled; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_btif_storage.cc b/system/test/mock/mock_btif_storage.cc index 2d528672f1f82582d7cc607aad14c7c13065ef92..c52925824fa497e5d2cf5995e573d7d2cd6c4646 100644 --- a/system/test/mock/mock_btif_storage.cc +++ b/system/test/mock/mock_btif_storage.cc @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Android Open Source Project + * Copyright 2023 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. @@ -13,232 +13,343 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /* * Generated mock file from original source file - * Functions generated:44 + * Functions generated:41 + * + * mockcify.pl ver 0.7.0 */ +// Mock include file to share data between tests and mock +#include "test/mock/mock_btif_storage.h" + #include -#include -#include "bta/include/bta_hearing_aid_api.h" -#include "stack/include/bt_octets.h" -#include "stack/include/btm_sec_api_types.h" #include "test/common/mock_functions.h" -#include "types/ble_address_with_type.h" -#include "types/bluetooth/uuid.h" -#include "types/raw_address.h" -Octet16 btif_storage_get_gatt_cl_db_hash(const RawAddress& bd_addr) { +// Original usings +using bluetooth::Uuid; + +// Mocked internal structures, if any + +namespace test { +namespace mock { +namespace btif_storage { + +// Function state capture and return values, if needed +struct btif_debug_linkkey_type_dump btif_debug_linkkey_type_dump; +struct btif_has_ble_keys btif_has_ble_keys; +struct btif_in_fetch_bonded_ble_device btif_in_fetch_bonded_ble_device; +struct btif_in_fetch_bonded_device btif_in_fetch_bonded_device; +struct btif_split_uuids_string btif_split_uuids_string; +struct btif_storage_add_ble_bonding_key btif_storage_add_ble_bonding_key; +struct btif_storage_add_ble_local_key btif_storage_add_ble_local_key; +struct btif_storage_add_bonded_device btif_storage_add_bonded_device; +struct btif_storage_add_remote_device btif_storage_add_remote_device; +struct btif_storage_get_adapter_prop btif_storage_get_adapter_prop; +struct btif_storage_get_adapter_property btif_storage_get_adapter_property; +struct btif_storage_get_ble_bonding_key btif_storage_get_ble_bonding_key; +struct btif_storage_get_ble_local_key btif_storage_get_ble_local_key; +struct btif_storage_get_gatt_cl_db_hash btif_storage_get_gatt_cl_db_hash; +struct btif_storage_get_gatt_cl_supp_feat btif_storage_get_gatt_cl_supp_feat; +struct btif_storage_get_local_io_caps btif_storage_get_local_io_caps; +struct btif_storage_get_num_bonded_devices btif_storage_get_num_bonded_devices; +struct btif_storage_get_remote_addr_type btif_storage_get_remote_addr_type; +struct btif_storage_get_remote_addr_type2 btif_storage_get_remote_addr_type2; +struct btif_storage_get_remote_device_property + btif_storage_get_remote_device_property; +struct btif_storage_get_remote_device_type btif_storage_get_remote_device_type; +struct btif_storage_get_remote_prop btif_storage_get_remote_prop; +struct btif_storage_get_sr_supp_feat btif_storage_get_sr_supp_feat; +struct btif_storage_get_stored_remote_name btif_storage_get_stored_remote_name; +struct btif_storage_invoke_addr_type_update + btif_storage_invoke_addr_type_update; +struct btif_storage_is_restricted_device btif_storage_is_restricted_device; +struct btif_storage_load_bonded_devices btif_storage_load_bonded_devices; +struct btif_storage_load_le_devices btif_storage_load_le_devices; +struct btif_storage_remove_ble_bonding_keys + btif_storage_remove_ble_bonding_keys; +struct btif_storage_remove_ble_local_keys btif_storage_remove_ble_local_keys; +struct btif_storage_remove_bonded_device btif_storage_remove_bonded_device; +struct btif_storage_remove_gatt_cl_db_hash btif_storage_remove_gatt_cl_db_hash; +struct btif_storage_remove_gatt_cl_supp_feat + btif_storage_remove_gatt_cl_supp_feat; +struct btif_storage_set_adapter_property btif_storage_set_adapter_property; +struct btif_storage_set_gatt_cl_db_hash btif_storage_set_gatt_cl_db_hash; +struct btif_storage_set_gatt_cl_supp_feat btif_storage_set_gatt_cl_supp_feat; +struct btif_storage_set_gatt_sr_supp_feat btif_storage_set_gatt_sr_supp_feat; +struct btif_storage_set_remote_addr_type btif_storage_set_remote_addr_type; +struct btif_storage_set_remote_addr_type2 btif_storage_set_remote_addr_type2; +struct btif_storage_set_remote_device_property + btif_storage_set_remote_device_property; +struct btif_storage_set_remote_device_type btif_storage_set_remote_device_type; + +} // namespace btif_storage +} // namespace mock +} // namespace test + +// Mocked function return values, if any +namespace test { +namespace mock { +namespace btif_storage { + +bool btif_has_ble_keys::return_value = false; +bt_status_t btif_in_fetch_bonded_ble_device::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_in_fetch_bonded_device::return_value = BT_STATUS_SUCCESS; +size_t btif_split_uuids_string::return_value = 0; +bt_status_t btif_storage_add_ble_bonding_key::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_add_ble_local_key::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_add_bonded_device::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_add_remote_device::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_get_adapter_prop::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_get_adapter_property::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_get_ble_bonding_key::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_get_ble_local_key::return_value = BT_STATUS_SUCCESS; +Octet16 btif_storage_get_gatt_cl_db_hash::return_value = {}; +uint8_t btif_storage_get_gatt_cl_supp_feat::return_value = 0; +tBTM_IO_CAP btif_storage_get_local_io_caps::return_value = 0; +int btif_storage_get_num_bonded_devices::return_value = 0; +bt_status_t btif_storage_get_remote_addr_type::return_value = BT_STATUS_SUCCESS; +bool btif_storage_get_remote_addr_type2::return_value = false; +bt_status_t btif_storage_get_remote_device_property::return_value = + BT_STATUS_SUCCESS; +bool btif_storage_get_remote_device_type::return_value = false; +bt_status_t btif_storage_get_remote_prop::return_value = BT_STATUS_SUCCESS; +uint8_t btif_storage_get_sr_supp_feat::return_value = 0; +bool btif_storage_get_stored_remote_name::return_value = false; +bool btif_storage_is_restricted_device::return_value = false; +bt_status_t btif_storage_load_bonded_devices::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_remove_ble_bonding_keys::return_value = + BT_STATUS_SUCCESS; +bt_status_t btif_storage_remove_ble_local_keys::return_value = + BT_STATUS_SUCCESS; +bt_status_t btif_storage_remove_bonded_device::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_set_adapter_property::return_value = BT_STATUS_SUCCESS; +bt_status_t btif_storage_set_remote_device_property::return_value = + BT_STATUS_SUCCESS; + +} // namespace btif_storage +} // namespace mock +} // namespace test + +// Mocked functions, if any +void btif_debug_linkkey_type_dump(int fd) { inc_func_call_count(__func__); - Octet16 octet; - return octet; + test::mock::btif_storage::btif_debug_linkkey_type_dump(fd); } bool btif_has_ble_keys(const std::string& bdstr) { inc_func_call_count(__func__); - return false; + return test::mock::btif_storage::btif_has_ble_keys(bdstr); } -bool btif_storage_get_hearing_aid_prop( - const RawAddress& address, uint8_t* capabilities, uint64_t* hi_sync_id, - uint16_t* render_delay, uint16_t* preparation_delay, uint16_t* codecs) { +bt_status_t btif_in_fetch_bonded_ble_device( + const std::string& remote_bd_addr, int add, + btif_bonded_devices_t* p_bonded_devices) { inc_func_call_count(__func__); - return false; + return test::mock::btif_storage::btif_in_fetch_bonded_ble_device( + remote_bd_addr, add, p_bonded_devices); } -bool btif_storage_get_stored_remote_name(const RawAddress& bd_addr, - char* name) { +bt_status_t btif_in_fetch_bonded_device(const std::string& bdstr) { inc_func_call_count(__func__); - return false; + return test::mock::btif_storage::btif_in_fetch_bonded_device(bdstr); } -bool btif_storage_is_restricted_device(const RawAddress* remote_bd_addr) { +size_t btif_split_uuids_string(const char* str, bluetooth::Uuid* p_uuid, + size_t max_uuids) { inc_func_call_count(__func__); - return false; + return test::mock::btif_storage::btif_split_uuids_string(str, p_uuid, + max_uuids); } bt_status_t btif_storage_add_ble_bonding_key(RawAddress* remote_bd_addr, - const uint8_t* key, + const uint8_t* key_value, uint8_t key_type, uint8_t key_length) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_add_ble_bonding_key( + remote_bd_addr, key_value, key_type, key_length); } -bt_status_t btif_storage_add_ble_local_key(const Octet16& key, +bt_status_t btif_storage_add_ble_local_key(const Octet16& key_value, uint8_t key_type) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_add_ble_local_key(key_value, + key_type); } bt_status_t btif_storage_add_bonded_device(RawAddress* remote_bd_addr, LinkKey link_key, uint8_t key_type, uint8_t pin_length) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; -} -bt_status_t btif_storage_add_hid_device_info( - RawAddress* remote_bd_addr, uint16_t attr_mask, uint8_t sub_class, - uint8_t app_id, uint16_t vendor_id, uint16_t product_id, uint16_t version, - uint8_t ctry_code, uint16_t ssr_max_latency, uint16_t ssr_min_tout, - uint16_t dl_len, uint8_t* dsc_list) { - inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_add_bonded_device( + remote_bd_addr, link_key, key_type, pin_length); } bt_status_t btif_storage_add_remote_device(const RawAddress* remote_bd_addr, uint32_t num_properties, bt_property_t* properties) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_add_remote_device( + remote_bd_addr, num_properties, properties); +} +bt_status_t btif_storage_get_adapter_prop(bt_property_type_t type, void* buf, + int size, bt_property_t* property) { + inc_func_call_count(__func__); + return test::mock::btif_storage::btif_storage_get_adapter_prop( + type, buf, size, property); } bt_status_t btif_storage_get_adapter_property(bt_property_t* property) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_adapter_property(property); } bt_status_t btif_storage_get_ble_bonding_key(const RawAddress& remote_bd_addr, uint8_t key_type, uint8_t* key_value, int key_length) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_ble_bonding_key( + remote_bd_addr, key_type, key_value, key_length); } bt_status_t btif_storage_get_ble_local_key(uint8_t key_type, Octet16* key_value) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; -} -bt_status_t btif_storage_get_remote_addr_type(const RawAddress* remote_bd_addr, - tBLE_ADDR_TYPE* addr_type) { - inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_ble_local_key(key_type, + key_value); } -bt_status_t btif_storage_get_remote_device_property( - const RawAddress* remote_bd_addr, bt_property_t* property) { +Octet16 btif_storage_get_gatt_cl_db_hash(const RawAddress& bd_addr) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_gatt_cl_db_hash(bd_addr); } -bt_status_t btif_storage_load_bonded_devices(void) { +uint8_t btif_storage_get_gatt_cl_supp_feat(const RawAddress& bd_addr) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_gatt_cl_supp_feat(bd_addr); } -bt_status_t btif_storage_load_bonded_hid_info(void) { +tBTM_IO_CAP btif_storage_get_local_io_caps() { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_local_io_caps(); } -bt_status_t btif_storage_load_hidd(void) { +int btif_storage_get_num_bonded_devices(void) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_num_bonded_devices(); } -bt_status_t btif_storage_remove_ble_bonding_keys( - const RawAddress* remote_bd_addr) { +bt_status_t btif_storage_get_remote_addr_type(const RawAddress* remote_bd_addr, + tBLE_ADDR_TYPE* addr_type) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_remote_addr_type( + remote_bd_addr, addr_type); } -bt_status_t btif_storage_remove_ble_local_keys(void) { +bool btif_storage_get_remote_addr_type(const RawAddress& remote_bd_addr, + tBLE_ADDR_TYPE& addr_type) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_remote_addr_type2( + remote_bd_addr, addr_type); } -bt_status_t btif_storage_remove_bonded_device( - const RawAddress* remote_bd_addr) { +bt_status_t btif_storage_get_remote_device_property( + const RawAddress* remote_bd_addr, bt_property_t* property) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_remote_device_property( + remote_bd_addr, property); } -bt_status_t btif_storage_remove_hid_info(const RawAddress& remote_bd_addr) { +bool btif_storage_get_remote_device_type(const RawAddress& remote_bd_addr, + tBT_DEVICE_TYPE& device_type) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_remote_device_type( + remote_bd_addr, device_type); } -bt_status_t btif_storage_remove_hidd(RawAddress* remote_bd_addr) { +bt_status_t btif_storage_get_remote_prop(RawAddress* remote_addr, + bt_property_type_t type, void* buf, + int size, bt_property_t* property) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_remote_prop( + remote_addr, type, buf, size, property); } -bt_status_t btif_storage_set_adapter_property(bt_property_t* property) { +uint8_t btif_storage_get_sr_supp_feat(const RawAddress& bd_addr) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_sr_supp_feat(bd_addr); } -bt_status_t btif_storage_set_hidd(const RawAddress& remote_bd_addr) { +bool btif_storage_get_stored_remote_name(const RawAddress& bd_addr, + char* name) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + return test::mock::btif_storage::btif_storage_get_stored_remote_name(bd_addr, + name); } -bt_status_t btif_storage_set_remote_addr_type(const RawAddress* remote_bd_addr, - tBLE_ADDR_TYPE addr_type) { +void btif_storage_invoke_addr_type_update(const RawAddress& remote_bd_addr, + const tBLE_ADDR_TYPE& addr_type) { inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; + test::mock::btif_storage::btif_storage_invoke_addr_type_update(remote_bd_addr, + addr_type); } -bt_status_t btif_storage_set_remote_device_property( - const RawAddress* remote_bd_addr, bt_property_t* property) { - inc_func_call_count(__func__); - return BT_STATUS_SUCCESS; -} -void btif_storage_add_hearing_aid(const HearingDevice& dev_info) { +bool btif_storage_is_restricted_device(const RawAddress* remote_bd_addr) { inc_func_call_count(__func__); + return test::mock::btif_storage::btif_storage_is_restricted_device( + remote_bd_addr); } -int btif_storage_get_num_bonded_devices(void) { +bt_status_t btif_storage_load_bonded_devices(void) { inc_func_call_count(__func__); - return 0; + return test::mock::btif_storage::btif_storage_load_bonded_devices(); } -size_t btif_split_uuids_string(const char* str, bluetooth::Uuid* p_uuid, - size_t max_uuids) { +void btif_storage_load_le_devices(void) { inc_func_call_count(__func__); - return 0; + test::mock::btif_storage::btif_storage_load_le_devices(); } -uint8_t btif_storage_get_gatt_cl_supp_feat(const RawAddress& bd_addr) { +bt_status_t btif_storage_remove_ble_bonding_keys( + const RawAddress* remote_bd_addr) { inc_func_call_count(__func__); - return 0; + return test::mock::btif_storage::btif_storage_remove_ble_bonding_keys( + remote_bd_addr); } -tBTM_IO_CAP btif_storage_get_local_io_caps() { +bt_status_t btif_storage_remove_ble_local_keys(void) { inc_func_call_count(__func__); - return BTM_IO_CAP_UNKNOWN; + return test::mock::btif_storage::btif_storage_remove_ble_local_keys(); } -tBTM_IO_CAP btif_storage_get_local_io_caps_ble() { +bt_status_t btif_storage_remove_bonded_device( + const RawAddress* remote_bd_addr) { inc_func_call_count(__func__); - return BTM_IO_CAP_UNKNOWN; + return test::mock::btif_storage::btif_storage_remove_bonded_device( + remote_bd_addr); } -void btif_storage_load_bonded_hearing_aids() { inc_func_call_count(__func__); } void btif_storage_remove_gatt_cl_db_hash(const RawAddress& bd_addr) { inc_func_call_count(__func__); + test::mock::btif_storage::btif_storage_remove_gatt_cl_db_hash(bd_addr); } void btif_storage_remove_gatt_cl_supp_feat(const RawAddress& bd_addr) { inc_func_call_count(__func__); + test::mock::btif_storage::btif_storage_remove_gatt_cl_supp_feat(bd_addr); } -void btif_storage_remove_hearing_aid(const RawAddress& address) { +bt_status_t btif_storage_set_adapter_property(bt_property_t* property) { inc_func_call_count(__func__); + return test::mock::btif_storage::btif_storage_set_adapter_property(property); } void btif_storage_set_gatt_cl_db_hash(const RawAddress& bd_addr, Octet16 hash) { inc_func_call_count(__func__); + test::mock::btif_storage::btif_storage_set_gatt_cl_db_hash(bd_addr, hash); } void btif_storage_set_gatt_cl_supp_feat(const RawAddress& bd_addr, uint8_t feat) { inc_func_call_count(__func__); -} -void btif_storage_set_hearing_aid_acceptlist(const RawAddress& address, - bool add_to_acceptlist) { - inc_func_call_count(__func__); + test::mock::btif_storage::btif_storage_set_gatt_cl_supp_feat(bd_addr, feat); } void btif_storage_set_gatt_sr_supp_feat(const RawAddress& addr, uint8_t feat) { inc_func_call_count(__func__); + test::mock::btif_storage::btif_storage_set_gatt_sr_supp_feat(addr, feat); } -uint8_t btif_storage_get_sr_supp_feat(const RawAddress& bd_addr) { - inc_func_call_count(__func__); - return 0; -} -void btif_storage_add_groups(RawAddress const&) { - inc_func_call_count(__func__); -} -void btif_storage_remove_groups(RawAddress const&) { - inc_func_call_count(__func__); -} -void btif_storage_load_bonded_groups() { inc_func_call_count(__func__); } -void btif_storage_set_csis_autoconnect(const RawAddress& addr, - bool autoconnect) { - inc_func_call_count(__func__); -} -void btif_storage_update_csis_info(const RawAddress& addr) { +bt_status_t btif_storage_set_remote_addr_type(const RawAddress* remote_bd_addr, + const tBLE_ADDR_TYPE addr_type) { inc_func_call_count(__func__); + return test::mock::btif_storage::btif_storage_set_remote_addr_type( + remote_bd_addr, addr_type); } -void btif_storage_load_bonded_csis_devices() { inc_func_call_count(__func__); } -void btif_storage_remove_csis_device(const RawAddress& address) { +void btif_storage_set_remote_addr_type(const RawAddress& remote_bd_addr, + const tBLE_ADDR_TYPE& addr_type) { inc_func_call_count(__func__); + test::mock::btif_storage::btif_storage_set_remote_addr_type2(remote_bd_addr, + addr_type); } -void btif_storage_set_pce_profile_version(const RawAddress& remote_bd_addr, - uint16_t peer_pce_version) { +bt_status_t btif_storage_set_remote_device_property( + const RawAddress* remote_bd_addr, bt_property_t* property) { inc_func_call_count(__func__); + return test::mock::btif_storage::btif_storage_set_remote_device_property( + remote_bd_addr, property); } -bool btif_storage_is_pce_version_102(const RawAddress& remote_bd_addr) { +void btif_storage_set_remote_device_type(const RawAddress& remote_bd_addr, + const tBT_DEVICE_TYPE& device_type) { inc_func_call_count(__func__); - return false; + test::mock::btif_storage::btif_storage_set_remote_device_type(remote_bd_addr, + device_type); } +// Mocked functions complete +// END mockcify generation diff --git a/system/test/mock/mock_btif_storage.h b/system/test/mock/mock_btif_storage.h new file mode 100644 index 0000000000000000000000000000000000000000..e38a1bb5441377266469bcac71f97f341270c6ba --- /dev/null +++ b/system/test/mock/mock_btif_storage.h @@ -0,0 +1,627 @@ +/* + * Copyright 2023 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 + +/* + * Generated mock file from original source file + * Functions generated:41 + * + * mockcify.pl ver 0.7.0 + */ + +#include +#include + +// Original included files, if any +// NOTE: Since this is a mock file with mock definitions some number of +// include files may not be required. The include-what-you-use +// still applies, but crafting proper inclusion is out of scope +// for this effort. This compilation unit may compile as-is, or +// may need attention to prune from (or add to ) the inclusion set. + +#include "btif/include/btif_storage.h" +#include "stack/include/bt_octets.h" +#include "types/bluetooth/uuid.h" +#include "types/raw_address.h" + +// Original usings + +// Mocked compile conditionals, if any + +namespace test { +namespace mock { +namespace btif_storage { + +// Shared state between mocked functions and tests +// Name: btif_debug_linkkey_type_dump +// Params: int fd +// Return: void +struct btif_debug_linkkey_type_dump { + std::function body{[](int /* fd */) {}}; + void operator()(int fd) { body(fd); }; +}; +extern struct btif_debug_linkkey_type_dump btif_debug_linkkey_type_dump; + +// Name: btif_has_ble_keys +// Params: const std::string& bdstr +// Return: bool +struct btif_has_ble_keys { + static bool return_value; + std::function body{ + [](const std::string& /* bdstr */) { return return_value; }}; + bool operator()(const std::string& bdstr) { return body(bdstr); }; +}; +extern struct btif_has_ble_keys btif_has_ble_keys; + +// Name: btif_in_fetch_bonded_ble_device +// Params: const std::string& remote_bd_addr, int add, btif_bonded_devices_t* +// p_bonded_devices Return: bt_status_t +struct btif_in_fetch_bonded_ble_device { + static bt_status_t return_value; + std::function + body{[](const std::string& /* remote_bd_addr */, int /* add */, + btif_bonded_devices_t* /* p_bonded_devices */) { + return return_value; + }}; + bt_status_t operator()(const std::string& remote_bd_addr, int add, + btif_bonded_devices_t* p_bonded_devices) { + return body(remote_bd_addr, add, p_bonded_devices); + }; +}; +extern struct btif_in_fetch_bonded_ble_device btif_in_fetch_bonded_ble_device; + +// Name: btif_in_fetch_bonded_device +// Params: const std::string& bdstr +// Return: bt_status_t +struct btif_in_fetch_bonded_device { + static bt_status_t return_value; + std::function body{ + [](const std::string& /* bdstr */) { return return_value; }}; + bt_status_t operator()(const std::string& bdstr) { return body(bdstr); }; +}; +extern struct btif_in_fetch_bonded_device btif_in_fetch_bonded_device; + +// Name: btif_split_uuids_string +// Params: const char* str, bluetooth::Uuid* p_uuid, size_t max_uuids +// Return: size_t +struct btif_split_uuids_string { + static size_t return_value; + std::function + body{[](const char* /* str */, bluetooth::Uuid* /* p_uuid */, + size_t /* max_uuids */) { return return_value; }}; + size_t operator()(const char* str, bluetooth::Uuid* p_uuid, + size_t max_uuids) { + return body(str, p_uuid, max_uuids); + }; +}; +extern struct btif_split_uuids_string btif_split_uuids_string; + +// Name: btif_storage_add_ble_bonding_key +// Params: RawAddress* remote_bd_addr, const uint8_t* key_value, uint8_t +// key_type, uint8_t key_length Return: bt_status_t +struct btif_storage_add_ble_bonding_key { + static bt_status_t return_value; + std::function + body{[](RawAddress* /* remote_bd_addr */, const uint8_t* /* key_value */, + uint8_t /* key_type */, + uint8_t /* key_length */) { return return_value; }}; + bt_status_t operator()(RawAddress* remote_bd_addr, const uint8_t* key_value, + uint8_t key_type, uint8_t key_length) { + return body(remote_bd_addr, key_value, key_type, key_length); + }; +}; +extern struct btif_storage_add_ble_bonding_key btif_storage_add_ble_bonding_key; + +// Name: btif_storage_add_ble_local_key +// Params: const Octet16& key_value, uint8_t key_type +// Return: bt_status_t +struct btif_storage_add_ble_local_key { + static bt_status_t return_value; + std::function body{ + [](const Octet16& /* key_value */, uint8_t /* key_type */) { + return return_value; + }}; + bt_status_t operator()(const Octet16& key_value, uint8_t key_type) { + return body(key_value, key_type); + }; +}; +extern struct btif_storage_add_ble_local_key btif_storage_add_ble_local_key; + +// Name: btif_storage_add_bonded_device +// Params: RawAddress* remote_bd_addr, LinkKey link_key, uint8_t key_type, +// uint8_t pin_length Return: bt_status_t +struct btif_storage_add_bonded_device { + static bt_status_t return_value; + std::function + body{[](RawAddress* /* remote_bd_addr */, LinkKey /* link_key */, + uint8_t /* key_type */, + uint8_t /* pin_length */) { return return_value; }}; + bt_status_t operator()(RawAddress* remote_bd_addr, LinkKey link_key, + uint8_t key_type, uint8_t pin_length) { + return body(remote_bd_addr, link_key, key_type, pin_length); + }; +}; +extern struct btif_storage_add_bonded_device btif_storage_add_bonded_device; + +// Name: btif_storage_add_remote_device +// Params: const RawAddress* remote_bd_addr, uint32_t num_properties, +// bt_property_t* properties Return: bt_status_t +struct btif_storage_add_remote_device { + static bt_status_t return_value; + std::function + body{[](const RawAddress* /* remote_bd_addr */, + uint32_t /* num_properties */, + bt_property_t* /* properties */) { return return_value; }}; + bt_status_t operator()(const RawAddress* remote_bd_addr, + uint32_t num_properties, bt_property_t* properties) { + return body(remote_bd_addr, num_properties, properties); + }; +}; +extern struct btif_storage_add_remote_device btif_storage_add_remote_device; + +// Name: btif_storage_get_adapter_prop +// Params: bt_property_type_t type, void* buf, int size, bt_property_t* property +// Return: bt_status_t +struct btif_storage_get_adapter_prop { + static bt_status_t return_value; + std::function + body{[](bt_property_type_t /* type */, void* /* buf */, int /* size */, + bt_property_t* /* property */) { return return_value; }}; + bt_status_t operator()(bt_property_type_t type, void* buf, int size, + bt_property_t* property) { + return body(type, buf, size, property); + }; +}; +extern struct btif_storage_get_adapter_prop btif_storage_get_adapter_prop; + +// Name: btif_storage_get_adapter_property +// Params: bt_property_t* property +// Return: bt_status_t +struct btif_storage_get_adapter_property { + static bt_status_t return_value; + std::function body{ + [](bt_property_t* /* property */) { return return_value; }}; + bt_status_t operator()(bt_property_t* property) { return body(property); }; +}; +extern struct btif_storage_get_adapter_property + btif_storage_get_adapter_property; + +// Name: btif_storage_get_ble_bonding_key +// Params: const RawAddress& remote_bd_addr, uint8_t key_type, uint8_t* +// key_value, int key_length Return: bt_status_t +struct btif_storage_get_ble_bonding_key { + static bt_status_t return_value; + std::function + body{[](const RawAddress& /* remote_bd_addr */, uint8_t /* key_type */, + uint8_t* /* key_value */, + int /* key_length */) { return return_value; }}; + bt_status_t operator()(const RawAddress& remote_bd_addr, uint8_t key_type, + uint8_t* key_value, int key_length) { + return body(remote_bd_addr, key_type, key_value, key_length); + }; +}; +extern struct btif_storage_get_ble_bonding_key btif_storage_get_ble_bonding_key; + +// Name: btif_storage_get_ble_local_key +// Params: uint8_t key_type, Octet16* key_value +// Return: bt_status_t +struct btif_storage_get_ble_local_key { + static bt_status_t return_value; + std::function body{ + [](uint8_t /* key_type */, Octet16* /* key_value */) { + return return_value; + }}; + bt_status_t operator()(uint8_t key_type, Octet16* key_value) { + return body(key_type, key_value); + }; +}; +extern struct btif_storage_get_ble_local_key btif_storage_get_ble_local_key; + +// Name: btif_storage_get_gatt_cl_db_hash +// Params: const RawAddress& bd_addr +// Return: Octet16 +struct btif_storage_get_gatt_cl_db_hash { + static Octet16 return_value; + std::function body{ + [](const RawAddress& /* bd_addr */) { return return_value; }}; + Octet16 operator()(const RawAddress& bd_addr) { return body(bd_addr); }; +}; +extern struct btif_storage_get_gatt_cl_db_hash btif_storage_get_gatt_cl_db_hash; + +// Name: btif_storage_get_gatt_cl_supp_feat +// Params: const RawAddress& bd_addr +// Return: uint8_t +struct btif_storage_get_gatt_cl_supp_feat { + static uint8_t return_value; + std::function body{ + [](const RawAddress& /* bd_addr */) { return return_value; }}; + uint8_t operator()(const RawAddress& bd_addr) { return body(bd_addr); }; +}; +extern struct btif_storage_get_gatt_cl_supp_feat + btif_storage_get_gatt_cl_supp_feat; + +// Name: btif_storage_get_local_io_caps +// Params: +// Return: tBTM_IO_CAP +struct btif_storage_get_local_io_caps { + static tBTM_IO_CAP return_value; + std::function body{[]() { return return_value; }}; + tBTM_IO_CAP operator()() { return body(); }; +}; +extern struct btif_storage_get_local_io_caps btif_storage_get_local_io_caps; + +// Name: btif_storage_get_num_bonded_devices +// Params: void +// Return: int +struct btif_storage_get_num_bonded_devices { + static int return_value; + std::function body{[](void) { return return_value; }}; + int operator()(void) { return body(); }; +}; +extern struct btif_storage_get_num_bonded_devices + btif_storage_get_num_bonded_devices; + +// Name: btif_storage_get_remote_addr_type +// Params: const RawAddress* remote_bd_addr, tBLE_ADDR_TYPE addr_type +// Return: bt_status_t +struct btif_storage_get_remote_addr_type { + static bt_status_t return_value; + std::function + body{[](const RawAddress* /* remote_bd_addr */, + tBLE_ADDR_TYPE* /* addr_type */) -> bt_status_t { + return return_value; + }}; + bt_status_t operator()(const RawAddress* remote_bd_addr, + tBLE_ADDR_TYPE* addr_type) { + return body(remote_bd_addr, addr_type); + }; +}; +extern struct btif_storage_get_remote_addr_type + btif_storage_get_remote_addr_type; + +// Name: btif_storage_get_remote_addr_type2 +// Params: const RawAddress& remote_bd_addr, tBLE_ADDR_TYPE& addr_type +// Return: bool +struct btif_storage_get_remote_addr_type2 { + static bool return_value; + std::function + body{[](const RawAddress& /* remote_bd_addr */, + tBLE_ADDR_TYPE& /* addr_type */) { return return_value; }}; + bool operator()(const RawAddress& remote_bd_addr, tBLE_ADDR_TYPE& addr_type) { + return body(remote_bd_addr, addr_type); + }; +}; +extern struct btif_storage_get_remote_addr_type2 + btif_storage_get_remote_addr_type2; + +// Name: btif_storage_get_remote_device_property +// Params: const RawAddress* remote_bd_addr, bt_property_t* property +// Return: bt_status_t +struct btif_storage_get_remote_device_property { + static bt_status_t return_value; + std::function + body{[](const RawAddress* /* remote_bd_addr */, + bt_property_t* /* property */) { return return_value; }}; + bt_status_t operator()(const RawAddress* remote_bd_addr, + bt_property_t* property) { + return body(remote_bd_addr, property); + }; +}; +extern struct btif_storage_get_remote_device_property + btif_storage_get_remote_device_property; + +// Name: btif_storage_get_remote_device_type +// Params: const RawAddress& remote_bd_addr, tBT_DEVICE_TYPE& device_type +// Return: bool +struct btif_storage_get_remote_device_type { + static bool return_value; + std::function + body{[](const RawAddress& /* remote_bd_addr */, + tBT_DEVICE_TYPE& /* device_type */) { return return_value; }}; + bool operator()(const RawAddress& remote_bd_addr, + tBT_DEVICE_TYPE& device_type) { + return body(remote_bd_addr, device_type); + }; +}; +extern struct btif_storage_get_remote_device_type + btif_storage_get_remote_device_type; + +// Name: btif_storage_get_remote_prop +// Params: RawAddress* remote_addr, bt_property_type_t type, void* buf, int +// size, bt_property_t* property Return: bt_status_t +struct btif_storage_get_remote_prop { + static bt_status_t return_value; + std::function + body{[](RawAddress* /* remote_addr */, bt_property_type_t /* type */, + void* /* buf */, int /* size */, + bt_property_t* /* property */) { return return_value; }}; + bt_status_t operator()(RawAddress* remote_addr, bt_property_type_t type, + void* buf, int size, bt_property_t* property) { + return body(remote_addr, type, buf, size, property); + }; +}; +extern struct btif_storage_get_remote_prop btif_storage_get_remote_prop; + +// Name: btif_storage_get_sr_supp_feat +// Params: const RawAddress& bd_addr +// Return: uint8_t +struct btif_storage_get_sr_supp_feat { + static uint8_t return_value; + std::function body{ + [](const RawAddress& /* bd_addr */) { return return_value; }}; + uint8_t operator()(const RawAddress& bd_addr) { return body(bd_addr); }; +}; +extern struct btif_storage_get_sr_supp_feat btif_storage_get_sr_supp_feat; + +// Name: btif_storage_get_stored_remote_name +// Params: const RawAddress& bd_addr, char* name +// Return: bool +struct btif_storage_get_stored_remote_name { + static bool return_value; + std::function body{ + [](const RawAddress& /* bd_addr */, char* /* name */) { + return return_value; + }}; + bool operator()(const RawAddress& bd_addr, char* name) { + return body(bd_addr, name); + }; +}; +extern struct btif_storage_get_stored_remote_name + btif_storage_get_stored_remote_name; + +// Name: btif_storage_invoke_addr_type_update +// Params: const RawAddress& remote_bd_addr, const tBLE_ADDR_TYPE& addr_type +// Return: void +struct btif_storage_invoke_addr_type_update { + std::function + body{[](const RawAddress& /* remote_bd_addr */, + const tBLE_ADDR_TYPE& /* addr_type */) {}}; + void operator()(const RawAddress& remote_bd_addr, + const tBLE_ADDR_TYPE& addr_type) { + body(remote_bd_addr, addr_type); + }; +}; +extern struct btif_storage_invoke_addr_type_update + btif_storage_invoke_addr_type_update; + +// Name: btif_storage_is_restricted_device +// Params: const RawAddress* remote_bd_addr +// Return: bool +struct btif_storage_is_restricted_device { + static bool return_value; + std::function body{ + [](const RawAddress* /* remote_bd_addr */) { return return_value; }}; + bool operator()(const RawAddress* remote_bd_addr) { + return body(remote_bd_addr); + }; +}; +extern struct btif_storage_is_restricted_device + btif_storage_is_restricted_device; + +// Name: btif_storage_load_bonded_devices +// Params: void +// Return: bt_status_t +struct btif_storage_load_bonded_devices { + static bt_status_t return_value; + std::function body{[](void) { return return_value; }}; + bt_status_t operator()(void) { return body(); }; +}; +extern struct btif_storage_load_bonded_devices btif_storage_load_bonded_devices; + +// Name: btif_storage_load_le_devices +// Params: void +// Return: void +struct btif_storage_load_le_devices { + std::function body{[](void) {}}; + void operator()(void) { body(); }; +}; +extern struct btif_storage_load_le_devices btif_storage_load_le_devices; + +// Name: btif_storage_remove_ble_bonding_keys +// Params: const RawAddress* remote_bd_addr +// Return: bt_status_t +struct btif_storage_remove_ble_bonding_keys { + static bt_status_t return_value; + std::function body{ + [](const RawAddress* /* remote_bd_addr */) { return return_value; }}; + bt_status_t operator()(const RawAddress* remote_bd_addr) { + return body(remote_bd_addr); + }; +}; +extern struct btif_storage_remove_ble_bonding_keys + btif_storage_remove_ble_bonding_keys; + +// Name: btif_storage_remove_ble_local_keys +// Params: void +// Return: bt_status_t +struct btif_storage_remove_ble_local_keys { + static bt_status_t return_value; + std::function body{[](void) { return return_value; }}; + bt_status_t operator()(void) { return body(); }; +}; +extern struct btif_storage_remove_ble_local_keys + btif_storage_remove_ble_local_keys; + +// Name: btif_storage_remove_bonded_device +// Params: const RawAddress* remote_bd_addr +// Return: bt_status_t +struct btif_storage_remove_bonded_device { + static bt_status_t return_value; + std::function body{ + [](const RawAddress* /* remote_bd_addr */) { return return_value; }}; + bt_status_t operator()(const RawAddress* remote_bd_addr) { + return body(remote_bd_addr); + }; +}; +extern struct btif_storage_remove_bonded_device + btif_storage_remove_bonded_device; + +// Name: btif_storage_remove_gatt_cl_db_hash +// Params: const RawAddress& bd_addr +// Return: void +struct btif_storage_remove_gatt_cl_db_hash { + std::function body{ + [](const RawAddress& /* bd_addr */) {}}; + void operator()(const RawAddress& bd_addr) { body(bd_addr); }; +}; +extern struct btif_storage_remove_gatt_cl_db_hash + btif_storage_remove_gatt_cl_db_hash; + +// Name: btif_storage_remove_gatt_cl_supp_feat +// Params: const RawAddress& bd_addr +// Return: void +struct btif_storage_remove_gatt_cl_supp_feat { + std::function body{ + [](const RawAddress& /* bd_addr */) {}}; + void operator()(const RawAddress& bd_addr) { body(bd_addr); }; +}; +extern struct btif_storage_remove_gatt_cl_supp_feat + btif_storage_remove_gatt_cl_supp_feat; + +// Name: btif_storage_set_adapter_property +// Params: bt_property_t* property +// Return: bt_status_t +struct btif_storage_set_adapter_property { + static bt_status_t return_value; + std::function body{ + [](bt_property_t* /* property */) { return return_value; }}; + bt_status_t operator()(bt_property_t* property) { return body(property); }; +}; +extern struct btif_storage_set_adapter_property + btif_storage_set_adapter_property; + +// Name: btif_storage_set_gatt_cl_db_hash +// Params: const RawAddress& bd_addr, Octet16 hash +// Return: void +struct btif_storage_set_gatt_cl_db_hash { + std::function body{ + [](const RawAddress& /* bd_addr */, Octet16 /* hash */) {}}; + void operator()(const RawAddress& bd_addr, Octet16 hash) { + body(bd_addr, hash); + }; +}; +extern struct btif_storage_set_gatt_cl_db_hash btif_storage_set_gatt_cl_db_hash; + +// Name: btif_storage_set_gatt_cl_supp_feat +// Params: const RawAddress& bd_addr, uint8_t feat +// Return: void +struct btif_storage_set_gatt_cl_supp_feat { + std::function body{ + [](const RawAddress& /* bd_addr */, uint8_t /* feat */) {}}; + void operator()(const RawAddress& bd_addr, uint8_t feat) { + body(bd_addr, feat); + }; +}; +extern struct btif_storage_set_gatt_cl_supp_feat + btif_storage_set_gatt_cl_supp_feat; + +// Name: btif_storage_set_gatt_sr_supp_feat +// Params: const RawAddress& addr, uint8_t feat +// Return: void +struct btif_storage_set_gatt_sr_supp_feat { + std::function body{ + [](const RawAddress& /* addr */, uint8_t /* feat */) {}}; + void operator()(const RawAddress& addr, uint8_t feat) { body(addr, feat); }; +}; +extern struct btif_storage_set_gatt_sr_supp_feat + btif_storage_set_gatt_sr_supp_feat; + +// Name: btif_storage_set_remote_addr_type +// Params: const RawAddress& remote_bd_addr, const tBLE_ADDR_TYPE& addr_type +// Return: void +struct btif_storage_set_remote_addr_type { + std::function + body{[](const RawAddress* /* remote_bd_addr */, + const tBLE_ADDR_TYPE /* addr_type */) { + return BT_STATUS_SUCCESS; + }}; + bt_status_t operator()(const RawAddress* remote_bd_addr, + const tBLE_ADDR_TYPE addr_type) { + return body(remote_bd_addr, addr_type); + }; +}; +extern struct btif_storage_set_remote_addr_type + btif_storage_set_remote_addr_type; + +// Name: btif_storage_set_remote_addr_type +// Params: const RawAddress& remote_bd_addr, const tBLE_ADDR_TYPE& addr_type +// Return: void +struct btif_storage_set_remote_addr_type2 { + std::function + body{[](const RawAddress& /* remote_bd_addr */, + const tBLE_ADDR_TYPE& /* addr_type */) {}}; + void operator()(const RawAddress& remote_bd_addr, + const tBLE_ADDR_TYPE& addr_type) { + body(remote_bd_addr, addr_type); + }; +}; +extern struct btif_storage_set_remote_addr_type2 + btif_storage_set_remote_addr_type2; + +// Name: btif_storage_set_remote_device_property +// Params: const RawAddress* remote_bd_addr, bt_property_t* property +// Return: bt_status_t +struct btif_storage_set_remote_device_property { + static bt_status_t return_value; + std::function + body{[](const RawAddress* /* remote_bd_addr */, + bt_property_t* /* property */) { return return_value; }}; + bt_status_t operator()(const RawAddress* remote_bd_addr, + bt_property_t* property) { + return body(remote_bd_addr, property); + }; +}; +extern struct btif_storage_set_remote_device_property + btif_storage_set_remote_device_property; + +// Name: btif_storage_set_remote_device_type +// Params: const RawAddress& remote_bd_addr, const tBT_DEVICE_TYPE& device_type +// Return: void +struct btif_storage_set_remote_device_type { + std::function + body{[](const RawAddress& /* remote_bd_addr */, + const tBT_DEVICE_TYPE& /* device_type */) {}}; + void operator()(const RawAddress& remote_bd_addr, + const tBT_DEVICE_TYPE& device_type) { + body(remote_bd_addr, device_type); + }; +}; +extern struct btif_storage_set_remote_device_type + btif_storage_set_remote_device_type; + +} // namespace btif_storage +} // namespace mock +} // namespace test + +// END mockcify generation diff --git a/system/test/mock/mock_btif_util.cc b/system/test/mock/mock_btif_util.cc index 4a469f955d63feb9b71e68769ff8a97e4d3ceead..07c350be51e2d034dc687e945a0ec0e894d3999c 100644 --- a/system/test/mock/mock_btif_util.cc +++ b/system/test/mock/mock_btif_util.cc @@ -90,7 +90,7 @@ int ascii_2_hex(const char* p_ascii, int len, uint8_t* p_hex) { inc_func_call_count(__func__); return test::mock::btif_util::ascii_2_hex(p_ascii, len, p_hex); } -uint32_t devclass2uint(DEV_CLASS dev_class) { +uint32_t devclass2uint(const DEV_CLASS dev_class) { inc_func_call_count(__func__); return test::mock::btif_util::devclass2uint(dev_class); } @@ -154,9 +154,9 @@ const char* dump_thread_evt(bt_cb_thread_evt evt) { inc_func_call_count(__func__); return test::mock::btif_util::dump_thread_evt(evt); } -void uint2devclass(uint32_t cod, DEV_CLASS dev_class) { +DEV_CLASS uint2devclass(uint32_t cod) { inc_func_call_count(__func__); - test::mock::btif_util::uint2devclass(cod, dev_class); + return test::mock::btif_util::uint2devclass(cod); } // Mocked functions complete // END mockcify generation diff --git a/system/test/mock/mock_btif_util.h b/system/test/mock/mock_btif_util.h index 473c924b3c7e014e217838281baaff1d4bf744bb..dd7dec3a39708eb1a8629065881b23882e56a003 100644 --- a/system/test/mock/mock_btif_util.h +++ b/system/test/mock/mock_btif_util.h @@ -46,7 +46,7 @@ namespace btif_util { struct ascii_2_hex { static int return_value; std::function body{ - [](const char* p_ascii, int len, uint8_t* p_hex) { + [](const char* /* p_ascii */, int /* len */, uint8_t* /* p_hex */) { return return_value; }}; int operator()(const char* p_ascii, int len, uint8_t* p_hex) { @@ -61,7 +61,7 @@ extern struct ascii_2_hex ascii_2_hex; struct devclass2uint { static uint32_t return_value; std::function body{ - [](DEV_CLASS dev_class) { return return_value; }}; + [](DEV_CLASS /* dev_class */) { return return_value; }}; uint32_t operator()(DEV_CLASS dev_class) { return body(dev_class); }; }; extern struct devclass2uint devclass2uint; @@ -72,7 +72,7 @@ extern struct devclass2uint devclass2uint; struct dump_adapter_scan_mode { static const char* return_value; std::function body{ - [](bt_scan_mode_t mode) { return return_value; }}; + [](bt_scan_mode_t /* mode */) { return return_value; }}; const char* operator()(bt_scan_mode_t mode) { return body(mode); }; }; extern struct dump_adapter_scan_mode dump_adapter_scan_mode; @@ -83,7 +83,7 @@ extern struct dump_adapter_scan_mode dump_adapter_scan_mode; struct dump_av_audio_state { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_av_audio_state dump_av_audio_state; @@ -94,7 +94,7 @@ extern struct dump_av_audio_state dump_av_audio_state; struct dump_av_conn_state { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_av_conn_state dump_av_conn_state; @@ -105,7 +105,7 @@ extern struct dump_av_conn_state dump_av_conn_state; struct dump_bt_status { static const char* return_value; std::function body{ - [](bt_status_t status) { return return_value; }}; + [](bt_status_t /* status */) { return return_value; }}; const char* operator()(bt_status_t status) { return body(status); }; }; extern struct dump_bt_status dump_bt_status; @@ -116,7 +116,7 @@ extern struct dump_bt_status dump_bt_status; struct dump_dm_event { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_dm_event dump_dm_event; @@ -127,7 +127,7 @@ extern struct dump_dm_event dump_dm_event; struct dump_dm_search_event { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_dm_search_event dump_dm_search_event; @@ -138,7 +138,7 @@ extern struct dump_dm_search_event dump_dm_search_event; struct dump_hd_event { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_hd_event dump_hd_event; @@ -149,7 +149,7 @@ extern struct dump_hd_event dump_hd_event; struct dump_hf_client_event { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_hf_client_event dump_hf_client_event; @@ -160,7 +160,7 @@ extern struct dump_hf_client_event dump_hf_client_event; struct dump_hf_event { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_hf_event dump_hf_event; @@ -171,7 +171,7 @@ extern struct dump_hf_event dump_hf_event; struct dump_hh_event { static const char* return_value; std::function body{ - [](uint16_t event) { return return_value; }}; + [](uint16_t /* event */) { return return_value; }}; const char* operator()(uint16_t event) { return body(event); }; }; extern struct dump_hh_event dump_hh_event; @@ -182,7 +182,7 @@ extern struct dump_hh_event dump_hh_event; struct dump_property_type { static const char* return_value; std::function body{ - [](bt_property_type_t type) { return return_value; }}; + [](bt_property_type_t /* type */) { return return_value; }}; const char* operator()(bt_property_type_t type) { return body(type); }; }; extern struct dump_property_type dump_property_type; @@ -193,7 +193,7 @@ extern struct dump_property_type dump_property_type; struct dump_rc_event { static const char* return_value; std::function body{ - [](uint8_t event) { return return_value; }}; + [](uint8_t /* event */) { return return_value; }}; const char* operator()(uint8_t event) { return body(event); }; }; extern struct dump_rc_event dump_rc_event; @@ -204,7 +204,7 @@ extern struct dump_rc_event dump_rc_event; struct dump_rc_notification_event_id { static const char* return_value; std::function body{ - [](uint8_t event_id) { return return_value; }}; + [](uint8_t /* event_id */) { return return_value; }}; const char* operator()(uint8_t event_id) { return body(event_id); }; }; extern struct dump_rc_notification_event_id dump_rc_notification_event_id; @@ -215,7 +215,7 @@ extern struct dump_rc_notification_event_id dump_rc_notification_event_id; struct dump_rc_pdu { static const char* return_value; std::function body{ - [](uint8_t pdu) { return return_value; }}; + [](uint8_t /* pdu */) { return return_value; }}; const char* operator()(uint8_t pdu) { return body(pdu); }; }; extern struct dump_rc_pdu dump_rc_pdu; @@ -226,7 +226,7 @@ extern struct dump_rc_pdu dump_rc_pdu; struct dump_thread_evt { static const char* return_value; std::function body{ - [](bt_cb_thread_evt evt) { return return_value; }}; + [](bt_cb_thread_evt /* evt */) { return return_value; }}; const char* operator()(bt_cb_thread_evt evt) { return body(evt); }; }; extern struct dump_thread_evt dump_thread_evt; @@ -235,9 +235,10 @@ extern struct dump_thread_evt dump_thread_evt; // Params: uint32_t cod, DEV_CLASS dev_class // Return: void struct uint2devclass { - std::function body{ - [](uint32_t cod, DEV_CLASS dev_class) {}}; - void operator()(uint32_t cod, DEV_CLASS dev_class) { body(cod, dev_class); }; + static constexpr DEV_CLASS return_value{}; + std::function body{ + [](uint32_t /* cod */) { return return_value; }}; + DEV_CLASS operator()(uint32_t cod) { return body(cod); }; }; extern struct uint2devclass uint2devclass; diff --git a/system/test/mock/mock_device_controller.cc b/system/test/mock/mock_device_controller.cc index da98d0e30ff002378d449f49b7c468a560b4f8a9..698b54180d901f3382a0362cb2fc85cacd33a832 100644 --- a/system/test/mock/mock_device_controller.cc +++ b/system/test/mock/mock_device_controller.cc @@ -101,34 +101,6 @@ uint8_t* get_local_supported_codecs(uint8_t* number_of_codecs) { const uint8_t* get_ble_supported_states(void) { return ble_supported_states; } -bool supports_simple_pairing(void) { return simple_pairing_supported; } - -bool supports_secure_connections(void) { return secure_connections_supported; } - -bool supports_simultaneous_le_bredr(void) { - return HCI_SIMUL_LE_BREDR_SUPPORTED(features_classic[0].as_array); -} - -bool supports_reading_remote_extended_features(void) { - return HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(supported_commands); -} - -bool supports_interlaced_inquiry_scan(void) { - return HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(features_classic[0].as_array); -} - -bool supports_rssi_with_inquiry_results(void) { - return HCI_LMP_INQ_RSSI_SUPPORTED(features_classic[0].as_array); -} - -bool supports_extended_inquiry_response(void) { - return HCI_EXT_INQ_RSP_SUPPORTED(features_classic[0].as_array); -} - -bool supports_central_peripheral_role_switch(void) { - return HCI_SWITCH_SUPPORTED(features_classic[0].as_array); -} - bool supports_enhanced_setup_synchronous_connection(void) { return HCI_ENH_SETUP_SYNCH_CONN_SUPPORTED(supported_commands); } @@ -137,82 +109,6 @@ bool supports_enhanced_accept_synchronous_connection(void) { return HCI_ENH_ACCEPT_SYNCH_CONN_SUPPORTED(supported_commands); } -bool supports_3_slot_packets(void) { - return HCI_3_SLOT_PACKETS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_5_slot_packets(void) { - return HCI_5_SLOT_PACKETS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_classic_2m_phy(void) { - return HCI_EDR_ACL_2MPS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_classic_3m_phy(void) { - return HCI_EDR_ACL_3MPS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_3_slot_edr_packets(void) { - return HCI_3_SLOT_EDR_ACL_SUPPORTED(features_classic[0].as_array); -} - -bool supports_5_slot_edr_packets(void) { - return HCI_5_SLOT_EDR_ACL_SUPPORTED(features_classic[0].as_array); -} - -bool supports_sco(void) { - return HCI_SCO_LINK_SUPPORTED(features_classic[0].as_array); -} - -bool supports_hv2_packets(void) { - return HCI_HV2_PACKETS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_hv3_packets(void) { - return HCI_HV3_PACKETS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_ev3_packets(void) { - return HCI_ESCO_EV3_SUPPORTED(features_classic[0].as_array); -} - -bool supports_ev4_packets(void) { - return HCI_ESCO_EV4_SUPPORTED(features_classic[0].as_array); -} - -bool supports_ev5_packets(void) { - return HCI_ESCO_EV5_SUPPORTED(features_classic[0].as_array); -} - -bool supports_esco_2m_phy(void) { - return HCI_EDR_ESCO_2MPS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_esco_3m_phy(void) { - return HCI_EDR_ESCO_3MPS_SUPPORTED(features_classic[0].as_array); -} - -bool supports_3_slot_esco_edr_packets(void) { - return HCI_3_SLOT_EDR_ESCO_SUPPORTED(features_classic[0].as_array); -} - -bool supports_role_switch(void) { - return HCI_SWITCH_SUPPORTED(features_classic[0].as_array); -} - -bool supports_non_flushable_pb(void) { - return HCI_NON_FLUSHABLE_PB_SUPPORTED(features_classic[0].as_array); -} - -bool supports_sniff_subrating(void) { - return HCI_SNIFF_SUB_RATE_SUPPORTED(features_classic[0].as_array); -} - -bool supports_encryption_pause(void) { - return HCI_ATOMIC_ENCRYPT_SUPPORTED(features_classic[0].as_array); -} - bool supports_configure_data_path(void) { return HCI_CONFIGURE_DATA_PATH_SUPPORTED(supported_commands); } @@ -266,10 +162,6 @@ bool supports_ble_peripheral_initiated_feature_exchange(void) { return HCI_LE_PERIPHERAL_INIT_FEAT_EXC_SUPPORTED(features_ble.as_array); } -bool supports_ble_connection_parameter_request(void) { - return HCI_LE_CONN_PARAM_REQ_SUPPORTED(features_ble.as_array); -} - bool supports_ble_periodic_advertising_sync_transfer_sender(void) { return HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER( features_ble.as_array); @@ -369,15 +261,16 @@ tBTM_STATUS clear_event_filter() { return BTM_SUCCESS; } tBTM_STATUS clear_event_mask() { return BTM_SUCCESS; } -tBTM_STATUS le_rand(LeRandCallback cb) { return BTM_SUCCESS; } +tBTM_STATUS le_rand(LeRandCallback /* cb */) { return BTM_SUCCESS; } tBTM_STATUS set_event_filter_connection_setup_all_devices() { return BTM_SUCCESS; } tBTM_STATUS set_event_filter_allow_device_connection( - std::vector devices) { + std::vector /* devices */) { return BTM_SUCCESS; } -tBTM_STATUS set_default_event_mask_except(uint64_t mask, uint64_t le_mask) { +tBTM_STATUS set_default_event_mask_except(uint64_t /* mask */, + uint64_t /* le_mask */) { return BTM_SUCCESS; } tBTM_STATUS set_event_filter_inquiry_result_all_devices() { @@ -392,38 +285,8 @@ const controller_t interface = { get_ble_supported_states, - supports_simple_pairing, - supports_secure_connections, - supports_simultaneous_le_bredr, - supports_reading_remote_extended_features, - supports_interlaced_inquiry_scan, - supports_rssi_with_inquiry_results, - supports_extended_inquiry_response, - supports_central_peripheral_role_switch, supports_enhanced_setup_synchronous_connection, supports_enhanced_accept_synchronous_connection, - supports_3_slot_packets, - supports_5_slot_packets, - supports_classic_2m_phy, - supports_classic_3m_phy, - supports_3_slot_edr_packets, - supports_5_slot_edr_packets, - supports_sco, - supports_hv2_packets, - supports_hv3_packets, - supports_ev3_packets, - supports_ev4_packets, - supports_ev5_packets, - supports_esco_2m_phy, - supports_esco_3m_phy, - supports_3_slot_esco_edr_packets, - supports_role_switch, - []() { return supports_hold_mode; }, - []() { return supports_sniff_mode; }, - []() { return supports_park_mode; }, - supports_non_flushable_pb, - supports_sniff_subrating, - supports_encryption_pause, supports_configure_data_path, supports_set_min_encryption_key_size, supports_read_encryption_key_size, @@ -438,7 +301,6 @@ const controller_t interface = { supports_ble_extended_advertising, supports_ble_periodic_advertising, supports_ble_peripheral_initiated_feature_exchange, - supports_ble_connection_parameter_request, supports_ble_periodic_advertising_sync_transfer_sender, supports_ble_periodic_advertising_sync_transfer_recipient, supports_ble_connected_isochronous_stream_central, diff --git a/system/test/mock/mock_device_esco_parameters.cc b/system/test/mock/mock_device_esco_parameters.cc index c5441a9afa6d3caa077137307066ef4b304e3666..311daf7f0b8f163953f63b319a5fccc82e265acd 100644 --- a/system/test/mock/mock_device_esco_parameters.cc +++ b/system/test/mock/mock_device_esco_parameters.cc @@ -44,7 +44,7 @@ enh_esco_params_t esco_parameters_for_codec(esco_codec_t codec) { return test::mock::device_esco_parameters::esco_parameters_for_codec(codec); } -enh_esco_params_t esco_parameters_for_codec(esco_codec_t codec, bool b) { +enh_esco_params_t esco_parameters_for_codec(esco_codec_t codec, bool /* b */) { inc_func_call_count(__func__); return test::mock::device_esco_parameters::esco_parameters_for_codec(codec); } diff --git a/system/test/mock/mock_device_esco_parameters.h b/system/test/mock/mock_device_esco_parameters.h index ecaefdb96df6f3243904a131cb557e29baf9a2fc..2e2e2a60f72737df20bcb52a4466b39bb7aa2867 100644 --- a/system/test/mock/mock_device_esco_parameters.h +++ b/system/test/mock/mock_device_esco_parameters.h @@ -40,7 +40,7 @@ namespace device_esco_parameters { struct esco_parameters_for_codec { enh_esco_params_t return_value{}; std::function body{ - [this](esco_codec_t codec) { return return_value; }}; + [this](esco_codec_t /* codec */) { return return_value; }}; enh_esco_params_t operator()(esco_codec_t codec) { return body(codec); }; }; extern struct esco_parameters_for_codec esco_parameters_for_codec; diff --git a/system/test/mock/mock_device_interop.h b/system/test/mock/mock_device_interop.h index b0362a394814f8e836309cc67b0d5e4494b46f10..2f3a486267b6e2f96350a663b49d4df56196c8d6 100644 --- a/system/test/mock/mock_device_interop.h +++ b/system/test/mock/mock_device_interop.h @@ -46,8 +46,8 @@ namespace device_interop { struct interop_database_add { std::function - body{ - [](const uint16_t feature, const RawAddress* addr, size_t length) {}}; + body{[](const uint16_t /* feature */, const RawAddress* /* addr */, + size_t /* length */) {}}; void operator()(const uint16_t feature, const RawAddress* addr, size_t length) { body(feature, addr, length); @@ -61,8 +61,8 @@ extern struct interop_database_add interop_database_add; struct interop_database_add_addr { std::function - body{ - [](const uint16_t feature, const RawAddress* addr, size_t length) {}}; + body{[](const uint16_t /* feature */, const RawAddress* /* addr */, + size_t /* length */) {}}; void operator()(const uint16_t feature, const RawAddress* addr, size_t length) { body(feature, addr, length); @@ -76,8 +76,9 @@ extern struct interop_database_add_addr interop_database_add_addr; struct interop_database_add_addr_lmp_version { std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - uint8_t lmp_ver, uint16_t lmp_sub_ver) {}}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, uint8_t /* lmp_ver */, + uint16_t /* lmp_sub_ver */) {}}; void operator()(const interop_feature_t feature, const RawAddress* addr, uint8_t lmp_ver, uint16_t lmp_sub_ver) { body(feature, addr, lmp_ver, lmp_sub_ver); @@ -92,8 +93,8 @@ extern struct interop_database_add_addr_lmp_version struct interop_database_add_addr_max_lat { std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - uint16_t max_lat) {}}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, uint16_t /* max_lat */) {}}; void operator()(const interop_feature_t feature, const RawAddress* addr, uint16_t max_lat) { body(feature, addr, max_lat); @@ -107,7 +108,8 @@ extern struct interop_database_add_addr_max_lat // Return: void struct interop_database_add_manufacturer { std::function - body{[](const interop_feature_t feature, uint16_t manufacturer) {}}; + body{[](const interop_feature_t /* feature */, + uint16_t /* manufacturer */) {}}; void operator()(const interop_feature_t feature, uint16_t manufacturer) { body(feature, manufacturer); }; @@ -120,7 +122,7 @@ extern struct interop_database_add_manufacturer // Return: void struct interop_database_add_name { std::function body{ - [](const uint16_t feature, const char* name) {}}; + [](const uint16_t /* feature */, const char* /* name */) {}}; void operator()(const uint16_t feature, const char* name) { body(feature, name); }; @@ -132,7 +134,7 @@ extern struct interop_database_add_name interop_database_add_name; // Return: void struct interop_database_add_version { std::function body{ - [](const interop_feature_t feature, uint16_t version) {}}; + [](const interop_feature_t /* feature */, uint16_t /* version */) {}}; void operator()(const interop_feature_t feature, uint16_t version) { body(feature, version); }; @@ -145,8 +147,8 @@ extern struct interop_database_add_version interop_database_add_version; struct interop_database_add_vndr_prdt { std::function - body{[](const interop_feature_t feature, uint16_t vendor_id, - uint16_t product_id) {}}; + body{[](const interop_feature_t /* feature */, uint16_t /* vendor_id */, + uint16_t /* product_id */) {}}; void operator()(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id) { body(feature, vendor_id, product_id); @@ -169,9 +171,8 @@ extern struct interop_database_clear interop_database_clear; struct interop_database_match_addr { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr) { - return return_value; - }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr) { return body(feature, addr); }; @@ -185,9 +186,9 @@ struct interop_database_match_addr_get_lmp_ver { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - uint8_t* lmp_ver, - uint16_t* lmp_sub_ver) { return return_value; }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, uint8_t* /* lmp_ver */, + uint16_t* /* lmp_sub_ver */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr, uint8_t* lmp_ver, uint16_t* lmp_sub_ver) { return body(feature, addr, lmp_ver, lmp_sub_ver); @@ -203,8 +204,9 @@ struct interop_database_match_addr_get_max_lat { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - uint16_t* max_lat) { return return_value; }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, + uint16_t* /* max_lat */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr, uint16_t* max_lat) { return body(feature, addr, max_lat); @@ -219,9 +221,8 @@ extern struct interop_database_match_addr_get_max_lat struct interop_database_match_manufacturer { static bool return_value; std::function - body{[](const interop_feature_t feature, uint16_t manufacturer) { - return return_value; - }}; + body{[](const interop_feature_t /* feature */, + uint16_t /* manufacturer */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t manufacturer) { return body(feature, manufacturer); }; @@ -235,7 +236,7 @@ extern struct interop_database_match_manufacturer struct interop_database_match_name { static bool return_value; std::function body{ - [](const interop_feature_t feature, const char* name) { + [](const interop_feature_t /* feature */, const char* /* name */) { return return_value; }}; bool operator()(const interop_feature_t feature, const char* name) { @@ -250,7 +251,7 @@ extern struct interop_database_match_name interop_database_match_name; struct interop_database_match_version { static bool return_value; std::function body{ - [](const interop_feature_t feature, uint16_t version) { + [](const interop_feature_t /* feature */, uint16_t /* version */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t version) { @@ -266,8 +267,8 @@ struct interop_database_match_vndr_prdt { static bool return_value; std::function - body{[](const interop_feature_t feature, uint16_t vendor_id, - uint16_t product_id) { return return_value; }}; + body{[](const interop_feature_t /* feature */, uint16_t /* vendor_id */, + uint16_t /* product_id */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id) { return body(feature, vendor_id, product_id); @@ -281,9 +282,8 @@ extern struct interop_database_match_vndr_prdt interop_database_match_vndr_prdt; struct interop_database_remove_addr { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr) { - return return_value; - }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr) { return body(feature, addr); }; @@ -297,8 +297,9 @@ struct interop_database_remove_addr_lmp_version { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - uint8_t lmp_ver, uint16_t lmp_sub_ver) { return return_value; }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, uint8_t /* lmp_ver */, + uint16_t /* lmp_sub_ver */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr, uint8_t lmp_ver, uint16_t lmp_sub_ver) { return body(feature, addr, lmp_ver, lmp_sub_ver); @@ -314,8 +315,9 @@ struct interop_database_remove_addr_max_lat { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - uint16_t max_lat) { return return_value; }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, + uint16_t /* max_lat */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr, uint16_t max_lat) { return body(feature, addr, max_lat); @@ -330,7 +332,7 @@ extern struct interop_database_remove_addr_max_lat struct interop_database_remove_feature { static bool return_value; std::function body{ - [](const interop_feature_t feature) { return return_value; }}; + [](const interop_feature_t /* feature */) { return return_value; }}; bool operator()(const interop_feature_t feature) { return body(feature); }; }; extern struct interop_database_remove_feature interop_database_remove_feature; @@ -341,9 +343,8 @@ extern struct interop_database_remove_feature interop_database_remove_feature; struct interop_database_remove_manufacturer { static bool return_value; std::function - body{[](const interop_feature_t feature, uint16_t manufacturer) { - return return_value; - }}; + body{[](const interop_feature_t /* feature */, + uint16_t /* manufacturer */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t manufacturer) { return body(feature, manufacturer); }; @@ -357,7 +358,7 @@ extern struct interop_database_remove_manufacturer struct interop_database_remove_name { static bool return_value; std::function body{ - [](const interop_feature_t feature, const char* name) { + [](const interop_feature_t /* feature */, const char* /* name */) { return return_value; }}; bool operator()(const interop_feature_t feature, const char* name) { @@ -372,7 +373,7 @@ extern struct interop_database_remove_name interop_database_remove_name; struct interop_database_remove_version { static bool return_value; std::function body{ - [](const interop_feature_t feature, uint16_t version) { + [](const interop_feature_t /* feature */, uint16_t /* version */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t version) { @@ -388,8 +389,8 @@ struct interop_database_remove_vndr_prdt { static bool return_value; std::function - body{[](const interop_feature_t feature, uint16_t vendor_id, - uint16_t product_id) { return return_value; }}; + body{[](const interop_feature_t /* feature */, uint16_t /* vendor_id */, + uint16_t /* product_id */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id) { return body(feature, vendor_id, product_id); @@ -404,7 +405,7 @@ extern struct interop_database_remove_vndr_prdt struct interop_feature_name_to_feature_id { static int return_value; std::function body{ - [](const char* feature_name) { return return_value; }}; + [](const char* /* feature_name */) { return return_value; }}; int operator()(const char* feature_name) { return body(feature_name); }; }; extern struct interop_feature_name_to_feature_id @@ -416,7 +417,7 @@ extern struct interop_feature_name_to_feature_id struct interop_get_allowlisted_media_players_list { static bool return_value; std::function body{ - [](list_t* p_bl_devices) { return return_value; }}; + [](list_t* /* p_bl_devices */) { return return_value; }}; bool operator()(list_t* p_bl_devices) { return body(p_bl_devices); }; }; extern struct interop_get_allowlisted_media_players_list @@ -428,9 +429,8 @@ extern struct interop_get_allowlisted_media_players_list struct interop_match_addr { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr) { - return return_value; - }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr) { return body(feature, addr); }; @@ -444,8 +444,9 @@ struct interop_match_addr_get_max_lat { static bool return_value; std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - uint16_t* max_lat) { return return_value; }}; + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, + uint16_t* /* max_lat */) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr, uint16_t* max_lat) { return body(feature, addr, max_lat); @@ -461,8 +462,9 @@ struct interop_match_addr_or_name { std::function - body{[](const interop_feature_t feature, const RawAddress* addr, - bt_status_t (*get_remote_device_property)( + body{[](const interop_feature_t /* feature */, + const RawAddress* /* addr */, + bt_status_t (* /* get_remote_device_property */)( const RawAddress*, bt_property_t*)) { return return_value; }}; bool operator()(const interop_feature_t feature, const RawAddress* addr, bt_status_t (*get_remote_device_property)(const RawAddress*, @@ -478,9 +480,8 @@ extern struct interop_match_addr_or_name interop_match_addr_or_name; struct interop_match_manufacturer { static bool return_value; std::function - body{[](const interop_feature_t feature, uint16_t manufacturer) { - return return_value; - }}; + body{[](const interop_feature_t /* feature */, + uint16_t /* manufacturer */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t manufacturer) { return body(feature, manufacturer); }; @@ -493,7 +494,7 @@ extern struct interop_match_manufacturer interop_match_manufacturer; struct interop_match_name { static bool return_value; std::function body{ - [](const interop_feature_t feature, const char* name) { + [](const interop_feature_t /* feature */, const char* /* name */) { return return_value; }}; bool operator()(const interop_feature_t feature, const char* name) { @@ -509,8 +510,8 @@ struct interop_match_vendor_product_ids { static bool return_value; std::function - body{[](const interop_feature_t feature, uint16_t vendor_id, - uint16_t product_id) { return return_value; }}; + body{[](const interop_feature_t /* feature */, uint16_t /* vendor_id */, + uint16_t /* product_id */) { return return_value; }}; bool operator()(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id) { return body(feature, vendor_id, product_id); @@ -524,7 +525,7 @@ extern struct interop_match_vendor_product_ids interop_match_vendor_product_ids; struct token_to_ul { static bool return_value; std::function body{ - [](char* token, uint16_t* ul) { return return_value; }}; + [](char* /* token */, uint16_t* /* ul */) { return return_value; }}; bool operator()(char* token, uint16_t* ul) { return body(token, ul); }; }; extern struct token_to_ul token_to_ul; diff --git a/system/test/mock/mock_device_iot_config.h b/system/test/mock/mock_device_iot_config.h index fd22398b5b0eeb5248528ac0eef26b6d26c87447..cb750a3362fae5c01b72c0c4d2a5b6eac75f4fa3 100644 --- a/system/test/mock/mock_device_iot_config.h +++ b/system/test/mock/mock_device_iot_config.h @@ -14,6 +14,7 @@ * limitations under the License. */ #include +#include #include namespace test { @@ -28,8 +29,9 @@ struct device_iot_config_get_int { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, - int& value) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, + int& /* value */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, int& value) { return body(section, key, value); @@ -44,8 +46,9 @@ struct device_iot_config_set_int { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, - int value) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, + int /* value */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, int value) { return body(section, key, value); @@ -59,7 +62,7 @@ extern struct device_iot_config_set_int device_iot_config_set_int; struct device_iot_config_int_add_one { bool return_value{false}; std::function body{ - [this](const std::string& section, const std::string& key) { + [this](const std::string& /* section */, const std::string& /* key */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key) { @@ -75,8 +78,9 @@ struct device_iot_config_get_hex { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, - int& value) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, + int& /* value */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, int& value) { return body(section, key, value); @@ -92,8 +96,9 @@ struct device_iot_config_set_hex { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, int value, - int byte_num) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, int /* value */, + int /* byte_num */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, int value, int byte_num) { return body(section, key, value, byte_num); @@ -109,8 +114,9 @@ struct device_iot_config_set_hex_if_greater { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, int value, - int byte_num) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, int /* value */, + int /* byte_num */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, int value, int byte_num) { return body(section, key, value, byte_num); @@ -127,8 +133,9 @@ struct device_iot_config_get_str { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, - char* value, int* size_bytes) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, char* /* value */, + int* /* size_bytes */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, char* value, int* size_bytes) { return body(section, key, value, size_bytes); @@ -144,8 +151,9 @@ struct device_iot_config_set_str { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, - const std::string& value) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, + const std::string& /* value */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, const std::string& value) { return body(section, key, value); @@ -161,8 +169,9 @@ struct device_iot_config_get_bin { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, - uint8_t* value, size_t* length) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, uint8_t* /* value */, + size_t* /* length */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, uint8_t* value, size_t* length) { return body(section, key, value, length); @@ -178,9 +187,9 @@ struct device_iot_config_set_bin { bool return_value{false}; std::function - body{[this](const std::string& section, const std::string& key, - const uint8_t* value, - size_t length) { return return_value; }}; + body{[this](const std::string& /* section */, + const std::string& /* key */, const uint8_t* /* value */, + size_t /* length */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key, const uint8_t* value, size_t length) { return body(section, key, value, length); @@ -194,9 +203,8 @@ extern struct device_iot_config_set_bin device_iot_config_set_bin; struct device_iot_config_get_bin_length { size_t return_value{0}; std::function - body{[this](const std::string& section, const std::string& key) { - return return_value; - }}; + body{[this](const std::string& /* section */, + const std::string& /* key */) { return return_value; }}; size_t operator()(const std::string& section, const std::string& key) { return body(section, key); }; @@ -209,7 +217,7 @@ extern struct device_iot_config_get_bin_length device_iot_config_get_bin_length; struct device_iot_config_has_section { bool return_value{false}; std::function body{ - [this](const std::string& section) { return return_value; }}; + [this](const std::string& /* section */) { return return_value; }}; bool operator()(const std::string& section) { return body(section); }; }; extern struct device_iot_config_has_section device_iot_config_has_section; @@ -220,7 +228,7 @@ extern struct device_iot_config_has_section device_iot_config_has_section; struct device_iot_config_exist { bool return_value{false}; std::function body{ - [this](const std::string& section, const std::string& key) { + [this](const std::string& /* section */, const std::string& /* key */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key) { @@ -235,7 +243,7 @@ extern struct device_iot_config_exist device_iot_config_exist; struct device_iot_config_remove { bool return_value{false}; std::function body{ - [this](const std::string& section, const std::string& key) { + [this](const std::string& /* section */, const std::string& /* key */) { return return_value; }}; bool operator()(const std::string& section, const std::string& key) { @@ -267,11 +275,11 @@ extern struct device_iot_config_flush device_iot_config_flush; // Params: int fd // Return: void struct device_debug_iot_config_dump { - std::function body{[](int fd) {}}; + std::function body{[](int /* fd */) {}}; void operator()(int fd) { body(fd); }; }; extern struct device_debug_iot_config_dump device_debug_iot_config_dump; } // namespace device_iot_config } // namespace mock -} // namespace test \ No newline at end of file +} // namespace test diff --git a/system/stack/test/common/mock_main_shim.cc b/system/test/mock/mock_jni_thread.cc similarity index 50% rename from system/stack/test/common/mock_main_shim.cc rename to system/test/mock/mock_jni_thread.cc index 47e5c378c5472283dafe2752ae4bcd330773c616..bcc047138431d390d68420b322b49e136f7b9197 100644 --- a/system/stack/test/common/mock_main_shim.cc +++ b/system/test/mock/mock_jni_thread.cc @@ -16,35 +16,37 @@ /* * Generated mock file from original source file - * Functions generated:14 + * Functions generated:27 */ -#include -#include +#include -#define LOG_TAG "bt_shim" -#include "gd/common/init_flags.h" -#include "main/shim/entry.h" -#include "main/shim/shim.h" -#include "test/common/mock_functions.h" +#include -#ifndef UNUSED_ATTR -#define UNUSED_ATTR -#endif +#include "btif/include/btif_common.h" +#include "include/hardware/bluetooth.h" +#include "test/common/jni_thread.h" +#include "test/common/mock_functions.h" -bool bluetooth::shim::is_gd_stack_started_up() { +bool is_on_jni_thread() { inc_func_call_count(__func__); return false; } -future_t* GeneralShutDown() { +bt_status_t btif_transfer_context(tBTIF_CBACK* /* p_cback */, + uint16_t /* event */, char* /* p_params */, + int /* param_len */, + tBTIF_COPY_CBACK* /* p_copy_cback */) { inc_func_call_count(__func__); - return nullptr; + return BT_STATUS_SUCCESS; } -future_t* IdleModuleStartUp() { +bt_status_t do_in_jni_thread(base::OnceClosure task) { inc_func_call_count(__func__); - return nullptr; + do_in_jni_thread_task_queue.push(std::move(task)); + return BT_STATUS_SUCCESS; } -future_t* ShimModuleStartUp() { +bt_status_t do_in_jni_thread(const base::Location& /* from_here */, + base::OnceClosure task) { inc_func_call_count(__func__); - return nullptr; + do_in_jni_thread_task_queue.push(std::move(task)); + return BT_STATUS_SUCCESS; } diff --git a/system/test/mock/mock_legacy_hci_interface.h b/system/test/mock/mock_legacy_hci_interface.h index 49d925b54ce86d6308bef642f7e16b12e2de8ba6..3ae95fa4291bd94d9225680bfe8b14aeb27426fe 100644 --- a/system/test/mock/mock_legacy_hci_interface.h +++ b/system/test/mock/mock_legacy_hci_interface.h @@ -23,10 +23,6 @@ namespace bluetooth::legacy::hci::testing { class MockInterface : public Interface { public: - MOCK_METHOD(void, StartInquiry, - (const LAP inq_lap, uint8_t duration, uint8_t response_cnt), - (const)); - MOCK_METHOD(void, InquiryCancel, (), (const)); MOCK_METHOD(void, Disconnect, (uint16_t handle, uint8_t reason), (const)); MOCK_METHOD(void, ChangeConnectionPacketType, (uint16_t handle, uint16_t packet_types), (const)); diff --git a/system/test/mock/mock_main_shim.cc b/system/test/mock/mock_main_shim.cc index 8a7699d4165af26a09075d4b6bd6a468a29b8ce2..ccb175cf1b6d971187d248368e5a10b80988dcc4 100644 --- a/system/test/mock/mock_main_shim.cc +++ b/system/test/mock/mock_main_shim.cc @@ -37,15 +37,3 @@ bool bluetooth::shim::is_gd_stack_started_up() { inc_func_call_count(__func__); return test::mock::bluetooth_shim_is_gd_stack_started_up; } -future_t* GeneralShutDown() { - inc_func_call_count(__func__); - return nullptr; -} -future_t* IdleModuleStartUp() { - inc_func_call_count(__func__); - return nullptr; -} -future_t* ShimModuleStartUp() { - inc_func_call_count(__func__); - return nullptr; -} diff --git a/system/test/mock/mock_main_shim_BtifConfigInterface.cc b/system/test/mock/mock_main_shim_BtifConfigInterface.cc index cdb4680debd1fd558a9f01daec8c0291cf07dde1..07635f093464305f3c12249b9922d7360c6c321e 100644 --- a/system/test/mock/mock_main_shim_BtifConfigInterface.cc +++ b/system/test/mock/mock_main_shim_BtifConfigInterface.cc @@ -19,69 +19,67 @@ #include "main/shim/config.h" bool bluetooth::shim::BtifConfigInterface::HasSection( - const std::string& section) { + const std::string& /* section */) { return false; } bool bluetooth::shim::BtifConfigInterface::HasProperty( - const std::string& section, const std::string& property) { + const std::string& /* section */, const std::string& /* property */) { return false; } -bool bluetooth::shim::BtifConfigInterface::GetInt(const std::string& section, - const std::string& key, - int* value) { +bool bluetooth::shim::BtifConfigInterface::GetInt( + const std::string& /* section */, const std::string& /* key */, + int* /* value */) { return false; } -bool bluetooth::shim::BtifConfigInterface::SetInt(const std::string& section, - const std::string& key, - int value) { +bool bluetooth::shim::BtifConfigInterface::SetInt( + const std::string& /* section */, const std::string& /* key */, + int /* value */) { return false; } -bool bluetooth::shim::BtifConfigInterface::GetUint64(const std::string& section, - const std::string& key, - uint64_t* value) { +bool bluetooth::shim::BtifConfigInterface::GetUint64( + const std::string& /* section */, const std::string& /* key */, + uint64_t* /* value */) { return false; } -bool bluetooth::shim::BtifConfigInterface::SetUint64(const std::string& section, - const std::string& key, - uint64_t value) { +bool bluetooth::shim::BtifConfigInterface::SetUint64( + const std::string& /* section */, const std::string& /* key */, + uint64_t /* value */) { return false; } -bool bluetooth::shim::BtifConfigInterface::GetStr(const std::string& section, - const std::string& key, - char* value, - int* size_bytes) { +bool bluetooth::shim::BtifConfigInterface::GetStr( + const std::string& /* section */, const std::string& /* key */, + char* /* value */, int* /* size_bytes */) { return false; } std::optional bluetooth::shim::BtifConfigInterface::GetStr( - const std::string& section, const std::string& key) { + const std::string& /* section */, const std::string& /* key */) { return std::string(); } -bool bluetooth::shim::BtifConfigInterface::SetStr(const std::string& section, - const std::string& key, - const std::string& value) { +bool bluetooth::shim::BtifConfigInterface::SetStr( + const std::string& /* section */, const std::string& /* key */, + const std::string& /* value */) { return false; } -bool bluetooth::shim::BtifConfigInterface::GetBin(const std::string& section, - const std::string& key, - uint8_t* value, - size_t* length) { +bool bluetooth::shim::BtifConfigInterface::GetBin( + const std::string& /* section */, const std::string& /* key */, + uint8_t* /* value */, size_t* /* length */) { return false; } size_t bluetooth::shim::BtifConfigInterface::GetBinLength( - const std::string& section, const std::string& key) { + const std::string& /* section */, const std::string& /* key */) { return 0; } -bool bluetooth::shim::BtifConfigInterface::SetBin(const std::string& section, - const std::string& key, - const uint8_t* value, - size_t length) { +bool bluetooth::shim::BtifConfigInterface::SetBin( + const std::string& /* section */, const std::string& /* key */, + const uint8_t* /* value */, size_t /* length */) { return false; } bool bluetooth::shim::BtifConfigInterface::RemoveProperty( - const std::string& section, const std::string& key) { + const std::string& /* section */, const std::string& /* key */) { return false; } -void bluetooth::shim::BtifConfigInterface::RemoveSection(const std::string& section){}; +void bluetooth::shim::BtifConfigInterface::RemoveSection( + const std::string& /* section */){}; std::vector bluetooth::shim::BtifConfigInterface::GetPersistentDevices() { return std::vector(); diff --git a/system/test/mock/mock_main_shim_acl.cc b/system/test/mock/mock_main_shim_acl.cc index 4244b9446e739b259e5edba6d7502f5b4188dcf1..0b1480231c197590775c8eefb3606c340700a92c 100644 --- a/system/test/mock/mock_main_shim_acl.cc +++ b/system/test/mock/mock_main_shim_acl.cc @@ -14,12 +14,238 @@ * limitations under the License. */ -/* - * Generated mock file from original source file - * Functions generated:7 - */ +#include +#include + +#include +#include +#include +#include +#include -#include "main/shim/acl_api.h" +#include "common/sync_map_count.h" +#include "device/include/controller.h" +#include "hci/acl_manager.h" +#include "hci/acl_manager/classic_acl_connection.h" +#include "hci/acl_manager/le_acl_connection.h" +#include "hci/address.h" +#include "hci/address_with_type.h" +#include "hci/class_of_device.h" +#include "main/shim/acl.h" +#include "main/shim/entry.h" +#include "os/handler.h" +#include "stack/acl/acl.h" #include "test/common/mock_functions.h" +#include "types/raw_address.h" + +using namespace bluetooth; + +void DumpsysL2cap(int /* fd */) { inc_func_call_count(__func__); } + +void DumpsysAcl(int /* fd */) { inc_func_call_count(__func__); } + +void DumpsysBtm(int /* fd */) { inc_func_call_count(__func__); } + +void DumpsysRecord(int /* fd */) { inc_func_call_count(__func__); } + +void DumpsysNeighbor(int /* fd */) { inc_func_call_count(__func__); } + +void shim::legacy::Acl::Dump(int /* fd */) const { + inc_func_call_count(__func__); +} + +shim::legacy::Acl::Acl(os::Handler* /* handler */, + const acl_interface_t& acl_interface, + uint8_t /* max_acceptlist_size */, + uint8_t /* max_address_resolution_size */) + : acl_interface_(acl_interface) { + inc_func_call_count(__func__); +} +shim::legacy::Acl::~Acl() { inc_func_call_count(__func__); } + +bool shim::legacy::Acl::CheckForOrphanedAclConnections() const { + inc_func_call_count(__func__); + return false; +} + +void shim::legacy::Acl::on_incoming_acl_credits(uint16_t /* handle */, + uint16_t /* credits */) { + inc_func_call_count(__func__); +} + +using HciHandle = uint16_t; + +struct shim::legacy::Acl::impl {}; + +void shim::legacy::Acl::CreateClassicConnection( + const hci::Address& /* address */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::CancelClassicConnection( + const hci::Address& /* address */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::AcceptLeConnectionFrom( + const hci::AddressWithType& /* address_with_type */, bool /* is_direct */, + std::promise /* promise */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::IgnoreLeConnectionFrom( + const hci::AddressWithType& /* address_with_type */) { + inc_func_call_count(__func__); +} + +void bluetooth::shim::legacy::Acl::OnClassicLinkDisconnected( + HciHandle /* handle */, hci::ErrorCode /* reason */) { + inc_func_call_count(__func__); +} + +bluetooth::hci::AddressWithType shim::legacy::Acl::GetConnectionLocalAddress( + uint16_t /* handle */, bool /* ota_address */) { + inc_func_call_count(__func__); + return hci::AddressWithType(); +} +bluetooth::hci::AddressWithType shim::legacy::Acl::GetConnectionPeerAddress( + uint16_t /* handle */, bool /* ota_address */) { + inc_func_call_count(__func__); + return hci::AddressWithType(); +} + +std::optional shim::legacy::Acl::GetAdvertisingSetConnectedTo( + const RawAddress& /* remote_bda */) { + inc_func_call_count(__func__); + return std::nullopt; + ; +} + +void shim::legacy::Acl::OnLeLinkDisconnected(HciHandle /* handle */, + hci::ErrorCode /* reason */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::OnConnectSuccess( + std::unique_ptr /* connection */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::OnConnectRequest(hci::Address /* address */, + hci::ClassOfDevice /* cod */) { + inc_func_call_count(__func__); +} +void shim::legacy::Acl::OnConnectFail(hci::Address /* address */, + hci::ErrorCode /* reason */, + bool /* locally_initiated */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::OnLeConnectSuccess( + hci::AddressWithType /* address_with_type */, + std::unique_ptr /* connection */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::OnLeConnectFail( + hci::AddressWithType /* address_with_type */, hci::ErrorCode /* reason */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::DisconnectClassic(uint16_t /* handle */, + tHCI_STATUS /* reason */, + std::string /* comment */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::DisconnectLe(uint16_t /* handle */, + tHCI_STATUS /* reason */, + std::string /* comment */) { + inc_func_call_count(__func__); +} + +bool shim::legacy::Acl::HoldMode(uint16_t /* hci_handle */, + uint16_t /* max_interval */, + uint16_t /* min_interval */) { + inc_func_call_count(__func__); + return false; +} + +bool shim::legacy::Acl::SniffMode(uint16_t /* hci_handle */, + uint16_t /* max_interval */, + uint16_t /* min_interval */, + uint16_t /* attempt */, + uint16_t /* timeout */) { + inc_func_call_count(__func__); + return false; +} + +bool shim::legacy::Acl::ExitSniffMode(uint16_t /* hci_handle */) { + inc_func_call_count(__func__); + return false; +} + +bool shim::legacy::Acl::SniffSubrating(uint16_t /* hci_handle */, + uint16_t /* maximum_latency */, + uint16_t /* minimum_remote_timeout */, + uint16_t /* minimum_local_timeout */) { + inc_func_call_count(__func__); + return false; +} + +void shim::legacy::Acl::LeSetDefaultSubrate(uint16_t /* subrate_min */, + uint16_t /* subrate_max */, + uint16_t /* max_latency */, + uint16_t /* cont_num */, + uint16_t /* sup_tout */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::LeSubrateRequest(uint16_t /* hci_handle */, + uint16_t /* subrate_min */, + uint16_t /* subrate_max */, + uint16_t /* max_latency */, + uint16_t /* cont_num */, + uint16_t /* sup_tout */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::DumpConnectionHistory(int /* fd */) const { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::DisconnectAllForSuspend() { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::Shutdown() { inc_func_call_count(__func__); } + +void shim::legacy::Acl::FinalShutdown() { inc_func_call_count(__func__); } + +void shim::legacy::Acl::ClearFilterAcceptList() { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::LeRand(LeRandCallback /* cb */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::AddToAddressResolution( + const hci::AddressWithType& /* address_with_type */, + const std::array& /* peer_irk */, + const std::array& /* local_irk */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::RemoveFromAddressResolution( + const hci::AddressWithType& /* address_with_type */) { + inc_func_call_count(__func__); +} + +void shim::legacy::Acl::ClearAddressResolution() { + inc_func_call_count(__func__); +} -void bluetooth::shim::ACL_Shutdown() { inc_func_call_count(__func__); } +void shim::legacy::Acl::SetSystemSuspendState(bool /* suspended */) { + inc_func_call_count(__func__); +} diff --git a/system/test/mock/mock_main_shim_acl_api.cc b/system/test/mock/mock_main_shim_acl_api.cc index 6107e430b37e0b37154bba2e9d5039dbe3842480..e679183e6e253e11bfe191d5fbb4acdb8b59a294 100644 --- a/system/test/mock/mock_main_shim_acl_api.cc +++ b/system/test/mock/mock_main_shim_acl_api.cc @@ -30,74 +30,80 @@ #include "types/raw_address.h" void bluetooth::shim::ACL_CreateClassicConnection( - const RawAddress& raw_address) { + const RawAddress& /* raw_address */) { inc_func_call_count(__func__); } void bluetooth::shim::ACL_CancelClassicConnection( - const RawAddress& raw_address) { + const RawAddress& /* raw_address */) { inc_func_call_count(__func__); } bool bluetooth::shim::ACL_AcceptLeConnectionFrom( - const tBLE_BD_ADDR& legacy_address_with_type, bool is_direct) { + const tBLE_BD_ADDR& /* legacy_address_with_type */, bool /* is_direct */) { inc_func_call_count(__func__); return true; } void bluetooth::shim::ACL_IgnoreLeConnectionFrom( - const tBLE_BD_ADDR& legacy_address_with_type) { + const tBLE_BD_ADDR& /* legacy_address_with_type */) { inc_func_call_count(__func__); } -void bluetooth::shim::ACL_ConfigureLePrivacy(bool is_le_privacy_enabled) { +void bluetooth::shim::ACL_ConfigureLePrivacy(bool /* is_le_privacy_enabled */) { inc_func_call_count(__func__); } -void bluetooth::shim::ACL_WriteData(uint16_t handle, BT_HDR* p_buf) { +void bluetooth::shim::ACL_WriteData(uint16_t /* handle */, + BT_HDR* /* p_buf */) { inc_func_call_count(__func__); } -void bluetooth::shim::ACL_Disconnect(uint16_t handle, bool is_classic, - tHCI_STATUS reason, std::string comment) { +void bluetooth::shim::ACL_Disconnect(uint16_t /* handle */, + bool /* is_classic */, + tHCI_STATUS /* reason */, + std::string /* comment */) { inc_func_call_count(__func__); } void bluetooth::shim::ACL_IgnoreAllLeConnections() { inc_func_call_count(__func__); } -void bluetooth::shim::ACL_ReadConnectionAddress(uint16_t handle, - RawAddress& conn_addr, - tBLE_ADDR_TYPE* p_addr_type, - bool ota_address) { +void bluetooth::shim::ACL_ReadConnectionAddress( + uint16_t /* handle */, RawAddress& /* conn_addr */, + tBLE_ADDR_TYPE* /* p_addr_type */, bool /* ota_address */) { inc_func_call_count(__func__); } -void bluetooth::shim::ACL_ReadPeerConnectionAddress(uint16_t handle, - RawAddress& conn_addr, - tBLE_ADDR_TYPE* p_addr_type, - bool ota_address) { +void bluetooth::shim::ACL_ReadPeerConnectionAddress( + uint16_t /* handle */, RawAddress& /* conn_addr */, + tBLE_ADDR_TYPE* /* p_addr_type */, bool /* ota_address */) { inc_func_call_count(__func__); } std::optional bluetooth::shim::ACL_GetAdvertisingSetConnectedTo( - const RawAddress& addr) { + const RawAddress& /* addr */) { inc_func_call_count(__func__); return std::nullopt; } void bluetooth::shim::ACL_AddToAddressResolution( - const tBLE_BD_ADDR& legacy_address_with_type, const Octet16& peer_irk, - const Octet16& local_irk) { + const tBLE_BD_ADDR& /* legacy_address_with_type */, + const Octet16& /* peer_irk */, const Octet16& /* local_irk */) { inc_func_call_count(__func__); } void bluetooth::shim::ACL_RemoveFromAddressResolution( - const tBLE_BD_ADDR& legacy_address_with_type) { + const tBLE_BD_ADDR& /* legacy_address_with_type */) { inc_func_call_count(__func__); } void bluetooth::shim::ACL_ClearAddressResolution() { inc_func_call_count(__func__); } -void bluetooth::shim::ACL_LeSetDefaultSubrate(uint16_t subrate_min, - uint16_t subrate_max, - uint16_t max_latency, - uint16_t cont_num, - uint16_t sup_tout) { +void bluetooth::shim::ACL_LeSetDefaultSubrate(uint16_t /* subrate_min */, + uint16_t /* subrate_max */, + uint16_t /* max_latency */, + uint16_t /* cont_num */, + uint16_t /* sup_tout */) { inc_func_call_count(__func__); } -void bluetooth::shim::ACL_LeSubrateRequest( - uint16_t hci_handle, uint16_t subrate_min, uint16_t subrate_max, - uint16_t max_latency, uint16_t cont_num, uint16_t sup_tout) { +void bluetooth::shim::ACL_LeSubrateRequest(uint16_t /* hci_handle */, + uint16_t /* subrate_min */, + uint16_t /* subrate_max */, + uint16_t /* max_latency */, + uint16_t /* cont_num */, + uint16_t /* sup_tout */) { inc_func_call_count(__func__); } + +void bluetooth::shim::ACL_Shutdown() { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_main_shim_acl_legacy_interface.cc b/system/test/mock/mock_main_shim_acl_legacy_interface.cc new file mode 100644 index 0000000000000000000000000000000000000000..a7edba589007923c38f40f6ec3d1776f6b57bb53 --- /dev/null +++ b/system/test/mock/mock_main_shim_acl_legacy_interface.cc @@ -0,0 +1,73 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "main/shim/acl_legacy_interface.h" + +namespace bluetooth { +namespace shim { +namespace legacy { + +acl_interface_t acl_interface_ = { + .on_send_data_upwards = nullptr, + .on_packets_completed = nullptr, + + .connection.classic.on_connected = nullptr, + .connection.classic.on_connect_request = nullptr, + .connection.classic.on_failed = nullptr, + .connection.classic.on_disconnected = nullptr, + + .connection.le.on_connected = nullptr, + .connection.le.on_failed = nullptr, + .connection.le.on_disconnected = nullptr, + + .link.classic.on_authentication_complete = nullptr, + .link.classic.on_central_link_key_complete = nullptr, + .link.classic.on_change_connection_link_key_complete = nullptr, + .link.classic.on_encryption_change = nullptr, + .link.classic.on_flow_specification_complete = nullptr, + .link.classic.on_flush_occurred = nullptr, + .link.classic.on_mode_change = nullptr, + .link.classic.on_packet_type_changed = nullptr, + .link.classic.on_qos_setup_complete = nullptr, + .link.classic.on_read_afh_channel_map_complete = nullptr, + .link.classic.on_read_automatic_flush_timeout_complete = nullptr, + .link.classic.on_sniff_subrating = nullptr, + .link.classic.on_read_clock_complete = nullptr, + .link.classic.on_read_clock_offset_complete = nullptr, + .link.classic.on_read_failed_contact_counter_complete = nullptr, + .link.classic.on_read_link_policy_settings_complete = nullptr, + .link.classic.on_read_link_quality_complete = nullptr, + .link.classic.on_read_link_supervision_timeout_complete = nullptr, + .link.classic.on_read_remote_version_information_complete = nullptr, + .link.classic.on_read_remote_supported_features_complete = nullptr, + .link.classic.on_read_remote_extended_features_complete = nullptr, + .link.classic.on_read_rssi_complete = nullptr, + .link.classic.on_read_transmit_power_level_complete = nullptr, + .link.classic.on_role_change = nullptr, + .link.classic.on_role_discovery_complete = nullptr, + + .link.le.on_connection_update = nullptr, + .link.le.on_data_length_change = nullptr, + .link.le.on_read_remote_version_information_complete = nullptr, + .link.le.on_phy_update = nullptr, + .link.le.on_le_subrate_change = nullptr, +}; + +const acl_interface_t& GetAclInterface() { return acl_interface_; } + +} // namespace legacy +} // namespace shim +} // namespace bluetooth diff --git a/system/test/mock/mock_main_shim_btm_api.cc b/system/test/mock/mock_main_shim_btm_api.cc index 94f1c599749f6c59190791af9d0971df7e6b336e..35300b11cfa56dad3c4c03da4eb6bc697e26e78c 100644 --- a/system/test/mock/mock_main_shim_btm_api.cc +++ b/system/test/mock/mock_main_shim_btm_api.cc @@ -33,19 +33,19 @@ Octet16 octet16; -bool bluetooth::shim::BTM_HasEirService(const uint32_t* p_eir_uuid, - uint16_t uuid16) { +bool bluetooth::shim::BTM_HasEirService(const uint32_t* /* p_eir_uuid */, + uint16_t /* uuid16 */) { inc_func_call_count(__func__); return false; } bool bluetooth::shim::BTM_ReadConnectedTransportAddress( - RawAddress* remote_bda, tBT_TRANSPORT transport) { + RawAddress* /* remote_bda */, tBT_TRANSPORT /* transport */) { inc_func_call_count(__func__); return false; } bool bluetooth::shim::BTM_ReadRemoteConnectionAddr( - const RawAddress& pseudo_addr, RawAddress& conn_addr, - tBLE_ADDR_TYPE* p_addr_type, bool ota_address) { + const RawAddress& /* pseudo_addr */, RawAddress& /* conn_addr */, + tBLE_ADDR_TYPE* /* p_addr_type */, bool /* ota_address */) { inc_func_call_count(__func__); return false; } @@ -54,109 +54,96 @@ tBTM_INQ_INFO* bluetooth::shim::BTM_InqDbFirst(void) { inc_func_call_count(__func__); return nullptr; } -tBTM_INQ_INFO* bluetooth::shim::BTM_InqDbNext(tBTM_INQ_INFO* p_cur) { +tBTM_INQ_INFO* bluetooth::shim::BTM_InqDbNext(tBTM_INQ_INFO* /* p_cur */) { inc_func_call_count(__func__); return nullptr; } -tBTM_INQ_INFO* bluetooth::shim::BTM_InqDbRead(const RawAddress& p_bda) { +tBTM_INQ_INFO* bluetooth::shim::BTM_InqDbRead(const RawAddress& /* p_bda */) { inc_func_call_count(__func__); return nullptr; } -tBTM_STATUS bluetooth::shim::BTM_BleObserve(bool start, uint8_t duration_sec, - tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb) { +tBTM_STATUS bluetooth::shim::BTM_BleObserve( + bool /* start */, uint8_t /* duration_sec */, + tBTM_INQ_RESULTS_CB* /* p_results_cb */, tBTM_CMPL_CB* /* p_cmpl_cb */) { inc_func_call_count(__func__); return BTM_SUCCESS; } void bluetooth::shim::BTM_BleOpportunisticObserve( - bool enable, tBTM_INQ_RESULTS_CB* p_results_cb) { + bool /* enable */, tBTM_INQ_RESULTS_CB* /* p_results_cb */) { inc_func_call_count(__func__); } void bluetooth::shim::BTM_BleTargetAnnouncementObserve( - bool enable, tBTM_INQ_RESULTS_CB* p_results_cb) { + bool /* enable */, tBTM_INQ_RESULTS_CB* /* p_results_cb */) { inc_func_call_count(__func__); } tBTM_STATUS bluetooth::shim::BTM_CancelRemoteDeviceName(void) { inc_func_call_count(__func__); return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_ClearInqDb(const RawAddress* p_bda) { +tBTM_STATUS bluetooth::shim::BTM_ClearInqDb(const RawAddress* /* p_bda */) { inc_func_call_count(__func__); return BTM_SUCCESS; } tBTM_STATUS bluetooth::shim::BTM_ReadRemoteDeviceName( - const RawAddress& raw_address, tBTM_NAME_CMPL_CB* callback, - tBT_TRANSPORT transport) { + const RawAddress& /* raw_address */, tBTM_NAME_CMPL_CB* /* callback */, + tBT_TRANSPORT /* transport */) { inc_func_call_count(__func__); return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_SetConnectability(uint16_t page_mode, - uint16_t window, - uint16_t interval) { +tBTM_STATUS bluetooth::shim::BTM_SetConnectability(uint16_t /* page_mode */, + uint16_t /* window */, + uint16_t /* interval */) { inc_func_call_count(__func__); return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_SetDeviceClass(DEV_CLASS dev_class) { +tBTM_STATUS bluetooth::shim::BTM_SetDeviceClass(DEV_CLASS /* dev_class */) { inc_func_call_count(__func__); return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_SetDiscoverability(uint16_t discoverable_mode, - uint16_t window, - uint16_t interval) { +tBTM_STATUS bluetooth::shim::BTM_SetDiscoverability( + uint16_t /* discoverable_mode */, uint16_t /* window */, + uint16_t /* interval */) { inc_func_call_count(__func__); return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_SetInquiryMode(uint8_t inquiry_mode) { +tBTM_STATUS bluetooth::shim::BTM_SetInquiryMode(uint8_t /* inquiry_mode */) { inc_func_call_count(__func__); return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb) { - inc_func_call_count(__func__); - return BTM_SUCCESS; -} - -uint16_t bluetooth::shim::BTM_GetHCIConnHandle(const RawAddress& remote_bda, - tBT_TRANSPORT transport) { - inc_func_call_count(__func__); - return 0; -} -uint16_t bluetooth::shim::BTM_IsInquiryActive(void) { +uint16_t bluetooth::shim::BTM_GetHCIConnHandle( + const RawAddress& /* remote_bda */, tBT_TRANSPORT /* transport */) { inc_func_call_count(__func__); return 0; } - uint8_t bluetooth::shim::BTM_BleMaxMultiAdvInstanceCount() { inc_func_call_count(__func__); return 0; } -void bluetooth::shim::BTM_AddEirService(uint32_t* p_eir_uuid, uint16_t uuid16) { +void bluetooth::shim::BTM_AddEirService(uint32_t* /* p_eir_uuid */, + uint16_t /* uuid16 */) { inc_func_call_count(__func__); } void bluetooth::shim::BTM_BleAdvFilterParamSetup( - tBTM_BLE_SCAN_COND_OP action, tBTM_BLE_PF_FILT_INDEX filt_index, - std::unique_ptr p_filt_params, - tBTM_BLE_PF_PARAM_CB cb) { + tBTM_BLE_SCAN_COND_OP /* action */, tBTM_BLE_PF_FILT_INDEX /* filt_index */, + std::unique_ptr /* p_filt_params */, + tBTM_BLE_PF_PARAM_CB /* cb */) { inc_func_call_count(__func__); } -void bluetooth::shim::BTM_BleSetConnScanParams(uint32_t scan_interval, - uint32_t scan_window) { +void bluetooth::shim::BTM_BleSetConnScanParams(uint32_t /* scan_interval */, + uint32_t /* scan_window */) { inc_func_call_count(__func__); } -void bluetooth::shim::BTM_BleSetPrefConnParams(const RawAddress& bd_addr, - uint16_t min_conn_int, - uint16_t max_conn_int, - uint16_t peripheral_latency, - uint16_t supervision_tout) { +void bluetooth::shim::BTM_BleSetPrefConnParams( + const RawAddress& /* bd_addr */, uint16_t /* min_conn_int */, + uint16_t /* max_conn_int */, uint16_t /* peripheral_latency */, + uint16_t /* supervision_tout */) { inc_func_call_count(__func__); } -void bluetooth::shim::BTM_CancelInquiry(void) { inc_func_call_count(__func__); } - void bluetooth::shim::BTM_EnableInterlacedInquiryScan() { inc_func_call_count(__func__); } @@ -164,35 +151,34 @@ void bluetooth::shim::BTM_EnableInterlacedPageScan() { inc_func_call_count(__func__); } -void bluetooth::shim::BTM_ReadConnectionAddr(const RawAddress& remote_bda, - RawAddress& local_conn_addr, - tBLE_ADDR_TYPE* p_addr_type, - bool ota_address) { +void bluetooth::shim::BTM_ReadConnectionAddr(const RawAddress& /* remote_bda */, + RawAddress& /* local_conn_addr */, + tBLE_ADDR_TYPE* /* p_addr_type */, + bool /* ota_address */) { inc_func_call_count(__func__); } -void bluetooth::shim::SendRemoteNameRequest(const RawAddress& raw_address) { +void bluetooth::shim::SendRemoteNameRequest( + const RawAddress& /* raw_address */) { inc_func_call_count(__func__); } -void btm_api_process_extended_inquiry_result(RawAddress raw_address, - uint8_t page_scan_rep_mode, - DEV_CLASS device_class, - uint16_t clock_offset, int8_t rssi, - const uint8_t* eir_data, - size_t eir_len) { +void btm_api_process_extended_inquiry_result( + RawAddress /* raw_address */, uint8_t /* page_scan_rep_mode */, + DEV_CLASS /* device_class */, uint16_t /* clock_offset */, + int8_t /* rssi */, const uint8_t* /* eir_data */, size_t /* eir_len */) { inc_func_call_count(__func__); } -void btm_api_process_inquiry_result(const RawAddress& raw_address, - uint8_t page_scan_rep_mode, - DEV_CLASS device_class, - uint16_t clock_offset) { +void btm_api_process_inquiry_result(const RawAddress& /* raw_address */, + uint8_t /* page_scan_rep_mode */, + DEV_CLASS /* device_class */, + uint16_t /* clock_offset */) { inc_func_call_count(__func__); } -void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address, - uint8_t page_scan_rep_mode, - DEV_CLASS device_class, - uint16_t clock_offset, - int8_t rssi) { +void btm_api_process_inquiry_result_with_rssi(RawAddress /* raw_address */, + uint8_t /* page_scan_rep_mode */, + DEV_CLASS /* device_class */, + uint16_t /* clock_offset */, + int8_t /* rssi */) { inc_func_call_count(__func__); } @@ -216,7 +202,7 @@ tBTM_STATUS bluetooth::shim::BTM_DisconnectAllAcls() { return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_LeRand(LeRandCallback cb) { +tBTM_STATUS bluetooth::shim::BTM_LeRand(LeRandCallback /* cb */) { inc_func_call_count(__func__); return BTM_SUCCESS; } @@ -227,20 +213,20 @@ tBTM_STATUS bluetooth::shim::BTM_SetEventFilterConnectionSetupAllDevices() { } tBTM_STATUS bluetooth::shim::BTM_AllowWakeByHid( - std::vector classic_hid_devices, - std::vector> le_hid_devices) { + std::vector /* classic_hid_devices */, + std::vector> /* le_hid_devices */) { inc_func_call_count(__func__); return BTM_SUCCESS; } tBTM_STATUS bluetooth::shim::BTM_RestoreFilterAcceptList( - std::vector> le_devices) { + std::vector> /* le_devices */) { inc_func_call_count(__func__); return BTM_SUCCESS; } -tBTM_STATUS bluetooth::shim::BTM_SetDefaultEventMaskExcept(uint64_t mask, - uint64_t le_mask) { +tBTM_STATUS bluetooth::shim::BTM_SetDefaultEventMaskExcept( + uint64_t /* mask */, uint64_t /* le_mask */) { inc_func_call_count(__func__); return BTM_SUCCESS; } @@ -254,3 +240,7 @@ tBTM_STATUS bluetooth::shim::BTM_BleResetId() { inc_func_call_count(__func__); return BTM_SUCCESS; } +size_t bluetooth::shim::BTM_BleGetNumberOfAdvertisingInstancesInUse() { + inc_func_call_count(__func__); + return 0; +} diff --git a/system/test/mock/mock_main_shim_dumpsys.cc b/system/test/mock/mock_main_shim_dumpsys.cc index 0f3f773ef012773605d8c3f7d92c45efa45f8710..51fcf5541deedb7e94f4c9b3bd24aabda19ac4f5 100644 --- a/system/test/mock/mock_main_shim_dumpsys.cc +++ b/system/test/mock/mock_main_shim_dumpsys.cc @@ -20,15 +20,18 @@ */ #include "main/shim/dumpsys.h" +#include "shim/dumpsys.h" #include "test/common/mock_functions.h" -void bluetooth::shim::RegisterDumpsysFunction(const void* token, - DumpsysFunction func) { +void bluetooth::shim::RegisterDumpsysFunction(const void* /* token */, + DumpsysFunction /* func */) { inc_func_call_count(__func__); } -void bluetooth::shim::Dump(int fd, const char** args) { +void bluetooth::shim::Dump(int /* fd */, const char** /* args */) { inc_func_call_count(__func__); } -void bluetooth::shim::UnregisterDumpsysFunction(const void* token) { +void bluetooth::shim::UnregisterDumpsysFunction(const void* /* token */) { inc_func_call_count(__func__); } + +void bluetooth::shim::Dumpsys::Dump(int /* fd */, const char** /* args */) {} diff --git a/system/test/mock/mock_main_shim_entry.cc b/system/test/mock/mock_main_shim_entry.cc index 44438034cc60652ecc23cc2c2c2478db291439e4..f8d9848f3135622d1415d91b5752fc5cbef07541 100644 --- a/system/test/mock/mock_main_shim_entry.cc +++ b/system/test/mock/mock_main_shim_entry.cc @@ -14,28 +14,28 @@ * limitations under the License. */ -#include "gd/hci/acl_manager_mock.h" -#include "gd/hci/controller_mock.h" -#include "gd/hci/distance_measurement_manager_mock.h" -#include "gd/hci/hci_layer.h" -#include "gd/hci/hci_layer_mock.h" -#include "gd/hci/le_advertising_manager_mock.h" -#include "gd/hci/le_scanning_manager_mock.h" -#include "gd/neighbor/connectability.h" -#include "gd/neighbor/discoverability.h" -#include "gd/neighbor/inquiry.h" -#include "gd/neighbor/page.h" -#include "gd/os/handler.h" -#include "gd/security/security_module.h" -#include "gd/storage/storage_module.h" +#include "hci/acl_manager_mock.h" +#include "hci/controller_interface_mock.h" +#include "hci/distance_measurement_manager_mock.h" +#include "hci/hci_layer.h" +#include "hci/hci_layer_mock.h" +#include "hci/le_advertising_manager_mock.h" +#include "hci/le_scanning_manager_mock.h" #include "main/shim/entry.h" +#include "neighbor/connectability.h" +#include "neighbor/discoverability.h" +#include "neighbor/inquiry.h" +#include "neighbor/page.h" +#include "os/handler.h" +#include "storage/storage_module.h" namespace bluetooth { namespace hci { namespace testing { MockAclManager* mock_acl_manager_{nullptr}; -MockController* mock_controller_{nullptr}; +MockControllerInterface* mock_controller_{nullptr}; +shim::Dumpsys* shim_dumpsys_ = {}; MockHciLayer* mock_hci_layer_{nullptr}; os::Handler* mock_gd_shim_handler_{nullptr}; MockLeAdvertisingManager* mock_le_advertising_manager_{nullptr}; @@ -49,9 +49,11 @@ class Dumpsys; namespace shim { -Dumpsys* GetDumpsys() { return nullptr; } +Dumpsys* GetDumpsys() { return hci::testing::shim_dumpsys_; } hci::AclManager* GetAclManager() { return hci::testing::mock_acl_manager_; } -hci::Controller* GetController() { return hci::testing::mock_controller_; } +hci::ControllerInterface* GetController() { + return hci::testing::mock_controller_; +} hci::HciLayer* GetHciLayer() { return hci::testing::mock_hci_layer_; } hci::LeAdvertisingManager* GetAdvertising() { return hci::testing::mock_le_advertising_manager_; @@ -65,14 +67,11 @@ hci::DistanceMeasurementManager* GetDistanceMeasurementManager() { hci::VendorSpecificEventManager* GetVendorSpecificEventManager() { return nullptr; } -l2cap::classic::L2capClassicModule* GetL2capClassicModule() { return nullptr; } -l2cap::le::L2capLeModule* GetL2capLeModule() { return nullptr; } neighbor::ConnectabilityModule* GetConnectability() { return nullptr; } neighbor::DiscoverabilityModule* GetDiscoverability() { return nullptr; } neighbor::InquiryModule* GetInquiry() { return nullptr; } neighbor::PageModule* GetPage() { return nullptr; } os::Handler* GetGdShimHandler() { return hci::testing::mock_gd_shim_handler_; } -security::SecurityModule* GetSecurityModule() { return nullptr; } hal::SnoopLogger* GetSnoopLogger() { return nullptr; } storage::StorageModule* GetStorage() { return nullptr; } metrics::CounterMetrics* GetCounterMetrics() { return nullptr; } diff --git a/system/test/mock/mock_main_shim_entry.h b/system/test/mock/mock_main_shim_entry.h index 2285edea0de279cb292e062b935a58d721063aaf..394c13812f6cc49091f53b2b7d71c58b47efcada 100644 --- a/system/test/mock/mock_main_shim_entry.h +++ b/system/test/mock/mock_main_shim_entry.h @@ -14,19 +14,23 @@ * limitations under the License. */ +#include + #include "hci/acl_manager_mock.h" -#include "hci/controller_mock.h" +#include "hci/controller_interface_mock.h" #include "hci/distance_measurement_manager_mock.h" #include "hci/hci_layer_mock.h" #include "hci/le_advertising_manager_mock.h" #include "hci/le_scanning_manager_mock.h" +#include "shim/dumpsys.h" namespace bluetooth { namespace hci { namespace testing { extern MockAclManager* mock_acl_manager_; -extern MockController* mock_controller_; +extern MockControllerInterface* mock_controller_; +extern std::function shim_dumpsys_; extern MockHciLayer* mock_hci_layer_; extern os::Handler* mock_gd_shim_handler_; extern MockLeAdvertisingManager* mock_le_advertising_manager_; diff --git a/system/test/mock/mock_main_shim_hci_layer.cc b/system/test/mock/mock_main_shim_hci_layer.cc index 46031a613b805cb668ea37ff1719b00e88935406..ff7f1e6631148d3b0f4710d4d8e0c175f65233db 100644 --- a/system/test/mock/mock_main_shim_hci_layer.cc +++ b/system/test/mock/mock_main_shim_hci_layer.cc @@ -16,14 +16,80 @@ /* * Generated mock file from original source file - * Functions generated:3 + * Functions generated:5 * - * mockcify.pl ver 0.3.0 + * mockcify.pl ver 0.7.0 */ // Mock include file to share data between tests and mock #include "test/mock/mock_main_shim_hci_layer.h" +#include "main/shim/hci_layer.h" +#include "test/common/mock_functions.h" + +// Original usings + // Mocked internal structures, if any -const hci_t* bluetooth::shim::hci_layer_get_interface() { return nullptr; } \ No newline at end of file +namespace bluetooth::shim { +namespace testing { +const hci_t* test_interface = nullptr; +void hci_layer_set_interface(const hci_t* interface) { + test_interface = interface; +} +} // namespace testing +} // namespace bluetooth::shim + +const hci_t* bluetooth::shim::hci_layer_get_interface() { + return testing::test_interface; +} + +namespace test { +namespace mock { +namespace main_shim_hci_layer { + +// Function state capture and return values, if needed +struct OnTransmitPacketCommandComplete OnTransmitPacketCommandComplete; +struct OnTransmitPacketStatus OnTransmitPacketStatus; +struct hci_on_reset_complete hci_on_reset_complete; +struct hci_on_shutting_down hci_on_shutting_down; + +} // namespace main_shim_hci_layer +} // namespace mock +} // namespace test + +// Mocked function return values, if any +namespace test { +namespace mock { +namespace main_shim_hci_layer {} // namespace main_shim_hci_layer +} // namespace mock +} // namespace test + +// Mocked functions, if any +namespace cpp { +void OnTransmitPacketCommandComplete(command_complete_cb complete_callback, + void* context, + bluetooth::hci::CommandCompleteView view) { + inc_func_call_count(__func__); + test::mock::main_shim_hci_layer::OnTransmitPacketCommandComplete( + complete_callback, context, view); +} +void OnTransmitPacketStatus(command_status_cb status_callback, void* context, + std::unique_ptr command, + bluetooth::hci::CommandStatusView view) { + inc_func_call_count(__func__); + test::mock::main_shim_hci_layer::OnTransmitPacketStatus( + status_callback, context, std::move(command), view); +} +} // namespace cpp + +void bluetooth::shim::hci_on_reset_complete() { + inc_func_call_count(__func__); + test::mock::main_shim_hci_layer::hci_on_reset_complete(); +} +void bluetooth::shim::hci_on_shutting_down() { + inc_func_call_count(__func__); + test::mock::main_shim_hci_layer::hci_on_shutting_down(); +} +// Mocked functions complete +// END mockcify generation diff --git a/system/test/mock/mock_main_shim_hci_layer.h b/system/test/mock/mock_main_shim_hci_layer.h index 69d6548099e0163e9903ae15ed5cb557fda0f200..c54735d971dedc0d49db28a1e3cf633ec072bbd9 100644 --- a/system/test/mock/mock_main_shim_hci_layer.h +++ b/system/test/mock/mock_main_shim_hci_layer.h @@ -18,10 +18,107 @@ /* * Generated mock file from original source file - * Functions generated:3 + * Functions generated:5 * - * mockcify.pl ver 0.3.0 + * mockcify.pl ver 0.7.0 */ +#include + +#include "hci/include/hci_layer.h" + // Original included files, if any -#include "main/shim/hci_layer.h" +// NOTE: Since this is a mock file with mock definitions some number of +// include files may not be required. The include-what-you-use +// still applies, but crafting proper inclusion is out of scope +// for this effort. This compilation unit may compile as-is, or +// may need attention to prune from (or add to ) the inclusion set. +#include + +#include "hci/hci_packets.h" +#include "osi/include/allocator.h" + +// Original usings +using CommandCallbackData = struct { + void* context; +}; +// Mocked compile conditionals, if any + +namespace bluetooth::shim { +namespace testing { +extern void hci_layer_set_interface(const hci_t* interface); +} // namespace testing +} // namespace bluetooth::shim + +namespace test { +namespace mock { +namespace main_shim_hci_layer { + +// Shared state between mocked functions and tests +// Name: OnTransmitPacketCommandComplete +// Params: command_complete_cb complete_callback, void* context, +// bluetooth::hci::CommandCompleteView view Return: void +struct OnTransmitPacketCommandComplete { + std::function + body{[](command_complete_cb /* complete_callback */, void* /* context */, + bluetooth::hci::CommandCompleteView /* view */) {}}; + void operator()(command_complete_cb complete_callback, void* context, + bluetooth::hci::CommandCompleteView view) { + body(complete_callback, context, view); + }; +}; +extern struct OnTransmitPacketCommandComplete OnTransmitPacketCommandComplete; + +// Name: OnTransmitPacketStatus +// Params: command_status_cb status_callback, void* context, +// std::unique_ptr command, bluetooth::hci::CommandStatusView view +// Return: void +struct OnTransmitPacketStatus { + std::function command, + bluetooth::hci::CommandStatusView view)> + body{[](command_status_cb /* status_callback */, void* /* context */, + std::unique_ptr /* command */, + bluetooth::hci::CommandStatusView /* view */) {}}; + void operator()(command_status_cb status_callback, void* context, + std::unique_ptr command, + bluetooth::hci::CommandStatusView view) { + body(status_callback, context, std::move(command), view); + }; +}; +extern struct OnTransmitPacketStatus OnTransmitPacketStatus; + +// Name: hci_layer_get_interface +// Params: +// Return: const hci_t* +struct hci_layer_get_interface { + static const hci_t* return_value; + std::function body{[]() { return return_value; }}; + const hci_t* operator()() { return body(); }; +}; +extern struct hci_layer_get_interface hci_layer_get_interface; + +// Name: hci_on_reset_complete +// Params: +// Return: void +struct hci_on_reset_complete { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct hci_on_reset_complete hci_on_reset_complete; + +// Name: hci_on_shutting_down +// Params: +// Return: void +struct hci_on_shutting_down { + std::function body{[]() {}}; + void operator()() { body(); }; +}; +extern struct hci_on_shutting_down hci_on_shutting_down; + +} // namespace main_shim_hci_layer +} // namespace mock +} // namespace test + +// END mockcify generation diff --git a/system/test/mock/mock_main_shim_l2cap_api.cc b/system/test/mock/mock_main_shim_l2cap_api.cc index e0cfe37ee67af1697d1ecdf97b60740d8267ea3a..2683e7da3fcd3cda710232f76d74608568a8a808 100644 --- a/system/test/mock/mock_main_shim_l2cap_api.cc +++ b/system/test/mock/mock_main_shim_l2cap_api.cc @@ -20,309 +20,3 @@ * * mockcify.pl ver 0.2 */ - -#include "test/mock/mock_main_shim_l2cap_api.h" - -#include - -// Mock include file to share data between tests and mock - -#include "main/shim/l2c_api.h" -#include "test/common/mock_functions.h" - -// Mocked compile conditionals, if any -// Mocked internal structures, if any - -namespace test { -namespace mock { -namespace main_shim_l2cap_api { - -// Function state capture and return values, if needed -struct L2CA_ReadRemoteVersion L2CA_ReadRemoteVersion; -struct L2CA_ReadRemoteFeatures L2CA_ReadRemoteFeatures; -struct L2CA_Register L2CA_Register; -struct L2CA_Deregister L2CA_Deregister; -struct L2CA_ConnectReq L2CA_ConnectReq; -struct L2CA_DisconnectReq L2CA_DisconnectReq; -struct L2CA_DataWrite L2CA_DataWrite; -struct L2CA_ReconfigCreditBasedConnsReq L2CA_ReconfigCreditBasedConnsReq; -struct L2CA_ConnectCreditBasedReq L2CA_ConnectCreditBasedReq; -struct L2CA_ConnectCreditBasedRsp L2CA_ConnectCreditBasedRsp; -struct L2CA_SetIdleTimeoutByBdAddr L2CA_SetIdleTimeoutByBdAddr; -struct L2CA_SetAclPriority L2CA_SetAclPriority; -struct L2CA_SetAclPriority2 L2CA_SetAclPriority2; -struct L2CA_GetPeerFeatures L2CA_GetPeerFeatures; -struct L2CA_RegisterFixedChannel L2CA_RegisterFixedChannel; -struct L2CA_ConnectFixedChnl L2CA_ConnectFixedChnl; -struct L2CA_SendFixedChnlData L2CA_SendFixedChnlData; -struct L2CA_RemoveFixedChnl L2CA_RemoveFixedChnl; -struct L2CA_GetLeHandle L2CA_GetLeHandle; -struct L2CA_LeConnectionUpdate L2CA_LeConnectionUpdate; -struct L2CA_EnableUpdateBleConnParams L2CA_EnableUpdateBleConnParams; -struct L2CA_GetRemoteCid L2CA_GetRemoteCid; -struct L2CA_SetTxPriority L2CA_SetTxPriority; -struct L2CA_SetLeGattTimeout L2CA_SetLeGattTimeout; -struct L2CA_SetChnlFlushability L2CA_SetChnlFlushability; -struct L2CA_FlushChannel L2CA_FlushChannel; -struct L2CA_IsLinkEstablished L2CA_IsLinkEstablished; -struct L2CA_IsLeLink L2CA_IsLeLink; -struct L2CA_ReadConnectionAddr L2CA_ReadConnectionAddr; -struct L2CA_ReadRemoteConnectionAddr L2CA_ReadRemoteConnectionAddr; -struct L2CA_GetBleConnRole L2CA_GetBleConnRole; -struct L2CA_ConnectForSecurity L2CA_ConnectForSecurity; -struct L2CA_SetBondingState L2CA_SetBondingState; -struct L2CA_DisconnectLink L2CA_DisconnectLink; -struct L2CA_GetNumLinks L2CA_GetNumLinks; -struct L2CA_AllocateLePSM L2CA_AllocateLePSM; -struct L2CA_FreeLePSM L2CA_FreeLePSM; -struct L2CA_RegisterLECoc L2CA_RegisterLECoc; -struct L2CA_DeregisterLECoc L2CA_DeregisterLECoc; -struct L2CA_ConnectLECocReq L2CA_ConnectLECocReq; -struct L2CA_GetPeerLECocConfig L2CA_GetPeerLECocConfig; -struct L2CA_DisconnectLECocReq L2CA_DisconnectLECocReq; -struct L2CA_LECocDataWrite L2CA_LECocDataWrite; -struct L2CA_SwitchRoleToCentral L2CA_SwitchRoleToCentral; - -} // namespace main_shim_l2cap_api -} // namespace mock -} // namespace test - -// Mocked functions, if any -bool bluetooth::shim::L2CA_ReadRemoteVersion(const RawAddress& addr, - uint8_t* lmp_version, - uint16_t* manufacturer, - uint16_t* lmp_sub_version) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ReadRemoteVersion( - addr, lmp_version, manufacturer, lmp_sub_version); -} -uint8_t* bluetooth::shim::L2CA_ReadRemoteFeatures(const RawAddress& addr) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ReadRemoteFeatures(addr); -} -uint16_t bluetooth::shim::L2CA_Register( - uint16_t client_psm, const tL2CAP_APPL_INFO& callbacks, bool enable_snoop, - tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, - uint16_t required_remote_mtu, uint16_t sec_level) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_Register( - client_psm, callbacks, enable_snoop, p_ertm_info, my_mtu, - required_remote_mtu, sec_level); -} -void bluetooth::shim::L2CA_Deregister(uint16_t psm) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_Deregister(psm); -} -uint16_t bluetooth::shim::L2CA_ConnectReq(uint16_t psm, - const RawAddress& raw_address) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ConnectReq(psm, raw_address); -} -bool bluetooth::shim::L2CA_DisconnectReq(uint16_t cid) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_DisconnectReq(cid); -} -uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_DataWrite(cid, p_data); -} -bool bluetooth::shim::L2CA_ReconfigCreditBasedConnsReq( - const RawAddress& bd_addr, std::vector& lcids, - tL2CAP_LE_CFG_INFO* p_cfg) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ReconfigCreditBasedConnsReq( - bd_addr, lcids, p_cfg); -} -std::vector bluetooth::shim::L2CA_ConnectCreditBasedReq( - uint16_t psm, const RawAddress& p_bd_addr, tL2CAP_LE_CFG_INFO* p_cfg) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ConnectCreditBasedReq( - psm, p_bd_addr, p_cfg); -} -bool bluetooth::shim::L2CA_ConnectCreditBasedRsp( - const RawAddress& bd_addr, uint8_t id, - std::vector& accepted_lcids, uint16_t result, - tL2CAP_LE_CFG_INFO* p_cfg) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ConnectCreditBasedRsp( - bd_addr, id, accepted_lcids, result, p_cfg); -} -bool bluetooth::shim::L2CA_SetIdleTimeoutByBdAddr(const RawAddress& bd_addr, - uint16_t timeout, - tBT_TRANSPORT transport) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_SetIdleTimeoutByBdAddr( - bd_addr, timeout, transport); -} -bool bluetooth::shim::L2CA_SetAclPriority(const RawAddress& bd_addr, - tL2CAP_PRIORITY priority) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_SetAclPriority2(bd_addr, - priority); -} -bool bluetooth::shim::L2CA_GetPeerFeatures(const RawAddress& bd_addr, - uint32_t* p_ext_feat, - uint8_t* p_chnl_mask) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_GetPeerFeatures( - bd_addr, p_ext_feat, p_chnl_mask); -} -bool bluetooth::shim::L2CA_RegisterFixedChannel(uint16_t cid, - tL2CAP_FIXED_CHNL_REG* p_freg) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_RegisterFixedChannel(cid, - p_freg); -} -bool bluetooth::shim::L2CA_ConnectFixedChnl(uint16_t cid, - const RawAddress& rem_bda) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ConnectFixedChnl(cid, rem_bda); -} -uint16_t bluetooth::shim::L2CA_SendFixedChnlData(uint16_t cid, - const RawAddress& rem_bda, - BT_HDR* p_buf) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_SendFixedChnlData(cid, rem_bda, - p_buf); -} -bool bluetooth::shim::L2CA_RemoveFixedChnl(uint16_t cid, - const RawAddress& rem_bda) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_RemoveFixedChnl(cid, rem_bda); -} -uint16_t bluetooth::shim::L2CA_GetLeHandle(const RawAddress& rem_bda) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_GetLeHandle(rem_bda); -} -void bluetooth::shim::L2CA_LeConnectionUpdate( - const RawAddress& rem_bda, uint16_t min_int, uint16_t max_int, - uint16_t latency, uint16_t timeout, uint16_t min_ce_len, - uint16_t max_ce_len) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_LeConnectionUpdate( - rem_bda, min_int, max_int, latency, timeout, min_ce_len, max_ce_len); -} -bool bluetooth::shim::L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, - bool enable) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_EnableUpdateBleConnParams( - rem_bda, enable); -} -bool bluetooth::shim::L2CA_GetRemoteCid(uint16_t lcid, uint16_t* rcid) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_GetRemoteCid(lcid, rcid); -} -bool bluetooth::shim::L2CA_SetTxPriority(uint16_t cid, - tL2CAP_CHNL_PRIORITY priority) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_SetTxPriority(cid, priority); -} -bool bluetooth::shim::L2CA_SetLeGattTimeout(const RawAddress& rem_bda, - uint16_t idle_tout) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_SetLeGattTimeout(rem_bda, - idle_tout); -} -bool bluetooth::shim::L2CA_SetChnlFlushability(uint16_t cid, - bool is_flushable) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_SetChnlFlushability( - cid, is_flushable); -} -uint16_t bluetooth::shim::L2CA_FlushChannel(uint16_t lcid, - uint16_t num_to_flush) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_FlushChannel(lcid, num_to_flush); -} -bool bluetooth::shim::L2CA_IsLinkEstablished(const RawAddress& bd_addr, - tBT_TRANSPORT transport) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_IsLinkEstablished(bd_addr, - transport); -} -bool bluetooth::shim::L2CA_IsLeLink(uint16_t acl_handle) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_IsLeLink(acl_handle); -} -void bluetooth::shim::L2CA_ReadConnectionAddr(const RawAddress& pseudo_addr, - RawAddress& conn_addr, - tBLE_ADDR_TYPE* p_addr_type) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_ReadConnectionAddr( - pseudo_addr, conn_addr, p_addr_type); -} -bool bluetooth::shim::L2CA_ReadRemoteConnectionAddr( - const RawAddress& pseudo_addr, RawAddress& conn_addr, - tBLE_ADDR_TYPE* p_addr_type) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ReadRemoteConnectionAddr( - pseudo_addr, conn_addr, p_addr_type); -} -hci_role_t bluetooth::shim::L2CA_GetBleConnRole(const RawAddress& bd_addr) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_GetBleConnRole(bd_addr); -} -void bluetooth::shim::L2CA_ConnectForSecurity(const RawAddress& bd_addr) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_ConnectForSecurity(bd_addr); -} -void bluetooth::shim::L2CA_SetBondingState(const RawAddress& bd_addr, - bool is_bonding) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_SetBondingState(bd_addr, is_bonding); -} -void bluetooth::shim::L2CA_DisconnectLink(const RawAddress& remote) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_DisconnectLink(remote); -} -uint16_t bluetooth::shim::L2CA_GetNumLinks() { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_GetNumLinks(); -} -uint16_t bluetooth::shim::L2CA_AllocateLePSM() { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_AllocateLePSM(); -} -void bluetooth::shim::L2CA_FreeLePSM(uint16_t psm) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_FreeLePSM(psm); -} -uint16_t bluetooth::shim::L2CA_RegisterLECoc(uint16_t psm, - const tL2CAP_APPL_INFO& callbacks, - uint16_t sec_level, - tL2CAP_LE_CFG_INFO cfg) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_RegisterLECoc(psm, callbacks, - sec_level, cfg); -} -void bluetooth::shim::L2CA_DeregisterLECoc(uint16_t psm) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_DeregisterLECoc(psm); -} -uint16_t bluetooth::shim::L2CA_ConnectLECocReq(uint16_t psm, - const RawAddress& p_bd_addr, - tL2CAP_LE_CFG_INFO* p_cfg) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_ConnectLECocReq(psm, p_bd_addr, - p_cfg); -} -bool bluetooth::shim::L2CA_GetPeerLECocConfig(uint16_t cid, - tL2CAP_LE_CFG_INFO* peer_cfg) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_GetPeerLECocConfig(cid, - peer_cfg); -} -bool bluetooth::shim::L2CA_DisconnectLECocReq(uint16_t cid) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_DisconnectLECocReq(cid); -} -uint8_t bluetooth::shim::L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) { - inc_func_call_count(__func__); - return test::mock::main_shim_l2cap_api::L2CA_LECocDataWrite(cid, p_data); -} -void bluetooth::shim::L2CA_SwitchRoleToCentral(const RawAddress& addr) { - inc_func_call_count(__func__); - test::mock::main_shim_l2cap_api::L2CA_SwitchRoleToCentral(addr); -} - -// END mockcify generation diff --git a/system/test/mock/mock_main_shim_l2cap_api.h b/system/test/mock/mock_main_shim_l2cap_api.h index 3905742bb92cd6d53cc38130f18432d9ade4cc35..340ce3de821007b13138edda4580612167ddcb37 100644 --- a/system/test/mock/mock_main_shim_l2cap_api.h +++ b/system/test/mock/mock_main_shim_l2cap_api.h @@ -291,17 +291,30 @@ struct L2CA_LeConnectionUpdate { }; }; extern struct L2CA_LeConnectionUpdate L2CA_LeConnectionUpdate; -// Name: L2CA_EnableUpdateBleConnParams +// Name: L2CA_LockBleConnParamsForServiceDiscovery // Params: const RawAddress& rem_bda, bool enable -// Returns: bool -struct L2CA_EnableUpdateBleConnParams { - std::function body{ +// Returns: void +struct L2CA_LockBleConnParamsForServiceDiscovery { + std::function body{ + [](const RawAddress& rem_bda, bool enable) { return false; }}; + void operator()(const RawAddress& rem_bda, bool enable) { + return body(rem_bda, enable); + }; +}; +extern struct L2CA_LockBleConnParamsForServiceDiscovery + L2CA_LockBleConnParamsForServiceDiscovery; +// Name: L2CA_LockBleConnParamsForProfileConnection +// Params: const RawAddress& rem_bda, bool enable +// Returns: void +struct L2CA_LockBleConnParamsForProfileConnection { + std::function body{ [](const RawAddress& rem_bda, bool enable) { return false; }}; - bool operator()(const RawAddress& rem_bda, bool enable) { + void operator()(const RawAddress& rem_bda, bool enable) { return body(rem_bda, enable); }; }; -extern struct L2CA_EnableUpdateBleConnParams L2CA_EnableUpdateBleConnParams; +extern struct L2CA_LockBleConnParamsForProfileConnection + L2CA_LockBleConnParamsForProfileConnection; // Name: L2CA_GetRemoteCid // Params: uint16_t lcid, uint16_t* rcid // Returns: bool diff --git a/system/test/mock/mock_main_shim_le_advertising_manager.cc b/system/test/mock/mock_main_shim_le_advertising_manager.cc index f8488dabfc832f102f34de0604943fa9c9421d39..a137f25a53d88fafe9890b3e4cbcc6bde97de09b 100644 --- a/system/test/mock/mock_main_shim_le_advertising_manager.cc +++ b/system/test/mock/mock_main_shim_le_advertising_manager.cc @@ -1,5 +1,6 @@ /* - * Copyright 2021 The Android Open Source Project + * 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. @@ -14,19 +15,31 @@ * limitations under the License. */ -/* - * Generated mock file from original source file - * Functions generated:3 - */ +#include "mock_main_shim_le_advertising_manager.h" + +#include -#include "include/hardware/ble_advertiser.h" #include "main/shim/le_advertising_manager.h" -#include "test/common/mock_functions.h" -BleAdvertiserInterface* bluetooth::shim::get_ble_advertiser_instance() { - inc_func_call_count(__func__); - return nullptr; +namespace { +MockBleAdvertisingManager* bt_le_advertiser_instance; +} // namespace + +void MockBleAdvertisingManager::Initialize() { + if (bt_le_advertiser_instance == nullptr) { + bt_le_advertiser_instance = new MockBleAdvertisingManager(); + } } -void bluetooth::shim::init_advertising_manager() { - inc_func_call_count(__func__); + +void MockBleAdvertisingManager::CleanUp() { + delete bt_le_advertiser_instance; + bt_le_advertiser_instance = nullptr; +} + +MockBleAdvertisingManager* MockBleAdvertisingManager::Get() { + return bt_le_advertiser_instance; +} + +BleAdvertiserInterface* bluetooth::shim::get_ble_advertiser_instance() { + return static_cast(bt_le_advertiser_instance); } diff --git a/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h b/system/test/mock/mock_main_shim_le_advertising_manager.h similarity index 99% rename from system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h rename to system/test/mock/mock_main_shim_le_advertising_manager.h index 9b555ece5ad2e11b74ae0a586c11112019ac1b83..9f60b58aed6ce0fe6a48d2f36157ef4d87086a63 100644 --- a/system/bta/le_audio/broadcaster/mock_ble_advertising_manager.h +++ b/system/test/mock/mock_main_shim_le_advertising_manager.h @@ -22,6 +22,8 @@ #include #include +#include + #include "include/hardware/ble_advertiser.h" class MockBleAdvertisingManager : public BleAdvertiserInterface { diff --git a/system/test/mock/mock_main_shim_le_scanning_manager.cc b/system/test/mock/mock_main_shim_le_scanning_manager.cc index 58fd38e36856e538f902c4dc0ee9641c8bad92aa..d43b758cf4afbb291c2bf20996c3cad9c28ce223 100644 --- a/system/test/mock/mock_main_shim_le_scanning_manager.cc +++ b/system/test/mock/mock_main_shim_le_scanning_manager.cc @@ -34,14 +34,14 @@ bool bluetooth::shim::is_ad_type_filter_supported() { return false; } -void bluetooth::shim::set_ad_type_rsi_filter(bool enable) { +void bluetooth::shim::set_ad_type_rsi_filter(bool /* enable */) { inc_func_call_count(__func__); } -void bluetooth::shim::set_empty_filter(bool enable) { +void bluetooth::shim::set_empty_filter(bool /* enable */) { inc_func_call_count(__func__); } -void bluetooth::shim::set_target_announcements_filter(bool enable) { +void bluetooth::shim::set_target_announcements_filter(bool /* enable */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_main_shim_metric_id_api.cc b/system/test/mock/mock_main_shim_metric_id_api.cc index 3c49f494ac046a2b598b3fa7b63165067b289737..afd5135289bb623700884a67cd744d51028042d4 100644 --- a/system/test/mock/mock_main_shim_metric_id_api.cc +++ b/system/test/mock/mock_main_shim_metric_id_api.cc @@ -27,8 +27,9 @@ namespace bluetooth { namespace shim { bool InitMetricIdAllocator( - const std::unordered_map& paired_device_map, - CallbackLegacy save_id_callback, CallbackLegacy forget_device_callback) { + const std::unordered_map& /* paired_device_map */, + CallbackLegacy /* save_id_callback */, + CallbackLegacy /* forget_device_callback */) { inc_func_call_count(__func__); return false; } @@ -40,19 +41,19 @@ bool IsEmptyMetricIdAllocator() { inc_func_call_count(__func__); return false; } -bool IsValidIdFromMetricIdAllocator(const int id) { +bool IsValidIdFromMetricIdAllocator(const int /* id */) { inc_func_call_count(__func__); return false; } -bool SaveDeviceOnMetricIdAllocator(const RawAddress& raw_address) { +bool SaveDeviceOnMetricIdAllocator(const RawAddress& /* raw_address */) { inc_func_call_count(__func__); return false; } -int AllocateIdFromMetricIdAllocator(const RawAddress& raw_address) { +int AllocateIdFromMetricIdAllocator(const RawAddress& /* raw_address */) { inc_func_call_count(__func__); return 0; } -void ForgetDeviceFromMetricIdAllocator(const RawAddress& raw_address) { +void ForgetDeviceFromMetricIdAllocator(const RawAddress& /* raw_address */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_main_shim_metrics_api.cc b/system/test/mock/mock_main_shim_metrics_api.cc index 3c1615fd3321a515df579270715ac86289560309..a9869c950c511f008c97bb7be403305fcb28e4e1 100644 --- a/system/test/mock/mock_main_shim_metrics_api.cc +++ b/system/test/mock/mock_main_shim_metrics_api.cc @@ -43,6 +43,7 @@ struct LogMetricLinkLayerConnectionEvent LogMetricLinkLayerConnectionEvent; struct LogMetricA2dpAudioUnderrunEvent LogMetricA2dpAudioUnderrunEvent; struct LogMetricA2dpAudioOverrunEvent LogMetricA2dpAudioOverrunEvent; struct LogMetricA2dpPlaybackEvent LogMetricA2dpPlaybackEvent; +struct LogMetricA2dpSessionMetricsEvent LogMetricA2dpSessionMetricsEvent; struct LogMetricHfpPacketLossStats LogMetricHfpPacketLossStats; struct LogMetricMmcTranscodeRttStats LogMetricMmcTranscodeRttStats; struct LogMetricReadRssiResult LogMetricReadRssiResult; @@ -93,6 +94,20 @@ void bluetooth::shim::LogMetricA2dpPlaybackEvent(const RawAddress& raw_address, test::mock::main_shim_metrics_api::LogMetricA2dpPlaybackEvent( raw_address, playback_state, audio_coding_mode); } +void bluetooth::shim::LogMetricA2dpSessionMetricsEvent( + const RawAddress& raw_address, int64_t audio_duration_ms, + int media_timer_min_ms, int media_timer_max_ms, + int /* media_timer_avg_ms */, int total_scheduling_count, + int buffer_overruns_max_count, int buffer_overruns_total, + float buffer_underruns_average, int buffer_underruns_count, + int64_t codec_index, bool is_a2dp_offload) { + inc_func_call_count(__func__); + test::mock::main_shim_metrics_api::LogMetricA2dpSessionMetricsEvent( + raw_address, audio_duration_ms, media_timer_min_ms, media_timer_max_ms, + audio_duration_ms, total_scheduling_count, buffer_overruns_max_count, + buffer_overruns_total, buffer_underruns_average, buffer_underruns_count, + codec_index, is_a2dp_offload); +} void bluetooth::shim::LogMetricHfpPacketLossStats(const RawAddress& raw_address, int num_decoded_frames, double packet_loss_ratio, @@ -179,17 +194,18 @@ void bluetooth::shim::LogMetricManufacturerInfo( raw_address, address_type, source_type, source_name, manufacturer, model, hardware_version, software_version); } -bool bluetooth::shim::CountCounterMetrics(int32_t key, int64_t count) { +bool bluetooth::shim::CountCounterMetrics(int32_t /* key */, + int64_t /* count */) { inc_func_call_count(__func__); return false; - } void bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( - const RawAddress& raw_address, - android::bluetooth::le::LeConnectionOriginType origin_type, - android::bluetooth::le::LeConnectionType connection_type, - android::bluetooth::le::LeConnectionState transaction_state, - std::vector> argument_list) { + const RawAddress& /* raw_address */, + android::bluetooth::le::LeConnectionOriginType /* origin_type */, + android::bluetooth::le::LeConnectionType /* connection_type */, + android::bluetooth::le::LeConnectionState /* transaction_state */, + std::vector< + std::pair> /* argument_list */) { inc_func_call_count(__func__); // test::mock::main_shim_metrics_api::LogMetricBluetoothLEConnectionMetricEvent(raw_address, origin_type, connection_type, transaction_state, argument_list); } diff --git a/system/test/mock/mock_main_shim_metrics_api.h b/system/test/mock/mock_main_shim_metrics_api.h index acfe15a6a1b0388d6eaef6226a54a4233c42b7c1..f65a6240db62794784da63f586a4b959af834594 100644 --- a/system/test/mock/mock_main_shim_metrics_api.h +++ b/system/test/mock/mock_main_shim_metrics_api.h @@ -26,9 +26,9 @@ #include // Original included files, if any -#include +// #include -#include "gd/os/metrics.h" +#include "os/metrics.h" #include "types/raw_address.h" // Mocked compile conditionals, if any @@ -48,10 +48,12 @@ struct LogMetricLinkLayerConnectionEvent { uint16_t link_type, uint32_t hci_cmd, uint16_t hci_event, uint16_t hci_ble_event, uint16_t cmd_status, uint16_t reason_code)> - body{[](const RawAddress* raw_address, uint32_t connection_handle, - android::bluetooth::DirectionEnum direction, uint16_t link_type, - uint32_t hci_cmd, uint16_t hci_event, uint16_t hci_ble_event, - uint16_t cmd_status, uint16_t reason_code) {}}; + body{[](const RawAddress* /* raw_address */, + uint32_t /* connection_handle */, + android::bluetooth::DirectionEnum /* direction */, + uint16_t /* link_type */, uint32_t /* hci_cmd */, + uint16_t /* hci_event */, uint16_t /* hci_ble_event */, + uint16_t /* cmd_status */, uint16_t /* reason_code */) {}}; void operator()(const RawAddress* raw_address, uint32_t connection_handle, android::bluetooth::DirectionEnum direction, uint16_t link_type, uint32_t hci_cmd, uint16_t hci_event, @@ -70,8 +72,9 @@ struct LogMetricA2dpAudioUnderrunEvent { std::function - body{[](const RawAddress& raw_address, uint64_t encoding_interval_millis, - int num_missing_pcm_bytes) {}}; + body{[](const RawAddress& /* raw_address */, + uint64_t /* encoding_interval_millis */, + int /* num_missing_pcm_bytes */) {}}; void operator()(const RawAddress& raw_address, uint64_t encoding_interval_millis, int num_missing_pcm_bytes) { @@ -88,9 +91,11 @@ struct LogMetricA2dpAudioOverrunEvent { uint64_t encoding_interval_millis, int num_dropped_buffers, int num_dropped_encoded_frames, int num_dropped_encoded_bytes)> - body{[](const RawAddress& raw_address, uint64_t encoding_interval_millis, - int num_dropped_buffers, int num_dropped_encoded_frames, - int num_dropped_encoded_bytes) {}}; + body{[](const RawAddress& /* raw_address */, + uint64_t /* encoding_interval_millis */, + int /* num_dropped_buffers */, + int /* num_dropped_encoded_frames */, + int /* num_dropped_encoded_bytes */) {}}; void operator()(const RawAddress& raw_address, uint64_t encoding_interval_millis, int num_dropped_buffers, int num_dropped_encoded_frames, @@ -106,13 +111,45 @@ extern struct LogMetricA2dpAudioOverrunEvent LogMetricA2dpAudioOverrunEvent; struct LogMetricA2dpPlaybackEvent { std::function - body{[](const RawAddress& raw_address, int playback_state, - int audio_coding_mode) {}}; + body{[](const RawAddress& /* raw_address */, int /* playback_state */, + int /* audio_coding_mode */) {}}; void operator()(const RawAddress& raw_address, int playback_state, int audio_coding_mode) { body(raw_address, playback_state, audio_coding_mode); }; }; +extern struct LogMetricA2dpSessionMetricsEvent LogMetricA2dpSessionMetricsEvent; +// Name: LogMetricA2dpSessionMetricsEvent +// Params: const RawAddress& raw_address, int playback_state, int +// audio_coding_mode Returns: void +struct LogMetricA2dpSessionMetricsEvent { + std::function + body{[](const RawAddress& /* raw_address */, + int64_t /* audio_duration_ms */, int /* media_timer_min_ms */, + int /* media_timer_max_ms */, int /* media_timer_avg_ms */, + int /* total_scheduling_count */, + int /* buffer_overruns_max_count */, + int /* buffer_overruns_total */, + float /* buffer_underruns_average */, + int /* buffer_underruns_count */, int64_t /* codec_index */, + bool /* is_a2dp_offload */) {}}; + void operator()(const RawAddress& raw_address, int64_t audio_duration_ms, + int media_timer_min_ms, int media_timer_max_ms, + int /* media_timer_avg_ms */, int total_scheduling_count, + int buffer_overruns_max_count, int buffer_overruns_total, + float buffer_underruns_average, int buffer_underruns_count, + int64_t codec_index, bool is_a2dp_offload) { + body(raw_address, audio_duration_ms, media_timer_min_ms, media_timer_max_ms, + audio_duration_ms, total_scheduling_count, buffer_overruns_max_count, + buffer_overruns_total, buffer_underruns_average, + buffer_underruns_count, codec_index, is_a2dp_offload); + }; +}; extern struct LogMetricA2dpPlaybackEvent LogMetricA2dpPlaybackEvent; // Name: LogMetricHfpPacketLossStats // Params: const RawAddress& raw_address, int num_decoded_frames, double @@ -120,8 +157,8 @@ extern struct LogMetricA2dpPlaybackEvent LogMetricA2dpPlaybackEvent; struct LogMetricHfpPacketLossStats { std::function - body{[](const RawAddress& raw_address, int num_decoded_frames, - double packet_loss_ratio, uint16_t codec_type) {}}; + body{[](const RawAddress& /* raw_address */, int /* num_decoded_frames */, + double /* packet_loss_ratio */, uint16_t /* codec_type */) {}}; void operator()(const RawAddress& raw_address, int num_decoded_frames, double packet_loss_ratio, uint16_t codec_type) { body(raw_address, num_decoded_frames, packet_loss_ratio, codec_type); @@ -134,8 +171,8 @@ extern struct LogMetricHfpPacketLossStats LogMetricHfpPacketLossStats; struct LogMetricMmcTranscodeRttStats { std::function - body{[](int maximum_rtt, double mean_rtt, int num_requests, - int codec_type) {}}; + body{[](int /* maximum_rtt */, double /* mean_rtt */, + int /* num_requests */, int /* codec_type */) {}}; void operator()(int maximum_rtt, double mean_rtt, int num_requests, int codec_type) { body(maximum_rtt, mean_rtt, num_requests, codec_type); @@ -148,8 +185,8 @@ extern struct LogMetricMmcTranscodeRttStats LogMetricMmcTranscodeRttStats; struct LogMetricReadRssiResult { std::function - body{[](const RawAddress& raw_address, uint16_t handle, - uint32_t cmd_status, int8_t rssi) {}}; + body{[](const RawAddress& /* raw_address */, uint16_t /* handle */, + uint32_t /* cmd_status */, int8_t /* rssi */) {}}; void operator()(const RawAddress& raw_address, uint16_t handle, uint32_t cmd_status, int8_t rssi) { body(raw_address, handle, cmd_status, rssi); @@ -162,8 +199,9 @@ extern struct LogMetricReadRssiResult LogMetricReadRssiResult; struct LogMetricReadFailedContactCounterResult { std::function - body{[](const RawAddress& raw_address, uint16_t handle, - uint32_t cmd_status, int32_t failed_contact_counter) {}}; + body{[](const RawAddress& /* raw_address */, uint16_t /* handle */, + uint32_t /* cmd_status */, + int32_t /* failed_contact_counter */) {}}; void operator()(const RawAddress& raw_address, uint16_t handle, uint32_t cmd_status, int32_t failed_contact_counter) { body(raw_address, handle, cmd_status, failed_contact_counter); @@ -177,8 +215,9 @@ extern struct LogMetricReadFailedContactCounterResult struct LogMetricReadTxPowerLevelResult { std::function - body{[](const RawAddress& raw_address, uint16_t handle, - uint32_t cmd_status, int32_t transmit_power_level) {}}; + body{[](const RawAddress& /* raw_address */, uint16_t /* handle */, + uint32_t /* cmd_status */, + int32_t /* transmit_power_level */) {}}; void operator()(const RawAddress& raw_address, uint16_t handle, uint32_t cmd_status, int32_t transmit_power_level) { body(raw_address, handle, cmd_status, transmit_power_level); @@ -193,9 +232,9 @@ struct LogMetricSmpPairingEvent { std::function - body{[](const RawAddress& raw_address, uint16_t smp_cmd, - android::bluetooth::DirectionEnum direction, - uint16_t smp_fail_reason) {}}; + body{[](const RawAddress& /* raw_address */, uint16_t /* smp_cmd */, + android::bluetooth::DirectionEnum /* direction */, + uint16_t /* smp_fail_reason */) {}}; void operator()(const RawAddress& raw_address, uint16_t smp_cmd, android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason) { @@ -211,9 +250,10 @@ struct LogMetricClassicPairingEvent { std::function - body{[](const RawAddress& raw_address, uint16_t handle, uint32_t hci_cmd, - uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code, - int64_t event_value) {}}; + body{[](const RawAddress& /* raw_address */, uint16_t /* handle */, + uint32_t /* hci_cmd */, uint16_t /* hci_event */, + uint16_t /* cmd_status */, uint16_t /* reason_code */, + int64_t /* event_value */) {}}; void operator()(const RawAddress& raw_address, uint16_t handle, uint32_t hci_cmd, uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code, int64_t event_value) { @@ -230,9 +270,9 @@ struct LogMetricSdpAttribute { std::function - body{[](const RawAddress& raw_address, uint16_t protocol_uuid, - uint16_t attribute_id, size_t attribute_size, - const char* attribute_value) {}}; + body{[](const RawAddress& /* raw_address */, uint16_t /* protocol_uuid */, + uint16_t /* attribute_id */, size_t /* attribute_size */, + const char* /* attribute_value */) {}}; void operator()(const RawAddress& raw_address, uint16_t protocol_uuid, uint16_t attribute_id, size_t attribute_size, const char* attribute_value) { @@ -252,10 +292,13 @@ struct LogMetricSocketConnectionState { android::bluetooth::SocketConnectionstateEnum connection_state, int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port, android::bluetooth::SocketRoleEnum socket_role)> - body{[](const RawAddress& raw_address, int port, int type, - android::bluetooth::SocketConnectionstateEnum connection_state, - int64_t tx_bytes, int64_t rx_bytes, int uid, int server_port, - android::bluetooth::SocketRoleEnum socket_role) {}}; + body{[](const RawAddress& /* raw_address */, int /* port */, + int /* type */, + android::bluetooth:: + SocketConnectionstateEnum /* connection_state */, + int64_t /* tx_bytes */, int64_t /* rx_bytes */, int /* uid */, + int /* server_port */, + android::bluetooth::SocketRoleEnum /* socket_role */) {}}; void operator()( const RawAddress& raw_address, int port, int type, android::bluetooth::SocketConnectionstateEnum connection_state, @@ -279,12 +322,14 @@ struct LogMetricManufacturerInfo { const std::string& manufacturer, const std::string& model, const std::string& hardware_version, const std::string& software_version)> - body{[](const RawAddress& raw_address, - android::bluetooth::AddressTypeEnum address_type, - android::bluetooth::DeviceInfoSrcEnum source_type, - const std::string& source_name, const std::string& manufacturer, - const std::string& model, const std::string& hardware_version, - const std::string& software_version) {}}; + body{[](const RawAddress& /* raw_address */, + android::bluetooth::AddressTypeEnum /* address_type */, + android::bluetooth::DeviceInfoSrcEnum /* source_type */, + const std::string& /* source_name */, + const std::string& /* manufacturer */, + const std::string& /* model */, + const std::string& /* hardware_version */, + const std::string& /* software_version */) {}}; void operator()(const RawAddress& raw_address, android::bluetooth::AddressTypeEnum address_type, android::bluetooth::DeviceInfoSrcEnum source_type, @@ -311,15 +356,14 @@ struct LogMetricBluetoothLEConnectionMetricEvent { android::bluetooth::le::LeConnectionOriginType origin_type, android::bluetooth::le::LeConnectionType connection_type, android::bluetooth::le::LeConnectionState transaction_state, - std::vector> - argument_list)> - body{[](const RawAddress& raw_address, - android::bluetooth::le::LeConnectionOriginType origin_type, - android::bluetooth::le::LeConnectionType connection_type, + std::vector> argument_list)> + body{[](const RawAddress& /* raw_address */, + android::bluetooth::le::LeConnectionOriginType /* origin_type */, + android::bluetooth::le::LeConnectionType /* connection_type */, android::bluetooth::le::LeConnectionState - transaction_state, + /* transaction_state */, std::vector> - argument_list) {}}; + /* argument_list */) {}}; void operator()( const RawAddress& raw_address, android::bluetooth::le::LeConnectionOriginType origin_type, diff --git a/system/test/mock/mock_osi_alarm.h b/system/test/mock/mock_osi_alarm.h index 339a5b1098f6082e3f3ce06eba7fe327f6db80d3..eba4330ee8cd8dc266e5f8bd6ca9d49c9673fc6b 100644 --- a/system/test/mock/mock_osi_alarm.h +++ b/system/test/mock/mock_osi_alarm.h @@ -40,7 +40,7 @@ namespace osi_alarm { // Params: alarm_t* alarm // Return: void struct alarm_cancel { - std::function body{[](alarm_t* alarm) {}}; + std::function body{[](alarm_t* /* alarm */) {}}; void operator()(alarm_t* alarm) { body(alarm); }; }; extern struct alarm_cancel alarm_cancel; @@ -58,7 +58,7 @@ extern struct alarm_cleanup alarm_cleanup; // Params: int fd // Return: void struct alarm_debug_dump { - std::function body{[](int fd) {}}; + std::function body{[](int /* fd */) {}}; void operator()(int fd) { body(fd); }; }; extern struct alarm_debug_dump alarm_debug_dump; @@ -67,7 +67,7 @@ extern struct alarm_debug_dump alarm_debug_dump; // Params: alarm_t* alarm // Return: void struct alarm_free { - std::function body{[](alarm_t* alarm) {}}; + std::function body{[](alarm_t* /* alarm */) {}}; void operator()(alarm_t* alarm) { body(alarm); }; }; extern struct alarm_free alarm_free; @@ -78,7 +78,7 @@ extern struct alarm_free alarm_free; struct alarm_get_remaining_ms { uint64_t return_value{0}; std::function body{ - [this](const alarm_t* alarm) { return return_value; }}; + [this](const alarm_t* /* alarm */) { return return_value; }}; uint64_t operator()(const alarm_t* alarm) { return body(alarm); }; }; extern struct alarm_get_remaining_ms alarm_get_remaining_ms; @@ -89,7 +89,7 @@ extern struct alarm_get_remaining_ms alarm_get_remaining_ms; struct alarm_is_scheduled { bool return_value{false}; std::function body{ - [this](const alarm_t* alarm) { return return_value; }}; + [this](const alarm_t* /* alarm */) { return return_value; }}; bool operator()(const alarm_t* alarm) { return body(alarm); }; }; extern struct alarm_is_scheduled alarm_is_scheduled; @@ -100,7 +100,7 @@ extern struct alarm_is_scheduled alarm_is_scheduled; struct alarm_new { alarm_t* return_value{0}; std::function body{ - [this](const char* name) { return return_value; }}; + [this](const char* /* name */) { return return_value; }}; alarm_t* operator()(const char* name) { return body(name); }; }; extern struct alarm_new alarm_new; @@ -111,7 +111,7 @@ extern struct alarm_new alarm_new; struct alarm_new_periodic { alarm_t* return_value{0}; std::function body{ - [this](const char* name) { return return_value; }}; + [this](const char* /* name */) { return return_value; }}; alarm_t* operator()(const char* name) { return body(name); }; }; extern struct alarm_new_periodic alarm_new_periodic; @@ -122,8 +122,8 @@ extern struct alarm_new_periodic alarm_new_periodic; struct alarm_set { std::function - body{[](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, - void* data) {}}; + body{[](alarm_t* /* alarm */, uint64_t /* interval_ms */, + alarm_callback_t /* cb */, void* /* data */) {}}; void operator()(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { body(alarm, interval_ms, cb, data); @@ -137,8 +137,8 @@ extern struct alarm_set alarm_set; struct alarm_set_on_mloop { std::function - body{[](alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, - void* data) {}}; + body{[](alarm_t* /* alarm */, uint64_t /* interval_ms */, + alarm_callback_t /* cb */, void* /* data */) {}}; void operator()(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) { body(alarm, interval_ms, cb, data); @@ -150,4 +150,4 @@ extern struct alarm_set_on_mloop alarm_set_on_mloop; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_osi_allocator.cc b/system/test/mock/mock_osi_allocator.cc index 224d51ed7c43face3c836bf9cacd3cc9da0c46d2..5702c41f6a0ddafb088c8077c9d8d37754cb2fef 100644 --- a/system/test/mock/mock_osi_allocator.cc +++ b/system/test/mock/mock_osi_allocator.cc @@ -23,10 +23,26 @@ // Mock include file to share data between tests and mock #include "test/mock/mock_osi_allocator.h" +#include "osi/include/allocator.h" #include "test/common/mock_functions.h" // Mocked internal structures, if any +OsiObject::OsiObject(void* ptr) : ptr_(ptr) {} + +OsiObject::OsiObject(const void* ptr) : ptr_(const_cast(ptr)) {} + +OsiObject::~OsiObject() { + if (ptr_ != nullptr) { + osi_free(ptr_); + } +} + +void* OsiObject::Release() { + void* ptr = ptr_; + ptr_ = nullptr; + return ptr; +} namespace test { namespace mock { namespace osi_allocator { diff --git a/system/test/mock/mock_osi_allocator.h b/system/test/mock/mock_osi_allocator.h index ee5459e6ebc3e3849309a5ff85b4d50a30f2a5dc..ef905f286b97cc93cbbb8189b617b522f0a1d5f3 100644 --- a/system/test/mock/mock_osi_allocator.h +++ b/system/test/mock/mock_osi_allocator.h @@ -41,7 +41,7 @@ namespace osi_allocator { struct osi_calloc { void* return_value{}; std::function body{ - [this](size_t size) { return return_value; }}; + [this](size_t /* size */) { return return_value; }}; void* operator()(size_t size) { return body(size); }; }; extern struct osi_calloc osi_calloc; @@ -50,7 +50,7 @@ extern struct osi_calloc osi_calloc; // Params: void* ptr // Return: void struct osi_free { - std::function body{[](void* ptr) {}}; + std::function body{[](void* /* ptr */) {}}; void operator()(void* ptr) { body(ptr); }; }; extern struct osi_free osi_free; @@ -59,7 +59,7 @@ extern struct osi_free osi_free; // Params: void** p_ptr // Return: void struct osi_free_and_reset { - std::function body{[](void** p_ptr) {}}; + std::function body{[](void** /* p_ptr */) {}}; void operator()(void** p_ptr) { body(p_ptr); }; }; extern struct osi_free_and_reset osi_free_and_reset; @@ -70,7 +70,7 @@ extern struct osi_free_and_reset osi_free_and_reset; struct osi_malloc { void* return_value{}; std::function body{ - [this](size_t size) { return return_value; }}; + [this](size_t /* size */) { return return_value; }}; void* operator()(size_t size) { return body(size); }; }; extern struct osi_malloc osi_malloc; @@ -81,7 +81,7 @@ extern struct osi_malloc osi_malloc; struct osi_strdup { char* return_value{0}; std::function body{ - [this](const char* str) { return return_value; }}; + [this](const char* /* str */) { return return_value; }}; char* operator()(const char* str) { return body(str); }; }; extern struct osi_strdup osi_strdup; @@ -92,7 +92,7 @@ extern struct osi_strdup osi_strdup; struct osi_strndup { char* return_value{0}; std::function body{ - [this](const char* str, size_t len) { return return_value; }}; + [this](const char* /* str */, size_t /* len */) { return return_value; }}; char* operator()(const char* str, size_t len) { return body(str, len); }; }; extern struct osi_strndup osi_strndup; diff --git a/system/test/mock/mock_osi_config.h b/system/test/mock/mock_osi_config.h index 7344bbfcfbe9515613a352576889ec179bd31b18..ee9dce58a3e9e5a7ad38df514f7d7fde0964a1e6 100644 --- a/system/test/mock/mock_osi_config.h +++ b/system/test/mock/mock_osi_config.h @@ -51,7 +51,7 @@ namespace osi_config { struct checksum_read { std::string return_value{std::string()}; std::function body{ - [this](const char* filename) { return return_value; }}; + [this](const char* /* filename */) { return return_value; }}; std::string operator()(const char* filename) { return body(filename); }; }; extern struct checksum_read checksum_read; @@ -62,9 +62,8 @@ extern struct checksum_read checksum_read; struct checksum_save { bool return_value{false}; std::function - body{[this](const std::string& checksum, const std::string& filename) { - return return_value; - }}; + body{[this](const std::string& /* checksum */, + const std::string& /* filename */) { return return_value; }}; bool operator()(const std::string& checksum, const std::string& filename) { return body(checksum, filename); }; @@ -78,9 +77,10 @@ struct config_get_bool { bool return_value{false}; std::function - body{[this](const config_t& config, const std::string& section, - const std::string& key, - bool def_value) { return return_value; }}; + body{[this](const config_t& /* config */, + const std::string& /* section */, + const std::string& /* key */, + bool /* def_value */) { return return_value; }}; bool operator()(const config_t& config, const std::string& section, const std::string& key, bool def_value) { return body(config, section, key, def_value); @@ -95,9 +95,10 @@ struct config_get_int { int return_value{0}; std::function - body{[this](const config_t& config, const std::string& section, - const std::string& key, - int def_value) { return return_value; }}; + body{[this](const config_t& /* config */, + const std::string& /* section */, + const std::string& /* key */, + int /* def_value */) { return return_value; }}; int operator()(const config_t& config, const std::string& section, const std::string& key, int def_value) { return body(config, section, key, def_value); @@ -113,9 +114,10 @@ struct config_get_string { std::function - body{[this](const config_t& config, const std::string& section, - const std::string& key, - const std::string* def_value) { return return_value; }}; + body{[this](const config_t& /* config */, + const std::string& /* section */, + const std::string& /* key */, + const std::string* /* def_value */) { return return_value; }}; const std::string* operator()(const config_t& config, const std::string& section, const std::string& key, @@ -132,9 +134,10 @@ struct config_get_uint64 { uint64_t return_value{0}; std::function - body{[this](const config_t& config, const std::string& section, - const std::string& key, - uint64_t def_value) { return return_value; }}; + body{[this](const config_t& /* config */, + const std::string& /* section */, + const std::string& /* key */, + uint64_t /* def_value */) { return return_value; }}; uint64_t operator()(const config_t& config, const std::string& section, const std::string& key, uint64_t def_value) { return body(config, section, key, def_value); @@ -149,8 +152,9 @@ struct config_has_key { bool return_value{false}; std::function - body{[this](const config_t& config, const std::string& section, - const std::string& key) { return return_value; }}; + body{[this](const config_t& /* config */, + const std::string& /* section */, + const std::string& /* key */) { return return_value; }}; bool operator()(const config_t& config, const std::string& section, const std::string& key) { return body(config, section, key); @@ -163,10 +167,10 @@ extern struct config_has_key config_has_key; // Return: bool struct config_has_section { bool return_value{false}; - std::function body{ - [this](const config_t& config, const std::string& section) { - return return_value; - }}; + std::function + body{[this](const config_t& /* config */, + const std::string& /* section */) { return return_value; }}; bool operator()(const config_t& config, const std::string& section) { return body(config, section); }; @@ -178,7 +182,7 @@ extern struct config_has_section config_has_section; // Return: std::unique_ptr struct config_new { std::function(const char* filename)> body{ - [](const char* filename) { return std::make_unique(); }}; + [](const char* /* filename */) { return std::make_unique(); }}; std::unique_ptr operator()(const char* filename) { return body(filename); }; @@ -190,7 +194,7 @@ extern struct config_new config_new; // Return: std::unique_ptr struct config_new_clone { std::function(const config_t& src)> body{ - [](const config_t& src) { return std::make_unique(); }}; + [](const config_t& /* src */) { return std::make_unique(); }}; std::unique_ptr operator()(const config_t& src) { return body(src); }; @@ -214,8 +218,8 @@ struct config_remove_key { bool return_value{false}; std::function - body{[this](config_t* config, const std::string& section, - const std::string& key) { return return_value; }}; + body{[this](config_t* /* config */, const std::string& /* section */, + const std::string& /* key */) { return return_value; }}; bool operator()(config_t* config, const std::string& section, const std::string& key) { return body(config, section, key); @@ -229,7 +233,7 @@ extern struct config_remove_key config_remove_key; struct config_remove_section { bool return_value{false}; std::function body{ - [this](config_t* config, const std::string& section) { + [this](config_t* /* config */, const std::string& /* section */) { return return_value; }}; bool operator()(config_t* config, const std::string& section) { @@ -244,7 +248,7 @@ extern struct config_remove_section config_remove_section; struct config_save { bool return_value{false}; std::function body{ - [this](const config_t& config, const std::string& filename) { + [this](const config_t& /* config */, const std::string& /* filename */) { return return_value; }}; bool operator()(const config_t& config, const std::string& filename) { @@ -259,8 +263,8 @@ extern struct config_save config_save; struct config_set_bool { std::function - body{[](config_t* config, const std::string& section, - const std::string& key, bool value) {}}; + body{[](config_t* /* config */, const std::string& /* section */, + const std::string& /* key */, bool /* value */) {}}; void operator()(config_t* config, const std::string& section, const std::string& key, bool value) { body(config, section, key, value); @@ -274,8 +278,8 @@ extern struct config_set_bool config_set_bool; struct config_set_int { std::function - body{[](config_t* config, const std::string& section, - const std::string& key, int value) {}}; + body{[](config_t* /* config */, const std::string& /* section */, + const std::string& /* key */, int /* value */) {}}; void operator()(config_t* config, const std::string& section, const std::string& key, int value) { body(config, section, key, value); @@ -289,8 +293,8 @@ extern struct config_set_int config_set_int; struct config_set_string { std::function - body{[](config_t* config, const std::string& section, - const std::string& key, const std::string& value) {}}; + body{[](config_t* /* config */, const std::string& /* section */, + const std::string& /* key */, const std::string& /* value */) {}}; void operator()(config_t* config, const std::string& section, const std::string& key, const std::string& value) { body(config, section, key, value); @@ -304,8 +308,8 @@ extern struct config_set_string config_set_string; struct config_set_uint64 { std::function - body{[](config_t* config, const std::string& section, - const std::string& key, uint64_t value) {}}; + body{[](config_t* /* config */, const std::string& /* section */, + const std::string& /* key */, uint64_t /* value */) {}}; void operator()(config_t* config, const std::string& section, const std::string& key, uint64_t value) { body(config, section, key, value); @@ -319,7 +323,9 @@ extern struct config_set_uint64 config_set_uint64; struct config_t_Find { std::list section_; std::function::iterator(const std::string& section)> - body{[this](const std::string& section) { return section_.begin(); }}; + body{[this](const std::string& /* section */) { + return section_.begin(); + }}; std::list::iterator operator()(const std::string& section) { return body(section); }; @@ -332,7 +338,7 @@ extern struct config_t_Find config_t_Find; struct config_t_Has { bool return_value{false}; std::function body{ - [this](const std::string& key) { return return_value; }}; + [this](const std::string& /* key */) { return return_value; }}; bool operator()(const std::string& key) { return body(key); }; }; extern struct config_t_Has config_t_Has; @@ -343,7 +349,7 @@ extern struct config_t_Has config_t_Has; struct section_t_Find { std::list list_; std::function::iterator(const std::string& key)> body{ - [this](const std::string& key) { return list_.begin(); }}; + [this](const std::string& /* key */) { return list_.begin(); }}; std::list::iterator operator()(const std::string& key) { return body(key); }; @@ -356,7 +362,7 @@ extern struct section_t_Find section_t_Find; struct section_t_Has { bool return_value{false}; std::function body{ - [this](const std::string& key) { return return_value; }}; + [this](const std::string& /* key */) { return return_value; }}; bool operator()(const std::string& key) { return body(key); }; }; extern struct section_t_Has section_t_Has; @@ -366,7 +372,7 @@ extern struct section_t_Has section_t_Has; // Return: void struct section_t_Set { std::function body{ - [](std::string key, std::string value) {}}; + [](std::string /* key */, std::string /* value */) {}}; void operator()(std::string key, std::string value) { body(key, value); }; }; extern struct section_t_Set section_t_Set; diff --git a/system/test/mock/mock_osi_fixed_queue.h b/system/test/mock/mock_osi_fixed_queue.h index 786ab27b2ea586042900284c6c66def2d4f4aa21..5f51faec6ac133f053f69bc9cc6bbe33db8b1fe2 100644 --- a/system/test/mock/mock_osi_fixed_queue.h +++ b/system/test/mock/mock_osi_fixed_queue.h @@ -44,7 +44,7 @@ namespace osi_fixed_queue { struct fixed_queue_capacity { size_t return_value{0}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; size_t operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_capacity fixed_queue_capacity; @@ -55,7 +55,7 @@ extern struct fixed_queue_capacity fixed_queue_capacity; struct fixed_queue_dequeue { void* return_value{}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; void* operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_dequeue fixed_queue_dequeue; @@ -65,7 +65,7 @@ extern struct fixed_queue_dequeue fixed_queue_dequeue; // Return: void struct fixed_queue_enqueue { std::function body{ - [](fixed_queue_t* queue, void* data) {}}; + [](fixed_queue_t* /* queue */, void* /* data */) {}}; void operator()(fixed_queue_t* queue, void* data) { body(queue, data); }; }; extern struct fixed_queue_enqueue fixed_queue_enqueue; @@ -75,7 +75,7 @@ extern struct fixed_queue_enqueue fixed_queue_enqueue; // Return: void struct fixed_queue_flush { std::function body{ - [](fixed_queue_t* queue, fixed_queue_free_cb free_cb) {}}; + [](fixed_queue_t* /* queue */, fixed_queue_free_cb /* free_cb */) {}}; void operator()(fixed_queue_t* queue, fixed_queue_free_cb free_cb) { body(queue, free_cb); }; @@ -87,7 +87,7 @@ extern struct fixed_queue_flush fixed_queue_flush; // Return: void struct fixed_queue_free { std::function body{ - [](fixed_queue_t* queue, fixed_queue_free_cb free_cb) {}}; + [](fixed_queue_t* /* queue */, fixed_queue_free_cb /* free_cb */) {}}; void operator()(fixed_queue_t* queue, fixed_queue_free_cb free_cb) { body(queue, free_cb); }; @@ -100,7 +100,7 @@ extern struct fixed_queue_free fixed_queue_free; struct fixed_queue_get_dequeue_fd { int return_value{0}; std::function body{ - [this](const fixed_queue_t* queue) { return return_value; }}; + [this](const fixed_queue_t* /* queue */) { return return_value; }}; int operator()(const fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_get_dequeue_fd fixed_queue_get_dequeue_fd; @@ -111,7 +111,7 @@ extern struct fixed_queue_get_dequeue_fd fixed_queue_get_dequeue_fd; struct fixed_queue_get_enqueue_fd { int return_value{0}; std::function body{ - [this](const fixed_queue_t* queue) { return return_value; }}; + [this](const fixed_queue_t* /* queue */) { return return_value; }}; int operator()(const fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_get_enqueue_fd fixed_queue_get_enqueue_fd; @@ -122,7 +122,7 @@ extern struct fixed_queue_get_enqueue_fd fixed_queue_get_enqueue_fd; struct fixed_queue_get_list { list_t* return_value{0}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; list_t* operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_get_list fixed_queue_get_list; @@ -133,7 +133,7 @@ extern struct fixed_queue_get_list fixed_queue_get_list; struct fixed_queue_is_empty { bool return_value{false}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; bool operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_is_empty fixed_queue_is_empty; @@ -144,7 +144,7 @@ extern struct fixed_queue_is_empty fixed_queue_is_empty; struct fixed_queue_length { size_t return_value{0}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; size_t operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_length fixed_queue_length; @@ -155,7 +155,7 @@ extern struct fixed_queue_length fixed_queue_length; struct fixed_queue_new { fixed_queue_t* return_value{0}; std::function body{ - [this](size_t capacity) { return return_value; }}; + [this](size_t /* capacity */) { return return_value; }}; fixed_queue_t* operator()(size_t capacity) { return body(capacity); }; }; extern struct fixed_queue_new fixed_queue_new; @@ -166,8 +166,8 @@ extern struct fixed_queue_new fixed_queue_new; struct fixed_queue_register_dequeue { std::function - body{[](fixed_queue_t* queue, reactor_t* reactor, fixed_queue_cb ready_cb, - void* context) {}}; + body{[](fixed_queue_t* /* queue */, reactor_t* /* reactor */, + fixed_queue_cb /* ready_cb */, void* /* context */) {}}; void operator()(fixed_queue_t* queue, reactor_t* reactor, fixed_queue_cb ready_cb, void* context) { body(queue, reactor, ready_cb, context); @@ -181,7 +181,7 @@ extern struct fixed_queue_register_dequeue fixed_queue_register_dequeue; struct fixed_queue_try_dequeue { void* return_value{}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; void* operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_try_dequeue fixed_queue_try_dequeue; @@ -192,7 +192,9 @@ extern struct fixed_queue_try_dequeue fixed_queue_try_dequeue; struct fixed_queue_try_enqueue { bool return_value{false}; std::function body{ - [this](fixed_queue_t* queue, void* data) { return return_value; }}; + [this](fixed_queue_t* /* queue */, void* /* data */) { + return return_value; + }}; bool operator()(fixed_queue_t* queue, void* data) { return body(queue, data); }; @@ -205,7 +207,7 @@ extern struct fixed_queue_try_enqueue fixed_queue_try_enqueue; struct fixed_queue_try_peek_first { void* return_value{}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; void* operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_try_peek_first fixed_queue_try_peek_first; @@ -216,7 +218,7 @@ extern struct fixed_queue_try_peek_first fixed_queue_try_peek_first; struct fixed_queue_try_peek_last { void* return_value{}; std::function body{ - [this](fixed_queue_t* queue) { return return_value; }}; + [this](fixed_queue_t* /* queue */) { return return_value; }}; void* operator()(fixed_queue_t* queue) { return body(queue); }; }; extern struct fixed_queue_try_peek_last fixed_queue_try_peek_last; @@ -227,7 +229,9 @@ extern struct fixed_queue_try_peek_last fixed_queue_try_peek_last; struct fixed_queue_try_remove_from_queue { void* return_value{}; std::function body{ - [this](fixed_queue_t* queue, void* data) { return return_value; }}; + [this](fixed_queue_t* /* queue */, void* /* data */) { + return return_value; + }}; void* operator()(fixed_queue_t* queue, void* data) { return body(queue, data); }; @@ -239,7 +243,8 @@ extern struct fixed_queue_try_remove_from_queue // Params: fixed_queue_t* queue // Return: void struct fixed_queue_unregister_dequeue { - std::function body{[](fixed_queue_t* queue) {}}; + std::function body{ + [](fixed_queue_t* /* queue */) {}}; void operator()(fixed_queue_t* queue) { body(queue); }; }; extern struct fixed_queue_unregister_dequeue fixed_queue_unregister_dequeue; @@ -248,4 +253,4 @@ extern struct fixed_queue_unregister_dequeue fixed_queue_unregister_dequeue; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_osi_future.h b/system/test/mock/mock_osi_future.h index 0998b191949976353f416aadd2b615cdf0f34eab..90dd29c62755f87eb0c14882c54b0f2370f254e0 100644 --- a/system/test/mock/mock_osi_future.h +++ b/system/test/mock/mock_osi_future.h @@ -26,6 +26,7 @@ // Original included files, if any #include +#include "include/check.h" #include "osi/include/future.h" // Mocked compile conditionals, if any @@ -41,7 +42,7 @@ namespace osi_future { struct future_await { void* return_value{}; std::function body{ - [this](future_t* future) { return return_value; }}; + [this](future_t* /* future */) { return return_value; }}; void* operator()(future_t* future) { return body(future); }; }; extern struct future_await future_await; @@ -62,7 +63,7 @@ extern struct future_new future_new; struct future_new_named { future_t* return_value{0}; std::function body{ - [this](const char* name) { return return_value; }}; + [this](const char* /* name */) { return return_value; }}; future_t* operator()(const char* name) { return body(name); }; }; extern struct future_new_named future_new_named; @@ -72,7 +73,7 @@ extern struct future_new_named future_new_named; // Return: future_t* struct future_new_immediate { future_t* return_value{0}; - std::function body{[this](void* value) { + std::function body{[this](void* /* value */) { CHECK(0); return return_value; }}; @@ -85,7 +86,7 @@ extern struct future_new_immediate future_new_immediate; // Return: void struct future_ready { std::function body{ - [](future_t* future, void* value) {}}; + [](future_t* /* future */, void* /* value */) {}}; void operator()(future_t* future, void* value) { body(future, value); }; }; extern struct future_ready future_ready; diff --git a/system/test/mock/mock_osi_list.h b/system/test/mock/mock_osi_list.h index 494ef88f577a8cf6bb1c8d6be72ad1c2b38e2790..8ee1088615917662562c05ee6f5a93d35ddda3c4 100644 --- a/system/test/mock/mock_osi_list.h +++ b/system/test/mock/mock_osi_list.h @@ -42,7 +42,7 @@ namespace osi_list { struct list_append { bool return_value{false}; std::function body{ - [this](list_t* list, void* data) { return return_value; }}; + [this](list_t* /* list */, void* /* data */) { return return_value; }}; bool operator()(list_t* list, void* data) { return body(list, data); }; }; extern struct list_append list_append; @@ -53,7 +53,7 @@ extern struct list_append list_append; struct list_back { void* return_value{}; std::function body{ - [this](const list_t* list) { return return_value; }}; + [this](const list_t* /* list */) { return return_value; }}; void* operator()(const list_t* list) { return body(list); }; }; extern struct list_back list_back; @@ -64,7 +64,7 @@ extern struct list_back list_back; struct list_back_node { list_node_t* return_value{0}; std::function body{ - [this](const list_t* list) { return return_value; }}; + [this](const list_t* /* list */) { return return_value; }}; list_node_t* operator()(const list_t* list) { return body(list); }; }; extern struct list_back_node list_back_node; @@ -75,7 +75,7 @@ extern struct list_back_node list_back_node; struct list_begin { list_node_t* return_value{0}; std::function body{ - [this](const list_t* list) { return return_value; }}; + [this](const list_t* /* list */) { return return_value; }}; list_node_t* operator()(const list_t* list) { return body(list); }; }; extern struct list_begin list_begin; @@ -84,7 +84,7 @@ extern struct list_begin list_begin; // Params: list_t* list // Return: void struct list_clear { - std::function body{[](list_t* list) {}}; + std::function body{[](list_t* /* list */) {}}; void operator()(list_t* list) { body(list); }; }; extern struct list_clear list_clear; @@ -95,7 +95,9 @@ extern struct list_clear list_clear; struct list_contains { bool return_value{false}; std::function body{ - [this](const list_t* list, const void* data) { return return_value; }}; + [this](const list_t* /* list */, const void* /* data */) { + return return_value; + }}; bool operator()(const list_t* list, const void* data) { return body(list, data); }; @@ -108,7 +110,7 @@ extern struct list_contains list_contains; struct list_end { list_node_t* return_value{0}; std::function body{ - [this](const list_t* list) { return return_value; }}; + [this](const list_t* /* list */) { return return_value; }}; list_node_t* operator()(const list_t* list) { return body(list); }; }; extern struct list_end list_end; @@ -120,9 +122,8 @@ struct list_foreach { list_node_t* return_value{0}; std::function - body{[this](const list_t* list, list_iter_cb callback, void* context) { - return return_value; - }}; + body{[this](const list_t* /* list */, list_iter_cb /* callback */, + void* /* context */) { return return_value; }}; list_node_t* operator()(const list_t* list, list_iter_cb callback, void* context) { return body(list, callback, context); @@ -134,7 +135,7 @@ extern struct list_foreach list_foreach; // Params: list_t* list // Return: void struct list_free { - std::function body{[](list_t* list) {}}; + std::function body{[](list_t* /* list */) {}}; void operator()(list_t* list) { body(list); }; }; extern struct list_free list_free; @@ -145,7 +146,7 @@ extern struct list_free list_free; struct list_front { void* return_value{}; std::function body{ - [this](const list_t* list) { return return_value; }}; + [this](const list_t* /* list */) { return return_value; }}; void* operator()(const list_t* list) { return body(list); }; }; extern struct list_front list_front; @@ -156,9 +157,8 @@ extern struct list_front list_front; struct list_insert_after { bool return_value{false}; std::function body{ - [this](list_t* list, list_node_t* prev_node, void* data) { - return return_value; - }}; + [this](list_t* /* list */, list_node_t* /* prev_node */, + void* /* data */) { return return_value; }}; bool operator()(list_t* list, list_node_t* prev_node, void* data) { return body(list, prev_node, data); }; @@ -171,7 +171,7 @@ extern struct list_insert_after list_insert_after; struct list_is_empty { bool return_value{false}; std::function body{ - [this](const list_t* list) { return return_value; }}; + [this](const list_t* /* list */) { return return_value; }}; bool operator()(const list_t* list) { return body(list); }; }; extern struct list_is_empty list_is_empty; @@ -182,7 +182,7 @@ extern struct list_is_empty list_is_empty; struct list_length { size_t return_value{0}; std::function body{ - [this](const list_t* list) { return return_value; }}; + [this](const list_t* /* list */) { return return_value; }}; size_t operator()(const list_t* list) { return body(list); }; }; extern struct list_length list_length; @@ -193,7 +193,7 @@ extern struct list_length list_length; struct list_new { list_t* return_value{0}; std::function body{ - [this](list_free_cb callback) { return return_value; }}; + [this](list_free_cb /* callback */) { return return_value; }}; list_t* operator()(list_free_cb callback) { return body(callback); }; }; extern struct list_new list_new; @@ -205,7 +205,8 @@ struct list_new_internal { list_t* return_value{0}; std::function - body{[this](list_free_cb callback, const allocator_t* zeroed_allocator) { + body{[this](list_free_cb /* callback */, + const allocator_t* /* zeroed_allocator */) { return return_value; }}; list_t* operator()(list_free_cb callback, @@ -221,7 +222,7 @@ extern struct list_new_internal list_new_internal; struct list_next { list_node_t* return_value{0}; std::function body{ - [this](const list_node_t* node) { return return_value; }}; + [this](const list_node_t* /* node */) { return return_value; }}; list_node_t* operator()(const list_node_t* node) { return body(node); }; }; extern struct list_next list_next; @@ -232,7 +233,7 @@ extern struct list_next list_next; struct list_node { void* return_value{}; std::function body{ - [this](const list_node_t* node) { return return_value; }}; + [this](const list_node_t* /* node */) { return return_value; }}; void* operator()(const list_node_t* node) { return body(node); }; }; extern struct list_node list_node; @@ -243,7 +244,7 @@ extern struct list_node list_node; struct list_prepend { bool return_value{false}; std::function body{ - [this](list_t* list, void* data) { return return_value; }}; + [this](list_t* /* list */, void* /* data */) { return return_value; }}; bool operator()(list_t* list, void* data) { return body(list, data); }; }; extern struct list_prepend list_prepend; @@ -254,7 +255,7 @@ extern struct list_prepend list_prepend; struct list_remove { bool return_value{false}; std::function body{ - [this](list_t* list, void* data) { return return_value; }}; + [this](list_t* /* list */, void* /* data */) { return return_value; }}; bool operator()(list_t* list, void* data) { return body(list, data); }; }; extern struct list_remove list_remove; @@ -263,4 +264,4 @@ extern struct list_remove list_remove; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_osi_properties.cc b/system/test/mock/mock_osi_properties.cc index e5997ac2038576497ad4912b6c7e249968d6e45f..46e0f9a9715f5830d9da7ce18c951e26c67864e2 100644 --- a/system/test/mock/mock_osi_properties.cc +++ b/system/test/mock/mock_osi_properties.cc @@ -59,7 +59,7 @@ int32_t osi_property_get_int32(const char* key, int32_t default_value) { return test::mock::osi_properties::osi_property_get_int32(key, default_value); } std::vector osi_property_get_uintlist( - const char* key, std::vector default_value) { + const char* /* key */, std::vector default_value) { inc_func_call_count(__func__); return default_value; } diff --git a/system/test/mock/mock_osi_properties.h b/system/test/mock/mock_osi_properties.h index 3ef42786a82cba1095dc215610771373c026f46f..9ff364b1417864200fb21be47217419f9455b4b4 100644 --- a/system/test/mock/mock_osi_properties.h +++ b/system/test/mock/mock_osi_properties.h @@ -40,9 +40,8 @@ namespace osi_properties { struct osi_property_get { int return_value{0}; std::function - body{[this](const char* key, char* value, const char* default_value) { - return return_value; - }}; + body{[this](const char* /* key */, char* /* value */, + const char* /* default_value */) { return return_value; }}; int operator()(const char* key, char* value, const char* default_value) { return body(key, value, default_value); }; @@ -55,7 +54,9 @@ extern struct osi_property_get osi_property_get; struct osi_property_get_bool { bool return_value{false}; std::function body{ - [this](const char* key, bool default_value) { return return_value; }}; + [this](const char* /* key */, bool /* default_value */) { + return return_value; + }}; bool operator()(const char* key, bool default_value) { return body(key, default_value); }; @@ -68,7 +69,9 @@ extern struct osi_property_get_bool osi_property_get_bool; struct osi_property_get_int32 { int32_t return_value{0}; std::function body{ - [this](const char* key, int32_t default_value) { return return_value; }}; + [this](const char* /* key */, int32_t /* default_value */) { + return return_value; + }}; int32_t operator()(const char* key, int32_t default_value) { return body(key, default_value); }; @@ -81,7 +84,9 @@ extern struct osi_property_get_int32 osi_property_get_int32; struct osi_property_set { int return_value{0}; std::function body{ - [this](const char* key, const char* value) { return return_value; }}; + [this](const char* /* key */, const char* /* value */) { + return return_value; + }}; int operator()(const char* key, const char* value) { return body(key, value); }; @@ -92,4 +97,4 @@ extern struct osi_property_set osi_property_set; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_osi_ringbuffer.h b/system/test/mock/mock_osi_ringbuffer.h index 8128a2ee3ba8128cbd6f1485c66ac98edd83c0b3..09e4f64242a075461d8cd508a5d45d13dfbe46ab 100644 --- a/system/test/mock/mock_osi_ringbuffer.h +++ b/system/test/mock/mock_osi_ringbuffer.h @@ -43,7 +43,7 @@ namespace osi_ringbuffer { struct ringbuffer_available { size_t return_value{0}; std::function body{ - [this](const ringbuffer_t* rb) { return return_value; }}; + [this](const ringbuffer_t* /* rb */) { return return_value; }}; size_t operator()(const ringbuffer_t* rb) { return body(rb); }; }; extern struct ringbuffer_available ringbuffer_available; @@ -54,7 +54,9 @@ extern struct ringbuffer_available ringbuffer_available; struct ringbuffer_delete { size_t return_value{0}; std::function body{ - [this](ringbuffer_t* rb, size_t length) { return return_value; }}; + [this](ringbuffer_t* /* rb */, size_t /* length */) { + return return_value; + }}; size_t operator()(ringbuffer_t* rb, size_t length) { return body(rb, length); }; @@ -65,7 +67,7 @@ extern struct ringbuffer_delete ringbuffer_delete; // Params: ringbuffer_t* rb // Return: void struct ringbuffer_free { - std::function body{[](ringbuffer_t* rb) {}}; + std::function body{[](ringbuffer_t* /* rb */) {}}; void operator()(ringbuffer_t* rb) { body(rb); }; }; extern struct ringbuffer_free ringbuffer_free; @@ -76,7 +78,7 @@ extern struct ringbuffer_free ringbuffer_free; struct ringbuffer_init { ringbuffer_t* return_value{0}; std::function body{ - [this](const size_t size) { return return_value; }}; + [this](const size_t /* size */) { return return_value; }}; ringbuffer_t* operator()(const size_t size) { return body(size); }; }; extern struct ringbuffer_init ringbuffer_init; @@ -87,9 +89,8 @@ extern struct ringbuffer_init ringbuffer_init; struct ringbuffer_insert { size_t return_value{0}; std::function body{ - [this](ringbuffer_t* rb, const uint8_t* p, size_t length) { - return return_value; - }}; + [this](ringbuffer_t* /* rb */, const uint8_t* /* p */, + size_t /* length */) { return return_value; }}; size_t operator()(ringbuffer_t* rb, const uint8_t* p, size_t length) { return body(rb, p, length); }; @@ -103,8 +104,9 @@ struct ringbuffer_peek { size_t return_value{0}; std::function - body{[this](const ringbuffer_t* rb, off_t offset, uint8_t* p, - size_t length) { return return_value; }}; + body{[this](const ringbuffer_t* /* rb */, off_t /* offset */, + uint8_t* /* p */, + size_t /* length */) { return return_value; }}; size_t operator()(const ringbuffer_t* rb, off_t offset, uint8_t* p, size_t length) { return body(rb, offset, p, length); @@ -118,7 +120,7 @@ extern struct ringbuffer_peek ringbuffer_peek; struct ringbuffer_pop { size_t return_value{0}; std::function body{ - [this](ringbuffer_t* rb, uint8_t* p, size_t length) { + [this](ringbuffer_t* /* rb */, uint8_t* /* p */, size_t /* length */) { return return_value; }}; size_t operator()(ringbuffer_t* rb, uint8_t* p, size_t length) { @@ -133,7 +135,7 @@ extern struct ringbuffer_pop ringbuffer_pop; struct ringbuffer_size { size_t return_value{0}; std::function body{ - [this](const ringbuffer_t* rb) { return return_value; }}; + [this](const ringbuffer_t* /* rb */) { return return_value; }}; size_t operator()(const ringbuffer_t* rb) { return body(rb); }; }; extern struct ringbuffer_size ringbuffer_size; @@ -142,4 +144,4 @@ extern struct ringbuffer_size ringbuffer_size; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_osi_socket.cc b/system/test/mock/mock_osi_socket.cc index 353faf06bf121e31f64d0501c4bc04d46ef06ad7..be411f2f9a350f14901cad8a6ff81f8fde0a0409 100644 --- a/system/test/mock/mock_osi_socket.cc +++ b/system/test/mock/mock_osi_socket.cc @@ -99,3 +99,8 @@ ssize_t socket_write_and_transfer_fd(const socket_t* socket, const void* buf, } // Mocked functions complete // END mockcify generation +int osi_socket_local_server_bind(int /* s */, const char* /* name */, + int /* namespaceId */) { + inc_func_call_count(__func__); + return 0; +} diff --git a/system/test/mock/mock_osi_socket.h b/system/test/mock/mock_osi_socket.h index f966e87d637fcb43bb59cce1da861074b9917c90..6c86bfeb9084327b9b7223c43afbea5fd8e31c64 100644 --- a/system/test/mock/mock_osi_socket.h +++ b/system/test/mock/mock_osi_socket.h @@ -40,7 +40,7 @@ namespace osi_socket { struct socket_accept { socket_t* return_value{0}; std::function body{ - [this](const socket_t* socket) { return return_value; }}; + [this](const socket_t* /* socket */) { return return_value; }}; socket_t* operator()(const socket_t* socket) { return body(socket); }; }; extern struct socket_accept socket_accept; @@ -51,7 +51,7 @@ extern struct socket_accept socket_accept; struct socket_bytes_available { ssize_t return_value{0}; std::function body{ - [this](const socket_t* socket) { return return_value; }}; + [this](const socket_t* /* socket */) { return return_value; }}; ssize_t operator()(const socket_t* socket) { return body(socket); }; }; extern struct socket_bytes_available socket_bytes_available; @@ -60,7 +60,7 @@ extern struct socket_bytes_available socket_bytes_available; // Params: socket_t* socket // Return: void struct socket_free { - std::function body{[](socket_t* socket) {}}; + std::function body{[](socket_t* /* socket */) {}}; void operator()(socket_t* socket) { body(socket); }; }; extern struct socket_free socket_free; @@ -71,7 +71,9 @@ extern struct socket_free socket_free; struct socket_listen { bool return_value{false}; std::function body{ - [this](const socket_t* socket, port_t port) { return return_value; }}; + [this](const socket_t* /* socket */, port_t /* port */) { + return return_value; + }}; bool operator()(const socket_t* socket, port_t port) { return body(socket, port); }; @@ -94,7 +96,7 @@ extern struct socket_new socket_new; struct socket_new_from_fd { socket_t* return_value{0}; std::function body{ - [this](int fd) { return return_value; }}; + [this](int /* fd */) { return return_value; }}; socket_t* operator()(int fd) { return body(fd); }; }; extern struct socket_new_from_fd socket_new_from_fd; @@ -105,9 +107,8 @@ extern struct socket_new_from_fd socket_new_from_fd; struct socket_read { ssize_t return_value{0}; std::function body{ - [this](const socket_t* socket, void* buf, size_t count) { - return return_value; - }}; + [this](const socket_t* /* socket */, void* /* buf */, + size_t /* count */) { return return_value; }}; ssize_t operator()(const socket_t* socket, void* buf, size_t count) { return body(socket, buf, count); }; @@ -120,8 +121,9 @@ extern struct socket_read socket_read; struct socket_register { std::function - body{[](socket_t* socket, reactor_t* reactor, void* context, - socket_cb read_cb, socket_cb write_cb) {}}; + body{[](socket_t* /* socket */, reactor_t* /* reactor */, + void* /* context */, socket_cb /* read_cb */, + socket_cb /* write_cb */) {}}; void operator()(socket_t* socket, reactor_t* reactor, void* context, socket_cb read_cb, socket_cb write_cb) { body(socket, reactor, context, read_cb, write_cb); @@ -133,7 +135,7 @@ extern struct socket_register socket_register; // Params: socket_t* socket // Return: void struct socket_unregister { - std::function body{[](socket_t* socket) {}}; + std::function body{[](socket_t* /* socket */) {}}; void operator()(socket_t* socket) { body(socket); }; }; extern struct socket_unregister socket_unregister; @@ -144,9 +146,8 @@ extern struct socket_unregister socket_unregister; struct socket_write { ssize_t return_value{0}; std::function - body{[this](const socket_t* socket, const void* buf, size_t count) { - return return_value; - }}; + body{[this](const socket_t* /* socket */, const void* /* buf */, + size_t /* count */) { return return_value; }}; ssize_t operator()(const socket_t* socket, const void* buf, size_t count) { return body(socket, buf, count); }; @@ -160,8 +161,8 @@ struct socket_write_and_transfer_fd { ssize_t return_value{0}; std::function - body{[this](const socket_t* socket, const void* buf, size_t count, - int fd) { return return_value; }}; + body{[this](const socket_t* /* socket */, const void* /* buf */, + size_t /* count */, int /* fd */) { return return_value; }}; ssize_t operator()(const socket_t* socket, const void* buf, size_t count, int fd) { return body(socket, buf, count, fd); @@ -173,4 +174,4 @@ extern struct socket_write_and_transfer_fd socket_write_and_transfer_fd; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_osi_stack_power_telemetry.cc b/system/test/mock/mock_osi_stack_power_telemetry.cc index c7d145b19b8ff47901be2017a4d5aead455e6caf..850dd62c094faf2599d659298821d7e9afb3062b 100644 --- a/system/test/mock/mock_osi_stack_power_telemetry.cc +++ b/system/test/mock/mock_osi_stack_power_telemetry.cc @@ -59,42 +59,41 @@ void power_telemetry::PowerTelemetry::LogScanStarted() { inc_func_call_count(__func__); } void power_telemetry::PowerTelemetry::LogChannelConnected( - uint16_t psm, int32_t src_id, int32_t dst_id, const RawAddress& bd_addr) { + uint16_t /* psm */, int32_t /* src_id */, int32_t /* dst_id */, + const RawAddress& /* bd_addr */) { inc_func_call_count(__func__); } void power_telemetry::PowerTelemetry::LogChannelDisconnected( - uint16_t psm, int32_t src_id, int32_t dst_id, const RawAddress& bd_addr) { + uint16_t /* psm */, int32_t /* src_id */, int32_t /* dst_id */, + const RawAddress& /* bd_addr */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogTxBytes(uint16_t psm, int32_t src_id, - int32_t dst_id, - const RawAddress& bd_addr, - int32_t num_bytes) { +void power_telemetry::PowerTelemetry::LogTxBytes( + uint16_t /* psm */, int32_t /* src_id */, int32_t /* dst_id */, + const RawAddress& /* bd_addr */, int32_t /* num_bytes */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogRxBytes(uint16_t psm, int32_t src_id, - int32_t dst_id, - const RawAddress& bd_addr, - int32_t num_bytes) { +void power_telemetry::PowerTelemetry::LogRxBytes( + uint16_t /* psm */, int32_t /* src_id */, int32_t /* dst_id */, + const RawAddress& /* bd_addr */, int32_t /* num_bytes */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::Dumpsys(int32_t fd) { +void power_telemetry::PowerTelemetry::Dumpsys(int32_t /* fd */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogRxAclPktData(uint16_t len) { +void power_telemetry::PowerTelemetry::LogRxAclPktData(uint16_t /* len */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogTxAclPktData(uint16_t len) { +void power_telemetry::PowerTelemetry::LogTxAclPktData(uint16_t /* len */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogLinkDetails(uint16_t handle, - const RawAddress& bdaddr, - bool isConnected, - bool is_acl_link) { +void power_telemetry::PowerTelemetry::LogLinkDetails( + uint16_t /* handle */, const RawAddress& /* bdaddr */, + bool /* isConnected */, bool /* is_acl_link */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogAclTxPowerLevel(uint16_t handle, - uint8_t txPower) { +void power_telemetry::PowerTelemetry::LogAclTxPowerLevel( + uint16_t /* handle */, uint8_t /* txPower */) { inc_func_call_count(__func__); } void power_telemetry::PowerTelemetry::LogInqScanStarted() { @@ -115,21 +114,21 @@ void power_telemetry::PowerTelemetry::LogHciCmdDetail() { void power_telemetry::PowerTelemetry::LogHciEvtDetail() { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogTxPower(void* res) { +void power_telemetry::PowerTelemetry::LogTxPower(void* /* res */) { inc_func_call_count(__func__); } void power_telemetry::PowerTelemetry::LogTrafficData() { inc_func_call_count(__func__); } void power_telemetry::PowerTelemetry::LogSniffStarted( - uint16_t handle, const RawAddress& bdaddr) { + uint16_t /* handle */, const RawAddress& /* bdaddr */) { inc_func_call_count(__func__); } void power_telemetry::PowerTelemetry::LogSniffStopped( - uint16_t handle, const RawAddress& bdaddr) { + uint16_t /* handle */, const RawAddress& /* bdaddr */) { inc_func_call_count(__func__); } -void power_telemetry::PowerTelemetry::LogBleScan(uint16_t num_resps) { +void power_telemetry::PowerTelemetry::LogBleScan(uint16_t /* num_resps */) { inc_func_call_count(__func__); } power_telemetry::PowerTelemetry& power_telemetry::GetInstance() { diff --git a/system/test/mock/mock_osi_thread.h b/system/test/mock/mock_osi_thread.h index 6ff2bbdd79ac20eb91aaaa6bf426308220496fe6..967e12e21f2bf6d480259bcfbfa61ac0cf228259 100644 --- a/system/test/mock/mock_osi_thread.h +++ b/system/test/mock/mock_osi_thread.h @@ -39,7 +39,7 @@ namespace osi_thread { // Params: thread_t* thread // Return: void struct thread_free { - std::function body{[](thread_t* thread) {}}; + std::function body{[](thread_t* /* thread */) {}}; void operator()(thread_t* thread) { body(thread); }; }; extern struct thread_free thread_free; @@ -50,7 +50,7 @@ extern struct thread_free thread_free; struct thread_get_reactor { reactor_t* return_value{0}; std::function body{ - [this](const thread_t* thread) { return return_value; }}; + [this](const thread_t* /* thread */) { return return_value; }}; reactor_t* operator()(const thread_t* thread) { return body(thread); }; }; extern struct thread_get_reactor thread_get_reactor; @@ -61,7 +61,7 @@ extern struct thread_get_reactor thread_get_reactor; struct thread_is_self { bool return_value{false}; std::function body{ - [this](const thread_t* thread) { return return_value; }}; + [this](const thread_t* /* thread */) { return return_value; }}; bool operator()(const thread_t* thread) { return body(thread); }; }; extern struct thread_is_self thread_is_self; @@ -70,7 +70,7 @@ extern struct thread_is_self thread_is_self; // Params: thread_t* thread // Return: void struct thread_join { - std::function body{[](thread_t* thread) {}}; + std::function body{[](thread_t* /* thread */) {}}; void operator()(thread_t* thread) { body(thread); }; }; extern struct thread_join thread_join; @@ -81,7 +81,7 @@ extern struct thread_join thread_join; struct thread_name { const char* return_value{0}; std::function body{ - [this](const thread_t* thread) { return return_value; }}; + [this](const thread_t* /* thread */) { return return_value; }}; const char* operator()(const thread_t* thread) { return body(thread); }; }; extern struct thread_name thread_name; @@ -92,7 +92,7 @@ extern struct thread_name thread_name; struct thread_new { thread_t* return_value{0}; std::function body{ - [this](const char* name) { return return_value; }}; + [this](const char* /* name */) { return return_value; }}; thread_t* operator()(const char* name) { return body(name); }; }; extern struct thread_new thread_new; @@ -103,7 +103,7 @@ extern struct thread_new thread_new; struct thread_new_sized { thread_t* return_value{0}; std::function body{ - [this](const char* name, size_t work_queue_capacity) { + [this](const char* /* name */, size_t /* work_queue_capacity */) { return return_value; }}; thread_t* operator()(const char* name, size_t work_queue_capacity) { @@ -118,9 +118,8 @@ extern struct thread_new_sized thread_new_sized; struct thread_post { bool return_value{false}; std::function body{ - [this](thread_t* thread, thread_fn func, void* context) { - return return_value; - }}; + [this](thread_t* /* thread */, thread_fn /* func */, + void* /* context */) { return return_value; }}; bool operator()(thread_t* thread, thread_fn func, void* context) { return body(thread, func, context); }; @@ -133,7 +132,9 @@ extern struct thread_post thread_post; struct thread_set_priority { bool return_value{false}; std::function body{ - [this](thread_t* thread, int priority) { return return_value; }}; + [this](thread_t* /* thread */, int /* priority */) { + return return_value; + }}; bool operator()(thread_t* thread, int priority) { return body(thread, priority); }; @@ -146,7 +147,9 @@ extern struct thread_set_priority thread_set_priority; struct thread_set_rt_priority { bool return_value{false}; std::function body{ - [this](thread_t* thread, int priority) { return return_value; }}; + [this](thread_t* /* thread */, int /* priority */) { + return return_value; + }}; bool operator()(thread_t* thread, int priority) { return body(thread, priority); }; @@ -157,7 +160,7 @@ extern struct thread_set_rt_priority thread_set_rt_priority; // Params: thread_t* thread // Return: void struct thread_stop { - std::function body{[](thread_t* thread) {}}; + std::function body{[](thread_t* /* thread */) {}}; void operator()(thread_t* thread) { body(thread); }; }; extern struct thread_stop thread_stop; @@ -166,4 +169,4 @@ extern struct thread_stop thread_stop; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_osi_thread_scheduler.h b/system/test/mock/mock_osi_thread_scheduler.h index d5fdd79afdbd1cbef5fc3e14c19c383116e3fc56..c90ee85e00e44be36a8b70a532fb4d48b9261ebb 100644 --- a/system/test/mock/mock_osi_thread_scheduler.h +++ b/system/test/mock/mock_osi_thread_scheduler.h @@ -40,7 +40,7 @@ namespace osi_thread_scheduler { struct thread_scheduler_enable_real_time { bool return_value{false}; std::function body{ - [this](pid_t linux_tid) { return return_value; }}; + [this](pid_t /* linux_tid */) { return return_value; }}; bool operator()(pid_t linux_tid) { return body(linux_tid); }; }; extern struct thread_scheduler_enable_real_time @@ -52,7 +52,7 @@ extern struct thread_scheduler_enable_real_time struct thread_scheduler_get_priority_range { bool return_value{false}; std::function body{ - [this](int& min, int& max) { return return_value; }}; + [this](int& /* min */, int& /* max */) { return return_value; }}; bool operator()(int& min, int& max) { return body(min, max); }; }; extern struct thread_scheduler_get_priority_range diff --git a/system/test/mock/mock_osi_wakelock.h b/system/test/mock/mock_osi_wakelock.h index 6e14e65aa0ca558fadf3df3b13b6b357e167a1af..2a6b664b661ab8f2df960ca1463f2cae4497ffda 100644 --- a/system/test/mock/mock_osi_wakelock.h +++ b/system/test/mock/mock_osi_wakelock.h @@ -58,7 +58,7 @@ extern struct wakelock_cleanup wakelock_cleanup; // Params: int fd // Return: void struct wakelock_debug_dump { - std::function body{[](int fd) {}}; + std::function body{[](int /* fd */) {}}; void operator()(int fd) { body(fd); }; }; extern struct wakelock_debug_dump wakelock_debug_dump; @@ -78,7 +78,7 @@ extern struct wakelock_release wakelock_release; // Return: void struct wakelock_set_os_callouts { std::function body{ - [](bt_os_callouts_t* callouts) {}}; + [](bt_os_callouts_t* /* callouts */) {}}; void operator()(bt_os_callouts_t* callouts) { body(callouts); }; }; extern struct wakelock_set_os_callouts wakelock_set_os_callouts; @@ -88,7 +88,7 @@ extern struct wakelock_set_os_callouts wakelock_set_os_callouts; // Return: void struct wakelock_set_paths { std::function body{ - [](const char* lock_path, const char* unlock_path) {}}; + [](const char* /* lock_path */, const char* /* unlock_path */) {}}; void operator()(const char* lock_path, const char* unlock_path) { body(lock_path, unlock_path); }; @@ -99,4 +99,4 @@ extern struct wakelock_set_paths wakelock_set_paths; } // namespace mock } // namespace test -// END mockcify generation \ No newline at end of file +// END mockcify generation diff --git a/system/test/mock/mock_stack_a2dp_codec_config.cc b/system/test/mock/mock_stack_a2dp_codec_config.cc index 129da3a07d729777e2a3aa14e0059a02aae9f9f5..0d2f73e10037105328e30b2be1061056e0b85e49 100644 --- a/system/test/mock/mock_stack_a2dp_codec_config.cc +++ b/system/test/mock/mock_stack_a2dp_codec_config.cc @@ -44,10 +44,16 @@ A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig( inc_func_call_count(__func__); return nullptr; } +A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig( + btav_a2dp_codec_index_t /* codec_index */) { + inc_func_call_count(__func__); + return nullptr; +} A2dpCodecConfig::A2dpCodecConfig(btav_a2dp_codec_index_t codec_index, - const std::string& name, + uint64_t codec_id, const std::string& name, btav_a2dp_codec_priority_t codec_priority) : codec_index_(codec_index), + codec_id_(codec_id), name_(name), default_codec_priority_(codec_priority) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_stack_acl.cc b/system/test/mock/mock_stack_acl.cc index 5ca96ee704f3c082f5240c46ce8603c1b9c8e327..83df034d1e59e02806fbd72f2d3001ad3d9a1d63 100644 --- a/system/test/mock/mock_stack_acl.cc +++ b/system/test/mock/mock_stack_acl.cc @@ -26,10 +26,10 @@ #include #include +#include "hci/class_of_device.h" #include "stack/include/acl_client_callbacks.h" #include "stack/include/bt_hdr.h" #include "test/common/mock_functions.h" -#include "types/class_of_device.h" #include "types/raw_address.h" // Mocked compile conditionals, if any @@ -40,8 +40,6 @@ namespace mock { namespace stack_acl { // Function state capture and return values, if needed -struct ACL_SupportTransparentSynchronousData - ACL_SupportTransparentSynchronousData; struct BTM_BLE_IS_RESOLVE_BDA BTM_BLE_IS_RESOLVE_BDA; struct BTM_IsAclConnectionUp BTM_IsAclConnectionUp; struct BTM_IsAclConnectionUpAndHandleValid BTM_IsAclConnectionUpAndHandleValid; @@ -118,14 +116,12 @@ struct btm_acl_connected btm_acl_connected; struct btm_acl_created btm_acl_created; struct btm_acl_device_down btm_acl_device_down; struct btm_acl_disconnected btm_acl_disconnected; -struct btm_acl_iso_disconnected btm_acl_iso_disconnected; struct btm_acl_encrypt_change btm_acl_encrypt_change; struct btm_acl_notif_conn_collision btm_acl_notif_conn_collision; struct btm_acl_process_sca_cmpl_pkt btm_acl_process_sca_cmpl_pkt; struct btm_acl_removed btm_acl_removed; struct btm_acl_role_changed btm_acl_role_changed; struct btm_acl_update_conn_addr btm_acl_update_conn_addr; -struct btm_acl_update_inquiry_status btm_acl_update_inquiry_status; struct btm_ble_refresh_local_resolvable_private_addr btm_ble_refresh_local_resolvable_private_addr; struct btm_cont_rswitch_from_handle btm_cont_rswitch_from_handle; @@ -166,10 +162,6 @@ struct BTM_unblock_role_switch_and_sniff_mode_for } // namespace test // Mocked functions, if any -bool ACL_SupportTransparentSynchronousData(const RawAddress& bd_addr) { - inc_func_call_count(__func__); - return test::mock::stack_acl::ACL_SupportTransparentSynchronousData(bd_addr); -} bool BTM_BLE_IS_RESOLVE_BDA(const RawAddress& x) { inc_func_call_count(__func__); return test::mock::stack_acl::BTM_BLE_IS_RESOLVE_BDA(x); @@ -499,10 +491,6 @@ void btm_acl_disconnected(tHCI_STATUS status, uint16_t handle, inc_func_call_count(__func__); test::mock::stack_acl::btm_acl_disconnected(status, handle, reason); } -void btm_acl_iso_disconnected(uint16_t handle, tHCI_REASON reason) { - inc_func_call_count(__func__); - test::mock::stack_acl::btm_acl_iso_disconnected(handle, reason); -} void btm_acl_encrypt_change(uint16_t handle, uint8_t status, uint8_t encr_enable) { inc_func_call_count(__func__); @@ -529,10 +517,6 @@ void btm_acl_update_conn_addr(uint16_t handle, const RawAddress& address) { inc_func_call_count(__func__); test::mock::stack_acl::btm_acl_update_conn_addr(handle, address); } -void btm_acl_update_inquiry_status(uint8_t status) { - inc_func_call_count(__func__); - test::mock::stack_acl::btm_acl_update_inquiry_status(status); -} void btm_ble_refresh_local_resolvable_private_addr( const RawAddress& pseudo_addr, const RawAddress& local_rpa) { inc_func_call_count(__func__); @@ -644,7 +628,7 @@ void hci_btm_set_link_supervision_timeout(tACL_CONN& link, uint16_t timeout) { test::mock::stack_acl::hci_btm_set_link_supervision_timeout(link, timeout); } void btm_connection_request(const RawAddress& bda, - const bluetooth::types::ClassOfDevice& cod) { + const bluetooth::hci::ClassOfDevice& cod) { test::mock::stack_acl::btm_connection_request(bda, cod); } void on_acl_br_edr_connected(const RawAddress& bda, uint16_t handle, diff --git a/system/test/mock/mock_stack_acl.h b/system/test/mock/mock_stack_acl.h index 62ae3cdd751eb896e6de918c18947580f10abc0f..57a4563767e3005732491257e848e2f5d7b65cc7 100644 --- a/system/test/mock/mock_stack_acl.h +++ b/system/test/mock/mock_stack_acl.h @@ -27,11 +27,11 @@ // Original included files, if any #include "device/include/controller.h" +#include "hci/class_of_device.h" #include "stack/acl/acl.h" #include "stack/btm/security_device_record.h" #include "stack/include/acl_client_callbacks.h" #include "stack/include/bt_hdr.h" -#include "types/class_of_device.h" #include "types/raw_address.h" // Mocked compile conditionals, if any @@ -39,17 +39,6 @@ namespace test { namespace mock { namespace stack_acl { -// Shared state between mocked functions and tests -// Name: ACL_SupportTransparentSynchronousData -// Params: const RawAddress& bd_addr -// Returns: bool -struct ACL_SupportTransparentSynchronousData { - std::function body{ - [](const RawAddress& /* bd_addr */) { return false; }}; - bool operator()(const RawAddress& bd_addr) { return body(bd_addr); }; -}; -extern struct ACL_SupportTransparentSynchronousData - ACL_SupportTransparentSynchronousData; // Name: BTM_BLE_IS_RESOLVE_BDA // Params: const RawAddress& x // Returns: bool @@ -790,15 +779,15 @@ struct btm_acl_connected { }; extern struct btm_acl_connected btm_acl_connected; // Name: btm_connection_request -// Params: const RawAddress& bda, const bluetooth::types::ClassOfDevice& cod +// Params: const RawAddress& bda, const bluetooth::hci::ClassOfDevice& cod // Returns: void struct btm_connection_request { std::function + const bluetooth::hci::ClassOfDevice& cod)> body{[](const RawAddress& /* bda */, - const bluetooth::types::ClassOfDevice& /* cod */) { ; }}; + const bluetooth::hci::ClassOfDevice& /* cod */) { ; }}; void operator()(const RawAddress& bda, - const bluetooth::types::ClassOfDevice& cod) { + const bluetooth::hci::ClassOfDevice& cod) { body(bda, cod); }; }; @@ -837,17 +826,6 @@ struct btm_acl_disconnected { }; }; extern struct btm_acl_disconnected btm_acl_disconnected; -// Name: btm_acl_iso_disconnected -// Params: uint16_t handle, tHCI_REASON reason -// Returns: void -struct btm_acl_iso_disconnected { - std::function body{ - [](uint16_t /* handle */, tHCI_REASON /* reason */) { ; }}; - void operator()(uint16_t handle, tHCI_REASON reason) { - body(handle, reason); - }; -}; -extern struct btm_acl_iso_disconnected btm_acl_iso_disconnected; // Name: btm_acl_encrypt_change // Params: uint16_t handle, uint8_t status, uint8_t encr_enable // Returns: void @@ -911,14 +889,6 @@ struct btm_acl_update_conn_addr { }; }; extern struct btm_acl_update_conn_addr btm_acl_update_conn_addr; -// Name: btm_acl_update_inquiry_status -// Params: uint8_t status -// Returns: void -struct btm_acl_update_inquiry_status { - std::function body{[](uint8_t /* status */) { ; }}; - void operator()(uint8_t status) { body(status); }; -}; -extern struct btm_acl_update_inquiry_status btm_acl_update_inquiry_status; // Name: btm_ble_refresh_local_resolvable_private_addr // Params: const RawAddress& pseudo_addr, const RawAddress& local_rpa // Returns: void 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 deleted file mode 100644 index 20bb590cac1607fd7e24a50851fcbff885996cb4..0000000000000000000000000000000000000000 --- a/system/test/mock/mock_stack_acl_btm_ble_connection_establishment.h +++ /dev/null @@ -1,51 +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. - */ - -/* - * Generated mock file from original source file - * Functions generated:6 - * - * mockcify.pl ver 0.2 - */ - -#include - -// Original included files, if any - -#include "stack/include/hci_error_code.h" -#include "types/ble_address_with_type.h" -#include "types/raw_address.h" - -// Mocked compile conditionals, if any -namespace test { -namespace mock { -namespace stack_acl_btm_ble_connection_establishment { - -// Shared state between mocked functions and tests -// Name: btm_ble_create_ll_conn_complete -// Params: tHCI_STATUS status -// Returns: void -struct btm_ble_create_ll_conn_complete { - std::function body{[](tHCI_STATUS /* status */) {}}; - void operator()(tHCI_STATUS status) { body(status); }; -}; -extern struct btm_ble_create_ll_conn_complete btm_ble_create_ll_conn_complete; - -} // namespace stack_acl_btm_ble_connection_establishment -} // namespace mock -} // namespace test - -// END mockcify generation diff --git a/system/test/mock/mock_stack_acl_btm_pm.cc b/system/test/mock/mock_stack_acl_btm_pm.cc index 99f83442b1d4075d3b3f62c856e7480119b0da64..abbc88e166f87d9be1cbc2ae5e7b4fdf625aebc8 100644 --- a/system/test/mock/mock_stack_acl_btm_pm.cc +++ b/system/test/mock/mock_stack_acl_btm_pm.cc @@ -41,6 +41,22 @@ tBTM_CONTRL_STATE BTM_PM_ReadControllerState(void) { inc_func_call_count(__func__); return BTM_CONTRL_UNKNOWN; } +uint8_t BTM_PM_ReadSniffLinkCount(void) { + inc_func_call_count(__func__); + return 0; +} +uint8_t BTM_PM_ReadBleLinkCount(void) { + inc_func_call_count(__func__); + return 0; +} +bool BTM_PM_DeviceInScanState(void) { + inc_func_call_count(__func__); + return false; +} +uint32_t BTM_PM_ReadBleScanDutyCycle(void) { + inc_func_call_count(__func__); + return 0; +} tBTM_STATUS BTM_PmRegister(uint8_t /* mask */, uint8_t* /* p_pm_id */, tBTM_PM_STATUS_CBACK* /* p_cb */) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_stack_bnep_api.cc b/system/test/mock/mock_stack_bnep_api.cc index 041e67a3d94ebe6900758c493f0b64ab09d075ea..242debdc2988036928ff911a37997e78ddf327c1 100644 --- a/system/test/mock/mock_stack_bnep_api.cc +++ b/system/test/mock/mock_stack_bnep_api.cc @@ -61,18 +61,18 @@ tBNEP_RESULT BNEP_SetProtocolFilters(uint16_t /* handle */, return 0; } tBNEP_RESULT BNEP_Write(uint16_t /* handle */, - const RawAddress& /* p_dest_addr */, + const RawAddress& /* dest_addr */, uint8_t* /* p_data */, uint16_t /* len */, uint16_t /* protocol */, - const RawAddress* /* p_src_addr */, + const RawAddress& /* src_addr */, bool /* fw_ext_present */) { inc_func_call_count(__func__); return 0; } tBNEP_RESULT BNEP_WriteBuf(uint16_t /* handle */, - const RawAddress& /* p_dest_addr */, + const RawAddress& /* dest_addr */, BT_HDR* /* p_buf */, uint16_t /* protocol */, - const RawAddress* /* p_src_addr */, + const RawAddress& /* src_addr */, bool /* fw_ext_present */) { inc_func_call_count(__func__); return 0; diff --git a/system/test/mock/mock_stack_btm_ble_addr.h b/system/test/mock/mock_stack_btm_ble_addr.h index dace61b37ea689c05c0fdc71552eb3a0895d5d1e..d30ebcbef53a359057626e170766fe4aae02e9c7 100644 --- a/system/test/mock/mock_stack_btm_ble_addr.h +++ b/system/test/mock/mock_stack_btm_ble_addr.h @@ -21,7 +21,8 @@ * mockcify.pl ver 0.2 */ -#include +#include + #include // Original included files, if any diff --git a/system/test/mock/mock_stack_btm_ble_batchscan.cc b/system/test/mock/mock_stack_btm_ble_batchscan.cc deleted file mode 100644 index 8365f97bec5288b0b2239e3ae5a4704cdaadde16..0000000000000000000000000000000000000000 --- a/system/test/mock/mock_stack_btm_ble_batchscan.cc +++ /dev/null @@ -1,55 +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. - */ - -/* - * Generated mock file from original source file - * Functions generated:7 - */ - -#include -#include - -#include "btm_ble_api.h" -#include "test/common/mock_functions.h" - -void BTM_BleDisableBatchScan(base::Callback /* cb */) { - inc_func_call_count(__func__); -} -void BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE /* scan_mode */, - uint32_t /* scan_interval */, - uint32_t /* scan_window */, - tBLE_ADDR_TYPE /* addr_type */, - tBTM_BLE_DISCARD_RULE /* discard_rule */, - base::Callback /* cb */) { - inc_func_call_count(__func__); -} -void BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE /* scan_mode */, - tBTM_BLE_SCAN_REP_CBACK /* cb */) { - inc_func_call_count(__func__); -} -void BTM_BleSetStorageConfig(uint8_t /* batch_scan_full_max */, - uint8_t /* batch_scan_trunc_max */, - uint8_t /* batch_scan_notify_threshold */, - base::Callback /* cb */, - tBTM_BLE_SCAN_THRESHOLD_CBACK* /* p_thres_cback */, - tBTM_BLE_REF_VALUE /* ref_value */) { - inc_func_call_count(__func__); -} -void BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK* /* p_track_cback */, - tBTM_BLE_REF_VALUE /* ref_value */) { - inc_func_call_count(__func__); -} -void btm_ble_batchscan_init(void) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_stack_btm_ble_bgconn.cc b/system/test/mock/mock_stack_btm_ble_bgconn.cc index d3561a4f9adcf0b6449939b488e685de5b8c547d..bec5e59efbc198a8038ee5a775e2c7c2cd8309c1 100644 --- a/system/test/mock/mock_stack_btm_ble_bgconn.cc +++ b/system/test/mock/mock_stack_btm_ble_bgconn.cc @@ -37,8 +37,6 @@ namespace stack_btm_ble_bgconn { // Function state capture and return values, if needed struct btm_update_scanner_filter_policy btm_update_scanner_filter_policy; -struct btm_ble_suspend_bg_conn btm_ble_suspend_bg_conn; -struct btm_ble_resume_bg_conn btm_ble_resume_bg_conn; struct BTM_SetLeConnectionModeToFast BTM_SetLeConnectionModeToFast; struct BTM_SetLeConnectionModeToSlow BTM_SetLeConnectionModeToSlow; struct BTM_AcceptlistAdd BTM_AcceptlistAdd; @@ -55,14 +53,6 @@ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) { test::mock::stack_btm_ble_bgconn::btm_update_scanner_filter_policy( scan_policy); } -bool btm_ble_suspend_bg_conn(void) { - inc_func_call_count(__func__); - return test::mock::stack_btm_ble_bgconn::btm_ble_suspend_bg_conn(); -} -bool btm_ble_resume_bg_conn(void) { - inc_func_call_count(__func__); - return test::mock::stack_btm_ble_bgconn::btm_ble_resume_bg_conn(); -} bool BTM_SetLeConnectionModeToFast() { inc_func_call_count(__func__); return test::mock::stack_btm_ble_bgconn::BTM_SetLeConnectionModeToFast(); diff --git a/system/test/mock/mock_stack_btm_ble_bgconn.h b/system/test/mock/mock_stack_btm_ble_bgconn.h index 66c488bbbc97f57bf3f64e7644e583835613c66a..08de0bcc2a22f3ff03a9b4ad8fbdfbde68ffb2ee 100644 --- a/system/test/mock/mock_stack_btm_ble_bgconn.h +++ b/system/test/mock/mock_stack_btm_ble_bgconn.h @@ -43,23 +43,6 @@ struct btm_update_scanner_filter_policy { void operator()(tBTM_BLE_SFP scan_policy) { body(scan_policy); }; }; extern struct btm_update_scanner_filter_policy btm_update_scanner_filter_policy; -// Name: btm_ble_suspend_bg_conn -// Params: void -// Returns: bool -struct btm_ble_suspend_bg_conn { - std::function body{[](void) { return false; }}; - bool operator()(void) { return body(); }; -}; -extern struct btm_ble_suspend_bg_conn btm_ble_suspend_bg_conn; -// Name: btm_ble_resume_bg_conn -// Params: void -// Returns: bool -struct btm_ble_resume_bg_conn { - std::function body{[](void) { return false; }}; - bool operator()(void) { return body(); }; -}; -extern struct btm_ble_resume_bg_conn btm_ble_resume_bg_conn; - // Name: BTM_SetLeConnectionModeToFast // Params: // Returns: bool diff --git a/system/test/mock/mock_stack_btm_ble_gap.cc b/system/test/mock/mock_stack_btm_ble_gap.cc index 23c22b4e4223c92b74d8a8bac2d21b00fa0354de..808888b906583167707a336c7ea4309281315a14 100644 --- a/system/test/mock/mock_stack_btm_ble_gap.cc +++ b/system/test/mock/mock_stack_btm_ble_gap.cc @@ -27,7 +27,7 @@ #include "stack/btm/btm_ble_int.h" #include "stack/btm/btm_ble_int_types.h" -#include "stack/btm/btm_dev.h" +#include "stack/include/bt_dev_class.h" #include "stack/include/btm_api_types.h" #include "stack/include/hci_error_code.h" #include "test/common/mock_functions.h" @@ -138,19 +138,15 @@ void btm_ble_increment_link_topology_mask(uint8_t /* link_role */) { inc_func_call_count(__func__); } void btm_ble_init(void) { inc_func_call_count(__func__); } -bool btm_ble_get_appearance_as_cod(std::vector const& /* data */, - DEV_CLASS /* dev_class */) { +DEV_CLASS btm_ble_get_appearance_as_cod( + std::vector const& /* data */) { inc_func_call_count(__func__); - return false; + return kDevClassUnclassified; } void btm_ble_process_adv_addr(RawAddress& /* bda */, tBLE_ADDR_TYPE* /* addr_type */) { inc_func_call_count(__func__); } -void btm_ble_process_adv_pkt(uint8_t /* data_len */, - const uint8_t* /* data */) { - inc_func_call_count(__func__); -} void btm_ble_process_adv_pkt_cont( uint16_t /* evt_type */, tBLE_ADDR_TYPE /* addr_type */, const RawAddress& /* bda */, uint8_t /* primary_phy */, @@ -168,13 +164,6 @@ void btm_ble_process_adv_pkt_cont_for_inquiry( std::vector /* advertising_data */) { inc_func_call_count(__func__); } -void btm_ble_process_ext_adv_pkt(uint8_t /* data_len */, - const uint8_t* /* data */) { - inc_func_call_count(__func__); -} -void btm_ble_process_phy_update_pkt(uint8_t /* len */, uint8_t* /* data */) { - inc_func_call_count(__func__); -} void btm_ble_read_remote_features_complete(uint8_t* /* p */, uint8_t /* length */) { inc_func_call_count(__func__); @@ -194,14 +183,6 @@ void btm_ble_update_dmt_flag_bits(uint8_t* /* adv_flag_value */, const uint16_t /* disc_mode */) { inc_func_call_count(__func__); } -void btm_ble_update_inq_result( - tINQ_DB_ENT* /* p_i */, uint8_t /* addr_type */, - const RawAddress& /* bda */, uint16_t /* evt_type */, - uint8_t /* primary_phy */, uint8_t /* secondary_phy */, - uint8_t /* advertising_sid */, int8_t /* tx_power */, int8_t /* rssi */, - uint16_t /* periodic_adv_int */, std::vector const& /* data */) { - inc_func_call_count(__func__); -} void btm_ble_update_mode_operation(uint8_t /* link_role */, const RawAddress* /* bd_addr */, tHCI_STATUS /* status */) { @@ -218,38 +199,6 @@ void btm_send_hci_set_scan_params(uint8_t /* scan_type */, uint8_t /* scan_filter_policy */) { inc_func_call_count(__func__); } -void BTM_BleStartPeriodicSync(uint8_t /* adv_sid */, RawAddress /* address */, - uint16_t /* skip */, uint16_t /* timeout */, - StartSyncCb /* syncCb */, - SyncReportCb /* reportCb */, - SyncLostCb /* lostCb */) { - inc_func_call_count(__func__); -} -void BTM_BleStopPeriodicSync(uint16_t /* handle */) { - inc_func_call_count(__func__); -} -void BTM_BleCancelPeriodicSync(uint8_t /* adv_sid */, - RawAddress /* address */) { - inc_func_call_count(__func__); -} -void BTM_BlePeriodicSyncTransfer(RawAddress /* addr */, - uint16_t /* service_data */, - uint16_t /* sync_handle */, - SyncTransferCb /* cb */) { - inc_func_call_count(__func__); -} -void BTM_BlePeriodicSyncSetInfo(RawAddress /* addr */, - uint16_t /* service_data */, - uint8_t /* adv_handle */, - SyncTransferCb /* cb */) { - inc_func_call_count(__func__); -} -void BTM_BlePeriodicSyncTxParameters(RawAddress /* addr */, uint8_t /* mode */, - uint16_t /* skip */, - uint16_t /* timeout */, - StartSyncCb /* syncCb */) { - inc_func_call_count(__func__); -} void btm_ble_periodic_adv_sync_tx_rcvd(const uint8_t* /* p */, uint16_t /* param_len */) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_stack_btm_ble_scanner.cc b/system/test/mock/mock_stack_btm_ble_scanner.cc index 63951f555ef414cd1a49de4ade9be7b8a6efa1f9..e65f1f7e592a8a0301c77a14331754942b0ca12d 100644 --- a/system/test/mock/mock_stack_btm_ble_scanner.cc +++ b/system/test/mock/mock_stack_btm_ble_scanner.cc @@ -19,7 +19,6 @@ #include #include #include -#include #include "ble_scanner.h" #include "stack/btm/ble_scanner_hci_interface.h" diff --git a/system/test/mock/mock_stack_btm_dev.cc b/system/test/mock/mock_stack_btm_dev.cc index 5c4958dbfd125be29205de7a613063704de0c58d..e63b2161a182c2abc03b5fac986b90ff5f7fe7c4 100644 --- a/system/test/mock/mock_stack_btm_dev.cc +++ b/system/test/mock/mock_stack_btm_dev.cc @@ -46,9 +46,10 @@ struct maybe_resolve_address maybe_resolve_address; } // namespace test bool BTM_SecAddDevice(const RawAddress& /* bd_addr */, - DEV_CLASS /* dev_class */, const BD_NAME& /* bd_name */, - uint8_t* /* features */, LinkKey* /* p_link_key */, - uint8_t /* key_type */, uint8_t /* pin_length */) { + const DEV_CLASS /* dev_class */, + const BD_NAME& /* bd_name */, uint8_t* /* features */, + LinkKey* /* p_link_key */, uint8_t /* key_type */, + uint8_t /* pin_length */) { inc_func_call_count(__func__); return false; } diff --git a/system/test/mock/mock_stack_btm_dev.h b/system/test/mock/mock_stack_btm_dev.h index 7fd76bbd11b28e3e868cd19059aadedb92eb634f..cf14da37c4800cc31289b1c36fa8bee648f2f0ba 100644 --- a/system/test/mock/mock_stack_btm_dev.h +++ b/system/test/mock/mock_stack_btm_dev.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + #include "stack/btm/btm_dev.h" #include "types/raw_address.h" diff --git a/system/test/mock/mock_stack_btm_devctl.cc b/system/test/mock/mock_stack_btm_devctl.cc index fb0581f487f6f954a1ddbf697a9892c924071c6d..27a4e5efb8bf8914390c47f3e37dbc5e2489a362 100644 --- a/system/test/mock/mock_stack_btm_devctl.cc +++ b/system/test/mock/mock_stack_btm_devctl.cc @@ -24,6 +24,7 @@ #include #include +#include "bt_dev_class.h" #include "stack/include/btm_api_types.h" #include "stack/include/btm_status.h" #include "test/common/mock_functions.h" @@ -81,9 +82,9 @@ tBTM_STATUS BTM_SetLocalDeviceName(const char* /* p_name */) { inc_func_call_count(__func__); return BTM_SUCCESS; } -uint8_t* BTM_ReadDeviceClass(void) { +DEV_CLASS BTM_ReadDeviceClass(void) { inc_func_call_count(__func__); - return nullptr; + return kDevClassEmpty; } void BTM_VendorSpecificCommand(uint16_t /* opcode */, uint8_t /* param_len */, uint8_t* /* p_param_buf */, diff --git a/system/test/mock/mock_stack_btm_inq.cc b/system/test/mock/mock_stack_btm_inq.cc index 8ff677f2abd0a5e4e9c5b6e0e3f59faf9a3d216b..fbdd94138cda80a9936b298bad027436140aeb7b 100644 --- a/system/test/mock/mock_stack_btm_inq.cc +++ b/system/test/mock/mock_stack_btm_inq.cc @@ -69,9 +69,7 @@ struct btm_inq_find_bdaddr btm_inq_find_bdaddr; struct btm_inq_remote_name_timer_timeout btm_inq_remote_name_timer_timeout; struct btm_inq_rmt_name_failed_cancelled btm_inq_rmt_name_failed_cancelled; struct btm_inq_stop_on_ssp btm_inq_stop_on_ssp; -struct btm_process_cancel_complete btm_process_cancel_complete; struct btm_process_inq_complete btm_process_inq_complete; -struct btm_process_inq_results btm_process_inq_results; struct btm_process_remote_name btm_process_remote_name; struct btm_set_eir_uuid btm_set_eir_uuid; struct btm_sort_inq_result btm_sort_inq_result; @@ -256,20 +254,10 @@ void btm_inq_stop_on_ssp(void) { inc_func_call_count(__func__); test::mock::stack_btm_inq::btm_inq_stop_on_ssp(); } -void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) { - inc_func_call_count(__func__); - test::mock::stack_btm_inq::btm_process_cancel_complete(status, mode); -} void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) { inc_func_call_count(__func__); test::mock::stack_btm_inq::btm_process_inq_complete(status, mode); } -void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len, - uint8_t inq_res_mode) { - inc_func_call_count(__func__); - test::mock::stack_btm_inq::btm_process_inq_results(p, hci_evt_len, - inq_res_mode); -} void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn, uint16_t evt_len, tHCI_STATUS hci_status) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_stack_btm_inq.h b/system/test/mock/mock_stack_btm_inq.h index c9f2411eaaaf5f77df2ce53e8d21c024db80a231..39f62a1dbdf414037d6e4327df252e242d6f97b9 100644 --- a/system/test/mock/mock_stack_btm_inq.h +++ b/system/test/mock/mock_stack_btm_inq.h @@ -35,6 +35,7 @@ #include "stack/btm/neighbor_inquiry.h" #include "stack/include/bt_hdr.h" #include "types/bluetooth/uuid.h" +#include "types/bt_transport.h" #include "types/raw_address.h" // Original usings @@ -428,16 +429,6 @@ struct btm_inq_stop_on_ssp { }; extern struct btm_inq_stop_on_ssp btm_inq_stop_on_ssp; -// Name: btm_process_cancel_complete -// Params: tHCI_STATUS status, uint8_t mode -// Return: void -struct btm_process_cancel_complete { - std::function body{ - [](tHCI_STATUS /* status */, uint8_t /* mode */) {}}; - void operator()(tHCI_STATUS status, uint8_t mode) { body(status, mode); }; -}; -extern struct btm_process_cancel_complete btm_process_cancel_complete; - // Name: btm_process_inq_complete // Params: tHCI_STATUS status, uint8_t mode // Return: void @@ -448,20 +439,6 @@ struct btm_process_inq_complete { }; extern struct btm_process_inq_complete btm_process_inq_complete; -// Name: btm_process_inq_results -// Params: const uint8_t* p, uint8_t hci_evt_len, uint8_t inq_res_mode -// Return: void -struct btm_process_inq_results { - std::function - body{[](const uint8_t* /* p */, uint8_t /* hci_evt_len */, - uint8_t /* inq_res_mode */) {}}; - void operator()(const uint8_t* p, uint8_t hci_evt_len, uint8_t inq_res_mode) { - body(p, hci_evt_len, inq_res_mode); - }; -}; -extern struct btm_process_inq_results btm_process_inq_results; - // Name: btm_process_remote_name // Params: const RawAddress* bda, const BD_NAME bdn, uint16_t evt_len, // tHCI_STATUS hci_status Return: void diff --git a/system/test/mock/mock_stack_btm_interface.cc b/system/test/mock/mock_stack_btm_interface.cc index 323d891bda2bada33341629ef5fe1ddb2c340435..75b2d7c1794896437aa90166f8e11fb3fd9bbc78 100644 --- a/system/test/mock/mock_stack_btm_interface.cc +++ b/system/test/mock/mock_stack_btm_interface.cc @@ -24,6 +24,7 @@ #include "stack/include/btm_client_interface.h" #include "stack/include/btm_sec_api.h" #include "stack/include/btm_sec_api_types.h" +#include "types/bt_transport.h" #include "types/raw_address.h" // Test accessible feature page @@ -53,13 +54,6 @@ struct btm_client_interface_t default_btm_client_interface = { .BTM_reset_complete = []() {}, }, .peer = { - .features = - { - .SupportTransparentSynchronousData = - [](const RawAddress& /* bd_addr */) -> bool { - return false; - }, - }, .BTM_IsAclConnectionUp = [](const RawAddress& /* remote_bda */, tBT_TRANSPORT /* transport */) -> bool { return false; @@ -120,50 +114,27 @@ struct btm_client_interface_t default_btm_client_interface = { .security = { .BTM_Sec_Init = []() {}, .BTM_Sec_Free = []() {}, - .BTM_SecAddDevice = BTM_SecAddDevice, - .BTM_SecAddRmtNameNotifyCallback = - [](tBTM_RMT_NAME_CALLBACK* /* p_callback */) -> bool { - return false; - }, - .BTM_SecDeleteDevice = BTM_SecDeleteDevice, + .BTM_SecRegister = [](const tBTM_APPL_INFO* /* p_cb_info */) -> bool { return false; }, - .BTM_SecReadDevName = [](const RawAddress& /* bd_addr */) - -> const char* { return nullptr; }, - .BTM_SecBond = [](const RawAddress& /* bd_addr */, - tBLE_ADDR_TYPE /* addr_type */, - tBT_TRANSPORT /* transport */, - tBT_DEVICE_TYPE /* device_type */) -> tBTM_STATUS { - return BTM_SUCCESS; - }, - .BTM_SecBondCancel = [](const RawAddress& /* bd_addr */) - -> tBTM_STATUS { return BTM_SUCCESS; }, - .BTM_SecAddBleKey = [](const RawAddress& /* bd_addr */, - tBTM_LE_KEY_VALUE* /* p_le_key */, - tBTM_LE_KEY_TYPE /* key_type */) {}, + + .BTM_BleLoadLocalKeys = [](uint8_t /* key_type */, + tBTM_BLE_LOCAL_KEYS* /* p_key */) {}, + + .BTM_SecAddDevice = BTM_SecAddDevice, .BTM_SecAddBleDevice = [](const RawAddress& /* bd_addr */, tBT_DEVICE_TYPE /* dev_type */, tBLE_ADDR_TYPE /* addr_type */) {}, + + .BTM_SecDeleteDevice = BTM_SecDeleteDevice, + + .BTM_SecAddBleKey = [](const RawAddress& /* bd_addr */, + tBTM_LE_KEY_VALUE* /* p_le_key */, + tBTM_LE_KEY_TYPE /* key_type */) {}, + .BTM_SecClearSecurityFlags = BTM_SecClearSecurityFlags, - .BTM_SecClrService = [](uint8_t /* service_id */) -> uint8_t { - return 0; - }, - .BTM_SecClrServiceByPsm = [](uint16_t /* psm */) -> uint8_t { - return 0; - }, - .BTM_RemoteOobDataReply = - [](tBTM_STATUS /* res */, const RawAddress& /* bd_addr */, - const Octet16& /* c */, const Octet16& /* r */) {}, - .BTM_PINCodeReply = [](const RawAddress& /* bd_addr */, - tBTM_STATUS /* res */, uint8_t /* pin_len */, - uint8_t* /* p_pin */) {}, - .BTM_ConfirmReqReply = [](tBTM_STATUS /* res */, - const RawAddress& /* bd_addr */) {}, - .BTM_SecDeleteRmtNameNotifyCallback = - [](tBTM_RMT_NAME_CALLBACK* /* p_callback */) -> bool { - return false; - }, + .BTM_SetEncryption = [](const RawAddress& /* bd_addr */, tBT_TRANSPORT /* transport */, tBTM_SEC_CALLBACK* /* p_callback */, void* /* p_ref_data */, @@ -180,9 +151,50 @@ struct btm_client_interface_t default_btm_client_interface = { tBT_TRANSPORT /* transport */) -> bool { return false; }, + + .BTM_SecClrService = [](uint8_t /* service_id */) -> uint8_t { + return 0; + }, + .BTM_SecClrServiceByPsm = [](uint16_t /* psm */) -> uint8_t { + return 0; + }, + + .BTM_SecBond = [](const RawAddress& /* bd_addr */, + tBLE_ADDR_TYPE /* addr_type */, + tBT_TRANSPORT /* transport */, + tBT_DEVICE_TYPE /* device_type */) -> tBTM_STATUS { + return BTM_SUCCESS; + }, + .BTM_SecBondCancel = [](const RawAddress& /* bd_addr */) + -> tBTM_STATUS { return BTM_SUCCESS; }, + + .BTM_RemoteOobDataReply = + [](tBTM_STATUS /* res */, const RawAddress& /* bd_addr */, + const Octet16& /* c */, const Octet16& /* r */) {}, + .BTM_PINCodeReply = [](const RawAddress& /* bd_addr */, + tBTM_STATUS /* res */, uint8_t /* pin_len */, + uint8_t* /* p_pin */) {}, + .BTM_SecConfirmReqReply = [](tBTM_STATUS /* res */, + tBT_TRANSPORT /* transport */, + const RawAddress /* bd_addr */) {}, .BTM_BleSirkConfirmDeviceReply = [](const RawAddress& /* bd_addr */, uint8_t /* res */) {}, + .BTM_BlePasskeyReply = [](const RawAddress& /* bd_addr */, + uint8_t /* res */, uint32_t /* passkey */) {}, + .BTM_GetSecurityMode = []() -> uint8_t { return 0; }, + + .BTM_SecReadDevName = [](const RawAddress& /* bd_addr */) + -> const char* { return nullptr; }, + + .BTM_SecAddRmtNameNotifyCallback = + [](tBTM_RMT_NAME_CALLBACK* /* p_callback */) -> bool { + return false; + }, + .BTM_SecDeleteRmtNameNotifyCallback = + [](tBTM_RMT_NAME_CALLBACK* /* p_callback */) -> bool { + return false; + }, }, .ble = { .BTM_BleGetEnergyInfo = @@ -198,12 +210,7 @@ struct btm_client_interface_t default_btm_client_interface = { .BTM_SetBleDataLength = [](const RawAddress& /* bd_addr */, uint16_t /* tx_pdu_length */) -> tBTM_STATUS { return BTM_SUCCESS; }, - .BTM_BleConfirmReply = [](const RawAddress& /* bd_addr */, - uint8_t /* res */) {}, - .BTM_BleLoadLocalKeys = [](uint8_t /* key_type */, - tBTM_BLE_LOCAL_KEYS* /* p_key */) {}, - .BTM_BlePasskeyReply = [](const RawAddress& /* bd_addr */, - uint8_t /* res */, uint32_t /* passkey */) {}, + .BTM_BleReadControllerFeatures = [](tBTM_BLE_CTRL_FEATURES_CBACK* /* p_vsc_cback */) {}, .BTM_BleSetConnScanParams = [](uint32_t /* scan_interval */, diff --git a/system/test/mock/mock_stack_btm_iso.cc b/system/test/mock/mock_stack_btm_iso.cc index 1112ec3fc606f873ebde58bdebd6d715f5779d8e..c0645aa5f8a1e478a87390f6f6c2e95d1c4b015d 100644 --- a/system/test/mock/mock_stack_btm_iso.cc +++ b/system/test/mock/mock_stack_btm_iso.cc @@ -1,3 +1,18 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "stack/include/btm_iso_api.h" diff --git a/system/test/mock/mock_stack_btm_sco.cc b/system/test/mock/mock_stack_btm_sco.cc index d7ad6d37d1bbda0c3825a3661e74e0ab1e772ce9..36eb7027af87d7c18bd9fd5fb5b0bfd99beb5d52 100644 --- a/system/test/mock/mock_stack_btm_sco.cc +++ b/system/test/mock/mock_stack_btm_sco.cc @@ -22,13 +22,12 @@ #include #include "device/include/esco_parameters.h" +#include "hci/class_of_device.h" #include "stack/btm/btm_sco.h" -#include "stack/include/bt_hdr.h" #include "stack/include/btm_api_types.h" #include "stack/include/btm_status.h" #include "stack/include/hci_error_code.h" #include "test/common/mock_functions.h" -#include "types/class_of_device.h" #include "types/raw_address.h" bool BTM_IsScoActiveByBdaddr(const RawAddress& /* remote_bda */) { @@ -113,12 +112,12 @@ void btm_sco_disc_chk_pend_for_modechange(uint16_t /* hci_handle */) { } void btm_sco_on_esco_connect_request( const RawAddress& /* bda */, - const bluetooth::types::ClassOfDevice& /* cod */) { + const bluetooth::hci::ClassOfDevice& /* cod */) { inc_func_call_count(__func__); } void btm_sco_on_sco_connect_request( const RawAddress& /* bda */, - const bluetooth::types::ClassOfDevice& /* cod */) { + const bluetooth::hci::ClassOfDevice& /* cod */) { inc_func_call_count(__func__); } void btm_sco_on_disconnected(uint16_t /* hci_handle */, diff --git a/system/test/mock/mock_stack_btm_sco_hfp_hal.cc b/system/test/mock/mock_stack_btm_sco_hfp_hal.cc index 96d18afe24a738b0131889bd4aac74c522f2c9fb..1083a3601afaccfb2f3bf209ccfc0ce8755b8322 100644 --- a/system/test/mock/mock_stack_btm_sco_hfp_hal.cc +++ b/system/test/mock/mock_stack_btm_sco_hfp_hal.cc @@ -47,6 +47,7 @@ struct init init; struct notify_sco_connection_change notify_sco_connection_change; struct set_codec_datapath set_codec_datapath; struct update_esco_parameters update_esco_parameters; +struct is_coding_format_supported is_coding_format_supported; } // namespace stack_btm_sco_hfp_hal } // namespace mock @@ -64,6 +65,7 @@ bool get_offload_supported::return_value = false; int get_packet_size::return_value = 0; bool get_wbs_supported::return_value = false; bool get_swb_supported::return_value = false; +bool is_coding_format_supported::return_value = false; } // namespace stack_btm_sco_hfp_hal } // namespace mock @@ -100,6 +102,11 @@ bool get_swb_supported() { inc_func_call_count(__func__); return test::mock::stack_btm_sco_hfp_hal::get_swb_supported(); } +bool is_coding_format_supported(esco_coding_format_t coding_format) { + inc_func_call_count(__func__); + return test::mock::stack_btm_sco_hfp_hal::is_coding_format_supported( + coding_format); +} void init() { inc_func_call_count(__func__); test::mock::stack_btm_sco_hfp_hal::init(); diff --git a/system/test/mock/mock_stack_btm_sco_hfp_hal.h b/system/test/mock/mock_stack_btm_sco_hfp_hal.h index fdabd2b150240e8dc69d50341c657659ef3d8955..9474d4c9c62d43b86878e70b7d7f8ed50c957a14 100644 --- a/system/test/mock/mock_stack_btm_sco_hfp_hal.h +++ b/system/test/mock/mock_stack_btm_sco_hfp_hal.h @@ -114,6 +114,19 @@ struct get_swb_supported { }; extern struct get_swb_supported get_swb_supported; +// Name: is_coding_format_supported +// Params: esco_coding_format_t coding_format +// Return: bool +struct is_coding_format_supported { + static bool return_value; + std::function body{ + [](esco_coding_format_t /* coding_format */) { return return_value; }}; + bool operator()(esco_coding_format_t coding_format) { + return body(coding_format); + }; +}; +extern struct is_coding_format_supported is_coding_format_supported; + // Name: init // Params: // Return: void diff --git a/system/test/mock/mock_stack_btm_sec.cc b/system/test/mock/mock_stack_btm_sec.cc index 7bea4563242273f77b820185eba9e6bf7ef35364..1f656f3a6da67052e4b14e4bea37c6156bcdf757 100644 --- a/system/test/mock/mock_stack_btm_sec.cc +++ b/system/test/mock/mock_stack_btm_sec.cc @@ -89,6 +89,7 @@ struct btm_sec_dev_reset btm_sec_dev_reset; struct btm_sec_disconnect btm_sec_disconnect; struct btm_sec_disconnected btm_sec_disconnected; struct btm_sec_encrypt_change btm_sec_encrypt_change; +struct btm_sec_encryption_change_evt btm_sec_encryption_change_evt; struct btm_sec_is_a_bonded_dev btm_sec_is_a_bonded_dev; struct btm_sec_l2cap_access_req btm_sec_l2cap_access_req; struct btm_sec_l2cap_access_req_by_requirement @@ -137,7 +138,7 @@ bool BTM_SecIsSecurityPending::return_value = false; bool BTM_SecRegister::return_value = false; tBTM_STATUS BTM_SetEncryption::return_value = 0; bool BTM_SetSecurityLevel::return_value = false; -const uint8_t* btm_get_dev_class::return_value = nullptr; +const DEV_CLASS btm_get_dev_class::return_value = kDevClassEmpty; tBTM_STATUS btm_sec_bond_by_transport::return_value = 0; tBTM_STATUS btm_sec_disconnect::return_value = 0; bool btm_sec_is_a_bonded_dev::return_value = false; @@ -286,7 +287,7 @@ void btm_create_conn_cancel_complete(uint8_t status, const RawAddress bd_addr) { inc_func_call_count(__func__); test::mock::stack_btm_sec::btm_create_conn_cancel_complete(status, bd_addr); } -const uint8_t* btm_get_dev_class(const RawAddress& bda) { +const DEV_CLASS btm_get_dev_class(const RawAddress& bda) { inc_func_call_count(__func__); return test::mock::stack_btm_sec::btm_get_dev_class(bda); } @@ -377,6 +378,12 @@ void btm_sec_encrypt_change(uint16_t handle, tHCI_STATUS status, test::mock::stack_btm_sec::btm_sec_encrypt_change(handle, status, encr_enable); } +void btm_sec_encryption_change_evt(uint16_t handle, tHCI_STATUS status, + uint8_t encr_enable) { + inc_func_call_count(__func__); + test::mock::stack_btm_sec::btm_sec_encryption_change_evt(handle, status, + encr_enable); +} bool btm_sec_is_a_bonded_dev(const RawAddress& bda) { inc_func_call_count(__func__); return test::mock::stack_btm_sec::btm_sec_is_a_bonded_dev(bda); diff --git a/system/test/mock/mock_stack_btm_sec.h b/system/test/mock/mock_stack_btm_sec.h index 824c7b2047a2307769a8a874b14367e9b7ec05e7..d7575922805f281f88e0fdea3047d6f1010ff5f8 100644 --- a/system/test/mock/mock_stack_btm_sec.h +++ b/system/test/mock/mock_stack_btm_sec.h @@ -443,12 +443,12 @@ extern struct btm_create_conn_cancel_complete btm_create_conn_cancel_complete; // Name: btm_get_dev_class // Params: const RawAddress& bda -// Return: const uint8_t* +// Return: DEV_CLASS struct btm_get_dev_class { - static const uint8_t* return_value; - std::function body{ + static const DEV_CLASS return_value; + std::function body{ [](const RawAddress& /* bda */) { return return_value; }}; - const uint8_t* operator()(const RawAddress& bda) { return body(bda); }; + const DEV_CLASS operator()(const RawAddress& bda) { return body(bda); }; }; extern struct btm_get_dev_class btm_get_dev_class; @@ -669,6 +669,19 @@ struct btm_sec_encrypt_change { }; extern struct btm_sec_encrypt_change btm_sec_encrypt_change; +// Name: btm_sec_encryption_change_evt +// Params: uint16_t handle, tHCI_STATUS status, uint8_t encr_enable +// Return: void +struct btm_sec_encryption_change_evt { + std::function + body{[](uint16_t /* handle */, tHCI_STATUS /* status */, + uint8_t /* encr_enable */) {}}; + void operator()(uint16_t handle, tHCI_STATUS status, uint8_t encr_enable) { + body(handle, status, encr_enable); + }; +}; +extern struct btm_sec_encryption_change_evt btm_sec_encryption_change_evt; + // Name: btm_sec_is_a_bonded_dev // Params: const RawAddress& bda // Return: bool diff --git a/system/test/mock/mock_stack_btu_hcif.cc b/system/test/mock/mock_stack_btu_hcif.cc index ba9967917c8a314cf398a89a19c79e30baebc9fa..e525c9225d45214e6320b60bae644fe9e65e046e 100644 --- a/system/test/mock/mock_stack_btu_hcif.cc +++ b/system/test/mock/mock_stack_btu_hcif.cc @@ -38,20 +38,20 @@ struct cmd_with_cb_data { base::Location posted_from; }; -void btu_hcif_process_event(uint8_t controller_id, BT_HDR* p_msg) { +void btu_hcif_process_event(uint8_t /* controller_id */, BT_HDR* /* p_msg */) { inc_func_call_count(__func__); } -void btu_hcif_send_cmd(uint8_t controller_id, const BT_HDR* p_buf) { +void btu_hcif_send_cmd(uint8_t /* controller_id */, const BT_HDR* /* p_buf */) { inc_func_call_count(__func__); } -void btu_hcif_send_cmd_with_cb(const base::Location& posted_from, - uint16_t opcode, uint8_t* params, - uint8_t params_len, hci_cmd_cb cb) { +void btu_hcif_send_cmd_with_cb(const base::Location& /* posted_from */, + uint16_t /* opcode */, uint8_t* /* params */, + uint8_t /* params_len */, hci_cmd_cb /* cb */) { inc_func_call_count(__func__); } -void cmd_with_cb_data_cleanup(cmd_with_cb_data* cb_wrapper) { +void cmd_with_cb_data_cleanup(cmd_with_cb_data* /* cb_wrapper */) { inc_func_call_count(__func__); } -void cmd_with_cb_data_init(cmd_with_cb_data* cb_wrapper) { +void cmd_with_cb_data_init(cmd_with_cb_data* /* cb_wrapper */) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_stack_gatt_main.cc b/system/test/mock/mock_stack_gatt_main.cc index 5a6bf35641745f5b58f4522964aaccdb130d944b..50cd730a672e1b195aab54d789f46d5cc5bc6165 100644 --- a/system/test/mock/mock_stack_gatt_main.cc +++ b/system/test/mock/mock_stack_gatt_main.cc @@ -108,3 +108,7 @@ void gatt_update_app_use_link_flag(tGATT_IF /* gatt_if */, bool /* check_acl_link */) { inc_func_call_count(__func__); } + +void gatt_tcb_dump(int fd) { + inc_func_call_count(__func__); +} diff --git a/system/test/mock/mock_stack_hcic_hciblecmds.h b/system/test/mock/mock_stack_hcic_hciblecmds.h index 5d9b5766b452f5750efa9bcee9be0efaa3643699..ef6873638869e5a9e35d005cb7e28943e7e3c279 100644 --- a/system/test/mock/mock_stack_hcic_hciblecmds.h +++ b/system/test/mock/mock_stack_hcic_hciblecmds.h @@ -45,9 +45,9 @@ namespace stack_hcic_hciblecmds { struct btsnd_hci_ble_add_device_to_periodic_advertiser_list { std::function)> - body{[](uint8_t adv_addr_type, const RawAddress& adv_addr, - uint8_t adv_sid, - base::OnceCallback cb) {}}; + body{[](uint8_t /* adv_addr_type */, const RawAddress& /* adv_addr */, + uint8_t /* adv_sid */, + base::OnceCallback /* cb */) {}}; void operator()(uint8_t adv_addr_type, const RawAddress& adv_addr, uint8_t adv_sid, base::OnceCallback cb) { @@ -76,9 +76,9 @@ extern struct btsnd_hci_ble_clear_periodic_advertiser_list struct btsnd_hci_ble_remove_device_from_periodic_advertiser_list { std::function)> - body{[](uint8_t adv_addr_type, const RawAddress& adv_addr, - uint8_t adv_sid, - base::OnceCallback cb) {}}; + body{[](uint8_t /* adv_addr_type */, const RawAddress& /* adv_addr */, + uint8_t /* adv_sid */, + base::OnceCallback /* cb */) {}}; void operator()(uint8_t adv_addr_type, const RawAddress& adv_addr, uint8_t adv_sid, base::OnceCallback cb) { @@ -92,7 +92,8 @@ extern struct btsnd_hci_ble_remove_device_from_periodic_advertiser_list // Params: uint16_t conn_handle // Return: void struct btsnd_hcic_accept_cis_req { - std::function body{[](uint16_t conn_handle) {}}; + std::function body{ + [](uint16_t /* conn_handle */) {}}; void operator()(uint16_t conn_handle) { body(conn_handle); }; }; extern struct btsnd_hcic_accept_cis_req btsnd_hcic_accept_cis_req; @@ -103,8 +104,9 @@ extern struct btsnd_hcic_accept_cis_req btsnd_hcic_accept_cis_req; struct btsnd_hcic_ble_add_device_resolving_list { std::function - body{[](uint8_t addr_type_peer, const RawAddress& bda_peer, - const Octet16& irk_peer, const Octet16& irk_local) {}}; + body{[](uint8_t /* addr_type_peer */, const RawAddress& /* bda_peer */, + const Octet16& /* irk_peer */, + const Octet16& /* irk_local */) {}}; void operator()(uint8_t addr_type_peer, const RawAddress& bda_peer, const Octet16& irk_peer, const Octet16& irk_local) { body(addr_type_peer, bda_peer, irk_peer, irk_local); @@ -128,7 +130,7 @@ extern struct btsnd_hcic_ble_clear_resolving_list // Return: void struct btsnd_hcic_ble_enh_rx_test { std::function body{ - [](uint8_t rx_chan, uint8_t phy, uint8_t mod_index) {}}; + [](uint8_t /* rx_chan */, uint8_t /* phy */, uint8_t /* mod_index */) {}}; void operator()(uint8_t rx_chan, uint8_t phy, uint8_t mod_index) { body(rx_chan, phy, mod_index); }; @@ -141,8 +143,8 @@ extern struct btsnd_hcic_ble_enh_rx_test btsnd_hcic_ble_enh_rx_test; struct btsnd_hcic_ble_enh_tx_test { std::function - body{[](uint8_t tx_chan, uint8_t data_len, uint8_t payload, uint8_t phy) { - }}; + body{[](uint8_t /* tx_chan */, uint8_t /* data_len */, + uint8_t /* payload */, uint8_t /* phy */) {}}; void operator()(uint8_t tx_chan, uint8_t data_len, uint8_t payload, uint8_t phy) { body(tx_chan, data_len, payload, phy); @@ -154,7 +156,7 @@ extern struct btsnd_hcic_ble_enh_tx_test btsnd_hcic_ble_enh_tx_test; // Params: uint16_t handle // Return: void struct btsnd_hcic_ble_ltk_req_neg_reply { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_ble_ltk_req_neg_reply btsnd_hcic_ble_ltk_req_neg_reply; @@ -164,7 +166,7 @@ extern struct btsnd_hcic_ble_ltk_req_neg_reply btsnd_hcic_ble_ltk_req_neg_reply; // Return: void struct btsnd_hcic_ble_ltk_req_reply { std::function body{ - [](uint16_t handle, const Octet16& ltk) {}}; + [](uint16_t /* handle */, const Octet16& /* ltk */) {}}; void operator()(uint16_t handle, const Octet16& ltk) { body(handle, ltk); }; }; extern struct btsnd_hcic_ble_ltk_req_reply btsnd_hcic_ble_ltk_req_reply; @@ -177,9 +179,10 @@ struct btsnd_hcic_ble_periodic_advertising_create_sync { std::function - body{[](uint8_t options, uint8_t adv_sid, uint8_t adv_addr_type, - const RawAddress& adv_addr, uint16_t skip_num, - uint16_t sync_timeout, uint8_t sync_cte_type) {}}; + body{[](uint8_t /* options */, uint8_t /* adv_sid */, + uint8_t /* adv_addr_type */, const RawAddress& /* adv_addr */, + uint16_t /* skip_num */, uint16_t /* sync_timeout */, + uint8_t /* sync_cte_type */) {}}; void operator()(uint8_t options, uint8_t adv_sid, uint8_t adv_addr_type, const RawAddress& adv_addr, uint16_t skip_num, uint16_t sync_timeout, uint8_t sync_cte_type) { @@ -195,7 +198,7 @@ extern struct btsnd_hcic_ble_periodic_advertising_create_sync // Return: void struct btsnd_hcic_ble_periodic_advertising_create_sync_cancel { std::function)> body{ - [](base::OnceCallback cb) {}}; + [](base::OnceCallback /* cb */) {}}; void operator()(base::OnceCallback cb) { body(std::move(cb)); }; @@ -209,8 +212,9 @@ extern struct btsnd_hcic_ble_periodic_advertising_create_sync_cancel struct btsnd_hcic_ble_periodic_advertising_set_info_transfer { std::function)> - body{[](uint16_t conn_handle, uint16_t service_data, uint8_t adv_handle, - base::OnceCallback cb) {}}; + body{[](uint16_t /* conn_handle */, uint16_t /* service_data */, + uint8_t /* adv_handle */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t conn_handle, uint16_t service_data, uint8_t adv_handle, base::OnceCallback cb) { @@ -226,8 +230,9 @@ extern struct btsnd_hcic_ble_periodic_advertising_set_info_transfer struct btsnd_hcic_ble_periodic_advertising_sync_transfer { std::function)> - body{[](uint16_t conn_handle, uint16_t service_data, uint16_t sync_handle, - base::OnceCallback cb) {}}; + body{[](uint16_t /* conn_handle */, uint16_t /* service_data */, + uint16_t /* sync_handle */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t conn_handle, uint16_t service_data, uint16_t sync_handle, base::OnceCallback cb) { @@ -242,8 +247,8 @@ extern struct btsnd_hcic_ble_periodic_advertising_sync_transfer // Return: void struct btsnd_hcic_ble_periodic_advertising_terminate_sync { std::function)> - body{[](uint16_t sync_handle, - base::OnceCallback cb) {}}; + body{[](uint16_t /* sync_handle */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t sync_handle, base::OnceCallback cb) { body(sync_handle, std::move(cb)); @@ -257,7 +262,7 @@ extern struct btsnd_hcic_ble_periodic_advertising_terminate_sync // Return: void struct btsnd_hcic_ble_rand { std::function)> body{ - [](base::Callback cb) {}}; + [](base::Callback /* cb */) {}}; void operator()(base::Callback cb) { body(std::move(cb)); }; }; extern struct btsnd_hcic_ble_rand btsnd_hcic_ble_rand; @@ -267,7 +272,7 @@ extern struct btsnd_hcic_ble_rand btsnd_hcic_ble_rand; // Return: void struct btsnd_hcic_ble_rc_param_req_neg_reply { std::function body{ - [](uint16_t handle, uint8_t reason) {}}; + [](uint16_t /* handle */, uint8_t /* reason */) {}}; void operator()(uint16_t handle, uint8_t reason) { body(handle, reason); }; }; extern struct btsnd_hcic_ble_rc_param_req_neg_reply @@ -282,9 +287,10 @@ struct btsnd_hcic_ble_rc_param_req_reply { uint16_t conn_int_max, uint16_t conn_latency, uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len)> - body{[](uint16_t handle, 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) {}}; + body{[](uint16_t /* handle */, 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 */) {}}; void operator()(uint16_t handle, 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) { @@ -309,7 +315,7 @@ extern struct btsnd_hcic_ble_read_adv_chnl_tx_power // Params: uint16_t handle // Return: void struct btsnd_hcic_ble_read_remote_feat { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_ble_read_remote_feat btsnd_hcic_ble_read_remote_feat; @@ -319,7 +325,7 @@ extern struct btsnd_hcic_ble_read_remote_feat btsnd_hcic_ble_read_remote_feat; // Return: void struct btsnd_hcic_ble_read_resolvable_addr_peer { std::function body{ - [](uint8_t addr_type_peer, const RawAddress& bda_peer) {}}; + [](uint8_t /* addr_type_peer */, const RawAddress& /* bda_peer */) {}}; void operator()(uint8_t addr_type_peer, const RawAddress& bda_peer) { body(addr_type_peer, bda_peer); }; @@ -331,7 +337,7 @@ extern struct btsnd_hcic_ble_read_resolvable_addr_peer // Params: uint8_t rx_freq // Return: void struct btsnd_hcic_ble_receiver_test { - std::function body{[](uint8_t rx_freq) {}}; + std::function body{[](uint8_t /* rx_freq */) {}}; void operator()(uint8_t rx_freq) { body(rx_freq); }; }; extern struct btsnd_hcic_ble_receiver_test btsnd_hcic_ble_receiver_test; @@ -341,7 +347,7 @@ extern struct btsnd_hcic_ble_receiver_test btsnd_hcic_ble_receiver_test; // Return: void struct btsnd_hcic_ble_rm_device_resolving_list { std::function body{ - [](uint8_t addr_type_peer, const RawAddress& bda_peer) {}}; + [](uint8_t /* addr_type_peer */, const RawAddress& /* bda_peer */) {}}; void operator()(uint8_t addr_type_peer, const RawAddress& bda_peer) { body(addr_type_peer, bda_peer); }; @@ -354,7 +360,7 @@ extern struct btsnd_hcic_ble_rm_device_resolving_list // Return: void struct btsnd_hcic_ble_set_adv_data { std::function body{ - [](uint8_t data_len, uint8_t* p_data) {}}; + [](uint8_t /* data_len */, uint8_t* /* p_data */) {}}; void operator()(uint8_t data_len, uint8_t* p_data) { body(data_len, p_data); }; @@ -365,7 +371,7 @@ extern struct btsnd_hcic_ble_set_adv_data btsnd_hcic_ble_set_adv_data; // Params: uint8_t adv_enable // Return: void struct btsnd_hcic_ble_set_adv_enable { - std::function body{[](uint8_t adv_enable) {}}; + std::function body{[](uint8_t /* adv_enable */) {}}; void operator()(uint8_t adv_enable) { body(adv_enable); }; }; extern struct btsnd_hcic_ble_set_adv_enable btsnd_hcic_ble_set_adv_enable; @@ -376,7 +382,8 @@ extern struct btsnd_hcic_ble_set_adv_enable btsnd_hcic_ble_set_adv_enable; struct btsnd_hcic_ble_set_data_length { std::function - body{[](uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time) {}}; + body{[](uint16_t /* conn_handle */, uint16_t /* tx_octets */, + uint16_t /* tx_time */) {}}; void operator()(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time) { body(conn_handle, tx_octets, tx_time); }; @@ -390,9 +397,10 @@ extern struct btsnd_hcic_ble_set_data_length btsnd_hcic_ble_set_data_length; struct btsnd_hcic_ble_set_default_periodic_advertising_sync_transfer_params { std::function)> - body{[](uint16_t conn_handle, uint8_t mode, uint16_t skip, - uint16_t sync_timeout, uint8_t cte_type, - base::OnceCallback cb) {}}; + body{[](uint16_t /* conn_handle */, uint8_t /* mode */, + uint16_t /* skip */, uint16_t /* sync_timeout */, + uint8_t /* cte_type */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t conn_handle, uint8_t mode, uint16_t skip, uint16_t sync_timeout, uint8_t cte_type, base::OnceCallback cb) { @@ -409,8 +417,8 @@ extern struct struct btsnd_hcic_ble_set_extended_scan_enable { std::function - body{[](uint8_t enable, uint8_t filter_duplicates, uint16_t duration, - uint16_t period) {}}; + body{[](uint8_t /* enable */, uint8_t /* filter_duplicates */, + uint16_t /* duration */, uint16_t /* period */) {}}; void operator()(uint8_t enable, uint8_t filter_duplicates, uint16_t duration, uint16_t period) { body(enable, filter_duplicates, duration, period); @@ -425,8 +433,9 @@ extern struct btsnd_hcic_ble_set_extended_scan_enable struct btsnd_hcic_ble_set_extended_scan_params { std::function - body{[](uint8_t own_address_type, uint8_t scanning_filter_policy, - uint8_t scanning_phys, scanning_phy_cfg* phy_cfg) {}}; + body{[](uint8_t /* own_address_type */, + uint8_t /* scanning_filter_policy */, uint8_t /* scanning_phys */, + scanning_phy_cfg* /* phy_cfg */) {}}; void operator()(uint8_t own_address_type, uint8_t scanning_filter_policy, uint8_t scanning_phys, scanning_phy_cfg* phy_cfg) { body(own_address_type, scanning_filter_policy, scanning_phys, phy_cfg); @@ -441,8 +450,8 @@ extern struct btsnd_hcic_ble_set_extended_scan_params struct btsnd_hcic_ble_set_periodic_advertising_receive_enable { std::function)> - body{[](uint16_t sync_handle, bool enable, - base::OnceCallback cb) {}}; + body{[](uint16_t /* sync_handle */, bool /* enable */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t sync_handle, bool enable, base::OnceCallback cb) { body(sync_handle, enable, std::move(cb)); @@ -458,9 +467,10 @@ extern struct btsnd_hcic_ble_set_periodic_advertising_receive_enable struct btsnd_hcic_ble_set_periodic_advertising_sync_transfer_params { std::function)> - body{[](uint16_t conn_handle, uint8_t mode, uint16_t skip, - uint16_t sync_timeout, uint8_t cte_type, - base::OnceCallback cb) {}}; + body{[](uint16_t /* conn_handle */, uint8_t /* mode */, + uint16_t /* skip */, uint16_t /* sync_timeout */, + uint8_t /* cte_type */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t conn_handle, uint8_t mode, uint16_t skip, uint16_t sync_timeout, uint8_t cte_type, base::OnceCallback cb) { @@ -476,8 +486,8 @@ extern struct btsnd_hcic_ble_set_periodic_advertising_sync_transfer_params struct btsnd_hcic_ble_set_privacy_mode { std::function - body{[](uint8_t addr_type_peer, const RawAddress& bda_peer, - uint8_t privacy_type) {}}; + body{[](uint8_t /* addr_type_peer */, const RawAddress& /* bda_peer */, + uint8_t /* privacy_type */) {}}; void operator()(uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t privacy_type) { body(addr_type_peer, bda_peer, privacy_type); @@ -489,7 +499,8 @@ extern struct btsnd_hcic_ble_set_privacy_mode btsnd_hcic_ble_set_privacy_mode; // Params: uint16_t rpa_timout // Return: void struct btsnd_hcic_ble_set_rand_priv_addr_timeout { - std::function body{[](uint16_t rpa_timout) {}}; + std::function body{ + [](uint16_t /* rpa_timout */) {}}; void operator()(uint16_t rpa_timout) { body(rpa_timout); }; }; extern struct btsnd_hcic_ble_set_rand_priv_addr_timeout @@ -500,7 +511,7 @@ extern struct btsnd_hcic_ble_set_rand_priv_addr_timeout // Return: void struct btsnd_hcic_ble_set_scan_enable { std::function body{ - [](uint8_t scan_enable, uint8_t duplicate) {}}; + [](uint8_t /* scan_enable */, uint8_t /* duplicate */) {}}; void operator()(uint8_t scan_enable, uint8_t duplicate) { body(scan_enable, duplicate); }; @@ -513,8 +524,9 @@ extern struct btsnd_hcic_ble_set_scan_enable btsnd_hcic_ble_set_scan_enable; struct btsnd_hcic_ble_set_scan_params { std::function - body{[](uint8_t scan_type, uint16_t scan_int, uint16_t scan_win, - uint8_t addr_type_own, uint8_t scan_filter_policy) {}}; + body{[](uint8_t /* scan_type */, uint16_t /* scan_int */, + uint16_t /* scan_win */, uint8_t /* addr_type_own */, + uint8_t /* scan_filter_policy */) {}}; void operator()(uint8_t scan_type, uint16_t scan_int, uint16_t scan_win, uint8_t addr_type_own, uint8_t scan_filter_policy) { body(scan_type, scan_int, scan_win, addr_type_own, scan_filter_policy); @@ -528,8 +540,8 @@ extern struct btsnd_hcic_ble_set_scan_params btsnd_hcic_ble_set_scan_params; struct btsnd_hcic_ble_start_enc { std::function - body{[](uint16_t handle, uint8_t rand[HCIC_BLE_RAND_DI_SIZE], - uint16_t ediv, const Octet16& ltk) {}}; + body{[](uint16_t /* handle */, uint8_t[HCIC_BLE_RAND_DI_SIZE] /* rand */, + uint16_t /* ediv */, const Octet16& /* ltk */) {}}; void operator()(uint16_t handle, uint8_t rand[HCIC_BLE_RAND_DI_SIZE], uint16_t ediv, const Octet16& ltk) { body(handle, rand, ediv, ltk); @@ -551,7 +563,8 @@ extern struct btsnd_hcic_ble_test_end btsnd_hcic_ble_test_end; // Return: void struct btsnd_hcic_ble_transmitter_test { std::function - body{[](uint8_t tx_freq, uint8_t test_data_len, uint8_t payload) {}}; + body{[](uint8_t /* tx_freq */, uint8_t /* test_data_len */, + uint8_t /* payload */) {}}; void operator()(uint8_t tx_freq, uint8_t test_data_len, uint8_t payload) { body(tx_freq, test_data_len, payload); }; @@ -567,9 +580,10 @@ struct btsnd_hcic_ble_upd_ll_conn_params { uint16_t conn_int_max, uint16_t conn_latency, uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len)> - body{[](uint16_t handle, 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) {}}; + body{[](uint16_t /* handle */, 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 */) {}}; void operator()(uint16_t handle, 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) { @@ -589,10 +603,11 @@ struct btsnd_hcic_ble_write_adv_params { uint8_t adv_type, tBLE_ADDR_TYPE addr_type_own, tBLE_ADDR_TYPE addr_type_dir, const RawAddress& direct_bda, uint8_t channel_map, uint8_t adv_filter_policy)> - body{[](uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, - tBLE_ADDR_TYPE addr_type_own, tBLE_ADDR_TYPE addr_type_dir, - const RawAddress& direct_bda, uint8_t channel_map, - uint8_t adv_filter_policy) {}}; + body{[](uint16_t /* adv_int_min */, uint16_t /* adv_int_max */, + uint8_t /* adv_type */, tBLE_ADDR_TYPE /* addr_type_own */, + tBLE_ADDR_TYPE /* addr_type_dir */, + const RawAddress& /* direct_bda */, uint8_t /* channel_map */, + uint8_t /* adv_filter_policy */) {}}; void operator()(uint16_t adv_int_min, uint16_t adv_int_max, uint8_t adv_type, tBLE_ADDR_TYPE addr_type_own, tBLE_ADDR_TYPE addr_type_dir, const RawAddress& direct_bda, uint8_t channel_map, @@ -614,11 +629,12 @@ struct btsnd_hcic_create_big { uint16_t transport_latency, uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing, uint8_t enc, std::array bcst_code)> - body{[](uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, - uint32_t sdu_itv, uint16_t max_sdu_size, - uint16_t transport_latency, uint8_t rtn, uint8_t phy, - uint8_t packing, uint8_t framing, uint8_t enc, - std::array bcst_code) {}}; + body{[](uint8_t /* big_handle */, uint8_t /* adv_handle */, + uint8_t /* num_bis */, uint32_t /* sdu_itv */, + uint16_t /* max_sdu_size */, uint16_t /* transport_latency */, + uint8_t /* rtn */, uint8_t /* phy */, uint8_t /* packing */, + uint8_t /* framing */, uint8_t /* enc */, + std::array /* bcst_code */) {}}; void operator()(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, uint32_t sdu_itv, uint16_t max_sdu_size, uint16_t transport_latency, uint8_t rtn, uint8_t phy, @@ -636,8 +652,8 @@ extern struct btsnd_hcic_create_big btsnd_hcic_create_big; struct btsnd_hcic_create_cis { std::function)> - body{[](uint8_t num_cis, const EXT_CIS_CREATE_CFG* cis_cfg, - base::OnceCallback cb) {}}; + body{[](uint8_t /* num_cis */, const EXT_CIS_CREATE_CFG* /* cis_cfg */, + base::OnceCallback /* cb */) {}}; void operator()(uint8_t num_cis, const EXT_CIS_CREATE_CFG* cis_cfg, base::OnceCallback cb) { body(num_cis, cis_cfg, std::move(cb)); @@ -650,7 +666,7 @@ extern struct btsnd_hcic_create_cis btsnd_hcic_create_cis; // Return: void struct btsnd_hcic_read_iso_link_quality { std::function)> - body{[](uint16_t iso_handle, + body{[](uint16_t /* iso_handle */, base::OnceCallback) {}}; void operator()(uint16_t iso_handle, base::OnceCallback cb) { @@ -665,8 +681,8 @@ extern struct btsnd_hcic_read_iso_link_quality btsnd_hcic_read_iso_link_quality; struct btsnd_hcic_rej_cis_req { std::function)> - body{[](uint16_t conn_handle, uint8_t reason, - base::OnceCallback cb) {}}; + body{[](uint16_t /* conn_handle */, uint8_t /* reason */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t conn_handle, uint8_t reason, base::OnceCallback cb) { body(conn_handle, reason, std::move(cb)); @@ -679,8 +695,8 @@ extern struct btsnd_hcic_rej_cis_req btsnd_hcic_rej_cis_req; // Return: void struct btsnd_hcic_remove_cig { std::function)> - body{[](uint8_t cig_id, base::OnceCallback cb) { - }}; + body{[](uint8_t /* cig_id */, + base::OnceCallback /* cb */) {}}; void operator()(uint8_t cig_id, base::OnceCallback cb) { body(cig_id, std::move(cb)); @@ -694,8 +710,8 @@ extern struct btsnd_hcic_remove_cig btsnd_hcic_remove_cig; struct btsnd_hcic_remove_iso_data_path { std::function)> - body{[](uint16_t iso_handle, uint8_t data_path_dir, - base::OnceCallback cb) {}}; + body{[](uint16_t /* iso_handle */, uint8_t /* data_path_dir */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t iso_handle, uint8_t data_path_dir, base::OnceCallback cb) { body(iso_handle, data_path_dir, std::move(cb)); @@ -707,7 +723,7 @@ extern struct btsnd_hcic_remove_iso_data_path btsnd_hcic_remove_iso_data_path; // Params: uint16_t conn_handle // Return: void struct btsnd_hcic_req_peer_sca { - std::function body{[](uint16_t conn_handle) {}}; + std::function body{[](uint16_t /* conn_handle */) {}}; void operator()(uint16_t conn_handle) { body(conn_handle); }; }; extern struct btsnd_hcic_req_peer_sca btsnd_hcic_req_peer_sca; @@ -721,11 +737,13 @@ struct btsnd_hcic_set_cig_params { std::function)> - body{[](uint8_t cig_id, uint32_t sdu_itv_mtos, uint32_t sdu_itv_stom, - uint8_t sca, uint8_t packing, uint8_t framing, - uint16_t max_trans_lat_stom, uint16_t max_trans_lat_mtos, - uint8_t cis_cnt, const EXT_CIS_CFG* cis_cfg, - base::OnceCallback cb) {}}; + body{[](uint8_t /* cig_id */, uint32_t /* sdu_itv_mtos */, + uint32_t /* sdu_itv_stom */, uint8_t /* sca */, + uint8_t /* packing */, uint8_t /* framing */, + uint16_t /* max_trans_lat_stom */, + uint16_t /* max_trans_lat_mtos */, uint8_t /* cis_cnt */, + const EXT_CIS_CFG* /* cis_cfg */, + base::OnceCallback /* cb */) {}}; void operator()(uint8_t cig_id, uint32_t sdu_itv_mtos, uint32_t sdu_itv_stom, uint8_t sca, uint8_t packing, uint8_t framing, uint16_t max_trans_lat_stom, uint16_t max_trans_lat_mtos, @@ -747,11 +765,12 @@ struct btsnd_hcic_setup_iso_data_path { std::function, base::OnceCallback)> - body{[](uint16_t iso_handle, uint8_t data_path_dir, uint8_t data_path_id, - uint8_t codec_id_format, uint16_t codec_id_company, - uint16_t codec_id_vendor, uint32_t controller_delay, - std::vector codec_conf, - base::OnceCallback cb) {}}; + body{[](uint16_t /* iso_handle */, uint8_t /* data_path_dir */, + uint8_t /* data_path_id */, uint8_t /* codec_id_format */, + uint16_t /* codec_id_company */, uint16_t /* codec_id_vendor */, + uint32_t /* controller_delay */, + std::vector /* codec_conf */, + base::OnceCallback /* cb */) {}}; void operator()(uint16_t iso_handle, uint8_t data_path_dir, uint8_t data_path_id, uint8_t codec_id_format, uint16_t codec_id_company, uint16_t codec_id_vendor, @@ -769,7 +788,7 @@ extern struct btsnd_hcic_setup_iso_data_path btsnd_hcic_setup_iso_data_path; // Return: void struct btsnd_hcic_term_big { std::function body{ - [](uint8_t big_handle, uint8_t reason) {}}; + [](uint8_t /* big_handle */, uint8_t /* reason */) {}}; void operator()(uint8_t big_handle, uint8_t reason) { body(big_handle, reason); }; diff --git a/system/test/mock/mock_stack_hcic_hcicmds.h b/system/test/mock/mock_stack_hcic_hcicmds.h index b0d5d3ef78fc13b910c2854286fcd13aa867f57a..232a60f6714928a3652363cac9dcd25e00e6113f 100644 --- a/system/test/mock/mock_stack_hcic_hcicmds.h +++ b/system/test/mock/mock_stack_hcic_hcicmds.h @@ -44,7 +44,7 @@ namespace stack_hcic_hcicmds { // Return: void struct btsnd_hcic_accept_conn { std::function body{ - [](const RawAddress& dest, uint8_t role) {}}; + [](const RawAddress& /* dest */, uint8_t /* role */) {}}; void operator()(const RawAddress& dest, uint8_t role) { body(dest, role); }; }; extern struct btsnd_hcic_accept_conn btsnd_hcic_accept_conn; @@ -58,10 +58,11 @@ struct btsnd_hcic_accept_esco_conn { uint32_t receive_bandwidth, uint16_t max_latency, uint16_t content_fmt, uint8_t retrans_effort, uint16_t packet_types)> - body{[](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) {}}; + body{[](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 operator()(const RawAddress& bd_addr, uint32_t transmit_bandwidth, uint32_t receive_bandwidth, uint16_t max_latency, uint16_t content_fmt, uint8_t retrans_effort, @@ -77,7 +78,7 @@ extern struct btsnd_hcic_accept_esco_conn btsnd_hcic_accept_esco_conn; // Return: void struct btsnd_hcic_add_SCO_conn { std::function body{ - [](uint16_t handle, uint16_t packet_types) {}}; + [](uint16_t /* handle */, uint16_t /* packet_types */) {}}; void operator()(uint16_t handle, uint16_t packet_types) { body(handle, packet_types); }; @@ -88,7 +89,7 @@ extern struct btsnd_hcic_add_SCO_conn btsnd_hcic_add_SCO_conn; // Params: uint16_t handle // Return: void struct btsnd_hcic_auth_request { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_auth_request btsnd_hcic_auth_request; @@ -97,7 +98,7 @@ extern struct btsnd_hcic_auth_request btsnd_hcic_auth_request; // Params: BD_NAME name // Return: void struct btsnd_hcic_change_name { - std::function body{[](BD_NAME name) {}}; + std::function body{[](BD_NAME /* name */) {}}; void operator()(BD_NAME name) { body(name); }; }; extern struct btsnd_hcic_change_name btsnd_hcic_change_name; @@ -107,7 +108,7 @@ extern struct btsnd_hcic_change_name btsnd_hcic_change_name; // Return: void struct btsnd_hcic_create_conn_cancel { std::function body{ - [](const RawAddress& dest) {}}; + [](const RawAddress& /* dest */) {}}; void operator()(const RawAddress& dest) { body(dest); }; }; extern struct btsnd_hcic_create_conn_cancel btsnd_hcic_create_conn_cancel; @@ -117,7 +118,7 @@ extern struct btsnd_hcic_create_conn_cancel btsnd_hcic_create_conn_cancel; // Return: void struct btsnd_hcic_delete_stored_key { std::function body{ - [](const RawAddress& bd_addr, bool delete_all_flag) {}}; + [](const RawAddress& /* bd_addr */, bool /* delete_all_flag */) {}}; void operator()(const RawAddress& bd_addr, bool delete_all_flag) { body(bd_addr, delete_all_flag); }; @@ -138,7 +139,8 @@ extern struct btsnd_hcic_enable_test_mode btsnd_hcic_enable_test_mode; // Return: void struct btsnd_hcic_enhanced_accept_synchronous_connection { std::function - body{[](const RawAddress& bd_addr, enh_esco_params_t* p_params) {}}; + body{[](const RawAddress& /* bd_addr */, + enh_esco_params_t* /* p_params */) {}}; void operator()(const RawAddress& bd_addr, enh_esco_params_t* p_params) { body(bd_addr, p_params); }; @@ -151,7 +153,7 @@ extern struct btsnd_hcic_enhanced_accept_synchronous_connection // Return: void struct btsnd_hcic_enhanced_flush { std::function body{ - [](uint16_t handle, uint8_t packet_type) {}}; + [](uint16_t /* handle */, uint8_t /* packet_type */) {}}; void operator()(uint16_t handle, uint8_t packet_type) { body(handle, packet_type); }; @@ -163,7 +165,7 @@ extern struct btsnd_hcic_enhanced_flush btsnd_hcic_enhanced_flush; // Return: void struct btsnd_hcic_enhanced_set_up_synchronous_connection { std::function body{ - [](uint16_t conn_handle, enh_esco_params_t* p_params) {}}; + [](uint16_t /* conn_handle */, enh_esco_params_t* /* p_params */) {}}; void operator()(uint16_t conn_handle, enh_esco_params_t* p_params) { body(conn_handle, p_params); }; @@ -175,7 +177,7 @@ extern struct btsnd_hcic_enhanced_set_up_synchronous_connection // Params: uint16_t handle // Return: void struct btsnd_hcic_exit_park_mode { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_exit_park_mode btsnd_hcic_exit_park_mode; @@ -184,7 +186,7 @@ extern struct btsnd_hcic_exit_park_mode btsnd_hcic_exit_park_mode; // Params: uint16_t handle // Return: void struct btsnd_hcic_exit_sniff_mode { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_exit_sniff_mode btsnd_hcic_exit_sniff_mode; @@ -195,8 +197,8 @@ extern struct btsnd_hcic_exit_sniff_mode btsnd_hcic_exit_sniff_mode; struct btsnd_hcic_hold_mode { std::function - body{[](uint16_t handle, uint16_t max_hold_period, - uint16_t min_hold_period) {}}; + body{[](uint16_t /* handle */, uint16_t /* max_hold_period */, + uint16_t /* min_hold_period */) {}}; void operator()(uint16_t handle, uint16_t max_hold_period, uint16_t min_hold_period) { body(handle, max_hold_period, min_hold_period); @@ -209,7 +211,7 @@ extern struct btsnd_hcic_hold_mode btsnd_hcic_hold_mode; // Return: void struct btsnd_hcic_io_cap_req_neg_reply { std::function body{ - [](const RawAddress& bd_addr, uint8_t err_code) {}}; + [](const RawAddress& /* bd_addr */, uint8_t /* err_code */) {}}; void operator()(const RawAddress& bd_addr, uint8_t err_code) { body(bd_addr, err_code); }; @@ -222,8 +224,8 @@ extern struct btsnd_hcic_io_cap_req_neg_reply btsnd_hcic_io_cap_req_neg_reply; struct btsnd_hcic_io_cap_req_reply { std::function - body{[](const RawAddress& bd_addr, uint8_t capability, - uint8_t oob_present, uint8_t auth_req) {}}; + body{[](const RawAddress& /* bd_addr */, uint8_t /* capability */, + uint8_t /* oob_present */, uint8_t /* auth_req */) {}}; void operator()(const RawAddress& bd_addr, uint8_t capability, uint8_t oob_present, uint8_t auth_req) { body(bd_addr, capability, oob_present, auth_req); @@ -236,7 +238,7 @@ extern struct btsnd_hcic_io_cap_req_reply btsnd_hcic_io_cap_req_reply; // Return: void struct btsnd_hcic_link_key_neg_reply { std::function body{ - [](const RawAddress& bd_addr) {}}; + [](const RawAddress& /* bd_addr */) {}}; void operator()(const RawAddress& bd_addr) { body(bd_addr); }; }; extern struct btsnd_hcic_link_key_neg_reply btsnd_hcic_link_key_neg_reply; @@ -246,7 +248,7 @@ extern struct btsnd_hcic_link_key_neg_reply btsnd_hcic_link_key_neg_reply; // Return: void struct btsnd_hcic_link_key_req_reply { std::function body{ - [](const RawAddress& bd_addr, const LinkKey& link_key) {}}; + [](const RawAddress& /* bd_addr */, const LinkKey& /* link_key */) {}}; void operator()(const RawAddress& bd_addr, const LinkKey& link_key) { body(bd_addr, link_key); }; @@ -259,8 +261,8 @@ extern struct btsnd_hcic_link_key_req_reply btsnd_hcic_link_key_req_reply; struct btsnd_hcic_park_mode { std::function - body{[](uint16_t handle, uint16_t beacon_max_interval, - uint16_t beacon_min_interval) {}}; + body{[](uint16_t /* handle */, uint16_t /* beacon_max_interval */, + uint16_t /* beacon_min_interval */) {}}; void operator()(uint16_t handle, uint16_t beacon_max_interval, uint16_t beacon_min_interval) { body(handle, beacon_max_interval, beacon_min_interval); @@ -273,7 +275,7 @@ extern struct btsnd_hcic_park_mode btsnd_hcic_park_mode; // Return: void struct btsnd_hcic_pin_code_neg_reply { std::function body{ - [](const RawAddress& bd_addr) {}}; + [](const RawAddress& /* bd_addr */) {}}; void operator()(const RawAddress& bd_addr) { body(bd_addr); }; }; extern struct btsnd_hcic_pin_code_neg_reply btsnd_hcic_pin_code_neg_reply; @@ -284,8 +286,8 @@ extern struct btsnd_hcic_pin_code_neg_reply btsnd_hcic_pin_code_neg_reply; struct btsnd_hcic_pin_code_req_reply { std::function - body{[](const RawAddress& bd_addr, uint8_t pin_code_len, - PIN_CODE pin_code) {}}; + body{[](const RawAddress& /* bd_addr */, uint8_t /* pin_code_len */, + PIN_CODE /* pin_code */) {}}; void operator()(const RawAddress& bd_addr, uint8_t pin_code_len, PIN_CODE pin_code) { body(bd_addr, pin_code_len, pin_code); @@ -298,7 +300,7 @@ extern struct btsnd_hcic_pin_code_req_reply btsnd_hcic_pin_code_req_reply; // Return: void struct btsnd_hcic_read_encryption_key_size { std::function body{ - [](uint16_t handle, ReadEncKeySizeCb cb) {}}; + [](uint16_t /* handle */, ReadEncKeySizeCb /* cb */) {}}; void operator()(uint16_t handle, ReadEncKeySizeCb cb) { body(handle, std::move(cb)); }; @@ -310,7 +312,7 @@ extern struct btsnd_hcic_read_encryption_key_size // Params: uint16_t handle // Return: void struct btsnd_hcic_read_failed_contact_counter { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_read_failed_contact_counter @@ -338,7 +340,7 @@ extern struct btsnd_hcic_read_name btsnd_hcic_read_name; // Params: uint16_t handle // Return: void struct btsnd_hcic_read_rmt_clk_offset { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_read_rmt_clk_offset btsnd_hcic_read_rmt_clk_offset; @@ -347,7 +349,7 @@ extern struct btsnd_hcic_read_rmt_clk_offset btsnd_hcic_read_rmt_clk_offset; // Params: uint16_t handle // Return: void struct btsnd_hcic_read_rssi { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_read_rssi btsnd_hcic_read_rssi; @@ -357,7 +359,7 @@ extern struct btsnd_hcic_read_rssi btsnd_hcic_read_rssi; // Return: void struct btsnd_hcic_read_tx_power { std::function body{ - [](uint16_t handle, uint8_t type) {}}; + [](uint16_t /* handle */, uint8_t /* type */) {}}; void operator()(uint16_t handle, uint8_t type) { body(handle, type); }; }; extern struct btsnd_hcic_read_tx_power btsnd_hcic_read_tx_power; @@ -367,7 +369,7 @@ extern struct btsnd_hcic_read_tx_power btsnd_hcic_read_tx_power; // Return: void struct btsnd_hcic_reject_conn { std::function body{ - [](const RawAddress& dest, uint8_t reason) {}}; + [](const RawAddress& /* dest */, uint8_t /* reason */) {}}; void operator()(const RawAddress& dest, uint8_t reason) { body(dest, reason); }; @@ -379,7 +381,7 @@ extern struct btsnd_hcic_reject_conn btsnd_hcic_reject_conn; // Return: void struct btsnd_hcic_reject_esco_conn { std::function body{ - [](const RawAddress& bd_addr, uint8_t reason) {}}; + [](const RawAddress& /* bd_addr */, uint8_t /* reason */) {}}; void operator()(const RawAddress& bd_addr, uint8_t reason) { body(bd_addr, reason); }; @@ -391,7 +393,7 @@ extern struct btsnd_hcic_reject_esco_conn btsnd_hcic_reject_esco_conn; // Return: void struct btsnd_hcic_rem_oob_neg_reply { std::function body{ - [](const RawAddress& bd_addr) {}}; + [](const RawAddress& /* bd_addr */) {}}; void operator()(const RawAddress& bd_addr) { body(bd_addr); }; }; extern struct btsnd_hcic_rem_oob_neg_reply btsnd_hcic_rem_oob_neg_reply; @@ -402,8 +404,8 @@ extern struct btsnd_hcic_rem_oob_neg_reply btsnd_hcic_rem_oob_neg_reply; struct btsnd_hcic_rem_oob_reply { std::function - body{ - [](const RawAddress& bd_addr, const Octet16& c, const Octet16& r) {}}; + body{[](const RawAddress& /* bd_addr */, const Octet16& /* c */, + const Octet16& /* r */) {}}; void operator()(const RawAddress& bd_addr, const Octet16& c, const Octet16& r) { body(bd_addr, c, r); @@ -416,7 +418,7 @@ extern struct btsnd_hcic_rem_oob_reply btsnd_hcic_rem_oob_reply; // Return: void struct btsnd_hcic_rmt_ext_features { std::function body{ - [](uint16_t handle, uint8_t page_num) {}}; + [](uint16_t /* handle */, uint8_t /* page_num */) {}}; void operator()(uint16_t handle, uint8_t page_num) { body(handle, page_num); }; @@ -429,8 +431,8 @@ extern struct btsnd_hcic_rmt_ext_features btsnd_hcic_rmt_ext_features; struct btsnd_hcic_rmt_name_req { std::function - body{[](const RawAddress& bd_addr, uint8_t page_scan_rep_mode, - uint8_t page_scan_mode, uint16_t clock_offset) {}}; + body{[](const RawAddress& /* bd_addr */, uint8_t /* page_scan_rep_mode */, + uint8_t /* page_scan_mode */, uint16_t /* clock_offset */) {}}; void operator()(const RawAddress& bd_addr, uint8_t page_scan_rep_mode, uint8_t page_scan_mode, uint16_t clock_offset) { body(bd_addr, page_scan_rep_mode, page_scan_mode, clock_offset); @@ -443,7 +445,7 @@ extern struct btsnd_hcic_rmt_name_req btsnd_hcic_rmt_name_req; // Return: void struct btsnd_hcic_rmt_name_req_cancel { std::function body{ - [](const RawAddress& bd_addr) {}}; + [](const RawAddress& /* bd_addr */) {}}; void operator()(const RawAddress& bd_addr) { body(bd_addr); }; }; extern struct btsnd_hcic_rmt_name_req_cancel btsnd_hcic_rmt_name_req_cancel; @@ -452,7 +454,7 @@ extern struct btsnd_hcic_rmt_name_req_cancel btsnd_hcic_rmt_name_req_cancel; // Params: uint16_t handle // Return: void struct btsnd_hcic_rmt_ver_req { - std::function body{[](uint16_t handle) {}}; + std::function body{[](uint16_t /* handle */) {}}; void operator()(uint16_t handle) { body(handle); }; }; extern struct btsnd_hcic_rmt_ver_req btsnd_hcic_rmt_ver_req; @@ -462,7 +464,7 @@ extern struct btsnd_hcic_rmt_ver_req btsnd_hcic_rmt_ver_req; // Return: void struct btsnd_hcic_set_conn_encrypt { std::function body{ - [](uint16_t handle, bool enable) {}}; + [](uint16_t /* handle */, bool /* enable */) {}}; void operator()(uint16_t handle, bool enable) { body(handle, enable); }; }; extern struct btsnd_hcic_set_conn_encrypt btsnd_hcic_set_conn_encrypt; @@ -473,8 +475,8 @@ extern struct btsnd_hcic_set_conn_encrypt btsnd_hcic_set_conn_encrypt; struct btsnd_hcic_set_event_filter { std::function - body{[](uint8_t filt_type, uint8_t filt_cond_type, uint8_t* filt_cond, - uint8_t filt_cond_len) {}}; + body{[](uint8_t /* filt_type */, uint8_t /* filt_cond_type */, + uint8_t* /* filt_cond */, uint8_t /* filt_cond_len */) {}}; void operator()(uint8_t filt_type, uint8_t filt_cond_type, uint8_t* filt_cond, uint8_t filt_cond_len) { body(filt_type, filt_cond_type, filt_cond, filt_cond_len); @@ -491,9 +493,10 @@ struct btsnd_hcic_setup_esco_conn { uint32_t receive_bandwidth, uint16_t max_latency, uint16_t voice, uint8_t retrans_effort, uint16_t packet_types)> - body{[](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) {}}; + body{[](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 operator()(uint16_t handle, uint32_t transmit_bandwidth, uint32_t receive_bandwidth, uint16_t max_latency, uint16_t voice, uint8_t retrans_effort, @@ -511,9 +514,9 @@ struct btsnd_hcic_sniff_mode { std::function - body{[](uint16_t handle, uint16_t max_sniff_period, - uint16_t min_sniff_period, uint16_t sniff_attempt, - uint16_t sniff_timeout) {}}; + body{[](uint16_t /* handle */, uint16_t /* max_sniff_period */, + uint16_t /* min_sniff_period */, uint16_t /* sniff_attempt */, + uint16_t /* sniff_timeout */) {}}; void operator()(uint16_t handle, uint16_t max_sniff_period, uint16_t min_sniff_period, uint16_t sniff_attempt, uint16_t sniff_timeout) { @@ -529,8 +532,8 @@ extern struct btsnd_hcic_sniff_mode btsnd_hcic_sniff_mode; struct btsnd_hcic_sniff_sub_rate { std::function - body{[](uint16_t handle, uint16_t max_lat, uint16_t min_remote_lat, - uint16_t min_local_lat) {}}; + body{[](uint16_t /* handle */, uint16_t /* max_lat */, + uint16_t /* min_remote_lat */, uint16_t /* min_local_lat */) {}}; void operator()(uint16_t handle, uint16_t max_lat, uint16_t min_remote_lat, uint16_t min_local_lat) { body(handle, max_lat, min_remote_lat, min_local_lat); @@ -543,7 +546,7 @@ extern struct btsnd_hcic_sniff_sub_rate btsnd_hcic_sniff_sub_rate; // Return: void struct btsnd_hcic_user_conf_reply { std::function body{ - [](const RawAddress& bd_addr, bool is_yes) {}}; + [](const RawAddress& /* bd_addr */, bool /* is_yes */) {}}; void operator()(const RawAddress& bd_addr, bool is_yes) { body(bd_addr, is_yes); }; @@ -555,7 +558,7 @@ extern struct btsnd_hcic_user_conf_reply btsnd_hcic_user_conf_reply; // Return: void struct btsnd_hcic_user_passkey_neg_reply { std::function body{ - [](const RawAddress& bd_addr) {}}; + [](const RawAddress& /* bd_addr */) {}}; void operator()(const RawAddress& bd_addr) { body(bd_addr); }; }; extern struct btsnd_hcic_user_passkey_neg_reply @@ -566,7 +569,7 @@ extern struct btsnd_hcic_user_passkey_neg_reply // Return: void struct btsnd_hcic_user_passkey_reply { std::function body{ - [](const RawAddress& bd_addr, uint32_t value) {}}; + [](const RawAddress& /* bd_addr */, uint32_t /* value */) {}}; void operator()(const RawAddress& bd_addr, uint32_t value) { body(bd_addr, value); }; @@ -579,8 +582,8 @@ extern struct btsnd_hcic_user_passkey_reply btsnd_hcic_user_passkey_reply; struct btsnd_hcic_vendor_spec_cmd { std::function - body{[](uint16_t opcode, uint8_t len, uint8_t* p_data, - tBTM_VSC_CMPL_CB* p_cmd_cplt_cback) {}}; + body{[](uint16_t /* opcode */, uint8_t /* len */, uint8_t* /* p_data */, + tBTM_VSC_CMPL_CB* /* p_cmd_cplt_cback */) {}}; void operator()(uint16_t opcode, uint8_t len, uint8_t* p_data, tBTM_VSC_CMPL_CB* p_cmd_cplt_cback) { body(opcode, len, p_data, p_cmd_cplt_cback); @@ -592,7 +595,7 @@ extern struct btsnd_hcic_vendor_spec_cmd btsnd_hcic_vendor_spec_cmd; // Params: uint8_t flag // Return: void struct btsnd_hcic_write_auth_enable { - std::function body{[](uint8_t flag) {}}; + std::function body{[](uint8_t /* flag */) {}}; void operator()(uint8_t flag) { body(flag); }; }; extern struct btsnd_hcic_write_auth_enable btsnd_hcic_write_auth_enable; @@ -602,7 +605,7 @@ extern struct btsnd_hcic_write_auth_enable btsnd_hcic_write_auth_enable; // Return: void struct btsnd_hcic_write_auto_flush_tout { std::function body{ - [](uint16_t handle, uint16_t tout) {}}; + [](uint16_t /* handle */, uint16_t /* tout */) {}}; void operator()(uint16_t handle, uint16_t tout) { body(handle, tout); }; }; extern struct btsnd_hcic_write_auto_flush_tout btsnd_hcic_write_auto_flush_tout; @@ -612,7 +615,7 @@ extern struct btsnd_hcic_write_auto_flush_tout btsnd_hcic_write_auto_flush_tout; // Return: void struct btsnd_hcic_write_cur_iac_lap { std::function body{ - [](uint8_t num_cur_iac, LAP* const iac_lap) {}}; + [](uint8_t /* num_cur_iac */, LAP* const /* iac_lap */) {}}; void operator()(uint8_t num_cur_iac, LAP* const iac_lap) { body(num_cur_iac, iac_lap); }; @@ -623,7 +626,7 @@ extern struct btsnd_hcic_write_cur_iac_lap btsnd_hcic_write_cur_iac_lap; // Params: uint16_t settings // Return: void struct btsnd_hcic_write_def_policy_set { - std::function body{[](uint16_t settings) {}}; + std::function body{[](uint16_t /* settings */) {}}; void operator()(uint16_t settings) { body(settings); }; }; extern struct btsnd_hcic_write_def_policy_set btsnd_hcic_write_def_policy_set; @@ -632,7 +635,8 @@ extern struct btsnd_hcic_write_def_policy_set btsnd_hcic_write_def_policy_set; // Params: DEV_CLASS dev_class // Return: void struct btsnd_hcic_write_dev_class { - std::function body{[](DEV_CLASS dev_class) {}}; + std::function body{ + [](DEV_CLASS /* dev_class */) {}}; void operator()(DEV_CLASS dev_class) { body(dev_class); }; }; extern struct btsnd_hcic_write_dev_class btsnd_hcic_write_dev_class; @@ -642,7 +646,7 @@ extern struct btsnd_hcic_write_dev_class btsnd_hcic_write_dev_class; // Return: void struct btsnd_hcic_write_ext_inquiry_response { std::function body{ - [](void* buffer, uint8_t fec_req) {}}; + [](void* /* buffer */, uint8_t /* fec_req */) {}}; void operator()(void* buffer, uint8_t fec_req) { body(buffer, fec_req); }; }; extern struct btsnd_hcic_write_ext_inquiry_response @@ -653,7 +657,7 @@ extern struct btsnd_hcic_write_ext_inquiry_response // Return: void struct btsnd_hcic_write_inqscan_cfg { std::function body{ - [](uint16_t interval, uint16_t window) {}}; + [](uint16_t /* interval */, uint16_t /* window */) {}}; void operator()(uint16_t interval, uint16_t window) { body(interval, window); }; @@ -664,7 +668,7 @@ extern struct btsnd_hcic_write_inqscan_cfg btsnd_hcic_write_inqscan_cfg; // Params: uint8_t type // Return: void struct btsnd_hcic_write_inqscan_type { - std::function body{[](uint8_t type) {}}; + std::function body{[](uint8_t /* type */) {}}; void operator()(uint8_t type) { body(type); }; }; extern struct btsnd_hcic_write_inqscan_type btsnd_hcic_write_inqscan_type; @@ -673,7 +677,7 @@ extern struct btsnd_hcic_write_inqscan_type btsnd_hcic_write_inqscan_type; // Params: uint8_t mode // Return: void struct btsnd_hcic_write_inquiry_mode { - std::function body{[](uint8_t mode) {}}; + std::function body{[](uint8_t /* mode */) {}}; void operator()(uint8_t mode) { body(mode); }; }; extern struct btsnd_hcic_write_inquiry_mode btsnd_hcic_write_inquiry_mode; @@ -683,7 +687,7 @@ extern struct btsnd_hcic_write_inquiry_mode btsnd_hcic_write_inquiry_mode; // Return: void struct btsnd_hcic_write_link_super_tout { std::function body{ - [](uint16_t handle, uint16_t timeout) {}}; + [](uint16_t /* handle */, uint16_t /* timeout */) {}}; void operator()(uint16_t handle, uint16_t timeout) { body(handle, timeout); }; }; extern struct btsnd_hcic_write_link_super_tout btsnd_hcic_write_link_super_tout; @@ -692,7 +696,7 @@ extern struct btsnd_hcic_write_link_super_tout btsnd_hcic_write_link_super_tout; // Params: uint16_t timeout // Return: void struct btsnd_hcic_write_page_tout { - std::function body{[](uint16_t timeout) {}}; + std::function body{[](uint16_t /* timeout */) {}}; void operator()(uint16_t timeout) { body(timeout); }; }; extern struct btsnd_hcic_write_page_tout btsnd_hcic_write_page_tout; @@ -702,7 +706,7 @@ extern struct btsnd_hcic_write_page_tout btsnd_hcic_write_page_tout; // Return: void struct btsnd_hcic_write_pagescan_cfg { std::function body{ - [](uint16_t interval, uint16_t window) {}}; + [](uint16_t /* interval */, uint16_t /* window */) {}}; void operator()(uint16_t interval, uint16_t window) { body(interval, window); }; @@ -713,7 +717,7 @@ extern struct btsnd_hcic_write_pagescan_cfg btsnd_hcic_write_pagescan_cfg; // Params: uint8_t type // Return: void struct btsnd_hcic_write_pagescan_type { - std::function body{[](uint8_t type) {}}; + std::function body{[](uint8_t /* type */) {}}; void operator()(uint8_t type) { body(type); }; }; extern struct btsnd_hcic_write_pagescan_type btsnd_hcic_write_pagescan_type; @@ -722,7 +726,7 @@ extern struct btsnd_hcic_write_pagescan_type btsnd_hcic_write_pagescan_type; // Params: uint8_t type // Return: void struct btsnd_hcic_write_pin_type { - std::function body{[](uint8_t type) {}}; + std::function body{[](uint8_t /* type */) {}}; void operator()(uint8_t type) { body(type); }; }; extern struct btsnd_hcic_write_pin_type btsnd_hcic_write_pin_type; @@ -732,7 +736,7 @@ extern struct btsnd_hcic_write_pin_type btsnd_hcic_write_pin_type; // Return: void struct btsnd_hcic_write_policy_set { std::function body{ - [](uint16_t handle, uint16_t settings) {}}; + [](uint16_t /* handle */, uint16_t /* settings */) {}}; void operator()(uint16_t handle, uint16_t settings) { body(handle, settings); }; @@ -743,7 +747,7 @@ extern struct btsnd_hcic_write_policy_set btsnd_hcic_write_policy_set; // Params: uint8_t flag // Return: void struct btsnd_hcic_write_scan_enable { - std::function body{[](uint8_t flag) {}}; + std::function body{[](uint8_t /* flag */) {}}; void operator()(uint8_t flag) { body(flag); }; }; extern struct btsnd_hcic_write_scan_enable btsnd_hcic_write_scan_enable; @@ -752,7 +756,7 @@ extern struct btsnd_hcic_write_scan_enable btsnd_hcic_write_scan_enable; // Params: uint16_t flags // Return: void struct btsnd_hcic_write_voice_settings { - std::function body{[](uint16_t flags) {}}; + std::function body{[](uint16_t /* flags */) {}}; void operator()(uint16_t flags) { body(flags); }; }; extern struct btsnd_hcic_write_voice_settings btsnd_hcic_write_voice_settings; diff --git a/system/test/mock/mock_stack_l2cap_ble.cc b/system/test/mock/mock_stack_l2cap_ble.cc index 8c0c6cfd280a98d1cc73c9cf0943cd10b16d10c5..de4a83166202f71dea3f86f35a561413a094e8d4 100644 --- a/system/test/mock/mock_stack_l2cap_ble.cc +++ b/system/test/mock/mock_stack_l2cap_ble.cc @@ -37,7 +37,10 @@ namespace stack_l2cap_ble { // Function state capture and return values, if needed struct L2CA_UpdateBleConnParams L2CA_UpdateBleConnParams; -struct L2CA_EnableUpdateBleConnParams L2CA_EnableUpdateBleConnParams; +struct L2CA_LockBleConnParamsForServiceDiscovery + L2CA_LockBleConnParamsForServiceDiscovery; +struct L2CA_LockBleConnParamsForProfileConnection + L2CA_LockBleConnParamsForProfileConnection; struct L2CA_ConsolidateParams L2CA_ConsolidateParams; struct L2CA_GetBleConnRole L2CA_GetBleConnRole; struct l2cble_notify_le_connection l2cble_notify_le_connection; @@ -75,10 +78,17 @@ bool L2CA_UpdateBleConnParams(const RawAddress& rem_bda, uint16_t min_int, return test::mock::stack_l2cap_ble::L2CA_UpdateBleConnParams( rem_bda, min_int, max_int, latency, timeout, min_ce_len, max_ce_len); } -bool L2CA_EnableUpdateBleConnParams(const RawAddress& rem_bda, bool enable) { +void L2CA_LockBleConnParamsForServiceDiscovery(const RawAddress& rem_bda, + bool enable) { inc_func_call_count(__func__); - return test::mock::stack_l2cap_ble::L2CA_EnableUpdateBleConnParams(rem_bda, - enable); + return test::mock::stack_l2cap_ble::L2CA_LockBleConnParamsForServiceDiscovery( + rem_bda, enable); +} +void L2CA_LockBleConnParamsForProfileConnection(const RawAddress& rem_bda, + bool enable) { + inc_func_call_count(__func__); + return test::mock::stack_l2cap_ble:: + L2CA_LockBleConnParamsForProfileConnection(rem_bda, enable); } void L2CA_Consolidate(const RawAddress& identity_addr, const RawAddress& rpa) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_stack_l2cap_ble.h b/system/test/mock/mock_stack_l2cap_ble.h index 5c21a06efc8d36994a36e884200ea544007b0d85..0b12f859d50a49bae7d1bf0ef6294e1dd049113b 100644 --- a/system/test/mock/mock_stack_l2cap_ble.h +++ b/system/test/mock/mock_stack_l2cap_ble.h @@ -56,20 +56,30 @@ struct L2CA_UpdateBleConnParams { }; }; extern struct L2CA_UpdateBleConnParams L2CA_UpdateBleConnParams; -// Name: L2CA_EnableUpdateBleConnParams +// Name: L2CA_LockBleConnParamsForServiceDiscovery // Params: const RawAddress& rem_bda, bool enable -// Returns: bool -struct L2CA_EnableUpdateBleConnParams { - std::function body{ +// Returns: void +struct L2CA_LockBleConnParamsForServiceDiscovery { + std::function body{ [](const RawAddress& /* rem_bda */, bool /* enable */) { return false; }}; - bool operator()(const RawAddress& rem_bda, bool enable) { + void operator()(const RawAddress& rem_bda, bool enable) { return body(rem_bda, enable); }; }; -extern struct L2CA_EnableUpdateBleConnParams L2CA_EnableUpdateBleConnParams; -// Name: L2CA_ConsolidateParams -// Params: const RawAddress& identity, const RawAddress& rpa -// Returns: bool +extern struct L2CA_LockBleConnParamsForServiceDiscovery + L2CA_LockBleConnParamsForServiceDiscovery; +// Name: L2CA_LockBleConnParamsForProfileConnection +// Params: const RawAddress& rem_bda, bool enable +// Returns: void +struct L2CA_LockBleConnParamsForProfileConnection { + std::function body{ + [](const RawAddress& /* rem_bda */, bool /* enable */) { return false; }}; + void operator()(const RawAddress& rem_bda, bool enable) { + return body(rem_bda, enable); + }; +}; +extern struct L2CA_LockBleConnParamsForProfileConnection + L2CA_LockBleConnParamsForProfileConnection; struct L2CA_ConsolidateParams { std::function body{[](const RawAddress& /* identity_addr */, diff --git a/system/test/mock/mock_stack_metrics_logging.h b/system/test/mock/mock_stack_metrics_logging.h index fd34980a107af2304264e2da4ffc244e24f68091..ca938a698e6a3acb2a99f294a31df514be07f3c4 100644 --- a/system/test/mock/mock_stack_metrics_logging.h +++ b/system/test/mock/mock_stack_metrics_logging.h @@ -44,9 +44,10 @@ struct log_classic_pairing_event { std::function - body{[](const RawAddress& address, uint16_t handle, uint32_t hci_cmd, - uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code, - int64_t event_value) {}}; + body{[](const RawAddress& /* address */, uint16_t /* handle */, + uint32_t /* hci_cmd */, uint16_t /* hci_event */, + uint16_t /* cmd_status */, uint16_t /* reason_code */, + int64_t /* event_value */) {}}; void operator()(const RawAddress& address, uint16_t handle, uint32_t hci_cmd, uint16_t hci_event, uint16_t cmd_status, uint16_t reason_code, int64_t event_value) { @@ -66,10 +67,11 @@ struct log_link_layer_connection_event { uint16_t link_type, uint32_t hci_cmd, uint16_t hci_event, uint16_t hci_ble_event, uint16_t cmd_status, uint16_t reason_code)> - body{[](const RawAddress* address, uint32_t connection_handle, - android::bluetooth::DirectionEnum direction, uint16_t link_type, - uint32_t hci_cmd, uint16_t hci_event, uint16_t hci_ble_event, - uint16_t cmd_status, uint16_t reason_code) {}}; + body{[](const RawAddress* /* address */, uint32_t /* connection_handle */, + android::bluetooth::DirectionEnum /* direction */, + uint16_t /* link_type */, uint32_t /* hci_cmd */, + uint16_t /* hci_event */, uint16_t /* hci_ble_event */, + uint16_t /* cmd_status */, uint16_t /* reason_code */) {}}; void operator()(const RawAddress* address, uint32_t connection_handle, android::bluetooth::DirectionEnum direction, uint16_t link_type, uint32_t hci_cmd, uint16_t hci_event, @@ -88,9 +90,9 @@ struct log_smp_pairing_event { std::function - body{[](const RawAddress& address, uint16_t smp_cmd, - android::bluetooth::DirectionEnum direction, - uint16_t smp_fail_reason) {}}; + body{[](const RawAddress& /* address */, uint16_t /* smp_cmd */, + android::bluetooth::DirectionEnum /* direction */, + uint16_t /* smp_fail_reason */) {}}; void operator()(const RawAddress& address, uint16_t smp_cmd, android::bluetooth::DirectionEnum direction, uint16_t smp_fail_reason) { @@ -106,9 +108,9 @@ struct log_sdp_attribute { std::function - body{[](const RawAddress& address, uint16_t protocol_uuid, - uint16_t attribute_id, size_t attribute_size, - const char* attribute_value) {}}; + body{[](const RawAddress& /* address */, uint16_t /* protocol_uuid */, + uint16_t /* attribute_id */, size_t /* attribute_size */, + const char* /* attribute_value */) {}}; void operator()(const RawAddress& address, uint16_t protocol_uuid, uint16_t attribute_id, size_t attribute_size, const char* attribute_value) { @@ -129,12 +131,14 @@ struct log_manufacturer_info { const std::string& manufacturer, const std::string& model, const std::string& hardware_version, const std::string& software_version)> - body2{[](const RawAddress& address, - android::bluetooth::AddressTypeEnum address_type, - android::bluetooth::DeviceInfoSrcEnum source_type, - const std::string& source_name, const std::string& manufacturer, - const std::string& model, const std::string& hardware_version, - const std::string& software_version) {}}; + body2{[](const RawAddress& /* address */, + android::bluetooth::AddressTypeEnum /* address_type */, + android::bluetooth::DeviceInfoSrcEnum /* source_type */, + const std::string& /* source_name */, + const std::string& /* manufacturer */, + const std::string& /* model */, + const std::string& /* hardware_version */, + const std::string& /* software_version */) {}}; void operator()(const RawAddress& address, android::bluetooth::AddressTypeEnum address_type, android::bluetooth::DeviceInfoSrcEnum source_type, @@ -151,11 +155,13 @@ struct log_manufacturer_info { const std::string& manufacturer, const std::string& model, const std::string& hardware_version, const std::string& software_version)> - body{[](const RawAddress& address, - android::bluetooth::DeviceInfoSrcEnum source_type, - const std::string& source_name, const std::string& manufacturer, - const std::string& model, const std::string& hardware_version, - const std::string& software_version) {}}; + body{[](const RawAddress& /* address */, + android::bluetooth::DeviceInfoSrcEnum /* source_type */, + const std::string& /* source_name */, + const std::string& /* manufacturer */, + const std::string& /* model */, + const std::string& /* hardware_version */, + const std::string& /* software_version */) {}}; void operator()(const RawAddress& address, android::bluetooth::DeviceInfoSrcEnum source_type, const std::string& source_name, @@ -172,8 +178,8 @@ extern struct log_manufacturer_info log_manufacturer_info; struct log_counter_metrics { std::function - body{ - [](android::bluetooth::CodePathCounterKeyEnum key, int64_t value) {}}; + body{[](android::bluetooth::CodePathCounterKeyEnum /* key */, + int64_t /* value */) {}}; void operator()(android::bluetooth::CodePathCounterKeyEnum key, int64_t value) { body(key, value); @@ -185,8 +191,8 @@ extern struct log_counter_metrics log_counter_metrics; struct log_hfp_audio_packet_loss_stats { std::function - body{[](const RawAddress& address, int num_decoded_frames, - double packet_loss_ratio, uint16_t codec_type) {}}; + body{[](const RawAddress& /* address */, int /* num_decoded_frames */, + double /* packet_loss_ratio */, uint16_t /* codec_type */) {}}; void operator()(const RawAddress& address, int num_decoded_frames, double packet_loss_ratio, uint16_t codec_type) { body(address, num_decoded_frames, packet_loss_ratio, codec_type); @@ -198,8 +204,8 @@ extern struct log_hfp_audio_packet_loss_stats log_hfp_audio_packet_loss_stats; struct log_mmc_transcode_rtt_stats { std::function - body{[](int maximum_rtt, double mean_rtt, int num_requests, - int codec_type) {}}; + body{[](int /* maximum_rtt */, double /* mean_rtt */, + int /* num_requests */, int /* codec_type */) {}}; void operator()(int maximum_rtt, double mean_rtt, int num_requests, int codec_type) { body(maximum_rtt, mean_rtt, num_requests, codec_type); diff --git a/system/test/mock/mock_stack_smp_api.cc b/system/test/mock/mock_stack_smp_api.cc index faeef318d8548c400c99c1b99aaf63843fb2159c..f71c260609e418cd0b4005e22b90649f83a6d45a 100644 --- a/system/test/mock/mock_stack_smp_api.cc +++ b/system/test/mock/mock_stack_smp_api.cc @@ -19,7 +19,6 @@ * Functions generated:11 */ -#include "stack/btm/btm_dev.h" #include "stack/include/smp_api.h" #include "test/common/mock_functions.h" #include "types/raw_address.h" diff --git a/system/test/stub/osi.cc b/system/test/stub/osi.cc index 6643ad7b5c98843f8b9e6bfc6aa681f7884adbcd..894c009886ee5c6b6479a7e60188423adfa8ef4b 100644 --- a/system/test/stub/osi.cc +++ b/system/test/stub/osi.cc @@ -26,6 +26,7 @@ #include #include +#include "os/log.h" #include "osi/include/alarm.h" #include "osi/include/allocator.h" #include "osi/include/config.h" @@ -33,7 +34,6 @@ #include "osi/include/future.h" #include "osi/include/hash_map_utils.h" #include "osi/include/list.h" -#include "osi/include/log.h" #include "osi/include/reactor.h" #include "osi/include/ringbuffer.h" #include "osi/include/socket.h" @@ -47,6 +47,22 @@ #define UNUSED_ATTR #endif +OsiObject::OsiObject(void* ptr) : ptr_(ptr) {} + +OsiObject::OsiObject(const void* ptr) : ptr_(const_cast(ptr)) {} + +OsiObject::~OsiObject() { + if (ptr_ != nullptr) { + osi_free(ptr_); + } +} + +void* OsiObject::Release() { + void* ptr = ptr_; + ptr_ = nullptr; + return ptr; +} + struct StringComparison { bool operator()(char const* lhs, char const* rhs) const { return strcmp(lhs, rhs) < 0; diff --git a/system/test/suite/Android.bp b/system/test/suite/Android.bp index 1234a49397cc3dc0edac0543fa5e5386357aa198..fcfe5c88fa105bf77335c46dce701ff4a423d3f9 100644 --- a/system/test/suite/Android.bp +++ b/system/test/suite/Android.bp @@ -19,13 +19,11 @@ cc_defaults { "packages/modules/Bluetooth/system/bta/sys", "packages/modules/Bluetooth/system/btif/avrcp", "packages/modules/Bluetooth/system/btif/co", - "packages/modules/Bluetooth/system/btif/include", "packages/modules/Bluetooth/system/device/include", "packages/modules/Bluetooth/system/embdrv/sbc/decoder/include", "packages/modules/Bluetooth/system/embdrv/sbc/encoder/include", "packages/modules/Bluetooth/system/gd", "packages/modules/Bluetooth/system/include", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/a2dp", "packages/modules/Bluetooth/system/stack/avdt", "packages/modules/Bluetooth/system/stack/btm", @@ -71,6 +69,8 @@ cc_defaults { "libbluetooth-types", "libbluetooth_core_rs", "libbluetooth_core_rs_bridge", + "libbluetooth_log", + "libbt-audio-asrc", "libbt-audio-hal-interface", "libbt-bta", "libbt-bta-core", @@ -117,9 +117,13 @@ cc_test { "gatt/gatt_unittest.cc", ], static_libs: [ + "libbluetooth-gdx", "libbluetooth_crypto_toolbox", "libbluetooth_gd", + "libbluetooth_hci_pdl", + "libbluetooth_log", "libbt-btu-main-thread", + "libbt-jni-thread", "libbt-platform-protos-lite", "libbt_shim_bridge", "libchrome", @@ -127,8 +131,12 @@ cc_test { "libprotobuf-cpp-lite", ], shared_libs: [ + "libbase", "server_configurable_flags", ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + ], target: { android: { static_libs: [ diff --git a/system/test/tool/mockcify.pl b/system/test/tool/mockcify.pl index dd974c0aaeb6f6146a026bbe84e29cf966c52a1d..724f26d03cd31bf5a898bbf6c9bf9c1f405a3ece 100755 --- a/system/test/tool/mockcify.pl +++ b/system/test/tool/mockcify.pl @@ -264,7 +264,7 @@ sub compilation_screen { my $link="test/mock/$hdr"; unlink "$INCDIR/$link"; symlink "$OUTDIR/$hdr", "$INCDIR/$link"; - system("$CC -c -std=c++17 -o /dev/null -D" . join(" -D", @defs) . " -I" . join(" -I", @incs) . " $OUTDIR/$src"); + system("$CC -c -std=c++20 -o /dev/null -D" . join(" -D", @defs) . " -I" . join(" -I", @incs) . " $OUTDIR/$src"); my $rc = $?; ($? == 0) ? printf(STDERR "SUCCESS Compiled unit \'$src\'\n") diff --git a/system/types/Android.bp b/system/types/Android.bp index e556f8e5f25be0a0be519800610b160dae4c56cb..742d6d3efb84d29fb9e54758dd01da3c27c5b8b7 100644 --- a/system/types/Android.bp +++ b/system/types/Android.bp @@ -41,7 +41,6 @@ cc_library_static { host_supported: true, srcs: [ "bluetooth/uuid.cc", - "class_of_device.cc", "raw_address.cc", ], static_libs: ["libchrome"], @@ -68,13 +67,13 @@ cc_test { ], include_dirs: [ "packages/modules/Bluetooth/system", + "packages/modules/Bluetooth/system/include", ], host_supported: true, srcs: [ "test/ble_address_with_type_unittest.cc", "test/bluetooth/uuid_unittest.cc", "test/bt_name_test.cc", - "test/class_of_device_unittest.cc", "test/raw_address_unittest.cc", ], shared_libs: ["liblog"], diff --git a/system/types/BUILD.gn b/system/types/BUILD.gn index 407c12b9eeab2d75ec654093cc22b0e3455f75f6..92159efc0dc84ae45583c6fd92b23b308170b7ae 100644 --- a/system/types/BUILD.gn +++ b/system/types/BUILD.gn @@ -20,7 +20,6 @@ static_library("types") { ] sources = [ - "class_of_device.cc", "bluetooth/uuid.cc", "raw_address.cc", ] @@ -37,7 +36,6 @@ static_library("types") { if (use.test) { executable("net_test_types") { sources = [ - "test/class_of_device_unittest.cc", "test/raw_address_unittest.cc", "test/bluetooth/uuid_unittest.cc", ] diff --git a/system/types/ble_address_with_type.h b/system/types/ble_address_with_type.h index 90aefdd28907e7e42e3ba32da81caf3b3b684b33..5c0f5318c78b1591055793c3f777ae98499dd4e2 100644 --- a/system/types/ble_address_with_type.h +++ b/system/types/ble_address_with_type.h @@ -18,6 +18,8 @@ #include #include + +#include "types/bt_transport.h" #include "types/raw_address.h" #define BLE_ADDR_PUBLIC 0x00 @@ -149,4 +151,40 @@ struct std::hash { } }; +struct tAclLinkSpec { + tBLE_BD_ADDR addrt; + tBT_TRANSPORT transport; + + bool operator==(const tAclLinkSpec rhs) const { + if (rhs.addrt != addrt) return false; + + if (rhs.transport == BT_TRANSPORT_AUTO || transport == BT_TRANSPORT_AUTO) { + return true; + } + + return rhs.transport == transport; + } + + bool operator!=(const tAclLinkSpec rhs) const { return !(*this == rhs); } + + bool StrictlyEquals(const tAclLinkSpec rhs) const { + return rhs.addrt == addrt && rhs.transport == transport; + } + + std::string ToString() const { + return std::string(addrt.ToString() + "[" + bt_transport_text(transport) + + "]"); + } + + std::string ToStringForLogging() const { + return addrt.ToStringForLogging() + "[" + bt_transport_text(transport) + + "]"; + } + + std::string ToRedactedStringForLogging() const { + return addrt.ToRedactedStringForLogging() + "[" + + bt_transport_text(transport) + "]"; + } +}; + #endif diff --git a/system/types/bluetooth/uuid.h b/system/types/bluetooth/uuid.h index f3e6ec2f1feb2a03872494457ff977fb0ffcd22b..0bdab40fce4f42584e9119b0828c72c8fd2e2820 100644 --- a/system/types/bluetooth/uuid.h +++ b/system/types/bluetooth/uuid.h @@ -19,6 +19,7 @@ #pragma once #include + #include #include @@ -145,3 +146,16 @@ struct hash { }; } // namespace std + +// This file is used outside bluetooth in components +// that do not have access to bluetooth/log.h +#if __has_include() + +#include + +namespace fmt { +template <> +struct formatter : ostream_formatter {}; +} // namespace fmt + +#endif // __has_include() diff --git a/system/types/class_of_device.cc b/system/types/class_of_device.cc deleted file mode 100644 index 775a412a35096292e9963d1b4488070b6ade0cf5..0000000000000000000000000000000000000000 --- a/system/types/class_of_device.cc +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** - * - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#include "class_of_device.h" - -#include -#include -#include -#include -#include - -static_assert(sizeof(ClassOfDevice) == ClassOfDevice::kLength, - "ClassOfDevice must be 3 bytes long!"); - -ClassOfDevice::ClassOfDevice(const uint8_t (&class_of_device)[kLength]) { - std::copy(class_of_device, class_of_device + kLength, cod); -}; - -std::string ClassOfDevice::ToString() const { - return base::StringPrintf("%03x-%01x-%02x", - (static_cast(cod[2]) << 4) | cod[1] >> 4, - cod[1] & 0x0f, cod[0]); -} - -bool ClassOfDevice::FromString(const std::string& from, ClassOfDevice& to) { - ClassOfDevice new_cod; - if (from.length() != 8) return false; - - std::vector byte_tokens = - base::SplitString(from, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - if (byte_tokens.size() != 3) return false; - if (byte_tokens[0].length() != 3) return false; - if (byte_tokens[1].length() != 1) return false; - if (byte_tokens[2].length() != 2) return false; - - uint16_t values[3]; - - for (size_t i = 0; i < kLength; i++) { - const auto& token = byte_tokens[i]; - - char* temp = nullptr; - values[i] = strtol(token.c_str(), &temp, 16); - if (*temp != '\0') return false; - } - - new_cod.cod[0] = values[2]; - new_cod.cod[1] = values[1] | ((values[0] & 0xf) << 4); - new_cod.cod[2] = values[0] >> 4; - - to = new_cod; - return true; -} - -size_t ClassOfDevice::FromOctets(const uint8_t* from) { - std::copy(from, from + kLength, cod); - return kLength; -}; - -bool ClassOfDevice::IsValid(const std::string& cod) { - ClassOfDevice tmp; - return ClassOfDevice::FromString(cod, tmp); -} diff --git a/system/types/class_of_device.h b/system/types/class_of_device.h deleted file mode 100644 index 7a2ec0301b853bf0ee3a2b1e625db37d8aa5344f..0000000000000000000000000000000000000000 --- a/system/types/class_of_device.h +++ /dev/null @@ -1,64 +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 -#include -#include - -namespace bluetooth { -namespace types { - -/** Bluetooth Class of Device */ -class ClassOfDevice final { - public: - static constexpr unsigned int kLength = 3; - - uint8_t cod[kLength]; - - ClassOfDevice() = default; - ClassOfDevice(const uint8_t (&class_of_device)[kLength]); - - bool operator==(const ClassOfDevice& rhs) const { - return (std::memcmp(cod, rhs.cod, sizeof(cod)) == 0); - } - - std::string ToString() const; - - // Converts |string| to ClassOfDevice and places it in |to|. If |from| does - // not represent a Class of Device, |to| is not modified and this function - // returns false. Otherwise, it returns true. - static bool FromString(const std::string& from, ClassOfDevice& to); - - // Copies |from| raw Class of Device octets to the local object. - // Returns the number of copied octets (always ClassOfDevice::kLength) - size_t FromOctets(const uint8_t* from); - - static bool IsValid(const std::string& class_of_device); -}; - -inline std::ostream& operator<<(std::ostream& os, const ClassOfDevice& c) { - os << c.ToString(); - return os; -} - -} // namespace types -} // namespace bluetooth - -using ::bluetooth::types::ClassOfDevice; // TODO, remove diff --git a/system/types/hci_role.h b/system/types/hci_role.h index eb582b8212bf5d423be4bd4012dd594b03f37534..bdd0940756b5e1b1eadeb2b12604e0448b60c873 100644 --- a/system/types/hci_role.h +++ b/system/types/hci_role.h @@ -47,3 +47,14 @@ inline tHCI_ROLE to_hci_role(const uint8_t& role) { typedef tHCI_ROLE hci_role_t; // LEGACY const auto RoleText = hci_role_text; // LEGACY + +#if __has_include() + +#include + +namespace fmt { +template <> +struct formatter : enum_formatter {}; +} // namespace fmt + +#endif // __has_include() diff --git a/system/types/test/ble_address_with_type_unittest.cc b/system/types/test/ble_address_with_type_unittest.cc index 5332d99e28666dd6b4b199a49c916dc44f219be1..60eaffb0c0caaacff6928f5ffb34789a1aebf614 100644 --- a/system/types/test/ble_address_with_type_unittest.cc +++ b/system/types/test/ble_address_with_type_unittest.cc @@ -17,6 +17,8 @@ #include "types/ble_address_with_type.h" #include +static constexpr uint8_t RAW_ADDRESS_TEST1[6] = {0x01, 0x02, 0x03, + 0x04, 0x05, 0x06}; TEST(BleAddressWithTypeTest, to_ble_addr_type) { for (unsigned i = 0; i < 0xff + 1; i++) { @@ -97,6 +99,23 @@ TEST(BleAddressWithTypeTest, STREAM_TO_BLE_ADDR_TYPE) { } } +TEST(BleAddressWithTypeTest, TYPED_ADDRESS_TRANSPORT) { + tAclLinkSpec linkSpecA = {{BLE_ADDR_PUBLIC, RAW_ADDRESS_TEST1}, + BT_TRANSPORT_AUTO}; + tAclLinkSpec linkSpecB = {{BLE_ADDR_PUBLIC, RAW_ADDRESS_TEST1}, + BT_TRANSPORT_BR_EDR}; + tAclLinkSpec linkSpecC = {{BLE_ADDR_PUBLIC, RAW_ADDRESS_TEST1}, + BT_TRANSPORT_LE}; + + ASSERT_EQ(linkSpecA, linkSpecB); + ASSERT_EQ(linkSpecA, linkSpecC); + ASSERT_NE(linkSpecB, linkSpecC); + + ASSERT_FALSE(linkSpecA.StrictlyEquals(linkSpecB)); + ASSERT_FALSE(linkSpecA.StrictlyEquals(linkSpecC)); + ASSERT_FALSE(linkSpecB.StrictlyEquals(linkSpecC)); +} + TEST(BleAddressWithTypeTest, BLE_ADDR_TYPE_TO_STREAM) { uint8_t buf[256] = {0}; uint8_t* p = buf; diff --git a/system/types/test/class_of_device_unittest.cc b/system/types/test/class_of_device_unittest.cc deleted file mode 100644 index 5d652a5bf5474c9c0aae1a52e0d42037d160787c..0000000000000000000000000000000000000000 --- a/system/types/test/class_of_device_unittest.cc +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** - * - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -#include - -#include "class_of_device.h" - -static const char* test_class = "efc-d-ab"; -static const uint8_t test_bytes[]{0xab, 0xcd, 0xef}; - -TEST(ClassOfDeviceUnittest, test_constructor_array) { - ClassOfDevice cod(test_bytes); - - ASSERT_EQ(test_bytes[0], cod.cod[0]); - ASSERT_EQ(test_bytes[1], cod.cod[1]); - ASSERT_EQ(test_bytes[2], cod.cod[2]); - - std::string ret = cod.ToString(); - - ASSERT_STREQ(test_class, ret.c_str()); -} - -TEST(ClassOfDeviceUnittest, test_to_from_str) { - ClassOfDevice cod; - ClassOfDevice::FromString(test_class, cod); - - ASSERT_EQ(test_bytes[0], cod.cod[0]); - ASSERT_EQ(test_bytes[1], cod.cod[1]); - ASSERT_EQ(test_bytes[2], cod.cod[2]); - - std::string ret = cod.ToString(); - - ASSERT_STREQ(test_class, ret.c_str()); -} - -TEST(ClassOfDeviceUnittest, test_from_octets) { - ClassOfDevice cod; - size_t expected_result = ClassOfDevice::kLength; - ASSERT_EQ(expected_result, cod.FromOctets(test_bytes)); - - ASSERT_EQ(test_bytes[0], cod.cod[0]); - ASSERT_EQ(test_bytes[1], cod.cod[1]); - ASSERT_EQ(test_bytes[2], cod.cod[2]); - - std::string ret = cod.ToString(); - - ASSERT_STREQ(test_class, ret.c_str()); -} - -TEST(ClassOfDeviceTest, test_copy) { - ClassOfDevice cod1; - ClassOfDevice cod2; - ClassOfDevice::FromString(test_class, cod1); - cod2 = cod1; - - ASSERT_EQ(cod1.cod[0], cod2.cod[0]); - ASSERT_EQ(cod1.cod[1], cod2.cod[1]); - ASSERT_EQ(cod1.cod[2], cod2.cod[2]); -} - -TEST(ClassOfDeviceTest, IsValid) { - EXPECT_FALSE(ClassOfDevice::IsValid("")); - EXPECT_FALSE(ClassOfDevice::IsValid("000000")); - EXPECT_FALSE(ClassOfDevice::IsValid("00-00-00")); - EXPECT_FALSE(ClassOfDevice::IsValid("000-0-0")); - EXPECT_TRUE(ClassOfDevice::IsValid("000-0-00")); - EXPECT_TRUE(ClassOfDevice::IsValid("ABc-d-00")); - EXPECT_TRUE(ClassOfDevice::IsValid("aBc-D-eF")); -} - -TEST(ClassOfDeviceTest, classOfDeviceFromString) { - ClassOfDevice cod; - - EXPECT_TRUE(ClassOfDevice::FromString("000-0-00", cod)); - const ClassOfDevice result0 = {{0x00, 0x00, 0x00}}; - EXPECT_EQ(0, memcmp(&cod, &result0, sizeof(cod))); - - EXPECT_TRUE(ClassOfDevice::FromString("ab2-1-4C", cod)); - const ClassOfDevice result1 = {{0x4c, 0x21, 0xab}}; - EXPECT_EQ(0, memcmp(&cod, &result1, sizeof(cod))); -} diff --git a/system/udrv/Android.bp b/system/udrv/Android.bp index 2f89f4729659b288fc026979c7aa0e52803173db..0e8be074e0cdf9e5c31c5eef8275cbcaa2dee7b9 100644 --- a/system/udrv/Android.bp +++ b/system/udrv/Android.bp @@ -16,7 +16,6 @@ cc_library_static { include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/gd", - "packages/modules/Bluetooth/system/internal_include", "packages/modules/Bluetooth/system/stack/include", ], local_include_dirs: [ @@ -29,5 +28,8 @@ cc_library_static { ], min_sdk_version: "Tiramisu", header_libs: ["libbluetooth_headers"], - static_libs: ["libbt_shim_bridge"], + static_libs: [ + "libbluetooth_log", + "libbt_shim_bridge", + ], } diff --git a/system/udrv/BUILD.gn b/system/udrv/BUILD.gn index 849f260d8d7568fbb86088f856c449f97f0760d4..2c872d6470d2cb653792a52ccf5b4988de8c191f 100644 --- a/system/udrv/BUILD.gn +++ b/system/udrv/BUILD.gn @@ -23,12 +23,12 @@ source_set("udrv") { "include", "uipc", "//bt/system/", - "//bt/system/internal_include", "//bt/system/stack/include", ] configs += [ "//bt/system:target_defaults", + "//bt/system/log:log_defaults", ] deps = [ diff --git a/tools/rootcanal/Android.bp b/tools/rootcanal/Android.bp index a30c69b309d12bf3651b704a96d274fc3d9da4ae..20447c8fad0dc6ff942a64128ba72bb9faa6da5e 100644 --- a/tools/rootcanal/Android.bp +++ b/tools/rootcanal/Android.bp @@ -38,7 +38,7 @@ cc_defaults { misc_undefined: ["bounds"], }, c_std: "c99", - cpp_std: "c++17", + cpp_std: "c++20", cflags: [ "-DGOOGLE_PROTOBUF_NO_RTTI", "-Wall", @@ -309,9 +309,11 @@ python_test_host { "test/LL/CIS/CEN/*.py", "test/LL/CIS/PER/*.py", "test/LL/CON_/CEN/*.py", + "test/LL/CON_/INI/*.py", "test/LL/CON_/PER/*.py", "test/LL/DDI/ADV/*.py", "test/LL/DDI/SCN/*.py", + "test/LL/SEC/ADV/*.py", "test/LMP/*.py", "test/LMP/LIH/*.py", "test/main.py", @@ -343,6 +345,7 @@ cc_test_host { srcs: [ "test/async_manager_unittest.cc", "test/h4_parser_unittest.cc", + "test/invalid_packet_handler_unittest.cc", "test/pcap_filter_unittest.cc", "test/posix_socket_unittest.cc", ], @@ -354,6 +357,8 @@ cc_test_host { ], shared_libs: [ "libbase", + "libcrypto", + "libprotobuf-cpp-full", ], static_libs: [ "libbt-rootcanal", diff --git a/tools/rootcanal/include/hci/address.h b/tools/rootcanal/include/hci/address.h index 74f93907229ed6e09f8d8ac26c7b40983585d189..18b38ee8d3be03a6f67c1405a1129d5b266eb3bc 100644 --- a/tools/rootcanal/include/hci/address.h +++ b/tools/rootcanal/include/hci/address.h @@ -123,7 +123,7 @@ struct fmt::formatter { // Check if reached the end of the range: if (it != end && *it != '}') { - ctx.on_error("invalid format"); + throw_format_error("invalid format"); } // Return an iterator past the end of the parsed range: diff --git a/tools/rootcanal/include/hci/address_with_type.h b/tools/rootcanal/include/hci/address_with_type.h index 01968b8c251492a70db444f414903dfe188f88e1..65c4223ef271fe6c88e6475f426c22445c992d1b 100644 --- a/tools/rootcanal/include/hci/address_with_type.h +++ b/tools/rootcanal/include/hci/address_with_type.h @@ -157,7 +157,7 @@ struct fmt::formatter { // Check if reached the end of the range: if (it != end && *it != '}') { - ctx.on_error("invalid format"); + throw_format_error("invalid format"); } // Return an iterator past the end of the parsed range: diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc index c7bee2c2dcd37d5fb2b0d0fe66ffb43b9b0438e1..d7f7dc28db40db9b15096a559542eac0da695814 100644 --- a/tools/rootcanal/model/controller/dual_mode_controller.cc +++ b/tools/rootcanal/model/controller/dual_mode_controller.cc @@ -52,6 +52,14 @@ constexpr uint8_t kTransmitPowerLevel = -20; constexpr bool kLeApcfTransportDiscoveryDataFilterSupported = true; constexpr bool kLeApcfAdTypeFilterSupported = true; +#define CHECK_PACKET_VIEW(view) \ + do { \ + if (!CheckPacketView(view, fmt::format("{}:{} - {}() invalid packet", \ + __FILE__, __LINE__, __func__))) { \ + return; \ + } \ + } while (0) + void DualModeController::SetProperties(ControllerProperties properties) { WARNING(id_, "updating the device properties!"); properties_ = std::move(properties); @@ -89,6 +97,12 @@ DualModeController::DualModeController(ControllerProperties properties) ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address)); SetAddress(public_address); + // Default invalid packet handler will abort the controller + // when receiving an invalid packet. + invalid_packet_handler_ = + [](uint32_t, InvalidPacketReason, std::string message, + std::vector const&) { FATAL("{}", message); }; + link_layer_controller_.RegisterRemoteChannel( [this](std::shared_ptr packet, Phy::Type phy_type, int8_t tx_power) { @@ -109,7 +123,8 @@ void DualModeController::ForwardToLl(CommandView command) { void DualModeController::HandleAcl( std::shared_ptr> packet) { auto acl_packet = bluetooth::hci::AclView::Create(pdl::packet::slice(packet)); - ASSERT(acl_packet.IsValid()); + CHECK_PACKET_VIEW(acl_packet); + if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) { uint16_t handle = acl_packet.GetHandle(); @@ -134,7 +149,8 @@ void DualModeController::HandleAcl( void DualModeController::HandleSco( std::shared_ptr> packet) { auto sco_packet = bluetooth::hci::ScoView::Create(pdl::packet::slice(packet)); - ASSERT(sco_packet.IsValid()); + CHECK_PACKET_VIEW(sco_packet); + if (loopback_mode_ == LoopbackMode::ENABLE_LOCAL) { uint16_t handle = sco_packet.GetHandle(); @@ -159,7 +175,7 @@ void DualModeController::HandleSco( void DualModeController::HandleIso( std::shared_ptr> packet) { auto iso = bluetooth::hci::IsoView::Create(pdl::packet::slice(packet)); - ASSERT(iso.IsValid()); + CHECK_PACKET_VIEW(iso); link_layer_controller_.HandleIso(iso); } @@ -167,7 +183,7 @@ void DualModeController::HandleCommand( std::shared_ptr> packet) { auto command_packet = bluetooth::hci::CommandView::Create(pdl::packet::slice(packet)); - ASSERT(command_packet.IsValid()); + CHECK_PACKET_VIEW(command_packet); OpCode op_code = command_packet.GetOpCode(); const bool is_vendor_command = (static_cast(op_code) >> 10) == 0x3f; @@ -237,6 +253,13 @@ void DualModeController::HandleCommand( } } +void DualModeController::RegisterInvalidPacketHandler( + const std::function const&)>& handler) { + INFO(id_, "updating the invalid packet handler"); + invalid_packet_handler_ = handler; +} + void DualModeController::RegisterEventChannel( const std::function>)>& send_event) { @@ -284,7 +307,7 @@ void DualModeController::RegisterIsoChannel( void DualModeController::Reset(CommandView command) { auto command_view = bluetooth::hci::ResetView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Reset"); @@ -298,7 +321,7 @@ void DualModeController::Reset(CommandView command) { void DualModeController::ReadBufferSize(CommandView command) { auto command_view = bluetooth::hci::ReadBufferSizeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Buffer Size"); @@ -312,7 +335,7 @@ void DualModeController::ReadBufferSize(CommandView command) { void DualModeController::ReadFailedContactCounter(CommandView command) { auto command_view = bluetooth::hci::ReadFailedContactCounterView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); uint16_t failed_contact_counter = 0; @@ -330,7 +353,7 @@ void DualModeController::ReadFailedContactCounter(CommandView command) { void DualModeController::ResetFailedContactCounter(CommandView command) { auto command_view = bluetooth::hci::ReadFailedContactCounterView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Reset Failed Contact Counter"); @@ -346,7 +369,7 @@ void DualModeController::ResetFailedContactCounter(CommandView command) { void DualModeController::ReadRssi(CommandView command) { auto command_view = bluetooth::hci::ReadRssiView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); int8_t rssi = 0; @@ -362,7 +385,7 @@ void DualModeController::ReadRssi(CommandView command) { void DualModeController::ReadEncryptionKeySize(CommandView command) { auto command_view = bluetooth::hci::ReadEncryptionKeySizeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Encryption Key Size"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -375,7 +398,7 @@ void DualModeController::ReadEncryptionKeySize(CommandView command) { void DualModeController::HostBufferSize(CommandView command) { auto command_view = bluetooth::hci::HostBufferSizeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Host Buffer Size"); @@ -386,7 +409,7 @@ void DualModeController::HostBufferSize(CommandView command) { void DualModeController::ReadLocalVersionInformation(CommandView command) { auto command_view = bluetooth::hci::ReadLocalVersionInformationView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Local Version Information"); @@ -405,7 +428,7 @@ void DualModeController::ReadLocalVersionInformation(CommandView command) { void DualModeController::ReadRemoteVersionInformation(CommandView command) { auto command_view = bluetooth::hci::ReadRemoteVersionInformationView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Remote Version Information"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -420,7 +443,7 @@ void DualModeController::ReadRemoteVersionInformation(CommandView command) { void DualModeController::ReadBdAddr(CommandView command) { auto command_view = bluetooth::hci::ReadBdAddrView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read BD_ADDR"); @@ -431,7 +454,7 @@ void DualModeController::ReadBdAddr(CommandView command) { void DualModeController::ReadLocalSupportedCommands(CommandView command) { auto command_view = bluetooth::hci::ReadLocalSupportedCommandsView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Local Supported Commands"); @@ -442,7 +465,7 @@ void DualModeController::ReadLocalSupportedCommands(CommandView command) { void DualModeController::ReadLocalSupportedFeatures(CommandView command) { auto command_view = bluetooth::hci::ReadLocalSupportedFeaturesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Local Supported Features"); @@ -454,7 +477,7 @@ void DualModeController::ReadLocalSupportedFeatures(CommandView command) { void DualModeController::ReadLocalSupportedCodecsV1(CommandView command) { auto command_view = bluetooth::hci::ReadLocalSupportedCodecsV1View::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Local Supported Codecs V1"); @@ -467,7 +490,7 @@ void DualModeController::ReadLocalSupportedCodecsV1(CommandView command) { void DualModeController::ReadLocalExtendedFeatures(CommandView command) { auto command_view = bluetooth::hci::ReadLocalExtendedFeaturesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint8_t page_number = command_view.GetPageNumber(); DEBUG(id_, "<< Read Local Extended Features"); @@ -482,7 +505,7 @@ void DualModeController::ReadLocalExtendedFeatures(CommandView command) { void DualModeController::ReadRemoteExtendedFeatures(CommandView command) { auto command_view = bluetooth::hci::ReadRemoteExtendedFeaturesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Remote Extended Features"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -498,7 +521,7 @@ void DualModeController::ReadRemoteExtendedFeatures(CommandView command) { void DualModeController::SwitchRole(CommandView command) { auto command_view = bluetooth::hci::SwitchRoleView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Switch Role"); DEBUG(id_, " bd_addr={}", command_view.GetBdAddr()); @@ -514,7 +537,7 @@ void DualModeController::SwitchRole(CommandView command) { void DualModeController::ReadRemoteSupportedFeatures(CommandView command) { auto command_view = bluetooth::hci::ReadRemoteSupportedFeaturesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Remote Supported Features"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -529,7 +552,7 @@ void DualModeController::ReadRemoteSupportedFeatures(CommandView command) { void DualModeController::ReadClockOffset(CommandView command) { auto command_view = bluetooth::hci::ReadClockOffsetView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Clock Offset"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -547,7 +570,7 @@ void DualModeController::ReadClockOffset(CommandView command) { // Support is provided to satisfy PTS tester requirements. void DualModeController::AddScoConnection(CommandView command) { auto command_view = bluetooth::hci::AddScoConnectionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Add SCO Connection"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -564,7 +587,7 @@ void DualModeController::AddScoConnection(CommandView command) { void DualModeController::SetupSynchronousConnection(CommandView command) { auto command_view = bluetooth::hci::SetupSynchronousConnectionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Setup Synchronous Connection"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -584,7 +607,7 @@ void DualModeController::SetupSynchronousConnection(CommandView command) { void DualModeController::AcceptSynchronousConnection(CommandView command) { auto command_view = bluetooth::hci::AcceptSynchronousConnectionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Accept Synchronous Connection"); DEBUG(id_, " bd_addr={}", command_view.GetBdAddr()); @@ -606,7 +629,7 @@ void DualModeController::EnhancedSetupSynchronousConnection( auto command_view = bluetooth::hci::EnhancedSetupSynchronousConnectionView::Create(command); auto status = ErrorCode::SUCCESS; - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Enhanced Setup Synchronous Connection"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -753,7 +776,7 @@ void DualModeController::EnhancedAcceptSynchronousConnection( auto command_view = bluetooth::hci::EnhancedAcceptSynchronousConnectionView::Create(command); auto status = ErrorCode::SUCCESS; - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Enhanced Accept Synchronous Connection"); DEBUG(id_, " bd_addr={}", command_view.GetBdAddr()); @@ -897,7 +920,7 @@ void DualModeController::EnhancedAcceptSynchronousConnection( void DualModeController::RejectSynchronousConnection(CommandView command) { auto command_view = bluetooth::hci::RejectSynchronousConnectionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Reject Synchronous Connection"); DEBUG(id_, " bd_addr={}", command_view.GetBdAddr()); @@ -916,7 +939,7 @@ void DualModeController::ReadInquiryResponseTransmitPowerLevel( auto command_view = bluetooth::hci::ReadInquiryResponseTransmitPowerLevelView::Create( command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Inquiry Response Transmit Power Level"); @@ -928,7 +951,7 @@ void DualModeController::ReadInquiryResponseTransmitPowerLevel( void DualModeController::EnhancedFlush(CommandView command) { auto command_view = bluetooth::hci::EnhancedFlushView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Enhanced Flush"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -948,7 +971,7 @@ void DualModeController::EnhancedFlush(CommandView command) { void DualModeController::SetEventMaskPage2(CommandView command) { auto command_view = bluetooth::hci::SetEventMaskPage2View::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Set Event Mask Page 2"); DEBUG(id_, " event_mask_page_2=0x{:x}", command_view.GetEventMaskPage2()); @@ -978,7 +1001,7 @@ void DualModeController::ReadLocalOobExtendedData(CommandView command) { void DualModeController::WriteSimplePairingMode(CommandView command) { auto command_view = bluetooth::hci::WriteSimplePairingModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Simple Pairing Mode"); DEBUG(id_, " simple_pairing_mode={}", @@ -994,7 +1017,7 @@ void DualModeController::WriteSimplePairingMode(CommandView command) { void DualModeController::ChangeConnectionPacketType(CommandView command) { auto command_view = bluetooth::hci::ChangeConnectionPacketTypeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Change Connection Packet Type"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -1011,7 +1034,7 @@ void DualModeController::ChangeConnectionPacketType(CommandView command) { void DualModeController::WriteLeHostSupport(CommandView command) { auto command_view = bluetooth::hci::WriteLeHostSupportView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write LE Host Support"); DEBUG(id_, " le_supported_host={}", @@ -1028,7 +1051,7 @@ void DualModeController::WriteSecureConnectionsHostSupport( CommandView command) { auto command_view = bluetooth::hci::WriteSecureConnectionsHostSupportView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Secure Connections Host Support"); DEBUG(id_, " secure_connections_host_support={}", @@ -1045,7 +1068,7 @@ void DualModeController::WriteSecureConnectionsHostSupport( void DualModeController::SetEventMask(CommandView command) { auto command_view = bluetooth::hci::SetEventMaskView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Set Event Mask"); DEBUG(id_, " event_mask=0x{:x}", command_view.GetEventMask()); @@ -1057,7 +1080,7 @@ void DualModeController::SetEventMask(CommandView command) { void DualModeController::ReadInquiryMode(CommandView command) { auto command_view = bluetooth::hci::ReadInquiryModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Inquiry Mode"); @@ -1069,7 +1092,7 @@ void DualModeController::ReadInquiryMode(CommandView command) { void DualModeController::WriteInquiryMode(CommandView command) { auto command_view = bluetooth::hci::WriteInquiryModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Inquiry Mode"); DEBUG(id_, " inquiry_mode={}", @@ -1083,7 +1106,7 @@ void DualModeController::WriteInquiryMode(CommandView command) { void DualModeController::ReadPageScanType(CommandView command) { auto command_view = bluetooth::hci::ReadPageScanTypeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Page Scan Type"); @@ -1095,7 +1118,7 @@ void DualModeController::ReadPageScanType(CommandView command) { void DualModeController::WritePageScanType(CommandView command) { auto command_view = bluetooth::hci::WritePageScanTypeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Page Scan Type"); DEBUG(id_, " page_scan_type={}", @@ -1107,7 +1130,7 @@ void DualModeController::WritePageScanType(CommandView command) { void DualModeController::ReadInquiryScanType(CommandView command) { auto command_view = bluetooth::hci::ReadInquiryScanTypeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Inquiry Scan Type"); @@ -1119,7 +1142,7 @@ void DualModeController::ReadInquiryScanType(CommandView command) { void DualModeController::WriteInquiryScanType(CommandView command) { auto command_view = bluetooth::hci::WriteInquiryScanTypeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Inquiry Scan Type"); DEBUG(id_, " inquiry_scan_type={}", @@ -1132,7 +1155,7 @@ void DualModeController::WriteInquiryScanType(CommandView command) { void DualModeController::ChangeConnectionLinkKey(CommandView command) { auto command_view = bluetooth::hci::ChangeConnectionLinkKeyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Change Connection Link Key"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -1146,10 +1169,11 @@ void DualModeController::ChangeConnectionLinkKey(CommandView command) { void DualModeController::CentralLinkKey(CommandView command) { auto command_view = bluetooth::hci::CentralLinkKeyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Central Link Key"); - DEBUG(id_, " key_flag={}", command_view.GetKeyFlag()); + DEBUG(id_, " key_flag={}", + bluetooth::hci::KeyFlagText(command_view.GetKeyFlag())); uint8_t key_flag = static_cast(command_view.GetKeyFlag()); auto status = link_layer_controller_.CentralLinkKey(key_flag); @@ -1161,11 +1185,12 @@ void DualModeController::CentralLinkKey(CommandView command) { void DualModeController::WriteAuthenticationEnable(CommandView command) { auto command_view = bluetooth::hci::WriteAuthenticationEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Authentication Enable"); DEBUG(id_, " authentication_enable={}", - command_view.GetAuthenticationEnable()); + bluetooth::hci::AuthenticationEnableText( + command_view.GetAuthenticationEnable())); link_layer_controller_.SetAuthenticationEnable( command_view.GetAuthenticationEnable()); @@ -1176,7 +1201,7 @@ void DualModeController::WriteAuthenticationEnable(CommandView command) { void DualModeController::ReadAuthenticationEnable(CommandView command) { auto command_view = bluetooth::hci::ReadAuthenticationEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Authentication Enable"); @@ -1188,7 +1213,7 @@ void DualModeController::ReadAuthenticationEnable(CommandView command) { void DualModeController::ReadClassOfDevice(CommandView command) { auto command_view = bluetooth::hci::ReadClassOfDeviceView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Class of Device"); @@ -1199,7 +1224,7 @@ void DualModeController::ReadClassOfDevice(CommandView command) { void DualModeController::WriteClassOfDevice(CommandView command) { auto command_view = bluetooth::hci::WriteClassOfDeviceView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Class of Device"); DEBUG(id_, " class_of_device=0x{:x}", command_view.GetClassOfDevice()); @@ -1211,7 +1236,7 @@ void DualModeController::WriteClassOfDevice(CommandView command) { void DualModeController::ReadPageTimeout(CommandView command) { auto command_view = bluetooth::hci::ReadPageTimeoutView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Page Timeout"); @@ -1222,7 +1247,7 @@ void DualModeController::ReadPageTimeout(CommandView command) { void DualModeController::WritePageTimeout(CommandView command) { auto command_view = bluetooth::hci::WritePageTimeoutView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Page Timeout"); DEBUG(id_, " page_timeout={}", command_view.GetPageTimeout()); @@ -1234,7 +1259,7 @@ void DualModeController::WritePageTimeout(CommandView command) { void DualModeController::HoldMode(CommandView command) { auto command_view = bluetooth::hci::HoldModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); uint16_t hold_mode_max_interval = command_view.GetHoldModeMaxInterval(); uint16_t hold_mode_min_interval = command_view.GetHoldModeMinInterval(); @@ -1251,7 +1276,7 @@ void DualModeController::HoldMode(CommandView command) { void DualModeController::SniffMode(CommandView command) { auto command_view = bluetooth::hci::SniffModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); uint16_t sniff_max_interval = command_view.GetSniffMaxInterval(); uint16_t sniff_min_interval = command_view.GetSniffMinInterval(); @@ -1271,7 +1296,7 @@ void DualModeController::SniffMode(CommandView command) { void DualModeController::ExitSniffMode(CommandView command) { auto command_view = bluetooth::hci::ExitSniffModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Exit Sniff Mode"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -1285,7 +1310,7 @@ void DualModeController::ExitSniffMode(CommandView command) { void DualModeController::QosSetup(CommandView command) { auto command_view = bluetooth::hci::QosSetupView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); uint8_t service_type = static_cast(command_view.GetServiceType()); uint32_t token_rate = command_view.GetTokenRate(); @@ -1306,7 +1331,7 @@ void DualModeController::QosSetup(CommandView command) { void DualModeController::RoleDiscovery(CommandView command) { auto command_view = bluetooth::hci::RoleDiscoveryView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Role Discovery"); @@ -1322,7 +1347,7 @@ void DualModeController::RoleDiscovery(CommandView command) { void DualModeController::ReadDefaultLinkPolicySettings(CommandView command) { auto command_view = bluetooth::hci::ReadDefaultLinkPolicySettingsView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Default Link Policy Settings"); @@ -1335,7 +1360,7 @@ void DualModeController::ReadDefaultLinkPolicySettings(CommandView command) { void DualModeController::WriteDefaultLinkPolicySettings(CommandView command) { auto command_view = bluetooth::hci::WriteDefaultLinkPolicySettingsView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Default Link Policy Settings"); DEBUG(id_, " default_link_policy_settings=0x{:x}", @@ -1350,7 +1375,7 @@ void DualModeController::WriteDefaultLinkPolicySettings(CommandView command) { void DualModeController::SniffSubrating(CommandView command) { auto command_view = bluetooth::hci::SniffSubratingView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Sniff Subrating"); @@ -1362,7 +1387,7 @@ void DualModeController::SniffSubrating(CommandView command) { void DualModeController::FlowSpecification(CommandView command) { auto command_view = bluetooth::hci::FlowSpecificationView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); uint8_t flow_direction = static_cast(command_view.GetFlowDirection()); @@ -1386,7 +1411,7 @@ void DualModeController::FlowSpecification(CommandView command) { void DualModeController::ReadLinkPolicySettings(CommandView command) { auto command_view = bluetooth::hci::ReadLinkPolicySettingsView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Read Link Policy Settings"); @@ -1403,7 +1428,7 @@ void DualModeController::ReadLinkPolicySettings(CommandView command) { void DualModeController::WriteLinkPolicySettings(CommandView command) { auto command_view = bluetooth::hci::WriteLinkPolicySettingsView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); uint16_t settings = command_view.GetLinkPolicySettings(); @@ -1421,7 +1446,7 @@ void DualModeController::WriteLinkPolicySettings(CommandView command) { void DualModeController::WriteLinkSupervisionTimeout(CommandView command) { auto command_view = bluetooth::hci::WriteLinkSupervisionTimeoutView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); uint16_t timeout = command_view.GetLinkSupervisionTimeout(); @@ -1438,7 +1463,7 @@ void DualModeController::WriteLinkSupervisionTimeout(CommandView command) { void DualModeController::ReadLocalName(CommandView command) { auto command_view = bluetooth::hci::ReadLocalNameView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Local Name"); @@ -1449,7 +1474,7 @@ void DualModeController::ReadLocalName(CommandView command) { void DualModeController::WriteLocalName(CommandView command) { auto command_view = bluetooth::hci::WriteLocalNameView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Local Name"); @@ -1461,7 +1486,7 @@ void DualModeController::WriteLocalName(CommandView command) { void DualModeController::WriteExtendedInquiryResponse(CommandView command) { auto command_view = bluetooth::hci::WriteExtendedInquiryResponseView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Extended Inquiry Response"); @@ -1474,7 +1499,7 @@ void DualModeController::WriteExtendedInquiryResponse(CommandView command) { void DualModeController::RefreshEncryptionKey(CommandView command) { auto command_view = bluetooth::hci::RefreshEncryptionKeyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Refresh Encryption Key"); @@ -1489,7 +1514,7 @@ void DualModeController::RefreshEncryptionKey(CommandView command) { void DualModeController::ReadVoiceSetting(CommandView command) { auto command_view = bluetooth::hci::ReadVoiceSettingView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Voice Setting"); @@ -1500,7 +1525,7 @@ void DualModeController::ReadVoiceSetting(CommandView command) { void DualModeController::WriteVoiceSetting(CommandView command) { auto command_view = bluetooth::hci::WriteVoiceSettingView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Voice Setting"); DEBUG(id_, " voice_setting=0x{:x}", command_view.GetVoiceSetting()); @@ -1514,7 +1539,7 @@ void DualModeController::WriteVoiceSetting(CommandView command) { void DualModeController::ReadNumberOfSupportedIac(CommandView command) { auto command_view = bluetooth::hci::ReadNumberOfSupportedIacView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Number of Supported Iac"); @@ -1524,7 +1549,7 @@ void DualModeController::ReadNumberOfSupportedIac(CommandView command) { void DualModeController::ReadCurrentIacLap(CommandView command) { auto command_view = bluetooth::hci::ReadCurrentIacLapView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Current Iac Lap"); @@ -1535,7 +1560,7 @@ void DualModeController::ReadCurrentIacLap(CommandView command) { void DualModeController::WriteCurrentIacLap(CommandView command) { auto command_view = bluetooth::hci::WriteCurrentIacLapView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Current Iac Lap"); @@ -1546,7 +1571,7 @@ void DualModeController::WriteCurrentIacLap(CommandView command) { void DualModeController::ReadPageScanActivity(CommandView command) { auto command_view = bluetooth::hci::ReadPageScanActivityView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Page Scan Activity"); @@ -1559,7 +1584,7 @@ void DualModeController::ReadPageScanActivity(CommandView command) { void DualModeController::WritePageScanActivity(CommandView command) { auto command_view = bluetooth::hci::WritePageScanActivityView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Page Scan Activity"); @@ -1570,7 +1595,7 @@ void DualModeController::WritePageScanActivity(CommandView command) { void DualModeController::ReadInquiryScanActivity(CommandView command) { auto command_view = bluetooth::hci::ReadInquiryScanActivityView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Inquiry Scan Activity"); @@ -1583,7 +1608,7 @@ void DualModeController::ReadInquiryScanActivity(CommandView command) { void DualModeController::WriteInquiryScanActivity(CommandView command) { auto command_view = bluetooth::hci::WriteInquiryScanActivityView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Inquiry Scan Activity"); @@ -1593,7 +1618,7 @@ void DualModeController::WriteInquiryScanActivity(CommandView command) { void DualModeController::ReadScanEnable(CommandView command) { auto command_view = bluetooth::hci::ReadScanEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Scan Enable"); @@ -1613,7 +1638,7 @@ void DualModeController::ReadScanEnable(CommandView command) { void DualModeController::WriteScanEnable(CommandView command) { auto command_view = bluetooth::hci::WriteScanEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); bluetooth::hci::ScanEnable scan_enable = command_view.GetScanEnable(); bool inquiry_scan = scan_enable == bluetooth::hci::ScanEnable::INQUIRY_AND_PAGE_SCAN || @@ -1633,7 +1658,7 @@ void DualModeController::WriteScanEnable(CommandView command) { void DualModeController::ReadTransmitPowerLevel(CommandView command) { auto command_view = bluetooth::hci::ReadTransmitPowerLevelView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Read Transmit Power Level"); @@ -1649,7 +1674,7 @@ void DualModeController::ReadTransmitPowerLevel(CommandView command) { void DualModeController::ReadEnhancedTransmitPowerLevel(CommandView command) { auto command_view = bluetooth::hci::ReadEnhancedTransmitPowerLevelView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Read Enhanced Transmit Power Level"); @@ -1667,7 +1692,7 @@ void DualModeController::ReadEnhancedTransmitPowerLevel(CommandView command) { void DualModeController::ReadSynchronousFlowControlEnable(CommandView command) { auto command_view = bluetooth::hci::ReadSynchronousFlowControlEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Synchronous Flow Control Enable"); @@ -1684,7 +1709,7 @@ void DualModeController::WriteSynchronousFlowControlEnable( CommandView command) { auto command_view = bluetooth::hci::WriteSynchronousFlowControlEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); auto enabled = command_view.GetEnable() == bluetooth::hci::Enable::ENABLED; DEBUG(id_, "<< Write Synchronous Flow Control Enable"); @@ -1698,7 +1723,7 @@ void DualModeController::WriteSynchronousFlowControlEnable( void DualModeController::SetEventFilter(CommandView command) { auto command_view = bluetooth::hci::SetEventFilterView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Set Event Filter"); DEBUG(id_, " filter_type={}", @@ -1714,7 +1739,7 @@ void DualModeController::SetEventFilter(CommandView command) { void DualModeController::Inquiry(CommandView command) { auto command_view = bluetooth::hci::InquiryView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); auto max_responses = command_view.GetNumResponses(); auto length = command_view.GetInquiryLength(); @@ -1737,7 +1762,7 @@ void DualModeController::Inquiry(CommandView command) { void DualModeController::InquiryCancel(CommandView command) { auto command_view = bluetooth::hci::InquiryCancelView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Inquiry Cancel"); @@ -1749,7 +1774,7 @@ void DualModeController::InquiryCancel(CommandView command) { void DualModeController::AcceptConnectionRequest(CommandView command) { auto command_view = bluetooth::hci::AcceptConnectionRequestView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); Address bd_addr = command_view.GetBdAddr(); bool try_role_switch = command_view.GetRole() == @@ -1768,7 +1793,7 @@ void DualModeController::AcceptConnectionRequest(CommandView command) { void DualModeController::RejectConnectionRequest(CommandView command) { auto command_view = bluetooth::hci::RejectConnectionRequestView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); Address bd_addr = command_view.GetBdAddr(); auto reason = command_view.GetReason(); @@ -1785,7 +1810,7 @@ void DualModeController::RejectConnectionRequest(CommandView command) { void DualModeController::DeleteStoredLinkKey(CommandView command) { auto command_view = bluetooth::hci::DeleteStoredLinkKeyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Delete Stored Link Key"); @@ -1795,7 +1820,7 @@ void DualModeController::DeleteStoredLinkKey(CommandView command) { void DualModeController::RemoteNameRequest(CommandView command) { auto command_view = bluetooth::hci::RemoteNameRequestView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); Address bd_addr = command_view.GetBdAddr(); DEBUG(id_, "<< Remote Name Request"); @@ -1810,7 +1835,7 @@ void DualModeController::RemoteNameRequest(CommandView command) { void DualModeController::LeSetEventMask(CommandView command) { auto command_view = bluetooth::hci::LeSetEventMaskView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Event Mask"); DEBUG(id_, " le_event_mask=0x{:x}", command_view.GetLeEventMask()); @@ -1822,7 +1847,7 @@ void DualModeController::LeSetEventMask(CommandView command) { void DualModeController::LeRequestPeerSca(CommandView command) { auto command_view = bluetooth::hci::LeRequestPeerScaView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< LE Request Peer SCA"); @@ -1854,7 +1879,7 @@ void DualModeController::LeRequestPeerSca(CommandView command) { void DualModeController::LeSetHostFeature(CommandView command) { auto command_view = bluetooth::hci::LeSetHostFeatureView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint8_t bit_number = static_cast(command_view.GetBitNumber()); uint8_t bit_value = static_cast(command_view.GetBitValue()); @@ -1870,7 +1895,7 @@ void DualModeController::LeSetHostFeature(CommandView command) { void DualModeController::LeReadBufferSizeV1(CommandView command) { auto command_view = bluetooth::hci::LeReadBufferSizeV1View::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Buffer Size V1"); @@ -1885,7 +1910,7 @@ void DualModeController::LeReadBufferSizeV1(CommandView command) { void DualModeController::LeReadBufferSizeV2(CommandView command) { auto command_view = bluetooth::hci::LeReadBufferSizeV2View::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Buffer Size V2"); @@ -1905,7 +1930,7 @@ void DualModeController::LeReadBufferSizeV2(CommandView command) { void DualModeController::LeSetAddressResolutionEnable(CommandView command) { auto command_view = bluetooth::hci::LeSetAddressResolutionEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Address Resolution Enable"); DEBUG(id_, " address_resolution_enable={}", @@ -1924,7 +1949,7 @@ void DualModeController::LeSetResolvablePrivateAddressTimeout( CommandView command) { auto command_view = bluetooth::hci::LeSetResolvablePrivateAddressTimeoutView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Resolvable Private Address Timeout"); @@ -1939,7 +1964,7 @@ void DualModeController::LeSetResolvablePrivateAddressTimeout( void DualModeController::LeReadLocalSupportedFeatures(CommandView command) { auto command_view = bluetooth::hci::LeReadLocalSupportedFeaturesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Local Supported Features"); @@ -1951,7 +1976,7 @@ void DualModeController::LeReadLocalSupportedFeatures(CommandView command) { void DualModeController::LeSetRandomAddress(CommandView command) { auto command_view = bluetooth::hci::LeSetRandomAddressView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Random Address"); DEBUG(id_, " random_address={}", command_view.GetRandomAddress()); @@ -1965,7 +1990,7 @@ void DualModeController::LeSetRandomAddress(CommandView command) { void DualModeController::LeSetAdvertisingParameters(CommandView command) { auto command_view = bluetooth::hci::LeSetAdvertisingParametersView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Advertising Parameters"); @@ -1985,7 +2010,7 @@ void DualModeController::LeReadAdvertisingPhysicalChannelTxPower( auto command_view = bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerView::Create( command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Physical Channel Tx Power"); @@ -1997,7 +2022,7 @@ void DualModeController::LeReadAdvertisingPhysicalChannelTxPower( void DualModeController::LeSetAdvertisingData(CommandView command) { auto command_view = bluetooth::hci::LeSetAdvertisingDataView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Advertising Data"); @@ -2010,7 +2035,7 @@ void DualModeController::LeSetAdvertisingData(CommandView command) { void DualModeController::LeSetScanResponseData(CommandView command) { auto command_view = bluetooth::hci::LeSetScanResponseDataView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Scan Response Data"); @@ -2023,7 +2048,7 @@ void DualModeController::LeSetScanResponseData(CommandView command) { void DualModeController::LeSetAdvertisingEnable(CommandView command) { auto command_view = bluetooth::hci::LeSetAdvertisingEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Advertising Enable"); DEBUG(id_, " advertising_enable={}", @@ -2037,7 +2062,7 @@ void DualModeController::LeSetAdvertisingEnable(CommandView command) { void DualModeController::LeSetScanParameters(CommandView command) { auto command_view = bluetooth::hci::LeSetScanParametersView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Scan Parameters"); @@ -2051,7 +2076,7 @@ void DualModeController::LeSetScanParameters(CommandView command) { void DualModeController::LeSetScanEnable(CommandView command) { auto command_view = bluetooth::hci::LeSetScanEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Scan Enable"); DEBUG(id_, " scan_enable={}", @@ -2066,7 +2091,7 @@ void DualModeController::LeSetScanEnable(CommandView command) { void DualModeController::LeCreateConnection(CommandView command) { auto command_view = bluetooth::hci::LeCreateConnectionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Create Connection"); DEBUG(id_, " peer_address={}", command_view.GetPeerAddress()); @@ -2096,7 +2121,7 @@ void DualModeController::LeCreateConnection(CommandView command) { void DualModeController::LeCreateConnectionCancel(CommandView command) { auto command_view = bluetooth::hci::LeCreateConnectionCancelView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Create Connection Cancel"); @@ -2107,7 +2132,7 @@ void DualModeController::LeCreateConnectionCancel(CommandView command) { void DualModeController::LeConnectionUpdate(CommandView command) { auto command_view = bluetooth::hci::LeConnectionUpdateView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Connection Update"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -2124,7 +2149,7 @@ void DualModeController::LeConnectionUpdate(CommandView command) { void DualModeController::CreateConnection(CommandView command) { auto command_view = bluetooth::hci::CreateConnectionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); Address bd_addr = command_view.GetBdAddr(); uint16_t packet_type = command_view.GetPacketType(); uint8_t page_scan_mode = @@ -2152,7 +2177,7 @@ void DualModeController::CreateConnection(CommandView command) { void DualModeController::CreateConnectionCancel(CommandView command) { auto command_view = bluetooth::hci::CreateConnectionCancelView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); Address address = command_view.GetBdAddr(); DEBUG(id_, "<< Create Connection Cancel"); @@ -2166,7 +2191,7 @@ void DualModeController::CreateConnectionCancel(CommandView command) { void DualModeController::Disconnect(CommandView command) { auto command_view = bluetooth::hci::DisconnectView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< Disconnect"); @@ -2187,7 +2212,7 @@ void DualModeController::Disconnect(CommandView command) { void DualModeController::LeReadFilterAcceptListSize(CommandView command) { auto command_view = bluetooth::hci::LeReadFilterAcceptListSizeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Filter Accept List Size"); @@ -2199,7 +2224,7 @@ void DualModeController::LeReadFilterAcceptListSize(CommandView command) { void DualModeController::LeClearFilterAcceptList(CommandView command) { auto command_view = bluetooth::hci::LeClearFilterAcceptListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Clear Filter Accept List"); @@ -2211,7 +2236,7 @@ void DualModeController::LeClearFilterAcceptList(CommandView command) { void DualModeController::LeAddDeviceToFilterAcceptList(CommandView command) { auto command_view = bluetooth::hci::LeAddDeviceToFilterAcceptListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Add Device To Filter Accept List"); DEBUG(id_, " address={}", command_view.GetAddress()); @@ -2230,7 +2255,7 @@ void DualModeController::LeRemoveDeviceFromFilterAcceptList( CommandView command) { auto command_view = bluetooth::hci::LeRemoveDeviceFromFilterAcceptListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Remove Device From Filter Accept List"); DEBUG(id_, " address={}", command_view.GetAddress()); @@ -2247,7 +2272,7 @@ void DualModeController::LeRemoveDeviceFromFilterAcceptList( void DualModeController::LeClearResolvingList(CommandView command) { auto command_view = bluetooth::hci::LeClearResolvingListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Clear Resolving List"); @@ -2259,7 +2284,7 @@ void DualModeController::LeClearResolvingList(CommandView command) { void DualModeController::LeReadResolvingListSize(CommandView command) { auto command_view = bluetooth::hci::LeReadResolvingListSizeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Resolving List Size"); @@ -2271,7 +2296,7 @@ void DualModeController::LeReadResolvingListSize(CommandView command) { void DualModeController::LeReadPeerResolvableAddress(CommandView command) { auto command_view = bluetooth::hci::LeReadPeerResolvableAddressView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Peer Resolvable Address"); DEBUG(id_, " peer_identity_address={}", @@ -2292,7 +2317,7 @@ void DualModeController::LeReadPeerResolvableAddress(CommandView command) { void DualModeController::LeReadLocalResolvableAddress(CommandView command) { auto command_view = bluetooth::hci::LeReadLocalResolvableAddressView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Local Resolvable Address"); DEBUG(id_, " peer_identity_address={}", @@ -2313,7 +2338,7 @@ void DualModeController::LeReadLocalResolvableAddress(CommandView command) { void DualModeController::LeReadMaximumDataLength(CommandView command) { auto command_view = bluetooth::hci::LeReadMaximumDataLengthView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Maximum Data Length"); @@ -2328,7 +2353,7 @@ void DualModeController::LeReadMaximumDataLength(CommandView command) { void DualModeController::LeReadPhy(CommandView command) { auto command_view = bluetooth::hci::LeReadPhyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t connection_handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< LE Read Phy"); @@ -2344,7 +2369,7 @@ void DualModeController::LeReadPhy(CommandView command) { void DualModeController::LeSetDefaultPhy(CommandView command) { auto command_view = bluetooth::hci::LeSetDefaultPhyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Default Phy"); @@ -2358,7 +2383,7 @@ void DualModeController::LeSetDefaultPhy(CommandView command) { void DualModeController::LeSetPhy(CommandView command) { auto command_view = bluetooth::hci::LeSetPhyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Phy"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -2375,7 +2400,7 @@ void DualModeController::LeSetPhy(CommandView command) { void DualModeController::LeReadSuggestedDefaultDataLength(CommandView command) { auto command_view = bluetooth::hci::LeReadSuggestedDefaultDataLengthView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Suggested Default Data Length"); @@ -2390,7 +2415,7 @@ void DualModeController::LeWriteSuggestedDefaultDataLength( CommandView command) { auto command_view = bluetooth::hci::LeWriteSuggestedDefaultDataLengthView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Write Suggested Default Data Length"); @@ -2413,7 +2438,7 @@ void DualModeController::LeWriteSuggestedDefaultDataLength( void DualModeController::LeAddDeviceToResolvingList(CommandView command) { auto command_view = bluetooth::hci::LeAddDeviceToResolvingListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Add Device to Resolving List"); DEBUG(id_, " peer_identity_address={}", @@ -2433,7 +2458,7 @@ void DualModeController::LeAddDeviceToResolvingList(CommandView command) { void DualModeController::LeRemoveDeviceFromResolvingList(CommandView command) { auto command_view = bluetooth::hci::LeRemoveDeviceFromResolvingListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Remove Device from Resolving List"); DEBUG(id_, " peer_identity_address={}", @@ -2454,7 +2479,7 @@ void DualModeController::LeSetPeriodicAdvertisingParameters( CommandView command) { auto command_view = bluetooth::hci::LeSetPeriodicAdvertisingParametersView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Periodic Advertising Parameters"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -2472,7 +2497,7 @@ void DualModeController::LeSetPeriodicAdvertisingParameters( void DualModeController::LeSetPeriodicAdvertisingData(CommandView command) { auto command_view = bluetooth::hci::LeSetPeriodicAdvertisingDataView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Periodic Advertising Data"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -2488,7 +2513,7 @@ void DualModeController::LeSetPeriodicAdvertisingData(CommandView command) { void DualModeController::LeSetPeriodicAdvertisingEnable(CommandView command) { auto command_view = bluetooth::hci::LeSetPeriodicAdvertisingEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Periodic Advertising Enable"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -2505,7 +2530,7 @@ void DualModeController::LeSetPeriodicAdvertisingEnable(CommandView command) { void DualModeController::LePeriodicAdvertisingCreateSync(CommandView command) { auto command_view = bluetooth::hci::LePeriodicAdvertisingCreateSyncView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Periodic Advertising Create Sync"); DEBUG(id_, " advertiser_address={}", command_view.GetAdvertiserAddress()); @@ -2528,7 +2553,7 @@ void DualModeController::LePeriodicAdvertisingCreateSyncCancel( auto command_view = bluetooth::hci::LePeriodicAdvertisingCreateSyncCancelView::Create( command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Periodic Advertising Create Sync Cancel"); @@ -2543,7 +2568,7 @@ void DualModeController::LePeriodicAdvertisingTerminateSync( CommandView command) { auto command_view = bluetooth::hci::LePeriodicAdvertisingTerminateSyncView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Periodic Advertising Terminate Sync"); DEBUG(id_, " sync_handle=0x{:x}", command_view.GetSyncHandle()); @@ -2559,7 +2584,7 @@ void DualModeController::LeAddDeviceToPeriodicAdvertiserList( CommandView command) { auto command_view = bluetooth::hci::LeAddDeviceToPeriodicAdvertiserListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Add Device to Periodic Advertiser List"); DEBUG(id_, " advertiser_address={}", command_view.GetAdvertiserAddress()); @@ -2580,7 +2605,7 @@ void DualModeController::LeRemoveDeviceFromPeriodicAdvertiserList( auto command_view = bluetooth::hci::LeRemoveDeviceFromPeriodicAdvertiserListView::Create( command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Remove Device from Periodic Advertiser List"); DEBUG(id_, " advertiser_address={}", command_view.GetAdvertiserAddress()); @@ -2601,7 +2626,7 @@ void DualModeController::LeRemoveDeviceFromPeriodicAdvertiserList( void DualModeController::LeClearPeriodicAdvertiserList(CommandView command) { auto command_view = bluetooth::hci::LeClearPeriodicAdvertiserListView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Clear Periodic Advertiser List"); @@ -2614,7 +2639,7 @@ void DualModeController::LeClearPeriodicAdvertiserList(CommandView command) { void DualModeController::LeReadPeriodicAdvertiserListSize(CommandView command) { auto command_view = bluetooth::hci::LeReadPeriodicAdvertiserListSizeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Periodic Advertiser List Size"); @@ -2627,7 +2652,7 @@ void DualModeController::LeReadPeriodicAdvertiserListSize(CommandView command) { void DualModeController::LeSetExtendedScanParameters(CommandView command) { auto command_view = bluetooth::hci::LeSetExtendedScanParametersView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Extended Scan Parameters"); @@ -2642,7 +2667,7 @@ void DualModeController::LeSetExtendedScanParameters(CommandView command) { void DualModeController::LeSetExtendedScanEnable(CommandView command) { auto command_view = bluetooth::hci::LeSetExtendedScanEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Extended Scan Enable"); DEBUG(id_, " enable={}", @@ -2659,7 +2684,7 @@ void DualModeController::LeSetExtendedScanEnable(CommandView command) { void DualModeController::LeExtendedCreateConnection(CommandView command) { auto command_view = bluetooth::hci::LeExtendedCreateConnectionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Extended Create Connection"); DEBUG(id_, " peer_address={}", command_view.GetPeerAddress()); @@ -2694,7 +2719,7 @@ void DualModeController::LeExtendedCreateConnection(CommandView command) { void DualModeController::LeSetPrivacyMode(CommandView command) { auto command_view = bluetooth::hci::LeSetPrivacyModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Privacy Mode"); DEBUG(id_, " peer_identity_address={}", @@ -2714,7 +2739,7 @@ void DualModeController::LeSetPrivacyMode(CommandView command) { void DualModeController::LeReadRemoteFeatures(CommandView command) { auto command_view = bluetooth::hci::LeReadRemoteFeaturesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< LE Read Remote Features"); @@ -2729,7 +2754,7 @@ void DualModeController::LeReadRemoteFeatures(CommandView command) { void DualModeController::LeEncrypt(CommandView command) { auto command_view = bluetooth::hci::LeEncryptView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Encrypt"); @@ -2742,7 +2767,7 @@ void DualModeController::LeEncrypt(CommandView command) { void DualModeController::LeRand(CommandView command) { auto command_view = bluetooth::hci::LeRandView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Rand"); @@ -2753,7 +2778,7 @@ void DualModeController::LeRand(CommandView command) { void DualModeController::LeReadSupportedStates(CommandView command) { auto command_view = bluetooth::hci::LeReadSupportedStatesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Supported States"); @@ -2766,7 +2791,7 @@ void DualModeController::LeRemoteConnectionParameterRequestReply( auto command_view = bluetooth::hci::LeRemoteConnectionParameterRequestReplyView::Create( command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Remote Connection Parameters Request Reply"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -2786,7 +2811,7 @@ void DualModeController::LeRemoteConnectionParameterRequestNegativeReply( CommandView command) { auto command_view = bluetooth::hci:: LeRemoteConnectionParameterRequestNegativeReplyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Remote Connection Parameters Request Negative Reply"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -2804,7 +2829,7 @@ void DualModeController::LeRemoteConnectionParameterRequestNegativeReply( void DualModeController::LeGetVendorCapabilities(CommandView command) { auto command_view = bluetooth::hci::LeGetVendorCapabilitiesView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); if (!properties_.supports_le_get_vendor_capabilities_command) { SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_GET_VENDOR_CAPABILITIES); @@ -2834,13 +2859,13 @@ void DualModeController::LeGetVendorCapabilities(CommandView command) { void DualModeController::LeBatchScan(CommandView command) { auto command_view = bluetooth::hci::LeBatchScanView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_BATCH_SCAN); } void DualModeController::LeApcf(CommandView command) { auto command_view = bluetooth::hci::LeApcfView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); if (!properties_.supports_le_apcf_vendor_command) { SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_APCF); @@ -2851,10 +2876,11 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::ENABLE: { auto subcommand_view = bluetooth::hci::LeApcfEnableView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Enable"); - DEBUG(id_, " enable={}", subcommand_view.GetApcfEnable()); + DEBUG(id_, " enable={}", + bluetooth::hci::EnableText(subcommand_view.GetApcfEnable())); ErrorCode status = link_layer_controller_.LeApcfEnable( subcommand_view.GetApcfEnable() == bluetooth::hci::Enable::ENABLED); @@ -2866,10 +2892,11 @@ void DualModeController::LeApcf(CommandView command) { auto subcommand_view = bluetooth::hci::LeApcfSetFilteringParametersView::Create( command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Set Filtering Parameters"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); ErrorCode status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; uint8_t apcf_available_spaces = 0; @@ -2879,7 +2906,7 @@ void DualModeController::LeApcf(CommandView command) { auto subsubcommand_view = bluetooth::hci::LeApcfAddFilteringParametersView::Create( subcommand_view); - ASSERT(subsubcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); status = link_layer_controller_.LeApcfAddFilteringParameters( subsubcommand_view.GetApcfFilterIndex(), subsubcommand_view.GetApcfFeatureSelection(), @@ -2899,7 +2926,7 @@ void DualModeController::LeApcf(CommandView command) { auto subsubcommand_view = bluetooth::hci::LeApcfDeleteFilteringParametersView::Create( subcommand_view); - ASSERT(subsubcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); status = link_layer_controller_.LeApcfDeleteFilteringParameters( subsubcommand_view.GetApcfFilterIndex(), &apcf_available_spaces); break; @@ -2908,13 +2935,14 @@ void DualModeController::LeApcf(CommandView command) { auto subsubcommand_view = bluetooth::hci::LeApcfClearFilteringParametersView::Create( subcommand_view); - ASSERT(subsubcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); status = link_layer_controller_.LeApcfClearFilteringParameters( &apcf_available_spaces); break; } default: - INFO(id_, "unknown apcf action {}", subcommand_view.GetApcfAction()); + INFO(id_, "unknown apcf action {}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); break; } @@ -2927,10 +2955,11 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::BROADCASTER_ADDRESS: { auto subcommand_view = bluetooth::hci::LeApcfBroadcasterAddressView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Broadcaster Address"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); ErrorCode status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; uint8_t apcf_available_spaces = 0; @@ -2940,7 +2969,7 @@ void DualModeController::LeApcf(CommandView command) { auto subsubcommand_view = bluetooth::hci::LeApcfAddBroadcasterAddressView::Create( subcommand_view); - ASSERT(subsubcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); status = link_layer_controller_.LeApcfBroadcasterAddress( bluetooth::hci::ApcfAction::ADD, subsubcommand_view.GetApcfFilterIndex(), @@ -2953,7 +2982,7 @@ void DualModeController::LeApcf(CommandView command) { auto subsubcommand_view = bluetooth::hci::LeApcfDeleteBroadcasterAddressView::Create( subcommand_view); - ASSERT(subsubcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); status = link_layer_controller_.LeApcfBroadcasterAddress( bluetooth::hci::ApcfAction::DELETE, subsubcommand_view.GetApcfFilterIndex(), @@ -2966,7 +2995,7 @@ void DualModeController::LeApcf(CommandView command) { auto subsubcommand_view = bluetooth::hci::LeApcfClearBroadcasterAddressView::Create( subcommand_view); - ASSERT(subsubcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); status = link_layer_controller_.LeApcfBroadcasterAddress( bluetooth::hci::ApcfAction::CLEAR, subsubcommand_view.GetApcfFilterIndex(), Address(), @@ -2975,7 +3004,8 @@ void DualModeController::LeApcf(CommandView command) { break; } default: - INFO(id_, "unknown apcf action {}", subcommand_view.GetApcfAction()); + INFO(id_, "unknown apcf action {}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); break; } @@ -2988,10 +3018,11 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::SERVICE_UUID: { auto subcommand_view = bluetooth::hci::LeApcfServiceUuidView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Service UUID"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); uint8_t apcf_available_spaces = 0; ErrorCode status = link_layer_controller_.LeApcfServiceUuid( @@ -3006,10 +3037,11 @@ void DualModeController::LeApcf(CommandView command) { auto subcommand_view = bluetooth::hci::LeApcfServiceSolicitationUuidView::Create( command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Service Solicitation UUID"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); uint8_t apcf_available_spaces = 0; ErrorCode status = link_layer_controller_.LeApcfServiceSolicitationUuid( @@ -3024,10 +3056,11 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::LOCAL_NAME: { auto subcommand_view = bluetooth::hci::LeApcfLocalNameView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Local Name"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); uint8_t apcf_available_spaces = 0; ErrorCode status = link_layer_controller_.LeApcfLocalName( @@ -3041,10 +3074,11 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::MANUFACTURER_DATA: { auto subcommand_view = bluetooth::hci::LeApcfManufacturerDataView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Manufacturer Data"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); uint8_t apcf_available_spaces = 0; ErrorCode status = link_layer_controller_.LeApcfManufacturerData( @@ -3058,10 +3092,11 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::SERVICE_DATA: { auto subcommand_view = bluetooth::hci::LeApcfServiceDataView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Service Data"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); uint8_t apcf_available_spaces = 0; ErrorCode status = link_layer_controller_.LeApcfServiceData( @@ -3075,10 +3110,11 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::AD_TYPE_FILTER: { auto subcommand_view = bluetooth::hci::LeApcfAdTypeFilterView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF AD Type Filter"); - DEBUG(id_, " action={}", subcommand_view.GetApcfAction()); + DEBUG(id_, " action={}", + bluetooth::hci::ApcfActionText(subcommand_view.GetApcfAction())); uint8_t apcf_available_spaces = 0; ErrorCode status = link_layer_controller_.LeApcfAdTypeFilter( @@ -3093,7 +3129,7 @@ void DualModeController::LeApcf(CommandView command) { case bluetooth::hci::ApcfOpcode::READ_EXTENDED_FEATURES: { auto subcommand_view = bluetooth::hci::LeApcfReadExtendedFeaturesView::Create(command_view); - ASSERT(subcommand_view.IsValid()); + CHECK_PACKET_VIEW(subcommand_view); DEBUG(id_, "<< LE APCF Read Extended Features"); @@ -3105,7 +3141,8 @@ void DualModeController::LeApcf(CommandView command) { break; } default: - FATAL(id_, "unknown APCF opcode {}", command_view.GetApcfOpcode()); + FATAL(id_, "unknown APCF opcode {}", + static_cast(command_view.GetApcfOpcode())); } } @@ -3113,7 +3150,7 @@ void DualModeController::LeGetControllerActivityEnergyInfo( CommandView command) { auto command_view = bluetooth::hci::LeGetControllerActivityEnergyInfoView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); SendCommandCompleteUnknownOpCodeEvent( OpCode::LE_GET_CONTROLLER_ACTIVITY_ENERGY_INFO); } @@ -3121,14 +3158,14 @@ void DualModeController::LeGetControllerActivityEnergyInfo( void DualModeController::LeExSetScanParameters(CommandView command) { auto command_view = bluetooth::hci::LeExSetScanParametersView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); SendCommandCompleteUnknownOpCodeEvent(OpCode::LE_EX_SET_SCAN_PARAMETERS); } void DualModeController::GetControllerDebugInfo(CommandView command) { auto command_view = bluetooth::hci::GetControllerDebugInfoView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Get Controller Debug Info"); @@ -3255,14 +3292,16 @@ void DualModeController::CsrReadVarid(CsrVarid varid, break; default: - INFO(id_, "Unsupported read of CSR varid 0x{:04x}", varid); + INFO(id_, "Unsupported read of CSR varid 0x{:04x}", + static_cast(varid)); break; } } void DualModeController::CsrWriteVarid( CsrVarid varid, std::vector const& /*value*/) const { - INFO(id_, "Unsupported write of CSR varid 0x{:04x}", varid); + INFO(id_, "Unsupported write of CSR varid 0x{:04x}", + static_cast(varid)); } void DualModeController::CsrReadPskey(CsrPskey pskey, @@ -3286,7 +3325,8 @@ void DualModeController::CsrReadPskey(CsrPskey pskey, break; default: - INFO(id_, "Unsupported read of CSR pskey 0x{:04x}", pskey); + INFO(id_, "Unsupported read of CSR pskey 0x{:04x}", + static_cast(pskey)); break; } } @@ -3305,7 +3345,8 @@ void DualModeController::CsrWritePskey(CsrPskey pskey, break; default: - INFO(id_, "Unsupported write of CSR pskey 0x{:04x}", pskey); + INFO(id_, "Unsupported write of CSR pskey 0x{:04x}", + static_cast(pskey)); break; } } @@ -3313,7 +3354,7 @@ void DualModeController::CsrWritePskey(CsrPskey pskey, void DualModeController::LeSetAdvertisingSetRandomAddress(CommandView command) { auto command_view = bluetooth::hci::LeSetAdvertisingSetRandomAddressView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Advertising Set Random Address"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -3330,7 +3371,7 @@ void DualModeController::LeSetExtendedAdvertisingParameters( CommandView command) { auto command_view = bluetooth::hci::LeSetExtendedAdvertisingParametersView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Extended Advertising Parameters"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -3359,7 +3400,7 @@ void DualModeController::LeSetExtendedAdvertisingParameters( void DualModeController::LeSetExtendedAdvertisingData(CommandView command) { auto command_view = bluetooth::hci::LeSetExtendedAdvertisingDataView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Extended Advertising Data"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -3375,7 +3416,7 @@ void DualModeController::LeSetExtendedAdvertisingData(CommandView command) { void DualModeController::LeSetExtendedScanResponseData(CommandView command) { auto command_view = bluetooth::hci::LeSetExtendedScanResponseDataView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Extended Scan Response Data"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -3391,7 +3432,7 @@ void DualModeController::LeSetExtendedScanResponseData(CommandView command) { void DualModeController::LeSetExtendedAdvertisingEnable(CommandView command) { auto command_view = bluetooth::hci::LeSetExtendedAdvertisingEnableView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Set Extended Advertising Enable"); DEBUG(id_, " enable={}", @@ -3412,7 +3453,7 @@ void DualModeController::LeReadMaximumAdvertisingDataLength( CommandView command) { auto command_view = bluetooth::hci::LeReadMaximumAdvertisingDataLengthView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Maximum Advertising Data Length"); @@ -3427,7 +3468,7 @@ void DualModeController::LeReadNumberOfSupportedAdvertisingSets( auto command_view = bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsView::Create( command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Read Number of Supported Advertising Sets"); @@ -3440,7 +3481,7 @@ void DualModeController::LeReadNumberOfSupportedAdvertisingSets( void DualModeController::LeRemoveAdvertisingSet(CommandView command) { auto command_view = bluetooth::hci::LeRemoveAdvertisingSetView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Remove Advertising Set"); DEBUG(id_, " advertising_handle={}", command_view.GetAdvertisingHandle()); @@ -3454,7 +3495,7 @@ void DualModeController::LeRemoveAdvertisingSet(CommandView command) { void DualModeController::LeClearAdvertisingSets(CommandView command) { auto command_view = bluetooth::hci::LeClearAdvertisingSetsView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Clear Advertising Sets"); @@ -3465,7 +3506,7 @@ void DualModeController::LeClearAdvertisingSets(CommandView command) { void DualModeController::LeStartEncryption(CommandView command) { auto command_view = bluetooth::hci::LeStartEncryptionView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< LE Start Encryption"); DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle()); @@ -3481,7 +3522,7 @@ void DualModeController::LeStartEncryption(CommandView command) { void DualModeController::LeLongTermKeyRequestReply(CommandView command) { auto command_view = bluetooth::hci::LeLongTermKeyRequestReplyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< LE Long Term Key Request Reply"); @@ -3498,7 +3539,7 @@ void DualModeController::LeLongTermKeyRequestNegativeReply( CommandView command) { auto command_view = bluetooth::hci::LeLongTermKeyRequestNegativeReplyView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); uint16_t handle = command_view.GetConnectionHandle(); DEBUG(id_, "<< LE Long Term Key Request Negative Reply"); @@ -3515,7 +3556,7 @@ void DualModeController::LeLongTermKeyRequestNegativeReply( void DualModeController::ReadConnectionAcceptTimeout(CommandView command) { auto command_view = bluetooth::hci::ReadConnectionAcceptTimeoutView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Connection Accept Timeout"); @@ -3528,7 +3569,7 @@ void DualModeController::ReadConnectionAcceptTimeout(CommandView command) { void DualModeController::WriteConnectionAcceptTimeout(CommandView command) { auto command_view = bluetooth::hci::WriteConnectionAcceptTimeoutView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Connection Accept Timeout"); @@ -3542,7 +3583,7 @@ void DualModeController::WriteConnectionAcceptTimeout(CommandView command) { void DualModeController::ReadLoopbackMode(CommandView command) { auto command_view = bluetooth::hci::ReadLoopbackModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Read Loopback Mode"); @@ -3552,10 +3593,11 @@ void DualModeController::ReadLoopbackMode(CommandView command) { void DualModeController::WriteLoopbackMode(CommandView command) { auto command_view = bluetooth::hci::WriteLoopbackModeView::Create(command); - ASSERT(command_view.IsValid()); + CHECK_PACKET_VIEW(command_view); DEBUG(id_, "<< Write Loopback Mode"); - DEBUG(id_, " loopback_mode={}", command_view.GetLoopbackMode()); + DEBUG(id_, " loopback_mode={}", + bluetooth::hci::LoopbackModeText(command_view.GetLoopbackMode())); loopback_mode_ = command_view.GetLoopbackMode(); // ACL channel diff --git a/tools/rootcanal/model/controller/dual_mode_controller.h b/tools/rootcanal/model/controller/dual_mode_controller.h index 3f56acc7893c2a8fefba2d654f9940b732be0ea6..f3b0ce1726823929b7a61ab6a4bc537ff3408515 100644 --- a/tools/rootcanal/model/controller/dual_mode_controller.h +++ b/tools/rootcanal/model/controller/dual_mode_controller.h @@ -40,6 +40,13 @@ namespace rootcanal { using ::bluetooth::hci::Address; using ::bluetooth::hci::CommandView; +// List of reject reasons for invalid packets. +enum InvalidPacketReason { + kUnknown = 0, + kParseError = 1, + kUnsupported = 2, +}; + // Emulates a dual mode BR/EDR + LE controller by maintaining the link layer // state machine detailed in the Bluetooth Core Specification Version 4.2, // Volume 6, Part B, Section 1.1 (page 30). Provides methods corresponding to @@ -78,6 +85,13 @@ class DualModeController : public Device { void HandleSco(std::shared_ptr> sco_packet); void HandleIso(std::shared_ptr> iso_packet); + /// Report invalid packets received for this controller instance + /// to an external tracker. Packets are rejected if they failed to + /// be parsed, or run into an unimplemented part of the controller. + void RegisterInvalidPacketHandler( + const std::function const&)>& handler); + // Set the callbacks for sending packets to the HCI. void RegisterEventChannel( const std::function>)>& @@ -539,6 +553,24 @@ class DualModeController : public Device { void SendCommandCompleteUnknownOpCodeEvent( bluetooth::hci::OpCode op_code) const; + // Validate that a received packet is correctly formatted. + // If the packet failed to be parsed, the function sends a + // HCI Hardware Error event to the host and logs the packet to + // the configured handler. + template + bool CheckPacketView(T const& view, std::string reason) { + if (view.IsValid()) { + return true; + } + + // Send a hardware error to reset the host, and report the packet + // for tracing. + send_event_(bluetooth::hci::HardwareErrorBuilder::Create(0x43)); + invalid_packet_handler_(id_, InvalidPacketReason::kParseError, reason, + view.bytes().bytes()); + return false; + } + // Callbacks to send packets back to the HCI. std::function)> send_acl_; std::function)> @@ -546,6 +578,11 @@ class DualModeController : public Device { std::function)> send_sco_; std::function)> send_iso_; + // Report invalid packets received on this controller instance. + std::function const&)> + invalid_packet_handler_; + // Loopback mode (Vol 4, Part E § 7.6.1). // The local loopback mode is used to pass the android Vendor Test Suite // with RootCanal. diff --git a/tools/rootcanal/model/controller/le_advertiser.cc b/tools/rootcanal/model/controller/le_advertiser.cc index 865ceeb6b9734da449d189b8535913c16488fef2..c27beef9e5c8e5b37246fa799e8db0996a6f2828 100644 --- a/tools/rootcanal/model/controller/le_advertiser.cc +++ b/tools/rootcanal/model/controller/le_advertiser.cc @@ -47,8 +47,10 @@ slots operator"" _slots(unsigned long long count) { return slots(count); } // ============================================================================= // Vol 6, Part B § 4.4.2.4.3 High duty cycle connectable directed advertising. +// NB: The interval is specified to be 3.75ms, but it does not make sense to +// use this value with the timer tick at 5ms. const chrono::duration adv_direct_ind_high_timeout = 1280ms; -const chrono::duration adv_direct_ind_high_interval = 3750us; +const chrono::duration adv_direct_ind_high_interval = 10ms /*3750us*/; // Vol 6, Part B § 2.3.4.9 Host Advertising Data. const uint16_t max_legacy_advertising_pdu_size = 31; @@ -546,7 +548,7 @@ ErrorCode LinkLayerController::LeSetExtendedAdvertisingParameters( #if 0 if (advertiser.periodic_advertising_enable) { // TODO - INFO(id_, + INFO(id_, "periodic advertising is enabled for the specified advertising set" " and the secondary PHY does not match the periodic" " advertising PHY"); @@ -1148,6 +1150,19 @@ ErrorCode LinkLayerController::LeSetExtendedAdvertisingEnable( } break; } + + // If an IRK is available in the Link Layer Resolving List for the peer + // device, then the target’s device address (TargetA field) shall + // use a resolvable private address. If an IRK is not available in the + // Link Layer Resolving List or the IRK is set to zero for the peer device, + // then the target’s device address (TargetA field) shall use the Identity + // Address when entering the Advertising State and using connectable + // directed events. + if (advertiser.IsDirected()) { + advertiser.target_address = + GenerateResolvablePrivateAddress(peer_address, IrkSelection::Peer) + .value_or(peer_address); + } } for (auto& set : sets) { @@ -1661,7 +1676,8 @@ void LinkLayerController::LeAdvertising() { // Generate Link Layer Advertising events when advertising is enabled // and a full interval has passed since the last event. if (legacy_advertiser_.IsEnabled() && now >= legacy_advertiser_.next_event) { - legacy_advertiser_.next_event += legacy_advertiser_.advertising_interval; + legacy_advertiser_.next_event = + now + legacy_advertiser_.advertising_interval; model::packets::LegacyAdvertisingType type; bool attach_advertising_data = true; switch (legacy_advertiser_.advertising_type) { diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc index 1ef188ba9aa98084288eda40100027469050f109..d0754bd6fbe8cea6704a492d64922b30e56d2074 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.cc +++ b/tools/rootcanal/model/controller/link_layer_controller.cc @@ -58,6 +58,7 @@ using TaskId = rootcanal::LinkLayerController::TaskId; namespace rootcanal { +constexpr milliseconds kScanRequestTimeout(200); constexpr milliseconds kNoDelayMs(0); constexpr milliseconds kPageInterval(1000); @@ -207,7 +208,7 @@ bool LinkLayerController::ResolvingListBusy() { } std::optional LinkLayerController::ResolvePrivateAddress( - AddressWithType address, IrkSelection irk) { + AddressWithType address) { if (!address.IsRpa()) { return address; } @@ -217,31 +218,50 @@ std::optional LinkLayerController::ResolvePrivateAddress( } for (auto& entry : le_resolving_list_) { - std::array const& used_irk = - irk == IrkSelection::Local ? entry.local_irk : entry.peer_irk; - - if (address.IsRpaThatMatchesIrk(used_irk)) { + if (address.IsRpaThatMatchesIrk(entry.peer_irk)) { // Update the peer resolvable address used for the peer // with the returned identity address. - if (irk == IrkSelection::Peer) { - entry.peer_resolvable_address = address.GetAddress(); - } + entry.peer_resolvable_address = address.GetAddress(); - return PeerIdentityAddress(entry.peer_identity_address, - entry.peer_identity_address_type); + return PeerDeviceAddress(entry.peer_identity_address, + entry.peer_identity_address_type); } } return {}; } -std::optional -LinkLayerController::GenerateResolvablePrivateAddress(AddressWithType address, - IrkSelection irk) { +bool LinkLayerController::ResolveTargetA(AddressWithType target_a, + AddressWithType adv_a) { if (!le_resolving_list_enabled_) { - return {}; + return false; + } + + for (auto const& entry : le_resolving_list_) { + if (adv_a == PeerDeviceAddress(entry.peer_identity_address, + entry.peer_identity_address_type) && + target_a.IsRpaThatMatchesIrk(entry.local_irk)) { + return true; + } + } + + return false; +} + +bool LinkLayerController::ValidateTargetA(AddressWithType target_a, + AddressWithType adv_a) { + if (IsLocalPublicOrRandomAddress(target_a)) { + return true; } + if (target_a.IsRpa()) { + return ResolveTargetA(target_a, adv_a); + } + return false; +} +std::optional +LinkLayerController::GenerateResolvablePrivateAddress(AddressWithType address, + IrkSelection irk) { for (auto& entry : le_resolving_list_) { if (address.GetAddress() == entry.peer_identity_address && address.ToPeerAddressType() == entry.peer_identity_address_type) { @@ -1255,6 +1275,7 @@ ErrorCode LinkLayerController::LeSetScanEnable(bool enable, if (!enable) { scanner_.scan_enable = false; scanner_.pending_scan_request = {}; + scanner_.pending_scan_request_timeout = {}; scanner_.history.clear(); return ErrorCode::SUCCESS; } @@ -1284,6 +1305,7 @@ ErrorCode LinkLayerController::LeSetScanEnable(bool enable, scanner_.timeout = {}; scanner_.periodical_timeout = {}; scanner_.pending_scan_request = {}; + scanner_.pending_scan_request_timeout = {}; scanner_.filter_duplicates = filter_duplicates ? bluetooth::hci::FilterDuplicates::ENABLED : bluetooth::hci::FilterDuplicates::DISABLED; @@ -1415,6 +1437,7 @@ ErrorCode LinkLayerController::LeSetExtendedScanEnable( if (!enable) { scanner_.scan_enable = false; scanner_.pending_scan_request = {}; + scanner_.pending_scan_request_timeout = {}; scanner_.history.clear(); return ErrorCode::SUCCESS; } @@ -1472,6 +1495,7 @@ ErrorCode LinkLayerController::LeSetExtendedScanEnable( scanner_.timeout = {}; scanner_.periodical_timeout = {}; scanner_.pending_scan_request = {}; + scanner_.pending_scan_request_timeout = {}; scanner_.filter_duplicates = filter_duplicates; scanner_.duration = duration_ms; scanner_.period = period_ms; @@ -2897,11 +2921,7 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( // address. The scanner’s filter policy shall then determine if the scanner // responds with a scan request. AddressWithType resolved_advertising_address = - ResolvePrivateAddress(advertising_address, IrkSelection::Peer) - .value_or(advertising_address); - - std::optional resolved_target_address = - ResolvePrivateAddress(target_address, IrkSelection::Peer); + ResolvePrivateAddress(advertising_address).value_or(advertising_address); if (resolved_advertising_address != advertising_address) { DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address, @@ -2944,8 +2964,7 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( // resolution is enabled, and the address is resolved successfully case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL: case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY: - if (!IsLocalPublicOrRandomAddress(target_address) && - !(target_address.IsRpa() && resolved_target_address)) { + if (!ValidateTargetA(target_address, resolved_advertising_address)) { DEBUG(id_, "Legacy advertising ignored by scanner because the directed " "address {} does not match the current device or cannot be " @@ -2971,7 +2990,8 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( return; } should_send_directed_advertising_report = - target_address.IsRpa() && !resolved_target_address; + target_address.IsRpa() && + !ResolveTargetA(target_address, resolved_advertising_address); break; } } @@ -3145,7 +3165,10 @@ void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( // Save the original advertising type to report if the advertising // is connectable in the scan response report. scanner_.connectable_scan_response = connectable_advertising; + scanner_.extended_scan_response = false; scanner_.pending_scan_request = advertising_address; + scanner_.pending_scan_request_timeout = + std::chrono::steady_clock::now() + kScanRequestTimeout; INFO(id_, "Sending LE Scan request to advertising address {} with scanning " @@ -3202,12 +3225,7 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu( static_cast(pdu.GetTargetAddressType())}; AddressWithType resolved_advertising_address = - ResolvePrivateAddress(advertising_address, IrkSelection::Peer) - .value_or(advertising_address); - - AddressWithType resolved_target_address = - ResolvePrivateAddress(target_address, IrkSelection::Peer) - .value_or(target_address); + ResolvePrivateAddress(advertising_address).value_or(advertising_address); // Vol 6, Part B § 4.3.5 Initiator filter policy. switch (initiator_.initiator_filter_policy) { @@ -3240,14 +3258,14 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu( // contain Public or Static addresses for the target’s address (TargetA // field). if (directed_advertising) { - if (!IsLocalPublicOrRandomAddress(resolved_target_address)) { + if (!ValidateTargetA(target_address, resolved_advertising_address)) { DEBUG(id_, "Directed legacy advertising ignored by initiator because the " "target address {} does not match the current device addresses", - resolved_advertising_address); + target_address); return; } - if (resolved_target_address == target_address && + if (!target_address.IsRpa() && (initiator_.own_address_type == OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS || initiator_.own_address_type == @@ -3256,7 +3274,7 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu( "Directed legacy advertising ignored by initiator because the " "target address {} is static or public and the initiator is " "configured to use resolvable addresses", - resolved_advertising_address); + target_address); return; } } @@ -3370,16 +3388,14 @@ void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu( // address. The scanner’s filter policy shall then determine if the scanner // responds with a scan request. AddressWithType resolved_advertising_address = - ResolvePrivateAddress(advertising_address, IrkSelection::Peer) - .value_or(advertising_address); - - std::optional resolved_target_address = - ResolvePrivateAddress(target_address, IrkSelection::Peer); + ResolvePrivateAddress(advertising_address).value_or(advertising_address); if (resolved_advertising_address != advertising_address) { DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address, - advertising_address.GetAddressType(), resolved_advertising_address, - resolved_advertising_address.GetAddressType()); + bluetooth::hci::AddressTypeText(advertising_address.GetAddressType()), + resolved_advertising_address, + bluetooth::hci::AddressTypeText( + resolved_advertising_address.GetAddressType())); } // Vol 6, Part B § 4.3.3 Scanner filter policy @@ -3409,8 +3425,7 @@ void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu( // resolution is enabled, and the address is resolved successfully case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL: case bluetooth::hci::LeScanningFilterPolicy::FILTER_ACCEPT_LIST_ONLY: - if (!IsLocalPublicOrRandomAddress(target_address) && - !(target_address.IsRpa() && resolved_target_address)) { + if (!ValidateTargetA(target_address, resolved_advertising_address)) { DEBUG(id_, "Extended advertising ignored by scanner because the directed " "address {} does not match the current device or cannot be " @@ -3574,6 +3589,7 @@ void LinkLayerController::ScanIncomingLeExtendedAdvertisingPdu( // Save the original advertising type to report if the advertising // is connectable in the scan response report. scanner_.connectable_scan_response = connectable_advertising; + scanner_.extended_scan_response = true; scanner_.pending_scan_request = advertising_address; INFO(id_, @@ -3629,12 +3645,7 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu( static_cast(pdu.GetTargetAddressType())}; AddressWithType resolved_advertising_address = - ResolvePrivateAddress(advertising_address, IrkSelection::Peer) - .value_or(advertising_address); - - AddressWithType resolved_target_address = - ResolvePrivateAddress(target_address, IrkSelection::Peer) - .value_or(target_address); + ResolvePrivateAddress(advertising_address).value_or(advertising_address); // Vol 6, Part B § 4.3.5 Initiator filter policy. switch (initiator_.initiator_filter_policy) { @@ -3667,14 +3678,14 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu( // contain Public or Static addresses for the target’s address (TargetA // field). if (pdu.GetDirected()) { - if (!IsLocalPublicOrRandomAddress(resolved_target_address)) { + if (!ValidateTargetA(target_address, resolved_advertising_address)) { DEBUG(id_, "Directed extended advertising ignored by initiator because the " "target address {} does not match the current device addresses", - resolved_advertising_address); + target_address); return; } - if (resolved_target_address == target_address && + if (!target_address.IsRpa() && (initiator_.own_address_type == OwnAddressType::RESOLVABLE_OR_PUBLIC_ADDRESS || initiator_.own_address_type == @@ -3683,7 +3694,7 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu( "Directed extended advertising ignored by initiator because the " "target address {} is static or public and the initiator is " "configured to use resolvable addresses", - resolved_advertising_address); + target_address); return; } } @@ -3790,8 +3801,7 @@ void LinkLayerController::IncomingLePeriodicAdvertisingPdu( // address. The scanner's periodic sync establishment filter policy shall // determine if the scanner processes the advertising packet. AddressWithType resolved_advertiser_address = - ResolvePrivateAddress(advertiser_address, IrkSelection::Peer) - .value_or(advertiser_address); + ResolvePrivateAddress(advertiser_address).value_or(advertiser_address); bluetooth::hci::AdvertiserAddressType advertiser_address_type; switch (resolved_advertiser_address.GetAddressType()) { @@ -4232,16 +4242,7 @@ uint16_t LinkLayerController::HandleLeConnection( AddressType peer_address_type = address.GetAddressType(); if (peer_resolved_address != AddressWithType()) { peer_resolvable_private_address = address.GetAddress(); - if (peer_resolved_address.GetAddressType() == - AddressType::PUBLIC_DEVICE_ADDRESS) { - peer_address_type = AddressType::PUBLIC_IDENTITY_ADDRESS; - } else if (peer_resolved_address.GetAddressType() == - AddressType::RANDOM_DEVICE_ADDRESS) { - peer_address_type = AddressType::RANDOM_IDENTITY_ADDRESS; - } else { - WARNING(id_, "Unhandled resolved address type {} -> {}", address, - peer_resolved_address); - } + peer_address_type = peer_resolved_address.GetAddressType(); connection_address = peer_resolved_address.GetAddress(); } Address local_resolved_address = own_address.GetAddress(); @@ -4322,8 +4323,7 @@ bool LinkLayerController::ProcessIncomingLegacyConnectRequest( // The advertising filter policy shall then determine if the // advertiser establishes a connection. AddressWithType resolved_initiating_address = - ResolvePrivateAddress(initiating_address, IrkSelection::Peer) - .value_or(initiating_address); + ResolvePrivateAddress(initiating_address).value_or(initiating_address); if (resolved_initiating_address != initiating_address) { DEBUG(id_, "Resolved the initiating address {} to {}", initiating_address, @@ -4333,11 +4333,14 @@ bool LinkLayerController::ProcessIncomingLegacyConnectRequest( // When the Link Layer is [...] connectable directed advertising events the // advertising filter policy shall be ignored. if (legacy_advertiser_.IsDirected()) { - if (legacy_advertiser_.GetTargetAddress() != resolved_initiating_address) { + if (resolved_initiating_address != + PeerDeviceAddress(legacy_advertiser_.peer_address, + legacy_advertiser_.peer_address_type)) { DEBUG(id_, "LE Connect request ignored by legacy advertiser because the " - "initiating address {} does not match the target address {}", - resolved_initiating_address, legacy_advertiser_.GetTargetAddress()); + "initiating address {} does not match the target address {}[{}]", + resolved_initiating_address, legacy_advertiser_.peer_address, + PeerAddressTypeText(legacy_advertiser_.peer_address_type)); return false; } } else { @@ -4434,8 +4437,7 @@ bool LinkLayerController::ProcessIncomingExtendedConnectRequest( // The advertising filter policy shall then determine if the // advertiser establishes a connection. AddressWithType resolved_initiating_address = - ResolvePrivateAddress(initiating_address, IrkSelection::Peer) - .value_or(initiating_address); + ResolvePrivateAddress(initiating_address).value_or(initiating_address); if (resolved_initiating_address != initiating_address) { DEBUG(id_, "Resolved the initiating address {} to {}", initiating_address, @@ -4445,12 +4447,15 @@ bool LinkLayerController::ProcessIncomingExtendedConnectRequest( // When the Link Layer is [...] connectable directed advertising events the // advertising filter policy shall be ignored. if (advertiser.IsDirected()) { - if (advertiser.GetTargetAddress() != resolved_initiating_address) { + if (resolved_initiating_address != + PeerDeviceAddress(advertiser.peer_address, + advertiser.peer_address_type)) { DEBUG(id_, "LE Connect request ignored by extended advertiser {} because the " - "initiating address {} does not match the target address {}", + "initiating address {} does not match the target address {}[{}]", advertiser.advertising_handle, resolved_initiating_address, - advertiser.GetTargetAddress()); + advertiser.peer_address, + PeerAddressTypeText(advertiser.peer_address_type)); return false; } } else { @@ -4869,8 +4874,7 @@ void LinkLayerController::IncomingLeScanPacket( // address. The advertising filter policy shall then determine if // the advertiser processes the scan request. AddressWithType resolved_scanning_address = - ResolvePrivateAddress(scanning_address, IrkSelection::Peer) - .value_or(scanning_address); + ResolvePrivateAddress(scanning_address).value_or(scanning_address); if (resolved_scanning_address != scanning_address) { DEBUG(id_, "Resolved the scanning address {} to {}", scanning_address, @@ -4919,8 +4923,7 @@ void LinkLayerController::IncomingLeScanResponsePacket( } AddressWithType resolved_advertising_address = - ResolvePrivateAddress(advertising_address, IrkSelection::Peer) - .value_or(advertising_address); + ResolvePrivateAddress(advertising_address).value_or(advertising_address); if (advertising_address != resolved_advertising_address) { DEBUG(id_, "Resolved the advertising address {} to {}", advertising_address, @@ -4962,15 +4965,36 @@ void LinkLayerController::IncomingLeScanResponsePacket( resolved_advertising_address.GetAddressType()); response.connectable_ = scanner_.connectable_scan_response; response.scannable_ = true; - response.legacy_ = true; + response.legacy_ = !scanner_.extended_scan_response; response.scan_response_ = true; response.primary_phy_ = bluetooth::hci::PrimaryPhyType::LE_1M; + // TODO: SID should be set in scan response PDU response.advertising_sid_ = 0xFF; response.tx_power_ = 0x7F; - response.advertising_data_ = scan_response.GetScanResponseData(); response.rssi_ = rssi; - send_event_( - bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({response})); + response.direct_address_type_ = + bluetooth::hci::DirectAdvertisingAddressType::NO_ADDRESS_PROVIDED; + + // Each extended advertising report can only pass 229 bytes of + // advertising data (255 - size of report fields). + // RootCanal must fragment the report as necessary. + const size_t max_fragment_size = 229; + size_t offset = 0; + std::vector advertising_data = scan_response.GetScanResponseData(); + + do { + size_t remaining_size = advertising_data.size() - offset; + size_t fragment_size = std::min(max_fragment_size, remaining_size); + response.data_status_ = remaining_size <= max_fragment_size + ? bluetooth::hci::DataStatus::COMPLETE + : bluetooth::hci::DataStatus::CONTINUING; + response.advertising_data_ = + std::vector(advertising_data.begin() + offset, + advertising_data.begin() + offset + fragment_size); + offset += fragment_size; + send_event_(bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create( + {response})); + } while (offset < advertising_data.size()); } } @@ -5017,6 +5041,15 @@ void LinkLayerController::LeScanning() { scanner_.timeout = now + scanner_.duration; scanner_.periodical_timeout = now + scanner_.period; } + + // Pending scan timeout. + // Cancel the pending scan request. This may condition may be triggered + // when the advertiser is stopped before sending the scan request. + if (scanner_.pending_scan_request_timeout.has_value() && + now >= scanner_.pending_scan_request_timeout.value()) { + scanner_.pending_scan_request = {}; + scanner_.pending_scan_request_timeout = {}; + } } void LinkLayerController::LeSynchronization() { diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h index ce50d91f1f409d3e3c320375139d98518ef35d7e..e9645b8087a042ece5f67e50a7f19ff90966d71d 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.h +++ b/tools/rootcanal/model/controller/link_layer_controller.h @@ -228,8 +228,17 @@ class LinkLayerController { // resolve the address using the resolving list. If the address cannot // be resolved none is returned. If the address is not a Resolvable // Private Address, the original address is returned. - std::optional ResolvePrivateAddress(AddressWithType address, - IrkSelection irk); + std::optional ResolvePrivateAddress(AddressWithType address); + + // Returns true if the input address resolves with the local IRK + // associated with the given peer identity address. + bool ResolveTargetA(AddressWithType target_a, AddressWithType adv_a); + + // Returns true if either: + // • TargetA is identical to the device address, or + // • TargetA is a resolvable private address, address + // resolution is enabled, and the address is resolved successfully + bool ValidateTargetA(AddressWithType target_a, AddressWithType adv_a); // Generate a Resolvable Private for the selected peer. // If the address is not found in the resolving list none is returned. @@ -1061,7 +1070,10 @@ class LinkLayerController { // Save information about the advertising PDU being scanned. bool connectable_scan_response; + bool extended_scan_response; std::optional pending_scan_request{}; + std::optional + pending_scan_request_timeout{}; // Time keeping std::optional timeout; diff --git a/tools/rootcanal/model/devices/scripted_beacon.cc b/tools/rootcanal/model/devices/scripted_beacon.cc index 7215066d68d5817e5ced76b192662ac370221aa8..9095d11401ed864a75ebbb68aa36973c198fccbc 100644 --- a/tools/rootcanal/model/devices/scripted_beacon.cc +++ b/tools/rootcanal/model/devices/scripted_beacon.cc @@ -97,7 +97,7 @@ bool has_time_elapsed(steady_clock::time_point time_point) { static void populate_event(PlaybackEvent* event, PlaybackEvent::PlaybackEventType type) { - INFO("Adding event: {}", type); + INFO("Adding event: {}", PlaybackEvent::PlaybackEventType_Name(type)); event->set_type(type); event->set_secs_since_epoch(system_clock::now().time_since_epoch().count()); } @@ -111,7 +111,8 @@ void ScriptedBeacon::set_state(PlaybackEvent::PlaybackEventType state) { events_ostream_.open(events_file_, std::ios::out | std::ios::binary | std::ios::trunc); if (!events_ostream_.is_open()) { - INFO("Events file not opened yet, for event: {}", state); + INFO("Events file not opened yet, for event: {}", + PlaybackEvent::PlaybackEventType_Name(state)); return; } } diff --git a/tools/rootcanal/model/hci/h4_data_channel_packetizer.cc b/tools/rootcanal/model/hci/h4_data_channel_packetizer.cc index e8f2114ecd25257b279ec1d644f1087d1f865f65..15e6f3d63c9001ad5a04b402d2f6e36f54dbb7b3 100644 --- a/tools/rootcanal/model/hci/h4_data_channel_packetizer.cc +++ b/tools/rootcanal/model/hci/h4_data_channel_packetizer.cc @@ -90,7 +90,8 @@ void H4DataChannelPacketizer::OnDataReady( disconnect_cb_(); return; } - FATAL("Read error in {}: {}", h4_parser_.CurrentState(), strerror(errno)); + FATAL("Read error in {}: {}", fmt::underlying(h4_parser_.CurrentState()), + strerror(errno)); } h4_parser_.Consume(buffer.data(), bytes_read); } diff --git a/tools/rootcanal/model/hci/h4_parser.cc b/tools/rootcanal/model/hci/h4_parser.cc index c263cd7389aacd8ab81516d5cda3af4fcecd5346..b84ad1f63086f82f7f5c7a8a9973f4eac56c470a 100644 --- a/tools/rootcanal/model/hci/h4_parser.cc +++ b/tools/rootcanal/model/hci/h4_parser.cc @@ -85,7 +85,7 @@ void H4Parser::OnPacketReady() { iso_cb_(packet_); break; default: - FATAL("Unimplemented packet type {}", hci_packet_type_); + FATAL("Unimplemented packet type {}", fmt::underlying(hci_packet_type_)); } // Get ready for the next type byte. hci_packet_type_ = PacketType::UNKNOWN; diff --git a/tools/rootcanal/model/hci/hci_socket_transport.cc b/tools/rootcanal/model/hci/hci_socket_transport.cc index 82632e466ddb0c74085cd4c49c22085493e197e9..0fc556e9b7ae777c0d7d3723badc47182c3a01db 100644 --- a/tools/rootcanal/model/hci/hci_socket_transport.cc +++ b/tools/rootcanal/model/hci/hci_socket_transport.cc @@ -59,7 +59,8 @@ void HciSocketTransport::Tick() { h4_.OnDataReady(socket_); } void HciSocketTransport::Send(PacketType packet_type, const std::vector& packet) { if (!socket_ || !socket_->Connected()) { - INFO("Closed socket. Dropping packet of type {}", packet_type); + INFO("Closed socket. Dropping packet of type {}", + fmt::underlying(packet_type)); return; } uint8_t type = static_cast(packet_type); diff --git a/tools/rootcanal/model/setup/async_manager.cc b/tools/rootcanal/model/setup/async_manager.cc index 2bbdfba6d2c2997e9d620791db6c0213151782a3..caa92a0fc08f760741a4bf6e908f47c6c7fb894f 100644 --- a/tools/rootcanal/model/setup/async_manager.cc +++ b/tools/rootcanal/model/setup/async_manager.cc @@ -19,14 +19,24 @@ #include #include #include +#include #include +#include #include +#include #include -#include "fcntl.h" #include "log.h" -#include "sys/select.h" -#include "unistd.h" + +#ifndef TEMP_FAILURE_RETRY +/* Used to retry syscalls that can return EINTR. */ +#define TEMP_FAILURE_RETRY(exp) ({ \ + __typeof__(exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; }) +#endif // TEMP_FAILURE_RETRY namespace rootcanal { // Implementation of AsyncManager is divided between two classes, three if @@ -157,13 +167,23 @@ class AsyncManager::AsyncFdWatcher { } // set up the communication channel int pipe_fds[2]; - if (pipe2(pipe_fds, O_NONBLOCK)) { + if (pipe(pipe_fds)) { ERROR( "{}: Unable to establish a communication channel to the reading " "thread", __func__); return -1; } + // configure the fds as non blocking. + if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) || + fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK)) { + ERROR( + "{}: Unable to configure the communication channel to the reading " + "thread", + __func__); + return -1; + } + notification_listen_fd_ = pipe_fds[0]; notification_write_fd_ = pipe_fds[1]; diff --git a/tools/rootcanal/packets/hci_packets.pdl b/tools/rootcanal/packets/hci_packets.pdl index a2610f9c7a73c8c59c0d87ba7cf33c746e294cd6..363002aa48b5b59e71e7a0681c820ce74da68ad5 100644 --- a/tools/rootcanal/packets/hci_packets.pdl +++ b/tools/rootcanal/packets/hci_packets.pdl @@ -5646,7 +5646,7 @@ struct VendorCapabilities_V_0_96 { filtering_support: 8, max_filter: 8, activity_energy_info_support: 8, - _fixed_ = 0x6000 : 16, // v0.96 + _fixed_ = 0x0060 : 16, // v0.96 total_num_of_advt_tracked: 16, extended_scan_support: 8, debug_logging_supported: 8, @@ -5661,7 +5661,7 @@ struct VendorCapabilities_V_0_98 { filtering_support: 8, max_filter: 8, activity_energy_info_support: 8, - _fixed_ = 0x6200 : 16, // v0.98 + _fixed_ = 0x0062 : 16, // v0.98 total_num_of_advt_tracked: 16, extended_scan_support: 8, debug_logging_supported: 8, @@ -5678,7 +5678,7 @@ struct VendorCapabilities_V_1_03 { filtering_support: 8, max_filter: 8, activity_energy_info_support: 8, - _fixed_ = 0x0301 : 16, // v1.03 + _fixed_ = 0x0103 : 16, // v1.03 total_num_of_advt_tracked: 16, extended_scan_support: 8, debug_logging_supported: 8, diff --git a/tools/rootcanal/test/LL/CON_/INI/BV_08_C.py b/tools/rootcanal/test/LL/CON_/INI/BV_08_C.py new file mode 100644 index 0000000000000000000000000000000000000000..bfc23e8a9cf6adf8bac8bc372a1f423ead62d5af --- /dev/null +++ b/tools/rootcanal/test/LL/CON_/INI/BV_08_C.py @@ -0,0 +1,144 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 hci_packets as hci +import link_layer_packets as ll +import unittest +from hci_packets import ErrorCode +from py.bluetooth import Address +from py.controller import ControllerTest, generate_rpa + + +class Test(ControllerTest): + + LL_initiator_scanInterval_MIN = 0x2000 + LL_initiator_scanInterval_MAX = 0x2000 + LL_initiator_scanWindow_MIN = 0x200 + LL_initiator_scanWindow_MAX = 0x200 + LL_initiator_Adv_Channel_Map = 0x7 + LL_initiator_Channel_Map = 0x7 + + # LL/CON/INI/BV-08-C [Network Privacy – Connection Establishment responding + # to connectable undirected advertising, Initiator] + async def test(self): + # Test parameters. + controller = self.controller + local_irk = bytes([1] * 16) + peer_address = Address('aa:bb:cc:dd:ee:ff') + + if not controller.le_features.ll_privacy: + self.skipTest("LL privacy not supported") + + # 1. Configure the Lower Tester to advertise using a valid public or static random address (identity + # address). + + # 2. The Upper Tester adds the Identity Address of the Lower Tester to the Resolving List with all zero + # peer IRK, and with a local IRK. + controller.send_cmd( + hci.LeAddDeviceToResolvingList( + peer_irk=bytes([0] * 16), + local_irk=local_irk, + peer_identity_address=peer_address, + peer_identity_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS)) + + await self.expect_evt( + hci.LeAddDeviceToResolvingListComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetResolvablePrivateAddressTimeout(rpa_timeout=0x10)) + + await self.expect_evt( + hci.LeSetResolvablePrivateAddressTimeoutComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.ENABLED)) + + await self.expect_evt( + hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 3. The Upper Tester enables the initiator state in the IUT. + controller.send_cmd( + hci.LeCreateConnection(le_scan_interval=Test.LL_initiator_scanInterval_MIN, + le_scan_window=Test.LL_initiator_scanWindow_MIN, + initiator_filter_policy=hci.InitiatorFilterPolicy.USE_PEER_ADDRESS, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + own_address_type=hci.OwnAddressType.RESOLVABLE_OR_PUBLIC_ADDRESS, + connection_interval_min=0x200, + connection_interval_max=0x200, + max_latency=0x6, + supervision_timeout=0xc80, + min_ce_length=0, + max_ce_length=0)) + + await self.expect_evt(hci.LeCreateConnectionStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 4. Lower Tester sends ADV_IND packets, each advertising event on the selected advertising + # channel, using the selected advertising interval. + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=peer_address, + advertising_address_type=ll.AddressType.PUBLIC, + advertising_type=ll.LegacyAdvertisingType.ADV_IND, + advertising_data=[1, 2, 3]), + rssi=-16) + + # 5. The Lower Tester receives a CONNECT_IND packet T_IFS after any of the ADV_IND packets. + # The InitA field contains a resolvable private address from the IUT. + connect_ind = await self.expect_ll( + ll.LeConnect(source_address=self.Any, + destination_address=peer_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.PUBLIC, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + self.assertTrue(connect_ind.source_address.is_resolvable()) + self.assertTrue(connect_ind.source_address != controller.address) + + controller.send_ll( + ll.LeConnectComplete(source_address=peer_address, + destination_address=connect_ind.source_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.PUBLIC, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + # 6. Upper Tester receives an HCI_LE_Enhanced_Connection_Complete event from the IUT + # including the Lower Tester address and connection interval selected. + connect_complete = await self.expect_evt( + hci.LeEnhancedConnectionComplete(status=ErrorCode.SUCCESS, + connection_handle=self.Any, + role=hci.Role.CENTRAL, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + connection_interval=0x200, + peripheral_latency=0x6, + supervision_timeout=0xc80, + local_resolvable_private_address=connect_ind.source_address, + central_clock_accuracy=hci.ClockAccuracy.PPM_500)) + + # 7. After the CONNECT_IND has been received, the Lower Tester receives the first correctly + # formatted LL Data Channel PDU on the data channel. + + # 8. The Lower Tester sends a correctly formatted LL Data Channel PDU to the IUT on the same data + # channel using the acknowledgement scheme. + + controller.send_ll( + ll.Disconnect(source_address=peer_address, + destination_address=connect_ind.source_address, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) + + await self.expect_evt( + hci.DisconnectionComplete(status=hci.ErrorCode.SUCCESS, + connection_handle=connect_complete.connection_handle, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) diff --git a/tools/rootcanal/test/LL/CON_/INI/BV_09_C.py b/tools/rootcanal/test/LL/CON_/INI/BV_09_C.py new file mode 100644 index 0000000000000000000000000000000000000000..782c25ec335c41a818ab8430ec54afe456c58445 --- /dev/null +++ b/tools/rootcanal/test/LL/CON_/INI/BV_09_C.py @@ -0,0 +1,179 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 +import hci_packets as hci +import link_layer_packets as ll +import unittest +from hci_packets import ErrorCode +from py.bluetooth import Address +from py.controller import ControllerTest, generate_rpa + + +class Test(ControllerTest): + + LL_initiator_scanInterval_MIN = 0x2000 + LL_initiator_scanInterval_MAX = 0x2000 + LL_initiator_scanWindow_MIN = 0x200 + LL_initiator_scanWindow_MAX = 0x200 + LL_initiator_Adv_Channel_Map = 0x7 + LL_initiator_Channel_Map = 0x7 + + # LL/CON/INI/BV-09-C [Network Privacy – Connection Establishment using + # resolving list, Initiator] + # + # Verify that the IUT when initiating connection establishment only connects + # to devices that are in the resolving list. The Lower Tester uses + # connectable undirected advertising. + async def test(self): + # Test parameters. + controller = self.controller + local_irk = bytes([1] * 16) + peer_irk = bytes([2] * 16) + random_irk = bytes([3] * 16) + peer_address = Address('aa:bb:cc:dd:ee:ff') + + if not controller.le_features.ll_privacy: + self.skipTest("LL privacy not supported") + + # 1. Configure the Lower Tester to start advertising with a resolvable + # private address generated from a random IRK. + + # 2. The Upper Tester adds the Lower Tester to the resolving list using + # a different IRK than in step 1. + controller.send_cmd( + hci.LeAddDeviceToResolvingList( + peer_irk=peer_irk, + local_irk=local_irk, + peer_identity_address=peer_address, + peer_identity_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS)) + + await self.expect_evt( + hci.LeAddDeviceToResolvingListComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetResolvablePrivateAddressTimeout(rpa_timeout=0x10)) + + await self.expect_evt( + hci.LeSetResolvablePrivateAddressTimeoutComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.ENABLED)) + + await self.expect_evt( + hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 3. The Upper Tester enables the initiator state in the IUT. + controller.send_cmd( + hci.LeCreateConnection(le_scan_interval=Test.LL_initiator_scanInterval_MIN, + le_scan_window=Test.LL_initiator_scanWindow_MIN, + initiator_filter_policy=hci.InitiatorFilterPolicy.USE_PEER_ADDRESS, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + own_address_type=hci.OwnAddressType.RESOLVABLE_OR_PUBLIC_ADDRESS, + connection_interval_min=0x200, + connection_interval_max=0x200, + max_latency=0x6, + supervision_timeout=0xc80, + min_ce_length=0, + max_ce_length=0)) + + await self.expect_evt(hci.LeCreateConnectionStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 4. Lower Tester sends ADV_IND packets, each advertising event, using the selected advertising + # interval. Lower Tester repeats until the time exceeds 4 * scanInterval + 3 * scanWindow. + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=generate_rpa(random_irk), + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_IND, + advertising_data=[1, 2, 3]), + rssi=-16) + + # 5. The IUT compares the address by checking against its resolving list and does not find a match. + + # 6. The Lower Tester receives no CONNECT_IND after any of the ADV_IND packets. + try: + await self.expect_ll(ll.LeConnect, timeout=1.0) + self.assertTrue(False) + except asyncio.exceptions.TimeoutError: + pass + + # 7. The Lower Tester stops advertising. + + # 8. The Lower Tester begins advertising again using the correct + # resolvable address, which matches the one in the IUT resolving list. + # Lower Tester repeats until the time exceeds 4 * scanInterval + + # 3 * scanWindow, or step 9 occurs. + peer_resolvable_address = generate_rpa(peer_irk) + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=peer_resolvable_address, + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_IND, + advertising_data=[1, 2, 3]), + rssi=-16) + + # 9. The Lower Tester receives a CONNECT_IND packet T_IFS after any of the ADV_IND packets. + connect_ind = await self.expect_ll( + ll.LeConnect(source_address=self.Any, + destination_address=peer_resolvable_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + self.assertTrue(connect_ind.source_address.is_resolvable()) + self.assertTrue(connect_ind.source_address != controller.address) + + controller.send_ll( + ll.LeConnectComplete(source_address=peer_resolvable_address, + destination_address=connect_ind.source_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + # 10. Upper Tester receives an HCI_LE_Enhanced_Connection_Complete event from the IUT + # including the Lower Tester’s RPA and Identity address and connection interval selected. + connect_complete = await self.expect_evt( + hci.LeEnhancedConnectionComplete(status=ErrorCode.SUCCESS, + connection_handle=self.Any, + role=hci.Role.CENTRAL, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + peer_resolvable_private_address=peer_resolvable_address, + local_resolvable_private_address=connect_ind.source_address, + connection_interval=0x200, + peripheral_latency=0x6, + supervision_timeout=0xc80, + central_clock_accuracy=hci.ClockAccuracy.PPM_500)) + + # 11. After the CONNECT_IND has been received, the Lower Tester receives the first correctly + # formatted LL Data Channel PDU on the data channel. + + # 12. The Lower Tester sends a correctly formatted LL Data Channel PDU to the IUT on the same data + # channel using the acknowledgement scheme. + + # 13. The Lower Tester receives correctly formatted LL Data Channel PDUs on subsequent data + # channels at connection intervals, calculated for the connection interval used. + + # 14. Repeat a number of events (at least 100 events) to verify that the connection is maintained. + + # 15. The Upper Tester terminates the connection. + controller.send_ll( + ll.Disconnect(source_address=peer_resolvable_address, + destination_address=connect_ind.source_address, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) + + await self.expect_evt( + hci.DisconnectionComplete(status=hci.ErrorCode.SUCCESS, + connection_handle=connect_complete.connection_handle, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) diff --git a/tools/rootcanal/test/LL/CON_/INI/BV_10_C.py b/tools/rootcanal/test/LL/CON_/INI/BV_10_C.py new file mode 100644 index 0000000000000000000000000000000000000000..faa3d90b4b0a50d79006508dea31e3cbede6dcf2 --- /dev/null +++ b/tools/rootcanal/test/LL/CON_/INI/BV_10_C.py @@ -0,0 +1,178 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 +import hci_packets as hci +import link_layer_packets as ll +import unittest +from hci_packets import ErrorCode +from py.bluetooth import Address +from py.controller import ControllerTest, generate_rpa + + +class Test(ControllerTest): + + LL_initiator_scanInterval_MIN = 0x2000 + LL_initiator_scanInterval_MAX = 0x2000 + LL_initiator_scanWindow_MIN = 0x200 + LL_initiator_scanWindow_MAX = 0x200 + LL_initiator_Adv_Channel_Map = 0x7 + LL_initiator_Channel_Map = 0x7 + + # LL/CON/INI/BV-10-C [Network Privacy – Connection Establishment using + # directed advertising and resolving list, Initiator] + # + # Verify that the IUT when initiating connection establishment with the + # resolving list connects only to peer devices that are in the resolving + # list. The Lower Tester uses directed advertising. The IUT may use a public + # or static random device address + async def test(self): + # Test parameters. + controller = self.controller + peer_irk = bytes([2] * 16) + random_irk = bytes([3] * 16) + peer_address = Address('aa:bb:cc:dd:ee:ff') + + if not controller.le_features.ll_privacy: + self.skipTest("LL privacy not supported") + + # 1. Configure the Lower Tester to use the first supported advertising channel and a valid resolvable + # private address in the AdvA field, which is not known by the IUT (not in the resolving list). + + # 2. The Upper Tester adds the Lower Tester to the resolving list using a different IRK than in step 1. + controller.send_cmd( + hci.LeAddDeviceToResolvingList( + peer_irk=peer_irk, + local_irk=bytes([0] * 16), + peer_identity_address=peer_address, + peer_identity_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS)) + + await self.expect_evt( + hci.LeAddDeviceToResolvingListComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetResolvablePrivateAddressTimeout(rpa_timeout=0x10)) + + await self.expect_evt( + hci.LeSetResolvablePrivateAddressTimeoutComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.ENABLED)) + + await self.expect_evt( + hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 3. The Upper Tester enables the initiator state in the IUT. + controller.send_cmd( + hci.LeCreateConnection(le_scan_interval=Test.LL_initiator_scanInterval_MIN, + le_scan_window=Test.LL_initiator_scanWindow_MIN, + initiator_filter_policy=hci.InitiatorFilterPolicy.USE_PEER_ADDRESS, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + own_address_type=hci.OwnAddressType.PUBLIC_DEVICE_ADDRESS, + connection_interval_min=0x200, + connection_interval_max=0x200, + max_latency=0x6, + supervision_timeout=0xc80, + min_ce_length=0, + max_ce_length=0)) + + await self.expect_evt(hci.LeCreateConnectionStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 4. Lower Tester sends ADV_DIRECT_IND packets directed to the IUT, each advertising event on + # the selected advertising channel, using the selected advertising interval. + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=generate_rpa(random_irk), + destination_address=controller.address, + target_address_type=ll.AddressType.PUBLIC, + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND, + advertising_data=[1, 2, 3]), + rssi=-16) + + # 5. The IUT resolves and compares the address in the AdvA field by checking against its resolving + # list and does not find a match. + try: + await self.expect_ll(ll.LeConnect, timeout=1.0) + self.assertTrue(False) + except asyncio.exceptions.TimeoutError: + pass + + # 6. Repeat the advertising steps 4–5 for at least 20 advertising intervals. + + # 7. The Lower Tester stops advertising. + + # 8. The Lower Tester begins advertising again using the correct resolvable address, which matches + # the one stored in the IUT’s resolving list. + peer_resolvable_address = generate_rpa(peer_irk) + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=peer_resolvable_address, + destination_address=controller.address, + target_address_type=ll.AddressType.PUBLIC, + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND, + advertising_data=[1, 2, 3]), + rssi=-16) + + # 9. The Lower Tester receives a CONNECT_IND packet T_IFS after any of the ADV_DIRECT_IND + # packets. The AdvA field is the same as the one received in the ADV_DIRECT_IND. + await self.expect_ll( + ll.LeConnect(source_address=controller.address, + destination_address=peer_resolvable_address, + initiating_address_type=ll.AddressType.PUBLIC, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + controller.send_ll( + ll.LeConnectComplete(source_address=peer_resolvable_address, + destination_address=controller.address, + initiating_address_type=ll.AddressType.PUBLIC, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + # 10. Upper Tester receives an HCI_LE_Enhanced_Connection_Complete event from the IUT + # including the Lower Tester address and connection interval selected. + connect_complete = await self.expect_evt( + hci.LeEnhancedConnectionComplete(status=ErrorCode.SUCCESS, + connection_handle=self.Any, + role=hci.Role.CENTRAL, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + peer_resolvable_private_address=peer_resolvable_address, + connection_interval=0x200, + peripheral_latency=0x6, + supervision_timeout=0xc80, + central_clock_accuracy=hci.ClockAccuracy.PPM_500)) + + # 11. After the CONNECT_IND has been received, the Lower Tester receives the first correctly + # formatted LL Data Channel PDU on the data channel. + + # 12. The Lower Tester sends a correctly formatted LL Data Channel PDU to the IUT on the same data + # channel using the acknowledgement scheme. + + # 13. The Lower Tester receives correctly formatted LL Data Channel PDUs on subsequent data + # channels at connection intervals, calculated for the connection interval used. + + # 14. Repeat a number of events (at least 100 events) to verify that the connection is maintained. + + # 15. The Upper Tester terminates the connection. + controller.send_ll( + ll.Disconnect(source_address=peer_resolvable_address, + destination_address=controller.address, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) + + await self.expect_evt( + hci.DisconnectionComplete(status=hci.ErrorCode.SUCCESS, + connection_handle=connect_complete.connection_handle, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) diff --git a/tools/rootcanal/test/LL/CON_/INI/BV_11_C.py b/tools/rootcanal/test/LL/CON_/INI/BV_11_C.py new file mode 100644 index 0000000000000000000000000000000000000000..bb5341268ef26e5807ed6647454fd23a50e953af --- /dev/null +++ b/tools/rootcanal/test/LL/CON_/INI/BV_11_C.py @@ -0,0 +1,192 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 +import hci_packets as hci +import link_layer_packets as ll +import unittest +from hci_packets import ErrorCode +from py.bluetooth import Address +from py.controller import ControllerTest, generate_rpa + + +class Test(ControllerTest): + + LL_initiator_scanInterval_MIN = 0x2000 + LL_initiator_scanInterval_MAX = 0x2000 + LL_initiator_scanWindow_MIN = 0x200 + LL_initiator_scanWindow_MAX = 0x200 + LL_initiator_Adv_Channel_Map = 0x7 + LL_initiator_Channel_Map = 0x7 + + # LL/CON/INI/BV-11-C [Network Privacy – Connection Establishment using + # directed advertising with wrong address and resolving list, Initiator] + # + # Verify that the IUT when initiating connection establishment with the + # resolving list connects only to directed advertisements that are + # addressed to the IUT. + async def test(self): + # Test parameters. + controller = self.controller + local_irk = bytes([1] * 16) + peer_irk = bytes([2] * 16) + random_irk = bytes([3] * 16) + peer_address = Address('aa:bb:cc:dd:ee:ff') + + if not controller.le_features.ll_privacy: + self.skipTest("LL privacy not supported") + + # 1. Configure the Lower Tester to start directed advertising using a valid resolvable private address + # in the AdvA field. + + # 2. The Upper Tester adds the Lower Tester to the resolving list with both peer Identity (IRK and + # Identity Address) and local IRK. + controller.send_cmd( + hci.LeAddDeviceToResolvingList( + peer_irk=peer_irk, + local_irk=local_irk, + peer_identity_address=peer_address, + peer_identity_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS)) + + await self.expect_evt( + hci.LeAddDeviceToResolvingListComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetResolvablePrivateAddressTimeout(rpa_timeout=0x10)) + + await self.expect_evt( + hci.LeSetResolvablePrivateAddressTimeoutComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.ENABLED)) + + await self.expect_evt( + hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 3. The Upper Tester enables the initiator state in the IUT. + controller.send_cmd( + hci.LeCreateConnection(le_scan_interval=Test.LL_initiator_scanInterval_MIN, + le_scan_window=Test.LL_initiator_scanWindow_MIN, + initiator_filter_policy=hci.InitiatorFilterPolicy.USE_PEER_ADDRESS, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + own_address_type=hci.OwnAddressType.RESOLVABLE_OR_PUBLIC_ADDRESS, + connection_interval_min=0x200, + connection_interval_max=0x200, + max_latency=0x6, + supervision_timeout=0xc80, + min_ce_length=0, + max_ce_length=0)) + + await self.expect_evt(hci.LeCreateConnectionStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 4. Lower Tester sends ADV_DIRECT_IND packets, each advertising event, using the selected + # advertising interval and with a resolvable private address in the InitA field generated from a + # random IRK different from the one distributed to the IUT. + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=generate_rpa(peer_irk), + destination_address=generate_rpa(random_irk), + target_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND, + advertising_data=[1, 2, 3]), + rssi=-16) + + # 5. The IUT tries to resolve the address in the InitA field by checking against its resolving list and + # does not find a match. + try: + await self.expect_ll(ll.LeConnect, timeout=1.0) + self.assertTrue(False) + except asyncio.exceptions.TimeoutError: + pass + + # 6. Repeat the advertising steps 4–5 for at least 20 advertising intervals. + + # 7. The Lower Tester stops advertising. + + # 8. The Lower Tester begins advertising again using the correct resolvable address, which resolves + # with the IUT’s local IRK. + peer_resolvable_address = generate_rpa(peer_irk) + local_resolvable_address = generate_rpa(local_irk) + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=peer_resolvable_address, + destination_address=local_resolvable_address, + target_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND, + advertising_data=[1, 2, 3]), + rssi=-16) + + # 9. The Lower Tester receives a CONNECT_IND packet T_IFS after any of the ADV_DIRECT_IND + # packets. The InitA field contains a resolvable private address generated by the IUT. The address + # should be different from the address received in the ADV_DIRECT_IND packet. + connect_ind = await self.expect_ll( + ll.LeConnect(source_address=self.Any, + destination_address=peer_resolvable_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + self.assertTrue(connect_ind.source_address.is_resolvable()) + self.assertTrue(connect_ind.source_address != controller.address) + self.assertTrue(connect_ind.source_address != local_resolvable_address) + + controller.send_ll( + ll.LeConnectComplete(source_address=peer_resolvable_address, + destination_address=connect_ind.source_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + # 10. Upper Tester receives an HCI_LE_Enhanced_Connection_Complete event from the IUT + # including the Lower Tester address and connection interval selected. + connect_complete = await self.expect_evt( + hci.LeEnhancedConnectionComplete(status=ErrorCode.SUCCESS, + connection_handle=self.Any, + role=hci.Role.CENTRAL, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + peer_resolvable_private_address=peer_resolvable_address, + local_resolvable_private_address=connect_ind.source_address, + connection_interval=0x200, + peripheral_latency=0x6, + supervision_timeout=0xc80, + central_clock_accuracy=hci.ClockAccuracy.PPM_500)) + + # 11. After the CONNECT_IND has been received, the Lower Tester receives the first correctly + # formatted LL Data Channel PDU on the data channel. + + # 12. The Lower Tester sends a correctly formatted LL Data Channel PDU to the IUT on the same data + # channel using the acknowledgement scheme. + + # 13. The Lower Tester receives correctly formatted LL Data Channel PDUs on subsequent data + # channels at connection intervals, calculated for the connection interval used. + + # 14. Repeat a number of events (at least 100 events) to verify that the connection is maintained. + + # 15. The IUT (Central) maintains the link for the address refresh timeout before terminating the + # connection. + + # 16. Repeat steps 3–10 to see that the InitA field of the CONNECT_IND have been refreshed. + + # 17. The Upper Tester terminates the connection + controller.send_ll( + ll.Disconnect(source_address=peer_resolvable_address, + destination_address=connect_ind.source_address, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) + + await self.expect_evt( + hci.DisconnectionComplete(status=hci.ErrorCode.SUCCESS, + connection_handle=connect_complete.connection_handle, + reason=hci.ErrorCode.REMOTE_USER_TERMINATED_CONNECTION)) diff --git a/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py b/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py index 014417f9becdafe783c74f19de455efc4538aefe..51c24bdcc980feed0fe3c59a080ee370b0f31054 100644 --- a/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py +++ b/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py @@ -115,10 +115,6 @@ class Test(ControllerTest): conn_supervision_timeout=self.LL_initiator_connSupervisionTimeout), rssi=-16) - # Note: another advertising pdu is received waiting from the connect - # complete. - await self.expect_ll(ll.LeLegacyAdvertisingPdu) - # Note: Link layer sends LeConnectComplete here. await self.expect_ll( ll.LeConnectComplete(source_address=controller.address, diff --git a/tools/rootcanal/test/LL/DDI/SCN/BV_13_C.py b/tools/rootcanal/test/LL/DDI/SCN/BV_13_C.py index e25f2dbbbdea673eba5b2e343d73b9f344ee8d98..fb14450336bd9305da54ab2a66f40f2fb6685178 100644 --- a/tools/rootcanal/test/LL/DDI/SCN/BV_13_C.py +++ b/tools/rootcanal/test/LL/DDI/SCN/BV_13_C.py @@ -93,7 +93,7 @@ class Test(ControllerTest): await self.expect_evt( hci.LeAdvertisingReport(responses=[ hci.LeAdvertisingResponse(event_type=hci.AdvertisingEventType.ADV_NONCONN_IND, - address_type=hci.AddressType.PUBLIC_IDENTITY_ADDRESS, + address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, address=peer_identity_address, advertising_data=[1, 2, 3], rssi=0xf0) diff --git a/tools/rootcanal/test/LL/DDI/SCN/BV_18_C.py b/tools/rootcanal/test/LL/DDI/SCN/BV_18_C.py index 55369396e4ccef04dfe629419f5925b6ed7b250a..7484377da2199872facbcefe92adaff0e6a1c582 100644 --- a/tools/rootcanal/test/LL/DDI/SCN/BV_18_C.py +++ b/tools/rootcanal/test/LL/DDI/SCN/BV_18_C.py @@ -116,7 +116,7 @@ class Test(ControllerTest): await self.expect_evt( hci.LeAdvertisingReport(responses=[ hci.LeAdvertisingResponse(event_type=hci.AdvertisingEventType.ADV_SCAN_IND, - address_type=hci.AddressType.PUBLIC_IDENTITY_ADDRESS, + address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, address=peer_identity_address, advertising_data=[1, 2, 3], rssi=0xf0) @@ -135,7 +135,7 @@ class Test(ControllerTest): # information. await self.expect_evt(hci.LeAdvertisingReport(responses=[ hci.LeAdvertisingResponse(event_type=hci.AdvertisingEventType.SCAN_RESPONSE, - address_type=hci.AddressType.PUBLIC_IDENTITY_ADDRESS, + address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, address=peer_identity_address, advertising_data=[4, 5, 6], rssi=0xf0) diff --git a/tools/rootcanal/test/LL/DDI/SCN/BV_20_C.py b/tools/rootcanal/test/LL/DDI/SCN/BV_20_C.py new file mode 100644 index 0000000000000000000000000000000000000000..726e35afcfc16b1d9611f9a632f8a0d60fe53806 --- /dev/null +++ b/tools/rootcanal/test/LL/DDI/SCN/BV_20_C.py @@ -0,0 +1,264 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 hci_packets as hci +import link_layer_packets as ll +import math +import random +from dataclasses import dataclass +from hci_packets import ErrorCode +from py.bluetooth import Address +from py.controller import ControllerTest +from typing import Optional + +ADV_IND = 0x13 +ADV_DIRECT_IND = 0x15 +ADV_SCAN_IND = 0x12 +ADV_EXT_IND = 0x02 + + +@dataclass +class TestRound: + advertising_event_properties: int + target_address: Optional[Address] + scan_data_length: int + + +class Test(ControllerTest): + + # LL/DDI/SCN/BV-20-C [Extended Scanning, Active – LE 1M PHY, Core 5.0] + # + # Verify that a scanner IUT detects and requests additional information from + # advertisements received and reports the results from the Controller. The + # Lower Tester advertises using scannable extended advertising events on one + # channel at a time and expects the IUT to report the advertising to the + # Upper Tester. Both directed and undirected advertising events are tested. + async def test(self): + # Test rounds. + # Note: some tests are skipped as no distinction is made between + # ADV_EXT_IND, AUX_ADV_IND, AUX_CHAIN_IND. + controller = self.controller + invalid_address = Address("11:22:33:44:55:66") + test_rounds = [ + TestRound(ADV_IND, None, 0), + TestRound(ADV_IND, None, 31), + TestRound(ADV_SCAN_IND, None, 0), + TestRound(ADV_SCAN_IND, None, 31), + TestRound(ADV_EXT_IND, None, 1), + TestRound(ADV_EXT_IND, controller.address, 1), + TestRound(ADV_EXT_IND, invalid_address, 1), + TestRound(ADV_EXT_IND, None, 191), + TestRound(ADV_EXT_IND, None, 382), + TestRound(ADV_EXT_IND, None, 1647), + ] + + # 1. For each round as specified in Table 4.2-35 based on Table 4.2-36, if ScanData Length is less + # than or equal to the “Scan Max Data” then perform steps 2–8 and otherwise omit this round. + for test_round in test_rounds: + await self.steps_2_8(**vars(test_round)) + + async def steps_2_8(self, advertising_event_properties: int, target_address: Optional[Address], + scan_data_length: int): + + controller = self.controller + lower_tester_address = Address("ca:fe:ca:fe:00:01") + + # 2. The Upper Tester sends an HCI_LE_Set_Extended_Scan_Parameters command to the IUT. The + # Scanning_PHYs parameter is set as specified in Table 4.2-35, Scan_Type[0] set to 0x01 (Active + # Scanning), Scan_Interval[0] set to 0x0010, and Scan_Window[0] set to 0x0010. + # Own_Address_Type is set to 0x00 (Public Device Address), and Scanning_Filter_Policy is set to + # 0x00 (Accept All) and receives a successful HCI_Command_Complete. + controller.send_cmd( + hci.LeSetExtendedScanParameters(own_address_type=hci.OwnAddressType.PUBLIC_DEVICE_ADDRESS, + scanning_filter_policy=hci.LeScanningFilterPolicy.ACCEPT_ALL, + scanning_phys=0x1, + scanning_phy_parameters=[ + hci.ScanningPhyParameters(le_scan_type=hci.LeScanType.ACTIVE, + le_scan_interval=0x0010, + le_scan_window=0x0010) + ])) + + await self.expect_evt( + hci.LeSetExtendedScanParametersComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 3. The Upper Tester sends an HCI_LE_Set_Extended_Scan_Enable command to the IUT to enable + # scanning. Filter_Duplicates, Duration, and Period are all set to zero and receive a successful + # HCI_Command_Complete. + controller.send_cmd( + hci.LeSetExtendedScanEnable(enable=hci.Enable.ENABLED, + filter_duplicates=hci.Enable.DISABLED, + duration=0, + period=0)) + + await self.expect_evt(hci.LeSetExtendedScanEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 4. The Lower Tester begins advertising on the channel as specified in Table 4.2-35 using the PDU + # Type specified in Table 4.2-36 for this round. If AUX_ADV_IND is included in the round, the + # ADV_EXT_IND includes an AuxPtr that refers to the AUX_ADV_IND on the PHY as specified in + # Table 4.2-35, and all fields specified should be included with the AUX_ADV_IND only. If AdvA is + # specified, the appropriate PDU includes the field, where “LT” equals the Lower Tester address. If + # TargetA is specified, the appropriate PDU includes the field, where “IUT” equals the IUT address + # and “Not IUT” equals a random address other than the IUT address. Repeat for at least 20 + # advertising intervals or until step 5 occurs. + connectable = (advertising_event_properties & 0x1) != 0 + scannable = (advertising_event_properties & 0x2) != 0 + directed = (advertising_event_properties & 0x4) != 0 + high_duty_cycle = (advertising_event_properties & 0x8) != 0 + legacy = (advertising_event_properties & 0x10) != 0 + + if legacy: + if advertising_event_properties == ADV_IND: + advertising_type = ll.LegacyAdvertisingType.ADV_IND + elif advertising_event_properties == ADV_DIRECT_IND: + advertising_type = ll.LegacyAdvertisingType.ADV_DIRECT_IND + elif advertising_event_properties == ADV_SCAN_IND: + advertising_type = ll.LegacyAdvertisingType.ADV_SCAN_IND + elif advertising_event_properties == ADV_NONCONN_IND: + advertising_type = ll.LegacyAdvertisingType.ADV_NONCONN_IND + pdu = ll.LeLegacyAdvertisingPdu(source_address=lower_tester_address, + destination_address=target_address or Address(), + advertising_address_type=ll.AddressType.PUBLIC, + target_address_type=ll.AddressType.PUBLIC, + advertising_type=advertising_type, + advertising_data=[]) + else: + pdu = ll.LeExtendedAdvertisingPdu(source_address=lower_tester_address, + destination_address=target_address or Address(), + advertising_address_type=ll.AddressType.PUBLIC, + target_address_type=ll.AddressType.PUBLIC, + connectable=connectable, + scannable=scannable, + directed=not target_address is None, + sid=0, + tx_power=0x7f, + primary_phy=ll.PrimaryPhyType.LE_1M, + secondary_phy=ll.SecondaryPhyType.NO_PACKETS, + advertising_data=[]) + + # 5. For undirected advertisements or advertisements directed at the IUT, the Lower Tester receives + # either a SCAN_REQ (if advertising with legacy PDUs) or an AUX_SCAN_REQ (if advertising with + # extended PDUs) on the appropriate advertising channel. The ScanA field is set to the IUT’s + # address, and the AdvA address is set to the Lower Tester’s address. The Upper Tester receives + # an HCI_LE_Extended_Advertising_Report event from the IUT with an Event_Type where bit 3 + # (Scan response) is not set, the Data Status in the Event_Type field is set to Complete (0b00), + # Periodic_Advertising_Interval is set to 0, and no advertising data. If the advertisements were + # directed but TargetA is not the IUT, skip to step 8. + for n in range(3): + if not legacy: + sid = random.randint(0, 15) + pdu.sid = sid + else: + sid = 0xff + + controller.send_ll(pdu, rssi=0) + + if target_address and target_address != controller.address: + # If the controller still emits an event, the error + # will appear in the subsequent rounds. + continue + + await self.expect_evt( + hci.LeExtendedAdvertisingReport(responses=[ + hci.LeExtendedAdvertisingResponse( + connectable=connectable, + scannable=scannable, + directed=not target_address is None, + scan_response=False, + legacy=legacy, + data_status=hci.DataStatus.COMPLETE, + address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + address=lower_tester_address, + primary_phy=hci.PrimaryPhyType.LE_1M, + secondary_phy=hci.SecondaryPhyType.NO_PACKETS, + advertising_sid=sid, + tx_power=0x7f, + rssi=0, + periodic_advertising_interval=0, + direct_address_type=hci.DirectAdvertisingAddressType.NO_ADDRESS_PROVIDED + if not target_address else hci.DirectAdvertisingAddressType.PUBLIC_DEVICE_ADDRESS, + direct_address=target_address or Address(), + advertising_data=[]) + ])) + + await self.expect_ll( + ll.LeScan(source_address=controller.address, + destination_address=lower_tester_address, + scanning_address_type=ll.AddressType.PUBLIC, + advertising_address_type=ll.AddressType.PUBLIC)) + + advertising_data = [random.randint(1, 254) for n in range(scan_data_length)] + + # 6. Perform step 6A or 6B depending on the PDU sent by the IUT in step 5. + # Alternative 6A (The IUT sent a SCAN_REQ in step 5): + # 6A.1 The Lower Tester responds with a SCAN_RSP packet to the IUT T_IFS after the end + # of the SCAN_REQ PDU. If ScanData is specified, the SCAN_RSP PDU includes the + # field populated with random octets from 1 to 254 of the specified count. + # Alternative 6B (The IUT sent an AUX_SCAN_REQ in step 5): + # 6B.1 The Lower Tester responds with an AUX_SCAN_RSP packet to the IUT T_IFS after + # the end of the AUX_SCAN_REQ PDU with an AdvMode of 0b00. If ScanData is + # specified, the AUX_SCAN_RSP PDU includes the AdvData field populated with + # random octets from 1 to 254 of the specified count. If the ScanData is greater in + # length than will fit in one PDU, the Lower Tester includes an AuxPtr field and sends + # one or more AUX_CHAIN_IND PDUs containing the remaining data. Each PDU + # except the last contains as much AdvData as can fit. + controller.send_ll(ll.LeScanResponse(source_address=lower_tester_address, + destination_address=controller.address, + advertising_address_type=ll.AddressType.PUBLIC, + scan_response_data=advertising_data), + rssi=0) + + # 7. If the Lower Tester sent a scan response in step 6, the Upper Tester receives one or more + # HCI_LE_Extended_Advertising_Report events from the IUT with an Event_Type where bit 3 + # (Scan response) is set, and Periodic_Advertising_Interval is set to 0. If ScanData was included in + # the response, the Upper Tester receives the data included in one of the advertising packets. If + # ScanData is sent to the Upper Tester in multiple reports, the Data Status in the Event_Type field + # for each report except the last is set to “Incomplete, more data to come”, 0b01. The Event_Type + # field for the last report sent with advertisement data is set to “Complete”, 0b00. + offset = 0 + max_fragment_length = 229 + num_fragments = math.ceil(scan_data_length / max_fragment_length) or 1 + + for n in range(num_fragments): + remaining_length = scan_data_length - offset + fragment_length = min(max_fragment_length, remaining_length) + data_status = hci.DataStatus.CONTINUING if remaining_length > max_fragment_length else hci.DataStatus.COMPLETE + await self.expect_evt( + hci.LeExtendedAdvertisingReport(responses=[ + hci.LeExtendedAdvertisingResponse( + connectable=connectable, + scannable=scannable, + directed=False, + scan_response=True, + legacy=legacy, + data_status=data_status, + address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + address=lower_tester_address, + primary_phy=hci.PrimaryPhyType.LE_1M, + secondary_phy=hci.SecondaryPhyType.NO_PACKETS, + # TODO SID should be set in scan response PDU + advertising_sid=0xff, + tx_power=0x7f, + rssi=0, + periodic_advertising_interval=0, + direct_address_type=hci.DirectAdvertisingAddressType.NO_ADDRESS_PROVIDED, + direct_address=Address(), + advertising_data=advertising_data[offset:offset + fragment_length]) + ])) + offset += fragment_length + + # 8. The Upper Tester sends an HCI_LE_Set_Scan_Enable to the IUT to disable scanning and + # receives an HCI_Command_Complete event in response. + controller.send_cmd(hci.LeSetExtendedScanEnable(enable=hci.Enable.DISABLED)) + + await self.expect_evt(hci.LeSetExtendedScanEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) diff --git a/tools/rootcanal/test/LL/SEC/ADV/BV_11_C.py b/tools/rootcanal/test/LL/SEC/ADV/BV_11_C.py new file mode 100644 index 0000000000000000000000000000000000000000..ff100c5234d88a0a497a36bdb762257a56204150 --- /dev/null +++ b/tools/rootcanal/test/LL/SEC/ADV/BV_11_C.py @@ -0,0 +1,224 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 +import hci_packets as hci +import link_layer_packets as ll +import math +import random +import unittest +from dataclasses import dataclass +from hci_packets import ErrorCode, FragmentPreference +from py.bluetooth import Address +from py.controller import ControllerTest, generate_rpa +from typing import List + + +@dataclass +class TestRound: + data_length: int + + +class Test(ControllerTest): + # Test parameters. + LL_advertiser_advInterval_MIN = 0x800 + LL_advertiser_advInterval_MAX = 0x800 + LL_advertiser_Adv_Channel_Map = 0x7 + LL_initiator_connInterval = 0x200 + LL_initiator_connPeripheralLatency = 0x200 + LL_initiator_connSupervisionTimeout = 0x200 + + # LL/SEC/ADV/BV-11-C [Network Privacy - Directed Connectable Advertising + # using local and remote IRK] + # + # Verify that the IUT, when transmitting directed connectable advertising + # events, is using resolvable private addresses for AdvA and InitA fields + # when the Lower Tester has distributed its own IRK. + # + # Verify that when address resolution is disabled on the IUT, the Lower + # Tester resolvable private address is not resolved, and therefore a + # connection is not established. + async def test(self): + controller = self.controller + local_irk = bytes([1] * 16) + peer_irk = bytes([2] * 16) + random_irk = bytes([3] * 16) + peer_address = Address('aa:bb:cc:dd:ee:ff') + + # 1. The Lower Tester adds the Device Identity of the IUT to its resolving list. + # 2. Configure the Lower Tester to initiate a connection while using a resolvable private address. + + # 3. The Upper Tester populates the resolving list with the device identity of the Lower Tester + # connected with the local device identity. The IUT use these when generating resolvable private + # addresses for use in the advertising packet’s AdvA and InitA fields. + controller.send_cmd( + hci.LeAddDeviceToResolvingList( + peer_irk=peer_irk, + local_irk=local_irk, + peer_identity_address=peer_address, + peer_identity_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS)) + + await self.expect_evt( + hci.LeAddDeviceToResolvingListComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetResolvablePrivateAddressTimeout(rpa_timeout=0x10)) + + await self.expect_evt( + hci.LeSetResolvablePrivateAddressTimeoutComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 4. The Upper Tester enables resolving list and directed connectable advertising in the IUT. + controller.send_cmd( + hci.LeSetAdvertisingParameters(advertising_interval_min=Test.LL_advertiser_advInterval_MIN, + advertising_interval_max=Test.LL_advertiser_advInterval_MAX, + advertising_type=hci.AdvertisingType.ADV_DIRECT_IND_HIGH, + own_address_type=hci.OwnAddressType.RESOLVABLE_OR_PUBLIC_ADDRESS, + peer_address=peer_address, + peer_address_type=hci.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, + advertising_channel_map=0x7, + advertising_filter_policy=hci.AdvertisingFilterPolicy.ALL_DEVICES)) + + await self.expect_evt( + hci.LeSetAdvertisingParametersComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetAdvertisingData()) + + await self.expect_evt(hci.LeSetAdvertisingDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.ENABLED)) + + await self.expect_evt( + hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True)) + + await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 5. The Lower Tester expects the IUT to send ADV_DIRECT_IND packets on an applicable + # advertising channel. + direct_ind = await self.expect_ll(ll.LeLegacyAdvertisingPdu( + source_address=self.Any, + destination_address=self.Any, + advertising_address_type=ll.AddressType.RANDOM, + target_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND, + advertising_data=[]), + timeout=5) + + self.assertTrue(direct_ind.source_address.is_resolvable()) + self.assertTrue(direct_ind.destination_address.is_resolvable()) + + # 6. The Lower Tester identifies the IUT. The Lower Tester sends a CONNECT_IND with the AdvA + # address of the ADV_DIRECT_IND and the InitA generated based on its Device Identity. The IUT + # verifies AdvA and resolves the InitA Address and identifies the Lower Tester. + # 7. The Lower Tester connects to the IUT. The Lower Tester sends empty LL DATA packets starting + # with the first event one connection interval after the connection request using the common data + # channel selection parameters. + init_a = generate_rpa(peer_irk) + controller.send_ll( + ll.LeConnect(source_address=init_a, + destination_address=direct_ind.source_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=Test.LL_initiator_connInterval, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + await self.expect_ll( + ll.LeConnectComplete(source_address=direct_ind.source_address, + destination_address=init_a, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=Test.LL_initiator_connInterval, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + connection_complete_evt = await self.expect_evt( + hci.LeEnhancedConnectionComplete( + status=hci.ErrorCode.SUCCESS, + connection_handle=self.Any, + role=hci.Role.PERIPHERAL, + peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS, + peer_address=peer_address, + local_resolvable_private_address=direct_ind.source_address, + peer_resolvable_private_address=init_a, + connection_interval=0x200, + peripheral_latency=0x6, + supervision_timeout=0xc80, + central_clock_accuracy=hci.ClockAccuracy.PPM_500, + )) + + # 8. The Upper Tester terminates the connection. + controller.send_cmd( + hci.Disconnect(connection_handle=connection_complete_evt.connection_handle, + reason=hci.DisconnectReason.REMOTE_USER_TERMINATED_CONNECTION)) + + await self.expect_evt(hci.DisconnectStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + await self.expect_ll( + ll.Disconnect(source_address=direct_ind.source_address, + destination_address=init_a, + reason=hci.DisconnectReason.REMOTE_USER_TERMINATED_CONNECTION)) + + await self.expect_evt( + hci.DisconnectionComplete(status=ErrorCode.SUCCESS, + connection_handle=connection_complete_evt.connection_handle, + reason=ErrorCode.CONNECTION_TERMINATED_BY_LOCAL_HOST)) + + # 9. The Upper Tester disables address resolution in the IUT. + controller.send_cmd(hci.LeSetAddressResolutionEnable(address_resolution_enable=hci.Enable.DISABLED)) + + await self.expect_evt( + hci.LeSetAddressResolutionEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 10. Repeat steps 11–14 at least 20 times. + + # 11. The Upper Tester enables directed connectable advertising in the IUT. + controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True)) + + await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + # 12. The Lower Tester expects the IUT to send ADV_DIRECT_IND packets on an applicable + # advertising channel. The Lower Tester resolves the AdvA address and identifies the IUT. + direct_ind = await self.expect_ll(ll.LeLegacyAdvertisingPdu( + source_address=self.Any, + destination_address=self.Any, + advertising_address_type=ll.AddressType.RANDOM, + target_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_DIRECT_IND, + advertising_data=[]), + timeout=5) + + self.assertTrue(direct_ind.source_address.is_resolvable()) + self.assertTrue(direct_ind.destination_address.is_resolvable()) + + # 13. The Lower Tester sends a CONNECT_IND with the AdvA address of the ADV_IND and the InitA + # set to a different address than the last CONNECT_IND. The IUT does not resolve the address in + # the InitA field. No connection event is sent to the Upper Tester. + init_a = generate_rpa(local_irk) + controller.send_ll( + ll.LeConnect(source_address=init_a, + destination_address=direct_ind.source_address, + initiating_address_type=ll.AddressType.RANDOM, + advertising_address_type=ll.AddressType.RANDOM, + conn_interval=0x200, + conn_peripheral_latency=0x6, + conn_supervision_timeout=0xc80)) + + # 14. The Upper Tester receives an HCI_LE_Connection_Complete event or an + # HCI_LE_Enhanced_Connection_Complete event with the Status code set to Advertising Timeout + # (0x3C). + await self.expect_evt(hci.LeConnectionComplete(status=hci.ErrorCode.ADVERTISING_TIMEOUT,)) + + # Empty the LL queue. + controller.ll_queue.clear() diff --git a/tools/rootcanal/test/LL/scan_timeout.py b/tools/rootcanal/test/LL/scan_timeout.py new file mode 100644 index 0000000000000000000000000000000000000000..8a6dd066cc1ff16d8248cd3455993e355797ac2b --- /dev/null +++ b/tools/rootcanal/test/LL/scan_timeout.py @@ -0,0 +1,111 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 +import hci_packets as hci +import link_layer_packets as ll +import unittest +from hci_packets import ErrorCode +from py.bluetooth import Address +from py.controller import ControllerTest, generate_rpa + + +class Test(ControllerTest): + + # Verify that the scanner gracefully handles missing scan responses + # after a timeout. + async def test(self): + # Test parameters. + LL_scanner_scanInterval_MIN = 0x2000 + LL_scanner_scanInterval_MAX = 0x2000 + LL_scanner_scanWindow_MIN = 0x200 + LL_scanner_scanWindow_MAX = 0x200 + LL_scanner_Adv_Channel_Map = 0x7 + + controller = self.controller + peer_address = Address('aa:bb:cc:dd:ee:ff') + + controller.send_cmd( + hci.LeSetScanParameters(le_scan_type=hci.LeScanType.ACTIVE, + le_scan_interval=LL_scanner_scanInterval_MAX, + le_scan_window=LL_scanner_scanWindow_MAX, + own_address_type=hci.OwnAddressType.RESOLVABLE_OR_PUBLIC_ADDRESS, + scanning_filter_policy=hci.LeScanningFilterPolicy.ACCEPT_ALL)) + + await self.expect_evt(hci.LeSetScanParametersComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_cmd( + hci.LeSetScanEnable(le_scan_enable=hci.Enable.ENABLED, filter_duplicates=hci.Enable.DISABLED)) + + await self.expect_evt(hci.LeSetScanEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1)) + + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=peer_address, + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_SCAN_IND, + advertising_data=[]), + rssi=-16) + + await self.expect_evt( + hci.LeAdvertisingReport(responses=[ + hci.LeAdvertisingResponse(event_type=hci.AdvertisingEventType.ADV_SCAN_IND, + address_type=hci.AddressType.RANDOM_DEVICE_ADDRESS, + address=peer_address, + advertising_data=[], + rssi=0xf0) + ])) + + await self.expect_ll( + ll.LeScan(source_address=controller.address, + destination_address=peer_address, + advertising_address_type=ll.AddressType.RANDOM, + scanning_address_type=ll.AddressType.PUBLIC)) + + # No response is sent for the duration of the scan request timeout. + # The next scan request must be correctly handled. + await asyncio.sleep(1.0) + + controller.send_ll(ll.LeLegacyAdvertisingPdu(source_address=peer_address, + advertising_address_type=ll.AddressType.RANDOM, + advertising_type=ll.LegacyAdvertisingType.ADV_SCAN_IND, + advertising_data=[]), + rssi=-16) + + await self.expect_evt( + hci.LeAdvertisingReport(responses=[ + hci.LeAdvertisingResponse(event_type=hci.AdvertisingEventType.ADV_SCAN_IND, + address_type=hci.AddressType.RANDOM_DEVICE_ADDRESS, + address=peer_address, + advertising_data=[], + rssi=0xf0) + ])) + + await self.expect_ll( + ll.LeScan(source_address=controller.address, + destination_address=peer_address, + advertising_address_type=ll.AddressType.RANDOM, + scanning_address_type=ll.AddressType.PUBLIC)) + + controller.send_ll(ll.LeScanResponse(source_address=peer_address, + advertising_address_type=ll.AddressType.RANDOM, + scan_response_data=[]), + rssi=-16) + + await self.expect_evt( + hci.LeAdvertisingReport(responses=[ + hci.LeAdvertisingResponse(event_type=hci.AdvertisingEventType.SCAN_RESPONSE, + address_type=hci.AddressType.RANDOM_DEVICE_ADDRESS, + address=peer_address, + advertising_data=[], + rssi=0xf0) + ])) diff --git a/tools/rootcanal/test/invalid_packet_handler_unittest.cc b/tools/rootcanal/test/invalid_packet_handler_unittest.cc new file mode 100644 index 0000000000000000000000000000000000000000..803124bdcd46f544a292ad4aa1ecd81a98a152eb --- /dev/null +++ b/tools/rootcanal/test/invalid_packet_handler_unittest.cc @@ -0,0 +1,82 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "log.h" +#include "model/controller/dual_mode_controller.h" + +namespace rootcanal { + +using namespace bluetooth::hci; + +class InvalidPacketHandlerTest : public ::testing::Test { + public: + InvalidPacketHandlerTest() = default; + ~InvalidPacketHandlerTest() override = default; + + protected: + DualModeController controller_; +}; + +// Set Event Mask command with missing parameters. +const std::vector kInvalidCommandPacket = {0x01, 0x0C, 0x03, + 0xff, 0xff, 0xff}; + +// Hardware Error event with code 0x43. +const std::vector kHardwareErrorEvent = {0x10, 0x01, 0x43}; + +TEST_F(InvalidPacketHandlerTest, DefaultHandler) { + // Validate that the default invalid packet handler causes + // an abort when an invalid packet is received. + ASSERT_DEATH(controller_.HandleCommand(std::make_shared>( + kInvalidCommandPacket)), + ""); +} + +TEST_F(InvalidPacketHandlerTest, RegisteredHandler) { + static struct { + uint32_t id; + InvalidPacketReason reason; + std::vector bytes; + } invalid_packet; + + static std::vector hci_event; + + // Validate that the registered invalid packet handler is correctly + // invoked when an invalid packet is received. + controller_.RegisterInvalidPacketHandler( + [&](uint32_t id, InvalidPacketReason reason, std::string, + std::vector const& bytes) { + invalid_packet.id = id; + invalid_packet.reason = reason; + invalid_packet.bytes = bytes; + }); + + controller_.RegisterEventChannel( + [&](std::shared_ptr> packet) { + hci_event = std::vector(*packet); + }); + + controller_.HandleCommand( + std::make_shared>(kInvalidCommandPacket)); + ASSERT_EQ(invalid_packet.id, controller_.id_); + ASSERT_EQ(invalid_packet.reason, InvalidPacketReason::kParseError); + ASSERT_EQ(invalid_packet.bytes, kInvalidCommandPacket); + ASSERT_EQ(hci_event, kHardwareErrorEvent); +} + +} // namespace rootcanal diff --git a/tools/rootcanal/test/main.py b/tools/rootcanal/test/main.py index 63e223a1f078c9b1f30174dbaa5fd19458d7dedc..b61a5b87a7813e333f9185e7c72b1ec4a66d1c99 100644 --- a/tools/rootcanal/test/main.py +++ b/tools/rootcanal/test/main.py @@ -28,6 +28,10 @@ tests = [ 'LL.CIS.PER.BV_02_C', 'LL.CON_.CEN.BV_41_C', 'LL.CON_.CEN.BV_43_C', + 'LL.CON_.INI.BV_08_C', + 'LL.CON_.INI.BV_09_C', + 'LL.CON_.INI.BV_10_C', + 'LL.CON_.INI.BV_11_C', 'LL.CON_.PER.BV_40_C', 'LL.CON_.PER.BV_42_C', 'LL.DDI.ADV.BV_01_C', @@ -54,7 +58,9 @@ tests = [ 'LL.DDI.SCN.BV_14_C', 'LL.DDI.SCN.BV_18_C', 'LL.DDI.SCN.BV_19_C', + 'LL.DDI.SCN.BV_20_C', 'LL.DDI.SCN.BV_79_C', + 'LL.SEC.ADV.BV_11_C', 'LMP.LIH.BV_01_C', 'LMP.LIH.BV_02_C', 'LMP.LIH.BV_78_C', @@ -64,6 +70,7 @@ tests = [ 'LMP.LIH.BV_144_C', 'LMP.LIH.BV_149_C', 'LL.scan_collision', + 'LL.scan_timeout', 'LMP.page_collision', ]