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
16 #include "generic_access_service.h"
17 #include <string>
18 #include "adapter_device_config.h"
19 #include "bt_def.h"
20 #include "gatt/gatt_defines.h"
21 #include "interface_adapter_ble.h"
22 #include "interface_adapter_classic.h"
23 #include "interface_adapter_manager.h"
24 #include "log.h"
25 #include "securec.h"
26
27 namespace OHOS {
28 namespace bluetooth {
29 const uint16_t GenericAccessService::GATT_UUID_GAP_SERVICE = 0x1800;
30 const uint16_t GenericAccessService::GATT_UUID_GAP_DEVICE_NAME = 0x2A00;
31 const uint16_t GenericAccessService::GATT_UUID_GAP_APPEARANCE = 0x2A01;
32 const uint16_t GenericAccessService::GATT_UUID_GAP_CENTRAL_ADDR_RESOLUTION = 0x2AA6;
33 const std::string GenericAccessService::DEFAULT_DEVICE_NAME = "BluetoothDevice";
34 const uint16_t GenericAccessService::DEFAULT_APPEARANCE = 0x02;
35 const size_t GenericAccessService::APPEARANCE_DATE_LENGTH = 0x02;
36 const size_t GenericAccessService::CENTRAL_ADDR_RESOLUTION_DATE_LENGTH = 0x01;
37
38 class GenericAccessService::GattServerCallbackImpl : public IGattServerCallback {
39 public:
OnCharacteristicReadRequest(const GattDevice & device,const Characteristic & characteristic)40 void OnCharacteristicReadRequest(const GattDevice &device, const Characteristic &characteristic) override
41 {
42 auto cIt = std::find_if(service_.instance_->characteristics_.begin(),
43 service_.instance_->characteristics_.end(),
44 [&characteristic](Characteristic &ccc) {
45 return ccc.handle_ == characteristic.handle_;
46 });
47
48 if (cIt != service_.instance_->characteristics_.end()) {
49 Characteristic result(characteristic.handle_, cIt->value_.get(), cIt->length_);
50 service_.serverService_.RespondCharacteristicRead(device, result, GattStatus::GATT_SUCCESS);
51 return;
52 }
53
54 Characteristic result(characteristic.handle_);
55 service_.serverService_.RespondCharacteristicRead(device, result, GattStatus::GATT_FAILURE);
56 }
57
OnCharacteristicReadByUuidRequest(const GattDevice & device,const Characteristic & characteristic)58 void OnCharacteristicReadByUuidRequest(const GattDevice &device, const Characteristic &characteristic) override
59 {
60 auto cIt = std::find_if(service_.instance_->characteristics_.begin(),
61 service_.instance_->characteristics_.end(),
62 [&characteristic](Characteristic &ccc) {
63 return ccc.handle_ == characteristic.handle_;
64 });
65
66 if (cIt != service_.instance_->characteristics_.end()) {
67 Characteristic result(characteristic.handle_, cIt->value_.get(), cIt->length_);
68 service_.serverService_.RespondCharacteristicReadByUuid(device, result, GattStatus::GATT_SUCCESS);
69 return;
70 }
71
72 Characteristic result(characteristic.handle_);
73 service_.serverService_.RespondCharacteristicReadByUuid(device, result, GattStatus::GATT_FAILURE);
74 }
75
OnConnectionStateChanged(const GattDevice & device,int ret,int state)76 void OnConnectionStateChanged(const GattDevice &device, int ret, int state) override
77 {}
78
GattServerCallbackImpl(const GenericAccessService & service)79 explicit GattServerCallbackImpl(const GenericAccessService &service) : service_(service)
80 {}
~GattServerCallbackImpl()81 ~GattServerCallbackImpl()
82 {}
83
84 private:
85 const GenericAccessService &service_;
86 };
87
88 class GenericAccessService::AdapterBleObserverImpl : public IAdapterBleObserver {
89 public:
AdapterBleObserverImpl(GenericAccessService & service)90 explicit AdapterBleObserverImpl(GenericAccessService &service) : service_(service)
91 {}
92 ~AdapterBleObserverImpl() = default;
OnDiscoveryStateChanged(const int status)93 void OnDiscoveryStateChanged(const int status)
94 {}
OnDiscoveryResult(const RawAddress & device,int rssi,const std::string deviceName,int deviceClass)95 void OnDiscoveryResult(
96 const RawAddress &device, int rssi, const std::string deviceName, int deviceClass)
97 {}
OnPairRequested(const BTTransport transport,const RawAddress & device)98 void OnPairRequested(const BTTransport transport, const RawAddress &device)
99 {}
OnPairConfirmed(const BTTransport transport,const RawAddress & device,const int reqType,const int number)100 void OnPairConfirmed(const BTTransport transport, const RawAddress &device, const int reqType, const int number)
101 {}
OnScanModeChanged(const int mode)102 void OnScanModeChanged(const int mode)
103 {}
OnDeviceNameChanged(const std::string deviceName)104 void OnDeviceNameChanged(const std::string deviceName)
105 {
106 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnDeviceNameChanged, &service_, deviceName));
107 }
OnDeviceAddrChanged(const std::string address)108 void OnDeviceAddrChanged(const std::string address)
109 {}
OnAdvertisingStateChanged(const int state)110 void OnAdvertisingStateChanged(const int state)
111 {
112 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnAdvertisingStateChanged, &service_, state));
113 }
114
115 private:
116 GenericAccessService &service_;
117 };
118
119 class GenericAccessService::AdapterClassicObserverImpl : public IAdapterClassicObserver {
120 public:
AdapterClassicObserverImpl(GenericAccessService & service)121 explicit AdapterClassicObserverImpl(GenericAccessService &service) : service_(service)
122 {}
123 ~AdapterClassicObserverImpl() = default;
OnDiscoveryStateChanged(int status)124 void OnDiscoveryStateChanged(int status)
125 {}
OnDiscoveryResult(const RawAddress & device,int rssi,const std::string deviceName,int deviceClass)126 void OnDiscoveryResult(
127 const RawAddress &device, int rssi, const std::string deviceName, int deviceClass)
128 {}
OnPairRequested(const BTTransport transport,const RawAddress & device)129 void OnPairRequested(const BTTransport transport, const RawAddress &device)
130 {}
OnPairConfirmed(const BTTransport transport,const RawAddress & device,int reqType,int number)131 void OnPairConfirmed(const BTTransport transport, const RawAddress &device, int reqType, int number)
132 {}
133
OnScanModeChanged(int mode)134 void OnScanModeChanged(int mode)
135 {
136 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnScanModeChanged, &service_, mode));
137 }
138
OnDeviceNameChanged(const std::string & deviceName)139 void OnDeviceNameChanged(const std::string &deviceName)
140 {
141 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnDeviceNameChanged, &service_, deviceName));
142 }
OnDeviceAddrChanged(const std::string & address)143 void OnDeviceAddrChanged(const std::string &address)
144 {}
145
146 private:
147 GenericAccessService &service_;
148 };
149
GenericAccessService(GattServerService & service,utility::Dispatcher & dispatcher)150 GenericAccessService::GenericAccessService(GattServerService &service, utility::Dispatcher &dispatcher)
151 : serviceCallback_(std::make_shared<GattServerCallbackImpl>(*this)),
152 adapterBleObserver_(std::make_unique<AdapterBleObserverImpl>(*this)),
153 adapterClassicObserver_(std::make_unique<AdapterClassicObserverImpl>(*this)),
154 serverService_(service),
155 dispatcher_(dispatcher)
156 {}
157
~GenericAccessService()158 GenericAccessService::~GenericAccessService()
159 {
160 LOG_INFO("%{public}s:%{public}d:%{public}s", __FILE__, __LINE__, __FUNCTION__);
161 }
162
RegisterService()163 int GenericAccessService::RegisterService()
164 {
165 auto adapterBle = IAdapterManager::GetInstance()->GetBleAdapterInterface();
166 if (adapterBle != nullptr) {
167 adapterBle->RegisterBleAdapterObserver(*adapterBleObserver_.get());
168 auto state = adapterBle->GetAdvertisingStatus();
169 if (state == BleAdvState::BLE_ADV_STATE_ADVERTISING) {
170 bleDiscoverable_ = true;
171 } else {
172 bleDiscoverable_ = false;
173 }
174 central_addr_resolution_ = adapterBle->IsLlPrivacySupported() ? 1 : 0;
175 }
176
177 auto adapterClassic = IAdapterManager::GetInstance()->GetClassicAdapterInterface();
178 if (adapterClassic != nullptr) {
179 adapterClassic->RegisterClassicAdapterObserver(*adapterClassicObserver_.get());
180 auto mode = adapterClassic->GetBtScanMode();
181 if (mode == SCAN_MODE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_LIMITED_DISCOVERABLE ||
182 mode == SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE) {
183 classicDiscoverable_ = true;
184 } else {
185 classicDiscoverable_ = false;
186 }
187 }
188
189 appId_ = serverService_.RegisterApplicationSync(serviceCallback_);
190 if (appId_ < 0) {
191 return appId_;
192 }
193
194 instance_ = BuildService();
195 int result = serverService_.AddServiceSync(appId_, *instance_);
196 if (result != GattStatus::GATT_SUCCESS) {
197 LOG_WARN("%{public}s:%{public}d:%{public}s : Add GAS Failed! ret: %{public}d", __FILE__, __LINE__, __FUNCTION__, result);
198 }
199
200 return result;
201 }
202
DeregisterService()203 void GenericAccessService::DeregisterService()
204 {
205 LOG_INFO("%{public}s:%{public}d:%{public}s", __FILE__, __LINE__, __FUNCTION__);
206 auto adapterBle = IAdapterManager::GetInstance()->GetBleAdapterInterface();
207 if (adapterBle != nullptr) {
208 adapterBle->DeregisterBleAdapterObserver(*adapterBleObserver_.get());
209 }
210
211 auto adapterClassic = IAdapterManager::GetInstance()->GetClassicAdapterInterface();
212 if (adapterClassic != nullptr) {
213 adapterClassic->DeregisterClassicAdapterObserver(*adapterClassicObserver_.get());
214 }
215
216 serverService_.DeregisterApplicationSync(appId_);
217 }
218
BuildService()219 std::unique_ptr<Service> GenericAccessService::BuildService()
220 {
221 std::unique_ptr<Service> svc = std::make_unique<Service>(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_SERVICE), 0, 0, 0);
222 svc->isPrimary_ = true;
223
224 std::string value = GetDeviceName();
225 svc->characteristics_.push_back(Characteristic(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME),
226 0,
227 (bleDiscoverable_ || classicDiscoverable_) ? CHARACTERISTIC_PROPERTIE_READ : 0,
228 (bleDiscoverable_ || classicDiscoverable_) ? (int)GattPermissionService::READABLE : 0,
229 (uint8_t *)value.c_str(),
230 value.size()));
231
232 svc->characteristics_.push_back(Characteristic(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_APPEARANCE),
233 0,
234 CHARACTERISTIC_PROPERTIE_READ,
235 (int)GattPermissionService::READABLE,
236 GetAppearance().get(),
237 APPEARANCE_DATE_LENGTH));
238
239 svc->characteristics_.push_back(Characteristic(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_CENTRAL_ADDR_RESOLUTION),
240 0,
241 CHARACTERISTIC_PROPERTIE_READ,
242 (int)GattPermissionService::READABLE,
243 ¢ral_addr_resolution_,
244 CENTRAL_ADDR_RESOLUTION_DATE_LENGTH));
245 return svc;
246 }
247
GetDeviceName()248 std::string GenericAccessService::GetDeviceName()
249 {
250 std::string result = DEFAULT_DEVICE_NAME;
251 AdapterDeviceConfig::GetInstance()->GetValue(SECTION_HOST, PROPERTY_DEVICE_NAME, result);
252 return result;
253 }
254
GetAppearance() const255 std::unique_ptr<uint8_t[]> GenericAccessService::GetAppearance() const
256 {
257 int appearance = DEFAULT_APPEARANCE;
258 AdapterDeviceConfig::GetInstance()->GetValue(SECTION_HOST, PROPERTY_BLE_APPEARANCE, appearance);
259
260 std::unique_ptr<uint8_t[]> result = std::make_unique<uint8_t[]>(APPEARANCE_DATE_LENGTH);
261 if (memcpy_s(result.get(), APPEARANCE_DATE_LENGTH, &appearance, APPEARANCE_DATE_LENGTH) != EOK) {
262 LOG_DEBUG("%{public}s:%{public}d:%{public}s : memcpy_s fail", __FILE__, __LINE__, __FUNCTION__);
263 return NULL;
264 }
265
266 return result;
267 }
268
OnDeviceNameChanged(std::string & deviceName) const269 void GenericAccessService::OnDeviceNameChanged(std::string &deviceName) const
270 {
271 LOG_DEBUG("%{public}s:%{public}d:%{public}s : device name: %{public}s", __FILE__, __LINE__, __FUNCTION__, deviceName.c_str());
272
273 auto cIt = std::find_if(instance_->characteristics_.begin(),
274 instance_->characteristics_.end(),
275 [](Characteristic &ccc) {
276 return ccc.uuid_ == Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME);
277 });
278
279 if (cIt != instance_->characteristics_.end()) {
280 cIt->SetValue((uint8_t *)deviceName.c_str(), deviceName.length());
281 serverService_.SetCharacteristicValue(*cIt);
282 return;
283 }
284 }
285
OnAdvertisingStateChanged(int state)286 void GenericAccessService::OnAdvertisingStateChanged(int state)
287 {
288 LOG_DEBUG("%{public}s:%{public}d:%{public}s :state: %{public}d", __FILE__, __LINE__, __FUNCTION__, state);
289 if (state == BleAdvState::BLE_ADV_STATE_ADVERTISING) {
290 bleDiscoverable_ = true;
291 } else {
292 bleDiscoverable_ = false;
293 }
294
295 for (auto &ccc : instance_->characteristics_) {
296 if (!(ccc.uuid_ == Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME))) {
297 continue;
298 }
299 if (classicDiscoverable_ || bleDiscoverable_) {
300 if (!(ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ)) {
301 serverService_.SetCharacteristicPermission(ccc,
302 ccc.properties_ | CHARACTERISTIC_PROPERTIE_READ,
303 ccc.permissions_ | (int)GattPermissionService::READABLE);
304 }
305 } else {
306 if (ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ) {
307 serverService_.SetCharacteristicPermission(ccc,
308 ccc.properties_ & ~CHARACTERISTIC_PROPERTIE_READ,
309 ccc.permissions_ & ~(int)GattPermissionService::READABLE);
310 }
311 }
312 return;
313 }
314 }
315
OnScanModeChanged(int mode)316 void GenericAccessService::OnScanModeChanged(int mode)
317 {
318 LOG_DEBUG("%{public}s:%{public}d:%{public}s :mode: %{public}d", __FILE__, __LINE__, __FUNCTION__, mode);
319 if (mode == SCAN_MODE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_LIMITED_DISCOVERABLE ||
320 mode == SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE) {
321 classicDiscoverable_ = true;
322 } else {
323 classicDiscoverable_ = false;
324 }
325
326 for (auto &ccc : instance_->characteristics_) {
327 if (!(ccc.uuid_ == Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME))) {
328 continue;
329 }
330 if (classicDiscoverable_ || bleDiscoverable_) {
331 if (!(ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ)) {
332 serverService_.SetCharacteristicPermission(ccc,
333 ccc.properties_ | CHARACTERISTIC_PROPERTIE_READ,
334 ccc.permissions_ | (int)GattPermissionService::READABLE);
335 }
336 } else {
337 if (ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ) {
338 serverService_.SetCharacteristicPermission(ccc,
339 ccc.properties_ & ~CHARACTERISTIC_PROPERTIE_READ,
340 ccc.permissions_ & ~(int)GattPermissionService::READABLE);
341 }
342 }
343 return;
344 }
345 }
346 } // namespace bluetooth
347 } // namespace OHOS