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