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