1 /*
2 * Copyright (C) 2024 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 "bt_connection_manager.h"
17
18 #include "common_event_manager.h"
19 #include "common_event_support.h"
20 #include "external_deps_proxy.h"
21 #include "infc_service.h"
22 #include "loghelper.h"
23 #include "nfc_service.h"
24
25 namespace OHOS {
26 namespace NFC {
27 namespace TAG {
28 const uint64_t BT_ENABLE_TIMEOUT = 3000; // ms
29 const uint64_t BT_PAIR_TIMEOUT = 10000; // ms
30 const uint64_t BT_CONNECT_TIMEOUT = 5000; // ms
31 const uint8_t PROFILE_MAX_SIZE = 21;
32
33 enum BtConnAction {
34 ACTION_INIT = 1,
35 ACTION_DISCONNECT,
36 ACTION_CONNECT
37 };
38
39 enum BtConnState {
40 STATE_WAITING_FOR_BT_ENABLE = 1,
41 STATE_INIT,
42 STATE_INIT_COMPLETE,
43 STATE_PAIRING,
44 STATE_PAIR_COMPLETE,
45 STATE_CONNECTING,
46 STATE_DISCONNECTING,
47 STATE_COMPLETE
48 };
49
50 enum BtConnResult {
51 CONN_RES_WAITING = 1,
52 CONN_RES_CONNECTED,
53 CONN_RES_DISCONNECTED
54 };
55
56 static Bluetooth::A2dpSource *g_a2dp;
57 static Bluetooth::HandsFreeAudioGateway *g_hfp;
58 static Bluetooth::HidHost *g_hid;
59
60 Bluetooth::BluetoothRemoteDevice g_device;
61 std::shared_ptr<BtData> g_btData {};
62
63 bool g_isStateObserverRegistered = false;
64 bool g_isDevObserverRegistered = false;
65 bool g_isA2dpSupported = false;
66 bool g_isHfpSupported = false;
67
68 uint8_t g_a2dpConnState = 0;
69 uint8_t g_hfpConnState = 0;
70 uint8_t g_hidConnState = 0;
71
72 uint8_t g_state = 0;
73 uint8_t g_action = 0;
74
BtConnectionManager()75 BtConnectionManager::BtConnectionManager()
76 {
77 }
78
GetInstance()79 BtConnectionManager& BtConnectionManager::GetInstance()
80 {
81 static BtConnectionManager instance;
82 return instance;
83 }
84
Initialize(std::weak_ptr<NfcService> nfcService)85 void BtConnectionManager::Initialize(std::weak_ptr<NfcService> nfcService)
86 {
87 DebugLog("Init: isInitialized = %{public}d", isInitialized_);
88 if (isInitialized_) {
89 return;
90 }
91 nfcService_ = nfcService;
92 isInitialized_ = true;
93 }
94
SendMsgToEvtHandler(NfcCommonEvent evt,int64_t delay)95 void BtConnectionManager::SendMsgToEvtHandler(NfcCommonEvent evt, int64_t delay)
96 {
97 if (nfcService_.expired()) {
98 ErrorLog("nfcService expired");
99 return;
100 }
101 if (nfcService_.lock()->eventHandler_ == nullptr) {
102 ErrorLog("event handler is null");
103 return;
104 }
105 DebugLog("SendMsgToEvtHandler: event:%{public}d, delay:%{public}ld", evt, delay);
106 nfcService_.lock()->eventHandler_->SendEvent(static_cast<uint32_t>(evt), delay);
107 }
108
SendConnMsgToEvtHandler(NfcCommonEvent evt,const Bluetooth::BluetoothRemoteDevice & device,int32_t state,BtProfileType type)109 void BtConnectionManager::SendConnMsgToEvtHandler(NfcCommonEvent evt, const Bluetooth::BluetoothRemoteDevice &device,
110 int32_t state, BtProfileType type)
111 {
112 if (nfcService_.expired()) {
113 ErrorLog("nfcService expired");
114 return;
115 }
116 if (nfcService_.lock()->eventHandler_ == nullptr) {
117 ErrorLog("event handler is null");
118 return;
119 }
120 std::shared_ptr<BtConnectionInfo> info = std::make_shared<BtConnectionInfo>();
121 info->macAddr_ = device.GetDeviceAddr();
122 info->state_ = state;
123 info->type_ = static_cast<uint8_t>(type);
124 DebugLog("SendConnMsgToEvtHandler: event:%{public}d", evt);
125 nfcService_.lock()->eventHandler_->SendEvent(static_cast<uint32_t>(evt), info, 0);
126 }
127
RemoveMsgFromEvtHandler(NfcCommonEvent evt)128 void BtConnectionManager::RemoveMsgFromEvtHandler(NfcCommonEvent evt)
129 {
130 if (nfcService_.expired()) {
131 ErrorLog("nfcService expired");
132 return;
133 }
134 if (nfcService_.lock()->eventHandler_ == nullptr) {
135 ErrorLog("event handler is null");
136 return;
137 }
138 DebugLog("RemoveMsgFromEvtHandler: event:%{public}d", evt);
139 nfcService_.lock()->eventHandler_->RemoveEvent(static_cast<uint32_t>(evt), static_cast<int64_t>(0));
140 }
141
RegisterBtObserver()142 void BtConnectionManager::RegisterBtObserver()
143 {
144 DebugLog("RegisterBtStateObserver");
145 if (btObserver_ == nullptr) {
146 btObserver_ = BtConnectionManager::BtStateObserver::GetInstance();
147 }
148 Bluetooth::BluetoothHost::GetDefaultHost().RegisterObserver(btObserver_);
149 g_isStateObserverRegistered = true;
150 }
151
UnregisterBtObserverAndProfile()152 void BtConnectionManager::UnregisterBtObserverAndProfile()
153 {
154 DebugLog("UnregisterBtObserverAndProfile");
155 if (btObserver_ != nullptr && g_isStateObserverRegistered) {
156 Bluetooth::BluetoothHost::GetDefaultHost().DeregisterObserver(btObserver_);
157 btObserver_ = nullptr;
158 g_isStateObserverRegistered = false;
159 DebugLog("UnregisterBtObserverAndProfile: bt state observer deregistered");
160 }
161 if (btRemoteDevObserver_ != nullptr && g_isDevObserverRegistered) {
162 Bluetooth::BluetoothHost::GetDefaultHost().DeregisterRemoteDeviceObserver(btRemoteDevObserver_);
163 btRemoteDevObserver_ = nullptr;
164 g_isDevObserverRegistered = false;
165 DebugLog("UnregisterBtObserverAndProfile: bt remote device observer deregistered");
166 }
167 if (g_a2dp != nullptr) {
168 if (btA2dpObserver_) {
169 g_a2dp->DeregisterObserver(btA2dpObserver_);
170 btA2dpObserver_ = nullptr;
171 DebugLog("UnregisterBtObserverAndProfile: bt a2dp observer deregistered");
172 }
173 g_a2dp = nullptr;
174 }
175 if (g_hfp != nullptr) {
176 if (btHfpObserver_) {
177 g_hfp->DeregisterObserver(btHfpObserver_);
178 btHfpObserver_ = nullptr;
179 DebugLog("UnregisterBtObserverAndProfile: bt state observer deregistered");
180 }
181 g_hfp = nullptr;
182 }
183 if (g_hid != nullptr) {
184 if (btHidObserver_) {
185 g_hid->DeregisterObserver(btHidObserver_);
186 btHidObserver_ = nullptr;
187 DebugLog("UnregisterBtObserverAndProfile: bt state observer deregistered");
188 }
189 g_hid = nullptr;
190 }
191 }
192
193 // lock outside
OnFinish()194 void BtConnectionManager::OnFinish()
195 {
196 DebugLog("OnFinish");
197 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT);
198 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT);
199 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_TIMEOUT);
200 UnregisterBtObserverAndProfile();
201 g_isStateObserverRegistered = false;
202 g_isDevObserverRegistered = false;
203 g_isA2dpSupported = false;
204 g_isHfpSupported = false;
205 g_a2dpConnState = 0;
206 g_hfpConnState = 0;
207 g_hidConnState = 0;
208 g_state = 0;
209 g_action = 0;
210 g_btData = nullptr;
211 }
212
HandleBtEnableFailed()213 void BtConnectionManager::HandleBtEnableFailed()
214 {
215 std::unique_lock<std::shared_mutex> guard(mutex_);
216 ErrorLog("Bt Enable Failed");
217 OnFinish();
218 }
219
HandleBtPairFailed()220 void BtConnectionManager::HandleBtPairFailed()
221 {
222 std::unique_lock<std::shared_mutex> guard(mutex_);
223 ErrorLog("Bt Pair Failed");
224 OnFinish();
225 }
226
HandleBtConnectFailed()227 void BtConnectionManager::HandleBtConnectFailed()
228 {
229 std::unique_lock<std::shared_mutex> guard(mutex_);
230 ErrorLog("Bt Connect Failed");
231 OnFinish();
232 }
233
IsBtEnabled()234 bool BtConnectionManager::IsBtEnabled()
235 {
236 bool isEnabled = Bluetooth::BluetoothHost::GetDefaultHost().IsBrEnabled();
237 InfoLog("IsBtEnabled: %{public}d", isEnabled);
238 return isEnabled;
239 }
240
HandleEnableBt()241 bool BtConnectionManager::HandleEnableBt()
242 {
243 DebugLog("HandleEnableBt");
244 SendMsgToEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT, BT_ENABLE_TIMEOUT);
245 if (Bluetooth::BluetoothHost::GetDefaultHost().EnableBle() != Bluetooth::RET_NO_ERROR) { // EnableBt() is deprecated
246 ErrorLog("HandleEnableBt: failed");
247 return false;
248 }
249 return true;
250 }
251
HandleBtPair()252 bool BtConnectionManager::HandleBtPair()
253 {
254 DebugLog("HandleBtPair");
255 bool isDiscovering = false;
256 Bluetooth::BluetoothHost::GetDefaultHost().IsBtDiscovering(isDiscovering, g_btData->transport_);
257 if (isDiscovering) {
258 InfoLog("Cancel discovery");
259 Bluetooth::BluetoothHost::GetDefaultHost().CancelBtDiscovery();
260 }
261 // oob pair mode currently not supported by bluetooth
262 if (btRemoteDevObserver_ == nullptr) {
263 btRemoteDevObserver_ = std::make_shared<BtRemoteDevObserver>();
264 }
265 Bluetooth::BluetoothHost::GetDefaultHost().RegisterRemoteDeviceObserver(btRemoteDevObserver_);
266 g_isDevObserverRegistered = true;
267
268 InfoLog("Handle bt pair start");
269 g_device.StartCrediblePair();
270 SendMsgToEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT, BT_PAIR_TIMEOUT);
271 return true;
272 }
273
IsA2dpSupported()274 bool BtConnectionManager::IsA2dpSupported()
275 {
276 if (g_btData == nullptr) {
277 ErrorLog("IsA2dpSupported: g_btData error");
278 return false;
279 }
280 for (Bluetooth::UUID uuid : g_btData->uuids_) {
281 if ((uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_A2DP_SINK) == 0) ||
282 (uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_AVRCP_CT) == 0)) {
283 return true;
284 }
285 }
286 return g_btData->btClass_.IsProfileSupported(Bluetooth::PROFILE_ID_A2DP_SRC);
287 }
288
IsHfpSupported()289 bool BtConnectionManager::IsHfpSupported()
290 {
291 if (g_btData == nullptr) {
292 ErrorLog("IsHfpSupported: g_btData error");
293 return false;
294 }
295 for (Bluetooth::UUID uuid : g_btData->uuids_) {
296 if ((uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_HFP_AG) == 0) ||
297 (uuid.ToString().compare(Bluetooth::BLUETOOTH_UUID_HFP_HF) == 0)) {
298 return true;
299 }
300 }
301 return g_btData->btClass_.IsProfileSupported(Bluetooth::PROFILE_ID_HFP_AG);
302 }
303
304 // false to OnFinish()
HandleBtInit()305 bool BtConnectionManager::HandleBtInit()
306 {
307 if (g_btData == nullptr) {
308 ErrorLog("HandleBtInit: g_btData error");
309 return false;
310 }
311 if (g_device.GetDeviceAddr().compare(g_btData->macAddress_) != 0) {
312 g_device = Bluetooth::BluetoothRemoteDevice(g_btData->macAddress_, g_btData->transport_);
313 }
314 if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
315 InfoLog("Init: hid getprofile");
316 if (g_hid == nullptr) {
317 g_hid = Bluetooth::HidHost::GetProfile();
318 }
319 } else {
320 if (g_a2dp == nullptr) {
321 g_a2dp = Bluetooth::A2dpSource::GetProfile();
322 }
323 if (g_hfp == nullptr) {
324 g_hfp = Bluetooth::HandsFreeAudioGateway::GetProfile();
325 }
326 g_isA2dpSupported = IsA2dpSupported();
327 g_isHfpSupported = IsHfpSupported();
328 InfoLog("Init:a2dp: %{public}d, hfp: %{public}d", g_isA2dpSupported, g_isHfpSupported);
329 if (!g_isA2dpSupported && !g_isHfpSupported) {
330 // if both not supported, maybe the info is empty in ndef
331 // try both
332 g_isA2dpSupported = true;
333 g_isHfpSupported = true;
334 InfoLog("Init:a2dp and hid not supported");
335 }
336 }
337 return true;
338 }
339
340 // false to OnFinish()
DecideInitNextAction()341 bool BtConnectionManager::DecideInitNextAction()
342 {
343 if (g_btData == nullptr) {
344 ErrorLog("HandleBtInit: g_btData error");
345 return false;
346 }
347 int32_t state = 0;
348 if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
349 if (!g_hid) {
350 ErrorLog("DecideInitNextAction: hid not supported");
351 return false;
352 }
353 g_hid->GetDeviceState(g_device, state);
354 InfoLog("DecideInitNextAction: hid device state: %{public}d", state);
355 if (state == static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
356 g_action = ACTION_DISCONNECT;
357 } else {
358 g_action = ACTION_CONNECT;
359 }
360 } else {
361 if (g_a2dp && g_isA2dpSupported) {
362 g_a2dp->GetDeviceState(g_device, state);
363 }
364
365 InfoLog("DecideInitNextAction: a2dp device state: %{public}d", state);
366 if (state == static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
367 g_action = ACTION_DISCONNECT;
368 } else {
369 // unconnected a2dp and all hfp go to connect action
370 g_action = ACTION_CONNECT;
371 }
372 }
373 return true;
374 }
375
GetProfileList()376 bool BtConnectionManager::GetProfileList()
377 {
378 std::vector<uint32_t> profileList = Bluetooth::BluetoothHost::GetDefaultHost().GetProfileList();
379 if (profileList.size() == 0 && profileList.size() > PROFILE_MAX_SIZE) {
380 ErrorLog("profile list size error");
381 return false;
382 }
383 for (uint32_t i = 0; i < profileList.size(); i++) {
384 if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE &&
385 profileList[i] == Bluetooth::PROFILE_ID_HID_HOST) {
386 InfoLog("PROFILE_ID_HID_HOST");
387 return true;
388 } else {
389 if (profileList[i] == Bluetooth::PROFILE_ID_A2DP_SRC ||
390 profileList[i] == Bluetooth::PROFILE_ID_HFP_AG) {
391 InfoLog("PROFILE_ID_A2DP_SRC OR PROFILE_ID_HFP_AG");
392 return true;
393 }
394 }
395 }
396 return false;
397 }
398
NextActionInit()399 void BtConnectionManager::NextActionInit()
400 {
401 InfoLog("NextActionInit: g_state: %{public}d", g_state);
402 if (g_state == STATE_WAITING_FOR_BT_ENABLE) {
403 return;
404 }
405 if (g_state == STATE_INIT) {
406 if (!GetProfileList()) {
407 ErrorLog("NextActionInit: GetProfileList error");
408 return OnFinish();
409 }
410 if (!HandleBtInit()) {
411 ErrorLog("NextActionInit: HandleBtInit error");
412 return OnFinish();
413 }
414 if (!DecideInitNextAction()) {
415 ErrorLog("NextActionInit: DecideInitNextAction error");
416 return OnFinish();
417 }
418 g_state = STATE_INIT_COMPLETE;
419 }
420 NextAction();
421 }
422
RegisterProfileObserver(BtProfileType type)423 void BtConnectionManager::RegisterProfileObserver(BtProfileType type)
424 {
425 InfoLog("RegisterProfileObserver type: %{public}d", type);
426 switch (type) {
427 case A2DP_SRC: {
428 if (!g_a2dp || !g_isA2dpSupported) {
429 ErrorLog("RegisterProfileObserver: a2dp error");
430 break;
431 }
432 if (!btA2dpObserver_) {
433 btA2dpObserver_ = std::make_shared<BtA2dpObserver>();
434 g_a2dp->RegisterObserver(btA2dpObserver_);
435 }
436 break;
437 }
438 case HFP_AG: {
439 if (!g_hfp || !g_isHfpSupported) {
440 ErrorLog("RegisterProfileObserver: hfp error");
441 break;
442 }
443 if (!btHfpObserver_) {
444 btHfpObserver_ = std::make_shared<BtHfpObserver>();
445 g_hfp->RegisterObserver(btHfpObserver_);
446 }
447 break;
448 }
449 case HID_HOST: {
450 if (!g_hid) {
451 ErrorLog("RegisterProfileObserver: hid error");
452 break;
453 }
454 if (!btHidObserver_) {
455 btHidObserver_ = std::make_shared<BtHidObserver>();
456 g_hid->RegisterObserver(btHidObserver_);
457 }
458 break;
459 }
460 default:
461 break;
462 }
463 }
464
465 // true for need wait, false for go to NextStep
HandleBtConnect()466 bool BtConnectionManager::HandleBtConnect()
467 {
468 DebugLog("HandleBtConnect");
469 int32_t state = 0;
470 if (g_hfp) {
471 g_hfp->GetDeviceState(g_device, state);
472 InfoLog("HandleBtConnect: hfp state = %{public}d", state);
473 if (state != static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
474 if (g_isHfpSupported) {
475 g_hfpConnState = BtConnResult::CONN_RES_WAITING;
476 RegisterProfileObserver(HFP_AG);
477 InfoLog("HandleBtConnect: hfp connect start");
478 g_hfp->Connect(g_device);
479 } else {
480 g_hfpConnState = BtConnResult::CONN_RES_DISCONNECTED;
481 InfoLog("HandleBtConnect: hfp disconnected");
482 }
483 } else {
484 g_hfpConnState = BtConnResult::CONN_RES_CONNECTED;
485 InfoLog("HandleBtConnect: hfp connected");
486 }
487 }
488 if (g_a2dp) {
489 g_a2dp->GetDeviceState(g_device, state);
490 InfoLog("HandleBtConnect: a2dp state = %{public}d", state);
491 if (state != static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
492 if (g_isA2dpSupported) {
493 g_a2dpConnState = BtConnResult::CONN_RES_WAITING;
494 RegisterProfileObserver(A2DP_SRC);
495 InfoLog("HandleBtConnect: a2dp connect start");
496 g_a2dp->Connect(g_device);
497 } else {
498 g_a2dpConnState = BtConnResult::CONN_RES_DISCONNECTED;
499 InfoLog("HandleBtConnect: a2dp disconnected");
500 }
501 } else {
502 g_a2dpConnState = BtConnResult::CONN_RES_CONNECTED;
503 InfoLog("HandleBtConnect: a2dp connected");
504 }
505 }
506 if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
507 g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
508 InfoLog("HandleBtConnect: waiting for connect result");
509 SendMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_TIMEOUT, BT_CONNECT_TIMEOUT);
510 return true;
511 }
512 return false;
513 }
514
515 // true for need wait, false for go to OnFinish()
HandleBtConnectWaiting()516 bool BtConnectionManager::HandleBtConnectWaiting()
517 {
518 if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
519 g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
520 InfoLog("HandleBtConnectWaiting: waiting for connect result");
521 return true;
522 }
523 if (g_a2dpConnState == BtConnResult::CONN_RES_CONNECTED ||
524 g_hfpConnState == BtConnResult::CONN_RES_CONNECTED) {
525 InfoLog("HandleBtConnectWaiting: connect success");
526 g_device.SetDeviceAlias(g_btData->name_);
527 return false;
528 } else {
529 // connect failed
530 return false;
531 }
532 }
533
NextActionConnect()534 void BtConnectionManager::NextActionConnect()
535 {
536 int pairState = 0;
537 g_device.GetPairState(pairState);
538 InfoLog("NextActionConnect: state: %{public}d, pairState: %{public}d", g_state, pairState);
539 switch (g_state) {
540 case STATE_INIT_COMPLETE: {
541 if (pairState != Bluetooth::PAIR_PAIRED) {
542 g_state = STATE_PAIRING;
543 PublishPairBtNtf();
544 break;
545 }
546 // fall-through
547 // when already paired
548 }
549 case STATE_PAIR_COMPLETE: {
550 g_state = STATE_CONNECTING;
551 if (g_btData->transport_ != Bluetooth::GATT_TRANSPORT_TYPE_LE) {
552 if (HandleBtConnect()) {
553 InfoLog("connecting, need wait");
554 break;
555 }
556 }
557 // fall-through
558 // when transport not LE or connect success
559 }
560 case STATE_CONNECTING: {
561 if (g_btData->transport_ != Bluetooth::GATT_TRANSPORT_TYPE_LE) {
562 if (!HandleBtConnectWaiting()) {
563 OnFinish();
564 }
565 }
566 break;
567 }
568 default:
569 break;
570 }
571 }
572
573 // true for need wait, false for go to NextStep
HandleBtDisconnect()574 bool BtConnectionManager::HandleBtDisconnect()
575 {
576 int32_t devState = 0;
577 if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
578 if (!g_hid) {
579 return false;
580 }
581 g_hid->GetDeviceState(g_device, devState);
582 if (devState != static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
583 g_hidConnState = BtConnResult::CONN_RES_WAITING;
584 RegisterProfileObserver(HID_HOST);
585 InfoLog("HandleBtDisconnect: hid disconnect start");
586 g_hid->Disconnect(g_device);
587 return true;
588 } else {
589 g_hidConnState = BtConnResult::CONN_RES_DISCONNECTED;
590 InfoLog("HandleBtDisconnect: hfp disconnect");
591 }
592 } else {
593 if (g_hfp && g_isHfpSupported) {
594 g_hfp->GetDeviceState(g_device, devState);
595 if (devState != static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
596 g_hfpConnState = BtConnResult::CONN_RES_WAITING;
597 RegisterProfileObserver(HFP_AG);
598 InfoLog("HandleBtDisconnect: hfp disconnect start");
599 } else {
600 g_hfpConnState = BtConnResult::CONN_RES_DISCONNECTED;
601 InfoLog("HandleBtDisconnect: hfp disconnected");
602 }
603 }
604 if (g_a2dp && g_isA2dpSupported) {
605 g_a2dp->GetDeviceState(g_device, devState);
606 if (devState != static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
607 g_a2dpConnState = BtConnResult::CONN_RES_WAITING;
608 RegisterProfileObserver(A2DP_SRC);
609 InfoLog("HandleBtDisconnect: a2dp disconnect start");
610 } else {
611 g_a2dpConnState = BtConnResult::CONN_RES_DISCONNECTED;
612 InfoLog("HandleBtDisconnect: a2dp disconnected");
613 }
614 }
615 if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
616 g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
617 Bluetooth::BluetoothHost::GetDefaultHost().DisconnectAllowedProfiles(g_btData->macAddress_);
618 InfoLog("HandleBtDisconnect: waiting for disconnect result");
619 return true;
620 }
621 }
622 return false;
623 }
624
625 // true for need wait, false for go to OnFinish()
HandleBtDisconnectWaiting()626 bool BtConnectionManager::HandleBtDisconnectWaiting()
627 {
628 if (g_btData->transport_ == Bluetooth::GATT_TRANSPORT_TYPE_LE) {
629 if (g_hidConnState == BtConnResult::CONN_RES_DISCONNECTED) {
630 InfoLog("HandleBtDisconnectWaiting:hid disconnected");
631 return false;
632 }
633 } else {
634 if (g_a2dpConnState == BtConnResult::CONN_RES_WAITING ||
635 g_hfpConnState == BtConnResult::CONN_RES_WAITING) {
636 InfoLog("HandleBtDisconnectWaiting: waiting for disconnect result");
637 return true;
638 }
639 if (g_a2dpConnState == BtConnResult::CONN_RES_DISCONNECTED &&
640 g_hfpConnState == BtConnResult::CONN_RES_DISCONNECTED) {
641 InfoLog("HandleBtDisconnectWaiting: disconnect success");
642 return false;
643 }
644 }
645 return false;
646 }
647
NextActionDisconnect()648 void BtConnectionManager::NextActionDisconnect()
649 {
650 int pairState = 0;
651 g_device.GetPairState(pairState);
652 InfoLog("NextActionConnect: state: %{public}d, pairState: %{public}d", g_state, pairState);
653 switch (g_state) {
654 case STATE_INIT_COMPLETE: {
655 g_state = STATE_DISCONNECTING;
656 if (HandleBtDisconnect()) {
657 InfoLog("NextActionConnect: disconnecting need wait");
658 break;
659 }
660 // fall-through
661 // when already disconnected
662 }
663 case STATE_DISCONNECTING: {
664 if (!HandleBtDisconnectWaiting()) {
665 OnFinish();
666 }
667 break;
668 }
669 default:
670 break;
671 }
672 }
673
NextAction()674 void BtConnectionManager::NextAction()
675 {
676 InfoLog("NextAction: state: %{public}d action: %{public}d", g_state, g_action);
677 switch (g_action) {
678 case ACTION_INIT:
679 NextActionInit();
680 break;
681 case ACTION_CONNECT:
682 NextActionConnect();
683 break;
684 case ACTION_DISCONNECT:
685 NextActionDisconnect();
686 break;
687 default:
688 break;
689 }
690 }
691
TryPairBt(std::shared_ptr<BtData> data)692 void BtConnectionManager::TryPairBt(std::shared_ptr<BtData> data)
693 {
694 std::unique_lock<std::shared_mutex> guard(mutex_);
695 if (!data || !data->isValid_) {
696 ErrorLog("TryPairBt: data error");
697 return;
698 }
699 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT);
700 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_TIMEOUT);
701 g_btData = data;
702 g_action = ACTION_INIT;
703 RegisterBtObserver();
704 if (IsBtEnabled()) {
705 g_state = STATE_INIT;
706 NextAction();
707 } else {
708 g_state = STATE_WAITING_FOR_BT_ENABLE;
709 if (!HandleEnableBt()) {
710 ErrorLog("TryPairBt enable bt failed");
711 OnFinish();
712 }
713 }
714 }
715
PublishPairBtNtf()716 void BtConnectionManager::PublishPairBtNtf()
717 {
718 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT);
719 if (g_btData == nullptr) {
720 ErrorLog("PublishPairBtNtf: g_btData nullptr");
721 return;
722 }
723 InfoLog("PublishPairBtNtf: Publish notification name: %{private}s", g_btData->name_.c_str());
724 ExternalDepsProxy::GetInstance().PublishNfcNotification(NFC_BT_NOTIFICATION_ID, g_btData->name_, 0);
725 }
726
OnBtNtfClicked()727 void BtConnectionManager::OnBtNtfClicked()
728 {
729 InfoLog("OnBtNtfClicked");
730 std::unique_lock<std::shared_mutex> guard(mutex_);
731 if (g_btData == nullptr) {
732 ErrorLog("OnBtNtfClicked: g_btData error");
733 return;
734 }
735 g_action = ACTION_CONNECT;
736 if (IsBtEnabled()) {
737 g_state = STATE_PAIRING;
738 HandleBtPair();
739 NextAction();
740 } else {
741 g_state = STATE_WAITING_FOR_BT_ENABLE;
742 if (!HandleEnableBt()) {
743 ErrorLog("OnBtNtfClicked enable bt failed");
744 OnFinish();
745 }
746 }
747 }
748
OnBtEnabled()749 void BtConnectionManager::OnBtEnabled()
750 {
751 DebugLog("OnBtEnabled");
752 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_ENABLE_TIMEOUT);
753 if (g_state == STATE_WAITING_FOR_BT_ENABLE) {
754 g_state = STATE_INIT;
755 NextAction();
756 }
757 }
758
OnStateChanged(const int transport,const int status)759 void BtConnectionManager::BtStateObserver::OnStateChanged(const int transport, const int status)
760 {
761 InfoLog("OnStateChanged transport: %{public}d, status: %{public}d", transport, status);
762 if (transport == static_cast<int>(Bluetooth::BTTransport::ADAPTER_BREDR) &&
763 status == static_cast<int>(Bluetooth::STATE_TURN_ON)) {
764 BtConnectionManager::GetInstance().OnBtEnabled();
765 }
766 }
767
OnPairStatusChanged(std::shared_ptr<BtConnectionInfo> info)768 void BtConnectionManager::OnPairStatusChanged(std::shared_ptr<BtConnectionInfo> info)
769 {
770 std::unique_lock<std::shared_mutex> guard(mutex_);
771 if (info == nullptr) {
772 ErrorLog("OnPairStatusChanged: info is null");
773 return;
774 }
775 if (g_btData == nullptr) {
776 ErrorLog("OnPairStatusChanged: g_btData error");
777 return;
778 }
779 if (info->macAddr_.compare(g_btData->macAddress_) != 0) {
780 ErrorLog("OnPairStatusChanged not same device");
781 return;
782 }
783 if (g_state == STATE_PAIRING) {
784 if (info->state_ == Bluetooth::PAIR_PAIRED) {
785 RemoveMsgFromEvtHandler(NfcCommonEvent::MSG_BT_PAIR_TIMEOUT);
786 g_state = STATE_PAIR_COMPLETE;
787 NextAction();
788 } else if (info->state_ == Bluetooth::PAIR_NONE) {
789 // timeout msg removed in OnFinish()
790 OnFinish();
791 }
792 }
793 }
794
OnPairStatusChanged(const Bluetooth::BluetoothRemoteDevice & device,int status,int cause)795 void BtConnectionManager::BtRemoteDevObserver::OnPairStatusChanged(const Bluetooth::BluetoothRemoteDevice &device,
796 int status, int cause)
797 {
798 (void)cause; // Unused parameter
799 InfoLog("OnPairStatusChanged status: %{public}d", status);
800 BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_PAIR_STATUS_CHANGED,
801 device, status, BtConnectionManager::BtProfileType::A2DP_SRC);
802 }
803
OnConnectionStateChanged(std::shared_ptr<BtConnectionInfo> info)804 void BtConnectionManager::OnConnectionStateChanged(std::shared_ptr<BtConnectionInfo> info)
805 {
806 std::unique_lock<std::shared_mutex> guard(mutex_);
807 if (info == nullptr) {
808 ErrorLog("OnConnectionStateChanged: info is null");
809 return;
810 }
811 if (g_btData == nullptr) {
812 ErrorLog("OnConnectionStateChanged: g_btData error");
813 return;
814 }
815 if (info->macAddr_.compare(g_btData->macAddress_) != 0) {
816 ErrorLog("OnConnectionStateChanged not same device");
817 return;
818 }
819 if (info->state_ == static_cast<int32_t>(Bluetooth::BTConnectState::CONNECTED)) {
820 {
821 if (info->type_ == static_cast<uint8_t>(HFP_AG)) {
822 g_hfpConnState = CONN_RES_CONNECTED;
823 } else if (info->type_ == static_cast<uint8_t>(A2DP_SRC)) {
824 g_a2dpConnState = CONN_RES_CONNECTED;
825 } else if (info->type_ == static_cast<uint8_t>(HID_HOST)) {
826 g_hidConnState = CONN_RES_CONNECTED;
827 }
828 }
829 NextAction();
830 } else if (info->state_ == static_cast<int32_t>(Bluetooth::BTConnectState::DISCONNECTED)) {
831 {
832 if (g_action == ACTION_CONNECT) {
833 // need retry
834 return;
835 }
836 if (info->type_ == static_cast<uint8_t>(HFP_AG)) {
837 g_hfpConnState = CONN_RES_DISCONNECTED;
838 } else if (info->type_ == static_cast<uint8_t>(A2DP_SRC)) {
839 g_a2dpConnState = CONN_RES_DISCONNECTED;
840 } else if (info->type_ == static_cast<uint8_t>(HID_HOST)) {
841 g_hidConnState = CONN_RES_DISCONNECTED;
842 }
843 }
844 NextAction();
845 }
846 }
847
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state,int32_t cause)848 void BtConnectionManager::BtA2dpObserver::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
849 int32_t state, int32_t cause)
850 {
851 (void)cause; // Unused param
852 InfoLog("BtA2dpObserver::OnConnectionStateChanged state: %{public}d", state);
853 BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_STATUS_CHANGED,
854 device, state, BtConnectionManager::BtProfileType::A2DP_SRC);
855 }
856
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state,int32_t cause)857 void BtConnectionManager::BtHfpObserver::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
858 int32_t state, int32_t cause)
859 {
860 (void)cause; // Unused param
861 InfoLog("BtHfpObserver::OnConnectionStateChanged state: %{public}d", state);
862 BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_STATUS_CHANGED,
863 device, state, BtConnectionManager::BtProfileType::HFP_AG);
864 }
865
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int state,int cause)866 void BtConnectionManager::BtHidObserver::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
867 int state, int cause)
868 {
869 (void)cause; // Unused param
870 InfoLog("BtHidObserver::OnConnectionStateChanged state: %{public}d", state);
871 BtConnectionManager::GetInstance().SendConnMsgToEvtHandler(NfcCommonEvent::MSG_BT_CONNECT_STATUS_CHANGED,
872 device, state, BtConnectionManager::BtProfileType::HID_HOST);
873 }
874 } // namespace TAG
875 } // namespace NFC
876 } // namespace OHOS
877