Merge branch 'dev/11/fp3/security-aosp-rvc-release' into int/11/fp3
* dev/11/fp3/security-aosp-rvc-release:
Fix integer overflow when parsing avrc response
Add length check when copy AVDT and AVCT packet
Add missing increment in bnep_api.cc
RESTRICT AUTOMERGE Added max buffer length check
Add length check when copy AVDTP packet
Change-Id: Ied3618797353514a8d4d5bcf60ebfae9195a1d3d
diff --git a/apex/Android.bp b/apex/Android.bp
index fc143ba..82f8713 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -4,10 +4,10 @@
manifest: "apex_manifest.json",
native_shared_libs: [
- "libbluetooth_jni",
+ "//packages/apps/Bluetooth:libbluetooth_jni",
"libbluetooth"
],
- apps: ["Bluetooth"],
+ apps: ["//packages/apps/Bluetooth:Bluetooth"],
compile_multilib: "both",
diff --git a/audio_a2dp_hw/include/audio_a2dp_hw.h b/audio_a2dp_hw/include/audio_a2dp_hw.h
index 4d32432..3bdefeb 100644
--- a/audio_a2dp_hw/include/audio_a2dp_hw.h
+++ b/audio_a2dp_hw/include/audio_a2dp_hw.h
@@ -52,7 +52,7 @@
// 20 * 512 is not sufficient to smooth the variability for some BT devices,
// resulting in mixer sleep and throttling. We increase this to 28 * 512 to help
// reduce the effect of variable data consumption.
-#define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 512)
+#define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 1024)
#define AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ 256
// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided
@@ -78,6 +78,7 @@
typedef enum {
A2DP_CTRL_CMD_NONE,
A2DP_CTRL_CMD_CHECK_READY,
+ A2DP_CTRL_CMD_CHECK_STREAM_STARTED,
A2DP_CTRL_CMD_START,
A2DP_CTRL_CMD_STOP,
A2DP_CTRL_CMD_SUSPEND,
@@ -86,15 +87,17 @@
A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG,
A2DP_CTRL_CMD_OFFLOAD_START,
A2DP_CTRL_GET_PRESENTATION_POSITION,
+ A2DP_CTRL_CMD_STREAM_OPEN,
} tA2DP_CTRL_CMD;
typedef enum {
A2DP_CTRL_ACK_SUCCESS,
A2DP_CTRL_ACK_FAILURE,
A2DP_CTRL_ACK_INCALL_FAILURE, /* Failure when in Call*/
+ A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS,
+ A2DP_CTRL_ACK_PREVIOUS_COMMAND_PENDING,
A2DP_CTRL_ACK_UNSUPPORTED,
A2DP_CTRL_ACK_PENDING,
- A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS,
} tA2DP_CTRL_ACK;
typedef uint32_t tA2DP_SAMPLE_RATE;
diff --git a/audio_a2dp_hw/src/audio_a2dp_hw.cc b/audio_a2dp_hw/src/audio_a2dp_hw.cc
index 2fb139f..204b4d4 100644
--- a/audio_a2dp_hw/src/audio_a2dp_hw.cc
+++ b/audio_a2dp_hw/src/audio_a2dp_hw.cc
@@ -46,10 +46,13 @@
#include "osi/include/hash_map_utils.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
+#include "osi/include/properties.h"
#include "osi/include/socket_utils/sockets.h"
#include "audio_a2dp_hw.h"
+static char a2dp_hal_imp[PROPERTY_VALUE_MAX] = "false";
+
/*****************************************************************************
* Constants & Macros
*****************************************************************************/
@@ -58,6 +61,7 @@
#define USEC_PER_SEC 1000000L
#define SOCK_SEND_TIMEOUT_MS 2000 /* Timeout for sending */
#define SOCK_RECV_TIMEOUT_MS 5000 /* Timeout for receiving */
+#define SOCK_RECV_TIMEOUT_MS_2 3000 /* Timeout for receiving */
#define SEC_TO_MS 1000
#define SEC_TO_NS 1000000000
#define MS_TO_NS 1000000
@@ -153,7 +157,7 @@
*****************************************************************************/
static bool enable_delay_reporting = false;
-
+static int open_ctrl_chnl_fail_count = 0;
/*****************************************************************************
* Static functions
*****************************************************************************/
@@ -241,10 +245,22 @@
int ret;
int skt_fd;
int len;
+ int sock_recv_timeout_ms = SOCK_RECV_TIMEOUT_MS;
+
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ WARN("a2dp hal implementation, scoket receive timeout: %d", SOCK_RECV_TIMEOUT_MS_2);
+ sock_recv_timeout_ms = SOCK_RECV_TIMEOUT_MS_2;
+ }
INFO("connect to %s (sz %zu)", path, buffer_sz);
skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if(skt_fd < 0)
+ {
+ ERROR("failed to create socket");
+ return -1;
+ }
if (osi_socket_local_client_connect(
skt_fd, path, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) {
@@ -264,8 +280,8 @@
/* Socket send/receive timeout value */
struct timeval tv;
- tv.tv_sec = SOCK_SEND_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_SEND_TIMEOUT_MS % 1000) * 1000;
+ tv.tv_sec = sock_recv_timeout_ms / 1000;
+ tv.tv_usec = (sock_recv_timeout_ms % 1000) * 1000;
ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
@@ -353,24 +369,30 @@
ssize_t ret;
int i;
- for (i = 0;; i++) {
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
- if (ret > 0) {
- break;
+ ERROR("a2dp_ctrl_receive: ret=%d", (int)ret);
+ } else {
+ for (i = 0;; i++) {
+ OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
+ if (ret > 0) {
+ break;
+ }
+ if (ret == 0) {
+ ERROR("receive control data failed: peer closed");
+ break;
+ }
+ if (errno != EWOULDBLOCK && errno != EAGAIN) {
+ ERROR("receive control data failed: error(%s)", strerror(errno));
+ break;
+ }
+ if (i == (CTRL_CHAN_RETRY_COUNT - 1)) {
+ ERROR("receive control data failed: max retry count");
+ break;
+ }
+ INFO("receive control data failed (%s), retrying", strerror(errno));
}
- if (ret == 0) {
- ERROR("receive control data failed: peer closed");
- break;
- }
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("receive control data failed: error(%s)", strerror(errno));
- break;
- }
- if (i == (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("receive control data failed: max retry count");
- break;
- }
- INFO("receive control data failed (%s), retrying", strerror(errno));
}
if (ret <= 0) {
skt_disconnect(common->ctrl_fd);
@@ -424,9 +446,11 @@
static int a2dp_command(struct a2dp_stream_common* common, tA2DP_CTRL_CMD cmd) {
char ack;
- DEBUG("A2DP COMMAND %s", audio_a2dp_hw_dump_ctrl_event(cmd));
+ DEBUG("A2DP COMMAND %s, , fail count: %d", audio_a2dp_hw_dump_ctrl_event(cmd),
+ open_ctrl_chnl_fail_count);
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
+ if ((common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
+ && (open_ctrl_chnl_fail_count < 5)) {
INFO("starting up or recovering from previous error: command=%s",
audio_a2dp_hw_dump_ctrl_event(cmd));
a2dp_open_ctrl_path(common);
@@ -435,6 +459,9 @@
audio_a2dp_hw_dump_ctrl_event(cmd));
return -1;
}
+ } else if (open_ctrl_chnl_fail_count >= 5) {
+ WARN("control channel open alreday failed 5 times, bailing out");
+ return -1;
}
/* send command */
@@ -451,15 +478,29 @@
/* wait for ack byte */
if (a2dp_ctrl_receive(common, &ack, 1) < 0) {
ERROR("A2DP COMMAND %s: no ACK", audio_a2dp_hw_dump_ctrl_event(cmd));
- return -1;
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ //On no ACK scenario also we need to fake as success
+ return 0;
+ } else {
+ return -1;
+ }
}
DEBUG("A2DP COMMAND %s DONE STATUS %d", audio_a2dp_hw_dump_ctrl_event(cmd),
ack);
- if (ack == A2DP_CTRL_ACK_INCALL_FAILURE) {
- ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
- return ack;
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ if ((ack == A2DP_CTRL_ACK_INCALL_FAILURE) || (ack == A2DP_CTRL_ACK_PREVIOUS_COMMAND_PENDING)) {
+ ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
+ return ack;
+ }
+ } else {
+ if (ack == A2DP_CTRL_ACK_INCALL_FAILURE) {
+ ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
+ return ack;
+ }
}
if (ack != A2DP_CTRL_ACK_SUCCESS) {
ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
@@ -481,9 +522,18 @@
tA2DP_SAMPLE_RATE sample_rate;
tA2DP_CHANNEL_COUNT channel_count;
- if (a2dp_command(common, A2DP_CTRL_GET_INPUT_AUDIO_CONFIG) < 0) {
- ERROR("get a2dp input audio config failed");
- return -1;
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ if (a2dp_command(common, A2DP_CTRL_GET_INPUT_AUDIO_CONFIG) != 0) {
+ // Now >0 return value (prev command pending) should also be considered as error
+ ERROR("get a2dp input audio config failed");
+ return -1;
+ }
+ } else {
+ if (a2dp_command(common, A2DP_CTRL_GET_INPUT_AUDIO_CONFIG) < 0) {
+ ERROR("get a2dp input audio config failed");
+ return -1;
+ }
}
if (a2dp_ctrl_receive(common, &sample_rate, sizeof(tA2DP_SAMPLE_RATE)) < 0)
@@ -528,9 +578,18 @@
btav_a2dp_codec_config_t* codec_capability, bool update_stream_config) {
struct a2dp_config stream_config;
- if (a2dp_command(common, A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("get a2dp output audio config failed");
- return -1;
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ if (a2dp_command(common, A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG) != 0) {
+ // Now >0 return value (prev command pending) should also be considered as error
+ ERROR("get a2dp output audio config failed");
+ return -1;
+ }
+ } else {
+ if (a2dp_command(common, A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG) < 0) {
+ ERROR("get a2dp output audio config failed");
+ return -1;
+ }
}
// Receive the current codec config
@@ -782,6 +841,8 @@
static void a2dp_open_ctrl_path(struct a2dp_stream_common* common) {
int i;
+ ssize_t ret;
+ char ack;
if (common->ctrl_fd != AUDIO_SKT_DISCONNECTED) return; // already connected
@@ -790,8 +851,22 @@
/* connect control channel if not already connected */
if ((common->ctrl_fd = skt_connect(
A2DP_CTRL_PATH, AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ)) >= 0) {
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ WARN("a2dp hal implementation, connect ctrl socket");
+ OSI_NO_INTR(ret = recv(common->ctrl_fd, &ack, 1, MSG_NOSIGNAL | MSG_DONTWAIT));
+ if (ret > 0)
+ {
+ ERROR("a2dp_open_ctrl_path: flush stale ACK byte");
+ }
+ }
+
/* success, now check if stack is ready */
- if (check_a2dp_ready(common) == 0) break;
+ if (check_a2dp_ready(common) == 0) {
+ open_ctrl_chnl_fail_count = 0;
+ WARN("a2dp_open_ctrl_path : Fail count reset to 0");
+ break;
+ }
ERROR("error : a2dp not ready, wait 250 ms and retry");
usleep(250000);
@@ -802,6 +877,12 @@
/* ctrl channel not ready, wait a bit */
usleep(250000);
}
+ INFO("a2dp_open_ctrl_path : ctrl_fd: %d", common->ctrl_fd);
+ if (common->ctrl_fd <= 0) {
+ open_ctrl_chnl_fail_count += 1;
+ WARN("a2dp_open_ctrl_path : Fail count raised to: %d",
+ open_ctrl_chnl_fail_count);
+ }
}
/*****************************************************************************
@@ -843,6 +924,11 @@
} else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE) {
ERROR("Audiopath start failed - in call, move to suspended");
goto error;
+ } else if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true") &&
+ a2dp_status == A2DP_CTRL_ACK_PREVIOUS_COMMAND_PENDING) {
+ ERROR("start_audio_datapath: Audiopath start failed as previous\
+ command is pending, fake as success");
}
/* connect socket if not yet connected */
@@ -850,7 +936,17 @@
common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
if (common->audio_fd < 0) {
ERROR("Audiopath start failed - error opening data socket");
- goto error;
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ if ((a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE)
+ || (a2dp_status < 0))
+ goto error;
+ else
+ INFO("Ignore Audiopath start failure");
+ } else {
+ ERROR("Audiopath start failed - error opening data socket");
+ goto error;
+ }
}
}
common->state = (a2dp_state_t)AUDIO_A2DP_STATE_STARTED;
@@ -960,6 +1056,12 @@
lock.lock();
if (sent == -1) {
+ if (osi_property_get("persist.vendor.bt.a2dp.hal.implementation", a2dp_hal_imp, "false") &&
+ !strcmp(a2dp_hal_imp, "true")) {
+ sent = bytes;
+ ERROR("ignore data write failure");
+ }
+
skt_disconnect(out->common.audio_fd);
out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
if ((out->common.state != AUDIO_A2DP_STATE_SUSPENDED) &&
@@ -1182,7 +1284,7 @@
if (params["A2dpSuspended"].compare("true") == 0) {
if (out->common.state == AUDIO_A2DP_STATE_STARTED)
status = suspend_audio_datapath(&out->common, false);
- } else {
+ } else if (params["A2dpSuspended"].compare("false") == 0) {
/* Do not start the streaming automatically. If the phone was streaming
* prior to being suspended, the next out_write shall trigger the
* AVDTP start procedure */
@@ -1580,6 +1682,7 @@
struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
struct a2dp_stream_out* out;
int ret = 0;
+ open_ctrl_chnl_fail_count = 0;
INFO("opening output");
// protect against adev->output and stream_out from being inconsistent
@@ -1660,6 +1763,8 @@
*stream_out = &out->stream;
a2dp_dev->output = out;
+ DEBUG("A2DP_CTRL_CMD_STREAM_OPEN sent to unblock audio start");
+ a2dp_command(&out->common, A2DP_CTRL_CMD_STREAM_OPEN);
DEBUG("success");
/* Delay to ensure Headset is in proper state when START is initiated from
* DUT immediately after the connection due to ongoing music playback. */
diff --git a/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc b/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc
index 984e46b..b4324d5 100644
--- a/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc
+++ b/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc
@@ -27,6 +27,7 @@
switch (event) {
CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
+ CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_STREAM_STARTED)
CASE_RETURN_STR(A2DP_CTRL_CMD_START)
CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
@@ -35,6 +36,7 @@
CASE_RETURN_STR(A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG)
CASE_RETURN_STR(A2DP_CTRL_CMD_OFFLOAD_START)
CASE_RETURN_STR(A2DP_CTRL_GET_PRESENTATION_POSITION)
+ CASE_RETURN_STR(A2DP_CTRL_CMD_STREAM_OPEN)
}
return "UNKNOWN A2DP_CTRL_CMD";
diff --git a/binder/Android.bp b/binder/Android.bp
index e4beadb..adc27c4 100644
--- a/binder/Android.bp
+++ b/binder/Android.bp
@@ -115,5 +115,9 @@
"android/bluetooth/le/IAdvertisingSetCallback.aidl",
"android/bluetooth/le/IPeriodicAdvertisingCallback.aidl",
"android/bluetooth/le/IScannerCallback.aidl",
+ "android/bluetooth/IBluetoothDun.aidl",
+ "android/bluetooth/IBluetoothDeviceGroup.aidl",
+ "android/bluetooth/IBluetoothGroupCallback.aidl",
+ "android/bluetooth/IBluetoothVcp.aidl",
],
}
diff --git a/binder/android/bluetooth/BluetoothQualityReport.aidl b/binder/android/bluetooth/BluetoothQualityReport.aidl
new file mode 100644
index 0000000..a00b329
--- /dev/null
+++ b/binder/android/bluetooth/BluetoothQualityReport.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+
+package android.bluetooth;
+
+parcelable BluetoothQualityReport;
diff --git a/binder/android/bluetooth/DeviceGroup.aidl b/binder/android/bluetooth/DeviceGroup.aidl
new file mode 100644
index 0000000..3b4260d
--- /dev/null
+++ b/binder/android/bluetooth/DeviceGroup.aidl
@@ -0,0 +1,32 @@
+/******************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ *****************************************************************************/
+
+package android.bluetooth;
+
+parcelable DeviceGroup;
\ No newline at end of file
diff --git a/binder/android/bluetooth/IBluetooth.aidl b/binder/android/bluetooth/IBluetooth.aidl
index 0e554b7..3591589 100644
--- a/binder/android/bluetooth/IBluetooth.aidl
+++ b/binder/android/bluetooth/IBluetooth.aidl
@@ -1,4 +1,38 @@
/*
+ * Copyright (C) 2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ * * 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 Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. 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.
+ */
+/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -72,6 +106,7 @@
boolean removeBond(in BluetoothDevice device);
int getBondState(in BluetoothDevice device);
boolean isBondingInitiatedLocally(in BluetoothDevice device);
+ void setBondingInitiatedLocally(in BluetoothDevice devicei, in boolean localInitiated);
long getSupportedProfiles();
int getConnectionState(in BluetoothDevice device);
@@ -88,6 +123,8 @@
int getBatteryLevel(in BluetoothDevice device);
int getMaxConnectedAudioDevices();
+ boolean isTwsPlusDevice(in BluetoothDevice device);
+ String getTwsPlusPeerAddress(in BluetoothDevice device);
boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);
boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]
passkey);
@@ -138,7 +175,10 @@
oneway void requestActivityInfo(in ResultReceiver result);
void onLeServiceUp();
+ void updateQuietModeStatus(boolean quietMode);
void onBrEdrDown();
+ int setSocketOpt(int type, int port, int optionName, in byte [] optionVal, int optionLen);
+ int getSocketOpt(int type, int port, int optionName, out byte [] optionVal);
boolean connectAllEnabledProfiles(in BluetoothDevice device);
boolean disconnectAllEnabledProfiles(in BluetoothDevice device);
@@ -148,4 +188,9 @@
List<BluetoothDevice> getMostRecentlyConnectedDevices();
boolean removeActiveDevice(in int profiles);
+
+ int getDeviceType(in BluetoothDevice device);
+
+ boolean isBroadcastActive();
+
}
diff --git a/binder/android/bluetooth/IBluetoothDeviceGroup.aidl b/binder/android/bluetooth/IBluetoothDeviceGroup.aidl
new file mode 100644
index 0000000..1412fbd
--- /dev/null
+++ b/binder/android/bluetooth/IBluetoothDeviceGroup.aidl
@@ -0,0 +1,58 @@
+/******************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ *****************************************************************************/
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.DeviceGroup;
+import android.os.ParcelUuid;
+
+import android.bluetooth.IBluetoothGroupCallback;
+
+/**
+ * API for interacting with Group Service
+ * @hide
+ */
+
+interface IBluetoothDeviceGroup {
+ void connect (in int appId, in BluetoothDevice device);
+ void disconnect (in int appId, in BluetoothDevice device);
+ void registerGroupClientApp(in ParcelUuid uuid, in IBluetoothGroupCallback callback);
+ void unregisterGroupClientApp(in int appId);
+ void startGroupDiscovery(in int appId, in int groupId);
+ void stopGroupDiscovery(in int appId, in int groupId);
+ List<DeviceGroup> getDiscoveredGroups(in boolean mPublicAddr);
+ DeviceGroup getDeviceGroup(in int groupId, in boolean mPublicAddr);
+ int getRemoteDeviceGroupId (in BluetoothDevice device, in ParcelUuid uuid,
+ in boolean mPublicAddr);
+ boolean isGroupDiscoveryInProgress(in int groupId);
+ void setExclusiveAccess(in int appId, in int groupId, in List<BluetoothDevice> devices,
+ in int value);
+ void getExclusiveAccessStatus(in int appId, in int groupId, in List<BluetoothDevice> devices);
+}
diff --git a/binder/android/bluetooth/IBluetoothDun.aidl b/binder/android/bluetooth/IBluetoothDun.aidl
new file mode 100644
index 0000000..aca57c4
--- /dev/null
+++ b/binder/android/bluetooth/IBluetoothDun.aidl
@@ -0,0 +1,45 @@
+/*
+*Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved.
+*
+*Redistribution and use in source and binary forms, with or without
+*modification, are permitted provided that the following conditions are
+*met:
+* * 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+*WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+*MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+*ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+*/
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * API for Bluetooth Dun service
+ *
+ * {@hide}
+ */
+interface IBluetoothDun {
+ // Public API
+ boolean disconnect(in BluetoothDevice device);
+ int getConnectionState(in BluetoothDevice device);
+ List<BluetoothDevice> getConnectedDevices();
+ List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+}
diff --git a/binder/android/bluetooth/IBluetoothGatt.aidl b/binder/android/bluetooth/IBluetoothGatt.aidl
index 78d0261..c9171d0 100644
--- a/binder/android/bluetooth/IBluetoothGatt.aidl
+++ b/binder/android/bluetooth/IBluetoothGatt.aidl
@@ -70,9 +70,10 @@
void registerSync(in ScanResult scanResult, in int skip, in int timeout, in IPeriodicAdvertisingCallback callback);
void unregisterSync(in IPeriodicAdvertisingCallback callback);
-
+ void transferSync(in BluetoothDevice bda, in int serviceData, in int syncHandle);
+ void transferSetInfo(in BluetoothDevice bda, in int serviceData, in int advertisingHandle, in IPeriodicAdvertisingCallback callback);
@UnsupportedAppUsage
- void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
+ void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback, in boolean eattSupport);
@UnsupportedAppUsage
void unregisterClient(in int clientIf);
@@ -101,7 +102,7 @@
int maxInterval, int slaveLatency, int supervisionTimeout,
int minConnectionEventLen, int maxConnectionEventLen);
- void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback);
+ void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback, in boolean eattSupport);
void unregisterServer(in int serverIf);
void serverConnect(in int serverIf, in String address, in boolean isDirect, in int transport);
void serverDisconnect(in int serverIf, in String address);
diff --git a/binder/android/bluetooth/IBluetoothGroupCallback.aidl b/binder/android/bluetooth/IBluetoothGroupCallback.aidl
new file mode 100644
index 0000000..0e7761f
--- /dev/null
+++ b/binder/android/bluetooth/IBluetoothGroupCallback.aidl
@@ -0,0 +1,48 @@
+/******************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ *****************************************************************************/
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.DeviceGroup;
+import android.os.ParcelUuid;
+
+/** @hide */
+interface IBluetoothGroupCallback {
+ void onConnectionStateChanged(in int state, in BluetoothDevice device);
+ void onGroupClientAppRegistered(in int status, in int appId);
+ void onGroupClientAppUnregistered(in int status);
+ void onNewGroupFound(in int groupId, in BluetoothDevice device, in ParcelUuid uuid);
+ void onGroupDiscoveryStatusChanged(in int groupId, in int status, in int reason);
+ void onGroupDeviceFound(in int groupId, in BluetoothDevice groupDevice);
+ void onExclusiveAccessChanged(in int groupId, in int accessValue, in int accessStatus,
+ in List<BluetoothDevice> devices);
+ void onExclusiveAccessAvailable(in int groupId, in BluetoothDevice device);
+ void onExclusiveAccessStatusFetched(in int groupId, in int accessValue);
+}
diff --git a/binder/android/bluetooth/IBluetoothHeadsetPhone.aidl b/binder/android/bluetooth/IBluetoothHeadsetPhone.aidl
index 8309780..04f8341 100644
--- a/binder/android/bluetooth/IBluetoothHeadsetPhone.aidl
+++ b/binder/android/bluetooth/IBluetoothHeadsetPhone.aidl
@@ -31,6 +31,9 @@
String getSubscriberNumber();
boolean listCurrentCalls();
boolean queryPhoneState();
+ boolean isHighDefCallInProgress();
+ boolean isCsCallInProgress();
+
// Internal for phone app to call
void updateBtHandsfreeAfterRadioTechnologyChange();
diff --git a/binder/android/bluetooth/IBluetoothManager.aidl b/binder/android/bluetooth/IBluetoothManager.aidl
index e94fe64..49d3f1a 100644
--- a/binder/android/bluetooth/IBluetoothManager.aidl
+++ b/binder/android/bluetooth/IBluetoothManager.aidl
@@ -55,6 +55,7 @@
boolean enableBle(String packageName, IBinder b);
boolean disableBle(String packageName, IBinder b);
boolean isBleAppPresent();
+ boolean factoryReset();
boolean isHearingAidProfileSupported();
List<String> getSystemConfigEnabledProfilesForPackage(String packageName);
diff --git a/binder/android/bluetooth/IBluetoothVcp.aidl b/binder/android/bluetooth/IBluetoothVcp.aidl
new file mode 100644
index 0000000..6e44c2c
--- /dev/null
+++ b/binder/android/bluetooth/IBluetoothVcp.aidl
@@ -0,0 +1,39 @@
+/*
+ *Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *Not a contribution
+ */
+
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * APIs for Bluetooth Vcp Service
+ *
+ * @hide
+ */
+interface IBluetoothVcp {
+ // Public API
+ int getConnectionState(in BluetoothDevice device);
+ int getConnectionMode(in BluetoothDevice device);
+ void setAbsoluteVolume(in BluetoothDevice device, int volume);
+ int getAbsoluteVolume(in BluetoothDevice device);
+ void setMute (in BluetoothDevice device, in boolean enableMute);
+ boolean isMute(in BluetoothDevice device);
+}
diff --git a/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl b/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
index 84bbc14..34eda66 100644
--- a/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
+++ b/binder/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl
@@ -28,4 +28,5 @@
in int skip, in int timeout, in int status);
void onPeriodicAdvertisingReport(in PeriodicAdvertisingReport report);
void onSyncLost(in int syncHandle);
+ void onSyncTransfered(in BluetoothDevice device, in int status);
}
diff --git a/bta/av/bta_av_main.cc b/bta/av/bta_av_main.cc
index 61e4b4e..f0f4640 100644
--- a/bta/av/bta_av_main.cc
+++ b/bta/av/bta_av_main.cc
@@ -86,7 +86,7 @@
#endif
#ifndef AVRCP_DEFAULT_VERSION
-#define AVRCP_DEFAULT_VERSION AVRCP_1_4_STRING
+#define AVRCP_DEFAULT_VERSION AVRCP_1_5_STRING
#endif
/* state machine states */
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index 3900594..d1b260c 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -39,7 +39,6 @@
#include "bta_dm_int.h"
#include "bta_sys.h"
#include "btif_storage.h"
-#include "btif_config.h"
#include "btm_api.h"
#include "btm_int.h"
#include "btu.h"
@@ -49,7 +48,6 @@
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "sdp_api.h"
-#include "stack/btm/btm_ble_int.h"
#include "stack/gatt/connection_manager.h"
#include "stack/include/gatt_api.h"
#include "utl.h"
@@ -707,12 +705,6 @@
if (!other_address_connected && !other_address.IsEmpty()) {
bta_dm_process_remove_device(other_address);
}
-
- /* Check the length of the paired devices, and if 0 then reset IRK */
- if (btif_storage_get_num_bonded_devices() < 1) {
- LOG(INFO) << "Last paired device removed, resetting IRK";
- btm_ble_reset_id();
- }
}
/*******************************************************************************
diff --git a/btif/src/btif_a2dp_audio_interface.cc b/btif/src/btif_a2dp_audio_interface.cc
index 026baa1..0ced7f4 100644
--- a/btif/src/btif_a2dp_audio_interface.cc
+++ b/btif/src/btif_a2dp_audio_interface.cc
@@ -196,6 +196,11 @@
LOG_INFO(LOG_TAG, "%s", __func__);
tBT_A2DP_OFFLOAD a2dp_offload;
A2dpCodecConfig* a2dpCodecConfig = bta_av_get_a2dp_current_codec();
+ if (!a2dpCodecConfig) {
+ APPL_TRACE_ERROR("%s: failed to get current a2dp codec config", __func__);
+ return;
+ }
+
a2dpCodecConfig->getCodecSpecificConfig(&a2dp_offload);
btav_a2dp_codec_config_t codec_config;
codec_config = a2dpCodecConfig->getCodecConfig();
diff --git a/btif/src/btif_ble_advertiser.cc b/btif/src/btif_ble_advertiser.cc
index d1923bd..d150650 100644
--- a/btif/src/btif_ble_advertiser.cc
+++ b/btif/src/btif_ble_advertiser.cc
@@ -235,6 +235,16 @@
std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
}
+ void CreateBIG(int advertiser_id, CreateBIGParameters create_big_params,
+ CreateBIGCallback cb) override {
+ VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id;
+ }
+
+ void TerminateBIG(int advertiser_id, int big_handle, int reason,
+ TerminateBIGCallback cb) override {
+ VLOG(1) << __func__ << "big_handle: " << +big_handle;
+ }
+
void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
StatusCallback cb) override {
VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
diff --git a/btif/src/btif_ble_scanner.cc b/btif/src/btif_ble_scanner.cc
index b314993..e01fe98 100644
--- a/btif/src/btif_ble_scanner.cc
+++ b/btif/src/btif_ble_scanner.cc
@@ -285,10 +285,11 @@
jni_thread_wrapper(FROM_HERE, std::move(cb))));
}
- void SetScanParameters(int scan_interval, int scan_window,
+ void SetScanParameters(int scan_phy, std::vector<uint32_t> scan_interval,
+ std::vector<uint32_t> scan_window,
Callback cb) override {
do_in_main_thread(
- FROM_HERE, base::Bind(&BTM_BleSetScanParams, scan_interval, scan_window,
+ FROM_HERE, base::Bind(&BTM_BleSetScanParams, scan_interval[0], scan_window[0],
BTM_BLE_SCAN_MODE_ACTI,
jni_thread_wrapper(FROM_HERE, std::move(cb))));
}
@@ -330,6 +331,14 @@
SyncLostCb lost_cb) override {}
void StopSync(uint16_t handle) override {}
+ void CancelCreateSync(uint8_t sid, RawAddress address) override {}
+ void TransferSync(RawAddress address, uint16_t service_data,
+ uint16_t sync_handle, SyncTransferCb cb) override {}
+
+ void TransferSetInfo(RawAddress address, uint16_t service_data,
+ uint8_t adv_handle, SyncTransferCb cb) override {}
+ void SyncTxParameters(RawAddress address, uint8_t mode, uint16_t skip,
+ uint16_t timeout, StartSyncCb cb) override {}
};
BleScannerInterface* btLeScannerInstance = nullptr;
diff --git a/btif/src/btif_config.cc b/btif/src/btif_config.cc
index 49cb19f..ca69ee8 100644
--- a/btif/src/btif_config.cc
+++ b/btif/src/btif_config.cc
@@ -194,7 +194,7 @@
metrics_salt.fill(0);
}
if (!AddressObfuscator::IsSaltValid(metrics_salt)) {
- LOG(INFO) << __func__ << ": Metrics salt is not invalid, creating new one";
+ LOG(INFO) << __func__ << ": Metrics salt is] not invalid, creating new one";
if (RAND_bytes(metrics_salt.data(), metrics_salt.size()) != 1) {
LOG(FATAL) << __func__ << "Failed to generate salt for metrics";
}
@@ -488,8 +488,8 @@
auto value_str_from_config = btif_config_cache.GetString(section, key);
if (!value_str_from_config) {
- VLOG(1) << __func__ << ": cannot find string for section " << section
- << ", key " << key;
+ LOG(WARNING) << __func__ << ": cannot find string for section " << section
+ << ", key " << key;
return false;
}
diff --git a/btif/src/btif_gatt_client.cc b/btif/src/btif_gatt_client.cc
index 14433d3..1a696d6 100644
--- a/btif/src/btif_gatt_client.cc
+++ b/btif/src/btif_gatt_client.cc
@@ -220,7 +220,7 @@
* Client API Functions
******************************************************************************/
-bt_status_t btif_gattc_register_app(const Uuid& uuid) {
+bt_status_t btif_gattc_register_app(const Uuid& uuid, bool eatt_support) {
CHECK_BTGATT_INIT();
return do_in_jni_thread(Bind(
diff --git a/btif/src/btif_gatt_server.cc b/btif/src/btif_gatt_server.cc
index 6dc5eb7..62ca59f 100644
--- a/btif/src/btif_gatt_server.cc
+++ b/btif/src/btif_gatt_server.cc
@@ -266,7 +266,7 @@
/*******************************************************************************
* Server API Functions
******************************************************************************/
-static bt_status_t btif_gatts_register_app(const Uuid& bt_uuid) {
+static bt_status_t btif_gatts_register_app(const Uuid& bt_uuid, bool eatt_support) {
CHECK_BTGATT_INIT();
return do_in_jni_thread(
diff --git a/common/Android.bp b/common/Android.bp
index e05528c..7aeb2c7 100644
--- a/common/Android.bp
+++ b/common/Android.bp
@@ -9,6 +9,7 @@
"system/bt",
"system/bt/stack/include",
],
+ // TODO (b/121280692) address_obfuscator.cc still reverted
srcs: [
"address_obfuscator.cc",
"message_loop_thread.cc",
diff --git a/conf/Android.bp b/conf/Android.bp
index ecf4922..8f28a67 100644
--- a/conf/Android.bp
+++ b/conf/Android.bp
@@ -1,10 +1,10 @@
// Bluetooth bt_stack.conf config file
// ========================================================
-prebuilt_etc {
- name: "bt_stack.conf",
- src: "bt_stack.conf",
- sub_dir: "bluetooth",
-}
+//prebuilt_etc {
+// name: "bt_stack.conf",
+// src: "bt_stack.conf",
+// sub_dir: "bluetooth",
+//}
// Bluetooth bt_did.conf config file
// ========================================================
diff --git a/device/include/interop.h b/device/include/interop.h
index d7ca917..efbafa1 100644
--- a/device/include/interop.h
+++ b/device/include/interop.h
@@ -99,7 +99,15 @@
// The public address of these devices are same as the Random address in ADV.
// Then will get name by LE_Create_connection, actually fails,
// but will block pairing.
- INTEROP_DISABLE_NAME_REQUEST
+ INTEROP_DISABLE_NAME_REQUEST,
+
+ // Respond AVRCP profile version only 1.4 for some device.
+ INTEROP_AVRCP_1_4_ONLY,
+
+ // Disable sniff mode for headsets/car-kits
+ // Some car kits supports sniff mode but when DUT initiates sniff req
+ // Remote will go to bad state and its leads to LMP time out.
+ INTEROP_DISABLE_SNIFF
} interop_feature_t;
// Check if a given |addr| matches a known interoperability workaround as
diff --git a/device/include/interop_database.h b/device/include/interop_database.h
index b4b1b07..8010bcc 100644
--- a/device/include/interop_database.h
+++ b/device/include/interop_database.h
@@ -150,6 +150,24 @@
// for skip name request,
// because BR/EDR address and ADV random address are the same
{{{0xd4, 0x7a, 0xe2, 0, 0, 0}}, 3, INTEROP_DISABLE_NAME_REQUEST},
+
+ // Lexus Carkit
+ {{{0x64, 0xd4, 0xbd, 0, 0, 0}}, 3, INTEROP_AVRCP_1_4_ONLY},
+
+ // Mazda Carkit
+ {{{0xfc, 0x35, 0xe6, 0, 0, 0}}, 3, INTEROP_AVRCP_1_4_ONLY},
+
+ // Toyota Car Audio
+ {{{0x00, 0x17, 0x53, 0, 0, 0}}, 3, INTEROP_AVRCP_1_4_ONLY},
+
+ // Honda High End Carkit
+ {{{0x9c, 0x8d, 0x7c, 0, 0, 0}}, 3, INTEROP_AVRCP_1_4_ONLY},
+
+ // Honda Civic Carkit
+ {{{0x0c, 0xd9, 0xc1, 0, 0, 0}}, 3, INTEROP_AVRCP_1_4_ONLY},
+
+ // KDDI Carkit
+ {{{0x44, 0xea, 0xd8, 0, 0, 0}}, 3, INTEROP_DISABLE_SNIFF}
};
typedef struct {
diff --git a/device/src/interop.cc b/device/src/interop.cc
index 9a701b1..a1e45d2 100644
--- a/device/src/interop.cc
+++ b/device/src/interop.cc
@@ -132,6 +132,8 @@
CASE_RETURN_STR(INTEROP_DISABLE_ROLE_SWITCH)
CASE_RETURN_STR(INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL)
CASE_RETURN_STR(INTEROP_DISABLE_NAME_REQUEST)
+ CASE_RETURN_STR(INTEROP_AVRCP_1_4_ONLY)
+ CASE_RETURN_STR(INTEROP_DISABLE_SNIFF)
}
return "UNKNOWN";
diff --git a/gd/hal/hci_hal_host_rootcanal_test.cc b/gd/hal/hci_hal_host_rootcanal_test.cc
index 9783e84..aeff6a8 100644
--- a/gd/hal/hci_hal_host_rootcanal_test.cc
+++ b/gd/hal/hci_hal_host_rootcanal_test.cc
@@ -172,9 +172,9 @@
void check_packet_equal(std::pair<uint8_t, HciPacket> hci_packet1_type_data_pair, H4Packet h4_packet2) {
auto packet1_hci_size = hci_packet1_type_data_pair.second.size();
- EXPECT_EQ(packet1_hci_size + 1, h4_packet2.size());
- EXPECT_EQ(hci_packet1_type_data_pair.first, h4_packet2[0]);
- EXPECT_EQ(memcmp(hci_packet1_type_data_pair.second.data(), h4_packet2.data() + 1, packet1_hci_size), 0);
+ ASSERT_EQ(packet1_hci_size + 1, h4_packet2.size());
+ ASSERT_EQ(hci_packet1_type_data_pair.first, h4_packet2[0]);
+ ASSERT_EQ(memcmp(hci_packet1_type_data_pair.second.data(), h4_packet2.data() + 1, packet1_hci_size), 0);
}
HciPacket make_sample_hci_cmd_pkt(uint8_t parameter_total_length) {
@@ -223,6 +223,16 @@
return pkt;
}
+size_t read_with_retry(int socket, uint8_t* data, size_t length) {
+ size_t bytes_read = 0;
+ ssize_t bytes_read_current = 0;
+ do {
+ bytes_read_current = read(socket, data + bytes_read, length - bytes_read);
+ bytes_read += bytes_read_current;
+ } while (length > bytes_read && bytes_read_current > 0);
+ return bytes_read;
+}
+
TEST_F(HciHalRootcanalTest, init_and_close) {}
TEST_F(HciHalRootcanalTest, receive_hci_evt) {
@@ -319,9 +329,9 @@
hal_->sendHciCommand(hci_data);
H4Packet read_buf(1 + 2 + 1 + hci_cmd_param_size);
SetFakeServerSocketToBlocking();
- auto size_read = read(fake_server_socket_, read_buf.data(), read_buf.size());
+ auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
- EXPECT_EQ(size_read, 1 + hci_data.size());
+ ASSERT_EQ(size_read, 1 + hci_data.size());
check_packet_equal({kH4Command, hci_data}, read_buf);
}
@@ -331,9 +341,9 @@
hal_->sendAclData(acl_packet);
H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
SetFakeServerSocketToBlocking();
- auto size_read = read(fake_server_socket_, read_buf.data(), read_buf.size());
+ auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
- EXPECT_EQ(size_read, 1 + acl_packet.size());
+ ASSERT_EQ(size_read, 1 + acl_packet.size());
check_packet_equal({kH4Acl, acl_packet}, read_buf);
}
@@ -343,9 +353,9 @@
hal_->sendScoData(sco_packet);
H4Packet read_buf(1 + 3 + sco_payload_size);
SetFakeServerSocketToBlocking();
- auto size_read = read(fake_server_socket_, read_buf.data(), read_buf.size());
+ auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
- EXPECT_EQ(size_read, 1 + sco_packet.size());
+ ASSERT_EQ(size_read, 1 + sco_packet.size());
check_packet_equal({kH4Sco, sco_packet}, read_buf);
}
@@ -359,8 +369,8 @@
H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
SetFakeServerSocketToBlocking();
for (int i = 0; i < num_packets; i++) {
- auto size_read = read(fake_server_socket_, read_buf.data(), read_buf.size());
- EXPECT_EQ(size_read, 1 + acl_packet.size());
+ auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
+ ASSERT_EQ(size_read, 1 + acl_packet.size());
check_packet_equal({kH4Acl, acl_packet}, read_buf);
}
}
@@ -373,8 +383,8 @@
for (int i = 0; i < num_packets; i++) {
hal_->sendAclData(acl_packet);
H4Packet read_buf(1 + 2 + 2 + acl_payload_size);
- auto size_read = read(fake_server_socket_, read_buf.data(), read_buf.size());
- EXPECT_EQ(size_read, 1 + acl_packet.size());
+ auto size_read = read_with_retry(fake_server_socket_, read_buf.data(), read_buf.size());
+ ASSERT_EQ(size_read, 1 + acl_packet.size());
check_packet_equal({kH4Acl, acl_packet}, read_buf);
}
}
@@ -382,7 +392,7 @@
TEST(HciHalHidlTest, serialize) {
std::vector<uint8_t> bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9};
auto packet_bytes = hal::SerializePacket(std::unique_ptr<packet::BasePacketBuilder>(new packet::RawBuilder(bytes)));
- EXPECT_EQ(bytes, packet_bytes);
+ ASSERT_EQ(bytes, packet_bytes);
}
} // namespace
} // namespace hal
diff --git a/include/hardware/ble_advertiser.h b/include/hardware/ble_advertiser.h
index 6055d89..b8a07dc 100644
--- a/include/hardware/ble_advertiser.h
+++ b/include/hardware/ble_advertiser.h
@@ -34,6 +34,20 @@
uint8_t scan_request_notification_enable;
};
+struct CreateBIGParameters {
+ uint8_t adv_handle;
+ uint8_t num_bis;
+ uint32_t sdu_int;
+ uint16_t max_sdu;
+ uint16_t max_transport_latency;
+ uint8_t rtn;
+ uint8_t phy;
+ uint8_t packing;
+ uint8_t framing;
+ uint8_t encryption;
+ std::vector<uint8_t> broadcast_code;
+};
+
struct PeriodicAdvertisingParameters {
uint8_t enable;
uint16_t min_interval;
@@ -54,7 +68,15 @@
uint8_t /* status */)>;
using ParametersCallback =
base::Callback<void(uint8_t /* status */, int8_t /* tx_power */)>;
-
+ using CreateBIGCallback = base::Callback<void(uint8_t /*adv_inst_id*/,
+ uint8_t /*status*/, uint8_t /*big_handle*/, uint32_t /*big_sync_delay*/,
+ uint32_t /*transport_latency_big*/, uint8_t /*phy*/, uint8_t /*nse*/,
+ uint8_t /*bn*/, uint8_t /*pto*/, uint8_t /*irc*/, uint16_t /*max_pdu*/,
+ uint16_t /*iso_int*/, uint8_t /*num_bis*/,
+ std::vector<uint16_t> /*conn_handle_list*/)>;
+ using TerminateBIGCallback =
+ base::Callback<void(uint8_t /* status */, uint8_t /* advertiser_id */,
+ uint8_t /* big_handle */, uint8_t /* reason */)>;
/** Registers an advertiser with the stack */
virtual void RegisterAdvertiser(IdStatusCallback) = 0;
@@ -103,6 +125,14 @@
std::vector<uint8_t> data,
StatusCallback cb) = 0;
+ virtual void CreateBIG(
+ int advertiser_id, CreateBIGParameters create_big_params,
+ CreateBIGCallback cb) = 0;
+
+ virtual void TerminateBIG(
+ int advertiser_id, int big_handle, int reason,
+ TerminateBIGCallback cb) = 0;
+
virtual void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable,
StatusCallback cb) = 0;
};
diff --git a/include/hardware/ble_scanner.h b/include/hardware/ble_scanner.h
index efa9662..d057392 100644
--- a/include/hardware/ble_scanner.h
+++ b/include/hardware/ble_scanner.h
@@ -96,7 +96,8 @@
virtual void ScanFilterEnable(bool enable, EnableCallback cb) = 0;
/** Sets the LE scan interval and window in units of N*0.625 msec */
- virtual void SetScanParameters(int scan_interval, int scan_window,
+ virtual void SetScanParameters(int scan_phy, std::vector<uint32_t> scan_interval,
+ std::vector<uint32_t> scan_window,
Callback cb) = 0;
/* Configure the batchscan storage */
@@ -128,6 +129,16 @@
uint16_t timeout, StartSyncCb start_cb,
SyncReportCb report_cb, SyncLostCb lost_cb) = 0;
virtual void StopSync(uint16_t handle) = 0;
+ virtual void CancelCreateSync(uint8_t sid, RawAddress address) = 0;
+ using SyncTransferCb =
+ base::Callback<void(uint8_t /*status*/, RawAddress /*addr*/)>;
+
+ virtual void TransferSync(RawAddress address, uint16_t service_data,
+ uint16_t sync_handle, SyncTransferCb cb) = 0;
+ virtual void TransferSetInfo(RawAddress address, uint16_t service_data,
+ uint8_t adv_handle, SyncTransferCb cb) = 0;
+ virtual void SyncTxParameters(RawAddress addr, uint8_t mode, uint16_t skip,
+ uint16_t timeout,StartSyncCb start_cb) = 0;
};
-#endif /* ANDROID_INCLUDE_BLE_SCANNER_H */
\ No newline at end of file
+#endif /* ANDROID_INCLUDE_BLE_SCANNER_H */
diff --git a/include/hardware/bt_av.h b/include/hardware/bt_av.h
index c4c0ecc..dcc3760 100644
--- a/include/hardware/bt_av.h
+++ b/include/hardware/bt_av.h
@@ -53,7 +53,9 @@
BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
BTAV_A2DP_CODEC_INDEX_SOURCE_APTX,
BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
+ BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_ADAPTIVE,
BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC,
+ BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_TWS,
BTAV_A2DP_CODEC_INDEX_SOURCE_MAX,
@@ -146,9 +148,15 @@
case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
codec_name_str = "aptX HD";
break;
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_ADAPTIVE:
+ codec_name_str = "aptX Adaptive";
+ break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
codec_name_str = "LDAC";
break;
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_TWS:
+ codec_name_str = "aptX TWS";
+ break;
case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
codec_name_str = "SBC (Sink)";
break;
diff --git a/include/hardware/bt_common_types.h b/include/hardware/bt_common_types.h
index 0a315fe..1447f58 100644
--- a/include/hardware/bt_common_types.h
+++ b/include/hardware/bt_common_types.h
@@ -99,6 +99,10 @@
uint16_t company_mask;
std::vector<uint8_t> data;
std::vector<uint8_t> data_mask;
+ uint8_t org_id;
+ uint8_t tds_flags;
+ uint8_t tds_flags_mask;
+ bool group_filter_enabled;
};
#endif /* ANDROID_INCLUDE_BT_COMMON_TYPES_H */
diff --git a/include/hardware/bt_gatt_client.h b/include/hardware/bt_gatt_client.h
index 6ea1c89..e56ccc5 100644
--- a/include/hardware/bt_gatt_client.h
+++ b/include/hardware/bt_gatt_client.h
@@ -207,7 +207,7 @@
typedef struct {
/** Registers a GATT client application with the stack */
- bt_status_t (*register_client)(const bluetooth::Uuid& uuid);
+ bt_status_t (*register_client)(const bluetooth::Uuid& uuid, bool eatt_support);
/** Unregister a client application from the stack */
bt_status_t (*unregister_client)(int client_if);
diff --git a/include/hardware/bt_gatt_server.h b/include/hardware/bt_gatt_server.h
index 1b1db37..23389c3 100644
--- a/include/hardware/bt_gatt_server.h
+++ b/include/hardware/bt_gatt_server.h
@@ -138,7 +138,7 @@
/** Represents the standard BT-GATT server interface. */
typedef struct {
/** Registers a GATT server application with the stack */
- bt_status_t (*register_server)(const bluetooth::Uuid& uuid);
+ bt_status_t (*register_server)(const bluetooth::Uuid& uuid, bool eatt_support);
/** Unregister a server application from the stack */
bt_status_t (*unregister_server)(int server_if);
diff --git a/packet/tests/avrcp/avrcp_test_packets.h b/packet/tests/avrcp/avrcp_test_packets.h
index 14e30e7..9028805 100644
--- a/packet/tests/avrcp/avrcp_test_packets.h
+++ b/packet/tests/avrcp/avrcp_test_packets.h
@@ -316,6 +316,10 @@
std::vector<uint8_t> set_browsed_player_request = {0x70, 0x00, 0x02, 0x00,
0x02};
+// AVRCP Set Browsed Player Request with player_id = 0
+std::vector<uint8_t> set_browsed_player_id_0_request = {0x70, 0x00, 0x02, 0x00,
+ 0x00};
+
// AVRCP Set Browsed Player Response with num items = 4 and depth = 0
std::vector<uint8_t> set_browsed_player_response = {
0x70, 0x00, 0x0a, 0x04, 0x00, 0x00, 0x00,
diff --git a/profile/avrcp/device.cc b/profile/avrcp/device.cc
index a7e0e9a..34292d2 100644
--- a/profile/avrcp/device.cc
+++ b/profile/avrcp/device.cc
@@ -1257,6 +1257,14 @@
return;
}
+ if (pkt->GetPlayerId() == 0 && num_items == 0) {
+ // Response fail if no browsable player in Bluetooth Player
+ auto response = SetBrowsedPlayerResponseBuilder::MakeBuilder(
+ Status::PLAYER_NOT_BROWSABLE, 0x0000, num_items, 0, "");
+ send_message(label, true, std::move(response));
+ return;
+ }
+
curr_browsed_player_id_ = pkt->GetPlayerId();
// Clear the path and push the new root.
diff --git a/profile/avrcp/tests/avrcp_device_test.cc b/profile/avrcp/tests/avrcp_device_test.cc
index d221e1b..8d70e43 100644
--- a/profile/avrcp/tests/avrcp_device_test.cc
+++ b/profile/avrcp/tests/avrcp_device_test.cc
@@ -1035,6 +1035,44 @@
SendMessage(1, request);
}
+TEST_F(AvrcpDeviceTest, setBrowsedPlayerTest) {
+ MockMediaInterface interface;
+ NiceMock<MockA2dpInterface> a2dp_interface;
+
+ test_device->RegisterInterfaces(&interface, &a2dp_interface, nullptr);
+
+ EXPECT_CALL(interface, SetBrowsedPlayer(_, _))
+ .Times(3)
+ .WillOnce(InvokeCb<1>(true, "", 0))
+ .WillOnce(InvokeCb<1>(false, "", 0))
+ .WillOnce(InvokeCb<1>(true, "", 2));
+
+ auto not_browsable_rsp = SetBrowsedPlayerResponseBuilder::MakeBuilder(
+ Status::PLAYER_NOT_BROWSABLE, 0x0000, 0, 0, "");
+ EXPECT_CALL(response_cb,
+ Call(1, true, matchPacket(std::move(not_browsable_rsp))))
+ .Times(1);
+
+ auto player_id_0_request =
+ TestBrowsePacket::Make(set_browsed_player_id_0_request);
+ SendBrowseMessage(1, player_id_0_request);
+
+ auto invalid_id_rsp = SetBrowsedPlayerResponseBuilder::MakeBuilder(
+ Status::INVALID_PLAYER_ID, 0x0000, 0, 0, "");
+ EXPECT_CALL(response_cb,
+ Call(2, true, matchPacket(std::move(invalid_id_rsp))))
+ .Times(1);
+
+ SendBrowseMessage(2, player_id_0_request);
+
+ auto response = SetBrowsedPlayerResponseBuilder::MakeBuilder(
+ Status::NO_ERROR, 0x0000, 2, 0, "");
+ EXPECT_CALL(response_cb, Call(3, true, matchPacket(std::move(response))))
+ .Times(1);
+
+ SendBrowseMessage(3, player_id_0_request);
+}
+
TEST_F(AvrcpDeviceTest, volumeChangedTest) {
MockMediaInterface interface;
NiceMock<MockA2dpInterface> a2dp_interface;
diff --git a/profile/sdp/Android.bp b/profile/sdp/Android.bp
index 5abd77b..11c1680 100644
--- a/profile/sdp/Android.bp
+++ b/profile/sdp/Android.bp
@@ -35,6 +35,7 @@
"libgmock",
"sdp_service",
"lib-bt-packets",
+ "liblog",
"libbluetooth-types",
],
}
diff --git a/service/gatt_client.cc b/service/gatt_client.cc
index 629b82a..6c9def5 100644
--- a/service/gatt_client.cc
+++ b/service/gatt_client.cc
@@ -67,7 +67,7 @@
const btgatt_client_interface_t* hal_iface =
hal::BluetoothGattInterface::Get()->GetClientHALInterface();
- if (hal_iface->register_client(uuid) != BT_STATUS_SUCCESS) return false;
+ if (hal_iface->register_client(uuid, false) != BT_STATUS_SUCCESS) return false;
pending_calls_[uuid] = callback;
diff --git a/service/gatt_server.cc b/service/gatt_server.cc
index f911f54..8d8468a 100644
--- a/service/gatt_server.cc
+++ b/service/gatt_server.cc
@@ -590,7 +590,7 @@
const btgatt_server_interface_t* hal_iface =
hal::BluetoothGattInterface::Get()->GetServerHALInterface();
- if (hal_iface->register_server(uuid) != BT_STATUS_SUCCESS) return false;
+ if (hal_iface->register_server(uuid, false) != BT_STATUS_SUCCESS) return false;
pending_calls_[uuid] = callback;
diff --git a/service/gatt_server_old.cc b/service/gatt_server_old.cc
index cfc394c..c6fd9fe 100644
--- a/service/gatt_server_old.cc
+++ b/service/gatt_server_old.cc
@@ -200,7 +200,7 @@
// It must be different than any other registered Uuid.
bluetooth::Uuid client_id = bluetooth::Uuid::GetRandom();
- bt_status_t btstat = g_internal->gatt->client->register_client(client_id);
+ bt_status_t btstat = g_internal->gatt->client->register_client(client_id, false);
if (btstat != BT_STATUS_SUCCESS) {
LOG_ERROR(LOG_TAG, "%s: Failed to register client", __func__);
}
@@ -546,7 +546,7 @@
return false;
}
- bt_status_t btstat = internal_->gatt->server->register_server(service_id);
+ bt_status_t btstat = internal_->gatt->server->register_server(service_id, false);
if (btstat != BT_STATUS_SUCCESS) {
LOG_ERROR(LOG_TAG, "Failed to register server");
return false;
diff --git a/service/hal/fake_bluetooth_gatt_interface.cc b/service/hal/fake_bluetooth_gatt_interface.cc
index dbbbcaa..084aae1 100644
--- a/service/hal/fake_bluetooth_gatt_interface.cc
+++ b/service/hal/fake_bluetooth_gatt_interface.cc
@@ -28,8 +28,8 @@
std::shared_ptr<FakeBluetoothGattInterface::TestClientHandler> g_client_handler;
std::shared_ptr<FakeBluetoothGattInterface::TestServerHandler> g_server_handler;
-bt_status_t FakeRegisterClient(const bluetooth::Uuid& app_uuid) {
- if (g_client_handler) return g_client_handler->RegisterClient(app_uuid);
+bt_status_t FakeRegisterClient(const bluetooth::Uuid& app_uuid, bool eatt_support) {
+ if (g_client_handler) return g_client_handler->RegisterClient(app_uuid, eatt_support);
return BT_STATUS_FAIL;
}
@@ -57,8 +57,8 @@
return BT_STATUS_FAIL;
}
-bt_status_t FakeRegisterServer(const bluetooth::Uuid& app_uuid) {
- if (g_server_handler) return g_server_handler->RegisterServer(app_uuid);
+bt_status_t FakeRegisterServer(const bluetooth::Uuid& app_uuid, bool eatt_support) {
+ if (g_server_handler) return g_server_handler->RegisterServer(app_uuid, eatt_support);
return BT_STATUS_FAIL;
}
diff --git a/service/hal/fake_bluetooth_gatt_interface.h b/service/hal/fake_bluetooth_gatt_interface.h
index a991a21..6297e6c 100644
--- a/service/hal/fake_bluetooth_gatt_interface.h
+++ b/service/hal/fake_bluetooth_gatt_interface.h
@@ -35,7 +35,7 @@
public:
virtual ~TestClientHandler() = default;
- virtual bt_status_t RegisterClient(const bluetooth::Uuid& app_uuid) = 0;
+ virtual bt_status_t RegisterClient(const bluetooth::Uuid& app_uuid, bool eatt_support) = 0;
virtual bt_status_t UnregisterClient(int client_if) = 0;
virtual bt_status_t Connect(int client_if, const RawAddress& bd_addr,
@@ -51,7 +51,7 @@
public:
virtual ~TestServerHandler() = default;
- virtual bt_status_t RegisterServer(const bluetooth::Uuid& app_uuid) = 0;
+ virtual bt_status_t RegisterServer(const bluetooth::Uuid& app_uuid, bool eatt_support) = 0;
virtual bt_status_t UnregisterServer(int server_if) = 0;
virtual bt_status_t AddService(
int server_if, std::vector<btgatt_db_element_t> service) = 0;
diff --git a/service/low_energy_client.cc b/service/low_energy_client.cc
index cb8bcf1..7095619 100644
--- a/service/low_energy_client.cc
+++ b/service/low_energy_client.cc
@@ -218,7 +218,7 @@
const btgatt_client_interface_t* hal_iface =
hal::BluetoothGattInterface::Get()->GetClientHALInterface();
- if (hal_iface->register_client(uuid) != BT_STATUS_SUCCESS) return false;
+ if (hal_iface->register_client(uuid, false) != BT_STATUS_SUCCESS) return false;
pending_calls_[uuid] = callback;
diff --git a/service/test/gatt_client_unittest.cc b/service/test/gatt_client_unittest.cc
index 310e4b9..2552369 100644
--- a/service/test/gatt_client_unittest.cc
+++ b/service/test/gatt_client_unittest.cc
@@ -33,7 +33,7 @@
MockGattHandler() = default;
~MockGattHandler() override = default;
- MOCK_METHOD1(RegisterClient, bt_status_t(const bluetooth::Uuid&));
+ MOCK_METHOD2(RegisterClient, bt_status_t(const bluetooth::Uuid&, bool));
MOCK_METHOD1(UnregisterClient, bt_status_t(int));
MOCK_METHOD1(Scan, bt_status_t(bool));
MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int));
@@ -77,7 +77,7 @@
};
TEST_F(GattClientTest, RegisterInstance) {
- EXPECT_CALL(*mock_handler_, RegisterClient(_))
+ EXPECT_CALL(*mock_handler_, RegisterClient(_, _))
.Times(2)
.WillOnce(Return(BT_STATUS_FAIL))
.WillOnce(Return(BT_STATUS_SUCCESS));
@@ -116,7 +116,7 @@
// Call with a different Uuid while one is pending.
Uuid uuid1 = Uuid::GetRandom();
- EXPECT_CALL(*mock_handler_, RegisterClient(_))
+ EXPECT_CALL(*mock_handler_, RegisterClient(_, _))
.Times(1)
.WillOnce(Return(BT_STATUS_SUCCESS));
EXPECT_TRUE(factory_->RegisterInstance(uuid1, callback));
diff --git a/service/test/gatt_server_unittest.cc b/service/test/gatt_server_unittest.cc
index e19742d..830836a 100644
--- a/service/test/gatt_server_unittest.cc
+++ b/service/test/gatt_server_unittest.cc
@@ -32,7 +32,7 @@
MockGattHandler() = default;
~MockGattHandler() override = default;
- MOCK_METHOD1(RegisterServer, bt_status_t(const bluetooth::Uuid&));
+ MOCK_METHOD2(RegisterServer, bt_status_t(const bluetooth::Uuid&, bool));
MOCK_METHOD1(UnregisterServer, bt_status_t(int));
MOCK_METHOD2(AddService, bt_status_t(int, std::vector<btgatt_db_element_t>));
MOCK_METHOD5(AddCharacteristic,
@@ -223,7 +223,7 @@
static_cast<GattServer*>(in_client.release()));
};
- EXPECT_CALL(*mock_handler_, RegisterServer(_))
+ EXPECT_CALL(*mock_handler_, RegisterServer(_, _))
.Times(1)
.WillOnce(Return(BT_STATUS_SUCCESS));
@@ -298,7 +298,7 @@
};
TEST_F(GattServerTest, RegisterServer) {
- EXPECT_CALL(*mock_handler_, RegisterServer(_))
+ EXPECT_CALL(*mock_handler_, RegisterServer(_, _))
.Times(2)
.WillOnce(Return(BT_STATUS_FAIL))
.WillOnce(Return(BT_STATUS_SUCCESS));
@@ -337,7 +337,7 @@
// Call with a different Uuid while one is pending.
Uuid uuid1 = Uuid::GetRandom();
- EXPECT_CALL(*mock_handler_, RegisterServer(_))
+ EXPECT_CALL(*mock_handler_, RegisterServer(_, _))
.Times(1)
.WillOnce(Return(BT_STATUS_SUCCESS));
EXPECT_TRUE(factory_->RegisterInstance(uuid1, callback));
diff --git a/service/test/low_energy_advertiser_unittest.cc b/service/test/low_energy_advertiser_unittest.cc
index ad76d82..96beceb 100644
--- a/service/test/low_energy_advertiser_unittest.cc
+++ b/service/test/low_energy_advertiser_unittest.cc
@@ -68,6 +68,8 @@
void(int, PeriodicAdvertisingParameters, StatusCallback));
MOCK_METHOD3(SetPeriodicAdvertisingData,
void(int, std::vector<uint8_t>, StatusCallback));
+ MOCK_METHOD3(CreateBIG, void(int, CreateBIGParameters, CreateBIGCallback));
+ MOCK_METHOD4(TerminateBIG, void(int, int, int, TerminateBIGCallback));
MOCK_METHOD3(SetPeriodicAdvertisingEnable, void(int, bool, StatusCallback));
private:
diff --git a/service/test/low_energy_client_unittest.cc b/service/test/low_energy_client_unittest.cc
index ce3c7c0..6478dba 100644
--- a/service/test/low_energy_client_unittest.cc
+++ b/service/test/low_energy_client_unittest.cc
@@ -40,7 +40,7 @@
MockGattHandler(){};
~MockGattHandler() override = default;
- MOCK_METHOD1(RegisterClient, bt_status_t(const bluetooth::Uuid&));
+ MOCK_METHOD2(RegisterClient, bt_status_t(const bluetooth::Uuid&, bool));
MOCK_METHOD1(UnregisterClient, bt_status_t(int));
MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int));
MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int));
@@ -145,7 +145,7 @@
static_cast<LowEnergyClient*>(in_client.release())));
};
- EXPECT_CALL(*mock_handler_, RegisterClient(_))
+ EXPECT_CALL(*mock_handler_, RegisterClient(_, _))
.Times(1)
.WillOnce(Return(BT_STATUS_SUCCESS));
@@ -166,7 +166,7 @@
};
TEST_F(LowEnergyClientTest, RegisterInstance) {
- EXPECT_CALL(*mock_handler_, RegisterClient(_))
+ EXPECT_CALL(*mock_handler_, RegisterClient(_, _))
.Times(2)
.WillOnce(Return(BT_STATUS_FAIL))
.WillOnce(Return(BT_STATUS_SUCCESS));
@@ -205,7 +205,7 @@
// Call with a different Uuid while one is pending.
Uuid uuid1 = Uuid::GetRandom();
- EXPECT_CALL(*mock_handler_, RegisterClient(_))
+ EXPECT_CALL(*mock_handler_, RegisterClient(_, _))
.Times(1)
.WillOnce(Return(BT_STATUS_SUCCESS));
EXPECT_TRUE(ble_factory_->RegisterInstance(uuid1, callback));
diff --git a/service/test/low_energy_scanner_unittest.cc b/service/test/low_energy_scanner_unittest.cc
index 9a7875d..a3999a3 100644
--- a/service/test/low_energy_scanner_unittest.cc
+++ b/service/test/low_energy_scanner_unittest.cc
@@ -51,8 +51,8 @@
FilterParamSetupCallback cb));
MOCK_METHOD2(ScanFilterClear, void(int filt_index, FilterConfigCallback cb));
MOCK_METHOD2(ScanFilterEnable, void(bool enable, EnableCallback cb));
- MOCK_METHOD3(SetScanParameters,
- void(int scan_interval, int scan_window, Callback cb));
+ MOCK_METHOD4(SetScanParameters,
+ void(int scan_phy, std::vector<uint32_t> scan_interval, std::vector<uint32_t> scan_window, Callback cb));
MOCK_METHOD5(BatchscanConfigStorage,
void(int client_if, int batch_scan_full_max,
@@ -71,6 +71,14 @@
StartSyncCb, SyncReportCb, SyncLostCb));
MOCK_METHOD1(StopSync, void(uint16_t));
+ MOCK_METHOD2(CancelCreateSync, void(uint8_t, RawAddress));
+
+ MOCK_METHOD4(TransferSync, void(RawAddress, uint16_t, uint16_t, SyncTransferCb));
+
+ MOCK_METHOD4(TransferSetInfo, void(RawAddress, uint16_t, uint8_t, SyncTransferCb));
+
+ MOCK_METHOD5(SyncTxParameters, void(RawAddress, uint8_t, uint16_t, uint16_t, StartSyncCb));
+
void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters,
FilterConfigCallback cb) override{};
diff --git a/stack/a2dp/a2dp_aac.cc b/stack/a2dp/a2dp_aac.cc
index a7b7218..2e915b0 100644
--- a/stack/a2dp/a2dp_aac.cc
+++ b/stack/a2dp/a2dp_aac.cc
@@ -35,6 +35,7 @@
#include "bt_utils.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
+#include "osi/include/properties.h"
#define A2DP_AAC_DEFAULT_BITRATE 320000 // 320 kbps
#define A2DP_AAC_MIN_BITRATE 64000 // 64 kbps
@@ -50,8 +51,11 @@
btav_a2dp_codec_bits_per_sample_t bits_per_sample;
} tA2DP_AAC_CIE;
+static bool aac_source_caps_configured = false;
+static tA2DP_AAC_CIE a2dp_aac_source_caps = {};
+
/* AAC Source codec capabilities */
-static const tA2DP_AAC_CIE a2dp_aac_source_caps = {
+static const tA2DP_AAC_CIE a2dp_aac_cbr_source_caps = {
// objectType
A2DP_AAC_OBJECT_TYPE_MPEG2_LC,
// sampleRate
@@ -66,6 +70,22 @@
// bits_per_sample
BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16};
+/* AAC Source codec capabilities */
+static const tA2DP_AAC_CIE a2dp_aac_vbr_source_caps = {
+ // objectType
+ A2DP_AAC_OBJECT_TYPE_MPEG2_LC,
+ // sampleRate
+ // TODO: AAC 48.0kHz sampling rate should be added back - see b/62301376
+ A2DP_AAC_SAMPLING_FREQ_44100,
+ // channelMode
+ A2DP_AAC_CHANNEL_MODE_STEREO,
+ // variableBitRateSupport
+ A2DP_AAC_VARIABLE_BIT_RATE_ENABLED,
+ // bitRate
+ A2DP_AAC_DEFAULT_BITRATE,
+ // bits_per_sample
+ BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16};
+
/* AAC Sink codec capabilities */
static const tA2DP_AAC_CIE a2dp_aac_sink_caps = {
// objectType
@@ -708,7 +728,19 @@
const char* A2DP_CodecIndexStrAacSink(void) { return "AAC SINK"; }
+void aac_source_caps_initialize() {
+ if (aac_source_caps_configured) {
+ return;
+ }
+ a2dp_aac_source_caps =
+ osi_property_get_bool("persist.bluetooth.a2dp_aac.vbr_supported", false)
+ ? a2dp_aac_vbr_source_caps
+ : a2dp_aac_cbr_source_caps;
+ aac_source_caps_configured = true;
+}
+
bool A2DP_InitCodecConfigAac(AvdtpSepConfig* p_cfg) {
+ aac_source_caps_initialize();
if (A2DP_BuildInfoAac(AVDT_MEDIA_TYPE_AUDIO, &a2dp_aac_source_caps,
p_cfg->codec_info) != A2DP_SUCCESS) {
return false;
@@ -754,6 +786,7 @@
btav_a2dp_codec_priority_t codec_priority)
: A2dpCodecConfigAacBase(BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
A2DP_CodecIndexStrAac(), codec_priority, true) {
+ aac_source_caps_initialize();
// Compute the local capability
if (a2dp_aac_source_caps.sampleRate & A2DP_AAC_SAMPLING_FREQ_44100) {
codec_local_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
@@ -1036,6 +1069,14 @@
result_config_cie.variableBitRateSupport =
p_a2dp_aac_caps->variableBitRateSupport &
peer_info_cie.variableBitRateSupport;
+ if (result_config_cie.variableBitRateSupport !=
+ A2DP_AAC_VARIABLE_BIT_RATE_DISABLED) {
+ codec_config_.codec_specific_1 =
+ static_cast<int64_t>(AacEncoderBitrateMode::AACENC_BR_MODE_VBR_5);
+ } else {
+ codec_config_.codec_specific_1 =
+ static_cast<int64_t>(AacEncoderBitrateMode::AACENC_BR_MODE_CBR);
+ }
// Set the bit rate as follows:
// 1. If the remote device reports a bogus bit rate
@@ -1308,16 +1349,41 @@
goto fail;
}
- if (A2DP_BuildInfoAac(AVDT_MEDIA_TYPE_AUDIO, &result_config_cie,
- p_result_codec_config) != A2DP_SUCCESS) {
- goto fail;
- }
-
//
// Copy the codec-specific fields if they are not zero
//
- if (codec_user_config_.codec_specific_1 != 0)
- codec_config_.codec_specific_1 = codec_user_config_.codec_specific_1;
+ if (codec_user_config_.codec_specific_1 != 0) {
+ if (result_config_cie.variableBitRateSupport !=
+ A2DP_AAC_VARIABLE_BIT_RATE_DISABLED) {
+ auto user_bitrate_mode = codec_user_config_.codec_specific_1;
+ switch (static_cast<AacEncoderBitrateMode>(user_bitrate_mode)) {
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_C:
+ // VBR is supported, and is disabled by the user preference
+ result_config_cie.variableBitRateSupport =
+ A2DP_AAC_VARIABLE_BIT_RATE_DISABLED;
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_1:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_2:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_3:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_4:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_5:
+ codec_config_.codec_specific_1 = codec_user_config_.codec_specific_1;
+ break;
+ default:
+ codec_config_.codec_specific_1 =
+ static_cast<int64_t>(AacEncoderBitrateMode::AACENC_BR_MODE_VBR_5);
+ }
+ } else {
+ // It is no needed to check the user preference when Variable Bitrate
+ // unsupported by one of source or sink
+ codec_config_.codec_specific_1 =
+ static_cast<int64_t>(AacEncoderBitrateMode::AACENC_BR_MODE_CBR);
+ }
+ }
if (codec_user_config_.codec_specific_2 != 0)
codec_config_.codec_specific_2 = codec_user_config_.codec_specific_2;
if (codec_user_config_.codec_specific_3 != 0)
@@ -1325,6 +1391,11 @@
if (codec_user_config_.codec_specific_4 != 0)
codec_config_.codec_specific_4 = codec_user_config_.codec_specific_4;
+ if (A2DP_BuildInfoAac(AVDT_MEDIA_TYPE_AUDIO, &result_config_cie,
+ p_result_codec_config) != A2DP_SUCCESS) {
+ goto fail;
+ }
+
// Create a local copy of the peer codec capability/config, and the
// result codec config.
if (is_capability) {
@@ -1361,6 +1432,7 @@
tA2DP_AAC_CIE peer_info_cie;
uint8_t channelMode;
uint16_t sampleRate;
+ uint8_t variableBitRateSupport;
const tA2DP_AAC_CIE* p_a2dp_aac_caps =
(is_source_) ? &a2dp_aac_source_caps : &a2dp_aac_sink_caps;
@@ -1413,6 +1485,17 @@
BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
}
+ // Compute the selectable capability - variable bitrate mode
+ variableBitRateSupport = p_a2dp_aac_caps->variableBitRateSupport &
+ peer_info_cie.variableBitRateSupport;
+ if (variableBitRateSupport != A2DP_AAC_VARIABLE_BIT_RATE_DISABLED) {
+ codec_selectable_capability_.codec_specific_1 =
+ static_cast<int64_t>(AacEncoderBitrateMode::AACENC_BR_MODE_VBR_5);
+ } else {
+ codec_selectable_capability_.codec_specific_1 =
+ static_cast<int64_t>(AacEncoderBitrateMode::AACENC_BR_MODE_CBR);
+ }
+
status = A2DP_BuildInfoAac(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie,
ota_codec_peer_capability_);
CHECK(status == A2DP_SUCCESS);
diff --git a/stack/a2dp/a2dp_aac_encoder.cc b/stack/a2dp/a2dp_aac_encoder.cc
index 665bb04..8f32c1f 100644
--- a/stack/a2dp/a2dp_aac_encoder.cc
+++ b/stack/a2dp/a2dp_aac_encoder.cc
@@ -414,7 +414,29 @@
"invalid codec bit rate mode",
__func__);
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
+ // A2DP_AAC_VARIABLE_BIT_RATE_DISABLED is equal to AACENC_BR_MODE_CBR
+ auto bitrate_mode = a2dp_codec_config->getCodecConfig().codec_specific_1;
+ switch (static_cast<AacEncoderBitrateMode>(bitrate_mode)) {
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_1:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_2:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_3:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_4:
+ [[fallthrough]];
+ case AacEncoderBitrateMode::AACENC_BR_MODE_VBR_5:
+ break;
+ default:
+ bitrate_mode =
+ static_cast<int64_t>(AacEncoderBitrateMode::AACENC_BR_MODE_VBR_5);
+ }
+ aac_param_value =
+ static_cast<uint8_t>(bitrate_mode) & ~A2DP_AAC_VARIABLE_BIT_RATE_MASK;
}
+ LOG_INFO(LOG_TAG, "%s: AACENC_BITRATEMODE: %d", __func__, aac_param_value);
aac_error = aacEncoder_SetParam(a2dp_aac_encoder_cb.aac_handle,
AACENC_BITRATEMODE, aac_param_value);
if (aac_error != AACENC_OK) {
@@ -740,6 +762,14 @@
A2dpCodecConfig::debug_codec_dump(fd);
+ auto codec_specific_1 = getCodecConfig().codec_specific_1;
+ dprintf(
+ fd,
+ " AAC bitrate mode : %s "
+ "(0x%" PRIx64 ")\n",
+ ((codec_specific_1 & ~A2DP_AAC_VARIABLE_BIT_RATE_MASK) == 0 ? "Constant"
+ : "Variable"),
+ codec_specific_1);
dprintf(fd,
" Packet counts (expected/dropped) : %zu / "
"%zu\n",
diff --git a/stack/a2dp/a2dp_codec_config.cc b/stack/a2dp/a2dp_codec_config.cc
index edf7e0c..2480cdc 100644
--- a/stack/a2dp/a2dp_codec_config.cc
+++ b/stack/a2dp/a2dp_codec_config.cc
@@ -128,12 +128,16 @@
case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
codec_config = new A2dpCodecConfigAptxHd(codec_priority);
break;
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_ADAPTIVE:
+ break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
codec_config = new A2dpCodecConfigLdacSource(codec_priority);
break;
case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
codec_config = new A2dpCodecConfigLdacSink(codec_priority);
break;
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_TWS:
+ break;
case BTAV_A2DP_CODEC_INDEX_MAX:
break;
}
diff --git a/stack/a2dp/a2dp_vendor.cc b/stack/a2dp/a2dp_vendor.cc
index bcea13d..804fcc9 100644
--- a/stack/a2dp/a2dp_vendor.cc
+++ b/stack/a2dp/a2dp_vendor.cc
@@ -595,10 +595,14 @@
return A2DP_VendorCodecIndexStrAptx();
case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
return A2DP_VendorCodecIndexStrAptxHd();
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_ADAPTIVE:
+ break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
return A2DP_VendorCodecIndexStrLdac();
case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
return A2DP_VendorCodecIndexStrLdacSink();
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_TWS:
+ break;
// Add a switch statement for each vendor-specific codec
case BTAV_A2DP_CODEC_INDEX_MAX:
break;
@@ -620,10 +624,14 @@
return A2DP_VendorInitCodecConfigAptx(p_cfg);
case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
return A2DP_VendorInitCodecConfigAptxHd(p_cfg);
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_ADAPTIVE:
+ break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
return A2DP_VendorInitCodecConfigLdac(p_cfg);
case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
return A2DP_VendorInitCodecConfigLdacSink(p_cfg);
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_TWS:
+ break;
// Add a switch statement for each vendor-specific codec
case BTAV_A2DP_CODEC_INDEX_MAX:
break;
diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc
index 5f195ae..b2b6aa9 100644
--- a/stack/avrc/avrc_pars_tg.cc
+++ b/stack/avrc/avrc_pars_tg.cc
@@ -77,6 +77,8 @@
break;
}
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
+ if (len < 5) return AVRC_STS_INTERNAL_ERR;
+
BE_STREAM_TO_UINT8(p_result->reg_notif.event_id, p);
BE_STREAM_TO_UINT32(p_result->reg_notif.param, p);
diff --git a/stack/btm/btm_acl.cc b/stack/btm/btm_acl.cc
index e132f6f..2c7bebd 100644
--- a/stack/btm/btm_acl.cc
+++ b/stack/btm/btm_acl.cc
@@ -746,7 +746,8 @@
*settings);
}
if ((*settings & HCI_ENABLE_SNIFF_MODE) &&
- (!HCI_SNIFF_MODE_SUPPORTED(localFeatures))) {
+ ((!HCI_SNIFF_MODE_SUPPORTED(localFeatures)) ||
+ interop_match_addr(INTEROP_DISABLE_SNIFF, &remote_bda))) {
*settings &= (~HCI_ENABLE_SNIFF_MODE);
BTM_TRACE_API("BTM_SetLinkPolicy sniff not supported (settings: 0x%04x)",
*settings);
diff --git a/stack/btm/btm_pm.cc b/stack/btm/btm_pm.cc
index 793c854..60d5b06 100644
--- a/stack/btm/btm_pm.cc
+++ b/stack/btm/btm_pm.cc
@@ -42,6 +42,7 @@
#include "btm_int.h"
#include "btm_int_types.h"
#include "btu.h"
+#include "device/include/interop.h"
#include "hcidefs.h"
#include "hcimsgs.h"
#include "l2c_int.h"
@@ -177,7 +178,8 @@
/* check if the requested mode is supported */
ind = mode - BTM_PM_MD_HOLD; /* make it base 0 */
p_features = BTM_ReadLocalFeatures();
- if (!(p_features[btm_pm_mode_off[ind]] & btm_pm_mode_msk[ind])) {
+ if (!(p_features[btm_pm_mode_off[ind]] & btm_pm_mode_msk[ind]) ||
+ interop_match_addr(INTEROP_DISABLE_SNIFF, &remote_bda)) {
LOG(ERROR) << __func__ << ": pm_id " << unsigned(pm_id) << " mode "
<< unsigned(mode) << " is not supported for " << remote_bda;
return BTM_MODE_UNSUPPORTED;
diff --git a/stack/include/a2dp_aac_encoder.h b/stack/include/a2dp_aac_encoder.h
index 143a577..5e909d8 100644
--- a/stack/include/a2dp_aac_encoder.h
+++ b/stack/include/a2dp_aac_encoder.h
@@ -21,8 +21,29 @@
#ifndef A2DP_AAC_ENCODER_H
#define A2DP_AAC_ENCODER_H
+#include "a2dp_aac_constants.h"
#include "a2dp_codec_api.h"
+// Is used in btav_a2dp_codec_config_t.codec_specific_1 when codec is AAC
+enum class AacEncoderBitrateMode : int64_t {
+ // Variable bitrate mode unsupported when used in a codec report, and upper
+ // layer can use this value as system default (keep current settings)
+ AACENC_BR_MODE_CBR = A2DP_AAC_VARIABLE_BIT_RATE_DISABLED,
+ // Constant bitrate mode when Variable bitrate mode is supported. This can
+ // also be used to disable Variable bitrate mode by upper layer
+ AACENC_BR_MODE_VBR_C = (A2DP_AAC_VARIABLE_BIT_RATE_ENABLED | 0x00),
+ // Variable bitrate mode (very low bitrate for software encoding).
+ AACENC_BR_MODE_VBR_1 = (A2DP_AAC_VARIABLE_BIT_RATE_ENABLED | 0x01),
+ // Variable bitrate mode (low bitrate for software encoding).
+ AACENC_BR_MODE_VBR_2 = (A2DP_AAC_VARIABLE_BIT_RATE_ENABLED | 0x02),
+ // Variable bitrate mode (medium bitrate for software encoding).
+ AACENC_BR_MODE_VBR_3 = (A2DP_AAC_VARIABLE_BIT_RATE_ENABLED | 0x03),
+ // Variable bitrate mode (high bitrate for software encoding).
+ AACENC_BR_MODE_VBR_4 = (A2DP_AAC_VARIABLE_BIT_RATE_ENABLED | 0x04),
+ // Variable bitrate mode (very high bitrate for software encoding).
+ AACENC_BR_MODE_VBR_5 = (A2DP_AAC_VARIABLE_BIT_RATE_ENABLED | 0x05),
+};
+
// Loads the A2DP AAC encoder.
// Return true on success, otherwise false.
bool A2DP_LoadEncoderAac(void);
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index 50bcfeb..2009dda 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -29,6 +29,8 @@
#include "bt_common.h"
#include "bt_types.h"
+#include "avrc_defs.h"
+#include "device/include/interop.h"
#include "osi/include/osi.h"
#include "sdp_api.h"
#include "sdpint.h"
@@ -552,6 +554,7 @@
tSDP_RECORD* p_rec;
tSDP_ATTR_SEQ attr_seq, attr_seq_sav;
tSDP_ATTRIBUTE* p_attr;
+ tSDP_ATTRIBUTE attr_sav;
bool maxxed_out = false, is_cont = false;
uint8_t* p_seq_start;
uint16_t seq_len, attr_len;
@@ -650,6 +653,19 @@
attr_seq.attr_entry[xx].end);
if (p_attr) {
+ // Check if the attribute contain AVRCP profile description list
+ uint16_t avrcp_version = sdpu_is_avrcp_profile_description_list(p_attr);
+ if (avrcp_version > AVRC_REV_1_4 &&
+ interop_match_addr(INTEROP_AVRCP_1_4_ONLY,
+ &(p_ccb->device_address))) {
+ SDP_TRACE_DEBUG(
+ "%s, device=%s is only accept AVRCP 1.4, reply AVRCP 1.4 "
+ "instead.",
+ __func__, p_ccb->device_address.ToString().c_str());
+ memcpy(&attr_sav, p_attr, sizeof(tSDP_ATTRIBUTE));
+ attr_sav.value_ptr[attr_sav.len - 1] = 0x04;
+ p_attr = &attr_sav;
+ }
/* Check if attribute fits. Assume 3-byte value type/length */
rem_len = max_list_len - (int16_t)(p_rsp - &p_ccb->rsp_list[0]);
@@ -829,5 +845,4 @@
/* Send the buffer through L2CAP */
L2CA_DataWrite(p_ccb->connection_id, p_buf);
}
-
#endif /* SDP_SERVER_ENABLED == TRUE */
diff --git a/stack/sdp/sdp_utils.cc b/stack/sdp/sdp_utils.cc
index f66a8fd..f8cde2c 100644
--- a/stack/sdp/sdp_utils.cc
+++ b/stack/sdp/sdp_utils.cc
@@ -31,6 +31,7 @@
#include "bt_types.h"
#include "btif_config.h"
+#include "avrc_defs.h"
#include "sdp_api.h"
#include "sdpint.h"
@@ -1155,3 +1156,41 @@
osi_free(p_attr_buff);
return p_out;
}
+/*******************************************************************************
+ *
+ * Function sdpu_is_avrcp_profile_description_list
+ *
+ * Description This function is to check if attirbute contain AVRCP profile
+ * description list
+ *
+ * p_attr: attibute to be check
+ *
+ * Returns AVRCP profile version if matched, else 0
+ *
+ ******************************************************************************/
+uint16_t sdpu_is_avrcp_profile_description_list(tSDP_ATTRIBUTE* p_attr) {
+ if (p_attr->id != ATTR_ID_BT_PROFILE_DESC_LIST || p_attr->len != 8) {
+ return 0;
+ }
+
+ uint8_t* p_uuid = p_attr->value_ptr + 3;
+ // Check if AVRCP profile UUID
+ if (p_uuid[0] != 0x11 || p_uuid[1] != 0xe) {
+ return 0;
+ }
+ uint8_t p_version = *(p_uuid + 4);
+ switch (p_version) {
+ case 0x0:
+ return AVRC_REV_1_0;
+ case 0x3:
+ return AVRC_REV_1_3;
+ case 0x4:
+ return AVRC_REV_1_4;
+ case 0x5:
+ return AVRC_REV_1_5;
+ case 0x6:
+ return AVRC_REV_1_6;
+ default:
+ return 0;
+ }
+}
diff --git a/stack/sdp/sdpint.h b/stack/sdp/sdpint.h
index af9ccb8..ea6941c 100644
--- a/stack/sdp/sdpint.h
+++ b/stack/sdp/sdpint.h
@@ -235,6 +235,7 @@
extern uint8_t* sdpu_build_partial_attrib_entry(uint8_t* p_out,
tSDP_ATTRIBUTE* p_attr,
uint16_t len, uint16_t* offset);
+extern uint16_t sdpu_is_avrcp_profile_description_list(tSDP_ATTRIBUTE* p_attr);
/* Functions provided by sdp_db.cc
*/
diff --git a/stack/smp/smp_br_main.cc b/stack/smp/smp_br_main.cc
index b06055f..2f5fe76 100644
--- a/stack/smp/smp_br_main.cc
+++ b/stack/smp/smp_br_main.cc
@@ -303,7 +303,6 @@
tSMP_BR_STATE curr_state = p_cb->br_state;
tSMP_BR_SM_TBL state_table;
uint8_t action, entry;
- tSMP_BR_ENTRY_TBL entry_table = smp_br_entry_table[p_cb->role];
SMP_TRACE_EVENT("main %s", __func__);
if (curr_state >= SMP_BR_STATE_MAX) {
@@ -317,6 +316,8 @@
return;
}
+ tSMP_BR_ENTRY_TBL entry_table = smp_br_entry_table[p_cb->role];
+
SMP_TRACE_DEBUG("SMP Role: %s State: [%s (%d)], Event: [%s (%d)]",
(p_cb->role == HCI_ROLE_SLAVE) ? "Slave" : "Master",
smp_get_br_state_name(p_cb->br_state), p_cb->br_state,
diff --git a/stack/test/stack_a2dp_test.cc b/stack/test/stack_a2dp_test.cc
index fecb3ca..bfe20c1 100644
--- a/stack/test/stack_a2dp_test.cc
+++ b/stack/test/stack_a2dp_test.cc
@@ -172,6 +172,8 @@
static const char* APTX_ENCODER_LIB_NAME = "libaptX_encoder.so";
static const char* APTX_HD_ENCODER_LIB_NAME = "libaptXHD_encoder.so";
+static const char* APTX_ADAPTIVE_ENCODER_LIB_NAME = "libaptXAdaptive_encoder.so";
+static const char* APTX_TWS_ENCODER_LIB_NAME = "libaptXTws_encoder.so";
static const char* LDAC_ENCODER_LIB_NAME = "libldacBT_enc.so";
static const char* LDAC_DECODER_LIB_NAME = "libldacBT_dec.so";
@@ -213,11 +215,21 @@
// shared library installed.
supported = has_shared_library(APTX_HD_ENCODER_LIB_NAME);
break;
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_ADAPTIVE:
+ // Codec aptX-HD is supported only if the device has the corresponding
+ // shared library installed.
+ supported = has_shared_library(APTX_ADAPTIVE_ENCODER_LIB_NAME);
+ break;
case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
// Codec LDAC is supported only if the device has the corresponding
// shared library installed.
supported = has_shared_library(LDAC_ENCODER_LIB_NAME);
break;
+ case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_TWS:
+ // Codec aptX-TWS is supported only if the device has the corresponding
+ // shared library installed.
+ supported = has_shared_library(APTX_TWS_ENCODER_LIB_NAME);
+ break;
case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
supported = true;
break;
diff --git a/test/rootcanal/bluetooth_hci.cc b/test/rootcanal/bluetooth_hci.cc
index 908554b..963f1a7 100644
--- a/test/rootcanal/bluetooth_hci.cc
+++ b/test/rootcanal/bluetooth_hci.cc
@@ -112,8 +112,11 @@
hidl_vec<uint8_t> hci_event(packet->begin(), packet->end());
auto ret = cb->hciEventReceived(hci_event);
if (!ret.isOk()) {
- CHECK(death_recipient_->getHasDied())
- << "Error sending event callback, but no death notification.";
+ LOG_ERROR("Error sending event callback");
+ if (!death_recipient_->getHasDied()) {
+ LOG_ERROR("Closing");
+ close();
+ }
}
});
@@ -122,8 +125,11 @@
hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end());
auto ret = cb->aclDataReceived(acl_packet);
if (!ret.isOk()) {
- CHECK(death_recipient_->getHasDied())
- << "Error sending acl callback, but no death notification.";
+ LOG_ERROR("Error sending acl callback");
+ if (!death_recipient_->getHasDied()) {
+ LOG_ERROR("Closing");
+ close();
+ }
}
});
@@ -132,8 +138,11 @@
hidl_vec<uint8_t> sco_packet(packet->begin(), packet->end());
auto ret = cb->aclDataReceived(sco_packet);
if (!ret.isOk()) {
- CHECK(death_recipient_->getHasDied())
- << "Error sending sco callback, but no death notification.";
+ LOG_ERROR("Error sending sco callback");
+ if (!death_recipient_->getHasDied()) {
+ LOG_ERROR("Closing");
+ close();
+ }
}
});
@@ -143,8 +152,11 @@
hidl_vec<uint8_t> iso_packet(packet->begin(), packet->end());
auto ret = cb_1_1->isoDataReceived(iso_packet);
if (!ret.isOk()) {
- CHECK(death_recipient_->getHasDied())
- << "Error sending iso callback, but no death notification.";
+ LOG_ERROR("Error sending iso callback");
+ if (!death_recipient_->getHasDied()) {
+ LOG_ERROR("Closing");
+ close();
+ }
}
});
}
diff --git a/test/suite/gatt/gatt_unittest.cc b/test/suite/gatt/gatt_unittest.cc
index b02c96a..e91e7f6 100644
--- a/test/suite/gatt/gatt_unittest.cc
+++ b/test/suite/gatt/gatt_unittest.cc
@@ -27,7 +27,7 @@
TEST_F(GattTest, GattClientRegister) {
// Registers gatt client.
bluetooth::Uuid gatt_client_uuid = bluetooth::Uuid::GetRandom();
- gatt_client_interface()->register_client(gatt_client_uuid);
+ gatt_client_interface()->register_client(gatt_client_uuid, false);
semaphore_wait(register_client_callback_sem_);
EXPECT_TRUE(status() == BT_STATUS_SUCCESS)
<< "Error registering GATT client app callback.";
@@ -39,7 +39,7 @@
TEST_F(GattTest, GattServerRegister) {
// Registers gatt server.
bluetooth::Uuid gatt_server_uuid = bluetooth::Uuid::GetRandom();
- gatt_server_interface()->register_server(gatt_server_uuid);
+ gatt_server_interface()->register_server(gatt_server_uuid, false);
semaphore_wait(register_server_callback_sem_);
EXPECT_TRUE(status() == BT_STATUS_SUCCESS)
<< "Error registering GATT server app callback.";
@@ -51,7 +51,7 @@
TEST_F(GattTest, GattServerBuild) {
// Registers gatt server.
bluetooth::Uuid gatt_server_uuid = bluetooth::Uuid::GetRandom();
- gatt_server_interface()->register_server(gatt_server_uuid);
+ gatt_server_interface()->register_server(gatt_server_uuid, false);
semaphore_wait(register_server_callback_sem_);
EXPECT_TRUE(status() == BT_STATUS_SUCCESS)
<< "Error registering GATT server app callback.";