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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶meters.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(¶meters.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