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