void set_parameters(AdvertiserId advertiser_id, ExtendedAdvertisingConfig config) {
switch (advertising_api_type_) {
case (AdvertisingApiType::LEGACY): {
- // TODO
+ le_advertising_interface_->EnqueueCommand(
+ hci::LeSetAdvertisingParametersBuilder::Create(
+ config.interval_min,
+ config.interval_max,
+ config.advertising_type,
+ config.own_address_type,
+ config.peer_address_type,
+ config.peer_address,
+ config.channel_map,
+ config.filter_policy),
+ module_handler_->BindOnceOn(
+ this, &impl::check_status_with_id<LeSetAdvertisingParametersCompleteView>, advertiser_id));
} break;
case (AdvertisingApiType::ANDROID_HCI): {
// TODO
void set_data(AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data) {
switch (advertising_api_type_) {
case (AdvertisingApiType::LEGACY): {
- // TODO
+ if (set_scan_rsp) {
+ le_advertising_interface_->EnqueueCommand(
+ hci::LeSetScanResponseDataBuilder::Create(data),
+ module_handler_->BindOnceOn(
+ this, &impl::check_status_with_id<LeSetScanResponseDataCompleteView>, advertiser_id));
+ } else {
+ le_advertising_interface_->EnqueueCommand(
+ hci::LeSetAdvertisingDataBuilder::Create(data),
+ module_handler_->BindOnceOn(
+ this, &impl::check_status_with_id<LeSetAdvertisingDataCompleteView>, advertiser_id));
+ }
} break;
case (AdvertisingApiType::ANDROID_HCI): {
// TODO
switch (advertising_api_type_) {
case (AdvertisingApiType::LEGACY): {
- // TODO
+ le_advertising_interface_->EnqueueCommand(
+ hci::LeSetAdvertisingEnableBuilder::Create(Enable::DISABLED),
+ module_handler_->BindOnceOn(
+ this,
+ &impl::on_set_advertising_enable_complete<LeSetAdvertisingEnableCompleteView>,
+ enable,
+ enabled_sets));
} break;
case (AdvertisingApiType::ANDROID_HCI): {
// TODO
return;
}
for (EnabledSet enabled_set : enabled_sets) {
+ bool started = advertising_sets_[enabled_set.advertising_handle_].started;
uint8_t id = enabled_set.advertising_handle_;
if (id == kInvalidHandle) {
continue;
}
- advertising_callbacks_->OnAdvertisingEnabled(id, enable, advertising_status);
+
+ if (started) {
+ advertising_callbacks_->OnAdvertisingEnabled(id, enable, advertising_status);
+ } else {
+ int reg_id = id_map_[id];
+ advertising_sets_[enabled_set.advertising_handle_].started = true;
+ // TODO read tx power
+ advertising_callbacks_->OnAdvertisingSetStarted(reg_id, id, 0x00, advertising_status);
+ }
}
}
OpCode opcode = view.GetCommandOpCode();
switch (opcode) {
+ case OpCode::LE_SET_ADVERTISING_PARAMETERS:
+ // TODO read tx power
+ advertising_callbacks_->OnAdvertisingParametersUpdated(id, 0x00, advertising_status);
+ break;
case OpCode::LE_SET_ADVERTISING_DATA:
case OpCode::LE_SET_EXTENDED_ADVERTISING_DATA:
advertising_callbacks_->OnAdvertisingDataSet(id, advertising_status);
} mock_advertising_callback_;
};
+class LeAdvertisingAPITest : public LeAdvertisingManagerTest {
+ protected:
+ void SetUp() override {
+ LeAdvertisingManagerTest::SetUp();
+
+ // start advertising set
+ ExtendedAdvertisingConfig advertising_config{};
+ advertising_config.advertising_type = AdvertisingType::ADV_IND;
+ advertising_config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
+ std::vector<GapData> gap_data{};
+ GapData data_item{};
+ data_item.data_type_ = GapDataType::FLAGS;
+ data_item.data_ = {0x34};
+ gap_data.push_back(data_item);
+ data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+ data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+ gap_data.push_back(data_item);
+ advertising_config.advertisement = gap_data;
+ advertising_config.scan_response = gap_data;
+
+ auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE);
+ advertiser_id_ = le_advertising_manager_->ExtendedCreateAdvertiser(
+ 0x00, advertising_config, scan_callback, set_terminated_callback, client_handler_);
+ ASSERT_NE(LeAdvertisingManager::kInvalidId, advertiser_id_);
+ EXPECT_CALL(
+ mock_advertising_callback_,
+ OnAdvertisingSetStarted(0x00, advertiser_id_, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+ std::vector<OpCode> adv_opcodes = {
+ OpCode::LE_SET_ADVERTISING_PARAMETERS,
+ OpCode::LE_SET_SCAN_RESPONSE_DATA,
+ OpCode::LE_SET_ADVERTISING_DATA,
+ OpCode::LE_SET_ADVERTISING_ENABLE,
+ };
+ auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+ std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS)};
+ ASSERT_EQ(std::future_status::ready, result);
+ for (size_t i = 0; i < adv_opcodes.size(); i++) {
+ auto packet_view = test_hci_layer_->GetCommandPacket(adv_opcodes[i]);
+ CommandPacketView command_packet_view = CommandPacketView::Create(packet_view);
+ auto command = ConnectionManagementCommandView::Create(AclCommandView::Create(command_packet_view));
+ test_hci_layer_->IncomingEvent(
+ CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique<RawBuilder>(success_vector)));
+ }
+ sync_client_handler();
+ }
+
+ AdvertiserId advertiser_id_;
+};
+
class LeAndroidHciAdvertisingManagerTest : public LeAdvertisingManagerTest {
protected:
void SetUp() override {
OpCode::LE_SET_ADVERTISING_ENABLE,
};
EXPECT_CALL(
- mock_advertising_callback_, OnAdvertisingEnabled(id, true, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+ mock_advertising_callback_,
+ OnAdvertisingSetStarted(0x00, id, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS));
std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS)};
auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
sync_client_handler();
}
+TEST_F(LeAdvertisingAPITest, startup_teardown) {}
+
TEST_F(LeExtendedAdvertisingAPITest, startup_teardown) {}
+TEST_F(LeAdvertisingAPITest, set_parameter) {
+ ExtendedAdvertisingConfig advertising_config{};
+ advertising_config.advertising_type = AdvertisingType::ADV_IND;
+ advertising_config.own_address_type = OwnAddressType::PUBLIC_DEVICE_ADDRESS;
+ std::vector<GapData> gap_data{};
+ GapData data_item{};
+ data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+ data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+ gap_data.push_back(data_item);
+ advertising_config.advertisement = gap_data;
+ advertising_config.channel_map = 1;
+ le_advertising_manager_->SetParameters(advertiser_id_, advertising_config);
+ auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_PARAMETERS);
+ auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+ ASSERT_EQ(std::future_status::ready, result);
+ EXPECT_CALL(
+ mock_advertising_callback_,
+ OnAdvertisingParametersUpdated(advertiser_id_, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+ test_hci_layer_->IncomingEvent(LeSetAdvertisingParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+ sync_client_handler();
+}
+
TEST_F(LeExtendedAdvertisingAPITest, set_parameter) {
ExtendedAdvertisingConfig advertising_config{};
advertising_config.advertising_type = AdvertisingType::ADV_IND;
sync_client_handler();
}
+TEST_F(LeAdvertisingAPITest, set_data_test) {
+ // Set advertising data
+ std::vector<GapData> advertising_data{};
+ GapData data_item{};
+ data_item.data_type_ = GapDataType::TX_POWER_LEVEL;
+ data_item.data_ = {0x00};
+ advertising_data.push_back(data_item);
+ le_advertising_manager_->SetData(advertiser_id_, false, advertising_data);
+ auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_DATA);
+ auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+ ASSERT_EQ(std::future_status::ready, result);
+ EXPECT_CALL(
+ mock_advertising_callback_,
+ OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+ test_hci_layer_->IncomingEvent(LeSetAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+ sync_client_handler();
+
+ // Set scan response data
+ std::vector<GapData> response_data{};
+ GapData data_item2{};
+ data_item2.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
+ data_item2.data_ = {'t', 'e', 's', 't', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
+ response_data.push_back(data_item2);
+ le_advertising_manager_->SetData(advertiser_id_, true, response_data);
+ last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_SCAN_RESPONSE_DATA);
+ result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+ ASSERT_EQ(std::future_status::ready, result);
+ EXPECT_CALL(
+ mock_advertising_callback_,
+ OnScanResponseDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+ test_hci_layer_->IncomingEvent(LeSetScanResponseDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+ sync_client_handler();
+}
+
TEST_F(LeExtendedAdvertisingAPITest, set_data_test) {
// Set advertising data
std::vector<GapData> advertising_data{};
sync_client_handler();
}
-TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_ad_structure) {
+TEST_F(LeExtendedAdvertisingAPITest, set_data_with_invalid_ad_structure) {
// Set advertising data with AD structure that length greater than 251
std::vector<GapData> advertising_data{};
GapData data_item{};
sync_client_handler();
}
-TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_length) {
+TEST_F(LeExtendedAdvertisingAPITest, set_data_with_invalid_length) {
// Set advertising data with data that greater than le_maximum_advertising_data_length_
std::vector<GapData> advertising_data{};
for (uint8_t i = 0; i < 10; i++) {
sync_client_handler();
}
+TEST_F(LeAdvertisingAPITest, disable_enable_advertiser_test) {
+ // disable advertiser
+ le_advertising_manager_->EnableAdvertiser(advertiser_id_, false, 0x00, 0x00);
+ auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE);
+ auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+ ASSERT_EQ(std::future_status::ready, result);
+ EXPECT_CALL(
+ mock_advertising_callback_,
+ OnAdvertisingEnabled(advertiser_id_, false, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+ test_hci_layer_->IncomingEvent(LeSetAdvertisingEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+ sync_client_handler();
+
+ // enable advertiser
+ le_advertising_manager_->EnableAdvertiser(advertiser_id_, true, 0x00, 0x00);
+ last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE);
+ result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
+ ASSERT_EQ(std::future_status::ready, result);
+ EXPECT_CALL(
+ mock_advertising_callback_,
+ OnAdvertisingEnabled(advertiser_id_, true, AdvertisingCallback::AdvertisingStatus::SUCCESS));
+ test_hci_layer_->IncomingEvent(LeSetAdvertisingEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
+ sync_client_handler();
+}
+
TEST_F(LeExtendedAdvertisingAPITest, disable_enable_advertiser_test) {
// disable advertiser
le_advertising_manager_->EnableAdvertiser(advertiser_id_, false, 0x00, 0x00);