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