• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         &central_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