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