cat 电话增加耳机音频选项(暂不要通过) 1508/2
authorhcj <1224667075@qq.com>
Tue, 10 Dec 2024 02:47:34 +0000 (10:47 +0800)
committerhcj <1224667075@qq.com>
Tue, 10 Dec 2024 02:47:34 +0000 (10:47 +0800)
26 files changed:
code/sdk/application/wearable/fd230app/CMakeLists.txt
code/sdk/application/wearable/fd230app/nativelauncher/include/UiConfig.h
code/sdk/application/wearable/fd230app/nativeui/bluetooth/include/BluetoothHeadsetEvent.h
code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothHeadsetEvent.cpp
code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp
code/sdk/application/wearable/fd230app/nativeui/callerlog/include/CallerLogModel.h
code/sdk/application/wearable/fd230app/nativeui/callerlog/src/CallerLogModel.cpp
code/sdk/application/wearable/fd230app/nativeui/makephone/include/CallingView.h
code/sdk/application/wearable/fd230app/nativeui/makephone/include/MainCallingView.h
code/sdk/application/wearable/fd230app/nativeui/makephone/src/CallingView.cpp
code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/makephone/src/MainCallingView.cpp
code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAGService.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneAudio.h
code/sdk/application/wearable/fd230app/nativeui/phoneservice/include/PhoneServiceC.h
code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAGService.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneAudio.cpp
code/sdk/application/wearable/fd230app/nativeui/phoneservice/src/PhoneService.cpp
code/sdk/application/wearable/nativeabilityfwk/src/Ability.cpp
code/sdk/application/wearable/service/msg_center/src/msg_center_customer.cpp
code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/res/makephone/headset_3.bin [new file with mode: 0644]
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.cpp
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ctl.h
code/sdk/drivers/peripheral/utils/custom_cmd_service.c
code/sdk/drivers/peripheral/utils/custom_utils.h
code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp

index 6dd2c4d..a433804 100644 (file)
@@ -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
index a589f69..6bcbd0a 100644 (file)
@@ -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";
index 3f5709c..4334047 100644 (file)
@@ -31,6 +31,10 @@ typedef struct {
     profile_connect_state_t avrcp_srv_conn_stat;\r
 } BtAvrcpTgInf;\r
 \r
+extern BtAvrcpTgInf g_avrcp_srv_inf;\r
+\r
+bd_addr_t *BtAvrcpSrvGetActiveAddr(void);\r
+\r
 void UsingPressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue);\r
 void MediaStatusCallback(bt_avrcp_tg_evt_status_param *eventStatusParam);\r
 void PressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue);\r
index fa26ec8..963b644 100644 (file)
@@ -228,11 +228,13 @@ void ConnCtStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t
     g_avrcp_srv_inf.avrcp_srv_conn_stat = state;\r
 }\r
 \r
-static bd_addr_t *BtAvrcpSrvGetActiveAddr(void)\r
+bd_addr_t *BtAvrcpSrvGetActiveAddr(void)\r
 {\r
     return &g_avrcp_srv_inf.bd_addr;\r
 }\r
 \r
+\r
+\r
 void ConnectTgStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t state)\r
 {\r
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "avrcp tg update conn stat:%u", state);\r
index 6cb7f13..999f9bd 100644 (file)
@@ -52,6 +52,7 @@
 #include "uiservice/include/ui_service.h"\r
 #include "vibrator_service.h"\r
 #include "ConfigModel.h"\r
+#include "PhoneAGService.h"\r
 namespace OHOS {\r
 \r
 #define BT_SPP_TASK_STACK_SIZE 2048\r
@@ -1073,9 +1074,18 @@ void BluetoothModel::BtGapAclStateChangedHandle(gap_acl_state_t state, unsigned
                 ACLConnectionFail(bdAddr);\r
             }\r
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "a2dp_src_connect result 0x%x", retA2dp);\r
+errcode_t rethfp= hfp_ag_cmd_conn_hfp(&bdAddr);\r
+            if(rethfp)\r
+            {\r
+                 ACLConnectionFail(bdAddr);\r
+            }\r
+\r
+\r
         } else {\r
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ingore a2dp_src_connect");\r
         }\r
+\r
+\r
     }\r
 }\r
 static uint8_t ALC_State_flag=0;\r
index 2bef3f1..da02f92 100644 (file)
@@ -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));
+}
 
 
 /* 开启定时器 */
index 378b519..81579ba 100644 (file)
@@ -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};
index d870120..2817f51 100644 (file)
@@ -37,7 +37,7 @@ public:
     CallingView *GetScreenView();
 
     void updataCallingname(void);
-
+    void update_headset_state(uint8_t data);
 private:
     bool InitPointerValue();
     UIViewGroup *displayGroup{nullptr};
index 165b6bb..22c0402 100644 (file)
@@ -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;
index ff59e61..3fa35b0 100644 (file)
@@ -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;
index 6c4f2fd..339e08d 100644 (file)
@@ -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 (file)
index 0000000..8ced3ea
--- /dev/null
@@ -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 <stdint.h>
+
+#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 */
index 3c456f9..25f1896 100644 (file)
@@ -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 (file)
index 0000000..a5b6008
--- /dev/null
@@ -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 <soc_osal.h>
+#include <td_base.h>
+#include <stdlib.h>
+#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);
+}
+
+/* <addr> */
+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;
+}
+
+/* <addr> */
+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;
+}
+
+/* <addr> */
+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]);
+}
+
+/* <addr> */
+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);
+}
+
+/* <addr> */
+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);
+}
+
+/* <addr> */
+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);
+}
+
+/* <addr> */
+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);
+}
+
+/* <addr> <type> */
+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);
+}
+
+/* <addr> <volume_type> <volume> */
+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);
+}
+
+/* <addr> <event> <param> */
+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);
+}
+
+/* <addr> <type> <service> <number> <alpha_str> */
+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);
+}
+
+/* <addr> <idx> <dir> <status> <mode> <mpty> <type> <number> <is_last> */
+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);
+}
+
+/* <addr> <type> <service> <number> <alpha_str> <is_last> */
+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);
+}
+
+/* <addr> <value> */
+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);
+}
+
+/* <addr> <error_code> */
+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);
+}
+
+/* <addr> <mode> <format> <operator_name> */
+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);
+}
+
+/* <addr> <service> <call> <callsetup> <callheld> <signal> <roam> <battchg> */
+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);
+}
+
+/* <addr> */
+
+
+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 <cli_validity>
+//                                                 @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
index 0812d3f..dd280d0 100644 (file)
@@ -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<PhoneAudioInterruptListener>();
+    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<AudioStreamIn>(); 
+    g_streamOut[2] = std::make_shared<AudioStreamOut>();
+
+    g_streamOut[3] = std::make_shared<AudioStreamOut>(); 
+    g_streamIn [3]= std::make_shared<AudioStreamIn>(); 
+    
+    /* 初始化通话上行流实例 */ 
+    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
index 8e2f5ad..779fa3c 100644 (file)
@@ -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
index e89e2db..c2ae26e 100755 (executable)
@@ -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) {
index d5c0eb6..866aa2f 100644 (file)
@@ -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 (file)
index 0000000..ccb14bb
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c8bc7763c0e9325a91306ce88f3205cd2d0b2e82b053bd981334280faedf552d
+size 21624
index 122c805..7ed50fe 100644 (file)
@@ -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");
index 083799a..ee1bf38 100644 (file)
@@ -29,6 +29,8 @@ int32_t uapi_cat1_stop_volte_voice(void);
 \r
 uint8_t volte_voice_state(void);\r
 \r
+int32_t uapi_cat1_start_SCO_volte_voice(void);\r
+\r
 void uapi_cat1_remove_cat1_vote(void);\r
 void uapi_cat1_add_cat1_vote(void);\r
 void uapi_cat1_wakeup_cat1(uint8_t wakeup);\r
index 21cf367..6fabab3 100644 (file)
@@ -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);
index 8ef093f..9985ef7 100644 (file)
@@ -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,
index 9c614e7..23feaa9 100755 (executable)
@@ -59,11 +59,19 @@ static std::shared_ptr<AudioStreamOut> g_stream_out_uplink = nullptr;
 static std::shared_ptr<AudioStreamOut> g_stream_out_downink = nullptr;
 #endif
 
+
+static std::shared_ptr<AudioStreamIn> g_stream_in_uplink = nullptr;
+static std::shared_ptr<AudioStreamIn> g_stream_in_downink = nullptr;
+static std::shared_ptr<AudioStreamOut> g_stream_out_uplink = nullptr;
+static std::shared_ptr<AudioStreamOut> 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<VoiceCallVolteInterruptListener> interruptListener =
+        std::make_shared<VoiceCallVolteInterruptListener>(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<AudioStreamIn>();
+
+    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<AudioStreamOut>();
+    // 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<AudioStreamIn>();
+
+    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<AudioStreamOut>();
+
+    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