• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_def.h"
21 #include "bluetooth_gatt_client.h"
22 #include "bluetooth_gatt_client_proxy.h"
23 #include "bluetooth_gatt_client_callback_stub.h"
24 #include "bluetooth_host.h"
25 #include "bluetooth_host_proxy.h"
26 #include "bluetooth_log.h"
27 #include "gatt_data.h"
28 #include "hilog/log.h"
29 #include "i_bluetooth_gatt_client.h"
30 #include "iservice_registry.h"
31 #include "raw_address.h"
32 #include "system_ability_definition.h"
33 
34 namespace OHOS {
35 namespace Bluetooth {
36 std::string GattClientServiceName = "bluetooth-gatt-client-server";
37 constexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_READ = 0x00;
38 constexpr uint8_t REQUEST_TYPE_CHARACTERISTICS_WRITE = 0x01;
39 constexpr uint8_t REQUEST_TYPE_DESCRIPTOR_READ = 0x02;
40 constexpr uint8_t REQUEST_TYPE_DESCRIPTOR_WRITE = 0x03;
41 constexpr uint8_t REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS = 0x04;
42 
43 struct DiscoverInfomation {
44     struct Characteristics {
45         bool isDiscoverDescCompleted_;
CharacteristicsOHOS::Bluetooth::DiscoverInfomation::Characteristics46         Characteristics() : isDiscoverDescCompleted_(false)
47         {}
48     };
49 
50     struct Service {
51         bool isDiscoverCompleted_;
52         bool isDiscoverCharacteristicCompleted_;
53         bool isDiscoverIncludeSvcCompleted_;
54         uint16_t endHandle_;
55         std::map<uint16_t, Characteristics> characteristics_;
ServiceOHOS::Bluetooth::DiscoverInfomation::Service56         Service(uint16_t endHandle)
57             : isDiscoverCompleted_(false),
58               isDiscoverCharacteristicCompleted_(false),
59               isDiscoverIncludeSvcCompleted_(false),
60               endHandle_(endHandle)
61         {}
62     };
63     bool isDiscovering_;
64     bool needNotify_;
65     std::mutex mutex_;
66     std::condition_variable condition_;
67     std::map<uint16_t, Service> service_;
DiscoverInfomationOHOS::Bluetooth::DiscoverInfomation68     DiscoverInfomation() : isDiscovering_(false), needNotify_(false)
69     {}
70 };
71 
72 struct RequestInformation {
73     bool doing_;
74     uint8_t type_;
75     union {
76         GattCharacteristic *characteristic_;
77         GattDescriptor *descriptor_;
78     } context_;
79     std::mutex mutex_;
RequestInformationOHOS::Bluetooth::RequestInformation80     RequestInformation() : doing_(false)
81     {}
82 };
83 
84 struct GattClient::impl {
85     class BluetoothGattClientCallbackStubImpl;
86 
87     bool isGetServiceYet_;
88     bool isRegisterSucceeded_;
89     GattClientCallback *callback_;
90     int applicationId_;
91     int connectionState_;
92     BluetoothRemoteDevice device_;
93     sptr<IBluetoothGattClient> proxy_;
94     sptr<BluetoothGattClientCallbackStubImpl> clientCallback_;
95     std::vector<GattService> gattServices_;
96     std::mutex connStateMutex_;
97     RequestInformation requestInformation_;
98     DiscoverInfomation discoverInformation_;
99 
100     impl(GattClient &client, const BluetoothRemoteDevice &device);
101     ~impl();
102 
103     int DiscoverStart();
104     void DiscoverComplete(int state);
105     void BuildServiceList(const std::vector<BluetoothGattService> &src);
106     GattService *FindService(uint16_t handle);
107     void GetServices();
108     int GetTransport(int &transport);
109     void CleanConnectionInfo();
110 
111     class GattClientDeathRecipient;
112     sptr<GattClientDeathRecipient> deathRecipient_;
113 };
114 
115 class GattClient::impl::GattClientDeathRecipient final : public IRemoteObject::DeathRecipient {
116 public:
GattClientDeathRecipient(GattClient::impl & client)117     GattClientDeathRecipient(GattClient::impl &client) : client_(client){};
118     ~GattClientDeathRecipient() final = default;
119     BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(GattClientDeathRecipient);
120 
OnRemoteDied(const wptr<IRemoteObject> & remote)121     void OnRemoteDied(const wptr<IRemoteObject> &remote) final
122     {
123         HILOGI("GattClient::impl::GattClientDeathRecipient::OnRemoteDied starts");
124         client_.proxy_->AsObject()->RemoveDeathRecipient(client_.deathRecipient_);
125         client_.proxy_ = nullptr;
126     }
127 
128 private:
129     GattClient::impl &client_;
130 };
131 
132 class GattClient::impl::BluetoothGattClientCallbackStubImpl : public BluetoothGattClientCallbackStub {
133 public:
OnServicesChanged(std::vector<BluetoothGattService> & service)134     void OnServicesChanged(std::vector<BluetoothGattService> &service) override
135     {
136         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnServicesChanged Triggered!");
137         client_.pimpl->DiscoverStart();
138     }
139 
OnConnectionStateChanged(int32_t state,int32_t newState)140     void OnConnectionStateChanged(int32_t state, int32_t newState) override
141     {
142         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnConnectionStateChanged Triggered!");
143         if (newState == static_cast<int>(BTConnectState::DISCONNECTED)) {
144             client_.pimpl->CleanConnectionInfo();
145         }
146 
147         {
148             std::lock_guard<std::mutex> lck(client_.pimpl->connStateMutex_);
149             client_.pimpl->connectionState_ = newState;
150         }
151 
152         client_.pimpl->callback_->OnConnectionStateChanged(newState, state);
153     }
154 
OnCharacteristicChanged(const BluetoothGattCharacteristic & characteristic)155     void OnCharacteristicChanged(const BluetoothGattCharacteristic &characteristic) override
156     {
157         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnCharacteristicChanged Triggered!");
158         for (auto &svc : client_.pimpl->gattServices_) {
159             for (auto &character : svc.GetCharacteristics()) {
160                 if (character.GetHandle() == characteristic.handle_) {
161                     character.SetValue(characteristic.value_.get(), characteristic.length_);
162                     client_.pimpl->callback_->OnCharacteristicChanged(character);
163                 }
164             }
165         }
166     }
167 
OnCharacteristicRead(int32_t ret,const BluetoothGattCharacteristic & characteristic)168     void OnCharacteristicRead(int32_t ret, const BluetoothGattCharacteristic &characteristic) override
169     {
170         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnCharacteristicRead Triggered!");
171         std::lock_guard<std::mutex> lock(client_.pimpl->requestInformation_.mutex_);
172         client_.pimpl->requestInformation_.doing_ = false;
173         auto ptr = client_.pimpl->requestInformation_.context_.characteristic_;
174         if (client_.pimpl->requestInformation_.type_ != REQUEST_TYPE_CHARACTERISTICS_READ) {
175             HILOGE("Bluetooth Gatt Client Callback Stub Impl OnCharacteristicRead has Unexpected call!");
176         }
177         if (GattStatus::GATT_SUCCESS == ret) {
178             ptr->SetValue(characteristic.value_.get(), characteristic.length_);
179         }
180         client_.pimpl->callback_->OnCharacteristicReadResult(*ptr, ret);
181     }
182 
OnCharacteristicWrite(int32_t ret,const BluetoothGattCharacteristic & characteristic)183     void OnCharacteristicWrite(int32_t ret, const BluetoothGattCharacteristic &characteristic) override
184     {
185         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnCharacteristicWrite Triggered!");
186         std::lock_guard<std::mutex> lock(client_.pimpl->requestInformation_.mutex_);
187         client_.pimpl->requestInformation_.doing_ = false;
188         auto ptr = client_.pimpl->requestInformation_.context_.characteristic_;
189         if (client_.pimpl->requestInformation_.type_ != REQUEST_TYPE_CHARACTERISTICS_WRITE) {
190             HILOGE("Bluetooth Gatt Client Callback Stub Impl OnCharacteristicWrite has Unexpected call!");
191         }
192         client_.pimpl->callback_->OnCharacteristicWriteResult(*ptr, ret);
193     }
194 
OnDescriptorRead(int32_t ret,const BluetoothGattDescriptor & descriptor)195     void OnDescriptorRead(int32_t ret, const BluetoothGattDescriptor &descriptor) override
196     {
197         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnDescriptorRead Triggered!");
198         std::lock_guard<std::mutex> lock(client_.pimpl->requestInformation_.mutex_);
199         client_.pimpl->requestInformation_.doing_ = false;
200         auto ptr = client_.pimpl->requestInformation_.context_.descriptor_;
201         if (client_.pimpl->requestInformation_.type_ != REQUEST_TYPE_DESCRIPTOR_READ) {
202             HILOGE("Bluetooth Gatt Client Callback Stub Impl OnDescriptorRead has Unexpected call!");
203         }
204         if (GattStatus::GATT_SUCCESS == ret) {
205             ptr->SetValue(descriptor.value_.get(), descriptor.length_);
206         }
207         client_.pimpl->callback_->OnDescriptorReadResult(*ptr, ret);
208     }
209 
OnDescriptorWrite(int32_t ret,const BluetoothGattDescriptor & descriptor)210     void OnDescriptorWrite(int32_t ret, const BluetoothGattDescriptor &descriptor) override
211     {
212         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnDescriptorWrite Triggered!");
213         std::lock_guard<std::mutex> lock(client_.pimpl->requestInformation_.mutex_);
214         client_.pimpl->requestInformation_.doing_ = false;
215         auto ptr = client_.pimpl->requestInformation_.context_.descriptor_;
216         if (client_.pimpl->requestInformation_.type_ == REQUEST_TYPE_DESCRIPTOR_WRITE) {
217             client_.pimpl->callback_->OnDescriptorWriteResult(*ptr, ret);
218         } else if (client_.pimpl->requestInformation_.type_ == REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS) {
219             client_.pimpl->callback_->OnSetNotifyCharacteristic(ret);
220         } else {
221             HILOGE("Bluetooth Gatt Client Callback Stub Impl OnDescriptorWrite has Unexpected call!");
222         }
223     }
224 
OnMtuChanged(int32_t state,int32_t mtu)225     void OnMtuChanged(int32_t state, int32_t mtu) override
226     {
227         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnMtuChanged Triggered!");
228         client_.pimpl->callback_->OnMtuUpdate(mtu, state);
229     }
230 
OnServicesDiscovered(int32_t status)231     void OnServicesDiscovered(int32_t status) override
232     {
233         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnServicesDiscovered Triggered!");
234         client_.pimpl->DiscoverComplete(status);
235     }
236 
OnConnectionParameterChanged(int32_t interval,int32_t latency,int32_t timeout,int32_t status)237     void OnConnectionParameterChanged(int32_t interval, int32_t latency, int32_t timeout, int32_t status) override
238     {
239         HILOGI("Bluetooth Gatt Client Callback Stub Impl OnConnectionParameterChanged Triggered!");
240         client_.pimpl->callback_->OnConnectionParameterChanged(interval, latency, timeout, status);
241     }
242 
BluetoothGattClientCallbackStubImpl(GattClient & client)243     BluetoothGattClientCallbackStubImpl(GattClient &client) : client_(client)
244     {}
~BluetoothGattClientCallbackStubImpl()245     ~BluetoothGattClientCallbackStubImpl()
246     {}
247 
248 private:
249     GattClient &client_;
250 };
251 
impl(GattClient & client,const BluetoothRemoteDevice & device)252 GattClient::impl::impl(GattClient &client, const BluetoothRemoteDevice &device)
253     : isGetServiceYet_(false),
254       isRegisterSucceeded_(false),
255       callback_(nullptr),
256       applicationId_(0),
257       connectionState_(static_cast<int>(BTConnectState::DISCONNECTED)),
258       device_(device)
259 {
260     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
261     sptr<IRemoteObject> hostRemote = samgr->GetSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
262 
263     if (!hostRemote) {
264         HILOGI("GattClient::impl:impl() failed: no hostRemote");
265         return;
266     }
267 
268     sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
269     sptr<IRemoteObject> remote = hostProxy->GetProfile(PROFILE_GATT_CLIENT);
270 
271     if (!remote) {
272         HILOGI("GattClient::impl:impl() failed: no remote");
273         return;
274     }
275     HILOGI("GattClient::impl:impl() remote obtained");
276     proxy_ = iface_cast<IBluetoothGattClient>(remote);
277     clientCallback_ = new BluetoothGattClientCallbackStubImpl(client);
278 
279     deathRecipient_ = new GattClientDeathRecipient(*this);
280     if (!proxy_) {
281         HILOGI("GattClient::impl:impl() proxy_ is null when used!");
282     } else {
283         proxy_->AsObject()->AddDeathRecipient(deathRecipient_);
284     }
285 }
286 
~impl()287 GattClient::impl::~impl()
288 {
289     if (!proxy_) {
290         HILOGI("GattClient::impl:~impl() proxy_ is null when used!");
291     } else {
292         proxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
293     }
294 }
295 
DiscoverStart()296 int GattClient::impl::DiscoverStart()
297 {
298     {
299         std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
300         while (discoverInformation_.isDiscovering_) {
301             discoverInformation_.condition_.wait(lock);
302         }
303         discoverInformation_.isDiscovering_ = true;
304     }
305 
306     if (!isRegisterSucceeded_) {
307         return GattStatus::REQUEST_NOT_SUPPORT;
308     }
309     int result = GattStatus::GATT_FAILURE;
310     if (!proxy_) {
311         HILOGI("GattClient::impl:DiscoverStart() proxy_ is null when used!");
312     } else {
313         result = proxy_->DiscoveryServices(applicationId_);
314         if (GattStatus::GATT_SUCCESS != result) {
315             DiscoverComplete(GattStatus::GATT_FAILURE);
316         }
317     }
318     return result;
319 }
320 
DiscoverComplete(int state)321 void GattClient::impl::DiscoverComplete(int state)
322 {
323     bool ret = false;
324     {
325         std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
326         if (discoverInformation_.isDiscovering_) {
327             discoverInformation_.isDiscovering_ = false;
328             isGetServiceYet_ = false;
329             discoverInformation_.condition_.notify_all();
330             ret = true;
331         }
332     }
333     if (ret) {
334         callback_->OnServicesDiscovered(state);
335     }
336 }
337 
BuildServiceList(const std::vector<BluetoothGattService> & src)338 void GattClient::impl::BuildServiceList(const std::vector<BluetoothGattService> &src)
339 {
340     for (auto &svc : src) {
341         GattService svcTmp(UUID::ConvertFrom128Bits(svc.uuid_.ConvertTo128Bits()),
342             svc.handle_,
343             svc.endHandle_,
344             svc.isPrimary_ ? GattServiceType::PRIMARY : GattServiceType::SECONDARY);
345         for (auto &character : svc.characteristics_) {
346             GattCharacteristic characterTmp(UUID::ConvertFrom128Bits(character.uuid_.ConvertTo128Bits()),
347                 character.handle_,
348                 character.permissions_,
349                 character.properties_);
350             for (auto &desc : character.descriptors_) {
351                 characterTmp.AddDescriptor(GattDescriptor(
352                     UUID::ConvertFrom128Bits(desc.uuid_.ConvertTo128Bits()), desc.handle_, desc.permissions_));
353             }
354             svcTmp.AddCharacteristic(std::move(characterTmp));
355         }
356         gattServices_.emplace_back(std::move(svcTmp));
357     }
358     for (auto &svc : src) {
359         GattService *ptr = FindService(svc.handle_);
360         if (ptr == NULL) {
361             return;
362         }
363         for (auto &isvc : svc.includeServices_) {
364             GattService *iptr = FindService(isvc.startHandle_);
365             ptr->AddService(*iptr);
366         }
367     }
368 }
369 
FindService(uint16_t handle)370 GattService *GattClient::impl::FindService(uint16_t handle)
371 {
372     for (auto &item : gattServices_) {
373         if (item.GetHandle() == handle) {
374             return &item;
375         }
376     }
377     return nullptr;
378 }
379 
GetServices()380 void GattClient::impl::GetServices()
381 {
382     std::unique_lock<std::mutex> lock(discoverInformation_.mutex_);
383     while (discoverInformation_.isDiscovering_) {
384         discoverInformation_.condition_.wait(lock);
385     }
386     if (isGetServiceYet_) {
387         return;
388     }
389     if (!isRegisterSucceeded_) {
390         return;
391     }
392     gattServices_.clear();
393     std::vector<BluetoothGattService> result;
394     if (!proxy_) {
395         HILOGI("GattClient::impl:GetServices() proxy_ is null when used!");
396     } else {
397         proxy_->GetServices(applicationId_, result);
398         BuildServiceList(result);
399         isGetServiceYet_ = true;
400     }
401 }
402 
GetTransport(int & transport)403 int GattClient::impl::GetTransport(int &transport)
404 {
405     auto deviceType = device_.GetDeviceType();
406     switch (transport) {
407         case GATT_TRANSPORT_TYPE_LE: {
408             if (deviceType == DEVICE_TYPE_BREDR) {
409                 return GattStatus::REQUEST_NOT_SUPPORT;
410             }
411             break;
412         }
413         case GATT_TRANSPORT_TYPE_CLASSIC: {
414             if (deviceType == DEVICE_TYPE_LE) {
415                 return GattStatus::REQUEST_NOT_SUPPORT;
416             }
417             break;
418         }
419         case GATT_TRANSPORT_TYPE_AUTO: {
420             if (deviceType == DEVICE_TYPE_LE || deviceType == DEVICE_TYPE_DUAL_MONO ||
421                 deviceType == DEVICE_TYPE_UNKNOWN) {
422                 transport = GATT_TRANSPORT_TYPE_LE;
423             } else {
424                 transport = GATT_TRANSPORT_TYPE_CLASSIC;
425             }
426             break;
427         }
428         default:
429             return GattStatus::INVALID_PARAMETER;
430             break;
431     }
432     return GattStatus::GATT_SUCCESS;
433 }
434 
CleanConnectionInfo()435 void GattClient::impl::CleanConnectionInfo()
436 {
437     DiscoverComplete(GattStatus::GATT_FAILURE);
438     std::lock_guard<std::mutex> lock(requestInformation_.mutex_);
439     requestInformation_.doing_ = false;
440 }
441 
GattClient(const BluetoothRemoteDevice & device)442 GattClient::GattClient(const BluetoothRemoteDevice &device) : pimpl(new GattClient::impl(*this, device))
443 {
444     HILOGI("GattClient::GattClient called");
445 }
446 
~GattClient()447 GattClient::~GattClient()
448 {
449     if (pimpl->isRegisterSucceeded_) {
450         if (!pimpl->proxy_) {
451             HILOGI("GattClient::~GattClient() proxy_ is null when used!");
452         } else {
453             pimpl->proxy_->DeregisterApplication(pimpl->applicationId_);
454         }
455     }
456 }
457 
Connect(GattClientCallback & callback,bool isAutoConnect,int transport)458 int GattClient::Connect(GattClientCallback &callback, bool isAutoConnect, int transport)
459 {
460     HILOGI("GattClient::Connect called");
461     std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
462     if (pimpl->connectionState_ == static_cast<int>(BTConnectState::CONNECTED)) {
463         return GattStatus::REQUEST_NOT_SUPPORT;
464     }
465     if (pimpl->isRegisterSucceeded_) {
466         if (!pimpl->proxy_) {
467             HILOGI("GattClient::Connect() proxy_ is null when used!");
468             return GattStatus::GATT_FAILURE;
469         }
470         return pimpl->proxy_->Connect(pimpl->applicationId_, isAutoConnect);
471     }
472     pimpl->callback_ = &callback;
473     int32_t result = pimpl->GetTransport(transport);
474     if (GattStatus::GATT_SUCCESS != result) {
475         return result;
476     }
477     if ((transport == GATT_TRANSPORT_TYPE_LE && !IS_BLE_ENABLED()) ||
478         (transport == GATT_TRANSPORT_TYPE_CLASSIC && !IS_BT_ENABLED())) {
479         return GattStatus::REQUEST_NOT_SUPPORT;
480     }
481     if (transport == GATT_TRANSPORT_TYPE_CLASSIC && isAutoConnect) {
482         return GattStatus::REQUEST_NOT_SUPPORT;
483     }
484     if (!pimpl->device_.IsValidBluetoothRemoteDevice()) {
485         return GattStatus::INVALID_REMOTE_DEVICE;
486     }
487     if (!pimpl->proxy_) {
488         HILOGI("GattClient::Connect() proxy_ is null when used!");
489         return GattStatus::GATT_FAILURE;
490     }
491     result = pimpl->proxy_->RegisterApplication(
492         pimpl->clientCallback_, bluetooth::RawAddress(pimpl->device_.GetDeviceAddr()), transport);
493     if (result > 0) {
494         pimpl->applicationId_ = result;
495         pimpl->isRegisterSucceeded_ = true;
496         if (!pimpl->proxy_) {
497             HILOGI("GattClient::Connect() proxy_ is null when used!");
498             return GattStatus::GATT_FAILURE;
499         }
500         result = pimpl->proxy_->Connect(pimpl->applicationId_, isAutoConnect);
501     }
502     return result;
503 }
504 
Disconnect()505 int GattClient::Disconnect()
506 {
507     std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
508     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
509         return GattStatus::REQUEST_NOT_SUPPORT;
510     }
511     int result = GattStatus::GATT_FAILURE;
512     if (!pimpl->proxy_) {
513         HILOGI("GattClient::Disconnect() proxy_ is null when used!");
514         return GattStatus::GATT_FAILURE;
515     }
516     result = pimpl->proxy_->Disconnect(pimpl->applicationId_);
517     return result;
518 }
519 
DiscoverServices()520 int GattClient::DiscoverServices()
521 {
522     std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
523     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
524         return GattStatus::REQUEST_NOT_SUPPORT;
525     }
526     return pimpl->DiscoverStart();
527 }
528 
GetService(const UUID & uuid)529 std::optional<std::reference_wrapper<GattService>> GattClient::GetService(const UUID &uuid)
530 {
531     pimpl->GetServices();
532     for (auto &svc : pimpl->gattServices_) {
533         if (svc.GetUuid().Equals(uuid)) {
534             return svc;
535         }
536     }
537     return std::nullopt;
538 }
539 
GetService()540 std::vector<GattService> &GattClient::GetService()
541 {
542     pimpl->GetServices();
543     return pimpl->gattServices_;
544 }
545 
ReadCharacteristic(GattCharacteristic & characteristic)546 int GattClient::ReadCharacteristic(GattCharacteristic &characteristic)
547 {
548     HILOGI("ReadCharacteristic is called");
549     std::lock_guard<std::mutex> lock(pimpl->connStateMutex_);
550     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
551         return GattStatus::REQUEST_NOT_SUPPORT;
552     }
553     std::lock_guard<std::mutex> lck(pimpl->requestInformation_.mutex_);
554     if (pimpl->requestInformation_.doing_) {
555         return GattStatus::REMOTE_DEVICE_BUSY;
556     }
557     int result = GattStatus::GATT_FAILURE;
558     if (!pimpl->proxy_) {
559         HILOGI("GattClient::ReadCharacteristic() proxy_ is null when used!");
560         return GattStatus::GATT_FAILURE;
561     }
562     result = pimpl->proxy_->ReadCharacteristic(
563         pimpl->applicationId_, (BluetoothGattCharacteristic)bluetooth::Characteristic(characteristic.GetHandle()));
564     if (GattStatus::GATT_SUCCESS == result) {
565         pimpl->requestInformation_.doing_ = true;
566         pimpl->requestInformation_.type_ = REQUEST_TYPE_CHARACTERISTICS_READ;
567         pimpl->requestInformation_.context_.characteristic_ = &characteristic;
568     }
569     return result;
570 }
571 
ReadDescriptor(GattDescriptor & descriptor)572 int GattClient::ReadDescriptor(GattDescriptor &descriptor)
573 {
574     std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
575     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
576         return GattStatus::REQUEST_NOT_SUPPORT;
577     }
578     std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
579     if (pimpl->requestInformation_.doing_) {
580         return GattStatus::REMOTE_DEVICE_BUSY;
581     }
582     int result = GattStatus::GATT_FAILURE;
583     if (!pimpl->proxy_) {
584         HILOGI("GattClient::ReadDescriptor() proxy_ is null when used!");
585         return GattStatus::GATT_FAILURE;
586     }
587     result = pimpl->proxy_->ReadDescriptor(
588         pimpl->applicationId_, (BluetoothGattDescriptor)bluetooth::Descriptor(descriptor.GetHandle()));
589     if (GattStatus::GATT_SUCCESS == result) {
590         pimpl->requestInformation_.doing_ = true;
591         pimpl->requestInformation_.type_ = REQUEST_TYPE_DESCRIPTOR_READ;
592         pimpl->requestInformation_.context_.descriptor_ = &descriptor;
593     }
594     return result;
595 }
596 
RequestBleMtuSize(int mtu)597 int GattClient::RequestBleMtuSize(int mtu)
598 {
599     HILOGI("GattClient::RequestBleMtuSize called");
600     std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
601     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
602         return GattStatus::REQUEST_NOT_SUPPORT;
603     }
604     int result = GattStatus::GATT_FAILURE;
605     if (!pimpl->proxy_) {
606         HILOGI("GattClient::RequestBleMtuSize() proxy_ is null when used!");
607         return GattStatus::GATT_FAILURE;
608     }
609     result = pimpl->proxy_->RequestExchangeMtu(pimpl->applicationId_, mtu);
610     return result;
611 }
612 
SetNotifyCharacteristic(GattCharacteristic & characteristic,bool enable)613 int GattClient::SetNotifyCharacteristic(GattCharacteristic &characteristic, bool enable)
614 {
615     HILOGI("GattClient::SetNotifyCharacteristic called");
616     static const uint8_t NOTIFICATION[2] = {1, 0};
617     static const uint8_t DEFAULT_VALUE[2] = {0};
618     static const size_t CLIENT_CHARACTERISTIC_CONFIGURATION_VALUE_LENGTH = 0x02;
619     std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_);
620     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
621         return GattStatus::REQUEST_NOT_SUPPORT;
622     }
623     auto descriptor = characteristic.GetDescriptor(UUID::FromString("00002902-0000-1000-8000-00805F9B34FB"));
624     if (descriptor == nullptr) {
625         return GattStatus::INVALID_PARAMETER;
626     }
627     std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
628     if (pimpl->requestInformation_.doing_) {
629         return GattStatus::REMOTE_DEVICE_BUSY;
630     }
631     BluetoothGattDescriptor desc(bluetooth::Descriptor(descriptor->GetHandle(),
632         (enable ? NOTIFICATION : DEFAULT_VALUE),
633         CLIENT_CHARACTERISTIC_CONFIGURATION_VALUE_LENGTH));
634     int result = GattStatus::GATT_FAILURE;
635     if (!pimpl->proxy_) {
636         HILOGI("GattClient::SetNotifyCharacteristic() proxy_ is null when used!");
637         return GattStatus::GATT_FAILURE;
638     }
639     result = pimpl->proxy_->WriteDescriptor(pimpl->applicationId_, &desc);
640     if (GattStatus::GATT_SUCCESS == result) {
641         pimpl->requestInformation_.type_ = REQUEST_TYPE_SET_NOTIFY_CHARACTERISTICS;
642         pimpl->requestInformation_.context_.descriptor_ = descriptor;
643         pimpl->requestInformation_.doing_ = true;
644     }
645     return result;
646 }
647 
WriteCharacteristic(GattCharacteristic & characteristic)648 int GattClient::WriteCharacteristic(GattCharacteristic &characteristic)
649 {
650     HILOGI("GattClient::WriteCharacteristic called");
651     std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_);
652     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
653         return GattStatus::REQUEST_NOT_SUPPORT;
654     }
655     size_t length = 0;
656     auto &characterValue = characteristic.GetValue(&length);
657     if (characterValue == nullptr || length == 0) {
658         return GattStatus::INVALID_PARAMETER;
659     }
660     std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
661     if (pimpl->requestInformation_.doing_) {
662         return GattStatus::REMOTE_DEVICE_BUSY;
663     }
664     BluetoothGattCharacteristic character(
665         bluetooth::Characteristic(characteristic.GetHandle(), characterValue.get(), length));
666     int result = GattStatus::GATT_FAILURE;
667     bool withoutRespond = true;
668     if (characteristic.GetWriteType() == (int)GattCharacteristic::WriteType::SIGNED) {
669         if (!pimpl->proxy_) {
670             HILOGI("GattClient::WriteCharacteristic() proxy_ is null when used!");
671             return GattStatus::GATT_FAILURE;
672         }
673         result = pimpl->proxy_->SignedWriteCharacteristic(pimpl->applicationId_, &character);
674     } else {
675         withoutRespond =
676             ((characteristic.GetWriteType() == (int)GattCharacteristic::WriteType::DEFAULT) ? false : true);
677         if (!pimpl->proxy_) {
678             HILOGI("GattClient::WriteCharacteristic() proxy_ is null when used!");
679             return GattStatus::GATT_FAILURE;
680         }
681         result = pimpl->proxy_->WriteCharacteristic(pimpl->applicationId_, &character, withoutRespond);
682     }
683     if (GattStatus::GATT_SUCCESS == result && !withoutRespond) {
684         pimpl->requestInformation_.type_ = REQUEST_TYPE_CHARACTERISTICS_WRITE;
685         pimpl->requestInformation_.context_.characteristic_ = &characteristic;
686         pimpl->requestInformation_.doing_ = true;
687     }
688     return result;
689 }
690 
WriteDescriptor(GattDescriptor & descriptor)691 int GattClient::WriteDescriptor(GattDescriptor &descriptor)
692 {
693     HILOGI("GattClient::WriteDescriptor Called");
694     std::lock_guard<std::mutex> lck(pimpl->connStateMutex_);
695     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED) || !pimpl->isRegisterSucceeded_) {
696         return GattStatus::REQUEST_NOT_SUPPORT;
697     }
698     size_t length = 0;
699     auto &characterValue = descriptor.GetValue(&length);
700     if (characterValue == nullptr || length == 0) {
701         return GattStatus::INVALID_PARAMETER;
702     }
703     std::lock_guard<std::mutex> lock(pimpl->requestInformation_.mutex_);
704     if (pimpl->requestInformation_.doing_) {
705         return GattStatus::REMOTE_DEVICE_BUSY;
706     }
707     int result = GattStatus::GATT_FAILURE;
708     BluetoothGattDescriptor desc(bluetooth::Descriptor(descriptor.GetHandle(), characterValue.get(), length));
709     if (!pimpl->proxy_) {
710         HILOGI("GattClient::WriteDescriptor() proxy_ is null when used!");
711         return GattStatus::GATT_FAILURE;
712     }
713     result = pimpl->proxy_->WriteDescriptor(pimpl->applicationId_, &desc);
714     if (GattStatus::GATT_SUCCESS == result) {
715         pimpl->requestInformation_.doing_ = true;
716         pimpl->requestInformation_.type_ = REQUEST_TYPE_DESCRIPTOR_WRITE;
717         pimpl->requestInformation_.context_.descriptor_ = &descriptor;
718     }
719     return result;
720 }
721 
RequestConnectionPriority(int connPriority)722 int GattClient::RequestConnectionPriority(int connPriority)
723 {
724     std::lock_guard<std::mutex> lockConn(pimpl->connStateMutex_);
725     if (pimpl->connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
726         return GattStatus::REQUEST_NOT_SUPPORT;
727     }
728     if (connPriority != static_cast<int>(GattConnectionPriority::BALANCED) &&
729         connPriority != static_cast<int>(GattConnectionPriority::HIGH) &&
730         connPriority != static_cast<int>(GattConnectionPriority::LOW_POWER)) {
731         return GattStatus::INVALID_PARAMETER;
732     }
733     int result = GattStatus::GATT_FAILURE;
734     if (!pimpl->proxy_) {
735         HILOGI("GattClient::RequestConnectionPriority() proxy_ is null when used!");
736         return GattStatus::GATT_FAILURE;
737     }
738     result = pimpl->proxy_->RequestConnectionPriority(pimpl->applicationId_, connPriority);
739     return result;
740 }
741 }  // namespace Bluetooth
742 }  // namespace OHOS