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