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:
OnConnect(const GattDevice & device,uint16_t connectionHandle,int ret)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 
OnDisconnect(const GattDevice & device,uint16_t connectionHandle,int ret)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 
OnConnectionChanged(const GattDevice & device,uint16_t connectionHandle,int state)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 
OnConnectionParameterChanged(const GattDevice & device,int interval,int latency,int timeout,int status)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 
OnShutDown()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:
OnDiscoverAllPrimaryServicesEvent(int reqId,int ret,uint16_t connectHandle,const std::map<uint16_t,GattCache::Service> & services)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 
OnFindIncludedServicesEvent(int reqId,int ret,uint16_t connectHandle,uint16_t serviceHandle,const std::vector<GattCache::IncludeService> & services)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 
OnDiscoverAllCharacteristicOfServiceEvent(int reqId,int ret,uint16_t connectHandle,uint16_t serviceHandle,const std::map<uint16_t,GattCache::Characteristic> & characteristics)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 
OnDiscoverAllCharacteristicDescriptorsEvent(int reqId,int ret,uint16_t serviceHandle,uint16_t characteristicHandle,const std::map<uint16_t,GattCache::Descriptor> & descriptors)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 
OnReadCharacteristicValueEvent(int reqId,uint16_t handle,GattValue & value,size_t len,int result)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 
OnWriteCharacteristicValueEvent(int reqId,uint16_t connectHandle,uint16_t handle,int ret)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 
OnReadDescriptorValueEvent(int reqId,uint16_t handle,GattValue & value,size_t len,int result)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 
OnWriteDescriptorValueEvent(int reqId,uint16_t connectHandle,uint16_t handle,int ret)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 
OnCharacteristicNotifyEvent(uint16_t connectHandle,uint16_t handle,GattValue & value,size_t len,bool needConfirm)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 
OnExchangeMtuEvent(int reqId,uint16_t connectHandle,uint16_t rxMtu,bool status)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         Descriptor gattDescriptor;
1004         gattDescriptor.handle_ = valueHandle;
1005         it.value()->second.callback_.OnDescriptorWrite(ret, gattDescriptor);
1006     }
1007 }
1008 
OnCharacteristicNotifyEvent(uint16_t connectHandle,uint16_t valueHandle,GattValue & value,size_t length,bool needConfirm)1009 void GattClientService::impl::OnCharacteristicNotifyEvent(
1010     uint16_t connectHandle, uint16_t valueHandle, GattValue &value, size_t length, bool needConfirm)
1011 {
1012     if (needConfirm) {
1013         profile_->HandleValueConfirmation(connectHandle);
1014     }
1015 
1016     for (auto appId : handleMap_.find(connectHandle)->second) {
1017         auto client = GetValidApplication(appId);
1018         if (!client.has_value()) {
1019             continue;
1020         }
1021 
1022         if (client.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
1023             GattUpdatePowerStatus(client.value()->second.connection_.GetDevice().addr_);
1024         }
1025 
1026         auto ccc = profile_->GetCharacteristic(connectHandle, valueHandle);
1027         if (ccc == nullptr) {
1028             LOG_ERROR("%{public}s:%{public}d:%{public}s Gatt Cache Error: Can not find Characteristic by value handle.",
1029                 __FILE__,
1030                 __LINE__,
1031                 __FUNCTION__);
1032             return;
1033         }
1034 
1035         if (Uuid::ConvertFrom16Bits(UUID_SERVICE_CHANGED) == ccc->uuid_) {
1036             client.value()->second.callback_.OnServicesChanged(std::vector<Service>());
1037         } else {
1038             Characteristic gattCCC(ccc->uuid_, ccc->handle_, ccc->properties_);
1039             gattCCC.value_ = std::make_unique<uint8_t[]>(length);
1040             if (memcpy_s(gattCCC.value_.get(), length, (*value).get(), length) != EOK) {
1041                 return;
1042             }
1043             gattCCC.length_ = length;
1044             client.value()->second.callback_.OnCharacteristicChanged(gattCCC);
1045         }
1046     }
1047 }
1048 
OnExchangeMtuEvent(int requestId,uint16_t connectHandle,uint16_t rxMtu,bool status)1049 void GattClientService::impl::OnExchangeMtuEvent(int requestId, uint16_t connectHandle, uint16_t rxMtu, bool status)
1050 {
1051     auto it = GetValidApplication(requestId);
1052     if (it.has_value()) {
1053         if (it.value()->second.connection_.GetDevice().transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
1054             GattUpdatePowerStatus(it.value()->second.connection_.GetDevice().addr_);
1055         }
1056 
1057         it.value()->second.callback_.OnMtuChanged(status ? GattStatus::GATT_SUCCESS : GattStatus::GATT_FAILURE, rxMtu);
1058     }
1059 }
1060 
RegisterApplication(IGattClientCallback & callback,const GattDevice & device,std::promise<int> & promise,bool isShared)1061 void GattClientService::impl::RegisterApplication(
1062     IGattClientCallback &callback, const GattDevice &device, std::promise<int> &promise, bool isShared)
1063 {
1064     int result = GattStatus::DEVICE_ALREADY_BIND;
1065     int appid = GattServiceBase::GetApplicationId();
1066     if (clients_.size() >= MAXIMUM_NUMBER_APPLICATION) {
1067         promise.set_value(GattStatus::MAX_APPLICATIONS);
1068         return;
1069     }
1070 
1071     if (isShared) {
1072         if (clients_.emplace(appid, ClientApplication(callback, device, *profile_, isShared)).second) {
1073             result = GattStatus::GATT_SUCCESS;
1074         } else {
1075             result = GattStatus::GATT_FAILURE;
1076             LOG_ERROR("%{public}s:%{public}s:%{public}d register to application failed! same application ID!",
1077                 __FILE__, __FUNCTION__, __LINE__);
1078         }
1079     } else {
1080         auto app = GetValidApplication(device);
1081         if (!app.has_value()) {
1082             if (clients_.emplace(appid, ClientApplication(callback, device, *profile_, isShared)).second) {
1083                 result = GattStatus::GATT_SUCCESS;
1084             } else {
1085                 result = GattStatus::GATT_FAILURE;
1086                 LOG_ERROR("%{public}s:%{public}s:%{public}d register to application failed! same application ID!",
1087                     __FILE__,
1088                     __FUNCTION__,
1089                     __LINE__);
1090             }
1091         }
1092     }
1093 
1094     promise.set_value(((result == GattStatus::GATT_SUCCESS) ? appid : result));
1095 }
1096 
DeregisterApplication(int appId,std::promise<int> & promise)1097 void GattClientService::impl::DeregisterApplication(int appId, std::promise<int> &promise)
1098 {
1099     auto client = GetValidApplication(appId);
1100     if (client.has_value()) {
1101         auto map = handleMap_.find(client.value()->second.connection_.GetHandle());
1102         if (map != handleMap_.end()) {
1103             map->second.erase(appId);
1104         }
1105         clients_.erase(client.value());
1106     }
1107 
1108     promise.set_value(GattStatus::GATT_SUCCESS);
1109 }
1110 
OnConnect(const GattDevice & device,uint16_t connectionHandle,int ret)1111 void GattClientService::impl::OnConnect(const GattDevice &device, uint16_t connectionHandle, int ret)
1112 {
1113     auto map = handleMap_.emplace(std::make_pair<int, std::set<int>>(connectionHandle, {}));
1114     if (device.transport_ == GATT_TRANSPORT_TYPE_CLASSIC) {
1115         IPowerManager::GetInstance().StatusUpdate(
1116             RequestStatus::CONNECT_ON, PROFILE_NAME_GATT_CLIENT, device.addr_);
1117     }
1118 
1119     for (auto &it : clients_) {
1120         if (it.second.connection_.GetDevice() == device) {
1121             LOG_DEBUG("%{public}s:%{public}d:%{public}s, dev_role: %{public}d",
1122                 __FILE__, __LINE__, __FUNCTION__, device.role_);
1123             auto &client = it.second;
1124 
1125             client.connection_.SetHandle(connectionHandle);
1126             map.first->second.emplace(it.first);
1127 
1128             client.connState_ = static_cast<int>(BTConnectState::CONNECTED);
1129             if (device.role_ == GATT_ROLE_MASTER) {
1130                 client.callback_.OnConnectionStateChanged(ret, client.connState_);
1131             }
1132         }
1133     }
1134 }
1135 
OnDisconnect(const GattDevice & device,uint16_t connectionHandle,int ret)1136 void GattClientService::impl::OnDisconnect(const GattDevice &device, uint16_t connectionHandle, int ret)
1137 {
1138     LOG_INFO("%{public}s: client service dev_role: %{public}d, ret: %{public}d", __FUNCTION__, device.role_, ret);
1139     handleMap_.erase(connectionHandle);
1140     for (auto &it : clients_) {
1141         if (it.second.connection_.GetDevice() == device) {
1142             auto &client = it.second;
1143 
1144             client.connection_.SetHandle(0);
1145             client.connection_.SetMtu(0);
1146             client.connState_ = static_cast<int>(BTConnectState::DISCONNECTED);
1147             if (device.role_ == GATT_ROLE_MASTER) {
1148                 client.callback_.OnConnectionStateChanged(ret, client.connState_);
1149             }
1150         }
1151     }
1152 }
1153 
OnConnectionChanged(const GattDevice & device,uint16_t connectionHandle,int state)1154 void GattClientService::impl::OnConnectionChanged(const GattDevice &device, uint16_t connectionHandle, int state)
1155 {
1156     LOG_INFO("%{public}s:%{public}d:%{public}s", __FILE__, __LINE__, __FUNCTION__);
1157     if (device.role_ != GATT_ROLE_MASTER) {
1158         LOG_ERROR("%{public}s: device role is %{public}d", __FUNCTION__, device.role_);
1159         return;
1160     }
1161     for (auto &it : clients_) {
1162         if (it.second.connection_.GetDevice() == device) {
1163             if (it.second.connState_ == state) {
1164                 auto &client = it.second;
1165                 client.connection_.SetHandle(connectionHandle);
1166                 client.discover_.profile_.DiscoverAllPrimaryServicesInter(
1167                     it.first, client.connection_.GetHandle(), MIN_ATTRIBUTE_HANDLE, MAX_ATTRIBUTE_HANDLE);
1168             } else {
1169                 it.second.connState_ = state;
1170                 it.second.callback_.OnConnectionStateChanged(GattStatus::GATT_SUCCESS, it.second.connState_);
1171             }
1172         }
1173     }
1174 }
1175 
OnConnectionParameterChanged(const GattDevice & device,int interval,int latency,int timeout,int status)1176 void GattClientService::impl::OnConnectionParameterChanged(
1177     const GattDevice &device, int interval, int latency, int timeout, int status)
1178 {
1179     for (auto it : clients_) {
1180         if (it.second.connection_.GetDevice() == device) {
1181             it.second.callback_.OnConnectionParameterChanged(interval, latency, timeout, status);
1182         }
1183     }
1184 }
1185 
OnConnetionManagerShutDown()1186 void GattClientService::impl::OnConnetionManagerShutDown()
1187 {
1188     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Done", __FILE__, __LINE__, __FUNCTION__);
1189     self_.GetContext()->OnDisable(PROFILE_NAME_GATT_CLIENT, true);
1190 }
1191 
GetValidApplication(int appId)1192 std::optional<AppIterator> GattClientService::impl::GetValidApplication(int appId)
1193 {
1194     auto it = clients_.find(appId);
1195     if (it != clients_.end()) {
1196         return it;
1197     }
1198     return std::nullopt;
1199 }
1200 
GetValidApplication(const GattDevice & device)1201 std::optional<AppIterator> GattClientService::impl::GetValidApplication(const GattDevice &device)
1202 {
1203     for (auto it = clients_.begin(); it != clients_.end(); it++) {
1204         if (it->second.connection_.GetDevice() == device) {
1205             return it;
1206         }
1207     }
1208     return std::nullopt;
1209 }
1210 
Enable()1211 void GattClientService::impl::Enable()
1212 {
1213     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Entry", __FILE__, __LINE__, __FUNCTION__);
1214     if (GattStatus::GATT_SUCCESS != GattConnectionManager::GetInstance().StartUp(*self_.GetDispatcher())) {
1215         self_.GetContext()->OnEnable(PROFILE_NAME_GATT_CLIENT, false);
1216         return;
1217     }
1218 
1219     profile_->Enable();
1220 
1221     CleanApplication();
1222 
1223     Start();
1224 
1225     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Done", __FILE__, __LINE__, __FUNCTION__);
1226 
1227     self_.GetContext()->OnEnable(PROFILE_NAME_GATT_CLIENT, true);
1228 }
1229 
Disable()1230 void GattClientService::impl::Disable()
1231 {
1232     LOG_DEBUG("%{public}s:%{public}d:%{public}s :Gatt Client Service Entry", __FILE__, __LINE__, __FUNCTION__);
1233 
1234     Stop();
1235 
1236     profile_->Disable();
1237 
1238     GattConnectionManager::GetInstance().ShutDown();
1239 }
1240 
CleanApplication()1241 void GattClientService::impl::CleanApplication()
1242 {
1243     handleMap_.clear();
1244     clients_.clear();
1245 }
1246 
BuildService(GattCache::Service & src,Service & dest)1247 void GattClientService::impl::BuildService(GattCache::Service &src, Service &dest)
1248 {
1249     for (auto &isvc : src.includeServices_) {
1250         dest.includeServices_.push_back(Service(isvc.uuid_, isvc.handle_, isvc.handle_, isvc.endHandle_));
1251     }
1252 
1253     for (auto &ccc : src.characteristics_) {
1254         Characteristic cccTmp(ccc.second.uuid_, ccc.second.handle_, ccc.second.properties_);
1255         for (auto &desc : ccc.second.descriptors_) {
1256             cccTmp.descriptors_.push_back(Descriptor(desc.second.handle_, desc.second.uuid_, 0));
1257         }
1258         dest.characteristics_.push_back(std::move(cccTmp));
1259     }
1260 }
1261 
GattUpdatePowerStatus(const RawAddress & addr)1262 void GattClientService::impl::GattUpdatePowerStatus(const RawAddress &addr)
1263 {
1264     IPowerManager::GetInstance().StatusUpdate(RequestStatus::BUSY, PROFILE_NAME_GATT_CLIENT, addr);
1265     IPowerManager::GetInstance().StatusUpdate(RequestStatus::IDLE, PROFILE_NAME_GATT_CLIENT, addr);
1266 }
1267 
DiscoverNext(int appId)1268 bool ClientApplication::Discover::DiscoverNext(int appId)
1269 {
1270     bool doOnce = true;
1271     do {
1272         doOnce = true;
1273         if (tasks_.empty()) {
1274             return true;
1275         }
1276 
1277         auto &task = tasks_.front();
1278         switch (task.type_) {
1279             case Task::Type::SERVICE:
1280                 if (discovered_.emplace(task.startHandle_).second) {
1281                     profile_.DiscoverAllPrimaryServices(
1282                         appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1283                 } else {
1284                     doOnce = false;
1285                 }
1286                 break;
1287             case Task::Type::INCLUDE_SERVICE:
1288                 profile_.FindIncludedServices(
1289                     appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1290                 break;
1291             case Task::Type::CHARACTERISTICS:
1292                 profile_.DiscoverAllCharacteristicOfService(
1293                     appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1294                 break;
1295             case Task::Type::DESCRIPTOR:
1296                 profile_.DiscoverAllCharacteristicDescriptors(
1297                     appId, client_.connection_.GetHandle(), task.startHandle_, task.endHandle_);
1298                 break;
1299             default:
1300                 break;
1301         }
1302         tasks_.pop();
1303     } while (!doOnce);
1304 
1305     return false;
1306 }
1307 
Clear()1308 void ClientApplication::Discover::Clear()
1309 {
1310     while (tasks_.size() != 0) {
1311         tasks_.pop();
1312     }
1313     discovered_.clear();
1314 }
1315 
Enable()1316 void GattClientService::Enable()
1317 {
1318     if (pimpl->InRunningState()) {
1319         LOG_ERROR("ProfileService:%{public}s is already start up!", Name().c_str());
1320         return;
1321     }
1322 
1323     GetDispatcher()->PostTask(std::bind(&impl::Enable, pimpl.get()));
1324 }
1325 
Disable()1326 void GattClientService::Disable()
1327 {
1328     if (!pimpl->InRunningState()) {
1329         LOG_ERROR("ProfileService:%{public}s is already shut down!", Name().c_str());
1330         return;
1331     }
1332 
1333     GetDispatcher()->PostTask(std::bind(&impl::Disable, pimpl.get()));
1334 }
1335 
1336 REGISTER_CLASS_CREATOR(GattClientService);
1337 }  // namespace bluetooth
1338 }  // namespace OHOS
1339