1 /*
2  * Copyright (C) 2021-2022 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 <condition_variable>
17 #include <memory>
18 #include <set>
19 #include "bluetooth_gatt_server.h"
20 #include "bluetooth_host.h"
21 #include "bluetooth_log.h"
22 #include "bluetooth_utils.h"
23 #include "bluetooth_host_proxy.h"
24 #include "bluetooth_gatt_server_proxy.h"
25 #include "bluetooth_gatt_server_callback_stub.h"
26 #include "gatt_data.h"
27 #include "iservice_registry.h"
28 #include "raw_address.h"
29 #include "system_ability_definition.h"
30 #include "bluetooth_profile_manager.h"
31 
32 namespace OHOS {
33 namespace Bluetooth {
34 const int EIGHT_BITS = 8;
35 constexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_READ = 0x00;
36 constexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_WRITE = 0x01;
37 constexpr uint8_t REQUEST_TYPE_DESCRIPTOR_READ = 0x02;
38 constexpr uint8_t REQUEST_TYPE_DESCRIPTOR_WRITE = 0x03;
39 
40 struct RequestInformation {
41     uint8_t type_;
42     bluetooth::GattDevice device_;
43     union {
44         GattCharacteristic *characteristic_;
45         GattDescriptor *descriptor_;
46     } context_;
47 
RequestInformationOHOS::Bluetooth::RequestInformation48     RequestInformation(uint8_t type, const bluetooth::GattDevice &device, GattCharacteristic *characteristic)
49         : type_(type), device_(device), context_ {
50             .characteristic_ = characteristic
51         }
52     {}
53 
54     RequestInformation(uint8_t type, const bluetooth::GattDevice &device, GattDescriptor *decriptor)
55         : type_(type), device_(device), context_ {
56             .descriptor_ = decriptor
57         }
58     {}
59 
device_(device)60     RequestInformation(uint8_t type, const bluetooth::GattDevice &device) : type_(type), device_(device)
61     {}
62 
operator ==(const RequestInformation &rhs) const63     bool operator==(const RequestInformation &rhs) const
64     {
65         return (device_ == rhs.device_ && type_ == rhs.type_);
66     };
67 
operator <(const RequestInformation &rhs) const68     bool operator<(const RequestInformation &rhs) const
69     {
70         return (device_ < rhs.device_ && type_ == rhs.type_);
71     };
72 };
73 
74 struct GattServer::impl {
75     class BluetoothGattServerCallbackStubImpl;
76     bool isRegisterSucceeded_ = false;
77     std::mutex serviceListMutex_;
78     std::mutex requestListMutex_;
79     std::list<GattService> gattServices_;
80     sptr<BluetoothGattServerCallbackStubImpl> serviceCallback_;
81     std::optional<std::reference_wrapper<GattCharacteristic>> FindCharacteristic(uint16_t handle);
82     std::optional<std::reference_wrapper<GattDescriptor>> FindDescriptor(uint16_t handle);
83     std::set<RequestInformation> requests_;
84     std::list<bluetooth::GattDevice> devices_;
85     std::shared_ptr<GattServerCallback> callback_;
86     int BuildRequestId(uint8_t type, uint8_t transport);
87     int RespondCharacteristicRead(
88         const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret);
89     int RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret);
90     int RespondDescriptorRead(
91         const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret);
92     int RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret);
93     int applicationId_ = 0;
94     std::mutex deviceListMutex_;
95     GattService *GetIncludeService(uint16_t handle);
96     bluetooth::GattDevice *FindConnectedDevice(const BluetoothRemoteDevice &device);
97     GattService BuildService(const BluetoothGattService &service);
98     void BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs);
99     impl(std::shared_ptr<GattServerCallback> callback);
100     bool Init(std::weak_ptr<GattServer>);
101     int32_t profileRegisterId = 0;
102 };
103 
104 class GattServer::impl::BluetoothGattServerCallbackStubImpl : public BluetoothGattServerCallbackStub {
105 public:
GetServerSptr(void)106     inline std::shared_ptr<GattServer> GetServerSptr(void)
107     {
108         auto serverSptr = server_.lock();
109         if (!serverSptr) {
110             HILOGE("server_ is nullptr");
111             return nullptr;
112         }
113         if (!serverSptr->pimpl) {
114             HILOGE("impl is nullptr");
115             return nullptr;
116         }
117         return serverSptr;
118     }
119     void OnCharacteristicReadRequest(
120         const BluetoothGattDevice &device, const BluetoothGattCharacteristic &characteristic) override
121     {
122         HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
123             GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_);
124         auto serverSptr = GetServerSptr();
125         if (!serverSptr) {
126             return;
127         }
128 
129         std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
130         auto gattcharacter = serverSptr->pimpl->FindCharacteristic(characteristic.handle_);
131         if (gattcharacter.has_value()) {
132             {
133                 std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
134                 auto ret = serverSptr->pimpl->requests_.emplace(
135                     RequestInformation(REQUEST_TYPE_CHARACTERISTICS_READ, device, &gattcharacter.value().get()));
136                 if (!ret.second) {
137                     HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
138                         REQUEST_TYPE_CHARACTERISTICS_READ, GET_ENCRYPT_GATT_ADDR(device));
139                 }
140             }
141 
142             if (serverSptr->pimpl->callback_) {
143                 serverSptr->pimpl->callback_->OnCharacteristicReadRequest(
144                     BluetoothRemoteDevice(device.addr_.GetAddress(),
145                         (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
146                     gattcharacter.value().get(),
147                     serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_CHARACTERISTICS_READ, device.transport_));
148             }
149 
150             return;
151         } else {
152             HILOGE("Can not Find Characteristic!");
153         }
154         return;
155     }
156 
157     void OnCharacteristicWriteRequest(const BluetoothGattDevice &device,
158         const BluetoothGattCharacteristic &characteristic, bool needRespones) override
159     {
160         HILOGI("remote device: %{public}s, handle: 0x%{public}04X, length: %{public}zu",
161             GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_, characteristic.length_);
162         auto serverSptr = GetServerSptr();
163         if (!serverSptr) {
164             return;
165         }
166 
167         std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
168         auto gattcharacter = serverSptr->pimpl->FindCharacteristic(characteristic.handle_);
169         if (gattcharacter.has_value()) {
170             gattcharacter.value().get().SetValue(characteristic.value_.get(), characteristic.length_);
171             gattcharacter.value().get().SetWriteType(
172                 needRespones ? GattCharacteristic::WriteType::DEFAULT : GattCharacteristic::WriteType::NO_RESPONSE);
173 
174             if (needRespones) {
175                 std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
176                 auto ret = serverSptr->pimpl->requests_.emplace(
177                     RequestInformation(REQUEST_TYPE_CHARACTERISTICS_WRITE, device, &gattcharacter.value().get()));
178                 if (!ret.second) {
179                     HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
180                         REQUEST_TYPE_CHARACTERISTICS_WRITE, GET_ENCRYPT_GATT_ADDR(device));
181                 }
182             }
183 
184             if (serverSptr->pimpl->callback_) {
185                 serverSptr->pimpl->callback_->OnCharacteristicWriteRequest(
186                     BluetoothRemoteDevice(device.addr_.GetAddress(),
187                         (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
188                     gattcharacter.value().get(),
189                     serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_CHARACTERISTICS_WRITE, device.transport_));
190             }
191 
192             return;
193         } else {
194             HILOGE("Can not Find Characteristic!");
195         }
196 
197         return;
198     }
199 
200     void OnDescriptorReadRequest(const BluetoothGattDevice &device, const BluetoothGattDescriptor &descriptor) override
201     {
202         HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
203             GET_ENCRYPT_GATT_ADDR(device), descriptor.handle_);
204         auto serverSptr = GetServerSptr();
205         if (!serverSptr) {
206             return;
207         }
208 
209         std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
210         auto gattdesc = serverSptr->pimpl->FindDescriptor(descriptor.handle_);
211         if (gattdesc.has_value()) {
212             {
213                 std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
214                 auto ret = serverSptr->pimpl->requests_.emplace(
215                     RequestInformation(REQUEST_TYPE_DESCRIPTOR_READ, device, &gattdesc.value().get()));
216                 if (!ret.second) {
217                     HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
218                         REQUEST_TYPE_DESCRIPTOR_READ, GET_ENCRYPT_GATT_ADDR(device));
219                 }
220             }
221 
222             if (serverSptr->pimpl->callback_) {
223                 serverSptr->pimpl->callback_->OnDescriptorReadRequest(
224                     BluetoothRemoteDevice(device.addr_.GetAddress(),
225                         (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
226                     gattdesc.value().get(),
227                     serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_DESCRIPTOR_READ, device.transport_));
228             }
229 
230             return;
231         } else {
232             HILOGE("Can not Find Descriptor!");
233         }
234 
235         return;
236     }
237 
238     void OnDescriptorWriteRequest(const BluetoothGattDevice &device, const BluetoothGattDescriptor &descriptor) override
239     {
240         HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
241             GET_ENCRYPT_GATT_ADDR(device), descriptor.handle_);
242         auto serverSptr = GetServerSptr();
243         if (!serverSptr) {
244             return;
245         }
246 
247         std::lock_guard<std::mutex> lock(serverSptr->pimpl->serviceListMutex_);
248         auto gattdesc = serverSptr->pimpl->FindDescriptor(descriptor.handle_);
249         if (gattdesc.has_value()) {
250             gattdesc.value().get().SetValue(descriptor.value_.get(), descriptor.length_);
251 
252             {
253                 std::lock_guard<std::mutex> lck(serverSptr->pimpl->requestListMutex_);
254                 auto ret = serverSptr->pimpl->requests_.emplace(
255                     RequestInformation(REQUEST_TYPE_DESCRIPTOR_WRITE, device, &gattdesc.value().get()));
256                 if (!ret.second) {
257                     HILOGE("insert request failed, type: %{public}u, addr: %{public}s",
258                         REQUEST_TYPE_DESCRIPTOR_WRITE, GET_ENCRYPT_GATT_ADDR(device));
259                 }
260             }
261 
262             if (serverSptr->pimpl->callback_) {
263                 serverSptr->pimpl->callback_->OnDescriptorWriteRequest(
264                     BluetoothRemoteDevice(device.addr_.GetAddress(),
265                         (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
266                     gattdesc.value().get(),
267                     serverSptr->pimpl->BuildRequestId(REQUEST_TYPE_DESCRIPTOR_WRITE, device.transport_));
268             }
269 
270             return;
271         } else {
272             HILOGE("Can not Find Descriptor!");
273         }
274         return;
275     }
276 
277     void OnNotifyConfirm(
278         const BluetoothGattDevice &device, const BluetoothGattCharacteristic &characteristic, int result) override
279     {
280         HILOGI("remote device: %{public}s, handle: 0x%{public}04X",
281             GET_ENCRYPT_GATT_ADDR(device), characteristic.handle_);
282         auto serverSptr = GetServerSptr();
283         if (!serverSptr) {
284             return;
285         }
286 
287         if (serverSptr->pimpl->callback_) {
288             serverSptr->pimpl->callback_->OnNotificationCharacteristicChanged(
289                 BluetoothRemoteDevice(device.addr_.GetAddress(),
290                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
291                 result);
292         }
293         return;
294     }
295 
296     void OnConnectionStateChanged(const BluetoothGattDevice &device, int32_t ret, int32_t state) override
297     {
298         HILOGD("gattServer conn state, remote device: %{public}s, ret: %{public}d, state: %{public}s",
299             GET_ENCRYPT_GATT_ADDR(device), ret, GetProfileConnStateName(state).c_str());
300         auto serverSptr = GetServerSptr();
301         if (!serverSptr) {
302             return;
303         }
304 
305         if (state == static_cast<int>(BTConnectState::CONNECTED)) {
306             std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
307             serverSptr->pimpl->devices_.push_back((bluetooth::GattDevice)device);
308         } else if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
309             std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
310             for (auto it = serverSptr->pimpl->devices_.begin(); it != serverSptr->pimpl->devices_.end(); it++) {
311                 if (*it == (bluetooth::GattDevice)device) {
312                     serverSptr->pimpl->devices_.erase(it);
313                     break;
314                 }
315             }
316         }
317 
318         if (serverSptr->pimpl->callback_) {
319             serverSptr->pimpl->callback_->OnConnectionStateUpdate(
320                 BluetoothRemoteDevice(device.addr_.GetAddress(),
321                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
322                 state);
323         }
324 
325         return;
326     }
327 
328     void OnMtuChanged(const BluetoothGattDevice &device, int32_t mtu) override
329     {
330         HILOGI("remote device: %{public}s, mtu: %{public}d", GET_ENCRYPT_GATT_ADDR(device), mtu);
331         auto serverSptr = GetServerSptr();
332         if (!serverSptr) {
333             return;
334         }
335 
336         if (serverSptr->pimpl->callback_) {
337             serverSptr->pimpl->callback_->OnMtuUpdate(
338                 BluetoothRemoteDevice(device.addr_.GetAddress(),
339                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
340                 mtu);
341         }
342 
343         return;
344     }
345 
346     void OnAddService(int32_t ret, const BluetoothGattService &service) override
347     {
348         HILOGI("enter, ret: %{public}d, handle: %{public}d", ret, service.handle_);
349         auto serverSptr = GetServerSptr();
350         if (!serverSptr) {
351             return;
352         }
353 
354         GattService *ptr = nullptr;
355         if (ret == GattStatus::GATT_SUCCESS) {
356             GattService gattSvc = serverSptr->pimpl->BuildService(service);
357             serverSptr->pimpl->BuildIncludeService(gattSvc, service.includeServices_);
358             {
359                 std::lock_guard<std::mutex> lck(serverSptr->pimpl->serviceListMutex_);
360                 auto it = serverSptr->pimpl->gattServices_.emplace(
361                     serverSptr->pimpl->gattServices_.end(), std::move(gattSvc));
362                 ptr = &(*it);
363             }
364         }
365         if (serverSptr->pimpl && serverSptr->pimpl->callback_) {
366             serverSptr->pimpl->callback_->OnServiceAdded(ptr, ret);
367         }
368         return;
369     }
370 
371     void OnConnectionParameterChanged(
372         const BluetoothGattDevice &device, int32_t interval, int32_t latency, int32_t timeout, int32_t status) override
373     {
374         HILOGD("remote device: %{public}s, interval: %{public}d, "
375             "latency: %{public}d, timeout: %{public}d, status: %{public}d",
376             GET_ENCRYPT_GATT_ADDR(device), interval, latency, timeout, status);
377         auto serverSptr = GetServerSptr();
378         if (!serverSptr) {
379             return;
380         }
381 
382         if (serverSptr->pimpl->callback_) {
383             serverSptr->pimpl->callback_->OnConnectionParameterChanged(
384                 BluetoothRemoteDevice(device.addr_.GetAddress(),
385                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
386                 interval,
387                 latency,
388                 timeout,
389                 status);
390         }
391 
392         return;
393     }
394 
BluetoothGattServerCallbackStubImpl(std::weak_ptr<GattServer> server)395     explicit BluetoothGattServerCallbackStubImpl(std::weak_ptr<GattServer> server) : server_(server)
396     {
397         HILOGD("enter");
398     }
399     ~BluetoothGattServerCallbackStubImpl() override
400     {
401         HILOGD("enter");
402     }
403 
404 private:
405     std::weak_ptr<GattServer> server_;
406 };
407 
BuildService(const BluetoothGattService &service)408 GattService GattServer::impl::BuildService(const BluetoothGattService &service)
409 {
410     GattService gattService(UUID::ConvertFrom128Bits(service.uuid_.ConvertTo128Bits()),
411         service.handle_,
412         service.endHandle_,
413         service.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
414 
415     for (auto &character : service.characteristics_) {
416         GattCharacteristic gattcharacter(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()),
417             character.handle_,
418             character.permissions_,
419             character.properties_);
420 
421         gattcharacter.SetValue(character.value_.get(), character.length_);
422 
423         for (auto &desc : character.descriptors_) {
424             GattDescriptor gattDesc(
425                 UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_);
426 
427             gattDesc.SetValue(desc.value_.get(), desc.length_);
428             gattcharacter.AddDescriptor(std::move(gattDesc));
429         }
430 
431         gattService.AddCharacteristic(std::move(gattcharacter));
432     }
433 
434     return gattService;
435 }
436 
BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs)437 void GattServer::impl::BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs)
438 {
439     for (auto &iSvc : iSvcs) {
440         GattService *pSvc = GetIncludeService(iSvc.startHandle_);
441         if (!pSvc) {
442             HILOGE("Can not find include service entity in service ");
443             continue;
444         }
445         svc.AddService(std::ref(*pSvc));
446     }
447 }
448 
GetIncludeService(uint16_t handle)449 GattService *GattServer::impl::GetIncludeService(uint16_t handle)
450 {
451     for (auto &svc : gattServices_) {
452         if (svc.GetHandle() == handle) {
453             return &svc;
454         }
455     }
456 
457     return nullptr;
458 }
459 
impl(std::shared_ptr<GattServerCallback> callback)460 GattServer::impl::impl(std::shared_ptr<GattServerCallback> callback)
461     : isRegisterSucceeded_(false), callback_(callback), applicationId_(0)
462 {
463     HILOGD("enter");
464 };
465 
GattServer(std::shared_ptr<GattServerCallback> callback)466 GattServer::GattServer(std::shared_ptr<GattServerCallback> callback)
467 {
468     HILOGI("create GattServer start.");
469     pimpl = std::make_unique<GattServer::impl>(callback);
470     if (!pimpl) {
471         HILOGE("create GattServer failed.");
472     }
473 }
474 
Init(std::weak_ptr<GattServer> server)475 bool GattServer::impl::Init(std::weak_ptr<GattServer> server)
476 {
477     if (profileRegisterId != 0) { //ProxyManager has register callback
478         return true;
479     }
480     serviceCallback_ = new BluetoothGattServerCallbackStubImpl(server);
481     profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_GATT_SERVER,
482         [this](sptr<IRemoteObject> remote) {
483         sptr<IBluetoothGattServer> proxy = iface_cast<IBluetoothGattServer>(remote);
484         CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
485         int result = proxy->RegisterApplication(serviceCallback_);
486         if (result > 0) {
487             applicationId_ = result;
488             isRegisterSucceeded_ = true;
489         } else {
490             HILOGE("Can not Register to gatt server service! result = %{public}d", result);
491         }
492     });
493     return true;
494 }
495 
CreateInstance(std::shared_ptr<GattServerCallback> callback)496 std::shared_ptr<GattServer> GattServer::CreateInstance(std::shared_ptr<GattServerCallback> callback)
497 {
498     // The passkey pattern used here.
499     auto instance = std::make_shared<GattServer>(PassKey(), callback);
500     if (!instance->pimpl) {
501         HILOGE("failed: no impl");
502         return nullptr;
503     }
504 
505     instance->pimpl->Init(instance);
506     return instance;
507 }
508 
FindCharacteristic(uint16_t handle)509 std::optional<std::reference_wrapper<GattCharacteristic>> GattServer::impl::FindCharacteristic(uint16_t handle)
510 {
511     for (auto &svc : gattServices_) {
512         for (auto &character : svc.GetCharacteristics()) {
513             if (character.GetHandle() == handle) {
514                 return character;
515             }
516         }
517     }
518     return std::nullopt;
519 }
FindConnectedDevice(const BluetoothRemoteDevice &device)520 bluetooth::GattDevice *GattServer::impl::FindConnectedDevice(const BluetoothRemoteDevice &device)
521 {
522     std::lock_guard<std::mutex> lock(deviceListMutex_);
523     for (auto &gattDevice : devices_) {
524         if (device.GetDeviceAddr().compare(gattDevice.addr_.GetAddress()) == 0 &&
525             (device.GetTransportType() ==
526             (gattDevice.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR)) {
527             return &gattDevice;
528         }
529     }
530     return nullptr;
531 }
FindDescriptor(uint16_t handle)532 std::optional<std::reference_wrapper<GattDescriptor>> GattServer::impl::FindDescriptor(uint16_t handle)
533 {
534     for (auto &svc : gattServices_) {
535         for (auto &character : svc.GetCharacteristics()) {
536             for (auto &desc : character.GetDescriptors()) {
537                 if (desc.GetHandle() == handle) {
538                     return desc;
539                 }
540             }
541         }
542     }
543     return std::nullopt;
544 }
545 
BuildRequestId(uint8_t type, uint8_t transport)546 int GattServer::impl::BuildRequestId(uint8_t type, uint8_t transport)
547 {
548     int requestId = 0;
549 
550     requestId = type << EIGHT_BITS;
551     requestId |= transport;
552 
553     return requestId;
554 }
555 
RespondCharacteristicRead( const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)556 int GattServer::impl::RespondCharacteristicRead(
557     const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
558 {
559     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
560     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
561 
562     if (ret == GattStatus::GATT_SUCCESS) {
563         BluetoothGattCharacteristic character(bluetooth::Characteristic(handle, value, length));
564 
565         return proxy->RespondCharacteristicRead(device, &character, ret);
566     }
567     BluetoothGattCharacteristic character;
568     character.handle_ = handle;
569     return proxy->RespondCharacteristicRead(device, &character, ret);
570 }
571 
RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)572 int GattServer::impl::RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
573 {
574     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
575     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
576     return proxy->RespondCharacteristicWrite(
577         device, (BluetoothGattCharacteristic)bluetooth::Characteristic(handle), ret);
578 }
579 
RespondDescriptorRead( const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)580 int GattServer::impl::RespondDescriptorRead(
581     const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
582 {
583     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
584     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
585     if (ret == GattStatus::GATT_SUCCESS) {
586         BluetoothGattDescriptor desc(bluetooth::Descriptor(handle, value, length));
587         return proxy->RespondDescriptorRead(device, &desc, ret);
588     }
589     BluetoothGattDescriptor desc;
590     desc.handle_ = handle;
591     return proxy->RespondDescriptorRead(device, &desc, ret);
592 }
593 
RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)594 int GattServer::impl::RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
595 {
596     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
597     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
598     return proxy->RespondDescriptorWrite(device, (BluetoothGattDescriptor)bluetooth::Descriptor(handle), ret);
599 }
600 
AddService(GattService &service)601 int GattServer::AddService(GattService &service)
602 {
603     HILOGD("enter");
604     if (!IS_BLE_ENABLED()) {
605         HILOGE("bluetooth is off.");
606         return BT_ERR_INVALID_STATE;
607     }
608 
609     BluetoothGattService svc;
610     svc.isPrimary_ = service.IsPrimary();
611     svc.uuid_ = bluetooth::Uuid::ConvertFrom128Bits(service.GetUuid().ConvertTo128Bits());
612 
613     for (auto &isvc : service.GetIncludedServices()) {
614         svc.includeServices_.push_back(bluetooth::Service(isvc.get().GetHandle()));
615     }
616 
617     for (auto &character : service.GetCharacteristics()) {
618         size_t length = 0;
619         uint8_t *value = character.GetValue(&length).get();
620         bluetooth::Characteristic c(bluetooth::Uuid::ConvertFrom128Bits(character.GetUuid().ConvertTo128Bits()),
621             character.GetHandle(),
622             character.GetProperties(),
623             character.GetPermissions(),
624             value,
625             length);
626 
627         for (auto &desc : character.GetDescriptors()) {
628             value = desc.GetValue(&length).get();
629             bluetooth::Descriptor d(bluetooth::Uuid::ConvertFrom128Bits(desc.GetUuid().ConvertTo128Bits()),
630                 desc.GetHandle(),
631                 desc.GetPermissions(),
632                 value,
633                 length);
634 
635             c.descriptors_.push_back(std::move(d));
636         }
637 
638         svc.characteristics_.push_back(std::move(c));
639     }
640     int appId = pimpl->applicationId_;
641     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
642     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
643     int ret = proxy->AddService(appId, &svc);
644     HILOGI("appId = %{public}d, ret = %{public}d.", appId, ret);
645     return ret;
646 }
647 
ClearServices()648 void GattServer::ClearServices()
649 {
650     HILOGD("enter");
651     if (!IS_BLE_ENABLED()) {
652         HILOGE("bluetooth is off.");
653         return;
654     }
655 
656     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
657     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
658 
659     int appId = pimpl->applicationId_;
660     proxy->ClearServices(int(appId));
661     pimpl->gattServices_.clear();
662 }
663 
Close()664 int GattServer::Close()
665 {
666     HILOGD("enter");
667     if (!IS_BLE_ENABLED()) {
668         HILOGE("bluetooth is off.");
669         return BT_ERR_INVALID_STATE;
670     }
671     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
672     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
673 
674     int ret = proxy->DeregisterApplication(pimpl->applicationId_);
675     HILOGI("ret: %{public}d", ret);
676     if (ret == BT_NO_ERROR) {
677         pimpl->isRegisterSucceeded_ = false;
678     }
679     return ret;
680 }
681 
Connect(const BluetoothRemoteDevice &device, bool isDirect)682 int GattServer::Connect(const BluetoothRemoteDevice &device, bool isDirect)
683 {
684     CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
685     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
686     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
687     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
688 
689     int appId = pimpl->applicationId_;
690     HILOGI("appId: %{public}d, device: %{public}s, isDirect: %{public}d", appId, GET_ENCRYPT_ADDR(device), isDirect);
691 
692     bluetooth::GattDevice gattDevice(bluetooth::RawAddress(device.GetDeviceAddr()), GATT_TRANSPORT_TYPE_LE);
693     return proxy->Connect(appId, gattDevice, isDirect);
694 }
695 
CancelConnection(const BluetoothRemoteDevice &device)696 int GattServer::CancelConnection(const BluetoothRemoteDevice &device)
697 {
698     CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
699     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
700     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
701     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
702 
703     auto gattDevice = pimpl->FindConnectedDevice(device);
704     if (gattDevice == nullptr) {
705         HILOGE("gattDevice is nullptr");
706         return BT_ERR_INTERNAL_ERROR;
707     }
708 
709     int appId = pimpl->applicationId_;
710     HILOGI("appId: %{public}d, device: %{public}s", appId, GET_ENCRYPT_ADDR(device));
711     return proxy->CancelConnection(appId, *gattDevice);
712 }
GetService(const UUID &uuid, bool isPrimary)713 std::optional<std::reference_wrapper<GattService>> GattServer::GetService(const UUID &uuid, bool isPrimary)
714 {
715     HILOGD("enter");
716     if (!IS_BLE_ENABLED()) {
717         HILOGE("bluetooth is off.");
718         return std::nullopt;
719     }
720     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
721     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::nullopt, "failed: no proxy");
722 
723     std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
724 
725     for (auto &svc : pimpl->gattServices_) {
726         if (svc.GetUuid().Equals(uuid) && svc.IsPrimary() == isPrimary) {
727             HILOGI("Find service, handle: 0x%{public}04X", svc.GetHandle());
728             return svc;
729         }
730     }
731 
732     return std::nullopt;
733 }
734 
GetServices()735 std::list<GattService> &GattServer::GetServices()
736 {
737     HILOGD("enter");
738     if (!IS_BLE_ENABLED()) {
739         HILOGE("bluetooth is off.");
740         return pimpl->gattServices_;
741     }
742     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
743     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, pimpl->gattServices_, "failed: no proxy");
744 
745     std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
746     return pimpl->gattServices_;
747 }
NotifyCharacteristicChanged( const BluetoothRemoteDevice &device, const GattCharacteristic &characteristic, bool confirm)748 int GattServer::NotifyCharacteristicChanged(
749     const BluetoothRemoteDevice &device, const GattCharacteristic &characteristic, bool confirm)
750 {
751     HILOGI("remote device: %{public}s, handle: 0x%{public}04X, confirm: %{public}d",
752         GET_ENCRYPT_ADDR(device), characteristic.GetHandle(), confirm);
753     if (!IS_BLE_ENABLED()) {
754         HILOGE("bluetooth is off.");
755         return BT_ERR_INVALID_STATE;
756     }
757 
758     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
759     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
760 
761     if (!device.IsValidBluetoothRemoteDevice()) {
762         HILOGE("Invalid remote device");
763         return BT_ERR_INTERNAL_ERROR;
764     }
765     if (pimpl->FindConnectedDevice(device) == nullptr) {
766         HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
767         return BT_ERR_INTERNAL_ERROR;
768     }
769 
770     size_t length = 0;
771     auto &characterValue = characteristic.GetValue(&length);
772 
773     BluetoothGattCharacteristic character(
774         bluetooth::Characteristic(characteristic.GetHandle(), characterValue.get(), length));
775     std::string address = device.GetDeviceAddr();
776     int ret = proxy->NotifyClient(
777         bluetooth::GattDevice(bluetooth::RawAddress(address), 0), &character, confirm);
778     HILOGI("ret = %{public}d.", ret);
779     return ret;
780 }
781 
RemoveGattService(const GattService &service)782 int GattServer::RemoveGattService(const GattService &service)
783 {
784     HILOGD("enter");
785     if (!IS_BLE_ENABLED()) {
786         HILOGD("bluetooth is off.");
787         return BT_ERR_INVALID_STATE;
788     }
789 
790     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
791     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
792 
793     int ret = BT_ERR_INVALID_PARAM;
794     for (auto sIt = pimpl->gattServices_.begin(); sIt != pimpl->gattServices_.end(); sIt++) {
795         if (sIt->GetUuid().Equals(service.GetUuid())) {
796             ret = proxy->RemoveService(
797                 pimpl->applicationId_, (BluetoothGattService)bluetooth::Service(sIt->GetHandle()));
798             pimpl->gattServices_.erase(sIt);
799             break;
800         }
801     }
802     HILOGI("result = %{public}d.", ret);
803     return ret;
804 }
SendResponse( const BluetoothRemoteDevice &device, int requestId, int status, int offset, const uint8_t *value, int length)805 int GattServer::SendResponse(
806     const BluetoothRemoteDevice &device, int requestId, int status, int offset, const uint8_t *value, int length)
807 {
808     HILOGI("remote device: %{public}s, status: %{public}d", GET_ENCRYPT_ADDR(device), status);
809     if (!IS_BLE_ENABLED()) {
810         HILOGE("bluetooth is off.");
811         return BT_ERR_INVALID_STATE;
812     }
813 
814     if (!device.IsValidBluetoothRemoteDevice()) {
815         HILOGE("pimpl or gatt server proxy is nullptr");
816         return BT_ERR_INTERNAL_ERROR;
817     }
818 
819     if (pimpl->FindConnectedDevice(device) == nullptr) {
820         HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
821         return BT_ERR_INTERNAL_ERROR;
822     }
823 
824     int result = BT_ERR_INTERNAL_ERROR;
825     uint8_t requestType = requestId >> EIGHT_BITS;
826     uint8_t transport = requestId & 0xFF;
827     if (transport != GATT_TRANSPORT_TYPE_CLASSIC && transport != GATT_TRANSPORT_TYPE_LE) {
828         return result;
829     }
830     bluetooth::GattDevice gattdevice(bluetooth::RawAddress(device.GetDeviceAddr()), transport);
831 
832     std::lock_guard<std::mutex> lock(pimpl->requestListMutex_);
833     auto request = pimpl->requests_.find(RequestInformation(requestType, gattdevice));
834     if (request != pimpl->requests_.end()) {
835         switch (requestType) {
836             case REQUEST_TYPE_CHARACTERISTICS_READ:
837                 result = pimpl->RespondCharacteristicRead(
838                     gattdevice, request->context_.characteristic_->GetHandle(), value, length, status);
839                 break;
840             case REQUEST_TYPE_CHARACTERISTICS_WRITE:
841                 result = pimpl->RespondCharacteristicWrite(
842                     gattdevice, request->context_.characteristic_->GetHandle(), status);
843                 break;
844             case REQUEST_TYPE_DESCRIPTOR_READ:
845                 result = pimpl->RespondDescriptorRead(
846                     gattdevice, request->context_.descriptor_->GetHandle(), value, length, status);
847                 break;
848             case REQUEST_TYPE_DESCRIPTOR_WRITE:
849                 result = pimpl->RespondDescriptorWrite(gattdevice, request->context_.descriptor_->GetHandle(), status);
850                 break;
851             default:
852                 HILOGE("Error request Id!");
853                 break;
854         }
855         if (result == BT_NO_ERROR) {
856             pimpl->requests_.erase(request);
857         }
858     }
859     HILOGD("result = %{public}d.", result);
860     return result;
861 }
862 
~GattServer()863 GattServer::~GattServer()
864 {
865     HILOGD("enter");
866     BluetoothProfileManager::GetInstance().DeregisterFunc(pimpl->profileRegisterId);
867     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
868     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
869     if (pimpl->isRegisterSucceeded_) {
870         proxy->DeregisterApplication(pimpl->applicationId_);
871     }
872     HILOGI("end");
873 }
874 }  // namespace Bluetooth
875 }  // namespace OHOS
876