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 (dev.lastParam != MSBC_ESCO_T2) {
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 if (!BTM_IsSecureConnection(&btAddr)) {
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 && escoS4Support_) {
160 HILOGI("Try connect by CVSD ESCO S4.");
161 dev.linkType = LINK_TYPE_ESCO;
162 dev.lastParam = CVSD_ESCO_S4;
163 BtmCreateEscoConnectionParam param = CVSD_ESCO_S4_PARAM;
164 param.addr = btAddr;
165 ret = BTM_CreateEscoConnection(¶m);
166 HFP_AG_RETURN_IF_FAIL(ret);
167 } else if ((dev.lastParam == CVSD_ESCO_S4) && !BTM_IsSecureConnection(&btAddr)) {
168 HILOGI("Try connect by CVSD ESCO S1.");
169 dev.linkType = LINK_TYPE_ESCO;
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 } else if (!BTM_IsSecureConnection(&btAddr)) {
176 dev.linkType = LINK_TYPE_SCO;
177 HILOGI("Try connect by CVSD SCO.");
178 dev.lastParam = CVSD_SCO;
179 BtmCreateScoConnectionParam param = CVSD_SCO_PARAM;
180 param.addr = btAddr;
181 ret = BTM_CreateScoConnection(¶m);
182 HFP_AG_RETURN_IF_FAIL(ret);
183 } else {
184 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_CONNECT_FAILED_EVT);
185 return ret;
186 }
187
188 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_CONNECTING_EVT);
189 return ret;
190 }
191
ConnectAudio() const192 int HfpAgAudioConnection::ConnectAudio() const
193 {
194 HILOGI("Connect SCO to %{public}s", GetEncryptAddr(remoteAddr_).c_str());
195
196 if (remoteAddr_ != g_activeAddr) {
197 HILOGW("remoteAddr: %{public}s and g_activeAddr: %{public}s match failed!",
198 GetEncryptAddr(remoteAddr_).c_str(), GetEncryptAddr(g_activeAddr).c_str());
199 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_CONNECT_FAILED_EVT);
200 return BT_BAD_PARAM;
201 }
202
203 auto dev = GetDeviceByAddr(remoteAddr_);
204 if (dev == g_audioDevices.end()) {
205 HfpAgAudioConnection::AudioDevice audioDev;
206 audioDev.role = ROLE_INITIATOR;
207 audioDev.addr = remoteAddr_;
208 g_audioDevices.push_back(audioDev);
209 dev = GetDeviceByAddr(remoteAddr_);
210 HILOGI("Create Audio device for %{public}s", GetEncryptAddr(remoteAddr_).c_str());
211 } else {
212 HILOGI("Audio device: %{public}s already in device list", GetEncryptAddr(remoteAddr_).c_str());
213 }
214
215 bool msbcEscoFailed = false;
216 bool cvsdEscoFailed = false;
217 if (dev->lastConnectResult == CONNECT_FAIL) {
218 if (dev->lastParam == MSBC_ESCO_T2 || dev->lastParam == MSBC_ESCO_T1) {
219 msbcEscoFailed = true;
220 } else if (dev->lastParam == CVSD_ESCO_S4 || dev->lastParam == CVSD_ESCO_S1) {
221 cvsdEscoFailed = true;
222 } else {
223 HILOGI("Audio device: %{public}s, lastParam: %{public}d",
224 GetEncryptAddr(remoteAddr_).c_str(), dev->lastParam);
225 }
226 }
227
228 BtAddr btAddr = ConvertToBtAddr(remoteAddr_);
229 if (inUseCodec_ == HFP_AG_CODEC_MSBC) {
230 if ((!msbcEscoFailed || (dev->lastParam == MSBC_ESCO_T2)) && escoSupport_) {
231 return ConnectByMsbc(*dev, btAddr);
232 } else {
233 HILOGW("Need re-negotiate codec.");
234 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_SETUP_CODEC_CVSD);
235 return BT_BAD_PARAM;
236 }
237 } else if (inUseCodec_ == HFP_AG_CODEC_CVSD) {
238 return ConnectByCvsd(*dev, btAddr, cvsdEscoFailed);
239 } else {
240 HILOGI("RemoteAddr: %{public}s, invalid codec: %{public}d",
241 GetEncryptAddr(remoteAddr_).c_str(), inUseCodec_);
242 return BT_BAD_PARAM;
243 }
244
245 return BT_SUCCESS;
246 }
247
DisconnectAudio() const248 int HfpAgAudioConnection::DisconnectAudio() const
249 {
250 HILOGI("Disconnect SCO from %{public}s", GetEncryptAddr(remoteAddr_).c_str());
251
252 int ret;
253 auto dev = GetDeviceByAddr(remoteAddr_);
254 if (dev != g_audioDevices.end()) {
255 ret = BTM_DisconnectScoConnection(dev->handle, REMOTE_USER_TERMINATED_CONNECTION);
256 HFP_AG_RETURN_IF_FAIL(ret);
257 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(remoteAddr_, HFP_AG_AUDIO_DISCONNECTING_EVT);
258 } else {
259 HILOGW("%{public}s: Invalid Address", GetEncryptAddr(remoteAddr_).c_str());
260 ret = BT_DEVICE_ERROR;
261 }
262 return ret;
263 }
264
AcceptByMsbc(BtAddr btAddr)265 int HfpAgAudioConnection::AcceptByMsbc(BtAddr btAddr)
266 {
267 int ret = BTM_WriteVoiceSetting(BTM_VOICE_SETTING_TRANS);
268 HFP_AG_RETURN_IF_FAIL(ret);
269
270 if (BTM_IsSecureConnection(&btAddr)) {
271 HILOGI("Accept by MSBC T2.");
272 BtmCreateEscoConnectionParam param = MSBC_T2_PARAM;
273 param.addr = btAddr;
274 ret = BTM_AcceptEscoConnectionRequest(¶m);
275 HFP_AG_RETURN_IF_FAIL(ret);
276 } else {
277 HILOGI("Accept by MSBC T1.");
278 BtmCreateEscoConnectionParam param = MSBC_T1_PARAM;
279 param.addr = btAddr;
280 ret = BTM_AcceptEscoConnectionRequest(¶m);
281 HFP_AG_RETURN_IF_FAIL(ret);
282 }
283
284 return ret;
285 }
286
AcceptByCvsd(const AudioDevice & dev,BtAddr btAddr) const287 int HfpAgAudioConnection::AcceptByCvsd(const AudioDevice &dev, BtAddr btAddr) const
288 {
289 int ret = BTM_WriteVoiceSetting(BTM_VOICE_SETTING_CVSD);
290 HFP_AG_RETURN_IF_FAIL(ret);
291
292 if (dev.linkType == LINK_TYPE_ESCO && escoSupport_) {
293 if (escoS4Support_) {
294 HILOGI("Accept by CVSD ESCO S4.");
295 BtmCreateEscoConnectionParam param = CVSD_ESCO_S4_PARAM;
296 param.addr = btAddr;
297 ret = BTM_AcceptEscoConnectionRequest(¶m);
298 HFP_AG_RETURN_IF_FAIL(ret);
299 } else {
300 HILOGI("Accept by CVSD ESCO S1.");
301 BtmCreateEscoConnectionParam param = CVSD_ESCO_S1_PARAM;
302 param.addr = btAddr;
303 ret = BTM_AcceptEscoConnectionRequest(¶m);
304 HFP_AG_RETURN_IF_FAIL(ret);
305 }
306 } else if (dev.linkType == LINK_TYPE_SCO) {
307 HILOGI("Accept by CVSD SCO.");
308 BtmCreateScoConnectionParam param = CVSD_SCO_PARAM;
309 param.addr = btAddr;
310 ret = BTM_AcceptScoConnectionRequest(¶m);
311 HFP_AG_RETURN_IF_FAIL(ret);
312 } else {
313 HILOGI("CVSD ESCO connection fail, "
314 "linktype: %{public}hhu and escoSupport: %{public}d are not matched!",
315 dev.linkType,
316 escoSupport_);
317 return BT_BAD_PARAM;
318 }
319
320 return ret;
321 }
322
AcceptAudioConnection() const323 int HfpAgAudioConnection::AcceptAudioConnection() const
324 {
325 int ret = BT_SUCCESS;
326 BtAddr btAddr = ConvertToBtAddr(remoteAddr_);
327
328 // Only accpet CVSD sco from remote device.
329 auto dev = GetDeviceByAddr(remoteAddr_);
330 if (dev != g_audioDevices.end()) {
331 if (inUseCodec_ == HFP_AG_CODEC_MSBC) {
332 if (dev->linkType == LINK_TYPE_ESCO && escoSupport_) {
333 return AcceptByMsbc(btAddr);
334 } else {
335 HILOGI("MSBC ESCO connection fail, "
336 "linktype: %{public}hhu and escoSupport: %{public}d are not matched!",
337 dev->linkType,
338 escoSupport_);
339 return BT_BAD_PARAM;
340 }
341 } else if (inUseCodec_ == HFP_AG_CODEC_CVSD) {
342 return AcceptByCvsd(*dev, btAddr);
343 } else {
344 HILOGI("Invalid Codec: %{public}d", inUseCodec_);
345 return BT_BAD_PARAM;
346 }
347 } else {
348 HILOGW("%{public}s: Invalid Address", GetEncryptAddr(remoteAddr_).c_str());
349 return BT_BAD_PARAM;
350 }
351
352 return ret;
353 }
354
RejectAudioConnection() const355 int HfpAgAudioConnection::RejectAudioConnection() const
356 {
357 HILOGI("Reject sco connect request from %{public}s", GetEncryptAddr(remoteAddr_).c_str());
358 BtAddr btAddr = ConvertToBtAddr(remoteAddr_);
359 BtmRejectScoConnectionRequestParam param = {btAddr, REJECT_DUE_TO_LIMITED_RESOURCES};
360
361 int ret = BTM_RejectScoConnectionRequest(¶m);
362 HFP_AG_RETURN_IF_FAIL(ret);
363
364 return ret;
365 }
366
OnConnectRequest(const BtmScoConnectionRequestParam * param,void * context)367 void HfpAgAudioConnection::OnConnectRequest(const BtmScoConnectionRequestParam *param, void *context)
368 {
369 HILOGI("enter");
370 HfpScoConnectionRequestParam parameters;
371 parameters.linkType = param->linkType;
372 (void)memcpy_s(¶meters.addr, sizeof(BtAddr), param->addr, sizeof(BtAddr));
373 if (HfpAgProfileEventSender::GetInstance().GetDispatchter() == nullptr) {
374 HILOGI("GetDispatchter() return nullptr");
375 return;
376 }
377 HfpAgProfileEventSender::GetInstance().GetDispatchter()->PostTask(
378 std::bind(&HfpAgAudioConnection::ProcessOnConnectRequest, parameters));
379 }
380
ProcessOnConnectRequest(HfpScoConnectionRequestParam parameters)381 void HfpAgAudioConnection::ProcessOnConnectRequest(HfpScoConnectionRequestParam parameters)
382 {
383 HILOGI("enter");
384
385 RawAddress btAddr = RawAddress::ConvertToString(parameters.addr.addr);
386 std::string address = btAddr.GetAddress();
387
388 auto dev = GetDeviceByAddr(address);
389 if (dev == g_audioDevices.end()) {
390 HfpAgAudioConnection::AudioDevice audioDev;
391 audioDev.role = ROLE_ACCEPTOR;
392 audioDev.addr = address;
393 audioDev.linkType = parameters.linkType;
394 g_audioDevices.push_back(audioDev);
395 HILOGI("Create Audio device for %{public}s", GetEncryptAddr(address).c_str());
396 } else {
397 dev->linkType = parameters.linkType;
398 HILOGI("Audio device %{public}s already in device list",
399 GetEncryptAddr(address).c_str());
400 }
401 HfpAgProfileEventSender::GetInstance().ScoConnectRequest(
402 btAddr.GetAddress(), HFP_AG_AUDIO_CONNECT_REQUEST_EVT, parameters.linkType);
403 }
404
OnConnectCompleted(const BtmScoConnectionCompleteParam * param,void * context)405 void HfpAgAudioConnection::OnConnectCompleted(const BtmScoConnectionCompleteParam *param, void *context)
406 {
407 HILOGI("enter");
408 HfpScoConnectionCompleteParam parameters;
409 parameters.status = param->status;
410 parameters.connectionHandle = param->connectionHandle;
411 (void)memcpy_s(¶meters.addr, sizeof(BtAddr), param->addr, sizeof(BtAddr));
412 if (HfpAgProfileEventSender::GetInstance().GetDispatchter() == nullptr) {
413 HILOGI("GetDispatchter() return nullptr");
414 return;
415 }
416 HfpAgProfileEventSender::GetInstance().GetDispatchter()->PostTask(
417 std::bind(&HfpAgAudioConnection::ProcessOnConnectCompleted, parameters));
418 }
419
ProcessOnConnectCompletedFail(std::vector<HfpAgAudioConnection::AudioDevice>::iterator dev,const std::string & address)420 void HfpAgAudioConnection::ProcessOnConnectCompletedFail(
421 std::vector<HfpAgAudioConnection::AudioDevice>::iterator dev, const std::string &address)
422 {
423 dev->lastConnectResult = CONNECT_FAIL;
424 if (dev->role == ROLE_INITIATOR) {
425 switch (dev->lastParam) {
426 case MSBC_ESCO_T2:
427 HILOGI("MSBC ESCO T2 failed, Retry MSBC ESCO.");
428 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr,
429 HFP_AG_RETRY_CONNECT_AUDIO_EVT);
430 break;
431 case MSBC_ESCO_T1:
432 HILOGI("MSBC ESCO T1 failed, try CVSD ESCO.");
433 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_SETUP_CODEC_CVSD);
434 break;
435 case CVSD_ESCO_S4:
436 HILOGI("CVSD ESCO S4 failed, Retry CVSD ESCO");
437 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr,
438 HFP_AG_RETRY_CONNECT_AUDIO_EVT);
439 break;
440 case CVSD_ESCO_S1:
441 HILOGI("CVSD ESCO S1 failed, try CVSD SCO");
442 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr,
443 HFP_AG_RETRY_CONNECT_AUDIO_EVT);
444 break;
445 case CVSD_SCO:
446 HILOGI("CVSD SCO failed, report fail event to service");
447 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr,
448 HFP_AG_AUDIO_CONNECT_FAILED_EVT);
449 break;
450 default:
451 HILOGI("Invalidaddress: %{public}s, lastParam: %{public}d",
452 GetEncryptAddr(address).c_str(), dev->lastParam);
453 }
454 } else {
455 // As acceptor, report connect failed event to service directly.
456 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_AUDIO_CONNECT_FAILED_EVT);
457 HILOGI("Accept SCO from address: %{public}s failed", GetEncryptAddr(address).c_str());
458 }
459 }
460
ProcessOnConnectCompleted(HfpScoConnectionCompleteParam parameters)461 void HfpAgAudioConnection::ProcessOnConnectCompleted(HfpScoConnectionCompleteParam parameters)
462 {
463 HILOGI("enter");
464
465 RawAddress btAddr = RawAddress::ConvertToString(parameters.addr.addr);
466 std::string address = btAddr.GetAddress();
467 auto dev = GetDeviceByAddr(address);
468 if (dev != g_audioDevices.end()) {
469 dev->addr = address;
470 dev->handle = parameters.connectionHandle;
471 if (!parameters.status) {
472 HILOGI("SCO connect successfully!");
473 dev->lastConnectResult = CONNECT_SUCCESS;
474 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(dev->addr, HFP_AG_AUDIO_CONNECTED_EVT);
475 } else {
476 ProcessOnConnectCompletedFail(dev, address);
477 }
478 } else {
479 HILOGI("%{public}s: Invalid audio device", GetEncryptAddr(address).c_str());
480 }
481 }
482
OnDisconnectCompleted(const BtmScoDisconnectionCompleteParam * param,void * context)483 void HfpAgAudioConnection::OnDisconnectCompleted(const BtmScoDisconnectionCompleteParam *param, void *context)
484 {
485 HILOGI("enter");
486 HfpScoDisconnectionCompleteParam parameters;
487 parameters.connectionHandle = param->connectionHandle;
488 parameters.reason = param->reason;
489 parameters.status = param->status;
490 if (HfpAgProfileEventSender::GetInstance().GetDispatchter() == nullptr) {
491 HILOGI("GetDispatchter() return nullptr");
492 return;
493 }
494 HfpAgProfileEventSender::GetInstance().GetDispatchter()->PostTask(
495 std::bind(&HfpAgAudioConnection::ProcessOnDisconnectCompleted, parameters));
496 }
497
ProcessOnDisconnectCompleted(HfpScoDisconnectionCompleteParam parameters)498 void HfpAgAudioConnection::ProcessOnDisconnectCompleted(HfpScoDisconnectionCompleteParam parameters)
499 {
500 HILOGI("enter");
501
502 auto it = GetDeviceByHandle(parameters.connectionHandle);
503 if (it != g_audioDevices.end()) {
504 if (!parameters.status) {
505 HILOGI("Disconnect SCO from address: %{public}s successfully.", GetEncryptAddr(it->addr).c_str());
506 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(it->addr, HFP_AG_AUDIO_DISCONNECTED_EVT);
507 g_audioDevices.erase(it);
508 } else {
509 HILOGI("Disconnect SCO from address: %{public}s failed.", GetEncryptAddr(it->addr).c_str());
510 HfpAgProfileEventSender::GetInstance().UpdateScoConnectState(
511 it->addr, HFP_AG_AUDIO_DISCONNECT_FAILED_EVT);
512 }
513 } else {
514 HILOGI("Invalid audio device");
515 }
516 }
517
OnConnectionChanged(const BtmScoConnectionChangedParam * param,void * context)518 void HfpAgAudioConnection::OnConnectionChanged(const BtmScoConnectionChangedParam *param, void *context)
519 {
520 HILOGI("enter, connectionHandle: %{public}hu", param->connectionHandle);
521 }
522
OnWriteVoiceSettingCompleted(uint8_t status,void * context)523 void HfpAgAudioConnection::OnWriteVoiceSettingCompleted(uint8_t status, void *context)
524 {
525 HILOGI("enter, status: %{public}hhu", status);
526 }
527 } // namespace bluetooth
528 } // namespace OHOS