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