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