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