diff g23m/condat/ms/src/aci/cmh_ccf.c @ 0:509db1a7b7b8

initial import: leo2moko-r1
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 01 Jun 2015 03:24:05 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/g23m/condat/ms/src/aci/cmh_ccf.c	Mon Jun 01 03:24:05 2015 +0000
@@ -0,0 +1,2915 @@
+/*
++-----------------------------------------------------------------------------
+|  Project :  GSM-PS (6147)
+|  Modul   :  CMH_CCF
++-----------------------------------------------------------------------------
+|  Copyright 2002 Texas Instruments Berlin, AG
+|                 All rights reserved.
+|
+|                 This file is confidential and a trade secret of Texas
+|                 Instruments Berlin, AG
+|                 The receipt of or possession of this file does not convey
+|                 any rights to reproduce or disclose its contents or to
+|                 manufacture, use, or sell anything it may describe, in
+|                 whole, or in part, without the specific written consent of
+|                 Texas Instruments Berlin, AG.
++-----------------------------------------------------------------------------
+|  Purpose :  This module defines the functions used by the command
+|             handler for call control.
++-----------------------------------------------------------------------------
+*/
+
+#ifndef CMH_CCF_C
+#define CMH_CCF_C
+#endif
+
+#include "aci_all.h"
+
+/*==== INCLUDES ===================================================*/
+
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+#include "aci_cmd.h"
+#include "aci_mem.h"
+
+#ifdef FAX_AND_DATA
+#include "aci_fd.h"
+#endif
+
+#ifdef FF_TTY
+#include "audio.h"
+#endif
+
+#include "aci_io.h"
+
+#include "phb.h"
+#include "ksd.h"
+#include "aoc.h"
+#include "aci.h"
+#include "psa.h"
+#include "psa_cc.h"
+#include "psa_ss.h"
+#include "psa_util.h"
+#include "cmh.h"
+#include "cmh_cc.h"
+#include "cmh_ss.h"
+#include "cmh_phb.h"
+
+#include "aci_lst.h"
+
+#ifdef DTI
+#include "dti.h"      /* functionality of the dti library */
+#include "dti_conn_mng.h"
+#include "dti_cntrl_mng.h"
+#endif
+
+#ifdef UART
+#include "psa_uart.h"
+#include "cmh_uart.h"
+#endif
+
+#ifdef FAX_AND_DATA
+
+#include "psa_ra.h"
+#include "cmh_ra.h"
+#include "psa_l2r.h"
+#include "cmh_l2r.h"
+
+#ifdef FF_FAX
+#include "psa_t30.h"
+#include "cmh_t30.h"
+#endif /* FF_FAX */
+
+#endif /* FAX_AND_DATA */
+
+#if defined (FF_WAP) || defined (FF_TCP_IP) || defined(FF_GPF_TCPIP) || defined (FF_SAT_E)
+#include "wap_aci.h"
+#include "psa_ppp_w.h"
+#include "cmh_ppp.h"
+#endif /* of FF_WAP or FF_TCP_IP  || (FF_GPF_TCPIP)|| (FF_SAT_E)*/
+
+#ifdef FF_GPF_TCPIP
+#include "dcm_utils.h"
+#include "dcm_state.h"
+#include "dcm_env.h"
+#endif
+
+#ifdef SIM_TOOLKIT
+#include "psa_sat.h"
+#include "cmh_sat.h"
+#include "psa_sim.h"
+#endif
+
+#ifdef FF_PSI
+#include "psa_psi.h"
+#include "cmh_psi.h"
+#endif /*FF_PSI*/
+#include "l4_tim.h"
+
+#if defined(_TARGET_)
+#include "ffs/ffs.h"
+#include "ffs_coat.h"
+#endif /* _TARGET_ */
+
+#include "dcm_f.h"
+
+/*==== CONSTANTS ==================================================*/
+#define   ACI_MAX_DIAL_SHORT_STRING_LEN     2
+EXTERN T_ACI_CC_REDIAL_BLACKL * cc_blacklist_ptr;
+/*==== TYPES ======================================================*/
+
+/*==== EXPORT =====================================================*/
+
+/*==== VARIABLES ==================================================*/
+GLOBAL T_ACI_CUSCFG_PARAMS cuscfgParams;
+
+/*==== FUNCTIONS ==================================================*/
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH                     |
+|                                 ROUTINE : cmhCC_PrepareCmdEnd     |
++-------------------------------------------------------------------+
+
+  PURPOSE : Prepares the end of a CC related AT command.
+            cId describes a valid (non-NULL) call table entry.
+
+*/
+
+GLOBAL void cmhCC_PrepareCmdEnd (SHORT cId, UBYTE *cmdBuf, UBYTE *srcBuf)
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+
+  if (cmdBuf NEQ NULL)
+    *cmdBuf = ctb->curCmd;
+  if (srcBuf NEQ NULL)
+    *srcBuf = ctb->curSrc;
+  ctb->curCmd = AT_CMD_NONE;
+  ctb->curSrc = CMD_SRC_NONE;
+}
+
+
+GLOBAL UBYTE cmhCC_set_speech_serv (T_CC_CMD_PRM  *pCCCmdPrm)
+{
+#ifdef FF_TTY
+  UBYTE ctmReq;
+
+  /* check temporary inversion of CTM service request */
+  if (!ccShrdPrm.ctmOvwr)
+  {
+    ctmReq = ccShrdPrm.ctmReq;
+  }
+  else
+  {
+    if (ccShrdPrm.ctmReq EQ CTM_ENABLED)
+    {
+      ctmReq = CTM_DISABLED;
+      ccShrdPrm.ttyCmd = (UBYTE)TTY_OFF;
+    }
+    else
+    {
+      ctmReq = CTM_ENABLED;
+      ccShrdPrm.ttyCmd = (UBYTE)TTY_ALL;
+    }
+    /* reset temporary inversion */
+    ccShrdPrm.ctmOvwr = FALSE;
+  }
+#endif /* FF_TTY */
+#ifdef FF_TTY
+  if (ctmReq EQ CTM_ENABLED)
+  {
+    if (ccShrdPrm.ctmState EQ TTY_STATE_NONE)
+    {
+      ccShrdPrm.ctmState = TTY_STATE_IDLE;
+    }
+    if (pCCCmdPrm->ALSmode EQ ALS_MOD_AUX_SPEECH)
+    {
+      return BEARER_SERV_AUX_SPEECH_CTM;
+    }
+    else
+    {
+      return BEARER_SERV_SPEECH_CTM;
+    }
+  }
+  else
+#endif /* FF_TTY */
+  {
+#ifdef FF_TTY
+    if (ccShrdPrm.ctmState EQ TTY_STATE_IDLE)
+    {
+      ccShrdPrm.ctmState = TTY_STATE_NONE;
+    }
+#endif /* FF_TTY */
+    if (pCCCmdPrm->ALSmode EQ ALS_MOD_AUX_SPEECH)
+    {
+      return BEARER_SERV_AUX_SPEECH;
+    }
+  }
+  return BEARER_SERV_SPEECH;
+}
+
+GLOBAL T_ACI_RETURN cmhCC_chkShortString (T_ACI_CMD_SRC srcId,
+                                          SHORT         cId,
+                                          T_CLPTY_PRM   *cldPty)
+{
+  USHORT              num_len;
+  T_ACI_KSD_USSD_PRM  ksdString;
+
+  num_len = strlen (cldPty->num);
+
+  /* check the length */
+  if (!num_len OR (num_len > ACI_MAX_DIAL_SHORT_STRING_LEN))
+  {
+    return (AT_EXCT);
+  }
+
+  ksdString.ussd = (UBYTE*)cldPty->num;
+
+  /* check if MS is in a call */
+  if (cId NEQ NO_ENTRY)
+  {
+    /* call is active */
+    return (cmhSS_ksdUSSD (srcId, &ksdString));
+  }
+
+  /* check if input string is 2 digit starting with a 1 */
+  if ((num_len EQ ACI_MAX_DIAL_SHORT_STRING_LEN) AND
+      (*(cldPty->num) EQ '1') OR cuscfgParams.Two_digit_MO_Call)
+  {
+    /* normal dial */
+    return (AT_EXCT);
+  }
+
+  return (cmhSS_ksdUSSD (srcId, &ksdString));
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH                     |
+|                                 ROUTINE : cmhCC_find_call_for_DTMF|
++-------------------------------------------------------------------+
+
+  PURPOSE :searches for a call where it is possible to
+             send DTMF tones.
+*/
+GLOBAL BOOL is_call_ok_for_dtmf( SHORT cId )
+{
+  T_CC_CALL_TYPE calltype = cmhCC_getcalltype(cId);
+
+  if(calltype NEQ VOICE_CALL)
+  {
+    TRACE_EVENT_P1("calltype NEQ VOICE_CALL: %d", calltype);
+    return(FALSE);
+  }
+
+  if (ccShrdPrm.ctb[cId] EQ NULL)
+  {
+    TRACE_EVENT("ccShrdPrm.ctb[cId] EQ NULL");
+    return(FALSE);
+  }
+
+  switch(psaCC_ctb(cId)->calStat)
+  {
+    case(CS_ACT):
+    case(CS_ACT_REQ):
+    case(CS_DSC_REQ):
+    case(CS_CPL_REQ):
+      return(TRUE);
+
+    default:
+      TRACE_EVENT_P1("unexpected call status: %d", psaCC_ctb(cId)->calStat);
+      return(FALSE);
+  }
+}
+
+GLOBAL SHORT cmhCC_find_call_for_DTMF( void )
+{
+  SHORT ctbIdx;        /* holds call table index */
+
+  TRACE_FUNCTION("cmhCC_find_call_for_DTMF");
+
+  for( ctbIdx = 0; ctbIdx < MAX_CALL_NR; ctbIdx++ )
+  {
+    if( is_call_ok_for_dtmf(ctbIdx) )
+    {
+      return(ctbIdx);
+    }
+  }
+  return( NO_ENTRY );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH                     |
+|                                 ROUTINE : cmhCC_SendDTMFdig       |
++-------------------------------------------------------------------+
+
+  PURPOSE : send a DTMF digit for that call.
+    return value: TRUE if digit has been correctly proceeded.
+                  FALSE if an error occured.
+*/
+
+GLOBAL BOOL cmhCC_SendDTMFdig( T_ACI_AT_CMD cmd, SHORT cId, CHAR digit, UBYTE mode)
+{
+  TRACE_FUNCTION("cmhCC_SendDTMFdig");
+
+  TRACE_EVENT_P1("Sending DTMF tone: %d", digit);
+
+  switch( digit )
+  {
+    case( '0' ):
+    case( '1' ):
+    case( '2' ):
+    case( '3' ):
+    case( '4' ):
+    case( '5' ):
+    case( '6' ):
+    case( '7' ):
+    case( '8' ):
+    case( '9' ):
+    case( '*' ):
+    case( '#' ):
+    case( 'A' ):
+    case( 'B' ):
+    case( 'C' ):
+    case( 'D' ):
+      psaCC_SendDTMF( cId, digit, mode );
+      return( TRUE );
+
+    case( 'W' ):   /* FIXME: w should prompt the user for starting sending the following DTMF tones */
+    case( 'w' ):   /* since BMI does not support 'w' we assume to be the same as 'p' */
+    case( 'P' ):
+    case( 'p' ):
+      if(cmd NEQ AT_CMD_VTS)  /* this is only valid within a number to dial */
+      {
+        /* p within a number string: this is a 3 seconds pause */
+        TRACE_EVENT("DTMF pause requested: 3 seconds");
+#if defined (NEW_FRAME)
+        TIMERSTART( TDTMF_VALUE, ACI_TDTMF );
+#else
+        TIMERSTART( TDTMF_VALUE, t_dtmf_handle );
+#endif
+        return( TRUE );
+      }
+      /* fallthrough for else */
+      /*lint -fallthrough*/
+    default:
+      TRACE_EVENT_P1("Invalid DTMF digit: %d", digit);
+  }
+  return( FALSE );
+}
+
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SelRate           |
++-------------------------------------------------------------------+
+
+  PURPOSE : select the user rate out of the current speed setting
+
+*/
+
+GLOBAL UBYTE cmhCC_SelRate ( T_ACI_BS_SPEED speed )
+{
+  switch( speed )
+  {
+  case( BS_SPEED_300_V21      ):
+  case( BS_SPEED_300_V110     ): return( UR_0_3_KBIT );
+  case( BS_SPEED_1200_V22     ):
+  case( BS_SPEED_1200_V120    ):
+  case( BS_SPEED_1200_V110    ): return( UR_1_2_KBIT );
+  case( BS_SPEED_1200_75_V23  ): return( UR_1_2_KBIT_V23 );
+  case( BS_SPEED_2400_V22bis  ):
+  case( BS_SPEED_2400_V26ter  ):
+  case( BS_SPEED_2400_V120    ):
+  case( BS_SPEED_2400_V110    ): return( UR_2_4_KBIT );
+  case( BS_SPEED_4800_V32     ):
+  case( BS_SPEED_4800_V120    ):
+  case( BS_SPEED_4800_V110    ): return( UR_4_8_KBIT );
+  case( BS_SPEED_AUTO         ):
+  case( BS_SPEED_9600_V32     ):
+  case( BS_SPEED_9600_V34     ):
+  case( BS_SPEED_9600_V120    ):
+  case( BS_SPEED_9600_V110    ): return( UR_9_6_KBIT );
+  case( BS_SPEED_14400_V34    ):
+  case( BS_SPEED_14400_V120   ):
+  case( BS_SPEED_14400_V110   ): return( UR_14_4_KBIT );
+  default:                       return( UR_NOT_PRES  );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SelMT             |
++-------------------------------------------------------------------+
+
+  PURPOSE : select the modem type out of the current speed setting
+
+*/
+
+GLOBAL UBYTE cmhCC_SelMT ( T_ACI_BS_SPEED speed )
+{
+  switch( speed )
+  {
+  case( BS_SPEED_300_V21      ): return( MT_V21 );
+  case( BS_SPEED_1200_V22     ): return( MT_V22 );
+  case( BS_SPEED_2400_V22bis  ): return( MT_V22_BIS );
+  case( BS_SPEED_1200_75_V23  ): return( MT_V23 );
+  case( BS_SPEED_2400_V26ter  ): return( MT_V26_TER );
+  case( BS_SPEED_9600_V32     ):
+  case( BS_SPEED_4800_V32     ): return( MT_V32 );
+  case( BS_SPEED_1200_V120    ):
+  case( BS_SPEED_2400_V120    ):
+  case( BS_SPEED_4800_V120    ):
+  case( BS_SPEED_9600_V120    ):
+  case( BS_SPEED_14400_V120   ):
+  case( BS_SPEED_2400_V110    ):
+  case( BS_SPEED_4800_V110    ):
+  case( BS_SPEED_9600_V110    ):
+  case( BS_SPEED_14400_V110   ):
+  case( BS_SPEED_300_V110     ):
+  case( BS_SPEED_1200_V110    ): return( MT_NONE );
+  case( BS_SPEED_9600_V34     ):
+  case( BS_SPEED_14400_V34    ): return( MT_V34 );
+  default:                       return( MT_AUTOBAUD  );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SelServ           |
++-------------------------------------------------------------------+
+
+  PURPOSE : select the bearer service out of the current name setting
+
+*/
+
+GLOBAL UBYTE cmhCC_SelServ ( T_ACI_CBST_NAM name )
+{
+  switch( name )
+  {
+  case( CBST_NAM_Asynch ): return( BEARER_SERV_ASYNC );
+  case( CBST_NAM_Synch  ): return( BEARER_SERV_SYNC );
+  default:                 return( BEARER_SERV_NOT_PRES );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SelCE             |
++-------------------------------------------------------------------+
+
+  PURPOSE : select the connection element out of the current ce setting
+
+*/
+
+GLOBAL UBYTE cmhCC_SelCE ( T_ACI_CBST_CE ce )
+{
+  switch( ce )
+  {
+  case( CBST_CE_Transparent      ): return( CONN_ELEM_TRANS );
+  case( CBST_CE_NonTransparent   ): return( CONN_ELEM_NON_TRANS );
+  case( CBST_CE_BothTransPref    ): return( CONN_ELEM_TRANS_PREF );
+  case( CBST_CE_BothNonTransPref ): return( CONN_ELEM_NON_TRANS_PREF );
+  default:                          return( CONN_ELEM_NOT_PRES );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SelStopBit        |
++-------------------------------------------------------------------+
+
+  PURPOSE : select the stop bits out of the current character framing
+            setting
+
+*/
+
+GLOBAL UBYTE cmhCC_SelStopBit ( T_ACI_CMD_SRC srcId )
+{
+#ifdef UART
+  if (UART_IO_SB_2 EQ cmhUART_GetStopBitOverSrcID( (UBYTE) srcId ))
+  {
+    return( STOP_2_BIT );
+  }
+#endif /*UART*/
+#if defined (FF_PSI) AND defined (DTI)
+  if (UART_IO_SB_2 EQ cmhPSI_GetStopBitOverSrcID( (UBYTE) srcId ))
+  {
+    return( STOP_2_BIT );
+  }
+#endif /*FF_PSI*/
+
+  return( STOP_1_BIT );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SelDataBit        |
++-------------------------------------------------------------------+
+
+  PURPOSE : select the data bits out of the current character framing
+            setting
+
+*/
+
+GLOBAL UBYTE cmhCC_SelDataBit ( T_ACI_CMD_SRC srcId )
+{
+#ifdef UART
+  if ( UART_IO_BPC_7 EQ cmhUART_GetDataBitOverSrcID( (UBYTE) srcId ))
+
+  {
+    return( DATA_7_BIT );
+  }
+#endif /*UART*/
+
+#if defined (FF_PSI) AND defined (DTI)
+  if ( UART_IO_BPC_7 EQ cmhPSI_GetDataBitOverSrcID( (UBYTE) srcId ) )
+  {
+    return( DATA_7_BIT );
+  }
+#endif /*FF_PSI*/
+
+  return( DATA_8_BIT );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SelParity         |
++-------------------------------------------------------------------+
+
+  PURPOSE : select the data bits out of the current character framing
+            setting
+
+*/
+
+GLOBAL UBYTE cmhCC_SelParity ( T_ACI_CMD_SRC srcId )
+{
+  UBYTE parity=0;
+#if defined (FF_PSI) AND defined (DTI)
+  T_ACI_DTI_PRC_PSI  *src_infos = find_element (psi_src_params,
+                         (UBYTE)srcId, cmhPSItest_srcId);
+
+  if (src_infos EQ NULL)
+#endif /*FF_PSI*/
+
+#ifdef UART
+    parity =  cmhUART_GetParityOverSrcID( (UBYTE) srcId );
+#else /*UART*/
+    parity=0;
+#endif /*UART*/
+
+#if defined (FF_PSI) AND defined (DTI)
+  else
+    parity =  cmhPSI_GetParityOverSrcID( (UBYTE) srcId );
+#endif /*FF_PSI*/
+#ifdef UART
+  switch( parity )
+  {
+    case UART_IO_PA_NONE:                 return( PARITY_NONE );
+    case UART_IO_PA_EVEN:                 return( PARITY_EVEN );
+    case UART_IO_PA_ODD:                  return( PARITY_ODD );
+    case UART_IO_PA_SPACE:                return( PARITY_FORCED_TO_0 );
+    case NOT_SUPPORTED_UART_IO_PA_MARK:   return( PARITY_FORCED_TO_1 );
+    default:                              TRACE_EVENT( "UNEXP PARITY IN ICF" );
+  }
+#endif /*UART*/
+  return( PARITY_NONE );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_GetCallType       |
++-------------------------------------------------------------------+
+
+  PURPOSE : get call type out of bearer capabilities
+
+*/
+
+GLOBAL SHORT cmhCC_GetCallType_from_bearer ( void * bearCap )
+{
+  T_bcpara * pBC = (T_bcpara*) bearCap;
+
+  switch( pBC->bearer_serv )
+  {
+  case( BEARER_SERV_SYNC          ):
+    switch( pBC -> conn_elem )
+    {
+    case( CONN_ELEM_TRANS         ): return( CRING_TYP_Sync );
+    case( CONN_ELEM_NON_TRANS     ): return( CRING_TYP_RelSync );
+    default:                         TRACE_EVENT( "UNEXP CONN ELEMENT IN CTB" );
+    /*lint -fallthrough*/
+    case( CONN_ELEM_NOT_PRES      ): return( CRING_TYP_NotPresent );
+    }
+
+  case( BEARER_SERV_ASYNC         ):
+    switch( pBC -> conn_elem )
+    {
+    case( CONN_ELEM_TRANS         ): return( CRING_TYP_Async );
+    case( CONN_ELEM_NON_TRANS     ): return( CRING_TYP_RelAsync );
+    default:                         TRACE_EVENT( "UNEXP CONN ELEMENT IN CTB" );
+    /*lint -fallthrough*/
+    case( CONN_ELEM_NOT_PRES      ): return( CRING_TYP_NotPresent );
+    }
+
+  case( BEARER_SERV_FAX           ): return( CRING_TYP_Fax );
+
+  case( BEARER_SERV_SPEECH_CTM    ):
+  case( BEARER_SERV_SPEECH        ): return( CRING_TYP_Voice );
+
+  case( BEARER_SERV_AUX_SPEECH_CTM):
+  case( BEARER_SERV_AUX_SPEECH    ): return( CRING_TYP_AuxVoice );
+
+  default:                           TRACE_EVENT( "UNEXP BEARER SERVICE IN CTB" );
+  /*lint -fallthrough*/
+  case( BEARER_SERV_PAD_ACCESS    ):
+  case( BEARER_SERV_PACKET_ACCESS ):
+  case( BEARER_SERV_NOT_PRES      ): return( CRING_TYP_NotPresent );
+
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_GetSrvType        |
++-------------------------------------------------------------------+
+
+  PURPOSE : get service type out of bearer capabilities
+
+*/
+
+GLOBAL SHORT cmhCC_GetSrvType ( void * bearCap )
+{
+  T_bcpara * pBC = (T_bcpara*) bearCap;
+
+  switch( pBC->bearer_serv )
+  {
+  case( BEARER_SERV_SYNC          ):
+    switch( pBC -> conn_elem )
+    {
+    case( CONN_ELEM_TRANS         ): return( CR_SERV_Sync );
+    case( CONN_ELEM_NON_TRANS     ): return( CR_SERV_RelSync );
+    default:                         TRACE_EVENT( "UNEXP CONN ELEMENT IN CTB" );
+    /*lint -fallthrough*/
+    case( CONN_ELEM_NOT_PRES      ): return( CR_SERV_NotPresent );
+    }
+
+  case( BEARER_SERV_ASYNC         ):
+    switch( pBC -> conn_elem )
+    {
+    case( CONN_ELEM_TRANS         ): return( CR_SERV_Async );
+    case( CONN_ELEM_NON_TRANS     ): return( CR_SERV_RelAsync );
+    default:                         TRACE_EVENT( "UNEXP CONN ELEMENT IN CTB" );
+    /*lint -fallthrough*/
+    case( CONN_ELEM_NOT_PRES      ): return( CR_SERV_NotPresent );
+    }
+
+  default:                           TRACE_EVENT( "UNEXP BEARER SERVICE IN CTB" );
+  /*lint -fallthrough*/
+  case( BEARER_SERV_FAX           ):
+  case( BEARER_SERV_SPEECH_CTM    ):
+  case( BEARER_SERV_AUX_SPEECH_CTM):
+  case( BEARER_SERV_SPEECH        ):
+  case( BEARER_SERV_AUX_SPEECH    ):
+  case( BEARER_SERV_PAD_ACCESS    ):
+  case( BEARER_SERV_PACKET_ACCESS ):
+  case( BEARER_SERV_NOT_PRES      ): return( CR_SERV_NotPresent );
+
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_GetDataRate       |
++-------------------------------------------------------------------+
+
+  PURPOSE : get user data rate out of bearer capabilities
+
+*/
+
+GLOBAL SHORT cmhCC_GetDataRate ( void * bearCap )
+{
+  T_bcpara * pBC = (T_bcpara*) bearCap;
+
+  switch( pBC->rate )
+  {
+  case( UR_0_3_KBIT  ): return( BS_SPEED_300_V110   );
+  case( UR_1_2_KBIT  ): return( BS_SPEED_1200_V110  );
+  case( UR_2_4_KBIT  ): return( BS_SPEED_2400_V110  );
+  case( UR_4_8_KBIT  ): return( BS_SPEED_4800_V110  );
+  case( UR_9_6_KBIT  ): return( BS_SPEED_9600_V110  );
+  case( UR_14_4_KBIT ): return( BS_SPEED_14400_V110 );
+  default:              return( BS_SPEED_NotPresent );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_GetFormat         |
++-------------------------------------------------------------------+
+
+  PURPOSE : get character format out of bearer capabilities
+
+*/
+
+GLOBAL SHORT cmhCC_GetFormat ( void * bearCap )
+{
+  T_bcpara * pBC = (T_bcpara*) bearCap;
+
+  if( pBC->data_bits EQ DATA_7_BIT)
+  {
+    if( pBC->stop_bits EQ STOP_1_BIT )
+    {
+      if( pBC->parity EQ PARITY_NONE ) return( BS_FRM_Dat7_Par0_St1 );
+      else                             return( BS_FRM_Dat7_Par1_St1 );
+    }
+    else return( BS_FRM_Dat7_Par0_St2 );
+  }
+  else
+  {
+    if( pBC->stop_bits EQ STOP_1_BIT )
+    {
+      if( pBC->parity EQ PARITY_NONE ) return( BS_FRM_Dat8_Par0_St1 );
+      else                             return( BS_FRM_Dat8_Par1_St1 );
+    }
+    else return( BS_FRM_Dat8_Par0_St2 );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_GetParity         |
++-------------------------------------------------------------------+
+
+  PURPOSE : get parity out of bearer capabilities
+
+*/
+
+GLOBAL SHORT cmhCC_GetParity ( void * bearCap )
+{
+  T_bcpara * pBC = (T_bcpara*) bearCap;
+
+  switch( pBC->parity )
+  {
+  case( PARITY_ODD ):         return( BS_PAR_Odd );
+  case( PARITY_EVEN ):        return( BS_PAR_Even );
+  case( PARITY_FORCED_TO_0 ): return( BS_PAR_Space );
+  case( PARITY_FORCED_TO_1 ): return( BS_PAR_Mark );
+  case( PARITY_NONE ):
+  default:                    return( BS_PAR_NotPresent );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_GetCallClass      |
++-------------------------------------------------------------------+
+
+  PURPOSE : get call class out of bearer service
+
+*/
+
+GLOBAL T_ACI_CLASS cmhCC_GetCallClass ( SHORT cId )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+
+  switch( ctb->BC[ctb->curBC].bearer_serv )
+  {
+  case( BEARER_SERV_SPEECH_CTM ):
+  case( BEARER_SERV_SPEECH ):     return( CLASS_Vce );
+  case( BEARER_SERV_AUX_SPEECH_CTM ):
+  case( BEARER_SERV_AUX_SPEECH ): return( CLASS_AuxVce );
+  case( BEARER_SERV_FAX    ):     return( CLASS_Fax );
+  case( BEARER_SERV_SYNC   ):     return( CLASS_Dat );
+  case( BEARER_SERV_ASYNC  ):     return( CLASS_Dat );
+  default:                        return( CLASS_NotPresent );
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCF                 |
+|                                 ROUTINE : cmhCC_ctbGetCldNumTyp   |
++-------------------------------------------------------------------+
+
+  PURPOSE : this function builds the type of address information out
+            of the called party information.
+*/
+
+GLOBAL T_ACI_TOA* cmhCC_ctbGetCldNumTyp ( SHORT cId, T_ACI_TOA* pToaBuf )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+/*
+ *-------------------------------------------------------------------
+ * build type of address information
+ *-------------------------------------------------------------------
+ */
+  if (ctb->cldPty.ton EQ TON_NOT_PRES )
+
+    return( NULL );
+
+  pToaBuf -> ton = ctb->cldPty.ton;
+  pToaBuf -> npi = ctb->cldPty.npi;
+
+  return( pToaBuf );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCF                 |
+|                                 ROUTINE : cmhCC_ctbGetCldSubTyp   |
++-------------------------------------------------------------------+
+
+  PURPOSE : this function builds the type of subaddress information
+            out of the called party information.
+*/
+
+GLOBAL T_ACI_TOS* cmhCC_ctbGetCldSubTyp ( SHORT cId, T_ACI_TOS * pTosBuf )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+/*
+ *-------------------------------------------------------------------
+ * build type of subaddress information
+ *-------------------------------------------------------------------
+ */
+  if( ctb->cldPtySub.tos EQ TOS_NOT_PRES )
+
+    return( NULL );
+
+  pTosBuf -> tos = ctb->cldPtySub.tos;
+  pTosBuf -> oe  = ctb->cldPtySub.odd_even;
+
+  return( pTosBuf );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCF                 |
+|                                 ROUTINE : cmhCC_ctbGetClrNumTyp   |
++-------------------------------------------------------------------+
+
+  PURPOSE : this function builds the type of address information out
+            of the calling party information.
+*/
+
+GLOBAL T_ACI_TOA* cmhCC_ctbGetClrNumTyp ( SHORT cId, T_ACI_TOA* pToaBuf )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+/*
+ *-------------------------------------------------------------------
+ * build type of address information
+ *-------------------------------------------------------------------
+ */
+  if (ctb->clgPty.ton EQ TON_NOT_PRES )
+
+    return( NULL );
+
+  pToaBuf -> ton = ctb->clgPty.ton;
+  pToaBuf -> npi = ctb->clgPty.npi;
+
+  return( pToaBuf );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCF                 |
+|                                 ROUTINE : cmhCC_ctbGetClrSubTyp   |
++-------------------------------------------------------------------+
+
+  PURPOSE : this function builds the type of subaddress information
+            out of the calling party information.
+*/
+
+GLOBAL T_ACI_TOS* cmhCC_ctbGetClrSubTyp ( SHORT cId, T_ACI_TOS * pTosBuf )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+/*
+ *-------------------------------------------------------------------
+ * build type of subaddress information
+ *-------------------------------------------------------------------
+ */
+  if( ctb->clgPtySub.tos EQ TOS_NOT_PRES )
+
+    return( NULL );
+
+  pTosBuf -> tos = ctb->clgPtySub.tos;
+  pTosBuf -> oe  = ctb->clgPtySub.odd_even;
+
+  return( pTosBuf );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCF                 |
+|                                 ROUTINE : cmhCC_ctbGetRdrNumTyp   |
++-------------------------------------------------------------------+
+
+  PURPOSE : this function builds the type of address information out
+            of the redirecting party information.
+*/
+
+GLOBAL T_ACI_TOA* cmhCC_ctbGetRdrNumTyp ( SHORT cId, T_ACI_TOA* pToaBuf )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+/*
+ *-------------------------------------------------------------------
+ * build type of address information
+ *-------------------------------------------------------------------
+ */
+  if( ctb->rdrPty.ton EQ TON_NOT_PRES )
+
+    return( NULL );
+
+  pToaBuf -> ton = ctb->rdrPty.ton;
+  pToaBuf -> npi = ctb->rdrPty.npi;
+
+  return( pToaBuf );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCF                 |
+|                                 ROUTINE : cmhCC_ctbGetRdrSubTyp   |
++-------------------------------------------------------------------+
+
+  PURPOSE : this function builds the type of subaddress information
+            out of the redirecting party information.
+*/
+
+GLOBAL T_ACI_TOS* cmhCC_ctbGetRdrSubTyp ( SHORT cId, T_ACI_TOS * pTosBuf )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+/*
+ *-------------------------------------------------------------------
+ * build type of subaddress information
+ *-------------------------------------------------------------------
+ */
+  if( ctb->rdrPtySub.tos EQ TOS_NOT_PRES )
+
+    return( NULL );
+
+  pTosBuf -> tos = ctb->rdrPtySub.tos;
+  pTosBuf -> oe  = ctb->rdrPtySub.odd_even;
+
+  return( pTosBuf );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_CCR                      |
+|                            ROUTINE : cmhrat_no_carrier            |
++-------------------------------------------------------------------+
+
+  PURPOSE : Send NO CARRIER to user (saves memory in comparaison to R_AT).
+            It also send a log to MFW, and sends NO CARRIER to the owner
+            of the call if it is necessary (owner different from call killer).
+
+            It also sends a DCD off to UART.
+
+*/
+
+GLOBAL void cmhrat_calldisc( RAT_ID response, UBYTE srcId, T_ACI_AT_CMD cmdId, SHORT cId )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION("cmhrat_calldisc");
+
+  /* CHECK response: THIS ONLY WORKS BECAUSE R_AT has the same parameters
+  for RAT_NO_CARRIER, RAT_BUSY and RAT_NO_ANSWER */
+  switch( response )
+  {
+  case( RAT_NO_CARRIER ):
+  case( RAT_BUSY ):
+  case( RAT_NO_ANSWER ):
+    break;
+  default:
+    return;
+  }
+
+  if( srcId EQ (UBYTE)CMD_SRC_NONE       OR
+      srcId EQ ctb->calOwn )
+  {
+    /* inform only call owner */
+
+    R_AT( response, ctb->calOwn ) ( AT_CMD_NONE, cId+1 );
+  }
+  else
+  {
+    /* inform both call owner and call killer */
+    R_AT( response, ctb->calOwn ) ( AT_CMD_NONE, cId+1 );
+    R_AT( response, srcId ) ( cmdId, cId+1 );
+  }
+
+#ifdef FF_ATI
+  /* tlu:io_setDCD (ctb->calOwn, IO_DCD_OFF); */ /* V.24 DCD Line */
+#endif
+
+  cmh_logRslt ( (T_ACI_CMD_SRC)srcId, response, cmdId, (SHORT)(cId+1), -1, -1 );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_SndDiscRsn        |
++-------------------------------------------------------------------+
+
+  PURPOSE : Find out the reason for disconnection and send it to the
+            caller.
+
+*/
+
+GLOBAL void cmhCC_SndDiscRsn ( SHORT cId )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+  UBYTE cmdBuf;     /* buffers current command */
+  UBYTE srcBuf;     /* buffers current command source */
+
+  TRACE_FUNCTION ("cmhCC_SndDiscRsn()");
+
+  cmdBuf = ctb->curCmd;
+  srcBuf = ctb->curSrc;
+
+  if (rdlPrm.rdlcId EQ NO_ENTRY)
+  {
+    cmhCC_PrepareCmdEnd (cId, NULL, NULL);
+  }
+
+  if( cmdBuf EQ AT_CMD_NONE )
+  {
+    srcBuf = ctb->calOwn; /* call owner is the only one that
+                             could possibly be informed */
+  }
+
+  if( cmdBuf EQ AT_CMD_ABRT )
+  {
+    R_AT( RAT_OK, srcBuf )( cmdBuf );
+    /* log result */
+    cmh_logRslt ( srcBuf, RAT_OK,
+                  (T_ACI_AT_CMD)cmdBuf, (SHORT)(cId+1), -1, -1 );
+    return;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check for reject cause
+ *-------------------------------------------------------------------
+ */
+  /* 
+   * Make use of ctb here or die. Problem with TI compiler 1.22e.
+   * Seen. Exactly here. GET_CAUSE_VALUE() expression seems to become too 
+   * complicated without the help of this variable. You may get a wrong 
+   * ARM instruction otherwise in the generated code.
+   */
+  if(GET_CAUSE_VALUE(ctb->rejCs) NEQ NOT_PRESENT_8BIT)
+  {
+    /* when there is no SIM error, send the NO CARRIER command,
+       otherwise cmhSIM_GetSIMError send the error command (CME) */
+    if (GET_CAUSE_ORIGIN_ENTITY(ctb->rejCs) NEQ SIM_ORIGINATING_ENTITY OR
+        cmhSIM_GetSIMError(srcBuf, cmdBuf) EQ AT_FAIL )
+    {
+      cmhrat_calldisc(RAT_NO_CARRIER, srcBuf, cmdBuf, cId);
+      return;
+    }
+    else
+    {
+      cmh_logRslt ( srcBuf, RAT_CME,
+                   (T_ACI_AT_CMD)cmdBuf, (SHORT)(cId+1), -1, -1 );
+    }
+    return;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * otherwise check for normal cause
+ *-------------------------------------------------------------------
+ */
+  switch( ctb->nrmCs )
+  {
+  case( MNCC_CAUSE_USER_BUSY ):
+    cmhrat_calldisc(RAT_BUSY, srcBuf, cmdBuf, cId);
+    break;
+
+  case( MNCC_CAUSE_NO_RESPONSE ):
+  case( MNCC_CAUSE_ALERT_NO_ANSWER ):
+    cmhrat_calldisc(RAT_NO_ANSWER, srcBuf, cmdBuf, cId);
+    break;
+
+  default:
+    cmhrat_calldisc(RAT_NO_CARRIER, srcBuf, cmdBuf, cId);
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_ChckInCallMdfy    |
++-------------------------------------------------------------------+
+
+  PURPOSE : check the case of in-call modification. The function
+            returns TRUE or FALSE, whether a modification is allowed
+            or not.
+
+*/
+
+GLOBAL BOOL cmhCC_ChckInCallMdfy ( SHORT cId, UBYTE cmd )
+{
+#ifdef FAX_AND_DATA
+  T_CC_CALL_TYPE calltype = cmhCC_getcalltype(cId);
+
+  TRACE_FUNCTION ("cmhCC_ChckInCallMdfy()");
+
+#ifdef CO_UDP_IP
+  if(calltype EQ UDPIP_CALL)
+  {
+    /* modifying a Wap Call should not be allowed */
+    return( FALSE);
+  }
+#endif /* CO_UDP_IP */
+
+  /* check call mode */
+  switch( psaCC_ctb(cId)->rptInd )
+  {
+    /* single call */
+    case( RI_NOT_PRES ):
+      return( FALSE );
+
+    /* voice followed by data */
+    case( RI_SEQUENTIAL ):
+      if(calltype EQ VOICE_CALL)
+      {
+        switch( cmd )
+        {
+          case( AT_CMD_D ):       /* modify commands */
+          case( AT_CMD_A ):
+
+            TRACE_EVENT( "MODIFY FROM SPEECH" );
+            return( TRUE );
+        }
+      }
+      return( FALSE );
+
+    /* alternating call */
+    case( RI_CIRCULAR ):
+      switch(calltype)
+      {
+        case(VOICE_CALL):
+          switch( cmd )
+          {
+            case( AT_CMD_D ):       /* modify commands */
+            case( AT_CMD_A ):
+
+              TRACE_EVENT( "MODIFY FROM SPEECH" );
+              return( TRUE );
+          }
+          return( FALSE );
+
+        case( TRANS_CALL ):
+        case( NON_TRANS_CALL ):
+        case( FAX_CALL ):
+          if(cmd EQ AT_CMD_H )       /* modify commands */
+          {
+            TRACE_EVENT( "MODIFY FROM DATA/FAX" );
+            return( TRUE );
+          }
+          break;
+      }
+      return( FALSE );
+  }
+#endif /* FAX_AND_DATA */
+  return(FALSE);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_atdsendok         |
++-------------------------------------------------------------------+
+
+  PURPOSE : returns TRUE if OK is to be sent directly: in case of ATD,
+            if COLP is not set and source is neither LCL nor SAT nor CSSN ...
+*/
+
+GLOBAL BOOL cmhCC_atdsendok ( SHORT cId )
+{
+  T_CC_CALL_TYPE calltype = cmhCC_getcalltype(cId);
+  T_ACI_AT_CMD   cmd      = psaCC_ctb(cId)->curCmd;
+  SHORT          srcId    = psaCC_ctb(cId)->curSrc;
+  
+#ifdef FF_ATI 
+  TRACE_EVENT_P6("cmhCC_atdsendok(): cmd: %d, calltype: %d, srcId: %d, COLP_stat: %d, SATinv: %d, CSSI_stat: %d",
+                                     cmd,  calltype, srcId, at.flags.COLP_stat, psaCC_ctb(cId)->SATinv,
+                                     ati_user_output_cfg[srcId].CSSI_stat);
+#endif /* FF_ATI */ 
+
+#ifdef FF_ATI
+  if(cmd NEQ AT_CMD_D) /* can happen ONLY to ATD */
+    return(FALSE);
+
+  if (calltype NEQ VOICE_CALL      OR
+      srcId EQ CMD_SRC_LCL         OR
+      at.flags.COLP_stat EQ 1      OR
+      ati_user_output_cfg[srcId].CSSI_stat EQ 1      OR
+      ati_is_src_type((UBYTE)srcId, ATI_SRC_TYPE_SAT) OR   /* SAT run at cmd */
+      psaCC_ctb(cId)->SATinv )       /* call started by SAT */
+  {
+    TRACE_EVENT("send OK normally: at the end");
+    return(FALSE);   /* OK sent normally: after MNCC_SETUP_CNF has been received */
+  }
+  else
+  {
+    TRACE_EVENT("send OK directly after ATD");
+    return(TRUE);    /* OK sent as soon as MNCC_SETUP_REQ has been sent (see ITU. V25ter) */
+  }
+#else
+  return(FALSE);
+#endif /* AT INTERPRETER */
+
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_flagCall          |
++-------------------------------------------------------------------+
+
+  PURPOSE : flag a call for multy-call operation
+
+*/
+
+GLOBAL void cmhCC_flagCall ( SHORT cId, USHORT * flags )
+{
+  *flags |= (0x1 << cId);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_tstAndUnflagCall  |
++-------------------------------------------------------------------+
+
+  PURPOSE : test and unflag a call for multy-call operation. Return
+            the test result.
+
+*/
+
+GLOBAL BOOL cmhCC_tstAndUnflagCall ( SHORT cId, USHORT * flags )
+{
+  if( *flags & (1u << cId))
+  {
+    *flags &= ~(1u << cId);
+    return( TRUE );
+  }
+  return( FALSE );
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CC                  |
+|                                 ROUTINE : cmhCC_getcalltype       |
++-------------------------------------------------------------------+
+
+  PURPOSE : returns the type of call of cId (voice, data, fax...).
+
+*/
+
+GLOBAL T_CC_CALL_TYPE cmhCC_getcalltype(SHORT cId)
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+
+  /* Check whether the cId is valid or not, if not return NO_VLD_CC_CALL_TYPE */
+  if (!psaCC_ctbIsValid (cId))
+    return(NO_VLD_CC_CALL_TYPE);
+
+  if (ctb EQ NULL)
+    return (T_CC_CALL_TYPE)ccShrdPrm.callType[cId]; /* Call already gone */
+
+  /* determine type of call */
+  switch( ctb->BC[ctb->curBC].bearer_serv )
+  {
+    default:
+      return(NO_VLD_CC_CALL_TYPE);
+
+    case( BEARER_SERV_AUX_SPEECH ):
+    case( BEARER_SERV_SPEECH ):     /* voice call */
+    case( BEARER_SERV_AUX_SPEECH_CTM ):
+    case( BEARER_SERV_SPEECH_CTM ):     /* voice call with CTM */
+      return(VOICE_CALL);
+
+#ifdef FAX_AND_DATA
+    case( BEARER_SERV_ASYNC ):      /* asynchronous data call */
+      switch( ctb->BC[ctb->curBC].conn_elem )
+      {
+        case( CONN_ELEM_TRANS ):    /* transparent data call */
+        case( CONN_ELEM_NON_TRANS ):  /* non transparent data call */
+ /* check if a WAP call is in process... If yes then end call */
+#if defined(CO_UDP_IP) OR defined(FF_GPF_TCPIP)
+          if (Wap_Call)
+          {
+            if (cId EQ wapId)
+            {
+              if(is_gpf_tcpip_call()) {
+                GPF_TCPIP_STATEMENT(return(TCPIP_CALL));
+              }
+              else {
+                UDPIP_STATEMENT(return(UDPIP_CALL));
+              }
+            }
+          }
+#endif  /* CO_UDP_IP || FF_GPF_TCPIP */
+
+#ifdef FF_TCP_IP
+          if (pppShrdPrm.is_PPP_CALL EQ TRUE)
+          {
+            return (PPP_CALL);
+          }
+#endif  /* of #ifdef FF_TCP_IP */
+
+          if( ctb->BC[ctb->curBC].conn_elem EQ CONN_ELEM_TRANS )
+          {
+            return(TRANS_CALL);
+          }
+          else
+            return(NON_TRANS_CALL);
+      }
+      return(NO_VLD_CC_CALL_TYPE);
+
+    case( BEARER_SERV_FAX ):          /* fax call */
+      return(FAX_CALL);
+
+    case( BEARER_SERV_SYNC  ):
+    case( BEARER_SERV_PAD_ACCESS  ):
+    case( BEARER_SERV_PACKET_ACCESS ):
+      return(UNSUP_DATA_CALL);
+#endif /* of #ifdef FAX_AND_DATA */
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                 |
+|                                 ROUTINE : cmhCC_AcceptCall        |
++-------------------------------------------------------------------+
+
+  PURPOSE : accept a call.
+*/
+
+GLOBAL void cmhCC_AcceptCall(SHORT cId, T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd)
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+  UBYTE idx;                  /* holds index value */
+
+  TRACE_FUNCTION("cmhCC_AcceptCall( )");
+
+  if (ctb EQ NULL OR ctb->calStat NEQ CS_ACT_REQ)
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_Unknown );
+    R_AT(RAT_CME, srcId)(cmd, CME_ERR_Unknown);
+    return;
+  }
+
+  CHLDaddInfo = NO_CHLD_ADD_INFO;
+  ctb->curCmd = cmd;
+  ctb->calOwn = srcId;
+  ctb->curSrc = srcId;
+
+  /*
+   * ETSI 11.10 26.12.4 requires "that for speech calls, the mobile station
+   * shall attach the user connection at latest when sending the connect
+   * message, except if there is no compatible radio resource available at
+   * this time."
+   */
+
+  psaCC_phbAddNtry ( LRN, cId, CT_MTC, NULL );  /* add call to LRN PB */
+
+#ifdef FF_ATI
+  io_setRngInd ( IO_RING_OFF, CRING_TYP_NotPresent, CRING_TYP_NotPresent ); /* V.24 Ring Indicator Line */
+#endif
+
+  for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+  {
+    R_AT( RAT_CRING_OFF, idx )( cId+1 );
+  }
+
+  psaCC_AcceptCall(cId);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                 |
+|                                 ROUTINE : cmhCC_RetrieveCall      |
++-------------------------------------------------------------------+
+
+  PURPOSE : Retrieve either a Multyparty or a Normal Call
+*/
+GLOBAL void cmhCC_RetrieveCall(SHORT cId, T_ACI_CMD_SRC srcId)
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION("cmhCC_RetrieveCall( )");
+
+  if (ctb EQ NULL OR ctb->calStat NEQ CS_HLD)
+  {
+    return;
+  }
+
+  CHLDaddInfo = NO_CHLD_ADD_INFO;
+  ctb->curCmd = AT_CMD_CHLD;
+  ctb->curSrc = srcId;
+
+  if (ctb->mptyStat EQ CS_ACT )
+  {
+    psaCC_RetrieveMPTY (cId);
+  }
+  else
+  {
+    psaCC_RetrieveCall (cId);
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                 |
+|                                 ROUTINE : cmhCC_NewCall           |
++-------------------------------------------------------------------+
+
+  PURPOSE : Initiate a new call.
+*/
+GLOBAL void cmhCC_NewCall(SHORT cId, T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd)
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION("cmhCC_NewCall( )");
+
+  CHLDaddInfo = NO_CHLD_ADD_INFO;
+  ctb->curCmd = cmd;
+  ctb->calOwn = srcId;
+  ctb->curSrc = srcId;
+
+  psaCC_NewCall(cId);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                 |
+|                                 ROUTINE : cmhCC_HoldCall          |
++-------------------------------------------------------------------+
+
+  PURPOSE : Put a call on hold (multyparty or normal call)
+*/
+GLOBAL void cmhCC_HoldCall(SHORT cId, T_ACI_CMD_SRC srcId, T_ACI_AT_CMD cmd)
+{
+  T_CC_CALL_TBL  *ctb;         /* points to CC call table */
+  T_CC_CMD_PRM   *pCCCmdPrm;   /* points to CC command parameters */
+
+  TRACE_FUNCTION("cmhCC_HoldCall( )");
+
+  ctb = ccShrdPrm.ctb[cId];
+  pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm;
+
+  cmhCC_flagCall( cId, &(pCCCmdPrm->mltyCncFlg));
+  ctb->curCmd = cmd;
+  ctb->curSrc = srcId;
+
+  if (ctb->mptyStat EQ CS_ACT)
+  {
+    psaCC_HoldMPTY(cId);
+  }
+  else
+  {
+    psaCC_HoldCall(cId);
+  }
+}
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                 |
+|                                 ROUTINE : cmhCC_ClearCall         |
++-------------------------------------------------------------------+
+
+  PURPOSE : disconnect a call.
+*/
+
+GLOBAL void cmhCC_ClearCall ( SHORT cId,
+                              USHORT cs,
+                              T_ACI_CMD_SRC srcId,
+                              UBYTE cmd,
+                              SHORT *waitId )
+{
+  T_CC_CMD_PRM   *pCCCmdPrm = NULL;   /* points to CC command parameters */
+  T_CC_CALL_TYPE calltype = cmhCC_getcalltype(cId);
+  T_CC_CALL_TBL  *ctb = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION( "cmhCC_ClearCall()" );
+
+  if(srcId > CMD_SRC_NONE AND
+     srcId < CMD_SRC_MAX)
+  {
+    pCCCmdPrm = &cmhPrm[srcId].ccCmdPrm;
+  }
+
+  if (ccShrdPrm.ctb[cId] EQ NULL)
+  {
+    TRACE_EVENT("cmhCC_ClearCall(): Not a valid cId");
+    return;
+  }
+
+  TRACE_EVENT_P2("Clear Call ==> calStat: %d, calType: %d", ctb->calStat, ctb->calType NEQ CT_MOC);
+
+  if(cmd NEQ AT_CMD_NONE) /* for instance +CHUP / H / Z */
+  {
+    /* Check whether an incoming call is rejected by the user. */
+    if( ctb->calStat EQ CS_ACT_REQ AND
+        ctb->calType EQ CT_MTC)
+    {
+      psaCC_phbAddNtry ( LRN, cId, CT_MTC, NULL );  /* Add call to Last Received Number (LRN) PB */
+    }
+
+    /* Check whether call is a waiting call */
+    if(waitId NEQ NULL)
+    {
+      if( ctb->calStat EQ CS_ACT_REQ AND
+          ctb->calType EQ CT_MTC     AND
+          ctb->calOwn  EQ OWN_NONE )
+      {
+        /* tag a found waiting call */
+        TRACE_EVENT_P1("Waiting Call Found ! waitId=%d", cId);
+        *waitId = cId;
+        return;
+      }
+    }
+  }
+
+  ccShrdPrm.cIdFail = cId;
+  if ( cmd NEQ AT_CMD_NONE ) /* this will decide whether a result is sent to the user or not */
+  {
+    /* ATZ and ATH or AT+CHUP for instance */
+    if(pCCCmdPrm NEQ NULL)
+    {
+      cmhCC_flagCall( cId, &(pCCCmdPrm -> mltyDscFlg));
+    }
+    ctb->curCmd = cmd;
+    ctb->curSrc = srcId;
+  }
+  else
+  {
+    /* AOC for instance */
+    cmhCC_SndDiscRsn(cId);
+  }
+  ctb->nrmCs     = cs;
+
+  /* determine call status */
+  switch( ctb->calStat )
+  {
+    /* active calls */
+    case( CS_ACT ):
+      switch( calltype )
+      {
+        case( VOICE_CALL ):
+          psaCC_ClearCall (cId);
+          break;
+
+#if defined FAX_AND_DATA AND defined (DTI)
+
+        case( TRANS_CALL ):
+          ccShrdPrm.datStat = DS_DSC_REQ;
+          cmhTRA_Deactivate ();
+          break;
+
+        case( NON_TRANS_CALL ):
+          ccShrdPrm.datStat = DS_DSC_REQ;
+          cmhL2R_Deactivate ();
+          break;
+
+#ifdef FF_FAX
+        case( FAX_CALL ):
+          ccShrdPrm.datStat = DS_DSC_REQ;
+          cmhT30_Deactivate ();
+          break;
+#endif /* FF_FAX */
+
+#if defined(CO_UDP_IP) OR defined(FF_GPF_TCPIP)
+
+#ifdef CO_UDP_IP
+        case( UDPIP_CALL ):
+#endif
+
+#ifdef FF_GPF_TCPIP
+        case( TCPIP_CALL ):
+          {
+            T_DCM_STATUS_IND_MSG msg;
+            msg.hdr.msg_id = DCM_ERROR_IND_MSG;
+            msg.result     = DCM_PS_CONN_BROKEN;
+            dcm_send_message(msg, DCM_SUB_WAIT_SATDN_CNF);
+          }
+#endif
+          ccShrdPrm.datStat = DS_DSC_REQ;
+          /* also test whether a SAT E connection has to be shut down */
+          if ( (cmd NEQ AT_CMD_NONE)
+#ifdef FF_SAT_E
+              OR (satShrdPrm.opchAcptSrc EQ srcId)
+#endif
+             )
+          {
+            /* set the last possible state for the next "else if" statement */
+            T_ACI_WAP_STATES last_state = Wap_Not_Init;
+            if(is_gpf_tcpip_call()) {
+              GPF_TCPIP_STATEMENT(last_state = TCPIP_Deactivation);
+            }
+            else {
+              last_state = UDPA_Deactivation;
+            }
+
+            /* Terminate PPP if established. UP indicate that entities under PPP are still activ. */
+            if((pppShrdPrm.state EQ PPP_ESTABLISHED) OR
+               (pppShrdPrm.state EQ PPP_ESTABLISH))
+            {
+              cmhPPP_Terminate(UP);
+            }
+            else if (wap_state >  Wap_Not_Init  AND
+                     wap_state <= last_state)
+            {
+              cmhPPP_Terminated(); /* Trigger termination of SCPIP if PPP did not yet start (ACI-FIX-9317) */
+            }
+          }
+          break;
+#endif  /* defined(CO_UDP_IP) OR defined(FF_GPF_TCPIP) */
+
+#if defined (FF_TCP_IP) AND defined (DTI)
+        case( PPP_CALL ):
+          ccShrdPrm.datStat = DS_DSC_REQ;
+          if (pppShrdPrm.is_PPP_CALL EQ TRUE)
+          {
+            dti_cntrl_close_dpath_from_src_id((UBYTE)srcId);
+          }
+#endif  /* of #ifdef FF_TCP_IP */
+
+#endif    /* of #ifdef FAX_AND_DATA */
+        default:
+            TRACE_ERROR("Wrong call type");
+    }
+      break;
+
+      /* other present calls */
+    case( CS_HLD ):
+    case( CS_HLD_REQ ):
+    case( CS_MDF_REQ ):
+    case( CS_DSC_REQ ):
+    case( CS_ACT_REQ ):
+    case( CS_CPL_REQ ):
+      psaCC_ClearCall (cId);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_chkDTMFDig         |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function is used extract DTMF digits from the dialled
+            number. The DTMF digits, including separators, are stored
+            in the DTMF parameters and will be send automatically after
+            the connection is established.
+            BOOL within_dial_string parameter to tell if DTMF tones are
+            within a dial string or directly given.
+            USHROT length: possibility to give the number of dtmf to be
+            sent (relevant only if not within a dial string).
+*/
+
+/* next function fills up dtmf structure with extracted prms */
+LOCAL void cmhCC_fillDTMFDig ( SHORT cId, CHAR *dtmf, USHORT dtmf_length )
+{
+  TRACE_FUNCTION("cmhCC_fillDTMFDig()");
+
+  if( dtmf NEQ NULL )
+  {
+    ccShrdPrm.dtmf.cnt = MINIMUM( dtmf_length, MAX_DTMF_DIG );
+
+    strncpy( (char *)ccShrdPrm.dtmf.dig, dtmf, ccShrdPrm.dtmf.cnt );
+    ccShrdPrm.dtmf.dig[dtmf_length] = '\0';
+
+    ccShrdPrm.dtmf.cur = 0;
+    ccShrdPrm.dtmf.cId = cId;
+    TRACE_EVENT_P2("ccShrdPrm.dtmf.cnt: %d, ccShrdPrm.dtmf.cId: %d", ccShrdPrm.dtmf.cnt, ccShrdPrm.dtmf.cId);
+  }
+  else
+  {
+    ccShrdPrm.dtmf.cnt = 0;
+    ccShrdPrm.dtmf.cur = 0;
+    ccShrdPrm.dtmf.cId = NO_ENTRY;
+  }
+}
+
+GLOBAL BOOL is_digit_dtmf_separator(CHAR digit)
+{
+  switch(digit)
+  {
+    case('P'):  /* PHB_DIAL_PAUSE, PHB_DTMF_SEP */
+    case('p'):
+    case('W'):  /* PHB_DIAL_WAIT */
+    case('w'):
+      TRACE_EVENT("DTMF Separator Found");
+      return(TRUE);
+  }
+  return(FALSE);
+}
+
+LOCAL CHAR * find_dtmf_separator(CHAR *number_string, USHORT length)
+{
+  int i;
+
+  TRACE_FUNCTION("find_dtmf_separator()");
+
+  for(i=0; i<length; i++)
+  {
+    if(is_digit_dtmf_separator(*number_string))
+    {
+      return(number_string);
+    }
+    number_string++;
+  }
+  return(NULL);
+}
+
+GLOBAL void cmhCC_chkDTMFDig ( CHAR*  num,
+                               SHORT  cId,
+                               USHORT length,
+                               BOOL   within_dial_string )
+{
+  CHAR   *dtmf = num;
+  USHORT len   = length;
+
+  TRACE_FUNCTION("cmhCC_chkDTMFDig()");
+
+  if( within_dial_string )
+  {
+    dtmf = find_dtmf_separator(num, (USHORT)strlen(num)); /*strchr( num, PHB_DTMF_SEP ); */
+
+    if(dtmf NEQ NULL)
+    {
+      len = strlen(dtmf);
+      TRACE_EVENT_P1("Call number string contains %d DTMF tones", len);
+    }
+  }
+  else
+  {
+    /* already inialized for the case "not within a phone call" (e.g SAT Send DTMF) */
+  }
+
+  cmhCC_fillDTMFDig ( cId, dtmf, len );
+
+  if(dtmf NEQ NULL)
+  {
+    *dtmf = '\0';  /* split dial string from DTMF tones */
+  }
+
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_chkKeySeq          |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function is used to decode a keystroke sequence and
+            to initiate an appropriate action.
+*/
+GLOBAL T_ACI_RETURN cmhCC_chkKeySeq ( T_ACI_CMD_SRC srcId,
+                                      T_CLPTY_PRM *cldPty,
+                                      T_ACI_D_TOC *callType,
+                                      T_ACI_D_CLIR_OVRD *CLIRovrd,
+                                      T_CC_SIM_QLF ccSIMQlf )
+{
+  T_KSD_SEQGRP   seqGrp = SEQGRP_UNKNOWN;
+  T_KSD_SEQPARAM seqPrm;
+  CHAR          *restSeq = NULL;
+  T_ACI_RETURN   retVal;
+  T_PHB_RECORD   phbNtry;
+  T_PHB_TYPE     slctPHB;
+#ifdef SIM_TOOLKIT
+  T_sat_ussd     SATussd; /* to hold USSD string in case of SAT Control */
+#endif /* of SIM_TOOLKIT */
+
+  TRACE_FUNCTION ("cmhCC_chkKeySeq ()");
+
+  if( cldPty EQ NULL         OR
+    strlen (cldPty->num) EQ 0 )
+  {
+    return( AT_CMPL );
+  }
+
+  restSeq = cldPty->num;
+  seqGrp  = SEQGRP_UNKNOWN;
+
+#ifdef SIM_TOOLKIT
+  /* check for SAT SIM Call Control of SS strings */
+  if (ccSIMQlf EQ CC_SIM_YES)
+  {
+    if ( !ksd_isFDNCheckSeq ( cldPty-> num ) )
+      ;    /* bypass *#06# from SSCntrlBySIM */
+    else
+    {
+      retVal = AT_CMPL; /* init */
+      if( ksd_isSATSscs (cldPty->num) )
+      {
+        retVal = cmhSAT_SSCntrlBySIM( cldPty, (UBYTE)srcId );
+      }
+      else if( ksd_isUSSD (cldPty->num) )
+      {
+        if (psaSIM_ChkSIMSrvSup(SRV_USSDsupportInCC))
+        {
+          SATussd.dcs        = 0x0F; /* default alphabet see GSM 03.38 Cell Broadcast dcs */
+          SATussd.c_ussd_str = strlen(cldPty->num);
+          SATussd.ussd_str   = (UBYTE *)cldPty->num;
+
+          retVal = cmhSAT_USSDCntrlBySIM( &SATussd, (UBYTE)srcId );
+        }
+        else
+        {
+          retVal = cmhSAT_SSCntrlBySIM( cldPty, (UBYTE)srcId );
+        }
+      }
+
+      if( retVal NEQ AT_CMPL )
+        return( retVal );
+    }
+  }
+#endif
+
+/*
+ *-------------------------------------------------------------
+ * decode SS string
+ *-------------------------------------------------------------
+ */
+  if (ksd_decode (cldPty->num,
+                  psaCC_ctbAnyCallInUse(),  /* is there any call??? */
+                  &seqGrp,
+                  &restSeq,
+                  &seqPrm) EQ TRUE)
+  {
+    retVal  = AT_FAIL;
+
+  /*
+   *-------------------------------------------------------------
+   * perform desired action
+   *-------------------------------------------------------------
+   */
+    switch (seqGrp)
+    {
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group SEQGRP_IMEI
+       *---------------------------------------------------------
+       */
+      case ( SEQGRP_PRSNT_IMEI ):
+        retVal = cmhSS_ksdIMEI( srcId );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group SEQGRP_DIAL
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_DIAL):
+        strncpy(cldPty->num, seqPrm.dial.number, sizeof (cldPty->num) - 1);
+        cldPty->num[sizeof(cldPty->num) - 1] = '\0';
+        return( AT_CONT );
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group SEQGRP_CHLD
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_CHLD):
+        retVal = sAT_PlusCHLD( srcId, seqPrm.chld.mode, seqPrm.chld.call );
+        if (retVal NEQ AT_FAIL)
+          break; /* successfull CHLD */
+
+        /* else handle as USSD if this CHLD was unexpected/illegal */
+
+        seqPrm.ussd.ussd = (UBYTE *)cldPty->num;
+        seqGrp  = SEQGRP_USSD;
+        restSeq = cldPty->num + strlen (cldPty->num);
+        /* fallthrough */
+      /*lint -fallthrough*/
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group SEQGRP_USSD
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_USSD):
+        retVal = cmhSS_ksdUSSD( srcId, &seqPrm.ussd );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group SEQGRP_DIAL_IDX
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_DIAL_IDX):
+
+        if( !cmhPHB_cvtPhbType(cmhPrm[srcId].phbCmdPrm.cmhStor,
+                               &slctPHB ))
+          return( AT_FAIL );
+
+#ifdef TI_PS_FFS_PHB
+        if (pb_read_record (slctPHB, 
+                            seqPrm.dialIdx.index, 
+                            &phbNtry) EQ PHB_OK)
+#else
+        if( pb_read_phys_record( slctPHB, seqPrm.dialIdx.index,
+                                 &phbNtry )
+            EQ PHB_OK )
+#endif
+        {
+          cmhPHB_getAdrStr( cldPty->num, sizeof (cldPty->num) - 1,
+                            phbNtry.number, phbNtry.len );
+
+          cmh_demergeTOA ( phbNtry.ton_npi, &cldPty->ton, &cldPty->npi );
+
+          /*
+           *---------------------------------------------------------
+           * as long as the bearer capabilities are not read from
+           * the phonebook only voice calls are supported
+           *---------------------------------------------------------
+           */
+          *callType = D_TOC_Voice;
+
+          return( AT_CONT );
+        }
+
+        return( AT_FAIL );
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence groups which relates
+       * to call forwarding parameter
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_CF):
+        /* type of address has already been set,
+        and a possible "+" already been removed... */
+        if(seqPrm.cf.num NEQ NULL AND
+           seqPrm.cf.num[0] NEQ 0)   /* only set if there is actually a number */
+        {
+          seqPrm.cf.ton = cldPty->ton;
+          seqPrm.cf.npi = cldPty->npi;
+        }
+        else
+        {
+          seqPrm.cf.ton = TON_NOT_PRES;
+          seqPrm.cf.npi = NPI_NOT_PRES;
+        }
+
+        /* subaddress has also already been split up if existing */
+        if(cldPty->sub[0] NEQ 0)
+        {
+          seqPrm.cf.sub = (UBYTE *)cldPty->sub;
+          seqPrm.cf.tos = cldPty->tos;
+          seqPrm.cf.oe  = cldPty->oe;
+        }
+        else
+          seqPrm.cf.sub = NULL;
+
+        retVal = cmhSS_ksdCF( srcId, &seqPrm.cf );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence groups which relates to
+       * call barring parameter
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_CB):
+
+        retVal = cmhSS_ksdCB( srcId, &seqPrm.cb );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence groups which results in a change
+       * of CLIR parameter
+       * in temporary mode a call is set up
+       *---------------------------------------------------------
+       */
+
+      case (SEQGRP_SUP_COLR):
+      case (SEQGRP_INV_COLR):
+      case (SEQGRP_SUP_COLP):
+      case (SEQGRP_INV_COLP):
+      case (SEQGRP_SUP_CLIP):
+      case (SEQGRP_INV_CLIP):
+        if (strlen (restSeq) EQ 0)
+        {
+          T_ACI_KSD_USSD_PRM ksdString;
+
+          ksdString.ussd = (UBYTE*)cldPty->num;
+          retVal = cmhSS_ksdUSSD( srcId, &ksdString );
+        }
+        else
+        {
+          /*
+           *-----------------------------------------------------
+           * temporary mode nonexistant on CLIR, COLR and COLP!!
+           * So ignore USSD and continue calling: "Number not assigned"
+           * will be indicated to the user by the network
+           * This is the common behaviour as found on other phones
+           *-----------------------------------------------------
+           */
+          return( AT_CONT );
+        }
+        break;
+
+      case (SEQGRP_SUP_CLIR):
+      case (SEQGRP_INV_CLIR):
+        if (strlen (restSeq) EQ 0)
+        {
+#if defined(MFW) OR defined(FF_MMI_RIV)
+          if (srcId EQ CMD_SRC_LCL) /* VO: temp solution because MFW uses sAT_Dn to set CLIR */
+            retVal = sAT_PlusCLIR(srcId, seqPrm.Clir.mode);
+          else
+#endif
+          {
+            T_ACI_KSD_USSD_PRM ksdString;
+
+            ksdString.ussd = (UBYTE*)cldPty->num;
+            retVal = cmhSS_ksdUSSD( srcId, &ksdString );
+          }
+        }
+        else
+        {
+          /*
+           *-----------------------------------------------------
+           * in temporary mode a call is set up
+           *-----------------------------------------------------
+           */
+          T_KSD_CLIR   Clir;
+          T_KSD_SEQGRP nextGrp  = SEQGRP_UNKNOWN;
+          CHAR*        remSeq   = NULL;
+
+          Clir.mode = seqPrm.Clir.mode;
+
+          if (ksd_decode (restSeq, FALSE,
+                          &nextGrp, &remSeq,
+                          &seqPrm)
+              AND
+              nextGrp EQ SEQGRP_DIAL)
+          {
+            *CLIRovrd = (Clir.mode EQ CLIR_MOD_Supp)?
+                        D_CLIR_OVRD_Supp: D_CLIR_OVRD_Invoc;
+            strncpy(cldPty->num, seqPrm.dial.number, sizeof(cldPty->num) - 1);
+            cldPty->num[sizeof(cldPty->num) - 1] = '\0';
+            return( AT_CONT );
+          }
+        }
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group for TTY service
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_TTY_SERV):
+        if (strlen (restSeq) EQ 0)
+        {
+#ifdef FF_TTY
+          retVal = sAT_PercentCTTY (srcId, CTTY_MOD_NotPresent,
+                                    seqPrm.ctty.req);
+#else
+          retVal = AT_FAIL;
+#endif /* FF_TTY */
+        }
+        else
+        {
+          T_KSD_SEQGRP nextGrp  = SEQGRP_UNKNOWN;
+          CHAR*        remSeq   = NULL;
+#ifdef FF_TTY
+          if (seqPrm.ctty.req EQ CTTY_REQ_Off
+              AND ccShrdPrm.ctmReq EQ CTM_ENABLED)
+          {
+            ccShrdPrm.ctmOvwr = TRUE;
+          }
+          else if (seqPrm.ctty.req EQ CTTY_REQ_On
+                   AND ccShrdPrm.ctmReq EQ CTM_DISABLED)
+          {
+            ccShrdPrm.ctmOvwr = TRUE;
+          }
+          else
+          {
+            ccShrdPrm.ctmOvwr = FALSE;
+          }
+#endif /* FF_TTY */
+          if (ksd_decode (restSeq, FALSE,
+                          &nextGrp, &remSeq,
+                          &seqPrm)
+              AND
+              nextGrp EQ SEQGRP_DIAL)
+          {
+            strncpy(cldPty->num, seqPrm.dial.number, sizeof(cldPty->num) - 1);
+            cldPty->num[sizeof(cldPty->num) - 1] = '\0';
+            return( AT_CONT );
+          }
+        }
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group which relates to
+       * calling line supplementary services
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_CL):
+        retVal = cmhSS_ksdCL( srcId, &seqPrm.cl );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence groups which results in a
+       * registration of passwords
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_PWD):
+        retVal = cmhSS_ksdPW( srcId, &seqPrm.pwd );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence groups which results in a
+       * registration of passwords
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_UBLK):
+        retVal = cmhSS_ksdUBLK( srcId, &seqPrm.ublk );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence groups which relates to
+       * call waiting
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_CW):
+
+        retVal = cmhSS_ksdCW( srcId, &seqPrm.cw );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group SEQGRP_CCBS
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_CCBS):
+        retVal = cmhSS_ksdCCBS( srcId, &seqPrm.ccbs );
+        break;
+
+      /*
+       *---------------------------------------------------------
+       * handling of sequence group SEQGRP_UNKNOWN
+       *---------------------------------------------------------
+       */
+      case (SEQGRP_UNKNOWN):
+        TRACE_EVENT ("sequence group unknown");
+        break;
+    }
+  }
+  else
+  {
+    TRACE_EVENT ("ksd_decode failed");
+    return( AT_FAIL );
+  }
+
+  return( retVal );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_fillSetupPrm       |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function fills the call table entry with the
+            necessary setup parameters.
+*/
+
+GLOBAL T_ACI_RETURN cmhCC_fillSetupPrm ( SHORT              cId,
+                                         T_ACI_CMD_SRC      srcId,
+                                         T_CLPTY_PRM       *cldPty,
+                                         T_bcpara          *bc,
+                                         UBYTE              prio,
+                                         T_ACI_D_CLIR_OVRD  clirOvrd,
+                                         T_ACI_D_CUG_CTRL   cugCtrl,
+                                         T_ACI_D_TOC        callType )
+{
+  T_CC_CALL_TBL *pfilled_ctb;
+  T_CC_CMD_PRM  *pCCCmdPrm;  /* points to CC command parameters */
+#ifdef FF_FAX
+  T_T30_CMD_PRM *pT30CmdPrm; /* points to T30 command parameters */
+#endif
+
+  TRACE_FUNCTION ("cmhCC_fillSetupPrm()");
+
+  /* initializing local pointers: */
+  pCCCmdPrm  = &cmhPrm[srcId].ccCmdPrm;
+
+#ifdef FF_FAX
+  pT30CmdPrm = &fnd_cmhPrm[srcId].t30CmdPrm;
+#endif
+
+  pfilled_ctb = ccShrdPrm.ctb[cId];
+
+/*
+ *-----------------------------------------------------------------
+ * check data capabilities
+ *-----------------------------------------------------------------
+ */
+#ifndef FAX_AND_DATA
+  if( callType NEQ D_TOC_Voice )
+  {
+    TRACE_EVENT("No data calls supported");
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_NoDataCallSup );
+    return( AT_FAIL );        /* no data calls allowed */
+  }
+#endif  /* of #ifndef FAX_AND_DATA */
+
+/*
+ *-----------------------------------------------------------------
+ * called address
+ *-----------------------------------------------------------------
+ */
+  if( cldPty EQ NULL )
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return( AT_FAIL );        /* no number */
+  }
+
+  /* priority */
+  pfilled_ctb->prio = prio;
+
+  if ((prio EQ PRIO_NORM_CALL) AND
+      (aoc_check_moc() EQ FALSE))
+    /*
+     * check ACM exceeds ACMmax
+     * for non-emergency calls
+     */
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ceer, CAUSE_MAKE(DEFBY_STD,
+    ORIGSIDE_MS, ACI_ORIGINATING_ENTITY, CEER_ACM_Max ));
+    return( AT_FAIL );
+  }
+
+  /* subaddress */
+  pfilled_ctb->cldPtySub.tos      = cldPty->tos;
+  pfilled_ctb->cldPtySub.odd_even = cldPty->oe;
+  pfilled_ctb->cldPtySub.c_subaddr
+    = (UBYTE)utl_dialStr2BCD (cldPty->sub,
+                              pfilled_ctb->cldPtySub.subaddr,
+                              SUB_LENGTH);
+
+  /* address */
+  if( pCCCmdPrm -> CSTAdef NEQ TRUE )
+  {
+    pfilled_ctb->cldPty.npi = pCCCmdPrm -> CSTAtoa.npi;
+    pfilled_ctb->cldPty.ton = pCCCmdPrm -> CSTAtoa.ton;
+  }
+  else
+  {
+    pfilled_ctb->cldPty.npi = cldPty->npi;
+    pfilled_ctb->cldPty.ton = cldPty->ton;
+  }
+
+  if (pfilled_ctb->cldPty.called_num NEQ NULL)
+  {
+    ACI_MFREE (pfilled_ctb->cldPty.called_num);
+    pfilled_ctb->cldPty.called_num = NULL;
+  }
+  pfilled_ctb->cldPty.c_called_num =
+    (UBYTE)utl_dialStr2BCD (cldPty->num, NULL, MAX_CC_CALLED_NUMBER);
+  if (pfilled_ctb->cldPty.c_called_num NEQ 0)
+  {
+    ACI_MALLOC (pfilled_ctb->cldPty.called_num,
+                pfilled_ctb->cldPty.c_called_num);
+    (void)utl_dialStr2BCD (cldPty->num,
+                           pfilled_ctb->cldPty.called_num,
+                           pfilled_ctb->cldPty.c_called_num);
+  }
+
+  psaCC_phbSrchNum( cId, CT_MOC);    /* get alpha identifier */
+
+/*
+ *-----------------------------------------------------------------
+ * CLIR setting
+ *-----------------------------------------------------------------
+ */
+  switch( clirOvrd )
+  {
+    case( D_CLIR_OVRD_Supp ):
+      pfilled_ctb->CLIRsup = CLR_SUP;
+      break;
+
+    case( D_CLIR_OVRD_Invoc ):
+      pfilled_ctb->CLIRsup = CLR_SUP_NOT;
+      break;
+
+    case( D_CLIR_OVRD_Default ):
+
+      switch( pCCCmdPrm -> CLIRmode )
+      {
+        case( CLIR_MOD_Subscript ):
+          pfilled_ctb->CLIRsup = CLR_NOT_PRES;
+          break;
+        case( CLIR_MOD_Invoc ):
+          pfilled_ctb->CLIRsup = CLR_SUP_NOT;
+          break;
+        case( CLIR_MOD_Supp ):
+          pfilled_ctb->CLIRsup = CLR_SUP;
+          break;
+      }
+      break;
+
+    default:
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+      return( AT_FAIL );
+  }
+
+/*
+ *-----------------------------------------------------------------
+ * CUG setting
+ *-----------------------------------------------------------------
+ */
+  if ( cugCtrl               EQ D_CUG_CTRL_Present OR
+       pCCCmdPrm -> CCUGmode EQ CCUG_MOD_EnableTmp    )
+  {
+    pfilled_ctb->CUGidx = pCCCmdPrm -> CCUGidx;
+
+    switch( pCCCmdPrm -> CCUGinfo )
+    {
+      case( CCUG_INFO_No ):
+        break;
+      case( CCUG_INFO_SuppOa ):
+        pfilled_ctb->OAsup = TRUE;
+        break;
+      case( CCUG_INFO_SuppPrefCug ):
+        pfilled_ctb->CUGprf = TRUE;
+        break;
+      case( CCUG_INFO_SuppBoth ):
+        pfilled_ctb->OAsup = TRUE;
+        pfilled_ctb->CUGprf = TRUE;
+        break;
+    }
+  }
+
+#ifdef SIM_TOOLKIT
+/*
+ *-----------------------------------------------------------------
+ * SAT settings
+ *-----------------------------------------------------------------
+ */
+
+  /* decides if a disconnect event for a call has already been sent to SAT */
+  pfilled_ctb->SatDiscEvent = FALSE;
+#endif
+
+/*
+ *-----------------------------------------------------------------
+ * bearer services
+ *-----------------------------------------------------------------
+ */
+  switch( callType )
+  {
+    /*
+     *-----------------------------------------------------------------
+     * start with a voice call
+     *-----------------------------------------------------------------
+     */
+    case( D_TOC_Voice ):
+
+      pfilled_ctb->BC[0].rate        = UR_NOT_PRES;
+      pfilled_ctb->BC[0].bearer_serv = cmhCC_set_speech_serv (pCCCmdPrm);
+      pfilled_ctb->BC[0].conn_elem   = CONN_ELEM_NOT_PRES;
+
+      switch( ccShrdPrm.CMODmode )
+      {
+
+      case( CMOD_MOD_Single ):             /* single voice call */
+        pfilled_ctb->rptInd          = RI_NOT_PRES;
+
+        pfilled_ctb->BC[1].rate        = UR_NOT_PRES;
+        pfilled_ctb->BC[1].bearer_serv = BEARER_SERV_NOT_PRES;
+        pfilled_ctb->BC[1].conn_elem   = CONN_ELEM_NOT_PRES;
+        break;
+#ifdef UART
+      case( CMOD_MOD_VoiceDat ):           /* alternating voice/data call */
+        pfilled_ctb->rptInd          = RI_CIRCULAR;
+
+        pfilled_ctb->BC[1].rate        = cmhCC_SelRate( ccShrdPrm.CBSTspeed );
+        pfilled_ctb->BC[1].bearer_serv = cmhCC_SelServ( ccShrdPrm.CBSTname );
+        pfilled_ctb->BC[1].conn_elem   = cmhCC_SelCE  ( ccShrdPrm.CBSTce );
+        pfilled_ctb->BC[1].modem_type  = cmhCC_SelMT  ( ccShrdPrm.CBSTspeed );
+
+        pfilled_ctb->BC[1].stop_bits   = cmhCC_SelStopBit( srcId );
+        pfilled_ctb->BC[1].data_bits   = cmhCC_SelDataBit( srcId );
+        pfilled_ctb->BC[1].parity      = cmhCC_SelParity ( srcId );
+        break;
+
+      case( CMOD_MOD_VoiceFlwdDat ):       /* voice followed by data */
+        pfilled_ctb->rptInd          = RI_SEQUENTIAL;
+
+        pfilled_ctb->BC[1].rate        = cmhCC_SelRate( ccShrdPrm.CBSTspeed );
+        pfilled_ctb->BC[1].bearer_serv = cmhCC_SelServ( ccShrdPrm.CBSTname );
+        pfilled_ctb->BC[1].conn_elem   = cmhCC_SelCE(   ccShrdPrm.CBSTce );
+        pfilled_ctb->BC[1].modem_type  = cmhCC_SelMT  ( ccShrdPrm.CBSTspeed );
+
+        pfilled_ctb->BC[1].stop_bits   = cmhCC_SelStopBit( srcId );
+        pfilled_ctb->BC[1].data_bits   = cmhCC_SelDataBit( srcId );
+        pfilled_ctb->BC[1].parity      = cmhCC_SelParity ( srcId );
+        break;
+
+      case( CMOD_MOD_VoiceFax ):           /* alternating voice/fax call */
+        pfilled_ctb->rptInd          = RI_CIRCULAR;
+
+        pfilled_ctb->BC[1].rate        = cmhCC_SelRate( ccShrdPrm.CBSTspeed );
+        pfilled_ctb->BC[1].bearer_serv = BEARER_SERV_FAX;
+        pfilled_ctb->BC[1].conn_elem   = CONN_ELEM_TRANS;
+        pfilled_ctb->BC[1].modem_type  = MT_NONE;
+        break;
+#endif
+      default:                             /* unexpected call mode */
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_DataCorrupt );
+        return( AT_FAIL );
+      }
+      break;
+
+    /*
+     *-----------------------------------------------------------------
+     * start with a data call
+     *-----------------------------------------------------------------
+     */
+#ifdef FAX_AND_DATA
+
+      case( D_TOC_Data ):
+
+      switch( ccShrdPrm.CMODmode )
+      {
+      case( CMOD_MOD_Single ):             /* single data call */
+        pfilled_ctb->rptInd          = RI_NOT_PRES;
+
+        pfilled_ctb->BC[0].rate        = cmhCC_SelRate( ccShrdPrm.CBSTspeed );
+
+#ifdef FF_FAX
+        if( pT30CmdPrm -> FCLASSclass EQ FCLASS_CLASS_Fax20 )
+        {
+          pfilled_ctb->BC[0].bearer_serv = BEARER_SERV_FAX;
+          pfilled_ctb->BC[0].conn_elem   = CONN_ELEM_TRANS;
+          pfilled_ctb->BC[0].modem_type  = MT_NONE;
+        }
+        else
+#endif /* FF_FAX */
+        {
+          pfilled_ctb->BC[0].bearer_serv = cmhCC_SelServ( ccShrdPrm.CBSTname );
+          pfilled_ctb->BC[0].conn_elem   = cmhCC_SelCE(   ccShrdPrm.CBSTce );
+          pfilled_ctb->BC[0].modem_type  = cmhCC_SelMT  ( ccShrdPrm.CBSTspeed );
+
+          pfilled_ctb->BC[0].stop_bits   = cmhCC_SelStopBit( srcId );
+          pfilled_ctb->BC[0].data_bits   = cmhCC_SelDataBit( srcId );
+          pfilled_ctb->BC[0].parity      = cmhCC_SelParity ( srcId );
+        }
+
+        pfilled_ctb->BC[1].rate        = UR_NOT_PRES;
+        pfilled_ctb->BC[1].bearer_serv = BEARER_SERV_NOT_PRES;
+        pfilled_ctb->BC[1].conn_elem   = CONN_ELEM_NOT_PRES;
+        break;
+
+      case( CMOD_MOD_VoiceDat ):           /* alternating data/voice call */
+        pfilled_ctb->rptInd          = RI_CIRCULAR;
+
+        pfilled_ctb->BC[0].rate        = cmhCC_SelRate( ccShrdPrm.CBSTspeed );
+        pfilled_ctb->BC[0].bearer_serv = cmhCC_SelServ( ccShrdPrm.CBSTname );
+        pfilled_ctb->BC[0].conn_elem   = cmhCC_SelCE(   ccShrdPrm.CBSTce );
+        pfilled_ctb->BC[0].modem_type  = cmhCC_SelMT  ( ccShrdPrm.CBSTspeed );
+
+        pfilled_ctb->BC[0].stop_bits   = cmhCC_SelStopBit( srcId );
+        pfilled_ctb->BC[0].data_bits   = cmhCC_SelDataBit( srcId );
+        pfilled_ctb->BC[0].parity      = cmhCC_SelParity ( srcId );
+
+        pfilled_ctb->BC[1].rate        = UR_NOT_PRES;
+        pfilled_ctb->BC[1].bearer_serv = cmhCC_set_speech_serv (pCCCmdPrm);
+        pfilled_ctb->BC[1].conn_elem   = CONN_ELEM_NOT_PRES;
+        break;
+
+      case( CMOD_MOD_VoiceFlwdDat ):       /* voice followed by data call */
+
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+        return( AT_FAIL );                 /* operation not allowed */
+
+      case( CMOD_MOD_VoiceFax ):           /* alternating fax/voice call */
+        pfilled_ctb->rptInd          = RI_CIRCULAR;
+
+        pfilled_ctb->BC[0].rate        = cmhCC_SelRate( ccShrdPrm.CBSTspeed );
+        pfilled_ctb->BC[0].bearer_serv = BEARER_SERV_FAX;
+        pfilled_ctb->BC[0].conn_elem   = CONN_ELEM_TRANS;
+        pfilled_ctb->BC[0].modem_type  = MT_NONE;
+
+        pfilled_ctb->BC[1].rate        = UR_NOT_PRES;
+        pfilled_ctb->BC[1].bearer_serv = cmhCC_set_speech_serv (pCCCmdPrm);
+        pfilled_ctb->BC[1].conn_elem   = CONN_ELEM_NOT_PRES;
+        break;
+
+      default:                             /* unexpected call mode */
+        ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_DataCorrupt );
+        return( AT_FAIL );
+      }
+      break;
+
+#endif    /* of #ifdef FAX_AND_DATA */
+
+    default:                               /* unexpected call type */
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_DataCorrupt );
+      return( AT_FAIL );
+  }
+
+  return( AT_CMPL );
+}
+
+#ifdef FF_TTY
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_notifyTTY          |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function converts the TTY activity to the trx state
+            to be provided by '%CTYI: ...'.
+*/
+
+GLOBAL T_ACI_CTTY_TRX cmhCC_getTTYtrx_state (int ttyTrxState)
+{
+  switch (ttyTrxState)
+  {
+  case TTY_OFF:
+    return CTTY_TRX_Off;
+  case TTY_HCO:
+    return CTTY_TRX_SendOn;
+  case TTY_VCO:
+    return CTTY_TRX_RcvOn;
+  case TTY_ALL:
+    return CTTY_TRX_RcvSendOn;
+  default:
+    break;
+  }
+  return CTTY_TRX_Unknown;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_notifyTTY          |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function generates the unsolicited message '%CTYI: ...'
+            for any logical channel having registered for.
+*/
+
+GLOBAL void cmhCC_notifyTTY (T_ACI_CTTY_NEG neg,
+                             T_ACI_CTTY_TRX trx)
+{
+  int i;
+
+  for (i = CMD_SRC_LCL; i < CMD_SRC_MAX; i++)
+  {
+    if (cmhPrm[i].ccCmdPrm.CTTYmode EQ CTTY_MOD_Enable)
+    {
+      R_AT (RAT_CTYI, i) (neg, trx);
+    }
+  }
+}
+#endif /* FF_TTY */
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_checkALS_Support   |
++--------------------------------------------------------------------+
+
+  PURPOSE : These function checks for ALS support in two steps
+*/
+
+GLOBAL void cmhCC_checkALS_Support()
+{
+  TRACE_FUNCTION ("cmhCC_checkALS_Support()");
+
+  /* Step #1: read CPHS info first */
+  cmhSIM_ReadTranspEF( CMD_SRC_NONE,
+                       AT_CMD_NONE,
+                       SIM_CPHS_CINF,
+                       0,
+                       ACI_CPHS_INFO_SIZE,
+                       NULL,
+                       cmhCC_checkALS_Support_cb );
+}
+
+GLOBAL void cmhCC_checkALS_Support_2()
+{
+  TRACE_FUNCTION ("cmhCC_checkALS_Support_2()");
+
+  /* Step #2: then read the actual CSP */
+  cmhSIM_ReadTranspEF( CMD_SRC_NONE,
+                       AT_CMD_NONE,
+                       SIM_CPHS_CSP,
+                       0,
+                       0,
+                       NULL,
+                       cmhCC_checkALS_Support_cb_2 );
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_redialCheck        |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function evaluates conditions for redialling
+*/
+
+GLOBAL void cmhCC_redialCheck(SHORT cId)
+{
+  T_CC_CALL_TBL *ctbFail = ccShrdPrm.ctb[ccShrdPrm.cIdFail];
+  T_CC_CALL_TBL *ctb     = ccShrdPrm.ctb[cId];
+  SHORT error_indication;
+  int i;
+
+  TRACE_FUNCTION ("cmhCC_redialCheck()");
+
+  /* check conditions for error_indication check */
+  if((rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) AND (rdlPrm.rdlcId EQ NO_ENTRY))
+  {/* if black list is full no further redial attempts; user has to delete the black list */
+    if(cmhCC_redialChkBlackl(cId) EQ AT_CMPL)
+    {
+      if(cc_blacklist_ptr->blCount NEQ MAX_NUM_ENTR_BLACK_LIST)
+      {
+        if( ccShrdPrm.cIdFail < 0 OR ccShrdPrm.cIdFail > MAX_CALL_NR )
+        {
+          error_indication = GET_CAUSE_VALUE(CAUSE_MAKE(DEFBY_STD,
+                                                        ORIGSIDE_MS, 
+                                                        ACI_ORIGINATING_ENTITY,
+                                                        NOT_PRESENT_8BIT));
+        }
+        else if( GET_CAUSE_VALUE(ctbFail->rejCs) NEQ NOT_PRESENT_8BIT )
+        {
+         error_indication = GET_CAUSE_VALUE(ctbFail->rejCs);
+        }
+        else if( GET_CAUSE_VALUE(ctbFail->nrmCs) NEQ NOT_PRESENT_8BIT )
+        {
+          error_indication = GET_CAUSE_VALUE(ctbFail->nrmCs);
+        }
+        else if( GET_CAUSE_VALUE(ctbFail->rslt) NEQ NOT_PRESENT_8BIT )
+        {
+          error_indication = GET_CAUSE_VALUE(ctbFail->rslt);
+        }
+        else
+        {/* in case network has sent no extended report */
+          error_indication = GET_CAUSE_VALUE(CAUSE_MAKE(DEFBY_STD,
+                                                        ORIGSIDE_MS,
+                                                        ACI_ORIGINATING_ENTITY,
+                                                        NOT_PRESENT_8BIT));
+        }
+
+        /* check error_indication (ETSI 2.07, Annex A) and redial counter */
+        switch (error_indication)
+        {
+          /*** indications of category 1 ***/
+          case 17:            /* user busy */
+          /*** indications of category 2 ***/
+          case 18:            /* no user responding */
+          case 19:            /* user alterting, no answer */
+          case 27:            /* destination out of order */
+          case 34:            /* no circuit/channel available */
+          case 41:            /* temporary failure */
+          case 42:            /* switching equipment congestion */
+          case 44:            /* requested circuit/channel available */
+          case 47:            /*esources unavailable, unspecified */
+
+            if(!ctb->rdlCnt)
+            {/* first redial attempt, 5+5 sec for first call attempt */
+              rdlPrm.rdlcId = cId;
+              TIMERSTART(ACI_REPEAT_1+ACI_DELAY_TIMER,ACI_REPEAT_HND);
+              for(i = 0; i < CMD_SRC_MAX; i++)
+              {
+                R_AT(RAT_RDL, i)(CALL_ATTEMPT_FAILED);
+                R_AT(RAT_RDL, i)(REDIAL_TIM_START);
+              }
+            }
+            else if((ctb->rdlCnt>=1) AND (ctb->rdlCnt<=3))
+            {/* from 2nd to 4th redial attempt, 1 min + 5 sec for the following call attempt */
+              rdlPrm.rdlcId = cId;
+   #ifdef _SIMULATION_
+              TIMERSTART(ACI_REPEAT_1,ACI_REPEAT_HND);
+   #else
+              TIMERSTART(ACI_REPEAT_2_4+ACI_DELAY_TIMER,ACI_REPEAT_HND);
+   #endif
+              for(i = 0; i < CMD_SRC_MAX; i++)
+              {
+                R_AT(RAT_RDL, i)(CALL_ATTEMPT_FAILED);
+                R_AT(RAT_RDL, i)(REDIAL_TIM_START);
+              }
+            }
+            else if((ctb->rdlCnt >= 4) AND (ctb->rdlCnt < MAX_NUM_REPEAT_ATT))
+            {/* from 5th to 10th redial attempt, 3 x 1 min + 5 sec for the following call attempt */
+              rdlPrm.rdlcId = cId;
+  #ifdef _SIMULATION_
+              TIMERSTART(ACI_REPEAT_1,ACI_REPEAT_HND);
+  #else
+              ctb->rdlTimIndex = 1;
+              TIMERSTART(ACI_REPEAT_2_4+ACI_DELAY_TIMER,ACI_REPEAT_HND);
+  #endif
+              for(i = 0; i < CMD_SRC_MAX; i++)
+              {
+                R_AT(RAT_RDL, i)(CALL_ATTEMPT_FAILED);
+                R_AT(RAT_RDL, i)(REDIAL_TIM_START);
+              }
+            }
+            /* else : ctb->rdlCnt = MAX_NUM_REPEAT_ATT -> entry is black list */
+            break;
+          /*** indications of category 3 -> only one redial attempt is allowed ***/
+          case 28:            /* invalid number format */
+            ctb->rdlCnt = 0;
+            break;            /* for incorrect number we do not start redialling */
+          case 1:             /* unassigned (unallocated) number */
+          case 3:             /* no route to destination */
+          case 22:            /* number changed */
+          case 38:            /* network out of order */
+            if(!ctb->rdlCnt)
+            {/* first redial attempt */
+              ctb->rdlCnt = MAX_NUM_REPEAT_ATT - 1;
+              rdlPrm.rdlcId = cId;
+              /* 5+5 sec for first (= only) call attempt */
+              TIMERSTART(ACI_REPEAT_1+ACI_DELAY_TIMER,ACI_REPEAT_HND);
+              for(i = 0; i < CMD_SRC_MAX; i++)
+              {
+                R_AT(RAT_RDL, i)(CALL_ATTEMPT_FAILED);
+                R_AT(RAT_RDL, i)(REDIAL_TIM_START);
+              }
+            }
+            else
+            {/* more than one attempt is not allowed --> entry in blacklist */
+              ctb->rdlCnt = MAX_NUM_REPEAT_ATT;
+              for(i = 0; i < CMD_SRC_MAX; i++)
+              {
+                R_AT(RAT_RDL, i)(CALL_ATTEMPT_FAILED);
+              }
+             }
+             break;
+          default:
+            ctb->rdlCnt = 0;
+            break;
+        }
+      }
+
+      /* check redial counter against black list: add entry if the list is not full yet */
+      if((ctb->rdlCnt EQ MAX_NUM_REPEAT_ATT) AND
+        (cc_blacklist_ptr->blCount< MAX_NUM_ENTR_BLACK_LIST))
+      {/* add entry in black list */
+        cc_blacklist_ptr->blCount++;
+        cc_blacklist_ptr->blNum[cc_blacklist_ptr->blCount-1].numb_len = 
+          ctb->cldPty.c_called_num;
+        memcpy(cc_blacklist_ptr->blNum[cc_blacklist_ptr->blCount-1].number, 
+               ctb->cldPty.called_num,
+               ctb->cldPty.c_called_num);
+        cc_blacklist_ptr->blNum[cc_blacklist_ptr->blCount-1].type.ton =
+          ctb->cldPty.ton;
+        cc_blacklist_ptr->blNum[cc_blacklist_ptr->blCount-1].type.npi =
+          ctb->cldPty.npi;
+
+        ctb->rdlCnt = 0; /* reset redial counter in call table */
+        ctb->rdlTimIndex = RDL_TIM_INDEX_NOT_PRESENT;
+        if(cc_blacklist_ptr->blCount EQ MAX_NUM_ENTR_BLACK_LIST)
+        {
+          for(i = 0; i < CMD_SRC_MAX; i++)
+          {
+            R_AT(RAT_RDLB, i)(BLACKLIST_FULL);
+          }
+        }
+        else
+        {
+          for(i = 0; i < CMD_SRC_MAX; i++)
+          {
+            R_AT(RAT_RDLB, i)(ENTRY_BLACKLISTED);
+          }
+        }
+      }
+    }
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_redialChkBlackl    |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function checks the new cId against the black list
+*/
+
+GLOBAL T_ACI_RETURN cmhCC_redialChkBlackl(SHORT cId)
+{
+  UBYTE bl_index = 0;
+  int i;
+
+  TRACE_FUNCTION ("cmhCC_redialChkBlackl()");
+
+  if(cc_blacklist_ptr NEQ NULL)
+  {
+    for(bl_index=0; bl_index<cc_blacklist_ptr->blCount;bl_index++)
+    {
+      T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+
+      if (memcmp (cc_blacklist_ptr->blNum[bl_index].number,
+                  ctb->cldPty.called_num,
+                  ctb->cldPty.c_called_num) EQ 0)
+      {
+        for(i = 0; i < CMD_SRC_MAX; i++)
+        {
+          R_AT(RAT_RDLB, i)(ENTRY_IN_BLACKLIST);
+        }
+        return( AT_FAIL );
+      }
+    }
+  }
+  return( AT_CMPL );
+}
+#if defined(_TARGET_)
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : CMH_CCF                  |
+| STATE   : code                  ROUTINE : cmhCC_rd_mode_FFS        |
++--------------------------------------------------------------------+
+
+  PURPOSE : This function writes redial_mode in FFS
+*/
+
+GLOBAL T_ACI_RETURN cmhCC_rd_mode_FFS(T_ACI_CC_REDIAL_MODE rdl_mode,
+                                      T_ACI_CC_RDL_FFS ffs_mode)
+{
+  T_ACI_CC_REDIAL_MODE redial_mode;
+
+  TRACE_FUNCTION ("cmhCC_rd_mode_FFS()");
+
+  switch(FFS_mkdir("/gsm/com"))
+  {/* create/check ffs directory */
+    case EFFS_OK:
+    case EFFS_EXISTS:
+      break;
+    default:
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return ( AT_FAIL );
+  }
+
+  if(ffs_mode EQ WRITE_RDLmode)
+  {
+    if(FFS_fwrite("/gsm/com/redialMode",&rdl_mode, sizeof(T_ACI_CC_REDIAL_MODE)) NEQ EFFS_OK)
+    {
+      ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+      return ( AT_FAIL );
+    }
+    return AT_CMPL;
+  }
+  else if(ffs_mode EQ READ_RDLmode)
+  {
+    FFS_fread("/gsm/com/redialMode",&redial_mode, sizeof(T_ACI_CC_REDIAL_MODE));
+    switch(redial_mode)
+    {
+      case AUTOM_REP_NOT_PRESENT:
+        rdlPrm.rdlMod = AUTOM_REPEAT_OFF;
+        return AT_CMPL;;
+      case AUTOM_REPEAT_OFF:
+      case AUTOM_REPEAT_ON:
+        rdlPrm.rdlMod = redial_mode;
+        return AT_CMPL;;
+      default:
+       ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+       return ( AT_FAIL );
+    }
+  }
+  else
+  {
+    ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
+    return ( AT_FAIL );
+  }
+}
+#endif /* _TARGET_ */
+/*==== EOF ========================================================*/
+