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