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