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