From 63241f5a4f117562aa29315da6dc2ad7a37576f5 Mon Sep 17 00:00:00 2001 From: hcj <1224667075@qq.com> Date: Tue, 10 Dec 2024 10:47:34 +0800 Subject: [PATCH] =?utf8?q?cat=20=E7=94=B5=E8=AF=9D=E5=A2=9E=E5=8A=A0?= =?utf8?q?=E8=80=B3=E6=9C=BA=E9=9F=B3=E9=A2=91=E9=80=89=E9=A1=B9=EF=BC=88?= =?utf8?q?=E6=9A=82=E4=B8=8D=E8=A6=81=E9=80=9A=E8=BF=87=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../wearable/fd230app/CMakeLists.txt | 9 + .../nativelauncher/include/UiConfig.h | 3 + .../bluetooth/include/BluetoothHeadsetEvent.h | 4 + .../bluetooth/src/BluetoothHeadsetEvent.cpp | 4 +- .../nativeui/bluetooth/src/BluetoothModel.cpp | 10 + .../callerlog/include/CallerLogModel.h | 1 + .../nativeui/callerlog/src/CallerLogModel.cpp | 66 +- .../nativeui/makephone/include/CallingView.h | 8 +- .../makephone/include/MainCallingView.h | 2 +- .../nativeui/makephone/src/CallingView.cpp | 47 +- .../makephone/src/MainCallingPresenter.cpp | 4 + .../makephone/src/MainCallingView.cpp | 12 + .../phoneservice/include/PhoneAGService.h | 39 + .../phoneservice/include/PhoneAudio.h | 1 + .../phoneservice/include/PhoneServiceC.h | 9 +- .../phoneservice/src/PhoneAGService.cpp | 950 ++++++++++++++++++ .../nativeui/phoneservice/src/PhoneAudio.cpp | 85 +- .../phoneservice/src/PhoneService.cpp | 18 +- .../wearable/nativeabilityfwk/src/Ability.cpp | 9 +- .../msg_center/src/msg_center_customer.cpp | 30 +- .../fd230/fs/user/res/makephone/headset_3.bin | 3 + .../peripheral/slip/cat1Service/cat1_ctl.cpp | 28 +- .../peripheral/slip/cat1Service/cat1_ctl.h | 2 + .../peripheral/utils/custom_cmd_service.c | 10 + .../drivers/peripheral/utils/custom_utils.h | 8 + .../voice_call_volte_sample_wrapper.cpp | 365 +++++++ 26 files changed, 1688 insertions(+), 39 deletions(-) create mode 100644 code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAGService.h create mode 100644 code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAGService.cpp create mode 100644 code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/makephone/headset_3.bin diff --git a/code/sdk/application/wearable/fd230app/CMakeLists.txt b/code/sdk/application/wearable/fd230app/CMakeLists.txt index 6dd2c4dcc..a433804fa 100644 --- a/code/sdk/application/wearable/fd230app/CMakeLists.txt +++ b/code/sdk/application/wearable/fd230app/CMakeLists.txt @@ -14,6 +14,11 @@ set(PUBLIC_HEADER set(PRIVATE_HEADER ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/interfaces/base ${ROOT_DIR}/open_source/openharmony/third_party/cJSON + + ${ROOT_DIR}/protocol/bt/host/bt/bts/brandy_service/service/src + ${ROOT_DIR}/protocol/bt/host/bt/bts/brandy_service/service/src/base + ${ROOT_DIR}/protocol/bt/host/bt/bts/brandy_service/bt_audio_wrapper + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/main/include ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/clock/include ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/bloodoxygen/include @@ -40,7 +45,9 @@ set(PRIVATE_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/phone/include ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/player/include ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/applist/include + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/phoneservice/include + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/screensetting/include ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/uiservice/include ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/uisample/include @@ -534,6 +541,8 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/phoneservice/src/PhoneService.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/phoneservice/src/PhoneAudio.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/phoneservice/src/PhoneAGService.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/offlinevoice/src/VocassistModel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/offlinevoice/src/VocassistPresenter.cpp ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/offlinevoice/src/VocassistView.cpp diff --git a/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h b/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h index a589f69f5..6bcbd0a08 100644 --- a/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h +++ b/code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h @@ -158,6 +158,9 @@ namespace OHOS static constexpr const char *PNG_230_DIAL_IMAGE_PATH = APP_RES_PATH "/makephone/dial.bin"; static constexpr const char *PNG_230_HEADSET_1_IIMAGE_PATH = APP_RES_PATH "/makephone/headset_1.bin"; static constexpr const char *PNG_230_HEADSET_2_IIMAGE_PATH = APP_RES_PATH "/makephone/headset_2.bin"; + static constexpr const char *PNG_230_HEADSET_3_IIMAGE_PATH = APP_RES_PATH "/makephone/headset_3.bin"; + + static constexpr const char *PNG_ANSWER_230_TMAGE_PATH = APP_RES_PATH "/Phone/callanswer.bin"; static constexpr const char *PNG_HANDUP_230_IMAGE_PATH = APP_RES_PATH "/Phone/callhangup.bin"; diff --git a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/include/BluetoothHeadsetEvent.h b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/include/BluetoothHeadsetEvent.h index 3f5709cb6..43340472e 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/include/BluetoothHeadsetEvent.h +++ b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/include/BluetoothHeadsetEvent.h @@ -31,6 +31,10 @@ typedef struct { profile_connect_state_t avrcp_srv_conn_stat; } BtAvrcpTgInf; +extern BtAvrcpTgInf g_avrcp_srv_inf; + +bd_addr_t *BtAvrcpSrvGetActiveAddr(void); + void UsingPressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue); void MediaStatusCallback(bt_avrcp_tg_evt_status_param *eventStatusParam); void PressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue); diff --git a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp index fa26ec868..963b64400 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp @@ -228,11 +228,13 @@ void ConnCtStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t g_avrcp_srv_inf.avrcp_srv_conn_stat = state; } -static bd_addr_t *BtAvrcpSrvGetActiveAddr(void) +bd_addr_t *BtAvrcpSrvGetActiveAddr(void) { return &g_avrcp_srv_inf.bd_addr; } + + void ConnectTgStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t state) { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "avrcp tg update conn stat:%u", state); diff --git a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp index 6cb7f137e..999f9bd3a 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp @@ -52,6 +52,7 @@ #include "uiservice/include/ui_service.h" #include "vibrator_service.h" #include "ConfigModel.h" +#include "PhoneAGService.h" namespace OHOS { #define BT_SPP_TASK_STACK_SIZE 2048 @@ -1073,9 +1074,18 @@ void BluetoothModel::BtGapAclStateChangedHandle(gap_acl_state_t state, unsigned ACLConnectionFail(bdAddr); } WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "a2dp_src_connect result 0x%x", retA2dp); +errcode_t rethfp= hfp_ag_cmd_conn_hfp(&bdAddr); + if(rethfp) + { + ACLConnectionFail(bdAddr); + } + + } else { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ingore a2dp_src_connect"); } + + } } static uint8_t ALC_State_flag=0; diff --git a/code/sdk/application/wearable/fd230app/nativeui/callerlog/include/CallerLogModel.h b/code/sdk/application/wearable/fd230app/nativeui/callerlog/include/CallerLogModel.h index 412a54f1d..6aa7511e0 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/callerlog/include/CallerLogModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/callerlog/include/CallerLogModel.h @@ -49,6 +49,7 @@ void InitCallingTimer(); void calllognameupdate(void); +void Call_headset_state_updata(int data); namespace OHOS { diff --git a/code/sdk/application/wearable/fd230app/nativeui/callerlog/src/CallerLogModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/callerlog/src/CallerLogModel.cpp index 2bef3f136..da02f92ac 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/callerlog/src/CallerLogModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/callerlog/src/CallerLogModel.cpp @@ -26,6 +26,7 @@ #include "cat1_ctl.h" #include "cat1_server.h" #include "AlarmClockModel.h" +#include "PhoneAGService.h" #ifdef __cplusplus extern "C" { #endif @@ -142,7 +143,20 @@ void StatusReset(void) DisableCallingTimer(); if(CallerLogModel::GetInstance()->GetCallSource()==CallerLogModel::CallSourceCat1) - do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_STOP, nullptr, 0); + { + if(volte_voice_state()==2 && headset_Is_connect()) + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT_HFP_DIS_SCO_CONNECT, nullptr, 0); + } + else + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_STOP, nullptr, 0); + } + + + + } + CallerLogModel::GetInstance()->Setphonebname("",0); CallerLogModel::GetInstance()->SetCallDial(CallerLogModel::HFP_PHONE_DIAL); @@ -160,11 +174,11 @@ void StatusReset(void) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "xxxxxxxxxxxxx"); PhoneServiceScreenCtr(false); - if(NativeAbility::GetInstance().GetCurSliceId() == VIEW_INCOMING_CALL) + if(NativeAbility::GetInstance().GetCurSliceId() == VIEW_INCOMING_CALL || NativeAbility::GetInstance().GetCurSliceId() == VIEW_BLUETOOTH_EARPHONE) { NativeAbility::GetInstance().Back_CountSlice_make_phone(); } - else if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_REBOOTANDSHUTDOWN) + else if (NativeAbility::GetInstance().GetCurSliceId() == VIEW_REBOOTANDSHUTDOWN ) { NativeAbility::GetInstance().ClearSliceIdStack(); } @@ -202,14 +216,26 @@ static void CallTimerCallbackProc(int data) if( CallerLogModel::GetInstance()->GetCallSource() == CallerLogModel::CallSourceCat1 && NotificationManager::GetInstance()->GetWatchCallStatus()==true) { - if(!MainCallingView::GetInstance()->GetDisplayGroup()->IsVisible()) + if(MainCallingView::GetInstance()->GetDisplayGroup()) { - if(!volte_voice_state()) - do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_START, nullptr, 0); + // if(!MainCallingView::GetInstance()->GetDisplayGroup()->IsVisible()) + // { + // if( volte_voice_state!=2) + // { + // do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_START, nullptr, 0); + // } + // else if( && volte_voice_state()!=1) + // { + // do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_START, nullptr, 0); + // } + + + // } } + { - if(get_call_hungup_flag()>=1) + if(get_call_hungup_flag()>=2) { cat1_handle_call_disconnected((char *)CallerLogModel::GetInstance()->GetPhoneNumber().c_str()); } @@ -220,19 +246,10 @@ static void CallTimerCallbackProc(int data) } } +} -// if(MainCallingView::GetInstance()->GetScreenView()) -// { -// if (MainCallingView::GetInstance()->GetScreenView()->GetCallingDurationLabel()) -// { - -// MainCallingView::GetInstance()->GetScreenView()->GetCallingDurationLabel()-> -// SetText(CallerLogModel::GetInstance()->InitDateHourTime().c_str()); -// } -// } -} static void snakeCallback(int data) { @@ -248,6 +265,21 @@ static void CallTimerCallback(int data) GraphicService::GetInstance()->PostGraphicEvent(std::bind(CallTimerCallbackProc, data)); } +static void Call_headset_state_updata_Proc(int data) +{ + if(MainCallingView::GetInstance()==nullptr) + { + return; + } + + MainCallingView::GetInstance()->update_headset_state((uint8_t)data); + +} + +void Call_headset_state_updata(int data) +{ + GraphicService::GetInstance()->PostGraphicEvent(std::bind(Call_headset_state_updata_Proc, data)); +} /* 开启定时器 */ diff --git a/code/sdk/application/wearable/fd230app/nativeui/makephone/include/CallingView.h b/code/sdk/application/wearable/fd230app/nativeui/makephone/include/CallingView.h index 378b51978..81579ba9d 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/makephone/include/CallingView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/makephone/include/CallingView.h @@ -17,7 +17,7 @@ #include "UiConfig.h" #include "ChangeSliceListener.h" #include "components/ui_label_button.h" - +#include "BluetoothEarListView.h" namespace OHOS { class CallingView { @@ -33,12 +33,14 @@ public: void showdial(bool); void text_updata_buf(const char *buf); void updataCallingname(void); -private: + void update_headset_state(uint8_t state); + + private: bool InitAddOnclickevent(void); bool InitImageViewDisplay(void); bool InitUILabelDisplay(void); bool Initshowdial(void); - + UIViewGroup *group{nullptr}; UIView::OnClickListener* clickLeftListener{nullptr}; diff --git a/code/sdk/application/wearable/fd230app/nativeui/makephone/include/MainCallingView.h b/code/sdk/application/wearable/fd230app/nativeui/makephone/include/MainCallingView.h index d87012083..2817f51f2 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/makephone/include/MainCallingView.h +++ b/code/sdk/application/wearable/fd230app/nativeui/makephone/include/MainCallingView.h @@ -37,7 +37,7 @@ public: CallingView *GetScreenView(); void updataCallingname(void); - + void update_headset_state(uint8_t data); private: bool InitPointerValue(); UIViewGroup *displayGroup{nullptr}; diff --git a/code/sdk/application/wearable/fd230app/nativeui/makephone/src/CallingView.cpp b/code/sdk/application/wearable/fd230app/nativeui/makephone/src/CallingView.cpp index 165b6bb02..22c0402d7 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/makephone/src/CallingView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/makephone/src/CallingView.cpp @@ -16,6 +16,7 @@ #include "bletest.h" #include "ui_resource_string.h" +#include "PhoneAGService.h" namespace OHOS { static constexpr uint16 MATH_ZERO = 0; @@ -105,7 +106,7 @@ CallingView::~CallingView() dial_group = nullptr; } - + g_pMainView = nullptr; } @@ -125,7 +126,7 @@ bool CallingView::InitAddOnclickevent() imageHandUp->SetOnClickListener(clickLeftListener); imageHorns->SetOnClickListener(clickLeftListener); imagedial->SetOnClickListener(clickLeftListener); - + imageheadset->SetOnClickListener(clickLeftListener); for( int i=0;i<12;i++) { @@ -200,9 +201,26 @@ bool CallingView::InitImageViewDisplay() return false; } imageheadset->SetPosition(296, 296); // 30 : offset - imageheadset->SetSrc(PNG_230_HEADSET_1_IIMAGE_PATH); + + if(headset_SCO_Is_connect()) + { + imageheadset->SetSrc(PNG_230_HEADSET_2_IIMAGE_PATH); + imageheadset->SetViewId("callingheadset"); + } + else if (CallerLogModel::GetInstance()->GetCallSource() == CallerLogModel::CallSourceCat1) + { + imageheadset->SetSrc(PNG_230_HEADSET_3_IIMAGE_PATH); + imageheadset->SetViewId("callingheadset"); + } + else + { + imageheadset->SetSrc(PNG_230_HEADSET_1_IIMAGE_PATH); + imageheadset->SetViewId("headset"); + } + + imageheadset->SetTouchable(true); - imageheadset->SetViewId("headset"); + group->Add(imageheadset); imageperson = new UIImageView(); @@ -212,7 +230,7 @@ bool CallingView::InitImageViewDisplay() imageperson->SetPosition(158, 158); // 30 : offset imageperson->SetSrc(PNG_230_PERSON_IMAGE_PATH); imageperson->SetTouchable(true); - imageperson->SetViewId("headset"); + imageperson->SetViewId("imageperson"); group->Add(imageperson); char name_buf[NAME_LEN+1]={0}; @@ -228,6 +246,25 @@ bool CallingView::InitImageViewDisplay() return true; } +void CallingView::update_headset_state(uint8_t state) +{ + if(imageheadset) + { + if(state) + { + imageheadset->SetSrc(PNG_230_HEADSET_2_IIMAGE_PATH); + } + else + { + imageheadset->SetSrc(PNG_230_HEADSET_3_IIMAGE_PATH); + } + } + +} + + + + UIImageView *CallingView::GetImageMicrophone() { return imageMicrophone; diff --git a/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingPresenter.cpp b/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingPresenter.cpp index ff59e6164..3fa35b0ba 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingPresenter.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingPresenter.cpp @@ -434,6 +434,10 @@ bool MainCallingPresenter::OnClick(UIView& view, const ClickEvent& event) else view_->GetCallingView()->text_updata_buf(view.GetViewId()); } + else if (strcmp(view.GetViewId(), "callingheadset") == 0) + { + NativeAbility::GetInstance().EnterSlice(VIEW_BLUETOOTH_EARPHONE); + } return true; diff --git a/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingView.cpp b/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingView.cpp index 6c4f2fd2e..339e08d4b 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingView.cpp @@ -150,6 +150,18 @@ void MainCallingView::updataCallingname(void) } } +void MainCallingView::update_headset_state(uint8_t data) +{ + if(callView) + { + callView->update_headset_state(data); + RootView::GetInstance()->Invalidate(); + } + +} + + + void MainCallingView::OnStart() { WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "MainCallingView::OnStart"); diff --git a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAGService.h b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAGService.h new file mode 100644 index 000000000..8ced3eaca --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAGService.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) @CompanyNameMagicTag 2021. All rights reserved. + * Description: This module include test functions of HFP AG service. + */ +#ifndef HFP_AG_SERVICE_H +#define HFP_AG_SERVICE_H + +#include + +#include "bts_br_gap.h" +#include "bts_hfp_hf.h" +#include "ohos_types.h" + + +#define SAMPLE_HFP_PROF_VOL_LEVEL 15 +#define SAMPLE_HFP_MEDIA_VOL_LEVEL 100 + +void hfp_ag_reg_callback(void); + +errcode_t hfp_ag_cmd_conn_hfp(const bd_addr_t *bd_addr); + +errcode_t hfp_ag_cmd_disconn_hfp(const bd_addr_t *bd_addr); + + +void hfp_ag_cmd_conn_sco(const bd_addr_t *bd_addr ); + +void hfp_ag_cmd_disconn_sco(const bd_addr_t *bd_addr ); + +bool headset_Is_connect(void); + +bool headset_SCO_Is_connect(void); + +void cat1_set_headset_volume( unsigned char volume); + +int cat1_ag_send_call_event( uint32_t event_topic,const char* info); + +// void bt_hfp_ag_service_sample_cmd(uint32_t cmd_id, const char **params, int32_t params_cnt); + +#endif /* SAMPLE_HFP_AG_SERVICE_H */ diff --git a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAudio.h b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAudio.h index 0fc217683..74111a261 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAudio.h +++ b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAudio.h @@ -72,6 +72,7 @@ int32 PhoneCAT1AudioGetVolume(void); bool PhoneCATAudioSetVolume(int32 volume); +void Sample_audio_init(void); diff --git a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneServiceC.h b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneServiceC.h index 3c456f974..25f1896ee 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneServiceC.h +++ b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneServiceC.h @@ -4,8 +4,8 @@ * Create: 2021-09-22 */ -#ifndef PHONE_SERVICE_H -#define PHONE_SERVICE_H +#ifndef PHONE_SERVICE_C_H +#define PHONE_SERVICE_C_H #ifdef __cplusplus @@ -28,6 +28,11 @@ void cat1_audio_AudioRelease(void); int32_t PhoneAudioSetMicMuteCat1(bool isMute); +void cat1_connect_sco_(void); + +void cat1_disconn_sco_(void); + +void cat1_start_SCO_audio_(void); #ifdef __cplusplus } #endif diff --git a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAGService.cpp b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAGService.cpp new file mode 100644 index 000000000..a5b600863 --- /dev/null +++ b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAGService.cpp @@ -0,0 +1,950 @@ +/* + * Copyright (c) @CompanyNameMagicTag 2021. All rights reserved. + * Description: This module include test function of BT HFP Service module. + */ + +#include "PhoneAGService.h" +#include +#include +#include +#include "securec.h" +#include "errcode.h" +#include "bts_br_gap.h" +#include "bts_hfp_ag.h" +// #include "sample_common.h" +#ifdef MEMORY_MINI +#include "audio_manager.h" +#else +// #include "sdk_private.h" +// /home/hcj/FD230/code/sdk/protocol/bt/host/bt/bts/brandy_service/bt_audio_wrapper/bt_audio_manager_wrapper.h +#include "bt_audio_manager_wrapper.h" +#endif + +#include "wearable_log.h" +#include "common_def.h" +#include "PhoneAudio.h" +#include "cat1_ctl.h" +#include "BluetoothHeadsetEvent.h" + +#include "PhoneServiceC.h" +#include "notification_manager.h" + +#include "PhoneService.h" +#include "CallerLogModel.h" +#include "custom_utils.h" + + +#define SAMPLE_HFP_TASK_STACK_SIZE 0x1600 +#define SAMPLE_HFP_TASK_PRI 20 +#define HFP_MEDIA_STATUS_DEINIT 0 +#define HFP_MEDIA_STATUS_INIT 1 +#define HFP_MEDIA_STATUS_START 2 +#define HFP_MEDIA_FLAG_IDLE 0 +#define HFP_MEDIA_FLAG_BUSY 1 + +#define HFP_AG_IND_SIGNAL_DEFAULT 3 +#define HFP_AG_IND_BATTERY_DEFAULT 5 + +typedef enum { + SAMPLE_HFP_AG_CMD_INIT = 0, /* AG初始化 */ + SAMPLE_HFP_AG_CMD_DEINIT, /* AG去初始化 */ + SAMPLE_HFP_AG_CMD_REG_CALLBACK, /* 注册回调 */ + SAMPLE_HFP_AG_CMD_CONN_HFP, /* HFP连接 */ + SAMPLE_HFP_AG_CMD_DISCONN_HFP, /* HFP断开连接 */ + SAMPLE_HFP_AG_CMD_CONN_SCO = 5, /* 建立SCO连接 */ + SAMPLE_HFP_AG_CMD_DISCONN_SCO, /* 断开SCO连接 */ + SAMPLE_HFP_AG_CMD_GET_DEV_CONN_STATE, /* 获取设备Profile连接状态 */ + SAMPLE_HFP_AG_CMD_GET_SCO_CONN_STATE, /* 获取SCO连接状态 */ + SAMPLE_HFP_AG_CMD_ANSWER_CALL, /* 接听电话 */ + SAMPLE_HFP_AG_CMD_FINISH_CALL = 10, /* 挂断电话 */ + SAMPLE_HFP_AG_CMD_SET_VOLUME, /* 设置扬声器/麦克风音量 */ + SAMPLE_HFP_AG_CMD_SEND_INCOMING_EVENT, /* 发送来电事件 */ + SAMPLE_HFP_AG_CMD_SEND_NETWORK_EVENT, /* 发送网络事件 */ + SAMPLE_HFP_AG_CMD_SEND_CALL_LIST, /* 发送通话列表 */ + SAMPLE_HFP_AG_CMD_SEND_SUBSCRIBER_NUMBER = 15, /* 发送订阅号码信息 */ + SAMPLE_HFP_AG_CMD_SEND_BATTERY_CHARGE, /* 发送电量信息 */ + SAMPLE_HFP_AG_CMD_SEND_CMEE_ERROR, /* 发送扩展错误码信息 */ + SAMPLE_HFP_AG_CMD_SEND_NETWORK_OPERATOR, /* 发送运营商信息 */ + SAMPLE_HFP_AG_CMD_SEND_INDICATOR_VAL, /* 发送指示器值 */ + SAMPLE_HFP_AG_CMD_ORIGINATE_CALL, /* 呼出电话 */ +} sample_hfp_ag_cmd_id; + +typedef void (*hfp_ag_sample_cmd_handle_func)(const char **params, int32_t params_cnt); + +typedef struct { + sample_hfp_ag_cmd_id id; + hfp_ag_sample_cmd_handle_func func; +} sample_hfp_ag_hdl_info; + +static hfp_cind_info_t g_sample_hfp_cind_info = {0}; + + +static const bd_addr_t AG_bd_addr={0}; + + +static void sample_hfp_ag_print_addr(const bd_addr_t *bd_addr) +{ + if (bd_addr != NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"addr: %02x:%02x:**:**:**:%02x ", + bd_addr->addr[5], bd_addr->addr[4], bd_addr->addr[0]); /* addr 只打印0,4,5位 */ + } +} + +static int32_t g_hfp_media_status = 0; +static int32_t g_hfp_media_flag = 0; + + +static AudioCodecFormat g_hfp_codec = mSBC; +static int32_t g_hdl_up_mic = -1; +static int32_t g_hdl_up_sco = -1; +static int32_t g_hdl_dn_spk = -1; +static int32_t g_hdl_dn_sco = -1; +static int32_t g_hdl_up_modem = -1; +static int32_t g_hdl_dn_modem = -1; + + +#ifndef MEMORY_MINI +static int32_t audio_stream_init(void) +{ + /* 请求音频焦点 */ + /* deactive响铃时申请的焦点后,重新申请通话焦点 */ + audio_manager_activate_interrupt(AUDIO_STREAM_VOICE_CALL_VOLTE); + audio_manager_set_device_connection_state(IN_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED); + audio_manager_set_device_connection_state(OUT_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED); + audio_manager_set_device_connection_state(IN_MODEM_HEADSET, AUDIO_DEVICE_CONNECTED); + audio_manager_set_device_connection_state(OUT_MODEM_HEADSET, AUDIO_DEVICE_CONNECTED); + + g_hdl_up_sco = audio_stream_in_init(AUDIO_UP_LINK, PCM); + g_hdl_up_modem = audio_stream_out_init(AUDIO_UP_LINK, PCM); + + g_hdl_dn_sco = audio_stream_out_init(AUDIO_DOWN_LINK, mSBC); + g_hdl_dn_modem = audio_stream_in_init(AUDIO_DOWN_LINK, mSBC); + + return 0; +} + +static int32_t establish_audio_stream_pipeline(void) +{ + uint32_t modem_out_shm_id = 0; + uint32_t modem_in_shm_id = 0; + + audio_stream_in_start(g_hdl_dn_modem); + audio_stream_out_start(g_hdl_dn_sco); + audio_stream_in_get_channel_id(g_hdl_dn_modem, &modem_in_shm_id); + audio_stream_out_attach_frontend(g_hdl_dn_sco, modem_in_shm_id); + audio_stream_in_start(g_hdl_up_sco); + audio_stream_out_start(g_hdl_up_modem); + audio_stream_out_get_channel_id(g_hdl_up_modem, &modem_out_shm_id); + audio_stream_in_attach_backend(g_hdl_up_sco, modem_out_shm_id); + + return 0; +} + +static int32_t abrogation_audio_stream_pipeline(void) +{ + /* 销毁上下行通路 */ + audio_stream_in_stop(g_hdl_up_sco); + audio_stream_in_deinit(g_hdl_up_sco); + audio_stream_out_stop(g_hdl_up_modem); + audio_stream_out_deinit(g_hdl_up_modem); + audio_stream_out_stop(g_hdl_dn_sco); + audio_stream_out_deinit(g_hdl_dn_sco); + audio_stream_in_stop(g_hdl_dn_modem); + audio_stream_in_deinit(g_hdl_dn_modem); + audio_manager_set_device_connection_state(IN_BLUETOOTH_SCO, AUDIO_DEVICE_DISCONNECTED); + audio_manager_set_device_connection_state(OUT_BLUETOOTH_SCO, AUDIO_DEVICE_DISCONNECTED); + audio_manager_set_device_connection_state(IN_MODEM_HEADSET, AUDIO_DEVICE_DISCONNECTED); + audio_manager_set_device_connection_state(OUT_MODEM_HEADSET, AUDIO_DEVICE_DISCONNECTED); + /* 释放音频焦点 */ + audio_manager_deactivate_interrupt(); + audio_manager_deinit(); + + return 0; +} +#endif + + + + +static int32_t sample_audio_init_start_task_body(const void *data) +{ + // Sample_audio_init(); + + // return 0; + + unused(data); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample_audio_init_start enter\n"); + while ((g_hfp_media_flag != HFP_MEDIA_FLAG_IDLE) || (g_hfp_media_status != HFP_MEDIA_STATUS_DEINIT)) { + osal_msleep(1); + } + /* 设置媒体状态繁忙 */ + g_hfp_media_flag = HFP_MEDIA_FLAG_BUSY; + int ret; + audio_stream_init(); + + /* Init success */ + g_hfp_media_status = HFP_MEDIA_STATUS_INIT; + + /* 建立电话上下行通路 */ + establish_audio_stream_pipeline(); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample_audio_init_start end\n"); + /* Start success */ + g_hfp_media_status = HFP_MEDIA_STATUS_START; + g_hfp_media_flag = HFP_MEDIA_FLAG_IDLE; + return 0; +} + +static int32_t sample_audio_deinit_task_body(const void *data) +{ + unused(data); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample_audio_deinit enter\n"); + while ((g_hfp_media_flag != HFP_MEDIA_FLAG_IDLE) || (g_hfp_media_status != HFP_MEDIA_STATUS_START)) { + osal_msleep(1); + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample_audio_deinit start\n"); + /* 设置媒体状态繁忙 */ + g_hfp_media_flag = HFP_MEDIA_FLAG_BUSY; + abrogation_audio_stream_pipeline(); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample_audio_deinit end\n"); + /* Deinit success */ + g_hfp_media_status = HFP_MEDIA_STATUS_DEINIT; + g_hfp_media_flag = HFP_MEDIA_FLAG_IDLE; + return 0; +} + +static void sample_hfp_ag_set_spk_volume(uint8_t volume) +{ + + /* vol range [0, 100] */ + int32_t vol = volume * SAMPLE_HFP_MEDIA_VOL_LEVEL / SAMPLE_HFP_PROF_VOL_LEVEL; + audio_manager_set_volume(AUDIO_STREAM_VOICE_CALL_VOLTE, vol); + +} + + +static void sample_hfp_ag_conn_state_changed_callback(const bd_addr_t *bd_addr, profile_connect_state_t state) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"state: %d\n", state); + //如果触发连接为电话状态,自动切到电话 + if(state==PROFILE_STATE_CONNECTED) + { + if(OHOS::CallerLogModel::GetInstance()->GetCallSource() == OHOS::CallerLogModel::CallSourceCat1 + && OHOS::NotificationManager::GetInstance()->GetWatchCallStatus()) + { + cat1_connect_sco_(); + } + else + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"电话结束\n"); + } + } + + if(state==PROFILE_STATE_DISCONNECTED) + { + // if(OHOS::CallerLogModel::GetInstance()->GetCallSource() == OHOS::CallerLogModel::CallSourceCat1 + // && OHOS::NotificationManager::GetInstance()->GetWatchCallStatus()) + // { + // if(volte_voice_state()==0) + + // } + // else + // { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"电话结束\n"); + // } + } + +} + + +void cat1_start_SCO_audio_(void) +{ + uapi_cat1_start_SCO_volte_voice(); +} + +static void sample_hfp_ag_sco_conn_state_changed_callback(const bd_addr_t *bd_addr, hfp_sco_connect_state_t state) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"state: %d\n", state); + osal_kthread_handler task_body = NULL; + switch (state) { + case HFP_SCO_STATE_CONNECTING: + break; + + case HFP_SCO_STATE_CONNECTED: + if(volte_voice_state()==0) + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT_HFP_SCO_AUDIO_START, nullptr, 0); + } + else + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_STOP, nullptr, 0); + + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT_HFP_SCO_AUDIO_START, nullptr, 0); + } + Call_headset_state_updata(1); + + + break; + + case HFP_SCO_STATE_DISCONNECTING: + break; + case HFP_SCO_STATE_DISCONNECTED: + + if(OHOS::CallerLogModel::GetInstance()->GetCallSource() == OHOS::CallerLogModel::CallSourceCat1 + && OHOS::NotificationManager::GetInstance()->GetWatchCallStatus()) + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_STOP, nullptr, 0); + + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_START, nullptr, 0); + } + else + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_STOP, nullptr, 0); + } + + Call_headset_state_updata(0); + break; + + default: { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"invalid state!\n"); + break; + } + } +} + +static void sample_hfp_ag_codec_changed_callback(const bd_addr_t *bd_addr, hfp_ag_codec_id_t codec) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"codec : %d\n", codec); + +} + +static void sample_hfp_ag_volume_changed_callback(const bd_addr_t *bd_addr, hfp_volume_type_t type, uint8_t volume) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"type: %d, volume: %u\n", type, volume); + if (type == HFP_VOLUME_SPEAKER) { + sample_hfp_ag_set_spk_volume(volume); + } +} + +static void sample_hfp_ag_dial_req_callback(const bd_addr_t *bd_addr, unsigned char *number, unsigned int len) +{ + sample_hfp_ag_print_addr(bd_addr); + for (unsigned int i = 0; i < len; i++) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"number: %d ", *((uint8_t *)number + i)); + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"len: %d.\n", len); +} + +static void sample_hfp_ag_mem_dial_req_callback(const bd_addr_t *bd_addr, unsigned int index) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"index: %d.\n", index); +} + +static void sample_hfp_ag_lastnum_dial_req_callback(const bd_addr_t *bd_addr) +{ + sample_hfp_ag_print_addr(bd_addr); +} + +static void sample_hfp_ag_answer_call_req_callback(const bd_addr_t *bd_addr, hfp_ag_type_t type) +{ + sample_hfp_ag_print_addr(bd_addr); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"type: %d.\n", type); +} + +static void sample_hfp_ag_cancel_call_req_callback(const bd_addr_t *bd_addr, hfp_ag_type_t type) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"type: %d.\n", type); +} + +static void sample_hfp_ag_dtmf_req_callback(const bd_addr_t *bd_addr, unsigned int code) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"code: 0x%x.\n", code); +} + +static void sample_hfp_ag_subscriber_number_req_callback(const bd_addr_t *bd_addr) +{ + sample_hfp_ag_print_addr(bd_addr); + /* TODO 造数据响应 */ +} + +static void sample_hfp_ag_current_calls_req_callback(const bd_addr_t *bd_addr) +{ + sample_hfp_ag_print_addr(bd_addr); + /* TODO 造数据响应 */ +} + +static void sample_hfp_ag_current_indicator_req_callback(const bd_addr_t *bd_addr) +{ + g_sample_hfp_cind_info.service = 1; + g_sample_hfp_cind_info.call = 0; + g_sample_hfp_cind_info.callsetup = 0; + g_sample_hfp_cind_info.callheld = 0; + g_sample_hfp_cind_info.signal = HFP_AG_IND_SIGNAL_DEFAULT; + g_sample_hfp_cind_info.roam = 0; + g_sample_hfp_cind_info.battchg = HFP_AG_IND_BATTERY_DEFAULT; + errcode_t ret = (errcode_t)hfp_ag_send_indicator_val(bd_addr, &g_sample_hfp_cind_info); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag send cur indicator cbk ret=0x%x\n", ret); +} + +static void sample_hfp_ag_network_operator_format_req_callback(const bd_addr_t *bd_addr) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag AT+COPS= req cbk.\n"); +} + +static void sample_hfp_ag_network_operator_req_callback(const bd_addr_t *bd_addr) +{ + sample_hfp_ag_print_addr(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag AT+COPS? req cbk.\n"); +} + +static void sample_hfp_ag_init(const char **params, int32_t params_cnt) +{ + unused(params); + unused(params_cnt); + // hfp_ag_service_init(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag init done.\n"); +} + +static void sample_hfp_ag_deinit(const char **params, int32_t params_cnt) +{ + unused(params); + unused(params_cnt); + // hfp_ag_service_deinit(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag deinit done.\n"); +} + +void hfp_ag_reg_callback(void) +{ + + errcode_t ret = ERRCODE_BT_SUCCESS; + hfp_ag_callbacks_t callbacks = { + sample_hfp_ag_conn_state_changed_callback, + sample_hfp_ag_sco_conn_state_changed_callback, + sample_hfp_ag_codec_changed_callback, + sample_hfp_ag_volume_changed_callback, + sample_hfp_ag_dial_req_callback, + sample_hfp_ag_mem_dial_req_callback, + sample_hfp_ag_lastnum_dial_req_callback, + sample_hfp_ag_answer_call_req_callback, + sample_hfp_ag_cancel_call_req_callback, + sample_hfp_ag_dtmf_req_callback, + sample_hfp_ag_subscriber_number_req_callback, + sample_hfp_ag_current_calls_req_callback, + sample_hfp_ag_current_indicator_req_callback, + sample_hfp_ag_network_operator_format_req_callback, + sample_hfp_ag_network_operator_req_callback, + }; + ret = (errcode_t)hfp_ag_register_callbacks(&callbacks); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag reg cbk ret=0x%x\n", ret); +} + +/* */ +errcode_t hfp_ag_cmd_conn_hfp(const bd_addr_t *bd_addr) +{ + errcode_t ret = (errcode_t)hfp_ag_connect(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); + return ret; +} + +/* */ +errcode_t hfp_ag_cmd_disconn_hfp(const bd_addr_t *bd_addr) +{ + + errcode_t ret = (errcode_t)hfp_ag_disconnect(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); + return ret; +} + +/* */ +void hfp_ag_cmd_conn_sco(const bd_addr_t *bd_addr ) +{ + + errcode_t ret = (errcode_t)hfp_ag_audio_connect(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u %02X %02X %02X %02X %02X %02X\n", ret,bd_addr->addr[5] + ,bd_addr->addr[4],bd_addr->addr[3],bd_addr->addr[2],bd_addr->addr[1],bd_addr->addr[0]); +} + +/* */ +void hfp_ag_cmd_disconn_sco(const bd_addr_t *bd_addr ) +{ + errcode_t ret = (errcode_t)hfp_ag_audio_disconnect(bd_addr); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_get_dev_conn_state(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 1) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag dev conn state param is invalid.\n"); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag dev conn state decode addr error!\n"); + // return; + // } + // int ret = hfp_ag_get_device_connect_state(&bd_addr); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %d\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_get_sco_conn_state(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 1) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag sco state param is invalid.\n"); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag sco state decode addr error!\n"); + // return; + // } + // int ret = hfp_ag_get_sco_connect_state(&bd_addr); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %d\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_answer_call(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 1) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag answer call param is invalid.\n"); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag answer call decode addr error!\n"); + // return; + // } + // errcode_t ret = (errcode_t)hfp_ag_send_answer_call_event(&bd_addr); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %d\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_finish_call(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 2) { /* 2: param count */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag finish call param is invalid.\n"); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag finish call decode addr error!\n"); + // return; + // } + // hfp_ag_action_t type = (hfp_ag_action_t)atoi(params[1]); + // errcode_t ret = (errcode_t)hfp_ag_send_finish_call_event(&bd_addr, type); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"type: %d ret: %d\n", type, ret); +} + +/* */ +static void sample_hfp_ag_cmd_set_volume(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 3) { /* 3个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag set volume decode addr error!\n"); + // return; + // } + // hfp_volume_type_t type = (hfp_volume_type_t)atoi(params[1]); /* 第1个参数 */ + // uint8_t volume = (uint8_t)atoi(params[2]); /* 第2个参数 */ + // errcode_t ret = (errcode_t)hfp_ag_set_volume(&bd_addr, type, volume); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"type: %d volume: %u ret: %u\n", type, volume, ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_network_event(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 3) { /* 3个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag set volume decode addr error!\n"); + // return; + // } + // hfp_ag_network_event_t event = (hfp_ag_network_event_t)atoi(params[1]); /* 第1个参数 */ + // uint8_t param = (uint8_t)atoi(params[2]); /* 第2个参数 */ + // errcode_t ret = (errcode_t)hfp_ag_send_network_event(&bd_addr, event, param); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"event: %d param: %u ret: %u\n", event, param, ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_incoming_event(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 5) { /* 5个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag set volume decode addr error!\n"); + // return; + // } + + // uint8_t type = (uint8_t)atoi(params[1]); /* index:1 */ + // uint8_t service = (uint8_t)atoi(params[2]); /* index:2 */ + // char *number_str = params[3]; /* index:3 */ + // size_t str_len = strlen(number_str); + // if (str_len > HFP_AG_PHONENUM_MAX_DIGITS) { /* number最大长度为32 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"number len exceeds max limit! str_len = %u \n", str_len); + // return; + // } + // uint8_t number_len = (uint8_t)str_len; + + // char *name_str = params[4]; /* index:4 *//* index:4 */ + // size_t name_str_len = strlen(name_str); + // if (name_str_len > 256) { /* name最大长度为256 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"name len exceeds max limit! str_len = %u \n", str_len); + // return; + // } + // uint8_t name_len = (uint8_t)name_str_len; + + // hfp_phone_info_t *info = bt_os_new(sizeof(hfp_phone_info_t) + name_len); + // if (memset_s(info, sizeof(hfp_phone_info_t) + name_len, 0, + // sizeof(hfp_phone_info_t) + name_len) != EOK) { + // bt_os_free(info); + // return; + // } + // info->type = type; + // info->service = service; + // info->num_len = number_len; + // if (memcpy_s(info->number, HFP_AG_PHONENUM_MAX_DIGITS, (uint8_t *)number_str, str_len) != EOK) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"number memcpy error.\n"); + // bt_os_free(info); + // return; + // } + // info->name_len = name_len; + // if (memcpy_s(info->alpha_str, name_len, (int8_t *)name_str, name_len) != EOK) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"name memcpy error.\n"); + // bt_os_free(info); + // return; + // } + // errcode_t ret = (errcode_t)hfp_ag_send_network_incoming_event(&bd_addr, info); + // bt_os_free(info); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_call_list(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 9) { /* 9个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag set volume decode addr error!\n"); + // return; + // } + // uint8_t number_len = 0; + // char *number_str = params[7]; /* 7:idx */ + // size_t str_len = strlen(number_str); + // if (str_len > HFP_AG_PHONENUM_MAX_DIGITS) { /* number最大长度为32 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"number len exceeds max limit! str_len = %u \n", str_len); + // return; + // } + // number_len = (uint8_t)str_len; + // hfp_clcc_info_t *info = bt_os_new(sizeof(hfp_clcc_info_t) + number_len); + // if (memset_s(info, sizeof(hfp_clcc_info_t) + number_len, 0, + // sizeof(hfp_clcc_info_t) + number_len) != EOK) { + // bt_os_free(info); + // return; + // } + // info->idx = (uint8_t)atoi(params[1]); + // info->dir = (uint8_t)atoi(params[2]); /* 2:idx */ + // info->status = (uint8_t)atoi(params[3]); /* 3:idx */ + // info->mode = (uint8_t)atoi(params[4]); /* 4:idx */ + // info->mpty = (uint8_t)atoi(params[5]); /* 5:idx */ + // info->type = (uint8_t)atoi(params[6]); /* 6:idx */ + // info->num_len = number_len; + // if (memcpy_s(info->number, number_len, (uint8_t *)number_str, str_len) != EOK) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"number memcpy error.\n"); + // bt_os_free(info); + // return; + // } + + // hfp_ag_last_t is_last = (hfp_ag_last_t)atoi(params[8]); /* 8:idx */ + // errcode_t ret = (errcode_t)hfp_ag_send_current_calls(&bd_addr, info, is_last); + // bt_os_free(info); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_subscriber_number(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 6) { /* 6个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag set volume decode addr error!\n"); + // return; + // } + + // uint8_t type = (uint8_t)atoi(params[1]); /* index:1 */ + // uint8_t service = (uint8_t)atoi(params[2]); /* index:2 */ + // char *number_str = params[3]; /* index:3 */ + // size_t str_len = strlen(number_str); + // if (str_len > 32) { /* number最大长度为32 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"number len exceeds max limit! str_len = %u \n", str_len); + // return; + // } + // uint8_t number_len = (uint8_t)str_len; + + // char *name_str = params[4]; /* index:4 *//* index:4 */ + // size_t name_str_len = strlen(name_str); + // if (name_str_len > 256) { /* name最大长度为256 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"name len exceeds max limit! str_len = %u \n", str_len); + // return; + // } + // uint8_t name_len = (uint8_t)name_str_len; + + // hfp_phone_info_t *info = bt_os_new(sizeof(hfp_phone_info_t) + name_len); + // if (memset_s(info, sizeof(hfp_phone_info_t) + name_len, 0, + // sizeof(hfp_phone_info_t) + name_len) != EOK) { + // bt_os_free(info); + // return; + // } + // info->type = type; + // info->service = service; + // info->num_len = number_len; + // if (memcpy_s(info->number, HFP_AG_PHONENUM_MAX_DIGITS, (uint8_t *)number_str, str_len) != EOK) { + // bt_os_free(info); + // return; + // } + // info->name_len = name_len; + // if (memcpy_s(info->alpha_str, name_len, (int8_t *)name_str, name_len) != EOK) { + // bt_os_free(info); + // return; + // } + // hfp_ag_last_t is_last = (hfp_ag_last_t)atoi(params[5]); + // errcode_t ret = (errcode_t)hfp_ag_send_subscriber_number(&bd_addr, info, is_last); + // bt_os_free(info); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_battery_charge(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 2) { /* 2个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag send battery charge decode addr error!\n"); + // return; + // } + // uint8_t value = (uint8_t)atoi(params[1]); /* 第1个参数 */ + // errcode_t ret = (errcode_t)hfp_ag_send_battery_charge(&bd_addr, value); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"value: %d ret: %u\n", value, ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_cmee_error(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 2) { /* 2个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag send cmee error decode addr error!\n"); + // return; + // } + // hfp_ag_cmee_error_t error_code = (hfp_ag_cmee_error_t)atoi(params[1]); /* 第1个参数 */ + // errcode_t ret = (errcode_t)hfp_ag_send_cmee_error(&bd_addr, error_code); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"error_code: %d ret: %u\n", error_code, ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_network_operator(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 4) { /* 4个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag send network operator decode addr error!\n"); + // return; + // } + + // char *operator_name = params[3]; /* index3 */ + // uint8_t operator_len = 0; + // size_t name_str_len = strlen(operator_name); + // if (name_str_len > HFP_AG_COPS_OPERATOR_MAXLEN) { /* name最大长度为16 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"name len exceeds max limit! str_len = %u \n", name_str_len); + // return; + // } + // operator_len = (uint8_t)name_str_len; + + // hfp_cops_info_t *info = bt_os_new(sizeof(hfp_cops_info_t) + operator_len); + // if (memset_s(info, sizeof(hfp_cops_info_t) + operator_len, 0, + // sizeof(hfp_cops_info_t) + operator_len) != EOK) { + // bt_os_free(info); + // return; + // } + // info->mode = (uint8_t)atoi(params[1]); + // info->format = (uint8_t)atoi(params[2]); /* index2 */ + // info->operator_len = operator_len; + // if (memcpy_s(info->operator_name, operator_len, (int8_t *)operator_name, operator_len) != EOK) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"name memcpy error.\n"); + // bt_os_free(info); + // return; + // } + + // errcode_t ret = (errcode_t)hfp_ag_send_network_operator(&bd_addr, info); + // bt_os_free(info); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); +} + +/* */ +static void sample_hfp_ag_cmd_send_indicator_val(const char **params, int32_t params_cnt) +{ + // if (params_cnt != 8) { /* 8个参数 */ + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"params cnt err: %d!\n", params_cnt); + // return; + // } + // bd_addr_t bd_addr; + // if (decode_bd_addr_from_str(params[0], bd_addr.addr, BD_ADDR_LEN) != EXT_ERR_SUCCESS) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"sample hfp ag send indicator val decode addr error!\n"); + // return; + // } + + // g_sample_hfp_cind_info.service = (uint8_t)atoi(params[1]); + // g_sample_hfp_cind_info.call = (uint8_t)atoi(params[2]); /* index:2 */ + // g_sample_hfp_cind_info.callsetup = (uint8_t)atoi(params[3]); /* index:3 */ + // g_sample_hfp_cind_info.callheld = (uint8_t)atoi(params[4]); /* index:4 */ + // g_sample_hfp_cind_info.signal = (uint8_t)atoi(params[5]); /* index:5 */ + // g_sample_hfp_cind_info.roam = (uint8_t)atoi(params[6]); /* index:6 */ + // g_sample_hfp_cind_info.battchg = (uint8_t)atoi(params[7]); /* index:7 */ + + // errcode_t ret = (errcode_t)hfp_ag_send_indicator_val(&bd_addr, &g_sample_hfp_cind_info); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret: %u\n", ret); +} + +/* */ + + +bool headset_Is_connect(void) +{ + int state = hfp_ag_get_device_connect_state(BtAvrcpSrvGetActiveAddr()); + if(state==PROFILE_STATE_CONNECTED) + { + return true; + } + else + { + return false; + } +} + + +bool headset_SCO_Is_connect(void) +{ + int state = hfp_ag_get_sco_connect_state(BtAvrcpSrvGetActiveAddr()); + if(state==PROFILE_STATE_CONNECTED) + { + return true; + } + else + { + return false; + } +} + + + +void cat1_connect_sco_(void) +{ + //AudioActInterrupt(AUDIO_STREAM_VOICE_CALL_VOLTE); + hfp_ag_cmd_conn_sco(BtAvrcpSrvGetActiveAddr()); + +} + + +void cat1_disconn_sco_(void) +{ + //AudioActInterrupt(AUDIO_STREAM_VOICE_CALL_VOLTE); + hfp_ag_cmd_disconn_sco(BtAvrcpSrvGetActiveAddr()); + +} + +void cat1_set_headset_volume( unsigned char volume) +{ + //AudioActInterrupt(AUDIO_STREAM_VOICE_CALL_VOLTE); + hfp_ag_set_volume(BtAvrcpSrvGetActiveAddr(),HFP_VOLUME_SPEAKER,volume); + +} + + +// uint8_t type; /*!< @if Eng The format of the phone number provided, the region of value is 128-175 +// @else 电话号码类型,值范围是128-175 @endif */ +// uint8_t service; /*!< @if Eng Indicates which service this phone number relates to. +// Shall be either 4 (voice) or 5 (fax). See @ref hfp_ag_cnum_service_t +// @else 服务类型,协议支持4或5,见 @ref hfp_ag_cnum_service_t @endif */ +// uint8_t num_len; /*!< @if Eng The length of the phone number @else 电话号码长度 @endif */ +// int8_t number[HFP_AG_PHONENUM_MAX_DIGITS]; /*!< @if Eng Subscriber number, the length shall be 32 +// @else 订阅号码,最大长度是32 @endif */ +// uint8_t name_len; /*!< @if Eng Length of subaddr @else 子地址长度 @endif */ +// int8_t alpha_str[1]; /*!< @if Eng string type subaddress of format specified by +// @else 子地址,协议默认是0 @endif */ + + +int cat1_ag_send_call_event( uint32_t event_topic, const char* info) +{ + //AudioActInterrupt(AUDIO_STREAM_VOICE_CALL_VOLTE); + int ret=0; + + hfp_phone_info_t phone_info={0}; + if(info!=nullptr) + { + phone_info.type=128; + phone_info.service=4; + phone_info.num_len=strlen(info); + memcpy_s(phone_info.number,HFP_AG_PHONENUM_MAX_DIGITS,info,phone_info.num_len); + phone_info.alpha_str[0]=0; + } + + switch (event_topic) + { + case TOPIC_EVENT_CAT1_INCOMMING: + ret=hfp_ag_send_network_incoming_event(BtAvrcpSrvGetActiveAddr(),&phone_info); + break; + case TOPIC_EVENT_CAT1_CALLCONNTED: + ret=hfp_ag_send_answer_call_event(BtAvrcpSrvGetActiveAddr()); + break; + case TOPIC_EVENT_CAT1_CALLENDED: + ret=hfp_ag_send_finish_call_event(BtAvrcpSrvGetActiveAddr(),HFP_AG_CANCELED_LASTCALL); + break; + case TOPIC_EVENT_CAT1_CALLDIAL: + ret=hfp_ag_send_originate_call_event(BtAvrcpSrvGetActiveAddr()); + break; + default: + ret=ERRCODE_BT_FAIL; + break; + } + return ret; +} + + + +// #ifdef __cplusplus +// } +// #endif diff --git a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAudio.cpp b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAudio.cpp index 0812d3f02..dd280d04e 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAudio.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAudio.cpp @@ -19,6 +19,7 @@ #include "cat1_ctl.h" #include "PhoneServiceC.h" + #ifdef __cplusplus extern "C" { #endif @@ -36,7 +37,7 @@ using Audio::AudioInterrupt; static constexpr int32 AUDIO_CHANNEL_1 = 1; static constexpr int32 AUDIO_SAMPLE_RATE_16K = 16000; static constexpr int32 AUDIO_SAMPLE_RATE_8K = 8000; -static constexpr int32 AUDIO_STREAM_MAX_INSTANCE_NUM = 2; +static constexpr int32 AUDIO_STREAM_MAX_INSTANCE_NUM = 4; static constexpr int32 INVALID_AUDIO_VALUE = (-1); class PhoneAudioInterruptListener : public InterruptListener { @@ -532,6 +533,88 @@ int32 PhoneAudioManagerDeactInterrupt(void) WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[%s] line:%d success", __FUNCTION__, __LINE__); return AUDIO_SUCCESS; +} + +void Sample_audio_init(void) +{ + + + g_sessionId = g_amInstance.MakeSessionId(); + if (g_sessionId == AUDIO_SESSION_ID_NONE) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, make session id failed", __FUNCTION__, __LINE__); + return ; + } + + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, session id = %d", __FUNCTION__, __LINE__, g_sessionId); + + g_audioIntListener = std::make_shared(); + if (g_audioIntListener.get() == nullptr) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, g_audioIntListener is null", __FUNCTION__, __LINE__); + return ; + } + g_interrupt = { AUDIO_STREAM_VOICE_CALL_VOLTE, g_sessionId, g_audioIntListener }; + if (g_amInstance.ActivateAudioInterrupt(g_interrupt) == INTERRUPT_FAILED) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, ActivateAudioInterrupt failed", __FUNCTION__, __LINE__); + return ; + } + + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, success", __FUNCTION__, __LINE__); + + g_amInstance.SetDeviceConnectionState(IN_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED); + g_amInstance.SetDeviceConnectionState(OUT_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED); + g_amInstance.SetDeviceConnectionState(IN_MODEM_HEADSET, AUDIO_DEVICE_CONNECTED); + g_amInstance.SetDeviceConnectionState(OUT_MODEM_HEADSET, AUDIO_DEVICE_CONNECTED); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, success", __FUNCTION__, __LINE__); + + g_streamIn[2] = std::make_shared(); + g_streamOut[2] = std::make_shared(); + + g_streamOut[3] = std::make_shared(); + g_streamIn [3]= std::make_shared(); + + /* 初始化通话上行流实例 */ + CapturerInputConfig captureConfig = {}; + captureConfig.audioFormat = mSBC; + captureConfig.channelCount = 1; + captureConfig.linkDir = AUDIO_DOWN_LINK; + captureConfig.sampleRate = 16000; + captureConfig.sessionID = g_sessionId; + captureConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; + + g_streamIn[2]->Init(captureConfig); + g_streamIn[3]->Init(captureConfig); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, success", __FUNCTION__, __LINE__); + + /* 初始化通话上下行流实例 */ + AudioRendererConfig renderConfig = {}; + renderConfig.audioFormat = mSBC; + renderConfig.channelCount = 1; + renderConfig.linkDir = AUDIO_UP_LINK; + renderConfig.sampleRate = 16000; + renderConfig.sessionID = g_sessionId; + renderConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; + + g_streamOut[2]->Init(renderConfig); + g_streamOut[3]->Init(renderConfig); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, success", __FUNCTION__, __LINE__); + + /* 启动通话上行流 */ + g_streamIn[2] ->Start(); + g_streamOut[2]->Play(); + /* 启动通话下行流 */ + g_streamIn[3] ->Start(); + g_streamOut[3]->Play(); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[%s] line:%d, success", __FUNCTION__, __LINE__); + + + + + } #ifdef __cplusplus diff --git a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp index 8e2f5ad59..779fa3c1f 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp @@ -40,6 +40,7 @@ #include "ConfigModelC.h" #include "cat1_ctl.h" #include "UiConfig.h" +#include "PhoneAGService.h" #include "cmath" #ifdef __cplusplus extern "C" { @@ -403,7 +404,7 @@ void cat1_audio_AudioSetup(void) if(stopPhonePlayingMusic()) { BtA2dpSnkAudioDestroy(); - sleep(1);//等待释放音频 + sleep(1);//等待释放音频 } uapi_cat1_start_volte_voice(); usleep(5000);//等待释放音频 @@ -413,7 +414,7 @@ void cat1_audio_AudioSetup(void) void cat1_audio_AudioRelease(void) { uapi_cat1_stop_volte_voice(); - //usleep(5000); + sleep(1);//等待释放音频 } @@ -1823,6 +1824,9 @@ void PhoneServiceInit(void) (void)memset_s(g_bdAddr.addr, BD_ADDR_LEN, 0, BD_ADDR_LEN); CallListInit(); RegisterHfpHfCallbacks(); +//AG 服务注册 + hfp_ag_reg_callback(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[PhoneServiceInit] end"); } @@ -2063,6 +2067,16 @@ void SetSpeakerVolume(unsigned char hfpVolume) WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[SetSpeakerVolume] PhoneAudioSetVolume ret:%d", ret); return; } + + int32_t minVolume = PhoneAudioGetMinVolume(); + int32_t maxVolume = PhoneAudioGetMaxVolume(); + + unsigned char volumeValue = (unsigned char) round(((double) (hfpVolume * CALL_VOLUME_MAX) / (maxVolume - minVolume))); // 音量转换 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[SetSpeakerVolume] minVolume:%d, maxVolume:%d, 蓝牙音量调节映射后volume:%d",minVolume,maxVolume, volumeValue); + + + cat1_set_headset_volume(volumeValue) + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[SetSpeakerVolume] success!"); } else diff --git a/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp b/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp index e89e2dbe8..c2ae26e2e 100755 --- a/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp +++ b/code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp @@ -141,14 +141,15 @@ namespace OHOS if (targetSliceId == VIEW_INCOMING_CALL) { uint16_t id=GetCurSliceId(); - if(id==VIEW_REBOOTANDSHUTDOWN && VIEW_INCOMING_CALL==GettopSliceId()) + if(id==VIEW_REBOOTANDSHUTDOWN && VIEW_INCOMING_CALL==GettopSliceId() ) { ClearSliceIdStack(); } - - if(id!=VIEW_INCOMING_CALL) - make_phone_push(id); + + if(id!=VIEW_INCOMING_CALL && id!=VIEW_BLUETOOTH_EARPHONE) + make_phone_push(id); } + // showsStackSliceId(); /* if (GetCurSliceId() == targetSliceId) { diff --git a/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp b/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp index d5c0eb683..866aa2fff 100644 --- a/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp +++ b/code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp @@ -86,6 +86,7 @@ #include "DialModelDistance.h" #include "DialModelStepgoal.h" #include "msg_center_customerC.h" +#include "PhoneAGService.h" #define DIALDATASET 1 //#include "Systemupgrade.h" @@ -1050,6 +1051,10 @@ void MsgCenterNotifyCatIncomingCallProc(const Topic topic, Request* req) // Prevent this from happening: // When the incoming call view is displayed, the calling number is not set in CallerLogModel. //uapi_hfp_disconnect(); +//来电 + + cat1_ag_send_call_event(TOPIC_EVENT_CAT1_INCOMMING,call_data); + if(NotificationManager::GetInstance()->GetWatchCallStatus() && (CallerLogModel::GetInstance()->GetCallSource()==CallerLogModel::CallSourceCat1)) { @@ -1113,7 +1118,17 @@ void MsgCenterNotifyCat1CallConnectedProc(const Topic topic, Request* req) } AlarmClockModel::GetInstance()->AlarmPlayerStop(); //AlarmViewEventListener::GetInstance()->CancelAlarmRing(); + + if(headset_Is_connect()) + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT_HFP_SCO_CONNECT, nullptr, 0); + } + else + { do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_START, nullptr, 0); +} + cat1_ag_send_call_event(TOPIC_EVENT_CAT1_CALLCONNTED,NULL); + CallerLogModel::GetInstance()->SetCallSource(CallerLogModel::CallSource::CallSourceCat1); @@ -1153,6 +1168,7 @@ void MsgCenterNotifyCat1dialProc(const Topic topic, Request* req) } cat1_call_dial(call_data); +cat1_ag_send_call_event(TOPIC_EVENT_CAT1_CALLDIAL,NULL); CallerLogModel::GetInstance()->SetoperateNumber(call_data,req->len); @@ -1162,9 +1178,14 @@ void MsgCenterNotifyCat1dialProc(const Topic topic, Request* req) cat1_phone_state_change_cb(OPERATE_DIALING); +if(headset_Is_connect()) + { + do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT_HFP_SCO_CONNECT, nullptr, 0); + } + else + { do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_CAT1_AUDIO_START, nullptr, 0); - - + } } free(call_data); @@ -1197,7 +1218,9 @@ void MsgCenterNotifyCat1CallEndedProc(const Topic topic, Request* req) { cat1_call_hungup(); + cat1_phone_state_change_cb(OPERATE_WATCH_FINISH); +cat1_ag_send_call_event(TOPIC_EVENT_CAT1_CALLENDED,NULL); CustomEventPublish(TOPIC_EVENT_CAT1_CALL_FAIL,NULL,0); @@ -1223,11 +1246,14 @@ void MsgCenterNotifyCat1CallEndedProc(const Topic topic, Request* req) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "no OPERATE_WATCH_FINISH"); +cat1_ag_send_call_event(TOPIC_EVENT_CAT1_CALLENDED,NULL); + } else { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OPERATE_WATCH_FINISH"); cat1_phone_state_change_cb(OPERATE_WATCH_FINISH); +cat1_ag_send_call_event(TOPIC_EVENT_CAT1_CALLENDED,NULL); } free(call_data); diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/makephone/headset_3.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/makephone/headset_3.bin new file mode 100644 index 000000000..ccb14bbf8 --- /dev/null +++ b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/makephone/headset_3.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8bc7763c0e9325a91306ce88f3205cd2d0b2e82b053bd981334280faedf552d +size 21624 diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.cpp index 122c805ee..7ed50fe52 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.cpp @@ -83,12 +83,14 @@ int32_t uapi_cat1_start_volte_voice(void) int32_t ret = ERRCODE_FAIL; int32_t argc = 1; uint8_t *argv = (uint8_t *)"start"; - if(cat1_voice!=1) + + if(cat1_voice==0) { ret = VoiceCallVolteSample(argc, (const char **)&argv); if(ret==0) cat1_voice=1; } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret %d %d ",ret, cat1_voice); @@ -96,6 +98,30 @@ int32_t uapi_cat1_start_volte_voice(void) } +int32_t uapi_cat1_start_SCO_volte_voice(void) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"uapi_cat1_start_SCO_volte_voice\n"); + + int32_t ret = ERRCODE_FAIL; + int32_t argc = 1; + uint8_t *argv = (uint8_t *)"startSCO"; + + if(cat1_voice==0) + { + ret = VoiceCallVolteSample(argc, (const char **)&argv); + if(ret==0) + cat1_voice=2; + } + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret %d %d ",ret, cat1_voice); + + return ret; + +} + + + + int32_t uapi_cat1_stop_volte_voice(void) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"uapi_cat1_stop_volte_voice\n"); diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.h b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.h index 083799ac6..ee1bf385c 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.h +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.h @@ -29,6 +29,8 @@ int32_t uapi_cat1_stop_volte_voice(void); uint8_t volte_voice_state(void); +int32_t uapi_cat1_start_SCO_volte_voice(void); + void uapi_cat1_remove_cat1_vote(void); void uapi_cat1_add_cat1_vote(void); void uapi_cat1_wakeup_cat1(uint8_t wakeup); diff --git a/code/sdk/drivers/peripheral/utils/custom_cmd_service.c b/code/sdk/drivers/peripheral/utils/custom_cmd_service.c index 21cf3672f..6fabab38f 100644 --- a/code/sdk/drivers/peripheral/utils/custom_cmd_service.c +++ b/code/sdk/drivers/peripheral/utils/custom_cmd_service.c @@ -322,6 +322,16 @@ static void custom_cmd_service_check_task(void const *arg) case CUSTOM_CMD_MSG_TYPE_AGING_TEST: HandleUpdatelcdMode(4); break; + case CUSTOM_CMD_MSG_CAT_HFP_SCO_CONNECT: + cat1_connect_sco_(); + break; + case CUSTOM_CMD_MSG_CAT_HFP_DIS_SCO_CONNECT: + cat1_disconn_sco_(); + break; + case CUSTOM_CMD_MSG_CAT_HFP_SCO_AUDIO_START: + cat1_start_SCO_audio_(); + break; + default: PRINT("Unknown CUSTOM_CMD_MSG cmd 0x%02X \r\n", mail.cmd); diff --git a/code/sdk/drivers/peripheral/utils/custom_utils.h b/code/sdk/drivers/peripheral/utils/custom_utils.h index 8ef093f0a..9985ef715 100644 --- a/code/sdk/drivers/peripheral/utils/custom_utils.h +++ b/code/sdk/drivers/peripheral/utils/custom_utils.h @@ -252,6 +252,14 @@ uint32_t uapi_calendar_store_date(void); #define CUSTOM_CMD_MSG_TYPE_AGING_TEST 0x16 +// +#define CUSTOM_CMD_MSG_CAT_HFP_SCO_CONNECT 0x17 + +#define CUSTOM_CMD_MSG_CAT_HFP_DIS_SCO_CONNECT 0x18 + +#define CUSTOM_CMD_MSG_CAT_HFP_SCO_AUDIO_START 0x19 + + typedef enum { BR_HFP_CONNECT=1, BR_HFP_DISCONNECT, diff --git a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp index 9c614e7cc..23feaa910 100755 --- a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp +++ b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp @@ -59,11 +59,19 @@ static std::shared_ptr g_stream_out_uplink = nullptr; static std::shared_ptr g_stream_out_downink = nullptr; #endif + +static std::shared_ptr g_stream_in_uplink = nullptr; +static std::shared_ptr g_stream_in_downink = nullptr; +static std::shared_ptr g_stream_out_uplink = nullptr; +static std::shared_ptr g_stream_out_downink = nullptr; + + static int32_t StartVoiceCall(const char **param); static int32_t StopVoiceCall(const char **param); static int32_t VoiceCallSetVolume(const char **param); static int32_t VoiceCAllSeaEnable(const char **param); static int32_t VoiceCallMicMute(const char **param); +static int32_t StartHFPVoiceCall(const char **param); typedef struct { char cmd[MEDIA_CMD_LEN_MAX]; @@ -76,6 +84,7 @@ static FuncsMap g_voiceCallVolteFuncs[] = { { "setvolume", VoiceCallSetVolume }, { "seaenable", VoiceCAllSeaEnable }, { "mute", VoiceCallMicMute }, + { "startSCO",StartHFPVoiceCall} }; class VoiceCallVolteInterruptListener : public InterruptListener { @@ -129,6 +138,23 @@ static void DeinitVoiceCallVolteResources(VoiceCallVolteContext *context) } } + +static void NO_LOCAL_VOICE_CALL_DeinitVoiceCallVolteResources(VoiceCallVolteContext *context) +{ + (void)g_stream_in_uplink.reset(); + (void)g_stream_out_uplink.reset(); + (void)g_stream_in_downink.reset(); + (void)g_stream_out_downink.reset(); + + (void)MediaThreadCondDestroy(&context->cond); + (void)MediaMutexDestroy(&context->mutex); + + if (g_voiceCallVolteContext != nullptr) { + free(g_voiceCallVolteContext); + g_voiceCallVolteContext = nullptr; + } +} + static bool InitVoiceCallVolteResources(VoiceCallVolteContext *context) { context->mutex = MediaMutexCreate(nullptr); @@ -470,6 +496,49 @@ static bool RequsetAudioFocus(VoiceCallVolteContext *context) return true; } +static bool NO_LOCAL_VOICE_CALL_RequsetAudioFocus(VoiceCallVolteContext *context) +{ + bool success; + + success = g_amInstance.Initialize(); + if (!success) { + MEDIA_ERR_LOG("audiomanager init failed"); + return false; + } + + AudioSession sessionId; + + sessionId = g_amInstance.MakeSessionId(); + + if (sessionId == AUDIO_SESSION_ID_NONE) { + MEDIA_ERR_LOG("audio session id invalid"); + return false; + } + + + std::shared_ptr interruptListener = + std::make_shared(context); + if (interruptListener == nullptr || interruptListener.get() == nullptr) { + MEDIA_ERR_LOG("voice call volte interrupt listener is nullptr"); + return false; + } + + AudioInterrupt interrupt = { AUDIO_STREAM_VOICE_CALL_VOLTE, sessionId, interruptListener }; + if (g_amInstance.ActivateAudioInterrupt(interrupt) == INTERRUPT_FAILED) { + MEDIA_ERR_LOG("activate audio interrupt failed"); + return false; + } + + context->sessionId = sessionId; + context->interrupt = interrupt; + + + return true; +} + + + + #ifdef LOCAL_VOICE_CALL static bool ReleaseAudioFocus(void) { @@ -490,6 +559,17 @@ static bool ReleaseAudioFocus(VoiceCallVolteContext *context) } #endif +static bool ReleaseAudioFocus_HFP(VoiceCallVolteContext *context) +{ + if (g_amInstance.DeactivateAudioInterrupt(context->interrupt) != 0) { + MEDIA_ERR_LOG("deactivate audio interrupt failed"); + return false; + } + return true; +} + + + static void *VoiceCallVolteThread(void *priv) { VoiceCallVolteContext *context = (VoiceCallVolteContext *)priv; @@ -646,6 +726,291 @@ int32_t VoiceCallVolteSample(int32_t argc, const char *argv[]) return ret; } + +////////////////////////////////////CAT1蓝牙SCO音频///////////////////////////////////////// + + +static int32_t RunVoiceCallVolte_NO_LOCAL_VOICE_CALL(VoiceCallVolteContext *context) +{ + bool success = InitVoiceCallVolteResources(context); + if (!success) { + MEDIA_ERR_LOG("init voice call volte resources failed"); + return -1; + } + + int32_t ret = g_amInstance.SetDeviceConnectionState(IN_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set sco in device connect failed"); + } + + ret = g_amInstance.SetDeviceConnectionState(OUT_BLUETOOTH_SCO, AUDIO_DEVICE_CONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set sco out device connect failed"); + } + + ret = g_amInstance.SetDeviceConnectionState(IN_MODEM_HEADSET, AUDIO_DEVICE_CONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set modem headset in device connect failed"); + } + + ret = g_amInstance.SetDeviceConnectionState(OUT_MODEM_HEADSET, AUDIO_DEVICE_CONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set modem headset out device connect failed"); + } + + g_stream_in_uplink = std::make_shared(); + + CapturerInputConfig captureConfig = {}; + captureConfig.audioFormat = mSBC; + captureConfig.channelCount = 1; + captureConfig.linkDir = AUDIO_UP_LINK; + captureConfig.sampleRate = 16000; + captureConfig.sessionID = context->sessionId; + captureConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; + + ret = g_stream_in_uplink->Init(captureConfig); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in uplink init failed"); + } + + g_stream_out_uplink = std::make_shared(); + // 16000 32000 44100 48000 + AudioRendererConfig renderConfig = {}; + renderConfig.audioFormat = mSBC; + renderConfig.channelCount = 1; + renderConfig.linkDir = AUDIO_UP_LINK; + renderConfig.sampleRate = 16000; + renderConfig.sessionID = context->sessionId; + renderConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; + + ret = g_stream_out_uplink->Init(renderConfig); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out uplink init failed"); + } + + //下行 + g_stream_in_downink = std::make_shared(); + + captureConfig.audioFormat = mSBC; + captureConfig.channelCount = 1; + captureConfig.linkDir = AUDIO_DOWN_LINK; + captureConfig.sampleRate = 16000; + captureConfig.sessionID = context->sessionId; + captureConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; + + ret = g_stream_in_downink->Init(captureConfig); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in downink init failed"); + } + + g_stream_out_downink = std::make_shared(); + + renderConfig.audioFormat = mSBC; + renderConfig.channelCount = 1; + renderConfig.linkDir = AUDIO_DOWN_LINK; + renderConfig.sampleRate = 16000; + renderConfig.sessionID = context->sessionId; + renderConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; + + ret = g_stream_out_downink->Init(renderConfig); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out downink init failed"); + } + + ret = g_stream_in_uplink->Start(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in uplink start failed"); + } + + ret = g_stream_out_uplink->Play(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out uplink play failed"); + } + + ret = g_stream_in_downink->Start(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in downink start failed"); + } + + ret = g_stream_out_downink->Play(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out downink play failed"); + } + + uint32_t asoUplinkChannelId = 0; + g_stream_out_uplink->GetCurrentChannelId(asoUplinkChannelId); + + MEDIA_INFO_LOG("asoUplinkChannelId: 0x%x", asoUplinkChannelId); + + g_stream_in_uplink->AttachBackend(asoUplinkChannelId); + + uint32_t asiDownlinkChannelId = 0; + g_stream_in_downink->GetCurrentChannelId(asiDownlinkChannelId); + + MEDIA_INFO_LOG("asiDownlinkChannelId: 0x%x", asiDownlinkChannelId); + + g_stream_out_downink->AttachFrontend(asiDownlinkChannelId); + + + MediaMutexLock(context->mutex); + while (!context->isVoiceCallVolteStopped) { + MediaThreadCondWait(context->cond, context->mutex); + } + MediaMutexUnLock(context->mutex); + + + ret = g_stream_in_uplink->Stop(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in uplink stop failed"); + } + + ret = g_stream_out_uplink->Stop(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out uplink stop failed"); + } + + ret = g_stream_in_downink->Stop(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in downink stop failed"); + } + + ret = g_stream_out_downink->Stop(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out downink stop failed"); + } + + ret = g_stream_in_uplink->Release(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in uplink release failed"); + } + + ret = g_stream_out_uplink->Release(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out uplink release failed"); + } + + ret = g_stream_in_downink->Release(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream in downink release failed"); + } + + ret = g_stream_out_downink->Release(); + if (ret != 0) { + MEDIA_ERR_LOG("audio stream out downink release failed"); + } + + ret = g_amInstance.SetDeviceConnectionState(IN_BLUETOOTH_SCO, AUDIO_DEVICE_DISCONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set sco in device disconnect failed"); + } + + ret = g_amInstance.SetDeviceConnectionState(OUT_BLUETOOTH_SCO, AUDIO_DEVICE_DISCONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set sco out device disconnect failed"); + } + + ret = g_amInstance.SetDeviceConnectionState(IN_MODEM_HEADSET, AUDIO_DEVICE_DISCONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set modem headset in device disconnect failed"); + } + + ret = g_amInstance.SetDeviceConnectionState(OUT_MODEM_HEADSET, AUDIO_DEVICE_DISCONNECTED); + if (ret != 0) { + MEDIA_ERR_LOG("set modem headset out device disconnect failed"); + } + + + NO_LOCAL_VOICE_CALL_DeinitVoiceCallVolteResources(context); + + return 0; +} + + + +static void *VoiceCallVolteHFPThread(void *priv) +{ + VoiceCallVolteContext *context = (VoiceCallVolteContext *)priv; + + bool success = NO_LOCAL_VOICE_CALL_RequsetAudioFocus(context); + if (!success) { + MEDIA_ERR_LOG("requset audio focus failed"); + return nullptr; + } + + int32_t ret = RunVoiceCallVolte_NO_LOCAL_VOICE_CALL(context); + if (ret != 0) { + MEDIA_ERR_LOG("run voice call volte failed"); + + (void)ReleaseAudioFocus_HFP(context); + // (void)ReleaseAudioFocus(); + return nullptr; + } + + success = ReleaseAudioFocus_HFP(context); + // success = ReleaseAudioFocus(); + if (!success) { + MEDIA_ERR_LOG("release audio focus failed"); + return nullptr; + } + printf("VoiceCallVolteHFPThread END"); + return nullptr; +} + + + +static int32_t StartHFPVoiceCall(const char **param) +{ + MediaMutexLock(g_voiceCallVolteContextMutex); + if (g_voiceCallVolteContext != nullptr) { + MEDIA_ERR_LOG("invalid operation"); + return -1; + } + + // 1. create VoiceCallVolteContext + g_voiceCallVolteContext = (VoiceCallVolteContext *)malloc(sizeof(VoiceCallVolteContext)); + if (g_voiceCallVolteContext == nullptr) { + MEDIA_ERR_LOG("malloc failed"); + MediaMutexUnLock(g_voiceCallVolteContextMutex); + return -1; + } + if (memset_s(g_voiceCallVolteContext, sizeof(VoiceCallVolteContext), 0, sizeof(VoiceCallVolteContext)) != EOK) { + MEDIA_ERR_LOG("memset_s failed"); + } + MediaMutexUnLock(g_voiceCallVolteContextMutex); + + // 3. create voice call volte thread + MediaThreadattr attr = { "VoiceCallVolteThread", 0x2000, THREAD_SCHED_INVALID, 0, true }; + MediaThreadIdHandle taskHandle = MediaThreadCreate(VoiceCallVolteHFPThread, g_voiceCallVolteContext, &attr); + if (taskHandle == nullptr) { + MEDIA_ERR_LOG("create voice call volte thread failed"); + free(g_voiceCallVolteContext); + g_voiceCallVolteContext = nullptr; + return -1; + } + + // will free g_voiceCallVolteContext when sub thread play exit + return 0; +} + + + + + + + + + + + + + + + + + + + + #ifdef __cplusplus }; #endif -- 2.17.1