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