Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c9cc16fc authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Bluetooth 5 Periodic Advertising

This patch implements the initialization of Bluetooth 5 advertising.

Bug: 30622771
Test: manual
Change-Id: If06a6c827f1d8097aa3f019b99ebcb3933742d6c
parent 9589f47a
Loading
Loading
Loading
Loading
+109 −35
Original line number Original line Diff line number Diff line
@@ -105,7 +105,23 @@ void alarm_set_closure_on_queue(const tracked_objects::Location& posted_from,
  alarm_set_on_queue(alarm, interval_ms, alarm_closure_cb, data, queue);
  alarm_set_on_queue(alarm, interval_ms, alarm_closure_cb, data, queue);
}
}


}  // namespace
class BleAdvertisingManagerImpl;

/* 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;
};

using c_type = std::unique_ptr<CreatorParams>;


class BleAdvertisingManagerImpl
class BleAdvertisingManagerImpl
    : public BleAdvertisingManager,
    : public BleAdvertisingManager,
@@ -300,20 +316,6 @@ class BleAdvertisingManagerImpl
                           tBLE_PERIODIC_ADV_PARAMS* periodic_params,
                           tBLE_PERIODIC_ADV_PARAMS* periodic_params,
                           std::vector<uint8_t> periodic_data, int timeout_s,
                           std::vector<uint8_t> periodic_data, int timeout_s,
                           RegisterCb timeout_cb) override {
                           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;
    std::unique_ptr<CreatorParams> c;
    c.reset(new CreatorParams());
    c.reset(new CreatorParams());


@@ -327,7 +329,6 @@ class BleAdvertisingManagerImpl
    c->timeout_s = timeout_s;
    c->timeout_s = timeout_s;
    c->timeout_cb = std::move(timeout_cb);
    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
    // this code is intentionally left formatted this way to highlight the
    // asynchronous flow
    // asynchronous flow
@@ -382,6 +383,59 @@ class BleAdvertisingManagerImpl
                          return;
                          return;
                        }
                        }


                        if (c->periodic_params.enable) {
                          c->self->StartAdvertisingSetPeriodicPart(std::move(c));
                        } else {
                          c->self->StartAdvertisingSetFinish(std::move(c));
                        }
                    }, base::Passed(&c)));
                }, base::Passed(&c)));
            }, base::Passed(&c)));
        }, base::Passed(&c)));
    }, base::Passed(&c)));
    // clang-format on
  }

  void StartAdvertisingSetPeriodicPart(c_type c) {
    // this code is intentionally left formatted this way to highlight the
    // asynchronous flow
    // clang-format off
    c->self->SetPeriodicAdvertisingParameters(c->inst_id, &c->periodic_params, Bind(
      [](c_type c, uint8_t status) {
        if (status != 0) {
          c->self->Unregister(c->inst_id);
          LOG(ERROR) << "setting periodic parameters failed, status: " << +status;
          c->cb.Run(0, status);
          return;
        }

        c->self->SetPeriodicAdvertisingData(c->inst_id, std::move(c->periodic_data), Bind(
          [](c_type c, uint8_t status) {
            if (status != 0) {
              c->self->Unregister(c->inst_id);
              LOG(ERROR) << "setting periodic parameters failed, status: " << +status;
              c->cb.Run(0, status);
              return;
            }

            c->self->SetPeriodicAdvertisingEnable(c->inst_id, true, Bind(
              [](c_type c, uint8_t status) {
                if (status != 0) {
                  c->self->Unregister(c->inst_id);
                  LOG(ERROR) << "enabling periodic advertising failed, status: " << +status;
                  c->cb.Run(0, status);
                  return;
                }

                c->self->StartAdvertisingSetFinish(std::move(c));

              }, base::Passed(&c)));
        }, base::Passed(&c)));
    }, base::Passed(&c)));
    // clang-format on
  }

  void StartAdvertisingSetFinish(c_type c) {
    uint8_t inst_id = c->inst_id;
    uint8_t inst_id = c->inst_id;
    int timeout_s = c->timeout_s;
    int timeout_s = c->timeout_s;
    RegisterCb timeout_cb = std::move(c->timeout_cb);
    RegisterCb timeout_cb = std::move(c->timeout_cb);
@@ -398,14 +452,8 @@ class BleAdvertisingManagerImpl
        },
        },
        base::Passed(&c));
        base::Passed(&c));



    self->Enable(inst_id, true, std::move(enable_cb), timeout_s,
                        self->Enable(inst_id, true, std::move(enable_cb), timeout_s, Bind(std::move(timeout_cb), inst_id));
                 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,
  void EnableWithTimerCb(uint8_t inst_id, MultiAdvCb enable_cb, int timeout_s,
@@ -548,6 +596,33 @@ class BleAdvertisingManagerImpl
    }
    }
  }
  }


  void SetPeriodicAdvertisingParameters(uint8_t inst_id,
                                        tBLE_PERIODIC_ADV_PARAMS* params,
                                        MultiAdvCb cb) override {
    VLOG(1) << __func__ << " inst_id: " << +inst_id;

    GetHciInterface()->SetPeriodicAdvertisingParameters(
        inst_id, params->min_interval, params->max_interval,
        params->periodic_advertising_properties, cb);
  }

  void SetPeriodicAdvertisingData(uint8_t inst_id, std::vector<uint8_t> data,
                                  MultiAdvCb cb) override {
    VLOG(1) << __func__ << " inst_id: " << +inst_id;

    VLOG(1) << "data is: " << base::HexEncode(data.data(), data.size());

    GetHciInterface()->SetPeriodicAdvertisingData(inst_id, 0x03, data.size(),
                                                  data.data(), cb);
  }

  void SetPeriodicAdvertisingEnable(uint8_t inst_id, uint8_t enable,
                                    MultiAdvCb cb) override {
    VLOG(1) << __func__ << " inst_id: " << +inst_id << ", enable: " << +enable;

    GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, cb);
  }

  void Unregister(uint8_t inst_id) override {
  void Unregister(uint8_t inst_id) override {
    AdvertisingInstance* p_inst = &adv_inst[inst_id];
    AdvertisingInstance* p_inst = &adv_inst[inst_id];


@@ -604,7 +679,6 @@ class BleAdvertisingManagerImpl
  uint8_t inst_count;
  uint8_t inst_count;
};
};


namespace {
BleAdvertisingManager* instance;
BleAdvertisingManager* instance;
}
}


+13 −0
Original line number Original line Diff line number Diff line
@@ -123,6 +123,19 @@ class BleAdvertisingManager {
  virtual void SetData(uint8_t inst_id, bool is_scan_rsp,
  virtual void SetData(uint8_t inst_id, bool is_scan_rsp,
                       std::vector<uint8_t> data, MultiAdvCb cb) = 0;
                       std::vector<uint8_t> data, MultiAdvCb cb) = 0;


  /* This function configure instance with the specified periodic parameters */
  virtual void SetPeriodicAdvertisingParameters(
      uint8_t inst_id, tBLE_PERIODIC_ADV_PARAMS* params, MultiAdvCb cb) = 0;

  /* This function configure instance with the specified periodic data */
  virtual void SetPeriodicAdvertisingData(uint8_t inst_id,
                                          std::vector<uint8_t> data,
                                          MultiAdvCb cb) = 0;

  /* This function enables/disables periodic advertising on selected instance */
  virtual void SetPeriodicAdvertisingEnable(uint8_t inst_id, uint8_t enable,
                                            MultiAdvCb cb) = 0;

  /*  This function disable a Multi-ADV instance */
  /*  This function disable a Multi-ADV instance */
  virtual void Unregister(uint8_t inst_id) = 0;
  virtual void Unregister(uint8_t inst_id) = 0;