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