view src/aci2/aci/psa_ccp.c @ 581:a0a45c5eb3ef

gsmcomp.c: bumping trace partition size to 220 like in gprscomp.c This change is safe in terms of RAM usage because all of these partition pools have already been moved from XRAM to IRAM earlier, and our IRAM usage in VO configs is currently quite low - the one near the limit is XRAM on C11x.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 29 Jan 2019 03:52:49 +0000
parents 97b311bae21f
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  GSM-PS (6147)
|  Modul   :  PSA_CCP
+----------------------------------------------------------------------------- 
|  Copyright 2002 Texas Instruments Berlin, AG 
|                 All rights reserved. 
| 
|                 This file is confidential and a trade secret of Texas 
|                 Instruments Berlin, AG 
|                 The receipt of or possession of this file does not convey 
|                 any rights to reproduce or disclose its contents or to 
|                 manufacture, use, or sell anything it may describe, in 
|                 whole, or in part, without the specific written consent of 
|                 Texas Instruments Berlin, AG. 
+----------------------------------------------------------------------------- 
|  Purpose :  This module defines the processing functions for the
|             primitives send to the protocol stack adapter by call
|             control.
+----------------------------------------------------------------------------- 
*/ 

#ifndef PSA_CCP_C
#define PSA_CCP_C
#endif

#include "aci_all.h"

/*==== INCLUDES ===================================================*/
#include "ccdapi.h"

#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_cmd.h"
#include "aci_mem.h"
#include "aci_lst.h"

#ifdef FAX_AND_DATA
#include "aci_fd.h"
#endif    /* of #ifdef FAX_AND_DATA */

#include "aci.h"
#include "psa.h"
#include "psa_cc.h"
#include "psa_ss.h"
#include "psa_mmi.h"
#include "psa_mm.h"
#include "cmh.h"
#include "cmh_cc.h"

#ifdef SIM_TOOLKIT
#include "psa_sat.h"
#include "cmh_sat.h"
#endif    /* of #ifdef SIM_TOOLKIT */

#include "aoc.h"
#include "psa_sim.h"

#if defined (FF_WAP) || defined (FF_SAT_E)
#include "wap_aci.h"
#endif /* of FF_WAP */

#include "l4_tim.h"

/*==== CONSTANTS ==================================================*/


/*==== TYPES ======================================================*/


/*==== EXPORT =====================================================*/

#ifdef FF_EM_MODE
EXTERN USHORT em_relcs;
#endif /* FF_EM_MODE

/*==== VARIABLES ==================================================*/

EXTERN T_PCEER causeMod;
EXTERN SHORT causeCeer;

/*==== FUNCTIONS ==================================================*/


/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_setup_ind      |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_SETUP_IND primitive send by CC.
            this indicates an incoming call.

*/
// CC test 0319
extern void CongiureGPIO_Internal(int GpioPin);
extern void HighGPIO(int GpioPin);
extern void LowGPIO(int GpioPin);
// end

GLOBAL const void psa_mncc_setup_ind
                   ( T_MNCC_SETUP_IND *mncc_setup_ind )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */
  int i;

  TRACE_FUNCTION ("psa_mncc_setup_ind()");

  causeMod  = P_CEER_mod;      /* Clear module which was set for ceer */
  causeCeer = CEER_NotPresent; /* Clear extended error cause */

// CC test 0319
//   CongiureGPIO_Internal(1);
//   LowGPIO(1);
// end

  /* stop redialling timer if necessary */
  if (rdlPrm.rdlcId NEQ NO_ENTRY)
  {
    TIMERSTOP(ACI_REPEAT_HND);
    
    #ifdef SIM_TOOLKIT
      if( ( ccShrdPrm.ctb[rdlPrm.rdlcId]->SATinv & SAT_REDIAL ) )
      { /* This is the call invoked by SAT */
        T_ACI_SAT_TERM_RESP resp_data;

        psaSAT_InitTrmResp( &resp_data );
        psaSAT_SendTrmResp( RSLT_USR_CLR_DWN, &resp_data );
      }
    #endif /* SIM_TOOLKIT */

    psaCC_FreeCtbNtry (rdlPrm.rdlcId);  
    for(i = 0; i < CMD_SRC_MAX; i++)
    {
      R_AT(RAT_RDL, i)(REDIAL_STOP);
    }
    /* reset some redial parameter */
    rdlPrm.rdlcId =   NO_ENTRY;
  }

/*
 *-------------------------------------------------------------------
 * check for new entry in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbNewEntry();

  if( cId < 0 )
  {
   /*
    * disconnect call, due to full call table.
    */
    {
      UBYTE ti = mncc_setup_ind -> ti;
      PREUSE (mncc_setup_ind, mncc_disconnect_req, MNCC_DISCONNECT_REQ);
      mncc_disconnect_req -> ti    = ti;
      mncc_disconnect_req -> cause = MNCC_CAUSE_USER_BUSY;
      mncc_disconnect_req -> fac_inf.l_fac = 0;
      mncc_disconnect_req -> ss_version = SS_VER_NOT_PRES;
      PSENDX (CC, mncc_disconnect_req);
    }

    TRACE_EVENT ("MTC rejected due to full call table");

    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];
  pCtbNtry -> curCs = MNCC_CAUSE_NO_MS_CAUSE;

  pCtbNtry -> ti         = mncc_setup_ind -> ti;
  pCtbNtry -> rptInd     = mncc_setup_ind -> ri;
  pCtbNtry -> sigInf     = mncc_setup_ind -> sig;
  pCtbNtry -> clgPty     = mncc_setup_ind -> calling_party;
  pCtbNtry -> clgPtySub  = mncc_setup_ind -> calling_party_sub;

  /*
   * Assign called party 
   */
  pCtbNtry -> cldPty.ton = mncc_setup_ind -> called_party.ton;
  pCtbNtry -> cldPty.npi = mncc_setup_ind -> called_party.npi;
  pCtbNtry -> cldPty.c_called_num = 
    mncc_setup_ind -> called_party.c_called_num;
  if (pCtbNtry -> cldPty.called_num NEQ NULL)
  {
    ACI_MFREE (pCtbNtry -> cldPty.called_num);
    pCtbNtry -> cldPty.called_num = NULL;
  }
  if (pCtbNtry -> cldPty.c_called_num NEQ 0)
  {
    ACI_MALLOC (pCtbNtry -> cldPty.called_num, 
                pCtbNtry -> cldPty.c_called_num);
    memcpy (pCtbNtry -> cldPty.called_num, 
            mncc_setup_ind -> called_party.called_num,
            mncc_setup_ind -> called_party.c_called_num);
  }

  /*
   * Assign called party subaddress
   */
  pCtbNtry -> cldPtySub  = mncc_setup_ind -> called_party_sub;

  /* 
   * Assign redirecting party
   */
  pCtbNtry -> rdrPty.ton     = mncc_setup_ind -> redirecting_party.ton; 
  pCtbNtry -> rdrPty.npi     = mncc_setup_ind -> redirecting_party.npi;
  pCtbNtry -> rdrPty.present = mncc_setup_ind -> redirecting_party.present; 
  pCtbNtry -> rdrPty.screen  = mncc_setup_ind -> redirecting_party.screen;
  pCtbNtry -> rdrPty.c_redir_num = 
    mncc_setup_ind -> redirecting_party.c_redir_num;
  if (pCtbNtry -> rdrPty.redir_num NEQ NULL)
  {
    ACI_MFREE (pCtbNtry -> rdrPty.redir_num);
    pCtbNtry -> rdrPty.redir_num = NULL;
  }
  if (pCtbNtry -> rdrPty.c_redir_num NEQ 0)
  {
    ACI_MALLOC (pCtbNtry -> rdrPty.redir_num,
                pCtbNtry -> rdrPty.c_redir_num);
    memcpy (pCtbNtry -> rdrPty.redir_num, 
            mncc_setup_ind -> redirecting_party.redir_num,
            mncc_setup_ind -> redirecting_party.c_redir_num);
  }

  /* 
   * Assign redirecting party subaddress
   */
  pCtbNtry -> rdrPtySub.tos       = 
    mncc_setup_ind -> redirecting_party_sub.tos; 
  pCtbNtry -> rdrPtySub.odd_even  = 
    mncc_setup_ind -> redirecting_party_sub.odd_even;
  pCtbNtry -> rdrPtySub.c_subaddr = 
    mncc_setup_ind -> redirecting_party_sub.c_subaddr;
  if (pCtbNtry -> rdrPtySub.subaddr NEQ NULL)
  {
    ACI_MFREE (pCtbNtry -> rdrPtySub.subaddr);
    pCtbNtry -> rdrPtySub.subaddr = NULL;
  }
  if (pCtbNtry -> rdrPtySub.c_subaddr NEQ 0)
  {
    ACI_MALLOC (pCtbNtry -> rdrPtySub.subaddr, 
                pCtbNtry -> rdrPtySub.c_subaddr);
    memcpy (pCtbNtry -> rdrPtySub.subaddr, 
            mncc_setup_ind -> redirecting_party_sub.subaddr,
            mncc_setup_ind -> redirecting_party_sub.c_subaddr);
  }

  /* 
   * Assign bearer caps
   */  
  memcpy( &(pCtbNtry->BC[0]),&(mncc_setup_ind->bcpara),
          sizeof( T_bcpara) );
  memcpy( &(pCtbNtry->BC[1]),&(mncc_setup_ind->bcpara2),
          sizeof( T_bcpara) );

  psaCC_phbSrchNum( cId, CT_MTC );

  pCtbNtry -> calStat = CS_ACT_REQ;
  pCtbNtry -> calType = CT_MTC;

  pCtbNtry -> prio  = PRIO_NORM_CALL;
  pCtbNtry -> curBC = 0;

  psaCC_send_satevent( EVENT_MT_CALL, cId, FAR_END, FALSE );

/*
 *-------------------------------------------------------------------
 * indicate alerting
 *-------------------------------------------------------------------
 */

  /* replace invalid/unknown sigInf by SIG_NOT_PRES */
  switch (pCtbNtry -> sigInf)
  {
    case SIG_DIAL_TONE_ON:
    case SIG_RING_BACK_TONE_ON:
    case SIG_INT_TONE_ON:
    case SIG_NET_CONG_TONE_ON:
    case SIG_BUSY_TONE_ON:
    case SIG_CONF_TONE_ON:
    case SIG_ANS_TONE_ON:
    case SIG_CALL_WAIT_TONE_ON:
    case SIG_OFF_HOOK_WARN_TONE_ON:
    case SIG_TONES_OFF:
    case SIG_ALERT_OFF:
    case SIG_NOT_PRES:
      break; /* leave as it is */
    default: /* replace unknown value by something well known */
      pCtbNtry -> sigInf = SIG_NOT_PRES;
  }

  if( pCtbNtry -> sigInf NEQ SIG_NOT_PRES OR
      ccShrdPrm.TCHasg EQ TRUE )
  {
    {
      /* indicate alerting to network */
      UBYTE ti = mncc_setup_ind -> ti;
      PREUSE (mncc_setup_ind, mncc_alert_req, MNCC_ALERT_REQ);
      mncc_alert_req -> ti    = ti;
      PSENDX (CC, mncc_alert_req);
    }

    cmhCC_IncomingCall (cId);    /* indicate an incoming call */
    return;
  }
  else
  {
    pCtbNtry -> alrtStat = AS_PND;
  }

  /*
   * check for progress descriptions
   */
  psaCC_chkPrgDesc ( cId, mncc_setup_ind -> progress_desc, MT_SETUP );

  /*
   * start call time measurements
   */
  aoc_info (cId, AOC_START_TIME);
/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_setup_ind);
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_setup_cnf      |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_SETUP_CNF primitive send by CC.
            this terminates the call establishment request.

*/

GLOBAL const void psa_mncc_setup_cnf
                                 ( T_MNCC_SETUP_CNF *mncc_setup_cnf )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */
  int i;
  BOOL flag_redial = FALSE;

  TRACE_FUNCTION ("psa_mncc_setup_cnf()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_setup_cnf -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_setup_cnf);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];
  pCtbNtry -> curCs = mncc_setup_cnf -> cause;
  pCtbNtry -> rslt = mncc_setup_cnf -> cause;


  switch( mncc_setup_cnf -> cause )
  {
    case( MNCC_CAUSE_SUCCESS ):    /* successful establishment, call connected */

      /* 
       * MNCC_SETUP_CNF is received in call state other than CS_ACT_REQ
       * so reject the primitive.
      */
      if( pCtbNtry -> calStat NEQ CS_ACT_REQ)
      {
        TRACE_EVENT ("MNCC_SETUP_CNF is rejected as it is received in call state other than CS_ACT_REQ");
        break;
      }
      pCtbNtry -> clgPty.ton     = mncc_setup_cnf -> connected_number.ton;
      pCtbNtry -> clgPty.npi     = mncc_setup_cnf -> connected_number.npi;
      pCtbNtry -> clgPty.present = mncc_setup_cnf -> connected_number.present;
      pCtbNtry -> clgPty.screen  = mncc_setup_cnf -> connected_number.screen;
      pCtbNtry -> clgPty.c_num   = mncc_setup_cnf -> connected_number.c_num;

      memcpy( pCtbNtry -> clgPty.num,
              mncc_setup_cnf -> connected_number.num, MAX_CC_CALLING_NUMBER );

      pCtbNtry -> clgPtySub.tos = mncc_setup_cnf -> connected_number_sub.tos;
      pCtbNtry -> clgPtySub.odd_even = mncc_setup_cnf -> connected_number_sub.odd_even;
      pCtbNtry -> clgPtySub.c_subaddr = mncc_setup_cnf -> connected_number_sub.c_subaddr;

      memcpy( pCtbNtry -> clgPtySub.subaddr,
              mncc_setup_cnf -> connected_number_sub.subaddr, SUB_LENGTH );

      pCtbNtry -> inBndTns = FALSE;
      pCtbNtry -> calStat  = CS_ACT;

      /* check for progress descriptions */
      psaCC_chkPrgDesc ( cId, mncc_setup_cnf -> progress_desc, MT_CONN );


      if(pCtbNtry->calType EQ CT_MOC_RDL)
      {
        pCtbNtry->calType = CT_MOC;
        flag_redial = TRUE;
      }
      /* if redialling procedure was successful we finish redialling */
      if((rdlPrm.rdlMod EQ AUTOM_REPEAT_ON) AND flag_redial)
      {
        for(i = 0; i < CMD_SRC_MAX; i++)
        {
          R_AT(RAT_RDL, i)(CALL_ATTEMPT_SUCCESSFUL); 
        }
        pCtbNtry->rdlCnt = 0;
        rdlPrm.rdlcId = NO_ENTRY;
        pCtbNtry->rdlTimIndex = RDL_TIM_INDEX_NOT_PRESENT;
        flag_redial = FALSE;
      }
    
      /* Inform that a call goes to active state */
      psaCC_chngCalTypCnt( cId, +1 );

      cmhCC_CallConnected( cId );

      psaCC_send_satevent( EVENT_CALL_CONN, cId, FAR_END, FALSE );

      aoc_info (cId,AOC_CALL_CONNECTED);

      /* check for TTY service */
      cmhCC_TTY_Control ( cId, TTY_START );

      /* check for DTMF tones to send automatically */
      psaCC_DTMFSent ( cId );

#if defined (FF_WAP) || defined (FF_SAT_E)
      /* WAP STACK CALL is activ */
      if (Wap_Call)
        ccShrdPrm.wapStat = CC_WAP_STACK_UP;
#endif

      break;

    default:            /* unexpected result, assumed call disconnected */
      {
        TRACE_EVENT_P1("[ERR] UNEXP CAUSE IN SETUP CNF=%4x", mncc_setup_cnf -> cause);
      }
      /*FALLTHROUGH*/ /*lint -fallthrough*/

    /* unsuccessful establishment, call disconnected */
    case( MNCC_CAUSE_MS_TIMER ):

      pCtbNtry -> nrmCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
      pCtbNtry -> rejCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
#ifdef FF_EM_MODE
      em_relcs = MNCC_CAUSE_MS_TIMER;
#endif /* FF_EM_MODE */
      ccShrdPrm.cIdFail = cId;

      /* 
       * At this point the call has not yet gone completely always.
       * Call Control may not be in state U0, but in state U11, having
       * sent a DISCONNECT to the network, expecting the RELEASE
       * from the network or expiry of T308 in CC.
       * Implementation works, but it is not very nice here, releasing
       * the ti and decrementing the call count too early.
       */
      pCtbNtry -> calStat = CS_IDL;

      psaCC_chngCalTypCnt( cId, -1 );
      psaCC_retMOCTi( pCtbNtry -> ti );
      cmhCC_CallDisconnected (cId);
      psaCC_FreeCtbNtry (cId);
      break;
  }
/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_setup_cnf);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_setup_compl_ind|
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_SETUP_COMPL_IND primitive send by CC.
            this terminates the call establishment of an incoming call.

*/

GLOBAL const void psa_mncc_setup_compl_ind
                       ( T_MNCC_SETUP_COMPL_IND *mncc_setup_compl_ind )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_setup_compl_ind()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_setup_compl_ind -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_setup_compl_ind);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];

  pCtbNtry -> rslt = mncc_setup_compl_ind -> cause;
  pCtbNtry -> curCs = mncc_setup_compl_ind -> cause;

  switch( mncc_setup_compl_ind -> cause )
  {
    case( MNCC_CAUSE_SUCCESS ):    /* successful establishment, call connected */

      pCtbNtry -> inBndTns = FALSE;
      pCtbNtry -> calStat  = CS_ACT;

      psaCC_setSpeechMode ();

      /* check for TTY service */
      cmhCC_TTY_Control ( cId, TTY_START );

      /*
       * Inform that a call goes to active state
       */
      psaCC_chngCalTypCnt( cId, +1 );

      cmhCC_CallConnected( cId );

      aoc_info (cId, AOC_CALL_CONNECTED);
      break;

    default:            /* unexpected result, assumed call disconnected */
      {
        TRACE_EVENT_P1("[ERR] UNEXP CAUSE IN SETUP CMPL IND=%4x", mncc_setup_compl_ind -> cause);
      }
      /*FALLTHROUGH*/ /*lint -fallthrough*/

    /* unsuccessful establishment, call disconnected */
    case( MNCC_CAUSE_MS_TIMER ):

      pCtbNtry -> nrmCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
      pCtbNtry -> rejCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
#ifdef FF_EM_MODE
      em_relcs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
#endif /* FF_EM_MODE */
      ccShrdPrm.cIdFail = cId;
      
      /*
       * What happens below is somewhat questionable.
       * ACI sets the call to CS_IDL and free the transaction identifier.
       * What happened is that on CC level, in state U8 CONNECT REQUEST the
       * CONNECT message sent by CC has not been answered by the network by a 
       * CONNECT ACNOWLEDGE message.
       * In this situation CC sends a DISCONNECT to the network and enters
       * state U11 DISCONNECT REQUEST. This means, the call state in CC is
       * still different from U0 NULL.
       * However, problems in the field are not expected here.
       */
      pCtbNtry -> calStat = CS_IDL;

      psaCC_chngCalTypCnt( cId, -1 );
      psaCC_retMOCTi( pCtbNtry -> ti );

      cmhCC_CallDisconnected (cId);
      cmhCC_CallReleased (cId);

      break;
  }

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_setup_compl_ind);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_reject_ind     |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_REJECT_IND primitive send by CC.
            this indicates a cause for rejecting a call establishment.

*/

GLOBAL const void psa_mncc_reject_ind
                               ( T_MNCC_REJECT_IND *mncc_reject_ind )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_reject_ind()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_reject_ind -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_reject_ind);
    return;
  }
  psaCC_StopDTMF (cId); /* HM 27.07.00*/

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];
  pCtbNtry -> curCs = mncc_reject_ind -> cause;

  pCtbNtry -> rslt  = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
  pCtbNtry -> nrmCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
  pCtbNtry -> rejCs = mncc_reject_ind -> cause;
  /* In this case, the cause values are internal and not sent by network */
  pCtbNtry -> numRawCauseBytes = 0; 

#ifdef FF_EM_MODE
  em_relcs = mncc_reject_ind -> cause;
#endif /* FF_EM_MODE */  

  if( GET_CAUSE_VALUE(pCtbNtry -> rejCs) NEQ NOT_PRESENT_8BIT ) ccShrdPrm.cIdFail = cId;

  pCtbNtry -> calStat = CS_IDL;

  psaCC_chngCalTypCnt( cId, -1 );
  psaCC_retMOCTi( pCtbNtry -> ti );

  /* monitoring for SAT radio-link failure */
  psaCC_send_satevent( EVENT_CALL_DISC, cId, NEAR_END, TRUE );

  /* check conditions for redialling */
  cmhCC_redialCheck(cId);

#ifdef SIM_TOOLKIT
        if( pCtbNtry->SATinv )
        {
          cmhSAT_NtwErr( ADD_NO_CAUSE );
          pCtbNtry->SATinv = FALSE;
        }
#endif
  /* cmhCC_CallDisconnected(cId);*/
  cmhCC_CPIrejectMsg(cId);
  cmhCC_CallReleased(cId);

/* free the primitive buffer */
  PFREE (mncc_reject_ind);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_release_ind    |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_RELEASE_IND primitive send by CC.
  this indicates the release of a call.
  
*/

GLOBAL const void psa_mncc_release_ind
( T_MNCC_RELEASE_IND *mncc_release_ind )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */
  
  TRACE_FUNCTION ("psa_mncc_release_ind()");
  
  /*
  *-------------------------------------------------------------------
  * find call in call table
  *-------------------------------------------------------------------
  */
  cId = psaCC_ctbFindTi( mncc_release_ind -> ti );
  
  if( cId < 0 )
  {
    psaCC_retMOCTi( mncc_release_ind -> ti );
    
    /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_release_ind);
    return;
  }
  psaCC_StopDTMF ( cId ); /* HM 27.07.00 */
  
 /*
  *-------------------------------------------------------------------
  * update shared parameter and notify ACI
  *-------------------------------------------------------------------
  */
  pCtbNtry = ccShrdPrm.ctb[cId];
  
  pCtbNtry -> calStat = CS_DSC_REQ; /* Leave active state */
  pCtbNtry -> curCs = mncc_release_ind -> cause;
  pCtbNtry -> numRawCauseBytes = mncc_release_ind -> c_raw_cause;
  pCtbNtry -> rawCauseBytes    = mncc_release_ind -> raw_cause;

  psaCC_setSpeechMode ();
  
  /* check for TTY service */
  /*cmhCC_TTY_Control ( cId );*/
  
  if (pCtbNtry -> nrmCs EQ MNCC_CAUSE_NO_MS_CAUSE)    /* no Disconnect Cause available...*/
  {
    pCtbNtry -> nrmCs= mncc_release_ind -> cause; /* Check ### */
    ccShrdPrm.cIdFail = cId; /* Check ### */
#ifdef FF_EM_MODE
    em_relcs = mncc_release_ind -> cause; /* Check ### */
#endif /* FF_EM_MODE */  
  }
  
  pCtbNtry -> rejCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
  pCtbNtry -> rslt  = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
  
  psaCC_chngCalTypCnt( cId, -1 );
  psaCC_retMOCTi( pCtbNtry -> ti );
  
  psaCC_send_satevent( EVENT_CALL_DISC, cId, FAR_END, TRUE );

  pCtbNtry -> numRawCauseBytes = 0; /* Reset the cause value after sending the info to SAT */

  cmhCC_redialCheck(cId);
  
  /*
  if( pCtbNtry -> CCBSstat EQ CCBSS_PSSBL OR
  pCtbNtry -> calType  EQ CT_NI_MOC      )
  */
  switch (pCtbNtry->curCmd)
  {
  case( AT_CMD_A ):
  case( AT_CMD_D ):
  case( AT_CMD_NONE ):
  case( AT_CMD_ABRT ):
    {
      cmhCC_CallDisconnected(cId);
      cmhCC_CallReleased( cId );
    }
    break;
    
  case( AT_CMD_H ):
  case( AT_CMD_Z ):
  case( AT_CMD_CHUP ):
  case( AT_CMD_CHLD ):
    
#ifdef FF_FAX
  case( AT_CMD_FKS ):
  case( AT_CMD_FDT ):
  case( AT_CMD_FDR ):
#endif
    {
      cmhCC_CallDisconnected(cId);
      cmhCC_CPIReleaseMsg(cId);
    }
    break;
  }

  if (rdlPrm.rdlcId NEQ cId)
  {/* if redialling is active no clean cId entry */
    /*patch BE 30.06.00 to remove every other call drops*/
    psaCC_FreeCtbNtry (cId);
    /*end patch BE */
  }
  
  /* free the primitive buffer */
  PFREE (mncc_release_ind);
  
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_release_cnf    |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_RELEASE_CNF primitive send by CC.
            this confirmates the release request for a call.

*/

GLOBAL const void psa_mncc_release_cnf
                             ( T_MNCC_RELEASE_CNF *mncc_release_cnf )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_release_cnf()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_release_cnf -> ti );

  if( cId < 0 )
  {
    psaCC_retMOCTi( mncc_release_cnf -> ti );

   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_release_cnf);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];

  /* HM 02-Aug-2002, done while merging SBK code, check again this code*/
#if 0 /* Old code */
  if( mncc_release_cnf -> cause NEQ CAUSE_NOT_PRES )
  {
    pCtbNtry -> nrmCs = mncc_release_cnf -> cause;
    ccShrdPrm.cIdFail = cId;
#ifdef FF_EM_MODE
    em_relcs = mncc_release_cnf -> cause;
#endif /* FF_EM_MODE */  
  }
#endif /* #if 0 */

  if (pCtbNtry -> nrmCs EQ MNCC_CAUSE_NO_MS_CAUSE)    /* no Disconnect Cause available...*/
  {
    pCtbNtry -> nrmCs = mncc_release_cnf -> cause; /* Recheck ###*/
    ccShrdPrm.cIdFail = cId;  /* This line is considered harmful, only if cause present ### */
#ifdef FF_EM_MODE
    em_relcs = mncc_release_cnf -> cause;  /* Recheck ### */
#endif /* FF_EM_MODE */  
  }
  pCtbNtry -> rslt  = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
  pCtbNtry -> rejCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
  pCtbNtry -> curCs = pCtbNtry -> rejCs;
  pCtbNtry -> numRawCauseBytes = mncc_release_cnf -> c_raw_cause;
  pCtbNtry -> rawCauseBytes    = mncc_release_cnf -> raw_cause;
#ifdef SIM_TOOLKIT
  if(!(pCtbNtry -> SATinv & SAT_REDIAL))
#endif
    pCtbNtry -> calStat = CS_IDL;

  psaCC_chngCalTypCnt( cId, -1 );
  psaCC_retMOCTi( pCtbNtry -> ti );

  psaCC_send_satevent( EVENT_CALL_DISC, cId , FAR_END, TRUE );

  pCtbNtry -> numRawCauseBytes = 0; /* Reset the cause value after sending the info to SAT */

  cmhCC_redialCheck( cId);

  cmhCC_CallReleased (cId);

  /*patch BE 30.06.00 to remove every other call drops */
  {
#ifdef SIM_TOOLKIT
    if ( (pCtbNtry -> SATinv & SAT_REDIAL) EQ 0 )
    {
#endif  /* SIM_TOOLKIT */
      if (rdlPrm.rdlcId NEQ cId)
      {
        psaCC_FreeCtbNtry (cId);
      }
#ifdef SIM_TOOLKIT
    }
#endif  /* SIM_TOOLKIT */
  }
  /*end patch BE */

  switch(CHLDaddInfo)
  {
    case (CHLD_ADD_INFO_DIAL_CAL):
      cId = psaCC_ctbFindCall( NO_VLD_OWN, NO_VLD_CS, CT_MOC );
      if (cId NEQ NO_ENTRY)
      {
        cmhCC_NewCall(cId,psaCC_ctb(cId)->curSrc,AT_CMD_D);
      } 
      break;
    default:
      break;
  }
  /* free the primitive buffer */
  PFREE (mncc_release_cnf);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_disconnect_ind |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_DISCONNECT_IND primitive send by CC.
            this indicates the disconnection of a call.

*/

GLOBAL const void psa_mncc_disconnect_ind
                       ( T_MNCC_DISCONNECT_IND *mncc_disconnect_ind )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */
  BOOL held_call = FALSE;

  TRACE_FUNCTION ("psa_mncc_disconnect_ind()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_disconnect_ind -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_disconnect_ind);
    return;
  }
  psaCC_StopDTMF ( cId ); /* HM 27.07.00 */

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];

  pCtbNtry -> curCs = mncc_disconnect_ind -> cause;

  if( mncc_disconnect_ind->diagnostic EQ DIAG_CCBS_POSSIBLE )
  {
    pCtbNtry -> CCBSstat = CCBSS_PSSBL;
  }

  /* CQ 23619: copy ss diagnostic to shared parameters >> */
  pCtbNtry->ssDiag = mncc_disconnect_ind->ss_diag;
  /* CQ 23619 << */
  
#if 0
 if( mncc_disconnect_ind -> cause NEQ CAUSE_NOT_PRES )
  {
    pCtbNtry -> nrmCs = mncc_disconnect_ind -> cause;
    ccShrdPrm.cIdFail = cId;
#ifdef FF_EM_MODE
    em_relcs = mncc_disconnect_ind -> cause;
#endif /* FF_EM_MODE */
  }
#endif 

  pCtbNtry -> nrmCs = mncc_disconnect_ind -> cause; /* Recheck ### */
  ccShrdPrm.cIdFail = cId; /* Recheck ### */
#ifdef FF_EM_MODE
  em_relcs = mncc_disconnect_ind -> cause; /* Recheck ### */
#endif /* FF_EM_MODE */

  /* remember if call is currently on hold */
  if (pCtbNtry -> calStat EQ CS_HLD)
    held_call = TRUE;
  
  /* calStat has to be set before calling psaCC_chkPrgDesc, otherwise
     no CPI event will be send */
  pCtbNtry -> calStat = CS_DSC_REQ; 

  /* check for TTY service */
  /* cmhCC_TTY_Control ( cId ); */

  /* check for progress descriptions */
  psaCC_chkPrgDesc ( cId, mncc_disconnect_ind -> progress_desc, MT_DISC );

  pCtbNtry -> rslt  = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);
  pCtbNtry -> rejCs = CAUSE_MAKE(DEFBY_CONDAT, ORIGSIDE_MS, CC_ORIGINATING_ENTITY, NOT_PRESENT_8BIT);

  pCtbNtry -> numRawCauseBytes = mncc_disconnect_ind -> c_raw_cause;
  pCtbNtry -> rawCauseBytes    = mncc_disconnect_ind -> raw_cause;

  psaCC_send_satevent( EVENT_CALL_DISC, cId , FAR_END, TRUE );

  pCtbNtry -> numRawCauseBytes = 0; /* Reset the cause value after sending the info to SAT */

  /* If call was held upon mncc_disconnect_ind it is cleared anyway */
  if (held_call EQ TRUE)
  {
    TRACE_EVENT ("Release a held call");
    cmhCC_CallDisconnected (cId);
    psaCC_ClearCall (cId);
  }
  else
  {
    switch( cmhCC_getcalltype(cId) )
    {
      case( VOICE_CALL ):
      {
        /*
         * if in-band tones are available and TCH is assigned, request to disconnect the call
         * GSM 04.08/5.4.4.1.1.1
         */
        /*
          TRACE_EVENT("psa_mncc_disconnect_ind(): --> VOICE CALL");
          if ((pCtbNtry -> inBndTns EQ TRUE) 
          AND (pCtbNtry -> CCBSstat EQ NO_VLD_CCBSS)
          AND (ccShrdPrm.TCHasg EQ TRUE)) 
          {
            cmhCC_DisconnectCall (cId);
          }
          else
          {
            cmhCC_CallDisconnected (cId);
          }
        */
         /* check conditions for redialling */
         if((pCtbNtry->curCmd NEQ AT_CMD_H) AND
            (pCtbNtry->curCmd NEQ AT_CMD_CHUP))
         {
           cmhCC_redialCheck(cId);
         }


        /*
         * for CCBS support the "Prolonged Clearing Procedure"
         * GSM 04.08/5.4.4.2.1
         */
        cmhCC_CallDisconnected (cId);

        if ((pCtbNtry->inBndTns EQ TRUE)                  /* 5.4.4.2.1.1 */
          AND (pCtbNtry->CCBSstat EQ NO_VLD_CCBSS))
        {
          if (ccShrdPrm.TCHasg NEQ TRUE)
          {
            TRACE_EVENT ("4.08/5.4.4.2.1.1 i)");
            psaCC_ClearCall (cId);
          }
          else
          {
            TRACE_EVENT ("4.08/5.4.4.2.1.1 ii)");
            psaCC_setSpeechMode();
          }
        }
        else if (pCtbNtry->CCBSstat EQ CCBSS_PSSBL)       /* 5.4.4.2.2.1 */
        {
          TRACE_EVENT ("4.08/5.4.4.2.2.1");
          psaCC_setSpeechMode();
          cmhCC_SndDiscRsn( cId );                        /* FIXME: to emmit BUSY, but this is not good here
                                                             since BUSY is final result code and will be
                                                             emitted on Release again !!!!! */
        }
        else if ((pCtbNtry->inBndTns NEQ TRUE)            /* 5.4.4.2.3.1 */
          AND (pCtbNtry->CCBSstat EQ NO_VLD_CCBSS))
        {
          TRACE_EVENT ("4.08/5.4.4.2.3.1");
          psaCC_ClearCall (cId);
        }
        else                                              /* 5.4.4.2.3.2 */
        {
          TRACE_EVENT ("4.08/5.4.4.2.3.2");
          psaCC_ClearCall (cId);
        }
        break;
      }
      default: /* all non voice calls */
      {
        /*
         * see cmh_cc.h  T_CC_CALL_TYPE for all other call types
         */
        TRACE_EVENT("psa_mncc_disconnect_ind(): --> DATA CALL");
        cmhCC_CallDisconnected (cId);
        psaCC_ClearCall (cId);
        break;
      }
    }
  } /* else */

  /* free the primitive buffer */
  PFREE (mncc_disconnect_ind);
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_alert_ind      |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_ALERT_IND primitive send by CC.
            this indicates that the called party is alerted.

*/

GLOBAL const void psa_mncc_alert_ind
                             ( T_MNCC_ALERT_IND *mncc_alert_ind )
{
  SHORT cId;                 /* holds call id */

  TRACE_FUNCTION ("psa_mncc_alert_ind()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_alert_ind -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_alert_ind);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  psaCC_ctb(cId)->alrtStat = AS_SND;
  psaCC_ctb(cId)->curCs = MNCC_CAUSE_NO_MS_CAUSE;

  /* check for progress descriptions */
  psaCC_chkPrgDesc ( cId, mncc_alert_ind -> progress_desc, MT_ALRT );

  /* check for TTY service */
  cmhCC_TTY_Control ( cId, TTY_START );
/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_alert_ind);
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_call_proceed_ind|
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_CALL_PROCEED_IND primitive send by CC.
            this indicates a call proceeding information for a call.

*/

GLOBAL const void psa_mncc_call_proceed_ind
                   ( T_MNCC_CALL_PROCEED_IND *mncc_call_proceed_ind )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_call_proceed_ind()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_call_proceed_ind -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_call_proceed_ind);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];
  pCtbNtry -> curCs = MNCC_CAUSE_NO_MS_CAUSE;

  memcpy( &(pCtbNtry->BC[0]),&(mncc_call_proceed_ind->bcpara),
          sizeof( T_bcpara) );
  memcpy( &(pCtbNtry->BC[1]),&(mncc_call_proceed_ind->bcpara2),
          sizeof( T_bcpara) );
  pCtbNtry -> rptInd = mncc_call_proceed_ind -> ri;

  /* check for progress descriptions */
  psaCC_chkPrgDesc ( cId, mncc_call_proceed_ind -> progress_desc, MT_PROC );

  /* check for TTY service */
  cmhCC_TTY_Control ( cId, TTY_START );
/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_call_proceed_ind);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_progress_ind   |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_PROGRESS_IND primitive send by CC.
            this indicates a progress description for a call.

*/

GLOBAL const void psa_mncc_progress_ind
                          ( T_MNCC_PROGRESS_IND *mncc_progress_ind )
{
  SHORT cId;                 /* holds call id */

  TRACE_FUNCTION ("psa_mncc_progress_ind()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_progress_ind -> ti );


  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_progress_ind);
    return;
  }
  psaCC_ctb(cId)->curCs = MNCC_CAUSE_NO_MS_CAUSE;

  /*
   * check for progress descriptions
   */
  psaCC_chkPrgDesc ( cId, mncc_progress_ind -> progress_desc, MT_PROGR );

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_progress_ind);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_hold_cnf       |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_HOLD_CNF primitive send by CC.
            this confirmates that a call is being held.

*/

GLOBAL const void psa_mncc_hold_cnf
                                ( T_MNCC_HOLD_CNF *mncc_hold_cnf )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_hold_cnf()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_hold_cnf -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_hold_cnf);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];

  switch( mncc_hold_cnf -> cause )
  {
    case( MNCC_CAUSE_HOLD_SUCCESS ):    /* successful, call held */
    case( MNCC_CAUSE_SUCCESS ):
    case( MNCC_CAUSE_NO_MS_CAUSE ):

      pCtbNtry -> calStat = CS_HLD;

      psaCC_setSpeechMode ();

      /* check for TTY service */
      cmhCC_TTY_Control ( cId, TTY_PAUSE );
      break;

    default:    /* unsuccessful, call state unchanged */

      ccShrdPrm.cIdFail   = cId;
      pCtbNtry -> calStat = CS_ACT;
      break;
  }

  pCtbNtry -> rslt = mncc_hold_cnf -> cause;

  cmhCC_CallHeld(cId);

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_hold_cnf);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_retrieve_cnf   |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_RETRIEVE_CNF primitive send by CC.
            this confirmates that a call is retrieved.

*/

GLOBAL const void psa_mncc_retrieve_cnf
                           ( T_MNCC_RETRIEVE_CNF *mncc_retrieve_cnf )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_retrieve_cnf()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_retrieve_cnf -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_retrieve_cnf);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];

  switch( mncc_retrieve_cnf -> cause )
  {
    case( MNCC_CAUSE_RETRIEVE_SUCCESS ):    /* successful, call active */

      pCtbNtry -> calStat = CS_ACT;

      /* switch on vocoder */
      psaCC_setSpeechMode ();

      /* check for TTY service */
      cmhCC_TTY_Control ( cId, TTY_START );
      break;

    default:    /* unsuccessful, call state unchanged */

      ccShrdPrm.cIdFail   = cId;
      pCtbNtry -> calStat = CS_HLD;
      break;
  }

  pCtbNtry -> rslt = mncc_retrieve_cnf -> cause;

  cmhCC_CallRetrieved (cId);

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_retrieve_cnf);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_sync_ind       |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_SYNC_IND primitive send by CC.
            this indicates the change of the channel mode.

*/

GLOBAL const void psa_mncc_sync_ind( T_MNCC_SYNC_IND *mncc_sync_ind )
{
  SHORT cId = 0;                /* holds call id */

  TRACE_FUNCTION ("psa_mncc_sync_ind()");

  /*
  cause         cause 4.6   UBYTE
  channel mode  chm     4.14  STRUCT

  ch_type 0 CH_SDCCH  SDCCH channel
            1 CH_TCH_F  TCH Fullrate
            2 CH_TCH_H  TCH Halfrate

  ch_mode 0 CHM_SIG_ONLY  signalling only
            1 CHM_SPEECH      speech full rate or half rate version 1
            33  CHM_SPEECH_V2 speech full rate or half rate version 2
            65  CHM_SPEECH_V3 speech full rate or half rate version 3
            3 CHM_DATA_9_6  data 9.6 kBit/s
            11  CHM_DATA_4_8  data 4.8 kBit/s
            19  CHM_DATA_2_4  data 2.4 kBit/s
            15  CHM_DATA_14_4 data 14.4 kBit/s
  */

  TRACE_EVENT_P4("MNCC_SYNC_IND ti: %d, cause: %d, ch_type: %d, ch_mode: %d",
                 mncc_sync_ind -> ti,
                 mncc_sync_ind -> cause,
                 mncc_sync_ind -> chm.ch_type,
                 mncc_sync_ind -> chm.ch_mode);

  /* update shared parameter */
  ccShrdPrm.syncCs = mncc_sync_ind -> cause;
#ifdef FF_EM_MODE
  em_relcs = mncc_sync_ind -> cause;
#endif /* FF_EM_MODE */

  /* Inform Advice of Charge Module */
  switch (mncc_sync_ind->cause)
  {
    case MNCC_CAUSE_REEST_STARTED:
      for( cId = 0; cId < MAX_CALL_NR; cId++ )
        aoc_info (cId, AOC_SUSPEND_AOC);
      break;
    case MNCC_CAUSE_REEST_FINISHED:
      ccShrdPrm.aocRsmpPend = 1;
      break;
  }

  /* switch channel mode */
  if( mncc_sync_ind -> chm.ch_mode NEQ NOT_PRESENT_8BIT )
  {
    ccShrdPrm.chMod   = mncc_sync_ind -> chm.ch_mode;
    ccShrdPrm.chType  = mncc_sync_ind -> chm.ch_type;
    ccShrdPrm.TCHasg  = TRUE;
  }
  
    if ( ccShrdPrm.aocRsmpPend AND
          (ccShrdPrm.chMod EQ CHM_SPEECH)    OR
          (ccShrdPrm.chMod EQ CHM_SPEECH_V2) OR
          (ccShrdPrm.chMod EQ CHM_SPEECH_V3)    )
    {
      ccShrdPrm.aocRsmpPend = 0;
      for( cId = 0; cId < MAX_CALL_NR; cId++ )
        aoc_info (cId, AOC_RESUME_AOC);
    }

if( mncc_sync_ind -> chm.ch_mode NEQ NOT_PRESENT_8BIT )
  {
    /* service a pending alert */
    for( cId = 0; cId < MAX_CALL_NR; cId++ )
    {
      if (ccShrdPrm.ctb[cId] NEQ NULL)
      {
        psaCC_ctb(cId)->curCs = mncc_sync_ind -> cause;

        if( psaCC_ctb(cId)->alrtStat EQ AS_PND AND
            psaCC_ctb(cId)->calStat  EQ CS_ACT_REQ )
        {
          {
            /* indicate alerting to network */
            PALLOC (mncc_alert_req, MNCC_ALERT_REQ);
            mncc_alert_req -> ti    = psaCC_ctb(cId)->ti;
            PSENDX (CC, mncc_alert_req);
            psaCC_ctb(cId)->alrtStat = AS_SND;
          }
          cmhCC_IncomingCall (cId); /* indicate an incoming call */
        }
        if (psaCC_ctb(cId)->calStat NEQ CS_HLD AND
            psaCC_ctb(cId)->calStat NEQ CS_IDL)
        {
          /* check for TTY service */
          cmhCC_TTY_Control ( cId, TTY_TCH );
        }
      }
    }
  }
psaCC_setSpeechMode ();

  /* Remember cause for Call Reestablishment*/

  if (mncc_sync_ind -> cause EQ MNCC_CAUSE_REEST_FINISHED 
    OR mncc_sync_ind -> cause EQ MNCC_CAUSE_REEST_STARTED)
  {
    for( cId = 0; cId < MAX_CALL_NR; cId++ )
    {
      if (ccShrdPrm.ctb[cId] NEQ NULL)
      {
        psaCC_ctb(cId)->curCs = mncc_sync_ind -> cause;
      }
    }
   }

  cId = psaCC_ctbFindTi( mncc_sync_ind -> ti );

  /* For channel synchronization events the cId needs not to be valid here */
  cmhCC_Synchronized( cId );


  /* free the primitive buffer */
  PFREE (mncc_sync_ind);
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_user_ind       |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_USER_IND primitive send by CC.
            this indicates the receiving of user data.
*/

GLOBAL const void psa_mncc_user_ind( T_MNCC_USER_IND *mncc_user_ind )
{
  TRACE_FUNCTION ("psa_mncc_user_ind()");

  PFREE (mncc_user_ind);
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_start_dtmf_cnf |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_START_DTMF_CNF primitive send by CC.
            this is a confirmation for the sent DTMF tones.

*/

GLOBAL const void psa_mncc_start_dtmf_cnf
                       ( T_MNCC_START_DTMF_CNF *mncc_start_dtmf_cnf )
{
  SHORT cId;                 /* holds call id */

  TRACE_FUNCTION ("psa_mncc_start_dtmf_cnf()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_start_dtmf_cnf -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_start_dtmf_cnf);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  psaCC_ctb(cId)->nrmCs = mncc_start_dtmf_cnf -> cause;
  if ((mncc_start_dtmf_cnf->cause EQ MNCC_CAUSE_DTMF_STOP_SUCCESS) AND
        (mncc_start_dtmf_cnf->dtmf_mod EQ DTMF_MOD_MAN_STOP))
  {
    /* Reset the current dtmf digit */
    ccShrdPrm.dtmf.cur = 0;
  }
#ifdef FF_EM_MODE
  em_relcs = mncc_start_dtmf_cnf -> cause;
#endif /* FF_EM_MODE */

  psaCC_DTMFSent( cId );

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_start_dtmf_cnf);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_modify_ind     |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_MODIFY_IND primitive send by CC.
            this indicates a mobile terminated in-call modification.

*/

GLOBAL const void psa_mncc_modify_ind
                               ( T_MNCC_MODIFY_IND *mncc_modify_ind )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_modify_ind()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_modify_ind -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_modify_ind);
    return;
  }

  /* check for TTY service */
  cmhCC_TTY_Control ( cId, TTY_PAUSE );

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];

  pCtbNtry -> curBC = (pCtbNtry -> curBC EQ 0)?1:0;
  pCtbNtry -> rslt  = MNCC_CAUSE_MODIFY_SUCCESS; /* SBK-02-07-30: possibly to be revised as strictly speaking ACI is orignating entity */

  cmhCC_CallModified (cId);

  /* check for TTY service */
  cmhCC_TTY_Control ( cId, TTY_START );

  psaCC_StopDTMF ( cId );
/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_modify_ind);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_modify_cnf     |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_MODIFY_CNF primitive send by CC.
            this indicates the result for a mobile originated in-call
            modification.

*/

GLOBAL const void psa_mncc_modify_cnf
                               ( T_MNCC_MODIFY_CNF *mncc_modify_cnf )
{
  SHORT cId;                 /* holds call id */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_modify_cnf()");

/*
 *-------------------------------------------------------------------
 * find call in call table
 *-------------------------------------------------------------------
 */
  cId = psaCC_ctbFindTi( mncc_modify_cnf -> ti );

  if( cId < 0 )
  {
   /*
    * ignore primitive, due to not found transaction identifier.
    */
    TRACE_EVENT ("primitive rejected due to unused ti");
    PFREE(mncc_modify_cnf);
    return;
  }

/*
 *-------------------------------------------------------------------
 * update shared parameter and notify ACI
 *-------------------------------------------------------------------
 */
  pCtbNtry = ccShrdPrm.ctb[cId];

  pCtbNtry -> rslt = mncc_modify_cnf -> cause;

  switch( mncc_modify_cnf -> cause )
  {
    case( MNCC_CAUSE_MODIFY_SUCCESS ):    /* successful modification */

      pCtbNtry -> curBC = (pCtbNtry -> curBC EQ 0)?1:0;
      break;

    default:    /* unsuccessful modification */

      ccShrdPrm.cIdFail = cId;
      break;
  }
  psaCC_ctb(cId)->calStat = CS_ACT;

  cmhCC_CallModified (cId);

  /* check for TTY service */
  cmhCC_TTY_Control ( cId, TTY_START );

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_modify_cnf);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_bearer_cap_cnf |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_BEARER_CAP_CNF primitive send by CC.
            this is the result of the requested bearer coding/decoding.

*/

GLOBAL const void psa_mncc_bearer_cap_cnf
                         ( T_MNCC_BEARER_CAP_CNF *mncc_bearer_cap_cnf )
{

  TRACE_FUNCTION ("psa_mncc_bearer_cap_cnf()");

/*
 *-------------------------------------------------------------------
 * determine request id
 *-------------------------------------------------------------------
 */
  switch( mncc_bearer_cap_cnf -> req_id )
  {

#ifdef SIM_TOOLKIT

  case( BCRI_SAT ):

    switch( mncc_bearer_cap_cnf -> bc_mod )
    {
      case( BC_MOD_CODE ):

        cmhSAT_ResCapCode ( mncc_bearer_cap_cnf -> cause,
                            &mncc_bearer_cap_cnf -> bcconf );
        break;

      case( BC_MOD_DECODE ):

        cmhSAT_ResCapDecode ( mncc_bearer_cap_cnf -> cause,
                              &mncc_bearer_cap_cnf -> bcpara );
        break;
    }
    break;

#endif
  }

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_bearer_cap_cnf);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_prompt_ind     |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_PROMPT_IND primitive send by CC.
            this requests a transaction identifier for a CCBS recall.

*/

GLOBAL const void psa_mncc_prompt_ind
                         ( T_MNCC_PROMPT_IND *mncc_prompt_ind )
{
  SHORT ti;

  TRACE_FUNCTION ("psa_mncc_prompt_ind()");

/*
 *-------------------------------------------------------------------
 * allocate transaction identifier
 *-------------------------------------------------------------------
 */
  ti = psaCC_getMOCTi( -1 );

  if( ti NEQ -1 )
  {
    PALLOC (mncc_prompt_rsp, MNCC_PROMPT_RSP);
    mncc_prompt_rsp -> ti    = (UBYTE)ti;
    PSENDX (CC, mncc_prompt_rsp);
  }
  else
  {
    PALLOC (mncc_prompt_rej, MNCC_PROMPT_REJ);
    PSENDX (CC, mncc_prompt_rej);
  }

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_prompt_ind);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_recall_ind     |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_RECALL_IND primitive send by CC.
            this indicates a recall attempt from the network in case
            of CCBS.

*/

GLOBAL const void psa_mncc_recall_ind
                         ( T_MNCC_RECALL_IND *mncc_recall_ind )
{
  SHORT cId;                 /* holds call table identifier */
  T_CC_CALL_TBL * pCtbNtry;  /* holds pointer to call table entry */

  TRACE_FUNCTION ("psa_mncc_recall_ind()");

/*
 *-------------------------------------------------------------------
 * check for K.O. criteria
 *-------------------------------------------------------------------
 */
  if( aoc_check_moc() EQ FALSE )
  {
    PALLOC (mncc_reject_req, MNCC_REJECT_REQ);

    mncc_reject_req -> ti    = mncc_recall_ind -> ti;
    mncc_reject_req -> cause = MNCC_CAUSE_ACM_MAX;

    PSENDX (CC, mncc_reject_req);
  }

  else if((cId = psaCC_ctbNewEntry()) < 0 )
  {
    PALLOC (mncc_reject_req, MNCC_REJECT_REQ);

    mncc_reject_req -> ti    = mncc_recall_ind -> ti;
    mncc_reject_req -> cause = MNCC_CAUSE_USER_BUSY;

    PSENDX (CC, mncc_reject_req);
  }

/*
 *-------------------------------------------------------------------
 * insert recall parameters into call table entry
 *-------------------------------------------------------------------
 */
  else
  {
    pCtbNtry = ccShrdPrm.ctb[cId];

    pCtbNtry -> ti         = mncc_recall_ind -> ti;
    pCtbNtry -> rptInd     = mncc_recall_ind -> ri;

    /* 
     * Assign called party 
     */
    pCtbNtry -> cldPty.ton = mncc_recall_ind -> called_party.ton;
    pCtbNtry -> cldPty.npi = mncc_recall_ind -> called_party.npi;
    pCtbNtry -> cldPty.c_called_num = 
      mncc_recall_ind -> called_party.c_called_num;
    if (pCtbNtry -> cldPty.called_num NEQ NULL)
    {
      ACI_MFREE (pCtbNtry -> cldPty.called_num);
      pCtbNtry -> cldPty.called_num = NULL;    
    }
    if (pCtbNtry -> cldPty.c_called_num NEQ 0)
    {
      ACI_MALLOC (pCtbNtry -> cldPty.called_num, 
                  pCtbNtry -> cldPty.c_called_num);
      memcpy (pCtbNtry -> cldPty.called_num, 
              mncc_recall_ind -> called_party.called_num,
              mncc_recall_ind -> called_party.c_called_num);
    }

    /* 
     * Assign called party subaddress
     */    
    pCtbNtry -> cldPtySub  = mncc_recall_ind -> called_party_sub;

    /*
     * Assign bearer caps
     */    
    memcpy( &(pCtbNtry->BC[0]),&(mncc_recall_ind->bcpara),
            sizeof( T_bcpara) );
    memcpy( &(pCtbNtry->BC[1]),&(mncc_recall_ind->bcpara2),
            sizeof( T_bcpara) );

    psaCC_phbSrchNum( cId, CT_NI_MOC );

    pCtbNtry -> calStat = CS_ACT_REQ;
    pCtbNtry -> calType = CT_NI_MOC;

    pCtbNtry -> prio  = PRIO_NORM_CALL;
    pCtbNtry -> curBC = 0;

  }

/*
 *-------------------------------------------------------------------
 * free the primitive buffer
 *-------------------------------------------------------------------
 */
  PFREE (mncc_recall_ind);

}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_status_ind     |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_STATUS_IND primitive sent by CC.
            This indicates that a STATUS ENQUIRY message has been
            received by CC, the network awaits a CC STATUS message.
            Used to ensure that the auxiliary states between ACI and
            CC were synchronized before the STATUS message is sent.

*/

GLOBAL const void psa_mncc_status_ind (T_MNCC_STATUS_IND *mncc_status_ind)
{
  UBYTE ti;

  TRACE_FUNCTION ("psa_mncc_status_ind()");

  ti = mncc_status_ind->ti;

  {
    PREUSE (mncc_status_ind, mncc_status_res, MNCC_STATUS_RES);
    mncc_status_res->ti = ti;
    PSENDX (CC, mncc_status_res);
  }
}

/*
+-------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCP                 |
|                                 ROUTINE : psa_mncc_facility_ind   |
+-------------------------------------------------------------------+

  PURPOSE : processes the MNCC_FACILITY_IND primitive send by CC.
            this indicates the receiving of a facility information
            element. Handles multiple components in the facility info.

*/

GLOBAL const void psa_mncc_facility_ind(T_MNCC_FACILITY_IND * mncc_facility_ind)
{
  UBYTE  tlen = 0;
  USHORT offset_comp = 0, total_len = mncc_facility_ind->fac_inf.l_fac/8;
  UBYTE len_comp = 0;
  UBYTE *tPtrfac = mncc_facility_ind->fac_inf.fac;

  TRACE_FUNCTION ("psa_mncc_facility_ind()");

  if (tPtrfac[1] > 0x7F)/* For the case, when length is coded in non-standard way (0x80, 0x81, 0x82) we will be able to process only one component */
  {
     psaCC_ProcessCmp((T_MNCC_FACILITY_IND *)mncc_facility_ind);
     return;
  }

  offset_comp = mncc_facility_ind->fac_inf.o_fac;
  len_comp = tlen = tPtrfac[1] + 2;

  for ( ; total_len >= len_comp; len_comp+=tlen)
  {
    if ((*tPtrfac EQ 0xA1) OR
        (*tPtrfac EQ 0xA2) OR
        (*tPtrfac EQ 0xA3) OR
        (*tPtrfac EQ 0xA4))
    {
      PALLOC(new_mncc_facility_ind, MNCC_FACILITY_IND);

      new_mncc_facility_ind->ti = mncc_facility_ind->ti;
      new_mncc_facility_ind->fac_context = mncc_facility_ind->fac_context;
      new_mncc_facility_ind->fac_inf.l_fac = tlen * 8;
      new_mncc_facility_ind->fac_inf.o_fac = offset_comp;
      memcpy(new_mncc_facility_ind->fac_inf.fac, tPtrfac, tlen);

      psaCC_ProcessCmp((T_MNCC_FACILITY_IND *)new_mncc_facility_ind);

      tPtrfac = tPtrfac + tlen;
      tlen = tPtrfac[1] + 2;
      offset_comp = 0;
    }
  }
  
  PFREE(mncc_facility_ind);
}

/*==== EOF =========================================================*/