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 
43 using status_cb = BleAdvertiserHciInterface::status_cb;
44 
45 using hci_cmd_cb = base::Callback<void(uint8_t* /* return_parameters */,
46                                        uint16_t /* return_parameters_length*/)>;
47 extern 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 
51 namespace {
52 BleAdvertiserHciInterface* instance = nullptr;
53 
btm_ble_multi_adv_vsc_cmpl_cback(uint8_t expected_opcode,status_cb command_complete,uint8_t * param,uint16_t param_len)54 void 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 
parameters_response_parser(BleAdvertiserHciInterface::parameters_cb cb,uint8_t * ret_params,uint16_t ret_params_len)76 void 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 
known_tx_pwr(BleAdvertiserHciInterface::parameters_cb cb,int8_t tx_power,uint8_t status)88 void known_tx_pwr(BleAdvertiserHciInterface::parameters_cb cb, int8_t tx_power,
89                   uint8_t status) {
90   cb.Run(status, tx_power);
91 }
92 
93 class BleAdvertiserVscHciInterfaceImpl : public BleAdvertiserHciInterface {
SendAdvCmd(const tracked_objects::Location & posted_from,uint8_t param_len,uint8_t * param_buf,status_cb command_complete)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 
ReadInstanceCount(base::Callback<void (uint8_t)> cb)103   void ReadInstanceCount(
104       base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
105     cb.Run(BTM_BleMaxMultiAdvInstanceCount());
106   }
107 
SetAdvertisingEventObserver(AdvertisingEventObserver * observer)108   void SetAdvertisingEventObserver(
109       AdvertisingEventObserver* observer) override {
110     this->advertising_event_observer = observer;
111   }
112 
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,BD_ADDR own_address,uint8_t peer_address_type,BD_ADDR 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)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, BD_ADDR own_address,
116                      uint8_t peer_address_type, BD_ADDR 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 
SetAdvertisingData(uint8_t handle,uint8_t operation,uint8_t fragment_preference,uint8_t data_length,uint8_t * data,status_cb command_complete)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 
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)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 
SetRandomAddress(uint8_t handle,uint8_t random_address[6],status_cb command_complete)194   void SetRandomAddress(uint8_t handle, uint8_t random_address[6],
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 
Enable(uint8_t enable,uint8_t handle,uint16_t duration,uint8_t max_extended_advertising_events,status_cb command_complete)209   void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
210               uint8_t max_extended_advertising_events,
211               status_cb command_complete) override {
212     VLOG(1) << __func__;
213 
214     if (max_extended_advertising_events) {
215       command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
216       return;
217     }
218 
219     uint8_t param[BTM_BLE_MULTI_ADV_ENB_LEN];
220     memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
221 
222     uint8_t* pp = param;
223     UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_ENB);
224     UINT8_TO_STREAM(pp, enable);
225     UINT8_TO_STREAM(pp, handle);
226 
227     SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_ENB_LEN, param,
228                command_complete);
229   }
230 
SetPeriodicAdvertisingParameters(uint8_t,uint16_t,uint16_t,uint16_t,status_cb command_complete)231   void SetPeriodicAdvertisingParameters(uint8_t, uint16_t, uint16_t, uint16_t,
232                                         status_cb command_complete) override {
233     LOG(INFO) << __func__ << " VSC can't do periodic advertising";
234     command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
235   }
236 
SetPeriodicAdvertisingData(uint8_t,uint8_t,uint8_t,uint8_t *,status_cb command_complete)237   void SetPeriodicAdvertisingData(uint8_t, uint8_t, uint8_t, uint8_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 
SetPeriodicAdvertisingEnable(uint8_t,uint8_t,status_cb command_complete)243   void SetPeriodicAdvertisingEnable(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 
QuirkAdvertiserZeroHandle()249   bool QuirkAdvertiserZeroHandle() override {
250     // Android BT HCI Requirements version 0.96 and below specify that handle 0
251     // is equal to standard HCI interface, and should be accessed using non-VSC
252     // commands.
253     LOG(INFO) << "QuirkAdvertiserZeroHandle in use";
254     return true;
255   }
256 
RemoveAdvertisingSet(uint8_t handle,status_cb command_complete)257   void RemoveAdvertisingSet(uint8_t handle,
258                             status_cb command_complete) override {
259     // VSC Advertising don't have remove method.
260     command_complete.Run(0);
261   }
262 
263  public:
VendorSpecificEventCback(uint8_t length,uint8_t * p)264   static void VendorSpecificEventCback(uint8_t length, uint8_t* p) {
265     VLOG(1) << __func__;
266 
267     LOG_ASSERT(p);
268     uint8_t sub_event, adv_inst, change_reason;
269     uint16_t conn_handle;
270 
271     STREAM_TO_UINT8(sub_event, p);
272     length--;
273 
274     if (sub_event != HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG || length != 4) {
275       return;
276     }
277 
278     STREAM_TO_UINT8(adv_inst, p);
279     STREAM_TO_UINT8(change_reason, p);
280     STREAM_TO_UINT16(conn_handle, p);
281 
282     AdvertisingEventObserver* observer =
283         ((BleAdvertiserVscHciInterfaceImpl*)BleAdvertiserHciInterface::Get())
284             ->advertising_event_observer;
285     if (observer)
286       observer->OnAdvertisingSetTerminated(change_reason, adv_inst, conn_handle,
287                                            0x00);
288   }
289 
290  private:
291   AdvertisingEventObserver* advertising_event_observer = nullptr;
292 };
293 
adv_cmd_cmpl_cback(status_cb cb,uint8_t * return_parameters,uint16_t return_parameters_length)294 void adv_cmd_cmpl_cback(status_cb cb, uint8_t* return_parameters,
295                         uint16_t return_parameters_length) {
296   uint8_t status = *return_parameters;
297   cb.Run(status);
298 }
299 
300 class BleAdvertiserLegacyHciInterfaceImpl : public BleAdvertiserHciInterface {
SendAdvCmd(const tracked_objects::Location & posted_from,uint16_t opcode,uint8_t * param_buf,uint8_t param_buf_len,status_cb command_complete)301   void SendAdvCmd(const tracked_objects::Location& posted_from, uint16_t opcode,
302                   uint8_t* param_buf, uint8_t param_buf_len,
303                   status_cb command_complete) {
304     btu_hcif_send_cmd_with_cb(
305         posted_from, opcode, param_buf, param_buf_len,
306         base::Bind(&adv_cmd_cmpl_cback, command_complete));
307   }
308 
ReadInstanceCount(base::Callback<void (uint8_t)> cb)309   void ReadInstanceCount(
310       base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
311     cb.Run(1);
312   }
313 
SetAdvertisingEventObserver(AdvertisingEventObserver * observer)314   void SetAdvertisingEventObserver(
315       AdvertisingEventObserver* observer) override {}
316 
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,BD_ADDR,uint8_t peer_address_type,BD_ADDR 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)317   void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
318                      uint32_t adv_int_max, uint8_t channel_map,
319                      uint8_t own_address_type, BD_ADDR /* own_address */,
320                      uint8_t peer_address_type, BD_ADDR peer_address,
321                      uint8_t filter_policy, int8_t tx_power,
322                      uint8_t primary_phy, uint8_t secondary_max_skip,
323                      uint8_t secondary_phy, uint8_t advertising_sid,
324                      uint8_t scan_request_notify_enable,
325                      parameters_cb command_complete) override {
326     VLOG(1) << __func__;
327 
328     uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS];
329 
330     uint8_t* pp = param;
331     UINT16_TO_STREAM(pp, adv_int_min);
332     UINT16_TO_STREAM(pp, adv_int_max);
333 
334     if (properties == 0x0013) {
335       UINT8_TO_STREAM(pp, 0x00);  // ADV_IND
336     } else if (properties == 0x0012) {
337       UINT8_TO_STREAM(pp, 0x02);  // ADV_SCAN_IND
338     } else if (properties == 0x0010) {
339       UINT8_TO_STREAM(pp, 0x03);  // ADV_NONCONN_IND
340     } else {
341       LOG(ERROR) << "Unsupported advertisement type selected:" << std::hex
342                  << properties;
343       command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT, 0);
344       return;
345     }
346 
347     UINT8_TO_STREAM(pp, own_address_type);
348     UINT8_TO_STREAM(pp, peer_address_type);
349     BDADDR_TO_STREAM(pp, peer_address);
350     UINT8_TO_STREAM(pp, channel_map);
351     UINT8_TO_STREAM(pp, filter_policy);
352 
353     SendAdvCmd(
354         FROM_HERE, HCI_BLE_WRITE_ADV_PARAMS, param,
355         HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS,
356         base::Bind(&known_tx_pwr, std::move(command_complete), (int8_t)0));
357   }
358 
SetAdvertisingData(uint8_t handle,uint8_t operation,uint8_t fragment_preference,uint8_t data_length,uint8_t * data,status_cb command_complete)359   void SetAdvertisingData(uint8_t handle, uint8_t operation,
360                           uint8_t fragment_preference, uint8_t data_length,
361                           uint8_t* data, status_cb command_complete) override {
362     VLOG(1) << __func__;
363 
364     uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1];
365 
366     uint8_t* pp = param;
367     memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
368     UINT8_TO_STREAM(pp, data_length);
369     ARRAY_TO_STREAM(pp, data, data_length);
370 
371     SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_ADV_DATA, param,
372                HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1, command_complete);
373   }
374 
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)375   void SetScanResponseData(uint8_t handle, uint8_t operation,
376                            uint8_t fragment_preference,
377                            uint8_t scan_response_data_length,
378                            uint8_t* scan_response_data,
379                            status_cb command_complete) override {
380     VLOG(1) << __func__;
381     uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1];
382 
383     uint8_t* pp = param;
384     memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
385     UINT8_TO_STREAM(pp, scan_response_data_length);
386     ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
387 
388     SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_SCAN_RSP_DATA, param,
389                HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1, command_complete);
390   }
391 
SetRandomAddress(uint8_t handle,uint8_t random_address[6],status_cb command_complete)392   void SetRandomAddress(uint8_t handle, uint8_t random_address[6],
393                         status_cb command_complete) override {
394     VLOG(1) << __func__;
395 
396     uint8_t param[HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD];
397 
398     uint8_t* pp = param;
399     BDADDR_TO_STREAM(pp, random_address);
400 
401     SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_RANDOM_ADDR, param,
402                HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD, command_complete);
403   }
404 
Enable(uint8_t enable,uint8_t handle,uint16_t duration,uint8_t max_extended_advertising_events,status_cb command_complete)405   void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
406               uint8_t max_extended_advertising_events,
407               status_cb command_complete) override {
408     VLOG(1) << __func__;
409 
410     if (max_extended_advertising_events) {
411       command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
412       return;
413     }
414 
415     uint8_t param[HCIC_PARAM_SIZE_WRITE_ADV_ENABLE];
416 
417     uint8_t* pp = param;
418     UINT8_TO_STREAM(pp, enable);
419 
420     SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_ADV_ENABLE, param,
421                HCIC_PARAM_SIZE_WRITE_ADV_ENABLE, command_complete);
422   }
423 
SetPeriodicAdvertisingParameters(uint8_t,uint16_t,uint16_t,uint16_t,status_cb command_complete)424   void SetPeriodicAdvertisingParameters(uint8_t, uint16_t, uint16_t, uint16_t,
425                                         status_cb command_complete) override {
426     LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
427     command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
428   }
429 
SetPeriodicAdvertisingData(uint8_t,uint8_t,uint8_t,uint8_t *,status_cb command_complete)430   void SetPeriodicAdvertisingData(uint8_t, uint8_t, uint8_t, uint8_t*,
431                                   status_cb command_complete) override {
432     LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
433     command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
434   }
435 
SetPeriodicAdvertisingEnable(uint8_t,uint8_t,status_cb command_complete)436   void SetPeriodicAdvertisingEnable(uint8_t, uint8_t,
437                                     status_cb command_complete) override {
438     LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
439     command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
440   }
441 
RemoveAdvertisingSet(uint8_t handle,status_cb command_complete)442   void RemoveAdvertisingSet(uint8_t handle,
443                             status_cb command_complete) override {
444     // Legacy Advertising don't have remove method.
445     command_complete.Run(0);
446   }
447 };
448 
449 class BleAdvertiserHciExtendedImpl : public BleAdvertiserHciInterface {
SendAdvCmd(const tracked_objects::Location & posted_from,uint16_t opcode,uint8_t * param_buf,uint8_t param_buf_len,status_cb command_complete)450   void SendAdvCmd(const tracked_objects::Location& posted_from, uint16_t opcode,
451                   uint8_t* param_buf, uint8_t param_buf_len,
452                   status_cb command_complete) {
453     btu_hcif_send_cmd_with_cb(
454         posted_from, opcode, param_buf, param_buf_len,
455         base::Bind(&adv_cmd_cmpl_cback, command_complete));
456   }
457 
ReadInstanceCount(base::Callback<void (uint8_t)> cb)458   void ReadInstanceCount(
459       base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
460     cb.Run(controller_get_interface()
461                ->get_ble_number_of_supported_advertising_sets());
462   }
463 
SetAdvertisingEventObserver(AdvertisingEventObserver * observer)464   void SetAdvertisingEventObserver(
465       AdvertisingEventObserver* observer) override {
466     this->advertising_event_observer = observer;
467   }
468 
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,BD_ADDR,uint8_t peer_address_type,BD_ADDR 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)469   void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
470                      uint32_t adv_int_max, uint8_t channel_map,
471                      uint8_t own_address_type, BD_ADDR /* own_address */,
472                      uint8_t peer_address_type, BD_ADDR peer_address,
473                      uint8_t filter_policy, int8_t tx_power,
474                      uint8_t primary_phy, uint8_t secondary_max_skip,
475                      uint8_t secondary_phy, uint8_t advertising_sid,
476                      uint8_t scan_request_notify_enable,
477                      parameters_cb command_complete) override {
478     VLOG(1) << __func__;
479     const uint16_t HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN = 25;
480     uint8_t param[HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN];
481     memset(param, 0, HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN);
482 
483     uint8_t* pp = param;
484     UINT8_TO_STREAM(pp, handle);
485     UINT16_TO_STREAM(pp, properties);
486     UINT24_TO_STREAM(pp, adv_int_min);
487     UINT24_TO_STREAM(pp, adv_int_max);
488     UINT8_TO_STREAM(pp, channel_map);
489     UINT8_TO_STREAM(pp, own_address_type);
490     UINT8_TO_STREAM(pp, peer_address_type);
491     BDADDR_TO_STREAM(pp, peer_address);
492     UINT8_TO_STREAM(pp, filter_policy);
493     INT8_TO_STREAM(pp, tx_power);
494     UINT8_TO_STREAM(pp, primary_phy);
495     UINT8_TO_STREAM(pp, secondary_max_skip);
496     UINT8_TO_STREAM(pp, secondary_phy);
497     UINT8_TO_STREAM(pp, advertising_sid);
498     UINT8_TO_STREAM(pp, scan_request_notify_enable);
499 
500     btu_hcif_send_cmd_with_cb(
501         FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_PARAM, param,
502         HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN,
503         base::Bind(parameters_response_parser, std::move(command_complete)));
504   }
505 
SetAdvertisingData(uint8_t handle,uint8_t operation,uint8_t fragment_preference,uint8_t data_length,uint8_t * data,status_cb command_complete)506   void SetAdvertisingData(uint8_t handle, uint8_t operation,
507                           uint8_t fragment_preference, uint8_t data_length,
508                           uint8_t* data, status_cb command_complete) override {
509     VLOG(1) << __func__;
510 
511     const uint16_t cmd_length = 4 + data_length;
512     uint8_t param[cmd_length];
513     memset(param, 0, cmd_length);
514 
515     uint8_t* pp = param;
516     UINT8_TO_STREAM(pp, handle);
517     UINT8_TO_STREAM(pp, operation);
518     UINT8_TO_STREAM(pp, fragment_preference);
519     UINT8_TO_STREAM(pp, data_length);
520     ARRAY_TO_STREAM(pp, data, data_length);
521 
522     SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_DATA, param, cmd_length,
523                command_complete);
524   }
525 
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)526   void SetScanResponseData(uint8_t handle, uint8_t operation,
527                            uint8_t fragment_preference,
528                            uint8_t scan_response_data_length,
529                            uint8_t* scan_response_data,
530                            status_cb command_complete) override {
531     VLOG(1) << __func__;
532 
533     const uint16_t cmd_length = 4 + scan_response_data_length;
534     uint8_t param[cmd_length];
535     memset(param, 0, cmd_length);
536 
537     uint8_t* pp = param;
538     UINT8_TO_STREAM(pp, handle);
539     UINT8_TO_STREAM(pp, operation);
540     UINT8_TO_STREAM(pp, fragment_preference);
541     UINT8_TO_STREAM(pp, scan_response_data_length);
542     ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
543 
544     SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_SCAN_RESP, param,
545                cmd_length, command_complete);
546   }
547 
SetRandomAddress(uint8_t handle,uint8_t random_address[6],status_cb command_complete)548   void SetRandomAddress(uint8_t handle, uint8_t random_address[6],
549                         status_cb command_complete) override {
550     VLOG(1) << __func__;
551     const int LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN = 7;
552 
553     uint8_t param[LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN];
554     memset(param, 0, LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN);
555 
556     uint8_t* pp = param;
557     UINT8_TO_STREAM(pp, handle);
558     BDADDR_TO_STREAM(pp, random_address);
559 
560     SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_RANDOM_ADDRESS, param,
561                LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN, command_complete);
562   }
563 
Enable(uint8_t enable,uint8_t handle,uint16_t duration,uint8_t max_extended_advertising_events,status_cb command_complete)564   void Enable(uint8_t enable, uint8_t handle, uint16_t duration,
565               uint8_t max_extended_advertising_events,
566               status_cb command_complete) override {
567     VLOG(1) << __func__;
568 
569     /* cmd_length = header_size + num_of_of_advertiser * size_per_advertiser */
570     const uint16_t cmd_length = 2 + 1 * 4;
571     uint8_t param[cmd_length];
572     memset(param, 0, cmd_length);
573 
574     uint8_t* pp = param;
575     UINT8_TO_STREAM(pp, enable);
576     UINT8_TO_STREAM(pp, 0x01);  // just one set
577 
578     UINT8_TO_STREAM(pp, handle);
579     UINT16_TO_STREAM(pp, duration);
580     UINT8_TO_STREAM(pp, max_extended_advertising_events);
581 
582     SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_ENABLE, param, cmd_length,
583                command_complete);
584   }
585 
SetPeriodicAdvertisingParameters(uint8_t handle,uint16_t periodic_adv_int_min,uint16_t periodic_adv_int_max,uint16_t periodic_properties,status_cb command_complete)586   void SetPeriodicAdvertisingParameters(uint8_t handle,
587                                         uint16_t periodic_adv_int_min,
588                                         uint16_t periodic_adv_int_max,
589                                         uint16_t periodic_properties,
590                                         status_cb command_complete) override {
591     VLOG(1) << __func__;
592     const uint16_t HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN = 7;
593     uint8_t param[HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN];
594     memset(param, 0, HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN);
595 
596     uint8_t* pp = param;
597     UINT8_TO_STREAM(pp, handle);
598     UINT16_TO_STREAM(pp, periodic_adv_int_min);
599     UINT16_TO_STREAM(pp, periodic_adv_int_max);
600     UINT16_TO_STREAM(pp, periodic_properties);
601 
602     SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_PARAM, param,
603                HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN, command_complete);
604   }
605 
SetPeriodicAdvertisingData(uint8_t handle,uint8_t operation,uint8_t adv_data_length,uint8_t * adv_data,status_cb command_complete)606   void SetPeriodicAdvertisingData(uint8_t handle, uint8_t operation,
607                                   uint8_t adv_data_length, uint8_t* adv_data,
608                                   status_cb command_complete) override {
609     VLOG(1) << __func__;
610     const uint16_t HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN =
611         3 + adv_data_length;
612     uint8_t param[HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN];
613     memset(param, 0, HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN);
614     uint8_t* pp = param;
615     UINT8_TO_STREAM(pp, handle);
616     UINT8_TO_STREAM(pp, operation);
617     UINT8_TO_STREAM(pp, adv_data_length);
618     ARRAY_TO_STREAM(pp, adv_data, adv_data_length);
619     SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_DATA, param,
620                HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN, command_complete);
621   }
622 
SetPeriodicAdvertisingEnable(uint8_t enable,uint8_t handle,status_cb command_complete)623   void SetPeriodicAdvertisingEnable(uint8_t enable, uint8_t handle,
624                                     status_cb command_complete) override {
625     VLOG(1) << __func__;
626     const uint16_t HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN = 2;
627     uint8_t param[HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN];
628     memset(param, 0, HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN);
629     uint8_t* pp = param;
630     UINT8_TO_STREAM(pp, enable);
631     UINT8_TO_STREAM(pp, handle);
632     SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE, param,
633                HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN, command_complete);
634   }
635 
RemoveAdvertisingSet(uint8_t handle,status_cb command_complete)636   void RemoveAdvertisingSet(uint8_t handle,
637                             status_cb command_complete) override {
638     VLOG(1) << __func__;
639 
640     const uint16_t cmd_length = 1;
641     uint8_t param[cmd_length];
642     memset(param, 0, cmd_length);
643 
644     uint8_t* pp = param;
645     UINT8_TO_STREAM(pp, handle);
646 
647     SendAdvCmd(FROM_HERE, HCI_LE_REMOVE_ADVERTISING_SET, param, cmd_length,
648                command_complete);
649   }
650 
651  public:
OnAdvertisingSetTerminated(uint8_t length,uint8_t * p)652   void OnAdvertisingSetTerminated(uint8_t length, uint8_t* p) {
653     VLOG(1) << __func__;
654     LOG_ASSERT(p);
655     uint8_t status, advertising_handle, num_completed_extended_adv_events;
656     uint16_t conn_handle;
657 
658     STREAM_TO_UINT8(status, p);
659     STREAM_TO_UINT8(advertising_handle, p);
660     STREAM_TO_UINT16(conn_handle, p);
661     STREAM_TO_UINT8(num_completed_extended_adv_events, p);
662 
663     conn_handle = conn_handle & 0x0FFF;  // only 12 bits meaningful
664 
665     AdvertisingEventObserver* observer = this->advertising_event_observer;
666     if (observer)
667       observer->OnAdvertisingSetTerminated(status, advertising_handle,
668                                            conn_handle,
669                                            num_completed_extended_adv_events);
670   }
671 
672  private:
673   AdvertisingEventObserver* advertising_event_observer = nullptr;
674 };
675 
676 }  // namespace
677 
btm_le_on_advertising_set_terminated(uint8_t * p,uint16_t length)678 void btm_le_on_advertising_set_terminated(uint8_t* p, uint16_t length) {
679   if (BleAdvertiserHciInterface::Get()) {
680     ((BleAdvertiserHciExtendedImpl*)BleAdvertiserHciInterface::Get())
681         ->OnAdvertisingSetTerminated(length, p);
682   }
683 }
684 
Initialize()685 void BleAdvertiserHciInterface::Initialize() {
686   VLOG(1) << __func__;
687   LOG_ASSERT(instance == nullptr) << "Was already initialized.";
688 
689   if (controller_get_interface()->supports_ble_extended_advertising()) {
690     LOG(INFO) << "Extended advertising will be in use";
691     instance = new BleAdvertiserHciExtendedImpl();
692   } else if (BTM_BleMaxMultiAdvInstanceCount()) {
693     LOG(INFO) << "VSC advertising will be in use";
694     instance = new BleAdvertiserVscHciInterfaceImpl();
695     BTM_RegisterForVSEvents(
696         BleAdvertiserVscHciInterfaceImpl::VendorSpecificEventCback, true);
697   } else {
698     LOG(INFO) << "Legacy advertising will be in use";
699     instance = new BleAdvertiserLegacyHciInterfaceImpl();
700   }
701 }
702 
Get()703 BleAdvertiserHciInterface* BleAdvertiserHciInterface::Get() { return instance; }
704 
CleanUp()705 void BleAdvertiserHciInterface::CleanUp() {
706   VLOG(1) << __func__;
707 
708   if (BTM_BleMaxMultiAdvInstanceCount()) {
709     BTM_RegisterForVSEvents(
710         BleAdvertiserVscHciInterfaceImpl::VendorSpecificEventCback, false);
711   }
712 
713   delete instance;
714   instance = nullptr;
715 }
716