Loading system/gd/hci/le_advertising_manager.cc +81 −12 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb module_handler_ = handler; hci_layer_ = hci_layer; controller_ = controller; le_maximum_advertising_data_length_ = controller_->GetLeMaximumAdvertisingDataLength(); le_address_manager_ = acl_manager->GetLeAddressManager(); le_advertising_interface_ = hci_layer_->GetLeAdvertisingInterface(module_handler_->BindOn(this, &LeAdvertisingManager::impl::handle_event)); Loading Loading @@ -539,9 +540,65 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb // TODO } break; case (AdvertisingApiType::EXTENDED): { // TODO(b/149221472): Support fragmentation auto operation = Operation::COMPLETE_ADVERTISEMENT; uint16_t data_len = 0; // check data size for (int i = 0; i < data.size(); i++) { if (data[i].size() > kLeMaximumFragmentLength) { LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength); if (set_scan_rsp) { advertising_callbacks_->OnScanResponseDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR); } else { advertising_callbacks_->OnAdvertisingDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR); } return; } data_len += data[i].size(); } if (data_len > le_maximum_advertising_data_length_) { LOG_WARN( "advertising data len exceeds le_maximum_advertising_data_length_ %d", le_maximum_advertising_data_length_); if (advertising_callbacks_ != nullptr) { if (set_scan_rsp) { advertising_callbacks_->OnScanResponseDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE); } else { advertising_callbacks_->OnAdvertisingDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE); } } return; } if (data_len <= kLeMaximumFragmentLength) { send_data_fragment(advertiser_id, set_scan_rsp, data, Operation::COMPLETE_ADVERTISEMENT); } else { std::vector<GapData> sub_data; uint16_t sub_data_len = 0; Operation operation = Operation::FIRST_FRAGMENT; for (int i = 0; i < data.size(); i++) { if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) { send_data_fragment(advertiser_id, set_scan_rsp, sub_data, operation); operation = Operation::INTERMEDIATE_FRAGMENT; sub_data_len = 0; sub_data.clear(); } sub_data.push_back(data[i]); sub_data_len += data[i].size(); } send_data_fragment(advertiser_id, set_scan_rsp, sub_data, Operation::LAST_FRAGMENT); } } break; } } void send_data_fragment( AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data, Operation operation) { if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) { if (set_scan_rsp) { le_advertising_interface_->EnqueueCommand( hci::LeSetExtendedAdvertisingScanResponseBuilder::Create( Loading @@ -554,7 +611,18 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb module_handler_->BindOnceOn( this, &impl::check_status_with_id<LeSetExtendedAdvertisingDataCompleteView>, advertiser_id)); } } break; } else { // For first and intermediate fragment, do not trigger advertising_callbacks_. if (set_scan_rsp) { le_advertising_interface_->EnqueueCommand( hci::LeSetExtendedAdvertisingScanResponseBuilder::Create( advertiser_id, operation, kFragment_preference, data), module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingScanResponseCompleteView>)); } else { le_advertising_interface_->EnqueueCommand( hci::LeSetExtendedAdvertisingDataBuilder::Create(advertiser_id, operation, kFragment_preference, data), module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingDataCompleteView>)); } } } Loading Loading @@ -730,6 +798,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb os::Handler* module_handler_; hci::HciLayer* hci_layer_; hci::Controller* controller_; uint16_t le_maximum_advertising_data_length_; hci::LeAdvertisingInterface* le_advertising_interface_; std::map<AdvertiserId, Advertiser> advertising_sets_; hci::LeAddressManager* le_address_manager_; Loading system/gd/hci/le_advertising_manager.h +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ class LeAdvertisingManager : public bluetooth::Module { static constexpr AdvertiserId kInvalidId = 0xFF; static constexpr uint8_t kInvalidHandle = 0xFF; static constexpr uint8_t kAdvertisingSetIdMask = 0x0F; static constexpr uint16_t kLeMaximumFragmentLength = 251; static constexpr FragmentPreference kFragment_preference = FragmentPreference::CONTROLLER_SHOULD_NOT; LeAdvertisingManager(); Loading system/gd/hci/le_advertising_manager_test.cc +140 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,10 @@ class TestController : public Controller { return num_advertisers; } uint16_t GetLeMaximumAdvertisingDataLength() const override { return 0x0672; } uint8_t num_advertisers{0}; protected: Loading Loading @@ -636,6 +640,142 @@ TEST_F(LeExtendedAdvertisingAPITest, set_data_test) { sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, set_data_fragments_test) { // Set advertising data std::vector<GapData> advertising_data{}; for (uint8_t i = 0; i < 3; i++) { GapData data_item{}; data_item.data_.push_back(0xda); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, i}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[200]; std::copy_n(service_data, 200, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); } le_advertising_manager_->SetData(advertiser_id_, false, advertising_data); // First fragment auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_DATA); auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Intermediate fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_DATA); result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Last fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_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_, OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS)); test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, set_scan_response_fragments_test) { // Set advertising data std::vector<GapData> advertising_data{}; for (uint8_t i = 0; i < 3; i++) { GapData data_item{}; data_item.data_.push_back(0xfa); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, i}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[232]; std::copy_n(service_data, 232, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); } le_advertising_manager_->SetData(advertiser_id_, true, advertising_data); // First fragment auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE); auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Intermediate fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE); result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Last fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE); 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( LeSetExtendedAdvertisingScanResponseCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent( LeSetExtendedAdvertisingScanResponseCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent( LeSetExtendedAdvertisingScanResponseCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_ad_structure) { // Set advertising data with AD structure that length greater than 251 std::vector<GapData> advertising_data{}; GapData data_item{}; data_item.data_.push_back(0xfb); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[233]; std::copy_n(service_data, 233, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); EXPECT_CALL( mock_advertising_callback_, OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR)); le_advertising_manager_->SetData(advertiser_id_, false, advertising_data); EXPECT_CALL( mock_advertising_callback_, OnScanResponseDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR)); le_advertising_manager_->SetData(advertiser_id_, true, advertising_data); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, send_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++) { GapData data_item{}; data_item.data_.push_back(0xfb); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, i}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[200]; std::copy_n(service_data, 200, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); } EXPECT_CALL( mock_advertising_callback_, OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE)); le_advertising_manager_->SetData(advertiser_id_, false, advertising_data); EXPECT_CALL( mock_advertising_callback_, OnScanResponseDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE)); le_advertising_manager_->SetData(advertiser_id_, true, advertising_data); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, disable_enable_advertiser_test) { // disable advertiser le_advertising_manager_->EnableAdvertiser(advertiser_id_, false, 0x00, 0x00); Loading Loading
system/gd/hci/le_advertising_manager.cc +81 −12 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb module_handler_ = handler; hci_layer_ = hci_layer; controller_ = controller; le_maximum_advertising_data_length_ = controller_->GetLeMaximumAdvertisingDataLength(); le_address_manager_ = acl_manager->GetLeAddressManager(); le_advertising_interface_ = hci_layer_->GetLeAdvertisingInterface(module_handler_->BindOn(this, &LeAdvertisingManager::impl::handle_event)); Loading Loading @@ -539,9 +540,65 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb // TODO } break; case (AdvertisingApiType::EXTENDED): { // TODO(b/149221472): Support fragmentation auto operation = Operation::COMPLETE_ADVERTISEMENT; uint16_t data_len = 0; // check data size for (int i = 0; i < data.size(); i++) { if (data[i].size() > kLeMaximumFragmentLength) { LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength); if (set_scan_rsp) { advertising_callbacks_->OnScanResponseDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR); } else { advertising_callbacks_->OnAdvertisingDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR); } return; } data_len += data[i].size(); } if (data_len > le_maximum_advertising_data_length_) { LOG_WARN( "advertising data len exceeds le_maximum_advertising_data_length_ %d", le_maximum_advertising_data_length_); if (advertising_callbacks_ != nullptr) { if (set_scan_rsp) { advertising_callbacks_->OnScanResponseDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE); } else { advertising_callbacks_->OnAdvertisingDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE); } } return; } if (data_len <= kLeMaximumFragmentLength) { send_data_fragment(advertiser_id, set_scan_rsp, data, Operation::COMPLETE_ADVERTISEMENT); } else { std::vector<GapData> sub_data; uint16_t sub_data_len = 0; Operation operation = Operation::FIRST_FRAGMENT; for (int i = 0; i < data.size(); i++) { if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) { send_data_fragment(advertiser_id, set_scan_rsp, sub_data, operation); operation = Operation::INTERMEDIATE_FRAGMENT; sub_data_len = 0; sub_data.clear(); } sub_data.push_back(data[i]); sub_data_len += data[i].size(); } send_data_fragment(advertiser_id, set_scan_rsp, sub_data, Operation::LAST_FRAGMENT); } } break; } } void send_data_fragment( AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data, Operation operation) { if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) { if (set_scan_rsp) { le_advertising_interface_->EnqueueCommand( hci::LeSetExtendedAdvertisingScanResponseBuilder::Create( Loading @@ -554,7 +611,18 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb module_handler_->BindOnceOn( this, &impl::check_status_with_id<LeSetExtendedAdvertisingDataCompleteView>, advertiser_id)); } } break; } else { // For first and intermediate fragment, do not trigger advertising_callbacks_. if (set_scan_rsp) { le_advertising_interface_->EnqueueCommand( hci::LeSetExtendedAdvertisingScanResponseBuilder::Create( advertiser_id, operation, kFragment_preference, data), module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingScanResponseCompleteView>)); } else { le_advertising_interface_->EnqueueCommand( hci::LeSetExtendedAdvertisingDataBuilder::Create(advertiser_id, operation, kFragment_preference, data), module_handler_->BindOnce(impl::check_status<LeSetExtendedAdvertisingDataCompleteView>)); } } } Loading Loading @@ -730,6 +798,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb os::Handler* module_handler_; hci::HciLayer* hci_layer_; hci::Controller* controller_; uint16_t le_maximum_advertising_data_length_; hci::LeAdvertisingInterface* le_advertising_interface_; std::map<AdvertiserId, Advertiser> advertising_sets_; hci::LeAddressManager* le_address_manager_; Loading
system/gd/hci/le_advertising_manager.h +1 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ class LeAdvertisingManager : public bluetooth::Module { static constexpr AdvertiserId kInvalidId = 0xFF; static constexpr uint8_t kInvalidHandle = 0xFF; static constexpr uint8_t kAdvertisingSetIdMask = 0x0F; static constexpr uint16_t kLeMaximumFragmentLength = 251; static constexpr FragmentPreference kFragment_preference = FragmentPreference::CONTROLLER_SHOULD_NOT; LeAdvertisingManager(); Loading
system/gd/hci/le_advertising_manager_test.cc +140 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,10 @@ class TestController : public Controller { return num_advertisers; } uint16_t GetLeMaximumAdvertisingDataLength() const override { return 0x0672; } uint8_t num_advertisers{0}; protected: Loading Loading @@ -636,6 +640,142 @@ TEST_F(LeExtendedAdvertisingAPITest, set_data_test) { sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, set_data_fragments_test) { // Set advertising data std::vector<GapData> advertising_data{}; for (uint8_t i = 0; i < 3; i++) { GapData data_item{}; data_item.data_.push_back(0xda); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, i}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[200]; std::copy_n(service_data, 200, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); } le_advertising_manager_->SetData(advertiser_id_, false, advertising_data); // First fragment auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_DATA); auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Intermediate fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_DATA); result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Last fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_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_, OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::SUCCESS)); test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, set_scan_response_fragments_test) { // Set advertising data std::vector<GapData> advertising_data{}; for (uint8_t i = 0; i < 3; i++) { GapData data_item{}; data_item.data_.push_back(0xfa); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, i}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[232]; std::copy_n(service_data, 232, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); } le_advertising_manager_->SetData(advertiser_id_, true, advertising_data); // First fragment auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE); auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Intermediate fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE); result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); ASSERT_EQ(std::future_status::ready, result); // Last fragment last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE); 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( LeSetExtendedAdvertisingScanResponseCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent( LeSetExtendedAdvertisingScanResponseCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); test_hci_layer_->IncomingEvent( LeSetExtendedAdvertisingScanResponseCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, send_data_with_invalid_ad_structure) { // Set advertising data with AD structure that length greater than 251 std::vector<GapData> advertising_data{}; GapData data_item{}; data_item.data_.push_back(0xfb); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[233]; std::copy_n(service_data, 233, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); EXPECT_CALL( mock_advertising_callback_, OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR)); le_advertising_manager_->SetData(advertiser_id_, false, advertising_data); EXPECT_CALL( mock_advertising_callback_, OnScanResponseDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR)); le_advertising_manager_->SetData(advertiser_id_, true, advertising_data); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, send_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++) { GapData data_item{}; data_item.data_.push_back(0xfb); data_item.data_type_ = GapDataType::SERVICE_DATA_128_BIT_UUIDS; uint8_t uuid[16] = {0xf0, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, i}; std::copy_n(uuid, 16, std::back_inserter(data_item.data_)); uint8_t service_data[200]; std::copy_n(service_data, 200, std::back_inserter(data_item.data_)); advertising_data.push_back(data_item); } EXPECT_CALL( mock_advertising_callback_, OnAdvertisingDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE)); le_advertising_manager_->SetData(advertiser_id_, false, advertising_data); EXPECT_CALL( mock_advertising_callback_, OnScanResponseDataSet(advertiser_id_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE)); le_advertising_manager_->SetData(advertiser_id_, true, advertising_data); sync_client_handler(); } TEST_F(LeExtendedAdvertisingAPITest, disable_enable_advertiser_test) { // disable advertiser le_advertising_manager_->EnableAdvertiser(advertiser_id_, false, 0x00, 0x00); Loading