OSDN Git Service

Bluetooth 5 AdvertisingSet implementation (3/4)
authorJakub Pawlowski <jpawlowski@google.com>
Sun, 12 Mar 2017 00:46:00 +0000 (16:46 -0800)
committerJakub Pawlowski <jpawlowski@google.com>
Fri, 17 Mar 2017 00:38:28 +0000 (00:38 +0000)
This patch wires up fist methods of AdvertisingSet, making it possible
to start advertising and stop advertising. It also replaces legacy
implemementation with calls to new implementation.

Bug: 30622771
Test: sl4a ConcurrentBleAdvertisingTest
Change-Id: I843d8fc12ba1928c87e256a0fb6d730c9fa200e6

btif/src/btif_ble_advertiser.cc
service/test/low_energy_advertiser_unittest.cc
stack/btm/btm_ble_multi_adv.cc
stack/include/ble_advertiser.h

index f30192e..f274de2 100644 (file)
@@ -62,17 +62,14 @@ static inline OwnedArrayWrapper<T> OwnedArray(T* o) {
 class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
   ~BleAdvertiserInterfaceImpl(){};
 
-  void RegisterAdvertiserCb(
-      base::Callback<void(uint8_t /* adv_id */, uint8_t /* status */)> cb,
-      uint8_t advertiser_id, uint8_t status) {
+  void RegisterAdvertiserCb(IdStatusCallback cb, uint8_t advertiser_id,
+                            uint8_t status) {
     LOG(INFO) << __func__ << " status: " << +status
               << " , adveriser_id: " << +advertiser_id;
     do_in_jni_thread(Bind(cb, advertiser_id, status));
   }
 
-  void RegisterAdvertiser(
-      base::Callback<void(uint8_t /* advertiser_id */, uint8_t /* status */)>
-          cb) override {
+  void RegisterAdvertiser(IdStatusCallback cb) override {
     do_in_bta_thread(
         FROM_HERE, Bind(&BleAdvertisingManager::RegisterAdvertiser,
                         base::Unretained(BleAdvertisingManager::Get()),
@@ -87,7 +84,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
              base::Unretained(BleAdvertisingManager::Get()), advertiser_id));
   }
 
-  void SetParametersCb(Callback cb, uint8_t status) {
+  void SetParametersCb(StatusCallback cb, uint8_t status) {
     LOG(INFO) << __func__ << " status: " << +status;
     do_in_jni_thread(Bind(cb, status));
   }
@@ -97,7 +94,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
                      uint32_t min_interval, uint32_t max_interval, int chnl_map,
                      int tx_power, uint8_t primary_advertising_phy,
                      uint8_t secondary_advertising_phy,
-                     uint8_t scan_request_notification_enable, Callback cb) {
+                     uint8_t scan_request_notification_enable,
+                     StatusCallback cb) {
     tBTM_BLE_ADV_PARAMS* params = new tBTM_BLE_ADV_PARAMS;
 
     params->advertising_event_properties = advertising_event_properties;
@@ -119,7 +117,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
   }
 
   void SetData(int advertiser_id, bool set_scan_rsp, vector<uint8_t> data,
-               Callback cb) override {
+               StatusCallback cb) override {
     do_in_bta_thread(
         FROM_HERE,
         Bind(&BleAdvertisingManager::SetData,
@@ -127,8 +125,8 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
              set_scan_rsp, std::move(data), jni_thread_wrapper(FROM_HERE, cb)));
   }
 
-  void Enable(uint8_t advertiser_id, bool enable, Callback cb, int timeout_s,
-              Callback timeout_cb) override {
+  void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb,
+              int timeout_s, StatusCallback timeout_cb) override {
     VLOG(1) << __func__ << " advertiser_id: " << +advertiser_id
             << " ,enable: " << enable;
 
@@ -140,7 +138,7 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
              jni_thread_wrapper(FROM_HERE, timeout_cb)));
   }
 
-  void StartAdvertising(uint8_t advertiser_id, Callback cb,
+  void StartAdvertising(uint8_t advertiser_id, StatusCallback cb,
                         AdvertiseParameters params,
                         std::vector<uint8_t> advertise_data,
                         std::vector<uint8_t> scan_response_data, int timeout_s,
@@ -168,6 +166,44 @@ class BleAdvertiserInterfaceImpl : public BleAdvertiserInterface {
              std::move(advertise_data), std::move(scan_response_data),
              timeout_s, jni_thread_wrapper(FROM_HERE, timeout_cb)));
   }
+
+  void StartAdvertisingSet(IdStatusCallback cb, AdvertiseParameters params,
+                           std::vector<uint8_t> advertise_data,
+                           std::vector<uint8_t> scan_response_data,
+                           PeriodicAdvertisingParameters periodic_params,
+                           std::vector<uint8_t> periodic_data, int timeout_s,
+                           IdStatusCallback timeout_cb) {
+    VLOG(1) << __func__;
+
+    tBTM_BLE_ADV_PARAMS* p_params = new tBTM_BLE_ADV_PARAMS;
+    p_params->advertising_event_properties =
+        params.advertising_event_properties;
+    p_params->adv_int_min = params.min_interval;
+    p_params->adv_int_max = params.max_interval;
+    p_params->channel_map = params.channel_map;
+    p_params->adv_filter_policy = 0;
+    p_params->tx_power = params.tx_power;
+    p_params->primary_advertising_phy = params.primary_advertising_phy;
+    p_params->secondary_advertising_phy = params.secondary_advertising_phy;
+    p_params->scan_request_notification_enable =
+        params.scan_request_notification_enable;
+
+    tBLE_PERIODIC_ADV_PARAMS* p_periodic_params = new tBLE_PERIODIC_ADV_PARAMS;
+    p_periodic_params->enable = periodic_params.enable;
+    p_periodic_params->min_interval = periodic_params.min_interval;
+    p_periodic_params->max_interval = periodic_params.max_interval;
+    p_periodic_params->periodic_advertising_properties =
+        periodic_params.periodic_advertising_properties;
+
+    do_in_bta_thread(
+        FROM_HERE,
+        Bind(&BleAdvertisingManager::StartAdvertisingSet,
+             base::Unretained(BleAdvertisingManager::Get()),
+             jni_thread_wrapper(FROM_HERE, cb), base::Owned(p_params),
+             std::move(advertise_data), std::move(scan_response_data),
+             base::Owned(p_periodic_params), std::move(periodic_data),
+             timeout_s, jni_thread_wrapper(FROM_HERE, timeout_cb)));
+  };
 };
 
 BleAdvertiserInterface* btLeAdvertiserInstance = nullptr;
index a985254..eb2211c 100644 (file)
@@ -45,9 +45,7 @@ class MockAdvertiserHandler : public BleAdvertiserInterface {
   MockAdvertiserHandler() {}
   ~MockAdvertiserHandler() override = default;
 
-  MOCK_METHOD1(RegisterAdvertiser,
-               void(base::Callback<void(uint8_t /* advertiser_id */,
-                                        uint8_t /* status */)>));
+  MOCK_METHOD1(RegisterAdvertiser, void(IdStatusCallback));
   MOCK_METHOD1(Unregister, void(uint8_t));
   MOCK_METHOD10(SetParameters,
                 void(uint8_t advertiser_id,
@@ -55,14 +53,25 @@ class MockAdvertiserHandler : public BleAdvertiserInterface {
                      uint32_t min_interval, uint32_t max_interval, int chnl_map,
                      int tx_power, uint8_t primary_advertising_phy,
                      uint8_t secondary_advertising_phy,
-                     uint8_t scan_request_notification_enable, Callback cb));
+                     uint8_t scan_request_notification_enable,
+                     StatusCallback cb));
   MOCK_METHOD4(SetData, void(int advertiser_id, bool set_scan_rsp,
-                             std::vector<uint8_t> data, Callback cb));
-  MOCK_METHOD5(Enable, void(uint8_t advertiser_id, bool enable, Callback cb,
-                            int timeout_s, Callback timeout_cb));
+                             std::vector<uint8_t> data, StatusCallback cb));
+  MOCK_METHOD5(Enable,
+               void(uint8_t advertiser_id, bool enable, StatusCallback cb,
+                    int timeout_s, StatusCallback timeout_cb));
   MOCK_METHOD7(StartAdvertising,
-               void(uint8_t advertiser_id, Callback cb, AdvertiseParameters,
-                    std::vector<uint8_t>, std::vector<uint8_t>, int, Callback));
+               void(uint8_t advertiser_id, StatusCallback cb,
+                    AdvertiseParameters, std::vector<uint8_t>,
+                    std::vector<uint8_t>, int, StatusCallback));
+
+  MOCK_METHOD8(StartAdvertisingSet,
+               void(IdStatusCallback cb, AdvertiseParameters params,
+                    std::vector<uint8_t> advertise_data,
+                    std::vector<uint8_t> scan_response_data,
+                    PeriodicAdvertisingParameters periodic_params,
+                    std::vector<uint8_t> periodic_data, int timeout_s,
+                    IdStatusCallback timeout_cb));
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockAdvertiserHandler);
index 0e30bd0..339a82e 100644 (file)
@@ -32,6 +32,8 @@
 #include "btm_int_types.h"
 
 using base::Bind;
+using RegisterCb =
+    base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>;
 extern void btm_gen_resolvable_private_addr(
     base::Callback<void(uint8_t[8])> cb);
 extern fixed_queue_t* btu_general_alarm_queue;
@@ -292,6 +294,120 @@ class BleAdvertisingManagerImpl
     // clang-format on
   }
 
+  void StartAdvertisingSet(RegisterCb cb, tBTM_BLE_ADV_PARAMS* params,
+                           std::vector<uint8_t> advertise_data,
+                           std::vector<uint8_t> scan_response_data,
+                           tBLE_PERIODIC_ADV_PARAMS* periodic_params,
+                           std::vector<uint8_t> periodic_data, int timeout_s,
+                           RegisterCb timeout_cb) override {
+    /* a temporary type for holding all the data needed in callbacks below*/
+    struct CreatorParams {
+      uint8_t inst_id;
+      BleAdvertisingManagerImpl* self;
+      RegisterCb cb;
+      tBTM_BLE_ADV_PARAMS params;
+      std::vector<uint8_t> advertise_data;
+      std::vector<uint8_t> scan_response_data;
+      tBLE_PERIODIC_ADV_PARAMS periodic_params;
+      std::vector<uint8_t> periodic_data;
+      int timeout_s;
+      RegisterCb timeout_cb;
+    };
+
+    std::unique_ptr<CreatorParams> c;
+    c.reset(new CreatorParams());
+
+    c->self = this;
+    c->cb = std::move(cb);
+    c->params = *params;
+    c->advertise_data = std::move(advertise_data);
+    c->scan_response_data = std::move(scan_response_data);
+    c->periodic_params = *periodic_params;
+    c->periodic_data = std::move(periodic_data);
+    c->timeout_s = timeout_s;
+    c->timeout_cb = std::move(timeout_cb);
+
+    using c_type = std::unique_ptr<CreatorParams>;
+
+    // this code is intentionally left formatted this way to highlight the
+    // asynchronous flow
+    // clang-format off
+    c->self->RegisterAdvertiser(Bind(
+      [](c_type c, uint8_t advertiser_id, uint8_t status) {
+        if (status != 0) {
+          LOG(ERROR) << "registering advertiser failed, status: " << +status;
+          c->cb.Run(0, status);
+          return;
+        }
+
+        c->inst_id = advertiser_id;
+
+        c->self->SetParameters(c->inst_id, &c->params, Bind(
+          [](c_type c, uint8_t status) {
+            if (status != 0) {
+              c->self->Unregister(c->inst_id);
+              LOG(ERROR) << "setting parameters failed, status: " << +status;
+              c->cb.Run(0, status);
+              return;
+            }
+
+            //TODO(jpawlowski): obtain real tx_power from set parameters
+            // response, to put into adv data
+
+            BD_ADDR *rpa = &c->self->adv_inst[c->inst_id].own_address;
+            c->self->GetHciInterface()->SetRandomAddress(c->inst_id, *rpa, Bind(
+              [](c_type c, uint8_t status) {
+                if (status != 0) {
+                  c->self->Unregister(c->inst_id);
+                  LOG(ERROR) << "setting random address failed, status: " << +status;
+                  c->cb.Run(0, status);
+                  return;
+                }
+
+                c->self->SetData(c->inst_id, false, std::move(c->advertise_data), Bind(
+                  [](c_type c, uint8_t status) {
+                    if (status != 0) {
+                      c->self->Unregister(c->inst_id);
+                      LOG(ERROR) << "setting advertise data failed, status: " << +status;
+                      c->cb.Run(0, status);
+                      return;
+                    }
+
+                    c->self->SetData(c->inst_id, true, std::move(c->scan_response_data), Bind(
+                      [](c_type c, uint8_t status) {
+                        if (status != 0) {
+                          c->self->Unregister(c->inst_id);
+                          LOG(ERROR) << "setting scan response data failed, status: " << +status;
+                          c->cb.Run(0, status);
+                          return;
+                        }
+
+                        uint8_t inst_id = c->inst_id;
+                        int timeout_s = c->timeout_s;
+                        RegisterCb timeout_cb = std::move(c->timeout_cb);
+                        BleAdvertisingManagerImpl* self = c->self;
+                        MultiAdvCb enable_cb = Bind(
+                            [](c_type c, uint8_t status) {
+                              if (status != 0) {
+                                c->self->Unregister(c->inst_id);
+                                LOG(ERROR) << "enabling advertiser failed, status: " << +status;
+                                c->cb.Run(0, status);
+                                return;
+                              }
+                              c->cb.Run(c->inst_id, status);
+                            },
+                            base::Passed(&c));
+
+
+                        self->Enable(inst_id, true, std::move(enable_cb), timeout_s, Bind(std::move(timeout_cb), inst_id));
+                    }, base::Passed(&c)));
+                }, base::Passed(&c)));
+            }, base::Passed(&c)));
+        }, base::Passed(&c)));
+    }, base::Passed(&c)));
+    // clang-format on
+  }
+
   void EnableWithTimerCb(uint8_t inst_id, MultiAdvCb enable_cb, int timeout_s,
                          MultiAdvCb timeout_cb, uint8_t status) {
     AdvertisingInstance* p_inst = &adv_inst[inst_id];
@@ -374,8 +490,8 @@ class BleAdvertisingManagerImpl
         p_params->adv_int_min, p_params->adv_int_max, p_params->channel_map,
         p_inst->own_address_type, p_inst->own_address, 0x00, peer_address,
         p_params->adv_filter_policy, p_inst->tx_power,
-        p_params->primary_advertising_phy, 0x01, 0x01,
-        p_params->secondary_advertising_phy,
+        p_params->primary_advertising_phy, 0x01,
+        p_params->secondary_advertising_phy, 0x01 /* TODO: proper SID */,
         p_params->scan_request_notification_enable, cb);
 
     // TODO: re-enable only if it was enabled, properly call
index e4787ae..f50f87b 100644 (file)
@@ -51,6 +51,13 @@ typedef struct {
   uint8_t scan_request_notification_enable;
 } tBTM_BLE_ADV_PARAMS;
 
+typedef struct {
+  uint8_t enable;
+  uint16_t min_interval;
+  uint16_t max_interval;
+  uint16_t periodic_advertising_properties;
+} tBLE_PERIODIC_ADV_PARAMS;
+
 class BleAdvertiserHciInterface;
 
 class BleAdvertisingManager {
@@ -65,12 +72,12 @@ class BleAdvertisingManager {
   static BleAdvertisingManager* Get();
 
   /* Register an advertising instance, status will be returned in |cb|
-  * callback, with assigned id, if operation succeeds. Instance is freed when
-  * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
-  * of the operations fails.
-  * The instance will have data set to |advertise_data|, scan response set to
-  * |scan_response_data|, and will be enabled.
-  */
+   * callback, with assigned id, if operation succeeds. Instance is freed when
+   * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
+   * of the operations fails.
+   * The instance will have data set to |advertise_data|, scan response set to
+   * |scan_response_data|, and will be enabled.
+   */
   virtual void StartAdvertising(uint8_t advertiser_id, MultiAdvCb cb,
                                 tBTM_BLE_ADV_PARAMS* params,
                                 std::vector<uint8_t> advertise_data,
@@ -78,6 +85,23 @@ class BleAdvertisingManager {
                                 int timeout_s, MultiAdvCb timeout_cb) = 0;
 
   /* Register an advertising instance, status will be returned in |cb|
+   * callback, with assigned id, if operation succeeds. Instance is freed when
+   * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
+   * of the operations fails.
+   * The instance will have data set to |advertise_data|, scan response set to
+   * |scan_response_data|, periodic data set to |periodic_data| and will be
+   * enabled.
+   */
+  virtual void StartAdvertisingSet(
+      base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)> cb,
+      tBTM_BLE_ADV_PARAMS* params, std::vector<uint8_t> advertise_data,
+      std::vector<uint8_t> scan_response_data,
+      tBLE_PERIODIC_ADV_PARAMS* periodic_params,
+      std::vector<uint8_t> periodic_data, int timeout_s,
+      base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>
+          timeout_cb) = 0;
+
+  /* Register an advertising instance, status will be returned in |cb|
   * callback, with assigned id, if operation succeeds. Instance is freed when
   * advertising is disabled by calling |BTM_BleDisableAdvInstance|, or when any
   * of the operations fails. */