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