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,int32_t disconnectReason)142 void OnConnectionStateChanged(int32_t state, int32_t newState, int32_t disconnectReason) 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 WPTR_GATT_CBACK(
161 clientSptr->pimpl->callback_, OnConnectionStateChangedWithReason, newState, state, disconnectReason);
162 }
163
OnCharacteristicChanged(const BluetoothGattCharacteristic & characteristic)164 void OnCharacteristicChanged(const BluetoothGattCharacteristic &characteristic) override
165 {
166 HILOGD("recv notification, length:%{public}zu", characteristic.length_);
167 std::shared_ptr<GattClient> clientSptr = (client_).lock();
168 if (!clientSptr) {
169 HILOGE("callback client is nullptr");
170 return;
171 }
172 std::lock_guard<std::mutex> lock(clientSptr->pimpl->gattServicesMutex_);
173 for (auto &svc : clientSptr->pimpl->gattServices_) {
174 for (auto &character : svc.GetCharacteristics()) {
175 if (character.GetHandle() == characteristic.handle_) {
176 character.SetValue(characteristic.value_.get(), characteristic.length_);
177 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnCharacteristicChanged, character);
178 return;
179 }
180 }
181 }
182 HILOGE("recv notification failed, characteristic is not exist.");
183 }
184
OnCharacteristicRead(int32_t ret,const BluetoothGattCharacteristic & characteristic)185 void OnCharacteristicRead(int32_t ret, const BluetoothGattCharacteristic &characteristic) override
186 {
187 HILOGI("ret:%{public}d, length:%{public}zu", ret, characteristic.length_);
188 std::shared_ptr<GattClient> clientSptr = (client_).lock();
189 if (!clientSptr) {
190 HILOGE("callback client is nullptr");
191 return;
192 }
193 uint8_t requestType;
194 {
195 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
196 clientSptr->pimpl->requestInformation_.doing_ = false;
197 requestType = clientSptr->pimpl->requestInformation_.type_;
198 }
199 GattCharacteristic charac(UUID(), 0, 0);
200 bool isExist = clientSptr->pimpl->GetCharacteristicByHandle(characteristic.handle_, charac);
201 if (!isExist) {
202 HILOGE("no expected characteristic handle:%{public}d type:%{public}d",
203 characteristic.handle_, requestType);
204 ret = BT_ERR_INTERNAL_ERROR;
205 }
206 if (requestType != REQUEST_TYPE_CHARACTERISTICS_READ) {
207 HILOGE("Unexpected call!");
208 return;
209 }
210 if (ret == GattStatus::GATT_SUCCESS) {
211 charac.SetValue(characteristic.value_.get(), characteristic.length_);
212 }
213 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnCharacteristicReadResult, charac, ret);
214 }
215
OnCharacteristicWrite(int32_t ret,const BluetoothGattCharacteristic & characteristic)216 void OnCharacteristicWrite(int32_t ret, const BluetoothGattCharacteristic &characteristic) override
217 {
218 HILOGI("ret:%{public}d, length:%{public}zu", ret, characteristic.length_);
219 std::shared_ptr<GattClient> clientSptr = (client_).lock();
220 if (!clientSptr) {
221 HILOGE("callback client is nullptr");
222 return;
223 }
224 uint8_t requestType;
225 {
226 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
227 clientSptr->pimpl->requestInformation_.doing_ = false;
228 requestType = clientSptr->pimpl->requestInformation_.type_;
229 }
230 GattCharacteristic charac(UUID(), 0, 0);
231 bool isExist = clientSptr->pimpl->GetCharacteristicByHandle(characteristic.handle_, charac);
232 if (!isExist) {
233 HILOGE("no expected characteristic handle:%{public}d type:%{public}d",
234 characteristic.handle_, requestType);
235 ret = BT_ERR_INTERNAL_ERROR;
236 }
237 if (requestType != REQUEST_TYPE_CHARACTERISTICS_WRITE) {
238 HILOGE("Unexpected call!");
239 return;
240 }
241 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnCharacteristicWriteResult, charac, ret);
242 }
243
OnDescriptorRead(int32_t ret,const BluetoothGattDescriptor & descriptor)244 void OnDescriptorRead(int32_t ret, const BluetoothGattDescriptor &descriptor) override
245 {
246 HILOGI("ret:%{public}d, length:%{public}zu", ret, descriptor.length_);
247 std::shared_ptr<GattClient> clientSptr = (client_).lock();
248 if (!clientSptr) {
249 HILOGE("callback client is nullptr");
250 return;
251 }
252 uint8_t requestType;
253 {
254 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
255 clientSptr->pimpl->requestInformation_.doing_ = false;
256 requestType = clientSptr->pimpl->requestInformation_.type_;
257 }
258 GattDescriptor desc(UUID(), 0);
259 bool isExist = clientSptr->pimpl->GetDescriptorByHandle(descriptor.handle_, desc);
260 if (!isExist) {
261 HILOGE("no expected descriptor handle:%{public}d type:%{public}d",
262 descriptor.handle_, requestType);
263 ret = BT_ERR_INTERNAL_ERROR;
264 }
265 if (requestType != REQUEST_TYPE_DESCRIPTOR_READ) {
266 HILOGE("Unexpected call!");
267 return;
268 }
269 if (ret == GattStatus::GATT_SUCCESS) {
270 desc.SetValue(descriptor.value_.get(), descriptor.length_);
271 }
272 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnDescriptorReadResult, desc, ret);
273 }
274
OnDescriptorWrite(int32_t ret,const BluetoothGattDescriptor & descriptor)275 void OnDescriptorWrite(int32_t ret, const BluetoothGattDescriptor &descriptor) override
276 {
277 HILOGD("ret:%{public}d, length:%{public}zu", ret, descriptor.length_);
278 std::shared_ptr<GattClient> clientSptr = (client_).lock();
279 if (!clientSptr) {
280 HILOGE("callback client is nullptr");
281 return;
282 }
283 uint8_t requestType;
284 {
285 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
286 clientSptr->pimpl->requestInformation_.doing_ = false;
287 requestType = clientSptr->pimpl->requestInformation_.type_;
288 }
289 GattDescriptor desc(UUID(), 0);
290 bool isExist = clientSptr->pimpl->GetDescriptorByHandle(descriptor.handle_, desc);
291 if (!isExist) {
292 HILOGE("no expected descriptor handle:%{public}d type:%{public}d",
293 descriptor.handle_, requestType);
294 ret = BT_ERR_INTERNAL_ERROR;
295 }
296 if (requestType == REQUEST_TYPE_DESCRIPTOR_WRITE) {
297 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnDescriptorWriteResult, desc, ret);
298 } else if (requestType == REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS) {
299 GattCharacteristic charac(UUID(), 0, 0);
300 if (isExist && desc.GetCharacteristic() != nullptr) {
301 charac = *desc.GetCharacteristic();
302 }
303 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnSetNotifyCharacteristic, charac, ret);
304 } else {
305 HILOGE("Unexpected call!");
306 return;
307 }
308 }
309
OnMtuChanged(int32_t state,int32_t mtu)310 void OnMtuChanged(int32_t state, int32_t mtu) override
311 {
312 HILOGI("state: %{public}d, mtu: %{public}d", state, mtu);
313 std::shared_ptr<GattClient> clientSptr = (client_).lock();
314 if (!clientSptr) {
315 HILOGE("callback client is nullptr");
316 return;
317 }
318 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnMtuUpdate, mtu, state);
319 }
320
OnServicesDiscovered(int32_t status)321 void OnServicesDiscovered(int32_t status) override
322 {
323 HILOGI("status: %{public}d", status);
324 std::shared_ptr<GattClient> clientSptr = (client_).lock();
325 if (!clientSptr) {
326 HILOGE("callback client is nullptr");
327 return;
328 }
329 clientSptr->pimpl->DiscoverComplete(status);
330 }
331
OnConnectionParameterChanged(int32_t interval,int32_t latency,int32_t timeout,int32_t status)332 void OnConnectionParameterChanged(int32_t interval, int32_t latency, int32_t timeout, int32_t status) override
333 {
334 HILOGD("interval: %{public}d, latency: %{public}d, timeout: %{public}d, status: %{public}d",
335 interval, latency, timeout, status);
336 std::shared_ptr<GattClient> clientSptr = (client_).lock();
337 if (!clientSptr) {
338 HILOGE("callback client is nullptr");
339 return;
340 }
341
342 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnConnectionParameterChanged, interval, latency, timeout, status);
343 }
344
OnReadRemoteRssiValue(const bluetooth::RawAddress & addr,int32_t rssi,int32_t status)345 void OnReadRemoteRssiValue(const bluetooth::RawAddress &addr, int32_t rssi, int32_t status) override
346 {
347 HILOGI("rssi: %{public}d, status: %{public}d", rssi, status);
348 std::shared_ptr<GattClient> clientSptr = (client_).lock();
349 if (!clientSptr) {
350 HILOGE("callback client is nullptr");
351 return;
352 }
353 uint8_t requestType;
354 {
355 std::lock_guard<std::mutex> lock(clientSptr->pimpl->requestInformation_.mutex_);
356 clientSptr->pimpl->requestInformation_.doing_ = false;
357 requestType = clientSptr->pimpl->requestInformation_.type_;
358 }
359 if (requestType != REQUEST_TYPE_READ_REMOTE_RSSI_VALUE) {
360 HILOGE("Unexpected call!");
361 }
362 WPTR_GATT_CBACK(clientSptr->pimpl->callback_, OnReadRemoteRssiValueResult, rssi, status);
363 }
364
BluetoothGattClientCallbackStubImpl(std::weak_ptr<GattClient> client)365 explicit BluetoothGattClientCallbackStubImpl(std::weak_ptr<GattClient> client) : client_(client)
366 {}
~BluetoothGattClientCallbackStubImpl()367 ~BluetoothGattClientCallbackStubImpl() override
368 {}
369
370 private:
371 std::weak_ptr<GattClient> client_;
372 };
373
Init(std::weak_ptr<GattClient> client)374 bool GattClient::impl::Init(std::weak_ptr<GattClient> client)
375 {
376 if (clientCallback_ != nullptr) {
377 return true;
378 }
379 clientCallback_ = new BluetoothGattClientCallbackStubImpl(client);
380 return true;
381 }
382
impl(const BluetoothRemoteDevice & device)383 GattClient::impl::impl(const BluetoothRemoteDevice &device)
384 : isGetServiceYet_(false),
385 isRegisterSucceeded_(false),
386 applicationId_(0),
387 connectionState_(static_cast<int>(BTConnectState::DISCONNECTED)),
388 device_(device)
389 {
390 auto bluetoothTurnOffFunc = [this]() {
391 applicationId_ = 0;
392 isRegisterSucceeded_ = false;
393 };
394 ProfileFunctions profileFunctions = {
395 .bluetoothLoadedfunc = nullptr,
396 .bleTurnOnFunc = nullptr,
397 .bluetoothTurnOffFunc = bluetoothTurnOffFunc,
398 };
399 profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(
400 PROFILE_GATT_CLIENT, profileFunctions);
401 }
402
~impl()403 GattClient::impl::~impl()
404 {
405 HILOGI("GattClient ~impl");
406 BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
407 }
408
DiscoverStart()409 int GattClient::impl::DiscoverStart()
410 {
411 if (!IS_BLE_ENABLED()) {
412 HILOGE("bluetooth is off.");
413 return BT_ERR_INVALID_STATE;
414 }
415
416 {
417 std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
418 auto ret = discoverInformation_.condition_.wait_for(lock, std::chrono::seconds(WAIT_TIMEOUT), [this] {
419 return !discoverInformation_.isDiscovering_;
420 });
421 if (ret == false) {
422 HILOGE("timeout");
423 return BT_ERR_INTERNAL_ERROR;
424 }
425 discoverInformation_.isDiscovering_ = true;
426 }
427
428 if (!isRegisterSucceeded_) {
429 return BT_ERR_INTERNAL_ERROR;
430 }
431 int result = BT_ERR_INTERNAL_ERROR;
432 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
433 if (!proxy) {
434 HILOGE("proxy is null");
435 } else {
436 result = proxy->DiscoveryServices(applicationId_);
437 if (result != BT_NO_ERROR) {
438 DiscoverComplete(BT_ERR_INTERNAL_ERROR);
439 }
440 }
441 return result;
442 }
443
DiscoverComplete(int state)444 void GattClient::impl::DiscoverComplete(int state)
445 {
446 bool ret = false;
447 {
448 std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
449 if (discoverInformation_.isDiscovering_) {
450 discoverInformation_.isDiscovering_ = false;
451 isGetServiceYet_ = false;
452 discoverInformation_.condition_.notify_all();
453 ret = true;
454 }
455 }
456 if (ret) {
457 std::shared_ptr<GattClientCallback> clientSptr = (callback_).lock();
458 if (!clientSptr) {
459 HILOGE("callback is nullptr");
460 return;
461 }
462 clientSptr->OnServicesDiscovered(state);
463 }
464 }
465
BuildServiceList(const std::vector<BluetoothGattService> & src)466 void GattClient::impl::BuildServiceList(const std::vector<BluetoothGattService> &src)
467 {
468 HILOGI("enter");
469 for (auto &svc : src) {
470 GattService svcTmp(UUID::ConvertFrom128Bits(svc.uuid_.ConvertTo128Bits()),
471 svc.startHandle_,
472 svc.endHandle_,
473 svc.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
474 for (auto &character : svc.characteristics_) {
475 GattCharacteristic characterTmp(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()),
476 character.handle_,
477 character.permissions_,
478 character.properties_);
479 for (auto &desc : character.descriptors_) {
480 characterTmp.AddDescriptor(GattDescriptor(
481 UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_));
482 }
483 svcTmp.AddCharacteristic(std::move(characterTmp));
484 }
485 std::lock_guard<std::mutex> lock(gattServicesMutex_);
486 gattServices_.emplace_back(std::move(svcTmp));
487 }
488 for (auto &svc : src) {
489 GattService *ptr = FindService(svc.handle_);
490 if (ptr == NULL) {
491 return;
492 }
493 for (auto &isvc : svc.includeServices_) {
494 GattService *iptr = FindService(isvc.startHandle_);
495 if (iptr == nullptr) {
496 return;
497 }
498 ptr->AddService(*iptr);
499 }
500 }
501 }
502
FindService(uint16_t handle)503 GattService *GattClient::impl::FindService(uint16_t handle)
504 {
505 std::lock_guard<std::mutex> lock(gattServicesMutex_);
506 for (auto &item : gattServices_) {
507 if (item.GetHandle() == handle) {
508 return &item;
509 }
510 }
511 return nullptr;
512 }
513
GetServices()514 void GattClient::impl::GetServices()
515 {
516 HILOGD("enter");
517 if (!IS_BLE_ENABLED()) {
518 HILOGE("bluetooth is off.");
519 return;
520 }
521
522 std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
523 auto ret = discoverInformation_.condition_.wait_for(lock, std::chrono::seconds(WAIT_TIMEOUT), [this] {
524 return !discoverInformation_.isDiscovering_;
525 });
526 if (ret == false) {
527 HILOGE("timeout");
528 return;
529 }
530 if (isGetServiceYet_) {
531 HILOGD("isGetServiceYet_ is true");
532 return;
533 }
534 if (!isRegisterSucceeded_) {
535 HILOGE("isRegisterSucceeded_ is false");
536 return;
537 }
538 {
539 std::lock_guard<std::mutex> lock(gattServicesMutex_);
540 gattServices_.clear();
541 }
542 std::vector<BluetoothGattService> result;
543 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
544 if (!proxy) {
545 HILOGE("proxy is null");
546 } else {
547 proxy->GetServices(applicationId_, result);
548 BuildServiceList(result);
549 isGetServiceYet_ = true;
550 }
551 }
552
CleanConnectionInfo()553 void GattClient::impl::CleanConnectionInfo()
554 {
555 DiscoverComplete(GattStatus::GATT_FAILURE);
556 std::lock_guard<std::mutex> lock(requestInformation_.mutex_);
557 requestInformation_.doing_ = false;
558 }
559
GetCharacteristicByHandle(uint16_t handle,GattCharacteristic & outCharac)560 bool GattClient::impl::GetCharacteristicByHandle(uint16_t handle, GattCharacteristic &outCharac)
561 {
562 std::lock_guard<std::mutex> lock(gattServicesMutex_);
563 for (auto &svc : gattServices_) {
564 std::vector<GattCharacteristic> &characs = svc.GetCharacteristics();
565 for (auto &charac : characs) {
566 if (handle == charac.GetHandle()) {
567 outCharac = charac;
568 return true;
569 }
570 }
571 }
572 return false;
573 }
574
GetDescriptorByHandle(uint16_t handle,GattDescriptor & outDesc)575 bool GattClient::impl::GetDescriptorByHandle(uint16_t handle, GattDescriptor &outDesc)
576 {
577 std::lock_guard<std::mutex> lock(gattServicesMutex_);
578 auto getDescriptorFunc = [handle](std::vector<GattCharacteristic> &characs) -> GattDescriptor* {
579 for (auto &charac : characs) {
580 std::vector<GattDescriptor> &descs = charac.GetDescriptors();
581 for (auto &desc : descs) {
582 if (handle == desc.GetHandle()) {
583 return &desc;
584 }
585 }
586 }
587 return nullptr;
588 };
589
590 for (auto &svc : gattServices_) {
591 GattDescriptor *descPtr = getDescriptorFunc(svc.GetCharacteristics());
592 if (descPtr != nullptr) {
593 outDesc = *descPtr;
594 return true;
595 }
596 }
597 return false;
598 }
599
GattClient(const BluetoothRemoteDevice & device)600 GattClient::GattClient(const BluetoothRemoteDevice &device) : pimpl(new GattClient::impl(device))
601 {
602 HILOGI("enter");
603 }
604
Init()605 bool GattClient::Init()
606 {
607 HILOGI("GattClient Init");
608 return pimpl->Init(weak_from_this());
609 }
610
~GattClient()611 GattClient::~GattClient()
612 {
613 HILOGI("~GattClient");
614 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
615 CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
616 if (pimpl->isRegisterSucceeded_) {
617 proxy->DeregisterApplication(pimpl->applicationId_);
618 }
619 }
620
Connect(std::weak_ptr<GattClientCallback> callback,bool isAutoConnect,int transport)621 int GattClient::Connect(std::weak_ptr<GattClientCallback> callback, bool isAutoConnect, int transport)
622 {
623 HILOGI("enter, isAutoConnect: %{public}d, transport: %{public}d", isAutoConnect, transport);
624 if (!IS_BLE_ENABLED()) {
625 HILOGE("bluetooth is off.");
626 return BT_ERR_INVALID_STATE;
627 }
628
629 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
630 HILOGE("pimpl or gatt client proxy is nullptr");
631 return BT_ERR_INTERNAL_ERROR;
632 }
633
634 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
635 if (pimpl->connectionState_ == static_cast<int>(BTConnectState::CONNECTED)) {
636 HILOGE("Already connected");
637 return BT_ERR_INTERNAL_ERROR;
638 }
639 HILOGI("isRegisterSucceeded: %{public}d", pimpl->isRegisterSucceeded_);
640 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
641 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
642 if (pimpl->isRegisterSucceeded_) {
643 return proxy->Connect(pimpl->applicationId_, isAutoConnect);
644 }
645 pimpl->callback_ = callback;
646 if ((transport == GATT_TRANSPORT_TYPE_LE && !IS_BLE_ENABLED()) ||
647 (transport == GATT_TRANSPORT_TYPE_CLASSIC && !IS_BT_ENABLED())) {
648 HILOGE("Unsupported mode");
649 return BT_ERR_INTERNAL_ERROR;
650 }
651 if (transport == GATT_TRANSPORT_TYPE_CLASSIC && isAutoConnect) {
652 HILOGE("Unsupported mode");
653 return BT_ERR_INTERNAL_ERROR;
654 }
655 if (!pimpl->device_.IsValidBluetoothRemoteDevice()) {
656 HILOGE("Invalid remote device");
657 return BT_ERR_INTERNAL_ERROR;
658 }
659
660 int appId = 0;
661 int32_t result = proxy->RegisterApplication(
662 pimpl->clientCallback_, bluetooth::RawAddress(pimpl->device_.GetDeviceAddr()), transport, appId);
663 HILOGI("Proxy register application : %{public}d", appId);
664 if (result != BT_NO_ERROR) {
665 HILOGE("register application fail");
666 return result;
667 }
668 if (appId > 0) {
669 pimpl->applicationId_ = appId;
670 pimpl->isRegisterSucceeded_ = true;
671 result = proxy->Connect(pimpl->applicationId_, isAutoConnect);
672 }
673 return result;
674 }
675
Disconnect()676 int GattClient::Disconnect()
677 {
678 HILOGI("enter");
679 if (!IS_BLE_ENABLED()) {
680 HILOGE("bluetooth is off.");
681 return BT_ERR_INVALID_STATE;
682 }
683
684 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
685 HILOGE("pimpl or gatt client proxy is nullptr");
686 return BT_ERR_INTERNAL_ERROR;
687 }
688
689 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
690 if (!pimpl->isRegisterSucceeded_) {
691 HILOGE("Request not supported");
692 return BT_ERR_INTERNAL_ERROR;
693 }
694 int result = BT_ERR_INTERNAL_ERROR;
695 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
696 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
697 result = proxy->Disconnect(pimpl->applicationId_);
698 return result;
699 }
700
Close()701 int GattClient::Close()
702 {
703 HILOGI("enter");
704 if (!IS_BLE_ENABLED()) {
705 HILOGE("bluetooth is off.");
706 return BT_ERR_INVALID_STATE;
707 }
708 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
709 HILOGE("pimpl or gatt client proxy is nullptr");
710 return BT_ERR_INTERNAL_ERROR;
711 }
712
713 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
714 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
715 if (pimpl->isRegisterSucceeded_) {
716 int32_t result = proxy->DeregisterApplication(pimpl->applicationId_);
717 HILOGI("result: %{public}d", result);
718 if (result == BT_NO_ERROR) {
719 pimpl->isRegisterSucceeded_ = false;
720 }
721 return result;
722 }
723 HILOGI("isRegisterSucceeded_ is false");
724 return BT_NO_ERROR;
725 }
726
DiscoverServices()727 int GattClient::DiscoverServices()
728 {
729 HILOGI("enter");
730 if (!IS_BLE_ENABLED()) {
731 HILOGE("bluetooth is off.");
732 return BT_ERR_INVALID_STATE;
733 }
734
735 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
736 HILOGE("pimpl or gatt client proxy is nullptr");
737 return BT_ERR_INTERNAL_ERROR;
738 }
739
740 std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
741 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
742 HILOGE("Request not supported");
743 return BT_ERR_INTERNAL_ERROR;
744 }
745 return pimpl->DiscoverStart();
746 }
747
GetService(const UUID & uuid)748 std::optional<std::reference_wrapper<GattService>> GattClient::GetService(const UUID &uuid)
749 {
750 HILOGD("enter");
751 if (!IS_BLE_ENABLED()) {
752 HILOGE("bluetooth is off.");
753 return std::nullopt;
754 }
755
756 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
757 HILOGE("pimpl or gatt client proxy is nullptr");
758 return std::nullopt;
759 }
760
761 pimpl->GetServices();
762 std::lock_guard<std::mutex> lock(pimpl->gattServicesMutex_);
763 for (auto &svc : pimpl->gattServices_) {
764 if (svc.GetUuid().Equals(uuid)) {
765 HILOGD("successful");
766 return svc;
767 }
768 }
769 HILOGE("failed");
770 return std::nullopt;
771 }
772
GetService()773 std::vector<GattService> &GattClient::GetService()
774 {
775 HILOGI("enter");
776 if (!IS_BLE_ENABLED()) {
777 HILOGE("bluetooth is off.");
778 return pimpl->gattServices_;
779 }
780
781 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
782 HILOGE("pimpl or gatt client proxy is nullptr");
783 return pimpl->gattServices_;
784 }
785
786 pimpl->GetServices();
787 return pimpl->gattServices_;
788 }
789
ReadCharacteristic(GattCharacteristic & characteristic)790 int GattClient::ReadCharacteristic(GattCharacteristic &characteristic)
791 {
792 HILOGI("enter");
793 if (!IS_BLE_ENABLED()) {
794 HILOGE("bluetooth is off.");
795 return BT_ERR_INVALID_STATE;
796 }
797
798 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
799 HILOGE("pimpl or gatt client proxy is nullptr");
800 return BT_ERR_INTERNAL_ERROR;
801 }
802
803 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
804 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
805 HILOGE("Request not supported");
806 return BT_ERR_GATT_CONNECTION_NOT_ESTABILISHED;
807 }
808 std::lock_guard<std::mutex> lck(pimpl->requestInformation_.mutex_);
809 if (pimpl->requestInformation_.doing_) {
810 HILOGE("Remote device busy");
811 return BT_ERR_OPERATION_BUSY;
812 }
813 int result = GattStatus::GATT_FAILURE;
814 HILOGI("applicationId: %{public}d, handle: 0x%{public}04X", pimpl->applicationId_, characteristic.GetHandle());
815 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
816 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
817 result = proxy->ReadCharacteristic(
818 pimpl->applicationId_, (BluetoothGattCharacteristic)bluetooth::Characteristic(characteristic.GetHandle()));
819 HILOGI("result: %{public}d", result);
820 if (result == BT_NO_ERROR) {
821 pimpl->requestInformation_.doing_ = true;
822 pimpl->requestInformation_.type_ = REQUEST_TYPE_CHARACTERISTICS_READ;
823 }
824 return result;
825 }
826
ReadDescriptor(GattDescriptor & descriptor)827 int GattClient::ReadDescriptor(GattDescriptor &descriptor)
828 {
829 HILOGI("enter");
830 if (!IS_BLE_ENABLED()) {
831 HILOGE("bluetooth is off.");
832 return BT_ERR_INVALID_STATE;
833 }
834
835 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
836 HILOGE("pimpl or gatt client proxy is nullptr");
837 return BT_ERR_INTERNAL_ERROR;
838 }
839
840 std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
841 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
842 HILOGE("Request not supported");
843 return BT_ERR_GATT_CONNECTION_NOT_ESTABILISHED;
844 }
845 std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
846 if (pimpl->requestInformation_.doing_) {
847 HILOGE("Remote device busy");
848 return BT_ERR_OPERATION_BUSY;
849 }
850 int result = BT_ERR_INTERNAL_ERROR;
851 HILOGI("applicationId: %{public}d, handle: 0x%{public}04X", pimpl->applicationId_, descriptor.GetHandle());
852 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
853 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
854 result = proxy->ReadDescriptor(
855 pimpl->applicationId_, (BluetoothGattDescriptor)bluetooth::Descriptor(descriptor.GetHandle()));
856 HILOGI("result: %{public}d", result);
857 if (result == BT_NO_ERROR) {
858 pimpl->requestInformation_.doing_ = true;
859 pimpl->requestInformation_.type_ = REQUEST_TYPE_DESCRIPTOR_READ;
860 }
861 return result;
862 }
863
RequestBleMtuSize(int mtu)864 int GattClient::RequestBleMtuSize(int mtu)
865 {
866 HILOGD("enter");
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> lck(pimpl->connStateMutex_);
878 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
879 HILOGE("Request not supported");
880 return BT_ERR_INTERNAL_ERROR;
881 }
882 int result = BT_ERR_INTERNAL_ERROR;
883 HILOGI("applicationId: %{public}d, mtu: %{public}d", pimpl->applicationId_, mtu);
884 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
885 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
886 result = proxy->RequestExchangeMtu(pimpl->applicationId_, mtu);
887 HILOGI("result: %{public}d", result);
888 return result;
889 }
890
SetNotifyCharacteristicInner(GattCharacteristic & characteristic,bool enable,const std::vector<uint8_t> & descriptorValue)891 int GattClient::SetNotifyCharacteristicInner(GattCharacteristic &characteristic, bool enable,
892 const std::vector<uint8_t> &descriptorValue)
893 {
894 CHECK_AND_RETURN_LOG_RET(IS_BLE_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
895 bool isValid = (pimpl != nullptr && pimpl->Init(weak_from_this()));
896 CHECK_AND_RETURN_LOG_RET(isValid, BT_ERR_INTERNAL_ERROR, "pimpl or gatt client proxy is nullptr");
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_GATT_CONNECTION_NOT_ESTABILISHED;
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_OPERATION_BUSY;
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_GATT_CONNECTION_NOT_ESTABILISHED;
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_OPERATION_BUSY;
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_GATT_CONNECTION_NOT_ESTABILISHED;
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_OPERATION_BUSY;
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::LOW_POWER) &&
1098 connPriority != static_cast<int>(GattConnectionPriority::BALANCED) &&
1099 connPriority != static_cast<int>(GattConnectionPriority::HIGH) &&
1100 connPriority != static_cast<int>(GattConnectionPriority::LOW_POWER_WEAK) &&
1101 connPriority != static_cast<int>(GattConnectionPriority::LOW_POWER_ENHANCE) &&
1102 connPriority != static_cast<int>(GattConnectionPriority::LOW_POWER_ULTRA)) {
1103 HILOGE("Invalid parameters");
1104 return GattStatus::INVALID_PARAMETER;
1105 }
1106 int result = GattStatus::GATT_FAILURE;
1107 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
1108 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
1109 result = proxy->RequestConnectionPriority(pimpl->applicationId_, connPriority);
1110 HILOGI("result: %{public}d", result);
1111 return result;
1112 }
1113
RequestFastestConn()1114 int GattClient::RequestFastestConn()
1115 {
1116 HILOGI("enter");
1117 if (!IS_BLE_ENABLED()) {
1118 HILOGE("bluetooth is off.");
1119 return BT_ERR_INVALID_STATE;
1120 }
1121
1122 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
1123 HILOGE("pimpl or gatt client proxy is nullptr");
1124 return BT_ERR_INTERNAL_ERROR;
1125 }
1126
1127 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
1128 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
1129 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
1130 return proxy->RequestFastestConn(bluetooth::RawAddress(pimpl->device_.GetDeviceAddr()));
1131 }
ReadRemoteRssiValue()1132 int GattClient::ReadRemoteRssiValue()
1133 {
1134 HILOGI("enter");
1135 if (!IS_BLE_ENABLED()) {
1136 HILOGE("bluetooth is off.");
1137 return BT_ERR_INVALID_STATE;
1138 }
1139
1140 if (pimpl == nullptr || !pimpl->Init(weak_from_this())) {
1141 HILOGE("pimpl or gatt client proxy is nullptr");
1142 return BT_ERR_INTERNAL_ERROR;
1143 }
1144
1145 std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
1146 if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
1147 HILOGE("Request not supported");
1148 return BT_ERR_GATT_CONNECTION_NOT_ESTABILISHED;
1149 }
1150 std::lock_guard<std::mutex> lck(pimpl->requestInformation_.mutex_);
1151 if (pimpl->requestInformation_.doing_) {
1152 HILOGE("Remote device busy");
1153 return BT_ERR_OPERATION_BUSY;
1154 }
1155 int result = GattStatus::GATT_FAILURE;
1156 HILOGI("applicationId: %{public}d", pimpl->applicationId_);
1157 sptr<IBluetoothGattClient> proxy = GetRemoteProxy<IBluetoothGattClient>(PROFILE_GATT_CLIENT);
1158 CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "failed: no proxy");
1159 result = proxy->ReadRemoteRssiValue(pimpl->applicationId_);
1160 HILOGI("result: %{public}d", result);
1161 if (result == BT_NO_ERROR) {
1162 pimpl->requestInformation_.doing_ = true;
1163 pimpl->requestInformation_.type_ = REQUEST_TYPE_READ_REMOTE_RSSI_VALUE;
1164 }
1165 return result;
1166 }
1167
1168 } // namespace Bluetooth
1169 } // namespace OHOS