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