diff src/g23m-gsm/cc/cc_est.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-gsm/cc/cc_est.c	Sun Jul 15 04:40:46 2018 +0000
@@ -0,0 +1,1878 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GSM-PS (6147)
+|  Modul   :  CC_EST
++----------------------------------------------------------------------------- 
+|  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 Modul defines the functions for the establishment
+|             phase of the call control process of the component CC.
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifndef CC_EST_C
+#define CC_EST_C
+
+#define ENTITY_CC
+/*==== INCLUDES ===================================================*/
+
+#include <string.h>
+#include "typedefs.h"
+#include "pcm.h"
+#include "vsi.h"
+#include "custom.h"
+#include "gsm.h"
+#include "message.h"
+#include "ccdapi.h"
+#include "prim.h"
+#include "cnf_cc.h"
+#include "mon_cc.h"
+#include "pei.h"
+#include "tok.h"
+#include "cc.h"
+#include "cc_em.h"
+
+/*==== EXPORT =====================================================*/
+/*==== PROTOTYPE ==================================================*/
+/* Implements Measure#  19 */                                       
+LOCAL void cc_send_release_cmp (USHORT cause);
+LOCAL void cc_send_mncc_release_ind (UBYTE  ti, USHORT cause);
+/*==== PRIVAT =====================================================*/
+
+/*==== VARIABLES ==================================================*/
+
+/*==== FUNCTIONS ==================================================*/
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_init                    |
++--------------------------------------------------------------------+
+
+  PURPOSE : Initialisation of CC data.
+
+*/
+
+GLOBAL void cc_init (void)
+{
+#ifdef OPTION_MULTIPLE_INSTANCES
+
+  USHORT i;
+
+  TRACE_FUNCTION ("cc_init()");
+
+  for (i=0;i<MAX_INSTANCES;i++)
+    cc_init_data (&data_base[i]);
+}
+#else
+
+  TRACE_FUNCTION ("cc_init()");
+  cc_init_data ();
+#endif
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)            MODULE  : CC_EST                |
+| STATE   : code                     ROUTINE : cc_init_data          |
++--------------------------------------------------------------------+
+
+  PURPOSE : Initializes the data for one instance.
+
+*/
+
+GLOBAL void cc_init_data (void)
+{
+  GET_INSTANCE_DATA;
+  USHORT i;
+
+  TRACE_FUNCTION ("cc_init_data()");
+
+  memset (cc_data, 0, sizeof (T_CC_DATA));
+
+  /* No SETUP / EMERGENCY SETUP pending */
+  cc_data->stored_setup = NULL;
+
+  /* No CCBS SETUP pending */
+  cc_data->stored_ccbs_setup = NULL;
+  
+  cc_data->channel_mode = NAS_CHM_SIG_ONLY;
+
+  for (i=0;i<MAX_CC_CALLS;i++)
+  {
+    cc_data->stored_ti_values[i] = NOT_PRESENT_8BIT;
+  }
+
+  cc_csf_ms_cap ();
+
+  /*
+   * Initialise single numbering scheme
+   */
+  cc_data->sns_bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH;
+  cc_data->sns_mode = MNCC_SNS_MODE_VOICE;
+
+  /*
+   * Initialise connection element for MTC
+   */
+  cc_data->conn_elem = MNCC_CONN_ELEM_NON_TRANS;
+
+  /* 
+   * Initialize setup_reattempt_ti to not present 
+   */
+  cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_mncc_configure_req      |
++--------------------------------------------------------------------+
+
+  PURPOSE : Configuration of bearer capabilities and subaddress
+            by man machine interface.
+
+*/
+
+static const UBYTE def_modem_type [8] = 
+{
+    MNCC_MT_V21,       /* user rate 300 Baud    ->  modem type V.21    */
+    MNCC_MT_V22,       /* user rate 1200 Baud   ->  modem type V.22    */
+    MNCC_MT_V22_BIS,   /* user rate 2400 Baud   ->  modem type V.22bis */
+    MNCC_MT_V32,       /* user rate 4800 Baud   ->  modem type V32     */
+    MNCC_MT_V32,       /* user rate 9600 Baud   ->  modem type V32     */
+    MNCC_MT_V32,       /* 12k transparent, not supported now by ACI    */
+    MNCC_MT_V23,       /* user rate 12k/75 Baud ->  modem type V23     */
+    MNCC_MT_V21,       /* user rate 14.4 kBaud  ->  modem type V21 ??? */
+};
+
+GLOBAL void cc_mncc_configure_req (T_MNCC_CONFIGURE_REQ * config)
+{
+
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_configure_req()");
+
+  /*
+   * store own subadress if available
+   * 
+   * NOTE: T_called_party_sub is the wrong type here in MNCC_CONFIGURE_REQ, 
+   *       this should have been T_calling_party_sub as this is that what
+   *       the subaddress is used for in the uplink SETUP message later.
+   *       Doesn't really matter here as the types are identical, it's 
+   *       just somewhat confusing and could be occasionally be changed.
+   */
+  if (config->called_party_sub.c_subaddr)
+  {
+    cc_data->my_party_subaddr.v_tos      = TRUE;
+    cc_data->my_party_subaddr.tos        = config->called_party_sub.tos;
+    cc_data->my_party_subaddr.v_odd_even = TRUE;
+    cc_data->my_party_subaddr.odd_even   = config->called_party_sub.odd_even;
+    cc_data->my_party_subaddr.c_subaddr  = config->called_party_sub.c_subaddr;
+    memcpy (cc_data->my_party_subaddr.subaddr,
+            config->called_party_sub.subaddr,
+            config->called_party_sub.c_subaddr);
+  }
+  else
+    memset (&cc_data->my_party_subaddr, 0, sizeof (T_M_CC_called_subaddr));
+  /*
+   * Store CTM support
+   */
+  cc_data->ctm_ena = config->ctm_ena;
+  /*
+   * Store Single Numbering Scheme BC parameter and mode
+   * if available
+   */
+  if (config->sns_mode NEQ NOT_PRESENT_8BIT)
+  {
+   /*
+    * Store Connection Element for MTC
+    * Note that setting conditionally on sns_mode NEQ NOT_PRESENT_8BIT is 
+    * possible because ACI always sets sns_mode to something different from
+    * NOT_PRESENT_8BIT when it sends an MNCC_CONFIGURE_REQ.
+    * For future proof use of MNCC_CONFIGURE_REQ (e.g. only subaddress is valid!)
+    * it is convenient and correct to consider parameters only if they
+    * are valid.
+    */
+
+    cc_data->conn_elem = config->bcpara.conn_elem;
+
+    cc_data->sns_mode = config->sns_mode;
+
+    if (cc_data->sns_mode EQ MNCC_SNS_MODE_VOICE)
+    {
+      memset (&cc_data->sns_bcpara, 0 /*NOT_PRESENT_8BIT*/, sizeof (T_MNCC_bcpara));
+      cc_data->sns_bcpara.bearer_serv = (cc_data->ctm_ena EQ MNCC_CTM_ENABLED)?
+                                        MNCC_BEARER_SERV_SPEECH_CTM: MNCC_BEARER_SERV_SPEECH;
+    }
+    else
+      memcpy (&cc_data->sns_bcpara, &config->bcpara, sizeof (T_MNCC_bcpara));
+    /*
+     * Set modem type to default values for single numbering scheme
+     */
+    switch (cc_data->sns_bcpara.bearer_serv)
+    {
+      case MNCC_BEARER_SERV_FAX:
+        cc_data->sns_bcpara.modem_type = M_CC_MT_NONE;
+        break;
+      case MNCC_BEARER_SERV_SPEECH:
+      case MNCC_BEARER_SERV_AUX_SPEECH:
+      case MNCC_BEARER_SERV_SPEECH_CTM:
+      case MNCC_BEARER_SERV_AUX_SPEECH_CTM:
+        break;
+      default:
+        cc_data->sns_bcpara.modem_type = def_modem_type[config->bcpara.rate-1];
+        if (config->bcpara.modem_type == MNCC_MT_V34)
+        {
+          cc_data->sns_bcpara.modem_type = MNCC_MT_V34;
+        }
+        break;
+    }
+  }
+
+  /*
+   * define connection element if a preferred one is set by MMI
+   */
+  if (cc_data->sns_bcpara.conn_elem EQ MNCC_CONN_ELEM_TRANS_PREF)
+  {
+    /*
+     * check only if transparent asynchronous data services are supported
+     */
+    if (FldGet(cc_data->mscap.datCap1, AsySup))
+      cc_data->sns_bcpara.conn_elem = M_CC_CE_TRANSPA;
+    else
+      cc_data->sns_bcpara.conn_elem = M_CC_CE_RLP;
+  }
+
+  /*
+   * define connection element if a preferred one is set by MMI
+   */
+  if (cc_data->sns_bcpara.conn_elem EQ MNCC_CONN_ELEM_NON_TRANS_PREF)
+  {
+    /*
+     * check only if non-transparent asynchronous data services are supported
+     */
+    if (FldGet (cc_data->mscap.datCap1, RLPSup))
+      cc_data->sns_bcpara.conn_elem = M_CC_CE_RLP;
+    else
+      cc_data->sns_bcpara.conn_elem = M_CC_CE_TRANSPA;
+  }
+
+  PFREE (config);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_mncc_prompt_rsp         |
++--------------------------------------------------------------------+
+
+  PURPOSE : A new transaction identifier during network initiated 
+            mobile origination call establishment was assigned by 
+            upper layers. Under normal conditions this causes the 
+            emmission of an MMCC_DATA_REQ (START CC) 
+
+*/
+
+GLOBAL void cc_mncc_prompt_res (T_MNCC_PROMPT_RES * prompt)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_prompt_rsp()");
+
+  /* Check parameters */
+  if (prompt->ti >= 7)
+  {
+    /* Invalid transaction identifier */
+/* Implements Measure#  36, 48 */
+    cc_send_mncc_release_ind (prompt->ti, 
+                                CAUSE_MAKE(DEFBY_STD, 
+                                ORIGSIDE_MS, 
+                                MNCC_CC_ORIGINATING_ENTITY, 
+                                M_CC_CAUSE_INVALID_TI));    
+
+    PFREE (prompt);
+    return;
+  }
+
+  /* Assign ti and allocate a free entry in the call data */ 
+  cc_data->ti = prompt->ti;
+  cc_data->index_ti = srv_define_ti();
+  if (cc_data->index_ti EQ NOT_PRESENT_8BIT)
+  {
+    /*
+     * No call instance available
+     */
+/* Implements Measure#  36, 48 */
+    cc_send_mncc_release_ind (prompt->ti, MNCC_CAUSE_MAX_NO_CALLS_REACHED);
+
+    PFREE (prompt);
+    return;
+  }
+
+  /* Send MMCC_PROMPT_RSP */
+  {
+    PALLOC (prompt_rsp, MMCM_PROMPT_RES); // T_MMCM_ESTABLISH_REQ
+    prompt_rsp->ti = prompt->ti;
+    PSENDX (MM, prompt_rsp);
+  }
+  
+  /* Send MMCC_DATA_REQ (START CC) */
+  
+  CCD_START;
+  {
+    MCAST (start_cc, U_START_CC);
+    cc_build_start_cc (start_cc);
+    for_start_cc (start_cc);
+  }
+  CCD_END;
+
+  /* Start Timer T332 */
+  TIMERSTART (T332, T332_VALUE);
+
+  PFREE (prompt);
+  
+  /* Next state is WAIT FOR NETWORK INFO (U0.3) */
+  cc_set_state (M_CC_CS_03);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_mncc_prompt_rej         |
++--------------------------------------------------------------------+
+
+  PURPOSE : A new transaction identifier during network initiated 
+            mobile origination call establishment could not be 
+            assigned by upper layers. MM is informed by
+            MMCC_PROMPT_REJ.
+
+*/
+
+GLOBAL void cc_mncc_prompt_rej (T_MNCC_PROMPT_REJ * prompt)
+{
+  TRACE_FUNCTION ("cc_mncc_prompt_rej()");
+
+  PFREE (prompt);
+  
+  {
+    PALLOC (reject, MMCM_PROMPT_REJ);
+    PSENDX (MM, reject);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_mncc_setup_req          |
++--------------------------------------------------------------------+
+
+  PURPOSE : Starting of mobile originated call.
+
+*/
+
+GLOBAL void cc_mncc_setup_req (T_MNCC_SETUP_REQ * setup)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_setup_req()");
+  cc_data->index_ti = srv_convert_ti (setup->ti);
+  if (cc_data->index_ti NEQ NOT_PRESENT_8BIT)
+  {
+    /*
+     * Transaction identifier already present, this means, we know this ti
+     * and CC is not in M_CC_CS_0 state. This is okay for M_CC_CS_06 (CCBS), 
+     * for every other state this is an internal failure.
+     */
+    switch (cc_data->state[cc_data->index_ti])
+    {
+      case M_CC_CS_06: /* RECALL present */
+        /* 
+         * Don't use the setup parametes from ACI, instead use 
+         * the stored SETUP message in CC.
+         */
+
+        cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT;
+
+        /* No ugly CC setup reattempts here */
+        cc_data->setup_attempts = MAX_SETUP_ATTEMPTS;
+        cc_data->setup_reattempt_ti = NOT_PRESENT_8BIT;
+
+        /* Send stored SETUP message to network and forget it */
+        for_pd (cc_data->stored_ccbs_setup);
+        cc_data->stored_ccbs_setup = NULL;
+
+        /* Set parameters in cc_data */
+        cc_data->call_type [cc_data->index_ti]    = CALL_TYPE_MOC;
+
+        /* initialize disconnect collision flag */
+        cc_data->disc_coll [cc_data->index_ti]    = FALSE;
+
+        cc_data->t308_counter [cc_data->index_ti] = 0;
+        cc_reset_dtmf ();
+
+        /* Start T303 */
+        TIMERSTART (T303, T303_VALUE);
+
+        /* Next state is CALL INIT */
+        cc_set_state (M_CC_CS_1);
+        break;
+    
+      default: /* The ti is already in use and it is not CCBS recall */
+        {
+          PALLOC (rel, MNCC_RELEASE_IND);
+          rel->ti = setup->ti;
+          rel->cause = M_CC_CAUSE_INVALID_TI;
+          rel->c_raw_cause = 0;
+          PSENDX (MMI, rel);
+        }
+        break;
+    }
+    PFREE (setup);
+    return;
+  }
+
+  if (setup->ti >= 7)
+  {
+    /*
+     * Invalid transaction identifier
+     */
+/* Implements Measure#  36, 48 */
+    cc_send_mncc_release_ind (setup->ti,
+                                CAUSE_MAKE(DEFBY_STD, 
+                                ORIGSIDE_MS, 
+                                MNCC_CC_ORIGINATING_ENTITY, 
+                                M_CC_CAUSE_INVALID_TI));    
+    PFREE (setup);
+    return;
+  }
+
+  /*
+   * ti is valid here and not already in use
+   */
+  cc_data->ti = setup->ti;
+  cc_data->index_ti = srv_define_ti ();
+  if (cc_data->index_ti EQ NOT_PRESENT_8BIT)
+  {
+    /*
+     * No call instance available
+     */
+/* Implements Measure#  36, 48 */
+    cc_send_mncc_release_ind (setup->ti, MNCC_CAUSE_MAX_NO_CALLS_REACHED);
+    PFREE (setup);
+    return;
+  }
+
+  /*
+   * Security check: if bcpara indicates not present,
+   * set service to speech
+   */
+  if (setup->bcpara.bearer_serv EQ NOT_PRESENT_8BIT)
+  {
+    setup->bcpara.bearer_serv = (cc_data->ctm_ena EQ MNCC_CTM_ENABLED)?
+                                MNCC_BEARER_SERV_SPEECH_CTM: MNCC_BEARER_SERV_SPEECH;
+  }
+  /*
+   * Security check: if prio indicates emergency call,
+   * set service to speech or speech with CTM
+   */
+  if (setup->prio NEQ MNCC_PRIO_NORM_CALL)
+  {
+    switch (setup->bcpara.bearer_serv)
+    {
+    case MNCC_BEARER_SERV_SPEECH:
+    case MNCC_BEARER_SERV_SPEECH_CTM:
+      break;
+    case MNCC_BEARER_SERV_AUX_SPEECH_CTM:
+      setup->bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH_CTM;
+      break;
+    default:
+      setup->bcpara.bearer_serv = MNCC_BEARER_SERV_SPEECH;
+      break;
+    }
+  }
+
+  if (cc_check_capabilities (&setup->bcpara) EQ FALSE OR 
+      cc_check_capabilities ((T_MNCC_bcpara *)&setup->bcpara2) EQ FALSE)
+  {
+    /*
+     * MS doesn't support the requested services.
+     */
+    PALLOC ( rel, MNCC_RELEASE_IND);
+
+    rel->ti    = setup->ti;
+    rel->cause = CAUSE_MAKE(DEFBY_STD, 
+                            ORIGSIDE_MS, 
+                            MNCC_CC_ORIGINATING_ENTITY, 
+                            M_CC_CAUSE_BEARER_NOT_IMPLEM);
+    rel->c_raw_cause = 0;
+
+    PSENDX (MMI, rel);
+
+    srv_free_ti ();
+
+    PFREE (setup);
+  }
+  else
+  {
+    PALLOC (est, MMCM_ESTABLISH_REQ); /* T_MMCM_ESTABLISH_REQ */
+    cc_build_bc (&cc_data->bc1, &cc_data->serv1, &setup->bcpara);
+    cc_data->ri = setup->ri;
+    cc_data->bcpara1 = setup->bcpara;
+    memcpy (&cc_data->bcpara2, &setup->bcpara2, sizeof (T_MNCC_bcpara)); 
+
+    if (cc_data->ri EQ NOT_PRESENT_8BIT)
+      cc_data->serv2 = NOT_PRESENT_8BIT;
+    else
+      cc_build_bc (&cc_data->bc2, &cc_data->serv2, (T_MNCC_bcpara *)&setup->bcpara2);
+    memcpy (&cc_data->bcpara2, &setup->bcpara2, sizeof (T_MNCC_bcpara));
+    est->org_entity = NAS_ORG_ENTITY_CC;
+    est->ti = setup->ti;
+
+    /* Set establ_serv according to chosen bearer capability */
+    switch (cc_data->bcpara1.bearer_serv)
+    {
+      case MNCC_BEARER_SERV_SPEECH:
+          est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH;
+        break;
+
+      case MNCC_BEARER_SERV_ASYNC:
+        if (cc_data->bcpara1.conn_elem == MNCC_CONN_ELEM_TRANS ||
+          cc_data->bcpara1.conn_elem == MNCC_CONN_ELEM_TRANS_PREF)
+        {
+            est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
+        }
+        else
+        {
+            est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
+        }
+        break;
+
+      case MNCC_BEARER_SERV_FAX:
+          est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
+        break;
+
+      default:
+          est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH;
+        break;
+    }
+
+    switch (cc_data->serv1)
+    {
+      case MNCC_SERV_DATA:
+        if (FldGet(cc_data->mscap.datCap2, DHRSup))
+        {
+          /*
+           * Halfrate support for data
+           */
+          switch (setup->bcpara.rate)
+          {
+            case M_CC_UR_0_3_KBIT:
+            case M_CC_UR_1_2_KBIT:
+            case M_CC_UR_2_4_KBIT:
+            case M_CC_UR_4_8_KBIT:
+            case M_CC_UR_1_2_KBIT_V23:
+              est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
+              break;
+            default:
+              est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
+              break;
+          }
+        }
+        else
+          est->estcs = MMCM_ESTCS_MOB_ORIG_DATA;
+        break;
+
+      default: /* SERV_SPEECH */
+        if (setup->prio EQ MNCC_PRIO_NORM_CALL)
+          est->estcs = MMCM_ESTCS_MOB_ORIG_SPCH;
+        else
+          est->estcs = MMCM_ESTCS_EMERGE;
+        break;
+    }
+
+    /* Data solely needed for possible redial attempt */
+    cc_data->estcs              = est->estcs;
+    cc_data->setup_attempts     = 0;
+
+    srv_free_stored_setup ();
+    cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT;
+    cc_data->call_type [cc_data->index_ti]    = CALL_TYPE_MOC;
+    // PATCH LE 10.04.00
+    // initialize disconnect collision flag
+    cc_data->disc_coll [cc_data->index_ti]    = FALSE;
+    // END PATCH LE 10.04.00
+    cc_data->t308_counter [cc_data->index_ti] = 0;
+    cc_reset_dtmf ();
+
+    CCD_START;
+    if (setup->prio EQ MNCC_PRIO_NORM_CALL)
+    {
+      MCAST (setup_msg, U_SETUP);
+
+      cc_build_setup (setup_msg, setup);
+      for_setup (setup_msg);
+    }
+    else
+    {
+      MCAST (emergency_setup_msg, U_EMERGE_SETUP);
+
+      cc_build_emergency_setup (emergency_setup_msg);
+      for_emergency_setup (emergency_setup_msg);
+    }
+    CCD_END;
+
+    cc_set_state (M_CC_CS_01);
+    for_est_req (est);
+    TIMERSTART (T303, T303_VALUE);
+    PFREE (setup);
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_mncc_alert_req          |
++--------------------------------------------------------------------+
+
+  PURPOSE : The mobile side indicates alerting.
+
+*/
+
+GLOBAL void cc_mncc_alert_req (T_MNCC_ALERT_REQ * alert)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_alert_req()");
+
+  if ((cc_data->index_ti = srv_convert_ti (alert->ti))
+      EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (alert);
+    return;
+  }
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_9:
+      CCD_START;
+      {
+        MCAST (alert_msg, U_ALERT);
+        
+        cc_build_alert (alert_msg);
+        cc_set_state (M_CC_CS_7);
+        for_alert (alert_msg);
+      }
+      CCD_END;
+
+      EM_CC_ALERTING_SENT;
+
+      PFREE (alert);
+      break;
+
+    default:
+      PFREE (alert);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_mncc_setup_res          |
++--------------------------------------------------------------------+
+
+  PURPOSE : The mobile side indicates call acceptance.
+
+*/
+
+GLOBAL void cc_mncc_setup_res (T_MNCC_SETUP_RES * setup_res)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_setup_res()");
+
+  if ((cc_data->index_ti = srv_convert_ti (setup_res->ti))
+      EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (setup_res);
+    return;
+  }
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_7:
+    case M_CC_CS_9:
+      CCD_START;
+      {
+        MCAST (connect, U_CONNECT);
+        cc_build_connect (connect);
+        cc_set_state (M_CC_CS_8);
+        TIMERSTART (T313, T313_VALUE);
+        for_connect (connect);
+      }
+      CCD_END;
+
+      EM_CC_CONNECT_SENT;
+      
+      PFREE (setup_res);
+      break;
+
+    default:
+      PFREE (setup_res);
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_alert                   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming alert message.
+
+*/
+
+GLOBAL void cc_alert (T_D_ALERT * alert)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_alert()");
+
+  EM_CC_ALERTING_RECEIVED;
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_1:
+    case M_CC_CS_3:
+      if (cc_check_error_flag ())
+      {
+        PALLOC (alert_ind, MNCC_ALERT_IND);
+        TIMERSTOP (TIMER_CC);
+
+        if (alert->v_progress)
+        {
+          cc_data->progress_desc[cc_data->index_ti] = 
+            alert->progress.progress_desc;
+        }
+
+        cc_build_mncc_alert_ind (alert, alert_ind);
+        PSENDX (MMI, alert_ind);
+
+        cc_build_facility_ind (MNCC_FAC_IN_ALERT, alert->v_facility, &alert->facility);
+        cc_build_user_user_ind (MNCC_USER_IN_ALERT, alert->v_user_user, 
+                                &alert->user_user);
+        CCD_END;
+        srv_free_stored_setup ();
+        cc_set_state (M_CC_CS_4);
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_call_proceeding         |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming call proceed message.
+
+*/
+
+GLOBAL void cc_call_proceeding (T_D_CALL_PROCEED * proceed)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_call_proceeding()");
+
+  EM_CC_CALL_PROCEEDING_RECEIVED;
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_1:
+      if (cc_check_error_flag ())
+      {
+        TIMERSTOP (TIMER_CC); /* timer T303 */
+        if (cc_moc_compatibility (proceed) EQ OKAY)
+        {
+          PALLOC (proceed_ind, MNCC_CALL_PROCEED_IND);
+
+          cc_build_mncc_proceed_ind (proceed, proceed_ind);
+          PSENDX (MMI, proceed_ind);
+
+          cc_build_facility_ind (MNCC_FAC_IN_CALL_PROCEED, 
+                                   proceed->v_facility, &proceed->facility);
+          if (proceed->v_progress)
+          {
+             cc_data->progress_desc[cc_data->index_ti] = 
+               proceed->progress.progress_desc;
+          }
+    
+          CCD_END;
+          /* 
+           * - start T310 unless the CALL PROCEEDING message contains a progress indicator IE 
+           *   specifying progress description #1, #2, Ph2 handling is not done yet (#64), see
+           *   also issue 4967
+           * - start T310 unless a PROGRESS message with #1, 2, 64 has been 
+           *   received, this is achieved by remembering the progress description in cc_data
+           * - the case when 1. PROGRESS and 2. CALL PROCEEDING with e.g. #4 is handled by
+           *   interpreting 5.2.1.1.3 of 04.08 in the manner that a 2nd progress description
+           *   superseeds the first one. See also issue 4965 / CC-FIX-4965.
+           */
+          /* start T310 with Ph2 unless progress description value #1, #2 or #64 has been received */
+          {
+            UBYTE prog_desc = cc_data->progress_desc[cc_data->index_ti];
+            if ((prog_desc NEQ MNCC_PROG_NO_END_TO_END_PLMN)
+                  AND
+               (prog_desc NEQ MNCC_PROG_DEST_NON_PLMN)
+                  AND
+               (prog_desc NEQ MNCC_PROG_QUEUEING))
+            {
+                TIMERSTART (T310, T310_VALUE);
+            }
+          }
+          if (proceed->v_progress AND
+              proceed->progress.v_progress_desc AND 
+              proceed->progress.progress_desc EQ M_CC_PROG_INBAND_AVAIL)
+          {
+            /* 
+             * Avoid more call establishment attempts if there was
+             * inband announcement heard by the user. 
+             * The user should have no way to realize that more than one
+             * call attempt may be taken by CC.
+             */
+            cc_data->setup_attempts = MAX_SETUP_ATTEMPTS;
+          }
+
+          cc_set_state (M_CC_CS_3);
+        }
+        else /* bearer capability check on CALL PROCEEDING failed */
+        {
+          CCD_END;
+          CCD_START;
+          {
+            MCAST (disconnect, U_DISCONNECT);
+            PALLOC (rej_ind, MNCC_REJECT_IND);
+
+            rej_ind->ti  = cc_data->ti;
+            /* 
+             * GSM 04.08 does not specify what to do / which cause to use;
+             * Condat decided to use normal call clearing with cause #88
+             */
+            rej_ind->cause = CAUSE_MAKE(DEFBY_STD, 
+                                        ORIGSIDE_MS, 
+                                        MNCC_CC_ORIGINATING_ENTITY, 
+                                        MNCC_CAUSE_INCOMPAT_DEST); 
+            PSENDX (MMI, rej_ind);
+
+            cc_build_disconnect (disconnect, 
+                                 CAUSE_MAKE(DEFBY_STD, 
+                                            ORIGSIDE_MS, 
+                                            MNCC_CC_ORIGINATING_ENTITY,
+                                            MNCC_CAUSE_INCOMPAT_DEST),
+                                 NULL, MNCC_SS_VER_NOT_PRES);
+            cc_set_state (M_CC_CS_11);
+            for_disconnect (disconnect);
+          }
+          CCD_END;
+          TIMERSTART (T305, T305_VALUE);
+        }
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_connect                 |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming connect message.
+
+*/
+
+GLOBAL void cc_connect (T_D_CONNECT * connect)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_connect()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {  
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_1:
+    case M_CC_CS_3:
+    case M_CC_CS_4:
+      if (cc_check_error_flag ())
+      {
+        PALLOC (setup_cnf, MNCC_SETUP_CNF);
+
+        TIMERSTOP (TIMER_CC);
+
+        if (connect->v_progress)
+        {
+          cc_data->progress_desc[cc_data->index_ti] = 
+            connect->progress.progress_desc;
+        }
+
+        cc_build_mncc_setup_cnf (connect, setup_cnf);
+        PSENDX (MMI, setup_cnf);
+        cc_build_facility_ind (MNCC_FAC_IN_CONNECT, connect->v_facility,
+                               &connect->facility);
+        cc_build_user_user_ind (MNCC_USER_IN_CONNECT, connect->v_user_user,
+                                &connect->user_user);
+        CCD_END;
+        CCD_START;
+        {
+          MCAST (connect_ack, B_CONNECT_ACK);
+
+          connect_ack->msg_type = B_CONNECT_ACK;
+          for_connect_ack (connect_ack);
+        }
+        CCD_END;
+        srv_free_stored_setup ();
+        cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
+        cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE;
+        cc_set_state (M_CC_CS_10);
+      }
+
+      EM_CC_CONNECT_RECEIVED;
+
+      break;
+
+    default:
+/* Implements Measure#  3 and streamline encoding */
+    CCD_END;
+      cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_connect_ack             |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming connect acknowledge message.
+
+*/
+
+GLOBAL void cc_connect_ack (void)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_connect_ack()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_8:
+      if (cc_check_error_flag ())
+      {
+        PALLOC (setup_comp, MNCC_SETUP_COMPL_IND);
+
+        CCD_END;
+
+        TIMERSTOP (TIMER_CC);
+
+        setup_comp->ti  = cc_data->ti;
+        setup_comp->cause = MNCC_CAUSE_SUCCESS;
+        PSENDX (MMI, setup_comp);
+
+        cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
+        cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE;
+        cc_set_state (M_CC_CS_10);
+
+        EM_CC_CONNECT_ACKNOWLEDGE_RECEIVED;
+
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_progress                |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming progress message.
+
+*/
+
+GLOBAL void cc_progress (T_D_PROGRESS * progress)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_progress()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_1:
+    case M_CC_CS_3:
+    case M_CC_CS_4:
+    case M_CC_CS_6:
+    case M_CC_CS_7:
+    case M_CC_CS_8:
+    case M_CC_CS_9:
+    case M_CC_CS_11:
+    case M_CC_CS_12:
+    case M_CC_CS_19:
+      if (cc_check_error_flag ())
+      {
+        PALLOC (progress_ind, MNCC_PROGRESS_IND);
+
+        TIMERSTOP (TIMER_CC);
+        
+        /* Progress indicator IE here is mandatory IE, so no 
+         * checks for presence need to be done here */
+        cc_data->progress_desc[cc_data->index_ti] = 
+          progress->progress.progress_desc;
+       
+        cc_build_mncc_progress_ind (progress, progress_ind);
+        PSENDX (MMI, progress_ind);
+        cc_build_user_user_ind (MNCC_USER_IN_PROGRESS, progress->v_user_user,
+                                &progress->user_user);
+        CCD_END;
+      }
+
+      EM_CC_PROGRESS_RECEIVED;
+
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_cc_establishment        |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming CC ESTABLISHMENT message.
+            Because the only interesting part in this message
+            is the setup container, only the decoded SETUP message
+            is delivered here.
+
+*/
+
+GLOBAL void cc_cc_establishment (T_U_SETUP * setup)
+{
+  GET_INSTANCE_DATA;	
+  TRACE_FUNCTION ("cc_cc_establishment()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_03: /* WAIT FOR NW INFO */
+      
+      /* Check errors delivered by formatter */
+      switch (cc_data->error) 
+      {
+        case M_CC_CAUSE_INVALID_MAND_INFO:
+        case M_CC_CAUSE_COND_INFO_ELEM:
+          CCD_END;
+          /* Implements Measure#  7 and streamline encoding*/
+          cc_send_status (cc_data->error);  
+          return;
+
+        default: /* No error until now */
+          /* Stop TIMER T332 */
+          TIMERSTOP (TIMER_CC);
+   
+          if (cc_data->stored_ccbs_setup NEQ NULL) 
+          {
+            /* 
+             * There is only room for one stored CCBS SETUP message
+             * for all instances. In case this is already occupied, 
+             * the call is released with cause "user busy".
+             * In this case the CCBS recall is not lost, but suspended
+             * by the network until the mobile becomes idle.
+             */
+            CCD_END;
+           
+            /* Send RELEASE COMPLETE */
+            CCD_START;
+            {
+              MCAST (rel_com, U_RELEASE_COMP);
+              cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, 
+                                                                      ORIGSIDE_MS, 
+                                                                      MNCC_CC_ORIGINATING_ENTITY,
+                                                                      MNCC_CAUSE_USER_BUSY));
+              for_release_complete (rel_com);
+            }
+            CCD_END;
+
+            /* Inform MMI */
+            {
+              PALLOC (release, MNCC_RELEASE_IND);
+              release->ti    = cc_data->ti;
+              release->cause = MNCC_CAUSE_MAX_NO_RECALLS_REACHED;
+              release->c_raw_cause = 0;
+              PSENDX (MMI, release);
+            }
+
+            /* Release MM connection */
+            for_rel_req ();
+
+            /* Next state is NULL */
+            cc_set_state (M_CC_CS_0);
+            return;
+          }
+
+          /* Check bearer capabilities, do basic recall alignment */
+          if (cc_basic_service_align (setup) EQ ERROR)
+          {
+            /* Incompatible bearer capabilities. Clear call. */
+            CCD_END;
+            /* Implements Measure#  19 */
+            cc_send_release_cmp (CAUSE_MAKE(DEFBY_STD,
+                                           ORIGSIDE_MS, 
+                                           MNCC_CC_ORIGINATING_ENTITY, 
+                                           MNCC_CAUSE_INCOMPAT_DEST));
+            return;
+          }
+
+          /* 
+           * "If the CC Capabilities in the Setup Container IE is different
+           * to that supported by the mobile station, the mobile station 
+           * shall modify the CC Capabilities in the SETUP message to indicate
+           * the true capabilities of the mobile station" [GSM 04.08 5.2.3.2]
+           */
+          setup->call_ctrl_cap = cc_data->call_ctrl_cap; /* Struct copy */
+
+          /* 
+           * Handle facility alignment 
+           * ("Simple recall alignment",
+           *  "Advanced recall alignment" and 
+           *  "Recall alignment not essential").
+           */
+
+          /* "Simple recall alignment" handled automatically, do nothing */
+
+          if (setup->v_fac_adv) 
+          {
+            /* Advanced recall alignment not supported. Reject call. */
+            CCD_END;
+           /* Implements Measure#  19 */
+            cc_send_release_cmp (CAUSE_MAKE(DEFBY_STD,
+                                           ORIGSIDE_MS, 
+                                           MNCC_CC_ORIGINATING_ENTITY,
+                                           MNCC_CAUSE_FACILITY_REJECT));
+           
+            return;
+          }
+
+          /* 
+           * The recall alignment not essential facility IE 
+           * need not be handled directly here, it is simply 
+           * an optional IE which was ignored by CCD.
+           * The only handling we do is to delete the SS-Version 
+           * indicator if there are no remaining facility elements.
+           */
+          if (!setup->v_facility)
+            setup->v_ss_version = FALSE;
+
+          /* Store coded setup message in cc_data */
+          {
+            /* No assumtions made about length of this foreign message */
+            PALLOC_SDU (data, MMCM_DATA_REQ, M_CC_L3MAX << 3);
+            data->sdu.o_buf = CC_ENCODE_OFFSET;
+            ccd_codeMsg (CCDENT_CC,
+                         UPLINK,
+                         (T_MSGBUF *) &data->sdu,
+                         (UBYTE    *) setup,
+                          NOT_PRESENT_8BIT);
+            cc_data->stored_ccbs_setup = data;
+          }
+          CCD_END;
+
+          /* Send MMCC_DATA_REQ (CC EST. CONFIRMED) */
+          CCD_START;
+          {
+            MCAST (est_cnf, U_CC_EST_CONF);
+            if (cc_count_active_connections () EQ 0)
+              cc_build_cc_est_confirm (est_cnf, CAUSE_MAKE(DEFBY_CONDAT, 
+                                                                    ORIGSIDE_MS, 
+                                                                    MNCC_CC_ORIGINATING_ENTITY,
+                                                                    NOT_PRESENT_8BIT));
+            else
+              cc_build_cc_est_confirm (est_cnf, CAUSE_MAKE(DEFBY_STD, 
+                                                                    ORIGSIDE_MS, 
+                                                                    MNCC_CC_ORIGINATING_ENTITY,
+                                                                    MNCC_CAUSE_USER_BUSY));
+            for_cc_est_confirm (est_cnf);
+          }
+          CCD_END;
+
+          /* Start TIMER T335 */
+          TIMERSTART (T335, T335_VALUE);
+      
+          /* Enter the "CC-establishment confirmed" state */
+          cc_set_state (M_CC_CS_05);
+          break;
+      }
+      break;
+
+    default: 
+      /* Message not compatible with protocol state */
+      CCD_END;
+      
+      /* Implements Measure#  3 and streamline encoding */
+      cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_recall                  |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming recall message.
+
+*/
+
+GLOBAL void cc_recall (T_D_RECALL * recall)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_recall");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_05: /* CC ESTABLISHMENT CONFIRMED */
+      switch(cc_data->error)
+      {
+        case M_CC_CAUSE_INVALID_MAND_INFO:
+        case M_CC_CAUSE_COND_INFO_ELEM:
+          CCD_END;
+          /* Implements Measure#  7 and streamline encoding*/
+          cc_send_status (cc_data->error);  
+          return;
+
+        default:
+          /* Stop Timer T335 */
+          TIMERSTOP (TIMER_CC);
+          {
+            T_U_SETUP * setup;
+            UBYTE result;
+            PALLOC (fac_ind, MNCC_FACILITY_IND);
+
+            /* Process facility element. may be not present */
+            fac_ind->ti = cc_data->ti;
+            fac_ind->fac_context = MNCC_FAC_IN_RECALL;
+            fac_ind->fac_inf.l_fac = recall->facility.c_fac << 3;
+            fac_ind->fac_inf.o_fac = 0;
+            memcpy (fac_ind->fac_inf.fac,  
+                    recall->facility.fac,
+                    recall->facility.c_fac);
+
+            {
+              PALLOC (rec_ind, MNCC_RECALL_IND); /* T_MNCC_RECALL_IND */    
+
+              rec_ind->ti =  cc_data->ti;
+              rec_ind->rcl_type = recall->recall_type.rcl_type;
+              CCD_END;
+
+              /* 
+               * Unpack coded setup container.
+               * Conserving memory, so already processed parameters are 
+               * processed for a second time now. No errors expected.
+               */
+              assert (cc_data->stored_ccbs_setup NEQ NULL);
+              CCD_START;
+              result = ccd_decodeMsg (CCDENT_CC,
+                         UPLINK,
+                         (T_MSGBUF *) &cc_data->stored_ccbs_setup->sdu,
+                         (UBYTE    *) _decodedMsg,
+                         NOT_PRESENT_8BIT);
+              assert (result EQ ccdOK);
+              setup = (T_U_SETUP *)_decodedMsg;
+              result = cc_basic_service_align (setup);
+              assert (result NEQ ERROR);
+            
+              /* Process repeat indicator, BC I and BC II */
+              rec_ind->ri = cc_data->neg_ri;
+              memcpy (&rec_ind->bcpara, &cc_data->neg_bcpara1, 
+                      sizeof (T_MNCC_bcpara));
+              memcpy (&rec_ind->bcpara2, &cc_data->neg_bcpara2, 
+                      sizeof (T_MNCC_bcpara));
+            
+              /* Process called party address */   
+              rec_ind->called_party.ton          = setup->ul_called_num.ton;
+              rec_ind->called_party.npi          = setup->ul_called_num.npi;
+              rec_ind->called_party.c_called_num = setup->ul_called_num.c_num;
+              memcpy (rec_ind->called_party.called_num, 
+                      setup->ul_called_num.num, 
+                      setup->ul_called_num.c_num);
+
+              /* Process called party subaddress */
+              if (setup->v_called_subaddr)
+              {
+                rec_ind->called_party_sub.tos =  
+                  setup->called_subaddr.tos;
+                rec_ind->called_party_sub.odd_even = 
+                  setup->called_subaddr.odd_even;
+                rec_ind->called_party_sub.c_subaddr = 
+                  setup->called_subaddr.c_subaddr;
+                memcpy (rec_ind->called_party_sub.subaddr,
+                        setup->called_subaddr.subaddr, MNCC_SUB_LENGTH);
+              }
+              else
+              {
+                rec_ind->called_party_sub.tos = MNCC_TOS_NOT_PRES;
+                rec_ind->called_party_sub.c_subaddr = 0;
+              }                                             
+              CCD_END;
+            
+              /* Send MNCC_RECALL_IND */
+              PSENDX (MMI, rec_ind);
+            }
+
+            /* Handle MNCC_FACILITY_IND */
+            if (fac_ind->fac_inf.l_fac)
+            {
+              PSENDX (MMI, fac_ind);
+            }
+            else
+              PFREE (fac_ind);
+            
+            /* Next state is RECALL PRESENT */
+            cc_set_state (M_CC_CS_06);
+          }
+          break;
+      }
+      break; /* esac CS_05 */
+    default: 
+      CCD_END;
+      /* Message not compatible with protocol state */
+/* Implements Measure#  3 and streamline encoding*/
+      cc_send_status (MNCC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_setup                   |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming setup message.
+
+*/
+
+GLOBAL void cc_setup (T_D_SETUP * setup)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_setup()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_0:
+      if (cc_data->ti < 8)
+      {
+        /*
+         * This values are reserved for mobile originated calls.
+         */
+        CCD_END;
+        for_rel_req ();
+        break;
+      }
+
+      switch (cc_data->error)
+      {
+        case M_CC_CAUSE_INVALID_MAND_INFO:
+        case M_CC_CAUSE_COND_INFO_ELEM:
+          CCD_END;
+          CCD_START;
+          {
+            MCAST (rel_com, U_RELEASE_COMP);
+
+            cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, 
+                                                                    ORIGSIDE_MS, 
+                                                                    MNCC_CC_ORIGINATING_ENTITY,
+                                                                    cc_data->error));
+            for_release_complete (rel_com);
+          }
+          CCD_END;
+          for_rel_req ();
+          break;
+
+        default:
+          switch (cc_compatibility_check (setup))
+          {
+            case BAD_SUBADDRESS:
+              CCD_END;
+              CCD_START;
+              {
+                MCAST (rel_com, U_RELEASE_COMP);
+                cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, 
+                                                                        ORIGSIDE_MS, 
+                                                                        MNCC_CC_ORIGINATING_ENTITY,
+                                                                        MNCC_CAUSE_NO_ROUTE));
+                for_release_complete (rel_com);
+              }
+              CCD_END;
+              for_rel_req ();
+              cc_set_state (M_CC_CS_0);
+              break;
+
+            case ERROR:
+              CCD_END;
+              CCD_START;
+              {
+                MCAST (rel_com, U_RELEASE_COMP);
+                cc_build_release_complete (rel_com, CAUSE_MAKE(DEFBY_STD, 
+                                                                        ORIGSIDE_MS, 
+                                                                        MNCC_CC_ORIGINATING_ENTITY,
+                                                                        MNCC_CAUSE_INCOMPAT_DEST));
+                for_release_complete (rel_com);
+              }
+              CCD_END;
+              for_rel_req ();
+              cc_set_state (M_CC_CS_0);
+              break;
+
+            case OKAY:
+            case NEGOTIATION:
+            {
+              PALLOC (setup_ind, MNCC_SETUP_IND);
+
+              cc_data->progress_desc[cc_data->index_ti] = NOT_PRESENT_8BIT;
+
+              if (setup->v_progress)
+              {
+                cc_data->progress_desc[cc_data->index_ti] = 
+                  setup->progress.progress_desc;
+              }
+
+              cc_data->call_type [cc_data->index_ti] = CALL_TYPE_MTC;
+              // PATCH LE 10.04.00
+              // initialize disconnect collision flag
+              cc_data->disc_coll [cc_data->index_ti] = FALSE;
+              // END PATCH LE 10.04.00
+              cc_build_mncc_setup_ind (setup, setup_ind);
+
+              PSENDX (MMI, setup_ind);
+              cc_build_facility_ind (MNCC_FAC_IN_SETUP, setup->v_facility,
+                                     &setup->facility);
+              cc_build_user_user_ind (MNCC_USER_IN_SETUP, setup->v_user_user,
+                                      &setup->user_user);
+
+
+
+              CCD_END;
+              CCD_START;
+              {
+                MCAST (call_cnf, U_CALL_CONF);
+  
+                if (cc_count_active_connections () EQ 0)
+                  cc_build_call_confirm (call_cnf, CAUSE_MAKE(DEFBY_CONDAT, 
+                                                                       ORIGSIDE_MS, 
+                                                                       MNCC_CC_ORIGINATING_ENTITY,
+                                                                       NOT_PRESENT_8BIT));
+                else
+                  cc_build_call_confirm (call_cnf, CAUSE_MAKE(DEFBY_STD, 
+                                                                       ORIGSIDE_MS, 
+                                                                       MNCC_CC_ORIGINATING_ENTITY,
+                                                                       MNCC_CAUSE_USER_BUSY));
+                for_call_confirm (call_cnf);
+              }
+              CCD_END;
+              cc_set_state (M_CC_CS_9);
+
+              EM_CC_MM_CONNECTION_ESTABLISHED_MT;
+
+              break;
+            }
+
+            default:
+              CCD_END;
+              break;
+          }
+          break;
+      }
+      break;
+
+    default:
+      CCD_END;
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_sync_ind                |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming sync indication from
+            mobility management.
+
+*/
+
+GLOBAL void cc_sync_ind (T_MMCM_SYNC_IND * mmcm_sync)
+{
+  GET_INSTANCE_DATA;	
+  PALLOC ( mncc_sync, MNCC_SYNC_IND );
+
+  TRACE_FUNCTION ("cc_sync_ind()");
+
+
+  cc_data->channel_type = mmcm_sync->sync_info.ch_info.ch_type;
+  cc_data->channel_mode = mmcm_sync->sync_info.ch_info.ch_mode;
+
+  mncc_sync->ti         = mmcm_sync->ti;
+
+  mncc_sync->ch_info.ch_mode = mmcm_sync->sync_info.ch_info.ch_mode;
+  mncc_sync->ch_info.ch_type = mmcm_sync->sync_info.ch_info.ch_type;
+
+  mncc_sync->cause      = MNCC_CAUSE_CHANNEL_SYNC;
+  PSENDX (MMI, mncc_sync);
+  PFREE (mmcm_sync);
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_est_cnf                 |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming establish confirm from
+            mobility management.
+
+*/
+
+GLOBAL void cc_est_cnf (void)
+{
+  GET_INSTANCE_DATA;	
+  TRACE_FUNCTION ("cc_est_cnf()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_01:
+      {
+        /* 
+         * As CC may potentially do some ugly things like 
+         * MAX_SETUP_ATTEMPTS > 1, we cannot use the stored 
+         * SETUP or EMERGENCY SETUP message, but have to copy.
+         */
+        PALLOC_SDU (data, MMCM_DATA_REQ, cc_data->stored_setup->sdu.l_buf);
+
+        data->sdu.l_buf = cc_data->stored_setup->sdu.l_buf;
+        data->sdu.o_buf = cc_data->stored_setup->sdu.o_buf;
+        memcpy (&data->sdu.buf[data->sdu.o_buf >> 3],
+                &cc_data->stored_setup->sdu.buf[data->sdu.o_buf >> 3],
+                data->sdu.l_buf >> 3);
+
+        /* Forward the SETUP or EMERGENCY SETUP message to MM */
+        for_pd (data);
+      }
+
+      cc_set_state (M_CC_CS_1);
+      srv_use_stored_prim ();
+      break;
+
+    default:
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_reest_cnf               |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming re-establish confirm from
+            mobility management.
+
+*/
+
+GLOBAL void cc_reest_cnf (void)
+{
+  GET_INSTANCE_DATA;
+  
+  PALLOC (sync, MNCC_SYNC_IND);
+
+    TRACE_FUNCTION ("cc_reest_cnf()");
+
+    switch (cc_data->state[cc_data->index_ti])
+    {
+      case CS_101:
+        sync->ti    = cc_data->ti;
+        sync->cause = MNCC_CAUSE_REEST_FINISHED;
+        sync->ch_info.ch_mode = NOT_PRESENT_8BIT;
+        sync->ch_info.ch_type = NOT_PRESENT_8BIT;        
+        PSENDX (MMI, sync);
+
+        cc_set_state (M_CC_CS_10);
+        srv_use_stored_prim ();
+        break;
+
+      case CS_261:
+        sync->ti    = cc_data->ti;
+        sync->cause = MNCC_CAUSE_REEST_FINISHED;
+        sync->ch_info.ch_mode = NOT_PRESENT_8BIT;
+        sync->ch_info.ch_type = NOT_PRESENT_8BIT;
+        PSENDX (MMI, sync);
+
+        TIMERSTART (T323, T323_VALUE);
+        cc_set_state (M_CC_CS_26); 
+        srv_use_stored_prim ();
+        break;
+
+      default:
+        PFREE (sync);
+        break;
+    }
+}
+
+#ifdef SIM_TOOLKIT
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_mncc_bearer_cap_req     |
++--------------------------------------------------------------------+
+
+  PURPOSE:      Checks the compatibility of bearer capabilities. 
+                Bearer capabilities in coded form are tranformed to 
+                parameter form and vice versa.      
+*/
+
+GLOBAL void cc_mncc_bearer_cap_req (T_MNCC_BEARER_CAP_REQ * bc_req)
+{
+  PALLOC (bc_conf, MNCC_BEARER_CAP_CNF); 
+
+  TRACE_FUNCTION ("cc_mncc_bearer_cap_req()");
+
+  /* Copy input parameters */
+  bc_conf->req_id = bc_req->req_id;
+  bc_conf->bc_mod = bc_req->bc_mod;
+
+  /* Set default values to no bcpara to set valid values in case cc_bearer_cap_decode returns OKAY */
+  memset (&bc_conf->bcpara2, 0, sizeof (T_MNCC_bcpara));
+  bc_conf->bcpara2.bearer_serv = MNCC_BEARER_SERV_NOT_PRES;
+
+  if (bc_req->bc_mod EQ MNCC_BC_MOD_DECODE) 
+  {
+    /* Transform coded form into parameter form */
+    
+    /* Copy input parameters */
+    bc_conf->bcconf = bc_req->bcconf;
+    bc_conf->bcconf2 = bc_req->bcconf2;
+    
+    if (cc_bearer_cap_decode(&bc_req->bcconf, 
+                             &bc_conf->bcpara) 
+        EQ ERROR)
+    {
+      /* Bearer capabilities not supported */
+      PFREE (bc_req);
+      bc_conf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                ORIGSIDE_MS, 
+                                MNCC_CC_ORIGINATING_ENTITY, 
+                                MNCC_CAUSE_INCOMPAT_DEST);
+      PSENDX (MMI, bc_conf);
+      return;
+    } 
+
+    if (cc_bearer_cap_decode((T_MNCC_bcconf *)&bc_req->bcconf2, 
+                             (T_MNCC_bcpara *)&bc_conf->bcpara2)
+        EQ ERROR)
+    {
+      /* Bearer capabilities not supported */
+      PFREE (bc_req);
+      bc_conf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                ORIGSIDE_MS, 
+                                MNCC_CC_ORIGINATING_ENTITY, 
+                                MNCC_CAUSE_INCOMPAT_DEST);
+      PSENDX (MMI, bc_conf);
+      return;
+    }
+  }
+  else
+  {
+    /* Transform parameter form into coded form */
+
+    /* Copy input parameters */
+    bc_conf->bcpara  = bc_req->bcpara;
+    bc_conf->bcpara2 = bc_req->bcpara2;
+
+    if (cc_bearer_cap_code(&bc_req->bcpara, 
+                           &bc_conf->bcconf)
+        EQ ERROR)
+    {
+      /* Bearer capabilities not supported */
+      PFREE (bc_req);
+      bc_conf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                ORIGSIDE_MS, 
+                                MNCC_CC_ORIGINATING_ENTITY, 
+                                MNCC_CAUSE_INCOMPAT_DEST);
+      PSENDX (MMI, bc_conf);
+      return;
+    }
+
+    if (cc_bearer_cap_code((T_MNCC_bcpara *)&bc_req->bcpara2,
+                           (T_MNCC_bcconf *)&bc_conf->bcconf2)
+        EQ ERROR)
+    {
+      /* Bearer capabilities not supported */
+      PFREE (bc_req);
+      bc_conf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                ORIGSIDE_MS, 
+                                MNCC_CC_ORIGINATING_ENTITY, 
+                                MNCC_CAUSE_INCOMPAT_DEST);
+      PSENDX (MMI, bc_conf);
+      return;
+    }
+  }
+
+  bc_conf->cause = MNCC_CAUSE_SUCCESS; /* Positive result */
+  PSENDX (MMI, bc_conf);
+  PFREE (bc_req);
+}
+
+#endif /*SIM_TOOLKIT */
+
+
+/* Implements Measure#  3 and streamline encoding*/
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_send_status             |
++--------------------------------------------------------------------+
+
+  PURPOSE : Calls CCD Start and then cc_build_and_send_status 
+            for sending status message
+*/
+GLOBAL void cc_send_status (USHORT cause)
+{
+  TRACE_FUNCTION ("cc_send_status()");
+
+  CCD_START;
+  {
+    MCAST (status, B_STATUS);
+    cc_build_status (status, CAUSE_MAKE(DEFBY_STD, 
+                                      ORIGSIDE_MS, 
+                                      MNCC_CC_ORIGINATING_ENTITY,
+                                      cause));
+    for_status (status);
+  }
+  CCD_END;
+}
+
+/* Implements Measure#  19 */ 
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                     |
+| STATE   : code                ROUTINE : cc_send_release_cmp        |
++--------------------------------------------------------------------+
+
+  PURPOSE : Send release complete message.
+
+*/
+
+LOCAL void cc_send_release_cmp (USHORT cause)
+{
+  GET_INSTANCE_DATA; 
+  TRACE_FUNCTION ("cc_send_release_cmp()");
+  
+  /* Send RELEASE COMPLETE */
+  CCD_START;
+  {
+    MCAST (rel_com, U_RELEASE_COMP);
+    cc_build_release_complete (rel_com, cause);
+    for_release_complete (rel_com);
+  }
+  CCD_END;
+
+  /* Inform MMI */
+  {
+    PALLOC (release, MNCC_RELEASE_IND);
+    release->ti    = cc_data->ti;
+    release->cause = cause;
+    release->c_raw_cause = cause;
+    PSENDX (MMI, release);
+  }
+
+  /* Release MM connection */
+  for_rel_req ();
+
+  /* Next state is NULL */
+  cc_set_state (M_CC_CS_0);
+
+}
+
+/* Implements Measure#  36, 48 */ 
+/*
++--------------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_EST                           |
+| STATE   : code                ROUTINE : cc_send_mncc_release_ind         |
++--------------------------------------------------------------------------+
+
+  PURPOSE : Send release complete message with cause invalid ti.
+
+*/
+
+LOCAL void cc_send_mncc_release_ind(UBYTE  ti, USHORT cause)
+{
+  TRACE_FUNCTION ("cc_send_mncc_release_ind");  
+  {
+    PALLOC (release, MNCC_RELEASE_IND); 
+    release->ti          = ti;
+    release->cause       = cause;
+    release->c_raw_cause = 0;
+    PSENDX (MMI, release);
+  }
+}
+#endif