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