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)95 void OnDiscoveryResult(const RawAddress &device)
96 {}
OnPairRequested(const BTTransport transport,const RawAddress & device)97 void OnPairRequested(const BTTransport transport, const RawAddress &device)
98 {}
OnPairConfirmed(const BTTransport transport,const RawAddress & device,const int reqType,const int number)99 void OnPairConfirmed(const BTTransport transport, const RawAddress &device, const int reqType, const int number)
100 {}
OnScanModeChanged(const int mode)101 void OnScanModeChanged(const int mode)
102 {}
OnDeviceNameChanged(const std::string deviceName)103 void OnDeviceNameChanged(const std::string deviceName)
104 {
105 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnDeviceNameChanged, &service_, deviceName));
106 }
OnDeviceAddrChanged(const std::string address)107 void OnDeviceAddrChanged(const std::string address)
108 {}
OnAdvertisingStateChanged(const int state)109 void OnAdvertisingStateChanged(const int state)
110 {
111 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnAdvertisingStateChanged, &service_, state));
112 }
113
114 private:
115 GenericAccessService &service_;
116 };
117
118 class GenericAccessService::AdapterClassicObserverImpl : public IAdapterClassicObserver {
119 public:
AdapterClassicObserverImpl(GenericAccessService & service)120 explicit AdapterClassicObserverImpl(GenericAccessService &service) : service_(service)
121 {}
122 ~AdapterClassicObserverImpl() = default;
OnDiscoveryStateChanged(int status)123 void OnDiscoveryStateChanged(int status)
124 {}
OnDiscoveryResult(const RawAddress & device)125 void OnDiscoveryResult(const RawAddress &device)
126 {}
OnPairRequested(const BTTransport transport,const RawAddress & device)127 void OnPairRequested(const BTTransport transport, const RawAddress &device)
128 {}
OnPairConfirmed(const BTTransport transport,const RawAddress & device,int reqType,int number)129 void OnPairConfirmed(const BTTransport transport, const RawAddress &device, int reqType, int number)
130 {}
131
OnScanModeChanged(int mode)132 void OnScanModeChanged(int mode)
133 {
134 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnScanModeChanged, &service_, mode));
135 }
136
OnDeviceNameChanged(const std::string & deviceName)137 void OnDeviceNameChanged(const std::string &deviceName)
138 {
139 service_.dispatcher_.PostTask(std::bind(&GenericAccessService::OnDeviceNameChanged, &service_, deviceName));
140 }
OnDeviceAddrChanged(const std::string & address)141 void OnDeviceAddrChanged(const std::string &address)
142 {}
143
144 private:
145 GenericAccessService &service_;
146 };
147
GenericAccessService(GattServerService & service,utility::Dispatcher & dispatcher)148 GenericAccessService::GenericAccessService(GattServerService &service, utility::Dispatcher &dispatcher)
149 : serviceCallback_(std::make_shared<GattServerCallbackImpl>(*this)),
150 adapterBleObserver_(std::make_unique<AdapterBleObserverImpl>(*this)),
151 adapterClassicObserver_(std::make_unique<AdapterClassicObserverImpl>(*this)),
152 serverService_(service),
153 dispatcher_(dispatcher)
154 {}
155
~GenericAccessService()156 GenericAccessService::~GenericAccessService()
157 {
158 LOG_INFO("%{public}s:%{public}d:%{public}s", __FILE__, __LINE__, __FUNCTION__);
159 }
160
RegisterService()161 int GenericAccessService::RegisterService()
162 {
163 auto adapterBle = IAdapterManager::GetInstance()->GetBleAdapterInterface();
164 if (adapterBle != nullptr) {
165 adapterBle->RegisterBleAdapterObserver(*adapterBleObserver_.get());
166 auto state = adapterBle->GetAdvertisingStatus();
167 if (state == BleAdvState::BLE_ADV_STATE_ADVERTISING) {
168 bleDiscoverable_ = true;
169 } else {
170 bleDiscoverable_ = false;
171 }
172 central_addr_resolution_ = adapterBle->IsLlPrivacySupported() ? 1 : 0;
173 }
174
175 auto adapterClassic = IAdapterManager::GetInstance()->GetClassicAdapterInterface();
176 if (adapterClassic != nullptr) {
177 adapterClassic->RegisterClassicAdapterObserver(*adapterClassicObserver_.get());
178 auto mode = adapterClassic->GetBtScanMode();
179 if (mode == SCAN_MODE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_LIMITED_DISCOVERABLE ||
180 mode == SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE) {
181 classicDiscoverable_ = true;
182 } else {
183 classicDiscoverable_ = false;
184 }
185 }
186
187 appId_ = serverService_.RegisterApplicationSync(serviceCallback_);
188 if (appId_ < 0) {
189 return appId_;
190 }
191
192 instance_ = BuildService();
193 int result = serverService_.AddServiceSync(appId_, *instance_);
194 if (result != GattStatus::GATT_SUCCESS) {
195 LOG_WARN("%{public}s:%{public}d:%{public}s : Add GAS Failed! ret: %{public}d", __FILE__, __LINE__, __FUNCTION__, result);
196 }
197
198 return result;
199 }
200
DeregisterService()201 void GenericAccessService::DeregisterService()
202 {
203 LOG_INFO("%{public}s:%{public}d:%{public}s", __FILE__, __LINE__, __FUNCTION__);
204 auto adapterBle = IAdapterManager::GetInstance()->GetBleAdapterInterface();
205 if (adapterBle != nullptr) {
206 adapterBle->DeregisterBleAdapterObserver(*adapterBleObserver_.get());
207 }
208
209 auto adapterClassic = IAdapterManager::GetInstance()->GetClassicAdapterInterface();
210 if (adapterClassic != nullptr) {
211 adapterClassic->DeregisterClassicAdapterObserver(*adapterClassicObserver_.get());
212 }
213
214 serverService_.DeregisterApplicationSync(appId_);
215 }
216
BuildService()217 std::unique_ptr<Service> GenericAccessService::BuildService()
218 {
219 std::unique_ptr<Service> svc = std::make_unique<Service>(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_SERVICE), 0, 0, 0);
220 svc->isPrimary_ = true;
221
222 std::string value = GetDeviceName();
223 svc->characteristics_.push_back(Characteristic(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME),
224 0,
225 (bleDiscoverable_ || classicDiscoverable_) ? CHARACTERISTIC_PROPERTIE_READ : 0,
226 (bleDiscoverable_ || classicDiscoverable_) ? (int)GattPermissionService::READABLE : 0,
227 (uint8_t *)value.c_str(),
228 value.size()));
229
230 svc->characteristics_.push_back(Characteristic(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_APPEARANCE),
231 0,
232 CHARACTERISTIC_PROPERTIE_READ,
233 (int)GattPermissionService::READABLE,
234 GetAppearance().get(),
235 APPEARANCE_DATE_LENGTH));
236
237 svc->characteristics_.push_back(Characteristic(Uuid::ConvertFrom16Bits(GATT_UUID_GAP_CENTRAL_ADDR_RESOLUTION),
238 0,
239 CHARACTERISTIC_PROPERTIE_READ,
240 (int)GattPermissionService::READABLE,
241 ¢ral_addr_resolution_,
242 CENTRAL_ADDR_RESOLUTION_DATE_LENGTH));
243 return svc;
244 }
245
GetDeviceName()246 std::string GenericAccessService::GetDeviceName()
247 {
248 std::string result = DEFAULT_DEVICE_NAME;
249 AdapterDeviceConfig::GetInstance()->GetValue(SECTION_HOST, PROPERTY_DEVICE_NAME, result);
250 return result;
251 }
252
GetAppearance() const253 std::unique_ptr<uint8_t[]> GenericAccessService::GetAppearance() const
254 {
255 int appearance = DEFAULT_APPEARANCE;
256 AdapterDeviceConfig::GetInstance()->GetValue(SECTION_HOST, PROPERTY_BLE_APPEARANCE, appearance);
257
258 std::unique_ptr<uint8_t[]> result = std::make_unique<uint8_t[]>(APPEARANCE_DATE_LENGTH);
259 if (memcpy_s(result.get(), APPEARANCE_DATE_LENGTH, &appearance, APPEARANCE_DATE_LENGTH) != EOK) {
260 LOG_DEBUG("%{public}s:%{public}d:%{public}s : memcpy_s fail", __FILE__, __LINE__, __FUNCTION__);
261 return NULL;
262 }
263
264 return result;
265 }
266
OnDeviceNameChanged(std::string & deviceName) const267 void GenericAccessService::OnDeviceNameChanged(std::string &deviceName) const
268 {
269 LOG_DEBUG("%{public}s:%{public}d:%{public}s : device name: %{public}s", __FILE__, __LINE__, __FUNCTION__, deviceName.c_str());
270
271 auto cIt = std::find_if(instance_->characteristics_.begin(),
272 instance_->characteristics_.end(),
273 [](Characteristic &ccc) {
274 return ccc.uuid_ == Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME);
275 });
276
277 if (cIt != instance_->characteristics_.end()) {
278 cIt->SetValue((uint8_t *)deviceName.c_str(), deviceName.length());
279 serverService_.SetCharacteristicValue(*cIt);
280 return;
281 }
282 }
283
OnAdvertisingStateChanged(int state)284 void GenericAccessService::OnAdvertisingStateChanged(int state)
285 {
286 LOG_DEBUG("%{public}s:%{public}d:%{public}s :state: %{public}d", __FILE__, __LINE__, __FUNCTION__, state);
287 if (state == BleAdvState::BLE_ADV_STATE_ADVERTISING) {
288 bleDiscoverable_ = true;
289 } else {
290 bleDiscoverable_ = false;
291 }
292
293 for (auto &ccc : instance_->characteristics_) {
294 if (!(ccc.uuid_ == Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME))) {
295 continue;
296 }
297 if (classicDiscoverable_ || bleDiscoverable_) {
298 if (!(ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ)) {
299 serverService_.SetCharacteristicPermission(ccc,
300 ccc.properties_ | CHARACTERISTIC_PROPERTIE_READ,
301 ccc.permissions_ | (int)GattPermissionService::READABLE);
302 }
303 } else {
304 if (ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ) {
305 serverService_.SetCharacteristicPermission(ccc,
306 ccc.properties_ & ~CHARACTERISTIC_PROPERTIE_READ,
307 ccc.permissions_ & ~(int)GattPermissionService::READABLE);
308 }
309 }
310 return;
311 }
312 }
313
OnScanModeChanged(int mode)314 void GenericAccessService::OnScanModeChanged(int mode)
315 {
316 LOG_DEBUG("%{public}s:%{public}d:%{public}s :mode: %{public}d", __FILE__, __LINE__, __FUNCTION__, mode);
317 if (mode == SCAN_MODE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_LIMITED_DISCOVERABLE ||
318 mode == SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE || mode == SCAN_MODE_CONNECTABLE_LIMITED_DISCOVERABLE) {
319 classicDiscoverable_ = true;
320 } else {
321 classicDiscoverable_ = false;
322 }
323
324 for (auto &ccc : instance_->characteristics_) {
325 if (!(ccc.uuid_ == Uuid::ConvertFrom16Bits(GATT_UUID_GAP_DEVICE_NAME))) {
326 continue;
327 }
328 if (classicDiscoverable_ || bleDiscoverable_) {
329 if (!(ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ)) {
330 serverService_.SetCharacteristicPermission(ccc,
331 ccc.properties_ | CHARACTERISTIC_PROPERTIE_READ,
332 ccc.permissions_ | (int)GattPermissionService::READABLE);
333 }
334 } else {
335 if (ccc.properties_ & CHARACTERISTIC_PROPERTIE_READ) {
336 serverService_.SetCharacteristicPermission(ccc,
337 ccc.properties_ & ~CHARACTERISTIC_PROPERTIE_READ,
338 ccc.permissions_ & ~(int)GattPermissionService::READABLE);
339 }
340 }
341 return;
342 }
343 }
344 } // namespace bluetooth
345 } // namespace OHOS