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