• 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,int32_t disconnectReason)299     void OnConnectionStateChanged(const BluetoothGattDevice &device,
300         int32_t ret, int32_t state, int32_t disconnectReason) override
301     {
302         HILOGD("gattServer conn state, remote device: %{public}s, ret: %{public}d, state: %{public}s",
303             GET_ENCRYPT_GATT_ADDR(device), ret, GetProfileConnStateName(state).c_str());
304         auto serverSptr = GetServerSptr();
305         if (!serverSptr) {
306             return;
307         }
308 
309         if (state == static_cast<int>(BTConnectState::CONNECTED)) {
310             std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
311             serverSptr->pimpl->devices_.push_back((bluetooth::GattDevice)device);
312         } else if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
313             std::lock_guard<std::mutex> lck(serverSptr->pimpl->deviceListMutex_);
314             for (auto it = serverSptr->pimpl->devices_.begin(); it != serverSptr->pimpl->devices_.end(); it++) {
315                 if (*it == (bluetooth::GattDevice)device) {
316                     serverSptr->pimpl->devices_.erase(it);
317                     break;
318                 }
319             }
320         }
321 
322         if (serverSptr->pimpl->callback_) {
323             serverSptr->pimpl->callback_->OnConnectionStateUpdate(
324                 BluetoothRemoteDevice(device.addr_.GetAddress(),
325                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR), state);
326             serverSptr->pimpl->callback_->OnConnectionStateUpdateWithReason(
327                 BluetoothRemoteDevice(device.addr_.GetAddress(),
328                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
329                 state, disconnectReason);
330         }
331 
332         return;
333     }
334 
OnMtuChanged(const BluetoothGattDevice & device,int32_t mtu)335     void OnMtuChanged(const BluetoothGattDevice &device, int32_t mtu) override
336     {
337         HILOGI("remote device: %{public}s, mtu: %{public}d", GET_ENCRYPT_GATT_ADDR(device), mtu);
338         auto serverSptr = GetServerSptr();
339         if (!serverSptr) {
340             return;
341         }
342 
343         if (serverSptr->pimpl->callback_) {
344             serverSptr->pimpl->callback_->OnMtuUpdate(
345                 BluetoothRemoteDevice(device.addr_.GetAddress(),
346                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
347                 mtu);
348         }
349 
350         return;
351     }
352 
OnAddService(int32_t ret,const BluetoothGattService & service)353     void OnAddService(int32_t ret, const BluetoothGattService &service) override
354     {
355         HILOGI("enter, ret: %{public}d, handle: %{public}d", ret, service.handle_);
356         auto serverSptr = GetServerSptr();
357         if (!serverSptr) {
358             return;
359         }
360 
361         GattService gattService(UUID(), GattServiceType::PRIMARY);
362         if (ret == GattStatus::GATT_SUCCESS) {
363             gattService = serverSptr->pimpl->BuildService(service);
364             serverSptr->pimpl->BuildIncludeService(gattService, service.includeServices_);
365             {
366                 std::lock_guard<std::mutex> lck(serverSptr->pimpl->serviceListMutex_);
367                 serverSptr->pimpl->gattServices_.emplace(serverSptr->pimpl->gattServices_.end(), gattService);
368             }
369         }
370         if (serverSptr->pimpl && serverSptr->pimpl->callback_) {
371             serverSptr->pimpl->callback_->OnServiceAdded(gattService, ret);
372         }
373         return;
374     }
375 
OnConnectionParameterChanged(const BluetoothGattDevice & device,int32_t interval,int32_t latency,int32_t timeout,int32_t status)376     void OnConnectionParameterChanged(
377         const BluetoothGattDevice &device, int32_t interval, int32_t latency, int32_t timeout, int32_t status) override
378     {
379         HILOGD("remote device: %{public}s, interval: %{public}d, "
380             "latency: %{public}d, timeout: %{public}d, status: %{public}d",
381             GET_ENCRYPT_GATT_ADDR(device), interval, latency, timeout, status);
382         auto serverSptr = GetServerSptr();
383         if (!serverSptr) {
384             return;
385         }
386 
387         if (serverSptr->pimpl->callback_) {
388             serverSptr->pimpl->callback_->OnConnectionParameterChanged(
389                 BluetoothRemoteDevice(device.addr_.GetAddress(),
390                     (device.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR),
391                 interval,
392                 latency,
393                 timeout,
394                 status);
395         }
396 
397         return;
398     }
399 
BluetoothGattServerCallbackStubImpl(std::weak_ptr<GattServer> server)400     explicit BluetoothGattServerCallbackStubImpl(std::weak_ptr<GattServer> server) : server_(server)
401     {
402         HILOGD("enter");
403     }
~BluetoothGattServerCallbackStubImpl()404     ~BluetoothGattServerCallbackStubImpl() override
405     {
406         HILOGD("enter");
407     }
408 
409 private:
410     std::weak_ptr<GattServer> server_;
411 };
412 
BuildService(const BluetoothGattService & service)413 GattService GattServer::impl::BuildService(const BluetoothGattService &service)
414 {
415     GattService gattService(UUID::ConvertFrom128Bits(service.uuid_.ConvertTo128Bits()),
416         service.handle_,
417         service.endHandle_,
418         service.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
419 
420     for (auto &character : service.characteristics_) {
421         GattCharacteristic gattcharacter(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()),
422             character.handle_,
423             character.permissions_,
424             character.properties_);
425 
426         gattcharacter.SetValue(character.value_.get(), character.length_);
427 
428         for (auto &desc : character.descriptors_) {
429             GattDescriptor gattDesc(
430                 UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_);
431 
432             gattDesc.SetValue(desc.value_.get(), desc.length_);
433             gattcharacter.AddDescriptor(std::move(gattDesc));
434         }
435 
436         gattService.AddCharacteristic(std::move(gattcharacter));
437     }
438 
439     return gattService;
440 }
441 
BuildIncludeService(GattService & svc,const std::vector<bluetooth::Service> & iSvcs)442 void GattServer::impl::BuildIncludeService(GattService &svc, const std::vector<bluetooth::Service> &iSvcs)
443 {
444     for (auto &iSvc : iSvcs) {
445         GattService *pSvc = GetIncludeService(iSvc.startHandle_);
446         if (!pSvc) {
447             HILOGE("Can not find include service entity in service ");
448             continue;
449         }
450         svc.AddService(std::ref(*pSvc));
451     }
452 }
453 
GetIncludeService(uint16_t handle)454 GattService *GattServer::impl::GetIncludeService(uint16_t handle)
455 {
456     for (auto &svc : gattServices_) {
457         if (svc.GetHandle() == handle) {
458             return &svc;
459         }
460     }
461 
462     return nullptr;
463 }
464 
impl(std::shared_ptr<GattServerCallback> callback)465 GattServer::impl::impl(std::shared_ptr<GattServerCallback> callback)
466     : isRegisterSucceeded_(false), callback_(callback), applicationId_(0)
467 {
468     HILOGD("enter");
469 };
470 
GattServer(std::shared_ptr<GattServerCallback> callback)471 GattServer::GattServer(std::shared_ptr<GattServerCallback> callback)
472 {
473     HILOGI("create GattServer start.");
474     pimpl = std::make_unique<GattServer::impl>(callback);
475     if (!pimpl) {
476         HILOGE("create GattServer failed.");
477     }
478 }
479 
Init(std::weak_ptr<GattServer> server)480 bool GattServer::impl::Init(std::weak_ptr<GattServer> server)
481 {
482     if (profileRegisterId != 0) { //ProxyManager has register callback
483         return true;
484     }
485     serviceCallback_ = new BluetoothGattServerCallbackStubImpl(server);
486     profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_GATT_SERVER,
487         [this](sptr<IRemoteObject> remote) {
488         sptr<IBluetoothGattServer> proxy = iface_cast<IBluetoothGattServer>(remote);
489         CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
490         int result = proxy->RegisterApplication(serviceCallback_);
491         if (result > 0) {
492             applicationId_ = result;
493             isRegisterSucceeded_ = true;
494         } else {
495             HILOGE("Can not Register to gatt server service! result = %{public}d", result);
496         }
497     });
498     return true;
499 }
500 
CreateInstance(std::shared_ptr<GattServerCallback> callback)501 std::shared_ptr<GattServer> GattServer::CreateInstance(std::shared_ptr<GattServerCallback> callback)
502 {
503     // The passkey pattern used here.
504     auto instance = std::make_shared<GattServer>(PassKey(), callback);
505     if (!instance->pimpl) {
506         HILOGE("failed: no impl");
507         return nullptr;
508     }
509 
510     instance->pimpl->Init(instance);
511     return instance;
512 }
513 
FindCharacteristic(uint16_t handle)514 std::optional<std::reference_wrapper<GattCharacteristic>> GattServer::impl::FindCharacteristic(uint16_t handle)
515 {
516     for (auto &svc : gattServices_) {
517         for (auto &character : svc.GetCharacteristics()) {
518             if (character.GetHandle() == handle) {
519                 return character;
520             }
521         }
522     }
523     return std::nullopt;
524 }
FindConnectedDevice(const BluetoothRemoteDevice & device)525 bluetooth::GattDevice *GattServer::impl::FindConnectedDevice(const BluetoothRemoteDevice &device)
526 {
527     std::lock_guard<std::mutex> lock(deviceListMutex_);
528     for (auto &gattDevice : devices_) {
529         if (device.GetDeviceAddr().compare(gattDevice.addr_.GetAddress()) == 0 &&
530             (device.GetTransportType() ==
531             (gattDevice.transport_ == GATT_TRANSPORT_TYPE_LE) ? BT_TRANSPORT_BLE : BT_TRANSPORT_BREDR)) {
532             return &gattDevice;
533         }
534     }
535     return nullptr;
536 }
FindDescriptor(uint16_t handle)537 std::optional<std::reference_wrapper<GattDescriptor>> GattServer::impl::FindDescriptor(uint16_t handle)
538 {
539     for (auto &svc : gattServices_) {
540         for (auto &character : svc.GetCharacteristics()) {
541             for (auto &desc : character.GetDescriptors()) {
542                 if (desc.GetHandle() == handle) {
543                     return desc;
544                 }
545             }
546         }
547     }
548     return std::nullopt;
549 }
550 
BuildRequestId(uint8_t type,uint8_t transport)551 int GattServer::impl::BuildRequestId(uint8_t type, uint8_t transport)
552 {
553     int requestId = 0;
554 
555     requestId = type << EIGHT_BITS;
556     requestId |= transport;
557 
558     return requestId;
559 }
560 
RespondCharacteristicRead(const bluetooth::GattDevice & device,uint16_t handle,const uint8_t * value,size_t length,int ret)561 int GattServer::impl::RespondCharacteristicRead(
562     const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
563 {
564     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
565     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
566 
567     if (ret == GattStatus::GATT_SUCCESS) {
568         BluetoothGattCharacteristic character(bluetooth::Characteristic(handle, value, length));
569 
570         return proxy->RespondCharacteristicRead(device, &character, ret);
571     }
572     BluetoothGattCharacteristic character;
573     character.handle_ = handle;
574     return proxy->RespondCharacteristicRead(device, &character, ret);
575 }
576 
RespondCharacteristicWrite(const bluetooth::GattDevice & device,uint16_t handle,int ret)577 int GattServer::impl::RespondCharacteristicWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
578 {
579     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
580     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
581     return proxy->RespondCharacteristicWrite(
582         device, (BluetoothGattCharacteristic)bluetooth::Characteristic(handle), ret);
583 }
584 
RespondDescriptorRead(const bluetooth::GattDevice & device,uint16_t handle,const uint8_t * value,size_t length,int ret)585 int GattServer::impl::RespondDescriptorRead(
586     const bluetooth::GattDevice &device, uint16_t handle, const uint8_t *value, size_t length, int ret)
587 {
588     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
589     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
590     if (ret == GattStatus::GATT_SUCCESS) {
591         BluetoothGattDescriptor desc(bluetooth::Descriptor(handle, value, length));
592         return proxy->RespondDescriptorRead(device, &desc, ret);
593     }
594     BluetoothGattDescriptor desc;
595     desc.handle_ = handle;
596     return proxy->RespondDescriptorRead(device, &desc, ret);
597 }
598 
RespondDescriptorWrite(const bluetooth::GattDevice & device,uint16_t handle,int ret)599 int GattServer::impl::RespondDescriptorWrite(const bluetooth::GattDevice &device, uint16_t handle, int ret)
600 {
601     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
602     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, GattStatus::REQUEST_NOT_SUPPORT, "failed: no proxy");
603     return proxy->RespondDescriptorWrite(device, (BluetoothGattDescriptor)bluetooth::Descriptor(handle), ret);
604 }
605 
AddService(GattService & service)606 int GattServer::AddService(GattService &service)
607 {
608     HILOGD("enter");
609     if (!IS_BLE_ENABLED()) {
610         HILOGE("bluetooth is off.");
611         return BT_ERR_INVALID_STATE;
612     }
613 
614     BluetoothGattService svc;
615     svc.isPrimary_ = service.IsPrimary();
616     svc.uuid_ = bluetooth::Uuid::ConvertFrom128Bits(service.GetUuid().ConvertTo128Bits());
617 
618     for (auto &isvc : service.GetIncludedServices()) {
619         svc.includeServices_.push_back(bluetooth::Service(isvc.get().GetHandle()));
620     }
621 
622     for (auto &character : service.GetCharacteristics()) {
623         size_t length = 0;
624         uint8_t *value = character.GetValue(&length).get();
625         bluetooth::Characteristic c(bluetooth::Uuid::ConvertFrom128Bits(character.GetUuid().ConvertTo128Bits()),
626             character.GetHandle(),
627             character.GetProperties(),
628             character.GetPermissions(),
629             value,
630             length);
631 
632         for (auto &desc : character.GetDescriptors()) {
633             value = desc.GetValue(&length).get();
634             bluetooth::Descriptor d(bluetooth::Uuid::ConvertFrom128Bits(desc.GetUuid().ConvertTo128Bits()),
635                 desc.GetHandle(),
636                 desc.GetPermissions(),
637                 value,
638                 length);
639 
640             c.descriptors_.push_back(std::move(d));
641         }
642 
643         svc.characteristics_.push_back(std::move(c));
644     }
645     int appId = pimpl->applicationId_;
646     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
647     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
648     int ret = proxy->AddService(appId, &svc);
649     HILOGI("appId = %{public}d, ret = %{public}d.", appId, ret);
650     return ret;
651 }
652 
ClearServices()653 void GattServer::ClearServices()
654 {
655     HILOGD("enter");
656     if (!IS_BLE_ENABLED()) {
657         HILOGE("bluetooth is off.");
658         return;
659     }
660 
661     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
662     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
663 
664     int appId = pimpl->applicationId_;
665     proxy->ClearServices(int(appId));
666     pimpl->gattServices_.clear();
667 }
668 
Close()669 int GattServer::Close()
670 {
671     HILOGD("enter");
672     if (!IS_BLE_ENABLED()) {
673         HILOGE("bluetooth is off.");
674         return BT_ERR_INVALID_STATE;
675     }
676     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
677     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
678 
679     int ret = proxy->DeregisterApplication(pimpl->applicationId_);
680     HILOGI("ret: %{public}d", ret);
681     if (ret == BT_NO_ERROR) {
682         pimpl->isRegisterSucceeded_ = false;
683     }
684     return ret;
685 }
686 
Connect(const BluetoothRemoteDevice & device,bool isDirect)687 int GattServer::Connect(const BluetoothRemoteDevice &device, bool isDirect)
688 {
689     CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
690     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
691     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
692     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
693 
694     int appId = pimpl->applicationId_;
695     HILOGI("appId: %{public}d, device: %{public}s, isDirect: %{public}d", appId, GET_ENCRYPT_ADDR(device), isDirect);
696 
697     bluetooth::GattDevice gattDevice(bluetooth::RawAddress(device.GetDeviceAddr()), GATT_TRANSPORT_TYPE_LE);
698     return proxy->Connect(appId, gattDevice, isDirect);
699 }
700 
CancelConnection(const BluetoothRemoteDevice & device)701 int GattServer::CancelConnection(const BluetoothRemoteDevice &device)
702 {
703     CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off");
704     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
705     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
706     CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INTERNAL_ERROR, "Invalid remote device");
707 
708     auto gattDevice = pimpl->FindConnectedDevice(device);
709     if (gattDevice == nullptr) {
710         HILOGE("gattDevice is nullptr");
711         return BT_ERR_INTERNAL_ERROR;
712     }
713 
714     int appId = pimpl->applicationId_;
715     HILOGI("appId: %{public}d, device: %{public}s", appId, GET_ENCRYPT_ADDR(device));
716     return proxy->CancelConnection(appId, *gattDevice);
717 }
GetService(const UUID & uuid,bool isPrimary)718 std::optional<std::reference_wrapper<GattService>> GattServer::GetService(const UUID &uuid, bool isPrimary)
719 {
720     HILOGD("enter");
721     if (!IS_BLE_ENABLED()) {
722         HILOGE("bluetooth is off.");
723         return std::nullopt;
724     }
725     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
726     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::nullopt, "failed: no proxy");
727 
728     std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
729 
730     for (auto &svc : pimpl->gattServices_) {
731         if (svc.GetUuid().Equals(uuid) && svc.IsPrimary() == isPrimary) {
732             HILOGI("Find service, handle: 0x%{public}04X", svc.GetHandle());
733             return svc;
734         }
735     }
736 
737     return std::nullopt;
738 }
739 
GetServices()740 std::list<GattService> &GattServer::GetServices()
741 {
742     HILOGD("enter");
743     if (!IS_BLE_ENABLED()) {
744         HILOGE("bluetooth is off.");
745         return pimpl->gattServices_;
746     }
747     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
748     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, pimpl->gattServices_, "failed: no proxy");
749 
750     std::unique_lock<std::mutex> lock(pimpl->serviceListMutex_);
751     return pimpl->gattServices_;
752 }
NotifyCharacteristicChanged(const BluetoothRemoteDevice & device,const GattCharacteristic & characteristic,bool confirm)753 int GattServer::NotifyCharacteristicChanged(
754     const BluetoothRemoteDevice &device, const GattCharacteristic &characteristic, bool confirm)
755 {
756     HILOGI("remote device: %{public}s, handle: 0x%{public}04X, confirm: %{public}d",
757         GET_ENCRYPT_ADDR(device), characteristic.GetHandle(), confirm);
758     if (!IS_BLE_ENABLED()) {
759         HILOGE("bluetooth is off.");
760         return BT_ERR_INVALID_STATE;
761     }
762 
763     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
764     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
765 
766     if (!device.IsValidBluetoothRemoteDevice()) {
767         HILOGE("Invalid remote device");
768         return BT_ERR_INTERNAL_ERROR;
769     }
770     if (pimpl->FindConnectedDevice(device) == nullptr) {
771         HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
772         return BT_ERR_INTERNAL_ERROR;
773     }
774 
775     size_t length = 0;
776     auto &characterValue = characteristic.GetValue(&length);
777 
778     BluetoothGattCharacteristic character(
779         bluetooth::Characteristic(characteristic.GetHandle(), characterValue.get(), length));
780     std::string address = device.GetDeviceAddr();
781     int ret = proxy->NotifyClient(
782         bluetooth::GattDevice(bluetooth::RawAddress(address), 0), &character, confirm);
783     HILOGI("ret = %{public}d.", ret);
784     return ret;
785 }
786 
RemoveGattService(const GattService & service)787 int GattServer::RemoveGattService(const GattService &service)
788 {
789     HILOGD("enter");
790     if (!IS_BLE_ENABLED()) {
791         HILOGD("bluetooth is off.");
792         return BT_ERR_INVALID_STATE;
793     }
794 
795     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
796     CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
797 
798     int ret = BT_ERR_INVALID_PARAM;
799     for (auto sIt = pimpl->gattServices_.begin(); sIt != pimpl->gattServices_.end(); sIt++) {
800         if (sIt->GetUuid().Equals(service.GetUuid())) {
801             ret = proxy->RemoveService(
802                 pimpl->applicationId_, (BluetoothGattService)bluetooth::Service(sIt->GetHandle()));
803             pimpl->gattServices_.erase(sIt);
804             break;
805         }
806     }
807     HILOGI("result = %{public}d.", ret);
808     return ret;
809 }
SendResponse(const BluetoothRemoteDevice & device,int requestId,int status,int offset,const uint8_t * value,int length)810 int GattServer::SendResponse(
811     const BluetoothRemoteDevice &device, int requestId, int status, int offset, const uint8_t *value, int length)
812 {
813     HILOGI("remote device: %{public}s, status: %{public}d", GET_ENCRYPT_ADDR(device), status);
814     if (!IS_BLE_ENABLED()) {
815         HILOGE("bluetooth is off.");
816         return BT_ERR_INVALID_STATE;
817     }
818 
819     if (!device.IsValidBluetoothRemoteDevice()) {
820         HILOGE("pimpl or gatt server proxy is nullptr");
821         return BT_ERR_INTERNAL_ERROR;
822     }
823 
824     if (pimpl->FindConnectedDevice(device) == nullptr) {
825         HILOGE("No connection to device: %{public}s", GET_ENCRYPT_ADDR(device));
826         return BT_ERR_INTERNAL_ERROR;
827     }
828 
829     int result = BT_ERR_INTERNAL_ERROR;
830     uint8_t requestType = static_cast<uint32_t>(requestId) >> EIGHT_BITS;
831     uint8_t transport = static_cast<uint32_t>(requestId) & 0xFF;
832     if (transport != GATT_TRANSPORT_TYPE_CLASSIC && transport != GATT_TRANSPORT_TYPE_LE) {
833         return result;
834     }
835     bluetooth::GattDevice gattdevice(bluetooth::RawAddress(device.GetDeviceAddr()), transport);
836 
837     std::lock_guard<std::mutex> lock(pimpl->requestListMutex_);
838     auto request = pimpl->requests_.find(RequestInformation(requestType, gattdevice));
839     if (request != pimpl->requests_.end()) {
840         switch (requestType) {
841             case REQUEST_TYPE_CHARACTERISTICS_READ:
842                 result = pimpl->RespondCharacteristicRead(
843                     gattdevice, request->context_.characteristic_->GetHandle(), value, length, status);
844                 break;
845             case REQUEST_TYPE_CHARACTERISTICS_WRITE:
846                 result = pimpl->RespondCharacteristicWrite(
847                     gattdevice, request->context_.characteristic_->GetHandle(), status);
848                 break;
849             case REQUEST_TYPE_DESCRIPTOR_READ:
850                 result = pimpl->RespondDescriptorRead(
851                     gattdevice, request->context_.descriptor_->GetHandle(), value, length, status);
852                 break;
853             case REQUEST_TYPE_DESCRIPTOR_WRITE:
854                 result = pimpl->RespondDescriptorWrite(gattdevice, request->context_.descriptor_->GetHandle(), status);
855                 break;
856             default:
857                 HILOGE("Error request Id!");
858                 break;
859         }
860         if (result == BT_NO_ERROR) {
861             pimpl->requests_.erase(request);
862         }
863     }
864     HILOGD("result = %{public}d.", result);
865     return result;
866 }
867 
~GattServer()868 GattServer::~GattServer()
869 {
870     HILOGD("enter");
871     BluetoothProfileManager::GetInstance().DeregisterFunc(pimpl->profileRegisterId);
872     sptr<IBluetoothGattServer> proxy = GetRemoteProxy<IBluetoothGattServer>(PROFILE_GATT_SERVER);
873     CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
874     if (pimpl->isRegisterSucceeded_) {
875         proxy->DeregisterApplication(pimpl->applicationId_);
876     }
877     HILOGI("end");
878 }
879 }  // namespace Bluetooth
880 }  // namespace OHOS
881