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 "gatt_client_service.h"
17 #include <future>
18 #include <queue>
19 #include <set>
20 #include "class_creator.h"
21 #include "gatt_cache.h"
22 #include "gatt_client_profile.h"
23 #include "gatt_connection.h"
24 #include "gatt_connection_manager.h"
25 #include "gatt_defines.h"
26 #include "gatt_service_base.h"
27 #include "interface_profile.h"
28 #include "log.h"
29 #include "log_util.h"
30 #include "power_manager.h"
31 #include "securec.h"
32 
33 namespace OHOS {
34 namespace bluetooth {
35 struct ClientApplication {
36     struct Discover {
37         struct Task {
38             enum Type { SERVICE, INCLUDE_SERVICE, CHARACTERISTICS, DESCRIPTOR };
39             int type_ = 0;
40             uint16_t startHandle_ = 0;
41             uint16_t endHandle_ = 0;
42         };
43         std::queue<Task> tasks_ = {};
44         std::set<uint16_t> discovered_ = {};
45         ClientApplication &client_;
46         GattClientProfile &profile_;
47 
48         bool DiscoverNext(int appId);
49         void Clear();
DiscoverOHOS::bluetooth::ClientApplication::Discover50         Discover(ClientApplication &client, GattClientProfile &profile) : client_(client), profile_(profile)
51         {}
52     };
53 
ClientApplicationOHOS::bluetooth::ClientApplication54     ClientApplication(
55         IGattClientCallback &callback, const GattDevice &device, GattClientProfile &profile, bool isShared)
56         : isShared_(isShared),
57           connState_((int)BTConnectState::DISCONNECTED),
58           callback_(callback),
59           connection_(device),
60           discover_(*this, profile)
61     {}
62 
ClientApplicationOHOS::bluetooth::ClientApplication63     ClientApplication(const ClientApplication &src)
64         : isShared_(src.isShared_),
65           connState_((int)BTConnectState::DISCONNECTED),
66           callback_(src.callback_),
67           connection_(src.connection_),
68           discover_(*this, src.discover_.profile_)
69     {}
70 
71     ClientApplication &operator=(const ClientApplication &src) = delete;
72 
73     bool isShared_;
74     int connState_;
75     IGattClientCallback &callback_;
76     GattConnection connection_;
77     Discover discover_;
78 };
79 
80 using AppIterator = std::map<int, ClientApplication>::iterator;
81 
82 struct GattClientService::impl : public GattServiceBase {
83     class GattClientProfileCallbackImplement;
84     class GattConnectionObserverImplement;
85 
86     int connectionObserverId_ = 0;
87     GattClientService &self_;
88     std::unique_ptr<GattClientProfileCallbackImplement> profileCallback_ = {nullptr};
89     std::unique_ptr<GattClientProfile> profile_ = {nullptr};
90     std::unique_ptr<GattConnectionObserverImplement> connectionObserver_ = {nullptr};
91     // connection handle <-> application ID
92     std::map<uint16_t, std::set<int>> handleMap_ = {};
93     // application ID <-> application entity
94     std::map<int, ClientApplication> clients_ = {};
95 
96     explicit impl(GattClientService &service);
97     ~impl();
98 
99     void RegisterApplication(
100         IGattClientCallback &callback, const GattDevice &device, std::promise<int> &promise, bool isShared);
101     void DeregisterApplication(int appId, std::promise<int> &promise);
102     void Connect(int appId, bool autoConnect);
103     void Disconnect(int appId);
104 
105     void DiscoveryServices(int appId);
106     void ReadCharacteristic(int appId, uint16_t handle);
107     void ReadCharacteristicByUuid(int appId, const Uuid &uuid);
108     void WriteCharacteristic(
109         int appId, uint16_t handle, const GattValue &value, int length, bool withoutRespond = false);
110     void SignedWriteCharacteristic(int appId, uint16_t handle, const GattValue &value, int length);
111     void ReadDescriptor(int appId, uint16_t handle);
112     void WriteDescriptor(int appId, uint16_t handle, const GattValue &value, int length);
113     void RequestExchangeMtu(int appId, int mtu);
114     void RequestConnectionPriority(int appId, int connPriority);
115     void GetServices(int appId, std::promise<void> &promise, std::vector<Service> &services);
116 
117     void OnDiscoverAllPrimaryServicesEvent(
118         int requestId, int ret, uint16_t connectHandle, const std::map<uint16_t, GattCache::Service> &services);
119     void OnFindIncludedServicesEvent(int requestId, int ret, uint16_t connectHandle, uint16_t serviceHandle,
120         const std::vector<GattCache::IncludeService> &services);
121     void OnDiscoverAllCharacteristicOfServiceEvent(int requestId, int ret, uint16_t connectHandle,
122         uint16_t serviceHandle, const std::map<uint16_t, GattCache::Characteristic> &characteristics);
123     void OnDiscoverAllCharacteristicDescriptorsEvent(
124         int requestId, int ret, uint16_t serviceHandle, uint16_t characteristicHandle);
125     void OnReadCharacteristicValueEvent(
126         int requestId, uint16_t valueHandle, GattValue &value, size_t length, int ret);
127     void OnWriteCharacteristicValueEvent(int requestId, uint16_t connectHandle, uint16_t valueHandle, int ret);
128     void OnReadDescriptorValueEvent(
129         int requestId, uint16_t valueHandle, GattValue &value, size_t length, int ret);
130     void OnWriteDescriptorValueEvent(int requestId, uint16_t connectHandle, uint16_t valueHandle, int ret);
131     void OnCharacteristicNotifyEvent(
132         uint16_t connectHandle, uint16_t valueHandle, GattValue &value, size_t length, bool needConfirm);
133     void OnExchangeMtuEvent(int requestId, uint16_t connectHandle, uint16_t rxMtu, bool status);
134     void OnConnect(const GattDevice &device, uint16_t connectionHandle, int ret);
135     void OnDisconnect(const GattDevice &device, uint16_t connectionHandle, int ret);
136     void OnConnectionChanged(const GattDevice &device, uint16_t connectionHandle, int state);
137     void OnConnectionParameterChanged(const GattDevice &device, int interval, int latency, int timeout, int status);
138     void OnConnetionManagerShutDown();
139 
140     std::optional<AppIterator> GetValidApplication(int appId);
141     std::optional<AppIterator> GetValidApplication(const GattDevice &device);
142 
143     void Enable();
144     void Disable();
145     void CleanApplication();
146     static void BuildService(GattCache::Service &src, Service &dest);
147     static void GattUpdatePowerStatus(const RawAddress &addr);
148 };
149 
GattClientService()150 GattClientService::GattClientService()
151     : utility::Context(PROFILE_NAME_GATT_CLIENT, "5.0.0"), pimpl(std::make_unique<GattClientService::impl>(*this))
152 {
153     LOG_INFO("ProfileService:%{public}s Create", Name().c_str());
154 }
155 
~GattClientService()156 GattClientService::~GattClientService()
157 {}
158 
GetContext()159 utility::Context *GattClientService::GetContext()
160 {
161     return this;
162 }
163 
Connect(int appId, bool autoConnect)164 int GattClientService::Connect(int appId, bool autoConnect)
165 {
166     if (!pimpl->InRunningState()) {
167         return GattStatus::REQUEST_NOT_SUPPORT;
168     }
169 
170     GetDispatcher()->PostTask(std::bind(&impl::Connect, pimpl.get(), appId, autoConnect));
171 
172     return GattStatus::GATT_SUCCESS;
173 }
174 
Disconnect(int appId)175 int GattClientService::Disconnect(int appId)
176 {
177     if (!pimpl->InRunningState()) {
178         return GattStatus::REQUEST_NOT_SUPPORT;
179     }
180 
181     GetDispatcher()->PostTask(std::bind(&impl::Disconnect, pimpl.get(), appId));
182 
183     return GattStatus::GATT_SUCCESS;
184 }
185 
GetConnectDevices()186 std::list<RawAddress> GattClientService::GetConnectDevices()
187 {
188     return std::list<RawAddress>();
189 }
190 
Connect(const RawAddress &device)191 int GattClientService::Connect(const RawAddress &device)
192 {
193     return 0;
194 }
195 
Disconnect(const RawAddress &device)196 int GattClientService::Disconnect(const RawAddress &device)
197 {
198     return 0;
199 }
200 
GetConnectState()201 int GattClientService::GetConnectState()
202 {
203     return 0;
204 }
205 
GetMaxConnectNum()206 int GattClientService::GetMaxConnectNum()
207 {
208     auto maxNum = GattConnectionManager::GetInstance().GetMaximumNumberOfConnections();
209     return maxNum.first + maxNum.second;
210 }
211 
RegisterApplication(IGattClientCallback &callback, const RawAddress &addr, uint8_t transport)212 int GattClientService::RegisterApplication(IGattClientCallback &callback, const RawAddress &addr, uint8_t transport)
213 {
214     if (!pimpl->InRunningState()) {
215         return GattStatus::REQUEST_NOT_SUPPORT;
216     }
217 
218     std::promise<int> promise;
219     std::future<int> future = promise.get_future();
220     GetDispatcher()->PostTask(std::bind(&impl::RegisterApplication,
221         pimpl.get(),
222         std::ref(callback),
223         GattDevice(addr, transport),
224         std::ref(promise),
225         false));
226 
227     return future.get();
228 }
229 
RegisterSharedApplication( IGattClientCallback &callback, const RawAddress &addr, uint8_t transport)230 int GattClientService::RegisterSharedApplication(
231     IGattClientCallback &callback, const RawAddress &addr, uint8_t transport)
232 {
233     if (!pimpl->InRunningState()) {
234         return GattStatus::REQUEST_NOT_SUPPORT;
235     }
236 
237     std::promise<int> promise;
238     std::future<int> future = promise.get_future();
239     GetDispatcher()->PostTask(std::bind(&impl::RegisterApplication,
240         pimpl.get(),
241         std::ref(callback),
242         GattDevice(addr, transport),
243         std::ref(promise),
244         true));
245 
246     return future.get();
247 }
248 
DeregisterApplication(int appId)249 int GattClientService::DeregisterApplication(int appId)
250 {
251     if (!pimpl->InRunningState()) {
252         return GattStatus::REQUEST_NOT_SUPPORT;
253     }
254 
255     std::promise<int> promise;
256     std::future<int> future = promise.get_future();
257     GetDispatcher()->PostTask(std::bind(&impl::DeregisterApplication, pimpl.get(), appId, std::ref(promise)));
258 
259     return future.get();
260 }
261 
DiscoveryServices(int appId)262 int GattClientService::DiscoveryServices(int appId)
263 {
264     if (!pimpl->InRunningState()) {
265         return GattStatus::REQUEST_NOT_SUPPORT;
266     }
267 
268     GetDispatcher()->PostTask(std::bind(&impl::DiscoveryServices, pimpl.get(), appId));
269 
270     return GattStatus::GATT_SUCCESS;
271 }
272 
ReadCharacteristic(int appId, const Characteristic &characteristic)273 int GattClientService::ReadCharacteristic(int appId, const Characteristic &characteristic)
274 {
275     if (!pimpl->InRunningState()) {
276         return GattStatus::REQUEST_NOT_SUPPORT;
277     }
278 
279     GetDispatcher()->PostTask(std::bind(&impl::ReadCharacteristic, pimpl.get(), appId, characteristic.handle_));
280 
281     return GattStatus::GATT_SUCCESS;
282 }
283 
ReadCharacteristicByUuid(int appId, const Uuid &uuid)284 int GattClientService::ReadCharacteristicByUuid(int appId, const Uuid &uuid)
285 {
286     if (!pimpl->InRunningState()) {
287         return GattStatus::REQUEST_NOT_SUPPORT;
288     }
289 
290     GetDispatcher()->PostTask(std::bind(&impl::ReadCharacteristicByUuid, pimpl.get(), appId, uuid));
291 
292     return GattStatus::GATT_SUCCESS;
293 }
294 
WriteCharacteristic(int appId, Characteristic &characteristic, bool withoutRespond)295 int GattClientService::WriteCharacteristic(int appId, Characteristic &characteristic, bool withoutRespond)
296 {
297     if (!pimpl->InRunningState()) {
298         return GattStatus::REQUEST_NOT_SUPPORT;
299     }
300 
301     if (characteristic.value_ == nullptr || characteristic.length_ <= 0) {
302         return GattStatus::INVALID_PARAMETER;
303     }
304 
305     auto sharedPtr = pimpl->MoveToGattValue(characteristic.value_);
306     GetDispatcher()->PostTask(std::bind(&impl::WriteCharacteristic,
307         pimpl.get(),
308         appId,
309         characteristic.handle_,
310         sharedPtr,
311         characteristic.length_,
312         withoutRespond));
313 
314     return GattStatus::GATT_SUCCESS;
315 }
316 
SignedWriteCharacteristic(int appId, Characteristic &characteristic)317 int GattClientService::SignedWriteCharacteristic(int appId, Characteristic &characteristic)
318 {
319     if (!pimpl->InRunningState()) {
320         return GattStatus::REQUEST_NOT_SUPPORT;
321     }
322 
323     if (characteristic.value_ == nullptr || characteristic.length_ <= 0) {
324         return GattStatus::INVALID_PARAMETER;
325     }
326 
327     auto sharedPtr = pimpl->MoveToGattValue(characteristic.value_);
328     GetDispatcher()->PostTask(std::bind(&impl::SignedWriteCharacteristic,
329         pimpl.get(),
330         appId,
331         characteristic.handle_,
332         sharedPtr,
333         characteristic.length_));
334 
335     return GattStatus::GATT_SUCCESS;
336 }
337 
ReadDescriptor(int appId, const Descriptor &descriptor)338 int GattClientService::ReadDescriptor(int appId, const Descriptor &descriptor)
339 {
340     if (!pimpl->InRunningState()) {
341         return GattStatus::REQUEST_NOT_SUPPORT;
342     }
343 
344     GetDispatcher()->PostTask(std::bind(&impl::ReadDescriptor, pimpl.get(), appId, descriptor.handle_));
345 
346     return GattStatus::GATT_SUCCESS;
347 }
348 
WriteDescriptor(int appId, Descriptor &descriptor)349 int GattClientService::WriteDescriptor(int appId, Descriptor &descriptor)
350 {
351     LOG_INFO("%{public}s: appId=%{public}d", __FUNCTION__, appId);
352     if (!pimpl->InRunningState()) {
353         LOG_ERROR("%{public}s: pimpl->InRunningState is false", __FUNCTION__);
354         return GattStatus::REQUEST_NOT_SUPPORT;
355     }
356 
357     if (descriptor.value_ == nullptr || descriptor.length_ <= 0) {
358         return GattStatus::INVALID_PARAMETER;
359     }
360 
361     auto sharedPtr = pimpl->MoveToGattValue(descriptor.value_);
362     GetDispatcher()->PostTask(
363         std::bind(&impl::WriteDescriptor, pimpl.get(), appId, descriptor.handle_, sharedPtr, descriptor.length_));
364 
365     return GattStatus::GATT_SUCCESS;
366 }
367 
RequestExchangeMtu(int appId, int mtu)368 int GattClientService::RequestExchangeMtu(int appId, int mtu)
369 {
370     LOG_INFO("%{public}s: appId=%{public}d, mtu=%{public}d", __FUNCTION__, appId, mtu);
371     if (!pimpl->InRunningState()) {
372         LOG_ERROR("%{public}s: pimpl->InRunningState is false", __FUNCTION__);
373         return GattStatus::REQUEST_NOT_SUPPORT;
374     }
375 
376     GetDispatcher()->PostTask(std::bind(&impl::RequestExchangeMtu, pimpl.get(), appId, mtu));
377 
378     return GattStatus::GATT_SUCCESS;
379 }
380 
GetAllDevice()381 std::vector<GattDevice> GattClientService::GetAllDevice()
382 {
383     std::vector<GattDevice> devices;
384     GattConnectionManager::GetInstance().GetDevices(devices);
385 
386     return devices;
387 }
388 
RequestConnectionPriority(int appId, int connPriority)389 int GattClientService::RequestConnectionPriority(int appId, int connPriority)
390 {
391     if (!pimpl->InRunningState()) {
392         return GattStatus::REQUEST_NOT_SUPPORT;
393     }
394 
395     if (connPriority != static_cast<int>(GattConnectionPriority::LOW_POWER) &&
396         connPriority != static_cast<int>(GattConnectionPriority::BALANCED) &&
397         connPriority != static_cast<int>(GattConnectionPriority::HIGH)) {
398         return GattStatus::INVALID_PARAMETER;
399     }
400 
401     GetDispatcher()->PostTask(std::bind(&impl::RequestConnectionPriority, pimpl.get(), appId, connPriority));
402 
403     return GattStatus::GATT_SUCCESS;
404 }
405 
GetServices(int appId)406 std::vector<Service> GattClientService::GetServices(int appId)
407 {
408     if (!pimpl->InRunningState()) {
409         return std::vector<Service>();
410     }
411 
412     std::promise<void> promise;
413     std::future<void> future = promise.get_future();
414     std::vector<Service> services;
415     GetDispatcher()->PostTask(std::bind(&impl::GetServices, pimpl.get(), appId, std::ref(promise), std::ref(services)));
416     future.wait();
417 
418     return services;
419 }
420 
421 class GattClientService::impl::GattConnectionObserverImplement : public GattConnectionObserver {
422 public:
423     void OnConnect(const GattDevice &device, uint16_t connectionHandle, int ret) override
424     {
425         HILOGI("addr: %{public}s ret: %{public}d", GetEncryptAddr(device.addr_.GetAddress()).c_str(), ret);
426         service_.GetDispatcher()->PostTask(
427             std::bind(&impl::OnConnect, service_.pimpl.get(), device, connectionHandle, ret));
428     }
429 
430     void OnDisconnect(const GattDevice &device, uint16_t connectionHandle, int ret) override
431     {
432         HILOGI("addr: %{public}s ret: %{public}d", GetEncryptAddr(device.addr_.GetAddress()).c_str(), ret);
433         service_.GetDispatcher()->PostTask(
434             std::bind(&impl::OnDisconnect, service_.pimpl.get(), device, connectionHandle, ret));
435     }
436 
437     void OnConnectionChanged(const GattDevice &device, uint16_t connectionHandle, int state) override
438     {
439         HILOGI("addr: %{public}s ret: %{public}d", GetEncryptAddr(device.addr_.GetAddress()).c_str(), state);
440         service_.GetDispatcher()->PostTask(std::bind(&impl::OnConnectionChanged,
441             service_.pimpl.get(), device, connectionHandle, state));
442     }
443 
444     void OnConnectionParameterChanged(
445         const GattDevice &device, int interval, int latency, int timeout, int status) override
446     {
447         service_.GetDispatcher()->PostTask(std::bind(
448             &impl::OnConnectionParameterChanged, service_.pimpl.get(), device, interval, latency, timeout, status));
449     }
450 
451     void OnShutDown() override
452     {
453         service_.GetDispatcher()->PostTask(std::bind(&impl::OnConnetionManagerShutDown, service_.pimpl.get()));
454     }
455 
GattConnectionObserverImplement(GattClientService &service)456     explicit GattConnectionObserverImplement(GattClientService &service) : service_(service)
457     {}
~GattConnectionObserverImplement()458     ~GattConnectionObserverImplement()
459     {}
460 
461 private:
462     GattClientService &service_;
463 };
464 
465 class GattClientService::impl::GattClientProfileCallbackImplement : public GattClientProfileCallback {
466 public:
467     void OnDiscoverAllPrimaryServicesEvent(
468         int reqId, int ret, uint16_t connectHandle, const std::map<uint16_t, GattCache::Service> &services) override
469     {
470         service_.GetDispatcher()->PostTask(std::bind(&impl::OnDiscoverAllPrimaryServicesEvent,
471             service_.pimpl.get(),
472             reqId,
473             ret,
474             connectHandle,
475             std::ref(services)));
476     }
477 
478     void OnFindIncludedServicesEvent(int reqId, int ret, uint16_t connectHandle, uint16_t serviceHandle,
479         const std::vector<GattCache::IncludeService> &services) override
480     {
481         service_.GetDispatcher()->PostTask(std::bind(&impl::OnFindIncludedServicesEvent,
482             service_.pimpl.get(),
483             reqId,
484             ret,
485             connectHandle,
486             serviceHandle,
487             std::ref(services)));
488     }
489 
490     void OnDiscoverAllCharacteristicOfServiceEvent(int reqId, int ret, uint16_t connectHandle, uint16_t serviceHandle,
491         const std::map<uint16_t, GattCache::Characteristic> &characteristics) override
492     {
493         service_.GetDispatcher()->PostTask(std::bind(&impl::OnDiscoverAllCharacteristicOfServiceEvent,
494             service_.pimpl.get(),
495             reqId,
496             ret,
497             connectHandle,
498             serviceHandle,
499             std::ref(characteristics)));
500     }
501 
502     void OnDiscoverAllCharacteristicDescriptorsEvent(
503         int reqId, int ret, uint16_t serviceHandle, uint16_t characteristicHandle,
504         const std::map<uint16_t, GattCache::Descriptor> &descriptors) override
505     {
506         service_.GetDispatcher()->PostTask(std::bind(&impl::OnDiscoverAllCharacteristicDescriptorsEvent,
507             service_.pimpl.get(),
508             reqId,
509             ret,
510             serviceHandle,
511             characteristicHandle));
512     }
513 
514     void OnReadCharacteristicValueEvent(
515         int reqId, uint16_t handle, GattValue &value, size_t len, int result) override
516     {
517         service_.GetDispatcher()->PostTask(std::bind(&impl::OnReadCharacteristicValueEvent,
518             service_.pimpl.get(),
519             reqId,
520             handle,
521             value,
522             len,
523             result));
524     }
525 
526     void OnWriteCharacteristicValueEvent(int reqId, uint16_t connectHandle, uint16_t handle, int ret) override
527     {
528         service_.GetDispatcher()->PostTask(
529             std::bind(&impl::OnWriteCharacteristicValueEvent, service_.pimpl.get(), reqId, connectHandle, handle, ret));
530     }
531 
532     void OnReadDescriptorValueEvent(
533         int reqId, uint16_t handle, GattValue &value, size_t len, int result) override
534     {
535         service_.GetDispatcher()->PostTask(std::bind(
536             &impl::OnReadDescriptorValueEvent, service_.pimpl.get(), reqId, handle, value, len, result));
537     }
538 
539     void OnWriteDescriptorValueEvent(int reqId, uint16_t connectHandle, uint16_t handle, int ret) override
540     {
541         service_.GetDispatcher()->PostTask(
542             std::bind(&impl::OnWriteDescriptorValueEvent, service_.pimpl.get(), reqId, connectHandle, handle, ret));
543     }
544 
545     void OnCharacteristicNotifyEvent(
546         uint16_t connectHandle, uint16_t handle, GattValue &value, size_t len, bool needConfirm) override
547     {
548         service_.GetDispatcher()->PostTask(std::bind(
549             &impl::OnCharacteristicNotifyEvent, service_.pimpl.get(), connectHandle, handle, value, len, needConfirm));
550     }
551 
552     void OnExchangeMtuEvent(int reqId, uint16_t connectHandle, uint16_t rxMtu, bool status) override
553     {
554         service_.GetDispatcher()->PostTask(
555             std::bind(&impl::OnExchangeMtuEvent, service_.pimpl.get(), reqId, connectHandle, rxMtu, status));
556     }
557 
GattClientProfileCallbackImplement(GattClientService &service)558     GattClientProfileCallbackImplement(GattClientService &service) : service_(service)
559     {}
~GattClientProfileCallbackImplement()560     ~GattClientProfileCallbackImplement()
561     {}
562 
563 private:
564     GattClientService &service_;
565 };
566 
impl(GattClientService &service)567 GattClientService::impl::impl(GattClientService &service)
568     : self_(service),
569       profileCallback_(std::make_unique<GattClientProfileCallbackImplement>(service)),
570       profile_(std::make_unique<GattClientProfile>(profileCallback_.get(), service.GetDispatcher())),
571       connectionObserver_(std::make_unique<GattConnectionObserverImplement>(service))
572 {
573     connectionObserverId_ = GattConnectionManager::GetInstance().RegisterObserver(*connectionObserver_);
574     if (connectionObserverId_ < 0) {
575         LOG_ERROR("%{public}s:%{public}s:%{public}d register to connection manager failed!",
576             __FILE__, __FUNCTION__, __LINE__);
577     }
578 }
579 
~impl()580 GattClientService::impl::~impl()
581 {
582     GattConnectionManager::GetInstance().DeregisterObserver(connectionObserverId_);
583 }
584 
Connect(int appId, bool autoConnect)585 void GattClientService::impl::Connect(int appId, bool autoConnect)
586 {
587     static const int TUPLE_INDEX_FIRST = 0;
588     static const int TUPLE_INDEX_SECOND = 1;
589     static const int TUPLE_INDEX_THIRD = 2;
590     auto client = GetValidApplication(appId);
591     if (client.has_value()) {
592         int result = GattStatus::GATT_SUCCESS;
593         auto &manager = GattConnectionManager::GetInstance();
594         auto &device = client.value()->second.connection_.GetDevice();
595 
596         auto deviceInfo = GattConnectionManager::GetInstance().GetDeviceInformation(device);
597         if (std::get<TUPLE_INDEX_FIRST>(deviceInfo).compare(GattConnectionManager::Device::STATE_IDLE) == 0 ||
598             std::get<TUPLE_INDEX_FIRST>(deviceInfo).compare(GattConnectionManager::Device::STATE_DISCONNECTED) == 0) {
599             result = manager.Connect(device, autoConnect);
600             if (GattStatus::GATT_SUCCESS != result) {
601                 client.value()->second.connState_ = ConvertConnectionState(manager.GetDeviceState(device));
602                 client.value()->second.callback_.OnConnectionStateChanged(result, client.value()->second.connState_);
603             }
604         } else {
605             if (std::get<TUPLE_INDEX_FIRST>(deviceInfo).compare(GattConnectionManager::Device::STATE_CONNECTED) == 0) {
606                 client.value()->second.connection_.SetHandle(std::get<TUPLE_INDEX_SECOND>(deviceInfo));
607                 client.value()->second.connection_.SetMtu(std::get<TUPLE_INDEX_THIRD>(deviceInfo));
608 
609                 auto it = handleMap_.emplace(
610                     std::make_pair<int, std::set<int>>(std::get<TUPLE_INDEX_SECOND>(deviceInfo), {}));
611                 it.first->second.emplace(appId);
612 
613                 result = GattStatus::GATT_SUCCESS;
614                 GattConnectionManager::GetInstance().SetConnectionType(device, autoConnect);
615             }
616 
617             client.value()->second.connState_ = ConvertConnectionState(std::get<TUPLE_INDEX_FIRST>(deviceInfo));
618             client.value()->second.callback_.OnConnectionStateChanged(result, client.value()->second.connState_);
619         }
620     }
621 }
622 
Disconnect(int appId)623 void GattClientService::impl::Disconnect(int appId)
624 {
625     bool needDisconnect = true;
626     auto client = GetValidApplication(appId);
627     if (client.has_value()) {
628         auto &manager = GattConnectionManager::GetInstance();
629         auto &device = client.value()->second.connection_.GetDevice();
630 
631         client.value()->second.connState_ = (int)BTConnectState::DISCONNECTED;
632         auto map = handleMap_.find(client.value()->second.connection_.GetHandle());
633         if (map != handleMap_.end()) {
634             map->second.erase(appId);
635             for (auto aid : map->second) {
636                 auto app = GetValidApplication(aid);
637                 if (app.has_value() && app.value()->second.connState_ != (int)BTConnectState::DISCONNECTED) {
638                     needDisconnect = false;
639                     break;
640                 }
641             }
642         } else {
643             needDisconnect = false;
644         }
645 
646         if (!needDisconnect) {
647             client.value()->second.callback_.OnConnectionStateChanged(
648                 GattStatus::GATT_SUCCESS, client.value()->second.connState_);
649             return;
650         }
651 
652         int result = manager.Disconnect(device);
653         if (GattStatus::GATT_SUCCESS != result) {
654             if (device.transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
655                 IPowerManager::GetInstance().StatusUpdate(
656                     RequestStatus::CONNECT_OFF, PROFILE_NAME_GATT_CLIENT, device.addr_);
657             }
658 
659             client.value()->second.callback_.OnConnectionStateChanged(
660                 result, ConvertConnectionState(manager.GetDeviceState(device)));
661         }
662     }
663 }
664 
DiscoveryServices(int appId)665 void GattClientService::impl::DiscoveryServices(int appId)
666 {
667     auto it = GetValidApplication(appId);
668     if (it.has_value()) {
669         auto &client = it.value()->second;
670         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
671             client.callback_.OnServicesDiscovered(GattStatus::REQUEST_NOT_SUPPORT);
672             return;
673         }
674 
675         if (client.discover_.tasks_.size() != 0) {
676             client.callback_.OnServicesDiscovered(GattStatus::REMOTE_DEVICE_BUSY);
677             return;
678         }
679 
680         profile_->ClearCacheMap(client.connection_.GetHandle());
681         client.discover_.Clear();
682 
683         ClientApplication::Discover::Task task = {};
684         task.type_ = ClientApplication::Discover::Task::Type::SERVICE;
685         task.startHandle_ = MIN_ATTRIBUTE_HANDLE;
686         task.endHandle_ = MAX_ATTRIBUTE_HANDLE;
687         client.discover_.tasks_.push(task);
688 
689         client.discover_.DiscoverNext(appId);
690     }
691 }
692 
ReadCharacteristic(int appId, uint16_t handle)693 void GattClientService::impl::ReadCharacteristic(int appId, uint16_t handle)
694 {
695     auto it = GetValidApplication(appId);
696     if (it.has_value()) {
697         auto &client = it.value()->second;
698         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
699             client.callback_.OnCharacteristicRead(GattStatus::REQUEST_NOT_SUPPORT, Characteristic(handle));
700             return;
701         }
702         profile_->ReadCharacteristicValue(appId, client.connection_.GetHandle(), handle + 1);
703     }
704 }
705 
ReadCharacteristicByUuid(int appId, const Uuid &uuid)706 void GattClientService::impl::ReadCharacteristicByUuid(int appId, const Uuid &uuid)
707 {
708     auto it = GetValidApplication(appId);
709     if (it.has_value()) {
710         auto &client = it.value()->second;
711         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
712             LOG_DEBUG("%{public}s: %{public}hu: is not found in the map", __func__, client.connection_.GetHandle());
713             client.callback_.OnCharacteristicRead(GattStatus::REQUEST_NOT_SUPPORT, Characteristic(0));
714             return;
715         }
716         profile_->ReadUsingCharacteristicByUuid(appId, client.connection_.GetHandle(), uuid);
717     }
718 }
719 
WriteCharacteristic( int appId, uint16_t handle, const GattValue &value, int length, bool withoutRespond)720 void GattClientService::impl::WriteCharacteristic(
721     int appId, uint16_t handle, const GattValue &value, int length, bool withoutRespond)
722 {
723     auto it = GetValidApplication(appId);
724     if (it.has_value()) {
725         auto &client = it.value()->second;
726         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
727             if (!withoutRespond) {
728                 client.callback_.OnCharacteristicWrite(GattStatus::REQUEST_NOT_SUPPORT, Characteristic(handle));
729             }
730             return;
731         }
732         if (withoutRespond) {
733             profile_->WriteWithoutResponse(appId, client.connection_.GetHandle(), handle + 1, value, length);
734         } else {
735             profile_->WriteCharacteristicValue(appId, client.connection_.GetHandle(), handle + 1, value, length);
736         }
737     }
738 }
739 
SignedWriteCharacteristic(int appId, uint16_t handle, const GattValue &value, int length)740 void GattClientService::impl::SignedWriteCharacteristic(int appId, uint16_t handle, const GattValue &value, int length)
741 {
742     auto it = GetValidApplication(appId);
743     if (it.has_value()) {
744         auto &client = it.value()->second;
745         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
746             return;
747         }
748 
749         profile_->SignedWriteWithoutResponse(appId, client.connection_.GetHandle(), handle + 1, value, length);
750     }
751 }
752 
ReadDescriptor(int appId, uint16_t handle)753 void GattClientService::impl::ReadDescriptor(int appId, uint16_t handle)
754 {
755     auto it = GetValidApplication(appId);
756     if (it.has_value()) {
757         auto &client = it.value()->second;
758         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
759             client.callback_.OnDescriptorRead(GattStatus::REQUEST_NOT_SUPPORT, Descriptor(handle));
760             return;
761         }
762         profile_->ReadDescriptorValue(appId, client.connection_.GetHandle(), handle);
763     }
764 }
765 
WriteDescriptor(int appId, uint16_t handle, const GattValue &value, int length)766 void GattClientService::impl::WriteDescriptor(int appId, uint16_t handle, const GattValue &value, int length)
767 {
768     LOG_INFO("%{public}s: appId=%{public}d", __FUNCTION__, appId);
769     auto it = GetValidApplication(appId);
770     if (it.has_value()) {
771         auto &client = it.value()->second;
772         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
773             client.callback_.OnDescriptorWrite(GattStatus::REQUEST_NOT_SUPPORT, Descriptor(handle));
774             return;
775         }
776         profile_->WriteDescriptorValue(appId, client.connection_.GetHandle(), handle, value, length);
777     }
778 }
779 
RequestExchangeMtu(int appId, int mtu)780 void GattClientService::impl::RequestExchangeMtu(int appId, int mtu)
781 {
782     LOG_INFO("%{public}s: appId=%{public}d, mtu=%{public}d", __FUNCTION__, appId, mtu);
783     auto it = GetValidApplication(appId);
784     if (it.has_value()) {
785         auto &client = it.value()->second;
786         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
787             LOG_ERROR("%{public}s: failed and return REQUEST_NOT_SUPPORT(-18)", __FUNCTION__);
788             client.callback_.OnMtuChanged(GattStatus::REQUEST_NOT_SUPPORT, mtu);
789             return;
790         }
791         profile_->ExchangeMtu(appId, client.connection_.GetHandle(), mtu);
792     }
793 }
794 
RequestConnectionPriority(int appId, int connPriority)795 void GattClientService::impl::RequestConnectionPriority(int appId, int connPriority)
796 {
797     LOG_INFO("%{public}s: appId=%{public}d, priority=%{public}d", __FUNCTION__, appId, connPriority);
798     auto it = GetValidApplication(appId);
799     if (it.has_value()) {
800         auto &client = it.value()->second;
801         if (handleMap_.find(client.connection_.GetHandle()) == handleMap_.end()) {
802             LOG_ERROR("%{public}s: failed and return REQUEST_NOT_SUPPORT(-18)", __FUNCTION__);
803             client.callback_.OnConnectionParameterChanged(0, 0, 0, GattStatus::REQUEST_NOT_SUPPORT);
804             return;
805         }
806         int result = GattConnectionManager::GetInstance().RequestConnectionPriority(
807             client.connection_.GetHandle(), connPriority);
808         if (GattStatus::GATT_SUCCESS != result) {
809             client.callback_.OnConnectionParameterChanged(0, 0, 0, result);
810         }
811     }
812 }
813 
GetServices( int appId, std::promise<void> &promise, std::vector<Service> &services)814 void GattClientService::impl::GetServices(
815     int appId, std::promise<void> &promise, std::vector<Service> &services)
816 {
817     auto client = GetValidApplication(appId);
818     if (client.has_value() && client.value()->second.connState_ == (int)BTConnectState::CONNECTED) {
819         auto svcs = profile_->GetServices(client.value()->second.connection_.GetHandle());
820         if (svcs != nullptr) {
821             for (auto &svc : *svcs) {
822                 Service svcTmp(svc.second.uuid_, svc.second.handle_, svc.second.handle_, svc.second.endHandle_);
823 
824                 BuildService(svc.second, svcTmp);
825                 services.push_back(std::move(svcTmp));
826             }
827         }
828     }
829 
830     promise.set_value();
831 }
832 
OnDiscoverAllPrimaryServicesEvent( int requestId, int ret, uint16_t connectHandle, const std::map<uint16_t, GattCache::Service> &services)833 void GattClientService::impl::OnDiscoverAllPrimaryServicesEvent(
834     int requestId, int ret, uint16_t connectHandle, const std::map<uint16_t, GattCache::Service> &services)
835 {
836     auto it = GetValidApplication(requestId);
837     if (it.has_value()) {
838         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
839             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
840         }
841 
842         if (GattStatus::GATT_SUCCESS == ret) {
843             for (auto &serv : services) {
844                 ClientApplication::Discover::Task task = {};
845                 task.type_ = ClientApplication::Discover::Task::Type::INCLUDE_SERVICE;
846                 task.startHandle_ = serv.second.handle_;
847                 task.endHandle_ = serv.second.endHandle_;
848                 it.value()->second.discover_.tasks_.push(task);
849 
850                 task.type_ = ClientApplication::Discover::Task::Type::CHARACTERISTICS;
851                 it.value()->second.discover_.tasks_.push(task);
852             }
853             if (!it.value()->second.discover_.DiscoverNext(requestId)) {
854                 return;
855             }
856         }
857 
858         it.value()->second.discover_.Clear();
859         it.value()->second.callback_.OnServicesDiscovered(ret);
860     }
861 }
862 
OnFindIncludedServicesEvent(int requestId, int ret, uint16_t connectHandle, uint16_t serviceHandle, const std::vector<GattCache::IncludeService> &services)863 void GattClientService::impl::OnFindIncludedServicesEvent(int requestId, int ret, uint16_t connectHandle,
864     uint16_t serviceHandle, const std::vector<GattCache::IncludeService> &services)
865 {
866     auto it = GetValidApplication(requestId);
867     if (it.has_value()) {
868         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
869             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
870         }
871 
872         if (GattStatus::GATT_SUCCESS == ret) {
873             for (auto &serv : services) {
874                 ClientApplication::Discover::Task task = {};
875                 task.type_ = ClientApplication::Discover::Task::Type::SERVICE;
876                 task.startHandle_ = serv.startHandle_;
877                 task.endHandle_ = serv.startHandle_;
878 
879                 it.value()->second.discover_.tasks_.push(task);
880             }
881             if (!it.value()->second.discover_.DiscoverNext(requestId)) {
882                 return;
883             }
884         }
885 
886         it.value()->second.discover_.Clear();
887         it.value()->second.callback_.OnServicesDiscovered(ret);
888     }
889 }
890 
OnDiscoverAllCharacteristicOfServiceEvent(int requestId, int ret, uint16_t connectHandle, uint16_t serviceHandle, const std::map<uint16_t, GattCache::Characteristic> &characteristics)891 void GattClientService::impl::OnDiscoverAllCharacteristicOfServiceEvent(int requestId, int ret, uint16_t connectHandle,
892     uint16_t serviceHandle, const std::map<uint16_t, GattCache::Characteristic> &characteristics)
893 {
894     auto it = GetValidApplication(requestId);
895     if (it.has_value()) {
896         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
897             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
898         }
899 
900         if (GattStatus::GATT_SUCCESS == ret) {
901             for (auto &ccc : characteristics) {
902                 ClientApplication::Discover::Task task = {};
903                 task.type_ = ClientApplication::Discover::Task::Type::DESCRIPTOR;
904                 task.startHandle_ = ccc.second.handle_;
905                 task.endHandle_ = profile_->GetCharacteristicEndHandle(
906                     it.value()->second.connection_.GetHandle(), serviceHandle, ccc.second.handle_);
907 
908                 it.value()->second.discover_.tasks_.push(task);
909             }
910 
911             if (!it.value()->second.discover_.DiscoverNext(requestId)) {
912                 return;
913             }
914         }
915 
916         it.value()->second.discover_.Clear();
917         it.value()->second.callback_.OnServicesDiscovered(ret);
918     }
919 }
920 
OnDiscoverAllCharacteristicDescriptorsEvent(int requestId, int ret, uint16_t serviceHandle, uint16_t characteristicHandle)921 void GattClientService::impl::OnDiscoverAllCharacteristicDescriptorsEvent(int requestId, int ret,
922     uint16_t serviceHandle, uint16_t characteristicHandle)
923 {
924     auto it = GetValidApplication(requestId);
925     if (it.has_value()) {
926         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
927             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
928         }
929 
930         if (GattStatus::GATT_SUCCESS == ret) {
931             if (!it.value()->second.discover_.DiscoverNext(requestId)) {
932                 return;
933             }
934         }
935 
936         it.value()->second.discover_.Clear();
937         it.value()->second.callback_.OnServicesDiscovered(ret);
938     }
939 }
940 
OnReadCharacteristicValueEvent( int requestId, uint16_t valueHandle, GattValue &value, size_t length, int ret)941 void GattClientService::impl::OnReadCharacteristicValueEvent(
942     int requestId, uint16_t valueHandle, GattValue &value, size_t length, int ret)
943 {
944     auto it = GetValidApplication(requestId);
945     if (it.has_value()) {
946         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
947             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
948         }
949 
950         Characteristic gattCCC(valueHandle - 1);
951         if (value) {
952             gattCCC.value_ = std::move(*value);
953             gattCCC.length_ = length;
954             it.value()->second.callback_.OnCharacteristicRead(ret, gattCCC);
955         } else {
956             it.value()->second.callback_.OnCharacteristicRead(ret, gattCCC);
957         }
958     }
959 }
960 
OnWriteCharacteristicValueEvent( int requestId, uint16_t connectHandle, uint16_t valueHandle, int ret)961 void GattClientService::impl::OnWriteCharacteristicValueEvent(
962     int requestId, uint16_t connectHandle, uint16_t valueHandle, int ret)
963 {
964     auto it = GetValidApplication(requestId);
965     if (it.has_value()) {
966         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
967             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
968         }
969 
970         it.value()->second.callback_.OnCharacteristicWrite(ret, Characteristic());
971     }
972 }
973 
OnReadDescriptorValueEvent( int requestId, uint16_t valueHandle, GattValue &value, size_t length, int ret)974 void GattClientService::impl::OnReadDescriptorValueEvent(
975     int requestId, uint16_t valueHandle, GattValue &value, size_t length, int ret)
976 {
977     auto it = GetValidApplication(requestId);
978     if (it.has_value()) {
979         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
980             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
981         }
982 
983         Descriptor gattDescriptor;
984         if (value) {
985             gattDescriptor.value_ = std::move(*value);
986             gattDescriptor.length_ = length;
987             it.value()->second.callback_.OnDescriptorRead(ret, gattDescriptor);
988         } else {
989             it.value()->second.callback_.OnDescriptorRead(ret, gattDescriptor);
990         }
991     }
992 }
993 
OnWriteDescriptorValueEvent( int requestId, uint16_t connectHandle, uint16_t valueHandle, int ret)994 void GattClientService::impl::OnWriteDescriptorValueEvent(
995     int requestId, uint16_t connectHandle, uint16_t valueHandle, int ret)
996 {
997     auto it = GetValidApplication(requestId);
998     if (it.has_value()) {
999         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
1000             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
1001         }
1002 
1003         it.value()->second.callback_.OnDescriptorWrite(ret, Descriptor());
1004     }
1005 }
1006 
OnCharacteristicNotifyEvent( uint16_t connectHandle, uint16_t valueHandle, GattValue &value, size_t length, bool needConfirm)1007 void GattClientService::impl::OnCharacteristicNotifyEvent(
1008     uint16_t connectHandle, uint16_t valueHandle, GattValue &value, size_t length, bool needConfirm)
1009 {
1010     if (needConfirm) {
1011         profile_->HandleValueConfirmation(connectHandle);
1012     }
1013 
1014     for (auto appId : handleMap_.find(connectHandle)->second) {
1015         auto client = GetValidApplication(appId);
1016         if (!client.has_value()) {
1017             continue;
1018         }
1019 
1020         if (client.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
1021             GattUpdatePowerStatus(client.value()->second.connection_.GetDevice().addr_);
1022         }
1023 
1024         auto ccc = profile_->GetCharacteristic(connectHandle, valueHandle);
1025         if (ccc == nullptr) {
1026             LOG_ERROR("%{public}s:%{public}d:%{public}s Gatt Cache Error: Can not find Characteristic by value handle.",
1027                 __FILE__,
1028                 __LINE__,
1029                 __FUNCTION__);
1030             return;
1031         }
1032 
1033         if (Uuid::ConvertFrom16Bits(UUID_SERVICE_CHANGED) == ccc->uuid_) {
1034             client.value()->second.callback_.OnServicesChanged(std::vector<Service>());
1035         } else {
1036             Characteristic gattCCC(ccc->uuid_, ccc->handle_, ccc->properties_);
1037             gattCCC.value_ = std::make_unique<uint8_t[]>(length);
1038             if (memcpy_s(gattCCC.value_.get(), length, (*value).get(), length) != EOK) {
1039                 return;
1040             }
1041             gattCCC.length_ = length;
1042             client.value()->second.callback_.OnCharacteristicChanged(gattCCC);
1043         }
1044     }
1045 }
1046 
OnExchangeMtuEvent(int requestId, uint16_t connectHandle, uint16_t rxMtu, bool status)1047 void GattClientService::impl::OnExchangeMtuEvent(int requestId, uint16_t connectHandle, uint16_t rxMtu, bool status)
1048 {
1049     auto it = GetValidApplication(requestId);
1050     if (it.has_value()) {
1051         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
1052             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
1053         }
1054 
1055         it.value()->second.callback_.OnMtuChanged(status ? GattStatus::GATT_SUCCESS : GattStatus::GATT_FAILURE, rxMtu);
1056     }
1057 }
1058 
RegisterApplication( IGattClientCallback &callback, const GattDevice &device, std::promise<int> &promise, bool isShared)1059 void GattClientService::impl::RegisterApplication(
1060     IGattClientCallback &callback, const GattDevice &device, std::promise<int> &promise, bool isShared)
1061 {
1062     int result = GattStatus::DEVICE_ALREADY_BIND;
1063     int appid = GattServiceBase::GetApplicationId();
1064     if (clients_.size() >= MAXIMUM_NUMBER_APPLICATION) {
1065         promise.set_value(GattStatus::MAX_APPLICATIONS);
1066         return;
1067     }
1068 
1069     if (isShared) {
1070         if (clients_.emplace(appid, ClientApplication(callback, device, *profile_, isShared)).second) {
1071             result = GattStatus::GATT_SUCCESS;
1072         } else {
1073             result = GattStatus::GATT_FAILURE;
1074             LOG_ERROR("%{public}s:%{public}s:%{public}d register to application failed! same application ID!",
1075                 __FILE__, __FUNCTION__, __LINE__);
1076         }
1077     } else {
1078         auto app = GetValidApplication(device);
1079         if (!app.has_value()) {
1080             if (clients_.emplace(appid, ClientApplication(callback, device, *profile_, isShared)).second) {
1081                 result = GattStatus::GATT_SUCCESS;
1082             } else {
1083                 result = GattStatus::GATT_FAILURE;
1084                 LOG_ERROR("%{public}s:%{public}s:%{public}d register to application failed! same application ID!",
1085                     __FILE__,
1086                     __FUNCTION__,
1087                     __LINE__);
1088             }
1089         }
1090     }
1091 
1092     promise.set_value(((result == GattStatus::GATT_SUCCESS) ? appid : result));
1093 }
1094 
DeregisterApplication(int appId, std::promise<int> &promise)1095 void GattClientService::impl::DeregisterApplication(int appId, std::promise<int> &promise)
1096 {
1097     auto client = GetValidApplication(appId);
1098     if (client.has_value()) {
1099         auto map = handleMap_.find(client.value()->second.connection_.GetHandle());
1100         if (map != handleMap_.end()) {
1101             map->second.erase(appId);
1102         }
1103         clients_.erase(client.value());
1104     }
1105 
1106     promise.set_value(GattStatus::GATT_SUCCESS);
1107 }
1108 
OnConnect(const GattDevice &device, uint16_t connectionHandle, int ret)1109 void GattClientService::impl::OnConnect(const GattDevice &device, uint16_t connectionHandle, int ret)
1110 {
1111     auto map = handleMap_.emplace(std::make_pair<int, std::set<int>>(connectionHandle, {}));
1112     if (device.transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
1113         IPowerManager::GetInstance().StatusUpdate(
1114             RequestStatus::CONNECT_ON, PROFILE_NAME_GATT_CLIENT, device.addr_);
1115     }
1116 
1117     for (auto &it : clients_) {
1118         if (it.second.connection_.GetDevice() == device) {
1119             LOG_DEBUG("%{public}s:%{public}d:%{public}s, dev_role: %{public}d",
1120                 __FILE__, __LINE__, __FUNCTION__, device.role_);
1121             auto &client = it.second;
1122 
1123             client.connection_.SetHandle(connectionHandle);
1124             map.first->second.emplace(it.first);
1125 
1126             client.connState_ = static_cast<int>(BTConnectState::CONNECTED);
1127             if (device.role_ == GATT_ROLE_MASTER) {
1128                 client.callback_.OnConnectionStateChanged(ret, client.connState_);
1129             }
1130         }
1131     }
1132 }
1133 
OnDisconnect(const GattDevice &device, uint16_t connectionHandle, int ret)1134 void GattClientService::impl::OnDisconnect(const GattDevice &device, uint16_t connectionHandle, int ret)
1135 {
1136     LOG_INFO("%{public}s: client service dev_role: %{public}d, ret: %{public}d", __FUNCTION__, device.role_, ret);
1137     handleMap_.erase(connectionHandle);
1138     for (auto &it : clients_) {
1139         if (it.second.connection_.GetDevice() == device) {
1140             auto &client = it.second;
1141 
1142             client.connection_.SetHandle(0);
1143             client.connection_.SetMtu(0);
1144             client.connState_ = static_cast<int>(BTConnectState::DISCONNECTED);
1145             if (device.role_ == GATT_ROLE_MASTER) {
1146                 client.callback_.OnConnectionStateChanged(ret, client.connState_);
1147             }
1148         }
1149     }
1150 }
1151 
OnConnectionChanged(const GattDevice &device, uint16_t connectionHandle, int state)1152 void GattClientService::impl::OnConnectionChanged(const GattDevice &device, uint16_t connectionHandle, int state)
1153 {
1154     LOG_INFO("%{public}s:%{public}d:%{public}s", __FILE__, __LINE__, __FUNCTION__);
1155     if (device.role_ != GATT_ROLE_MASTER) {
1156         LOG_ERROR("%{public}s: device role is %{public}d", __FUNCTION__, device.role_);
1157         return;
1158     }
1159     for (auto &it : clients_) {
1160         if (it.second.connection_.GetDevice() == device) {
1161             if (it.second.connState_ == state) {
1162                 auto &client = it.second;
1163                 client.connection_.SetHandle(connectionHandle);
1164                 client.discover_.profile_.DiscoverAllPrimaryServicesInter(
1165                     it.first, client.connection_.GetHandle(), MIN_ATTRIBUTE_HANDLE, MAX_ATTRIBUTE_HANDLE);
1166             } else {
1167                 it.second.connState_ = state;
1168                 it.second.callback_.OnConnectionStateChanged(GattStatus::GATT_SUCCESS, it.second.connState_);
1169             }
1170         }
1171     }
1172 }
1173 
OnConnectionParameterChanged( const GattDevice &device, int interval, int latency, int timeout, int status)1174 void GattClientService::impl::OnConnectionParameterChanged(
1175     const GattDevice &device, int interval, int latency, int timeout, int status)
1176 {
1177     for (auto it : clients_) {
1178         if (it.second.connection_.GetDevice() == device) {
1179             it.second.callback_.OnConnectionParameterChanged(interval, latency, timeout, status);
1180         }
1181     }
1182 }
1183 
OnConnetionManagerShutDown()1184 void GattClientService::impl::OnConnetionManagerShutDown()
1185 {
1186     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Done", __FILE__, __LINE__, __FUNCTION__);
1187     self_.GetContext()->OnDisable(PROFILE_NAME_GATT_CLIENT, true);
1188 }
1189 
GetValidApplication(int appId)1190 std::optional<AppIterator> GattClientService::impl::GetValidApplication(int appId)
1191 {
1192     auto it = clients_.find(appId);
1193     if (it != clients_.end()) {
1194         return it;
1195     }
1196     return std::nullopt;
1197 }
1198 
GetValidApplication(const GattDevice &device)1199 std::optional<AppIterator> GattClientService::impl::GetValidApplication(const GattDevice &device)
1200 {
1201     for (auto it = clients_.begin(); it != clients_.end(); it++) {
1202         if (it->second.connection_.GetDevice() == device) {
1203             return it;
1204         }
1205     }
1206     return std::nullopt;
1207 }
1208 
Enable()1209 void GattClientService::impl::Enable()
1210 {
1211     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Entry", __FILE__, __LINE__, __FUNCTION__);
1212     if (GattStatus::GATT_SUCCESS != GattConnectionManager::GetInstance().StartUp(*self_.GetDispatcher())) {
1213         self_.GetContext()->OnEnable(PROFILE_NAME_GATT_CLIENT, false);
1214         return;
1215     }
1216 
1217     profile_->Enable();
1218 
1219     CleanApplication();
1220 
1221     Start();
1222 
1223     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Done", __FILE__, __LINE__, __FUNCTION__);
1224 
1225     self_.GetContext()->OnEnable(PROFILE_NAME_GATT_CLIENT, true);
1226 }
1227 
Disable()1228 void GattClientService::impl::Disable()
1229 {
1230     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Entry", __FILE__, __LINE__, __FUNCTION__);
1231 
1232     Stop();
1233 
1234     profile_->Disable();
1235 
1236     GattConnectionManager::GetInstance().ShutDown();
1237 }
1238 
CleanApplication()1239 void GattClientService::impl::CleanApplication()
1240 {
1241     handleMap_.clear();
1242     clients_.clear();
1243 }
1244 
BuildService(GattCache::Service &src, Service &dest)1245 void GattClientService::impl::BuildService(GattCache::Service &src, Service &dest)
1246 {
1247     for (auto &isvc : src.includeServices_) {
1248         dest.includeServices_.push_back(Service(isvc.uuid_, isvc.handle_, isvc.handle_, isvc.endHandle_));
1249     }
1250 
1251     for (auto &ccc : src.characteristics_) {
1252         Characteristic cccTmp(ccc.second.uuid_, ccc.second.handle_, ccc.second.properties_);
1253         for (auto &desc : ccc.second.descriptors_) {
1254             cccTmp.descriptors_.push_back(Descriptor(desc.second.handle_, desc.second.uuid_, 0));
1255         }
1256         dest.characteristics_.push_back(std::move(cccTmp));
1257     }
1258 }
1259 
GattUpdatePowerStatus(const RawAddress &addr)1260 void GattClientService::impl::GattUpdatePowerStatus(const RawAddress &addr)
1261 {
1262     IPowerManager::GetInstance().StatusUpdate(RequestStatus::BUSY, PROFILE_NAME_GATT_CLIENT, addr);
1263     IPowerManager::GetInstance().StatusUpdate(RequestStatus::IDLE, PROFILE_NAME_GATT_CLIENT, addr);
1264 }
1265 
DiscoverNext(int appId)1266 bool ClientApplication::Discover::DiscoverNext(int appId)
1267 {
1268     bool doOnce = true;
1269     do {
1270         doOnce = true;
1271         if (tasks_.empty()) {
1272             return true;
1273         }
1274 
1275         auto &task = tasks_.front();
1276         switch (task.type_) {
1277             case Task::Type::SERVICE:
1278                 if (discovered_.emplace(task.startHandle_).second) {
1279                     profile_.DiscoverAllPrimaryServices(
1280                         appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1281                 } else {
1282                     doOnce = false;
1283                 }
1284                 break;
1285             case Task::Type::INCLUDE_SERVICE:
1286                 profile_.FindIncludedServices(
1287                     appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1288                 break;
1289             case Task::Type::CHARACTERISTICS:
1290                 profile_.DiscoverAllCharacteristicOfService(
1291                     appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1292                 break;
1293             case Task::Type::DESCRIPTOR:
1294                 profile_.DiscoverAllCharacteristicDescriptors(
1295                     appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1296                 break;
1297             default:
1298                 break;
1299         }
1300         tasks_.pop();
1301     } while (!doOnce);
1302 
1303     return false;
1304 }
1305 
Clear()1306 void ClientApplication::Discover::Clear()
1307 {
1308     while (tasks_.size() != 0) {
1309         tasks_.pop();
1310     }
1311     discovered_.clear();
1312 }
1313 
Enable()1314 void GattClientService::Enable()
1315 {
1316     if (pimpl->InRunningState()) {
1317         LOG_ERROR("ProfileService:%{public}s is already start up!", Name().c_str());
1318         return;
1319     }
1320 
1321     GetDispatcher()->PostTask(std::bind(&impl::Enable, pimpl.get()));
1322 }
1323 
Disable()1324 void GattClientService::Disable()
1325 {
1326     if (!pimpl->InRunningState()) {
1327         LOG_ERROR("ProfileService:%{public}s is already shut down!", Name().c_str());
1328         return;
1329     }
1330 
1331     GetDispatcher()->PostTask(std::bind(&impl::Disable, pimpl.get()));
1332 }
1333 
1334 REGISTER_CLASS_CREATOR(GattClientService);
1335 }  // namespace bluetooth
1336 }  // namespace OHOS
1337