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