Advertising Extension Implementation am: 5af96d3fda am: 21c5dcc3d0 am: e5c176a09f
am: 1cf7d4e9af
Change-Id: I1a0ef9f2df5cd1dfc39f707906f9b5ddab17708e
diff --git a/stack/btm/ble_advertiser_hci_interface.cc b/stack/btm/ble_advertiser_hci_interface.cc
index 92423b1..44af09c 100644
--- a/stack/btm/ble_advertiser_hci_interface.cc
+++ b/stack/btm/ble_advertiser_hci_interface.cc
@@ -23,6 +23,7 @@
#include <utility>
#include "btm_api.h"
#include "btm_ble_api.h"
+#include "device/include/controller.h"
#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
#define BTM_BLE_MULTI_ADV_ENB_LEN 3
@@ -330,6 +331,146 @@
}
};
+class BleAdvertiserHciExtendedImpl : public BleAdvertiserHciInterface {
+ void SendAdvCmd(uint16_t opcode, uint8_t* param_buf, uint8_t param_buf_len,
+ status_cb command_complete) {
+ btu_hcif_send_cmd_with_cb(opcode, param_buf, param_buf_len,
+ adv_cmd_cmpl_cback);
+
+ legacy_pending_ops->push(std::make_pair(opcode, command_complete));
+ }
+
+ void ReadInstanceCount(
+ base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
+ cb.Run(controller_get_interface()
+ ->get_ble_number_of_supported_advertising_sets());
+ }
+
+ void SetAdvertisingEventObserver(
+ AdvertisingEventObserver* observer) override {}
+
+ void SetParameters(uint8_t adv_int_min, uint8_t adv_int_max,
+ uint8_t advertising_type, uint8_t own_address_type,
+ BD_ADDR own_address, uint8_t direct_address_type,
+ BD_ADDR direct_address, uint8_t channel_map,
+ uint8_t filter_policy, uint8_t advertising_handle,
+ uint8_t tx_power, status_cb command_complete) override {
+ VLOG(1) << __func__;
+ const uint16_t HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN = 25;
+ uint8_t param[HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN];
+ memset(param, 0, HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN);
+
+ uint8_t* pp = param;
+ UINT8_TO_STREAM(pp, advertising_handle);
+
+ if (advertising_type == 0x00) { // ADV_IND
+ UINT16_TO_STREAM(pp, 0x13);
+ } else if (advertising_type == 0x02) { // ADV_SCAN_IND
+ UINT16_TO_STREAM(pp, 0x12);
+ } else if (advertising_type == 0x03) { // ADV_NONCONN_IND
+ UINT16_TO_STREAM(pp, 0x10);
+ } else {
+ LOG_ASSERT("Unsupported advertisement type selected!");
+ }
+
+ UINT24_TO_STREAM(pp, (uint32_t)adv_int_min);
+ UINT24_TO_STREAM(pp, (uint32_t)adv_int_max);
+ UINT8_TO_STREAM(pp, channel_map);
+
+ UINT8_TO_STREAM(pp, own_address_type);
+ UINT8_TO_STREAM(pp, direct_address_type);
+ BDADDR_TO_STREAM(pp, direct_address);
+ UINT8_TO_STREAM(pp, filter_policy);
+
+ INT8_TO_STREAM(pp, tx_power);
+
+ UINT8_TO_STREAM(pp, 0x01); // primary advertising phy
+ UINT8_TO_STREAM(pp, 0x01); // secondary advertising max skip
+ UINT8_TO_STREAM(pp, 0x01); // secondary advertising phy
+ UINT8_TO_STREAM(pp, 0x00); // advertising SID
+ UINT8_TO_STREAM(pp, 0x00); // scan req notification
+
+ SendAdvCmd(HCI_LE_SET_EXT_ADVERTISING_PARAM, param,
+ HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN, command_complete);
+ }
+
+ void SetAdvertisingData(uint8_t data_length, uint8_t* data, uint8_t inst_id,
+ status_cb command_complete) override {
+ VLOG(1) << __func__;
+
+ const uint16_t cmd_length = 4 + data_length;
+ uint8_t param[cmd_length];
+ memset(param, 0, cmd_length);
+
+ uint8_t* pp = param;
+ UINT8_TO_STREAM(pp, inst_id);
+ UINT8_TO_STREAM(pp, 0x03); // complete advertising data
+ UINT8_TO_STREAM(pp, 0x01); // don't fragment
+ UINT8_TO_STREAM(pp, data_length);
+ ARRAY_TO_STREAM(pp, data, data_length);
+
+ SendAdvCmd(HCI_LE_SET_EXT_ADVERTISING_DATA, param, cmd_length,
+ command_complete);
+ }
+
+ void SetScanResponseData(uint8_t scan_response_data_length,
+ uint8_t* scan_response_data, uint8_t inst_id,
+ status_cb command_complete) override {
+ VLOG(1) << __func__;
+
+ const uint16_t cmd_length = 4 + scan_response_data_length;
+ uint8_t param[cmd_length];
+ memset(param, 0, cmd_length);
+
+ uint8_t* pp = param;
+ UINT8_TO_STREAM(pp, inst_id);
+ UINT8_TO_STREAM(pp, 0x03); // complete advertising data
+ UINT8_TO_STREAM(pp, 0x01); // don't fragment
+ UINT8_TO_STREAM(pp, scan_response_data_length);
+ ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
+
+ SendAdvCmd(HCI_LE_SET_EXT_ADVERTISING_SCAN_RESP, param, cmd_length,
+ command_complete);
+ }
+
+ void SetRandomAddress(uint8_t random_address[6], uint8_t advertising_handle,
+ status_cb command_complete) override {
+ VLOG(1) << __func__;
+ const int LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN = 7;
+
+ uint8_t param[LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN];
+ memset(param, 0, LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN);
+
+ uint8_t* pp = param;
+ UINT8_TO_STREAM(pp, advertising_handle);
+ BDADDR_TO_STREAM(pp, random_address);
+
+ SendAdvCmd(HCI_LE_SET_EXT_ADVERTISING_RANDOM_ADDRESS, param,
+ LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN, command_complete);
+ }
+
+ void Enable(uint8_t advertising_enable, uint8_t inst_id,
+ status_cb command_complete) override {
+ VLOG(1) << __func__;
+
+ /* cmd_length = header_size + num_of_of_advertiser * size_per_advertiser */
+ const uint16_t cmd_length = 2 + 1 * 4;
+ uint8_t param[cmd_length];
+ memset(param, 0, cmd_length);
+
+ uint8_t* pp = param;
+ UINT8_TO_STREAM(pp, 0x01); // enable
+ UINT8_TO_STREAM(pp, 0x01); // just one set
+
+ UINT8_TO_STREAM(pp, inst_id); // set_id
+ UINT16_TO_STREAM(pp, 0x0000); // duration
+ UINT8_TO_STREAM(pp, 0x00); // max extended advertising events
+
+ SendAdvCmd(HCI_LE_SET_EXT_ADVERTISING_ENABLE, param, cmd_length,
+ command_complete);
+ }
+};
+
} // namespace
void BleAdvertiserHciInterface::Initialize() {
@@ -338,7 +479,9 @@
pending_ops = new std::queue<std::pair<uint8_t, status_cb>>();
legacy_pending_ops = new std::queue<std::pair<uint16_t, status_cb>>();
- if (BTM_BleMaxMultiAdvInstanceCount()) {
+ if (controller_get_interface()->supports_ble_extended_advertising()) {
+ instance = new BleAdvertiserHciExtendedImpl();
+ } else if (BTM_BleMaxMultiAdvInstanceCount()) {
instance = new BleAdvertiserVscHciInterfaceImpl();
BTM_RegisterForVSEvents(
BleAdvertiserVscHciInterfaceImpl::VendorSpecificEventCback, true);
diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h
index 5b40feb..9f4f98c 100644
--- a/stack/include/hcidefs.h
+++ b/stack/include/hcidefs.h
@@ -356,6 +356,11 @@
#define HCI_BLE_SET_ADDR_RESOLUTION_ENABLE (0x002D | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT (0x002E | HCI_GRP_BLE_CMDS)
+#define HCI_LE_SET_EXT_ADVERTISING_RANDOM_ADDRESS (0x35 | HCI_GRP_BLE_CMDS)
+#define HCI_LE_SET_EXT_ADVERTISING_PARAM (0x36 | HCI_GRP_BLE_CMDS)
+#define HCI_LE_SET_EXT_ADVERTISING_DATA (0x37 | HCI_GRP_BLE_CMDS)
+#define HCI_LE_SET_EXT_ADVERTISING_SCAN_RESP (0x38 | HCI_GRP_BLE_CMDS)
+#define HCI_LE_SET_EXT_ADVERTISING_ENABLE (0x39 | HCI_GRP_BLE_CMDS)
#define HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH (0x003A | HCI_GRP_BLE_CMDS)
#define HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS \
(0x003B | HCI_GRP_BLE_CMDS)