1e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski/******************************************************************************
2e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *
3e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  Copyright (C) 2016 The Android Open Source Project
4e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *
5e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  Licensed under the Apache License, Version 2.0 (the "License");
6e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  you may not use this file except in compliance with the License.
7e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  You may obtain a copy of the License at:
8e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *
9e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  http://www.apache.org/licenses/LICENSE-2.0
10e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *
11e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  Unless required by applicable law or agreed to in writing, software
12e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  distributed under the License is distributed on an "AS IS" BASIS,
13e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  See the License for the specific language governing permissions and
15e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *  limitations under the License.
16e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski *
17e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski ******************************************************************************/
18e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
19e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#include "ble_advertiser_hci_interface.h"
201dd77510884826e6996264aa40db4f495c3ec67aJakub Pawlowski#include <base/callback.h>
21dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski#include <base/location.h>
22e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#include <base/logging.h>
23e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#include <queue>
24e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#include <utility>
25e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#include "btm_api.h"
261dd77510884826e6996264aa40db4f495c3ec67aJakub Pawlowski#include "btm_ble_api.h"
276d75adcc03975cf6c9cae95349233aa6c3a19da2Jakub Pawlowski#include "btm_int_types.h"
285af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski#include "device/include/controller.h"
291f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski#include "hcidefs.h"
30e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
31e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
32e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#define BTM_BLE_MULTI_ADV_ENB_LEN 3
33e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24
34e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#define BTM_BLE_AD_DATA_LEN 31
35e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski#define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3)
36e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
37d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE 1
38d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski#define HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD 6
39d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS 15
40d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski#define HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP 31
41d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA 31
42d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
43e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowskiusing status_cb = BleAdvertiserHciInterface::status_cb;
44e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
45dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowskiusing hci_cmd_cb = base::Callback<void(uint8_t* /* return_parameters */,
46dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                                       uint16_t /* return_parameters_length*/)>;
47dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowskiextern void btu_hcif_send_cmd_with_cb(
48dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    const tracked_objects::Location& posted_from, uint16_t opcode,
49dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    uint8_t* params, uint8_t params_len, hci_cmd_cb cb);
50e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
51d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowskinamespace {
52911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBleAdvertiserHciInterface* instance = nullptr;
53e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
54dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowskivoid btm_ble_multi_adv_vsc_cmpl_cback(uint8_t expected_opcode,
55dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                                      status_cb command_complete,
56dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                                      uint8_t* param, uint16_t param_len) {
57e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  uint8_t status, subcode;
58e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
59e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  // All multi-adv commands respond with status and inst_id.
60dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  LOG_ASSERT(param_len == 2) << "Received bad response length to multi-adv VSC";
61e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
62dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  STREAM_TO_UINT8(status, param);
63dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  STREAM_TO_UINT8(subcode, param);
64e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
65e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  VLOG(1) << "subcode = " << +subcode << ", status: " << +status;
66e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
67dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  if (expected_opcode != subcode) {
68e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    LOG(ERROR) << "unexpected VSC cmpl, expect: " << +subcode
69dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski               << " get: " << +expected_opcode;
70e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    return;
71e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
72e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
73dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  command_complete.Run(status);
74e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski}
75e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
76256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowskivoid parameters_response_parser(BleAdvertiserHciInterface::parameters_cb cb,
77256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski                                uint8_t* ret_params, uint16_t ret_params_len) {
78256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski  uint8_t status;
79256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski  int8_t tx_power;
80256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski
81256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski  uint8_t* pp = ret_params;
82256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski  STREAM_TO_UINT8(status, pp);
83256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski  STREAM_TO_INT8(tx_power, pp);
84256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski
85256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski  cb.Run(status, tx_power);
86256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski}
87256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski
88256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowskivoid known_tx_pwr(BleAdvertiserHciInterface::parameters_cb cb, int8_t tx_power,
89256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski                  uint8_t status) {
90256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski  cb.Run(status, tx_power);
91256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski}
92256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski
93d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowskiclass BleAdvertiserVscHciInterfaceImpl : public BleAdvertiserHciInterface {
94dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  void SendAdvCmd(const tracked_objects::Location& posted_from,
95dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                  uint8_t param_len, uint8_t* param_buf,
96dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                  status_cb command_complete) {
97dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    btu_hcif_send_cmd_with_cb(posted_from, HCI_BLE_MULTI_ADV_OCF, param_buf,
98dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                              param_len,
99dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                              base::Bind(&btm_ble_multi_adv_vsc_cmpl_cback,
100dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                                         param_buf[0], command_complete));
101e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
102e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
103d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  void ReadInstanceCount(
104d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski      base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
1051dd77510884826e6996264aa40db4f495c3ec67aJakub Pawlowski    cb.Run(BTM_BleMaxMultiAdvInstanceCount());
1061dd77510884826e6996264aa40db4f495c3ec67aJakub Pawlowski  }
1071dd77510884826e6996264aa40db4f495c3ec67aJakub Pawlowski
10806325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski  void SetAdvertisingEventObserver(
109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      AdvertisingEventObserver* observer) override {
11006325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski    this->advertising_event_observer = observer;
11106325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski  }
11206325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski
113699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
114699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                     uint32_t adv_int_max, uint8_t channel_map,
1159e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                     uint8_t own_address_type, const RawAddress& own_address,
1169e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                     uint8_t peer_address_type, const RawAddress& peer_address,
117cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t filter_policy, int8_t tx_power,
118cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t primary_phy, uint8_t secondary_max_skip,
119cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t secondary_phy, uint8_t advertising_sid,
120699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                     uint8_t scan_request_notify_enable,
121256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski                     parameters_cb command_complete) override {
122e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    VLOG(1) << __func__;
123e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    uint8_t param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN];
124e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN);
125e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
127e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM);
128e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT16_TO_STREAM(pp, adv_int_min);
129e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT16_TO_STREAM(pp, adv_int_max);
130699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski
131699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    if (properties == 0x0013) {
132699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      UINT8_TO_STREAM(pp, 0x00);  // ADV_IND
133699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    } else if (properties == 0x0012) {
134699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      UINT8_TO_STREAM(pp, 0x02);  // ADV_SCAN_IND
135699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    } else if (properties == 0x0010) {
136699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      UINT8_TO_STREAM(pp, 0x03);  // ADV_NONCONN_IND
137699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    } else {
138699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      LOG(ERROR) << "Unsupported advertisement type selected:" << std::hex
139699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                 << properties;
140256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT, 0);
141699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      return;
142699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    }
143699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski
144e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, own_address_type);
145b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BDADDR_TO_STREAM(pp, own_address);
146699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, peer_address_type);
147b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BDADDR_TO_STREAM(pp, peer_address);
148e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, channel_map);
149e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, filter_policy);
150699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, handle);
151699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    INT8_TO_STREAM(pp, tx_power);
152e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
153256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski    SendAdvCmd(
154256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        FROM_HERE, BTM_BLE_MULTI_ADV_SET_PARAM_LEN, param,
155256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        base::Bind(&known_tx_pwr, std::move(command_complete), tx_power));
156e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
157e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
158699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetAdvertisingData(uint8_t handle, uint8_t operation,
159699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                          uint8_t fragment_preference, uint8_t data_length,
160699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                          uint8_t* data, status_cb command_complete) override {
161e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    VLOG(1) << __func__;
162e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    uint8_t param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN];
163e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
164e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
165911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
166e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_WRITE_ADV_DATA);
167e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, data_length);
168e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    ARRAY_TO_STREAM(pp, data, data_length);
169699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1] = handle;
170e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
171dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN, param,
172dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski               command_complete);
173e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
174e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
175699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetScanResponseData(uint8_t handle, uint8_t operation,
176699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t fragment_preference,
177699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t scan_response_data_length,
178699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t* scan_response_data,
1796c0ca7abd9452473bcf6cc467923202d093dac59Jakub Pawlowski                           status_cb command_complete) override {
180e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    VLOG(1) << __func__;
181e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    uint8_t param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN];
182e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
183e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
185e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA);
186e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, scan_response_data_length);
187e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
188699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1] = handle;
189e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
190dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN, param,
191dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski               command_complete);
192e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
193e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
1949e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
1956c0ca7abd9452473bcf6cc467923202d093dac59Jakub Pawlowski                        status_cb command_complete) override {
196e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    VLOG(1) << __func__;
197e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    uint8_t param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN];
198e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN);
199e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
201e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR);
202b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BDADDR_TO_STREAM(pp, random_address);
203699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, handle);
204e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
205dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN, param,
206dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski               command_complete);
207e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
208e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
209be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
2106c0ca7abd9452473bcf6cc467923202d093dac59Jakub Pawlowski              status_cb command_complete) override {
211e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    VLOG(1) << __func__;
2121f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski
213be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    if (sets.size() != 1) {
214be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      LOG(ERROR) << "Trying to enable multiple sets in VSC implemenetation!";
215be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
216be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      return;
217be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    }
218be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    SetEnableData& set = sets[0];
219be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski
220be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    if (set.max_extended_advertising_events) {
2211f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
2221f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski      return;
2231f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski    }
2241f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski
225e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    uint8_t param[BTM_BLE_MULTI_ADV_ENB_LEN];
226e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
227e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
229e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_ENB);
230699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, enable);
231be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    UINT8_TO_STREAM(pp, set.handle);
232e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
233dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, (uint8_t)BTM_BLE_MULTI_ADV_ENB_LEN, param,
234dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski               command_complete);
235e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
236e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
2378e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingParameters(uint8_t, uint16_t, uint16_t, uint16_t,
2388e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                        status_cb command_complete) override {
2398e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    LOG(INFO) << __func__ << " VSC can't do periodic advertising";
2408e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
2418e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
2428e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
2438e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingData(uint8_t, uint8_t, uint8_t, uint8_t*,
2448e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                  status_cb command_complete) override {
2458e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    LOG(INFO) << __func__ << " VSC can't do periodic advertising";
2468e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
2478e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
2488e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
2498e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingEnable(uint8_t, uint8_t,
2508e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                    status_cb command_complete) override {
2518e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    LOG(INFO) << __func__ << " VSC can't do periodic advertising";
2528e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
2538e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
2548e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
2556d75adcc03975cf6c9cae95349233aa6c3a19da2Jakub Pawlowski  bool QuirkAdvertiserZeroHandle() override {
2566d75adcc03975cf6c9cae95349233aa6c3a19da2Jakub Pawlowski    // Android BT HCI Requirements version 0.96 and below specify that handle 0
2576d75adcc03975cf6c9cae95349233aa6c3a19da2Jakub Pawlowski    // is equal to standard HCI interface, and should be accessed using non-VSC
25810661946ccaf2e542d24ca0c8d837aa97fc3b8c1Jakub Pawlowski    // commands.
25910661946ccaf2e542d24ca0c8d837aa97fc3b8c1Jakub Pawlowski    LOG(INFO) << "QuirkAdvertiserZeroHandle in use";
26010661946ccaf2e542d24ca0c8d837aa97fc3b8c1Jakub Pawlowski    return true;
2616d75adcc03975cf6c9cae95349233aa6c3a19da2Jakub Pawlowski  }
2626d75adcc03975cf6c9cae95349233aa6c3a19da2Jakub Pawlowski
263bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski  void RemoveAdvertisingSet(uint8_t handle,
264bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski                            status_cb command_complete) override {
265bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    // VSC Advertising don't have remove method.
266bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    command_complete.Run(0);
267bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski  }
268bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski
269e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski public:
270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  static void VendorSpecificEventCback(uint8_t length, uint8_t* p) {
271e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    VLOG(1) << __func__;
272e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
273e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    LOG_ASSERT(p);
274e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    uint8_t sub_event, adv_inst, change_reason;
275e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    uint16_t conn_handle;
276e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
277e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    STREAM_TO_UINT8(sub_event, p);
278e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    length--;
279e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
280e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    if (sub_event != HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG || length != 4) {
281e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski      return;
282e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    }
283e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
284e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    STREAM_TO_UINT8(adv_inst, p);
285e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    STREAM_TO_UINT8(change_reason, p);
286e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski    STREAM_TO_UINT16(conn_handle, p);
28706325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski
288911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    AdvertisingEventObserver* observer =
289911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        ((BleAdvertiserVscHciInterfaceImpl*)BleAdvertiserHciInterface::Get())
290911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            ->advertising_event_observer;
29106325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski    if (observer)
292699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      observer->OnAdvertisingSetTerminated(change_reason, adv_inst, conn_handle,
293699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                                           0x00);
294e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  }
29506325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski
29606325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski private:
297911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  AdvertisingEventObserver* advertising_event_observer = nullptr;
298e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski};
299d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
300dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowskivoid adv_cmd_cmpl_cback(status_cb cb, uint8_t* return_parameters,
301d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski                        uint16_t return_parameters_length) {
302d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  uint8_t status = *return_parameters;
303dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  cb.Run(status);
304d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski}
305d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
306d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowskiclass BleAdvertiserLegacyHciInterfaceImpl : public BleAdvertiserHciInterface {
307dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  void SendAdvCmd(const tracked_objects::Location& posted_from, uint16_t opcode,
308dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                  uint8_t* param_buf, uint8_t param_buf_len,
309d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski                  status_cb command_complete) {
310dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    btu_hcif_send_cmd_with_cb(
311dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski        posted_from, opcode, param_buf, param_buf_len,
312dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski        base::Bind(&adv_cmd_cmpl_cback, command_complete));
313d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
314d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
315d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  void ReadInstanceCount(
316d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski      base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
317d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    cb.Run(1);
318d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
319d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
32006325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski  void SetAdvertisingEventObserver(
321911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      AdvertisingEventObserver* observer) override {}
32206325e3d5ddb863230f57e60bebac71ef7cb7cccJakub Pawlowski
323699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
324699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                     uint32_t adv_int_max, uint8_t channel_map,
325c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski                     uint8_t own_address_type,
3269e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                     const RawAddress& /* own_address */,
3279e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                     uint8_t peer_address_type, const RawAddress& peer_address,
328cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t filter_policy, int8_t tx_power,
329cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t primary_phy, uint8_t secondary_max_skip,
330cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t secondary_phy, uint8_t advertising_sid,
331699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                     uint8_t scan_request_notify_enable,
332256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski                     parameters_cb command_complete) override {
333d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    VLOG(1) << __func__;
334d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
335d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS];
336d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
337911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
338d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    UINT16_TO_STREAM(pp, adv_int_min);
339d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    UINT16_TO_STREAM(pp, adv_int_max);
340699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski
341699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    if (properties == 0x0013) {
342699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      UINT8_TO_STREAM(pp, 0x00);  // ADV_IND
343699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    } else if (properties == 0x0012) {
344699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      UINT8_TO_STREAM(pp, 0x02);  // ADV_SCAN_IND
345699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    } else if (properties == 0x0010) {
346699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      UINT8_TO_STREAM(pp, 0x03);  // ADV_NONCONN_IND
347699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    } else {
348699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      LOG(ERROR) << "Unsupported advertisement type selected:" << std::hex
349699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                 << properties;
350256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT, 0);
351699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      return;
352699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    }
353699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski
354d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    UINT8_TO_STREAM(pp, own_address_type);
355699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, peer_address_type);
356b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BDADDR_TO_STREAM(pp, peer_address);
357d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    UINT8_TO_STREAM(pp, channel_map);
358d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    UINT8_TO_STREAM(pp, filter_policy);
359d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
360256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski    SendAdvCmd(
361256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        FROM_HERE, HCI_BLE_WRITE_ADV_PARAMS, param,
362256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS,
363256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        base::Bind(&known_tx_pwr, std::move(command_complete), (int8_t)0));
364d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
365d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
366699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetAdvertisingData(uint8_t handle, uint8_t operation,
367699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                          uint8_t fragment_preference, uint8_t data_length,
368699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                          uint8_t* data, status_cb command_complete) override {
369d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    VLOG(1) << __func__;
370d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
371d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1];
372d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
373911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
374d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
375d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    UINT8_TO_STREAM(pp, data_length);
376d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    ARRAY_TO_STREAM(pp, data, data_length);
377d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
378dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_ADV_DATA, param,
379d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski               HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1, command_complete);
380d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
381d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
382699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetScanResponseData(uint8_t handle, uint8_t operation,
383699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t fragment_preference,
384699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t scan_response_data_length,
385699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t* scan_response_data,
386d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski                           status_cb command_complete) override {
387d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    VLOG(1) << __func__;
388d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    uint8_t param[HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1];
389d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
390911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
391d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
392d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    UINT8_TO_STREAM(pp, scan_response_data_length);
393d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
394d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
395dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_SCAN_RSP_DATA, param,
396d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski               HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1, command_complete);
397d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
398d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
3999e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
400d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski                        status_cb command_complete) override {
401d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    VLOG(1) << __func__;
402d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
403d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    uint8_t param[HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD];
404d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
406b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BDADDR_TO_STREAM(pp, random_address);
407d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
408dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_RANDOM_ADDR, param,
409d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski               HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD, command_complete);
410d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
411d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
412be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
413d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski              status_cb command_complete) override {
414d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    VLOG(1) << __func__;
4151f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski
416be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    if (sets.size() != 1) {
417be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      LOG(ERROR) << "Trying to enable multiple sets in legacy implemenetation!";
418be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
419be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      return;
420be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    }
421be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski
422be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    SetEnableData& set = sets[0];
423be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    if (set.max_extended_advertising_events) {
4241f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski      command_complete.Run(HCI_ERR_ILLEGAL_PARAMETER_FMT);
4251f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski      return;
4261f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski    }
4271f62c122e908573497a8c69ccd7bd829ce02a0b9Jakub Pawlowski
428d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    uint8_t param[HCIC_PARAM_SIZE_WRITE_ADV_ENABLE];
429d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    uint8_t* pp = param;
431699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, enable);
432d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
433dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_BLE_WRITE_ADV_ENABLE, param,
434d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski               HCIC_PARAM_SIZE_WRITE_ADV_ENABLE, command_complete);
435d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
4368e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
4378e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingParameters(uint8_t, uint16_t, uint16_t, uint16_t,
4388e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                        status_cb command_complete) override {
4398e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
4408e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
4418e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
4428e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
4438e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingData(uint8_t, uint8_t, uint8_t, uint8_t*,
4448e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                  status_cb command_complete) override {
4458e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
4468e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
4478e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
4488e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
4498e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingEnable(uint8_t, uint8_t,
4508e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                    status_cb command_complete) override {
4518e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    LOG(INFO) << __func__ << "Legacy can't do periodic advertising";
4528e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    command_complete.Run(HCI_ERR_ILLEGAL_COMMAND);
4538e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
454bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski
455bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski  void RemoveAdvertisingSet(uint8_t handle,
456bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski                            status_cb command_complete) override {
457bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    // Legacy Advertising don't have remove method.
458bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    command_complete.Run(0);
459bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski  }
460d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski};
461d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
4625af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowskiclass BleAdvertiserHciExtendedImpl : public BleAdvertiserHciInterface {
463dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski  void SendAdvCmd(const tracked_objects::Location& posted_from, uint16_t opcode,
464dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski                  uint8_t* param_buf, uint8_t param_buf_len,
4655af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski                  status_cb command_complete) {
466dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    btu_hcif_send_cmd_with_cb(
467dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski        posted_from, opcode, param_buf, param_buf_len,
468dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski        base::Bind(&adv_cmd_cmpl_cback, command_complete));
4695af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  }
4705af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
4715af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  void ReadInstanceCount(
4725af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski      base::Callback<void(uint8_t /* inst_cnt*/)> cb) override {
4735af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    cb.Run(controller_get_interface()
4745af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski               ->get_ble_number_of_supported_advertising_sets());
4755af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  }
4765af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
4775af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  void SetAdvertisingEventObserver(
478751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski      AdvertisingEventObserver* observer) override {
479751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    this->advertising_event_observer = observer;
480751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski  }
4815af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
482699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetParameters(uint8_t handle, uint16_t properties, uint32_t adv_int_min,
483699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                     uint32_t adv_int_max, uint8_t channel_map,
484c2276b06572ab6fc1f900fbb1f41087e77d47e2aJakub Pawlowski                     uint8_t own_address_type,
4859e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                     const RawAddress& /* own_address */,
4869e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski                     uint8_t peer_address_type, const RawAddress& peer_address,
487cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t filter_policy, int8_t tx_power,
488cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t primary_phy, uint8_t secondary_max_skip,
489cd0d18937e85cd55bcee6355a6688858eba63b16Jakub Pawlowski                     uint8_t secondary_phy, uint8_t advertising_sid,
490699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                     uint8_t scan_request_notify_enable,
491256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski                     parameters_cb command_complete) override {
4925af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    VLOG(1) << __func__;
4935af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    const uint16_t HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN = 25;
4945af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t param[HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN];
4955af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    memset(param, 0, HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN);
4965af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
4975af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t* pp = param;
498699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, handle);
499699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT16_TO_STREAM(pp, properties);
500699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT24_TO_STREAM(pp, adv_int_min);
501699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT24_TO_STREAM(pp, adv_int_max);
5025af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    UINT8_TO_STREAM(pp, channel_map);
5035af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    UINT8_TO_STREAM(pp, own_address_type);
504699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, peer_address_type);
505b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BDADDR_TO_STREAM(pp, peer_address);
5065af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    UINT8_TO_STREAM(pp, filter_policy);
5075af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    INT8_TO_STREAM(pp, tx_power);
508699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, primary_phy);
509699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, secondary_max_skip);
510699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, secondary_phy);
511699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, advertising_sid);
512699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, scan_request_notify_enable);
5135af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
514256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski    btu_hcif_send_cmd_with_cb(
515256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_PARAM, param,
516256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        HCI_LE_SET_EXT_ADVERTISING_PARAM_LEN,
517256afc4d84cc0b05b96881ade6bcbfbab8636c51Jakub Pawlowski        base::Bind(parameters_response_parser, std::move(command_complete)));
5185af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  }
5195af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
520699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetAdvertisingData(uint8_t handle, uint8_t operation,
521699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                          uint8_t fragment_preference, uint8_t data_length,
522699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                          uint8_t* data, status_cb command_complete) override {
5235af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    VLOG(1) << __func__;
5245af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5255af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    const uint16_t cmd_length = 4 + data_length;
5265af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t param[cmd_length];
5275af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    memset(param, 0, cmd_length);
5285af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5295af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t* pp = param;
530699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, handle);
531699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, operation);
532699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, fragment_preference);
5335af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    UINT8_TO_STREAM(pp, data_length);
5345af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    ARRAY_TO_STREAM(pp, data, data_length);
5355af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
536dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_DATA, param, cmd_length,
5375af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski               command_complete);
5385af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  }
5395af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
540699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski  void SetScanResponseData(uint8_t handle, uint8_t operation,
541699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t fragment_preference,
542699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t scan_response_data_length,
543699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                           uint8_t* scan_response_data,
5445af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski                           status_cb command_complete) override {
5455af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    VLOG(1) << __func__;
5465af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5475af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    const uint16_t cmd_length = 4 + scan_response_data_length;
5485af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t param[cmd_length];
5495af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    memset(param, 0, cmd_length);
5505af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5515af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t* pp = param;
552699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, handle);
553699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, operation);
554699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, fragment_preference);
5555af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    UINT8_TO_STREAM(pp, scan_response_data_length);
5565af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    ARRAY_TO_STREAM(pp, scan_response_data, scan_response_data_length);
5575af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
558dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_SCAN_RESP, param,
559dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski               cmd_length, command_complete);
5605af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  }
5615af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5629e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski  void SetRandomAddress(uint8_t handle, const RawAddress& random_address,
5635af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski                        status_cb command_complete) override {
5645af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    VLOG(1) << __func__;
5655af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    const int LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN = 7;
5665af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5675af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t param[LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN];
5685af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    memset(param, 0, LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN);
5695af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5705af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t* pp = param;
571699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, handle);
572b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BDADDR_TO_STREAM(pp, random_address);
5735af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
574dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_RANDOM_ADDRESS, param,
5755af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski               LE_SET_ADVERTISING_SET_RANDOM_ADDRESS_LEN, command_complete);
5765af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  }
5775af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
578be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski  void Enable(uint8_t enable, std::vector<SetEnableData> sets,
5795af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski              status_cb command_complete) override {
5805af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    VLOG(1) << __func__;
5815af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5825af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    /* cmd_length = header_size + num_of_of_advertiser * size_per_advertiser */
583be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    const uint16_t cmd_length = 2 + sets.size() * 4;
5845af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t param[cmd_length];
5855af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    memset(param, 0, cmd_length);
5865af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
5875af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    uint8_t* pp = param;
588699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    UINT8_TO_STREAM(pp, enable);
5895af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
590be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    UINT8_TO_STREAM(pp, sets.size());
591be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    for (const SetEnableData& set : sets) {
592be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      UINT8_TO_STREAM(pp, set.handle);
593be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      UINT16_TO_STREAM(pp, set.duration);
594be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski      UINT8_TO_STREAM(pp, set.max_extended_advertising_events);
595be8d3f542517246c9cc8b3b02f2519baf300c53fJakub Pawlowski    }
5965af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
597dabf8d36c6a6896953fff4a12365716d438f173aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_LE_SET_EXT_ADVERTISING_ENABLE, param, cmd_length,
5985af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski               command_complete);
5995af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  }
600751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski
6018e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingParameters(uint8_t handle,
6028e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                        uint16_t periodic_adv_int_min,
6038e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                        uint16_t periodic_adv_int_max,
6048e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                        uint16_t periodic_properties,
6058e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                        status_cb command_complete) override {
6068e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    VLOG(1) << __func__;
6078e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    const uint16_t HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN = 7;
6088e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    uint8_t param[HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN];
6098e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    memset(param, 0, HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN);
6108e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
6118e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    uint8_t* pp = param;
6128e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT8_TO_STREAM(pp, handle);
6138e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT16_TO_STREAM(pp, periodic_adv_int_min);
6148e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT16_TO_STREAM(pp, periodic_adv_int_max);
615a85cb8ea676601e430e0bbc4dc534129d1e0303fSunny Kapdi    UINT16_TO_STREAM(pp, periodic_properties);
6168e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
6178e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_PARAM, param,
6188e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K               HCI_LE_SET_PRIODIC_ADVERTISING_PARAM_LEN, command_complete);
6198e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
6208e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
6218e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingData(uint8_t handle, uint8_t operation,
6228e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                  uint8_t adv_data_length, uint8_t* adv_data,
6238e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                  status_cb command_complete) override {
6248e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    VLOG(1) << __func__;
6258e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    const uint16_t HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN =
6268e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K        3 + adv_data_length;
6278e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    uint8_t param[HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN];
6288e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    memset(param, 0, HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN);
6298e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    uint8_t* pp = param;
6308e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT8_TO_STREAM(pp, handle);
6318e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT8_TO_STREAM(pp, operation);
6328e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT8_TO_STREAM(pp, adv_data_length);
6338e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    ARRAY_TO_STREAM(pp, adv_data, adv_data_length);
6348e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_DATA, param,
6358e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K               HCI_LE_SET_PRIODIC_ADVERTISING_DATA_LEN, command_complete);
6368e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
6378e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
6388e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  void SetPeriodicAdvertisingEnable(uint8_t enable, uint8_t handle,
6398e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K                                    status_cb command_complete) override {
6408e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    VLOG(1) << __func__;
6418e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    const uint16_t HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN = 2;
6428e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    uint8_t param[HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN];
6438e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    memset(param, 0, HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN);
6448e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    uint8_t* pp = param;
6458e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT8_TO_STREAM(pp, enable);
6468e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    UINT8_TO_STREAM(pp, handle);
6478e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K    SendAdvCmd(FROM_HERE, HCI_LE_SET_PERIODIC_ADVERTISING_ENABLE, param,
6488e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K               HCI_LE_ENABLE_PRIODIC_ADVERTISEMENT_LEN, command_complete);
6498e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K  }
6508e774d1c533dde1b0775aa61933b24eef2213de4Lakshmipathi K
651bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski  void RemoveAdvertisingSet(uint8_t handle,
652bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski                            status_cb command_complete) override {
653bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    VLOG(1) << __func__;
654bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski
655bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    const uint16_t cmd_length = 1;
656bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    uint8_t param[cmd_length];
657bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    memset(param, 0, cmd_length);
658bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski
659bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    uint8_t* pp = param;
660bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    UINT8_TO_STREAM(pp, handle);
661bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski
662bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski    SendAdvCmd(FROM_HERE, HCI_LE_REMOVE_ADVERTISING_SET, param, cmd_length,
663bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski               command_complete);
664bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski  }
665bb858fbf93ed8c3b72dd8bcd8ad3fbcb65e5bb7aJakub Pawlowski
666751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski public:
667751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski  void OnAdvertisingSetTerminated(uint8_t length, uint8_t* p) {
668751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    VLOG(1) << __func__;
669751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    LOG_ASSERT(p);
670699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    uint8_t status, advertising_handle, num_completed_extended_adv_events;
671751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    uint16_t conn_handle;
672751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski
673751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    STREAM_TO_UINT8(status, p);
674751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    STREAM_TO_UINT8(advertising_handle, p);
675751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    STREAM_TO_UINT16(conn_handle, p);
676699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski    STREAM_TO_UINT8(num_completed_extended_adv_events, p);
677751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski
678751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    conn_handle = conn_handle & 0x0FFF;  // only 12 bits meaningful
679751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski
680751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    AdvertisingEventObserver* observer = this->advertising_event_observer;
681751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    if (observer)
682699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski      observer->OnAdvertisingSetTerminated(status, advertising_handle,
683699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                                           conn_handle,
684699888256f683c3b14305e834d1e622f66241e29Jakub Pawlowski                                           num_completed_extended_adv_events);
685751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski  }
686751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski
687751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski private:
688751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski  AdvertisingEventObserver* advertising_event_observer = nullptr;
6895af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski};
6905af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski
691e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski}  // namespace
692e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
693751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowskivoid btm_le_on_advertising_set_terminated(uint8_t* p, uint16_t length) {
694751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski  if (BleAdvertiserHciInterface::Get()) {
695751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski    ((BleAdvertiserHciExtendedImpl*)BleAdvertiserHciInterface::Get())
696751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski        ->OnAdvertisingSetTerminated(length, p);
697751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski  }
698751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski}
699751381c64fee63590f0888c8eac5c8a474f1e25bJakub Pawlowski
700e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowskivoid BleAdvertiserHciInterface::Initialize() {
701e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  VLOG(1) << __func__;
702e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  LOG_ASSERT(instance == nullptr) << "Was already initialized.";
703d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
7045af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  if (controller_get_interface()->supports_ble_extended_advertising()) {
7059bb5a643906130367d3a1bb57141ef2ebd6c7855Jakub Pawlowski    LOG(INFO) << "Extended advertising will be in use";
7065af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski    instance = new BleAdvertiserHciExtendedImpl();
7075af96d3fda59989740f694cf7683d55f66057cf4Jakub Pawlowski  } else if (BTM_BleMaxMultiAdvInstanceCount()) {
7089bb5a643906130367d3a1bb57141ef2ebd6c7855Jakub Pawlowski    LOG(INFO) << "VSC advertising will be in use";
709d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    instance = new BleAdvertiserVscHciInterfaceImpl();
710d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    BTM_RegisterForVSEvents(
711d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski        BleAdvertiserVscHciInterfaceImpl::VendorSpecificEventCback, true);
712d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  } else {
7139bb5a643906130367d3a1bb57141ef2ebd6c7855Jakub Pawlowski    LOG(INFO) << "Legacy advertising will be in use";
714d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    instance = new BleAdvertiserLegacyHciInterfaceImpl();
715d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
716e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski}
717e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
718911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonBleAdvertiserHciInterface* BleAdvertiserHciInterface::Get() { return instance; }
719e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski
720e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowskivoid BleAdvertiserHciInterface::CleanUp() {
721e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  VLOG(1) << __func__;
722d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
723d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  if (BTM_BleMaxMultiAdvInstanceCount()) {
724d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski    BTM_RegisterForVSEvents(
725d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski        BleAdvertiserVscHciInterfaceImpl::VendorSpecificEventCback, false);
726d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski  }
727d964cf944e23470d696177fb2ddf8df3684290b8Jakub Pawlowski
728e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  delete instance;
729e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski  instance = nullptr;
730e47b769e71fa88f207db747e62974662e43aa07cJakub Pawlowski}
731