Home | History | Annotate | Download | only in btm
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2017  The Android Open Source Project
      4  *  Copyright (C) 2014  Broadcom Corporation
      5  *
      6  *  Licensed under the Apache License, Version 2.0 (the "License");
      7  *  you may not use this file except in compliance with the License.
      8  *  You may obtain a copy of the License at:
      9  *
     10  *  http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  *  Unless required by applicable law or agreed to in writing, software
     13  *  distributed under the License is distributed on an "AS IS" BASIS,
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  *
     18  ******************************************************************************/
     19 
     20 #include <base/bind.h>
     21 #include <base/logging.h>
     22 #include <base/strings/string_number_conversions.h>
     23 #include <string.h>
     24 #include <queue>
     25 #include <vector>
     26 
     27 #include "bt_target.h"
     28 #include "device/include/controller.h"
     29 #include "osi/include/alarm.h"
     30 
     31 #include "ble_advertiser.h"
     32 #include "ble_advertiser_hci_interface.h"
     33 #include "btm_int_types.h"
     34 
     35 using base::Bind;
     36 using RegisterCb =
     37     base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>;
     38 using IdTxPowerStatusCb = base::Callback<void(
     39     uint8_t /* inst_id */, int8_t /* tx_power */, uint8_t /* status */)>;
     40 extern void btm_gen_resolvable_private_addr(
     41     base::Callback<void(uint8_t[8])> cb);
     42 extern fixed_queue_t* btu_general_alarm_queue;
     43 
     44 constexpr int ADV_DATA_LEN_MAX = 251;
     45 
     46 namespace {
     47 
     48 bool is_connectable(uint16_t advertising_event_properties) {
     49   return advertising_event_properties & 0x01;
     50 }
     51 
     52 struct AdvertisingInstance {
     53   uint8_t inst_id;
     54   bool in_use;
     55   uint8_t advertising_event_properties;
     56   alarm_t* adv_raddr_timer;
     57   int8_t tx_power;
     58   uint16_t duration;
     59   uint8_t maxExtAdvEvents;
     60   alarm_t* timeout_timer;
     61   uint8_t own_address_type;
     62   BD_ADDR own_address;
     63   MultiAdvCb timeout_cb;
     64   bool address_update_required;
     65 
     66   /* When true, advertising set is enabled, or last scheduled call to "LE Set
     67    * Extended Advertising Set Enable" is to enable this advertising set. Any
     68    * command scheduled when in this state will execute when the set is enabled,
     69    * unless enabling fails.
     70    *
     71    * When false, advertising set is disabled, or last scheduled call to "LE Set
     72    * Extended Advertising Set Enable" is to disable this advertising set. Any
     73    * command scheduled when in this state will execute when the set is disabled.
     74    */
     75   bool enable_status;
     76 
     77   bool IsEnabled() { return enable_status; }
     78 
     79   bool IsConnectable() { return is_connectable(advertising_event_properties); }
     80 
     81   AdvertisingInstance(int inst_id)
     82       : inst_id(inst_id),
     83         in_use(false),
     84         advertising_event_properties(0),
     85         tx_power(0),
     86         duration(0),
     87         timeout_timer(nullptr),
     88         own_address_type(0),
     89         own_address{0},
     90         address_update_required(false),
     91         enable_status(false) {
     92     adv_raddr_timer = alarm_new_periodic("btm_ble.adv_raddr_timer");
     93   }
     94 
     95   ~AdvertisingInstance() {
     96     alarm_free(adv_raddr_timer);
     97     if (timeout_timer) alarm_free(timeout_timer);
     98   }
     99 };
    100 
    101 void btm_ble_adv_raddr_timer_timeout(void* data);
    102 
    103 void DoNothing(uint8_t) {}
    104 void DoNothing2(uint8_t, uint8_t) {}
    105 
    106 struct closure_data {
    107   base::Closure user_task;
    108   tracked_objects::Location posted_from;
    109 };
    110 
    111 static void alarm_closure_cb(void* p) {
    112   closure_data* data = (closure_data*)p;
    113   VLOG(1) << "executing timer scheduled at %s" << data->posted_from.ToString();
    114   data->user_task.Run();
    115   delete data;
    116 }
    117 
    118 // Periodic alarms are not supported, because we clean up data in callback
    119 void alarm_set_closure_on_queue(const tracked_objects::Location& posted_from,
    120                                 alarm_t* alarm, period_ms_t interval_ms,
    121                                 base::Closure user_task, fixed_queue_t* queue) {
    122   closure_data* data = new closure_data;
    123   data->posted_from = posted_from;
    124   data->user_task = std::move(user_task);
    125   VLOG(1) << "scheduling timer %s" << data->posted_from.ToString();
    126   alarm_set_on_queue(alarm, interval_ms, alarm_closure_cb, data, queue);
    127 }
    128 
    129 class BleAdvertisingManagerImpl;
    130 
    131 /* a temporary type for holding all the data needed in callbacks below*/
    132 struct CreatorParams {
    133   uint8_t inst_id;
    134   BleAdvertisingManagerImpl* self;
    135   IdTxPowerStatusCb cb;
    136   tBTM_BLE_ADV_PARAMS params;
    137   std::vector<uint8_t> advertise_data;
    138   std::vector<uint8_t> scan_response_data;
    139   tBLE_PERIODIC_ADV_PARAMS periodic_params;
    140   std::vector<uint8_t> periodic_data;
    141   uint16_t duration;
    142   uint8_t maxExtAdvEvents;
    143   RegisterCb timeout_cb;
    144 };
    145 
    146 using c_type = std::unique_ptr<CreatorParams>;
    147 
    148 class BleAdvertisingManagerImpl
    149     : public BleAdvertisingManager,
    150       public BleAdvertiserHciInterface::AdvertisingEventObserver {
    151  public:
    152   BleAdvertisingManagerImpl(BleAdvertiserHciInterface* interface) {
    153     this->hci_interface = interface;
    154     hci_interface->ReadInstanceCount(
    155         base::Bind(&BleAdvertisingManagerImpl::ReadInstanceCountCb,
    156                    base::Unretained(this)));
    157   }
    158 
    159   ~BleAdvertisingManagerImpl() { adv_inst.clear(); }
    160 
    161   void GetOwnAddress(uint8_t inst_id, GetAddressCallback cb) override {
    162     bt_bdaddr_t addr;
    163     memcpy(addr.address, adv_inst[inst_id].own_address, BD_ADDR_LEN);
    164     cb.Run(adv_inst[inst_id].own_address_type, addr);
    165   }
    166 
    167   void ReadInstanceCountCb(uint8_t instance_count) {
    168     this->inst_count = instance_count;
    169     adv_inst.reserve(inst_count);
    170     /* Initialize adv instance indices and IDs. */
    171     for (uint8_t i = 0; i < inst_count; i++) {
    172       adv_inst.emplace_back(i);
    173     }
    174   }
    175 
    176   void OnRpaGenerationComplete(base::Callback<void(bt_bdaddr_t)> cb,
    177                                uint8_t rand[8]) {
    178     VLOG(1) << __func__;
    179 
    180     bt_bdaddr_t bda;
    181 
    182     rand[2] &= (~BLE_RESOLVE_ADDR_MASK);
    183     rand[2] |= BLE_RESOLVE_ADDR_MSB;
    184 
    185     bda.address[2] = rand[0];
    186     bda.address[1] = rand[1];
    187     bda.address[0] = rand[2];
    188 
    189     BT_OCTET16 irk;
    190     BTM_GetDeviceIDRoot(irk);
    191     tSMP_ENC output;
    192 
    193     if (!SMP_Encrypt(irk, BT_OCTET16_LEN, rand, 3, &output))
    194       LOG_ASSERT(false) << "SMP_Encrypt failed";
    195 
    196     /* set hash to be LSB of rpAddress */
    197     bda.address[5] = output.param_buf[0];
    198     bda.address[4] = output.param_buf[1];
    199     bda.address[3] = output.param_buf[2];
    200 
    201     cb.Run(bda);
    202   }
    203 
    204   void GenerateRpa(base::Callback<void(bt_bdaddr_t)> cb) {
    205     btm_gen_resolvable_private_addr(
    206         Bind(&BleAdvertisingManagerImpl::OnRpaGenerationComplete,
    207              base::Unretained(this), std::move(cb)));
    208   }
    209 
    210   void ConfigureRpa(AdvertisingInstance* p_inst, MultiAdvCb configuredCb) {
    211     /* Connectable advertising set must be disabled when updating RPA */
    212     bool restart = p_inst->IsEnabled() && p_inst->IsConnectable();
    213 
    214     // If there is any form of timeout on the set, schedule address update when
    215     // the set stops, because there is no good way to compute new timeout value.
    216     // Maximum duration value is around 10 minutes, so this is safe.
    217     if (restart && (p_inst->duration || p_inst->maxExtAdvEvents)) {
    218       p_inst->address_update_required = true;
    219       configuredCb.Run(0x01);
    220       return;
    221     }
    222 
    223     GenerateRpa(Bind(
    224         [](AdvertisingInstance* p_inst, MultiAdvCb configuredCb,
    225            bt_bdaddr_t bda) {
    226           /* Connectable advertising set must be disabled when updating RPA */
    227           bool restart = p_inst->IsEnabled() && p_inst->IsConnectable();
    228 
    229           auto hci_interface =
    230               ((BleAdvertisingManagerImpl*)BleAdvertisingManager::Get())
    231                   ->GetHciInterface();
    232 
    233           if (restart) {
    234             p_inst->enable_status = false;
    235             hci_interface->Enable(false, p_inst->inst_id, 0x00, 0x00,
    236                                   Bind(DoNothing));
    237           }
    238 
    239           /* set it to controller */
    240           hci_interface->SetRandomAddress(
    241               p_inst->inst_id, p_inst->own_address,
    242               Bind(
    243                   [](AdvertisingInstance* p_inst, bt_bdaddr_t bda,
    244                      MultiAdvCb configuredCb, uint8_t status) {
    245                     memcpy(p_inst->own_address, &bda, BD_ADDR_LEN);
    246                     configuredCb.Run(0x00);
    247                   },
    248                   p_inst, bda, configuredCb));
    249 
    250           if (restart) {
    251             p_inst->enable_status = true;
    252             hci_interface->Enable(true, p_inst->inst_id, 0x00, 0x00,
    253                                   Bind(DoNothing));
    254           }
    255         },
    256         p_inst, std::move(configuredCb)));
    257   }
    258 
    259   void RegisterAdvertiser(
    260       base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)> cb)
    261       override {
    262     AdvertisingInstance* p_inst = &adv_inst[0];
    263     for (uint8_t i = 0; i < inst_count; i++, p_inst++) {
    264       if (p_inst->in_use) continue;
    265 
    266       p_inst->in_use = true;
    267 
    268       // set up periodic timer to update address.
    269       if (BTM_BleLocalPrivacyEnabled()) {
    270         p_inst->own_address_type = BLE_ADDR_RANDOM;
    271         GenerateRpa(Bind(
    272             [](AdvertisingInstance* p_inst,
    273                base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>
    274                    cb,
    275                bt_bdaddr_t bda) {
    276               memcpy(p_inst->own_address, &bda, BD_ADDR_LEN);
    277 
    278               alarm_set_on_queue(p_inst->adv_raddr_timer,
    279                                  BTM_BLE_PRIVATE_ADDR_INT_MS,
    280                                  btm_ble_adv_raddr_timer_timeout, p_inst,
    281                                  btu_general_alarm_queue);
    282               cb.Run(p_inst->inst_id, BTM_BLE_MULTI_ADV_SUCCESS);
    283             },
    284             p_inst, cb));
    285       } else {
    286         p_inst->own_address_type = BLE_ADDR_PUBLIC;
    287         memcpy(p_inst->own_address,
    288                controller_get_interface()->get_address()->address, BD_ADDR_LEN);
    289 
    290         cb.Run(p_inst->inst_id, BTM_BLE_MULTI_ADV_SUCCESS);
    291       }
    292       return;
    293     }
    294 
    295     LOG(INFO) << "no free advertiser instance";
    296     cb.Run(0xFF, ADVERTISE_FAILED_TOO_MANY_ADVERTISERS);
    297   }
    298 
    299   void StartAdvertising(uint8_t advertiser_id, MultiAdvCb cb,
    300                         tBTM_BLE_ADV_PARAMS* params,
    301                         std::vector<uint8_t> advertise_data,
    302                         std::vector<uint8_t> scan_response_data, int duration,
    303                         MultiAdvCb timeout_cb) override {
    304     /* a temporary type for holding all the data needed in callbacks below*/
    305     struct CreatorParams {
    306       uint8_t inst_id;
    307       BleAdvertisingManagerImpl* self;
    308       MultiAdvCb cb;
    309       tBTM_BLE_ADV_PARAMS params;
    310       std::vector<uint8_t> advertise_data;
    311       std::vector<uint8_t> scan_response_data;
    312       int duration;
    313       MultiAdvCb timeout_cb;
    314     };
    315 
    316     std::unique_ptr<CreatorParams> c;
    317     c.reset(new CreatorParams());
    318 
    319     c->self = this;
    320     c->cb = std::move(cb);
    321     c->params = *params;
    322     c->advertise_data = std::move(advertise_data);
    323     c->scan_response_data = std::move(scan_response_data);
    324     c->duration = duration;
    325     c->timeout_cb = std::move(timeout_cb);
    326     c->inst_id = advertiser_id;
    327 
    328     using c_type = std::unique_ptr<CreatorParams>;
    329 
    330     // this code is intentionally left formatted this way to highlight the
    331     // asynchronous flow
    332     // clang-format off
    333     c->self->SetParameters(c->inst_id, &c->params, Bind(
    334       [](c_type c, uint8_t status, int8_t tx_power) {
    335         if (status != 0) {
    336           LOG(ERROR) << "setting parameters failed, status: " << +status;
    337           c->cb.Run(status);
    338           return;
    339         }
    340 
    341         c->self->adv_inst[c->inst_id].tx_power = tx_power;
    342 
    343         BD_ADDR *rpa = &c->self->adv_inst[c->inst_id].own_address;
    344         c->self->GetHciInterface()->SetRandomAddress(c->inst_id, *rpa, Bind(
    345           [](c_type c, uint8_t status) {
    346             if (status != 0) {
    347               LOG(ERROR) << "setting random address failed, status: " << +status;
    348               c->cb.Run(status);
    349               return;
    350             }
    351 
    352             c->self->SetData(c->inst_id, false, std::move(c->advertise_data), Bind(
    353               [](c_type c, uint8_t status) {
    354                 if (status != 0) {
    355                   LOG(ERROR) << "setting advertise data failed, status: " << +status;
    356                   c->cb.Run(status);
    357                   return;
    358                 }
    359 
    360                 c->self->SetData(c->inst_id, true, std::move(c->scan_response_data), Bind(
    361                   [](c_type c, uint8_t status) {
    362                     if (status != 0) {
    363                       LOG(ERROR) << "setting scan response data failed, status: " << +status;
    364                       c->cb.Run(status);
    365                       return;
    366                     }
    367 
    368                     c->self->Enable(c->inst_id, true, c->cb, c->duration, 0, std::move(c->timeout_cb));
    369 
    370                 }, base::Passed(&c)));
    371             }, base::Passed(&c)));
    372         }, base::Passed(&c)));
    373     }, base::Passed(&c)));
    374     // clang-format on
    375   }
    376 
    377   void StartAdvertisingSet(IdTxPowerStatusCb cb, tBTM_BLE_ADV_PARAMS* params,
    378                            std::vector<uint8_t> advertise_data,
    379                            std::vector<uint8_t> scan_response_data,
    380                            tBLE_PERIODIC_ADV_PARAMS* periodic_params,
    381                            std::vector<uint8_t> periodic_data,
    382                            uint16_t duration, uint8_t maxExtAdvEvents,
    383                            RegisterCb timeout_cb) override {
    384     std::unique_ptr<CreatorParams> c;
    385     c.reset(new CreatorParams());
    386 
    387     c->self = this;
    388     c->cb = std::move(cb);
    389     c->params = *params;
    390     c->advertise_data = std::move(advertise_data);
    391     c->scan_response_data = std::move(scan_response_data);
    392     c->periodic_params = *periodic_params;
    393     c->periodic_data = std::move(periodic_data);
    394     c->duration = duration;
    395     c->maxExtAdvEvents = maxExtAdvEvents;
    396     c->timeout_cb = std::move(timeout_cb);
    397 
    398 
    399     // this code is intentionally left formatted this way to highlight the
    400     // asynchronous flow
    401     // clang-format off
    402     c->self->RegisterAdvertiser(Bind(
    403       [](c_type c, uint8_t advertiser_id, uint8_t status) {
    404         if (status != 0) {
    405           LOG(ERROR) << "registering advertiser failed, status: " << +status;
    406           c->cb.Run(0, 0, status);
    407           return;
    408         }
    409 
    410         c->inst_id = advertiser_id;
    411 
    412         c->self->SetParameters(c->inst_id, &c->params, Bind(
    413           [](c_type c, uint8_t status, int8_t tx_power) {
    414             if (status != 0) {
    415               c->self->Unregister(c->inst_id);
    416               LOG(ERROR) << "setting parameters failed, status: " << +status;
    417               c->cb.Run(0, 0, status);
    418               return;
    419             }
    420 
    421             c->self->adv_inst[c->inst_id].tx_power = tx_power;
    422 
    423             BD_ADDR *rpa = &c->self->adv_inst[c->inst_id].own_address;
    424             c->self->GetHciInterface()->SetRandomAddress(c->inst_id, *rpa, Bind(
    425               [](c_type c, uint8_t status) {
    426                 if (status != 0) {
    427                   c->self->Unregister(c->inst_id);
    428                   LOG(ERROR) << "setting random address failed, status: " << +status;
    429                   c->cb.Run(0, 0, status);
    430                   return;
    431                 }
    432 
    433                 c->self->SetData(c->inst_id, false, std::move(c->advertise_data), Bind(
    434                   [](c_type c, uint8_t status) {
    435                     if (status != 0) {
    436                       c->self->Unregister(c->inst_id);
    437                       LOG(ERROR) << "setting advertise data failed, status: " << +status;
    438                       c->cb.Run(0, 0, status);
    439                       return;
    440                     }
    441 
    442                     c->self->SetData(c->inst_id, true, std::move(c->scan_response_data), Bind(
    443                       [](c_type c, uint8_t status) {
    444                         if (status != 0) {
    445                           c->self->Unregister(c->inst_id);
    446                           LOG(ERROR) << "setting scan response data failed, status: " << +status;
    447                           c->cb.Run(0, 0, status);
    448                           return;
    449                         }
    450 
    451                         if (c->periodic_params.enable) {
    452                           c->self->StartAdvertisingSetPeriodicPart(std::move(c));
    453                         } else {
    454                           c->self->StartAdvertisingSetFinish(std::move(c));
    455                         }
    456                     }, base::Passed(&c)));
    457                 }, base::Passed(&c)));
    458             }, base::Passed(&c)));
    459         }, base::Passed(&c)));
    460     }, base::Passed(&c)));
    461     // clang-format on
    462   }
    463 
    464   void StartAdvertisingSetPeriodicPart(c_type c) {
    465     // this code is intentionally left formatted this way to highlight the
    466     // asynchronous flow
    467     // clang-format off
    468     c->self->SetPeriodicAdvertisingParameters(c->inst_id, &c->periodic_params, Bind(
    469       [](c_type c, uint8_t status) {
    470         if (status != 0) {
    471           c->self->Unregister(c->inst_id);
    472           LOG(ERROR) << "setting periodic parameters failed, status: " << +status;
    473           c->cb.Run(0, 0, status);
    474           return;
    475         }
    476 
    477         c->self->SetPeriodicAdvertisingData(c->inst_id, std::move(c->periodic_data), Bind(
    478           [](c_type c, uint8_t status) {
    479             if (status != 0) {
    480               c->self->Unregister(c->inst_id);
    481               LOG(ERROR) << "setting periodic parameters failed, status: " << +status;
    482               c->cb.Run(0, 0, status);
    483               return;
    484             }
    485 
    486             c->self->SetPeriodicAdvertisingEnable(c->inst_id, true, Bind(
    487               [](c_type c, uint8_t status) {
    488                 if (status != 0) {
    489                   c->self->Unregister(c->inst_id);
    490                   LOG(ERROR) << "enabling periodic advertising failed, status: " << +status;
    491                   c->cb.Run(0, 0, status);
    492                   return;
    493                 }
    494 
    495                 c->self->StartAdvertisingSetFinish(std::move(c));
    496 
    497               }, base::Passed(&c)));
    498         }, base::Passed(&c)));
    499     }, base::Passed(&c)));
    500     // clang-format on
    501   }
    502 
    503   void StartAdvertisingSetFinish(c_type c) {
    504     uint8_t inst_id = c->inst_id;
    505     uint16_t duration = c->duration;
    506     uint8_t maxExtAdvEvents = c->maxExtAdvEvents;
    507     RegisterCb timeout_cb = std::move(c->timeout_cb);
    508     BleAdvertisingManagerImpl* self = c->self;
    509     MultiAdvCb enable_cb = Bind(
    510         [](c_type c, uint8_t status) {
    511           if (status != 0) {
    512             c->self->Unregister(c->inst_id);
    513             LOG(ERROR) << "enabling advertiser failed, status: " << +status;
    514             c->cb.Run(0, 0, status);
    515             return;
    516           }
    517           int8_t tx_power = c->self->adv_inst[c->inst_id].tx_power;
    518           c->cb.Run(c->inst_id, tx_power, status);
    519         },
    520         base::Passed(&c));
    521 
    522     self->Enable(inst_id, true, std::move(enable_cb), duration, maxExtAdvEvents,
    523                  Bind(std::move(timeout_cb), inst_id));
    524   }
    525 
    526   void EnableWithTimerCb(uint8_t inst_id, MultiAdvCb enable_cb, int duration,
    527                          MultiAdvCb timeout_cb, uint8_t status) {
    528     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    529     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    530 
    531     // Run the regular enable callback
    532     enable_cb.Run(status);
    533 
    534     p_inst->timeout_timer = alarm_new("btm_ble.adv_timeout");
    535 
    536     base::Closure cb = Bind(&BleAdvertisingManagerImpl::Enable,
    537                             base::Unretained(this), inst_id, 0 /* disable */,
    538                             std::move(timeout_cb), 0, 0, base::Bind(DoNothing));
    539 
    540     // schedule disable when the timeout passes
    541     alarm_set_closure_on_queue(FROM_HERE, p_inst->timeout_timer, duration * 10,
    542                                std::move(cb), btu_general_alarm_queue);
    543   }
    544 
    545   void Enable(uint8_t inst_id, bool enable, MultiAdvCb cb, uint16_t duration,
    546               uint8_t maxExtAdvEvents, MultiAdvCb timeout_cb) override {
    547     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    548     if (inst_id >= inst_count) {
    549       LOG(ERROR) << "bad instance id " << +inst_id;
    550       return;
    551     }
    552 
    553     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    554     VLOG(1) << __func__ << " enable: " << enable << ", duration: " << +duration;
    555     if (!p_inst->in_use) {
    556       LOG(ERROR) << "Invalid or no active instance";
    557       cb.Run(BTM_BLE_MULTI_ADV_FAILURE);
    558       return;
    559     }
    560 
    561     if (enable && (duration || maxExtAdvEvents)) {
    562       p_inst->timeout_cb = std::move(timeout_cb);
    563     }
    564 
    565     p_inst->duration = duration;
    566     p_inst->maxExtAdvEvents = maxExtAdvEvents;
    567 
    568     if (enable && p_inst->address_update_required) {
    569       p_inst->address_update_required = false;
    570       ConfigureRpa(p_inst, base::Bind(&BleAdvertisingManagerImpl::EnableFinish,
    571                                       base::Unretained(this), p_inst, enable,
    572                                       std::move(cb)));
    573       return;
    574     }
    575 
    576     EnableFinish(p_inst, enable, std::move(cb), 0);
    577   }
    578 
    579   void EnableFinish(AdvertisingInstance* p_inst, bool enable, MultiAdvCb cb,
    580                     uint8_t status) {
    581     if (enable && p_inst->duration) {
    582       p_inst->enable_status = enable;
    583       // TODO(jpawlowski): HCI implementation that can't do duration should
    584       // emulate it, not EnableWithTimerCb.
    585       GetHciInterface()->Enable(
    586           enable, p_inst->inst_id, p_inst->duration, p_inst->maxExtAdvEvents,
    587           Bind(&BleAdvertisingManagerImpl::EnableWithTimerCb,
    588                base::Unretained(this), p_inst->inst_id, std::move(cb),
    589                p_inst->duration, p_inst->timeout_cb));
    590 
    591     } else {
    592       if (p_inst->timeout_timer) {
    593         alarm_cancel(p_inst->timeout_timer);
    594         alarm_free(p_inst->timeout_timer);
    595         p_inst->timeout_timer = nullptr;
    596       }
    597 
    598       p_inst->enable_status = enable;
    599       GetHciInterface()->Enable(enable, p_inst->inst_id, p_inst->duration,
    600                                 p_inst->maxExtAdvEvents, std::move(cb));
    601     }
    602   }
    603 
    604   void SetParameters(uint8_t inst_id, tBTM_BLE_ADV_PARAMS* p_params,
    605                      ParametersCb cb) override {
    606     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    607     if (inst_id >= inst_count) {
    608       LOG(ERROR) << "bad instance id " << +inst_id;
    609       return;
    610     }
    611 
    612     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    613     if (!p_inst->in_use) {
    614       LOG(ERROR) << "adv instance not in use" << +inst_id;
    615       cb.Run(BTM_BLE_MULTI_ADV_FAILURE, 0);
    616       return;
    617     }
    618 
    619     // TODO: disable only if was enabled, currently no use scenario needs that,
    620     // we always set parameters before enabling
    621     // GetHciInterface()->Enable(false, inst_id, Bind(DoNothing));
    622     p_inst->advertising_event_properties =
    623         p_params->advertising_event_properties;
    624     p_inst->tx_power = p_params->tx_power;
    625     BD_ADDR peer_address = {0, 0, 0, 0, 0, 0};
    626 
    627     GetHciInterface()->SetParameters(
    628         p_inst->inst_id, p_params->advertising_event_properties,
    629         p_params->adv_int_min, p_params->adv_int_max, p_params->channel_map,
    630         p_inst->own_address_type, p_inst->own_address, 0x00, peer_address,
    631         p_params->adv_filter_policy, p_inst->tx_power,
    632         p_params->primary_advertising_phy, 0x01,
    633         p_params->secondary_advertising_phy, 0x01 /* TODO: proper SID */,
    634         p_params->scan_request_notification_enable, cb);
    635 
    636     // TODO: re-enable only if it was enabled, properly call
    637     // SetParamsCallback
    638     // currently no use scenario needs that
    639     // GetHciInterface()->Enable(true, inst_id, BTM_BleUpdateAdvInstParamCb);
    640   }
    641 
    642   void SetData(uint8_t inst_id, bool is_scan_rsp, std::vector<uint8_t> data,
    643                MultiAdvCb cb) override {
    644     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    645     if (inst_id >= inst_count) {
    646       LOG(ERROR) << "bad instance id " << +inst_id;
    647       return;
    648     }
    649 
    650     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    651     VLOG(1) << "is_scan_rsp = " << is_scan_rsp;
    652 
    653     if (!is_scan_rsp && is_connectable(p_inst->advertising_event_properties)) {
    654       uint8_t flags_val = BTM_GENERAL_DISCOVERABLE;
    655 
    656       if (p_inst->duration) flags_val = BTM_LIMITED_DISCOVERABLE;
    657 
    658       std::vector<uint8_t> flags;
    659       flags.push_back(2);  // length
    660       flags.push_back(HCI_EIR_FLAGS_TYPE);
    661       flags.push_back(flags_val);
    662 
    663       data.insert(data.begin(), flags.begin(), flags.end());
    664     }
    665 
    666     // Find and fill TX Power with the correct value
    667     if (data.size()) {
    668       size_t i = 0;
    669       while (i < data.size()) {
    670         uint8_t type = data[i + 1];
    671         if (type == HCI_EIR_TX_POWER_LEVEL_TYPE) {
    672           data[i + 2] = adv_inst[inst_id].tx_power;
    673         }
    674         i += data[i] + 1;
    675       }
    676     }
    677 
    678     VLOG(1) << "data is: " << base::HexEncode(data.data(), data.size());
    679     DivideAndSendData(
    680         inst_id, data, cb,
    681         base::Bind(&BleAdvertisingManagerImpl::SetDataAdvDataSender,
    682                    base::Unretained(this), is_scan_rsp));
    683   }
    684 
    685   void SetDataAdvDataSender(uint8_t is_scan_rsp, uint8_t inst_id,
    686                             uint8_t operation, uint8_t length, uint8_t* data,
    687                             MultiAdvCb cb) {
    688     if (is_scan_rsp)
    689       GetHciInterface()->SetScanResponseData(inst_id, operation, 0x01, length,
    690                                              data, cb);
    691     else
    692       GetHciInterface()->SetAdvertisingData(inst_id, operation, 0x01, length,
    693                                             data, cb);
    694   }
    695 
    696   using DataSender = base::Callback<void(
    697       uint8_t /*inst_id*/, uint8_t /* operation */, uint8_t /* length */,
    698       uint8_t* /* data */, MultiAdvCb /* done */)>;
    699 
    700   void DivideAndSendData(int inst_id, std::vector<uint8_t> data,
    701                          MultiAdvCb done_cb, DataSender sender) {
    702     DivideAndSendDataRecursively(true, inst_id, std::move(data), 0,
    703                                  std::move(done_cb), std::move(sender), 0);
    704   }
    705 
    706   static void DivideAndSendDataRecursively(bool isFirst, int inst_id,
    707                                            std::vector<uint8_t> data,
    708                                            int offset, MultiAdvCb done_cb,
    709                                            DataSender sender, uint8_t status) {
    710     constexpr uint8_t INTERMEDIATE =
    711         0x00;                        // Intermediate fragment of fragmented data
    712     constexpr uint8_t FIRST = 0x01;  // First fragment of fragmented data
    713     constexpr uint8_t LAST = 0x02;   // Last fragment of fragmented data
    714     constexpr uint8_t COMPLETE = 0x03;  // Complete extended advertising data
    715 
    716     int dataSize = (int)data.size();
    717     if (status != 0 || (!isFirst && offset == dataSize)) {
    718       /* if we got error writing data, or reached the end of data */
    719       done_cb.Run(status);
    720       return;
    721     }
    722 
    723     bool moreThanOnePacket = dataSize - offset > ADV_DATA_LEN_MAX;
    724     uint8_t operation = isFirst ? moreThanOnePacket ? FIRST : COMPLETE
    725                                 : moreThanOnePacket ? INTERMEDIATE : LAST;
    726     int length = moreThanOnePacket ? ADV_DATA_LEN_MAX : dataSize - offset;
    727     int newOffset = offset + length;
    728 
    729     sender.Run(
    730         inst_id, operation, length, data.data() + offset,
    731         Bind(&BleAdvertisingManagerImpl::DivideAndSendDataRecursively, false,
    732              inst_id, std::move(data), newOffset, std::move(done_cb), sender));
    733   }
    734 
    735   void SetPeriodicAdvertisingParameters(uint8_t inst_id,
    736                                         tBLE_PERIODIC_ADV_PARAMS* params,
    737                                         MultiAdvCb cb) override {
    738     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    739 
    740     GetHciInterface()->SetPeriodicAdvertisingParameters(
    741         inst_id, params->min_interval, params->max_interval,
    742         params->periodic_advertising_properties, cb);
    743   }
    744 
    745   void SetPeriodicAdvertisingData(uint8_t inst_id, std::vector<uint8_t> data,
    746                                   MultiAdvCb cb) override {
    747     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    748 
    749     VLOG(1) << "data is: " << base::HexEncode(data.data(), data.size());
    750 
    751     DivideAndSendData(
    752         inst_id, data, cb,
    753         base::Bind(&BleAdvertiserHciInterface::SetPeriodicAdvertisingData,
    754                    base::Unretained(GetHciInterface())));
    755   }
    756 
    757   void SetPeriodicAdvertisingEnable(uint8_t inst_id, uint8_t enable,
    758                                     MultiAdvCb cb) override {
    759     VLOG(1) << __func__ << " inst_id: " << +inst_id << ", enable: " << +enable;
    760 
    761     GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id, cb);
    762   }
    763 
    764   void Unregister(uint8_t inst_id) override {
    765     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    766 
    767     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    768     if (inst_id >= inst_count) {
    769       LOG(ERROR) << "bad instance id " << +inst_id;
    770       return;
    771     }
    772 
    773     if (adv_inst[inst_id].IsEnabled()) {
    774       p_inst->enable_status = false;
    775       GetHciInterface()->Enable(false, inst_id, 0x00, 0x00, Bind(DoNothing));
    776     }
    777 
    778     alarm_cancel(p_inst->adv_raddr_timer);
    779     p_inst->in_use = false;
    780     GetHciInterface()->RemoveAdvertisingSet(inst_id, Bind(DoNothing));
    781     p_inst->address_update_required = false;
    782   }
    783 
    784   void OnAdvertisingSetTerminated(
    785       uint8_t status, uint8_t advertising_handle, uint16_t connection_handle,
    786       uint8_t num_completed_extended_adv_events) override {
    787     AdvertisingInstance* p_inst = &adv_inst[advertising_handle];
    788     VLOG(1) << __func__ << "status: 0x" << std::hex << +status
    789             << ", advertising_handle: 0x" << std::hex << +advertising_handle
    790             << ", connection_handle: 0x" << std::hex << +connection_handle;
    791 
    792     if (status == 0x43 || status == 0x3C) {
    793       // either duration elapsed, or maxExtAdvEvents reached
    794       p_inst->enable_status = false;
    795 
    796       if (p_inst->timeout_cb.is_null()) {
    797         LOG(INFO) << __func__ << "No timeout callback";
    798         return;
    799       }
    800 
    801       p_inst->timeout_cb.Run(status);
    802       return;
    803     }
    804 
    805     if (BTM_BleLocalPrivacyEnabled() &&
    806         advertising_handle <= BTM_BLE_MULTI_ADV_MAX) {
    807       btm_acl_update_conn_addr(connection_handle, p_inst->own_address);
    808     }
    809 
    810     VLOG(1) << "reneabling advertising";
    811 
    812     if (p_inst->in_use == true) {
    813       // TODO(jpawlowski): we don't really allow to do directed advertising
    814       // right now. This should probably be removed, check with Andre.
    815       if ((p_inst->advertising_event_properties & 0x0C) ==
    816           0 /* directed advertising bits not set */) {
    817         GetHciInterface()->Enable(true, advertising_handle, 0x00, 0x00,
    818                                   Bind(DoNothing));
    819       } else {
    820         /* mark directed adv as disabled if adv has been stopped */
    821         p_inst->in_use = false;
    822       }
    823     }
    824   }
    825 
    826  private:
    827   BleAdvertiserHciInterface* GetHciInterface() { return hci_interface; }
    828 
    829   BleAdvertiserHciInterface* hci_interface = nullptr;
    830   std::vector<AdvertisingInstance> adv_inst;
    831   uint8_t inst_count;
    832 };
    833 
    834 BleAdvertisingManager* instance;
    835 
    836 void btm_ble_adv_raddr_timer_timeout(void* data) {
    837   ((BleAdvertisingManagerImpl*)BleAdvertisingManager::Get())
    838       ->ConfigureRpa((AdvertisingInstance*)data, base::Bind(DoNothing));
    839 }
    840 }  // namespace
    841 
    842 void BleAdvertisingManager::Initialize(BleAdvertiserHciInterface* interface) {
    843   instance = new BleAdvertisingManagerImpl(interface);
    844 }
    845 
    846 BleAdvertisingManager* BleAdvertisingManager::Get() {
    847   CHECK(instance);
    848   return instance;
    849 };
    850 
    851 void BleAdvertisingManager::CleanUp() {
    852   delete instance;
    853   instance = nullptr;
    854 };
    855 
    856 /**
    857  * This function initialize the advertising manager.
    858  **/
    859 void btm_ble_adv_init() {
    860   BleAdvertiserHciInterface::Initialize();
    861   BleAdvertisingManager::Initialize(BleAdvertiserHciInterface::Get());
    862   BleAdvertiserHciInterface::Get()->SetAdvertisingEventObserver(
    863       (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get());
    864 
    865   if (BleAdvertiserHciInterface::Get()->QuirkAdvertiserZeroHandle()) {
    866     // If handle 0 can't be used, register advertiser for it, but never use it.
    867     BleAdvertisingManager::Get()->RegisterAdvertiser(Bind(DoNothing2));
    868   }
    869 }
    870 
    871 /*******************************************************************************
    872  *
    873  * Function         btm_ble_multi_adv_cleanup
    874  *
    875  * Description      This function cleans up multi adv control block.
    876  *
    877  * Parameters
    878  * Returns          void
    879  *
    880  ******************************************************************************/
    881 void btm_ble_multi_adv_cleanup(void) {
    882   BleAdvertisingManager::CleanUp();
    883   BleAdvertiserHciInterface::CleanUp();
    884 }
    885