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