1 /*
2 * Copyright (C) 2021 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 "bluetooth_connection.h"
17
18 #include "telephony_log_wrapper.h"
19
20 #include "audio_control_manager.h"
21 #include "bluetooth_call_manager.h"
22 #ifdef ABILITY_BLUETOOTH_SUPPORT
23 #include "bt_def.h"
24 #endif
25
26 namespace OHOS {
27 namespace Telephony {
28 BtScoState BluetoothConnection::btScoState_ = BtScoState::SCO_STATE_DISCONNECTED;
29
BluetoothConnection()30 BluetoothConnection::BluetoothConnection() : connectedScoAddr_("") {}
31
~BluetoothConnection()32 BluetoothConnection::~BluetoothConnection()
33 {
34 connectedBtDevices_.clear();
35 }
36
ConnectBtSco()37 bool BluetoothConnection::ConnectBtSco()
38 {
39 if (btScoState_ == BtScoState::SCO_STATE_CONNECTED) {
40 TELEPHONY_LOGI("bluetooth sco is already connected");
41 return true;
42 }
43 #ifdef ABILITY_BLUETOOTH_SUPPORT
44 return Bluetooth::HandsFreeAudioGateway.GetProfile()->ConnectSco();
45 #endif
46 return true;
47 }
48
DisconnectBtSco()49 bool BluetoothConnection::DisconnectBtSco()
50 {
51 if (btScoState_ == BtScoState::SCO_STATE_DISCONNECTED) {
52 TELEPHONY_LOGI("bluetooth sco is already disconnected");
53 return true;
54 }
55 #ifdef ABILITY_BLUETOOTH_SUPPORT
56 return Bluetooth::HandsFreeAudioGateway.GetProfile()->DisconnectSco();
57 #endif
58 return true;
59 }
60
61 #ifdef ABILITY_BLUETOOTH_SUPPORT
ConnectBtSco(const Bluetooth::BluetoothRemoteDevice & device)62 bool BluetoothConnection::ConnectBtSco(const Bluetooth::BluetoothRemoteDevice &device)
63 {
64 bool result = Bluetooth::HandsFreeAudioGateway.GetProfile()->Connect(device);
65 if (result) {
66 connectedScoAddr_ = device.GetDeviceAddr();
67 btScoState_ = BtScoState::SCO_STATE_CONNECTED;
68 TELEPHONY_LOGI("connect bluetooth sco success");
69 } else {
70 TELEPHONY_LOGE("connect bluetooth sco failed");
71 }
72 return result;
73 }
74
DisconnectBtSco(const Bluetooth::BluetoothRemoteDevice & device)75 bool BluetoothConnection::DisconnectBtSco(const Bluetooth::BluetoothRemoteDevice &device)
76 {
77 bool result = Bluetooth::HandsFreeAudioGateway::GetProfile()->Disconnect(device);
78 if (result) {
79 connectedScoAddr_ = "";
80 btScoState_ = BtScoState::SCO_STATE_DISCONNECTED;
81 TELEPHONY_LOGI("disconnect bluetooth sco success");
82 } else {
83 TELEPHONY_LOGE("disconnect bluetooth sco failed");
84 }
85 return result;
86 }
87 #endif
88
IsBtScoConnected()89 bool BluetoothConnection::IsBtScoConnected()
90 {
91 return btScoState_ == BtScoState::SCO_STATE_CONNECTED;
92 }
93
SetBtScoState(BtScoState state)94 void BluetoothConnection::SetBtScoState(BtScoState state)
95 {
96 btScoState_ = state;
97 }
98
SendBtCallState(int32_t numActive,int32_t numHeld,int32_t callState,const std::string & number)99 int32_t BluetoothConnection::SendBtCallState(
100 int32_t numActive, int32_t numHeld, int32_t callState, const std::string &number)
101 {
102 #ifdef ABILITY_BLUETOOTH_SUPPORT
103 std::string nickName = "";
104 constexpr int32_t numberType = 0x81;
105 Bluetooth::HandsFreeAudioGateway.GetProfile()->
106 PhoneStateChanged(numActive, numHeld, callState, number, numberType, nickName);
107 #endif
108 TELEPHONY_LOGI("PhoneStateChanged,numActive:%{public}d,numHeld:%{public}d,callState:%{public}d",
109 numActive, numHeld, callState);
110 return TELEPHONY_SUCCESS;
111 }
112
GetBtScoState()113 BtScoState BluetoothConnection::GetBtScoState()
114 {
115 TELEPHONY_LOGI("current bluetooth sco state : %{public}d", btScoState_);
116 return btScoState_;
117 }
118
IsAudioActivated()119 bool BluetoothConnection::IsAudioActivated()
120 {
121 return DelayedSingleton<AudioControlManager>::GetInstance()->IsAudioActivated();
122 }
123
124 #ifdef ABILITY_BLUETOOTH_SUPPORT
OnScoStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state)125 void BluetoothConnection::OnScoStateChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t state)
126 {
127 switch (state) {
128 case (int32_t)Bluetooth::BTConnectState::CONNECTED:
129 if (connectedScoAddr_.empty()) {
130 connectedScoAddr_ = device.GetDeviceAddr();
131 BluetoothConnection::SetBtScoState(BtScoState::SCO_STATE_CONNECTED);
132 }
133 break;
134 case (int32_t)Bluetooth::BTConnectState::DISCONNECTED:
135 if (device.GetDeviceAddr() == connectedScoAddr_) {
136 connectedScoAddr_ = "";
137 BluetoothConnection::SetBtScoState(BtScoState::SCO_STATE_DISCONNECTED);
138 DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(
139 AudioEvent::BLUETOOTH_SCO_DISCONNECTED);
140 }
141 break;
142 default:
143 break;
144 }
145 }
146
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state)147 void BluetoothConnection::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t state)
148 {
149 std::string macAddress = device.GetDeviceAddr();
150 switch (state) {
151 case (int32_t)Bluetooth::BTConnectState::CONNECTED:
152 if (connectedBtDevices_.count(macAddress) == 0) {
153 connectedBtDevices_.insert(macAddress);
154 /** try to connect sco while new bluetooth device connected
155 * if connect sco successfully , should switch current audio device to bluetooth sco
156 */
157 if (BluetoothConnection::GetBtScoState() == BtScoState::SCO_STATE_DISCONNECTED &&
158 IsAudioActivated() && ConnectBtSco(macAddress)) {
159 connectedScoAddr_ = macAddress;
160 DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(
161 AudioEvent::BLUETOOTH_SCO_CONNECTED);
162 }
163 }
164 break;
165 case (int32_t)Bluetooth::BTConnectState::DISCONNECTED:
166 if (connectedBtDevices_.count(macAddress) > 0) {
167 connectedBtDevices_.erase(macAddress);
168 }
169 break;
170 default:
171 break;
172 }
173 }
174 #endif
175 } // namespace Telephony
176 } // namespace OHOS