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