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 "audio_control_manager.h"
19 #include "bluetooth_call_manager.h"
20 #include "telephony_log_wrapper.h"
21 #ifdef ABILITY_BLUETOOTH_SUPPORT
22 #include "bluetooth_host.h"
23
24 constexpr int32_t PHONE_NUMBER_TYPE = 0x81;
25 #endif
26
27 namespace OHOS {
28 namespace Telephony {
BluetoothConnection()29 BluetoothConnection::BluetoothConnection() : connectedScoAddr_("") {}
30
~BluetoothConnection()31 BluetoothConnection::~BluetoothConnection()
32 {
33 #ifdef ABILITY_BLUETOOTH_SUPPORT
34 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
35 if (profile == nullptr) {
36 TELEPHONY_LOGE("profile is nullptr");
37 } else {
38 profile->DeregisterObserver(this);
39 }
40
41 if (statusChangeListener_ != nullptr) {
42 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
43 if (samgrProxy != nullptr) {
44 samgrProxy->UnSubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, statusChangeListener_);
45 statusChangeListener_ = nullptr;
46 }
47 }
48 std::lock_guard<std::mutex> lock(bluetoothMutex_);
49 mapConnectedBtDevices_.clear();
50 #endif
51 }
52
Init()53 void BluetoothConnection::Init()
54 {
55 #ifdef ABILITY_BLUETOOTH_SUPPORT
56 statusChangeListener_ = new (std::nothrow) SystemAbilityListener();
57 if (statusChangeListener_ == nullptr) {
58 TELEPHONY_LOGE("failed to create statusChangeListener");
59 return;
60 }
61 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
62 if (managerPtr == nullptr) {
63 TELEPHONY_LOGE("get system ability manager error");
64 return;
65 }
66 int32_t ret = managerPtr->SubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, statusChangeListener_);
67 if (ret != TELEPHONY_SUCCESS) {
68 TELEPHONY_LOGE("failed to subscribe bluetooth service SA:%{public}d", BLUETOOTH_HOST_SYS_ABILITY_ID);
69 return;
70 }
71 TELEPHONY_LOGI("BluetoothConnection init success!");
72 #endif
73 }
74
ConnectBtSco()75 bool BluetoothConnection::ConnectBtSco()
76 {
77 if (btScoState_.load() == BtScoState::SCO_STATE_CONNECTED) {
78 TELEPHONY_LOGI("BluetoothConnection::ConnectBtSco bluetooth sco is already connected");
79 return true;
80 }
81 #ifdef ABILITY_BLUETOOTH_SUPPORT
82 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
83 if (profile == nullptr) {
84 TELEPHONY_LOGE("profile is nullptr");
85 return false;
86 }
87
88 Bluetooth::BluetoothRemoteDevice *device = nullptr;
89 std::string connectedScoAddr = GetConnectedScoAddr();
90 if (!connectedScoAddr.empty()) {
91 TELEPHONY_LOGI("connectedScoAddr_ is not empty");
92 device = GetBtDevice(connectedScoAddr);
93 } else {
94 std::lock_guard<std::mutex> lock(bluetoothMutex_);
95 if (!mapConnectedBtDevices_.empty()) {
96 TELEPHONY_LOGI("mapConnectedBtDevices_ is not empty");
97 device = &mapConnectedBtDevices_.begin()->second;
98 } else {
99 TELEPHONY_LOGE("device is invalid");
100 }
101 }
102
103 if (device == nullptr) {
104 TELEPHONY_LOGE("device is nullptr");
105 return false;
106 }
107 if (profile->SetActiveDevice(*device) && profile->ConnectSco()) {
108 return true;
109 }
110 #endif
111 TELEPHONY_LOGE("Connect Bluetooth Sco Fail !");
112 return false;
113 }
114
DisconnectBtSco()115 bool BluetoothConnection::DisconnectBtSco()
116 {
117 if (btScoState_.load() == BtScoState::SCO_STATE_DISCONNECTED) {
118 TELEPHONY_LOGI("bluetooth sco is already disconnected");
119 return true;
120 }
121 #ifdef ABILITY_BLUETOOTH_SUPPORT
122 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
123 if (profile == nullptr) {
124 TELEPHONY_LOGE("profile is nullptr");
125 return false;
126 }
127 return profile->DisconnectSco();
128 #endif
129 TELEPHONY_LOGE("Disconnect Bluetooth Sco Fail !");
130 return false;
131 }
132
133 #ifdef ABILITY_BLUETOOTH_SUPPORT
ConnectBtSco(const std::string & bluetoothAddress)134 bool BluetoothConnection::ConnectBtSco(const std::string &bluetoothAddress)
135 {
136 if (bluetoothAddress == GetConnectedScoAddr() && btScoState_.load() == BtScoState::SCO_STATE_CONNECTED) {
137 TELEPHONY_LOGI("bluetooth sco is already connected");
138 return true;
139 }
140
141 Bluetooth::BluetoothRemoteDevice device =
142 Bluetooth::BluetoothHost::GetDefaultHost().GetRemoteDevice(bluetoothAddress, Bluetooth::BT_TRANSPORT_BREDR);
143 AddBtDevice(bluetoothAddress, device);
144
145 return ConnectBtSco(device);
146 }
147
ConnectBtSco(const Bluetooth::BluetoothRemoteDevice & device)148 bool BluetoothConnection::ConnectBtSco(const Bluetooth::BluetoothRemoteDevice &device)
149 {
150 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
151 if (profile == nullptr) {
152 TELEPHONY_LOGE("profile is nullptr");
153 return false;
154 }
155
156 if (profile->SetActiveDevice(device) && profile->ConnectSco()) {
157 SetConnectedScoAddr(device.GetDeviceAddr());
158 btScoState_.store(BtScoState::SCO_STATE_CONNECTED);
159 TELEPHONY_LOGI("connect bluetooth sco success");
160 return true;
161 }
162 TELEPHONY_LOGE("connect bluetooth sco fail");
163 return false;
164 }
165
DisconnectBtSco(const Bluetooth::BluetoothRemoteDevice & device)166 bool BluetoothConnection::DisconnectBtSco(const Bluetooth::BluetoothRemoteDevice &device)
167 {
168 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
169 if (profile == nullptr) {
170 TELEPHONY_LOGE("profile is nullptr");
171 return false;
172 }
173
174 if (profile->Disconnect(device)) {
175 SetConnectedScoAddr("");
176 btScoState_.store(BtScoState::SCO_STATE_DISCONNECTED);
177 TELEPHONY_LOGI("disconnect bluetooth sco success");
178 return true;
179 }
180
181 TELEPHONY_LOGE("Disconnect Bluetooth Sco Fail !");
182 return false;
183 }
184
IsBtAvailble()185 bool BluetoothConnection::IsBtAvailble()
186 {
187 std::lock_guard<std::mutex> lock(bluetoothMutex_);
188 if (mapConnectedBtDevices_.empty()) {
189 TELEPHONY_LOGE("mapConnectedBtDevices_ is empty");
190 return false;
191 }
192
193 return true;
194 }
195 #endif
196
IsBtScoConnected()197 bool BluetoothConnection::IsBtScoConnected()
198 {
199 return btScoState_.load() == BtScoState::SCO_STATE_CONNECTED;
200 }
201
SetBtScoState(BtScoState state)202 void BluetoothConnection::SetBtScoState(BtScoState state)
203 {
204 btScoState_.store(state);
205 }
206
SendBtCallState(int32_t numActive,int32_t numHeld,int32_t callState,const std::string & number)207 int32_t BluetoothConnection::SendBtCallState(
208 int32_t numActive, int32_t numHeld, int32_t callState, const std::string &number)
209 {
210 #ifdef ABILITY_BLUETOOTH_SUPPORT
211 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
212 if (profile == nullptr) {
213 TELEPHONY_LOGE("profile is nullptr");
214 return TELEPHONY_ERROR;
215 }
216
217 std::string nickName = "";
218 profile->PhoneStateChanged(numActive, numHeld, callState, number, PHONE_NUMBER_TYPE, nickName);
219 #endif
220 TELEPHONY_LOGI("PhoneStateChanged,numActive:%{public}d,numHeld:%{public}d,callState:%{public}d", numActive, numHeld,
221 callState);
222 return TELEPHONY_SUCCESS;
223 }
224
GetBtScoState()225 BtScoState BluetoothConnection::GetBtScoState()
226 {
227 BtScoState btScoState = btScoState_.load();
228 TELEPHONY_LOGI("current bluetooth sco state : %{public}d", btScoState);
229 return btScoState;
230 }
231
IsAudioActivated()232 bool BluetoothConnection::IsAudioActivated()
233 {
234 return DelayedSingleton<AudioControlManager>::GetInstance()->IsAudioActivated();
235 }
236
GetConnectedScoAddr()237 std::string BluetoothConnection::GetConnectedScoAddr()
238 {
239 std::lock_guard<std::mutex> lock(scoAddrMutex_);
240 return connectedScoAddr_;
241 }
242
243 #ifdef ABILITY_BLUETOOTH_SUPPORT
SetConnectedScoAddr(std::string connectedScoAddr)244 void BluetoothConnection::SetConnectedScoAddr(std::string connectedScoAddr)
245 {
246 std::lock_guard<std::mutex> lock(scoAddrMutex_);
247 connectedScoAddr_ = connectedScoAddr;
248 }
249
ResetBtConnection()250 void BluetoothConnection::ResetBtConnection()
251 {
252 SetConnectedScoAddr("");
253 btScoState_.store(BtScoState::SCO_STATE_DISCONNECTED);
254 std::lock_guard<std::mutex> lock(bluetoothMutex_);
255 mapConnectedBtDevices_.clear();
256 }
257
RegisterObserver()258 void BluetoothConnection::RegisterObserver()
259 {
260 Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
261 if (profile == nullptr) {
262 TELEPHONY_LOGE("BluetoothConnection RegisterObserver fail!");
263 return;
264 }
265
266 profile->RegisterObserver(this);
267 }
268
OnScoStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state)269 void BluetoothConnection::OnScoStateChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t state)
270 {
271 TELEPHONY_LOGI("BluetoothConnection::OnScoStateChanged state : %{public}d", state);
272 switch (state) {
273 case (int32_t)Bluetooth::HfpScoConnectState::SCO_CONNECTED:
274 SetConnectedScoAddr(device.GetDeviceAddr());
275 btScoState_.store(BtScoState::SCO_STATE_CONNECTED);
276 break;
277 case (int32_t)Bluetooth::HfpScoConnectState::SCO_DISCONNECTED:
278 if (device.GetDeviceAddr() == GetConnectedScoAddr()) {
279 SetConnectedScoAddr("");
280 btScoState_.store(BtScoState::SCO_STATE_DISCONNECTED);
281 }
282 break;
283 default:
284 break;
285 }
286 }
287
AddBtDevice(const std::string & address,Bluetooth::BluetoothRemoteDevice device)288 void BluetoothConnection::AddBtDevice(const std::string &address, Bluetooth::BluetoothRemoteDevice device)
289 {
290 std::lock_guard<std::mutex> lock(bluetoothMutex_);
291 auto iter = mapConnectedBtDevices_.find(address);
292 if (iter != mapConnectedBtDevices_.end()) {
293 TELEPHONY_LOGI("device is existenced");
294 } else {
295 mapConnectedBtDevices_.insert(std::pair<std::string, const Bluetooth::BluetoothRemoteDevice>(address, device));
296 TELEPHONY_LOGI("AddBtDevice success");
297 }
298 }
299
RemoveBtDevice(const std::string & address)300 void BluetoothConnection::RemoveBtDevice(const std::string &address)
301 {
302 std::lock_guard<std::mutex> lock(bluetoothMutex_);
303 if (mapConnectedBtDevices_.count(address) > 0) {
304 mapConnectedBtDevices_.erase(address);
305 TELEPHONY_LOGI("RemoveBtDevice success");
306 } else {
307 TELEPHONY_LOGE("device is not existenced");
308 }
309 }
310
GetBtDevice(const std::string & address)311 Bluetooth::BluetoothRemoteDevice *BluetoothConnection::GetBtDevice(const std::string &address)
312 {
313 std::lock_guard<std::mutex> lock(bluetoothMutex_);
314 if (mapConnectedBtDevices_.count(address) > 0) {
315 auto iter = mapConnectedBtDevices_.find(address);
316 if (iter != mapConnectedBtDevices_.end()) {
317 return &iter->second;
318 }
319 }
320 TELEPHONY_LOGE("device is not existenced");
321 return nullptr;
322 }
323
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state)324 void BluetoothConnection::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t state)
325 {
326 TELEPHONY_LOGI("BluetoothConnection::OnConnectionStateChanged state : %{public}d", state);
327 std::string macAddress = device.GetDeviceAddr();
328 switch (state) {
329 case (int32_t)Bluetooth::BTConnectState::CONNECTED:
330 DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(
331 macAddress, AudioDeviceType::DEVICE_BLUETOOTH_SCO);
332 AddBtDevice(macAddress, device);
333 /** try to connect sco while new bluetooth device connected
334 * if connect sco successfully , should switch current audio device to bluetooth sco
335 */
336 if (BluetoothConnection::GetBtScoState() == BtScoState::SCO_STATE_DISCONNECTED && IsAudioActivated()) {
337 ConnectBtSco(device);
338 }
339 break;
340 case (int32_t)Bluetooth::BTConnectState::DISCONNECTED:
341 DelayedSingleton<AudioDeviceManager>::GetInstance()->RemoveAudioDeviceList(
342 macAddress, AudioDeviceType::DEVICE_BLUETOOTH_SCO);
343 RemoveBtDevice(macAddress);
344 break;
345 default:
346 break;
347 }
348 }
349
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)350 void SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
351 {
352 TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
353 if (!CheckInputSysAbilityId(systemAbilityId)) {
354 TELEPHONY_LOGE("added SA is invalid!");
355 return;
356 }
357 if (systemAbilityId != BLUETOOTH_HOST_SYS_ABILITY_ID) {
358 TELEPHONY_LOGE("added SA is not bluetooth service, ignored.");
359 return;
360 }
361
362 DelayedSingleton<BluetoothConnection>::GetInstance()->RegisterObserver();
363 }
364
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)365 void SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
366 {
367 TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
368 if (!CheckInputSysAbilityId(systemAbilityId)) {
369 TELEPHONY_LOGE("removed SA is invalid!");
370 return;
371 }
372 if (systemAbilityId != BLUETOOTH_HOST_SYS_ABILITY_ID) {
373 TELEPHONY_LOGE("removed SA is not bluetooth service, ignored.");
374 return;
375 }
376
377 DelayedSingleton<BluetoothConnection>::GetInstance()->ResetBtConnection();
378 std::shared_ptr<AudioDeviceManager> audioDeviceManager = DelayedSingleton<AudioDeviceManager>::GetInstance();
379 audioDeviceManager->ResetBtAudioDevicesList();
380 audioDeviceManager->ProcessEvent(AudioEvent::INIT_AUDIO_DEVICE);
381 }
382 #endif
383 } // namespace Telephony
384 } // namespace OHOS
385