• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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