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