• 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 "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