diff options
-rw-r--r-- | system/bta/has/has_client.cc | 15 | ||||
-rw-r--r-- | system/bta/has/has_client_test.cc | 94 | ||||
-rw-r--r-- | system/bta/has/has_ctp.cc | 11 | ||||
-rw-r--r-- | system/bta/has/has_ctp.h | 14 | ||||
-rw-r--r-- | system/bta/has/has_types.h | 10 |
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 { |