diff gsm-fw/g23m-gsm/cc/cc_act.c @ 673:2f7df7a314f8

gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 23:20:04 +0000
parents
children 75488f27acdd
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/g23m-gsm/cc/cc_act.c	Sun Sep 28 23:20:04 2014 +0000
@@ -0,0 +1,2312 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GSM-PS (6147)
+|  Modul   :  CC_ACT
++----------------------------------------------------------------------------- 
+|  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 primitive processing functions
+|             of the SDL process Call Control for the call active
+|             phase of the component CC of the mobile station
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifndef CC_ACT_C
+#define CC_ACT_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 =====================================================*/
+
+/*==== PROTOTYPES =================================================*/
+LOCAL void cc_mncc_hold_retrieve_req (T_PRIM * prim);
+
+/*==== PRIVAT =====================================================*/
+
+/*==== VARIABLES ==================================================*/
+
+/*==== FUNCTIONS ==================================================*/
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_dtmf_full               |
++--------------------------------------------------------------------+
+
+  PURPOSE : Check whether DTMF buffer is full
+
+*/
+
+LOCAL BOOL cc_dtmf_full (const T_DTMF *p_dtmf)
+{
+  TRACE_FUNCTION ("cc_dtmf_full()");
+  
+  return ((p_dtmf->read EQ p_dtmf->write + 1) OR
+          (p_dtmf->read EQ 0 AND p_dtmf->write EQ DTMF_BUF_SIZE - 1));
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_dtmf_empty              |
++--------------------------------------------------------------------+
+
+  PURPOSE : Check whether DTMF buffer is empty
+
+*/
+
+LOCAL BOOL cc_dtmf_empty (const T_DTMF *p_dtmf)
+{
+  TRACE_FUNCTION ("cc_dtmf_empty()");
+ 
+  return (p_dtmf->read EQ p_dtmf->write);
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_dtmf_write              |
++--------------------------------------------------------------------+
+
+  PURPOSE : Write next entry into DTMF buffer. 
+            No checks are done (e.g. buffer full)
+
+*/
+
+LOCAL void cc_dtmf_write (T_DTMF *p_dtmf, UBYTE val)
+{
+  TRACE_FUNCTION ("cc_dtmf_write()");
+  
+  p_dtmf->buf[p_dtmf->write++] = val;
+  if (p_dtmf->write EQ DTMF_BUF_SIZE) 
+    p_dtmf->write = 0; 
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_dtmf_write              |
++--------------------------------------------------------------------+
+
+  PURPOSE : Read next entry from DTMF buffer. 
+            No checks are done (e.g. buffer empty)
+
+*/
+
+LOCAL UBYTE cc_dtmf_read (T_DTMF *p_dtmf)
+{
+  UBYTE val;
+  
+  TRACE_FUNCTION ("cc_dtmf_read()");
+
+  val = p_dtmf->buf[p_dtmf->read++];
+  if (p_dtmf->read EQ DTMF_BUF_SIZE)
+    p_dtmf->read = 0;
+  return val;
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_dtmf_allowed            |
++--------------------------------------------------------------------+
+
+  PURPOSE : This functions returns TRUE if DTMF is allowed in the
+            current state, otherwise FALSE.
+
+*/
+
+LOCAL BOOL cc_dtmf_allowed (void)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_dtmf_allowed()");
+
+  /* 
+   * "The mobile station shall be capable of transmitting DTMF messages if
+   * and only if the mobile station has the user connection for speech 
+   * attached and an appropriate channel is available.
+   * 
+   * ".."
+   * 
+   * NOTE 1: This specification means that DTMF messages can generally be 
+   *         sent in the active state of a call in speech transmission 
+   *         mode or when a traffic channel is available during setup or 
+   *         release and the progress indicator IE has been received."
+   *
+   * [TS 24.008 subclause 5.5.7]
+   * 
+   * As of GSM 04.08 the progress indicator IE can be received by 
+   * CALL PROCEEDING, PROGRESS, CONNECT, SETUP, ALERTING and DISCONNECT.
+   */ 
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_3:   /* mobile originating call proceeding */
+    case M_CC_CS_4:   /* call delivered */
+    case M_CC_CS_8:   /* connect request */
+    case M_CC_CS_11:  /* disconnect request */ 
+    case M_CC_CS_12:  /* disconnect indication */
+    case M_CC_CS_19:  /* release request */ 
+    case CS_101: /* substate of CS_10, reestablish requested */     
+    case M_CC_CS_26:  /* mobile originating modify */
+    case CS_261: /* substate of CS_26, reestablish requested */
+      if (cc_data->progress_desc[cc_data->index_ti] EQ NOT_PRESENT_8BIT)
+        return FALSE; /* Progress indicator IE has not been received */
+      /*FALLTHROUGH*/ /*lint -fallthrough*/
+    case M_CC_CS_10: /* active */
+      if (cc_data->channel_type EQ NAS_CH_SDCCH)
+        return FALSE; /* No TCH assigned */
+  
+      if ((cc_data->channel_mode NEQ NAS_CHM_SPEECH) AND
+          (cc_data->channel_mode NEQ NAS_CHM_SPEECH_V2) AND
+          (cc_data->channel_mode NEQ NAS_CHM_SPEECH_V3))
+        return FALSE; /* Channel mode is not speech */
+
+      return TRUE;
+    
+    default:
+      return FALSE;
+  }
+}
+
+/*==== VARIABLES ==================================================*/
+
+/*==== FUNCTIONS ==================================================*/
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_start_dtmf_req     |
++--------------------------------------------------------------------+
+
+  PURPOSE : Sending of DTMF tones to the infrastructure side.
+
+*/
+
+GLOBAL void cc_mncc_start_dtmf_req (T_MNCC_START_DTMF_REQ * dtmf)
+{
+  GET_INSTANCE_DATA;
+  T_DTMF         * p_dtmf;
+
+  TRACE_FUNCTION ("cc_mncc_start_dtmf_req()");
+
+
+  if ((cc_data->index_ti = srv_convert_ti (dtmf->ti))
+       EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (dtmf);
+    return;
+  }
+  
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    default:
+      if (!cc_dtmf_allowed ())
+      {
+        /* Tone dropped. Confirm DTMF request with negative cause */
+        PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
+        dtmf_cnf->ti       = dtmf->ti;
+        dtmf_cnf->key      = dtmf->key;
+        dtmf_cnf->cause    = MNCC_CAUSE_DTMF_NOT_ALLOWED;
+        dtmf_cnf->dtmf_mod = dtmf->dtmf_mod;
+        PSENDX (MMI, dtmf_cnf);
+
+        PFREE (dtmf); 
+        return;
+      }
+
+      p_dtmf = &cc_data->dtmf [cc_data->index_ti];
+
+      if ( dtmf->dtmf_mod EQ MNCC_DTMF_MOD_AUTO OR 
+           dtmf->dtmf_mod EQ MNCC_DTMF_MOD_MAN_START )
+      {
+        if (p_dtmf->state EQ DTMF_IDLE)
+        {
+          /*
+           * If sending of DTMF tones is not in
+           * progress send the tone.
+           */
+          CCD_START;
+          {
+            MCAST (start_dtmf, U_START_DTMF);
+
+            cc_build_start_dtmf (dtmf->key, start_dtmf);
+            for_start_dtmf (start_dtmf);
+          }
+          CCD_END;
+          
+          /* On sending a START DTMF message the MS shall start T336 */
+          TIMERSTART (T336, T336_VALUE);
+
+          p_dtmf->state = DTMF_SEND_REQUEST;
+          p_dtmf->mode  = (dtmf->dtmf_mod EQ MNCC_DTMF_MOD_AUTO)?DTMF_AUTO:DTMF_MAN;
+          p_dtmf->key   = dtmf->key;
+        }
+        else
+        {
+          /*
+           * Not DTMF_IDLE.
+           */
+
+          if (dtmf->dtmf_mod EQ MNCC_DTMF_MOD_AUTO)
+          {
+            /* 
+             * If DTMF_MOD_AUTO, store the tone if the buffer is not full.
+             */ 
+            if (!cc_dtmf_full (p_dtmf))
+              cc_dtmf_write (p_dtmf, (UBYTE)SET_DTMF_MOD(dtmf->key, DTMF_AUTO));
+            // PATCH HM 13.04.00 >>>
+            else
+            {
+              /* Tone dropped. Confirm DTMF request with negative cause */
+              PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
+              dtmf_cnf->ti       = dtmf->ti;
+              dtmf_cnf->key      = dtmf->key;
+              dtmf_cnf->cause    = MNCC_CAUSE_DTMF_BUFFER_FULL;
+              dtmf_cnf->dtmf_mod = dtmf->dtmf_mod;
+              PSENDX(MMI, dtmf_cnf);
+            }
+            // PATCH HM 13.04.00 <<<
+          }
+          else
+          {
+            /* 
+             * If DTMF_MOD_MAN_START, two conditions have to be fullfilled 
+             * that the tone is stored and not dropped:
+             * 
+             * - The buffer is not full.
+             * - There is enough room to store the stop which 
+             *   will follow the tone.
+             */
+            if (!cc_dtmf_full (p_dtmf) AND
+                 (p_dtmf->read NEQ (p_dtmf->write + 2) % DTMF_BUF_SIZE))
+            {
+              cc_dtmf_write (p_dtmf, (UBYTE)SET_DTMF_MOD(dtmf->key, DTMF_MAN));
+            }
+            // PATCH HM 13.04.00 >>>
+            else
+            {
+              /* Tone dropped. Confirm DTMF request with negative cause */
+              PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
+              dtmf_cnf->ti       = dtmf->ti;
+              dtmf_cnf->key      = dtmf->key;
+              dtmf_cnf->cause    = MNCC_CAUSE_DTMF_BUFFER_FULL;
+              dtmf_cnf->dtmf_mod = dtmf->dtmf_mod;
+              PSENDX (MMI, dtmf_cnf);
+            }
+            // PATCH HM 13.04.00 <<<
+          }
+        }
+      }
+      else
+      {
+        /* 
+         * This is DTMF_MOD_MAN_STOP 
+         */
+        if ( p_dtmf->state EQ DTMF_SEND_ACKNOWLEDGE AND 
+             cc_dtmf_empty (p_dtmf))
+        {
+          /*
+           * If sending of DTMF tones is in
+           * progress stop the tone.
+           */
+          for_stop_dtmf ();
+
+          /* On sending a STOP DTMF message the MS shall start T337 */
+          TIMERSTART (T337, T337_VALUE);
+
+          p_dtmf->state = DTMF_STOP_REQUEST;
+        }
+        else
+        {
+          /* 
+           * If DTMF_MOD_MAN_STOP, the stop mark is stored if 
+           * the buffer is not full. If DTMF STOP ACK is received
+           * and there are unexpected stops in the buffer due to 
+           * a loss of the respective tones, the stops are dropped
+           * until a tone is found.
+           */
+          if (!cc_dtmf_full(p_dtmf))
+          {
+            cc_dtmf_write (p_dtmf, NOT_PRESENT_8BIT);
+          }
+        }
+      }
+      PFREE (dtmf) 
+      break;
+
+    case M_CC_CS_26: /* mobile originating modify */
+    case CS_101:
+    case CS_261:
+      srv_store_prim ((T_PRIM *)D2P(dtmf));
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_reset_dtmf              |
++--------------------------------------------------------------------+
+
+  PURPOSE : Reset DTMF machine. If used before CC leaves any state in 
+            which DTMF is possible MMI is informed about DTMF failure 
+            if there was still a DTMF request outstanding.
+
+*/
+
+GLOBAL void cc_reset_dtmf (void)
+{
+  GET_INSTANCE_DATA;
+  T_DTMF * p_dtmf;
+  BOOL dtmf_aborted;
+
+  TRACE_FUNCTION ("cc_reset_dtmf");
+
+  p_dtmf = &cc_data->dtmf[cc_data->index_ti];
+
+  if (cc_dtmf_allowed())
+  {
+    /* Stop all possibly running DTMF timers */
+    TIMERSTOP (TIMER_DTMF);
+
+    /*  
+     * A DTMF acknowledge maybe outstanding for ACI either if the 
+     * DTMF state is DTMF_SEND_REQ or 
+     * a tone was found in the DTMF send buffer
+     */
+    dtmf_aborted = (p_dtmf->state EQ DTMF_SEND_REQUEST);
+    while (!dtmf_aborted AND !cc_dtmf_empty(p_dtmf))
+      dtmf_aborted = (cc_dtmf_read (p_dtmf) NEQ NOT_PRESENT_8BIT);
+
+    if (dtmf_aborted)
+    {
+      /* Tone dropped. Confirm DTMF request with negative cause */
+      PALLOC (dtmf_cnf, MNCC_START_DTMF_CNF);
+      dtmf_cnf->ti       = cc_data->ti;
+      dtmf_cnf->key      = NOT_PRESENT_8BIT;
+      dtmf_cnf->cause    = MNCC_CAUSE_DTMF_ABORTED;
+      dtmf_cnf->dtmf_mod = NOT_PRESENT_8BIT;
+      PSENDX (MMI, dtmf_cnf);
+    }
+
+  }
+  p_dtmf->state = DTMF_IDLE;
+  p_dtmf->write = 0;
+  p_dtmf->read  = 0;
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_start_dtmf_ack          |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming start dtmf acknowledge message.
+
+*/
+
+GLOBAL void cc_start_dtmf_ack (T_D_START_DTMF_ACK * start_dtmf_ack)
+{
+  GET_INSTANCE_DATA;
+  T_DTMF               * p_dtmf;
+
+  TRACE_FUNCTION ("cc_start_dtmf_ack()");
+
+  if (cc_dtmf_allowed ())
+  {
+    if (cc_check_error_flag ())
+    {
+      p_dtmf = &cc_data->dtmf[cc_data->index_ti];
+      
+      /* Stop T336 */
+      TIMERSTOP (TIMER_DTMF);
+      
+      if (p_dtmf->state EQ DTMF_SEND_REQUEST)
+      {
+        PALLOC (start, MNCC_START_DTMF_CNF);
+        
+        start->ti       = cc_data->ti;
+        start->key      = start_dtmf_ack->key_facility.key;
+        start->cause    = MNCC_CAUSE_DTMF_START_SUCCESS;
+        start->dtmf_mod = (p_dtmf->mode EQ DTMF_AUTO) ?
+                          MNCC_DTMF_MOD_AUTO : MNCC_DTMF_MOD_MAN_START;
+        PSENDX (MMI, start);
+
+        EM_CC_START_DTMF_ACKNOWLEDGE;
+
+        if( p_dtmf->mode EQ DTMF_AUTO )
+        {
+          for_stop_dtmf ();
+          
+          /* On sending a STOP DTMF message the MS shall start T337 */
+          TIMERSTART (T337, T337_VALUE);
+          
+          p_dtmf->state = DTMF_STOP_REQUEST;
+        }
+        else
+        {
+          /* This is DTMF_MAN */
+          if (!cc_dtmf_empty (p_dtmf))
+          {
+            UBYTE tone;
+            
+            tone = cc_dtmf_read (p_dtmf);
+            if (tone EQ NOT_PRESENT_8BIT)
+            {
+              /* Should be always true */
+              p_dtmf->mode = GET_DTMF_MOD(tone);
+              for_stop_dtmf ();
+              
+              /* On sending a STOP DTMF message the MS shall start T337 */
+              TIMERSTART (T337, T337_VALUE);
+              
+              p_dtmf->state = DTMF_STOP_REQUEST;
+            }
+            while (!cc_dtmf_empty(p_dtmf) AND
+              p_dtmf->buf[p_dtmf->read] EQ NOT_PRESENT_8BIT)
+            {
+              /* Consume all unwanted stop marks */
+              (void)cc_dtmf_read(p_dtmf);
+            }
+          }              
+          else
+            p_dtmf->state = DTMF_SEND_ACKNOWLEDGE;
+        }
+/* Implements Measure#  3 and streamline encoding */
+        CCD_END;
+      }
+      else
+      {
+
+/* Implements Measure#  3 and streamline encoding */
+        CCD_END;
+        cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      }
+/* Implements Measure#  3 and streamline encoding */
+    } /* if (cc_check_error_flag (cc_data)) */
+  } /* if (cc_dtmf_allowed (cc_data)) */
+  else
+  {
+    /* 
+     * DTMF not allowed for some reason, e.g. wrong state,
+     * call is not a speech call, no TCH assigned etc.
+     */
+    CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+    cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_start_dtmf_rej          |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming start dtmf reject message.
+
+*/
+
+GLOBAL void cc_start_dtmf_rej (T_D_START_DTMF_REJ * start_dtmf_rej)
+{
+  GET_INSTANCE_DATA;
+  T_DTMF               * p_dtmf;
+
+  TRACE_FUNCTION ("cc_start_dtmf_rej()");
+
+  if (cc_dtmf_allowed ())
+  {
+    if (cc_check_error_flag ())
+    {
+      /* Stop T336 */
+      TIMERSTOP (TIMER_DTMF);
+      p_dtmf = &cc_data->dtmf[cc_data->index_ti];
+      if (p_dtmf->state EQ DTMF_SEND_REQUEST)
+      {
+        PALLOC (start, MNCC_START_DTMF_CNF);
+
+        start->ti       = cc_data->ti;
+        start->key      = NOT_PRESENT_8BIT;
+        start->dtmf_mod = NOT_PRESENT_8BIT;
+        /* 
+         * cause IE is mandatory and the check for presence has been done already 
+         * thus there is no need to check for validity of cause IE here anymore
+         */
+        start->cause = CAUSE_MAKE(DEFBY_STD, 
+                                  ORIGSIDE_NET, 
+                                  MNCC_CC_ORIGINATING_ENTITY, 
+                                  start_dtmf_rej->cc_cause.cause);
+        PSENDX (MMI, start);
+
+        p_dtmf->state = DTMF_IDLE;
+        p_dtmf->write = 0;
+        p_dtmf->read  = 0;
+/* Implements Measure#  3 and streamline encoding */
+       CCD_END; 
+      }
+      else
+      {
+/* Implements Measure#  3 and streamline encoding */
+        CCD_END;
+        cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      }
+/* Implements Measure#  3 and streamline encoding */
+    }
+  }
+  else
+  {
+    /* 
+     * DTMF not allowed for some reason, e.g. wrong state,
+     * call is not a speech call, no TCH assigned etc.
+     */
+    CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+    cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_stop_dtmf               |
++--------------------------------------------------------------------+
+
+  PURPOSE : Stops DTMF, back to DTMF_IDLE state.
+            Reasons for call: 
+            1.) Reception of STOP DTMF ACK message
+            2.) Expiry of T336
+            3.) Expiry of T337
+
+*/
+
+GLOBAL void cc_stop_dtmf (void)
+{
+  GET_INSTANCE_DATA;
+  T_DTMF               * p_dtmf;
+
+  TRACE_FUNCTION ("cc_stop_dtmf()");
+
+  p_dtmf = &cc_data->dtmf[cc_data->index_ti];
+
+  while (!cc_dtmf_empty(p_dtmf))
+  {
+    UBYTE tone;
+    
+    tone = cc_dtmf_read (p_dtmf);
+    if (tone NEQ NOT_PRESENT_8BIT)
+    {
+      /*
+       * another DTMF tone has to be sent
+       */
+      p_dtmf->mode = GET_DTMF_MOD (tone);
+      p_dtmf->key  = tone & 0x7f;
+      CCD_START;
+      {
+        MCAST (start, U_START_DTMF);
+
+        cc_build_start_dtmf (p_dtmf->key, start);
+        for_start_dtmf (start);
+      }
+      CCD_END;
+      
+      /* On sending a START DTMF message the MS shall start T336 */
+      TIMERSTART (T336, T336_VALUE);
+      
+      p_dtmf->state = DTMF_SEND_REQUEST;
+      return;
+    }
+  }
+  p_dtmf->state = DTMF_IDLE;
+  srv_use_stored_prim ();
+}    
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_stop_dtmf_ack           |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming stop dtmf ack message.
+
+*/
+
+GLOBAL void cc_stop_dtmf_ack (void)
+{
+  GET_INSTANCE_DATA;
+  T_DTMF               * p_dtmf;
+
+  TRACE_FUNCTION ("cc_stop_dtmf_ack()");
+
+  if (cc_dtmf_allowed ())
+  {
+    if (cc_check_error_flag ()) 
+    {
+      CCD_END;
+      p_dtmf = &cc_data->dtmf[cc_data->index_ti];
+      if (p_dtmf->state EQ DTMF_STOP_REQUEST)
+      {
+        if (p_dtmf->mode EQ DTMF_MAN)
+        {
+          PALLOC (start, MNCC_START_DTMF_CNF);
+          start->ti       = cc_data->ti;
+          start->key      = NOT_PRESENT_8BIT;
+          start->cause    = MNCC_CAUSE_DTMF_STOP_SUCCESS;
+          start->dtmf_mod = MNCC_DTMF_MOD_MAN_STOP;
+          PSENDX (MMI, start);
+        }
+        /* Stop T337 */
+        TIMERSTOP (TIMER_DTMF);
+        cc_stop_dtmf ();
+      }
+      else
+      {
+        /* 
+         * The STOP DTMF ACK message was not expected as we did not sent
+         * previously a START DTMF request.
+         */
+/* Implements Measure#  3 and streamline encoding */
+        cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      }
+    }
+  }
+  else
+  {
+    /* 
+     * DTMF not allowed in the current state 
+     */
+    CCD_END;    
+/* Implements Measure#  3 and streamline encoding */
+    cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_facility_req       |
++--------------------------------------------------------------------+
+
+  PURPOSE : Sending of Facility Information by the mobile side.
+
+*/
+
+GLOBAL void cc_mncc_facility_req (T_MNCC_FACILITY_REQ * facility)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_facility_req()");
+
+  if ((cc_data->index_ti = srv_convert_ti (facility->ti))
+       EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (facility);
+    return;
+  }
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_19:
+      PFREE (facility);
+      break;
+
+    case M_CC_CS_01:
+    case CS_101:
+    case CS_261:
+      srv_store_prim ((T_PRIM *)D2P(facility));
+      break;
+
+    default:
+      CCD_START;
+      {
+        MCAST (facility_msg, U_FACILITY);
+        cc_build_facility (facility, facility_msg);
+        for_facility (facility_msg);
+
+        EM_CC_FACILITY_TO_THE_NETWORK;
+
+      }
+      CCD_END;
+      PFREE (facility);
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_modify_req         |
++--------------------------------------------------------------------+
+
+  PURPOSE : Start of a mobile originated in-call modification.
+
+*/
+
+GLOBAL void cc_mncc_modify_req (T_MNCC_MODIFY_REQ * modify)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_modify_req()");
+
+  if ((cc_data->index_ti = srv_convert_ti (modify->ti))
+      EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (modify);
+    return;
+  }
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_10:
+      if (((cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_IDLE)) AND
+           (cc_data->dtmf[cc_data->index_ti].state EQ DTMF_IDLE))
+      {
+        /*
+         * If no other procedure is running
+         */
+        CCD_START;
+        {
+          MCAST (modify_msg, B_MODIFY);
+          cc_build_modify (modify, modify_msg);
+          for_modify (modify_msg);
+        }
+        CCD_END;
+        PFREE (modify);
+        cc_set_state (M_CC_CS_26);
+        TIMERSTART (T323, T323_VALUE);
+
+        EM_CC_MO_IN_CALL_MODIFICATION;
+
+      }
+      else
+        srv_store_prim ((T_PRIM *)D2P(modify));
+      break;
+
+    default:
+      PFREE (modify);
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_user_req           |
++--------------------------------------------------------------------+
+
+  PURPOSE : Send user information or congestion control.
+
+*/
+
+GLOBAL void cc_mncc_user_req (T_MNCC_USER_REQ * user)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_user_req()");
+
+  if ((cc_data->index_ti = srv_convert_ti (user->ti))
+       EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (user);
+    return;
+  }
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_10:
+      switch (user->congest_lev)
+      {
+        case M_CC_CL_RECEIVER_READY:
+        case M_CC_CL_RECEIVER_NOT_READY:
+          /*
+           * Send Congestion Control
+           */
+          CCD_START;
+          {
+            MCAST (cong_ctrl, B_CONGEST_CTRL);
+            
+            cc_build_congestion_control (user, cong_ctrl);
+            for_congestion_control (cong_ctrl);
+          }
+          CCD_END;
+          PFREE (user);
+          break;
+        default:
+          /*
+           * Send User Information
+           */
+          CCD_START;
+          {
+            MCAST (user_msg, B_USER_INFO);
+
+            cc_build_user_information (user, user_msg);
+            for_user_information (user_msg);
+          }
+          CCD_END;
+          PFREE (user);
+          break;
+      }
+      break;
+
+    case CS_101:
+      srv_store_prim ((T_PRIM *)D2P(user));
+      break;
+
+    default:
+      PFREE (user);
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_hold_req           |
++--------------------------------------------------------------------+
+
+  PURPOSE : Send hold message.
+
+*/
+
+GLOBAL void cc_mncc_hold_req (T_MNCC_HOLD_REQ * hold)
+{
+
+  TRACE_FUNCTION ("cc_mncc_hold_req()");
+
+/* Implements Measure# 18 */
+  cc_mncc_hold_retrieve_req ((T_PRIM *)D2P(hold));
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_retrieve_req       |
++--------------------------------------------------------------------+
+
+  PURPOSE : Send retrieve message.
+
+*/
+GLOBAL void cc_mncc_retrieve_req (T_MNCC_RETRIEVE_REQ * retrieve)
+{
+
+  TRACE_FUNCTION ("cc_mncc_retrieve_req()");
+
+/* Implements Measure# 18 */
+  cc_mncc_hold_retrieve_req ((T_PRIM *)D2P(retrieve));
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_call_is_active          |
++--------------------------------------------------------------------+
+
+  PURPOSE : Return TRUE if the respective CC instance is in an active
+            state, otherwise return FALSE.
+
+*/
+
+LOCAL BOOL cc_call_is_active (UBYTE index_ti)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_call_is_active()");
+  
+  switch (cc_data->state[index_ti])
+  {
+    case M_CC_CS_10:
+    case M_CC_CS_26:
+    case CS_101:
+    case CS_261:
+      return TRUE;
+
+    default:
+      return FALSE;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_sync_req           |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing a MNCC_SYNC_REQ primitive. To be able to 
+            understand  some details of this function, see first 
+            GSM 03.84, GSM 04.84 and GSM 11.10 chapters 31.4.1 and 31.4.2.
+
+*/
+
+GLOBAL void cc_mncc_sync_req (T_MNCC_SYNC_REQ * mncc_sync_req)
+{
+  GET_INSTANCE_DATA;
+  UBYTE i;
+
+  TRACE_FUNCTION ("cc_mncc_sync_req()");
+
+  if ((cc_data->index_ti = srv_convert_ti (mncc_sync_req->ti))
+      EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (mncc_sync_req);
+    return;
+  }
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /* 
+     * Note: MPTY and HOLD only has a meaning in the following states, 
+     *       in other states these aux states have absolutely no meaning.
+     */
+    case M_CC_CS_10:
+    case M_CC_CS_26:
+    case CS_101:
+    case CS_261:
+      switch (mncc_sync_req->synccs)
+      {
+        case MNCC_SYNCCS_MPTY_EVENT:
+
+          TRACE_EVENT_P2 ("  ti = %d, mpty_event = %d", 
+                          mncc_sync_req->ti, 
+                          mncc_sync_req->mpty_event);
+
+          switch (mncc_sync_req->mpty_event)
+          {
+            case MNCC_MPTY_BUILD_SENT:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND
+                    cc_data->mpty_state[i] EQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->mpty_state[i] = M_CC_MPTY_REQ;
+                }
+              }
+              break;
+
+            case MNCC_MPTY_BUILD_FAIL:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] EQ M_CC_MPTY_REQ)
+                {
+                  cc_data->mpty_state[i] =  M_CC_MPTY_IDLE;
+                }
+              }
+              break;
+
+            case MNCC_MPTY_BUILD_SUCCESS:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i))
+                {
+                  cc_data->mpty_state[i] = M_CC_MPTY_CALL;
+                  cc_data->hold_state[i] = M_CC_HLD_IDLE;
+                }
+              }
+              break;
+
+            /* -- */
+            
+            case MNCC_MPTY_SPLIT_SENT:
+              if (cc_data->mpty_state[cc_data->index_ti] EQ M_CC_MPTY_CALL)
+              {              
+                cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_SPLIT;
+              }
+              break;
+
+            case MNCC_MPTY_SPLIT_FAIL:
+              if (cc_data->mpty_state[cc_data->index_ti] EQ M_CC_MPTY_SPLIT)
+              {              
+                cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_CALL;
+              }
+              break;
+
+            case MNCC_MPTY_SPLIT_SUCCESS:
+              cc_data->mpty_state[cc_data->index_ti] = M_CC_MPTY_IDLE;
+              cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->hold_state[i] = M_CC_HLD_CALL_HELD;
+                }
+              }
+              break;
+
+            /* -- */
+
+            case MNCC_MPTY_HOLD_SENT:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->hold_state[i] = M_CC_HLD_HOLD_REQ;
+                }
+              }
+              break;
+
+            case MNCC_MPTY_HOLD_FAIL:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->hold_state[i] = M_CC_HLD_IDLE;
+                }
+              }
+              break;
+
+            case MNCC_MPTY_HOLD_SUCCESS:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->hold_state[i] = M_CC_HLD_CALL_HELD;
+                }
+              }
+              break;
+
+            /* -- */
+
+            case MNCC_MPTY_RETRIEVE_SENT:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->hold_state[i] = M_CC_HLD_RETRIEVE_REQ;
+                }
+              }
+              break;
+
+            case MNCC_MPTY_RETRIEVE_FAIL:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->hold_state[i] = M_CC_HLD_CALL_HELD;
+                }
+              }
+              break;
+
+            case MNCC_MPTY_RETRIEVE_SUCCESS:
+              for (i = 0; i < MAX_CC_CALLS; i++)
+              {
+                if (cc_call_is_active(i) AND 
+                    cc_data->mpty_state[i] NEQ M_CC_MPTY_IDLE)
+                {
+                  cc_data->hold_state[i] = M_CC_HLD_IDLE;
+                }
+              }
+              break;
+
+            /* -- */
+
+            default: 
+              TRACE_ERROR ("Illegal MPTY event");
+              break;
+          } /* switch (mncc_sync_req->mpty_event) */
+          break; 
+          
+        default:  
+          TRACE_ERROR ("Illegal SYNCCS");
+      } /* switch (mncc_sync_req->synccs) */
+      break;
+      
+    default:
+      break; /* Ignore the event */
+  } /* switch (cc_data->state[cc_data->index_ti]) */
+
+#ifndef NTRACE
+  for (i = 0; i < MAX_CC_CALLS; i++)
+  {
+    if (cc_call_is_active(i))
+    {
+      TRACE_EVENT_P4 ("  hold[%d] = %d, mpty[%d] = %d", 
+                      cc_data->stored_ti_values[i],
+                      cc_data->hold_state[i],
+                      cc_data->stored_ti_values[i],
+                      cc_data->mpty_state[i]);
+    }
+  }
+#endif /* #ifndef NTRACE */
+
+  PFREE (mncc_sync_req);
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_status_res         |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing a MNCC_STATUS_RES primitive. There is an
+            outstanding STATUS message which still has to be sent to 
+            the network after having received a STATUS ENQUIRY in U10.
+
+*/
+
+GLOBAL void cc_mncc_status_res (T_MNCC_STATUS_RES * mncc_status_res)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_mncc_status_res()");
+
+  if ((cc_data->index_ti = srv_convert_ti (mncc_status_res->ti))
+      EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (mncc_status_res);
+    return;
+  }
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_01:  /* MM connection pending */
+    case CS_101: /* No network connection, reestablishment in progress */
+    case CS_261:
+      break;
+
+    default:
+/* Implements Measure#  3 and streamline encoding */    
+      cc_send_status (M_CC_CAUSE_STATUS_ENQUIRY);
+      break;
+  }
+
+  PFREE (mncc_status_res);
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_facility                |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming facility message.
+
+*/
+
+GLOBAL void cc_facility (T_D_FACILITY * facility)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_facility()");
+
+  /* 
+   * A facility message can be received in every state where CC has a 
+   * MM connection, no need to check states here.
+   */
+  if (cc_check_error_flag ())
+  {
+    cc_build_facility_ind (MNCC_FAC_IN_FACILITY, TRUE, &facility->facility);
+    CCD_END;
+  }
+
+  EM_CC_FACILITY_FROM_THE_NETWORK;
+
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_hold_ack                |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming hold ack message.
+
+*/
+
+GLOBAL void cc_hold_ack (void)
+{
+  GET_INSTANCE_DATA;
+  CCD_END;
+
+  TRACE_FUNCTION ("cc_hold_ack()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+      /*
+       * CS_0 is handled by the formatter
+       */
+    case M_CC_CS_10:
+      if (cc_check_error_flag ())
+      {
+        if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_HOLD_REQ)
+        {
+          PALLOC (hold_cnf, MNCC_HOLD_CNF);
+
+          cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_CALL_HELD;
+          hold_cnf->ti = cc_data->ti;
+          hold_cnf->cause = MNCC_CAUSE_HOLD_SUCCESS;
+          PSENDX (MMI, hold_cnf);
+
+          EM_CC_CALL_HOLD_ACKNOWLEDGE;
+
+        }
+        else
+        {
+/* Implements Measure#  3 and streamline encoding */
+          cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+        }
+      }
+      break;
+
+    default:
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_hold_rej                |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming hold rej message.
+
+*/
+
+GLOBAL void cc_hold_rej (T_D_HOLD_REJ * hold_rej)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_hold_rej()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+      /*
+       * CS_0 is handled by the formatter
+       */
+    case M_CC_CS_10:
+      if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_HOLD_REQ)
+      {
+        PALLOC (hold_cnf, MNCC_HOLD_CNF);
+
+        cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
+        hold_cnf->ti = cc_data->ti;
+
+        /*
+         * It is possible for the network to send a REJ without a Cause IE.
+         * This causes the decoder to flag a Madatory IE error. According to
+         * 04.08 Sec: 8.5.3.e, the REJ should still be managed as if a correctly
+         * formatted REJ had been received. 
+         */
+        if (!hold_rej->cc_cause.v_cause)
+        {
+          hold_cnf->cause = MNCC_CAUSE_NO_NET_CAUSE;
+        }
+        else
+        {
+          hold_cnf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                       ORIGSIDE_NET, 
+                                       MNCC_CC_ORIGINATING_ENTITY, 
+                                       hold_rej->cc_cause.cause);
+        }
+        PSENDX (MMI, hold_cnf);
+        srv_use_stored_prim ();
+
+        EM_CC_CALL_HOLD_REJECT;
+
+        CCD_END;
+      }
+      else
+      {
+        CCD_END;
+/* Implements Measure#  3 and streamline encoding  */
+        cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_retrieve_ack            |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming retrieve ack message.
+
+*/
+
+GLOBAL void cc_retrieve_ack (void)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_retrieve_ack()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_10:
+      if (cc_check_error_flag ())
+      {
+        CCD_END;
+        if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_RETRIEVE_REQ)
+        {
+          PALLOC (retrieve_cnf, MNCC_RETRIEVE_CNF);
+
+          cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
+          retrieve_cnf->ti = cc_data->ti;
+          retrieve_cnf->cause = MNCC_CAUSE_RETRIEVE_SUCCESS;
+          PSENDX (MMI, retrieve_cnf);
+
+           EM_CC_CALL_RETRIEVE_ACKNOWLEDGE;
+
+        }
+        else
+        {
+/* Implements Measure#  3 and streamline encoding */
+          cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+        }
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_retrieve_rej            |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming retrieve rej message.
+
+*/
+
+GLOBAL void cc_retrieve_rej (T_D_RETRIEVE_REJ * retrieve_rej)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_retrieve_rej()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_10:
+      if (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_RETRIEVE_REQ)
+      {
+        PALLOC (retrieve_cnf, MNCC_RETRIEVE_CNF);
+
+        cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_CALL_HELD;
+        retrieve_cnf->ti = cc_data->ti;
+
+        /*
+         * It is possible for the network to send a REJ without a Cause IE.
+         * This causes the decoder to flag a Madatory IE error. According to
+         * 04.08 Sec: 8.5.3.e, the REJ should still be managed as if a correctly
+         * formatted REJ had been received. 
+         */
+        if (!retrieve_rej->cc_cause.v_cause)
+        {
+          retrieve_cnf->cause = MNCC_CAUSE_NO_NET_CAUSE;
+        }
+        else
+        {
+          retrieve_cnf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                           ORIGSIDE_NET, 
+                                           MNCC_CC_ORIGINATING_ENTITY, 
+                                           retrieve_rej->cc_cause.cause);
+        }
+        PSENDX (MMI, retrieve_cnf);
+        srv_use_stored_prim ();
+
+        EM_CC_CALL_RETRIEVE_REJECT;
+
+        CCD_END;
+      }
+      else
+      {
+        CCD_END;    
+/* Implements Measure#  3 and streamline encoding */
+        cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding */
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_congestion_control      |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming congestion control message.
+
+*/
+
+GLOBAL void cc_congestion_control (T_B_CONGEST_CTRL * cong)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_congestion_control()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+      /*
+       * CS_0 is handled by the formatter
+       */
+    case M_CC_CS_10:
+      if (cc_check_error_flag ())
+      {
+        PALLOC (user, MNCC_USER_IND);
+
+        cc_build_user_ind_from_cong (user, cong);
+        PSENDX (MMI, user);
+        CCD_END;
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  3 and streamline encoding*/
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_user_information        |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming user information message.
+
+*/
+
+GLOBAL void cc_user_information ( T_B_USER_INFO * user)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_user_information()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_10:
+      if (cc_check_error_flag ())
+      {
+        PALLOC (user_ind, MNCC_USER_IND);
+        
+        cc_build_user_ind_from_user (user_ind, user);
+        CCD_END;
+        PSENDX (MMI, user_ind);
+ 
+        EM_CC_USER_TO_USER_DATA_RECEIVED;
+
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  4 and streamline encoding*/
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_modify                  |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming modify message.
+
+*/
+
+GLOBAL void cc_modify (T_B_MODIFY * modify)
+{
+  GET_INSTANCE_DATA;
+
+  TRACE_FUNCTION ("cc_modify()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+      /*
+       * CS_0 is handled by the formatter
+       */
+    case M_CC_CS_10:
+      if (cc_check_error_flag ())
+      {
+        switch (cc_data->neg_ri)
+        {
+          case M_CC_REPEAT_CIRCULAR:
+            if (cc_data->active_service EQ cc_data->neg_serv1)
+            {
+              if (cc_bcs_compatible (&modify->bearer_cap,
+                                     &cc_data->neg_bc2, TRUE) EQ TRUE)
+              {
+                CCD_END;
+                cc_mod_complete ();
+              }
+              else
+              {
+                CCD_END;
+                cc_mod_reject ();
+              }
+            }
+            else
+            {
+              if (cc_bcs_compatible (&modify->bearer_cap,
+                                     &cc_data->neg_bc1, TRUE) EQ TRUE)
+              {
+                CCD_END;
+                cc_mod_complete ();
+              }
+              else
+              {
+                CCD_END;
+                cc_mod_reject ();
+              }
+            }
+            break;
+#ifndef REL99
+          case M_CC_REPEAT_SEQUENTIAL:
+            if (cc_data->active_service EQ cc_data->neg_serv1)
+            {
+              if (cc_bcs_compatible (&modify->bearer_cap,
+                                     &cc_data->neg_bc2, TRUE) EQ TRUE)
+              {
+                CCD_END;
+                cc_mod_complete ();
+              }
+              else
+              {
+                CCD_END;
+                cc_mod_reject ();
+              }
+            }
+            else
+            {
+              CCD_END;
+              cc_mod_reject ();
+            }
+            break;
+#endif /* #ifndef REL99 */
+          default:
+            CCD_END;
+            cc_mod_reject ();
+            break;
+        }
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  5 and streamline encoding*/
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mod_reject              |
++--------------------------------------------------------------------+
+
+  PURPOSE : Negative end of a mobile terminated in-call modification.
+
+*/
+
+GLOBAL void cc_mod_reject (void)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_mod_reject()");
+
+  CCD_START;
+  {
+    MCAST (modify_rej, B_MODIFY_REJ);
+
+
+    cc_build_modify_reject (modify_rej,
+                            CAUSE_MAKE(DEFBY_STD, 
+                                       ORIGSIDE_MS, 
+                                       MNCC_CC_ORIGINATING_ENTITY,
+                                       M_CC_CAUSE_BEARER_CAP_AUTHORIZ));
+    for_modify_reject (modify_rej);
+  }
+
+  EM_CC_MT_IN_CALL_MODIFICATION_FAILED;
+
+  CCD_END;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mod_complete            |
++--------------------------------------------------------------------+
+
+  PURPOSE : Positive end of a mobile terminated in-call modification.
+
+*/
+
+GLOBAL void cc_mod_complete (void)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_mod_complete()");
+  
+  CCD_START;
+  {
+    MCAST (modify_com, B_MODIFY_COMP);
+    PALLOC (mod_ind, MNCC_MODIFY_IND);
+
+
+    if (cc_data->active_service EQ cc_data->neg_serv1)
+      cc_data->active_service = cc_data->neg_serv2;
+    else
+      cc_data->active_service = cc_data->neg_serv1;
+
+    mod_ind->ti = cc_data->ti;
+    mod_ind->serv = cc_data->active_service;
+    PSENDX (MMI, mod_ind);
+
+    EM_CC_MT_IN_CALL_MODIFICATION_PASSED;
+
+    cc_build_modify_complete (modify_com);
+    for_modify_complete (modify_com);
+  }
+  CCD_END;
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_modify_complete         |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming modify complete message.
+
+*/
+
+GLOBAL void cc_modify_complete ( T_B_MODIFY_COMP * mod_com)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_modify_complete()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_26:
+      if (cc_check_error_flag ())
+      {
+        if (cc_data->new_itc EQ mod_com->bearer_cap.trans_cap)
+        {
+          PALLOC (mod_cnf, MNCC_MODIFY_CNF);
+
+          TIMERSTOP (TIMER_CC);
+          if (cc_data->active_service EQ cc_data->serv1)
+            cc_data->active_service = cc_data->serv2;
+          else
+            cc_data->active_service = cc_data->serv1;
+          mod_cnf->ti = cc_data->ti;
+          mod_cnf->cause = MNCC_CAUSE_MODIFY_SUCCESS;
+          /* Setting raw_cause to empty as we are not sending any cause from network*/ 
+          mod_cnf->c_raw_cause = 0;
+
+          EM_CC_MO_IN_CALL_MODIFICATION_PASSED;
+
+          PSENDX (MMI, mod_cnf);
+          cc_set_state (M_CC_CS_10);
+        }
+        CCD_END;
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  6 and streamline encoding*/
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }  
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_modify_reject           |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming modify reject message.
+
+*/
+
+GLOBAL void cc_modify_reject (T_B_MODIFY_REJ * mod_rej)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_modify_reject()");
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    /*
+     * CS_0 is handled by the formatter
+     */
+    case M_CC_CS_26:
+      if (cc_check_error_flag ())
+      {
+        if (cc_data->old_itc EQ mod_rej->bearer_cap.trans_cap)
+        {
+          PALLOC (mod_cnf, MNCC_MODIFY_CNF);
+
+          TIMERSTOP (TIMER_CC);
+          mod_cnf->ti = cc_data->ti;
+          /* 
+           * cause IE is mandatory and the check for presence has been done
+           * already thus there is no need to check for validity of cause IE
+           * here anymore
+           */
+          mod_cnf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                      ORIGSIDE_NET, 
+                                      MNCC_CC_ORIGINATING_ENTITY, 
+                                      mod_rej->cc_cause.cause);
+          mod_cnf->c_raw_cause = cc_build_cause (&mod_rej->cc_cause,
+                                                  mod_cnf->raw_cause);
+          PSENDX (MMI, mod_cnf);
+          cc_set_state (M_CC_CS_10);
+        }
+
+        EM_CC_MO_IN_CALL_MODIFICATION_FAILED;
+
+        CCD_END;
+      }
+      break;
+
+    default:
+      CCD_END;
+/* Implements Measure#  7 and streamline encoding*/
+      cc_send_status (M_CC_CAUSE_MESSAGE_TYPE_INCOMPAT);
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_status                  |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming status message.
+
+*/
+
+GLOBAL void cc_status (T_B_STATUS * status)
+{
+  GET_INSTANCE_DATA;
+  TRACE_FUNCTION ("cc_status()");
+
+  /* The cause is in STATUS a mandatory IE (given intact message) */
+  TRACE_EVENT_P1 ("STATUS cause: %02x", status->cc_cause.cause);
+
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_0:
+      CCD_END;
+      if (status->call_state.state NEQ M_CC_CS_0)
+      {
+        CCD_START;
+        {
+          MCAST (rel_com, U_RELEASE_COMP);
+ 
+          cc_build_release_complete (rel_com,
+                                     CAUSE_MAKE(DEFBY_STD, 
+                                                ORIGSIDE_MS, 
+                                                MNCC_CC_ORIGINATING_ENTITY,
+                                                M_CC_CAUSE_MESSAGE_INCOMPAT));
+          for_release_complete (rel_com);
+        }
+        CCD_END;
+      }
+      for_rel_req ();
+      break;
+
+    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_10:
+    case M_CC_CS_26:
+      if (cc_check_error_flag ())
+      {
+        /* check for incompatible state */
+        if (status->call_state.state NEQ cc_data->state[cc_data->index_ti])
+        {
+          PALLOC (rel_ind, MNCC_RELEASE_IND);
+
+          cc_reset_dtmf ();  // China change HM 11.07.00
+          
+          TIMERSTOP (TIMER_CC);
+
+          rel_ind->ti    = cc_data->ti;
+
+          rel_ind->cause = CAUSE_MAKE(DEFBY_STD, 
+                                      ORIGSIDE_MS, 
+                                      MNCC_CC_ORIGINATING_ENTITY, 
+                                      M_CC_CAUSE_MESSAGE_INCOMPAT);
+          rel_ind->c_raw_cause = 0;
+          PSENDX (MMI, rel_ind);
+ 
+          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,
+                                                  M_CC_CAUSE_MESSAGE_INCOMPAT));
+            for_release_complete (rel_com);
+          }
+          CCD_END;
+          for_rel_req ();
+          cc_set_state (M_CC_CS_0);
+        }
+        else 
+        /* 
+         * compatible, perform checks/ actions of 04.08, ch. 5.5.3.2.2;  
+         * Condat action (option!) is to initiate normal call clearing 
+         * (with DISCONNECT)
+         */
+        {
+          if ((status->cc_cause.cause >= M_CC_CAUSE_INCORRECT_MESSAGE)
+              AND
+              (status->cc_cause.cause <= M_CC_CAUSE_COND_INFO_ELEM))
+          {
+            /* 
+             * Block entered for 
+             * CAUSE_INCORRECT_MESSAGE, CAUSE_INVALID_MAND_INFO,
+             * CAUSE_MESSAGE_TYPE_NOT_IMPLEM, CAUSE_MESSAGE_TYPE_INCOMPAT,
+             * CAUSE_INFO_ELEM_NOT_IMPLEM, CAUSE_COND_INFO_ELEM. (0x5f..0x64)
+             */
+            if ((cc_data->state[cc_data->index_ti] EQ M_CC_CS_10) AND
+                (cc_data->hold_state[cc_data->index_ti] EQ M_CC_HLD_HOLD_REQ))
+            {
+              /* 
+               * Compatible state, last CC message was a hold request which is
+               * not supported by the network. Handled like HOLD REJECT.
+               */
+              PALLOC (hold_cnf, MNCC_HOLD_CNF); /* T_MNCC_HOLD_CNF */
+              cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_IDLE;
+              hold_cnf->ti = cc_data->ti;
+              hold_cnf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                           ORIGSIDE_NET, 
+                                           MNCC_CC_ORIGINATING_ENTITY, 
+                                           status->cc_cause.cause);
+              PSENDX (MMI, hold_cnf);
+              CCD_END;
+              srv_use_stored_prim ();
+            }
+            else if (status->cc_cause.cause NEQ M_CC_CAUSE_INFO_ELEM_NOT_IMPLEM)
+            {
+              /* 
+               * Compatible state, special condition for HOLD REQUEST not met.
+               * The network is also not complaining about an optional 
+               * information element which can be simply ignored.
+               * Disconnect the call.
+               */              
+              PALLOC (disc_ind, MNCC_DISCONNECT_IND);
+
+              TIMERSTOP (TIMER_CC);
+
+              disc_ind->ti    = cc_data->ti;
+              disc_ind->cause = CAUSE_MAKE(DEFBY_STD, 
+                                           ORIGSIDE_NET, 
+                                           MNCC_CC_ORIGINATING_ENTITY, 
+                                           status->cc_cause.cause);
+              disc_ind->c_raw_cause = cc_build_cause (&status->cc_cause,
+                                                       disc_ind->raw_cause);
+              disc_ind->diagnostic = NOT_PRESENT_8BIT;
+              disc_ind->progress_desc = MNCC_PROG_NOT_PRES;
+              PSENDX (MMI, disc_ind);
+
+              CCD_END;
+              CCD_START;
+              {
+                MCAST (disconnect, U_DISCONNECT);
+ 
+                cc_build_disconnect (disconnect, 
+                                     CAUSE_MAKE(DEFBY_STD, 
+                                                ORIGSIDE_MS, 
+                                                MNCC_CC_ORIGINATING_ENTITY,
+                                                M_CC_CAUSE_CALL_CLEAR),
+                                     NULL, MNCC_SS_VER_NOT_PRES);
+                for_disconnect (disconnect);
+              }
+              TIMERSTART (T305, T305_VALUE);
+              cc_set_state (M_CC_CS_11);
+            }
+          }
+          else 
+          {
+            /* 
+             * STATUS message but neither incompatible state nor indicating 
+             * incorrect message / IE; check if we received a STATUS with cause
+             * "message not compatible with protocol state". GSM 04.08 does not
+             * define what to do and also does not define that this case has to 
+             * be handled at all;
+             * Condat (HM) decided to "clear DTMF" if it was running to try to 
+             * recover from the misaligned states scenario.
+             */
+            T_DTMF *p_dtmf;
+
+            p_dtmf = &cc_data->dtmf[cc_data->index_ti];
+            if ((p_dtmf->state EQ DTMF_SEND_REQUEST) AND
+                (status->cc_cause.cause EQ M_CC_CAUSE_MESSAGE_INCOMPAT))
+            {
+              /* Send negative acknowledge for DTMF send request to MMI */
+              PALLOC (mncc_start_dtmf_cnf, MNCC_START_DTMF_CNF);
+              mncc_start_dtmf_cnf->ti       = cc_data->ti;
+              mncc_start_dtmf_cnf->key      = NOT_PRESENT_8BIT;
+              mncc_start_dtmf_cnf->dtmf_mod = NOT_PRESENT_8BIT;
+              mncc_start_dtmf_cnf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                                      ORIGSIDE_NET, 
+                                                      MNCC_CC_ORIGINATING_ENTITY, 
+                                                      M_CC_CAUSE_MESSAGE_INCOMPAT);
+              PSENDX (MMI, mncc_start_dtmf_cnf);
+            }
+
+            /* Bring screwed up network back to work */
+            for_stop_dtmf ();
+
+            /* Reset screwed up DTMF state machine */
+            p_dtmf->state = DTMF_IDLE;
+            p_dtmf->read  = 0;             
+            p_dtmf->write = 0;
+          }
+          CCD_END;
+        }
+      }
+      break;
+
+    case M_CC_CS_11:
+    case M_CC_CS_12:
+      if (cc_check_error_flag ())
+      {
+        if (status->call_state.state NEQ cc_data->state[cc_data->index_ti])
+        {
+          /* 
+           * STATUS message with incompatible state
+           * On receipt of a STATUS message reporting an incompatible call
+           * control state, the receiving entity shall clear the call by 
+           * sending a RELEASE COMPLETE message with cause # 101 "message 
+           * not compatible with protocol state". The reported call control
+           * state is incompatible if the combination of call control states
+           * at the sender and receiver side cannot occur, do not match or cannot
+           * be aligned by actions of the receiver; the exact definition is 
+           * implementation dependent. [04.08 clause 5.5.3.2.1] 
+           */
+          cc_reset_dtmf ();
+          
+          TIMERSTOP (TIMER_CC);
+          
+          /* Send MNCC_RELEASE_IND to MMI */
+          {
+            PALLOC (rel_ind, MNCC_RELEASE_IND); /* T_MNCC_RELEASE_IND */
+            rel_ind->ti    = cc_data->ti;
+            rel_ind->cause = CAUSE_MAKE(DEFBY_STD, 
+                                        ORIGSIDE_MS, 
+                                        MNCC_CC_ORIGINATING_ENTITY, 
+                                        M_CC_CAUSE_MESSAGE_INCOMPAT);
+            rel_ind->c_raw_cause = 0;
+            PSENDX (MMI, rel_ind);
+          }
+
+          CCD_END;
+          CCD_START;
+          {
+            MCAST (rel_com, U_RELEASE_COMP); /* T_U_RELEASE_COMP */
+            cc_build_release_complete (rel_com, 
+                                       CAUSE_MAKE(DEFBY_STD, 
+                                                  ORIGSIDE_MS, 
+                                                  MNCC_CC_ORIGINATING_ENTITY, 
+                                                  M_CC_CAUSE_MESSAGE_INCOMPAT));
+            for_release_complete (rel_com);
+            for_rel_req ();
+            cc_set_state (M_CC_CS_0);
+          }
+        }
+        CCD_END;
+      }
+      break;
+
+    case M_CC_CS_19:
+      if (cc_check_error_flag ())
+      {
+        if (status->call_state.state NEQ cc_data->state[cc_data->index_ti])
+        {
+          TIMERSTOP (TIMER_CC);
+
+          cc_reset_dtmf ();
+
+          {
+            PALLOC (rel_cnf, MNCC_RELEASE_CNF); /* T_MNCC_RELEASE_CNF */
+            rel_cnf->ti    = cc_data->ti;
+            rel_cnf->cause = CAUSE_MAKE(DEFBY_STD, 
+                                        ORIGSIDE_MS, 
+                                        MNCC_CC_ORIGINATING_ENTITY, 
+                                        M_CC_CAUSE_MESSAGE_INCOMPAT);
+            /* Setting raw_cause to empty as this is a local release
+             * of MM connection,CC is not receiving any cause value
+             * from Network
+             */
+            rel_cnf->c_raw_cause = 0;
+            PSENDX (MMI, rel_cnf);
+          }
+
+          CCD_END;
+          CCD_START;
+          {
+            MCAST (rel_com, U_RELEASE_COMP); /* T_U_RELEASE_COMP */
+            cc_build_release_complete (rel_com, 
+                                       CAUSE_MAKE(DEFBY_STD, 
+                                                  ORIGSIDE_MS, 
+                                                  MNCC_CC_ORIGINATING_ENTITY, 
+                                                  M_CC_CAUSE_MESSAGE_INCOMPAT));
+            for_release_complete (rel_com);
+            for_rel_req ();
+            cc_set_state (M_CC_CS_0);
+          }
+        }
+        CCD_END;
+      }
+      break;
+
+    default:
+      CCD_END;
+      break;
+  }
+
+  EM_CC_STATUS_RECEIVED;
+
+}
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_status_enquiry          |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing an incoming status enquiry message.
+
+*/
+
+GLOBAL void cc_status_enquiry (void)
+{
+  GET_INSTANCE_DATA;
+ 
+  TRACE_FUNCTION ("cc_status_enquiry()");
+
+  /*
+   * CS_0 is handled by the formatter
+   */
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_10:
+      /*
+       * Ensure synchronization of auxiliary states with ACI.
+       */
+      if (cc_check_error_flag ())
+      {
+        CCD_END;
+        {
+          PALLOC (mncc_status_ind, MNCC_STATUS_IND);
+          mncc_status_ind->ti = cc_data->ti;
+          PSENDX (MMI, mncc_status_ind);
+        }
+
+      EM_CC_STATUS_ENQUIRY_RECEIVED;
+
+      }
+      break;
+
+    default:
+      /*
+       * No auxiliary states in non-active states. Immediate response is safe.
+       */
+      if (cc_check_error_flag ())
+      {
+        CCD_END;
+        /* EM call moved above cc_send_status should not have any impact */
+        EM_CC_STATUS_ENQUIRY_RECEIVED;
+
+/* Implements Measure#  7 and streamline encoding*/
+        cc_send_status (M_CC_CAUSE_STATUS_ENQUIRY);  
+      }
+      break;
+  }
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_unknown_message         |
++--------------------------------------------------------------------+
+
+  PURPOSE : Processing of an incoming unknown message.
+
+*/
+
+GLOBAL void cc_unknown_message (void)
+{
+
+  CCD_END;
+  CCD_START;
+  {
+    MCAST (status, B_STATUS);
+
+    TRACE_FUNCTION ("cc_unknown_message()");
+
+    cc_build_status (status, 
+                     CAUSE_MAKE(DEFBY_STD,
+                                ORIGSIDE_MS,
+                                MNCC_CC_ORIGINATING_ENTITY,
+                                M_CC_CAUSE_MESSAGE_TYPE_NOT_IMPLEM));
+    for_status (status);
+  }
+  CCD_END;
+}
+
+/* Implements Measure#  18 */
+/*
++--------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)       MODULE  : CC_ACT                     |
+| STATE   : code                ROUTINE : cc_mncc_hold_retrieve_req  |
++--------------------------------------------------------------------+
+
+  PURPOSE : Send hold REQ/retrieve REQ.
+
+*/
+
+LOCAL void cc_mncc_hold_retrieve_req (T_PRIM * prim)
+{ 
+  GET_INSTANCE_DATA;
+  UBYTE      ti;
+
+  TRACE_FUNCTION ("cc_mncc_hold_retrieve_req()");
+
+  if(prim->custom.opc EQ MNCC_HOLD_REQ)
+  {
+    ti = ((T_MNCC_HOLD_REQ *)P2D(prim))->ti;    
+  }
+  else
+  {
+    ti = ((T_MNCC_RETRIEVE_REQ *)P2D(prim))->ti;
+  }
+  if ((cc_data->index_ti = srv_convert_ti (ti)) EQ NOT_PRESENT_8BIT)
+  {
+    PFREE (P2D(prim));
+    return;
+  }
+  
+  switch (cc_data->state[cc_data->index_ti])
+  {
+    case M_CC_CS_10:
+      if(prim->custom.opc EQ MNCC_HOLD_REQ)
+      {
+        /* We should think about storing the hold request 
+           until DTMF idle state reached. ...
+           This causes some other changes, we have to add some 
+           calls to serv_use_stored_prim() at some places after
+           state transition of the DTMF state machine to DTMF idle.*/
+        cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_HOLD_REQ;
+        for_hold ();
+        EM_CC_CALL_HOLD;
+      }
+      else
+      {
+        cc_data->hold_state[cc_data->index_ti] = M_CC_HLD_RETRIEVE_REQ;
+        for_retrieve ();
+        EM_CC_CALL_RETRIEVE;
+      }
+      PFREE (P2D(prim));     
+
+      break;
+
+    case CS_101:
+    case M_CC_CS_26:
+    case CS_261:
+      srv_store_prim (prim);
+      break;
+
+    default:
+      PFREE (P2D(prim));
+      break;
+  }
+}
+
+#endif