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