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