1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "rust/topshim/gatt/gatt_ble_advertiser_shim.h"
18 
19 #include <base/functional/bind.h>
20 #include <base/functional/callback.h>
21 
22 #include <algorithm>
23 #include <iterator>
24 #include <memory>
25 #include <vector>
26 
27 #include "bind_helpers.h"
28 #include "include/hardware/bt_common_types.h"
29 #include "rust/cxx.h"
30 #include "src/profiles/gatt.rs.h"
31 #include "types/bluetooth/uuid.h"
32 #include "types/raw_address.h"
33 
34 namespace bluetooth {
35 namespace topshim {
36 namespace rust {
37 
38 namespace rusty = ::bluetooth::topshim::rust;
39 
40 // AdvertisingCallbacks implementations
41 
OnAdvertisingSetStarted(int reg_id,uint8_t advertiser_id,int8_t tx_power,uint8_t status)42 void BleAdvertiserIntf::OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id, int8_t tx_power,
43                                                 uint8_t status) {
44   rusty::gdadv_on_advertising_set_started(reg_id, advertiser_id, tx_power, status);
45 }
OnAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)46 void BleAdvertiserIntf::OnAdvertisingEnabled(uint8_t advertiser_id, bool enable, uint8_t status) {
47   rusty::gdadv_on_advertising_enabled(advertiser_id, enable, status);
48 }
OnAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)49 void BleAdvertiserIntf::OnAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
50   rusty::gdadv_on_advertising_data_set(advertiser_id, status);
51 }
OnScanResponseDataSet(uint8_t advertiser_id,uint8_t status)52 void BleAdvertiserIntf::OnScanResponseDataSet(uint8_t advertiser_id, uint8_t status) {
53   rusty::gdadv_on_scan_response_data_set(advertiser_id, status);
54 }
OnAdvertisingParametersUpdated(uint8_t advertiser_id,int8_t tx_power,uint8_t status)55 void BleAdvertiserIntf::OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power,
56                                                        uint8_t status) {
57   rusty::gdadv_on_advertising_parameters_updated(advertiser_id, tx_power, status);
58 }
OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,uint8_t status)59 void BleAdvertiserIntf::OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,
60                                                                uint8_t status) {
61   rusty::gdadv_on_periodic_advertising_parameters_updated(advertiser_id, status);
62 }
OnPeriodicAdvertisingDataSet(uint8_t advertiser_id,uint8_t status)63 void BleAdvertiserIntf::OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, uint8_t status) {
64   rusty::gdadv_on_periodic_advertising_data_set(advertiser_id, status);
65 }
OnPeriodicAdvertisingEnabled(uint8_t advertiser_id,bool enable,uint8_t status)66 void BleAdvertiserIntf::OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable,
67                                                      uint8_t status) {
68   rusty::gdadv_on_periodic_advertising_enabled(advertiser_id, enable, status);
69 }
OnOwnAddressRead(uint8_t advertiser_id,uint8_t address_type,RawAddress addr)70 void BleAdvertiserIntf::OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type,
71                                          RawAddress addr) {
72   rusty::gdadv_on_own_address_read(advertiser_id, address_type, &addr);
73 }
74 
75 // BleAdvertiserInterface implementations
76 
RegisterAdvertiser()77 void BleAdvertiserIntf::RegisterAdvertiser() {
78   adv_intf_->RegisterAdvertiser(
79           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this)));
80 }
81 
Unregister(uint8_t adv_id)82 void BleAdvertiserIntf::Unregister(uint8_t adv_id) { adv_intf_->Unregister(adv_id); }
83 
GetOwnAddress(uint8_t adv_id)84 void BleAdvertiserIntf::GetOwnAddress(uint8_t adv_id) {
85   adv_intf_->GetOwnAddress(adv_id, base::Bind(&BleAdvertiserIntf::OnGetAddressCallback,
86                                               base::Unretained(this), adv_id));
87 }
88 
SetParameters(uint8_t adv_id,AdvertiseParameters params)89 void BleAdvertiserIntf::SetParameters(uint8_t adv_id, AdvertiseParameters params) {
90   adv_intf_->SetParameters(
91           adv_id, params,
92           base::Bind(&BleAdvertiserIntf::OnParametersCallback, base::Unretained(this), adv_id));
93 }
94 
SetData(uint8_t adv_id,bool set_scan_rsp,::rust::Vec<uint8_t> data)95 void BleAdvertiserIntf::SetData(uint8_t adv_id, bool set_scan_rsp, ::rust::Vec<uint8_t> data) {
96   std::vector<uint8_t> converted;
97   std::copy(data.begin(), data.end(), std::back_inserter(converted));
98 
99   adv_intf_->SetData(
100           adv_id, set_scan_rsp, converted,
101           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id));
102 }
103 
Enable(uint8_t adv_id,bool enable,uint16_t duration,uint8_t max_ext_adv_events)104 void BleAdvertiserIntf::Enable(uint8_t adv_id, bool enable, uint16_t duration,
105                                uint8_t max_ext_adv_events) {
106   adv_intf_->Enable(
107           adv_id, enable,
108           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id),
109           duration, max_ext_adv_events,
110           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id));
111 }
112 
StartAdvertising(uint8_t adv_id,AdvertiseParameters params,::rust::Vec<uint8_t> advertise_data,::rust::Vec<uint8_t> scan_response_data,int32_t timeout_in_sec)113 void BleAdvertiserIntf::StartAdvertising(uint8_t adv_id, AdvertiseParameters params,
114                                          ::rust::Vec<uint8_t> advertise_data,
115                                          ::rust::Vec<uint8_t> scan_response_data,
116                                          int32_t timeout_in_sec) {
117   std::vector<uint8_t> converted_adv_data, converted_scan_rsp_data;
118   std::copy(advertise_data.begin(), advertise_data.end(), std::back_inserter(converted_adv_data));
119   std::copy(scan_response_data.begin(), scan_response_data.end(),
120             std::back_inserter(converted_scan_rsp_data));
121 
122   adv_intf_->StartAdvertising(
123           adv_id,
124           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id),
125           params, converted_adv_data, converted_scan_rsp_data, timeout_in_sec,
126           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id));
127 }
128 
StartAdvertisingSet(int32_t reg_id,AdvertiseParameters params,::rust::Vec<uint8_t> advertise_data,::rust::Vec<uint8_t> scan_response_data,PeriodicAdvertisingParameters periodic_params,::rust::Vec<uint8_t> periodic_data,uint16_t duration,uint8_t max_ext_adv_events)129 void BleAdvertiserIntf::StartAdvertisingSet(int32_t reg_id, AdvertiseParameters params,
130                                             ::rust::Vec<uint8_t> advertise_data,
131                                             ::rust::Vec<uint8_t> scan_response_data,
132                                             PeriodicAdvertisingParameters periodic_params,
133                                             ::rust::Vec<uint8_t> periodic_data, uint16_t duration,
134                                             uint8_t max_ext_adv_events) {
135   std::vector<uint8_t> converted_adv_data, converted_scan_rsp_data, converted_periodic_data;
136   std::copy(advertise_data.begin(), advertise_data.end(), std::back_inserter(converted_adv_data));
137   std::copy(scan_response_data.begin(), scan_response_data.end(),
138             std::back_inserter(converted_scan_rsp_data));
139   std::copy(periodic_data.begin(), periodic_data.end(),
140             std::back_inserter(converted_periodic_data));
141 
142   adv_intf_->StartAdvertisingSet(
143           kAdvertiserClientIdJni, reg_id,
144           base::Bind(&BleAdvertiserIntf::OnIdTxPowerStatusCallback, base::Unretained(this)), params,
145           converted_adv_data, converted_scan_rsp_data, periodic_params, converted_periodic_data,
146           duration, max_ext_adv_events,
147           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this)));
148 }
149 
SetPeriodicAdvertisingParameters(uint8_t adv_id,PeriodicAdvertisingParameters params)150 void BleAdvertiserIntf::SetPeriodicAdvertisingParameters(uint8_t adv_id,
151                                                          PeriodicAdvertisingParameters params) {
152   adv_intf_->SetPeriodicAdvertisingParameters(
153           adv_id, params,
154           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id));
155 }
156 
SetPeriodicAdvertisingData(uint8_t adv_id,::rust::Vec<uint8_t> data)157 void BleAdvertiserIntf::SetPeriodicAdvertisingData(uint8_t adv_id, ::rust::Vec<uint8_t> data) {
158   std::vector<uint8_t> converted;
159   std::copy(data.begin(), data.end(), std::back_inserter(converted));
160 
161   adv_intf_->SetPeriodicAdvertisingData(
162           adv_id, converted,
163           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id));
164 }
165 
SetPeriodicAdvertisingEnable(uint8_t adv_id,bool enable,bool include_adi)166 void BleAdvertiserIntf::SetPeriodicAdvertisingEnable(uint8_t adv_id, bool enable,
167                                                      bool include_adi) {
168   adv_intf_->SetPeriodicAdvertisingEnable(
169           adv_id, enable, include_adi,
170           base::Bind(&BleAdvertiserIntf::OnIdStatusCallback, base::Unretained(this), adv_id));
171 }
172 
RegisterCallbacks()173 void BleAdvertiserIntf::RegisterCallbacks() { adv_intf_->RegisterCallbacks(this); }
174 
175 // Inband callbacks
176 
OnIdStatusCallback(uint8_t adv_id,uint8_t status)177 void BleAdvertiserIntf::OnIdStatusCallback(uint8_t adv_id, uint8_t status) {
178   gdadv_idstatus_callback(adv_id, status);
179 }
OnIdTxPowerStatusCallback(uint8_t adv_id,int8_t tx_power,uint8_t status)180 void BleAdvertiserIntf::OnIdTxPowerStatusCallback(uint8_t adv_id, int8_t tx_power, uint8_t status) {
181   gdadv_idtxpowerstatus_callback(adv_id, tx_power, status);
182 }
OnParametersCallback(uint8_t adv_id,uint8_t status,int8_t tx_power)183 void BleAdvertiserIntf::OnParametersCallback(uint8_t adv_id, uint8_t status, int8_t tx_power) {
184   gdadv_parameters_callback(adv_id, status, tx_power);
185 }
OnGetAddressCallback(uint8_t adv_id,uint8_t addr_type,RawAddress addr)186 void BleAdvertiserIntf::OnGetAddressCallback(uint8_t adv_id, uint8_t addr_type, RawAddress addr) {
187   gdadv_getaddress_callback(adv_id, addr_type, &addr);
188 }
189 
GetBleAdvertiserIntf(const unsigned char * gatt_intf)190 std::unique_ptr<BleAdvertiserIntf> GetBleAdvertiserIntf(const unsigned char* gatt_intf) {
191   return std::make_unique<BleAdvertiserIntf>(
192           reinterpret_cast<const btgatt_interface_t*>(gatt_intf)->advertiser);
193 }
194 
195 }  // namespace rust
196 }  // namespace topshim
197 }  // namespace bluetooth
198