summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/bta/has/has_client.cc15
-rw-r--r--system/bta/has/has_client_test.cc94
-rw-r--r--system/bta/has/has_ctp.cc11
-rw-r--r--system/bta/has/has_ctp.h14
-rw-r--r--system/bta/has/has_types.h10
5 files changed, 73 insertions, 71 deletions
diff --git a/system/bta/has/has_client.cc b/system/bta/has/has_client.cc
index 044713437f..875a41c2a1 100644
--- a/system/bta/has/has_client.cc
+++ b/system/bta/has/has_client.cc
@@ -395,7 +395,7 @@ class HasClientImpl : public HasClient {
}
auto op = op_opt.value();
- if (op.opcode == PresetCtpOpcode::READ_PRESET_BY_INDEX) {
+ if (op.opcode == PresetCtpOpcode::READ_PRESETS) {
callbacks_->OnPresetInfoError(device->addr, op.index,
GattStatus2SvcErrorCode(status));
@@ -588,7 +588,7 @@ class HasClientImpl : public HasClient {
if (status != ErrorCode::NO_ERROR) {
switch (operation.opcode) {
- case PresetCtpOpcode::READ_PRESET_BY_INDEX:
+ case PresetCtpOpcode::READ_PRESETS:
LOG_ASSERT(
std::holds_alternative<RawAddress>(operation.addr_or_group))
<< " Unsupported group operation!";
@@ -837,8 +837,8 @@ class HasClientImpl : public HasClient {
.available = preset->IsAvailable(),
.preset_name = preset->GetName()}});
} else {
- CpPresetIndexOperation(HasCtpOp(
- address, PresetCtpOpcode::READ_PRESET_BY_INDEX, preset_index));
+ CpPresetIndexOperation(
+ HasCtpOp(address, PresetCtpOpcode::READ_PRESETS, preset_index));
}
}
@@ -849,7 +849,7 @@ class HasClientImpl : public HasClient {
CpWritePresetNameOperation(HasCtpOp(addr_or_group_id,
PresetCtpOpcode::WRITE_PRESET_NAME,
- preset_index, name));
+ preset_index, 1 /* Don't care */, name));
}
void CleanUp() {
@@ -1662,8 +1662,9 @@ class HasClientImpl : public HasClient {
ccc_val);
/* Get all the presets */
- CpReadAllPresetsOperation(
- HasCtpOp(device->addr, PresetCtpOpcode::READ_ALL_PRESETS));
+ CpReadAllPresetsOperation(HasCtpOp(
+ device->addr, PresetCtpOpcode::READ_PRESETS,
+ le_audio::has::kStartPresetIndex, le_audio::has::kMaxNumOfPresets));
/* Read the current active preset index */
BtaGattQueue::ReadCharacteristic(
diff --git a/system/bta/has/has_client_test.cc b/system/bta/has/has_client_test.cc
index 571686981c..0c28ad7476 100644
--- a/system/bta/has/has_client_test.cc
+++ b/system/bta/has/has_client_test.cc
@@ -319,7 +319,7 @@ class HasClientTestBase : public ::testing::Test {
void* cb_data) {
auto pp = value.data();
auto len = value.size();
- uint8_t op, index;
+ uint8_t op, index, num_of_indices;
const bool indicate = false;
@@ -344,25 +344,21 @@ class HasClientTestBase : public ::testing::Test {
}
switch (static_cast<::le_audio::has::PresetCtpOpcode>(op)) {
- case ::le_audio::has::PresetCtpOpcode::READ_ALL_PRESETS:
- ASSERT_EQ(0u, len);
- InjectNotifyReadPresetsResponse(conn_id, address, handle, value,
- indicate, -1, cb, cb_data);
- break;
-
- case ::le_audio::has::PresetCtpOpcode::READ_PRESET_BY_INDEX:
- if (len < 1) {
+ case ::le_audio::has::PresetCtpOpcode::READ_PRESETS:
+ if (len < 2) {
if (cb)
cb(conn_id, GATT_INVALID_ATTR_LEN, handle, value.size(),
value.data(), cb_data);
} else {
STREAM_TO_UINT8(index, pp);
- --len;
+ STREAM_TO_UINT8(num_of_indices, pp);
+ len -= 2;
ASSERT_EQ(0u, len);
InjectNotifyReadPresetsResponse(conn_id, address, handle, value,
- indicate, index, cb, cb_data);
+ indicate, index, num_of_indices,
+ cb, cb_data);
}
break;
@@ -949,38 +945,43 @@ class HasClientTestBase : public ::testing::Test {
value, indicate);
}
- void InjectNotifyReadPresetsResponse(uint16_t conn_id,
- RawAddress const& address,
- uint16_t handle,
- std::vector<uint8_t> value,
- bool indicate, int index,
- GATT_WRITE_OP_CB cb, void* cb_data) {
+ void InjectNotifyReadPresetsResponse(
+ uint16_t conn_id, RawAddress const& address, uint16_t handle,
+ std::vector<uint8_t> value, bool indicate, int index, int num_of_indices,
+ GATT_WRITE_OP_CB cb, void* cb_data) {
auto presets = current_peer_presets_.at(conn_id);
LOG_ASSERT(!presets.empty()) << __func__ << " Mocking error!";
- if (index == -1) {
+ /* Index is a start index, not necessary is a valid index for the
+ * peer device */
+ auto preset = presets.find(index);
+ while (preset == presets.end() &&
+ index++ <= ::le_audio::has::kMaxNumOfPresets) {
+ preset = presets.find(index);
+ }
+
+ if (preset == presets.end()) {
+ /* operation not possible */
if (cb)
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data);
- /* Notify all presets */
- for (auto preset = presets.begin(); preset != presets.end(); preset++) {
- InjectNotifyReadPresetResponse(conn_id, address, handle, *preset,
- indicate,
- (preset == std::prev(presets.end())));
- }
- } else {
- auto preset = presets.find(index);
- if (preset != presets.end()) {
- if (cb)
- cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
- cb_data);
- InjectNotifyReadPresetResponse(conn_id, address, handle, *preset,
- indicate, true);
- } else {
- /* operation not possible */
- if (cb)
- cb(conn_id, (tGATT_STATUS)0x83, handle, value.size(), value.data(),
- cb_data);
- }
+ cb(conn_id, (tGATT_STATUS)0x83, handle, value.size(), value.data(),
+ cb_data);
+
+ return;
+ }
+
+ if (cb)
+ cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data);
+ /* Notify presets */
+ int num_of_notif = 1;
+ while (1) {
+ bool last =
+ preset == std::prev(presets.end()) || num_of_notif == num_of_indices;
+ InjectNotifyReadPresetResponse(conn_id, address, handle, *preset,
+ indicate, (last));
+ if (last) return;
+
+ num_of_notif++;
+ preset++;
}
}
@@ -3023,8 +3024,7 @@ TEST_F(HasTypesTest, test_group_op_coordinator_init) {
EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
HasCtpGroupOpCoordinator wrapper(
{address1, address2},
- HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESET_BY_INDEX,
- 6));
+ HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESETS, 6));
ASSERT_EQ(2u, wrapper.ref_cnt);
EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(1);
@@ -3043,12 +3043,10 @@ TEST_F(HasTypesTest, test_group_op_coordinator_copy) {
EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
HasCtpGroupOpCoordinator wrapper(
{address1, address2},
- HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESET_BY_INDEX,
- 6));
+ HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESETS, 6));
HasCtpGroupOpCoordinator wrapper2(
{address1},
- HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESET_BY_INDEX,
- 6));
+ HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESETS, 6));
ASSERT_EQ(3u, wrapper.ref_cnt);
HasCtpGroupOpCoordinator wrapper3 = wrapper2;
auto* wrapper4 =
@@ -3076,12 +3074,10 @@ TEST_F(HasTypesTest, test_group_op_coordinator_completion) {
EXPECT_CALL(*AlarmMock::Get(), AlarmNew(_)).Times(1);
HasCtpGroupOpCoordinator wrapper(
{address1, address3},
- HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESET_BY_INDEX,
- 6));
+ HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESETS, 6));
HasCtpGroupOpCoordinator wrapper2(
{address2},
- HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESET_BY_INDEX,
- 6));
+ HasCtpOp(0x01, ::le_audio::has::PresetCtpOpcode::READ_PRESETS, 6));
ASSERT_EQ(3u, wrapper.ref_cnt);
EXPECT_CALL(*AlarmMock::Get(), AlarmFree(_)).Times(0);
diff --git a/system/bta/has/has_ctp.cc b/system/bta/has/has_ctp.cc
index 1b88dcadfb..940a494df8 100644
--- a/system/bta/has/has_ctp.cc
+++ b/system/bta/has/has_ctp.cc
@@ -138,14 +138,14 @@ std::vector<uint8_t> HasCtpOp::ToCharacteristicValue() const {
auto* pp = value.data();
switch (opcode) {
- case PresetCtpOpcode::READ_ALL_PRESETS:
- value.resize(1);
+ case PresetCtpOpcode::READ_PRESETS:
+ value.resize(3);
pp = value.data();
UINT8_TO_STREAM(
pp, static_cast<std::underlying_type_t<PresetCtpOpcode>>(opcode));
+ UINT8_TO_STREAM(pp, index);
+ UINT8_TO_STREAM(pp, num_of_indices);
break;
-
- case PresetCtpOpcode::READ_PRESET_BY_INDEX:
case PresetCtpOpcode::SET_ACTIVE_PRESET:
case PresetCtpOpcode::SET_ACTIVE_PRESET_SYNC:
value.resize(2);
@@ -206,8 +206,7 @@ std::ostream& operator<<(std::ostream& out, const PresetCtpChangeId value) {
std::ostream& operator<<(std::ostream& out, const PresetCtpOpcode value) {
const char* ch = 0;
switch (value) {
- CASE_SET_PTR_TO_TOKEN_STR(PresetCtpOpcode::READ_ALL_PRESETS);
- CASE_SET_PTR_TO_TOKEN_STR(PresetCtpOpcode::READ_PRESET_BY_INDEX);
+ CASE_SET_PTR_TO_TOKEN_STR(PresetCtpOpcode::READ_PRESETS);
CASE_SET_PTR_TO_TOKEN_STR(PresetCtpOpcode::READ_PRESET_RESPONSE);
CASE_SET_PTR_TO_TOKEN_STR(PresetCtpOpcode::PRESET_CHANGED);
CASE_SET_PTR_TO_TOKEN_STR(PresetCtpOpcode::WRITE_PRESET_NAME);
diff --git a/system/bta/has/has_ctp.h b/system/bta/has/has_ctp.h
index 38cfe45514..963a23c7b1 100644
--- a/system/bta/has/has_ctp.h
+++ b/system/bta/has/has_ctp.h
@@ -41,8 +41,7 @@ std::ostream& operator<<(std::ostream& out, const PresetCtpChangeId value);
/* HAS control point Opcodes */
enum class PresetCtpOpcode : uint8_t {
- READ_ALL_PRESETS = 0,
- READ_PRESET_BY_INDEX,
+ READ_PRESETS = 1,
READ_PRESET_RESPONSE,
PRESET_CHANGED,
WRITE_PRESET_NAME,
@@ -67,8 +66,7 @@ static constexpr uint16_t PresetCtpOpcode2Bitmask(PresetCtpOpcode op) {
/* Mandatory opcodes if control point characteristic exists */
static constexpr uint16_t kControlPointMandatoryOpcodesBitmask =
- PresetCtpOpcode2Bitmask(PresetCtpOpcode::READ_ALL_PRESETS) |
- PresetCtpOpcode2Bitmask(PresetCtpOpcode::READ_PRESET_BY_INDEX) |
+ PresetCtpOpcode2Bitmask(PresetCtpOpcode::READ_PRESETS) |
PresetCtpOpcode2Bitmask(PresetCtpOpcode::SET_ACTIVE_PRESET) |
PresetCtpOpcode2Bitmask(PresetCtpOpcode::SET_NEXT_PRESET) |
PresetCtpOpcode2Bitmask(PresetCtpOpcode::SET_PREV_PRESET);
@@ -100,13 +98,19 @@ struct HasCtpOp {
std::variant<RawAddress, int> addr_or_group;
PresetCtpOpcode opcode;
uint8_t index;
+ uint8_t num_of_indices;
std::optional<std::string> name;
uint16_t op_id;
HasCtpOp(std::variant<RawAddress, int> addr_or_group_id, PresetCtpOpcode op,
uint8_t index = bluetooth::has::kHasPresetIndexInvalid,
+ uint8_t num_of_indices = 1,
std::optional<std::string> name = std::nullopt)
- : addr_or_group(addr_or_group_id), opcode(op), index(index), name(name) {
+ : addr_or_group(addr_or_group_id),
+ opcode(op),
+ index(index),
+ num_of_indices(num_of_indices),
+ name(name) {
/* Skip 0 on roll-over */
last_op_id_ += 1;
if (last_op_id_ == 0) last_op_id_ = 1;
diff --git a/system/bta/has/has_types.h b/system/bta/has/has_types.h
index d726f07cf7..e7d691deab 100644
--- a/system/bta/has/has_types.h
+++ b/system/bta/has/has_types.h
@@ -70,15 +70,17 @@ union HasGattOpContext {
static_assert(sizeof(HasGattOpContext) <= sizeof(void*));
/* Service UUIDs */
-/* FIXME: actually these were not yet assigned - using placeholders for now. */
static const bluetooth::Uuid kUuidHearingAccessService =
bluetooth::Uuid::From16Bit(0x1854);
static const bluetooth::Uuid kUuidHearingAidFeatures =
- bluetooth::Uuid::From16Bit(0xEEED);
+ bluetooth::Uuid::From16Bit(0x2BDA);
static const bluetooth::Uuid kUuidHearingAidPresetControlPoint =
- bluetooth::Uuid::From16Bit(0xEEEC);
+ bluetooth::Uuid::From16Bit(0x2BDB);
static const bluetooth::Uuid kUuidActivePresetIndex =
- bluetooth::Uuid::From16Bit(0xEEEB);
+ bluetooth::Uuid::From16Bit(0x2BDC);
+
+static const uint8_t kStartPresetIndex = 1;
+static const uint8_t kMaxNumOfPresets = 255;
/* Base device class for the GATT-based service clients */
class GattServiceDevice {