• 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     mapConnectedBtDevices_.clear();
35     Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
36     if (profile == nullptr) {
37         TELEPHONY_LOGE("profile is nullptr");
38     } else {
39         profile->DeregisterObserver(this);
40     }
41 #endif
42 }
43 
Init()44 void BluetoothConnection::Init()
45 {
46 #ifdef ABILITY_BLUETOOTH_SUPPORT
47     Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
48     if (profile == nullptr) {
49         TELEPHONY_LOGE("BluetoothConnection init fail!");
50         return;
51     }
52 
53     profile->RegisterObserver(this);
54     TELEPHONY_LOGI("BluetoothConnection init success!");
55 #endif
56 }
57 
ConnectBtSco()58 bool BluetoothConnection::ConnectBtSco()
59 {
60     if (btScoState_ == BtScoState::SCO_STATE_CONNECTED) {
61         TELEPHONY_LOGI("BluetoothConnection::ConnectBtSco bluetooth sco is already connected");
62         return true;
63     }
64 #ifdef ABILITY_BLUETOOTH_SUPPORT
65     Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
66     if (profile == nullptr) {
67         TELEPHONY_LOGE("profile is nullptr");
68         return false;
69     }
70 
71     Bluetooth::BluetoothRemoteDevice *device = nullptr;
72     if (!connectedScoAddr_.empty()) {
73         TELEPHONY_LOGI("connectedScoAddr_ is not empty");
74         device = GetBtDevice(connectedScoAddr_);
75     } else if (!mapConnectedBtDevices_.empty()) {
76         TELEPHONY_LOGI("mapConnectedBtDevices_ is not empty");
77         device = &mapConnectedBtDevices_.begin()->second;
78     } else {
79         TELEPHONY_LOGE("device is invalid");
80     }
81 
82     if (device == nullptr) {
83         TELEPHONY_LOGE("device is nullptr");
84         return false;
85     }
86     if (profile->SetActiveDevice(*device) && profile->ConnectSco()) {
87         btScoState_ = BtScoState::SCO_STATE_CONNECTED;
88         connectedScoAddr_ = device->GetDeviceAddr();
89         DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::BLUETOOTH_SCO_CONNECTED);
90         TELEPHONY_LOGI("bluetooth sco connected successfully.");
91         return true;
92     }
93 #endif
94     TELEPHONY_LOGE("Connect Bluetooth Sco Fail !");
95     return false;
96 }
97 
DisconnectBtSco()98 bool BluetoothConnection::DisconnectBtSco()
99 {
100     if (btScoState_ == BtScoState::SCO_STATE_DISCONNECTED) {
101         TELEPHONY_LOGI("bluetooth sco is already disconnected");
102         return true;
103     }
104 #ifdef ABILITY_BLUETOOTH_SUPPORT
105     Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
106     if (profile == nullptr) {
107         TELEPHONY_LOGE("profile is nullptr");
108         return false;
109     }
110     return profile->DisconnectSco();
111 #endif
112     TELEPHONY_LOGE("Disconnect Bluetooth Sco Fail !");
113     return false;
114 }
115 
116 #ifdef ABILITY_BLUETOOTH_SUPPORT
ConnectBtSco(const std::string & bluetoothAddress)117 bool BluetoothConnection::ConnectBtSco(const std::string &bluetoothAddress)
118 {
119     if (bluetoothAddress == connectedScoAddr_ && btScoState_ == BtScoState::SCO_STATE_CONNECTED) {
120         TELEPHONY_LOGI("bluetooth sco is already connected");
121         return true;
122     }
123 
124     Bluetooth::BluetoothRemoteDevice device =
125         Bluetooth::BluetoothHost::GetDefaultHost().GetRemoteDevice(bluetoothAddress, Bluetooth::BT_TRANSPORT_BREDR);
126     AddBtDevice(bluetoothAddress, device);
127 
128     return ConnectBtSco(device);
129 }
130 
ConnectBtSco(const Bluetooth::BluetoothRemoteDevice & device)131 bool BluetoothConnection::ConnectBtSco(const Bluetooth::BluetoothRemoteDevice &device)
132 {
133     Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
134     if (profile == nullptr) {
135         TELEPHONY_LOGE("profile is nullptr");
136         return false;
137     }
138 
139     if (profile->SetActiveDevice(device) && profile->ConnectSco()) {
140         connectedScoAddr_ = device.GetDeviceAddr();
141         btScoState_ = BtScoState::SCO_STATE_CONNECTED;
142         TELEPHONY_LOGI("connect bluetooth sco success");
143         return true;
144     }
145     TELEPHONY_LOGE("connect bluetooth sco fail");
146     return false;
147 }
148 
DisconnectBtSco(const Bluetooth::BluetoothRemoteDevice & device)149 bool BluetoothConnection::DisconnectBtSco(const Bluetooth::BluetoothRemoteDevice &device)
150 {
151     Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
152     if (profile == nullptr) {
153         TELEPHONY_LOGE("profile is nullptr");
154         return false;
155     }
156 
157     if (profile->Disconnect(device)) {
158         connectedScoAddr_ = "";
159         btScoState_ = BtScoState::SCO_STATE_DISCONNECTED;
160         TELEPHONY_LOGI("disconnect bluetooth sco success");
161         return true;
162     }
163 
164     TELEPHONY_LOGE("Disconnect Bluetooth Sco Fail !");
165     return false;
166 }
167 
IsBtAvailble()168 bool BluetoothConnection::IsBtAvailble()
169 {
170     if (mapConnectedBtDevices_.empty()) {
171         TELEPHONY_LOGE("mapConnectedBtDevices_ is empty");
172         return false;
173     }
174 
175     return true;
176 }
177 #endif
178 
IsBtScoConnected()179 bool BluetoothConnection::IsBtScoConnected()
180 {
181     return btScoState_ == BtScoState::SCO_STATE_CONNECTED;
182 }
183 
SetBtScoState(BtScoState state)184 void BluetoothConnection::SetBtScoState(BtScoState state)
185 {
186     btScoState_ = state;
187 }
188 
SendBtCallState(int32_t numActive,int32_t numHeld,int32_t callState,const std::string & number)189 int32_t BluetoothConnection::SendBtCallState(
190     int32_t numActive, int32_t numHeld, int32_t callState, const std::string &number)
191 {
192 #ifdef ABILITY_BLUETOOTH_SUPPORT
193     Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
194     if (profile == nullptr) {
195         TELEPHONY_LOGE("profile is nullptr");
196         return TELEPHONY_ERROR;
197     }
198 
199     std::string nickName = "";
200     profile->PhoneStateChanged(numActive, numHeld, callState, number, PHONE_NUMBER_TYPE, nickName);
201 #endif
202     TELEPHONY_LOGI("PhoneStateChanged,numActive:%{public}d,numHeld:%{public}d,callState:%{public}d", numActive, numHeld,
203         callState);
204     return TELEPHONY_SUCCESS;
205 }
206 
GetBtScoState()207 BtScoState BluetoothConnection::GetBtScoState()
208 {
209     TELEPHONY_LOGI("current bluetooth sco state : %{public}d", btScoState_);
210     return btScoState_;
211 }
212 
IsAudioActivated()213 bool BluetoothConnection::IsAudioActivated()
214 {
215     return DelayedSingleton<AudioControlManager>::GetInstance()->IsAudioActivated();
216 }
217 
218 #ifdef ABILITY_BLUETOOTH_SUPPORT
OnScoStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state)219 void BluetoothConnection::OnScoStateChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t state)
220 {
221     TELEPHONY_LOGI("BluetoothConnection::OnScoStateChanged state : %{public}d", state);
222     switch (state) {
223         case (int32_t)Bluetooth::HfpScoConnectState::SCO_CONNECTED:
224             connectedScoAddr_ = device.GetDeviceAddr();
225             btScoState_ = BtScoState::SCO_STATE_CONNECTED;
226             DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::BLUETOOTH_SCO_CONNECTED);
227             break;
228         case (int32_t)Bluetooth::HfpScoConnectState::SCO_DISCONNECTED:
229             if (device.GetDeviceAddr() == connectedScoAddr_) {
230                 connectedScoAddr_ = "";
231                 btScoState_ = BtScoState::SCO_STATE_DISCONNECTED;
232                 DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(
233                     AudioEvent::BLUETOOTH_SCO_DISCONNECTED);
234             }
235             break;
236         default:
237             break;
238     }
239 }
240 
AddBtDevice(const std::string & address,Bluetooth::BluetoothRemoteDevice device)241 void BluetoothConnection::AddBtDevice(const std::string &address, Bluetooth::BluetoothRemoteDevice device)
242 {
243     auto iter = mapConnectedBtDevices_.find(address);
244     if (iter != mapConnectedBtDevices_.end()) {
245         TELEPHONY_LOGI("device is existenced");
246     } else {
247         mapConnectedBtDevices_.insert(std::pair<std::string, const Bluetooth::BluetoothRemoteDevice>(address, device));
248         TELEPHONY_LOGI("AddBtDevice success");
249     }
250 }
251 
RemoveBtDevice(const std::string & address)252 void BluetoothConnection::RemoveBtDevice(const std::string &address)
253 {
254     if (mapConnectedBtDevices_.count(address) > 0) {
255         mapConnectedBtDevices_.erase(address);
256         TELEPHONY_LOGI("RemoveBtDevice success");
257     } else {
258         TELEPHONY_LOGE("device is not existenced");
259     }
260 }
261 
GetBtDevice(const std::string & address)262 Bluetooth::BluetoothRemoteDevice *BluetoothConnection::GetBtDevice(const std::string &address)
263 {
264     if (mapConnectedBtDevices_.count(address) > 0) {
265         auto iter = mapConnectedBtDevices_.find(address);
266         if (iter != mapConnectedBtDevices_.end()) {
267             return &iter->second;
268         }
269     }
270     TELEPHONY_LOGE("device is not existenced");
271     return nullptr;
272 }
273 
OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t state)274 void BluetoothConnection::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t state)
275 {
276     TELEPHONY_LOGI("BluetoothConnection::OnConnectionStateChanged state : %{public}d", state);
277     std::string macAddress = device.GetDeviceAddr();
278     switch (state) {
279         case (int32_t)Bluetooth::BTConnectState::CONNECTED:
280             AddBtDevice(macAddress, device);
281             /** try to connect sco while new bluetooth device connected
282              *  if connect sco successfully , should switch current audio device to bluetooth sco
283              */
284             if (BluetoothConnection::GetBtScoState() == BtScoState::SCO_STATE_DISCONNECTED && IsAudioActivated()) {
285                 ConnectBtSco(device);
286             }
287             break;
288         case (int32_t)Bluetooth::BTConnectState::DISCONNECTED:
289             RemoveBtDevice(macAddress);
290             break;
291         default:
292             break;
293     }
294 }
295 #endif
296 } // namespace Telephony
297 } // namespace OHOS
298