• 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 <cstring>
17 #include "btstack.h"
18 #include "hfp_ag_profile_event_sender.h"
19 #include "log_util.h"
20 #include "raw_address.h"
21 #include "securec.h"
22 #include "hfp_ag_audio_connection.h"
23 
24 namespace OHOS {
25 namespace bluetooth {
26 std::string HfpAgAudioConnection::g_activeAddr {NULL_ADDRESS};
27 std::vector<HfpAgAudioConnection::AudioDevice> HfpAgAudioConnection::g_audioDevices {};
28 
29 BtmScoCallbacks HfpAgAudioConnection::g_cbs = {
30     &HfpAgAudioConnection::OnConnectCompleted,
31     &HfpAgAudioConnection::OnConnectionChanged,
32     &HfpAgAudioConnection::OnDisconnectCompleted,
33     &HfpAgAudioConnection::OnConnectRequest,
34     &HfpAgAudioConnection::OnWriteVoiceSettingCompleted,
35 };
36 
SetRemoteAddr(const std::string & addr)37 void HfpAgAudioConnection::SetRemoteAddr(const std::string &addr)
38 {
39     remoteAddr_ = addr;
40 }
41 
SetActiveDevice(const std::string & address)42 void HfpAgAudioConnection::SetActiveDevice(const std::string &address)
43 {
44     g_activeAddr = address;
45 }
46 
IsAudioConnected(const std::string & address)47 bool HfpAgAudioConnection::IsAudioConnected(const std::string &address)
48 {
49     auto dev = GetDeviceByAddr(address);
50     if (dev != g_audioDevices.end()) {
51         if (dev->lastConnectResult == CONNECT_SUCCESS) {
52             return true;
53         }
54     }
55 
56     return false;
57 }
58 
GetActiveDevice()59 std::string HfpAgAudioConnection::GetActiveDevice()
60 {
61     return g_activeAddr;
62 }
63 
ConvertToBtAddr(std::string address)64 BtAddr HfpAgAudioConnection::ConvertToBtAddr(std::string address)
65 {
66     RawAddress rawAddr(address);
67     BtAddr btAddr;
68     rawAddr.ConvertToUint8(btAddr.addr);
69     btAddr.type = BT_PUBLIC_DEVICE_ADDRESS;
70     return btAddr;
71 }
72 
Register()73 int HfpAgAudioConnection::Register()
74 {
75     HILOGI("enter");
76     g_activeAddr = NULL_ADDRESS;
77     std::vector<HfpAgAudioConnection::AudioDevice>().swap(g_audioDevices);
78     int ret = BTM_RegisterScoCallbacks(&g_cbs, nullptr);
79     HFP_AG_RETURN_IF_FAIL(ret);
80     return ret;
81 }
82 
Deregister()83 int HfpAgAudioConnection::Deregister()
84 {
85     HILOGI("enter");
86     g_activeAddr = NULL_ADDRESS;
87     std::vector<HfpAgAudioConnection::AudioDevice>().swap(g_audioDevices);
88     int ret = BTM_DeregisterScoCallbacks(&g_cbs);
89     HFP_AG_RETURN_IF_FAIL(ret);
90     return ret;
91 }
92 
SetSupportFeatures(bool escoSupport,bool escoS4Support,int inUseCodec)93 void HfpAgAudioConnection::SetSupportFeatures(bool escoSupport, bool escoS4Support, int inUseCodec)
94 {
95     escoSupport_ = escoSupport;
96     escoS4Support_ = escoS4Support;
97     inUseCodec_ = inUseCodec;
98     HILOGI("escoSupport_: %{public}d, escoS4Support_: %{public}d, inUseCodec_: %{public}d",
99         escoSupport_,
100         escoS4Support_,
101         inUseCodec_);
102 }
103 
GetDeviceByAddr(const std::string & addr)104 std::vector<HfpAgAudioConnection::AudioDevice>::iterator HfpAgAudioConnection::GetDeviceByAddr(const std::string &addr)
105 {
106     std::vector<HfpAgAudioConnection::AudioDevice>::iterator it;
107     for (it = g_audioDevices.begin(); it != g_audioDevices.end(); ++it) {
108         if (it->addr == addr) {
109             break;
110         }
111     }
112     return it;
113 }
114 
GetDeviceByHandle(uint16_t handle)115 std::vector<HfpAgAudioConnection::AudioDevice>::iterator HfpAgAudioConnection::GetDeviceByHandle(uint16_t handle)
116 {
117     std::vector<HfpAgAudioConnection::AudioDevice>::iterator it;
118     for (it = g_audioDevices.begin(); it != g_audioDevices.end(); ++it) {
119         if (it->handle == handle) {
120             break;
121         }
122     }
123     return it;
124 }
125 
ConnectByMsbc(AudioDevice & dev,BtAddr btAddr) const126 int HfpAgAudioConnection::ConnectByMsbc(AudioDevice &dev, BtAddr btAddr) const
127 {
128     int ret = BTM_WriteVoiceSetting(BTM_VOICE_SETTING_TRANS);
129     HFP_AG_RETURN_IF_FAIL(ret);
130 
131     dev.linkType = LINK_TYPE_ESCO;
132 
133     if (BTM_IsSecureConnection(&btAddr)) {
134         HILOGI("Try connect by MSBC T2.");
135         BtmCreateEscoConnectionParam param = MSBC_T2_PARAM;
136         param.addr = btAddr;
137         ret = BTM_CreateEscoConnection(&param);
138         HFP_AG_RETURN_IF_FAIL(ret);
139         dev.lastParam = MSBC_ESCO_T2;
140     } else {
141         HILOGI("Try connect by MSBC T1.");
142         BtmCreateEscoConnectionParam param = MSBC_T1_PARAM;
143         param.addr = btAddr;
144         ret = BTM_CreateEscoConnection(&param);
145         HFP_AG_RETURN_IF_FAIL(ret);
146         dev.lastParam = MSBC_ESCO_T1;
147     }
148     HFP_AG_RETURN_IF_FAIL(ret);
149 
150     HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_CONNECTING_EVT);
151     return ret;
152 }
153 
ConnectByCvsd(AudioDevice & dev,BtAddr btAddr,bool cvsdEscoFailed) const154 int HfpAgAudioConnection::ConnectByCvsd(AudioDevice &dev, BtAddr btAddr, bool cvsdEscoFailed) const
155 {
156     int ret = BTM_WriteVoiceSetting(BTM_VOICE_SETTING_CVSD);
157     HFP_AG_RETURN_IF_FAIL(ret);
158 
159     if (escoSupport_ && !cvsdEscoFailed) {
160         dev.linkType = LINK_TYPE_ESCO;
161         if (escoS4Support_) {
162             HILOGI("Try connect by CVSD ESCO S4.");
163             dev.lastParam = CVSD_ESCO_S4;
164             BtmCreateEscoConnectionParam param = CVSD_ESCO_S4_PARAM;
165             param.addr = btAddr;
166             ret = BTM_CreateEscoConnection(&param);
167             HFP_AG_RETURN_IF_FAIL(ret);
168         } else {
169             HILOGI("Try connect by CVSD ESCO S1.");
170             dev.lastParam = CVSD_ESCO_S1;
171             BtmCreateEscoConnectionParam param = CVSD_ESCO_S1_PARAM;
172             param.addr = btAddr;
173             ret = BTM_CreateEscoConnection(&param);
174             HFP_AG_RETURN_IF_FAIL(ret);
175         }
176     } else {
177         if (!BTM_IsSecureConnection(&btAddr)) {
178             dev.linkType = LINK_TYPE_SCO;
179             HILOGI("Try connect by CVSD SCO.");
180             dev.lastParam = CVSD_SCO;
181             BtmCreateScoConnectionParam param = CVSD_SCO_PARAM;
182             param.addr = btAddr;
183             ret = BTM_CreateScoConnection(&param);
184             HFP_AG_RETURN_IF_FAIL(ret);
185         } else {
186             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_CONNECT_FAILED_EVT);
187             return ret;
188         }
189     }
190 
191     HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_CONNECTING_EVT);
192     return ret;
193 }
194 
ConnectAudio() const195 int HfpAgAudioConnection::ConnectAudio() const
196 {
197     HILOGI("Connect SCO to %{public}s", GetEncryptAddr(remoteAddr_).c_str());
198 
199     if (remoteAddr_ != g_activeAddr) {
200         HILOGW("remoteAddr: %{public}s and g_activeAddr: %{public}s match failed!",
201             GetEncryptAddr(remoteAddr_).c_str(), GetEncryptAddr(g_activeAddr).c_str());
202         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_CONNECT_FAILED_EVT);
203         return BT_BAD_PARAM;
204     }
205 
206     auto dev = GetDeviceByAddr(remoteAddr_);
207     if (dev == g_audioDevices.end()) {
208         HfpAgAudioConnection::AudioDevice audioDev;
209         audioDev.role = ROLE_INITIATOR;
210         audioDev.addr = remoteAddr_;
211         g_audioDevices.push_back(audioDev);
212         dev = GetDeviceByAddr(remoteAddr_);
213         HILOGI("Create Audio device for %{public}s", GetEncryptAddr(remoteAddr_).c_str());
214     } else {
215         HILOGI("Audio device: %{public}s already in device list", GetEncryptAddr(remoteAddr_).c_str());
216     }
217 
218     bool msbcEscoFailed = false;
219     bool cvsdEscoFailed = false;
220     if (dev->lastConnectResult == CONNECT_FAIL) {
221         if (dev->lastParam == MSBC_ESCO_T2 || dev->lastParam == MSBC_ESCO_T1) {
222             msbcEscoFailed = true;
223         } else if (dev->lastParam == CVSD_ESCO_S4 || dev->lastParam == CVSD_ESCO_S1) {
224             cvsdEscoFailed = true;
225         } else {
226             HILOGI("Audio device: %{public}s, lastParam: %{public}d",
227                 GetEncryptAddr(remoteAddr_).c_str(), dev->lastParam);
228         }
229     }
230 
231     BtAddr btAddr = ConvertToBtAddr(remoteAddr_);
232     if (inUseCodec_ == HFP_AG_CODEC_MSBC) {
233         if (!msbcEscoFailed && escoSupport_) {
234             return ConnectByMsbc(*dev, btAddr);
235         } else {
236             HILOGW("Need re-negotiate codec.");
237             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_SETUP_CODEC_CVSD);
238             return BT_BAD_PARAM;
239         }
240     } else if (inUseCodec_ == HFP_AG_CODEC_CVSD) {
241         return ConnectByCvsd(*dev, btAddr, cvsdEscoFailed);
242     } else {
243         HILOGI("RemoteAddr: %{public}s, invalid codec: %{public}d",
244             GetEncryptAddr(remoteAddr_).c_str(), inUseCodec_);
245         return BT_BAD_PARAM;
246     }
247 
248     return BT_SUCCESS;
249 }
250 
DisconnectAudio() const251 int HfpAgAudioConnection::DisconnectAudio() const
252 {
253     HILOGI("Disconnect SCO from %{public}s", GetEncryptAddr(remoteAddr_).c_str());
254 
255     int ret;
256     auto dev = GetDeviceByAddr(remoteAddr_);
257     if (dev != g_audioDevices.end()) {
258         ret = BTM_DisconnectScoConnection(dev->handle, REMOTE_USER_TERMINATED_CONNECTION);
259         HFP_AG_RETURN_IF_FAIL(ret);
260         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_DISCONNECTING_EVT);
261     } else {
262         HILOGW("%{public}s: Invalid Address", GetEncryptAddr(remoteAddr_).c_str());
263         ret = BT_DEVICE_ERROR;
264     }
265     return ret;
266 }
267 
AcceptByMsbc(BtAddr btAddr)268 int HfpAgAudioConnection::AcceptByMsbc(BtAddr btAddr)
269 {
270     int ret = BTM_WriteVoiceSetting(BTM_VOICE_SETTING_TRANS);
271     HFP_AG_RETURN_IF_FAIL(ret);
272 
273     if (BTM_IsSecureConnection(&btAddr)) {
274         HILOGI("Accept by MSBC T2.");
275         BtmCreateEscoConnectionParam param = MSBC_T2_PARAM;
276         param.addr = btAddr;
277         ret = BTM_AcceptEscoConnectionRequest(&param);
278         HFP_AG_RETURN_IF_FAIL(ret);
279     } else {
280         HILOGI("Accept by MSBC T1.");
281         BtmCreateEscoConnectionParam param = MSBC_T1_PARAM;
282         param.addr = btAddr;
283         ret = BTM_AcceptEscoConnectionRequest(&param);
284         HFP_AG_RETURN_IF_FAIL(ret);
285     }
286 
287     return ret;
288 }
289 
AcceptByCvsd(const AudioDevice & dev,BtAddr btAddr) const290 int HfpAgAudioConnection::AcceptByCvsd(const AudioDevice &dev, BtAddr btAddr) const
291 {
292     int ret = BTM_WriteVoiceSetting(BTM_VOICE_SETTING_CVSD);
293     HFP_AG_RETURN_IF_FAIL(ret);
294 
295     if (dev.linkType == LINK_TYPE_ESCO && escoSupport_) {
296         if (escoS4Support_) {
297             HILOGI("Accept by CVSD ESCO S4.");
298             BtmCreateEscoConnectionParam param = CVSD_ESCO_S4_PARAM;
299             param.addr = btAddr;
300             ret = BTM_AcceptEscoConnectionRequest(&param);
301             HFP_AG_RETURN_IF_FAIL(ret);
302         } else {
303             HILOGI("Accept by CVSD ESCO S1.");
304             BtmCreateEscoConnectionParam param = CVSD_ESCO_S1_PARAM;
305             param.addr = btAddr;
306             ret = BTM_AcceptEscoConnectionRequest(&param);
307             HFP_AG_RETURN_IF_FAIL(ret);
308         }
309     } else if (dev.linkType == LINK_TYPE_SCO) {
310         HILOGI("Accept by CVSD SCO.");
311         BtmCreateScoConnectionParam param = CVSD_SCO_PARAM;
312         param.addr = btAddr;
313         ret = BTM_AcceptScoConnectionRequest(&param);
314         HFP_AG_RETURN_IF_FAIL(ret);
315     } else {
316         HILOGI("CVSD ESCO connection fail, "
317             "linktype: %{public}hhu and escoSupport: %{public}d are not matched!",
318             dev.linkType,
319             escoSupport_);
320         return BT_BAD_PARAM;
321     }
322 
323     return ret;
324 }
325 
AcceptAudioConnection() const326 int HfpAgAudioConnection::AcceptAudioConnection() const
327 {
328     int ret = BT_SUCCESS;
329     BtAddr btAddr = ConvertToBtAddr(remoteAddr_);
330 
331     // Only accpet CVSD sco from remote device.
332     auto dev = GetDeviceByAddr(remoteAddr_);
333     if (dev != g_audioDevices.end()) {
334         if (inUseCodec_ == HFP_AG_CODEC_MSBC) {
335             if (dev->linkType == LINK_TYPE_ESCO && escoSupport_) {
336                 return AcceptByMsbc(btAddr);
337             } else {
338                 HILOGI("MSBC ESCO connection fail, "
339                     "linktype: %{public}hhu and escoSupport: %{public}d are not matched!",
340                     dev->linkType,
341                     escoSupport_);
342                 return BT_BAD_PARAM;
343             }
344         } else if (inUseCodec_ == HFP_AG_CODEC_CVSD) {
345             return AcceptByCvsd(*dev, btAddr);
346         } else {
347             HILOGI("Invalid Codec: %{public}d", inUseCodec_);
348             return BT_BAD_PARAM;
349         }
350     } else {
351         HILOGW("%{public}s: Invalid Address", GetEncryptAddr(remoteAddr_).c_str());
352         return BT_BAD_PARAM;
353     }
354 
355     return ret;
356 }
357 
RejectAudioConnection() const358 int HfpAgAudioConnection::RejectAudioConnection() const
359 {
360     HILOGI("Reject sco connect request from %{public}s", GetEncryptAddr(remoteAddr_).c_str());
361     BtAddr btAddr = ConvertToBtAddr(remoteAddr_);
362     BtmRejectScoConnectionRequestParam param = {btAddr, REJECT_DUE_TO_LIMITED_RESOURCES};
363 
364     int ret = BTM_RejectScoConnectionRequest(&param);
365     HFP_AG_RETURN_IF_FAIL(ret);
366 
367     return ret;
368 }
369 
OnConnectRequest(const BtmScoConnectionRequestParam * param,void * context)370 void HfpAgAudioConnection::OnConnectRequest(const BtmScoConnectionRequestParam *param, void *context)
371 {
372     HILOGI("enter");
373     HfpScoConnectionRequestParam parameters;
374     parameters.linkType = param->linkType;
375     (void)memcpy_s(&parameters.addr, sizeof(BtAddr), param->addr, sizeof(BtAddr));
376     if (HfpAgProfileEventSender::GetInstance().GetDispatchter() == nullptr) {
377         HILOGI("GetDispatchter() return nullptr");
378         return;
379     }
380     HfpAgProfileEventSender::GetInstance().GetDispatchter()->PostTask(
381         std::bind(&HfpAgAudioConnection::ProcessOnConnectRequest, parameters));
382 }
383 
ProcessOnConnectRequest(HfpScoConnectionRequestParam parameters)384 void HfpAgAudioConnection::ProcessOnConnectRequest(HfpScoConnectionRequestParam parameters)
385 {
386     HILOGI("enter");
387 
388     RawAddress btAddr = RawAddress::ConvertToString(parameters.addr.addr);
389     std::string address = btAddr.GetAddress();
390 
391     auto dev = GetDeviceByAddr(address);
392     if (dev == g_audioDevices.end()) {
393         HfpAgAudioConnection::AudioDevice audioDev;
394         audioDev.role = ROLE_ACCEPTOR;
395         audioDev.addr = address;
396         audioDev.linkType = parameters.linkType;
397         g_audioDevices.push_back(audioDev);
398         HILOGI("Create Audio device for %{public}s", GetEncryptAddr(address).c_str());
399     } else {
400         dev->linkType = parameters.linkType;
401         HILOGI("Audio device %{public}s already in device list",
402             GetEncryptAddr(address).c_str());
403     }
404     HfpAgProfileEventSender::GetInstance().ScoConnectRequest(
405         btAddr.GetAddress(), HFP_AG_AUDIO_CONNECT_REQUEST_EVT, parameters.linkType);
406 }
407 
OnConnectCompleted(const BtmScoConnectionCompleteParam * param,void * context)408 void HfpAgAudioConnection::OnConnectCompleted(const BtmScoConnectionCompleteParam *param, void *context)
409 {
410     HILOGI("enter");
411     HfpScoConnectionCompleteParam parameters;
412     parameters.status = param->status;
413     parameters.connectionHandle = param->connectionHandle;
414     (void)memcpy_s(&parameters.addr, sizeof(BtAddr), param->addr, sizeof(BtAddr));
415     if (HfpAgProfileEventSender::GetInstance().GetDispatchter() == nullptr) {
416         HILOGI("GetDispatchter() return nullptr");
417         return;
418     }
419     HfpAgProfileEventSender::GetInstance().GetDispatchter()->PostTask(
420         std::bind(&HfpAgAudioConnection::ProcessOnConnectCompleted, parameters));
421 }
422 
ProcessOnConnectCompletedFail(std::vector<HfpAgAudioConnection::AudioDevice>::iterator dev,const std::string & address)423 void HfpAgAudioConnection::ProcessOnConnectCompletedFail(
424     std::vector<HfpAgAudioConnection::AudioDevice>::iterator dev, const std::string &address)
425 {
426     dev->lastConnectResult = CONNECT_FAIL;
427     if (dev->role == ROLE_INITIATOR) {
428         if (dev->lastParam == MSBC_ESCO_T2 || dev->lastParam == MSBC_ESCO_T1) {
429             HILOGI("MSBC ESCO failed, try CVSD ESCO.");
430             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_SETUP_CODEC_CVSD);
431         } else if (dev->lastParam == CVSD_ESCO_S4 || dev->lastParam == CVSD_ESCO_S1) {
432             HILOGI("CVSD ESCO failed, try CVSD SCO");
433             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_RETRY_CONNECT_AUDIO_EVT);
434         } else if (dev->lastParam == CVSD_SCO) {
435             HILOGI("CVSD SCO failed, report fail event to service");
436             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_AUDIO_CONNECT_FAILED_EVT);
437         } else {
438             HILOGI("Invalidaddress: %{public}s, lastParam: %{public}d",
439                 GetEncryptAddr(address).c_str(), dev->lastParam);
440         }
441     } else {
442         // As acceptor, report connect failed event to service directly.
443         HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_AUDIO_CONNECT_FAILED_EVT);
444         HILOGI("Accept SCO from address: %{public}s failed", GetEncryptAddr(address).c_str());
445     }
446 }
447 
ProcessOnConnectCompleted(HfpScoConnectionCompleteParam parameters)448 void HfpAgAudioConnection::ProcessOnConnectCompleted(HfpScoConnectionCompleteParam parameters)
449 {
450     HILOGI("enter");
451 
452     RawAddress btAddr = RawAddress::ConvertToString(parameters.addr.addr);
453     std::string address = btAddr.GetAddress();
454     auto dev = GetDeviceByAddr(address);
455     if (dev != g_audioDevices.end()) {
456         dev->addr = address;
457         dev->handle = parameters.connectionHandle;
458         if (!parameters.status) {
459             HILOGI("SCO connect successfully!");
460             dev->lastConnectResult = CONNECT_SUCCESS;
461             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_AUDIO_CONNECTED_EVT);
462         } else {
463             ProcessOnConnectCompletedFail(dev, address);
464         }
465     } else {
466         HILOGI("%{public}s: Invalid audio device", GetEncryptAddr(address).c_str());
467     }
468 }
469 
OnDisconnectCompleted(const BtmScoDisconnectionCompleteParam * param,void * context)470 void HfpAgAudioConnection::OnDisconnectCompleted(const BtmScoDisconnectionCompleteParam *param, void *context)
471 {
472     HILOGI("enter");
473     HfpScoDisconnectionCompleteParam parameters;
474     parameters.connectionHandle = param->connectionHandle;
475     parameters.reason = param->reason;
476     parameters.status = param->status;
477     if (HfpAgProfileEventSender::GetInstance().GetDispatchter() == nullptr) {
478         HILOGI("GetDispatchter() return nullptr");
479         return;
480     }
481     HfpAgProfileEventSender::GetInstance().GetDispatchter()->PostTask(
482         std::bind(&HfpAgAudioConnection::ProcessOnDisconnectCompleted, parameters));
483 }
484 
ProcessOnDisconnectCompleted(HfpScoDisconnectionCompleteParam parameters)485 void HfpAgAudioConnection::ProcessOnDisconnectCompleted(HfpScoDisconnectionCompleteParam parameters)
486 {
487     HILOGI("enter");
488 
489     auto it = GetDeviceByHandle(parameters.connectionHandle);
490     if (it != g_audioDevices.end()) {
491         if (!parameters.status) {
492             HILOGI("Disconnect SCO from address: %{public}s successfully.", GetEncryptAddr(it->addr).c_str());
493             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(it->addr, HFP_AG_AUDIO_DISCONNECTED_EVT);
494             g_audioDevices.erase(it);
495         } else {
496             HILOGI("Disconnect SCO from address: %{public}s failed.", GetEncryptAddr(it->addr).c_str());
497             HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(
498                 it->addr, HFP_AG_AUDIO_DISCONNECT_FAILED_EVT);
499         }
500     } else {
501         HILOGI("Invalid audio device");
502     }
503 }
504 
OnConnectionChanged(const BtmScoConnectionChangedParam * param,void * context)505 void HfpAgAudioConnection::OnConnectionChanged(const BtmScoConnectionChangedParam *param, void *context)
506 {
507     HILOGI("enter, connectionHandle: %{public}hu", param->connectionHandle);
508 }
509 
OnWriteVoiceSettingCompleted(uint8_t status,void * context)510 void HfpAgAudioConnection::OnWriteVoiceSettingCompleted(uint8_t status, void *context)
511 {
512     HILOGI("enter, status: %{public}hhu", status);
513 }
514 }  // namespace bluetooth
515 }  // namespace OHOS