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