diff src/aci2/aci/psa_ccs.c @ 3:93999a60b835

src/aci2, src/condat2: import of g23m/condat source pieces from TCS211
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 26 Sep 2016 00:29:36 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aci2/aci/psa_ccs.c	Mon Sep 26 00:29:36 2016 +0000
@@ -0,0 +1,1083 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GSM-PS (6147)
+|  Modul   :  PSA_CCS
++----------------------------------------------------------------------------- 
+|  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 signalling functions of the 
+|             protocol stack adapter for call control.
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifndef PSA_CCS_C
+#define PSA_CCS_C
+#endif
+
+#include "aci_all.h"
+
+/*==== INCLUDES ===================================================*/
+#include "ccdapi.h"
+
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+#include "aci_cmd.h"
+#include "aci.h"
+#include "psa.h"
+#include "psa_cc.h"
+#include "psa_ss.h"
+#include "aoc.h"
+#include "l4_tim.h"
+
+#if !defined (MFW)
+#include "aci_io.h"
+#endif
+
+#include "aci_fd.h"
+#include "cmh.h"
+
+#include "cmh_cc.h"
+#include "psa_cc.h"
+
+#include "wap_aci.h"
+
+/*==== CONSTANTS ==================================================*/
+
+/*==== TYPES ======================================================*/
+
+/*==== IMPORT =====================================================*/
+
+/*==== VARIABLES ==================================================*/
+
+/*==== FUNCTIONS ==================================================*/
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : PSA_CCS                      |
+|                            ROUTINE : psaCC_NewCall                |
++-------------------------------------------------------------------+
+
+  PURPOSE : setup a new call
+
+*/
+
+GLOBAL SHORT psaCC_NewCall ( SHORT cId )
+{
+  T_CC_CALL_TBL *pCtbNtry = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION ("psaCC_NewCall()");
+
+  if (pCtbNtry EQ NULL)
+    return -1;
+
+  /* get a valid ti for a MOC, otherwise return */
+  if (psaCC_ctb(cId)->calType NEQ CT_NI_MOC )
+  {
+    if( psaCC_getMOCTi( cId ) < 0 ) return ( -1 );
+  }
+
+#if defined (FF_WAP) || defined (FF_GPF_TCPIP) || defined (FF_SAT_E)
+  /* if this call is a WAP call then set wapId to the current Call Id */
+  if (Wap_Call EQ TRUE)
+  {
+    wapId = cId;
+  }
+#endif /* defined(WAP) OR defined(FF_GPF_TCPIP) */
+
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  {
+    PALLOC (mncc_setup_req, MNCC_SETUP_REQ);
+
+    /*
+     * fill in primitive parameter: setup request
+     */
+    mncc_setup_req -> ti               = pCtbNtry -> ti;
+    mncc_setup_req -> prio             = pCtbNtry -> prio;
+    mncc_setup_req -> ri               = pCtbNtry -> rptInd;
+
+    mncc_setup_req->called_party.ton          = pCtbNtry->cldPty.ton;
+    mncc_setup_req->called_party.npi          = pCtbNtry->cldPty.npi;
+    mncc_setup_req->called_party.c_called_num = pCtbNtry->cldPty.c_called_num;
+    memcpy (mncc_setup_req->called_party.called_num, 
+            pCtbNtry->cldPty.called_num,
+            pCtbNtry->cldPty.c_called_num);
+
+    mncc_setup_req -> called_party_sub = pCtbNtry -> cldPtySub;
+    mncc_setup_req -> clir_sup         = pCtbNtry -> CLIRsup;
+    memcpy( &(mncc_setup_req->bcpara),&(pCtbNtry->BC[0]), 
+          sizeof( T_bcpara) ); 
+    memcpy( &(mncc_setup_req->bcpara2),&(pCtbNtry->BC[1]), 
+          sizeof( T_bcpara) ); 
+
+    /*
+     * fill in CUG info facility
+     */
+    if( !(pCtbNtry -> CUGidx EQ NOT_PRESENT_8BIT AND
+          pCtbNtry -> CUGprf EQ FALSE AND
+          pCtbNtry -> OAsup  EQ FALSE    ))
+    {
+      CCD_START;
+      psaCC_asmCUGInfo( cId );
+
+      {
+        UBYTE ccdRet;
+
+        MCAST( com, COMPONENT );
+
+        memset( com, 0, sizeof( T_COMPONENT ));
+
+        com -> v_inv_comp = TRUE;
+        com -> inv_comp.v_inv_id  = TRUE;
+        com -> inv_comp.inv_id    = pCtbNtry -> iId 
+                                  = ccShrdPrm.iIdNxt++;
+        com -> inv_comp.v_op_code = TRUE;
+        com -> inv_comp.op_code   = pCtbNtry -> opCode
+                                  = ssFIECodeBuf.buf[0];
+        com -> inv_comp.v_params  = TRUE;
+        com -> inv_comp.params.l_params = ssFIECodeBuf.l_buf-8;
+        com -> inv_comp.params.o_params = 8;
+        memcpy( com -> inv_comp.params.b_params, 
+                ssFIECodeBuf.buf, ssFIECodeBuf.l_buf );
+
+        mncc_setup_req -> fac_inf.l_fac = FACILITY_LEN<<3;
+        mncc_setup_req -> fac_inf.o_fac = 0;
+        ccdRet = ccd_codeMsg (CCDENT_FAC,
+                              UPLINK,
+                              (T_MSGBUF *) &mncc_setup_req -> fac_inf,
+                              (UBYTE    *) _decodedMsg,
+                              COMPONENT);
+
+        if( ccdRet NEQ ccdOK )
+        {
+          TRACE_EVENT_P1("CCD Coding Error: %d",ccdRet ); 
+          memset( &mncc_setup_req -> fac_inf, 0, sizeof( T_fac_inf));
+        }
+      }
+      CCD_END;
+    }
+    else
+    {
+      memset( &mncc_setup_req -> fac_inf, 0, sizeof( T_fac_inf));
+    }
+
+    if(pCtbNtry -> calType NEQ CT_MOC_RDL)
+    {
+      pCtbNtry -> calType = CT_MOC;
+    }
+    pCtbNtry -> curBC   = 0;
+
+    PSENDX (CC, mncc_setup_req);
+
+    /*
+     * update call status
+     */
+    pCtbNtry -> calStat = CS_ACT_REQ;
+  }
+#ifdef FF_TTY
+  /* TTY notification */
+  cmhCC_notifyTTY (((pCtbNtry->BC[0].bearer_serv EQ BEARER_SERV_SPEECH_CTM OR
+                     pCtbNtry->BC[0].bearer_serv EQ BEARER_SERV_AUX_SPEECH_CTM)?
+                    CTTY_NEG_Request: CTTY_NEG_None),
+                   CTTY_TRX_Unknown);
+#endif /* FF_TTY */
+  if(cmhCC_atdsendok ( cId ))
+  {
+    R_AT( RAT_OK, pCtbNtry->curSrc ) ( pCtbNtry->curCmd );
+  }
+
+  /* start call time measurement */
+  aoc_info (cId, AOC_START_TIME);
+
+  /* Disable voice path in case this is first call */
+  psaCC_setSpeechMode ();
+
+  return 0;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_AcceptCall        |
++-------------------------------------------------------------------+
+  PURPOSE : In addition to sending the setup response for an MT call
+            this function enables the vocoder if the call is a voice
+            call
+*/
+
+GLOBAL void psaCC_AcceptCall ( SHORT cId )
+{
+  T_CC_CALL_TBL * pCtbNtry;     /* holds pointer to call table entry */
+
+  TRACE_FUNCTION ("psaCC_AcceptCall()");
+
+  /* update call status and attach the user if not done previously */
+  pCtbNtry = ccShrdPrm.ctb[cId];
+  pCtbNtry -> calStat = CS_CPL_REQ;
+  psaCC_setSpeechMode();
+  
+  /* create and send primitive */
+  {
+    PALLOC (mncc_setup_res, MNCC_SETUP_RES);
+    mncc_setup_res -> ti = pCtbNtry -> ti;
+    PSENDX (CC, mncc_setup_res);
+    psaCC_send_satevent( EVENT_CALL_CONN, cId, NEAR_END, FALSE );
+  }
+
+  /* start call time measurement */
+  aoc_info (cId, AOC_START_TIME);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_ClearCall         |
++-------------------------------------------------------------------+
+
+  PURPOSE : clear a call
+*/
+
+GLOBAL void psaCC_ClearCall ( SHORT cId )
+{
+  T_CC_CALL_TBL *pCtbNtry = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION ("psaCC_ClearCall()");
+
+  if (!psaCC_ctbIsValid (cId))
+    return; /* Ensure we are not dereferencing NULL */
+
+  psaCC_StopDTMF ( cId );
+
+  /* inform advice of charge module */
+  aoc_info (cId, AOC_STOP_TIME);
+
+  /*
+   *-----------------------------------------------------------------
+   * relase call if in disconnect request state
+   *-----------------------------------------------------------------
+   */
+  if( pCtbNtry -> calStat EQ CS_DSC_REQ )
+  {
+    PALLOC (mncc_release_req, MNCC_RELEASE_REQ);
+
+    /* fill in primitive parameter: release request */
+    mncc_release_req -> ti    = pCtbNtry -> ti;
+    mncc_release_req -> cause = pCtbNtry -> nrmCs;
+      
+    /* fill in CCBS request facility */
+    if( pCtbNtry -> CCBSstat EQ CCBSS_REQ )
+    {
+      CCD_START;
+      {
+        psaCC_asmCCBSReq( cId );
+        psaCC_asmComponent( cId );
+      }
+      CCD_END;
+      
+      mncc_release_req -> fac_inf.l_fac = ssFIECodeBuf.l_buf;
+      mncc_release_req -> fac_inf.o_fac = 0;
+      memcpy (mncc_release_req->fac_inf.fac, 
+              ssFIECodeBuf.buf + (ssFIECodeBuf.o_buf >> 3),
+              ssFIECodeBuf.l_buf >> 3);
+
+      mncc_release_req -> ss_version = SS_VERSION_3;
+    }
+    else
+    {
+      memset( &mncc_release_req -> fac_inf, 0, sizeof( T_fac_inf));
+      mncc_release_req -> ss_version = SS_VER_NOT_PRES;
+    }
+
+    PSENDX (CC, mncc_release_req);
+
+    psaCC_send_satevent( EVENT_CALL_DISC, cId, NEAR_END, TRUE );
+  }
+
+  /*
+   *-----------------------------------------------------------------
+   * relase call if in activate request state, network initiated
+   *-----------------------------------------------------------------
+   */
+  else if( pCtbNtry -> calStat EQ CS_ACT_REQ AND
+           pCtbNtry -> calType EQ CT_NI_MOC      )
+  {
+    PALLOC (mncc_reject_req, MNCC_REJECT_REQ);
+
+    /* fill in primitive parameter: release request */
+    mncc_reject_req -> ti    = pCtbNtry -> ti;
+    mncc_reject_req -> cause = pCtbNtry -> nrmCs;
+
+    PSENDX (CC, mncc_reject_req);
+
+    /* free call table entry */
+    psaCC_retMOCTi( pCtbNtry -> ti );
+
+    psaCC_FreeCtbNtry (cId);
+  }
+      
+  /*
+   *-----------------------------------------------------------------
+   * disconnect all other calls
+   *-----------------------------------------------------------------
+   */
+  else
+  {
+    PALLOC (disc_req, MNCC_DISCONNECT_REQ); /* T_MNCC_DISCONNECT_REQ */
+    disc_req -> ti    = pCtbNtry -> ti;
+    disc_req -> cause = pCtbNtry -> nrmCs;
+    if (pCtbNtry -> curCmd EQ AT_CMD_CTFR)
+    {
+      /* We expect here an already built facility in ssFIECodeBuf */
+      disc_req -> fac_inf.l_fac = ssFIECodeBuf.l_buf;
+      disc_req -> fac_inf.o_fac = 0;
+      memcpy (disc_req->fac_inf.fac, 
+              ssFIECodeBuf.buf, 
+              ssFIECodeBuf.l_buf >> 3);
+      disc_req -> ss_version = SS_VERSION_2;
+    }
+    else
+    {
+      disc_req -> fac_inf.l_fac = 0;
+      disc_req -> ss_version    = SS_VER_NOT_PRES;
+    }
+    PSENDX (CC, disc_req);
+
+    /* update call status */
+    pCtbNtry -> calStat = CS_DSC_REQ;
+
+    /* monitoring for SAT */
+    psaCC_send_satevent( EVENT_CALL_DISC, cId , NEAR_END, TRUE );
+  }
+
+  /* Switch off audio path after user action (e.g. hangup) */
+/* clb this breaks ACI056 (among others..) necessary ??  pCtbNtry -> inBndTns = FALSE; */
+  psaCC_setSpeechMode ();
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_HoldCall          |
++-------------------------------------------------------------------+
+
+  PURPOSE : put a call into hold state
+
+*/
+
+GLOBAL void psaCC_HoldCall ( SHORT cId )
+{
+  T_CC_CALL_TBL *pCtbNtry = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION ("psaCC_HoldCall()");
+
+  if (pCtbNtry EQ NULL)
+    return; /* Ensure not to dereference NULL */
+
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  psaCC_StopDTMF ( cId );
+
+  {
+    PALLOC (mncc_hold_req, MNCC_HOLD_REQ);
+
+    /*
+     * fill in primitive parameter: hold request
+     */
+
+    mncc_hold_req -> ti = pCtbNtry -> ti;
+      
+    PSENDX (CC, mncc_hold_req);
+
+    /* update call status */
+    pCtbNtry -> calStat = CS_HLD_REQ;
+
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_RetrieveCall      |
++-------------------------------------------------------------------+
+
+  PURPOSE : retrieve a held call
+
+*/
+
+GLOBAL void psaCC_RetrieveCall ( SHORT cId )
+{
+  T_CC_CALL_TBL *pCtbNtry = ccShrdPrm.ctb[cId];
+
+  TRACE_FUNCTION ("psaCC_RetrieveCall()");
+
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  {
+    PALLOC (mncc_retrieve_req, MNCC_RETRIEVE_REQ);
+
+    /*
+     * fill in primitive parameter: retrieve request
+     */
+
+    mncc_retrieve_req -> ti = pCtbNtry -> ti;
+      
+    PSENDX (CC, mncc_retrieve_req);
+
+    /*
+     * update call status   ???
+     */
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_ModifyCall        |
++-------------------------------------------------------------------+
+
+  PURPOSE : modify an active call 
+
+*/
+
+GLOBAL SHORT psaCC_ModifyCall ( SHORT cId )
+{
+  T_CC_CALL_TBL *pCtbNtry = ccShrdPrm.ctb[cId];
+  UBYTE nomBC;                  /* holds nominal bearer capabilities */
+
+  TRACE_FUNCTION ("psaCC_ModifyCall()");
+
+  if (pCtbNtry EQ NULL)
+    return -1;
+
+/*
+ *-------------------------------------------------------------------
+ * check if call is in a active state
+ *-------------------------------------------------------------------
+ */
+ if(
+     (pCtbNtry -> calStat NEQ CS_ACT)     AND
+     (pCtbNtry -> calStat NEQ CS_ACT_REQ)
+   )
+   return( -1 );
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  psaCC_StopDTMF ( cId );
+  {
+    PALLOC (mncc_modify_req, MNCC_MODIFY_REQ);
+
+    /*
+     * fill in primitive parameter: modify request
+     */
+    nomBC = (pCtbNtry -> curBC)?0:1;
+
+    switch( pCtbNtry -> BC[nomBC].bearer_serv )
+    {
+    case( BEARER_SERV_AUX_SPEECH    ):
+    case( BEARER_SERV_SPEECH        ):
+    case( BEARER_SERV_AUX_SPEECH_CTM):
+    case( BEARER_SERV_SPEECH_CTM    ):
+      mncc_modify_req -> serv = SERV_SPEECH;
+      break;
+
+    case( BEARER_SERV_FAX           ):
+    case( BEARER_SERV_ASYNC         ):
+    case( BEARER_SERV_SYNC          ):
+    case( BEARER_SERV_PAD_ACCESS    ):
+    case( BEARER_SERV_PACKET_ACCESS ):
+      mncc_modify_req -> serv = SERV_DATA;
+
+      /* check for TTY service */
+      cmhCC_TTY_Control ( cId, TTY_PAUSE );
+      break;
+
+    default:
+      mncc_modify_req -> serv = SERV_NOT_PRES;
+    }
+    mncc_modify_req ->   ti = pCtbNtry -> ti;
+
+    PSENDX (CC, mncc_modify_req);
+
+    /*
+     * update call status
+     */
+    pCtbNtry -> calStat = CS_MDF_REQ;
+  }
+  return 0;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_SendDTMF          |
++-------------------------------------------------------------------+
+
+  PURPOSE : send DTMF tones
+
+*/
+
+GLOBAL SHORT psaCC_SendDTMF ( SHORT cId,
+                              UBYTE digit,
+                              UBYTE mode )
+{
+
+  TRACE_FUNCTION ("psaCC_SendDTMF()");
+
+  if (ccShrdPrm.ctb[cId] EQ NULL)
+    return -1; /* Ensure not to dereference NULL */
+
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  {
+    PALLOC (mncc_start_dtmf_req, MNCC_START_DTMF_REQ);
+
+    /*
+     * fill in primitive parameter: DTMF tone request
+     */
+
+    mncc_start_dtmf_req -> ti       = psaCC_ctb(cId)->ti;
+    mncc_start_dtmf_req -> key      = digit;
+    mncc_start_dtmf_req -> dtmf_mod = mode;
+      
+    PSENDX (CC, mncc_start_dtmf_req);
+  }
+
+  return 0;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_Config            |
++-------------------------------------------------------------------+
+  PURPOSE : configure CC entity
+*/
+
+GLOBAL void psaCC_Config ( void )
+{
+  T_bcpara *mtcBC;
+
+  TRACE_FUNCTION ("psaCC_Config()");
+
+  /* create and send primitive */
+  {
+    PALLOC (mncc_configure_req, MNCC_CONFIGURE_REQ);
+
+    /* fill in primitive parameter: configure request */
+    memset(&(mncc_configure_req -> called_party_sub), 0,
+            sizeof(T_called_party_sub));
+
+    /* MTC bearer caps */
+    mtcBC = &mncc_configure_req -> bcpara;
+    mtcBC->rate = cmhCC_SelRate( ccShrdPrm.CBSTspeed );
+
+    if( ccShrdPrm.snsMode EQ CSNS_MOD_Fax      OR
+        ccShrdPrm.snsMode EQ CSNS_MOD_VAFVoice OR
+        ccShrdPrm.snsMode EQ CSNS_MOD_VAFFax )
+    {
+      mtcBC->bearer_serv = BEARER_SERV_FAX;
+      mtcBC->modem_type  = MT_NONE;
+      mtcBC->conn_elem   = CONN_ELEM_TRANS;
+    }
+    else
+    {
+      mtcBC->bearer_serv = cmhCC_SelServ( ccShrdPrm.CBSTname );
+      mtcBC->modem_type  = cmhCC_SelMT  ( ccShrdPrm.CBSTspeed );
+      mtcBC->conn_elem   = cmhCC_SelCE  ( ccShrdPrm.CBSTce );
+    }
+
+    /* not sure whether this is taken into account by CC */
+    mtcBC->stop_bits   = DEF_BC1_SB; /*cmhCC_SelStopBit( srcId );*/
+    mtcBC->data_bits   = DEF_BC1_DB; /*cmhCC_SelDataBit( srcId );*/
+    mtcBC->parity      = DEF_BC1_PR; /*cmhCC_SelParity ( srcId );*/
+    mtcBC->flow_control = DEF_BC1_FC;
+    /*****************************************************/
+
+/*    mncc_configure_req -> bcpara   = *mtcBC; superfluous */
+    mncc_configure_req -> sns_mode = ccShrdPrm.snsMode;
+#ifdef FF_TTY
+    mncc_configure_req -> ctm_ena = ccShrdPrm.ctmReq;
+#else
+    mncc_configure_req -> ctm_ena = CTM_DISABLED;
+#endif /* FF_TTY */
+    PSENDX (CC, mncc_configure_req);
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_SendSS            |
++-------------------------------------------------------------------+
+
+  PURPOSE : send SS facility
+
+*/
+
+LOCAL SHORT psaCC_SendSS ( SHORT cId )
+{
+  T_CC_CALL_TBL *pCtbNtry = ccShrdPrm.ctb[cId];
+  UBYTE           ccdRet;       /* holds CCD return value */
+
+  TRACE_FUNCTION ("psaCC_SendSS()");
+
+  if (pCtbNtry EQ NULL)
+    return -1; /* Ensure not to dereference NULL */
+
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  {
+    PALLOC (mncc_facility_req, MNCC_FACILITY_REQ);
+
+    /*
+     * fill in primitive parameter: facility request
+     */
+
+    mncc_facility_req -> ti          = pCtbNtry -> ti;
+    mncc_facility_req -> ss_version  = pCtbNtry -> SSver;
+
+    CCD_START;
+    {
+      MCAST( com, COMPONENT );
+
+      memset( com, 0, sizeof( T_COMPONENT ));
+      switch( ccShrdPrm.cmpType )
+      {
+        case( CT_INV ):
+          com -> v_inv_comp = TRUE;
+          com -> inv_comp.v_inv_id  = TRUE;
+          com -> inv_comp.inv_id    = pCtbNtry -> iId 
+                                    = ccShrdPrm.iIdNxt++;
+          com -> inv_comp.v_op_code = TRUE;
+          com -> inv_comp.op_code   = pCtbNtry -> opCode
+                                    = ssFIECodeBuf.buf[0];
+          com -> inv_comp.v_params  = TRUE;
+          com -> inv_comp.params.l_params = ssFIECodeBuf.l_buf-8;
+          com -> inv_comp.params.o_params = 8;
+          memcpy( com -> inv_comp.params.b_params, 
+                  ssFIECodeBuf.buf, ssFIECodeBuf.l_buf );
+          break;
+        case( CT_RET_RSLT ):
+          break;
+        case( CT_RET_ERR ):
+          break;
+        case( CT_RET_REJ ):
+          break;
+      }
+      mncc_facility_req -> fac_inf.l_fac = FACILITY_LEN<<3;
+      mncc_facility_req -> fac_inf.o_fac = 0;
+      ccdRet = ccd_codeMsg (CCDENT_FAC,
+                            UPLINK,
+                            (T_MSGBUF *) &mncc_facility_req -> fac_inf,
+                            (UBYTE    *) _decodedMsg,
+                            COMPONENT);
+
+      if( ccdRet NEQ ccdOK )
+      {
+        TRACE_EVENT_P1( "CCD Coding Error: %d",ccdRet ); 
+        PFREE( mncc_facility_req );
+        CCD_END;
+        return( -1 );
+      }
+    }
+    CCD_END;
+
+    pCtbNtry -> srvType = ST_MOS;
+
+    psaCC_DumpFIE ( &mncc_facility_req -> fac_inf );
+    cmhCC_sendFie ( CSCN_FACILITY_DIRECTION_OUT,
+                    cId,
+                    &mncc_facility_req -> fac_inf );
+    
+    PSENDX (CC, mncc_facility_req);
+  }
+
+  return 0;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_BuildMPTY         |
++-------------------------------------------------------------------+
+
+  PURPOSE : build multiparty
+
+*/
+
+GLOBAL void psaCC_BuildMPTY ( SHORT cId )
+{
+  SHORT ctbIdx;     /* holds call table index */
+
+  TRACE_FUNCTION ("psaCC_BuildMPTY()");
+
+/*
+ *-------------------------------------------------------------------
+ * set multiparty status for held calls
+ *-------------------------------------------------------------------
+ */
+  for( ctbIdx = 0; ctbIdx < MAX_CALL_NR; ctbIdx++ )
+  {
+    if (ccShrdPrm.ctb[ctbIdx] NEQ NULL AND
+        psaCC_ctb(ctbIdx)->calStat EQ CS_HLD )
+    {
+      if( psaCC_ctb(ctbIdx)->mptyStat NEQ CS_ACT )
+      
+        psaCC_ctb(ctbIdx)->mptyStat = CS_ACT_REQ;
+    }
+  }
+
+  /* set multiparty status for active call */
+  if( psaCC_ctb(cId)->mptyStat NEQ CS_ACT )
+    psaCC_ctb(cId)->mptyStat = CS_ACT_REQ;
+
+/*
+ *-------------------------------------------------------------------
+ * send facility information element
+ *-------------------------------------------------------------------
+ */
+  psaCC_asmBuildMPTY();
+
+  if( psaCC_SendSS(cId) EQ 0 )
+  {
+    ccShrdPrm.cIdMPTY = cId;
+    TIMERSTART( TMPTY_VALUE, ACI_TMPTY );
+  }
+    
+  psaCC_MPTY (cId, MPTY_BUILD_SENT);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_HoldMPTY          |
++-------------------------------------------------------------------+
+
+  PURPOSE : hold multiparty
+
+*/
+
+GLOBAL void psaCC_HoldMPTY ( SHORT cId )
+{
+  SHORT ctbIdx;     /* holds call table index */
+
+  TRACE_FUNCTION ("psaCC_HoldMPTY()");
+
+/*
+ *-------------------------------------------------------------------
+ * set call status for multiparty members
+ *-------------------------------------------------------------------
+ */
+  for( ctbIdx = 0; ctbIdx < MAX_CALL_NR; ctbIdx++ )
+  {
+    if (ccShrdPrm.ctb[ctbIdx] NEQ NULL AND
+        psaCC_ctb(ctbIdx)->calStat  EQ CS_ACT AND 
+        psaCC_ctb(ctbIdx)->mptyStat EQ CS_ACT)
+    {
+      psaCC_ctb(ctbIdx)->calStat = CS_HLD_REQ;
+    }
+  }
+
+  /* set multiparty status for active call */
+  psaCC_ctb(cId)->calStat = CS_HLD_REQ;
+
+/*
+ *-------------------------------------------------------------------
+ * send facility information element
+ *-------------------------------------------------------------------
+ */
+  psaCC_asmHoldMPTY();
+
+  if( psaCC_SendSS(cId) EQ 0 )
+  {
+    ccShrdPrm.cIdMPTY = cId;
+    TIMERSTART( TMPTY_VALUE, ACI_TMPTY );
+  }
+
+  psaCC_MPTY (cId, MPTY_HOLD_SENT);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_RetrieveMPTY      |
++-------------------------------------------------------------------+
+
+  PURPOSE : retrieve multiparty
+
+*/
+
+GLOBAL void psaCC_RetrieveMPTY ( SHORT cId )
+{
+  SHORT ctbIdx;     /* holds call table index */
+
+  TRACE_FUNCTION ("psaCC_RetrieveMPTY()");
+
+/*
+ *-------------------------------------------------------------------
+ * set call status for multiparty members
+ *-------------------------------------------------------------------
+ */
+  for( ctbIdx = 0; ctbIdx < MAX_CALL_NR; ctbIdx++ )
+  {
+    if (ccShrdPrm.ctb[ctbIdx] NEQ NULL AND
+        psaCC_ctb(ctbIdx)->calStat  EQ CS_HLD AND 
+        psaCC_ctb(ctbIdx)->mptyStat EQ CS_ACT)
+    {
+      psaCC_ctb(ctbIdx)->calStat = CS_ACT_REQ;
+    }
+  }
+
+  /* set multiparty status for active call */
+  psaCC_ctb(cId)->calStat = CS_ACT_REQ;
+
+/*
+ *-------------------------------------------------------------------
+ * send facility information element
+ *-------------------------------------------------------------------
+ */
+  psaCC_asmRetrieveMPTY();
+
+  if( psaCC_SendSS(cId) EQ 0 )
+  {
+    ccShrdPrm.cIdMPTY = cId;
+    TIMERSTART( TMPTY_VALUE, ACI_TMPTY );
+  }
+
+  psaCC_MPTY (cId, MPTY_RETRIEVE_SENT);
+
+  return;
+}
+
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_CountMPTY         |
++-------------------------------------------------------------------+
+
+  PURPOSE : counts the number of parties in a MPTY
+
+*/
+
+GLOBAL int psaCC_CountMPTY ( void )
+{
+  int i = 0;
+  SHORT cId;
+  TRACE_FUNCTION ("psaCC_CountMPTY()");
+  
+  for( cId = 0; cId < MAX_CALL_NR; cId++ )
+  {
+    if (ccShrdPrm.ctb[cId] NEQ NULL AND
+        psaCC_ctb(cId)->mptyStat EQ CS_ACT)
+    {
+      i++;
+    }
+  }
+  return i;
+}
+
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_SplitMPTY         |
++-------------------------------------------------------------------+
+
+  PURPOSE : split multiparty
+
+*/
+
+GLOBAL void psaCC_SplitMPTY ( SHORT cId )
+{
+  TRACE_FUNCTION ("psaCC_SplitMPTY()");
+
+  /* set multiparty status for active call */
+  psaCC_ctb(cId)->mptyStat = CS_DSC_REQ;
+
+/*
+ *-------------------------------------------------------------------
+ * send facility information element
+ *-------------------------------------------------------------------
+ */
+  psaCC_asmSplitMPTY();
+
+  if( psaCC_SendSS(cId) EQ 0 )
+  {
+    ccShrdPrm.cIdMPTY = cId;
+    TIMERSTART( TMPTY_VALUE, ACI_TMPTY );
+  }
+
+  psaCC_MPTY (cId, MPTY_SPLIT_SENT);
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_ECT               |
++-------------------------------------------------------------------+
+
+  PURPOSE : explicit call transfer
+
+*/
+
+GLOBAL SHORT psaCC_ECT ( SHORT cId )
+{
+  SHORT psa_ret;
+  
+  TRACE_FUNCTION ("psaCC_ECT()");
+
+/*
+ *-------------------------------------------------------------------
+ * send facility information element
+ *-------------------------------------------------------------------
+ */
+  psaCC_asmECT();
+
+  psa_ret = psaCC_SendSS(cId);
+    
+  if( psa_ret EQ 0 )
+  {
+    TIMERSTART( TECT_VALUE, ACI_TECT );
+  }
+ 
+  return(psa_ret);
+}
+
+#if 0 /* HM 3-May-2005: This function is not used, but it's still planned for some day */
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_BCapCode          |
++-------------------------------------------------------------------+
+
+  PURPOSE : code bearer capabilites according GSM 04.08
+
+*/
+
+GLOBAL SHORT psaCC_BCapCode ( UBYTE reqId, SHORT cId, UBYTE bc )
+{
+  TRACE_FUNCTION ("psaCC_BCapCode()");
+
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  {
+    PALLOC (mncc_bearer_cap_req, MNCC_BEARER_CAP_REQ);
+
+    /*
+     * fill in primitive parameter: bearer capability coding request
+     */
+    mncc_bearer_cap_req -> req_id = reqId;
+    mncc_bearer_cap_req -> bc_mod = BC_MOD_CODE;
+    mncc_bearer_cap_req -> bcpara = psaCC_ctb(cId)->BC[bc];
+
+    PSENDX (CC, mncc_bearer_cap_req);
+  }
+
+  return 0;
+}
+#endif /* #if 0 */
+
+#if 0 /* HM 3-May-2005: This function is not used, but it's still planned for some day */
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_BCapDecode        |
++-------------------------------------------------------------------+
+
+  PURPOSE : decode bearer cpabilities according GSM 04.08 into struct
+            bcpara.
+
+*/
+
+GLOBAL SHORT psaCC_BCapDecode ( UBYTE reqId, UBYTE bcLen, UBYTE *bc )
+{
+  TRACE_FUNCTION ("psaCC_BCapDecode()");
+
+/*
+ *-------------------------------------------------------------------
+ * create and send primitive
+ *-------------------------------------------------------------------
+ */
+  if( bcLen > MAX_BC_LEN ) return -1;
+
+  {
+    PALLOC (mncc_bearer_cap_req, MNCC_BEARER_CAP_REQ);
+
+    /*
+     * fill in primitive parameter: bearer capability decoding request
+     */
+    mncc_bearer_cap_req -> req_id        = reqId;
+    mncc_bearer_cap_req -> bc_mod        = BC_MOD_DECODE;
+    mncc_bearer_cap_req -> bcconf.bc_len = bcLen;
+
+    memcpy( mncc_bearer_cap_req -> bcconf.bc, bc, bcLen );
+
+    PSENDX (CC, mncc_bearer_cap_req);
+  }
+
+  return 0;
+}
+#endif /* #if 0 */
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)         MODULE  : PSA_CCS                 |
+|                                 ROUTINE : psaCC_MPTY              |
++-------------------------------------------------------------------+
+
+  PURPOSE : Inform CC about an event related to a multiparty call
+            which may change the auxiliary state hold or mpty in CC.
+
+*/
+
+GLOBAL SHORT psaCC_MPTY ( SHORT cId, UBYTE mpty_event )
+{
+  TRACE_FUNCTION ("psaCC_MPTY()");
+  
+  /* Send the synchronization request to CC */
+  {
+    PALLOC (mncc_sync_req, MNCC_SYNC_REQ); /* T_MNCC_SYNC_REQ */
+    mncc_sync_req->synccs     = SYNCCS_MPTY_EVENT;
+    mncc_sync_req->ti         = psaCC_ctb(cId)->ti;
+    mncc_sync_req->mpty_event = mpty_event;
+    PSENDX (CC, mncc_sync_req);
+  }
+  return 0;
+}
+
+/*==== EOF ========================================================*/
+