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