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