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