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