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
20 #include "bluetooth_errorcode.h"
21 #include "bluetooth_def.h"
22 #include "bluetooth_gatt_client.h"
23 #include "bluetooth_gatt_client_proxy.h"
24 #include "bluetooth_gatt_client_callback_stub.h"
25 #include "bluetooth_host.h"
26 #include "bluetooth_host_proxy.h"
27 #include "bluetooth_log.h"
28 #include "bluetooth_utils.h"
29 #include "gatt_data.h"
30 #include "hilog/log.h"
31 #include "i_bluetooth_gatt_client.h"
32 #include "iservice_registry.h"
33 #include "raw_address.h"
34 #include "system_ability_definition.h"
35
36 namespace OHOS {
37 namespace Bluetooth {
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 constexpr uint8_t REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS = 0x04;
43 constexpr uint8_t REQUEST_TYPE_READ_REMOTE_RSSI_VALUE = 0x05;
44
45 constexpr const int WAIT_TIMEOUT = 3; // 3s
46 std::mutex g_gattClientProxyMutex;
47 struct DiscoverInfomation {
48 struct Characteristics {
49 bool isDiscoverDescCompleted_;
CharacteristicsOHOS::Bluetooth::DiscoverInfomation::Characteristics50 Characteristics() : isDiscoverDescCompleted_(false)
51 {}
52 };
53
54 struct Service {
55 bool isDiscoverCompleted_;
56 bool isDiscoverCharacteristicCompleted_;
57 bool isDiscoverIncludeSvcCompleted_;
58 uint16_t endHandle_;
59 std::map<uint16_t, Characteristics> characteristics_;
ServiceOHOS::Bluetooth::DiscoverInfomation::Service60 Service(uint16_t endHandle)
61 : isDiscoverCompleted_(false),
62 isDiscoverCharacteristicCompleted_(false),
63 isDiscoverIncludeSvcCompleted_(false),
64 endHandle_(endHandle)
65 {}
66 };
67 bool isDiscovering_;
68 bool needNotify_;
69 std::mutex mutex_;
70 std::condition_variable condition_;
71 std::map<uint16_t, Service> service_;
DiscoverInfomationOHOS::Bluetooth::DiscoverInfomation72 DiscoverInfomation() : isDiscovering_(false), needNotify_(false)
73 {}
74 };
75
76 struct RequestInformation {
77 bool doing_;
78 uint8_t type_;
79 union {
80 GattCharacteristic *characteristic_;
81 GattDescriptor *descriptor_;
82 } context_;
83 std::mutex mutex_;
RequestInformationOHOS::Bluetooth::RequestInformation84 RequestInformation() : doing_(false)
85 {}
86 };
87
88 struct GattClient::impl {
89 class BluetoothGattClientCallbackStubImpl;
90
91 bool isGetServiceYet_;
92 bool isRegisterSucceeded_;
93 GattClientCallback *callback_;
94 int applicationId_;
95 int connectionState_;
96 BluetoothRemoteDevice device_;
97 sptr<IBluetoothGattClient> proxy_;
98 sptr<BluetoothGattClientCallbackStubImpl> clientCallback_;
99 std::vector<GattService> gattServices_;
100 std::mutex connStateMutex_;
101 RequestInformation requestInformation_;
102 DiscoverInfomation discoverInformation_;
103
104 explicit impl(const BluetoothRemoteDevice &device);
105 ~impl();
106
107 bool Init(std::weak_ptr<GattClient> client);
108
109 int DiscoverStart();
110 void DiscoverComplete(int state);
111 void BuildServiceList(const std::vector<BluetoothGattService> &src);
112 GattService *FindService(uint16_t handle);
113 void GetServices();
114 void CleanConnectionInfo();
115
116 class GattClientDeathRecipient;
117 sptr<GattClientDeathRecipient> deathRecipient_;
118 };
119
120 class GattClient::impl::GattClientDeathRecipient final : public IRemoteObject::DeathRecipient {
121 public:
GattClientDeathRecipient(std::weak_ptr<GattClient> client)122 explicit GattClientDeathRecipient(std::weak_ptr<GattClient> client) : client_(client){};
123 ~GattClientDeathRecipient() final = default;
124 BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(GattClientDeathRecipient);
125
OnRemoteDied(const wptr<IRemoteObject> & remote)126 void OnRemoteDied(const wptr<IRemoteObject> &remote) final
127 {
128 HILOGI("enter");
129 std::lock_guard<std::mutex> lock(g_gattClientProxyMutex);
130 std::shared_ptr<GattClient> clientSptr = (client_).lock();
131 if (!clientSptr || !clientSptr->pimpl || !clientSptr->pimpl->proxy_) {
132 HILOGE("callback client is nullptr");
133 return;
134 }
135 clientSptr->pimpl->proxy_ = nullptr;
136 }
137
138 private:
139 std::weak_ptr<GattClient> client_;
140 };
141
142 class GattClient::impl::BluetoothGattClientCallbackStubImpl : public BluetoothGattClientCallbackStub {
143 public:
OnServicesChanged(std::vector<BluetoothGattService> & service)144 void OnServicesChanged(std::vector<BluetoothGattService> &service) override
145 {
146 HILOGI("enter");
147 std::shared_ptr<GattClient> clientSptr = (client_).lock();
148 if (!clientSptr) {
149 HILOGE("callback client is nullptr");
150 return;
151 }
152 clientSptr->pimpl->DiscoverStart();
153 }
154
OnConnectionStateChanged(int32_t state,int32_t newState)155 void OnConnectionStateChanged(int32_t state, int32_t newState) override
156 {
157 HILOGD("gattClient conn state, status: %{public}d, newState: %{public}s",
158 state, GetProfileConnStateName(newState).c_str());
159 std::shared_ptr<GattClient> clientSptr = (client_).lock();
160 if (!clientSptr) {
161 HILOGE("callback client is nullptr");
162 return;
163 }
164 if (newState == static_cast<int>(BTConnectState::DISCONNECTED)) {
165 clientSptr->pimpl->CleanConnectionInfo();
166 }
167
168 {
169 std::lock_guard<std::mutex> lck(clientSptr->pimpl->connStateMutex_);
170 clientSptr->pimpl->connectionState_ = newState;
171 }
172
173 clientSptr->pimpl->callback_->OnConnectionStateChanged(newState, state);
174 }
175
OnCharacteristicChanged(const BluetoothGattCharacteristic & characteristic)176 void OnCharacteristicChanged(const BluetoothGattCharacteristic &characteristic) override
177 {
178 HILOGD("recv notification, length:%{public}zu", characteristic.length_);
179 std::shared_ptr<GattClient> clientSptr = (client_).lock();
180 if (!clientSptr) {
181 HILOGE("callback client is nullptr");
182 return;
183 }
184 for (auto &svc : clientSptr->pimpl->gattServices_) {
185 for (auto &character : svc.GetCharacteristics()) {
186 if (character.GetHandle() == characteristic.handle_) {
187 character.SetValue(characteristic.value_.get(), characteristic.length_);
188 clientSptr->pimpl->callback_->OnCharacteristicChanged(character);
189 return;
190 }
191 }
192 }
193 HILOGE("recv notification failed, characteristic is not exist.");
194 }
195
OnCharacteristicRead(int32_t ret,const BluetoothGattCharacteristic & characteristic)196 void OnCharacteristicRead(int32_t ret, const BluetoothGattCharacteristic &characteristic) override
197 {
198 HILOGI("ret:%{public}d, length:%{public}zu", ret, characteristic.length_);
199 std::shared_ptr<GattClient> clientSptr = (client_).lock();
200 if (!clientSptr) {
201 HILOGE("callback client is nullptr");
202 return;
203 }
204 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
205 clientSptr->pimpl->requestInformation_.doing_ = false;
206 auto ptr = clientSptr->pimpl->requestInformation_.context_.characteristic_;
207 if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_CHARACTERISTICS_READ) {
208 HILOGE("Unexpected call!");
209 }
210 if (ret == GattStatus::GATT_SUCCESS) {
211 ptr->SetValue(characteristic.value_.get(), characteristic.length_);
212 }
213 clientSptr->pimpl->callback_->OnCharacteristicReadResult(*ptr, ret);
214 }
215
OnCharacteristicWrite(int32_t ret,const BluetoothGattCharacteristic & characteristic)216 void OnCharacteristicWrite(int32_t ret, const BluetoothGattCharacteristic &characteristic) override
217 {
218 HILOGI("ret:%{public}d, length:%{public}zu", ret, characteristic.length_);
219 std::shared_ptr<GattClient> clientSptr = (client_).lock();
220 if (!clientSptr) {
221 HILOGE("callback client is nullptr");
222 return;
223 }
224 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
225 clientSptr->pimpl->requestInformation_.doing_ = false;
226 auto ptr = clientSptr->pimpl->requestInformation_.context_.characteristic_;
227 if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_CHARACTERISTICS_WRITE) {
228 HILOGE("Unexpected call!");
229 }
230 clientSptr->pimpl->callback_->OnCharacteristicWriteResult(*ptr, ret);
231 }
232
OnDescriptorRead(int32_t ret,const BluetoothGattDescriptor & descriptor)233 void OnDescriptorRead(int32_t ret, const BluetoothGattDescriptor &descriptor) override
234 {
235 HILOGI("ret:%{public}d, length:%{public}zu", ret, descriptor.length_);
236 std::shared_ptr<GattClient> clientSptr = (client_).lock();
237 if (!clientSptr) {
238 HILOGE("callback client is nullptr");
239 return;
240 }
241 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
242 clientSptr->pimpl->requestInformation_.doing_ = false;
243 auto ptr = clientSptr->pimpl->requestInformation_.context_.descriptor_;
244 if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_DESCRIPTOR_READ) {
245 HILOGE("Unexpected call!");
246 }
247 if (ret == GattStatus::GATT_SUCCESS) {
248 ptr->SetValue(descriptor.value_.get(), descriptor.length_);
249 }
250 clientSptr->pimpl->callback_->OnDescriptorReadResult(*ptr, ret);
251 }
252
OnDescriptorWrite(int32_t ret,const BluetoothGattDescriptor & descriptor)253 void OnDescriptorWrite(int32_t ret, const BluetoothGattDescriptor &descriptor) override
254 {
255 HILOGI("ret:%{public}d, length:%{public}zu", ret, descriptor.length_);
256 std::shared_ptr<GattClient> clientSptr = (client_).lock();
257 if (!clientSptr) {
258 HILOGE("callback client is nullptr");
259 return;
260 }
261 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
262 clientSptr->pimpl->requestInformation_.doing_ = false;
263 auto ptr = clientSptr->pimpl->requestInformation_.context_.descriptor_;
264 if (clientSptr->pimpl->requestInformation_.type_ == REQUEST_TYPE_DESCRIPTOR_WRITE) {
265 clientSptr->pimpl->callback_->OnDescriptorWriteResult(*ptr, ret);
266 } else if (clientSptr->pimpl->requestInformation_.type_ == REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS) {
267 auto characterPtr = clientSptr->pimpl->requestInformation_.context_.characteristic_;
268 clientSptr->pimpl->callback_->OnSetNotifyCharacteristic(*characterPtr, ret);
269 } else {
270 HILOGE("Unexpected call!");
271 }
272 }
273
OnMtuChanged(int32_t state,int32_t mtu)274 void OnMtuChanged(int32_t state, int32_t mtu) override
275 {
276 HILOGI("state: %{public}d, mtu: %{public}d", state, mtu);
277 std::shared_ptr<GattClient> clientSptr = (client_).lock();
278 if (!clientSptr) {
279 HILOGE("callback client is nullptr");
280 return;
281 }
282 clientSptr->pimpl->callback_->OnMtuUpdate(mtu, state);
283 }
284
OnServicesDiscovered(int32_t status)285 void OnServicesDiscovered(int32_t status) override
286 {
287 HILOGI("status: %{public}d", status);
288 std::shared_ptr<GattClient> clientSptr = (client_).lock();
289 if (!clientSptr) {
290 HILOGE("callback client is nullptr");
291 return;
292 }
293 clientSptr->pimpl->DiscoverComplete(status);
294 }
295
OnConnectionParameterChanged(int32_t interval,int32_t latency,int32_t timeout,int32_t status)296 void OnConnectionParameterChanged(int32_t interval, int32_t latency, int32_t timeout, int32_t status) override
297 {
298 HILOGI("interval: %{public}d, latency: %{public}d, timeout: %{public}d, status: %{public}d",
299 interval, latency, timeout, status);
300 std::shared_ptr<GattClient> clientSptr = (client_).lock();
301 if (!clientSptr) {
302 HILOGE("callback client is nullptr");
303 return;
304 }
305 clientSptr->pimpl->callback_->OnConnectionParameterChanged(interval, latency, timeout, status);
306 }
307
OnReadRemoteRssiValue(const bluetooth::RawAddress & addr,int32_t rssi,int32_t status)308 void OnReadRemoteRssiValue(const bluetooth::RawAddress &addr, int32_t rssi, int32_t status) override
309 {
310 HILOGI("rssi: %{public}d, status: %{public}d", rssi, status);
311 std::shared_ptr<GattClient> clientSptr = (client_).lock();
312 if (!clientSptr) {
313 HILOGE("callback client is nullptr");
314 return;
315 }
316 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
317 clientSptr->pimpl->requestInformation_.doing_ = false;
318 if (clientSptr->pimpl->requestInformation_.type_ != REQUEST_TYPE_READ_REMOTE_RSSI_VALUE) {
319 HILOGE("Unexpected call!");
320 }
321 clientSptr->pimpl->callback_->OnReadRemoteRssiValueResult(rssi, status);
322 }
323
BluetoothGattClientCallbackStubImpl(std::weak_ptr<GattClient> client)324 explicit BluetoothGattClientCallbackStubImpl(std::weak_ptr<GattClient> client) : client_(client)
325 {}
~BluetoothGattClientCallbackStubImpl()326 ~BluetoothGattClientCallbackStubImpl() override
327 {}
328
329 private:
330 std::weak_ptr<GattClient> client_;
331 };
332
Init(std::weak_ptr<GattClient> client)333 bool GattClient::impl::Init(std::weak_ptr<GattClient> client)
334 {
335 std::lock_guard<std::mutex> lock(g_gattClientProxyMutex);
336 if (proxy_) {
337 return true;
338 }
339 HILOGE("enter!");
340 proxy_ = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
341 if (!proxy_) {
342 HILOGE("get gattClient proxy failed");
343 return false;
344 }
345 clientCallback_ = new BluetoothGattClientCallbackStubImpl(client);
346 deathRecipient_ = new GattClientDeathRecipient(client);
347 proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
348 return true;
349 }
350
impl(const BluetoothRemoteDevice & device)351 GattClient::impl::impl(const BluetoothRemoteDevice &device)
352 : isGetServiceYet_(false),
353 isRegisterSucceeded_(false),
354 callback_(nullptr),
355 applicationId_(0),
356 connectionState_(static_cast<int>(BTConnectState::DISCONNECTED)),
357 device_(device)
358 {
359 }
360
~impl()361 GattClient::impl::~impl()
362 {
363 HILOGI("GattClient ~impl");
364 if (!proxy_) {
365 HILOGE("proxy_ is null");
366 } else {
367 proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
368 }
369 }
370
DiscoverStart()371 int GattClient::impl::DiscoverStart()
372 {
373 if (!IS_BLE_ENABLED()) {
374 HILOGE("bluetooth is off.");
375 return BT_ERR_INVALID_STATE;
376 }
377
378 {
379 std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
380 while (discoverInformation_.isDiscovering_) {
381 auto ret = discoverInformation_.condition_.wait_for(lock, std::chrono::seconds(WAIT_TIMEOUT));
382 if (ret == std::cv_status::timeout) {
383 HILOGE("timeout");
384 return BT_ERR_INTERNAL_ERROR;
385 }
386 }
387 discoverInformation_.isDiscovering_ = true;
388 }
389
390 if (!isRegisterSucceeded_) {
391 return BT_ERR_INTERNAL_ERROR;
392 }
393 int result = BT_ERR_INTERNAL_ERROR;
394 if (!proxy_) {
395 HILOGE("proxy_ is null");
396 } else {
397 result = proxy_->DiscoveryServices(applicationId_);
398 if (result != BT_NO_ERROR) {
399 DiscoverComplete(BT_ERR_INTERNAL_ERROR);
400 }
401 }
402 return result;
403 }
404
DiscoverComplete(int state)405 void GattClient::impl::DiscoverComplete(int state)
406 {
407 bool ret = false;
408 {
409 std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
410 if (discoverInformation_.isDiscovering_) {
411 discoverInformation_.isDiscovering_ = false;
412 isGetServiceYet_ = false;
413 discoverInformation_.condition_.notify_all();
414 ret = true;
415 }
416 }
417 if (ret) {
418 callback_->OnServicesDiscovered(state);
419 }
420 }
421
BuildServiceList(const std::vector<BluetoothGattService> & src)422 void GattClient::impl::BuildServiceList(const std::vector<BluetoothGattService> &src)
423 {
424 HILOGI("enter");
425 for (auto &svc : src) {
426 GattService svcTmp(UUID::ConvertFrom128Bits(svc.uuid_.ConvertTo128Bits()),
427 svc.handle_,
428 svc.endHandle_,
429 svc.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
430 for (auto &character : svc.characteristics_) {
431 GattCharacteristic characterTmp(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()),
432 character.handle_,
433 character.permissions_,
434 character.properties_);
435 for (auto &desc : character.descriptors_) {
436 characterTmp.AddDescriptor(GattDescriptor(
437 UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_));
438 }
439 svcTmp.AddCharacteristic(std::move(characterTmp));
440 }
441 gattServices_.emplace_back(std::move(svcTmp));
442 }
443 for (auto &svc : src) {
444 GattService *ptr = FindService(svc.handle_);
445 if (ptr == NULL) {
446 return;
447 }
448 for (auto &isvc : svc.includeServices_) {
449 GattService *iptr = FindService(isvc.startHandle_);
450 ptr->AddService(*iptr);
451 }
452 }
453 }
454
FindService(uint16_t handle)455 GattService *GattClient::impl::FindService(uint16_t handle)
456 {
457 for (auto &item : gattServices_) {
458 if (item.GetHandle() == handle) {
459 return &item;
460 }
461 }
462 return nullptr;
463 }
464
GetServices()465 void GattClient::impl::GetServices()
466 {
467 HILOGD("enter");
468 if (!IS_BLE_ENABLED()) {
469 HILOGE("bluetooth is off.");
470 return;
471 }
472
473 std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
474 while (discoverInformation_.isDiscovering_) {
475 auto ret = discoverInformation_.condition_.wait_for(lock, std::chrono::seconds(WAIT_TIMEOUT));
476 if (ret == std::cv_status::timeout) {
477 HILOGE("timeout");
478 return;
479 }
480 }
481 if (isGetServiceYet_) {
482 HILOGE("isGetServiceYet_ is true");
483 return;
484 }
485 if (!isRegisterSucceeded_) {
486 HILOGE("isRegisterSucceeded_ is false");
487 return;
488 }
489 gattServices_.clear();
490 std::vector<BluetoothGattService> result;
491 if (!proxy_) {
492 HILOGE("proxy_ is null");
493 } else {
494 proxy_->GetServices(applicationId_, result);
495 BuildServiceList(result);
496 isGetServiceYet_ = true;
497 }
498 }
499
CleanConnectionInfo()500 void GattClient::impl::CleanConnectionInfo()
501 {
502 DiscoverComplete(GattStatus::GATT_FAILURE);
503 std::lock_guard<std::mutex> lock(requestInformation_.mutex_);
504 requestInformation_.doing_ = false;
505 }
506
GattClient(const BluetoothRemoteDevice & device)507 GattClient::GattClient(const BluetoothRemoteDevice &device) : pimpl(new GattClient::impl(device))
508 {
509 HILOGI("enter");
510 }
511
Init()512 bool GattClient::Init()
513 {
514 HILOGI("GattClient Init");
515 return pimpl->Init(weak_from_this());
516 }
517
~GattClient()518 GattClient::~GattClient()
519 {
520 HILOGI("~GattClient");
521 if (pimpl->isRegisterSucceeded_) {
522 if (!pimpl->proxy_) {
523 HILOGE("proxy_ is null");
524 } else {
525 pimpl->proxy_->DeregisterApplication(pimpl->applicationId_);
526 }
527 }
528 }
529
Connect(GattClientCallback & callback,bool isAutoConnect,int transport)530 int GattClient::Connect(GattClientCallback &callback, bool isAutoConnect, int transport)
531 {
532 HILOGI("enter, isAutoConnect: %{public}d, transport: %{public}d", isAutoConnect, transport);
533 if (!IS_BLE_ENABLED()) {
534 HILOGE("bluetooth is off.");
535 return BT_ERR_INVALID_STATE;
536 }
537
538 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
539 HILOGE("pimpl or gatt client proxy is nullptr");
540 return BT_ERR_INTERNAL_ERROR;
541 }
542
543 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
544 if (pimpl->connectionState_ == static_cast<int>(BTConnectState::CONNECTED)) {
545 HILOGE("Already connected");
546 return BT_ERR_INTERNAL_ERROR;
547 }
548 HILOGI("isRegisterSucceeded: %{public}d", pimpl->isRegisterSucceeded_);
549 if (pimpl->isRegisterSucceeded_) {
550 return pimpl->proxy_->Connect(pimpl->applicationId_, isAutoConnect);
551 }
552 pimpl->callback_ = &callback;
553 if ((transport == GATT_TRANSPORT_TYPE_LE && !IS_BLE_ENABLED()) ||
554 (transport == GATT_TRANSPORT_TYPE_CLASSIC && !IS_BT_ENABLED())) {
555 HILOGE("Unsupported mode");
556 return BT_ERR_INTERNAL_ERROR;
557 }
558 if (transport == GATT_TRANSPORT_TYPE_CLASSIC && isAutoConnect) {
559 HILOGE("Unsupported mode");
560 return BT_ERR_INTERNAL_ERROR;
561 }
562 if (!pimpl->device_.IsValidBluetoothRemoteDevice()) {
563 HILOGE("Invalid remote device");
564 return BT_ERR_INTERNAL_ERROR;
565 }
566
567 int appId = 0;
568 int32_t result = pimpl->proxy_->RegisterApplication(
569 pimpl->clientCallback_, bluetooth::RawAddress(pimpl->device_.GetDeviceAddr()), transport, appId);
570 HILOGI("Proxy register application : %{public}d", appId);
571 if (result != BT_NO_ERROR) {
572 HILOGE("register application fail");
573 return result;
574 }
575 if (appId > 0) {
576 pimpl->applicationId_ = appId;
577 pimpl->isRegisterSucceeded_ = true;
578 result = pimpl->proxy_->Connect(pimpl->applicationId_, isAutoConnect);
579 }
580 return result;
581 }
582
Disconnect()583 int GattClient::Disconnect()
584 {
585 HILOGI("enter");
586 if (!IS_BLE_ENABLED()) {
587 HILOGE("bluetooth is off.");
588 return BT_ERR_INVALID_STATE;
589 }
590
591 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
592 HILOGE("pimpl or gatt client proxy is nullptr");
593 return BT_ERR_INTERNAL_ERROR;
594 }
595
596 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
597 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
598 HILOGE("Request not supported");
599 return BT_ERR_INTERNAL_ERROR;
600 }
601 int result = BT_ERR_INTERNAL_ERROR;
602 result = pimpl->proxy_->Disconnect(pimpl->applicationId_);
603 return result;
604 }
605
Close()606 int GattClient::Close()
607 {
608 HILOGI("enter");
609 if (!IS_BLE_ENABLED()) {
610 HILOGE("bluetooth is off.");
611 return BT_ERR_INVALID_STATE;
612 }
613
614 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
615 HILOGE("pimpl or gatt client proxy is nullptr");
616 return BT_ERR_INTERNAL_ERROR;
617 }
618
619 if (pimpl->isRegisterSucceeded_) {
620 int32_t result = pimpl->proxy_->DeregisterApplication(pimpl->applicationId_);
621 HILOGI("result: %{public}d", result);
622 if (result == BT_NO_ERROR) {
623 pimpl->isRegisterSucceeded_ = false;
624 }
625 return result;
626 }
627 HILOGI("isRegisterSucceeded_ is false");
628 return BT_NO_ERROR;
629 }
630
DiscoverServices()631 int GattClient::DiscoverServices()
632 {
633 HILOGI("enter");
634 if (!IS_BLE_ENABLED()) {
635 HILOGE("bluetooth is off.");
636 return BT_ERR_INVALID_STATE;
637 }
638
639 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
640 HILOGE("pimpl or gatt client proxy is nullptr");
641 return BT_ERR_INTERNAL_ERROR;
642 }
643
644 std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
645 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
646 HILOGE("Request not supported");
647 return BT_ERR_INTERNAL_ERROR;
648 }
649 return pimpl->DiscoverStart();
650 }
651
GetService(const UUID & uuid)652 std::optional<std::reference_wrapper<GattService>> GattClient::GetService(const UUID &uuid)
653 {
654 HILOGD("enter");
655 if (!IS_BLE_ENABLED()) {
656 HILOGE("bluetooth is off.");
657 return std::nullopt;
658 }
659
660 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
661 HILOGE("pimpl or gatt client proxy is nullptr");
662 return std::nullopt;
663 }
664
665 pimpl->GetServices();
666 for (auto &svc : pimpl->gattServices_) {
667 if (svc.GetUuid().Equals(uuid)) {
668 HILOGD("successful");
669 return svc;
670 }
671 }
672 HILOGE("failed");
673 return std::nullopt;
674 }
675
GetService()676 std::vector<GattService> &GattClient::GetService()
677 {
678 HILOGI("enter");
679 if (!IS_BLE_ENABLED()) {
680 HILOGE("bluetooth is off.");
681 return pimpl->gattServices_;
682 }
683
684 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
685 HILOGE("pimpl or gatt client proxy is nullptr");
686 return pimpl->gattServices_;
687 }
688
689 pimpl->GetServices();
690 return pimpl->gattServices_;
691 }
692
ReadCharacteristic(GattCharacteristic & characteristic)693 int GattClient::ReadCharacteristic(GattCharacteristic &characteristic)
694 {
695 HILOGI("enter");
696 if (!IS_BLE_ENABLED()) {
697 HILOGE("bluetooth is off.");
698 return BT_ERR_INVALID_STATE;
699 }
700
701 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
702 HILOGE("pimpl or gatt client proxy is nullptr");
703 return BT_ERR_INTERNAL_ERROR;
704 }
705
706 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
707 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
708 HILOGE("Request not supported");
709 return BT_ERR_INTERNAL_ERROR;
710 }
711 std::lock_guard<std::mutex> lck(pimpl->requestInformation_.mutex_);
712 if (pimpl->requestInformation_.doing_) {
713 HILOGE("Remote device busy");
714 return BT_ERR_INTERNAL_ERROR;
715 }
716 int result = GattStatus::GATT_FAILURE;
717 HILOGI("applicationId: %{public}d, handle: 0x%{public}04X", pimpl->applicationId_, characteristic.GetHandle());
718 result = pimpl->proxy_->ReadCharacteristic(
719 pimpl->applicationId_, (BluetoothGattCharacteristic)bluetooth::Characteristic(characteristic.GetHandle()));
720 HILOGI("result: %{public}d", result);
721 if (result == BT_NO_ERROR) {
722 pimpl->requestInformation_.doing_ = true;
723 pimpl->requestInformation_.type_ = REQUEST_TYPE_CHARACTERISTICS_READ;
724 pimpl->requestInformation_.context_.characteristic_ = &characteristic;
725 }
726 return result;
727 }
728
ReadDescriptor(GattDescriptor & descriptor)729 int GattClient::ReadDescriptor(GattDescriptor &descriptor)
730 {
731 HILOGI("enter");
732 if (!IS_BLE_ENABLED()) {
733 HILOGE("bluetooth is off.");
734 return BT_ERR_INVALID_STATE;
735 }
736
737 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
738 HILOGE("pimpl or gatt client proxy is nullptr");
739 return BT_ERR_INTERNAL_ERROR;
740 }
741
742 std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
743 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
744 HILOGE("Request not supported");
745 return BT_ERR_INTERNAL_ERROR;
746 }
747 std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
748 if (pimpl->requestInformation_.doing_) {
749 HILOGE("Remote device busy");
750 return BT_ERR_INTERNAL_ERROR;
751 }
752 int result = BT_ERR_INTERNAL_ERROR;
753 HILOGI("applicationId: %{public}d, handle: 0x%{public}04X", pimpl->applicationId_, descriptor.GetHandle());
754 result = pimpl->proxy_->ReadDescriptor(
755 pimpl->applicationId_, (BluetoothGattDescriptor)bluetooth::Descriptor(descriptor.GetHandle()));
756 HILOGI("result: %{public}d", result);
757 if (result == BT_NO_ERROR) {
758 pimpl->requestInformation_.doing_ = true;
759 pimpl->requestInformation_.type_ = REQUEST_TYPE_DESCRIPTOR_READ;
760 pimpl->requestInformation_.context_.descriptor_ = &descriptor;
761 }
762 return result;
763 }
764
RequestBleMtuSize(int mtu)765 int GattClient::RequestBleMtuSize(int mtu)
766 {
767 HILOGD("enter");
768 if (!IS_BLE_ENABLED()) {
769 HILOGE("bluetooth is off.");
770 return BT_ERR_INVALID_STATE;
771 }
772
773 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
774 HILOGE("pimpl or gatt client proxy is nullptr");
775 return BT_ERR_INTERNAL_ERROR;
776 }
777
778 std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
779 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
780 HILOGE("Request not supported");
781 return BT_ERR_INTERNAL_ERROR;
782 }
783 int result = BT_ERR_INTERNAL_ERROR;
784 HILOGI("applicationId: %{public}d, mtu: %{public}d", pimpl->applicationId_, mtu);
785 result = pimpl->proxy_->RequestExchangeMtu(pimpl->applicationId_, mtu);
786 HILOGI("result: %{public}d", result);
787 return result;
788 }
789
SetNotifyCharacteristicInner(GattCharacteristic & characteristic,bool enable,const std::vector<uint8_t> & descriptorValue)790 int GattClient::SetNotifyCharacteristicInner(GattCharacteristic &characteristic, bool enable,
791 const std::vector<uint8_t> &descriptorValue)
792 {
793 if (!IS_BLE_ENABLED()) {
794 HILOGE("bluetooth is off.");
795 return BT_ERR_INVALID_STATE;
796 }
797
798 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
799 HILOGE("pimpl or gatt client proxy is nullptr");
800 return BT_ERR_INTERNAL_ERROR;
801 }
802
803 std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_);
804 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
805 HILOGE("Request not supported");
806 return BT_ERR_INTERNAL_ERROR;
807 }
808 std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
809 if (pimpl->requestInformation_.doing_) {
810 HILOGI("Remote device busy");
811 return BT_ERR_INTERNAL_ERROR;
812 }
813 int ret = pimpl->proxy_->RequestNotification(pimpl->applicationId_, characteristic.GetHandle(), enable);
814 if (ret != BT_NO_ERROR) {
815 return ret;
816 }
817 auto descriptor = characteristic.GetDescriptor(UUID::FromString("00002902-0000-1000-8000-00805F9B34FB"));
818 if (descriptor == nullptr) {
819 HILOGE("descriptor not exist.");
820 return ret;
821 }
822 BluetoothGattDescriptor desc(bluetooth::Descriptor(
823 descriptor->GetHandle(), descriptorValue.data(), descriptorValue.size()));
824 int result = GattStatus::GATT_FAILURE;
825 HILOGD("applicationId: %{public}d", pimpl->applicationId_);
826 result = pimpl->proxy_->WriteDescriptor(pimpl->applicationId_, &desc);
827 HILOGI("result: %{public}d", result);
828 if (result == BT_NO_ERROR) {
829 pimpl->requestInformation_.type_ = REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS;
830 pimpl->requestInformation_.context_.characteristic_ = &characteristic;
831 pimpl->requestInformation_.doing_ = true;
832 }
833 return result;
834 }
835
SetNotifyCharacteristic(GattCharacteristic & characteristic,bool enable)836 int GattClient::SetNotifyCharacteristic(GattCharacteristic &characteristic, bool enable)
837 {
838 HILOGI("handle: 0x%{public}04X, enable: %{public}d", characteristic.GetHandle(), enable);
839 std::vector<uint8_t> enableNotifyValue = {1, 0};
840 std::vector<uint8_t> disableValue = {0, 0};
841 return SetNotifyCharacteristicInner(characteristic, enable, (enable ? enableNotifyValue : disableValue));
842 }
843
SetIndicateCharacteristic(GattCharacteristic & characteristic,bool enable)844 int GattClient::SetIndicateCharacteristic(GattCharacteristic &characteristic, bool enable)
845 {
846 HILOGI("handle: 0x%{public}04X, enable: %{public}d", characteristic.GetHandle(), enable);
847 std::vector<uint8_t> enableIndicateValue = {2, 0};
848 std::vector<uint8_t> disableValue = {0, 0};
849 return SetNotifyCharacteristicInner(characteristic, enable, (enable ? enableIndicateValue : disableValue));
850 }
851
WriteCharacteristic(GattCharacteristic & characteristic)852 int GattClient::WriteCharacteristic(GattCharacteristic &characteristic)
853 {
854 size_t length = 0;
855 const uint8_t *pData = characteristic.GetValue(&length).get();
856 std::vector<uint8_t> value(pData, pData + length);
857 return WriteCharacteristic(characteristic, std::move(value));
858 }
859
WriteCharacteristic(GattCharacteristic & characteristic,std::vector<uint8_t> value)860 int GattClient::WriteCharacteristic(GattCharacteristic &characteristic, std::vector<uint8_t> value)
861 {
862 HILOGD("enter");
863 if (!IS_BLE_ENABLED()) {
864 HILOGE("bluetooth is off.");
865 return BT_ERR_INVALID_STATE;
866 }
867
868 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
869 HILOGE("pimpl or gatt client proxy is nullptr");
870 return BT_ERR_INTERNAL_ERROR;
871 }
872
873 std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_);
874 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
875 HILOGE("Request not supported");
876 return BT_ERR_INTERNAL_ERROR;
877 }
878 size_t length = value.size();
879 HILOGD("length:%{public}zu", length);
880 if (length == 0) {
881 HILOGE("Invalid parameters");
882 return BT_ERR_INTERNAL_ERROR;
883 }
884 std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
885 if (pimpl->requestInformation_.doing_) {
886 HILOGE("Remote device busy");
887 return BT_ERR_INTERNAL_ERROR;
888 }
889 BluetoothGattCharacteristic character(
890 bluetooth::Characteristic(characteristic.GetHandle(), value.data(), length));
891 int result = BT_ERR_INTERNAL_ERROR;
892 bool withoutRespond = true;
893 if (characteristic.GetWriteType() == static_cast<int>(GattCharacteristic::WriteType::SIGNED)) {
894 HILOGI("Signed write");
895 result = pimpl->proxy_->SignedWriteCharacteristic(pimpl->applicationId_, &character);
896 } else {
897 withoutRespond = ((characteristic.GetWriteType() ==
898 static_cast<int>(GattCharacteristic::WriteType::DEFAULT)) ? false : true);
899 HILOGD("Write without response");
900 result = pimpl->proxy_->WriteCharacteristic(pimpl->applicationId_, &character, withoutRespond);
901 }
902 if (result == GattStatus::GATT_SUCCESS && !withoutRespond) {
903 HILOGI("successful");
904 pimpl->requestInformation_.type_ = REQUEST_TYPE_CHARACTERISTICS_WRITE;
905 pimpl->requestInformation_.context_.characteristic_ = &characteristic;
906 pimpl->requestInformation_.doing_ = true;
907 } else {
908 HILOGD("result: %{public}d", result);
909 }
910 return result;
911 }
912
WriteDescriptor(GattDescriptor & descriptor)913 int GattClient::WriteDescriptor(GattDescriptor &descriptor)
914 {
915 HILOGI("enter");
916 if (!IS_BLE_ENABLED()) {
917 HILOGE("bluetooth is off.");
918 return BT_ERR_INVALID_STATE;
919 }
920
921 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
922 HILOGE("pimpl or gatt client proxy is nullptr");
923 return BT_ERR_INTERNAL_ERROR;
924 }
925
926 std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
927 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
928 HILOGE("Request not supported");
929 return BT_ERR_INTERNAL_ERROR;
930 }
931 size_t length = 0;
932 auto &characterValue = descriptor.GetValue(&length);
933 if (characterValue == nullptr || length == 0) {
934 HILOGE("Invalid parameters");
935 return BT_ERR_INTERNAL_ERROR;
936 }
937 std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
938 if (pimpl->requestInformation_.doing_) {
939 HILOGE("Remote device busy");
940 return BT_ERR_INTERNAL_ERROR;
941 }
942 int result = BT_ERR_INTERNAL_ERROR;
943 BluetoothGattDescriptor desc(bluetooth::Descriptor(descriptor.GetHandle(), characterValue.get(), length));
944 result = pimpl->proxy_->WriteDescriptor(pimpl->applicationId_, &desc);
945 HILOGI("result: %{public}d", result);
946 if (result == BT_NO_ERROR) {
947 pimpl->requestInformation_.doing_ = true;
948 pimpl->requestInformation_.type_ = REQUEST_TYPE_DESCRIPTOR_WRITE;
949 pimpl->requestInformation_.context_.descriptor_ = &descriptor;
950 }
951 return result;
952 }
953
RequestConnectionPriority(int connPriority)954 int GattClient::RequestConnectionPriority(int connPriority)
955 {
956 if (!IS_BLE_ENABLED()) {
957 HILOGE("bluetooth is off.");
958 return BT_ERR_INVALID_STATE;
959 }
960
961 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
962 HILOGE("pimpl or gatt client proxy is nullptr");
963 return BT_ERR_INTERNAL_ERROR;
964 }
965
966 std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_);
967 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
968 HILOGE("Not connected");
969 return GattStatus::REQUEST_NOT_SUPPORT;
970 }
971 if (connPriority != static_cast<int>(GattConnectionPriority::BALANCED) &&
972 connPriority != static_cast<int>(GattConnectionPriority::HIGH) &&
973 connPriority != static_cast<int>(GattConnectionPriority::LOW_POWER)) {
974 HILOGE("Invalid parameters");
975 return GattStatus::INVALID_PARAMETER;
976 }
977 int result = GattStatus::GATT_FAILURE;
978 result = pimpl->proxy_->RequestConnectionPriority(pimpl->applicationId_, connPriority);
979 HILOGI("result: %{public}d", result);
980 return result;
981 }
982
RequestFastestConn()983 int GattClient::RequestFastestConn()
984 {
985 HILOGI("enter");
986 if (!IS_BLE_ENABLED()) {
987 HILOGE("bluetooth is off.");
988 return BT_ERR_INVALID_STATE;
989 }
990
991 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
992 HILOGE("pimpl or gatt client proxy is nullptr");
993 return BT_ERR_INTERNAL_ERROR;
994 }
995
996 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
997 return pimpl->proxy_->RequestFastestConn(bluetooth::RawAddress(pimpl->device_.GetDeviceAddr()));
998 }
ReadRemoteRssiValue()999 int GattClient::ReadRemoteRssiValue()
1000 {
1001 HILOGI("enter");
1002 if (!IS_BLE_ENABLED()) {
1003 HILOGE("bluetooth is off.");
1004 return BT_ERR_INVALID_STATE;
1005 }
1006
1007 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
1008 HILOGE("pimpl or gatt client proxy is nullptr");
1009 return BT_ERR_INTERNAL_ERROR;
1010 }
1011
1012 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
1013 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
1014 HILOGE("Request not supported");
1015 return BT_ERR_INTERNAL_ERROR;
1016 }
1017 std::lock_guard<std::mutex> lck(pimpl->requestInformation_.mutex_);
1018 if (pimpl->requestInformation_.doing_) {
1019 HILOGE("Remote device busy");
1020 return BT_ERR_INTERNAL_ERROR;
1021 }
1022 int result = GattStatus::GATT_FAILURE;
1023 HILOGI("applicationId: %{public}d", pimpl->applicationId_);
1024 result = pimpl->proxy_->ReadRemoteRssiValue(pimpl->applicationId_);
1025 HILOGI("result: %{public}d", result);
1026 if (result == BT_NO_ERROR) {
1027 pimpl->requestInformation_.doing_ = true;
1028 pimpl->requestInformation_.type_ = REQUEST_TYPE_READ_REMOTE_RSSI_VALUE;
1029 }
1030 return result;
1031 }
1032
1033 } // namespace Bluetooth
1034 } // namespace OHOS