[Feature]Upload Modem source code

Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/audio/src/v1/sp_ps.c b/mcu/driver/audio/src/v1/sp_ps.c
new file mode 100644
index 0000000..1227614
--- /dev/null
+++ b/mcu/driver/audio/src/v1/sp_ps.c
@@ -0,0 +1,1641 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ *
+ * Filename:
+ * ---------
+ * sp_ps.c
+ *
+ * Project:
+ * --------
+ *   UMOLYE
+ *
+ * Description:
+ * ------------
+ *   Packet-switching speech interface
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ 
+ *******************************************************************************/
+
+#include "kal_public_api.h"
+#include "kal_general_types.h"
+#include "string.h"
+#include "kal_trace.h"
+#include "reg_base.h"
+#include "sync_data.h"
+
+#include "audio_dsp_d2c_def.h"
+#include "l1aud_common_def.h"
+#include "l1audio.h"
+#include "am.h"
+#include "l1audio_trace_utmd.h"
+#include "media.h" 
+#include "l1sp_trc.h"
+#include "amr_table.h"
+#include "sal_exp.h"
+#include "sal_def.h"
+#include "dcl.h"
+#include "drv_sap.h"
+#include "ltecsr_msgid.h"
+#include "audio_msgid.h"
+#include "sp_drv.h"
+
+#include "sp_ps.h"
+#include "sp_ps_aam.h"
+
+#include "sp_ps_codec_amr.h"
+#if defined(__EVS_CODEC_SUPPORT__)
+#include "sp_ps_codec_evs.h"
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+//#if defined(__G_CODEC_SUPPORT__)
+#include "sp_ps_codec_g.h"
+//#endif //#if defined(__G_CODEC_SUPPORT__)
+
+#include "sp_ps_dsp_opt.h"
+#include "sp_ps_aamp.h"
+
+//for query OP
+#include "ps_public_utility.h"
+
+//AAM related
+#include "l1sp_el2_struct.h"
+#include "el2_msgid.h"
+//#ifndef TK6291_FAKE_COMPILE
+//#include "uas_export_api.h"
+//#include "csr_export_api.h"
+//#endif //#ifndef TK6291_FAKE_COMPILE
+
+
+/*****************************
+Definitions
+*****************************/
+
+
+/*****************************
+External variables
+*****************************/
+extern kal_enhmutexid sp_handover_mutex;//sp_4g.c
+
+
+/*****************************
+External functions
+*****************************/
+extern void CSR_Codec_Close(int rab_id);
+extern void CSR_Codec_Ready(int rab_id);
+extern kal_uint32 SP3G_Rab_Id( void );
+extern uint32 L1I_GetTimeStamp( void );
+extern void sp4g_vmRecordService( uint32 *l1_info, uint16 crc_result, uint16 buf_status, uint16 *ul_frame_data, uint16* dl_frame_data, kal_bool bBufferOK);
+volatile uint16* SAL_PcmEx_Get4GULBuf(int *len);
+extern kal_uint32 get_is_fake_4g(void);
+
+
+/*****************************
+Local variables
+*****************************/
+static kal_uint8  spPS_reset_flag; // speech on and InterRAT : set TRUE
+static kal_bool   spPS_dtx_mode;
+static int		  spPS_fake_EVS_IO;
+static uint8	  spPS_est_codec_mode;	 
+static kal_uint32 spPS_rab_id;
+static kal_uint32 spPS_rab_id_record[SPPS_RAB_ID_MAX]; //valid element: 1~(SPPS_RAB_ID_MAX-1)
+static kal_bool   spPS_rab_state;
+static SP_PS_RADIO_TYPE spPS_RadioType;
+
+static kal_uint8 encodebits_null[32];
+static kal_uint8 bitlen_null;
+
+VoLTE_JBM_TS_Info_t JBM_info_local;
+
+SPPS_Struct_t *spPS;
+SPPS_Struct_t stSPPS;
+kal_spinlockid spinlock_sp4g;
+
+SP4G_PSR_CallType sp4g_PSR_CallType = SP4G_PSR_CallType_None;
+
+/*****************************
+Local functions
+*****************************/
+
+void SP4G_PSR_SetCallType(SP4G_PSR_CallType type){ 
+	sp4g_PSR_CallType = type;
+}
+SP4G_PSR_CallType SP4G_PSR_GetCallType(void){ 
+	return(sp4g_PSR_CallType);
+}
+
+void spPS_RadioType_set(SP_PS_RADIO_TYPE radio_type)
+{
+   spPS_RadioType = radio_type;
+}
+
+
+SP_PS_RADIO_TYPE spPS_RadioType_get(void)
+{
+   return(spPS_RadioType);
+}
+
+
+void spPS_reset_flag_set(kal_uint8 val)
+{
+   spPS_reset_flag = val;
+}
+
+
+kal_uint8 spPS_reset_flag_get(void)
+{
+   return(spPS_reset_flag);
+}
+
+
+bool is_g_codec(uint8 codec)
+{
+   return( sp_ps_codec_g_is_g_codec(codec) );
+}
+
+
+bool is_EVS_codec(uint8 codec)
+{
+   return( sp_ps_codec_evs_is_EVS_codec(codec) );
+}
+
+
+int UseEVSIO2ReplaceAWB(void)
+{
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   int ret  = (int)L1Audio_GetDebugInfo(SPH_DEBUGINFO);
+
+   ret = ret & SPH_DEBUGINFO12_BIT0;
+   if(ret == 0x00)
+      return(1);
+   else
+      return(0);
+#else //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   return(0);
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+}
+
+
+void PSR_SP4G_Callback( SP4G_Event event, void *data ){
+   if(get_is_fake_4g() == 0)
+   {
+      if(SP4G_UL_DATA_NOTIFY == event){
+         msg_send4(	MOD_L1SP, 				/* source module id */
+                    MOD_LTECSR, 				/* destination module id */
+                    L1SP_LTECSR_SAP,			/* sap id */
+                    MSG_ID_LTECSR_VOICE_UL_DATA_NOTIFY	/* message id */
+                  );
+      }else if(SP4G_UL_MUTE_NOTIFY == event){
+         msg_send4(	MOD_L1SP, 				/* source module id */
+                    MOD_LTECSR, 				/* destination module id */
+                    L1SP_LTECSR_SAP,			/* sap id */
+                    MSG_ID_LTECSR_VOICE_UL_MUTE_NOTIFY	/* message id */
+                  );
+      }else if(SP4G_DL_DATA_NOTIFY == event){
+#if 1      	
+         ilm_SP4G_PSR_DL_INFO_t *local_para;			   
+		     local_para = (ilm_SP4G_PSR_DL_INFO_t *) construct_local_para( sizeof(ilm_SP4G_PSR_DL_INFO_t), TD_CTRL );
+         local_para->JBM_info.TS_Switch			     = (kal_uint8)SAL_4G_GetTSSwitch();
+         local_para->JBM_info.TS_Remain_Length_ms = (kal_int16)SAL_Get_RingBuf_RemainLen();
+         local_para->JBM_info.TS_Total_Length_ms  = (kal_int16)SAL_Get_RingBuf_TotalLen();
+         msg_send6(MOD_L1SP, MOD_LTECSR, L1SP_LTECSR_SAP, MSG_ID_LTECSR_VOICE_DL_DATA_NOTIFY, (local_para_struct *)local_para, NULL);      	  	
+
+#endif                  
+      }
+      else if(SP4G_DL_MUTE_NOTIFY == event){
+#if 1      	
+         msg_send4(	MOD_L1SP, 				/* source module id */
+                    MOD_LTECSR, 				/* destination module id */
+                    L1SP_LTECSR_SAP,			/* sap id */
+                    MSG_ID_LTECSR_VOICE_DL_MUTE_NOTIFY	/* message id */
+                  );
+#endif                  
+      }
+   }
+   else
+   {
+      if(SP4G_UL_DATA_NOTIFY == event){
+         msg_send4(	MOD_L1SP, 				/* source module id */
+                    MOD_MED, 				/* destination module id */
+                    L1SP_LTECSR_SAP,			/* sap id */
+                    MSG_ID_LTECSR_VOICE_UL_DATA_NOTIFY	/* message id */
+                  );
+      }else if(SP4G_UL_MUTE_NOTIFY == event){
+         msg_send4(	MOD_L1SP, 				/* source module id */
+                    MOD_MED, 				/* destination module id */
+                    L1SP_LTECSR_SAP,			/* sap id */
+                    MSG_ID_LTECSR_VOICE_UL_MUTE_NOTIFY	/* message id */
+                  );
+      }else if(SP4G_DL_DATA_NOTIFY == event){
+         msg_send4(	MOD_L1SP, 				/* source module id */
+                    MOD_MED, 				/* destination module id */
+                    L1SP_LTECSR_SAP,			/* sap id */
+                    MSG_ID_LTECSR_VOICE_DL_DATA_NOTIFY	/* message id */
+                  );
+      }
+      else if(SP4G_DL_MUTE_NOTIFY == event){
+         msg_send4(	MOD_L1SP, 				/* source module id */
+                    MOD_MED, 				/* destination module id */
+                    L1SP_LTECSR_SAP,			/* sap id */
+                    MSG_ID_LTECSR_VOICE_DL_MUTE_NOTIFY	/* message id */
+                  );
+      }
+   }
+}
+
+
+int get_spps_fake_EVS_IO(void)
+{
+   return spPS_fake_EVS_IO;
+}
+
+
+int get_sp4g_fake_EVS_IO(void)
+{
+   return( get_spps_fake_EVS_IO() );
+}
+
+
+kal_int32 SP4G_PSR_getToneDeteResult(void)
+{
+#ifdef __SP_4G_OPT_TONE_DETECTION_EXECUTED_IN_DSP__
+   return( (kal_int32)SAL_Get_DuDuPtnFlag() );
+#else // __SP_4G_OPT_TONE_DETECTION_EXECUTED_IN_DSP__
+#if defined(__SP_4G_OPT_TONE_DETECTION__)
+   return( sp_ps_dsp_opt_ToneDeteGetResult() );
+#else //#if defined(__SP_4G_OPT_TONE_DETECTION__)
+   return( 0 );
+#endif //#if defined(__SP_4G_OPT_TONE_DETECTION__)
+#endif // __SP_4G_OPT_TONE_DETECTION_EXECUTED_IN_DSP__
+}
+
+
+kal_int32 SP4G_PSR_getEarPhone(void)
+{
+   if( SPH_EXTDEVINFO_EARPHONE == SP_GetExtDevInfo() ) {
+      return( 1 );
+   }
+   else {
+      return( 0 );
+   }
+}
+
+
+kal_uint32 SP4G_GetGCodecMode(void)
+{
+   return spPS->ul_codec_mode;
+
+}
+
+
+kal_bool   SP4G_IsGCodecMode()
+{
+   return sp_ps_codec_g_is_g_codec(spPS->ul_codec_mode);
+}
+
+
+kal_bool   SP4G_IsEVSCodecMode()
+{
+   return sp_ps_codec_evs_is_EVS_codec(spPS->ul_codec_mode);
+}
+
+
+kal_uint32 SP4G_GetCodecMode(void)
+{
+   if(spPS != NULL)
+       return spPS->ul_codec_mode;
+   else
+       return INIT_CODEC;
+}
+
+
+void sp_ps_link_est( uint32 rab_id, kal_uint8 default_speech_codec )
+{
+   kal_uint8 old_ul_codec_mode = spPS->ul_codec_mode;
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   kal_bool retval;
+   kal_uint8 new_SP4G_Codec;
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+
+   spPS_rab_id    = rab_id;
+   spPS_rab_state = KAL_TRUE;
+
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   if( UseEVSIO2ReplaceAWB() )
+   {
+      MD_TRC_SPPS_RAB_EST_USE_EVS_IO_REPLACE_AWB_IN(default_speech_codec, default_speech_codec);
+      retval = convert_AWB_to_EVSIOEnum( (SP4G_Codec)default_speech_codec, (SP4G_Codec*)&new_SP4G_Codec );
+      if(retval == KAL_TRUE) {
+         spPS_fake_EVS_IO = 1;
+      }
+      else {
+         spPS_fake_EVS_IO = 0;
+      }
+      default_speech_codec = new_SP4G_Codec;
+      MD_TRC_SPPS_RAB_EST_USE_EVS_IO_REPLACE_AWB_OUT(default_speech_codec, default_speech_codec);
+   }
+   else
+   {
+      spPS_fake_EVS_IO = 0;
+   }
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+
+   spPS_est_codec_mode = default_speech_codec;
+   if( (sp_ps_codec_g_is_g_codec(spPS_est_codec_mode) == false) && (sp_ps_codec_evs_is_EVS_codec(spPS_est_codec_mode) == false) )
+   {
+      spPS_est_codec_mode = sp_ps_codec_amr_Get_AmrFrameType2DspMode_spps(spPS_est_codec_mode);//GetFrameType2DspMode(spPS_est_codec_mode);
+   }
+   if(spPS != (SPPS_Struct_t *)NULL)
+   {
+      kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+      spPS->ul_codec_mode = spPS_est_codec_mode;//default_speech_codec;
+      kal_give_spinlock(spinlock_sp4g);
+   }
+   MD_TRC_SPPS_RAB_EST1(default_speech_codec, default_speech_codec, spPS_est_codec_mode);
+   MD_TRC_SPPS_RAB_EST2(rab_id, default_speech_codec, default_speech_codec/*spPS_est_codec_mode*/); /* Notice!! Due to the procedure of PSR, SP4G_Rab_Est must follow SetULFrameType so that spPS_est_codec_mode has been set properly*/
+#if defined(__C2K_SPEECH_SUPPORT__)
+   if( L1SP_GetState() == L1SP_STATE_C2K_SPEECH_ON ){//
+      //C2K_Codec_Close(SP3G_Rab_Id());
+      PSR_SP4G_Callback(SP4G_CODEC_READY, (void*)0 );
+      SP4G_Reset();
+      AM_InterRAT_C2K_to_4G(SP4G_GetCodecMode());
+      L1SP_SetState( L1SP_STATE_4G_SPEECH_ON );
+   }else
+#endif   
+   if( L1SP_GetState() == L1SP_STATE_3G_SPEECH_ON ){//
+      CSR_Codec_Close(SP3G_Rab_Id());
+      PSR_SP4G_Callback(SP4G_CODEC_READY, (void*)0 );
+      SP4G_Reset();
+
+      AM_InterRAT_3G_to_4G(SP4G_GetCodecMode());
+
+      //fix me , depend on codec
+
+      L1SP_SetState( L1SP_STATE_4G_SPEECH_ON );
+   }else
+   if( L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON ){//prepare InterRAT HO      
+      PSR_SP4G_Callback(SP4G_CODEC_READY, (void*)0 );
+      SP4G_Reset();
+      AM_InterRAT_2G_to_4G(SP4G_GetCodecMode());
+
+      //fix me , depend on codec
+
+      L1SP_SetState( L1SP_STATE_4G_SPEECH_ON );
+   }else
+   if( L1SP_GetState() == L1SP_STATE_4G_SPEECH_ON ){//prepare InterRAT HO      
+      uint32 resetType = PS_SRST_TYPE_HO_WITHOUT_VBIEND;
+      PSR_SP4G_Callback(SP4G_CODEC_READY, (void*)0 );
+      SP4G_Reset();
+      if( (sp_ps_codec_g_is_g_codec(old_ul_codec_mode) == true) || (sp_ps_codec_g_is_g_codec(default_speech_codec) == true) )
+      {
+         resetType = PS_SRST_TYPE_HO_WITH_VBIEND;
+      }
+      AM_4G_INTRARAT(SP4G_GetCodecMode(), resetType);
+
+      //fix me , depend on codec
+
+      L1SP_SetState( L1SP_STATE_4G_SPEECH_ON );
+   }
+}
+
+
+//CSR inform RAB is established, the rab_id should be set as parameter when callback to CSR
+kal_uint32 SPPS_PSR_Link_Est(SP4G_Codec default_speech_codec, SP_PS_RADIO_TYPE radio_type) // function call 
+{
+   kal_int32 i;
+   kal_uint8 speech_codec_local = (kal_uint8)default_speech_codec;
+   //spPS_rab_id++;
+   //if(spPS_rab_id > 5)//just want to get unique id without any extra purpose
+   //   spPS_rab_id = 0;
+
+   spPS_rab_id = 0;
+   for(i=1; i<SPPS_RAB_ID_MAX; i++)
+   {
+      if(spPS_rab_id_record[i] == 0)
+      {
+         spPS_rab_id = i;
+         spPS_rab_id_record[i] = 1;
+         break;
+      }
+   }
+   ASSERT(spPS_rab_id > 0);
+
+   kal_take_enh_mutex( sp_handover_mutex ); 
+   //AM_SetBlockMED( SAL_APP_TYPE_4GCall, true,  4);  
+   
+   SAL_Set_LinkStatus(SAL_LINKSTATUS_4G  , true);
+   spPS_RadioType = radio_type;
+   sp_ps_link_est( spPS_rab_id, speech_codec_local );
+
+   //AM_SetBlockMED( SAL_APP_TYPE_4GCall, false,  4);
+   kal_give_enh_mutex( sp_handover_mutex );
+
+   MD_TRC_SPPS_PSR_LINK_EST(spPS_rab_id);
+   return spPS_rab_id;
+}
+
+
+//CSR inform RAB is established, the rab_id should be set as parameter when callback to CSR
+kal_uint32 SP4G_PSR_Link_Est( SP4G_Codec default_speech_codec ) // function call 
+{
+   return( SPPS_PSR_Link_Est(default_speech_codec, SP_PS_RADIO_TYPE_LTE) );
+}
+
+
+void SP4G_PSR_Link_Deest(kal_uint32 id) // function call 
+{
+   kal_int32 i;
+   kal_uint32 spPS_rab_id_total;
+   MD_TRC_SPPS_RAB_DEEST(id);
+   //ASSERT(id == spPS_rab_id);
+   ASSERT(spPS_rab_id_record[id] == 1);
+
+   spPS_rab_id_record[id] = 0;
+   spPS_rab_id_total = 0;
+   for(i=1; i<SPPS_RAB_ID_MAX; i++)
+   {
+      spPS_rab_id_total |= spPS_rab_id_record[i];
+   }
+   if(spPS_rab_id_total == 0)
+   {
+      spPS_rab_state      = KAL_FALSE;
+      spPS_est_codec_mode = INIT_CODEC;
+      spPS_RadioType      = SP_PS_RADIO_TYPE_UNKNOWN;
+   }
+
+   MD_TRC_SPPS_PSR_LINK_DEEST(spPS_rab_state);
+   
+   SAL_Set_LinkStatus(SAL_LINKSTATUS_4G  , false);
+   kal_take_enh_mutex( sp_handover_mutex );
+#if defined(__C2K_SPEECH_SUPPORT__)
+   if( L1SP_isC2KSO_Connected() && L1SP_GetState() != L1SP_STATE_C2K_SPEECH_ON && L1SP_GetState() != L1SP_STATE_IDLE ){//4G->C2K 
+      PSR_SP4G_Callback(SP4G_CODEC_CLOSED, (void*)0 );  
+      AM_InterRAT_4G_to_C2K(L1SP_GetC2KSO_Codec());
+      L1SP_SetState( L1SP_STATE_C2K_SPEECH_ON );
+   }else
+#endif   
+   if( SP3G_Rab_State() && L1SP_GetState() != L1SP_STATE_3G_SPEECH_ON && L1SP_GetState() != L1SP_STATE_IDLE ){//4G->3G 
+      PSR_SP4G_Callback(SP4G_CODEC_CLOSED, (void*)0 );  
+      CSR_Codec_Ready(SP3G_Rab_Id());
+      AM_InterRAT_4G_to_3G(SP3G_GetCodecMode());
+      L1SP_SetState( L1SP_STATE_3G_SPEECH_ON );
+   }else
+   if( L1SP_TCH_State() && L1SP_GetState() != L1SP_STATE_2G_SPEECH_ON && L1SP_GetState() != L1SP_STATE_IDLE ){//4G->2G
+      PSR_SP4G_Callback(SP4G_CODEC_CLOSED, (void*)0 );
+      AM_InterRAT_4G_to_2G();
+      L1SP_SetState( L1SP_STATE_2G_SPEECH_ON );
+   }
+   kal_give_enh_mutex( sp_handover_mutex );   
+}
+
+
+kal_bool spPS_Rab_State_get( void )
+{
+   return spPS_rab_state;
+}
+
+
+kal_bool SP4G_Rab_State( void )
+{
+   return( spPS_Rab_State_get() );
+}
+
+
+kal_uint32 SP4G_Rab_Id( void )
+{
+   return spPS_rab_id;
+}
+
+
+void SP4G_GetSyncDelayRW( kal_uint16 *u16DelayR, kal_uint16 *u16DelayW, kal_uint16 *u16DelayM, kal_uint32 *u32CurTime64us)
+{
+   sp_ps_aam_GetSyncDelayRW(u16DelayR, u16DelayW, u16DelayM, u32CurTime64us);
+}
+
+
+void SP4G_Set_G711Parameters(kal_int32 law, kal_int32 dec_init_CNG_enable)
+{
+//#if defined(__G_CODEC_SUPPORT__)
+   sp_ps_codec_g_Set_G711Parameters(law, dec_init_CNG_enable);
+//#endif //#if defined(__G_CODEC_SUPPORT__)
+}
+
+
+void SP4G_PSR_UL_GSeries_GetSpeechFrame(SP4G_Codec *codec, kal_uint8 *encodebits, kal_uint8 *bitlen)
+{
+//#if defined(__G_CODEC_SUPPORT__)
+   MD_TRC_SPPS_PSR_UL_GSERIES_GETSPEECHFRAME();
+   sp_ps_codec_g_GetFrame((int8 *)codec, (int8 *)bitlen, (uint8 *)encodebits);
+   MD_TRC_SPPS_PSR_UL_GSERIES_GETSPEECHFRAME_INFO(*codec, *codec, encodebits[0], encodebits[1], encodebits[2], encodebits[3], *bitlen);
+   // SP_updateEmCodec(true, *codec, false, 0);
+//#endif
+}
+
+
+void SP4G_PSR_DL_GSeries_PutSpeechFrame(SP4G_Codec codec, kal_uint8 *encodebits, kal_uint8 *bitlen)
+{
+//#if defined(__G_CODEC_SUPPORT__)
+   if(encodebits == NULL)
+   {
+      encodebits = encodebits_null;
+      bitlen = &bitlen_null;
+      *bitlen = 0;      
+   }
+   MD_TRC_SPPS_PSR_DL_GSERIES_PUTSPEECHFRAME();
+   sp_ps_codec_g_PutFrame((int)codec, (int)(*bitlen), (uint8 *)encodebits);
+   MD_TRC_SPPS_PSR_DL_GSERIES_PUTSPEECHFRAME_INFO(codec, codec, encodebits[0], encodebits[1], encodebits[2], encodebits[3], *bitlen);
+   // SP_updateEmCodec(false, 0, true, codec);
+//#endif
+}
+
+
+/*
+return value:
+0: No more data in ul_buf.
+1: Have more data in ul_buf
+*/
+int SP4G_PSR_UL_GSeries_IsMoreData(void)
+{
+   return( sp_ps_codec_g_UL_GSeries_IsMoreData() );
+}
+
+
+void sp4g_hisr_ul_g(void *data)
+{
+   sp_ps_codec_g_hisr_ul_g((void *)0);
+}
+
+void sp4g_hisr_dl_g(void *data)
+{
+   sp_ps_codec_g_hisr_dl_g((void *)0);
+}
+
+void SP4G_EVS_CallOpenSetPar(void)
+{
+   sp_ps_codec_evs_CallOpenSetPar();
+}
+
+
+void SP4G_PSR_SetEVSEncCAPara(EVS_ENC_CA_PARAMETER *pEVS_CA_Par)
+{
+#if defined(__EVS_CODEC_SUPPORT__)
+   kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT);
+   sp_ps_codec_evs_SetEVSEncCAPara(pEVS_CA_Par);
+   kal_give_spinlock(spinlock_sp4g);
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+}
+
+
+void SP4G_PSR_SetEVSDecCAPara(EVS_DEC_CA_PARAMETER *pEVS_CA_Par)
+{
+#if defined(__EVS_CODEC_SUPPORT__)
+   sp_ps_codec_evs_SetEVSDecCAPara(pEVS_CA_Par);
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+}
+
+kal_bool SP4G_PSR_GetEVSDecCAPara(kal_uint8* CA_RF_Flag, kal_uint8* CA_RF_Offset, SP4G_Codec codec, kal_uint8* frame_pt, kal_uint8 offset)
+{
+#if defined(__EVS_CODEC_SUPPORT__)
+    kal_uint32 rf_flag, rf_offset, rf_type;
+    *CA_RF_Flag = 0;
+    *CA_RF_Offset = 0;
+
+    if (codec==SP4G_CODEC_EVS_16K_013_2 || codec==SP4G_CODEC_EVS_32K_013_2)   // EVS 13.2
+    {
+        rf_flag = SP4G_Get_Bit_Value(frame_pt, offset, 5);
+        rf_offset = SP4G_Get_Bit_Value(frame_pt, offset + 259, 2);
+        rf_type = SP4G_Get_Bit_Value(frame_pt, offset + 261, 3);
+        //FPRINT_04("VoLTE JBM Get_Payload_Info: rf_flag: %d, rf_offset: %d, rf_type: %d\n", rf_flag, rf_offset, rf_type);
+        if (rf_flag >=21 && rf_flag <=28 && rf_type != 0)
+        {
+            *CA_RF_Flag = 1;
+            if (rf_offset == 0)
+                *CA_RF_Offset = 2;
+            else if (rf_offset == 1)
+                *CA_RF_Offset = 3;
+            else if (rf_offset == 2)
+                *CA_RF_Offset = 5;
+            else if (rf_offset == 3)
+                *CA_RF_Offset = 7;
+            else
+                *CA_RF_Offset = 0;
+        }
+        return KAL_TRUE;
+    }
+
+    return KAL_FALSE;
+#else  //#if defined(__EVS_CODEC_SUPPORT__)
+    return KAL_FALSE;
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+}
+
+kal_uint32 SP4G_Get_Bit_Value(kal_uint8* frame_pt, kal_uint32 offset, kal_uint8 size)
+{
+    kal_uint8 index, bit_offset, data;
+    kal_uint32 ret = 0;
+    kal_uint8   bits;
+
+    if (size >32)
+    {        
+        return 0;
+    }
+    bits = sizeof(kal_uint8)*8;
+    index = offset/bits;
+    bit_offset = bits - 1 - offset%bits;
+    for (; size>0; size--)
+    {
+        ret = ret << 1;
+        data = frame_pt[index];
+        if (((data >> bit_offset) & 0x1) == 1)
+        {
+            ret++;
+        }
+        if (bit_offset == 0)
+        {
+            bit_offset = bits - 1;
+            index++;
+        }
+        else
+        {
+            bit_offset--;
+        }
+    }
+    return ret;
+}
+
+void SP4G_PSR_UL_EVS_GetSpeechFrame(SP4G_Codec *frame_type, kal_uint8 *encodebits, kal_uint32 *bitlen, VoLTE_JBM_TS_Info_t *JBM_info)
+{
+#if defined(__EVS_CODEC_SUPPORT__)
+   //kal_prompt_trace(MOD_L1SP, "SP4G_PSR_UL_EVS_GetSpeechFrame");
+   MD_TRC_SPPS_PSR_UL_EVS_GETSPEECHFRAME();
+
+   kal_take_enh_mutex( sp_handover_mutex );
+
+   sp_ps_codec_evs_UL_GetSpeechFrame(frame_type, encodebits, (kal_int32 *) bitlen);
+
+   kal_give_enh_mutex( sp_handover_mutex );
+
+   // SP_updateEmCodec(true, *frame_type, false, 0);
+#else //#if defined(__EVS_CODEC_SUPPORT__)
+   *frame_type = SP4G_CODEC_EVS_32K_000_0_NODATA;
+   *bitlen = 0;
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+}
+
+
+void SP4G_PSR_DL_EVS_PutSpeechFrame(kal_uint32 CFN, SP4G_Codec frame_type, kal_uint8 *encodebits, EVS_DEC_CA_PARAMETER *pEVS_Dec_CA_Par, kal_bool crc_status, VoLTE_JBM_TS_Info_t *JBM_info)
+{
+   kal_take_enh_mutex( sp_handover_mutex );
+   if( (VoLTE_JBM_TS_Info_t *)NULL == JBM_info )
+   {
+      JBM_info = &JBM_info_local;
+   }
+   sp_ps_codec_evs_DL_PutSpeechFrame(CFN, frame_type, encodebits, pEVS_Dec_CA_Par, crc_status, JBM_info);
+   kal_give_enh_mutex( sp_handover_mutex );
+}
+
+
+void sp4g_hisr_dl(void *data)
+{	
+   uint8 ul_codec_mode_local;
+
+   kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+
+   ASSERT(spPS != (SPPS_Struct_t*) 0);
+
+   ul_codec_mode_local = spPS->ul_codec_mode;
+
+   if( (L1SP_GetState() != L1SP_STATE_4G_SPEECH_ON) || (sp_ps_codec_g_is_g_codec(ul_codec_mode_local)) )
+   {
+      MD_TRC_SPPS_DL_HISR_SKIP(L1SP_GetState(), sp_ps_codec_g_is_g_codec(ul_codec_mode_local));
+      kal_give_spinlock(spinlock_sp4g);
+      return; 
+   }
+   kal_give_spinlock(spinlock_sp4g);
+
+
+#if defined(__EVS_CODEC_SUPPORT__)
+   if(sp_ps_codec_evs_is_EVS_codec(ul_codec_mode_local))
+   {
+      sp_ps_codec_evs_hisr_dl_EVS(data);
+   }
+   else
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+   {
+      sp_ps_codec_amr_hisr_dl_amr(data);
+   }
+}
+
+void SP4G_Reset( void )
+{
+   spPS_reset_flag = 1;
+}
+
+
+kal_bool spPS_IsDTXOn(void)
+{
+   return spPS_dtx_mode;
+}
+
+
+kal_bool SP4G_IsDTXOn(void)
+{
+   return( spPS_IsDTXOn() );
+}
+
+
+void SP4G_SetDTX(kal_bool on)
+{
+   spPS_dtx_mode = on;
+   MD_TRC_SPPS_SET_DTX(on);
+   if( L1SP_GetState() == L1SP_STATE_4G_SPEECH_ON )
+   {
+      kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+      
+	   SAL_3G_SetDtx(on);
+      
+      kal_give_spinlock(spinlock_sp4g);
+   }
+}
+
+
+void SP4G_PSR_SetDTX(kal_bool on)
+{
+   SP4G_SetDTX(on);
+}
+
+
+void SP4G_SetRxTypeToNoData( void )
+{
+   //SAL_3G_Set_RxType(SAL_3G_RX_NO_DATA);
+   SAL_4G_Set_RxType(SAL_3G_RX_NO_DATA, SAL_3G_RX_NO_DATA);
+}
+
+
+kal_uint32 SP4G_JBM_GetDLVADFlag()
+{
+    return SAL_GetDLVADFlag();
+}
+
+
+void sp4g_hisr_ul(void *data)
+{
+   uint8 ul_codec_mode_local;
+
+   kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+
+   ASSERT(spPS != (SPPS_Struct_t*) 0);
+
+   ul_codec_mode_local = spPS->ul_codec_mode;
+
+   if( (L1SP_GetState() != L1SP_STATE_4G_SPEECH_ON) || (sp_ps_codec_g_is_g_codec(ul_codec_mode_local)) )
+   {
+      MD_TRC_SPPS_UL_HISR_SKIP(L1SP_GetState(), sp_ps_codec_g_is_g_codec(ul_codec_mode_local));
+      kal_give_spinlock(spinlock_sp4g);
+      return; 
+   }
+   kal_give_spinlock(spinlock_sp4g);
+
+
+#if defined(__EVS_CODEC_SUPPORT__)
+   if(sp_ps_codec_evs_is_EVS_codec(ul_codec_mode_local))
+   {
+      sp_ps_codec_evs_hisr_ul_EVS(data);
+   }
+   else
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+   {
+      sp_ps_codec_amr_hisr_ul_amr(data);
+   }
+
+#if defined(__SP_4G_OPT_TONE_DETECTION__)
+   /**************************/
+   // Execute Tone Detection
+   /**************************/
+   L1Audio_SetEvent( sp_ps_dsp_opt_ToneDeteGetAudID(), (void *)0 );
+#endif //#if defined(__SP_4G_OPT_TONE_DETECTION__)
+}
+
+
+void sp_ps_reset_internal( void )
+{
+   // DL side(G-series)
+//#if defined(__G_CODEC_SUPPORT__)   
+   if(sp_ps_codec_g_is_g_codec(spPS->ul_codec_mode)){
+      sp_ps_codec_g_reset_internal();
+      spPS_reset_flag    = 2;
+   }else
+//#endif //#if defined(__G_CODEC_SUPPORT__)   
+   {
+#if defined(__EVS_CODEC_SUPPORT__)
+      if(sp_ps_codec_evs_is_EVS_codec(spPS->ul_codec_mode)) {
+         sp_ps_codec_evs_reset_internal();
+         spPS_reset_flag = 0;
+      }else
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+      {
+         sp_ps_codec_amr_reset_internal();
+         spPS_reset_flag    = 0; // clear reset flag, wait it to be 2
+      }
+      spPS->ul_waiting = KAL_FALSE;
+      spPS->dl_waiting = KAL_FALSE;
+   }
+}
+
+
+void sp4g_init( void )
+{
+   int i;
+
+   spPS_rab_id        = 0;
+   for(i=0; i<SPPS_RAB_ID_MAX; i++)
+   {
+      spPS_rab_id_record[i] = 0;
+   }
+   spPS_rab_state     = KAL_FALSE;
+   spPS_fake_EVS_IO = 0;
+   spPS_dtx_mode = 1;
+
+   spPS_RadioType = SP_PS_RADIO_TYPE_UNKNOWN;
+
+   JBM_info_local.TS_Switch = 0;
+   JBM_info_local.TS_HB_Frm_Num = 1;
+   JBM_info_local.TS_Frm_ID = 1;
+   JBM_info_local.TS_isRemainFrame = 0;
+   JBM_info_local.TS_Scale = 100;
+   JBM_info_local.TS_Max_Scale = 0;
+   JBM_info_local.TS_JBM_Reset_Flag = 0;
+   JBM_info_local.TS_DSP_Reset_Flag = 0;
+   JBM_info_local.TS_Remain_Length_ms = 0;
+   JBM_info_local.TS_Total_Length_ms = 0;
+   //JBM_info_local.TS_Reserve[JBM_TS_RESERVE];
+   JBM_info_local.Nodata_Type = JBM_NODATA_NORMAL;
+
+#if defined(__EVS_CODEC_SUPPORT__)
+   sp_ps_codec_evs_init();
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+
+#if defined(__SP4G_UL_RESYNC__)
+   sp_ps_aam_init();
+#endif
+
+   spPS = &stSPPS;
+   spinlock_sp4g = kal_create_spinlock("SP4GSL");
+}
+
+
+void sp4g_speech_init(uint8 RAT_Mode)
+{
+   ASSERT( RAT_Mode == RAT_4G_MODE  );
+   ASSERT( L1SP_GetState() == L1SP_STATE_IDLE );
+
+   memset(spPS, 0, sizeof(SPPS_Struct_t));
+   spPS->sp4g_mode = RAT_Mode; 
+   // UL side
+   spPS->ul_waiting = KAL_FALSE;
+   spPS->dl_waiting = KAL_FALSE;
+   spPS->ul_write_idx = 0;
+   spPS->ul_read_idx = 0;
+   spPS->ul_count = 0;
+   spPS->is_getting_ul_data = KAL_FALSE;
+   spPS->ul_delay = 0;
+   spPS->dl_delay = 0;
+   spPS->pre_ul_report = spPS->pre_dl_report = spPS->ul_report = spPS->dl_report = spPS_est_codec_mode;//INIT_CODEC;
+   MD_TRC_SPPS_DEBUG_SPPS_SPEECH_INIT(spPS_est_codec_mode);
+   if( spPS->sp4g_mode == RAT_4G_MODE )
+   {
+      spPS->ul_buffer_size = RAT_4G_UL_BUFFER_NUM;
+   }
+
+#if defined(UL_HARD_REAL_TIME_DEMAND)
+   spPS->ul_buffer_size = HARD_REAL_TIME_UL_BUFFER_NUM;
+#endif    
+
+   spPS->ul_codec_mode = spPS_est_codec_mode;//INIT_CODEC;//  use 12.20kbps rate initially
+      
+   spPS->ul_refresh  = KAL_FALSE; // detect change codec_mode  
+   spPS->ul_intrarat = KAL_FALSE;
+
+   // DL side 
+   spPS->dl_count     = 0;
+   spPS->dl_write_idx = 0;
+   spPS->dl_read_idx  = 0;
+   
+   if( spPS->sp4g_mode == RAT_4G_MODE ){
+      MD_TRC_SPPS_PP5_SP4G_RESET_FLAG_INFO(spPS_reset_flag, spPS->dl_count, spPS->dl_read_idx, spPS->dl_write_idx, spPS->dl_buffer_size);      
+      MD_TRC_SPPS_PP5_1(RAT_4G_DL_BUFFER_NUM_BEFORE_RESYNC);
+      spPS->dl_buffer_size = RAT_4G_DL_BUFFER_NUM_BEFORE_RESYNC;
+      spPS->dl_buffer_size = 2;
+      MD_TRC_SPPS_PP6_SP4G_RESET_FLAG_INFO(spPS_reset_flag, spPS->dl_count, spPS->dl_read_idx, spPS->dl_write_idx, spPS->dl_buffer_size);
+      spPS_reset_flag    = 1;
+   }
+   else{  // 4G324M 
+      spPS->dl_buffer_size = MAX_DL_BUFFER_NUM;
+      spPS_reset_flag    = 2;
+   }
+
+#if defined(__SP4G_UL_RESYNC__)
+   spPS->time[SP_PSCALL_EMAC][0] = spPS->time[SP_PSCALL_EMAC][1] = spPS->time[SP_PSCALL_EMAC][2] = 0;  
+   spPS->time[SP_PSCALL_NMAC][0] = spPS->time[SP_PSCALL_NMAC][1] = spPS->time[SP_PSCALL_NMAC][2] = 0;  
+   spPS->request_resync    = KAL_FALSE;
+   spPS->time2nextULHISR[SP_PSCALL_EMAC] = spPS->time2nextULHISR[SP_PSCALL_NMAC] = 0;  //unit: ms
+#endif
+
+#if defined(__SP4G_UL_RESYNC__)
+   sp_ps_aam_speech_init();
+#endif
+
+   sp_ps_aam_speech_init_SilenceDetection();
+
+#if defined(SP4G_UNIT_TEST)
+   L1Audio_HookHisrHandler(DP_D2C_4G,(L1Audio_EventHandler)sp4g_hisr_2, 0);
+#else 
+   L1Audio_HookHisrHandler(DP_D2C_4G_AMR_DONE_UL,(L1Audio_EventHandler)sp4g_hisr_ul, 0);
+   L1Audio_HookHisrHandler(DP_D2C_4G_AMR_DONE_DL,(L1Audio_EventHandler)sp4g_hisr_dl, 0);
+#endif
+
+#if defined(__SP4G_UL_RESYNC__)
+   L1Audio_HookHisrHandler(DP_D2C_4G_AAM,(L1Audio_EventHandler)sp_ps_AAM_hisr, 0);
+#endif
+
+#ifdef __SP_PS_AAM_PLUS__
+   L1Audio_HookHisrHandler(DP_D2C_4G_AAMPLUS,(L1Audio_EventHandler)sp_ps_AAMPlus_notify_EMAC, 0);//fix   
+#endif //#ifdef __SP_PS_AAM_PLUS__
+
+
+//#if defined(__G_CODEC_SUPPORT__)
+   sp_ps_codec_g_speech_init();
+//#endif//#if defined(__G_CODEC_SUPPORT__)
+
+#if defined(__EVS_CODEC_SUPPORT__)
+   sp_ps_codec_evs_speech_init();
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+
+#if defined(__SP_4G_OPT_TONE_DETECTION__)
+   sp_ps_dsp_opt_ToneDeteInit();
+   sp_ps_dsp_opt_ToneDeteTaskInit();
+#endif //#if defined(__SP_4G_OPT_TONE_DETECTION__)
+
+   spPS->l1_info_idx = 0;
+   spPS->dtx_state   = 0;
+
+#ifdef __SP_PS_AAM_PLUS__
+   sp_ps_AAMPlus_enable();
+#endif //#ifdef __SP_PS_AAM_PLUS__
+
+}
+
+SP_PSCALL_L2_MODE SP4G_GetL2Mode()
+{
+   return spPS->sph_l2_mode;	
+}
+//#if defined(__G_CODEC_SUPPORT__)
+void GSeries_Encode_Init(SP4G_Codec codec_)
+{
+   sp_ps_codec_g_Encode_Init(codec_);
+}
+
+
+void GSeries_Encode_DeInit()
+{
+   
+}
+
+
+void GSeries_Decode_Init(SP4G_Codec codec_)
+{
+   sp_ps_codec_g_Decode_Init(codec_);
+}
+
+
+void GSeries_Decode_DeInit()
+{
+   
+}
+
+
+void sp4g_speech_close( void )
+{         
+   L1Audio_UnhookHisrHandler(DP_D2C_4G_AMR_DONE_DL);
+   L1Audio_UnhookHisrHandler(DP_D2C_4G_AMR_DONE_UL);
+   L1Audio_UnhookHisrHandler(DP_D2C_4G_AAM); 
+#ifdef __SP_PS_AAM_PLUS__
+   L1Audio_UnhookHisrHandler(DP_D2C_4G_AAMPLUS); 
+#endif //#ifdef __SP_PS_AAM_PLUS__
+
+   sp_ps_codec_g_close();
+
+#if defined(__SP_4G_OPT_TONE_DETECTION__)
+   sp_ps_dsp_opt_ToneDeteClose();
+#endif //#if defined(__SP_4G_OPT_TONE_DETECTION__)
+
+#ifdef __SP_PS_AAM_PLUS__
+   sp_ps_AAMPlus_disable();
+#endif //#ifdef __SP_PS_AAM_PLUS__
+}
+
+
+kal_uint16 SP4G_PSR_GetCodecBitLength(SP4G_Codec codec) // function call 
+{
+   int len = 0/*, I*/;
+   
+   if(sp_ps_codec_g_is_g_codec(codec)){
+      if(codec ==  SP4G_CODEC_G711)
+      {
+         kal_uint16 G711_codec_bitlength = 80*8;    
+         return G711_codec_bitlength;
+      }
+      ASSERT(false);//FIX ME
+   }else if(GET_IS_SP4G_CODEC_ENUM_EVS_ID(codec)){
+      #if defined(__EVS_CODEC_SUPPORT__)
+         return( sp_ps_codec_evs_GetCodecBitLength(codec) );
+      #else //#if defined(__EVS_CODEC_SUPPORT__)
+         ASSERT(false);//FIX ME
+      #endif //#if defined(__EVS_CODEC_SUPPORT__)
+   }else{//AMR, WB-AMR      
+      return( sp_ps_codec_amr_GetCodecBitLength(codec) );
+   }   
+   return len;
+}
+
+
+void SP4G_UL_SetFrameType(uint8 amr_frame_type) // function call 
+{
+   uint8  state;
+   uint32 codec;
+   spPS_est_codec_mode = sp_ps_codec_amr_Get_AmrFrameType2DspMode_spps(amr_frame_type);//AmrFrameType2DspMode_spps[amr_frame_type]; 
+
+   if( (state = L1SP_GetState()) != L1SP_STATE_4G_SPEECH_ON){
+      return;
+   }      
+
+   ASSERT(spPS != (SPPS_Struct_t*) 0); 
+
+   MD_TRC_SPPS_REQUEST_UL_FRAME_TYPE(amr_frame_type, amr_frame_type);
+   codec = sp_ps_codec_amr_Get_AmrFrameType2DspMode_spps(amr_frame_type);//AmrFrameType2DspMode_spps[amr_frame_type];      
+   if( (sp_ps_codec_g_is_g_codec(spPS->ul_codec_mode)==true) || (sp_ps_codec_evs_is_EVS_codec(spPS->ul_codec_mode)==true) )
+   {
+      uint32 resetType = PS_SRST_TYPE_HO_WITHOUT_VBIEND;
+      if( sp_ps_codec_g_is_g_codec(spPS->ul_codec_mode) == true )
+      {
+         resetType = PS_SRST_TYPE_HO_WITH_VBIEND;
+      }
+      kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+      spPS->ul_codec_mode = codec;
+      kal_give_spinlock(spinlock_sp4g);
+      AM_4G_INTRARAT(codec, resetType);
+      //may add at 3G
+      //spPS->ul_intrarat = KAL_TRUE;
+      SP4G_Reset();
+      MD_TRC_SPPS_SETCODEC_SETFRAMETYPE1(spPS->ul_codec_mode, spPS->ul_codec_mode, codec, amr_frame_type, amr_frame_type, spPS->ul_intrarat);
+      //L1SP_SetState( L1SP_STATE_4G_SPEECH_ON );
+   }else if( (spPS->ul_codec_mode >= 0x20 && codec <= 0x0A) || (spPS->ul_codec_mode <= 0x0A && codec >= 0x20) ){//Intrarat
+      kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+      spPS->ul_codec_mode = codec;
+      kal_give_spinlock(spinlock_sp4g);
+      AM_4G_INTRARAT(codec, PS_SRST_TYPE_HO_WITHOUT_VBIEND);
+      //may add at 3G
+      spPS->ul_intrarat = KAL_TRUE;
+      SP4G_Reset();
+      MD_TRC_SPPS_SETCODEC_SETFRAMETYPE2(spPS->ul_codec_mode, codec, amr_frame_type, amr_frame_type, spPS->ul_intrarat);
+      //L1SP_SetState( L1SP_STATE_4G_SPEECH_ON );
+   }else{
+      if(spPS->ul_codec_mode != codec){
+         MD_TRC_SPPS_SETCODEC_SETFRAMETYPE3(spPS->ul_codec_mode, codec,amr_frame_type, amr_frame_type, spPS->ul_intrarat);
+         kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+         spPS->ul_codec_mode = codec;
+         spPS->ul_refresh = KAL_TRUE; 
+         kal_give_spinlock(spinlock_sp4g);
+      }
+   }
+}
+
+
+void SP4G_PSR_UL_SetFrameType(SP4G_Codec codec)
+{
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+      kal_bool retval;
+      kal_uint8 new_SP4G_Codec;
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+
+   kal_take_enh_mutex( sp_handover_mutex ); 
+
+   MD_TRC_SPPS_SETCODEC0(codec, codec);
+
+   MD_TRC_SPPS_PSR_UL_SETFRAMETYPE1(codec, L1SP_GetState(), sp_ps_codec_g_is_g_codec(codec), sp_ps_codec_evs_is_EVS_codec(codec));
+
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   if( UseEVSIO2ReplaceAWB() )
+   {
+      MD_TRC_SPPS_SETCODEC_USE_EVS_IO_REPLACE_AWB_IN(codec);
+      retval = convert_AWB_to_EVSIOEnum( codec, (SP4G_Codec*)&new_SP4G_Codec );
+      if(retval == KAL_TRUE) {
+         spPS_fake_EVS_IO = 1;
+      }
+      else {
+         spPS_fake_EVS_IO = 0;
+      }
+      codec = new_SP4G_Codec;
+      MD_TRC_SPPS_SETCODEC_USE_EVS_IO_REPLACE_AWB_OUT(codec);
+   }
+   else
+   {
+      spPS_fake_EVS_IO = 0;
+   }
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+
+   spPS_est_codec_mode = codec;
+   if( (sp_ps_codec_g_is_g_codec(spPS_est_codec_mode)==false) && (sp_ps_codec_evs_is_EVS_codec(spPS_est_codec_mode)==false) ){
+      spPS_est_codec_mode = sp_ps_codec_amr_Get_AmrFrameType2DspMode_spps(spPS_est_codec_mode);//GetFrameType2DspMode(spPS_est_codec_mode);
+   }
+
+   if( L1SP_GetState() != L1SP_STATE_4G_SPEECH_ON){
+      if( 1/*L1SP_STATE_IDLE == L1SP_GetState()*/ ){
+         if( spPS != (SPPS_Struct_t *)NULL ){
+            kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+            spPS->ul_codec_mode = spPS_est_codec_mode;//default_speech_codec;
+            kal_give_spinlock(spinlock_sp4g);
+         }
+         MD_TRC_SPPS_SETCODEC(codec, codec, spPS_est_codec_mode);
+      }
+      kal_give_enh_mutex( sp_handover_mutex );
+      return;
+   }
+
+   if(sp_ps_codec_g_is_g_codec(codec)){         
+      if(codec == spPS->ul_codec_mode){
+         MD_TRC_SPPS_SETCODEC_IS_EQUAL(codec, codec);
+         //return;	
+      }
+      else{
+         kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+         spPS->ul_codec_mode = codec;
+         kal_give_spinlock(spinlock_sp4g);
+         AM_4G_INTRARAT(codec, PS_SRST_TYPE_HO_WITH_VBIEND);
+         SP4G_Reset();         
+      }
+   }else if(sp_ps_codec_evs_is_EVS_codec(codec)){
+      if( /*sp_ps_codec_evs_is_EVS_codec(codec) ==*/ sp_ps_codec_evs_is_EVS_codec(spPS->ul_codec_mode) ){
+         if( GET_SP4G_CODEC_ENUM_NON_EVS_ID(codec) != GET_SP4G_CODEC_ENUM_NON_EVS_ID(spPS->ul_codec_mode) )
+         {
+            sp_ps_codec_evs_set_network_bw(codec);
+            kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+            spPS->ul_codec_mode = codec;
+            kal_give_spinlock(spinlock_sp4g);
+            AM_4G_INTRARAT(codec, PS_SRST_TYPE_HO_WITHOUT_VBIEND);
+            SP4G_Reset();
+         }
+         else if( codec != (spPS->ul_codec_mode) )
+         {
+            kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+            spPS->ul_codec_mode = codec;
+            kal_give_spinlock(spinlock_sp4g);
+         }
+      }
+      else
+      {
+         uint32 reset_type = PS_SRST_TYPE_HO_WITHOUT_VBIEND;
+         if( sp_ps_codec_g_is_g_codec(spPS->ul_codec_mode) == true )
+         {
+            reset_type = PS_SRST_TYPE_HO_WITH_VBIEND;
+         }
+         kal_take_spinlock(spinlock_sp4g, KAL_INFINITE_WAIT); 
+         spPS->ul_codec_mode = codec;
+         kal_give_spinlock(spinlock_sp4g);
+         AM_4G_INTRARAT(codec, reset_type);
+         SP4G_Reset();
+      }
+   }else{
+      SP4G_UL_SetFrameType(codec);
+   }
+
+   kal_give_enh_mutex( sp_handover_mutex );
+}
+
+
+void SP4G_PSR_UL_AMR_GetSpeechFrame(SP4G_Codec *frame_type, kal_uint8 *encodebits, kal_uint8 *bitlen, VoLTE_JBM_TS_Info_t *JBM_info)
+{
+   kal_take_enh_mutex( sp_handover_mutex ); 
+
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   if(spPS_fake_EVS_IO == 0) {
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+      sp_ps_codec_amr_UL_GetSpeechFrame(frame_type, encodebits, bitlen);
+      // SP_updateEmCodec(true, convert_SP4G_CODEC_AMR_AMRWB_to_SPH_CODEC((*frame_type)), false, 0);
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   } else {
+      kal_bool retval;
+      SP4G_Codec EVSIO_frame_type;
+      kal_uint32 u32bitlen;
+      uint8 EVS_codec_rate = 0;
+
+      //MD_TRC_SPPS_UL_GETSPEECHFRAME_USE_EVS_IO_REPLACE_AWB();
+
+      {
+#if defined(__EVS_CODEC_SUPPORT__)
+         sp_ps_codec_evs_UL_GetSpeechFrame(&EVSIO_frame_type, encodebits, (kal_int32 *)&u32bitlen);
+#else //#if defined(__EVS_CODEC_SUPPORT__)
+         *frame_type = SP4G_CODEC_EVS_32K_000_0_NODATA;
+         *bitlen = 0;
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+      }
+
+      EVS_codec_rate = GET_SP4G_CODEC_ENUM_EVS_RATE(EVSIO_frame_type);
+      *bitlen = (kal_uint8)sp_ps_codec_evs_Get_EVS_AWB_RAB_subflow(EVS_codec_rate, 3);//EVS_AWB_RAB_subflow[EVS_codec_rate][3];
+      MD_TRC_SPPS_UL_GETSPEECHFRAME_USE_EVS_IO_REPLACE_AWB_LEN(u32bitlen, *bitlen);
+
+      retval = convert_EVSIO_to_AWBEnum(EVSIO_frame_type, frame_type);
+      if(retval == KAL_FALSE) {
+         *frame_type = AMR_NO_DATA;
+         *bitlen = 0;
+      }
+   }
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+
+   kal_give_enh_mutex( sp_handover_mutex );
+}
+
+
+void SP4G_PSR_DL_AMR_PutSpeechFrame(kal_uint32 CFN, SP4G_PSR_Codec codec, SP4G_Codec frame_type, kal_bool crc_status, kal_uint8 *encodebits, VoLTE_JBM_TS_Info_t *JBM_info)
+{
+   kal_take_enh_mutex( sp_handover_mutex );
+
+   if( (VoLTE_JBM_TS_Info_t *)NULL == JBM_info )
+   {
+      JBM_info = &JBM_info_local;
+   }
+
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   if(spPS_fake_EVS_IO == 0) {
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+      sp_ps_codec_amr_DL_PutSpeechFrame(CFN, codec, frame_type, encodebits, crc_status, JBM_info);
+#if defined(__USE_EVS_IO_REPLACE_AWB__)
+   } else {
+      kal_bool retval;
+      SP4G_Codec EVSIO_frame_type;
+
+      //MD_TRC_SPPS_DL_PUTSPEECHFRAME_USE_EVS_IO_REPLACE_AWB();
+
+      retval = convert_AWB_to_EVSIOEnum(frame_type, &EVSIO_frame_type);
+      if(retval == KAL_FALSE) {
+         EVSIO_frame_type = SP4G_CODEC_EVS_AWB_00_00_NODATA;
+      }
+
+      sp_ps_codec_evs_DL_PutSpeechFrame(CFN, EVSIO_frame_type, encodebits, (EVS_DEC_CA_PARAMETER*)NULL, crc_status, JBM_info);
+   }
+#endif //#if defined(__USE_EVS_IO_REPLACE_AWB__)
+
+   kal_give_enh_mutex( sp_handover_mutex );
+}
+
+
+//=====================================
+// Fake 4G llopbck
+//=====================================
+kal_uint32 get_is_fake_4g(void);
+kal_uint32 encodebits_buf[1000];
+kal_uint8 encodebits[128];
+
+SP4G_Codec pscall_loopback_frame_type;
+kal_uint32 pscall_loopback_bitlen;
+kal_uint8  pscall_loopback_uint8_bitlen;
+
+void sp4g_EVS_loopback_ul(void)
+{
+#if defined(__EVS_CODEC_SUPPORT__)
+   kal_uint8 *encodebits = (kal_uint8 *)encodebits_buf;
+   MD_TRC_SPPS_PSR_EVS_LOOPBACK_UL_1();
+   if( sp_ps_codec_evs_is_EVS_codec(spPS->ul_codec_mode) )
+   {
+      SP4G_PSR_UL_EVS_GetSpeechFrame(&pscall_loopback_frame_type, encodebits, &pscall_loopback_bitlen, (VoLTE_JBM_TS_Info_t *)NULL);
+			{
+			   l1sp_emac_resync_info_struct *local_para;
+			   local_para = (l1sp_emac_resync_info_struct *) construct_local_para( sizeof(l1sp_emac_resync_info_struct), TD_CTRL );
+			   local_para->RX_period = 0;
+			   local_para->TX_period = 20;
+			   local_para->time2nextRX = 0;
+			   local_para->time2nextTX = 7;
+			   local_para->issueTime = ust_get_current_time();
+			
+			   msg_send6(MOD_EMAC, MOD_MED, AUDIO_SAP, MSG_ID_AUDIO_M2M_VOLTE_MAC_TIMING_INFO, (local_para_struct *)local_para, NULL);	 
+			}	       
+      MD_TRC_SPPS_PSR_EVS_LOOPBACK_UL_2(pscall_loopback_frame_type, pscall_loopback_bitlen);
+   }
+#endif //#if 0
+}
+
+void sp4g_EVS_loopback_dl(void)
+{
+#if defined(__EVS_CODEC_SUPPORT__)
+   kal_uint8 *encodebits = (kal_uint8 *)encodebits_buf;
+   EVS_DEC_CA_PARAMETER EVS_Dec_CA_Par;
+   EVS_DEC_CA_PARAMETER *pEVS_Dec_CA_Par = &EVS_Dec_CA_Par;
+
+   EVS_Dec_CA_Par.FrameMode = FRAMEMODE_NORMAL;
+   MD_TRC_SPPS_PSR_EVS_LOOPBACK_DL_1();
+   if( sp_ps_codec_evs_is_EVS_codec(spPS->ul_codec_mode) )
+   {
+   	  MD_TRC_SPPS_PSR_EVS_LOOPBACK_DL_2(pscall_loopback_frame_type, pscall_loopback_bitlen);
+      //SP4G_PSR_UL_EVS_GetSpeechFrame(&frame_type, encodebits, &bitlen, (VoLTE_JBM_TS_Info_t *)NULL);
+      if(pscall_loopback_bitlen == 0)
+      {
+         SP4G_PSR_DL_EVS_PutSpeechFrame(0, pscall_loopback_frame_type, NULL, pEVS_Dec_CA_Par, KAL_TRUE, (VoLTE_JBM_TS_Info_t *)NULL);
+      }
+      else
+      {
+         SP4G_PSR_DL_EVS_PutSpeechFrame(0, pscall_loopback_frame_type, encodebits, pEVS_Dec_CA_Par, KAL_TRUE, (VoLTE_JBM_TS_Info_t *)NULL);
+      }
+   }
+#endif //#if 0
+}
+
+
+void sp4g_EVS_loopback_SetEVSEncCAPara(void)
+{
+#if defined(__EVS_CODEC_SUPPORT__)
+   EVS_ENC_CA_PARAMETER EVS_CA_Par;
+
+   EVS_CA_Par.enable           = 0;
+   EVS_CA_Par.rf_fec_indicator = 0;
+   EVS_CA_Par.rf_fec_offset    = 0;
+   EVS_CA_Par.rev3             = 0;
+   EVS_CA_Par.rev4             = 0;
+   EVS_CA_Par.rev5             = 0;
+
+   SP4G_PSR_SetEVSEncCAPara(&EVS_CA_Par);
+#endif //#if defined(__EVS_CODEC_SUPPORT__)
+}
+
+
+void sp4g_AMR_NB_loopback_ul(void)
+{
+   SP4G_PSR_UL_AMR_GetSpeechFrame(&pscall_loopback_frame_type, encodebits, &pscall_loopback_uint8_bitlen, (VoLTE_JBM_TS_Info_t *)NULL);   
+}
+
+void sp4g_AMR_NB_loopback_dl(void)
+{
+   if( (pscall_loopback_frame_type >= SP4G_CODEC_WBAMR_6_6) && (pscall_loopback_frame_type <= SP4G_CODEC_WBAMR_SID) )
+   {
+      return;
+   }
+
+   if( (pscall_loopback_frame_type==SP4G_CODEC_AMR_NO_DATA) || (pscall_loopback_frame_type==SP4G_CODEC_LOST_FRAME) )
+   {
+      SP4G_PSR_DL_AMR_PutSpeechFrame(0, SP4G_PSR_AMR, pscall_loopback_frame_type, KAL_TRUE, NULL, (VoLTE_JBM_TS_Info_t *)NULL);
+   }
+   else
+   {
+      SP4G_PSR_DL_AMR_PutSpeechFrame(0, SP4G_PSR_AMR, pscall_loopback_frame_type, KAL_TRUE, encodebits, (VoLTE_JBM_TS_Info_t *)NULL);
+   }
+}
+
+void sp4g_AMR_WB_loopback_ul(void)
+{
+   SP4G_PSR_UL_AMR_GetSpeechFrame(&pscall_loopback_frame_type, encodebits, &pscall_loopback_uint8_bitlen, (VoLTE_JBM_TS_Info_t *)NULL);
+}
+
+void sp4g_AMR_WB_loopback_dl(void)
+{
+   if( pscall_loopback_frame_type <= SP4G_CODEC_AMR_SID )
+   {
+      return;
+   }
+
+   if( (pscall_loopback_frame_type==SP4G_CODEC_AMR_NO_DATA) || (pscall_loopback_frame_type==SP4G_CODEC_LOST_FRAME) )
+   {
+      SP4G_PSR_DL_AMR_PutSpeechFrame(0, SP4G_PSR_WBAMR, pscall_loopback_frame_type, KAL_TRUE, NULL, (VoLTE_JBM_TS_Info_t *)NULL);
+   }
+   else
+   {
+      SP4G_PSR_DL_AMR_PutSpeechFrame(0, SP4G_PSR_WBAMR, pscall_loopback_frame_type, KAL_TRUE, encodebits, (VoLTE_JBM_TS_Info_t *)NULL);
+   }
+}
+
+
+void sp4g_G711_loopback(void)
+{
+   SP4G_Codec frame_type;
+   kal_uint8 bitlen;
+
+   while(SP4G_PSR_UL_GSeries_IsMoreData())
+   {
+	   MD_TRC_SPPS_PSR_G711_LOOPBACK(0);	   
+	   SP4G_PSR_UL_GSeries_GetSpeechFrame(&frame_type, encodebits, &bitlen);	    
+	   MD_TRC_SPPS_PSR_G711_LOOPBACK(1);     
+	   SP4G_PSR_DL_GSeries_PutSpeechFrame(frame_type, encodebits, &bitlen);	   
+	   MD_TRC_SPPS_PSR_G711_LOOPBACK(2);       
+   }
+}
+
+
+void sp4g_fake_loopback_ul(void)
+{
+   uint8 local_ul_codec_mode = spPS->ul_codec_mode;
+
+   if( get_is_fake_4g() == 0 )
+   {
+      return;
+   }
+
+#ifdef TEST_AAM
+   if(KAL_TRUE == SPPS_is_trigger_mac_notify)
+   {
+      if(0 == test_aam_resync)
+      {
+         SP4G_Set_AAM_Info(40, 20, 30, 5);
+      }
+	  else
+	  {
+		 SP4G_Set_AAM_Info(40, 20, 30, 15);
+		 test_aam_resync = 0;
+	  }
+   }
+#endif //#ifdef TEST_AAM
+
+   //EVS
+   if( sp_ps_codec_evs_is_EVS_codec(local_ul_codec_mode) )
+   {
+      sp4g_EVS_loopback_ul();
+   }
+   //G series
+   else if( sp_ps_codec_g_is_g_codec(local_ul_codec_mode) )
+   {    
+      sp4g_G711_loopback();  
+   }
+   //AMR-NB
+   else if( local_ul_codec_mode <= 0xA )
+   {
+      sp4g_AMR_NB_loopback_ul();
+   }
+   //AMR-WB
+   else if( local_ul_codec_mode >= 0x20 )
+   {
+      sp4g_AMR_WB_loopback_dl();
+   }   
+}
+
+void sp4g_fake_loopback_dl(void)
+{
+   uint8 local_ul_codec_mode = spPS->ul_codec_mode;
+
+   if( get_is_fake_4g() == 0 )
+   {
+      return;
+   }
+
+#ifdef TEST_AAM
+   if(KAL_TRUE == SPPS_is_trigger_mac_notify)
+   {
+      if(0 == test_aam_resync)
+      {
+         SP4G_Set_AAM_Info(40, 20, 30, 5);
+      }
+	  else
+	  {
+		 SP4G_Set_AAM_Info(40, 20, 30, 15);
+		 test_aam_resync = 0;
+	  }
+   }
+#endif //#ifdef TEST_AAM
+
+   //EVS
+   if( sp_ps_codec_evs_is_EVS_codec(local_ul_codec_mode) )
+   {
+      sp4g_EVS_loopback_dl();
+   }
+   //G series
+   //else if( sp_ps_codec_g_is_g_codec(local_ul_codec_mode) )
+   //{    
+   //   sp4g_G711_loopback();  
+   //}
+   //AMR-NB
+   else if( local_ul_codec_mode <= 0xA )
+   {
+      sp4g_AMR_NB_loopback_dl();
+   }
+   //AMR-WB
+   else if( local_ul_codec_mode >= 0x20 )
+   {
+      sp4g_AMR_WB_loopback_dl();
+   }   
+}
+
+
+
+//#endif // __UMTS_RAT__
+
+
+
+