VoIPVoice.c
上传用户:lqx1163
上传日期:2014-08-13
资源大小:9183k
文件大小:34k
源码类别:

MTK

开发平台:

C/C++

  1. /*****************************************************************************
  2. *  Copyright Statement:
  3. *  --------------------
  4. *  This software is protected by Copyright and the information contained
  5. *  herein is confidential. The software may not be copied and the information
  6. *  contained herein may not be used or disclosed except with the written
  7. *  permission of MediaTek Inc. (C) 2005
  8. *
  9. *  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  10. *  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  11. *  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
  12. *  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  13. *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  14. *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  15. *  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  16. *  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  17. *  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
  18. *  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
  19. *  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
  20. *  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
  21. *
  22. *  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
  23. *  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  24. *  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  25. *  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
  26. *  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
  27. *
  28. *  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
  29. *  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
  30. *  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
  31. *  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
  32. *  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
  33. *
  34. *****************************************************************************/
  35. /*****************************************************************************
  36.  *
  37.  * Filename:
  38.  * ---------
  39.  *  VoIPVoice.c
  40.  *
  41.  * Project:
  42.  * --------
  43.  *  MAUI
  44.  *
  45.  * Description:
  46.  * ------------
  47.  *  Coding Template header file
  48.  *
  49.  * Author:
  50.  * -------
  51.  * -------
  52.  *
  53.  *============================================================================
  54.  *             HISTORY
  55.  * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  56.  *------------------------------------------------------------------------------
  57.  * removed!
  58.  *
  59.  * removed!
  60.  * removed!
  61.  * removed!
  62.  *
  63.  * removed!
  64.  * removed!
  65.  * removed!
  66.  *
  67.  * removed!
  68.  * removed!
  69.  * removed!
  70.  *
  71.  * removed!
  72.  * removed!
  73.  * removed!
  74.  *
  75.  * removed!
  76.  * removed!
  77.  * removed!
  78.  *
  79.  * removed!
  80.  * removed!
  81.  * removed!
  82.  *
  83.  * removed!
  84.  * removed!
  85.  * removed!
  86.  *
  87.  * removed!
  88.  * removed!
  89.  * removed!
  90.  *
  91.  * removed!
  92.  * removed!
  93.  * removed!
  94.  *
  95.  * removed!
  96.  * removed!
  97.  * removed!
  98.  *
  99.  * removed!
  100.  * removed!
  101.  * removed!
  102.  *
  103.  * removed!
  104.  * removed!
  105.  * removed!
  106.  *
  107.  * removed!
  108.  * removed!
  109.  * removed!
  110.  *
  111.  *------------------------------------------------------------------------------
  112.  * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
  113.  *============================================================================
  114.  ****************************************************************************/
  115. #ifndef __MTK_TARGET__
  116. #include <windows.h>
  117. #endif 
  118. #include "MMI_features.h"
  119. #ifdef __MMI_VOIP__
  120. #include "stdC.h"
  121. #include "L4Dr1.h"
  122. #include "DebugInitDef.h"
  123. #include "mmi_trc.h"            /* debug info */
  124. #include "GlobalMenuItems.h"
  125. #include "GlobalScrEnum.h"
  126. #include "CustMenuRes.h"
  127. #include "CustDataRes.h"
  128. #include "ProtocolEvents.h"
  129. #include "CommonScreens.h"
  130. #include "SettingProfile.h"
  131. #include "EventsGprot.h"
  132. #include "wgui_categories_popup.h"
  133. #include "wgui_categories_inputs.h"
  134. #include "wgui_categories_util.h"
  135. #include "NVRAMEnum.h"
  136. #include "NVRAMProt.h"
  137. #include "NVRAMType.h"
  138. #include "custom_nvram_editor_data_item.h"
  139. #include "custom_data_account.h"
  140. #include "AlarmFrameWorkProt.h"
  141. #include "CallManagementGprot.h"
  142. #include "gpioInc.h"
  143. #include "mdi_datatype.h"
  144. #include "mdi_audio.h"
  145. #include "ProfileGprots.h"
  146. #include "wgui_status_icons.h"
  147. #include "app2soc_struct.h"
  148. #include "soc_api.h"
  149. #include "med_struct.h"
  150. #include "rtp_api.h"
  151. #include "device.h"         /* for call_status_req enum */
  152. #include "VoIPDef.h"
  153. #include "VoIPGProt.h"
  154. #include "VoIPProt.h"
  155. /*****************************************************************************
  156.  * FUNCTION
  157.  *  mmi_voip_switch_session
  158.  * DESCRIPTION
  159.  *  Start critical session based on the current state. For bluetooth SCO link,
  160.  *  session is started when outgoing call is dialing or incoming call is ringing;
  161.  *  session is ended when the last call is disconnected.
  162.  *  For MDI sound control, session is started when outgoing call is dialing or
  163.  *  incoming call is answering; session is ended when the last call is disconnected or 
  164.  *  only one incoming call exists, because session should stop first in order to play ringtone.
  165.  * PARAMETERS
  166.  *  currState       [IN]        Current state to switch session
  167.  * RETURNS
  168.  *  void
  169.  *****************************************************************************/
  170. void mmi_voip_switch_session(mmi_voip_call_state_enum currState)
  171. {
  172.     /*----------------------------------------------------------------*/
  173.     /* Local Variables                                                */
  174.     /*----------------------------------------------------------------*/
  175.     /*----------------------------------------------------------------*/
  176.     /* Code Body                                                      */
  177.     /*----------------------------------------------------------------*/
  178.     switch (currState)
  179.     {
  180.         case MMI_VOIP_OUTGOING_STATE:
  181.             if (g_voip_cntx_p->call_list_info.numTotal == 1)
  182.             {
  183.                 AlmDisableExpiryHandler();
  184.             #ifdef __MMI_BT_PROFILE__
  185.                 mmi_profiles_bt_call_start_callback();
  186.             #endif
  187.                 mmi_voip_call_status_req(UEM_CALL_SETUP); /* trigger uem to send headset key gpio detection */
  188.                 if (g_voip_cntx_p->call_list_info.inSession == FALSE)
  189.                 {
  190.                     g_voip_cntx_p->call_list_info.inSession = TRUE;
  191.                     mdi_audio_speech_session_start(MDI_AUDIO_SPEECH_APP_ID_VOIP); /* set mdi speech mode on */
  192.                     /* mmi_sndrec_auto_record_switch(MDI_AUDIO_SPEECH_APP_ID_VOIP, MMI_TRUE); */
  193.                 }
  194.             }
  195.             break;
  196.         case MMI_VOIP_INCOMING_STATE:
  197.             if (g_voip_cntx_p->call_list_info.numTotal == 1)
  198.             {
  199.                 AlmDisableExpiryHandler();
  200.             #ifdef __MMI_BT_PROFILE__
  201.                 mmi_profiles_bt_call_start_callback();
  202.             #endif
  203.                 mmi_voip_call_status_req(UEM_CALL_SETUP); /* trigger uem to send headset key gpio detection */
  204.             }
  205.             break;
  206.         case MMI_VOIP_ACTIVE_STATE:
  207.             if (g_voip_cntx_p->call_list_info.inSession == FALSE)
  208.             {
  209.                 g_voip_cntx_p->call_list_info.inSession = TRUE;
  210.                 mdi_audio_speech_session_start(MDI_AUDIO_SPEECH_APP_ID_VOIP); /* set mdi speech mode on */
  211.                 /* mmi_sndrec_auto_record_switch(MDI_AUDIO_SPEECH_APP_ID_VOIP, MMI_TRUE); */
  212.             }
  213.             break;
  214.         case MMI_VOIP_IDLE_STATE:
  215.             /* incoming call needs to play ringtone, so mdi session should stop first. 
  216.                when accepting call, mdi session should not stop */
  217.             if ((g_voip_cntx_p->call_list_info.numTotal == 1) && 
  218.                 (mmi_voip_get_incoming_call_id() != -1) && 
  219.                 (g_voip_cntx_p->call_list_info.processCId == -1))
  220.             {
  221.                 if (g_voip_cntx_p->call_list_info.inSession == TRUE)
  222.                 {
  223.                     /* mmi_sndrec_auto_record_switch(MDI_AUDIO_SPEECH_APP_ID_VOIP, MMI_FALSE); */
  224.                     mdi_audio_speech_session_stop(MDI_AUDIO_SPEECH_APP_ID_VOIP); /* set mdi speech mode off */
  225.                     g_voip_cntx_p->call_list_info.inSession = FALSE;
  226.                 }
  227.             }
  228.             else if (g_voip_cntx_p->call_list_info.numTotal == 0)
  229.             {
  230.                 if (g_voip_cntx_p->call_misc_info.isMute == TRUE)
  231.                 {
  232.                     g_voip_cntx_p->call_misc_info.isMute = FALSE;
  233.                     MuteOffMicrophone();
  234.                     HideStatusIcon(STATUS_ICON_MUTE);
  235.                     UpdateStatusIcons();
  236.                 }
  237.                 if (g_voip_cntx_p->call_misc_info.isLoud == TRUE)
  238.                 {
  239.                     g_voip_cntx_p->call_misc_info.isLoud = FALSE;
  240.                     DisbleHandsFree();
  241.                     SetLoudSpeaker(FALSE);
  242.                 }
  243.                 /* reset common structure to prevent misuse by next call */
  244.                 memset(&g_voip_cntx_p->call_misc_info, 0, sizeof(mmi_voip_call_misc_struct));
  245.                 g_voip_cntx_p->call_misc_info.isDtmf = TRUE;
  246.                 if (g_voip_cntx_p->call_list_info.inSession == TRUE)
  247.                 {
  248.                     /* mmi_sndrec_auto_record_switch(MDI_AUDIO_SPEECH_APP_ID_VOIP, MMI_FALSE); */
  249.                     mdi_audio_speech_session_stop(MDI_AUDIO_SPEECH_APP_ID_VOIP); /* set mdi speech mode off */
  250.                     g_voip_cntx_p->call_list_info.inSession = FALSE;
  251.                 }
  252.                 mmi_voip_call_status_req(UEM_CALL_DISCONNECT); /* trigger uem to send headset key gpio detection */
  253.             #ifdef __MMI_BT_PROFILE__
  254.                 /* do not turn off sco link in case gsm needs to turn on again */
  255.                 if (GetTotalCallCount() == 0)
  256.                 {
  257.                     PRINT_INFORMATION(("n[mmi_voip_switch_session] SCO Endsn"));
  258.                     mmi_profiles_bt_call_end_callback();
  259.                 }
  260.                 else
  261.                 {
  262.                     PRINT_INFORMATION(("n[mmi_voip_switch_session] SCO Not Endsn"));
  263.                 }
  264.             #endif
  265.                 mdi_audio_resume_background_play(); /* resume audio */
  266.                 AlmEnableExpiryHandler();
  267.             }
  268.             break;
  269.         default:
  270.             MMI_ASSERT(0);
  271.             break;
  272.     }
  273. }
  274. /*****************************************************************************
  275.  * FUNCTION
  276.  *  mmi_voip_create_rtp
  277.  * DESCRIPTION
  278.  *  Create RTP.
  279.  * PARAMETERS
  280.  *  sdp     [IN]        Sdp information passed by voip cc
  281.  * RETURNS
  282.  *  rtp handle that is given by voip media
  283.  *****************************************************************************/
  284. S32 mmi_voip_create_rtp(voip_sdp_struct *sdp)
  285. {
  286.     /*----------------------------------------------------------------*/
  287.     /* Local Variables                                                */
  288.     /*----------------------------------------------------------------*/
  289.     S32 rtpHandle = 0, profIndex = 0, i = 0;
  290.     U16 sdpCodec = 0;
  291.     /*----------------------------------------------------------------*/
  292.     /* Code Body                                                      */
  293.     /*----------------------------------------------------------------*/
  294.     profIndex = g_voip_cntx_p->prof_setting_info.actprofIndex;
  295.     if (sdp->num_codec == 0)
  296.     {
  297.         return -1;
  298.     }
  299.     rtpHandle = rtp_create(
  300.                     g_voip_cntx_p->prof_setting_info.saved_prof[profIndex].comm_info.dataAcct,
  301.                     sdp->local_addr,
  302.                     sdp->remote_addr,
  303.                     sdp->remote_rtp_port,
  304.                     sdp->remote_rtcp_port,
  305.                     sdp->local_rtp_port,
  306.                     sdp->local_rtcp_port,
  307.                     SOC_QOS_VOICE);
  308.     if (rtpHandle < 0)
  309.     {
  310.         PRINT_INFORMATION(("n[mmi_voip_create_rtp] Create RTP Fail, RTP Handle: %dn", rtpHandle));
  311.         return -1;
  312.     }
  313.     rtp_set_payload_type(rtpHandle, sdp->local_payload_type[0]);
  314.     if (sdp->sdp_status & VOIP_SDP_STATUS_IS_DTMF)
  315.     {
  316.         rtp_set_dtmf_payload_type(rtpHandle, sdp->dtmf_payload_type);
  317.     }
  318.     voip_set_ptime(rtpHandle, sdp->ptime);
  319.     voip_set_maxptime(rtpHandle, sdp->maxptime);
  320.     sdpCodec = sdp->codec[0];
  321.     /* g7231 annexa */
  322.     if ((sdp->codec[0] == VOIP_CODEC_G7231) && (sdp->g7231_annexa != VOIP_ANNEX_NONE))
  323.     {
  324.         switch (sdp->g7231_annexa)
  325.         {
  326.             case VOIP_ANNEX_NO:
  327.                 sdpCodec |= VOIP_CODEC_G7231_ANNEXA_PRESENT;
  328.                 break;
  329.             case VOIP_ANNEX_YES:
  330.                 sdpCodec |= VOIP_CODEC_G7231_ANNEXA_PRESENT;
  331.                 sdpCodec |= VOIP_CODEC_G7231_ANNEXA;
  332.                 break;
  333.             default:
  334.                 MMI_ASSERT(0); /* g7231_annexa should either VOIP_ANNEX_NO or VOIP_ANNEX_YES */
  335.         }
  336.     }
  337.     /* g729 annexb */
  338.     if ((sdp->codec[0] == VOIP_CODEC_G729) && (sdp->g729_annexb != VOIP_ANNEX_NONE))
  339.     {
  340.         switch (sdp->g729_annexb)
  341.         {
  342.             case VOIP_ANNEX_NO:
  343.                 sdpCodec |= VOIP_CODEC_G729_ANNEXB_PRESENT;
  344.                 break;
  345.             case VOIP_ANNEX_YES:
  346.                 sdpCodec |= VOIP_CODEC_G729_ANNEXB_PRESENT;
  347.                 sdpCodec |= VOIP_CODEC_G729_ANNEXB;
  348.                 break;
  349.             default:
  350.                 MMI_ASSERT(0); /* g729_annexb should either VOIP_ANNEX_NO or VOIP_ANNEX_YES */
  351.         }
  352.     }
  353.     
  354.     /* comfort noise */
  355.     if (g_voip_cntx_p->call_setting_info.saved_setting.comfortNoise == 0)
  356.     {
  357.         for (i = 0; i < VOIP_MAX_NUM_CODEC; i++)
  358.         {
  359.             if (sdp->codec[i] == VOIP_CODEC_CN)
  360.             {
  361.                 sdpCodec |= VOIP_CODEC_CN;
  362.                 break;
  363.             }
  364.         }
  365.     }
  366.     rtp_voip_init(rtpHandle, sdpCodec, sdp->modeset[0]);
  367.     PRINT_INFORMATION(("n[mmi_voip_create_rtp] Use to Lock Resource...Start"));
  368.     mdi_audio_speech_encode_start((S8)rtpHandle);
  369.     mdi_audio_speech_encode_stop((S8)rtpHandle);
  370.     mdi_audio_speech_decode_start((S8)rtpHandle);
  371.     mdi_audio_speech_decode_stop((S8)rtpHandle);
  372.     PRINT_INFORMATION(("n[mmi_voip_create_rtp] Use to Lock Resource...End"));
  373.     return rtpHandle;
  374. }
  375. /*****************************************************************************
  376.  * FUNCTION
  377.  *  mmi_voip_close_rtp
  378.  * DESCRIPTION
  379.  *  Close RTP.
  380.  * PARAMETERS
  381.  *  rtpHandle       [IN]        Intended to close rtp handle
  382.  * RETURNS
  383.  *  void
  384.  *****************************************************************************/
  385. void mmi_voip_close_rtp(S32 rtpHandle)
  386. {
  387.     /*----------------------------------------------------------------*/
  388.     /* Local Variables                                                */
  389.     /*----------------------------------------------------------------*/
  390.     /*----------------------------------------------------------------*/
  391.     /* Code Body                                                      */
  392.     /*----------------------------------------------------------------*/
  393.     switch (voip_curr_voip_state((S8) rtpHandle))
  394.     {
  395.         case VOIP_ENCODE:
  396.             mdi_audio_speech_encode_stop((S8) rtpHandle);
  397.             break;
  398.         case VOIP_DECODE:
  399.             mdi_audio_speech_decode_stop((S8) rtpHandle);
  400.             break;
  401.         case VOIP_ENCODE_DECODE:
  402.             mdi_audio_speech_encode_stop((S8) rtpHandle);
  403.             mdi_audio_speech_decode_stop((S8) rtpHandle);
  404.             break;
  405.         default:
  406.             break;
  407.     }
  408.     rtp_close((S8) rtpHandle);
  409. }
  410. /*****************************************************************************
  411.  * FUNCTION
  412.  *  mmi_voip_switch_rtp
  413.  * DESCRIPTION
  414.  *  Switch RTP based on the current RTP direction in the call point of view.
  415.  * PARAMETERS
  416.  *  isSuspend       [IN]        Suspend all audio paths before action
  417.  *  callId          [IN]        Call id
  418.  *  dialogId        [IN]        Dialog id
  419.  * RETURNS
  420.  *  void
  421.  *****************************************************************************/
  422. void mmi_voip_switch_rtp(BOOL isSuspend, S32 callId, S32 dialogId)
  423. {
  424.     /*----------------------------------------------------------------*/
  425.     /* Local Variables                                                */
  426.     /*----------------------------------------------------------------*/
  427.     S32 callIndex = 0, dialogIndex = 0;
  428.     S32 i = 0, j = 0, rtpHandle = 0, rtpDirection = 0, numDialog = 0;
  429.     BOOL isMixer = FALSE;
  430.     /*----------------------------------------------------------------*/
  431.     /* Code Body                                                      */
  432.     /*----------------------------------------------------------------*/
  433.     if (callId != -1)
  434.     {
  435.         callIndex = mmi_voip_get_call_index(callId);
  436.         if (dialogId != -1)
  437.         {
  438.             dialogIndex = mmi_voip_get_dialog_index(callIndex, dialogId);
  439.             rtpHandle = g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[dialogIndex].rtpHandle;
  440.             if (rtpHandle != -1)
  441.             {
  442.                 numDialog = g_voip_cntx_p->call_list_info.call_info[callIndex].numDialog;
  443.                 rtpDirection =
  444.                     (isSuspend == TRUE) ? (VOIP_RTP_DIRECTION_INACTIVE) : (g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[dialogIndex].sdp_info.direction);
  445.                 if (numDialog == VOIP_MAX_NUM_DIALOG)
  446.                 {
  447.                     isMixer = g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[dialogIndex].isMixer;
  448.                     if ((rtpDirection == VOIP_RTP_DIRECTION_SENDRECV) && (isMixer == FALSE))
  449.                     {
  450.                         mmi_voip_control_rtp(rtpHandle, rtpDirection);
  451.                         mdi_audio_speech_mixer_add((S8) rtpHandle);
  452.                         g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[dialogIndex].isMixer = TRUE;
  453.                     }
  454.                     else if ((rtpDirection != VOIP_RTP_DIRECTION_SENDRECV) && (isMixer == TRUE))
  455.                     {
  456.                         mdi_audio_speech_mixer_remove((S8) rtpHandle);
  457.                         g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[dialogIndex].isMixer = FALSE;
  458.                         mmi_voip_control_rtp(rtpHandle, rtpDirection);
  459.                     }
  460.                     else
  461.                     {
  462.                         mmi_voip_control_rtp(rtpHandle, rtpDirection);  /* remain the same */
  463.                     }
  464.                 }
  465.                 else    /* not conference call */
  466.                 {
  467.                     g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[dialogIndex].isMixer = FALSE;
  468.                     mmi_voip_control_rtp(rtpHandle, rtpDirection);
  469.                 }
  470.             }
  471.         }
  472.         else    /* dialogId == -1 */
  473.         {
  474.             for (i = 0; i < g_voip_cntx_p->call_list_info.call_info[callIndex].numDialog; i++)
  475.             {
  476.                 rtpHandle = g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].rtpHandle;
  477.                 if (rtpHandle != -1)
  478.                 {
  479.                     numDialog = g_voip_cntx_p->call_list_info.call_info[callIndex].numDialog;
  480.                     rtpDirection =
  481.                         (isSuspend == TRUE) ? (VOIP_RTP_DIRECTION_INACTIVE) : (g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].sdp_info.direction);
  482.                     if (numDialog == VOIP_MAX_NUM_DIALOG)
  483.                     {
  484.                         isMixer = g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].isMixer;
  485.                         if ((rtpDirection == VOIP_RTP_DIRECTION_SENDRECV) && (isMixer == FALSE))
  486.                         {
  487.                             mmi_voip_control_rtp(rtpHandle, rtpDirection);
  488.                             mdi_audio_speech_mixer_add((S8) rtpHandle);
  489.                             g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].isMixer = TRUE;
  490.                         }
  491.                         else if ((rtpDirection != VOIP_RTP_DIRECTION_SENDRECV) && (isMixer == TRUE))
  492.                         {
  493.                             mdi_audio_speech_mixer_remove((S8) rtpHandle);
  494.                             g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].isMixer = FALSE;
  495.                             mmi_voip_control_rtp(rtpHandle, rtpDirection);
  496.                         }
  497.                         else
  498.                         {
  499.                             mmi_voip_control_rtp(rtpHandle, rtpDirection);      /* remain the same */
  500.                         }
  501.                     }
  502.                     else    /* not conference call */
  503.                     {
  504.                         g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].isMixer = FALSE;
  505.                         mmi_voip_control_rtp(rtpHandle, rtpDirection);
  506.                     }
  507.                 }
  508.             }
  509.         }
  510.     }
  511.     else    /* callId == -1 */
  512.     {
  513.         for (i = 0; i < g_voip_cntx_p->call_list_info.numTotal; i++)
  514.         {
  515.             for (j = 0; j < g_voip_cntx_p->call_list_info.call_info[i].numDialog; j++)
  516.             {
  517.                 rtpHandle = g_voip_cntx_p->call_list_info.call_info[i].dialog_info[j].rtpHandle;
  518.                 if (rtpHandle != -1)
  519.                 {
  520.                     numDialog = g_voip_cntx_p->call_list_info.call_info[i].numDialog;
  521.                     rtpDirection =
  522.                         (isSuspend == TRUE) ? (VOIP_RTP_DIRECTION_INACTIVE) : (g_voip_cntx_p->call_list_info.call_info[i].dialog_info[j].sdp_info.direction);
  523.                     if (numDialog == VOIP_MAX_NUM_DIALOG)
  524.                     {
  525.                         isMixer = g_voip_cntx_p->call_list_info.call_info[i].dialog_info[j].isMixer;
  526.                         if ((rtpDirection == VOIP_RTP_DIRECTION_SENDRECV) && (isMixer == FALSE))
  527.                         {
  528.                             mmi_voip_control_rtp(rtpHandle, rtpDirection);
  529.                             mdi_audio_speech_mixer_add((S8) rtpHandle);
  530.                             g_voip_cntx_p->call_list_info.call_info[i].dialog_info[j].isMixer = TRUE;
  531.                         }
  532.                         else if ((rtpDirection != VOIP_RTP_DIRECTION_SENDRECV) && (isMixer == TRUE))
  533.                         {
  534.                             mdi_audio_speech_mixer_remove((S8) rtpHandle);
  535.                             g_voip_cntx_p->call_list_info.call_info[i].dialog_info[j].isMixer = FALSE;
  536.                             mmi_voip_control_rtp(rtpHandle, rtpDirection);
  537.                         }
  538.                         else
  539.                         {
  540.                             mmi_voip_control_rtp(rtpHandle, rtpDirection);      /* remain the same */
  541.                         }
  542.                     }
  543.                     else    /* not conference call */
  544.                     {
  545.                         g_voip_cntx_p->call_list_info.call_info[i].dialog_info[j].isMixer = FALSE;
  546.                         mmi_voip_control_rtp(rtpHandle, rtpDirection);
  547.                     }
  548.                 }
  549.             }
  550.         }
  551.     }
  552. }
  553. /*****************************************************************************
  554.  * FUNCTION
  555.  *  mmi_voip_control_rtp
  556.  * DESCRIPTION
  557.  *  Switch RTP based on the current RTP direction in the RTP point of view.
  558.  * PARAMETERS
  559.  *  rtpHandle           [IN]        Rtp handle
  560.  *  rtpDirection        [IN]        Rtp direction
  561.  * RETURNS
  562.  *  void
  563.  *****************************************************************************/
  564. void mmi_voip_control_rtp(S32 rtpHandle, S32 rtpDirection)
  565. {
  566.     /*----------------------------------------------------------------*/
  567.     /* Local Variables                                                */
  568.     /*----------------------------------------------------------------*/
  569.     /*----------------------------------------------------------------*/
  570.     /* Code Body                                                      */
  571.     /*----------------------------------------------------------------*/
  572.     switch (rtpDirection)
  573.     {
  574.         case VOIP_RTP_DIRECTION_SENDRECV:                   /*  send and receive */
  575.             switch (voip_curr_voip_state((S8) rtpHandle))   /* ensure not to set encoding / decoding twice */
  576.             {
  577.                 case VOIP_IDLE:
  578.                     mdi_audio_speech_encode_start((S8) rtpHandle);
  579.                     mdi_audio_speech_decode_start((S8) rtpHandle);
  580.                     break;
  581.                 case VOIP_ENCODE:
  582.                     mdi_audio_speech_decode_start((S8) rtpHandle);
  583.                     break;
  584.                 case VOIP_DECODE:
  585.                     mdi_audio_speech_encode_start((S8) rtpHandle);
  586.                     break;
  587.                 case VOIP_ENCODE_DECODE:
  588.                     break;
  589.                 default:
  590.                     MMI_ASSERT(0);
  591.                     break;
  592.             }
  593.             break;
  594.         #if 0   /* implement send only as inactive */
  595. /* under construction !*/
  596. /* under construction !*/
  597. /* under construction !*/
  598. /* under construction !*/
  599. /* under construction !*/
  600. /* under construction !*/
  601. /* under construction !*/
  602. /* under construction !*/
  603. /* under construction !*/
  604. /* under construction !*/
  605. /* under construction !*/
  606. /* under construction !*/
  607. /* under construction !*/
  608. /* under construction !*/
  609. /* under construction !*/
  610. /* under construction !*/
  611. /* under construction !*/
  612. /* under construction !*/
  613. /* under construction !*/
  614. /* under construction !*/
  615.         #endif /* 0 */ 
  616.         case VOIP_RTP_DIRECTION_RECVONLY:                   /*  receive only */
  617.             switch (voip_curr_voip_state((S8) rtpHandle))   /* ensure not to set encoding / decoding twice */
  618.             {
  619.                 case VOIP_IDLE:
  620.                     mdi_audio_speech_decode_start((S8) rtpHandle);
  621.                     break;
  622.                 case VOIP_ENCODE:
  623.                     mdi_audio_speech_encode_stop((S8) rtpHandle);
  624.                     mdi_audio_speech_decode_start((S8) rtpHandle);
  625.                     break;
  626.                 case VOIP_DECODE:
  627.                     break;
  628.                 case VOIP_ENCODE_DECODE:
  629.                     mdi_audio_speech_encode_stop((S8) rtpHandle);
  630.                     break;
  631.                 default:
  632.                     MMI_ASSERT(0);
  633.                     break;
  634.             }
  635.             break;
  636.         case VOIP_RTP_DIRECTION_SENDONLY:                   /*  send only */
  637.         case VOIP_RTP_DIRECTION_INACTIVE:                   /*  rtp session suspends */
  638.             switch (voip_curr_voip_state((S8) rtpHandle))   /* ensure not to set encoding / decoding twice */
  639.             {
  640.                 case VOIP_IDLE:
  641.                     break;
  642.                 case VOIP_ENCODE:
  643.                     mdi_audio_speech_encode_stop((S8) rtpHandle);
  644.                     break;
  645.                 case VOIP_DECODE:
  646.                     mdi_audio_speech_decode_stop((S8) rtpHandle);
  647.                     break;
  648.                 case VOIP_ENCODE_DECODE:
  649.                     mdi_audio_speech_encode_stop((S8) rtpHandle);
  650.                     mdi_audio_speech_decode_stop((S8) rtpHandle);
  651.                     break;
  652.                 default:
  653.                     MMI_ASSERT(0);
  654.                     break;
  655.             }
  656.             break;
  657.         default:
  658.             MMI_ASSERT(0);
  659.     }
  660. }
  661. /*****************************************************************************
  662.  * FUNCTION
  663.  *  mmi_voip_remove_mixer_before_close
  664.  * DESCRIPTION
  665.  *  Remove mixer if any before closeing RTP.
  666.  * PARAMETERS
  667.  *  callIndex       [IN]        Call index
  668.  * RETURNS
  669.  *  void
  670.  *****************************************************************************/
  671. void mmi_voip_remove_mixer_before_close(S32 callIndex)
  672. {
  673.     /*----------------------------------------------------------------*/
  674.     /* Local Variables                                                */
  675.     /*----------------------------------------------------------------*/
  676.     S32 i = 0;
  677.     /*----------------------------------------------------------------*/
  678.     /* Code Body                                                      */
  679.     /*----------------------------------------------------------------*/
  680.     for (i = 0; i < VOIP_MAX_NUM_DIALOG; i++)
  681.     {
  682.         if (g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].isMixer == TRUE)
  683.         {
  684.             mdi_audio_speech_mixer_remove((S8) g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].rtpHandle);
  685.             g_voip_cntx_p->call_list_info.call_info[callIndex].dialog_info[i].isMixer = FALSE;
  686.         }
  687.     }
  688. }
  689. /*****************************************************************************
  690.  * FUNCTION
  691.  *  mmi_voip_send_dtmf_start
  692.  * DESCRIPTION
  693.  *  Send DTMF sound to remote side.
  694.  * PARAMETERS
  695.  *  void
  696.  * RETURNS
  697.  *  void
  698.  *****************************************************************************/
  699. void mmi_voip_send_dtmf_start(void)
  700. {
  701.     /*----------------------------------------------------------------*/
  702.     /* Local Variables                                                */
  703.     /*----------------------------------------------------------------*/
  704.     S32 i = 0, currhiliteTab = 0, numDialog = 0, rtpHandle[VOIP_MAX_NUM_DIALOG];
  705.     U16 keyCode = 0, keyType = 0;
  706.     BOOL outbandDtmf = FALSE;
  707.     /*----------------------------------------------------------------*/
  708.     /* Code Body                                                      */
  709.     /*----------------------------------------------------------------*/
  710.     currhiliteTab = g_voip_cntx_p->call_misc_info.currhiliteTab;
  711.     numDialog = g_voip_cntx_p->call_list_info.call_info[currhiliteTab].numDialog;
  712.     for (i = 0; i < numDialog; i++)
  713.     {
  714.         /* only send dtmf to the dialog that encoding is started */
  715.         if (g_voip_cntx_p->call_list_info.call_info[currhiliteTab].dialog_info[i].sdp_info.direction == VOIP_RTP_DIRECTION_SENDRECV)
  716.         {
  717.             rtpHandle[i] = g_voip_cntx_p->call_list_info.call_info[currhiliteTab].dialog_info[i].rtpHandle;
  718.             outbandDtmf = (g_voip_cntx_p->call_list_info.call_info[currhiliteTab].dialog_info[i].sdp_info.sdp_status & VOIP_SDP_STATUS_IS_DTMF);
  719.         }
  720.         else
  721.         {
  722.             rtpHandle[i] = -1;
  723.         }
  724.     }
  725.     if (numDialog == VOIP_MAX_NUM_DIALOG)
  726.     {
  727.         /* always send inband dtmf for conference call in case one dialog is inband and the other is outband */
  728.         outbandDtmf = FALSE;
  729.     }    
  730.     PRINT_INFORMATION(("n[mmi_voip_send_dtmf_start] Local DTMF: %d, Remote DTMF: %dn", g_voip_cntx_p->call_setting_info.saved_setting.dtmf, outbandDtmf));
  731.     GetkeyInfo(&keyCode, &keyType);
  732.     if (mmi_voip_validate_dtmf(keyCode))
  733.     {
  734.         if (g_voip_cntx_p->call_setting_info.saved_setting.dtmf == VOIP_DTMF_TYPE_NONE)
  735.         {
  736.             /* do nothing */
  737.         }
  738.         else if ((g_voip_cntx_p->call_setting_info.saved_setting.dtmf == VOIP_DTMF_IN_BAND) || 
  739.                  (outbandDtmf == FALSE)) /* remote doesn't support outband dtmf */
  740.         {
  741.             if (g_voip_cntx_p->call_misc_info.isMute == FALSE)
  742.             {
  743.                 MuteOnMicrophone(); /* temporarily turn off microphone */
  744.             }
  745.             for (i = 0; i < numDialog; i++)
  746.             {
  747.                 if (rtpHandle[i] != -1)
  748.                 {
  749.                     mdi_audio_speech_dtmf_start(
  750.                         rtpHandle[i],
  751.                         mmi_voip_get_dtmf_keycode_enum(&keyCode),
  752.                         RTP_DTMF_TYPE_INBAND);
  753.                 }
  754.             }
  755.         }
  756.         /* send outband dtmf only if both local and remote support outband dtmf */
  757.         else if ((g_voip_cntx_p->call_setting_info.saved_setting.dtmf == VOIP_DTMF_OUT_OF_BAND) && 
  758.                  (outbandDtmf == TRUE))
  759.         {
  760.             if (g_voip_cntx_p->call_misc_info.isMute == FALSE)
  761.             {
  762.                 MuteOnMicrophone(); /* temporarily turn off microphone */
  763.             }
  764.             for (i = 0; i < numDialog; i++)
  765.             {
  766.                 if (rtpHandle[i] != -1)
  767.                 {
  768.                     mdi_audio_speech_dtmf_start(
  769.                         rtpHandle[i],
  770.                         mmi_voip_get_dtmf_keycode_enum(&keyCode),
  771.                         RTP_DTMF_TYPE_RFC2833);
  772.                 }
  773.             }
  774.         }
  775.     }
  776.     wgui_execute_key_handler(keyCode, keyType);
  777. }
  778. /*****************************************************************************
  779.  * FUNCTION
  780.  *  mmi_voip_send_dtmf_stop
  781.  * DESCRIPTION
  782.  *  Stop DTMF sound to remote side.
  783.  * PARAMETERS
  784.  *  void
  785.  * RETURNS
  786.  *  void
  787.  *****************************************************************************/
  788. void mmi_voip_send_dtmf_stop(void)
  789. {
  790.     /*----------------------------------------------------------------*/
  791.     /* Local Variables                                                */
  792.     /*----------------------------------------------------------------*/
  793.     S32 i = 0, currhiliteTab = 0, numDialog = 0, rtpHandle[VOIP_MAX_NUM_DIALOG];
  794.     /*----------------------------------------------------------------*/
  795.     /* Code Body                                                      */
  796.     /*----------------------------------------------------------------*/
  797.     currhiliteTab = g_voip_cntx_p->call_misc_info.currhiliteTab;
  798.     numDialog = g_voip_cntx_p->call_list_info.call_info[currhiliteTab].numDialog;
  799.     for (i = 0; i < numDialog; i++)
  800.     {
  801.         /* only send dtmf to the dialog that encoding is started */
  802.         if (g_voip_cntx_p->call_list_info.call_info[currhiliteTab].dialog_info[i].sdp_info.direction == VOIP_RTP_DIRECTION_SENDRECV)
  803.         {
  804.             rtpHandle[i] = g_voip_cntx_p->call_list_info.call_info[currhiliteTab].dialog_info[i].rtpHandle;
  805.         }
  806.         else
  807.         {
  808.             rtpHandle[i] = -1;
  809.         }
  810.     } 
  811.     if (g_voip_cntx_p->call_setting_info.saved_setting.dtmf != VOIP_DTMF_TYPE_NONE)
  812.     {
  813.         if (g_voip_cntx_p->call_misc_info.isMute == FALSE)
  814.         {
  815.             MuteOffMicrophone();
  816.         }
  817.         for (i = 0; i < numDialog; i++)
  818.         {
  819.             if (rtpHandle[i] != -1)
  820.             {
  821.                 mdi_audio_speech_dtmf_stop(rtpHandle[i]);
  822.             }
  823.         }
  824.     }
  825.     else    /* g_voip_cntx_p->call_setting_info.saved_setting.dtmf == VOIP_DTMF_TYPE_NONE */
  826.     {
  827.         /* do nothing */
  828.     }
  829. }
  830. #endif /* __MMI_VOIP__ */