1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "bluetooth_ble_advertiser.h"
16
17 #include "bluetooth_ble_advertise_callback_stub.h"
18 #include "bluetooth_def.h"
19 #include "bluetooth_errorcode.h"
20 #include "bluetooth_host.h"
21 #include "bluetooth_log.h"
22 #include "bluetooth_observer_map.h"
23 #include "bluetooth_utils.h"
24 #include "i_bluetooth_ble_advertiser.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27
28 #include <memory>
29
30 namespace OHOS {
31 namespace Bluetooth {
32 using namespace OHOS::bluetooth;
33
34 struct BleAdvertiser::impl {
35 impl();
36 ~impl();
37 void ConvertBleAdvertiserData(const BleAdvertiserData &data, BluetoothBleAdvertiserData &outData);
38
39 class BluetoothBleAdvertiserCallbackImp : public BluetoothBleAdvertiseCallbackStub {
40 public:
BluetoothBleAdvertiserCallbackImp(BleAdvertiser::impl & bleAdvertiser)41 explicit BluetoothBleAdvertiserCallbackImp(BleAdvertiser::impl &bleAdvertiser)
42 : bleAdvertiser_(bleAdvertiser){};
~BluetoothBleAdvertiserCallbackImp()43 ~BluetoothBleAdvertiserCallbackImp()
44 {}
45
OnStartResultEvent(int32_t result,int32_t advHandle,int32_t opcode)46 void OnStartResultEvent(int32_t result, int32_t advHandle, int32_t opcode) override
47 {
48 HILOGI("result: %{public}d, advHandle: %{public}d, opcode: %{public}d", result, advHandle, opcode);
49 BleAdvertiseCallback *observer = nullptr;
50 if (opcode == bluetooth::BLE_ADV_START_FAILED_OP_CODE) {
51 observer = bleAdvertiser_.callbacks_.PopAdvertiserObserver(advHandle);
52 } else {
53 observer = bleAdvertiser_.callbacks_.GetAdvertiserObserver(advHandle);
54 }
55
56 if (observer != nullptr) {
57 observer->OnStartResultEvent(result);
58 }
59 }
60
OnAutoStopAdvEvent(int32_t advHandle)61 void OnAutoStopAdvEvent(int32_t advHandle) override
62 {
63 HILOGI("advHandle: %{public}d", advHandle);
64 BleAdvertiseCallback *observer = bleAdvertiser_.callbacks_.GetAdvertiserObserver(advHandle);
65 if (observer != nullptr) {
66 bleAdvertiser_.callbacks_.Deregister(observer);
67 }
68 }
69
70 private:
71 BleAdvertiser::impl &bleAdvertiser_;
72 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothBleAdvertiserCallbackImp);
73 };
74 sptr<BluetoothBleAdvertiserCallbackImp> callbackImp_ = nullptr;
75
76 BluetoothObserverMap<BleAdvertiseCallback> callbacks_;
77 sptr<IBluetoothBleAdvertiser> proxy_ = nullptr;
78 };
79
impl()80 BleAdvertiser::impl::impl()
81 {
82 HILOGI("enter");
83 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
84 if (!samgr) {
85 HILOGE("samgr is null");
86 return;
87 }
88
89 sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
90 if (!hostRemote) {
91 HILOGE("hostRemote is null");
92 return;
93 }
94 sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
95 if (!hostProxy) {
96 HILOGE("hostProxy is null");
97 return;
98 }
99 sptr<IRemoteObject> remote = hostProxy->GetBleRemote(BLE_ADVERTISER_SERVER);
100 if (!remote) {
101 HILOGE("remote is null");
102 return;
103 }
104 proxy_ = iface_cast<IBluetoothBleAdvertiser>(remote);
105 if (!proxy_) {
106 HILOGE("proxy is null");
107 return;
108 }
109
110 callbackImp_ = new BluetoothBleAdvertiserCallbackImp(*this);
111 proxy_->RegisterBleAdvertiserCallback(callbackImp_);
112 }
113
~impl()114 BleAdvertiser::impl::~impl()
115 {
116 proxy_->DeregisterBleAdvertiserCallback(callbackImp_);
117 }
118
BleAdvertiser()119 BleAdvertiser::BleAdvertiser() : pimpl(nullptr)
120 {
121 if (pimpl == nullptr) {
122 pimpl = std::make_unique<impl>();
123 if (!pimpl) {
124 HILOGE("failed, no pimpl");
125 }
126 }
127
128 HILOGI("successful");
129 }
130
~BleAdvertiser()131 BleAdvertiser::~BleAdvertiser()
132 {}
133
ConvertBleAdvertiserData(const BleAdvertiserData & data,BluetoothBleAdvertiserData & outData)134 void BleAdvertiser::impl::ConvertBleAdvertiserData(const BleAdvertiserData &data, BluetoothBleAdvertiserData &outData)
135 {
136 std::map<uint16_t, std::string> manufacturerData = data.GetManufacturerData();
137 for (auto iter = manufacturerData.begin(); iter != manufacturerData.end(); iter++) {
138 outData.AddManufacturerData(iter->first, iter->second);
139 }
140 std::map<ParcelUuid, std::string> serviceData = data.GetServiceData();
141 for (auto it = serviceData.begin(); it != serviceData.end(); it++) {
142 outData.AddServiceData(Uuid::ConvertFromString(it->first.ToString()), it->second);
143 }
144 std::vector<ParcelUuid> serviceUuids = data.GetServiceUuids();
145 for (auto it = serviceUuids.begin(); it != serviceUuids.end(); it++) {
146 outData.AddServiceUuid(Uuid::ConvertFromString(it->ToString()));
147 }
148 }
149
StartAdvertising(const BleAdvertiserSettings & settings,const BleAdvertiserData & advData,const BleAdvertiserData & scanResponse,BleAdvertiseCallback & callback)150 int BleAdvertiser::StartAdvertising(const BleAdvertiserSettings &settings, const BleAdvertiserData &advData,
151 const BleAdvertiserData &scanResponse, BleAdvertiseCallback &callback)
152 {
153 CHECK_PROXY_RETURN(pimpl->proxy_);
154 if (!BluetoothHost::GetDefaultHost().IsBleEnabled()) {
155 HILOGE("BLE is not enabled");
156 return BT_ERR_INVALID_STATE;
157 }
158
159 HILOGI("enter");
160
161 BluetoothBleAdvertiserSettings setting;
162 setting.SetConnectable(settings.IsConnectable());
163 setting.SetInterval(settings.GetInterval());
164 setting.SetLegacyMode(settings.IsLegacyMode());
165 setting.SetTxPower(settings.GetTxPower());
166
167 BluetoothBleAdvertiserData bleAdvertiserData;
168 BluetoothBleAdvertiserData bleScanResponse;
169 bleAdvertiserData.SetAdvFlag(advData.GetAdvFlag());
170 pimpl->ConvertBleAdvertiserData(advData, bleAdvertiserData);
171 pimpl->ConvertBleAdvertiserData(scanResponse, bleScanResponse);
172
173 int ret = 0;
174 int32_t advHandle = BLE_INVALID_ADVERTISING_HANDLE;
175 if (pimpl->callbacks_.IsExistAdvertiserCallback(&callback, advHandle)) {
176 ret = pimpl->proxy_->StartAdvertising(setting, bleAdvertiserData, bleScanResponse, advHandle, false);
177 } else {
178 advHandle = pimpl->proxy_->GetAdvertiserHandle();
179 if (advHandle == BLE_INVALID_ADVERTISING_HANDLE) {
180 HILOGE("Invalid advertising handle");
181 callback.OnStartResultEvent(BLE_INVALID_ADVERTISING_HANDLE);
182 return BT_ERR_INTERNAL_ERROR;
183 }
184 pimpl->callbacks_.Register(advHandle, &callback);
185 ret = pimpl->proxy_->StartAdvertising(setting, bleAdvertiserData, bleScanResponse, advHandle, false);
186 }
187 return ret;
188 }
189
StartAdvertising(const BleAdvertiserSettings & settings,const std::vector<uint8_t> & advData,const std::vector<uint8_t> & scanResponse,BleAdvertiseCallback & callback)190 int BleAdvertiser::StartAdvertising(const BleAdvertiserSettings &settings, const std::vector<uint8_t> &advData,
191 const std::vector<uint8_t> &scanResponse, BleAdvertiseCallback &callback)
192 {
193 CHECK_PROXY_RETURN(pimpl->proxy_);
194 if (!BluetoothHost::GetDefaultHost().IsBleEnabled()) {
195 HILOGE("BLE is not enabled");
196 return BT_ERR_INVALID_STATE;
197 }
198
199 HILOGI("enter");
200
201 BluetoothBleAdvertiserSettings setting;
202 setting.SetConnectable(settings.IsConnectable());
203 setting.SetInterval(settings.GetInterval());
204 setting.SetLegacyMode(settings.IsLegacyMode());
205 setting.SetTxPower(settings.GetTxPower());
206
207 BluetoothBleAdvertiserData bleAdvertiserData;
208 bleAdvertiserData.SetPayload(std::string(advData.begin(), advData.end()));
209 bleAdvertiserData.SetAdvFlag(0);
210 BluetoothBleAdvertiserData bleScanResponse;
211 bleScanResponse.SetPayload(std::string(scanResponse.begin(), scanResponse.end()));
212
213 int ret = 0;
214 int32_t advHandle = BLE_INVALID_ADVERTISING_HANDLE;
215 if (pimpl->callbacks_.IsExistAdvertiserCallback(&callback, advHandle)) {
216 ret = pimpl->proxy_->StartAdvertising(setting, bleAdvertiserData, bleScanResponse, advHandle, true);
217 } else {
218 advHandle = pimpl->proxy_->GetAdvertiserHandle();
219 if (advHandle == BLE_INVALID_ADVERTISING_HANDLE) {
220 HILOGE("Invalid advertising handle");
221 callback.OnStartResultEvent(BLE_INVALID_ADVERTISING_HANDLE);
222 return BT_ERR_INTERNAL_ERROR;
223 }
224 pimpl->callbacks_.Register(advHandle, &callback);
225 ret = pimpl->proxy_->StartAdvertising(setting, bleAdvertiserData, bleScanResponse, advHandle, true);
226 }
227 return ret;
228 }
229
StopAdvertising(BleAdvertiseCallback & callback)230 int BleAdvertiser::StopAdvertising(BleAdvertiseCallback &callback)
231 {
232 CHECK_PROXY_RETURN(pimpl->proxy_);
233 if (!BluetoothHost::GetDefaultHost().IsBleEnabled()) {
234 HILOGE("BLE is not enabled");
235 return BT_ERR_INVALID_STATE;
236 }
237
238 HILOGI("enter");
239 int ret = 0;
240 uint8_t advHandle = pimpl->callbacks_.GetAdvertiserHandle(&callback);
241 if (advHandle == BLE_INVALID_ADVERTISING_HANDLE) {
242 HILOGE("Invalid advertising handle");
243 return BT_ERR_INTERNAL_ERROR;
244 }
245
246 BleAdvertiseCallback *observer = pimpl->callbacks_.GetAdvertiserObserver(advHandle);
247 if (observer != nullptr) {
248 pimpl->callbacks_.Deregister(observer);
249 }
250
251 ret = pimpl->proxy_->StopAdvertising(advHandle);
252 return ret;
253 }
254
Close(BleAdvertiseCallback & callback)255 void BleAdvertiser::Close(BleAdvertiseCallback &callback)
256 {
257 if (!BluetoothHost::GetDefaultHost().IsBleEnabled()) {
258 HILOGE("BLE is not enabled");
259 return;
260 }
261
262 HILOGI("enter");
263 if (pimpl->proxy_ != nullptr) {
264 uint8_t advHandle = pimpl->callbacks_.GetAdvertiserHandle(&callback);
265 if (advHandle != BLE_INVALID_ADVERTISING_HANDLE) {
266 pimpl->proxy_->Close(advHandle);
267 }
268
269 BleAdvertiseCallback *observer = pimpl->callbacks_.GetAdvertiserObserver(advHandle);
270 if (observer != nullptr) {
271 pimpl->callbacks_.Deregister(observer);
272 }
273 }
274 }
275
BleAdvertiserData()276 BleAdvertiserData::BleAdvertiserData()
277 {}
278
~BleAdvertiserData()279 BleAdvertiserData::~BleAdvertiserData()
280 {}
281
AddServiceData(const ParcelUuid & uuid,const std::string & serviceData)282 void BleAdvertiserData::AddServiceData(const ParcelUuid &uuid, const std::string &serviceData)
283 {
284 if (serviceData.empty()) {
285 HILOGE("serviceData is empty");
286 return;
287 }
288
289 serviceData_.insert(std::make_pair(uuid, serviceData));
290 }
291
AddManufacturerData(uint16_t manufacturerId,const std::string & data)292 void BleAdvertiserData::AddManufacturerData(uint16_t manufacturerId, const std::string &data)
293 {
294 if (data.empty()) {
295 HILOGE("serviceData is empty");
296 return;
297 }
298
299 manufacturerSpecificData_.insert(std::make_pair(manufacturerId, data));
300 }
301
GetManufacturerData() const302 std::map<uint16_t, std::string> BleAdvertiserData::GetManufacturerData() const
303 {
304 return manufacturerSpecificData_;
305 }
306
AddServiceUuid(const ParcelUuid & serviceUuid)307 void BleAdvertiserData::AddServiceUuid(const ParcelUuid &serviceUuid)
308 {
309 serviceUuids_.push_back(serviceUuid);
310 }
311
GetServiceUuids() const312 std::vector<ParcelUuid> BleAdvertiserData::GetServiceUuids() const
313 {
314 return serviceUuids_;
315 }
316
SetAdvFlag(uint8_t flag)317 void BleAdvertiserData::SetAdvFlag(uint8_t flag)
318 {
319 advFlag_ = flag;
320 }
321
GetAdvFlag() const322 uint8_t BleAdvertiserData::GetAdvFlag() const
323 {
324 return advFlag_;
325 }
326
GetServiceData() const327 std::map<ParcelUuid, std::string> BleAdvertiserData::GetServiceData() const
328 {
329 return serviceData_;
330 }
331
BleAdvertiserSettings()332 BleAdvertiserSettings::BleAdvertiserSettings()
333 {}
334
~BleAdvertiserSettings()335 BleAdvertiserSettings::~BleAdvertiserSettings()
336 {}
337
SetConnectable(bool connectable)338 void BleAdvertiserSettings::SetConnectable(bool connectable)
339 {
340 connectable_ = connectable;
341 }
342
IsConnectable() const343 bool BleAdvertiserSettings::IsConnectable() const
344 {
345 return connectable_;
346 }
347
SetLegacyMode(bool legacyMode)348 void BleAdvertiserSettings::SetLegacyMode(bool legacyMode)
349 {
350 legacyMode_ = legacyMode;
351 }
352
IsLegacyMode() const353 bool BleAdvertiserSettings::IsLegacyMode() const
354 {
355 return legacyMode_;
356 }
357
SetInterval(uint16_t interval)358 void BleAdvertiserSettings::SetInterval(uint16_t interval)
359 {
360 interval_ = interval;
361 }
362
GetInterval() const363 uint16_t BleAdvertiserSettings::GetInterval() const
364 {
365 return interval_;
366 }
367
SetTxPower(uint8_t txPower)368 void BleAdvertiserSettings::SetTxPower(uint8_t txPower)
369 {
370 txPower_ = txPower;
371 }
372
GetTxPower() const373 uint8_t BleAdvertiserSettings::GetTxPower() const
374 {
375 return txPower_;
376 }
377
GetPrimaryPhy() const378 int BleAdvertiserSettings::GetPrimaryPhy() const
379 {
380 return primaryPhy_;
381 }
382
SetPrimaryPhy(int primaryPhy)383 void BleAdvertiserSettings::SetPrimaryPhy(int primaryPhy)
384 {
385 primaryPhy_ = primaryPhy;
386 }
387
GetSecondaryPhy() const388 int BleAdvertiserSettings::GetSecondaryPhy() const
389 {
390 return secondaryPhy_;
391 }
392
SetSecondaryPhy(int secondaryPhy)393 void BleAdvertiserSettings::SetSecondaryPhy(int secondaryPhy)
394 {
395 secondaryPhy_ = secondaryPhy;
396 }
397 } // namespace Bluetooth
398 } // namespace OHOS
399