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         &central_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