1/******************************************************************************
2 *
3 *  Copyright (C) 2016 The Android Open Source Project
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19#include "ble_advertiser_hci_interface.h"
20#include <base/callback.h>
21#include <base/location.h>
22#include <base/logging.h>
23#include <queue>
24#include <utility>
25#include "btm_api.h"
26#include "btm_ble_api.h"
27#include "btm_int_types.h"
28#include "device/include/controller.h"
29#include "hcidefs.h"
30
31#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
32#define BTM_BLE_MULTI_ADV_ENB_LEN 3
33#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24
34#define BTM_BLE_AD_DATA_LEN 31
35#define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3)
36
37#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE 1
38#define HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD 6
39#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS 15
40#define HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP 31
41#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA 31
42
43using status_cb = BleAdvertiserHciInterface::status_cb;
44
45using hci_cmd_cb = base::Callback<void(uint8_t* /* return_parameters */,
46                                       uint16_t /* return_parameters_length*/)>;
47extern void btu_hcif_send_cmd_with_cb(
48    const tracked_objects::Location& posted_from, uint16_t opcode,
49    uint8_t* params, uint8_t params_len, hci_cmd_cb cb);
50
51namespace {
52BleAdvertiserHciInterface* instance = nullptr;
53
54void btm_ble_multi_adv_vsc_cmpl_cback(uint8_t expected_opcode,
55                                      status_cb command_complete,
56                                      uint8_t* param, uint16_t param_len) {
57  uint8_t status, subcode;
58
59  // All multi-adv commands respond with status and inst_id.
60  LOG_ASSERT(param_len == 2) << "Received bad response length to multi-adv VSC";
61
62  STREAM_TO_UINT8(status, param);
63  STREAM_TO_UINT8(subcode, param);
64
65  VLOG(1) << "subcode = " << +subcode << ", status: " << +status;
66
67  if (expected_opcode != subcode) {
68    LOG(ERROR) << "unexpected VSC cmpl, expect: " << +subcode
69               << " get: " << +expected_opcode;
70    return;
71  }
72
73  command_complete.Run(status);
74}
75
76void parameters_response_parser(BleAdvertiserHciInterface::parameters_cb cb,
77                                uint8_t* ret_params, uint16_t ret_params_len) {
78  uint8_t status;
79  int8_t tx_power;
80
81  uint8_t* pp = ret_params;
82  STREAM_TO_UINT8(status, pp);
83  STREAM_TO_INT8(tx_power, pp);
84
85  cb.Run(status, tx_power);
86}
87
88void known_tx_pwr(BleAdvertiserHciInterface::parameters_cb cb, int8_t tx_power,
89                  uint8_t status) {
90  cb.Run(status, tx_power);
91}
92
93class BleAdvertiserVscHciInterfaceImpl : public BleAdvertiserHciInterface {
94  void SendAdvCmd(const tracked_objects::Location& posted_from,
95                  uint8_t param_len, uint8_t* param_buf,
96                  status_cb command_complete) {
97    btu_hcif_send_cmd_with_cb(posted_from, HCI_BLE_MULTI_ADV_OCF, param_buf,
98                              param_len,
99                              base::Bind(&btm_ble_multi_adv_vsc_cmpl_cback,
100                                         param_buf[0], command_complete));
101  }
102
103  void ReadInstanceCount(
104      base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
105    cb.Run(BTM_BleMaxMultiAdvInstanceCount());
106  }
107
108  void SetAdvertisingEventObserver(
109      AdvertisingEventObserver* observer) override {
110    this->advertising_event_observer = observer;
111  }
112
113  void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
114                     uint32_t adv_int_max, uint8_t channel_map,
115                     uint8_t own_address_type, const RawAddress& own_address,
116                     uint8_t peer_address_type, const RawAddress& peer_address,
117                     uint8_t filter_policy, int8_t tx_power,
118                     uint8_t primary_phy, uint8_t secondary_max_skip,
119                     uint8_t secondary_phy, uint8_t advertising_sid,
120                     uint8_t scan_request_notify_enable,
121                     parameters_cb command_complete) override {
122    VLOG(1) << __func__;
123    uint8_t param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN];
124    memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN);
125
126    uint8_t* pp = param;
127    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM);
128    UINT16_TO_STREAM(pp, adv_int_min);
129    UINT16_TO_STREAM(pp, adv_int_max);
130
131    if (properties == 0x0013) {
132      UINT8_TO_STREAM(pp, 0x00);  // ADV_IND
133    } else if (properties == 0x0012) {
134      UINT8_TO_STREAM(pp, 0x02);  // ADV_SCAN_IND
135    } else if (properties == 0x0010) {
136      UINT8_TO_STREAM(pp, 0x03);  // ADV_NONCONN_IND
137    } else {
138      LOG(ERROR) << "Unsupported advertisement type selected:" << std::hex
139                 << properties;
140      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT, 0);
141      return;
142    }
143
144    UINT8_TO_STREAM(pp, own_address_type);
145    BDADDR_TO_STREAM(pp, own_address);
146    UINT8_TO_STREAM(pp, peer_address_type);
147    BDADDR_TO_STREAM(pp, peer_address);
148    UINT8_TO_STREAM(pp, channel_map);
149    UINT8_TO_STREAM(pp, filter_policy);
150    UINT8_TO_STREAM(pp, handle);
151    INT8_TO_STREAM(pp, tx_power);
152
153    SendAdvCmd(
154        FROM_HERE, BTM_BLE_MULTI_ADV_SET_PARAM_LEN, param,
155        base::Bind(&known_tx_pwr, std::move(command_complete), tx_power));
156  }
157
158  void SetAdvertisingData(uint8_t handle, uint8_t operation,
159                          uint8_t fragment_preference, uint8_t data_length,
160                          uint8_t* data, status_cb command_complete) override {
161    VLOG(1) << __func__;
162    uint8_t param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN];
163    memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
164
165    uint8_t* pp = param;
166    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_WRITE_ADV_DATA);
167    UINT8_TO_STREAM(pp, data_length);
168    ARRAY_TO_STREAM(pp, data, data_length);
169    param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1] = handle;
170
171    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN, param,
172               command_complete);
173  }
174
175  void SetScanResponseData(uint8_t handle, uint8_t operation,
176                           uint8_t fragment_preference,
177                           uint8_t scan_response_data_length,
178                           uint8_t* scan_response_data,
179                           status_cb command_complete) override {
180    VLOG(1) << __func__;
181    uint8_t param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN];
182    memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
183
184    uint8_t* pp = param;
185    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA);
186    UINT8_TO_STREAM(pp, scan_response_data_length);
187    ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
188    param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1] = handle;
189
190    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN, param,
191               command_complete);
192  }
193
194  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
195                        status_cb command_complete) override {
196    VLOG(1) << __func__;
197    uint8_t param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN];
198    memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN);
199
200    uint8_t* pp = param;
201    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR);
202    BDADDR_TO_STREAM(pp, random_address);
203    UINT8_TO_STREAM(pp, handle);
204
205    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN, param,
206               command_complete);
207  }
208
209  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
210              status_cb command_complete) override {
211    VLOG(1) << __func__;
212
213    if (sets.size() != 1) {
214      LOG(ERROR) << "Trying to enable multiple sets in VSC implemenetation!";
215      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
216      return;
217    }
218    SetEnableData& set = sets[0];
219
220    if (set.max_extended_advertising_events) {
221      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
222      return;
223    }
224
225    uint8_t param[BTM_BLE_MULTI_ADV_ENB_LEN];
226    memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
227
228    uint8_t* pp = param;
229    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_ENB);
230    UINT8_TO_STREAM(pp, enable);
231    UINT8_TO_STREAM(pp, set.handle);
232
233    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_ENB_LEN, param,
234               command_complete);
235  }
236
237  void SetPeriodicAdvertisingParameters(uint8_t, uint16_t, uint16_t, uint16_t,
238                                        status_cb command_complete) override {
239    LOG(INFO) << __func__ << " VSC can't do periodic advertising";
240    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
241  }
242
243  void SetPeriodicAdvertisingData(uint8_t, uint8_t, uint8_t, uint8_t*,
244                                  status_cb command_complete) override {
245    LOG(INFO) << __func__ << " VSC can't do periodic advertising";
246    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
247  }
248
249  void SetPeriodicAdvertisingEnable(uint8_t, uint8_t,
250                                    status_cb command_complete) override {
251    LOG(INFO) << __func__ << " VSC can't do periodic advertising";
252    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
253  }
254
255  bool QuirkAdvertiserZeroHandle() override {
256    // Android BT HCI Requirements version 0.96 and below specify that handle 0
257    // is equal to standard HCI interface, and should be accessed using non-VSC
258    // commands.
259    LOG(INFO) << "QuirkAdvertiserZeroHandle in use";
260    return true;
261  }
262
263  void RemoveAdvertisingSet(uint8_t handle,
264                            status_cb command_complete) override {
265    // VSC Advertising don't have remove method.
266    command_complete.Run(0);
267  }
268
269 public:
270  static void VendorSpecificEventCback(uint8_t length, uint8_t* p) {
271    VLOG(1) << __func__;
272
273    LOG_ASSERT(p);
274    uint8_t sub_event, adv_inst, change_reason;
275    uint16_t conn_handle;
276
277    STREAM_TO_UINT8(sub_event, p);
278    length--;
279
280    if (sub_event != HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG || length != 4) {
281      return;
282    }
283
284    STREAM_TO_UINT8(adv_inst, p);
285    STREAM_TO_UINT8(change_reason, p);
286    STREAM_TO_UINT16(conn_handle, p);
287
288    AdvertisingEventObserver* observer =
289        ((BleAdvertiserVscHciInterfaceImpl*)BleAdvertiserHciInterface::Get())
290            ->advertising_event_observer;
291    if (observer)
292      observer->OnAdvertisingSetTerminated(change_reason, adv_inst, conn_handle,
293                                           0x00);
294  }
295
296 private:
297  AdvertisingEventObserver* advertising_event_observer = nullptr;
298};
299
300void adv_cmd_cmpl_cback(status_cb cb, uint8_t* return_parameters,
301                        uint16_t return_parameters_length) {
302  uint8_t status = *return_parameters;
303  cb.Run(status);
304}
305
306class BleAdvertiserLegacyHciInterfaceImpl : public BleAdvertiserHciInterface {
307  void SendAdvCmd(const tracked_objects::Location& posted_from, uint16_t opcode,
308                  uint8_t* param_buf, uint8_t param_buf_len,
309                  status_cb command_complete) {
310    btu_hcif_send_cmd_with_cb(
311        posted_from, opcode, param_buf, param_buf_len,
312        base::Bind(&adv_cmd_cmpl_cback, command_complete));
313  }
314
315  void ReadInstanceCount(
316      base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
317    cb.Run(1);
318  }
319
320  void SetAdvertisingEventObserver(
321      AdvertisingEventObserver* observer) override {}
322
323  void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
324                     uint32_t adv_int_max, uint8_t channel_map,
325                     uint8_t own_address_type,
326                     const RawAddress& /* own_address */,
327                     uint8_t peer_address_type, const RawAddress& peer_address,
328                     uint8_t filter_policy, int8_t tx_power,
329                     uint8_t primary_phy, uint8_t secondary_max_skip,
330                     uint8_t secondary_phy, uint8_t advertising_sid,
331                     uint8_t scan_request_notify_enable,
332                     parameters_cb command_complete) override {
333    VLOG(1) << __func__;
334
335    uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS];
336
337    uint8_t* pp = param;
338    UINT16_TO_STREAM(pp, adv_int_min);
339    UINT16_TO_STREAM(pp, adv_int_max);
340
341    if (properties == 0x0013) {
342      UINT8_TO_STREAM(pp, 0x00);  // ADV_IND
343    } else if (properties == 0x0012) {
344      UINT8_TO_STREAM(pp, 0x02);  // ADV_SCAN_IND
345    } else if (properties == 0x0010) {
346      UINT8_TO_STREAM(pp, 0x03);  // ADV_NONCONN_IND
347    } else {
348      LOG(ERROR) << "Unsupported advertisement type selected:" << std::hex
349                 << properties;
350      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT, 0);
351      return;
352    }
353
354    UINT8_TO_STREAM(pp, own_address_type);
355    UINT8_TO_STREAM(pp, peer_address_type);
356    BDADDR_TO_STREAM(pp, peer_address);
357    UINT8_TO_STREAM(pp, channel_map);
358    UINT8_TO_STREAM(pp, filter_policy);
359
360    SendAdvCmd(
361        FROM_HERE, HCI_BLE_WRITE_ADV_PARAMS, param,
362        HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS,
363        base::Bind(&known_tx_pwr, std::move(command_complete), (int8_t)0));
364  }
365
366  void SetAdvertisingData(uint8_t handle, uint8_t operation,
367                          uint8_t fragment_preference, uint8_t data_length,
368                          uint8_t* data, status_cb command_complete) override {
369    VLOG(1) << __func__;
370
371    uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1];
372
373    uint8_t* pp = param;
374    memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
375    UINT8_TO_STREAM(pp, data_length);
376    ARRAY_TO_STREAM(pp, data, data_length);
377
378    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_ADV_DATA, param,
379               HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1, command_complete);
380  }
381
382  void SetScanResponseData(uint8_t handle, uint8_t operation,
383                           uint8_t fragment_preference,
384                           uint8_t scan_response_data_length,
385                           uint8_t* scan_response_data,
386                           status_cb command_complete) override {
387    VLOG(1) << __func__;
388    uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1];
389
390    uint8_t* pp = param;
391    memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
392    UINT8_TO_STREAM(pp, scan_response_data_length);
393    ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
394
395    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_SCAN_RSP_DATA, param,
396               HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1, command_complete);
397  }
398
399  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
400                        status_cb command_complete) override {
401    VLOG(1) << __func__;
402
403    uint8_t param[HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD];
404
405    uint8_t* pp = param;
406    BDADDR_TO_STREAM(pp, random_address);
407
408    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_RANDOM_ADDR, param,
409               HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD, command_complete);
410  }
411
412  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
413              status_cb command_complete) override {
414    VLOG(1) << __func__;
415
416    if (sets.size() != 1) {
417      LOG(ERROR) << "Trying to enable multiple sets in legacy implemenetation!";
418      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
419      return;
420    }
421
422    SetEnableData& set = sets[0];
423    if (set.max_extended_advertising_events) {
424      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
425      return;
426    }
427
428    uint8_t param[HCIC_PARAM_SIZE_WRITE_ADV_ENABLE];
429
430    uint8_t* pp = param;
431    UINT8_TO_STREAM(pp, enable);
432
433    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_ADV_ENABLE, param,
434               HCIC_PARAM_SIZE_WRITE_ADV_ENABLE, command_complete);
435  }
436
437  void SetPeriodicAdvertisingParameters(uint8_t, uint16_t, uint16_t, uint16_t,
438                                        status_cb command_complete) override {
439    LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
440    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
441  }
442
443  void SetPeriodicAdvertisingData(uint8_t, uint8_t, uint8_t, uint8_t*,
444                                  status_cb command_complete) override {
445    LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
446    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
447  }
448
449  void SetPeriodicAdvertisingEnable(uint8_t, uint8_t,
450                                    status_cb command_complete) override {
451    LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
452    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
453  }
454
455  void RemoveAdvertisingSet(uint8_t handle,
456                            status_cb command_complete) override {
457    // Legacy Advertising don't have remove method.
458    command_complete.Run(0);
459  }
460};
461
462class BleAdvertiserHciExtendedImpl : public BleAdvertiserHciInterface {
463  void SendAdvCmd(const tracked_objects::Location& posted_from, uint16_t opcode,
464                  uint8_t* param_buf, uint8_t param_buf_len,
465                  status_cb command_complete) {
466    btu_hcif_send_cmd_with_cb(
467        posted_from, opcode, param_buf, param_buf_len,
468        base::Bind(&adv_cmd_cmpl_cback, command_complete));
469  }
470
471  void ReadInstanceCount(
472      base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
473    cb.Run(controller_get_interface()
474               ->get_ble_number_of_supported_advertising_sets());
475  }
476
477  void SetAdvertisingEventObserver(
478      AdvertisingEventObserver* observer) override {
479    this->advertising_event_observer = observer;
480  }
481
482  void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
483                     uint32_t adv_int_max, uint8_t channel_map,
484                     uint8_t own_address_type,
485                     const RawAddress& /* own_address */,
486                     uint8_t peer_address_type, const RawAddress& peer_address,
487                     uint8_t filter_policy, int8_t tx_power,
488                     uint8_t primary_phy, uint8_t secondary_max_skip,
489                     uint8_t secondary_phy, uint8_t advertising_sid,
490                     uint8_t scan_request_notify_enable,
491                     parameters_cb command_complete) override {
492    VLOG(1) << __func__;
493    const uint16_t HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN = 25;
494    uint8_t param[HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN];
495    memset(param, 0, HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN);
496
497    uint8_t* pp = param;
498    UINT8_TO_STREAM(pp, handle);
499    UINT16_TO_STREAM(pp, properties);
500    UINT24_TO_STREAM(pp, adv_int_min);
501    UINT24_TO_STREAM(pp, adv_int_max);
502    UINT8_TO_STREAM(pp, channel_map);
503    UINT8_TO_STREAM(pp, own_address_type);
504    UINT8_TO_STREAM(pp, peer_address_type);
505    BDADDR_TO_STREAM(pp, peer_address);
506    UINT8_TO_STREAM(pp, filter_policy);
507    INT8_TO_STREAM(pp, tx_power);
508    UINT8_TO_STREAM(pp, primary_phy);
509    UINT8_TO_STREAM(pp, secondary_max_skip);
510    UINT8_TO_STREAM(pp, secondary_phy);
511    UINT8_TO_STREAM(pp, advertising_sid);
512    UINT8_TO_STREAM(pp, scan_request_notify_enable);
513
514    btu_hcif_send_cmd_with_cb(
515        FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_PARAM, param,
516        HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN,
517        base::Bind(parameters_response_parser, std::move(command_complete)));
518  }
519
520  void SetAdvertisingData(uint8_t handle, uint8_t operation,
521                          uint8_t fragment_preference, uint8_t data_length,
522                          uint8_t* data, status_cb command_complete) override {
523    VLOG(1) << __func__;
524
525    const uint16_t cmd_length = 4 + data_length;
526    uint8_t param[cmd_length];
527    memset(param, 0, cmd_length);
528
529    uint8_t* pp = param;
530    UINT8_TO_STREAM(pp, handle);
531    UINT8_TO_STREAM(pp, operation);
532    UINT8_TO_STREAM(pp, fragment_preference);
533    UINT8_TO_STREAM(pp, data_length);
534    ARRAY_TO_STREAM(pp, data, data_length);
535
536    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_DATA, param, cmd_length,
537               command_complete);
538  }
539
540  void SetScanResponseData(uint8_t handle, uint8_t operation,
541                           uint8_t fragment_preference,
542                           uint8_t scan_response_data_length,
543                           uint8_t* scan_response_data,
544                           status_cb command_complete) override {
545    VLOG(1) << __func__;
546
547    const uint16_t cmd_length = 4 + scan_response_data_length;
548    uint8_t param[cmd_length];
549    memset(param, 0, cmd_length);
550
551    uint8_t* pp = param;
552    UINT8_TO_STREAM(pp, handle);
553    UINT8_TO_STREAM(pp, operation);
554    UINT8_TO_STREAM(pp, fragment_preference);
555    UINT8_TO_STREAM(pp, scan_response_data_length);
556    ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
557
558    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_SCAN_RESP, param,
559               cmd_length, command_complete);
560  }
561
562  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
563                        status_cb command_complete) override {
564    VLOG(1) << __func__;
565    const int LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN = 7;
566
567    uint8_t param[LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN];
568    memset(param, 0, LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN);
569
570    uint8_t* pp = param;
571    UINT8_TO_STREAM(pp, handle);
572    BDADDR_TO_STREAM(pp, random_address);
573
574    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_RANDOM_ADDRESS, param,
575               LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN, command_complete);
576  }
577
578  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
579              status_cb command_complete) override {
580    VLOG(1) << __func__;
581
582    /* cmd_length = header_size + num_of_of_advertiser * size_per_advertiser */
583    const uint16_t cmd_length = 2 + sets.size() * 4;
584    uint8_t param[cmd_length];
585    memset(param, 0, cmd_length);
586
587    uint8_t* pp = param;
588    UINT8_TO_STREAM(pp, enable);
589
590    UINT8_TO_STREAM(pp, sets.size());
591    for (const SetEnableData& set : sets) {
592      UINT8_TO_STREAM(pp, set.handle);
593      UINT16_TO_STREAM(pp, set.duration);
594      UINT8_TO_STREAM(pp, set.max_extended_advertising_events);
595    }
596
597    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_ENABLE, param, cmd_length,
598               command_complete);
599  }
600
601  void SetPeriodicAdvertisingParameters(uint8_t handle,
602                                        uint16_t periodic_adv_int_min,
603                                        uint16_t periodic_adv_int_max,
604                                        uint16_t periodic_properties,
605                                        status_cb command_complete) override {
606    VLOG(1) << __func__;
607    const uint16_t HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN = 7;
608    uint8_t param[HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN];
609    memset(param, 0, HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN);
610
611    uint8_t* pp = param;
612    UINT8_TO_STREAM(pp, handle);
613    UINT16_TO_STREAM(pp, periodic_adv_int_min);
614    UINT16_TO_STREAM(pp, periodic_adv_int_max);
615    UINT16_TO_STREAM(pp, periodic_properties);
616
617    SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_PARAM, param,
618               HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN, command_complete);
619  }
620
621  void SetPeriodicAdvertisingData(uint8_t handle, uint8_t operation,
622                                  uint8_t adv_data_length, uint8_t* adv_data,
623                                  status_cb command_complete) override {
624    VLOG(1) << __func__;
625    const uint16_t HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN =
626        3 + adv_data_length;
627    uint8_t param[HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN];
628    memset(param, 0, HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN);
629    uint8_t* pp = param;
630    UINT8_TO_STREAM(pp, handle);
631    UINT8_TO_STREAM(pp, operation);
632    UINT8_TO_STREAM(pp, adv_data_length);
633    ARRAY_TO_STREAM(pp, adv_data, adv_data_length);
634    SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_DATA, param,
635               HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN, command_complete);
636  }
637
638  void SetPeriodicAdvertisingEnable(uint8_t enable, uint8_t handle,
639                                    status_cb command_complete) override {
640    VLOG(1) << __func__;
641    const uint16_t HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN = 2;
642    uint8_t param[HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN];
643    memset(param, 0, HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN);
644    uint8_t* pp = param;
645    UINT8_TO_STREAM(pp, enable);
646    UINT8_TO_STREAM(pp, handle);
647    SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE, param,
648               HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN, command_complete);
649  }
650
651  void RemoveAdvertisingSet(uint8_t handle,
652                            status_cb command_complete) override {
653    VLOG(1) << __func__;
654
655    const uint16_t cmd_length = 1;
656    uint8_t param[cmd_length];
657    memset(param, 0, cmd_length);
658
659    uint8_t* pp = param;
660    UINT8_TO_STREAM(pp, handle);
661
662    SendAdvCmd(FROM_HERE, HCI_LE_REMOVE_ADVERTISING_SET, param, cmd_length,
663               command_complete);
664  }
665
666 public:
667  void OnAdvertisingSetTerminated(uint8_t length, uint8_t* p) {
668    VLOG(1) << __func__;
669    LOG_ASSERT(p);
670    uint8_t status, advertising_handle, num_completed_extended_adv_events;
671    uint16_t conn_handle;
672
673    STREAM_TO_UINT8(status, p);
674    STREAM_TO_UINT8(advertising_handle, p);
675    STREAM_TO_UINT16(conn_handle, p);
676    STREAM_TO_UINT8(num_completed_extended_adv_events, p);
677
678    conn_handle = conn_handle & 0x0FFF;  // only 12 bits meaningful
679
680    AdvertisingEventObserver* observer = this->advertising_event_observer;
681    if (observer)
682      observer->OnAdvertisingSetTerminated(status, advertising_handle,
683                                           conn_handle,
684                                           num_completed_extended_adv_events);
685  }
686
687 private:
688  AdvertisingEventObserver* advertising_event_observer = nullptr;
689};
690
691}  // namespace
692
693void btm_le_on_advertising_set_terminated(uint8_t* p, uint16_t length) {
694  if (BleAdvertiserHciInterface::Get()) {
695    ((BleAdvertiserHciExtendedImpl*)BleAdvertiserHciInterface::Get())
696        ->OnAdvertisingSetTerminated(length, p);
697  }
698}
699
700void BleAdvertiserHciInterface::Initialize() {
701  VLOG(1) << __func__;
702  LOG_ASSERT(instance == nullptr) << "Was already initialized.";
703
704  if (controller_get_interface()->supports_ble_extended_advertising()) {
705    LOG(INFO) << "Extended advertising will be in use";
706    instance = new BleAdvertiserHciExtendedImpl();
707  } else if (BTM_BleMaxMultiAdvInstanceCount()) {
708    LOG(INFO) << "VSC advertising will be in use";
709    instance = new BleAdvertiserVscHciInterfaceImpl();
710    BTM_RegisterForVSEvents(
711        BleAdvertiserVscHciInterfaceImpl::VendorSpecificEventCback, true);
712  } else {
713    LOG(INFO) << "Legacy advertising will be in use";
714    instance = new BleAdvertiserLegacyHciInterfaceImpl();
715  }
716}
717
718BleAdvertiserHciInterface* BleAdvertiserHciInterface::Get() { return instance; }
719
720void BleAdvertiserHciInterface::CleanUp() {
721  VLOG(1) << __func__;
722
723  if (BTM_BleMaxMultiAdvInstanceCount()) {
724    BTM_RegisterForVSEvents(
725        BleAdvertiserVscHciInterfaceImpl::VendorSpecificEventCback, false);
726  }
727
728  delete instance;
729  instance = nullptr;
730}
731