Home | History | Annotate | Download | only in btm
      1 /******************************************************************************
      2  *
      3  *  Copyright 2017  The Android Open Source Project
      4  *  Copyright 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/location.h>
     22 #include <base/logging.h>
     23 #include <base/memory/weak_ptr.h>
     24 #include <base/strings/string_number_conversions.h>
     25 #include <base/time/time.h>
     26 #include <string.h>
     27 #include <queue>
     28 #include <vector>
     29 
     30 #include "bt_target.h"
     31 #include "device/include/controller.h"
     32 #include "osi/include/alarm.h"
     33 
     34 #include "ble_advertiser.h"
     35 #include "ble_advertiser_hci_interface.h"
     36 #include "btm_int_types.h"
     37 
     38 using base::Bind;
     39 using base::TimeDelta;
     40 using base::TimeTicks;
     41 using RegisterCb =
     42     base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>;
     43 using IdTxPowerStatusCb = base::Callback<void(
     44     uint8_t /* inst_id */, int8_t /* tx_power */, uint8_t /* status */)>;
     45 using SetEnableData = BleAdvertiserHciInterface::SetEnableData;
     46 extern void btm_gen_resolvable_private_addr(
     47     base::Callback<void(uint8_t[8])> cb);
     48 
     49 constexpr int ADV_DATA_LEN_MAX = 251;
     50 
     51 namespace {
     52 
     53 bool is_connectable(uint16_t advertising_event_properties) {
     54   return advertising_event_properties & 0x01;
     55 }
     56 
     57 struct AdvertisingInstance {
     58   uint8_t inst_id;
     59   bool in_use;
     60   uint8_t advertising_event_properties;
     61   alarm_t* adv_raddr_timer;
     62   int8_t tx_power;
     63   uint16_t duration;  // 1 unit is 10ms
     64   uint8_t maxExtAdvEvents;
     65   alarm_t* timeout_timer;
     66   uint8_t own_address_type;
     67   RawAddress own_address;
     68   MultiAdvCb timeout_cb;
     69   bool address_update_required;
     70   bool periodic_enabled;
     71   uint32_t advertising_interval;  // 1 unit is 0.625 ms
     72 
     73   /* When true, advertising set is enabled, or last scheduled call to "LE Set
     74    * Extended Advertising Set Enable" is to enable this advertising set. Any
     75    * command scheduled when in this state will execute when the set is enabled,
     76    * unless enabling fails.
     77    *
     78    * When false, advertising set is disabled, or last scheduled call to "LE Set
     79    * Extended Advertising Set Enable" is to disable this advertising set. Any
     80    * command scheduled when in this state will execute when the set is disabled.
     81    */
     82   bool enable_status;
     83   TimeTicks enable_time;
     84 
     85   bool IsEnabled() { return enable_status; }
     86 
     87   bool IsConnectable() { return is_connectable(advertising_event_properties); }
     88 
     89   AdvertisingInstance(int inst_id)
     90       : inst_id(inst_id),
     91         in_use(false),
     92         advertising_event_properties(0),
     93         tx_power(0),
     94         duration(0),
     95         timeout_timer(nullptr),
     96         own_address_type(0),
     97         own_address(RawAddress::kEmpty),
     98         address_update_required(false),
     99         periodic_enabled(false),
    100         enable_status(false) {
    101     adv_raddr_timer = alarm_new_periodic("btm_ble.adv_raddr_timer");
    102   }
    103 
    104   ~AdvertisingInstance() {
    105     alarm_free(adv_raddr_timer);
    106     adv_raddr_timer = nullptr;
    107     if (timeout_timer) {
    108       alarm_free(timeout_timer);
    109       timeout_timer = nullptr;
    110     }
    111   }
    112 };
    113 
    114 void btm_ble_adv_raddr_timer_timeout(void* data);
    115 
    116 void DoNothing(uint8_t) {}
    117 void DoNothing2(uint8_t, uint8_t) {}
    118 
    119 struct closure_data {
    120   base::Closure user_task;
    121   tracked_objects::Location posted_from;
    122 };
    123 
    124 static void alarm_closure_cb(void* p) {
    125   closure_data* data = (closure_data*)p;
    126   VLOG(1) << "executing timer scheduled at %s" << data->posted_from.ToString();
    127   data->user_task.Run();
    128   delete data;
    129 }
    130 
    131 // Periodic alarms are not supported, because we clean up data in callback
    132 void alarm_set_closure(const tracked_objects::Location& posted_from,
    133                        alarm_t* alarm, period_ms_t interval_ms,
    134                        base::Closure user_task) {
    135   closure_data* data = new closure_data;
    136   data->posted_from = posted_from;
    137   data->user_task = std::move(user_task);
    138   VLOG(1) << "scheduling timer %s" << data->posted_from.ToString();
    139   alarm_set_on_mloop(alarm, interval_ms, alarm_closure_cb, data);
    140 }
    141 
    142 class BleAdvertisingManagerImpl;
    143 
    144 /* a temporary type for holding all the data needed in callbacks below*/
    145 struct CreatorParams {
    146   uint8_t inst_id;
    147   base::WeakPtr<BleAdvertisingManagerImpl> self;
    148   IdTxPowerStatusCb cb;
    149   tBTM_BLE_ADV_PARAMS params;
    150   std::vector<uint8_t> advertise_data;
    151   std::vector<uint8_t> scan_response_data;
    152   tBLE_PERIODIC_ADV_PARAMS periodic_params;
    153   std::vector<uint8_t> periodic_data;
    154   uint16_t duration;
    155   uint8_t maxExtAdvEvents;
    156   RegisterCb timeout_cb;
    157 };
    158 
    159 using c_type = std::unique_ptr<CreatorParams>;
    160 
    161 BleAdvertisingManager* instance;
    162 base::WeakPtr<BleAdvertisingManagerImpl> instance_weakptr;
    163 
    164 class BleAdvertisingManagerImpl
    165     : public BleAdvertisingManager,
    166       public BleAdvertiserHciInterface::AdvertisingEventObserver {
    167  public:
    168   BleAdvertisingManagerImpl(BleAdvertiserHciInterface* interface)
    169       : hci_interface(interface), weak_factory_(this) {
    170     hci_interface->ReadInstanceCount(
    171         base::Bind(&BleAdvertisingManagerImpl::ReadInstanceCountCb,
    172                    weak_factory_.GetWeakPtr()));
    173   }
    174 
    175   ~BleAdvertisingManagerImpl() { adv_inst.clear(); }
    176 
    177   void GetOwnAddress(uint8_t inst_id, GetAddressCallback cb) override {
    178     cb.Run(adv_inst[inst_id].own_address_type, adv_inst[inst_id].own_address);
    179   }
    180 
    181   void ReadInstanceCountCb(uint8_t instance_count) {
    182     this->inst_count = instance_count;
    183     adv_inst.reserve(inst_count);
    184     /* Initialize adv instance indices and IDs. */
    185     for (uint8_t i = 0; i < inst_count; i++) {
    186       adv_inst.emplace_back(i);
    187     }
    188   }
    189 
    190   void OnRpaGenerationComplete(base::Callback<void(RawAddress)> cb,
    191                                uint8_t rand[8]) {
    192     VLOG(1) << __func__;
    193 
    194     RawAddress bda;
    195 
    196     rand[2] &= (~BLE_RESOLVE_ADDR_MASK);
    197     rand[2] |= BLE_RESOLVE_ADDR_MSB;
    198 
    199     bda.address[2] = rand[0];
    200     bda.address[1] = rand[1];
    201     bda.address[0] = rand[2];
    202 
    203     BT_OCTET16 irk;
    204     BTM_GetDeviceIDRoot(irk);
    205     tSMP_ENC output;
    206 
    207     if (!SMP_Encrypt(irk, BT_OCTET16_LEN, rand, 3, &output))
    208       LOG_ASSERT(false) << "SMP_Encrypt failed";
    209 
    210     /* set hash to be LSB of rpAddress */
    211     bda.address[5] = output.param_buf[0];
    212     bda.address[4] = output.param_buf[1];
    213     bda.address[3] = output.param_buf[2];
    214 
    215     cb.Run(bda);
    216   }
    217 
    218   void GenerateRpa(base::Callback<void(RawAddress)> cb) {
    219     btm_gen_resolvable_private_addr(
    220         Bind(&BleAdvertisingManagerImpl::OnRpaGenerationComplete,
    221              weak_factory_.GetWeakPtr(), std::move(cb)));
    222   }
    223 
    224   void ConfigureRpa(AdvertisingInstance* p_inst, MultiAdvCb configuredCb) {
    225     /* Connectable advertising set must be disabled when updating RPA */
    226     bool restart = p_inst->IsEnabled() && p_inst->IsConnectable();
    227 
    228     // If there is any form of timeout on the set, schedule address update when
    229     // the set stops, because there is no good way to compute new timeout value.
    230     // Maximum duration value is around 10 minutes, so this is safe.
    231     if (restart && (p_inst->duration || p_inst->maxExtAdvEvents)) {
    232       p_inst->address_update_required = true;
    233       configuredCb.Run(0x01);
    234       return;
    235     }
    236 
    237     GenerateRpa(Bind(
    238         [](AdvertisingInstance* p_inst, MultiAdvCb configuredCb,
    239            RawAddress bda) {
    240           /* Connectable advertising set must be disabled when updating RPA */
    241           bool restart = p_inst->IsEnabled() && p_inst->IsConnectable();
    242 
    243           if (!instance_weakptr.get()) return;
    244           auto hci_interface = instance_weakptr.get()->GetHciInterface();
    245 
    246           if (restart) {
    247             p_inst->enable_status = false;
    248             hci_interface->Enable(false, p_inst->inst_id, 0x00, 0x00,
    249                                   Bind(DoNothing));
    250           }
    251 
    252           /* set it to controller */
    253           hci_interface->SetRandomAddress(
    254               p_inst->inst_id, bda,
    255               Bind(
    256                   [](AdvertisingInstance* p_inst, RawAddress bda,
    257                      MultiAdvCb configuredCb, uint8_t status) {
    258                     p_inst->own_address = bda;
    259                     configuredCb.Run(0x00);
    260                   },
    261                   p_inst, bda, configuredCb));
    262 
    263           if (restart) {
    264             p_inst->enable_status = true;
    265             hci_interface->Enable(true, p_inst->inst_id, 0x00, 0x00,
    266                                   Bind(DoNothing));
    267           }
    268         },
    269         p_inst, std::move(configuredCb)));
    270   }
    271 
    272   void RegisterAdvertiser(
    273       base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)> cb)
    274       override {
    275     AdvertisingInstance* p_inst = &adv_inst[0];
    276     for (uint8_t i = 0; i < inst_count; i++, p_inst++) {
    277       if (p_inst->in_use) continue;
    278 
    279       p_inst->in_use = true;
    280 
    281       // set up periodic timer to update address.
    282       if (BTM_BleLocalPrivacyEnabled()) {
    283         p_inst->own_address_type = BLE_ADDR_RANDOM;
    284         GenerateRpa(Bind(
    285             [](AdvertisingInstance* p_inst,
    286                base::Callback<void(uint8_t /* inst_id */, uint8_t /* status */)>
    287                    cb,
    288                RawAddress bda) {
    289               p_inst->own_address = bda;
    290 
    291               alarm_set_on_mloop(p_inst->adv_raddr_timer,
    292                                  BTM_BLE_PRIVATE_ADDR_INT_MS,
    293                                  btm_ble_adv_raddr_timer_timeout, p_inst);
    294               cb.Run(p_inst->inst_id, BTM_BLE_MULTI_ADV_SUCCESS);
    295             },
    296             p_inst, cb));
    297       } else {
    298         p_inst->own_address_type = BLE_ADDR_PUBLIC;
    299         p_inst->own_address = *controller_get_interface()->get_address();
    300 
    301         cb.Run(p_inst->inst_id, BTM_BLE_MULTI_ADV_SUCCESS);
    302       }
    303       return;
    304     }
    305 
    306     LOG(INFO) << "no free advertiser instance";
    307     cb.Run(0xFF, ADVERTISE_FAILED_TOO_MANY_ADVERTISERS);
    308   }
    309 
    310   void StartAdvertising(uint8_t advertiser_id, MultiAdvCb cb,
    311                         tBTM_BLE_ADV_PARAMS* params,
    312                         std::vector<uint8_t> advertise_data,
    313                         std::vector<uint8_t> scan_response_data, int duration,
    314                         MultiAdvCb timeout_cb) override {
    315     /* a temporary type for holding all the data needed in callbacks below*/
    316     struct CreatorParams {
    317       uint8_t inst_id;
    318       base::WeakPtr<BleAdvertisingManagerImpl> self;
    319       MultiAdvCb cb;
    320       tBTM_BLE_ADV_PARAMS params;
    321       std::vector<uint8_t> advertise_data;
    322       std::vector<uint8_t> scan_response_data;
    323       int duration;
    324       MultiAdvCb timeout_cb;
    325     };
    326 
    327     std::unique_ptr<CreatorParams> c;
    328     c.reset(new CreatorParams());
    329 
    330     c->self = weak_factory_.GetWeakPtr();
    331     c->cb = std::move(cb);
    332     c->params = *params;
    333     c->advertise_data = std::move(advertise_data);
    334     c->scan_response_data = std::move(scan_response_data);
    335     c->duration = duration;
    336     c->timeout_cb = std::move(timeout_cb);
    337     c->inst_id = advertiser_id;
    338 
    339     using c_type = std::unique_ptr<CreatorParams>;
    340 
    341     // this code is intentionally left formatted this way to highlight the
    342     // asynchronous flow
    343     // clang-format off
    344     c->self->SetParameters(c->inst_id, &c->params, Bind(
    345       [](c_type c, uint8_t status, int8_t tx_power) {
    346         if (!c->self) {
    347           LOG(INFO) << "Stack was shut down";
    348           return;
    349         }
    350 
    351         if (status) {
    352           LOG(ERROR) << "setting parameters failed, status: " << +status;
    353           c->cb.Run(status);
    354           return;
    355         }
    356 
    357         c->self->adv_inst[c->inst_id].tx_power = tx_power;
    358 
    359         const RawAddress& rpa = c->self->adv_inst[c->inst_id].own_address;
    360         c->self->GetHciInterface()->SetRandomAddress(c->inst_id, rpa, Bind(
    361           [](c_type c, uint8_t status) {
    362             if (!c->self) {
    363               LOG(INFO) << "Stack was shut down";
    364               return;
    365             }
    366 
    367             if (status != 0) {
    368               LOG(ERROR) << "setting random address failed, status: " << +status;
    369               c->cb.Run(status);
    370               return;
    371             }
    372 
    373             c->self->SetData(c->inst_id, false, std::move(c->advertise_data), Bind(
    374               [](c_type c, uint8_t status) {
    375                 if (!c->self) {
    376                   LOG(INFO) << "Stack was shut down";
    377                   return;
    378                 }
    379 
    380                 if (status != 0) {
    381                   LOG(ERROR) << "setting advertise data failed, status: " << +status;
    382                   c->cb.Run(status);
    383                   return;
    384                 }
    385 
    386                 c->self->SetData(c->inst_id, true, std::move(c->scan_response_data), Bind(
    387                   [](c_type c, uint8_t status) {
    388                     if (!c->self) {
    389                       LOG(INFO) << "Stack was shut down";
    390                       return;
    391                     }
    392 
    393                     if (status != 0) {
    394                       LOG(ERROR) << "setting scan response data failed, status: " << +status;
    395                       c->cb.Run(status);
    396                       return;
    397                     }
    398 
    399                     c->self->Enable(c->inst_id, true, c->cb, c->duration, 0, std::move(c->timeout_cb));
    400 
    401                 }, base::Passed(&c)));
    402             }, base::Passed(&c)));
    403         }, base::Passed(&c)));
    404     }, base::Passed(&c)));
    405     // clang-format on
    406   }
    407 
    408   void StartAdvertisingSet(IdTxPowerStatusCb cb, tBTM_BLE_ADV_PARAMS* params,
    409                            std::vector<uint8_t> advertise_data,
    410                            std::vector<uint8_t> scan_response_data,
    411                            tBLE_PERIODIC_ADV_PARAMS* periodic_params,
    412                            std::vector<uint8_t> periodic_data,
    413                            uint16_t duration, uint8_t maxExtAdvEvents,
    414                            RegisterCb timeout_cb) override {
    415     std::unique_ptr<CreatorParams> c;
    416     c.reset(new CreatorParams());
    417 
    418     c->self = weak_factory_.GetWeakPtr();
    419     c->cb = std::move(cb);
    420     c->params = *params;
    421     c->advertise_data = std::move(advertise_data);
    422     c->scan_response_data = std::move(scan_response_data);
    423     c->periodic_params = *periodic_params;
    424     c->periodic_data = std::move(periodic_data);
    425     c->duration = duration;
    426     c->maxExtAdvEvents = maxExtAdvEvents;
    427     c->timeout_cb = std::move(timeout_cb);
    428 
    429     // this code is intentionally left formatted this way to highlight the
    430     // asynchronous flow
    431     // clang-format off
    432     c->self->RegisterAdvertiser(Bind(
    433       [](c_type c, uint8_t advertiser_id, uint8_t status) {
    434         if (!c->self) {
    435           LOG(INFO) << "Stack was shut down";
    436           return;
    437         }
    438 
    439         if (status != 0) {
    440           LOG(ERROR) << " failed, status: " << +status;
    441           c->cb.Run(0, 0, status);
    442           return;
    443         }
    444 
    445         c->inst_id = advertiser_id;
    446 
    447         c->self->SetParameters(c->inst_id, &c->params, Bind(
    448           [](c_type c, uint8_t status, int8_t tx_power) {
    449             if (!c->self) {
    450               LOG(INFO) << "Stack was shut down";
    451               return;
    452             }
    453 
    454             if (status != 0) {
    455               c->self->Unregister(c->inst_id);
    456               LOG(ERROR) << "setting parameters failed, status: " << +status;
    457               c->cb.Run(0, 0, status);
    458               return;
    459             }
    460 
    461             c->self->adv_inst[c->inst_id].tx_power = tx_power;
    462 
    463             if (c->self->adv_inst[c->inst_id].own_address_type == BLE_ADDR_PUBLIC) {
    464               c->self->StartAdvertisingSetAfterAddressPart(std::move(c));
    465               return;
    466             }
    467 
    468             //own_address_type == BLE_ADDR_RANDOM
    469             const RawAddress& rpa = c->self->adv_inst[c->inst_id].own_address;
    470             c->self->GetHciInterface()->SetRandomAddress(c->inst_id, rpa, Bind(
    471               [](c_type c, uint8_t status) {
    472                 if (!c->self) {
    473                   LOG(INFO) << "Stack was shut down";
    474                   return;
    475                 }
    476 
    477                 if (status != 0) {
    478                   c->self->Unregister(c->inst_id);
    479                   LOG(ERROR) << "setting random address failed, status: " << +status;
    480                   c->cb.Run(0, 0, status);
    481                   return;
    482                 }
    483 
    484                 c->self->StartAdvertisingSetAfterAddressPart(std::move(c));
    485           }, base::Passed(&c)));
    486         }, base::Passed(&c)));
    487     }, base::Passed(&c)));
    488     // clang-format on
    489   }
    490 
    491   void StartAdvertisingSetAfterAddressPart(c_type c) {
    492     c->self->SetData(
    493         c->inst_id, false, std::move(c->advertise_data),
    494         Bind(
    495             [](c_type c, uint8_t status) {
    496               if (!c->self) {
    497                 LOG(INFO) << "Stack was shut down";
    498                 return;
    499               }
    500 
    501               if (status != 0) {
    502                 c->self->Unregister(c->inst_id);
    503                 LOG(ERROR) << "setting advertise data failed, status: "
    504                            << +status;
    505                 c->cb.Run(0, 0, status);
    506                 return;
    507               }
    508 
    509               c->self->SetData(
    510                   c->inst_id, true, std::move(c->scan_response_data),
    511                   Bind(
    512                       [](c_type c, uint8_t status) {
    513                         if (!c->self) {
    514                           LOG(INFO) << "Stack was shut down";
    515                           return;
    516                         }
    517 
    518                         if (status != 0) {
    519                           c->self->Unregister(c->inst_id);
    520                           LOG(ERROR)
    521                               << "setting scan response data failed, status: "
    522                               << +status;
    523                           c->cb.Run(0, 0, status);
    524                           return;
    525                         }
    526 
    527                         if (c->periodic_params.enable) {
    528                           c->self->StartAdvertisingSetPeriodicPart(
    529                               std::move(c));
    530                         } else {
    531                           c->self->StartAdvertisingSetFinish(std::move(c));
    532                         }
    533                       },
    534                       base::Passed(&c)));
    535             },
    536             base::Passed(&c)));
    537   }
    538 
    539   void StartAdvertisingSetPeriodicPart(c_type c) {
    540     // this code is intentionally left formatted this way to highlight the
    541     // asynchronous flow
    542     // clang-format off
    543     c->self->SetPeriodicAdvertisingParameters(c->inst_id, &c->periodic_params, Bind(
    544       [](c_type c, uint8_t status) {
    545         if (!c->self) {
    546           LOG(INFO) << "Stack was shut down";
    547           return;
    548         }
    549 
    550         if (status != 0) {
    551           c->self->Unregister(c->inst_id);
    552           LOG(ERROR) << "setting periodic parameters failed, status: " << +status;
    553           c->cb.Run(0, 0, status);
    554           return;
    555         }
    556 
    557         c->self->SetPeriodicAdvertisingData(c->inst_id, std::move(c->periodic_data), Bind(
    558           [](c_type c, uint8_t status) {
    559             if (!c->self) {
    560               LOG(INFO) << "Stack was shut down";
    561               return;
    562             }
    563 
    564             if (status != 0) {
    565               c->self->Unregister(c->inst_id);
    566               LOG(ERROR) << "setting periodic parameters failed, status: " << +status;
    567               c->cb.Run(0, 0, status);
    568               return;
    569             }
    570 
    571             c->self->SetPeriodicAdvertisingEnable(c->inst_id, true, Bind(
    572               [](c_type c, uint8_t status) {
    573                 if (!c->self) {
    574                   LOG(INFO) << "Stack was shut down";
    575                   return;
    576                 }
    577 
    578                 if (status != 0) {
    579                   c->self->Unregister(c->inst_id);
    580                   LOG(ERROR) << "enabling periodic advertising failed, status: " << +status;
    581                   c->cb.Run(0, 0, status);
    582                   return;
    583                 }
    584 
    585                 c->self->StartAdvertisingSetFinish(std::move(c));
    586 
    587               }, base::Passed(&c)));
    588         }, base::Passed(&c)));
    589     }, base::Passed(&c)));
    590     // clang-format on
    591   }
    592 
    593   void StartAdvertisingSetFinish(c_type c) {
    594     uint8_t inst_id = c->inst_id;
    595     uint16_t duration = c->duration;
    596     uint8_t maxExtAdvEvents = c->maxExtAdvEvents;
    597     RegisterCb timeout_cb = std::move(c->timeout_cb);
    598     base::WeakPtr<BleAdvertisingManagerImpl> self = c->self;
    599     MultiAdvCb enable_cb = Bind(
    600         [](c_type c, uint8_t status) {
    601           if (!c->self) {
    602             LOG(INFO) << "Stack was shut down";
    603             return;
    604           }
    605 
    606           if (status != 0) {
    607             c->self->Unregister(c->inst_id);
    608             LOG(ERROR) << "enabling advertiser failed, status: " << +status;
    609             c->cb.Run(0, 0, status);
    610             return;
    611           }
    612           int8_t tx_power = c->self->adv_inst[c->inst_id].tx_power;
    613           c->cb.Run(c->inst_id, tx_power, status);
    614         },
    615         base::Passed(&c));
    616 
    617     self->Enable(inst_id, true, std::move(enable_cb), duration, maxExtAdvEvents,
    618                  Bind(std::move(timeout_cb), inst_id));
    619   }
    620 
    621   void EnableWithTimerCb(uint8_t inst_id, MultiAdvCb enable_cb, int duration,
    622                          MultiAdvCb timeout_cb, uint8_t status) {
    623     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    624     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    625 
    626     // Run the regular enable callback
    627     enable_cb.Run(status);
    628 
    629     p_inst->timeout_timer = alarm_new("btm_ble.adv_timeout");
    630 
    631     base::Closure cb = Bind(
    632         &BleAdvertisingManagerImpl::Enable, weak_factory_.GetWeakPtr(), inst_id,
    633         0 /* disable */, std::move(timeout_cb), 0, 0, base::Bind(DoNothing));
    634 
    635     // schedule disable when the timeout passes
    636     alarm_set_closure(FROM_HERE, p_inst->timeout_timer, duration * 10,
    637                       std::move(cb));
    638   }
    639 
    640   void Enable(uint8_t inst_id, bool enable, MultiAdvCb cb, uint16_t duration,
    641               uint8_t maxExtAdvEvents, MultiAdvCb timeout_cb) override {
    642     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    643     if (inst_id >= inst_count) {
    644       LOG(ERROR) << "bad instance id " << +inst_id;
    645       return;
    646     }
    647 
    648     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    649     VLOG(1) << __func__ << " enable: " << enable << ", duration: " << +duration;
    650     if (!p_inst->in_use) {
    651       LOG(ERROR) << "Invalid or no active instance";
    652       cb.Run(BTM_BLE_MULTI_ADV_FAILURE);
    653       return;
    654     }
    655 
    656     if (enable && (duration || maxExtAdvEvents)) {
    657       p_inst->timeout_cb = std::move(timeout_cb);
    658     }
    659 
    660     p_inst->duration = duration;
    661     p_inst->maxExtAdvEvents = maxExtAdvEvents;
    662 
    663     if (enable && p_inst->address_update_required) {
    664       p_inst->address_update_required = false;
    665       ConfigureRpa(p_inst, base::Bind(&BleAdvertisingManagerImpl::EnableFinish,
    666                                       weak_factory_.GetWeakPtr(), p_inst,
    667                                       enable, std::move(cb)));
    668       return;
    669     }
    670 
    671     EnableFinish(p_inst, enable, std::move(cb), 0);
    672   }
    673 
    674   void EnableFinish(AdvertisingInstance* p_inst, bool enable, MultiAdvCb cb,
    675                     uint8_t status) {
    676     MultiAdvCb myCb;
    677     if (enable && p_inst->duration) {
    678       // TODO(jpawlowski): HCI implementation that can't do duration should
    679       // emulate it, not EnableWithTimerCb.
    680       myCb = Bind(&BleAdvertisingManagerImpl::EnableWithTimerCb,
    681                   weak_factory_.GetWeakPtr(), p_inst->inst_id, std::move(cb),
    682                   p_inst->duration, p_inst->timeout_cb);
    683     } else {
    684       myCb = std::move(cb);
    685 
    686       if (p_inst->timeout_timer) {
    687         alarm_cancel(p_inst->timeout_timer);
    688         alarm_free(p_inst->timeout_timer);
    689         p_inst->timeout_timer = nullptr;
    690       }
    691     }
    692 
    693     if (enable) p_inst->enable_time = TimeTicks::Now();
    694     p_inst->enable_status = enable;
    695     GetHciInterface()->Enable(enable, p_inst->inst_id, p_inst->duration,
    696                               p_inst->maxExtAdvEvents, std::move(myCb));
    697   }
    698 
    699   void SetParameters(uint8_t inst_id, tBTM_BLE_ADV_PARAMS* p_params,
    700                      ParametersCb cb) override {
    701     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    702     if (inst_id >= inst_count) {
    703       LOG(ERROR) << "bad instance id " << +inst_id;
    704       return;
    705     }
    706 
    707     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    708     if (!p_inst->in_use) {
    709       LOG(ERROR) << "adv instance not in use" << +inst_id;
    710       cb.Run(BTM_BLE_MULTI_ADV_FAILURE, 0);
    711       return;
    712     }
    713 
    714     // TODO: disable only if was enabled, currently no use scenario needs
    715     // that,
    716     // we always set parameters before enabling
    717     // GetHciInterface()->Enable(false, inst_id, Bind(DoNothing));
    718     p_inst->advertising_event_properties =
    719         p_params->advertising_event_properties;
    720     p_inst->tx_power = p_params->tx_power;
    721     p_inst->advertising_interval = p_params->adv_int_min;
    722     const RawAddress& peer_address = RawAddress::kEmpty;
    723 
    724     GetHciInterface()->SetParameters(
    725         p_inst->inst_id, p_params->advertising_event_properties,
    726         p_params->adv_int_min, p_params->adv_int_max, p_params->channel_map,
    727         p_inst->own_address_type, p_inst->own_address, 0x00, peer_address,
    728         p_params->adv_filter_policy, p_inst->tx_power,
    729         p_params->primary_advertising_phy, 0x00,
    730         p_params->secondary_advertising_phy, 0x01 /* TODO: proper SID */,
    731         p_params->scan_request_notification_enable, cb);
    732 
    733     // TODO: re-enable only if it was enabled, properly call
    734     // SetParamsCallback
    735     // currently no use scenario needs that
    736     // GetHciInterface()->Enable(true, inst_id, BTM_BleUpdateAdvInstParamCb);
    737   }
    738 
    739   void SetData(uint8_t inst_id, bool is_scan_rsp, std::vector<uint8_t> data,
    740                MultiAdvCb cb) override {
    741     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    742     if (inst_id >= inst_count) {
    743       LOG(ERROR) << "bad instance id " << +inst_id;
    744       return;
    745     }
    746 
    747     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    748     VLOG(1) << "is_scan_rsp = " << is_scan_rsp;
    749 
    750     if (!is_scan_rsp && is_connectable(p_inst->advertising_event_properties)) {
    751       uint8_t flags_val = BTM_GENERAL_DISCOVERABLE;
    752 
    753       if (p_inst->duration) flags_val = BTM_LIMITED_DISCOVERABLE;
    754 
    755       std::vector<uint8_t> flags;
    756       flags.push_back(2);  // length
    757       flags.push_back(HCI_EIR_FLAGS_TYPE);
    758       flags.push_back(flags_val);
    759 
    760       data.insert(data.begin(), flags.begin(), flags.end());
    761     }
    762 
    763     // Find and fill TX Power with the correct value
    764     if (data.size()) {
    765       size_t i = 0;
    766       while (i < data.size()) {
    767         uint8_t type = data[i + 1];
    768         if (type == HCI_EIR_TX_POWER_LEVEL_TYPE) {
    769           data[i + 2] = adv_inst[inst_id].tx_power;
    770         }
    771         i += data[i] + 1;
    772       }
    773     }
    774 
    775     VLOG(1) << "data is: " << base::HexEncode(data.data(), data.size());
    776     DivideAndSendData(
    777         inst_id, data, cb,
    778         base::Bind(&BleAdvertisingManagerImpl::SetDataAdvDataSender,
    779                    weak_factory_.GetWeakPtr(), is_scan_rsp));
    780   }
    781 
    782   void SetDataAdvDataSender(uint8_t is_scan_rsp, uint8_t inst_id,
    783                             uint8_t operation, uint8_t length, uint8_t* data,
    784                             MultiAdvCb cb) {
    785     if (is_scan_rsp)
    786       GetHciInterface()->SetScanResponseData(inst_id, operation, 0x01, length,
    787                                              data, cb);
    788     else
    789       GetHciInterface()->SetAdvertisingData(inst_id, operation, 0x01, length,
    790                                             data, cb);
    791   }
    792 
    793   using DataSender = base::Callback<void(
    794       uint8_t /*inst_id*/, uint8_t /* operation */, uint8_t /* length */,
    795       uint8_t* /* data */, MultiAdvCb /* done */)>;
    796 
    797   void DivideAndSendData(int inst_id, std::vector<uint8_t> data,
    798                          MultiAdvCb done_cb, DataSender sender) {
    799     DivideAndSendDataRecursively(true, inst_id, std::move(data), 0,
    800                                  std::move(done_cb), std::move(sender), 0);
    801   }
    802 
    803   static void DivideAndSendDataRecursively(bool isFirst, int inst_id,
    804                                            std::vector<uint8_t> data,
    805                                            int offset, MultiAdvCb done_cb,
    806                                            DataSender sender, uint8_t status) {
    807     constexpr uint8_t INTERMEDIATE =
    808         0x00;                        // Intermediate fragment of fragmented data
    809     constexpr uint8_t FIRST = 0x01;  // First fragment of fragmented data
    810     constexpr uint8_t LAST = 0x02;   // Last fragment of fragmented data
    811     constexpr uint8_t COMPLETE = 0x03;  // Complete extended advertising data
    812 
    813     int dataSize = (int)data.size();
    814     if (status != 0 || (!isFirst && offset == dataSize)) {
    815       /* if we got error writing data, or reached the end of data */
    816       done_cb.Run(status);
    817       return;
    818     }
    819 
    820     bool moreThanOnePacket = dataSize - offset > ADV_DATA_LEN_MAX;
    821     uint8_t operation = isFirst ? moreThanOnePacket ? FIRST : COMPLETE
    822                                 : moreThanOnePacket ? INTERMEDIATE : LAST;
    823     int length = moreThanOnePacket ? ADV_DATA_LEN_MAX : dataSize - offset;
    824     int newOffset = offset + length;
    825 
    826     sender.Run(
    827         inst_id, operation, length, data.data() + offset,
    828         Bind(&BleAdvertisingManagerImpl::DivideAndSendDataRecursively, false,
    829              inst_id, std::move(data), newOffset, std::move(done_cb), sender));
    830   }
    831 
    832   void SetPeriodicAdvertisingParameters(uint8_t inst_id,
    833                                         tBLE_PERIODIC_ADV_PARAMS* params,
    834                                         MultiAdvCb cb) override {
    835     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    836 
    837     GetHciInterface()->SetPeriodicAdvertisingParameters(
    838         inst_id, params->min_interval, params->max_interval,
    839         params->periodic_advertising_properties, cb);
    840   }
    841 
    842   void SetPeriodicAdvertisingData(uint8_t inst_id, std::vector<uint8_t> data,
    843                                   MultiAdvCb cb) override {
    844     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    845 
    846     VLOG(1) << "data is: " << base::HexEncode(data.data(), data.size());
    847 
    848     DivideAndSendData(
    849         inst_id, data, cb,
    850         base::Bind(&BleAdvertiserHciInterface::SetPeriodicAdvertisingData,
    851                    base::Unretained(GetHciInterface())));
    852   }
    853 
    854   void SetPeriodicAdvertisingEnable(uint8_t inst_id, uint8_t enable,
    855                                     MultiAdvCb cb) override {
    856     VLOG(1) << __func__ << " inst_id: " << +inst_id << ", enable: " << +enable;
    857 
    858     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    859     if (!p_inst->in_use) {
    860       LOG(ERROR) << "Invalid or not active instance";
    861       cb.Run(BTM_BLE_MULTI_ADV_FAILURE);
    862       return;
    863     }
    864 
    865     MultiAdvCb enable_cb = Bind(
    866         [](AdvertisingInstance* p_inst, uint8_t enable, MultiAdvCb cb,
    867            uint8_t status) {
    868           VLOG(1) << "periodc adv enable cb: inst_id: " << +p_inst->inst_id
    869                   << ", enable: " << +enable << ", status: " << std::hex
    870                   << +status;
    871           if (!status) p_inst->periodic_enabled = enable;
    872 
    873           cb.Run(status);
    874         },
    875         p_inst, enable, std::move(cb));
    876 
    877     GetHciInterface()->SetPeriodicAdvertisingEnable(enable, inst_id,
    878                                                     std::move(enable_cb));
    879   }
    880 
    881   void Unregister(uint8_t inst_id) override {
    882     AdvertisingInstance* p_inst = &adv_inst[inst_id];
    883 
    884     VLOG(1) << __func__ << " inst_id: " << +inst_id;
    885     if (inst_id >= inst_count) {
    886       LOG(ERROR) << "bad instance id " << +inst_id;
    887       return;
    888     }
    889 
    890     if (adv_inst[inst_id].IsEnabled()) {
    891       p_inst->enable_status = false;
    892       GetHciInterface()->Enable(false, inst_id, 0x00, 0x00, Bind(DoNothing));
    893     }
    894 
    895     if (p_inst->periodic_enabled) {
    896       p_inst->periodic_enabled = false;
    897       GetHciInterface()->SetPeriodicAdvertisingEnable(false, inst_id,
    898                                                       Bind(DoNothing));
    899     }
    900 
    901     alarm_cancel(p_inst->adv_raddr_timer);
    902     p_inst->in_use = false;
    903     GetHciInterface()->RemoveAdvertisingSet(inst_id, Bind(DoNothing));
    904     p_inst->address_update_required = false;
    905   }
    906 
    907   void RecomputeTimeout(AdvertisingInstance* inst, TimeTicks now) {
    908     TimeDelta duration = now - inst->enable_time;
    909     bool cb_fired = false;
    910     if (inst->duration) {
    911       int durationDone = (duration.InMilliseconds() / 10);
    912       if (durationDone + 1 >= inst->duration) {
    913         inst->enable_status = false;
    914         inst->timeout_cb.Run(0 /* TODO: STATUS HERE?*/);
    915         cb_fired = true;
    916       } else {
    917         inst->duration = inst->duration - durationDone;
    918       }
    919     }
    920 
    921     if (inst->maxExtAdvEvents && !cb_fired) {
    922       int eventsDone =
    923           (duration.InMilliseconds() / (inst->advertising_interval * 5 / 8));
    924 
    925       if (eventsDone + 1 >= inst->maxExtAdvEvents) {
    926         inst->enable_status = false;
    927         inst->timeout_cb.Run(0 /* TODO: STATUS HERE?*/);
    928       } else {
    929         inst->maxExtAdvEvents = inst->maxExtAdvEvents - eventsDone;
    930       }
    931     }
    932   }
    933 
    934   void Suspend() {
    935     std::vector<SetEnableData> sets;
    936 
    937     for (AdvertisingInstance& inst : adv_inst) {
    938       if (!inst.in_use || !inst.enable_status) continue;
    939 
    940       if (inst.duration || inst.maxExtAdvEvents)
    941         RecomputeTimeout(&inst, TimeTicks::Now());
    942 
    943       sets.emplace_back(SetEnableData{.handle = inst.inst_id});
    944     }
    945 
    946     if (!sets.empty()) GetHciInterface()->Enable(false, sets, Bind(DoNothing));
    947   }
    948 
    949   void Resume() override {
    950     std::vector<SetEnableData> sets;
    951 
    952     for (const AdvertisingInstance& inst : adv_inst) {
    953       if (inst.in_use && inst.enable_status) {
    954         sets.emplace_back(SetEnableData{
    955             .handle = inst.inst_id,
    956             .duration = inst.duration,
    957             .max_extended_advertising_events = inst.maxExtAdvEvents});
    958       }
    959     }
    960 
    961     if (!sets.empty()) GetHciInterface()->Enable(true, sets, Bind(DoNothing));
    962   }
    963 
    964   void OnAdvertisingSetTerminated(
    965       uint8_t status, uint8_t advertising_handle, uint16_t connection_handle,
    966       uint8_t num_completed_extended_adv_events) override {
    967     AdvertisingInstance* p_inst = &adv_inst[advertising_handle];
    968     VLOG(1) << __func__ << "status: " << loghex(status)
    969             << ", advertising_handle: " << loghex(advertising_handle)
    970             << ", connection_handle: " << loghex(connection_handle);
    971 
    972     if (status == HCI_ERR_LIMIT_REACHED ||
    973         status == HCI_ERR_ADVERTISING_TIMEOUT) {
    974       // either duration elapsed, or maxExtAdvEvents reached
    975       p_inst->enable_status = false;
    976 
    977       if (p_inst->timeout_cb.is_null()) {
    978         LOG(INFO) << __func__ << "No timeout callback";
    979         return;
    980       }
    981 
    982       p_inst->timeout_cb.Run(status);
    983       return;
    984     }
    985 
    986     if (BTM_BleLocalPrivacyEnabled() &&
    987         advertising_handle <= BTM_BLE_MULTI_ADV_MAX) {
    988       btm_acl_update_conn_addr(connection_handle, p_inst->own_address);
    989     }
    990 
    991     VLOG(1) << "reneabling advertising";
    992 
    993     if (p_inst->in_use) {
    994       // TODO(jpawlowski): we don't really allow to do directed advertising
    995       // right now. This should probably be removed, check with Andre.
    996       if ((p_inst->advertising_event_properties & 0x0C) == 0) {
    997         /* directed advertising bits not set */
    998 
    999         RecomputeTimeout(p_inst, TimeTicks::Now());
   1000         if (p_inst->enable_status) {
   1001           GetHciInterface()->Enable(true, advertising_handle, p_inst->duration,
   1002                                     p_inst->maxExtAdvEvents, Bind(DoNothing));
   1003         }
   1004 
   1005       } else {
   1006         /* mark directed adv as disabled if adv has been stopped */
   1007         p_inst->in_use = false;
   1008       }
   1009     }
   1010   }
   1011 
   1012   base::WeakPtr<BleAdvertisingManagerImpl> GetWeakPtr() {
   1013     return weak_factory_.GetWeakPtr();
   1014   }
   1015 
   1016   void CancelAdvAlarms() {
   1017     AdvertisingInstance* p_inst = &adv_inst[0];
   1018     for (uint8_t i = 0; i < inst_count; i++, p_inst++) {
   1019       if (p_inst->timeout_timer) {
   1020         alarm_cancel(p_inst->timeout_timer);
   1021       }
   1022       if (p_inst->adv_raddr_timer) {
   1023         alarm_cancel(p_inst->adv_raddr_timer);
   1024       }
   1025     }
   1026   }
   1027 
   1028  private:
   1029   BleAdvertiserHciInterface* GetHciInterface() { return hci_interface; }
   1030 
   1031   BleAdvertiserHciInterface* hci_interface = nullptr;
   1032   std::vector<AdvertisingInstance> adv_inst;
   1033   uint8_t inst_count;
   1034 
   1035   // Member variables should appear before the WeakPtrFactory, to ensure
   1036   // that any WeakPtrs are invalidated before its members
   1037   // variable's destructors are executed, rendering them invalid.
   1038   base::WeakPtrFactory<BleAdvertisingManagerImpl> weak_factory_;
   1039 };
   1040 
   1041 void btm_ble_adv_raddr_timer_timeout(void* data) {
   1042   BleAdvertisingManagerImpl* ptr = instance_weakptr.get();
   1043   if (ptr) ptr->ConfigureRpa((AdvertisingInstance*)data, base::Bind(DoNothing));
   1044 }
   1045 }  // namespace
   1046 
   1047 void BleAdvertisingManager::Initialize(BleAdvertiserHciInterface* interface) {
   1048   instance = new BleAdvertisingManagerImpl(interface);
   1049   instance_weakptr = ((BleAdvertisingManagerImpl*)instance)->GetWeakPtr();
   1050 }
   1051 
   1052 bool BleAdvertisingManager::IsInitialized() { return instance; }
   1053 
   1054 base::WeakPtr<BleAdvertisingManager> BleAdvertisingManager::Get() {
   1055   return instance_weakptr;
   1056 };
   1057 
   1058 void BleAdvertisingManager::CleanUp() {
   1059   if (instance_weakptr.get()) instance_weakptr.get()->CancelAdvAlarms();
   1060 
   1061   delete instance;
   1062   instance = nullptr;
   1063 };
   1064 
   1065 /**
   1066  * This function initialize the advertising manager.
   1067  **/
   1068 void btm_ble_adv_init() {
   1069   BleAdvertiserHciInterface::Initialize();
   1070   BleAdvertisingManager::Initialize(BleAdvertiserHciInterface::Get());
   1071   BleAdvertiserHciInterface::Get()->SetAdvertisingEventObserver(
   1072       (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get().get());
   1073 
   1074   if (BleAdvertiserHciInterface::Get()->QuirkAdvertiserZeroHandle()) {
   1075     // If handle 0 can't be used, register advertiser for it, but never use it.
   1076     BleAdvertisingManager::Get().get()->RegisterAdvertiser(Bind(DoNothing2));
   1077   }
   1078 }
   1079 
   1080 /*******************************************************************************
   1081  *
   1082  * Function         btm_ble_multi_adv_cleanup
   1083  *
   1084  * Description      This function cleans up multi adv control block.
   1085  *
   1086  * Parameters
   1087  * Returns          void
   1088  *
   1089  ******************************************************************************/
   1090 void btm_ble_multi_adv_cleanup(void) {
   1091   BleAdvertisingManager::CleanUp();
   1092   BleAdvertiserHciInterface::CleanUp();
   1093 }
   1094 
   1095 // TODO(jpawlowski): Find a nicer way to test RecomputeTimeout without exposing
   1096 // AdvertisingInstance
   1097 bool timeout_triggered = false;
   1098 void test_timeout_cb(uint8_t status) { timeout_triggered = true; }
   1099 
   1100 // verify that if duration passed, or is about to pass, recomputation will shut
   1101 // down the advertiser completly
   1102 void testRecomputeTimeout1() {
   1103   auto manager = (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get().get();
   1104 
   1105   TimeTicks start = TimeTicks::Now();
   1106   TimeTicks end = start + TimeDelta::FromMilliseconds(111);
   1107   AdvertisingInstance test1(0);
   1108   test1.enable_status = true;
   1109   test1.enable_time = start;
   1110   test1.duration = 12 /*120ms*/;
   1111   test1.timeout_cb = Bind(&test_timeout_cb);
   1112 
   1113   manager->RecomputeTimeout(&test1, end);
   1114 
   1115   CHECK(timeout_triggered);
   1116   timeout_triggered = false;
   1117   CHECK(!test1.enable_status);
   1118 }
   1119 
   1120 // verify that duration and maxExtAdvEvents are properly adjusted when
   1121 // recomputing.
   1122 void testRecomputeTimeout2() {
   1123   auto manager = (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get().get();
   1124 
   1125   TimeTicks start = TimeTicks::Now();
   1126   TimeTicks end = start + TimeDelta::FromMilliseconds(250);
   1127   AdvertisingInstance test1(0);
   1128   test1.enable_status = true;
   1129   test1.enable_time = start;
   1130   test1.duration = 50 /*500ms*/;
   1131   test1.maxExtAdvEvents = 50;
   1132   test1.advertising_interval = 16 /* 10 ms */;
   1133   test1.timeout_cb = Bind(&test_timeout_cb);
   1134 
   1135   manager->RecomputeTimeout(&test1, end);
   1136 
   1137   CHECK(!timeout_triggered);
   1138   CHECK(test1.enable_status);
   1139   CHECK(test1.duration == 25);
   1140   CHECK(test1.maxExtAdvEvents == 25);
   1141 }
   1142 
   1143 // verify that if maxExtAdvEvents were sent, or are close to end, recomputation
   1144 // wil shut down the advertiser completly
   1145 void testRecomputeTimeout3() {
   1146   auto manager = (BleAdvertisingManagerImpl*)BleAdvertisingManager::Get().get();
   1147 
   1148   TimeTicks start = TimeTicks::Now();
   1149   TimeTicks end = start + TimeDelta::FromMilliseconds(495);
   1150   AdvertisingInstance test1(0);
   1151   test1.enable_status = true;
   1152   test1.enable_time = start;
   1153   test1.maxExtAdvEvents = 50;
   1154   test1.advertising_interval = 16 /* 10 ms */;
   1155   test1.timeout_cb = Bind(&test_timeout_cb);
   1156 
   1157   manager->RecomputeTimeout(&test1, end);
   1158 
   1159   CHECK(timeout_triggered);
   1160   timeout_triggered = false;
   1161   CHECK(!test1.enable_status);
   1162 }
   1163