Loading system/stack/btm/btm_ble_multi_adv.cc +29 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct AdvertisingInstance { BD_ADDR own_address; MultiAdvCb timeout_cb; bool address_update_required; bool periodic_enabled; /* When true, advertising set is enabled, or last scheduled call to "LE Set * Extended Advertising Set Enable" is to enable this advertising set. Any Loading @@ -88,6 +89,7 @@ struct AdvertisingInstance { own_address_type(0), own_address{0}, address_update_required(false), periodic_enabled(false), enable_status(false) { adv_raddr_timer = alarm_new_periodic("btm_ble.adv_raddr_timer"); } Loading Loading @@ -758,7 +760,27 @@ class BleAdvertisingManagerImpl MultiAdvCb cb) override { VLOG(1) << __func__ << " inst_id: " << +inst_id << ", enable: " << +enable; GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, cb); AdvertisingInstance* p_inst = &adv_inst[inst_id]; if (!p_inst->in_use) { LOG(ERROR) << "Invalid or not active instance"; cb.Run(BTM_BLE_MULTI_ADV_FAILURE); return; } MultiAdvCb enable_cb = Bind( [](AdvertisingInstance* p_inst, uint8_t enable, MultiAdvCb cb, uint8_t status) { VLOG(1) << "periodc adv enable cb: inst_id: " << +p_inst->inst_id << ", enable: " << +enable << ", status: " << std::hex << +status; if (!status) p_inst->periodic_enabled = enable; cb.Run(status); }, p_inst, enable, std::move(cb)); GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, std::move(enable_cb)); } void Unregister(uint8_t inst_id) override { Loading @@ -775,6 +797,12 @@ class BleAdvertisingManagerImpl GetHciInterface()->Enable(false, inst_id, 0x00, 0x00, Bind(DoNothing)); } if (p_inst->periodic_enabled) { p_inst->periodic_enabled = false; GetHciInterface()->SetPeriodicAdvertisingEnable(false, inst_id, Bind(DoNothing)); } alarm_cancel(p_inst->adv_raddr_timer); p_inst->in_use = false; GetHciInterface()->RemoveAdvertisingSet(inst_id, Bind(DoNothing)); Loading system/stack/test/ble_advertiser_test.cc +90 −0 Original line number Diff line number Diff line Loading @@ -741,3 +741,93 @@ TEST_F(BleAdvertisingManagerTest, disable_cb.Run(0); remove_cb.Run(0); } /* This test makes sure that periodic advertising is stopped before * unregistering the advertiser, if it was enabled. */ TEST_F(BleAdvertisingManagerTest, test_periodic_adv_disable_on_unregister) { std::vector<uint8_t> adv_data; std::vector<uint8_t> scan_resp; tBTM_BLE_ADV_PARAMS params; params.advertising_event_properties = 0x1 /* connectable */; tBLE_PERIODIC_ADV_PARAMS periodic_params; periodic_params.enable = true; // enable periodic advertising std::vector<uint8_t> periodic_data; parameters_cb set_params_cb; status_cb set_address_cb; status_cb set_data_cb; status_cb set_scan_resp_data_cb; status_cb enable_cb; status_cb set_periodic_params_cb; status_cb set_periodic_data_cb; status_cb set_periodic_enable_cb; EXPECT_CALL(*hci_mock, SetParameters1(_, _, _, _, _, _, _, _, _)).Times(1); EXPECT_CALL(*hci_mock, SetParameters2(_, _, _, _, _, _, _, _)) .Times(1) .WillOnce(SaveArg<7>(&set_params_cb)); EXPECT_CALL(*hci_mock, SetRandomAddress(_, _, _)) .Times(1) .WillOnce(SaveArg<2>(&set_address_cb)); EXPECT_CALL(*hci_mock, SetAdvertisingData(_, _, _, _, _, _)) .Times(1) .WillOnce(SaveArg<5>(&set_data_cb)); EXPECT_CALL(*hci_mock, SetScanResponseData(_, _, _, _, _, _)) .Times(1) .WillOnce(SaveArg<5>(&set_scan_resp_data_cb)); EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingParameters(_, _, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&set_periodic_params_cb)); EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingData(_, _, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&set_periodic_data_cb)); EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x01 /* enable */, _, _)) .Times(1) .WillOnce(SaveArg<2>(&set_periodic_enable_cb)); EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&enable_cb)); BleAdvertisingManager::Get()->StartAdvertisingSet( Bind(&BleAdvertisingManagerTest::StartAdvertisingSetCb, base::Unretained(this)), ¶ms, adv_data, scan_resp, &periodic_params, periodic_data, 0 /* duration */, 0 /* maxExtAdvEvents */, Bind(DoNothing2)); // we are a truly gracious fake controller, let the commands succeed! int selected_tx_power = -15; set_params_cb.Run(0, selected_tx_power); set_address_cb.Run(0); set_data_cb.Run(0); set_scan_resp_data_cb.Run(0); set_periodic_params_cb.Run(0); set_periodic_data_cb.Run(0); set_periodic_enable_cb.Run(0); enable_cb.Run(0); EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, start_advertising_set_status); EXPECT_EQ(selected_tx_power, start_advertising_set_tx_power); int advertiser_id = start_advertising_set_advertiser_id; ::testing::Mock::VerifyAndClearExpectations(hci_mock.get()); // ... advertising ... // Unregister advertiser - should disable periodic advertising status_cb disable_cb; EXPECT_CALL(*hci_mock, Enable(0x00 /* disable */, advertiser_id, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&disable_cb)); status_cb disable_periodic_cb; EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x00 /* disable */, advertiser_id, _)) .Times(1) .WillOnce(SaveArg<2>(&disable_periodic_cb)); status_cb remove_cb; EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(advertiser_id, _)) .Times(1) .WillOnce(SaveArg<1>(&remove_cb)); BleAdvertisingManager::Get()->Unregister(advertiser_id); ::testing::Mock::VerifyAndClearExpectations(hci_mock.get()); disable_cb.Run(0); disable_periodic_cb.Run(0); remove_cb.Run(0); } Loading
system/stack/btm/btm_ble_multi_adv.cc +29 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct AdvertisingInstance { BD_ADDR own_address; MultiAdvCb timeout_cb; bool address_update_required; bool periodic_enabled; /* When true, advertising set is enabled, or last scheduled call to "LE Set * Extended Advertising Set Enable" is to enable this advertising set. Any Loading @@ -88,6 +89,7 @@ struct AdvertisingInstance { own_address_type(0), own_address{0}, address_update_required(false), periodic_enabled(false), enable_status(false) { adv_raddr_timer = alarm_new_periodic("btm_ble.adv_raddr_timer"); } Loading Loading @@ -758,7 +760,27 @@ class BleAdvertisingManagerImpl MultiAdvCb cb) override { VLOG(1) << __func__ << " inst_id: " << +inst_id << ", enable: " << +enable; GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, cb); AdvertisingInstance* p_inst = &adv_inst[inst_id]; if (!p_inst->in_use) { LOG(ERROR) << "Invalid or not active instance"; cb.Run(BTM_BLE_MULTI_ADV_FAILURE); return; } MultiAdvCb enable_cb = Bind( [](AdvertisingInstance* p_inst, uint8_t enable, MultiAdvCb cb, uint8_t status) { VLOG(1) << "periodc adv enable cb: inst_id: " << +p_inst->inst_id << ", enable: " << +enable << ", status: " << std::hex << +status; if (!status) p_inst->periodic_enabled = enable; cb.Run(status); }, p_inst, enable, std::move(cb)); GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, std::move(enable_cb)); } void Unregister(uint8_t inst_id) override { Loading @@ -775,6 +797,12 @@ class BleAdvertisingManagerImpl GetHciInterface()->Enable(false, inst_id, 0x00, 0x00, Bind(DoNothing)); } if (p_inst->periodic_enabled) { p_inst->periodic_enabled = false; GetHciInterface()->SetPeriodicAdvertisingEnable(false, inst_id, Bind(DoNothing)); } alarm_cancel(p_inst->adv_raddr_timer); p_inst->in_use = false; GetHciInterface()->RemoveAdvertisingSet(inst_id, Bind(DoNothing)); Loading
system/stack/test/ble_advertiser_test.cc +90 −0 Original line number Diff line number Diff line Loading @@ -741,3 +741,93 @@ TEST_F(BleAdvertisingManagerTest, disable_cb.Run(0); remove_cb.Run(0); } /* This test makes sure that periodic advertising is stopped before * unregistering the advertiser, if it was enabled. */ TEST_F(BleAdvertisingManagerTest, test_periodic_adv_disable_on_unregister) { std::vector<uint8_t> adv_data; std::vector<uint8_t> scan_resp; tBTM_BLE_ADV_PARAMS params; params.advertising_event_properties = 0x1 /* connectable */; tBLE_PERIODIC_ADV_PARAMS periodic_params; periodic_params.enable = true; // enable periodic advertising std::vector<uint8_t> periodic_data; parameters_cb set_params_cb; status_cb set_address_cb; status_cb set_data_cb; status_cb set_scan_resp_data_cb; status_cb enable_cb; status_cb set_periodic_params_cb; status_cb set_periodic_data_cb; status_cb set_periodic_enable_cb; EXPECT_CALL(*hci_mock, SetParameters1(_, _, _, _, _, _, _, _, _)).Times(1); EXPECT_CALL(*hci_mock, SetParameters2(_, _, _, _, _, _, _, _)) .Times(1) .WillOnce(SaveArg<7>(&set_params_cb)); EXPECT_CALL(*hci_mock, SetRandomAddress(_, _, _)) .Times(1) .WillOnce(SaveArg<2>(&set_address_cb)); EXPECT_CALL(*hci_mock, SetAdvertisingData(_, _, _, _, _, _)) .Times(1) .WillOnce(SaveArg<5>(&set_data_cb)); EXPECT_CALL(*hci_mock, SetScanResponseData(_, _, _, _, _, _)) .Times(1) .WillOnce(SaveArg<5>(&set_scan_resp_data_cb)); EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingParameters(_, _, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&set_periodic_params_cb)); EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingData(_, _, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&set_periodic_data_cb)); EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x01 /* enable */, _, _)) .Times(1) .WillOnce(SaveArg<2>(&set_periodic_enable_cb)); EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, _, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&enable_cb)); BleAdvertisingManager::Get()->StartAdvertisingSet( Bind(&BleAdvertisingManagerTest::StartAdvertisingSetCb, base::Unretained(this)), ¶ms, adv_data, scan_resp, &periodic_params, periodic_data, 0 /* duration */, 0 /* maxExtAdvEvents */, Bind(DoNothing2)); // we are a truly gracious fake controller, let the commands succeed! int selected_tx_power = -15; set_params_cb.Run(0, selected_tx_power); set_address_cb.Run(0); set_data_cb.Run(0); set_scan_resp_data_cb.Run(0); set_periodic_params_cb.Run(0); set_periodic_data_cb.Run(0); set_periodic_enable_cb.Run(0); enable_cb.Run(0); EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, start_advertising_set_status); EXPECT_EQ(selected_tx_power, start_advertising_set_tx_power); int advertiser_id = start_advertising_set_advertiser_id; ::testing::Mock::VerifyAndClearExpectations(hci_mock.get()); // ... advertising ... // Unregister advertiser - should disable periodic advertising status_cb disable_cb; EXPECT_CALL(*hci_mock, Enable(0x00 /* disable */, advertiser_id, _, _, _)) .Times(1) .WillOnce(SaveArg<4>(&disable_cb)); status_cb disable_periodic_cb; EXPECT_CALL(*hci_mock, SetPeriodicAdvertisingEnable(0x00 /* disable */, advertiser_id, _)) .Times(1) .WillOnce(SaveArg<2>(&disable_periodic_cb)); status_cb remove_cb; EXPECT_CALL(*hci_mock, RemoveAdvertisingSet(advertiser_id, _)) .Times(1) .WillOnce(SaveArg<1>(&remove_cb)); BleAdvertisingManager::Get()->Unregister(advertiser_id); ::testing::Mock::VerifyAndClearExpectations(hci_mock.get()); disable_cb.Run(0); disable_periodic_cb.Run(0); remove_cb.Run(0); }