OSDN Git Service

Reenable advertising instance after an LE advertising state change
authorJakub Pawlowski <jpawlowski@google.com>
Mon, 14 Nov 2016 19:20:52 +0000 (11:20 -0800)
committerAndre Eisenbach <eisenbach@google.com>
Mon, 14 Nov 2016 19:48:49 +0000 (19:48 +0000)
Ensure BleAdvertisingManager::OnAdvertisingStateChanged() is called
after an advertising state change to re-enable advertising after
a connection.

This patch also fixes the registration test, which was broken since
one more advertising instance was freed for general usage.

Test: net_test_stack_multi_adv native test
Change-Id: I76887d98cb3ec386ebc0f7fad95170b8c18b9116

stack/btm/ble_advertiser_hci_interface.cc
stack/btm/ble_advertiser_hci_interface.h
stack/btm/btm_ble_multi_adv.cc
stack/include/ble_advertiser.h
stack/test/ble_advertiser_test.cc

index 9b07383..eff5ea3 100644 (file)
@@ -87,6 +87,11 @@ class BleAdvertiserVscHciInterfaceImpl : public BleAdvertiserHciInterface {
     cb.Run(BTM_BleMaxMultiAdvInstanceCount());
   }
 
+  void SetAdvertisingEventObserver(
+      AdvertisingEventObserver *observer) override {
+    this->advertising_event_observer = observer;
+  }
+
   void SetParameters(uint8_t adv_int_min, uint8_t adv_int_max,
                      uint8_t advertising_type, uint8_t own_address_type,
                      BD_ADDR own_address, uint8_t direct_address_type,
@@ -196,7 +201,15 @@ class BleAdvertiserVscHciInterfaceImpl : public BleAdvertiserHciInterface {
     STREAM_TO_UINT8(adv_inst, p);
     STREAM_TO_UINT8(change_reason, p);
     STREAM_TO_UINT16(conn_handle, p);
+
+    AdvertisingEventObserver *observer =
+        ((BleAdvertiserVscHciInterfaceImpl *)BleAdvertiserHciInterface::Get())->advertising_event_observer;
+    if (observer)
+      observer->OnAdvertisingStateChanged(adv_inst, change_reason, conn_handle);
   }
+
+ private:
+  AdvertisingEventObserver *advertising_event_observer = nullptr;
 };
 
 std::queue<std::pair<uint16_t, status_cb>> *legacy_pending_ops = nullptr;
@@ -233,6 +246,9 @@ class BleAdvertiserLegacyHciInterfaceImpl : public BleAdvertiserHciInterface {
     cb.Run(1);
   }
 
+  void SetAdvertisingEventObserver(
+      AdvertisingEventObserver *observer) override {}
+
   void SetParameters(uint8_t adv_int_min, uint8_t adv_int_max,
                      uint8_t advertising_type, uint8_t own_address_type,
                      BD_ADDR own_address, uint8_t direct_address_type,
index aa90498..8b53573 100644 (file)
@@ -44,6 +44,7 @@ class BleAdvertiserHciInterface {
                                            uint16_t connection_handle) = 0;
   };
 
+  virtual void SetAdvertisingEventObserver(AdvertisingEventObserver *observer) = 0;
   virtual void ReadInstanceCount(base::Callback<void(uint8_t /* inst_cnt*/)> cb) = 0;
   virtual void SetParameters(uint8_t adv_int_min, uint8_t adv_int_max,
                              uint8_t advertising_type, uint8_t own_address_type,
index 9c77526..62d9017 100644 (file)
@@ -404,6 +404,8 @@ void btm_ble_adv_raddr_timer_timeout(void *data) {
 void btm_ble_multi_adv_init() {
   BleAdvertiserHciInterface::Initialize();
   BleAdvertisingManager::Initialize(BleAdvertiserHciInterface::Get());
+  BleAdvertiserHciInterface::Get()->SetAdvertisingEventObserver(
+      (BleAdvertisingManagerImpl *)BleAdvertisingManager::Get());
 }
 
 /*******************************************************************************
index a072a94..4b89461 100644 (file)
@@ -70,8 +70,8 @@ class BleAdvertisingManager {
 
   /* This function enables/disables an advertising instance. Operation status is
    * returned in |cb| */
-  virtual void Enable(uint8_t inst_id, bool enable, MultiAdvCb cb, int timeout_s,
-                    MultiAdvCb timeout_cb) = 0;
+  virtual void Enable(uint8_t inst_id, bool enable, MultiAdvCb cb,
+                      int timeout_s, MultiAdvCb timeout_cb) = 0;
 
   /* This function update a Multi-ADV instance with the specififed adv
    * parameters. */
@@ -85,6 +85,11 @@ class BleAdvertisingManager {
 
   /*  This function disable a Multi-ADV instance */
   virtual void Unregister(uint8_t inst_id) = 0;
+
+  /* This method is a member of BleAdvertiserHciInterface, and is exposed here
+   * just for tests. It should never be called from upper layers*/
+  virtual void OnAdvertisingStateChanged(uint8_t inst_id, uint8_t reason,
+                                         uint16_t conn_handle) = 0;
 };
 
 #endif  // BLE_ADVERTISER_H
index e76410c..787b7fd 100644 (file)
@@ -71,6 +71,7 @@ class AdvertiserHciMock : public BleAdvertiserHciInterface {
   ~AdvertiserHciMock() override = default;
 
   MOCK_METHOD1(ReadInstanceCount, void(base::Callback<void(uint8_t /* inst_cnt*/)>));
+  MOCK_METHOD1(SetAdvertisingEventObserver, void(AdvertisingEventObserver *observer));
   MOCK_METHOD4(SetAdvertisingData,
                void(uint8_t, uint8_t *, uint8_t, status_cb));
   MOCK_METHOD4(SetScanResponseData,
@@ -142,7 +143,7 @@ class BleAdvertisingManagerTest : public testing::Test {
 };
 
 TEST_F(BleAdvertisingManagerTest, test_registration) {
-  for (int i = 1; i < num_adv_instances; i++) {
+  for (int i = 0; i < num_adv_instances; i++) {
     BleAdvertisingManager::Get()->RegisterAdvertiser(base::Bind(
         &BleAdvertisingManagerTest::RegistrationCb, base::Unretained(this)));
     EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, reg_status);
@@ -316,3 +317,30 @@ TEST_F(BleAdvertisingManagerTest, test_adv_data_not_filling) {
   EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, set_data_status);
   ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
 }
+
+TEST_F(BleAdvertisingManagerTest, test_reenabling) {
+  BleAdvertisingManager::Get()->RegisterAdvertiser(base::Bind(
+      &BleAdvertisingManagerTest::RegistrationCb, base::Unretained(this)));
+  EXPECT_EQ(BTM_BLE_MULTI_ADV_SUCCESS, reg_status);
+  EXPECT_EQ(0, reg_inst_id);
+
+  uint8_t advertiser_id = reg_inst_id;
+
+  status_cb enable_cb;
+  EXPECT_CALL(*hci_mock, Enable(0x01 /* enable */, advertiser_id, _))
+      .Times(1)
+      .WillOnce(SaveArg<2>(&enable_cb));
+  BleAdvertisingManager::Get()->OnAdvertisingStateChanged(advertiser_id, 0, 5);
+  enable_cb.Run(0);
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+}
+
+/* Make sure that instance is not reenabled if it's already disabled */
+TEST_F(BleAdvertisingManagerTest, test_reenabling_disabled_instance) {
+  uint8_t advertiser_id = 1; // any unregistered value
+
+  EXPECT_CALL(*hci_mock, Enable(_, _, _))
+      .Times(Exactly(0));
+  BleAdvertisingManager::Get()->OnAdvertisingStateChanged(advertiser_id, 0, 5);
+  ::testing::Mock::VerifyAndClearExpectations(hci_mock.get());
+}
\ No newline at end of file